Skip to content

Commit 99a9299

Browse files
committed
8311546: Certificate name constraints improperly validated with leading period
8320372: test/jdk/sun/security/x509/DNSName/LeadingPeriod.java validity check failed 8347424: Fix and rewrite sun/security/x509/DNSName/LeadingPeriod.java test Reviewed-by: simonis Backport-of: bfaf5704e7e71f968b716b5f448860e9cda721b4
1 parent 5b377a3 commit 99a9299

File tree

8 files changed

+259
-9
lines changed

8 files changed

+259
-9
lines changed

src/java.base/share/classes/sun/security/x509/DNSName.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -200,18 +200,12 @@ public int hashCode() {
200200
* </ul>. These results are used in checking NameConstraints during
201201
* certification path verification.
202202
* <p>
203-
* RFC5280: DNS name restrictions are expressed as host.example.com.
203+
* RFC5280: For DNS names, restrictions MUST use the DNSName syntax in Section 4.2.1.6.
204204
* Any DNS name that can be constructed by simply adding zero or more
205205
* labels to the left-hand side of the name satisfies the name constraint.
206206
* For example, www.host.example.com would satisfy the constraint but
207207
* host1.example.com would not.
208208
* <p>
209-
* RFC 5280: DNSName restrictions are expressed as foo.bar.com.
210-
* Any DNSName that
211-
* can be constructed by simply adding to the left-hand side of the name
212-
* satisfies the name constraint. For example, www.foo.bar.com would
213-
* satisfy the constraint but foo1.bar.com would not.
214-
* <p>
215209
* RFC1034: By convention, domain names can be stored with arbitrary case, but
216210
* domain name comparisons for all present domain functions are done in a
217211
* case-insensitive manner, assuming an ASCII character set, and a high
@@ -236,13 +230,13 @@ else if (inputName.getType() != NAME_DNS)
236230
constraintType = NAME_MATCH;
237231
else if (thisName.endsWith(inName)) {
238232
int inNdx = thisName.lastIndexOf(inName);
239-
if (thisName.charAt(inNdx-1) == '.' )
233+
if (thisName.charAt(inNdx-1) == '.' ^ inName.charAt(0) == '.')
240234
constraintType = NAME_WIDENS;
241235
else
242236
constraintType = NAME_SAME_TYPE;
243237
} else if (inName.endsWith(thisName)) {
244238
int ndx = inName.lastIndexOf(thisName);
245-
if (inName.charAt(ndx-1) == '.' )
239+
if (inName.charAt(ndx-1) == '.' ^ thisName.charAt(0) == '.')
246240
constraintType = NAME_NARROWS;
247241
else
248242
constraintType = NAME_SAME_TYPE;
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8311546
27+
* @summary Adopt de-facto standards on x509 Name Constraints with leading dot. Certs
28+
* can be generated by running generate-certs.sh
29+
* @run main LeadingPeriod
30+
*/
31+
32+
import java.io.*;
33+
import java.nio.file.*;
34+
import java.util.*;
35+
import java.security.Security;
36+
import java.security.cert.*;
37+
38+
public class LeadingPeriod {
39+
40+
public static void main(String[] args) throws Exception {
41+
String certs = System.getProperty("test.src", "./") + "/certs/";
42+
validate(certs + "withoutLeadingPeriod");
43+
validate(certs + "withLeadingPeriod");
44+
}
45+
46+
public static void validate(String certPath) throws Exception {
47+
byte[] targetCertBytes = Files.readAllBytes(Paths.get(certPath + "/leaf.pem"));
48+
byte[] caCertBytes = Files.readAllBytes(Paths.get(certPath + "/ca.pem"));
49+
50+
CertificateFactory cf = CertificateFactory.getInstance("X.509");
51+
Certificate caCert = cf.generateCertificate(new ByteArrayInputStream(caCertBytes));
52+
Certificate targetCert = cf.generateCertificate(new ByteArrayInputStream(targetCertBytes));
53+
54+
TrustAnchor anchor = new TrustAnchor((X509Certificate) caCert, null);
55+
56+
PKIXParameters params = new PKIXParameters(Collections.singleton(anchor));
57+
58+
// Disable certificate revocation checking
59+
params.setRevocationEnabled(false);
60+
61+
// Set validity date, so that validation won't fail when cert expires
62+
params.setDate(((X509Certificate)targetCert).getNotBefore());
63+
64+
CertPath path = cf.generateCertPath(List.of(targetCert, caCert));
65+
66+
CertPathValidator validator = CertPathValidator.getInstance("PKIX");
67+
validator.validate(path, params);
68+
}
69+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
###############################################################
6+
# CA with a leading period in the name constraint #
7+
###############################################################
8+
mkdir -p withLeadingPeriod
9+
10+
openssl req \
11+
-newkey rsa:1024 \
12+
-keyout withLeadingPeriod/ca.key \
13+
-out withLeadingPeriod/ca.csr \
14+
-subj "/C=US/O=Example/CN=Example CA with period" \
15+
-nodes
16+
17+
openssl x509 \
18+
-req \
19+
-in withLeadingPeriod/ca.csr \
20+
-extfile openssl.cnf \
21+
-extensions withLeadingPeriod \
22+
-signkey withLeadingPeriod/ca.key \
23+
-out withLeadingPeriod/ca.pem
24+
25+
# leaf certificate
26+
openssl req \
27+
-newkey rsa:1024 \
28+
-keyout withLeadingPeriod/leaf.key \
29+
-out withLeadingPeriod/leaf.csr \
30+
-subj '/CN=demo.example.com' \
31+
-addext 'subjectAltName = DNS:demo.example.com' \
32+
-nodes
33+
34+
openssl x509 \
35+
-req \
36+
-in withLeadingPeriod/leaf.csr \
37+
-CAcreateserial \
38+
-CA withLeadingPeriod/ca.pem \
39+
-CAkey withLeadingPeriod/ca.key \
40+
-out withLeadingPeriod/leaf.pem
41+
42+
43+
# ##################################################################
44+
# # CA without a leading period in the name contraint #
45+
# ##################################################################
46+
mkdir -p withoutLeadingPeriod
47+
48+
openssl req \
49+
-newkey rsa:1024 \
50+
-keyout withoutLeadingPeriod/ca.key \
51+
-out withoutLeadingPeriod/ca.csr \
52+
-subj "/C=US/O=Example/CN=Example CA without period" \
53+
-nodes
54+
55+
openssl x509 \
56+
-req \
57+
-in withoutLeadingPeriod/ca.csr \
58+
-extfile openssl.cnf \
59+
-extensions withoutLeadingPeriod \
60+
-signkey withoutLeadingPeriod/ca.key \
61+
-out withoutLeadingPeriod/ca.pem
62+
63+
# leaf certificate
64+
openssl req \
65+
-newkey rsa:1024 \
66+
-keyout withoutLeadingPeriod/leaf.key \
67+
-out withoutLeadingPeriod/leaf.csr \
68+
-subj '/CN=demo.example.com' \
69+
-addext 'subjectAltName = DNS:demo.example.com' \
70+
-nodes
71+
72+
openssl x509 \
73+
-req \
74+
-in withoutLeadingPeriod/leaf.csr \
75+
-CAcreateserial \
76+
-CA withoutLeadingPeriod/ca.pem \
77+
-CAkey withoutLeadingPeriod/ca.key \
78+
-out withoutLeadingPeriod/leaf.pem
79+
80+
81+
# # Verify both leaf certificates
82+
83+
set +e
84+
openssl verify \
85+
-CAfile withLeadingPeriod/ca.pem \
86+
withLeadingPeriod/leaf.pem
87+
88+
openssl verify \
89+
-CAfile withoutLeadingPeriod/ca.pem \
90+
withoutLeadingPeriod/leaf.pem
91+
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#
2+
# OpenSSL configuration file.
3+
#
4+
5+
[ withLeadingPeriod ]
6+
subjectKeyIdentifier = hash
7+
authorityKeyIdentifier = keyid:always,issuer
8+
basicConstraints = critical,CA:true
9+
keyUsage = critical,keyCertSign
10+
nameConstraints = critical,permitted;DNS:.example.com
11+
12+
[ withoutLeadingPeriod ]
13+
subjectKeyIdentifier = hash
14+
authorityKeyIdentifier = keyid:always,issuer
15+
basicConstraints = critical,CA:true
16+
keyUsage = critical,keyCertSign
17+
nameConstraints = critical,permitted;DNS:example.com
18+
19+
[ v3_ca ]
20+
subjectKeyIdentifier = hash
21+
authorityKeyIdentifier = keyid:always,issuer
22+
basicConstraints = critical,CA:true
23+
keyUsage = critical,keyCertSign
24+
25+
26+
[req]
27+
distinguished_name = req_distinguished_name
28+
x509_extensions = v3_ca # The extentions to add to self signed certs
29+
req_extensions = v3_req # The extensions to add to req's
30+
31+
prompt = no
32+
33+
[req_distinguished_name]
34+
C = US
35+
O = Example
36+
CN = example.com
37+
38+
[v3_req]
39+
keyUsage = keyEncipherment, dataEncipherment
40+
extendedKeyUsage = serverAuth
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIICgzCCAeygAwIBAgIJANBGv+BGZZHtMA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV
3+
BAYTAlVTMRAwDgYDVQQKDAdFeGFtcGxlMR8wHQYDVQQDDBZFeGFtcGxlIENBIHdp
4+
dGggcGVyaW9kMB4XDTIzMTAxOTIwNTE0NVoXDTIzMTExODIwNTE0NVowQDELMAkG
5+
A1UEBhMCVVMxEDAOBgNVBAoMB0V4YW1wbGUxHzAdBgNVBAMMFkV4YW1wbGUgQ0Eg
6+
d2l0aCBwZXJpb2QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPfaISk+Dvzk
7+
m3AY7IDZYrGWpwxHciacalrsrOFl3mj3FQ/kVhofDri3mE7bxNKWyHNcbt+Cteck
8+
TsGKBH85QsIifju7hqlrR+UbYtQF9/REkxX72gzim4xGk9KmKkuGpT5aZgvTE5eg
9+
ZumJ9XxCjGn5nbsdJoqAE/9B96GqXJvlAgMBAAGjgYQwgYEwHQYDVR0OBBYEFG8h
10+
vtka47iFUsc+3wmQ3LQRXUv3MB8GA1UdIwQYMBaAFG8hvtka47iFUsc+3wmQ3LQR
11+
XUv3MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB4GA1UdHgEB/wQU
12+
MBKgEDAOggwuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADgYEAkPeCbKokI067
13+
Dt2bommouO7LhTXivjMsByfZs8i9LZUVJz5Is+mDC36nLy4U3+QhofRLlEkWyOlE
14+
033xBtm4YPsazpur79PJtvZemV0KwwMtKCoJYNlcy2llmdKjUwe4PsPnJPqH2KL5
15+
Cxios1gil8XL5OCmEUSCT9uBblh+9gk=
16+
-----END CERTIFICATE-----
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIB0jCCATsCCQCgOCS7vOUOXTANBgkqhkiG9w0BAQsFADBAMQswCQYDVQQGEwJV
3+
UzEQMA4GA1UECgwHRXhhbXBsZTEfMB0GA1UEAwwWRXhhbXBsZSBDQSB3aXRoIHBl
4+
cmlvZDAeFw0yMzEwMTkyMDUxNDVaFw0yMzExMTgyMDUxNDVaMBsxGTAXBgNVBAMM
5+
EGRlbW8uZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALxi
6+
O4r50rNBbHu/blOSRfo9Vqei+QFS7fPwme68FOcvG+uYXf7zluO59V+8O4RPO+ZJ
7+
W6meZvtpOCWFvlSMhBLTRz350LuSPWF+/tnbiyEv487Vi6Tp7kxJytIcMtH/sWkw
8+
hF0Og8YYt3Xm2aLYPxZHGkvOccjau5X1xG1YiULzAgMBAAEwDQYJKoZIhvcNAQEL
9+
BQADgYEA8OXnFO3yZSVmQfYvC2o9amYa7tNUPHgvEjp7xDlPkvL5zF+n8k0hT0kt
10+
pv4BXzRqVIWsZcNi3H1wk6LMeUXi8EWCOR6gclWI0wZkWBhtoh8SCd2VJRmcv+zG
11+
EnInCapszNKN05KEzaFOQv0QayILBUGgHTTXOgbEmryLHXg6zik=
12+
-----END CERTIFICATE-----
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIICiDCCAfGgAwIBAgIJALUX88nU2b75MA0GCSqGSIb3DQEBCwUAMEMxCzAJBgNV
3+
BAYTAlVTMRAwDgYDVQQKDAdFeGFtcGxlMSIwIAYDVQQDDBlFeGFtcGxlIENBIHdp
4+
dGhvdXQgcGVyaW9kMB4XDTIzMTAxOTIwNTE0NVoXDTIzMTExODIwNTE0NVowQzEL
5+
MAkGA1UEBhMCVVMxEDAOBgNVBAoMB0V4YW1wbGUxIjAgBgNVBAMMGUV4YW1wbGUg
6+
Q0Egd2l0aG91dCBwZXJpb2QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANmH
7+
HqVoDjgoS60aPhQisqEL3as81tPXxXgnp5M0TE+Lb0z/kXS2mkqYYhzcZneBhVyI
8+
oGTnSnTSh6S1r/gE80x+hH4ZrLZR7jJMRDA9Q7RTOZBNgozS4XnE3AV/EjrIzHJ1
9+
IEt1ezoj2QNdVOv7UHprHGoARl9tdxre4MVUv4S3AgMBAAGjgYMwgYAwHQYDVR0O
10+
BBYEFFG0Mvse4c5C01o8kvKiM4MKMJTCMB8GA1UdIwQYMBaAFFG0Mvse4c5C01o8
11+
kvKiM4MKMJTCMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMB0GA1Ud
12+
HgEB/wQTMBGgDzANggtleGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOBgQC0CKS0
13+
JOR8hfUkZHBo52PrF3IKs33wczH5mfV+HLTdSeKtBD0Vj/7DoT0Yx2k5n6vpwA/x
14+
LTSMC4wUo4hb5164ks45iloU0FrA+n9fWbeqwhQb+DW5MSOgoVLkW+rcdKbDatTO
15+
ENcKZsqiG3aKM7pS7mQa+kUUpXWBUgVnhcsYtQ==
16+
-----END CERTIFICATE-----
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIB1TCCAT4CCQDLscehyPPGXjANBgkqhkiG9w0BAQsFADBDMQswCQYDVQQGEwJV
3+
UzEQMA4GA1UECgwHRXhhbXBsZTEiMCAGA1UEAwwZRXhhbXBsZSBDQSB3aXRob3V0
4+
IHBlcmlvZDAeFw0yMzEwMTkyMDUxNDVaFw0yMzExMTgyMDUxNDVaMBsxGTAXBgNV
5+
BAMMEGRlbW8uZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
6+
AMZM9Prp5DkAe4pkLqn4v8DFamMtWVqPlYacJacGzBkuzBn8VNQQw4qnf6wiVHBj
7+
uXLHrUCbldtKFK4XdVukmVyYSLR5BBPxA20fjZcsrBZW7u/14qWmIZW7G0xphezg
8+
6g33qNPq9CPqVHR+IrfEmjWnLjc2KrZ3OQElpJOGp48hAgMBAAEwDQYJKoZIhvcN
9+
AQELBQADgYEAYbIuAQKTXsgaBP3pyMqxPHvklDI7wJjEapbKDsOXYmKMb33pmFSD
10+
ntQFZuOKYNV2rAqQaV/3kiWKyR4vO/gsCfuFeW8kxkhZEXX9CNU0Z6mKcvy274A4
11+
K0gqYGki8hyCc5IMWTUAX2TLdq8W1hwfbjeiNqTY21e+6lIa3kcuLC0=
12+
-----END CERTIFICATE-----

0 commit comments

Comments
 (0)