Repository navigation
tls: reject chains containing blocked public keys - #66871
Open
UlisesGascon wants to merge 2 commits into
Open
UlisesGascon wants to merge 2 commits into
UlisesGascon wants to merge 2 commits into
Conversation
Collaborator
|
Review requested:
|
UlisesGascon
force-pushed
the
fix/tls-spki-blocklist
branch
from
October 20, 2026 09:30
577a4a9 to
db7cfbb
Compare
UlisesGascon
marked this pull request as ready for review
October 20, 2026 09:31
Node.js embeds the Mozilla root store but has no equivalent of the browsers' CRLSet/OneCRL and no default online revocation checking, so a certificate chain through a compromised intermediate still verifies as long as it reaches a trusted root. Removing the affected roots would over-block, since other legitimate intermediates chain to them. Add a small compiled-in blocklist of SubjectPublicKeyInfo SHA-256 hashes and check every verified chain against it from a single SSL_CTX_set_cert_verify_callback hook. A hit is reported as X509_V_ERR_CERT_REVOKED through the normal verification path, so it honours rejectUnauthorized and surfaces as authorizationError on both client and server sockets. The hook is installed for every SSL_CTX Node.js creates: SecureContext, QUIC and DTLS. The OpenSSL 4.1 CN name constraint handling previously registered from crypto_tls.cc moves into the same hook, since OpenSSL allows only one. The initial entries are the eight eMudhra/emSign intermediates whose private keys were reported compromised in October 2026. The same list is shipped by Go (CVE-2026-111943) and Electron. Sessions resumed from before this change are not re-verified, as is standard for TLS resumption; the exposure ends with the session timeout. Test-only hooks on the crypto binding, reachable with --expose-internals, allow the test to block a fixture key and exercise the full handshake. Refs: electron/electron#55126 Refs: golang/go#82345 Assisted-by: Claude, Codex Signed-off-by: Ulises Gascon <ulisesgascongonzalez@gmail.com>
UlisesGascon
force-pushed
the
fix/tls-spki-blocklist
branch
from
October 20, 2026 09:36
db7cfbb to
71af0a9
Compare
Member
Author
Use only X509_STORE_CTX APIs that BoringSSL also provides. BoringSSL lacks X509_STORE_CTX_set_error_depth, X509_STORE_CTX_set_current_cert and X509_STORE_CTX_get_verify_cb, which broke the aarch64 shared BoringSSL build. Fetch the per-certificate callback from the SSL object instead and skip the two setters on BoringSSL, where Node.js' own callbacks never read them. Assisted-by: Claude Signed-off-by: Ulises Gascon <ulisesgascongonzalez@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Node.js embeds the Mozilla root store but has no equivalent of the
browsers' CRLSet/OneCRL and no default online revocation checking. When
an intermediate CA key is compromised, a chain through it still verifies
as long as it reaches a trusted root. Removing the affected roots would
over-block, since other legitimate intermediates chain to them.
This adds a small compiled-in blocklist of SubjectPublicKeyInfo SHA-256
hashes, checked from a single
SSL_CTX_set_cert_verify_callbackhook onevery SSL_CTX Node.js creates (SecureContext, QUIC, DTLS). A hit is
reported as
X509_V_ERR_CERT_REVOKEDthrough the normal verificationpath, so it honours
rejectUnauthorizedand surfaces asauthorizationErroron client and server sockets. The OpenSSL 4.1 CNname-constraint handling from #65957 moves into the same hook, since
OpenSSL allows only one.
The initial entries are the eight eMudhra/emSign intermediates whose
private keys were reported compromised in October 2026. The hashes are
byte-identical to Go's fix (CVE-2026-111943) and Electron's patch.
Known limitation
Sessions resumed from before the upgrade are not re-verified. This is
standard TLS resumption behaviour and ends with the session timeout.
Points for reviewers
deliberately narrow; whether it should be configurable or updatable
outside a release is open.
internalBinding('crypto')behind--expose-internals. Atest/addonsC++ addon is the alternative.AI disclosure
Assisted by Claude Code and Codex; reviewed, built and tested by me.
Refs: electron/electron#55126
Refs: golang/go#82345