以编程方式验证SSL证书

时间:2011-05-27 18:56:41

标签: openssl ssl-certificate verification

我知道这将是一个巨大的帖子,但我想通过基本上提供它的所有细节来呈现我面临的问题。

背景 我有一个应用程序触发firefox获取URL数据并显示网页中所有组件的单个组件加载时间(如Firebug)。但是,应用程序不会自动验证ssl证书(例如,如果没有用户手动接受/拒绝证书,则会因为证书错误而陷入困境,而且所有这些都是以编程方式完成的)。我需要通过在启动firefox进程之前尝试验证站点的证书来解决此问题。

我的解决方案

我发现这个C代码在C中以编程方式验证SSL证书。我简要概述了它。这是main()方法:

SSL_library_init();
ERR_load_BIO_strings();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();

/* Set up the SSL context */
ctx = SSL_CTX_new(SSLv23_client_method());

/* Load the trust store - in this case, it's just a single
 * certificate that has been created for testing purposes.
 */

if(! SSL_CTX_load_verify_locations(ctx,"certificate.pem",NULL))
{
    fprintf(stderr, "Error loading trust store\n");
    //ERR_print_errors_fp(stderr);
    SSL_CTX_free(ctx);
    return 0;
}

/* Setup the connection */
bio = BIO_new_ssl_connect(ctx);

/* Set the SSL_MODE_AUTO_RETRY flag */

BIO_get_ssl(bio, & ssl);
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

/* Create and setup the connection */

BIO_set_conn_hostname(bio, "mail.google.com:https");

fprintf(stderr, "Connecting to host ...\n");

if(BIO_do_connect(bio) <= 0)
{
    fprintf(stderr, "Error attempting to connect: %d\n",BIO_do_connect(bio));
    //ERR_print_errors_fp(stderr);
    BIO_free_all(bio);
    SSL_CTX_free(ctx);
    return 0;
}
/* Retrieve the peer certificate */

fprintf(stderr, "Retrieving peer certificate\n");
if(getPeerCert(ssl, & peerCert) != X509_V_OK)
{
    /* Can be changed to better handle a suspect certificate. However,
     * for the purposes of this demonstration, we're aborting.
     */
    fprintf(stderr, "Certificate verification error: %i\n",SSL_get_verify_result(ssl));
    BIO_free_all(bio);
    SSL_CTX_free(ctx);
    return 0;
}

我放弃了getPeerCert()方法的defenition,因为它获得了对等证书并使用openssl的方法进行验证。

certificate.pem也是一个pem文件,它是按照解决this问题的步骤获得的。

然而,当我尝试运行时,我得到了

Connecting to host ...
Retrieving peer certificate
Certificate verification error: 20

我无法理解为什么会发生这种情况,因为验证应该成功。我会很高兴能得到任何帮助。

更新1

我尝试使用open SSL命令并尝试从代码中调用命令,即

opensssl verify -CAfile ./ca-bundle.crt cert1...

但是我发现它验证了内部和外部证书,它似乎也验证了实际上应该是坏的证书(内部)(特别是糟糕的域证书)。我非常感谢对此的任何见解。

2 个答案:

答案 0 :(得分:2)

opensssl verify -CAfile ./ca-bundle.crt -untrusted cert1...

看到这篇文章,但我还不知道如何以编程方式做到这一点..

http://www.herongyang.com/crypto/openssl_verify_2.html \

答案 1 :(得分:1)

你要获得的specific error

20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate

the issuer certificate could not be found: this occurs if the issuer certificate of an untrusted certificate cannot be found.

尝试将gmail颁发者而不是gmail证书放入certificate.pem。

另外,请确保您了解Bruno对您问题的第一条评论。