Skip to content

tls: match IPv6 hosts against IP-Address SANs#64145

Open
JumpLink wants to merge 1 commit into
nodejs:mainfrom
JumpLink:tls-ipv6-ip-san
Open

tls: match IPv6 hosts against IP-Address SANs#64145
JumpLink wants to merge 1 commit into
nodejs:mainfrom
JumpLink:tls-ipv6-ip-san

Conversation

@JumpLink

Copy link
Copy Markdown

tls.checkServerIdentity() stopped matching an IPv6 host against a matching IP Address SAN, returning ERR_TLS_CERT_ALTNAME_INVALID (Cert does not contain a DNS name) where it used to return undefined.

The hostname is now run through domainToASCII() before the net.isIP() gate, and domainToASCII('::1') === '' (an IPv6 literal is not a domain), so net.isIP('') is 0, the IP-SAN branch is skipped, and (with no DNS SAN / CN) it falls through to the no-identifier reason. IPv4 is unaffected because dotted-decimal survives domainToASCII().

const tls = require('node:tls');
tls.checkServerIdentity('::1', { subject: {}, subjectaltname: 'IP Address:::1' });
// v24.16.0: undefined (matched)   v24.17.0+/v26.x: ERR_TLS_CERT_ALTNAME_INVALID

This matches IP hosts against the original hostname instead of the IDNA-normalized one. net.isIP() rejects non-ASCII input, so there is no IDNA confusion to guard against for an IP literal; the normalized form is still used for the DNS-name path. Adds IPv6 IP-SAN coverage (match, canonical-form match, non-match) to test-tls-check-server-identity.

Fixes: #64144

checkServerIdentity() stopped matching an IPv6 host against a matching
IP-Address SAN. The hostname is now run through domainToASCII() before
the net.isIP() gate, and domainToASCII('::1') === '' (an IPv6 literal is
not a domain), so net.isIP('') is 0, the IP-SAN branch is skipped, and
verification fails with "Cert does not contain a DNS name". IPv4 is
unaffected because dotted-decimal survives domainToASCII().

Match IP hosts against the original hostname instead of the IDNA-
normalized one. net.isIP() rejects non-ASCII input, so there is no IDNA
confusion to guard against for an IP literal; the normalized form is
still used for the DNS-name path.

Fixes: nodejs#64144
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/crypto
  • @nodejs/net

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. tls Issues and PRs related to the tls subsystem. labels Jun 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ci PRs that need a full CI run. tls Issues and PRs related to the tls subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tls: checkServerIdentity() no longer matches IPv6 IP-Address SANs (regressed in v24.17.0)

2 participants