SpacemanScott
SpacemanScott

Reputation: 1013

Another situation where I get X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY

As a followup to this original question:

Unable to get certificate locally

I did solve the original problem as jww answered.

And I have now followed the same steps of importing the certificate chain for our company site, from "comodo". I simply added them to the file which I originally used with the "google.com" root certs.

Now, although this still works fine with "google", when I connect to our company website, I still get the error code 20 on the SSL_get_verify_result() call.

Is this a result of our using a "wildcard" certificate? i.e.: *.domain.com.

The version of OpenSSL I am currently using is 1.0.1g.

I don't see any other differences from my perspective.

Thanks for any advice.

----- Updated ------

First, let me comment that I am not mentioning our domain, and not posting too much material from the OpenSSL command, as I am not familiar enough with what should be kept confidential.

What I did was combine the base64 encoded certificates into one big file, as the previous post instructed. And I obtained them via the browser "export" utility in the same manner for both. That means the certificates that we use, as well as the google certificates from my previous post are all concatenated. Specifically it looks like this now:

Our Company Cert -----BEGIN CERTIFICATE----- .... -----END CERTIFICATE----- and it is signed by these guys - ComodoRSA -----BEGIN CERTIFICATE----- .... -----END CERTIFICATE----- and that is signed at the root here - ComodoRoot -----BEGIN CERTIFICATE----- .... -----END CERTIFICATE----- and this is the GOOGLE G3 who signed the "www.google.com" -----BEGIN CERTIFICATE----- .... -----END CERTIFICATE----- and the GOOGLE G3 is signed by this one - globalSign -----BEGIN CERTIFICATE----- .... -----END CERTIFICATE-----

Then the code segment I use to test looks like this:

strcpy(host,"our.domain.com");
//  strcpy(host,"www.google.com");
/* Build our SSL context*/
ctx = initialize_ctx(KEYFILE,NULL);

/* Connect the TCP socket*/
sock = tcp_connect(host,port);

And then later...

result = SSL_get_verify_result(ssl);
switch(result) {
case X509_V_ERR_CERT_HAS_EXPIRED : break;
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN : break;
case X509_V_OK : break;
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT : break;
default :puts("Certificate doesn't verify");
}

Simply put, this same code, using this same CRT file, does not give me a "20" error when I use the www.google.com" host, but does give me an error "20" when I use our server. The extent of the test involves changing that commented out name of the host.

Connections to the HTTPS server with commercial clients (Chrome, IE, FF...) have no errors.

As for the comment that recommended the command, I get the following (hopefully I pasted the necessary information):

For Google:

depth=2 OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign verify return:1
depth=1 C = US, O = Google Trust Services, CN = Google Internet Authority G3
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com
verify return:1
read:errno=0
----   other stuff ----
Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google LLC/CN=www.google.com
   i:/C=US/O=Google Trust Services/CN=Google Internet Authority G3
 1 s:/C=US/O=Google Trust Services/CN=Google Internet Authority G3
   i:/OU=GlobalSign Root CA - R2/O=GlobalSign/CN=GlobalSign
---

And for our domain, I am getting the following (company specifics hidden):

depth=2 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
verify error:num=20:unable to get local issuer certificate
verify return:0
read:errno=10054
----   other stuff ---
Certificate chain
 0 s:/C=US/postalCode=00000/ST=IL/L=city/street=main/O=company./OU=PremiumSSL Wildcard/CN=*.domain.com
   i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA
 1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA
    i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
 2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
    i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
----

Now, the chain is that our certificate is signed by "ComodoRSA", and that it is signed by "ComodoRoot".

However, as I originally indicated, our certificate is a "wildcard" certificate, where the google certificate isn't.

So that was my question: Is there a problem using wild card certificates with the version of openSSL 1.0.1g?

--- EDIT2 ----

I am adding more content to the post, so I can include an image from the browser.

Our certificate is on a live web site, and is not self signed.

I am checking the common name in a portion of the code not shown. In this post I am only hoping for advice on this error.

I found a site that uses the same chain we use: DrudgeReport.com

I simply extracted the certificates with the browser, and saved them into a file. This was identical to the steps I used form the google.com site. (View certificate and copy to file)

DrudgeReport chain

The result from Drudge is error 19 which is "self signed", not error 20 which was my error. The root level (comodo secure) is the same when I copy to file from either site (as I would expect).

As I learn this from your comments and the link, I see the next intermediate question is: how do I know what certificates are being sent by the server, and which were in the store? Then I would know which to import. What, if any, is the indicator from the openssl command output you provided?

The educational material on openssl and this is rather difficult to find. Just a lot of doc, which to a novice such as myself, is rather circular in it's definitions.

Thanks for your feedback so far.

Upvotes: 0

Views: 1007

Answers (1)

Steffen Ullrich
Steffen Ullrich

Reputation: 123260

So that was my question: Is there a problem using wild card certificates with the version of openSSL 1.0.1g?

It is not a problem of wildcard certificates. In fact, your code does not even check the subject of the certificate at all (i.e. your code is insecure), it mostly checks the certificate chain, expiration and purpose of the certificate. And the error message from openssl s_client clearly points out the problem:

verify error:num=20:unable to get local issuer certificate

Thus, the problem is not the certificate subject but that it cannot find a local trust anchor. Looking at the certificate chain provided by your server gives the following certificate chain:

 [1] CN=*.domain.com, issued by [2]
 [2] CN=COMODO RSA Organization Validation Secure Server CA, issued by [3]
 [3] CN=COMODO RSA Certification Authority, issued by [ROOT]

The expected [ROOT] is "CN=AddTrust External CA Root" - only this CA is not in your list of trusted root CA.

While you give not the detailed names of the certificates you have in your local trust store my guess is that the CA you call "ComodoRoot" is similar to what I have as "[3] CN=COMODO RSA Certification Authority" in the list. Only, in your trust store it is likely the self-signed version of the certificate while in the certificate chain provided by the server it is a certificate issued by "[ROOT] CN=AddTrust External CA Root". Both certificates have the same public and private key which means that the signatures in certificate chain can be successfully validated with both.

But, the old (and long unsupported version) of OpenSSL you are using can not properly deal with this kind of situation. It will follow the certificate chain send by the server and then expect the last certificate in the chain signed by on of the certificates in your trust store. If this fails it will not check if a shorter chain might be validated successfully instead.

This means it will succeed if you either have "CN=AddTrust External CA Root" in your trust store or if the server sends a short chain which ends with "[2] CN=COMODO RSA Organization Validation Secure Server CA" since then it will find the issuer for this (your "ComodoRoot", i.e. "CN=COMODO RSA Certification Authority") in your trust store.

For a more detailed explanation of this problem see this answer at stackoverflow.com or this article. Note that there is no way to fix this in code with OpenSSL 1.0.1 - you need to either add the missing certificate to your trust store or make changes to the certificate chain send by the server.

Upvotes: 1

Related Questions