以编程方式进行SSL证书验证

问题描述:

我知道这将是一个巨大的职位,但我想通过提供所有细节来提出我所面临的问题.

I know this will be a huge post, but I wanted to present a problem that I am facing by essentially giving all the details of it.

背景 我有一个触发firefox来获取URL数据并显示网页(如Firebug)中所有组件的单个组件加载时间的应用程序.但是,该应用程序不会自动验证ssl证书(即,如果存在错误的证书,它将卡住,因为没有用户手动接受/拒绝证书,并且全部以编程方式完成).我需要通过在启动Firefox程序之前尝试验证网站的证书来解决此问题.

Background I have an application which triggers firefox to fetch URL data and present the individual component load time of all components in a web page (like Firebug). However the application does not validate ssl certs automatically (i.e it gets stuck up if there is a bad certificate as there is no user to manually accept/reject a certificate and it is all done programmatically). I need to solve this issue by trying to validate the site's certificate before the firefox process is started.

我的解决方案

我发现这部分C代码可以在C中以编程方式验证SSL证书.我对此进行了简要概述.这是main()方法:

I found this bit of C code that does verification of SSL certs programmatically in C. I am giving a brief overview of it. this is the main() method:

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;
}

在获取对等证书并使用openssl的方法进行验证时,我忽略了getPeerCert()方法的定义.

I am leaving out the getPeerCert() method's defenition as it gets the peer cert and verifies using openssl's methods.

certificate.pem也是一个pem文件,通过执行

Also the certificate.pem is a pem file obtained by following the steps for the solution to this question.

但是,当我尝试运行此程序时,我会得到

However When I try to run this i get

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

由于验证成功,所以我看不到为什么会发生这种情况.我将很感激并很高兴能得到我的任何帮助.

I am unable to see why this should happen as the verification should succeed. I would be grateful and glad to any help that I can get.

更新1

我尝试使用开放SSL命令,并尝试从代码(即

I tried using the open SSL command and tried calling the command from code i.e. the

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

但是我发现它可以验证内部和外部证书,它似乎也可以验证实际上应该是错误的(内部)证书(特别是错误的域证书).我将不胜感激对此有任何见识.

However I found that it validates internal and external certs, it also seemed to validate certs (internal) that should actually be bad (specifically bad domain certs). I would greatly appreciate any insight into this.

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

请参阅本文,但我还不知道如何以编程方式进行操作.

see this article, but I don't know yet how to do it programatically..

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