OpenSSL chain build error diagnostics - Re: Why does OpenSSL report google's certificate is "self-signed"?

David von Oheimb dev at ddvo.net
Sat Apr 3 19:20:58 UTC 2021


Hi Nan, Viktor, et al.,

/From: openssl-users <openssl-users-bounces at openssl.org
<https://mta.openssl.org/mailman/listinfo/openssl-users>> On Behalf Of
Viktor//Dukhovni //Sent: Wednesday, 31 March, 2021 10:31/
> Most likely you haven't configured a suitable CAfile and/or CApath,
> which contains the root CA that ultimately issued Google's certificate.

Yeah, that is the usual reason.

> It looks like Google includes a self-signed root CA in the wire
> certificate chain,
>
Not really. @Viktor, see the diagnostic output of the alternative call

   openssl s_client -connect google.com:443

that Nan provided below (and which is easy to reproduce):

> ---
> Certificate chain
>  0 s:C = US, ST = California, L = Mountain View, O = Google LLC, CN =
> *.google.com
>    i:C = US, O = Google Trust Services, CN = GTS CA 1O1
>  1 s:C = US, O = Google Trust Services, CN = GTS CA 1O1
>    i:OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
> ---
This chain does not include the root cert (which would be by GlobalSign
in this case).

@all, contrbuting to the discussion that spawned over the last couple of
days on whether the server should include the root of its chain:
IMO is should be advised not to include the root cert (i.e., the trust
anchor).
While the (needless) extra amount of data is usually not a problem,
the main problem that I see is that the receiver may be mislead to
accept the root cert as trusted although when received this way it is
not trustworthy.
Instead, when verifying the server chain, the receiver must already have
a trust store containing (root) certs that are considered trusted,
and for the chain received from the server there should be a suitable
trust anchor (which typically takes the form of a self-signed cert) in
that trust store.


> and if no match is found in the trust store,
> you'll get the reported error.
The reason must be something else. Note that the error was
X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT,
which means that the chain built contains only one element, and this
element is self-signed and not trusted.
So it cannot be the chain  *.google.com ->  GTS CA 1O1 -> GlobalSign.

@Nan, I find this error very unexpected - something pretty strange must
have happened in your application.
If no suitable trusted root is available in the trust store, the error
thrown should have been
20 ("unable to get local issuer certificate") =
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY.

BTW, many of those OpenSSL verify error codes are IMHO pretty hard to
(correctly) understand and therefore should be re-phrased for clarity.
And unfortunately OpenSSL by default does not give much further
diagnostics on cert verification errors.
I advise using `X509_STORE_CTX_print_verify_cb()` which I added last
year to the master as part of the CMP contribution.
This can be done simply as follows:

    X509_STORE_set_verify_cb(my_X509_STORE, X509_STORE_CTX_print_verify_cb);

On X509_verify_cert() error, this provides in the error queue not only
the error code and string, but also the cert for which the error occurred
as well as the set of untrusted certs and the set of trust anchor certs
that were available for chain building in the current X509_STORE_CTX.

Regards,

   David


On 31.03.21 07:49, Nan Xiao wrote:
> Hi OpenSSL users,
>
> Greetings from me!
>
> I am using the master branch of OpenSSL and testing client-arg program
> (in demos/bio) with "google.com:443":
>
> # LD_LIBRARY_PATH=/root/openssl/build gdb --args ./client-arg -connect
> "google.com:443"
> ......
> (gdb)
> 91     if (BIO_do_connect(sbio) <= 0) {
> (gdb)
> 97     if (BIO_do_handshake(sbio) <= 0) {
> (gdb) p ssl->verify_result
> $1 = 18
>
> The connection is successful, but the ssl->verify_result is 18, i.e.,
> X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT. I am a little confused why
> OpenSSL reports google's certificate is "self-signed"? And it should
> be not. The following result is from "openssl s_client":
>
> # openssl s_client -connect google.com:443
> CONNECTED(00000003)
> depth=2 OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
> verify return:1
> depth=1 C = US, O = Google Trust Services, CN = GTS CA 1O1
> verify return:1
> depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN
> = *.google.com
> verify return:1
> ---
> Certificate chain
>  0 s:C = US, ST = California, L = Mountain View, O = Google LLC, CN =
> *.google.com
>    i:C = US, O = Google Trust Services, CN = GTS CA 1O1
>  1 s:C = US, O = Google Trust Services, CN = GTS CA 1O1
>    i:OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
> ---
>
> Anyone can give some clues? Thanks very much in advance!
>
> Best Regards
> Nan Xiao
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mta.openssl.org/pipermail/openssl-users/attachments/20210403/f2e81636/attachment.html>


More information about the openssl-users mailing list