From c6aaf91d2bd6f231466d19fdde8a61eb90aeb61c Mon Sep 17 00:00:00 2001 From: Artur Barashev Date: Thu, 21 May 2026 21:05:25 +0000 Subject: [PATCH] 8385076: Follow-on fix for Improve certification checking Reviewed-by: ahgross, rhalade, jnibedita, pkumaraswamy, weijun, mullan --- .../share/classes/sun/security/x509/DNSName.java | 12 ++++++++++-- .../sun/security/x509/NameConstraintsExtension.java | 10 ++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/sun/security/x509/DNSName.java b/src/java.base/share/classes/sun/security/x509/DNSName.java index 17820d279a5..02948c0c04f 100644 --- a/src/java.base/share/classes/sun/security/x509/DNSName.java +++ b/src/java.base/share/classes/sun/security/x509/DNSName.java @@ -229,11 +229,13 @@ public class DNSName implements GeneralNameInterface { * order zero bit. * * @param inputName to be checked for being constrained + * @param matchWildcard whether to match a wildcard in inputName * @return constraint type above * @throws UnsupportedOperationException if name is not exact match, but narrowing and widening are * not supported for this name type. */ - public int constrains(GeneralNameInterface inputName) throws UnsupportedOperationException { + public int constrains(GeneralNameInterface inputName, boolean matchWildcard) + throws UnsupportedOperationException { int constraintType; if (inputName == null) constraintType = NAME_DIFF_TYPE; @@ -244,7 +246,9 @@ public class DNSName implements GeneralNameInterface { (((DNSName)inputName).getName()).toLowerCase(Locale.ENGLISH); String thisName = name.toLowerCase(Locale.ENGLISH); - if (HOSTNAME_CHECKER.isMatched(thisName, inName, false)) + if (inName.equals(thisName) || (matchWildcard + && inName.contains("*") + && HOSTNAME_CHECKER.isMatched(thisName, inName, false))) constraintType = NAME_MATCH; else if (thisName.endsWith(inName)) { int inNdx = thisName.lastIndexOf(inName); @@ -265,6 +269,10 @@ public class DNSName implements GeneralNameInterface { return constraintType; } + public int constrains(GeneralNameInterface inputName) { + return constrains(inputName, false); + } + /** * Return subtree depth of this name for purposes of determining * NameConstraints minimum and maximum bounds and for calculating diff --git a/src/java.base/share/classes/sun/security/x509/NameConstraintsExtension.java b/src/java.base/share/classes/sun/security/x509/NameConstraintsExtension.java index ce6d4721ad7..5b34a726796 100644 --- a/src/java.base/share/classes/sun/security/x509/NameConstraintsExtension.java +++ b/src/java.base/share/classes/sun/security/x509/NameConstraintsExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -506,9 +506,15 @@ public class NameConstraintsExtension extends Extension if (exName == null) continue; + // Match a wildcard in DNSName only against the excluded subtree + int matchResult = + exName.getType() == GeneralNameInterface.NAME_DNS + ? ((DNSName) exName).constrains(name, true) + : exName.constrains(name); + // if name matches or narrows any excluded subtree, // return false - switch (exName.constrains(name)) { + switch (matchResult) { case GeneralNameInterface.NAME_DIFF_TYPE: case GeneralNameInterface.NAME_WIDENS: // name widens excluded case GeneralNameInterface.NAME_SAME_TYPE: