<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Hi Nan, Viktor, et al.,<br>
    </p>
    <i>From: openssl-users <<a
        href="https://mta.openssl.org/mailman/listinfo/openssl-users">openssl-users-bounces
        at openssl.org</a>> On Behalf Of Viktor</i><i> Dukhovni
    </i><i>Sent: Wednesday, 31 March, 2021 10:31</i>
    <blockquote type="cite">
      <pre>Most likely you haven't configured a suitable CAfile and/or CApath,
which contains the root CA that ultimately issued Google's certificate.
</pre>
    </blockquote>
    <p>Yeah, that is the usual reason.<br>
      <br>
    </p>
    <blockquote type="cite">
      <pre>It looks like Google includes a self-signed root CA in the wire
certificate chain,

</pre>
    </blockquote>
    <p>Not really. @Viktor, see the diagnostic output of the alternative
      call<br>
    </p>
    <pre class="moz-quote-pre" wrap="">   openssl s_client -connect google.com:443</pre>
    <p>that Nan provided below (and which is easy to reproduce):<br>
      <blockquote type="cite">
        <pre class="moz-quote-pre" wrap="">---
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
---</pre>
      </blockquote>
      This chain does not include the root cert (which would be by
      GlobalSign in this case).<br>
    </p>
    <p>@all, contrbuting to the discussion that spawned over the last
      couple of days on whether the server should include the root of
      its chain:<br>
      IMO is should be advised not to include the root cert (i.e., the
      trust anchor).<br>
      While the (needless) extra amount of data is usually not a
      problem,<br>
      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.<br>
      Instead, when verifying the server chain, the receiver must
      already have a trust store containing (root) certs that are
      considered trusted, <br>
      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.<br>
    </p>
    <p><br>
    </p>
    <blockquote type="cite">
      <pre>and if no match is found in the trust store,
you'll get the reported error.</pre>
    </blockquote>
    The reason must be something else. Note that the error was
    X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT, <br>
    which means that the chain built contains only one element, and this
    element is self-signed and not trusted.<br>
    So it cannot be the chain  *.google.com ->  GTS CA 1O1 ->
    GlobalSign.<br>
    <br>
    @Nan, I find this error very unexpected - something pretty strange
    must have happened in your application.<br>
    If no suitable trusted root is available in the trust store, the
    error thrown should have been <br>
    20 ("unable to get local issuer certificate") =
    X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY.<br>
    <br>
    BTW, many of those OpenSSL verify error codes are IMHO pretty hard
    to (correctly) understand and therefore should be re-phrased for
    clarity.<br>
    And unfortunately OpenSSL by default does not give much further
    diagnostics on cert verification errors.<br>
    I advise using `X509_STORE_CTX_print_verify_cb()` which I added last
    year to the master as part of the CMP contribution.<br>
    This can be done simply as follows:<br>
    <pre>    X509_STORE_set_verify_cb(my_X509_STORE, X509_STORE_CTX_print_verify_cb);</pre>
    <p>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<br>
      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.<br>
    </p>
    <p>Regards,</p>
    <p>    David</p>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 31.03.21 07:49, Nan Xiao wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CA+MhoaN2xNSR1gynxzZG+-whPS0OOJySBhX2XRSm=mrQ2JKD1A@mail.gmail.com">
      <pre class="moz-quote-pre" wrap="">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

</pre>
    </blockquote>
  </body>
</html>