<div dir="ltr"><div>Hi Jesse!</div><div><br></div><div>I created  <a href="https://github.com/IngelaAndin/otp/pull/new/ingela/ssl/cert-encode-decode-issue">https://github.com/IngelaAndin/otp/pull/new/ingela/ssl/cert-encode-decode-issue</a> that hopefully will solve the problem that you are having by avoiding to re-encode a receive cert. </div><div>Please try that instead of my original patch, that case of comparison I think should actually work.  </div><div><br></div><div>Regards Ingela Erlang/OTP team - Ericsson AB</div><div><br></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Den tis 21 sep. 2021 kl 12:59 skrev Ingela Andin <<a href="mailto:ingela@andin.se">ingela@andin.se</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><br></div>Hi Bram!<div><br></div><div>Interesting observation!  I will keep digging. I actually believe my first patch solution will not fix the problem as although this code was changed in the version at hand, I checked further and the change should be backwards compatible.</div><div><br></div><div>Regards Ingela</div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Sep 21, 2021 at 10:26 AM Bram Verburg <<a href="mailto:bram.verburg@voltone.net" target="_blank">bram.verburg@voltone.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>Hi Ingela,<br></div><div><br></div><div>I was looking into this too, and I noticed that this particular leaf certificate, once decoded as an OTPCertificate record, does not encode back to the same DER value (which is likely due to the unusual representation of the KeyUsage extension in the original file):<br></div><div><br></div><div>1> {ok, PEM} = file:read_file("cert.pem").                                                      <br></div><div>{ok,<<"-----BEGIN CERTIFICATE-----\nMIIEfDCCAuSgAwIBAgIUdcWg+bxobl7OWSOjbNxyaXTnqx8wDQYJKoZIhvcNAQEL\nBQAwMTEXMBUGA1U"...>>}<br></div><div>2> DER = element(2, hd(public_key:pem_decode(PEM))).<br></div><div><<48,130,4,124,48,130,2,228,160,3,2,1,2,2,20,117,197,160,<br></div><div>  249,188,104,110,94,206,89,35,163,108,220,...>><br></div><div>3> DER = public_key:pkix_encode('OTPCertificate', public_key:pkix_decode_cert(DER, otp), otp).<br></div><div>** exception error: no match of right hand side value <<48,130,4,123,48,130,2,227,160,3,2,1,2,2,20,117,197,160,<br></div><div>                                                        249,188,104,110,94,206,89,35,163,108,220,...>><br></div><div><br></div><div><div></div><div></div></div><div>(That would presumably mean the original DER representation is not really proper DER, as I believe ASN.1's DER encoding is supposed to always produce the same (canonical) byte sequence, in order to allow for reliable signature verification...)<br></div><div><div><br></div><div>I haven't quite pinned it down, but this commit <a href="https://github.com/erlang/otp/pull/4941/commits/80f9b71323c9c5a3bc111fcbc5c6c5ee497e27a6" target="_blank">https://github.com/erlang/otp/pull/4941/commits/80f9b71323c9c5a3bc111fcbc5c6c5ee497e27a6</a> that was included in 24.0.4 seems to sometimes reconstruct a DER representation from an OTPCertificate record, and if that DER value is passed to public_key:pkix_verify/2 instead of the original DER representation, the signature won't match and ssl will throw the reported error.</div></div><div><br></div><div>Hope that might help,<br></div><div><br></div><div>Bram</div><div><br></div><div><div>‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐<br></div><div> On Tuesday, September 21st, 2021 at 10:48 AM, Ingela Andin <<a href="mailto:ingela.andin@gmail.com" target="_blank">ingela.andin@gmail.com</a>> wrote:<br></div></div><div><br></div><blockquote type="cite">
            <div dir="ltr"><div>Hello again! </div><div><br></div><div>I thought of a possible cause  of your strange problem. If the ROOT-cert is sent as part of the chain (optional in the protocol).  We must check that it is a certificate that we trust, part of our "trust store". This was done by  a match of the DER-version of the cert and we should match the decode  structure instead. </div><div><br></div><div>In such cases the following patch ought to solve your problem.  Can you please test it? It is based on the latest maint!</div><div><br></div><div><br></div><div>diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl<br>index cbeb4e4521..1a277964b6 100644<br>--- a/lib/ssl/src/ssl_certificate.erl<br>+++ b/lib/ssl/src/ssl_certificate.erl<br>@@ -596,13 +596,13 @@ path_candidate(Cert, ChainCandidateCAs, CertDbHandle) -><br>             [Root | lists:reverse(Chain)]<br>     end.<br> <br>-handle_partial_chain([#cert{der=DERIssuerCert, otp=OtpIssuerCert}=Cert| Rest] = Path, PartialChainHandler,<br>+handle_partial_chain([#cert{otp=OtpIssuerCert}=Cert| Rest] = Path, PartialChainHandler,<br>                      CertDbHandle, CertDbRef) -><br>     case public_key:pkix_is_self_signed(OtpIssuerCert) of<br>         true -> %% IssuerCert = ROOT (That is ROOT was included in chain)<br>             {ok, {SerialNr, IssuerId}} = public_key:pkix_issuer_id(OtpIssuerCert, self),<br>             case ssl_manager:lookup_trusted_cert(CertDbHandle, CertDbRef, SerialNr, IssuerId) of<br>-                {ok, #cert{der=DERIssuerCert}} -> %% Match sent ROOT to trusted ROOT<br>+                {ok, #cert{otp = OtpIssuerCert}} -> %% Match sent ROOT to trusted ROOT<br>                     maybe_shorten_path(Path, PartialChainHandler, {Cert, Rest});<br>                 {ok, _} -> %% Did not match trusted ROOT<br>                     maybe_shorten_path(Path, PartialChainHandler, {invalid_issuer, Path});<br></div><div><br></div><br><div class="gmail_quote"><div>Regards Ingela Erlang/OTP team- Ericsson AB</div><div dir="ltr"><br></div><div dir="ltr"><br></div><div dir="ltr">Den fre 17 sep. 2021 kl 18:24 skrev Jesse Bickel - NOAA Affiliate <<a href="mailto:jesse.bickel@noaa.gov" rel="noreferrer nofollow noopener" target="_blank">jesse.bickel@noaa.gov</a>>:<br></div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">Good morning,<br>
<br>
This is part question and part potential bug report. I don't have a github<br>
account associated with my workplace at the moment which is why I ask here.<br>
<br>
When we tested an upgrade to rabbitmq, the tls v1.2 server rejected client<br>
certificates with the following message: "In state certify at<br>
ssl_handshake.erl:1975 generated SERVER ALERT: Fatal - Bad Certificate." The<br>
issue happens with otp versions 24.0.4 and later. The earlier version 24.0.3<br>
interoperates with the certificates successfully. After we took a closer look,<br>
the issue has something to do with the key usage extension. If we generate a<br>
similar certificate in all other respects but remove the key usage extension<br>
otp does not reject the certificate. The issue also occurs without mutual<br>
authentication as a CLIENT ALERT when an erlang/otp client validates the same<br>
kind of server certificate.<br>
<br>
The certificates that otp 24.0.4+ rejects were generated by gnutls certtool,<br>
but more specifically the difference in the certificate itself is the length of<br>
the bit string in the key usage extension. Both openssl and gnutls certtool in<br>
their high-level text forms of the working and not working certificates show<br>
the key usage as having the same two values of digital signature and key<br>
encipherment. The difference underneath is that the one generated by gnutls<br>
certtool version 3.6.9 (rejected by otp) is nine bits, value 101000000, whereas<br>
the one generated by openssl 1.1.1f (accepted by otp) is three bits, value 101.<br>
Both versions appear to be valid asn.1, several tools appear to see both<br>
versions as valid certificates, and I cannot easily tell from the relevant ietf<br>
and itu documents that either is invalid.<br>
<br>
Below are sample certificate authority and leaf certificates that can reproduce<br>
the issue in two local erlang/otp sessions in a typical mode of server-only<br>
authentication with tls v1.2 during the handshake.<br>
<br>
Is this a bug introduced in otp 24.0.4 or is this an invalid certificate?<br>
<br>
Jesse Bickel<br>
<br>
-- <br>
Contractor, ERT, Inc.<br>
Federal Affiliation: NWC/OWP/NOAA/DOC<br>
<br>
Sample certificate authority x.509 certificate:<br>
<br>
-----BEGIN CERTIFICATE-----<br>
MIIEMzCCApugAwIBAgIUcgjKevzc6MaGOyaSC0VdidlvgO4wDQYJKoZIhvcNAQEL<br>
BQAwMTEXMBUGA1UEAxMORmFrZWRvbWFpbjIgQ0ExFjAUBgNVBAoTDUZha2UgRG9t<br>
YWluIDIwHhcNMjEwOTE0MTgzNDI5WhcNMjIwOTE0MTgzNDMxWjAxMRcwFQYDVQQD<br>
Ew5GYWtlZG9tYWluMiBDQTEWMBQGA1UEChMNRmFrZSBEb21haW4gMjCCAaIwDQYJ<br>
KoZIhvcNAQEBBQADggGPADCCAYoCggGBALLOuMsXBwU57q2cauVHr1zUneJ3KKt7<br>
6H8RzZJB/yoltld/9RjGeQGZ3EfeLb1dm9Gag2AwTBRzrnYIcQz215ABLfcdMYyo<br>
B3UE4rU+E3N9XMmGAEWbQh3lAprYeUnKbt7yjKOuUrQvfNtHhvNOpDQjg2VRbYnx<br>
TQS6Go/ycRSywoBKSlr3G/sZ0pKt+8BumfMfIZZtPQw9j46+VibBW9UyQZJ7iBUH<br>
q1AXT8XiFtAzVq33dwb+B5gd1QVrIu1vIzyGQt5dliEHHfJcdksmZBLru1GR6uzF<br>
bndg3Y9MyYj5YQ+6M9wtcLKgJwHHfLgb30FPmY5a945tSHL9cv38sk11o7zgI6Vn<br>
d+KhHxFRs8g0dBq8/ZKXF4UA7RxihXAB/SwVW4XVgpMGCMh/hrDzqKS/oexuOt8n<br>
NDumTd2NYsUx06+uV/lc405DGmnF0cvCsV+3wulBs09lUsQlwFvFhU3z2pDSWWPs<br>
8qCwcPn1WKBx1bZvBMZzys8qPc6NP4sjIQIDAQABo0MwQTAPBgNVHRMBAf8EBTAD<br>
AQH/MA8GA1UdDwEB/wQFAwMHhAAwHQYDVR0OBBYEFFJsVCuIulfHcznrk/ALXKSn<br>
Q+9IMA0GCSqGSIb3DQEBCwUAA4IBgQA6/WBJ5IYfcvxQnMeCQI2ewRiMxEQQxqFX<br>
E9aXJDq5ohhY+lquWcMD8+yNAQbsE2Sw3KQppelEvN1aLgDwW8e7LR5Dw7SLtwZB<br>
tFtWx2eJoqjuTLoxhjnWaR3A50YUgjNOiV5UIV5E8A1f1wsJcdM2VobQgdNyfvnm<br>
vDdHKaGP9+TfmrdGimVwVLmQCtXzp62pyIkJbc8lOOGifCNzDmRgl1ehsEYn4T/M<br>
NWxan3mRGLBjGn90ojxAMBXASB6BrQNa4Kvrs0bzyUToBPHMeBWsYA6SlyfLMN9L<br>
svajh99xEYN63+AVNpZMDIBe4Dhmw8dTU8z1beDJqdODG8+Krmp58KwTAZQYGp6o<br>
iyA5W1PmEms3Our9pBoJZ6guE8qMMxo6th+CwXsOQQLcmUIienLfFv6x1hZidN6G<br>
bTmD2GOK25J/2zXlEXQuT4HNZfDuIh2IBxlo607ct72Dq9OGENLL6ujGhzU2XL6J<br>
/TM/05Gfa+buDfysohjCSbtAIqvolr8=<br>
-----END CERTIFICATE-----<br>
<br>
Sample leaf certificate signed by above certificate authority:<br>
<br>
-----BEGIN CERTIFICATE-----<br>
MIIEfDCCAuSgAwIBAgIUdcWg+bxobl7OWSOjbNxyaXTnqx8wDQYJKoZIhvcNAQEL<br>
BQAwMTEXMBUGA1UEAxMORmFrZWRvbWFpbjIgQ0ExFjAUBgNVBAoTDUZha2UgRG9t<br>
YWluIDIwHhcNMjEwOTE0MTgzOTA0WhcNMjIwOTEzMTgzOTA2WjAsMRIwEAYDVQQD<br>
Ewlsb2NhbGhvc3QxFjAUBgNVBAoTDUZha2UgRG9tYWluIDIwggGiMA0GCSqGSIb3<br>
DQEBAQUAA4IBjwAwggGKAoIBgQDcNlMZrrMMWS5mKBCZKegx78hQutjQN4BEWsnK<br>
WNPEpgtBV6H7Ihk43Jn19EArCujglZfI5sdV9il/8uJFB9DplICnPvet6HvspxLa<br>
4hLFm+dI1Av6MglB6vaJInEXK6zVM39NMJVAy7LcryJYAhVMIuC4wTUOHRqAgx8o<br>
w6dtb7fKSV3OTN3UmGJRPnzGULR3wc8yjGCXnPgu0D497w2FoZ4IWU2H/T+djQDx<br>
i8giZ7KV+11XHfm3ZEsukutJIwsehP3XmCrvttZz8oQuNzJvA05BYRmgOkc7rJeW<br>
ioXL8SC3rMeN4tZHPOd1O6QMVA3IqRGqoobwvt6HKKgE5LWw8GMG5HBDUFuYFDWY<br>
cNkNObTM+x06WVoOKqjDUMb0x+clZwHSclTbEACzxT+iv3hh7+zQ9/0Z7BgYKxfN<br>
QQgtDxIvguFI5O/BKzWAeBY24InHyBphprXmAL+q79hqjpt6Diaz8GEY7qHJcvss<br>
npx7Q9HWqPd+GsPMBjGHRmy6Wk0CAwEAAaOBkDCBjTAUBgNVHREEDTALgglsb2Nh<br>
bGhvc3QwDAYDVR0TAQH/BAIwADAPBgNVHQ8BAf8EBQMDB6AAMBYGA1UdJQEB/wQM<br>
MAoGCCsGAQUFBwMBMB0GA1UdDgQWBBSblx0hTlJdxGO9+sAQnevrQUtX+jAfBgNV<br>
HSMEGDAWgBRSbFQriLpXx3M565PwC1ykp0PvSDANBgkqhkiG9w0BAQsFAAOCAYEA<br>
fHfAPrLNL2oChRjhS5h7twylgoxlAL06CITEwQtRSbdoP/g+XUdv/CFp7fqE9rKz<br>
XNrtgM6KSgK7N7riYojCheEo/76Jk+PHPljzCrv9BoX6K44liU1Nf2IXIAG2+llY<br>
aDmMeZPFI3pZ92oFCmKmzMvCaf/idOqNFihS/hBNXfbczuROnAuw/zip1QItnCJt<br>
YTk1Og7BMjF3LNQYZRwz3KuG/fyDJx7DMrKL+EOsOmebFnIqiM0Em0TGIzdY2aTG<br>
3hDbMUQz82R/8kO5d9keIGiL4pXp1gGDf8TdK7cEDblcwt1cyNX6jm6F1+qGWgCw<br>
EbnNn2MjpdBD0BDNluQaysQb6KDomv2HHhwDtB6RDM26GN3uUyZfPDzvzH8TmNbH<br>
UIymPlYs9XHlvEYJeeu9shd9hLegAidWHBs31eUKZaURJrsHd110iGhVpGEjvdvS<br>
+YxkNsVwgmiPjJpjxsHOABdwpFBO54F8ayEiYDiLhboXEHJj0ju57TMstzcOmQBL<br>
-----END CERTIFICATE-----<br>
<br>
</blockquote></div></div>

        </blockquote></blockquote></div></div></div>
</blockquote></div></div>