Skip to content

Commit e544cd9

Browse files
committed
8359956: Support algorithm constraints and certificate checks in SunX509 key manager
Reviewed-by: mullan
1 parent 458f033 commit e544cd9

File tree

17 files changed

+1854
-740
lines changed

17 files changed

+1854
-740
lines changed

src/java.base/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java

Lines changed: 79 additions & 197 deletions
Large diffs are not rendered by default.

src/java.base/share/classes/sun/security/ssl/X509KeyManagerCertChecking.java

Lines changed: 579 additions & 0 deletions
Large diffs are not rendered by default.

src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java

Lines changed: 42 additions & 484 deletions
Large diffs are not rendered by default.

test/jdk/javax/rmi/ssl/SSLSocketParametersTest.java

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2004, 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
@@ -24,7 +24,8 @@
2424
/*
2525
* @test
2626
* @bug 5016500
27-
* @library /test/lib/
27+
* @library /javax/net/ssl/templates
28+
* /test/lib/
2829
* @summary Test SslRmi[Client|Server]SocketFactory SSL socket parameters.
2930
* @run main/othervm SSLSocketParametersTest 1
3031
* @run main/othervm SSLSocketParametersTest 2
@@ -36,8 +37,6 @@
3637
*/
3738
import jdk.test.lib.Asserts;
3839

39-
import java.io.IOException;
40-
import java.io.File;
4140
import java.io.Serializable;
4241
import java.lang.ref.Reference;
4342
import java.rmi.ConnectIOException;
@@ -49,13 +48,17 @@
4948
import javax.rmi.ssl.SslRMIClientSocketFactory;
5049
import javax.rmi.ssl.SslRMIServerSocketFactory;
5150

52-
public class SSLSocketParametersTest implements Serializable {
51+
public class SSLSocketParametersTest extends SSLContextTemplate {
52+
53+
public SSLSocketParametersTest() throws Exception {
54+
SSLContext.setDefault(createServerSSLContext());
55+
}
5356

5457
public interface Hello extends Remote {
5558
String sayHello() throws RemoteException;
5659
}
5760

58-
public class HelloImpl implements Hello {
61+
public static class HelloImpl implements Hello {
5962
public String sayHello() {
6063
return "Hello World!";
6164
}
@@ -134,23 +137,7 @@ public void runTest(int testNumber) throws Exception {
134137
}
135138

136139
public static void main(String[] args) throws Exception {
137-
// Set keystore properties (server-side)
138-
//
139-
final String keystore = System.getProperty("test.src") +
140-
File.separator + "keystore";
141-
System.out.println("KeyStore = " + keystore);
142-
System.setProperty("javax.net.ssl.keyStore", keystore);
143-
System.setProperty("javax.net.ssl.keyStorePassword", "password");
144-
145-
// Set truststore properties (client-side)
146-
//
147-
final String truststore = System.getProperty("test.src") +
148-
File.separator + "truststore";
149-
System.out.println("TrustStore = " + truststore);
150-
System.setProperty("javax.net.ssl.trustStore", truststore);
151-
System.setProperty("javax.net.ssl.trustStorePassword", "trustword");
152-
153140
SSLSocketParametersTest test = new SSLSocketParametersTest();
154141
test.runTest(Integer.parseInt(args[0]));
155142
}
156-
}
143+
}

test/jdk/javax/rmi/ssl/keystore

-1.33 KB
Binary file not shown.

test/jdk/javax/rmi/ssl/truststore

-661 Bytes
Binary file not shown.

test/jdk/sun/net/www/protocol/https/HttpsClient/ServerIdentityTest.java

Lines changed: 150 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2001, 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
@@ -31,31 +31,58 @@
3131
* @bug 4328195
3232
* @summary Need to include the alternate subject DN for certs,
3333
* https should check for this
34+
* @modules java.base/sun.security.x509
35+
* java.base/sun.security.util
3436
* @library /javax/net/ssl/templates
35-
* @run main/othervm ServerIdentityTest dnsstore localhost
36-
* @run main/othervm ServerIdentityTest ipstore 127.0.0.1
37+
* /test/lib
38+
* @run main/othervm ServerIdentityTest dns localhost
39+
* @run main/othervm ServerIdentityTest ip 127.0.0.1
3740
*
3841
* @author Yingxian Wang
3942
*/
4043

41-
import java.io.InputStream;
44+
import static jdk.test.lib.Asserts.fail;
45+
4246
import java.io.BufferedWriter;
47+
import java.io.IOException;
48+
import java.io.InputStream;
4349
import java.io.OutputStreamWriter;
50+
import java.math.BigInteger;
4451
import java.net.HttpURLConnection;
4552
import java.net.InetAddress;
4653
import java.net.Proxy;
4754
import java.net.URL;
4855
import java.net.UnknownHostException;
49-
56+
import java.security.KeyPair;
57+
import java.security.KeyPairGenerator;
58+
import java.security.KeyStore;
59+
import java.security.PrivateKey;
60+
import java.security.PublicKey;
61+
import java.security.SecureRandom;
62+
import java.security.cert.Certificate;
63+
import java.security.cert.CertificateException;
64+
import java.security.cert.X509Certificate;
65+
import java.time.Instant;
66+
import java.time.temporal.ChronoUnit;
67+
import java.util.Date;
68+
import java.util.List;
5069
import javax.net.ssl.HttpsURLConnection;
70+
import javax.net.ssl.KeyManagerFactory;
5171
import javax.net.ssl.SSLContext;
5272
import javax.net.ssl.SSLSocket;
73+
import javax.net.ssl.TrustManagerFactory;
74+
import jdk.test.lib.security.CertificateBuilder;
75+
import sun.security.x509.AuthorityKeyIdentifierExtension;
76+
import sun.security.x509.GeneralName;
77+
import sun.security.x509.GeneralNames;
78+
import sun.security.x509.KeyIdentifier;
79+
import sun.security.x509.SerialNumber;
80+
import sun.security.x509.X500Name;
5381

5482
public final class ServerIdentityTest extends SSLSocketTemplate {
5583

56-
private static String keystore;
5784
private static String hostname;
58-
private static SSLContext context;
85+
private static SSLContext serverContext;
5986

6087
/*
6188
* Run the test case.
@@ -64,7 +91,7 @@ public static void main(String[] args) throws Exception {
6491
// Get the customized arguments.
6592
initialize(args);
6693

67-
(new ServerIdentityTest()).run();
94+
new ServerIdentityTest().run();
6895
}
6996

7097
ServerIdentityTest() throws UnknownHostException {
@@ -95,7 +122,7 @@ protected void runClientApplication(int serverPort) throws Exception {
95122
HttpURLConnection urlc = null;
96123
InputStream is = null;
97124
try {
98-
urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
125+
urlc = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
99126
is = urlc.getInputStream();
100127
} finally {
101128
if (is != null) {
@@ -109,31 +136,127 @@ protected void runClientApplication(int serverPort) throws Exception {
109136

110137
@Override
111138
protected SSLContext createServerSSLContext() throws Exception {
112-
return context;
113-
}
114-
115-
@Override
116-
protected SSLContext createClientSSLContext() throws Exception {
117-
return context;
139+
return serverContext;
118140
}
119141

120142
private static void initialize(String[] args) throws Exception {
121-
keystore = args[0];
143+
String mode = args[0];
122144
hostname = args[1];
123145

124-
String password = "changeit";
125-
String keyFilename =
126-
System.getProperty("test.src", ".") + "/" + keystore;
127-
String trustFilename =
128-
System.getProperty("test.src", ".") + "/" + keystore;
146+
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
147+
KeyPair caKeys = kpg.generateKeyPair();
148+
KeyPair serverKeys = kpg.generateKeyPair();
149+
KeyPair clientKeys = kpg.generateKeyPair();
150+
151+
CertificateBuilder serverCertificateBuilder = customCertificateBuilder(
152+
"CN=server, O=Some-Org, L=Some-City, ST=Some-State, C=US",
153+
serverKeys.getPublic(), caKeys.getPublic())
154+
.addBasicConstraintsExt(false, false, -1);
129155

130-
System.setProperty("javax.net.ssl.keyStore", keyFilename);
131-
System.setProperty("javax.net.ssl.keyStorePassword", password);
132-
System.setProperty("javax.net.ssl.trustStore", trustFilename);
133-
System.setProperty("javax.net.ssl.trustStorePassword", password);
156+
if (mode.equalsIgnoreCase("dns")) {
157+
serverCertificateBuilder.addSubjectAltNameDNSExt(List.of(hostname));
158+
} else if (mode.equalsIgnoreCase("ip")) {
159+
serverCertificateBuilder.addSubjectAltNameIPExt(List.of(hostname));
160+
} else {
161+
fail("Unknown mode: " + mode);
162+
}
163+
164+
X509Certificate trustedCert = createTrustedCert(caKeys);
165+
166+
X509Certificate serverCert = serverCertificateBuilder.build(
167+
trustedCert, caKeys.getPrivate(), "SHA256WithRSA");
168+
169+
X509Certificate clientCert = customCertificateBuilder(
170+
"CN=localhost, OU=SSL-Client, O=Some-Org, L=Some-City, ST=Some-State, C=US",
171+
clientKeys.getPublic(), caKeys.getPublic())
172+
.addBasicConstraintsExt(false, false, -1)
173+
.build(trustedCert, caKeys.getPrivate(), "SHA256WithRSA");
174+
175+
serverContext = getSSLContext(
176+
trustedCert, serverCert, serverKeys.getPrivate());
177+
178+
SSLContext clientContext = getSSLContext(
179+
trustedCert, clientCert, clientKeys.getPrivate());
134180

135-
context = SSLContext.getDefault();
136181
HttpsURLConnection.setDefaultSSLSocketFactory(
137-
context.getSocketFactory());
182+
clientContext.getSocketFactory());
138183
}
184+
185+
private static SSLContext getSSLContext(
186+
X509Certificate trustedCertificate, X509Certificate keyCertificate,
187+
PrivateKey privateKey)
188+
throws Exception {
189+
190+
// create a key store
191+
KeyStore ks = KeyStore.getInstance("PKCS12");
192+
ks.load(null, null);
193+
194+
// import the trusted cert
195+
ks.setCertificateEntry("TLS Signer", trustedCertificate);
196+
197+
// generate certificate chain
198+
Certificate[] chain = new Certificate[2];
199+
chain[0] = keyCertificate;
200+
chain[1] = trustedCertificate;
201+
202+
// import the key entry.
203+
final char[] passphrase = "passphrase".toCharArray();
204+
ks.setKeyEntry("Whatever", privateKey, passphrase, chain);
205+
206+
// Using PKIX TrustManager
207+
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
208+
tmf.init(ks);
209+
210+
// Using PKIX KeyManager
211+
KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX");
212+
213+
// create SSL context
214+
SSLContext ctx = SSLContext.getInstance("TLS");
215+
kmf.init(ks, passphrase);
216+
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
217+
return ctx;
218+
}
219+
220+
private static X509Certificate createTrustedCert(KeyPair caKeys)
221+
throws Exception {
222+
SecureRandom random = new SecureRandom();
223+
224+
KeyIdentifier kid = new KeyIdentifier(caKeys.getPublic());
225+
GeneralNames gns = new GeneralNames();
226+
GeneralName name = new GeneralName(new X500Name(
227+
"O=Some-Org, L=Some-City, ST=Some-State, C=US"));
228+
gns.add(name);
229+
BigInteger serialNumber = BigInteger.valueOf(
230+
random.nextLong(1000000) + 1);
231+
return customCertificateBuilder(
232+
"O=Some-Org, L=Some-City, ST=Some-State, C=US",
233+
caKeys.getPublic(), caKeys.getPublic())
234+
.setSerialNumber(serialNumber)
235+
.addExtension(new AuthorityKeyIdentifierExtension(kid, gns,
236+
new SerialNumber(serialNumber)))
237+
.addBasicConstraintsExt(true, true, -1)
238+
.build(null, caKeys.getPrivate(), "SHA256WithRSA");
239+
}
240+
241+
private static CertificateBuilder customCertificateBuilder(
242+
String subjectName, PublicKey publicKey, PublicKey caKey)
243+
throws CertificateException, IOException {
244+
SecureRandom random = new SecureRandom();
245+
246+
CertificateBuilder builder = new CertificateBuilder()
247+
.setSubjectName(subjectName)
248+
.setPublicKey(publicKey)
249+
.setNotBefore(
250+
Date.from(Instant.now().minus(1, ChronoUnit.HOURS)))
251+
.setNotAfter(Date.from(Instant.now().plus(1, ChronoUnit.HOURS)))
252+
.setSerialNumber(
253+
BigInteger.valueOf(random.nextLong(1000000) + 1))
254+
.addSubjectKeyIdExt(publicKey)
255+
.addAuthorityKeyIdExt(caKey);
256+
builder.addKeyUsageExt(
257+
new boolean[]{true, true, true, true, true, true});
258+
259+
return builder;
260+
}
261+
139262
}
-1.38 KB
Binary file not shown.
-1.38 KB
Binary file not shown.

test/jdk/sun/security/mscapi/ShortRSAKeyWithinTLS.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 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
@@ -29,6 +29,7 @@
2929
* @modules java.base/sun.security.util
3030
* java.base/sun.security.tools.keytool
3131
* java.base/sun.security.x509
32+
* @library /test/lib
3233
* @run main ShortRSAKeyWithinTLS 1024
3334
* @run main ShortRSAKeyWithinTLS 768
3435
* @run main ShortRSAKeyWithinTLS 512
@@ -42,6 +43,7 @@
4243
import javax.net.*;
4344
import javax.net.ssl.*;
4445

46+
import jdk.test.lib.security.SecurityUtils;
4547
import sun.security.tools.keytool.CertAndKeyGen;
4648
import sun.security.util.KeyUtil;
4749
import sun.security.x509.X500Name;
@@ -233,6 +235,10 @@ private void checkKeySize(KeyStore ks) throws Exception {
233235
private static String clientCiperSuite = null;
234236

235237
public static void main(String[] args) throws Exception {
238+
// Make sure we don't block the key on algorithm constraints check.
239+
SecurityUtils.removeFromDisabledAlgs("jdk.certpath.disabledAlgorithms",
240+
List.of("RSA keySize < 1024"));
241+
236242
if (debug) {
237243
System.setProperty("javax.net.debug", "all");
238244
}

0 commit comments

Comments
 (0)