8311546: Certificate name constraints improperly validated with leading period
Reviewed-by: mullan
This commit is contained in:
parent
d354141aa1
commit
bfaf5704e7
src/java.base/share/classes/sun/security/x509
test/jdk/sun/security/x509/DNSName
LeadingPeriod.java
certs
@ -200,18 +200,12 @@ public class DNSName implements GeneralNameInterface {
|
||||
* </ul>. These results are used in checking NameConstraints during
|
||||
* certification path verification.
|
||||
* <p>
|
||||
* 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
|
||||
* host1.example.com would not.
|
||||
* <p>
|
||||
* RFC 5280: DNSName restrictions are expressed as foo.bar.com.
|
||||
* Any DNSName that
|
||||
* can be constructed by simply adding to the left-hand side of the name
|
||||
* satisfies the name constraint. For example, www.foo.bar.com would
|
||||
* satisfy the constraint but foo1.bar.com would not.
|
||||
* <p>
|
||||
* RFC1034: By convention, domain names can be stored with arbitrary case, but
|
||||
* domain name comparisons for all present domain functions are done in a
|
||||
* case-insensitive manner, assuming an ASCII character set, and a high
|
||||
@ -236,13 +230,13 @@ public class DNSName implements GeneralNameInterface {
|
||||
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;
|
||||
|
113
test/jdk/sun/security/x509/DNSName/LeadingPeriod.java
Normal file
113
test/jdk/sun/security/x509/DNSName/LeadingPeriod.java
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 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
|
||||
* @library /test/lib
|
||||
* @modules java.base/sun.security.x509
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
import java.util.*;
|
||||
import java.security.Security;
|
||||
import java.security.cert.*;
|
||||
|
||||
public class LeadingPeriod {
|
||||
|
||||
private static CertPath makeCertPath(String caStr, String targetCertStr)
|
||||
throws CertificateException {
|
||||
// generate certificate from cert strings
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
|
||||
ByteArrayInputStream is;
|
||||
|
||||
is = new ByteArrayInputStream(targetCertStr.getBytes());
|
||||
Certificate targetCert = cf.generateCertificate(is);
|
||||
|
||||
is = new ByteArrayInputStream(caStr.getBytes());
|
||||
Certificate ca = cf.generateCertificate(is);
|
||||
|
||||
// generate certification path
|
||||
List<Certificate> list = List.of(targetCert, ca);
|
||||
|
||||
return cf.generateCertPath(list);
|
||||
}
|
||||
|
||||
private static PKIXParameters genParams(String caStr) throws Exception {
|
||||
// generate certificate from cert string
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(caStr.getBytes());
|
||||
Certificate selfSignedCert = cf.generateCertificate(is);
|
||||
|
||||
// generate a trust anchor
|
||||
TrustAnchor anchor = new TrustAnchor((X509Certificate) selfSignedCert, null);
|
||||
|
||||
Set<TrustAnchor> anchors = Collections.singleton(anchor);
|
||||
|
||||
PKIXParameters params = new PKIXParameters(anchors);
|
||||
|
||||
// disable certificate revocation checking
|
||||
params.setRevocationEnabled(false);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
CertPathValidator validator = CertPathValidator.getInstance("PKIX");
|
||||
|
||||
// Load certs with a NameConstraint where DNS value does not begin with a period
|
||||
Path targetFromCAWithoutPeriodPath = Paths.get(System.getProperty(
|
||||
"test.src", "./") + "/certs/withoutLeadingPeriod/leaf.pem");
|
||||
String targetFromCAWithoutPeriod = Files.readString(targetFromCAWithoutPeriodPath);
|
||||
|
||||
Path caWithoutLeadingPeriodPath = Paths.get(System.getProperty(
|
||||
"test.src", "./") + "/certs/withoutLeadingPeriod/ca.pem");
|
||||
String caWithoutLeadingPeriod = Files.readString(caWithoutLeadingPeriodPath);
|
||||
|
||||
PKIXParameters paramsForCAWithoutLeadingPeriod = genParams(caWithoutLeadingPeriod);
|
||||
CertPath pathWithoutLeadingPeriod = makeCertPath(caWithoutLeadingPeriod,
|
||||
targetFromCAWithoutPeriod);
|
||||
|
||||
validator.validate(pathWithoutLeadingPeriod, paramsForCAWithoutLeadingPeriod);
|
||||
|
||||
// Load certificates with a NameConstraint where the DNS value does begin with a period
|
||||
Path targetFromCAWithPeriodPath = Paths.get(System.getProperty(
|
||||
"test.src", "./") + "/certs/withLeadingPeriod/leaf.pem");
|
||||
String targetFromCAWithPeriod = Files.readString(targetFromCAWithPeriodPath);
|
||||
|
||||
Path caWithLeadingPeriodPath = Paths.get(System.getProperty(
|
||||
"test.src", "./") + "/certs/withLeadingPeriod/ca.pem");
|
||||
String caWithLeadingPeriod = Files.readString(caWithLeadingPeriodPath);
|
||||
|
||||
PKIXParameters paramsForCAWithLeadingPeriod = genParams(caWithLeadingPeriod);
|
||||
CertPath pathWithLeadingPeriod = makeCertPath(caWithLeadingPeriod, targetFromCAWithPeriod);
|
||||
|
||||
validator.validate(pathWithLeadingPeriod, paramsForCAWithLeadingPeriod);
|
||||
}
|
||||
}
|
91
test/jdk/sun/security/x509/DNSName/certs/generate-certs.sh
Normal file
91
test/jdk/sun/security/x509/DNSName/certs/generate-certs.sh
Normal file
@ -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
|
||||
|
40
test/jdk/sun/security/x509/DNSName/certs/openssl.cnf
Normal file
40
test/jdk/sun/security/x509/DNSName/certs/openssl.cnf
Normal file
@ -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
|
@ -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-----
|
@ -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-----
|
@ -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-----
|
@ -0,0 +1,12 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIB1TCCAT4CCQDLscehyPPGXjANBgkqhkiG9w0BAQsFADBDMQswCQYDVQQGEwJV
|
||||
UzEQMA4GA1UECgwHRXhhbXBsZTEiMCAGA1UEAwwZRXhhbXBsZSBDQSB3aXRob3V0
|
||||
IHBlcmlvZDAeFw0yMzEwMTkyMDUxNDVaFw0yMzExMTgyMDUxNDVaMBsxGTAXBgNV
|
||||
BAMMEGRlbW8uZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
|
||||
AMZM9Prp5DkAe4pkLqn4v8DFamMtWVqPlYacJacGzBkuzBn8VNQQw4qnf6wiVHBj
|
||||
uXLHrUCbldtKFK4XdVukmVyYSLR5BBPxA20fjZcsrBZW7u/14qWmIZW7G0xphezg
|
||||
6g33qNPq9CPqVHR+IrfEmjWnLjc2KrZ3OQElpJOGp48hAgMBAAEwDQYJKoZIhvcN
|
||||
AQELBQADgYEAYbIuAQKTXsgaBP3pyMqxPHvklDI7wJjEapbKDsOXYmKMb33pmFSD
|
||||
ntQFZuOKYNV2rAqQaV/3kiWKyR4vO/gsCfuFeW8kxkhZEXX9CNU0Z6mKcvy274A4
|
||||
K0gqYGki8hyCc5IMWTUAX2TLdq8W1hwfbjeiNqTY21e+6lIa3kcuLC0=
|
||||
-----END CERTIFICATE-----
|
Loading…
x
Reference in New Issue
Block a user