I am writing a very basic SSL client to connect to a HTTPS web server. I can connect and process the request/response just fine. However OpenSSL is reporting UNABLE_TO_GET_ISSUER_CERT_LOCALLY
, but so far I choose to ignore the error :-). Now I want to solve that part of the problem.
I am testing by connecting to a public SSL server on HTTPS, such as Google or Yahoo, and checking the return of SSL_get_verify_result(...)
.
As I understand it, I need the CA pem files for that specific site so that OpenSSL can verify the chain to a trusted certificate authority. In this case, that would be the authority that signed the certs for Google or Yahoo.
To get the PEM files which I expect should work, I opened my FireFox, navigated to those sites, and performed a View Certificate and exported each one up the list. So for example, I have a file called "GeoTrustGlobalCA.pem" which all looks good. In fact, when I went to the GeoTrust site directly and downloaded their root certificate, it is identical to the one I exported from FireFox, as I would expect.
So, for example with Google which showed two certificates in the tree in FireFox, I load each one with:
result = SSL_CTX_load_verify_locations(ctx,"GoogleInternetAuthorityG2.pem",NULL);
if (result == 0) {
puts("Opps... Can't load the certificate");
}
result = SSL_CTX_load_verify_locations(ctx,"GeoTrustGlobalCA.pem",NULL);
if (result == 0) {
puts("Opps... Can't load the certificate");
}
After that, the usual stuff to connect and communicate:
BIO_set_conn_hostname(bio, "www.google.com:https");
And get no errors when loading or connecting.
However, the verification does not work.
result = SSL_get_verify_result(ssl);
printf("The Verify Result is %d \n",result);
I get the return UNABLE_TO_GET_ISSUER_CERT_LOCALLY (error code 20)
.
So, am I missing some concept here? Wouldn't this give me the X509_V_OK
result because it has the trusted certificates? There were only two that were up the chain from google.com, and I used them.