<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <div class="moz-cite-prefix">On 2/13/2023 9:53 PM, Viktor Dukhovni
      wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:Y+r3l4RTQ1HeLBza@straasha.imrryr.org">
      <pre class="moz-quote-pre" wrap="">On Mon, Feb 13, 2023 at 07:56:22PM -0500, Karl Denninger wrote:

</pre>
      <blockquote type="cite">
        <pre class="moz-quote-pre" wrap="">Environment is a client/server, with both ends checking the certificates.

             Netscape Cert Type:
             X509v3 Extended Key Usage:
                 TLS Web Server Authentication, TLS Web Client Authentication

The client is able to follow the signature and verifies it. However,
the client certificate with the same extensions connects, but the
server complains on verification that the client cert supplied has
"invalid purpose."
</pre>
      </blockquote>
      <pre class="moz-quote-pre" wrap="">
The problem purpose may be a result of explicit EKUs for one of the
issuing CAs, that don't include "TLS Web Client Authentication" (a.k.a.
"clientAuth").

You don't need to test with TLS connections,  instead, for example:

    # hostname=...
    # CAfile=...
    # openssl verify -show_chain -purpose sslclient \
        -verify_hostname "$hostname" \
        -trusted "$CAfile" \
        -untrusted "/etc/letsencrypt/live/$hostname/fullchain.pem" \
        "/etc/letsencrypt/live/$hostname/cert.pem"
    /etc/letsencrypt/live/.../cert.pem: OK
    Chain:
    depth=0: CN = ... (untrusted)
    depth=1: C = US, O = Let's Encrypt, CN = R3 (untrusted)
    depth=2: C = US, O = Internet Security Research Group, CN = ISRG Root X1

While with "smimesign" as the purpose:

    # hostname=...
    # CAfile=...
    # openssl verify -show_chain -purpose smimesign \
        -verify_hostname "$hostname" \
        -trusted "$CAfile" \
        -untrusted "/etc/letsencrypt/live/$hostname/fullchain.pem" \
        "/etc/letsencrypt/live/$hostname/cert.pem"
    CN = ...
    error 26 at 0 depth lookup: unsupported certificate purpose
    C = US, O = Let's Encrypt, CN = R3
    error 26 at 1 depth lookup: unsupported certificate purpose
    error /etc/letsencrypt/live/.../cert.pem: verification failed

However, note that the error reported by OpenSSL is "unsupported
purpose", NOT "invalid purpose", for that error, I actually need to
specify a made up purpose name.  So it is unclear how your server
managed to report an "invalid purpose", perhaps there's a typo in
the server code, and it rejects all client certificates, because
it tries to check them against an unknown (to OpenSSL) "purpose".
</pre>
    </blockquote>
    <p>I generated a certificate for the connecting device with "server,
      client" as the purpose (not the EKUs but "nsCertType") and the
      server now accepts it.<br>
    </p>
    <p>This particular code set was used a number of years (and many
      OpenSSL releases) back and didn't complain about this; its not a
      big deal to issue the certs this way for the connecting client
      endpoints, but I was more than a bit surprised when I got the
      rejections, since the keyUsage and EKU parameters appeared to
      permit what I was doing.<br>
    </p>
    <div class="moz-signature">-- <br>
      --
      Karl Denninger<br>
      <i>The Market-Ticker</i><br>
      S/MIME Email accepted and preferred</div>
  </body>
</html>