From 4ed6fbc260205ba417cc0c03fd94daeac8ce3e1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sladk=C3=BD?= Date: Thu, 4 Jun 2026 11:00:35 +0200 Subject: [PATCH 1/3] backport d2fb8c273488f0ff57e5f0aacb00d679d7ffa849 --- .../classes/sun/security/x509/DNSName.java | 7 +- .../security/x509/DNSName/LeadingPeriod.java | 69 ++++++++++++++ .../x509/DNSName/certs/generate-certs.sh | 91 +++++++++++++++++++ .../security/x509/DNSName/certs/openssl.cnf | 40 ++++++++ .../DNSName/certs/withLeadingPeriod/ca.pem | 16 ++++ .../DNSName/certs/withLeadingPeriod/leaf.pem | 12 +++ .../DNSName/certs/withoutLeadingPeriod/ca.pem | 16 ++++ .../certs/withoutLeadingPeriod/leaf.pem | 12 +++ 8 files changed, 260 insertions(+), 3 deletions(-) create mode 100644 test/jdk/sun/security/x509/DNSName/LeadingPeriod.java create mode 100644 test/jdk/sun/security/x509/DNSName/certs/generate-certs.sh create mode 100644 test/jdk/sun/security/x509/DNSName/certs/openssl.cnf create mode 100644 test/jdk/sun/security/x509/DNSName/certs/withLeadingPeriod/ca.pem create mode 100644 test/jdk/sun/security/x509/DNSName/certs/withLeadingPeriod/leaf.pem create mode 100644 test/jdk/sun/security/x509/DNSName/certs/withoutLeadingPeriod/ca.pem create mode 100644 test/jdk/sun/security/x509/DNSName/certs/withoutLeadingPeriod/leaf.pem 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 c4400e419bf..41d185c22ee 100644 --- a/src/java.base/share/classes/sun/security/x509/DNSName.java +++ b/src/java.base/share/classes/sun/security/x509/DNSName.java @@ -202,7 +202,7 @@ public int hashCode() { * . These results are used in checking NameConstraints during * certification path verification. *

- * RFC5280: DNS name restrictions are expressed as host.example.com. + * RFC5280: For DNS names, restrictions MUST use the DNSName syntax in Section 4.2.1.6. * Any DNS name that can be constructed by simply adding zero or more * labels to the left-hand side of the name satisfies the name constraint. * For example, www.host.example.com would satisfy the constraint but @@ -238,13 +238,14 @@ else if (inputName.getType() != NAME_DNS) constraintType = NAME_MATCH; else if (thisName.endsWith(inName)) { int inNdx = thisName.lastIndexOf(inName); - if (thisName.charAt(inNdx-1) == '.' ) + if (thisName.charAt(inNdx-1) == '.' ^ inName.charAt(0) == '.') constraintType = NAME_WIDENS; else constraintType = NAME_SAME_TYPE; } else if (inName.endsWith(thisName)) { int ndx = inName.lastIndexOf(thisName); - if (inName.charAt(ndx-1) == '.' ) + if (inName.charAt(ndx-1) == '.' ^ thisName.charAt(0) == '.') + constraintType = NAME_NARROWS; else constraintType = NAME_SAME_TYPE; diff --git a/test/jdk/sun/security/x509/DNSName/LeadingPeriod.java b/test/jdk/sun/security/x509/DNSName/LeadingPeriod.java new file mode 100644 index 00000000000..2fa5eb6b8b5 --- /dev/null +++ b/test/jdk/sun/security/x509/DNSName/LeadingPeriod.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2023, 2025, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8311546 + * @summary Adopt de-facto standards on x509 Name Constraints with leading dot. Certs + * can be generated by running generate-certs.sh + * @run main LeadingPeriod + */ + +import java.io.*; +import java.nio.file.*; +import java.util.*; +import java.security.Security; +import java.security.cert.*; + +public class LeadingPeriod { + + public static void main(String[] args) throws Exception { + String certs = System.getProperty("test.src", "./") + "/certs/"; + validate(certs + "withoutLeadingPeriod"); + validate(certs + "withLeadingPeriod"); + } + + public static void validate(String certPath) throws Exception { + byte[] targetCertBytes = Files.readAllBytes(Paths.get(certPath + "/leaf.pem")); + byte[] caCertBytes = Files.readAllBytes(Paths.get(certPath + "/ca.pem")); + + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + Certificate caCert = cf.generateCertificate(new ByteArrayInputStream(caCertBytes)); + Certificate targetCert = cf.generateCertificate(new ByteArrayInputStream(targetCertBytes)); + + TrustAnchor anchor = new TrustAnchor((X509Certificate) caCert, null); + + PKIXParameters params = new PKIXParameters(Collections.singleton(anchor)); + + // Disable certificate revocation checking + params.setRevocationEnabled(false); + + // Set validity date, so that validation won't fail when cert expires + params.setDate(((X509Certificate)targetCert).getNotBefore()); + + CertPath path = cf.generateCertPath(List.of(targetCert, caCert)); + + CertPathValidator validator = CertPathValidator.getInstance("PKIX"); + validator.validate(path, params); + } +} diff --git a/test/jdk/sun/security/x509/DNSName/certs/generate-certs.sh b/test/jdk/sun/security/x509/DNSName/certs/generate-certs.sh new file mode 100644 index 00000000000..1377a18d80b --- /dev/null +++ b/test/jdk/sun/security/x509/DNSName/certs/generate-certs.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash + +set -e + +############################################################### +# CA with a leading period in the name constraint # +############################################################### +mkdir -p withLeadingPeriod + +openssl req \ + -newkey rsa:1024 \ + -keyout withLeadingPeriod/ca.key \ + -out withLeadingPeriod/ca.csr \ + -subj "/C=US/O=Example/CN=Example CA with period" \ + -nodes + +openssl x509 \ + -req \ + -in withLeadingPeriod/ca.csr \ + -extfile openssl.cnf \ + -extensions withLeadingPeriod \ + -signkey withLeadingPeriod/ca.key \ + -out withLeadingPeriod/ca.pem + +# leaf certificate +openssl req \ + -newkey rsa:1024 \ + -keyout withLeadingPeriod/leaf.key \ + -out withLeadingPeriod/leaf.csr \ + -subj '/CN=demo.example.com' \ + -addext 'subjectAltName = DNS:demo.example.com' \ + -nodes + +openssl x509 \ + -req \ + -in withLeadingPeriod/leaf.csr \ + -CAcreateserial \ + -CA withLeadingPeriod/ca.pem \ + -CAkey withLeadingPeriod/ca.key \ + -out withLeadingPeriod/leaf.pem + + +# ################################################################## +# # CA without a leading period in the name contraint # +# ################################################################## +mkdir -p withoutLeadingPeriod + +openssl req \ + -newkey rsa:1024 \ + -keyout withoutLeadingPeriod/ca.key \ + -out withoutLeadingPeriod/ca.csr \ + -subj "/C=US/O=Example/CN=Example CA without period" \ + -nodes + +openssl x509 \ + -req \ + -in withoutLeadingPeriod/ca.csr \ + -extfile openssl.cnf \ + -extensions withoutLeadingPeriod \ + -signkey withoutLeadingPeriod/ca.key \ + -out withoutLeadingPeriod/ca.pem + +# leaf certificate +openssl req \ + -newkey rsa:1024 \ + -keyout withoutLeadingPeriod/leaf.key \ + -out withoutLeadingPeriod/leaf.csr \ + -subj '/CN=demo.example.com' \ + -addext 'subjectAltName = DNS:demo.example.com' \ + -nodes + +openssl x509 \ + -req \ + -in withoutLeadingPeriod/leaf.csr \ + -CAcreateserial \ + -CA withoutLeadingPeriod/ca.pem \ + -CAkey withoutLeadingPeriod/ca.key \ + -out withoutLeadingPeriod/leaf.pem + + +# # Verify both leaf certificates + +set +e +openssl verify \ + -CAfile withLeadingPeriod/ca.pem \ + withLeadingPeriod/leaf.pem + +openssl verify \ + -CAfile withoutLeadingPeriod/ca.pem \ + withoutLeadingPeriod/leaf.pem + diff --git a/test/jdk/sun/security/x509/DNSName/certs/openssl.cnf b/test/jdk/sun/security/x509/DNSName/certs/openssl.cnf new file mode 100644 index 00000000000..a69d206a5fc --- /dev/null +++ b/test/jdk/sun/security/x509/DNSName/certs/openssl.cnf @@ -0,0 +1,40 @@ +# +# OpenSSL configuration file. +# + +[ withLeadingPeriod ] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical,CA:true +keyUsage = critical,keyCertSign +nameConstraints = critical,permitted;DNS:.example.com + +[ withoutLeadingPeriod ] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical,CA:true +keyUsage = critical,keyCertSign +nameConstraints = critical,permitted;DNS:example.com + +[ v3_ca ] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical,CA:true +keyUsage = critical,keyCertSign + + +[req] +distinguished_name = req_distinguished_name +x509_extensions = v3_ca # The extentions to add to self signed certs +req_extensions = v3_req # The extensions to add to req's + +prompt = no + +[req_distinguished_name] +C = US +O = Example +CN = example.com + +[v3_req] +keyUsage = keyEncipherment, dataEncipherment +extendedKeyUsage = serverAuth diff --git a/test/jdk/sun/security/x509/DNSName/certs/withLeadingPeriod/ca.pem b/test/jdk/sun/security/x509/DNSName/certs/withLeadingPeriod/ca.pem new file mode 100644 index 00000000000..535a8d9fc7e --- /dev/null +++ b/test/jdk/sun/security/x509/DNSName/certs/withLeadingPeriod/ca.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICgzCCAeygAwIBAgIJANBGv+BGZZHtMA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV +BAYTAlVTMRAwDgYDVQQKDAdFeGFtcGxlMR8wHQYDVQQDDBZFeGFtcGxlIENBIHdp +dGggcGVyaW9kMB4XDTIzMTAxOTIwNTE0NVoXDTIzMTExODIwNTE0NVowQDELMAkG +A1UEBhMCVVMxEDAOBgNVBAoMB0V4YW1wbGUxHzAdBgNVBAMMFkV4YW1wbGUgQ0Eg +d2l0aCBwZXJpb2QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPfaISk+Dvzk +m3AY7IDZYrGWpwxHciacalrsrOFl3mj3FQ/kVhofDri3mE7bxNKWyHNcbt+Cteck +TsGKBH85QsIifju7hqlrR+UbYtQF9/REkxX72gzim4xGk9KmKkuGpT5aZgvTE5eg +ZumJ9XxCjGn5nbsdJoqAE/9B96GqXJvlAgMBAAGjgYQwgYEwHQYDVR0OBBYEFG8h +vtka47iFUsc+3wmQ3LQRXUv3MB8GA1UdIwQYMBaAFG8hvtka47iFUsc+3wmQ3LQR +XUv3MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB4GA1UdHgEB/wQU +MBKgEDAOggwuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADgYEAkPeCbKokI067 +Dt2bommouO7LhTXivjMsByfZs8i9LZUVJz5Is+mDC36nLy4U3+QhofRLlEkWyOlE +033xBtm4YPsazpur79PJtvZemV0KwwMtKCoJYNlcy2llmdKjUwe4PsPnJPqH2KL5 +Cxios1gil8XL5OCmEUSCT9uBblh+9gk= +-----END CERTIFICATE----- diff --git a/test/jdk/sun/security/x509/DNSName/certs/withLeadingPeriod/leaf.pem b/test/jdk/sun/security/x509/DNSName/certs/withLeadingPeriod/leaf.pem new file mode 100644 index 00000000000..c587ca20c9a --- /dev/null +++ b/test/jdk/sun/security/x509/DNSName/certs/withLeadingPeriod/leaf.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB0jCCATsCCQCgOCS7vOUOXTANBgkqhkiG9w0BAQsFADBAMQswCQYDVQQGEwJV +UzEQMA4GA1UECgwHRXhhbXBsZTEfMB0GA1UEAwwWRXhhbXBsZSBDQSB3aXRoIHBl +cmlvZDAeFw0yMzEwMTkyMDUxNDVaFw0yMzExMTgyMDUxNDVaMBsxGTAXBgNVBAMM +EGRlbW8uZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALxi +O4r50rNBbHu/blOSRfo9Vqei+QFS7fPwme68FOcvG+uYXf7zluO59V+8O4RPO+ZJ +W6meZvtpOCWFvlSMhBLTRz350LuSPWF+/tnbiyEv487Vi6Tp7kxJytIcMtH/sWkw +hF0Og8YYt3Xm2aLYPxZHGkvOccjau5X1xG1YiULzAgMBAAEwDQYJKoZIhvcNAQEL +BQADgYEA8OXnFO3yZSVmQfYvC2o9amYa7tNUPHgvEjp7xDlPkvL5zF+n8k0hT0kt +pv4BXzRqVIWsZcNi3H1wk6LMeUXi8EWCOR6gclWI0wZkWBhtoh8SCd2VJRmcv+zG +EnInCapszNKN05KEzaFOQv0QayILBUGgHTTXOgbEmryLHXg6zik= +-----END CERTIFICATE----- diff --git a/test/jdk/sun/security/x509/DNSName/certs/withoutLeadingPeriod/ca.pem b/test/jdk/sun/security/x509/DNSName/certs/withoutLeadingPeriod/ca.pem new file mode 100644 index 00000000000..cb886c34a1d --- /dev/null +++ b/test/jdk/sun/security/x509/DNSName/certs/withoutLeadingPeriod/ca.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICiDCCAfGgAwIBAgIJALUX88nU2b75MA0GCSqGSIb3DQEBCwUAMEMxCzAJBgNV +BAYTAlVTMRAwDgYDVQQKDAdFeGFtcGxlMSIwIAYDVQQDDBlFeGFtcGxlIENBIHdp +dGhvdXQgcGVyaW9kMB4XDTIzMTAxOTIwNTE0NVoXDTIzMTExODIwNTE0NVowQzEL +MAkGA1UEBhMCVVMxEDAOBgNVBAoMB0V4YW1wbGUxIjAgBgNVBAMMGUV4YW1wbGUg +Q0Egd2l0aG91dCBwZXJpb2QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANmH +HqVoDjgoS60aPhQisqEL3as81tPXxXgnp5M0TE+Lb0z/kXS2mkqYYhzcZneBhVyI +oGTnSnTSh6S1r/gE80x+hH4ZrLZR7jJMRDA9Q7RTOZBNgozS4XnE3AV/EjrIzHJ1 +IEt1ezoj2QNdVOv7UHprHGoARl9tdxre4MVUv4S3AgMBAAGjgYMwgYAwHQYDVR0O +BBYEFFG0Mvse4c5C01o8kvKiM4MKMJTCMB8GA1UdIwQYMBaAFFG0Mvse4c5C01o8 +kvKiM4MKMJTCMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1Ud +HgEB/wQTMBGgDzANggtleGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOBgQC0CKS0 +JOR8hfUkZHBo52PrF3IKs33wczH5mfV+HLTdSeKtBD0Vj/7DoT0Yx2k5n6vpwA/x +LTSMC4wUo4hb5164ks45iloU0FrA+n9fWbeqwhQb+DW5MSOgoVLkW+rcdKbDatTO +ENcKZsqiG3aKM7pS7mQa+kUUpXWBUgVnhcsYtQ== +-----END CERTIFICATE----- diff --git a/test/jdk/sun/security/x509/DNSName/certs/withoutLeadingPeriod/leaf.pem b/test/jdk/sun/security/x509/DNSName/certs/withoutLeadingPeriod/leaf.pem new file mode 100644 index 00000000000..449176ff8a8 --- /dev/null +++ b/test/jdk/sun/security/x509/DNSName/certs/withoutLeadingPeriod/leaf.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB1TCCAT4CCQDLscehyPPGXjANBgkqhkiG9w0BAQsFADBDMQswCQYDVQQGEwJV +UzEQMA4GA1UECgwHRXhhbXBsZTEiMCAGA1UEAwwZRXhhbXBsZSBDQSB3aXRob3V0 +IHBlcmlvZDAeFw0yMzEwMTkyMDUxNDVaFw0yMzExMTgyMDUxNDVaMBsxGTAXBgNV +BAMMEGRlbW8uZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB +AMZM9Prp5DkAe4pkLqn4v8DFamMtWVqPlYacJacGzBkuzBn8VNQQw4qnf6wiVHBj +uXLHrUCbldtKFK4XdVukmVyYSLR5BBPxA20fjZcsrBZW7u/14qWmIZW7G0xphezg +6g33qNPq9CPqVHR+IrfEmjWnLjc2KrZ3OQElpJOGp48hAgMBAAEwDQYJKoZIhvcN +AQELBQADgYEAYbIuAQKTXsgaBP3pyMqxPHvklDI7wJjEapbKDsOXYmKMb33pmFSD +ntQFZuOKYNV2rAqQaV/3kiWKyR4vO/gsCfuFeW8kxkhZEXX9CNU0Z6mKcvy274A4 +K0gqYGki8hyCc5IMWTUAX2TLdq8W1hwfbjeiNqTY21e+6lIa3kcuLC0= +-----END CERTIFICATE----- From 22bd3f3fc703f7e39400a489d511164ca82006fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sladk=C3=BD?= Date: Fri, 5 Jun 2026 15:16:58 +0200 Subject: [PATCH 2/3] Remove extra new line --- src/java.base/share/classes/sun/security/x509/DNSName.java | 1 - 1 file changed, 1 deletion(-) 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 41d185c22ee..d650a419ff7 100644 --- a/src/java.base/share/classes/sun/security/x509/DNSName.java +++ b/src/java.base/share/classes/sun/security/x509/DNSName.java @@ -245,7 +245,6 @@ else if (thisName.endsWith(inName)) { } else if (inName.endsWith(thisName)) { int ndx = inName.lastIndexOf(thisName); if (inName.charAt(ndx-1) == '.' ^ thisName.charAt(0) == '.') - constraintType = NAME_NARROWS; else constraintType = NAME_SAME_TYPE; From dde9a9bf94fb921758f09ebe17e66038226c624d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Sladk=C3=BD?= Date: Mon, 8 Jun 2026 12:58:10 +0200 Subject: [PATCH 3/3] Add missing spaces --- test/jdk/sun/security/x509/DNSName/certs/generate-certs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/sun/security/x509/DNSName/certs/generate-certs.sh b/test/jdk/sun/security/x509/DNSName/certs/generate-certs.sh index 1377a18d80b..dbd2fd60e83 100644 --- a/test/jdk/sun/security/x509/DNSName/certs/generate-certs.sh +++ b/test/jdk/sun/security/x509/DNSName/certs/generate-certs.sh @@ -88,4 +88,4 @@ openssl verify \ openssl verify \ -CAfile withoutLeadingPeriod/ca.pem \ withoutLeadingPeriod/leaf.pem - +