SSL Certificate Verification programmatically
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.
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.
My solution
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_lib开发者_运维百科rary_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;
}
I am leaving out the getPeerCert() method's defenition as it gets the peer cert and verifies using openssl's methods.
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.
Update 1
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\
The specific error you are are getting is
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.
Try putting the gmail issuer, and not the gmail certificate, into certificate.pem.
Also, make sure you understand Bruno's first comment on your question.
精彩评论