Hello Chris,
Were you able to replicate the error on your side? Best, Alex Sent using Zoho Mail ---- On Thu, 22 May 2025 08:02:41 -0500 Christopher Schultz <ch...@christopherschultz.net> wrote --- Alex, On 5/21/25 9:01 PM, My Subs wrote: > Chris, > > > >> Is the client sending just their own cert, or also the chain? > It would > be unusual for the client to send a chain, but instead > just sends their > own leaf certificate. I'm assuming that both > the root and the > intermediate / subordinate cert are both in > the trust store. Is that > correct? > > > The client is > sending both the leaf and the intermediate certificates (both are in > the PKCS12 file imported into Firefox). That's the only way for the > chain of trust to work, because only the root certificate is in the > trust store (well, that's how it's supposed to be, as far as I > understand). And it works fine until the CRL comes into play. > > > > I also tested adding > the subordinate CA's certificate to the trust store. No change. > With no CRL configured, works alright; but when it is configured, I > get the same errors. Revoked client cert is rejected as such, and > valid client cert is rejected with SSL_ERROR_UNKNOWN_CA_ALERT. > > > > >> Can > you please try one more thing for me? > > > Can > you create a self-signed certificate, and use ONLY that self-signed > certificate in your trust store, and have the client send that > to the > server? > > > It will be easier > for me if I just have to deal with a single cert on > either side > of the connection rather than set up a whole signing > authority, > etc. before I'm able to reproduce it. > > > > Done. Removed root CA certificate from trust store, and left only a > self-signed certificate. The result is exactly the same. With no > CRL checking, it works fine. Add CRL checking, and I get: "Peer > does not recognize and trust the CA that issued your certificate. > Error code: SSL_ERROR_UNKNOWN_CA_ALERT" Perfect. That will make it a lot easier for me to duplicate your setup. > Guess the finger > increasingly points to the CRL checking code. Agreed, at least in theory. -chris > ---- On Wed, 21 May 2025 16:29:10 -0500 Christopher Schultz > <mailto:ch...@christopherschultz.net> wrote --- > > > > Alex, > > On 5/21/25 1:26 PM, My Subs wrote: >> To test this, I set >> certificateRevocationListPath to the directory having the CRL file; >> changed to certificateVerification="optional"; and >> downgraded to HTTP 1.1 (as mentioned, "optional" does not >> work with HTTP 2). The result is that requests without a client >> certificate get a 200 OK response. > > Good. > >> However, *all* requests having a client certificate (valid or >> revoked) are rejected. > > Okay. > >> If the client certificate is revoked, it is correctly identified as >> such. Firefox displays message "SSL peer rejected your >> certificate as revoked. Error code: SSL_ERROR_REVOKED_CERT_ALERT". > > Good! > >> If the client certificate is not revoked, the connection fails with >> Firefox displaying an unexpected message: "Peer does not >> recognize and trust the CA that issued your certificate. Error code: >> SSL_ERROR_UNKNOWN_CA_ALERT". > > Obviously, not good. > > But I wonder if this is a problem with adding the CRL (which looks like > it's working) versus the trust store. But... > >> But that same issuing CA is perfectly recognized when the >> certificateRevocationListPath attribute is removed from the >> connector. > Yeah, I was afraid you'd say that. > >> Requests with a non-revoked client certificate get a 200 OK >> response, and that certificate is made visible to servlets as a >> java.security.cert.X509Certificate object. This holds both for >> "optional" and> "required" verification. > > > It's CRL checking what triggers the error. >> >> I'm >> not sure whether the message "No client certificate >> CA names sent" means a problem with the trust store. As you can >> see from my connector, caCertificatePath is set to the trust store >> directory. It >> contains the certificate of the root CA, which signed the certificate >> of the subordinate CA. The client certificates used in the above >> test are signed by that subordinate CA. And as >> shown, those are correctly verified when no CRL is configured. > > Is the client sending just their own cert, or also the chain? It would > be unusual for the client to send a chain, but instead just sends their > own leaf certificate. I'm assuming that both the root and the > intermediate / subordinate cert are both in the trust store. Is that > correct? > >> > If you do not configure the CRL, are any CA certs listed in >> this output? >> >> No. Message "No client certificate CA names sent" is still there. >> The full output is: > > > [snip] > > >> --- >> >> No client certificate CA names sent > > Okay. > > Sounds like it's time for me to try to reproduce this. > > Can you please try one more thing for me? > > Can you create a self-signed certificate, and use ONLY that self-signed > certificate in your trust store, and have the client send that to the > server? > > It will be easier for me if I just have to deal with a single cert on > either side of the connection rather than set up a whole signing > authority, etc. before I'm able to reproduce it. > > -chris > >> ---- On Wed, 21 May 2025 07:19:06 -0500 Christopher Schultz >> <mailto:mailto:ch...@christopherschultz.net> wrote --- >> >> >> >> Alex, >> >> On 5/19/25 5:37 PM, My Subs wrote: >> > I'm using Ubuntu 20.04 with OpenSSL 1.1.1f. >> >> Okay. >> >>>> In your earlier message, you had a different configuration. This time you >>>> haven't specified the class name in the "protocol" attribute. Which one >>>> are you actually using? >>> >>> >>> >>> I did change the connector configuration because when updating to Tomcat >>> 10.1.40, I could no longer use class Http11AprProtocol on the protocol >>> attribute (I learned then that the APR connector had been deprecated). So, >>> I set it to "HTTP/1.1" to get automatic selection of the JSSE OpenSSL >>> implementation. >>> >>> >>> >>> I also set certificateVerification="required" because I found in the logs >>> an error message saying that "optional" does not work with HTTP/2. >>> >>> >>> >>> Besides, I'm now testing on Tomcat 11.0.6. >> >> Okay. >> >>>> So the above configuration works for all requests that do not try to send >>>> a client certificate during the handshake? It's only when you try to send >>>> a client certificate that things stop working? >>> >>> >>> >>> Actually, the configuration works seamlessly with client certificate >>> verification for as long as no CRL verification is set up. Client >>> certificates are accepted and made visible to servlets. >>> >>> >>> >>> However, as soon as I set on the <SSLHostConfig>, attribute >>> certificateRevocationListFile to the CRL file, or >>> certificateRevocationListPath to the directory containing the CRL file >>> (properly c_rehashed), all client certificates are rejected. >> >> When you have configured a CRL, are *all* requests rejected, or only >> those which include a client certificate during the handshake? I see you >> have configured certificateVerification="required" so maybe there are no >> modes of operation where client certificates are used. >> >> I'm trying to understand whether this is a problem with the whole setup >> when CRLs are added, or only a problem when a client certificate is >> actively being checked against the CRL. >> >>>> When they stop working, does that mean that no more requests are accepted >>>> and processed, or is it that handshakes fail with client certs but >>>> handshakes without client certs work okay? >>> >>> >>> >>> Since certificateVerification is now set to "required", it means that >>> handshakes fail with client certs, and therefore, there is no access at >>> all. >> >> Does the connection actually hang, or do you simply get a failed (but >> complete) handshake? >> >>>> If you connect to your server like this, what does the output look like: >>> >>> $ openssl s_client -showcerts -connect https://host/whatever >>> >>> >>> >>> I get the following: >>> >>> >>> >>> CONNECTED(00000003) >>> >>> Can't use SSL_get_servername >>> >>> depth=0 CN = localhost >>> >>> verify error:num=18:self signed certificate >>> >>> verify return:1 >>> >>> depth=0 CN = localhost >>> >>> verify return:1 >>> >>> --- >>> >>> Certificate chain >>> >>> 0 s:CN = localhost >>> >>> i:CN = localhost >>> >>> -----BEGIN CERTIFICATE----- >>> >>> MIIBfzCCASWgAwIBAgIUBtGtuw6cAZvC560e0RVjnI/+tnwwCgYIKoZIzj0EAwIw >>> >>> FDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTI1MDQxNjIyNTg0OFoYDzIxMjUwMzIz >>> >>> MjI1ODQ4WjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwWTATBgcqhkjOPQIBBggqhkjO >>> >>> PQMBBwNCAASWvdHleExdyTqn+wXgNY3XueCLjkkpbrtVhw8lB4DsmkTJDUCdszZX >>> >>> 9ElKT01bP10cX+mrinNNEtgKFPBwcTCXo1MwUTAdBgNVHQ4EFgQUJIQfq2nU9T2J >>> >>> uexYvw1bqosji6cwHwYDVR0jBBgwFoAUJIQfq2nU9T2JuexYvw1bqosji6cwDwYD >>> >>> VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiAUmPONFAU4ThvidgLnlXiu >>> >>> 7XElAkAGfmlXKkN0DgJWwAIhAPkF8ngCXY4G7Y2obrGUS2u80p06O2ZYFtXyrM3+ >>> >>> UuRN >>> >>> -----END CERTIFICATE----- >>> >>> --- >>> >>> Server certificate >>> >>> subject=CN = localhost >>> >>> >>> >>> issuer=CN = localhost >>> >>> >>> >>> --- >>> >>> No client certificate CA names sent >> >> This looks like a problem. Do you have the trusted certificates >> configured correctly? I would have expected Tomcat to send a list of >> acceptable certificates back to the client. That's not strictly required >> by the TLS spec, but it's handy for debugging like this. >> >> If you do not configure the CRL, are any CA certs listed in this output? >> >> I haven't used TLS with Tomcat much, so I'm not entirely sure what to >> expect. >> >>> Just to be clear, this is my current <Connector>: >>> >>> >>> >>> <Connector >>> >>> protocol="HTTP/1.1" >>> >>> port="8443" >>> >>> SSLEnabled="true" >>> >>> maxParameterCount="1000" >>> >>> > >>> >>> <SSLHostConfig >>> >>> protocols="TLSv1.3" >>> >>> certificateVerification="required" >>> >>> caCertificatePath="tls/client/certs-ca" >>> >>> certificateRevocationListPath="tls/client/crls" >>> >>> > >>> >>> <Certificate >>> >>> certificateKeyFile="tls/server/localhost-key.pem" >>> >>> certificateFile="tls/server/localhost-cert.pem" >>> >>> /> >>> >>> </SSLHostConfig> >>> >>> <UpgradeProtocol >>> >>> className="org.apache.coyote.http2.Http2Protocol" >>> >>> /> >>> >>> </Connector> >> >> >> Thanks for posting the whole thing. >> >> -chris >> >>> ---- On Fri, 09 May 2025 13:46:35 -0500 Christopher Schultz >>> <mailto:mailto:mailto:ch...@christopherschultz.net> wrote --- >>> >>> >>> >>> Alex, >>> >>> On 5/9/25 2:11 PM, My Subs wrote: >>>> I have tested on Tomcat 10.1.40 with Native >>>> Library 1.3.1 running on JDK 21.0.7+6. The result is exactly the >>>> same as described before. The connector below works well with client >>>> authentication, until I add the caCertificatePath attribute. There >>>> are no error messages in the logs. >>> >>> Thanks for confirming that. >>> >>> It probably does not matter, but what OS are you using, and what version >>> of OpenSSL are you using? >>> >>>> <Connector >>>> protocol="HTTP/1.1" >>>> port="8443" >>>> SSLEnabled="true" >>>> maxParameterCount="1000" >>>> > >>> >>> In your earlier message, you had a different configuration. This time >>> you haven't specified the class name in the "protocol" attribute. Which >>> one are you actually using? >>> >>>> <SSLHostConfig >>>> protocols="TLSv1.3" >>>> certificateVerification="required" >>>> caCertificatePath="tls/client/certs-ca" >>>> > >>>> <Certificate >>>> certificateKeyFile="tls/server/localhost-key.pem" >>>> certificateFile="tls/server/localhost-cert.pem" >>>> /> >>>> </SSLHostConfig> >>>> <UpgradeProtocol >>>> className="org.apache.coyote.http2.Http2Protocol" >>>> /> >>>> </Connector> >>>> >>>> >>>> This time around, Firefox only shows "0 B" on the >>>> "Transferred" column of the "Network" tab in >>>> developer tools. >>>> >>>> Any ideas on what could be wrong? >>> >>> So the above configuration works for all requests that do not try to >>> send a client certificate during the handshake? >>> >>> It's only when you try to send a client certificate that things stop >>> working? >>> >>> When they stop working, does that mean that no more requests are >>> accepted and processed, or is it that handshakes fail with client certs >>> but handshakes without client certs work okay? >>> >>> If you connect to your server like this, what does the output look like: >>> >>> $ openssl s_client -showcerts -connect https://host/whatever >>> >>> This would usually give you a list of allowable client certificates like >>> this: >>> " >>> Acceptable client certificate CA names >>> (cert 1) >>> (cert 2) >>> ... >>> (cert N) >>> " >>> >>> I'm interested in what that returns, if anything. >>> >>> -chris >>> >>>> ---- On Wed, 07 May 2025 12:37:16 -0500 Chuck Caldarale >>>> <mailto:mailto:mailto:mailto:n82...@gmail.com> wrote --- >>>> >>>> >>>> >>>> >>>>> On 2025 May 7, at 11:43, My Subs >>>>> <mailto:mailto:mailto:mailto:mailto:my.s...@zoho.com.invalid> wrote: >>>>> >>>>> I'm setting up certificate client authentication on Tomcat 10.0.0 >>>>> running on Java 16+36. >>>> >>>> >>>> Before doing anything else, you need to upgrade. That version of Tomcat is >>>> over 4 years old, and no 10.0.x version is currently supported. Move up to >>>> the 10.1.x level (current version is 10.1.40) and see if your issue has >>>> already been addressed. >>>> >>>> - Chuck >>>> >>>> >>>>> I'm having trouble getting it to work with a >>>>> CRL. My SSL connector is: >>>>> >>>>> <Connector >>>>> protocol="org.apache.coyote.http11.Http11AprProtocol" >>>>> port="8443" >>>>> SSLEnabled="true" >>>>> maxParameterCount="1000" >>>>> > >>>>> <SSLHostConfig >>>>> protocols="TLSv1.3" >>>>> certificateVerification="optional" >>>>> caCertificatePath="conf/ca-certs" >>>>> certificateRevocationListPath="conf/ca-crls" >>>>> > >>>>> <Certificate >>>>> certificateKeyFile="conf/localhost-ec-key.pem" >>>>> certificateFile="conf/localhost-ec-cert.pem" >>>>> /> >>>>> </SSLHostConfig> >>>>> <UpgradeProtocol >>>>> className="org.apache.coyote.http2.Http2Protocol" >>>>> /> >>>>> </Connector> >>>>> >>>>> In my PKI setup (using OpenSSL), I have a root CA >>>>> (cert: root-ca.pem), and a subordinate CA (cert: sub-ca-01.pem), >>>>> which signs leaf certificates, and issues a CRL (crl: >>>>> sub-ca-01-crl.pem). >>>>> >>>>> File root-ca.pem is in conf/ca-certs. File >>>>> sub-ca-01-crl.pem is in conf/ca-crls, as follows: >>>>> >>>>> 0551d8aa.r0 -> sub-ca-01-crl.pem >>>>> c79c8ddb.r0 -> sub-ca-01-crl.pem >>>>> sub-ca-01-crl.pem -> /home/me/somedir/sub-ca-01-crl.pem >>>>> >>>>> Before adding to <SSLHostConfig>, attribute >>>>> «certificateRevocationListPath="conf/ca-crls"», client >>>>> authentication works fine. The servlet can see a valid client >>>>> certificate and extract its attributes from the X509Certificate >>>>> object returned by >>>>> request.getAttribute("jakarta.servlet.request.X509Certificate"). >>>>> >>>>> However, once I add attribute >>>>> certificateRevocationListPath, the connector stops responding to >>>>> requests that present a client certificate regardless of whether the >>>>> certificate is valid or revoked —it still responds though if the >>>>> request does not present a client certificate. >>>>> >>>>> Firefox only shows error NS_ERROR_FAILURE on the >>>>> "Transferred" column of the "Network" tab in >>>>> developer tools. >>>>> >>>>> The CRL is not expired (and it won't be for long), >>>>> as its printout shows: >>>>> >>>>> Certificate Revocation List (CRL): >>>>> Version 2 (0x1) >>>>> Signature Algorithm: ecdsa-with-SHA256 >>>>> Issuer: CN = Sub CA 01 >>>>> Last Update: May 6 21:53:22 2025 GMT >>>>> Next Update: Apr 12 21:53:22 2125 GMT >>>>> CRL extensions: >>>>> X509v3 CRL Number: >>>>> 4097 >>>>> Revoked Certificates: >>>>> Serial Number: 82AB03509A91A8DCCBA0CE62A67417B6 >>>>> Revocation Date: May 6 21:51:40 2025 GMT >>>>> CRL entry extensions: >>>>> X509v3 CRL Reason Code: >>>>> Unspecified >>>>> Signature Algorithm: ecdsa-with-SHA256 >>>>> 30:45:02:21:00:f7:98:07:1f:2f:cf:d5:ad:b7:5e:20:61:de: >>>>> 1b:7b:1f:c7:74:f9:80:33:d8:a2:cc:3a:75:28:4c:64:65:93: >>>>> c1:02:20:5b:3e:e9:dd:52:9e:11:9b:45:5a:53:fc:2f:bb:b3: >>>>> f4:db:52:64:f6:ea:13:54:43:d6:54:2b:f3:28:03:ae:6f >>>>> >>>>> The problem persists if I drop attribute >>>>> certificateRevocationListPath, and replace it with >>>>> «certificateRevocationListFile="conf/ca-crls/sub-ca-01-crl.pem"». >>>>> It persists as well if I add to conf/ca-crls a CRL for the root CA. >>>>> >>>>> I found nothing helpful in the logs. The source >>>>> of the problem escapes me. How can I get certificate client >>>>> authentication to work with CRLs in Tomcat? >>>>> >>>>> Help is appreciated. Thank you. >>>> >>>> >>>> --------------------------------------------------------------------- >>>> To unsubscribe, e-mail: >>>> mailto:mailto:mailto:mailto:mailto:users-unsubscr...@tomcat.apache.org >>>> For additional commands, e-mail: >>>> mailto:mailto:mailto:mailto:mailto:users-h...@tomcat.apache.org >>> >>> >>> --------------------------------------------------------------------- >>> To unsubscribe, e-mail: >>> mailto:mailto:mailto:mailto:users-unsubscr...@tomcat.apache.org >>> For additional commands, e-mail: >>> mailto:mailto:mailto:mailto:users-h...@tomcat.apache.org >> >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: >> mailto:mailto:mailto:users-unsubscr...@tomcat.apache.org >> For additional commands, e-mail: >> mailto:mailto:mailto:users-h...@tomcat.apache.org > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: mailto:mailto:users-unsubscr...@tomcat.apache.org > For additional commands, e-mail: mailto:mailto:users-h...@tomcat.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: mailto:users-unsubscr...@tomcat.apache.org For additional commands, e-mail: mailto:users-h...@tomcat.apache.org