3

OpenSSL を使用して HTTPS 証明書チェーンを検証したかったのです。試行錯誤の後、私はこれを使用してこれを行うことができましたs_client

openssl s_client -connect google.com:https -CApath root < /dev/null

ここrootには、アップストリームからダウンロードした Google の 2 つのルート CA 証明書が含まれています (両方が必要かどうかはわかりませんが、この方法で機能します)。

$ ls -1 root
594f1775.0 // generated by c_rehash
7999be0d.0 // generated by c_rehash
Equifax_Secure_Certificate_Authority.pem
GeoTrust_Global_CA.pem

上記のopenssl s_clientコマンドは正常に機能1し、期待どおりに戻ります。

depth=3 /C=US/O=Equifax/OU=Equifax Secure Certificate Authority
verify return:1
depth=2 /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
verify return:1
depth=1 /C=US/O=Google Inc/CN=Google Internet Authority G2
verify return:1
depth=0 /C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
verify return:1

ここまでは順調ですね。しかし、libssl(OpenSSL API などの) を使用して同じ機能を実装しようとすると、うまくいきませんでした。すでにrootdir をCAPath(経由でSSL_CTX_load_verify_locations) 指定しましたが、エラー 20 が発生し続けました。

20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: ローカル発行者証明書を取得できません 発行者証明書が見つかりませんでした: これは、信頼されていない証明書の発行者証明書が見つからない場合に発生します。

私はしばらくデバッグしてきましたが、まったく手がかりがありません。どんな助けでも大歓迎です!

#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/bn.h>
#include <openssl/asn1.h>
#include <openssl/x509_vfy.h>
#include <openssl/pem.h>

#include <stdio.h>
#include <string.h>

#define MAX_LENGTH 1024

int main()
{
    BIO * bio;
    SSL * ssl;
    SSL_CTX * ctx;

    int p;

    /* Set up the library */
    ERR_load_BIO_strings();
    SSL_load_error_strings();
    SSL_library_init();
    OpenSSL_add_all_algorithms();

    /* Set up the SSL context */
    const SSL_METHOD *meth = SSLv23_client_method();
    ctx = SSL_CTX_new(meth);
    if (ctx == NULL) {
        ERR_print_errors_fp(stderr);
        SSL_CTX_free(ctx);
        return -1;
    }


    char* store_path = "./root";
    if(!SSL_CTX_load_verify_locations(ctx, NULL, store_path))
    {
        fprintf(stderr, "Can't load trusted CA from %s\n", store_path);
        return -1;
    }

    /* Setup the connection */
    bio = BIO_new_ssl_connect(ctx);
    BIO_get_ssl(bio, & ssl);
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

    // Set
    SSL_CTX_set_verify_depth(ctx, 50);
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);

    /* Create and setup the connection */

    BIO_set_conn_hostname(bio, "www.google.com:https");
    if(BIO_do_connect(bio) <= 0)
    {
        ERR_print_errors_fp(stderr);
        BIO_free_all(bio);
        SSL_CTX_free(ctx);
        return 0;
    }

    if(SSL_get_verify_result(ssl) != X509_V_OK)
    {
        fprintf(stderr, "Verification Error: %ld\n", SSL_get_verify_result(ssl));
        ERR_print_errors_fp(stderr);
        BIO_free_all(bio);
        SSL_CTX_free(ctx);
        return 0;
    }

    /* Close the connection and free the context */
    BIO_free_all(bio);
    SSL_CTX_free(ctx);
    return 0;
}
4

0 に答える 0