-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Verification of client cert checks issuer chain past trusted CA #29630
Comments
I think I understand your question but I believe the answer in all cases is "sorry, you can't do that." Certificates are checked starting from the root down to the leaf cert. In principle node can track through its There is a way to restrict the list of CAs that are sent in the handshake ( I'm not 100% sure about it being TLSv1.3-only but I can't seem to make it work with TLSv1.2 and there's at least one place in openssl's code base where the CA list is deliberately restricted to a TLSv1.3 handshake. You can disable validation if you really want to (and are really careful) and do it yourself. |
As a workaround, I'm implementing precisely what you suggested: setting rejectUnauthorized: false, and validating in the app with fidm/x509 But what you point out means that (maybe) I was wrong in that the issue is not with OpenSSL. Rather, the limitation is that from node there's no way to call SSL_set_client_CA_list, other than by calling SSLWrap::SetCACerts() which both calls both SSL_set1_verify_cert_store and SSL_set_client_CA_list on the same input. The docs for SSL_set_client_CA_list() in OpenSSL 1.1.1 discuss both TLS 1.2 and 1.3 and the differences, and my read is that it is not TLSv1.3-only for server-to-client. Apparently, in TLSv1.3 the client can also specify a list of acceptable CAs, to the server, but that seems to be mostly pointless. Could another option be added to renegotiate() for the client_CA_list? |
Sure, pull requests are welcome. |
Will it be better to use maximum depth option for verifying certificate, so that by using appropriate hierarchy, a particular set of certificates at lower depth will become valid for verify purpose, even if full chain is supplied. Open SSL allows SSL_CTX_set_verify_depth method to set the maximum depth. #39208 Verification happens till it has reached a self-signed cert or num > max_depth or can't find an issuer in the untrusted list. |
There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment. For more information on how the project manages feature requests, please consult the feature request management document. |
There has been no activity on this feature request and it is being closed. If you feel closing this issue is not the right thing to do, please leave a comment. For more information on how the project manages feature requests, please consult the feature request management document. |
When calling
socket.renegotiate({requestCert: true, rejectUnauthorized: true}, cbFunc)
, the client certificate is verified against the trusted certs passed to theca
option ofhttps.createServer()
. This process fails if the entire chain cannot be verified to a self-signed certificate (i.e. a root cert), withsocket.authorizationError
set toUNABLE_TO_GET_ISSUER_CERT
. I suspect this is a problem even without trying to use renegotiation.Here's why this is a problem: my employer has about 3 million users with smartcards, each of which has 3-4 user certificates - one for email encryption, one for identity proofing, one for digital signatures, etc. These certificates are issued by different intermediate CAs, but the intermediate CA certificates are issued by a single root CA.
When the https.server requests a client cert, it passes the DN of all trusted CAs to the client. If the root CA is included, then the browser will prompt the user to select which certificate to send, which will be all available certs on the smartcard (ID, email, and signature), and the user will often pick the "wrong" cert.
Alternatively, if only the desired intermediate CAs are trusted (the ID CA, say), then the user will only be presented the single user-certificate that was issued by that CA, but verification will fail, presumably because the trusted intermediate CA cert cannot be verified up to a self-signed root.
I think this is actually a limitation in
SSL_get_verify_result()
- that it only accepts self-signed certs as trust anchors - which doesn't align with RFC 5280, which says "The selection of a trust anchor is a matter of policy: it could be the top CA in a hierarchical PKI, the CA that issued the verifier's own certificate(s), or any other CA in a network PKI."Alternatively, is there a way to limit the list of allowable CAs presented in the requestClientCert message to a subset of the trusted CAs?
The text was updated successfully, but these errors were encountered: