Skip to content

Commit b30105c

Browse files
committed
8346587: Distrust TLS server certificates anchored by Camerfirma Root CAs
1 parent e8c86cc commit b30105c

12 files changed

+408
-8
lines changed

jdk/src/share/classes/sun/security/validator/CADistrustPolicy.java

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -69,6 +69,22 @@ void checkDistrust(String variant, X509Certificate[] chain)
6969
}
7070
EntrustTLSPolicy.checkDistrust(chain);
7171
}
72+
},
73+
74+
/**
75+
* Distrust TLS Server certificates anchored by a CAMERFIRMA root CA and
76+
* issued after April 15, 2025. If enabled, this policy is currently
77+
* enforced by the PKIX and SunX509 TrustManager implementations
78+
* of the SunJSSE provider implementation.
79+
*/
80+
CAMERFIRMA_TLS {
81+
void checkDistrust(String variant, X509Certificate[] chain)
82+
throws ValidatorException {
83+
if (!variant.equals(Validator.VAR_TLS_SERVER)) {
84+
return;
85+
}
86+
CamerfirmaTLSPolicy.checkDistrust(chain);
87+
}
7288
};
7389

7490
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright (c) 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. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package sun.security.validator;
26+
27+
import java.security.cert.X509Certificate;
28+
import java.time.LocalDate;
29+
import java.time.Month;
30+
import java.time.ZoneOffset;
31+
import java.util.Date;
32+
import java.util.Map;
33+
import java.util.Set;
34+
35+
import sun.security.util.Debug;
36+
import sun.security.x509.X509CertImpl;
37+
38+
/**
39+
* This class checks if Camerfirma issued TLS Server certificates should be
40+
* restricted.
41+
*/
42+
final class CamerfirmaTLSPolicy {
43+
44+
private static final Debug debug = Debug.getInstance("certpath");
45+
46+
// SHA-256 certificate fingerprints of distrusted roots
47+
private static final Set<String> FINGERPRINTS = Set.of(
48+
// cacerts alias: camerfirmachamberscommerceca
49+
// DN: CN=Chambers of Commerce Root,
50+
// OU=http://www.chambersign.org,
51+
// O=AC Camerfirma SA CIF A82743287, C=EU
52+
"0C258A12A5674AEF25F28BA7DCFAECEEA348E541E6F5CC4EE63B71B361606AC3",
53+
// cacerts alias: camerfirmachambersca
54+
// DN: CN=Chambers of Commerce Root - 2008,
55+
// O=AC Camerfirma S.A., SERIALNUMBER=A82743287,
56+
// L=Madrid (see current address at www.camerfirma.com/address),
57+
// C=EU
58+
"063E4AFAC491DFD332F3089B8542E94617D893D7FE944E10A7937EE29D9693C0",
59+
// cacerts alias: camerfirmachambersignca
60+
// DN: CN=Global Chambersign Root - 2008,
61+
// O=AC Camerfirma S.A., SERIALNUMBER=A82743287,
62+
// L=Madrid (see current address at www.camerfirma.com/address),
63+
// C=EU
64+
"136335439334A7698016A0D324DE72284E079D7B5220BB8FBD747816EEBEBACA"
65+
);
66+
67+
// Any TLS Server certificate that is anchored by one of the Camerfirma
68+
// roots above and is issued after this date will be distrusted.
69+
private static final LocalDate APRIL_15_2025 =
70+
LocalDate.of(2025, Month.APRIL, 15);
71+
72+
/**
73+
* This method assumes the eeCert is a TLS Server Cert and chains back to
74+
* the anchor.
75+
*
76+
* @param chain the end-entity's certificate chain. The end entity cert
77+
* is at index 0, the trust anchor at index n-1.
78+
* @throws ValidatorException if the certificate is distrusted
79+
*/
80+
static void checkDistrust(X509Certificate[] chain)
81+
throws ValidatorException {
82+
X509Certificate anchor = chain[chain.length-1];
83+
String fp = fingerprint(anchor);
84+
if (fp == null) {
85+
throw new ValidatorException("Cannot generate fingerprint for "
86+
+ "trust anchor of TLS server certificate");
87+
}
88+
if (FINGERPRINTS.contains(fp)) {
89+
Date notBefore = chain[0].getNotBefore();
90+
LocalDate ldNotBefore = LocalDate.ofInstant(notBefore.toInstant(),
91+
ZoneOffset.UTC);
92+
// reject if certificate is issued after April 15, 2025
93+
checkNotBefore(ldNotBefore, APRIL_15_2025, anchor);
94+
}
95+
}
96+
97+
private static String fingerprint(X509Certificate cert) {
98+
return X509CertImpl.getFingerprint("SHA-256", cert);
99+
}
100+
101+
private static void checkNotBefore(LocalDate notBeforeDate,
102+
LocalDate distrustDate, X509Certificate anchor)
103+
throws ValidatorException {
104+
if (notBeforeDate.isAfter(distrustDate)) {
105+
throw new ValidatorException
106+
("TLS Server certificate issued after " + distrustDate +
107+
" and anchored by a distrusted legacy Camerfirma root CA: "
108+
+ anchor.getSubjectX500Principal(),
109+
ValidatorException.T_UNTRUSTED_CERT, anchor);
110+
}
111+
}
112+
113+
private CamerfirmaTLSPolicy() {}
114+
}

jdk/src/share/lib/security/java.security-aix

+4-1
Original file line numberDiff line numberDiff line change
@@ -1215,6 +1215,9 @@ jdk.sasl.disabledMechanisms=
12151215
# ENTRUST_TLS : Distrust TLS Server certificates anchored by
12161216
# an Entrust root CA and issued after November 11, 2024.
12171217
#
1218+
# CAMERFIRMA_TLS : Distrust TLS Server certificates anchored by
1219+
# a Camerfirma root CA and issued after April 15, 2025.
1220+
#
12181221
# Leading and trailing whitespace surrounding each value are ignored.
12191222
# Unknown values are ignored. If the property is commented out or set to the
12201223
# empty String, no policies are enforced.
@@ -1226,7 +1229,7 @@ jdk.sasl.disabledMechanisms=
12261229
# jdk.certpath.disabledAlgorithms; those restrictions are still enforced even
12271230
# if this property is not enabled.
12281231
#
1229-
jdk.security.caDistrustPolicies=SYMANTEC_TLS,ENTRUST_TLS
1232+
jdk.security.caDistrustPolicies=SYMANTEC_TLS,ENTRUST_TLS,CAMERFIRMA_TLS
12301233

12311234
#
12321235
# Policies for the proxy_impersonator Kerberos ccache configuration entry

jdk/src/share/lib/security/java.security-linux

+4-1
Original file line numberDiff line numberDiff line change
@@ -1221,6 +1221,9 @@ jdk.sasl.disabledMechanisms=
12211221
# ENTRUST_TLS : Distrust TLS Server certificates anchored by
12221222
# an Entrust root CA and issued after November 11, 2024.
12231223
#
1224+
# CAMERFIRMA_TLS : Distrust TLS Server certificates anchored by
1225+
# a Camerfirma root CA and issued after April 15, 2025.
1226+
#
12241227
# Leading and trailing whitespace surrounding each value are ignored.
12251228
# Unknown values are ignored. If the property is commented out or set to the
12261229
# empty String, no policies are enforced.
@@ -1232,7 +1235,7 @@ jdk.sasl.disabledMechanisms=
12321235
# jdk.certpath.disabledAlgorithms; those restrictions are still enforced even
12331236
# if this property is not enabled.
12341237
#
1235-
jdk.security.caDistrustPolicies=SYMANTEC_TLS,ENTRUST_TLS
1238+
jdk.security.caDistrustPolicies=SYMANTEC_TLS,ENTRUST_TLS,CAMERFIRMA_TLS
12361239

12371240
#
12381241
# Policies for the proxy_impersonator Kerberos ccache configuration entry

jdk/src/share/lib/security/java.security-macosx

+4-1
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,9 @@ jdk.sasl.disabledMechanisms=
12191219
# ENTRUST_TLS : Distrust TLS Server certificates anchored by
12201220
# an Entrust root CA and issued after November 11, 2024.
12211221
#
1222+
# CAMERFIRMA_TLS : Distrust TLS Server certificates anchored by
1223+
# a Camerfirma root CA and issued after April 15, 2025.
1224+
#
12221225
# Leading and trailing whitespace surrounding each value are ignored.
12231226
# Unknown values are ignored. If the property is commented out or set to the
12241227
# empty String, no policies are enforced.
@@ -1230,7 +1233,7 @@ jdk.sasl.disabledMechanisms=
12301233
# jdk.certpath.disabledAlgorithms; those restrictions are still enforced even
12311234
# if this property is not enabled.
12321235
#
1233-
jdk.security.caDistrustPolicies=SYMANTEC_TLS,ENTRUST_TLS
1236+
jdk.security.caDistrustPolicies=SYMANTEC_TLS,ENTRUST_TLS,CAMERFIRMA_TLS
12341237

12351238
#
12361239
# Policies for the proxy_impersonator Kerberos ccache configuration entry

jdk/src/share/lib/security/java.security-solaris

+4-1
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,9 @@ jdk.sasl.disabledMechanisms=
12171217
# ENTRUST_TLS : Distrust TLS Server certificates anchored by
12181218
# an Entrust root CA and issued after November 11, 2024.
12191219
#
1220+
# CAMERFIRMA_TLS : Distrust TLS Server certificates anchored by
1221+
# a Camerfirma root CA and issued after April 15, 2025.
1222+
#
12201223
# Leading and trailing whitespace surrounding each value are ignored.
12211224
# Unknown values are ignored. If the property is commented out or set to the
12221225
# empty String, no policies are enforced.
@@ -1228,7 +1231,7 @@ jdk.sasl.disabledMechanisms=
12281231
# jdk.certpath.disabledAlgorithms; those restrictions are still enforced even
12291232
# if this property is not enabled.
12301233
#
1231-
jdk.security.caDistrustPolicies=SYMANTEC_TLS,ENTRUST_TLS
1234+
jdk.security.caDistrustPolicies=SYMANTEC_TLS,ENTRUST_TLS,CAMERFIRMA_TLS
12321235

12331236
#
12341237
# Policies for the proxy_impersonator Kerberos ccache configuration entry

jdk/src/share/lib/security/java.security-windows

+4-1
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,9 @@ jdk.sasl.disabledMechanisms=
12191219
# ENTRUST_TLS : Distrust TLS Server certificates anchored by
12201220
# an Entrust root CA and issued after November 11, 2024.
12211221
#
1222+
# CAMERFIRMA_TLS : Distrust TLS Server certificates anchored by
1223+
# a Camerfirma root CA and issued after April 15, 2025.
1224+
#
12221225
# Leading and trailing whitespace surrounding each value are ignored.
12231226
# Unknown values are ignored. If the property is commented out or set to the
12241227
# empty String, no policies are enforced.
@@ -1230,7 +1233,7 @@ jdk.sasl.disabledMechanisms=
12301233
# jdk.certpath.disabledAlgorithms; those restrictions are still enforced even
12311234
# if this property is not enabled.
12321235
#
1233-
jdk.security.caDistrustPolicies=SYMANTEC_TLS,ENTRUST_TLS
1236+
jdk.security.caDistrustPolicies=SYMANTEC_TLS,ENTRUST_TLS,CAMERFIRMA_TLS
12341237

12351238
#
12361239
# Policies for the proxy_impersonator Kerberos ccache configuration entry
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (c) 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+
import java.io.File;
25+
import java.security.Security;
26+
import java.time.*;
27+
import java.util.*;
28+
import javax.net.ssl.*;
29+
30+
/**
31+
* @test
32+
* @bug 8346587
33+
* @summary Check that TLS Server certificates chaining back to distrusted
34+
* Camerfirma roots are invalid
35+
* @library /lib/security
36+
* @modules java.base/sun.security.validator
37+
* @run main/othervm Camerfirma after policyOn invalid
38+
* @run main/othervm Camerfirma after policyOff valid
39+
* @run main/othervm Camerfirma before policyOn valid
40+
* @run main/othervm Camerfirma before policyOff valid
41+
*/
42+
43+
public class Camerfirma {
44+
45+
private static final String certPath = "chains" + File.separator + "camerfirma";
46+
47+
// Each of the roots have a test certificate chain stored in a file
48+
// named "<root>-chain.pem".
49+
private static String[] rootsToTest = new String[] {
50+
"camerfirmachamberscommerceca", "camerfirmachambersca",
51+
"camerfirmachambersignca"};
52+
53+
// Date after the restrictions take effect
54+
private static final ZonedDateTime DISTRUST_DATE =
55+
LocalDate.of(2025, 04, 16).atStartOfDay(ZoneOffset.UTC);
56+
57+
public static void main(String[] args) throws Exception {
58+
59+
// All of the test certificates are signed with SHA-1 so we need
60+
// to remove the constraint that disallows SHA-1 certificates.
61+
String prop = Security.getProperty("jdk.certpath.disabledAlgorithms");
62+
String newProp = prop.replace(", SHA1 jdkCA & usage TLSServer", "");
63+
Security.setProperty("jdk.certpath.disabledAlgorithms", newProp);
64+
65+
Distrust distrust = new Distrust(args);
66+
67+
X509TrustManager[] tms = new X509TrustManager[]{
68+
distrust.getTMF("PKIX", null),
69+
distrust.getTMF("SunX509", null)
70+
};
71+
72+
Date notBefore = distrust.getNotBefore(DISTRUST_DATE);
73+
distrust.testCertificateChain(certPath, notBefore, tms, rootsToTest);
74+
}
75+
}

jdk/test/sun/security/ssl/X509TrustManagerImpl/distrust/Distrust.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -196,7 +196,13 @@ public boolean[] getIssuerUniqueID() {
196196
public boolean[] getSubjectUniqueID() {
197197
return cert.getSubjectUniqueID();
198198
}
199-
public boolean[] getKeyUsage() { return cert.getKeyUsage(); }
199+
public boolean[] getKeyUsage() {
200+
// Turn on the Digital Signature bit. Some certs that we want
201+
// to use as test certs don't have this bit turned on.
202+
boolean[] withDigitalSignature = cert.getKeyUsage();
203+
withDigitalSignature[0] = true;
204+
return withDigitalSignature;
205+
}
200206
public int getBasicConstraints() { return cert.getBasicConstraints(); }
201207
public byte[] getEncoded() throws CertificateEncodingException {
202208
return cert.getEncoded();

0 commit comments

Comments
 (0)