Skip to content

Commit f5eecc4

Browse files
author
Matthew Donovan
committed
8353738: Update TLS unit tests to not use certificates with MD5 signatures
Reviewed-by: djelinski, abarashev
1 parent 160148c commit f5eecc4

File tree

14 files changed

+524
-3079
lines changed

14 files changed

+524
-3079
lines changed
1.35 KB
Binary file not shown.
1.35 KB
Binary file not shown.
2.04 KB
Binary file not shown.
2.04 KB
Binary file not shown.

test/jdk/javax/net/ssl/HttpsURLConnection/CriticalSubjectAltName.java

Lines changed: 139 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -27,31 +27,60 @@
2727
//
2828

2929
/*
30-
* @test
30+
* @test id=tls12
3131
* @bug 6668231
3232
* @summary Presence of a critical subjectAltName causes JSSE's SunX509 to
3333
* fail trusted checks
34-
* @run main/othervm CriticalSubjectAltName
34+
* @library /test/lib
35+
* @modules java.base/sun.security.x509 java.base/sun.security.util
36+
* @run main/othervm CriticalSubjectAltName TLSv1.2 MD5withRSA
3537
* @author Xuelei Fan
3638
*/
3739

40+
3841
/*
39-
* This test depends on binary keystore, crisubn.jks and trusted.jks. Because
40-
* JAVA keytool cannot generate X509 certificate with SubjectAltName extension,
41-
* the certificates are generated with openssl toolkits and then imported into
42-
* JAVA keystore.
43-
*
44-
* The crisubn.jks holds a private key entry and the corresponding X509
45-
* certificate issued with an empty Subject field, and a critical
46-
* SubjectAltName extension.
47-
*
48-
* The trusted.jks holds the trusted certificate.
42+
* @test id=tls13
43+
* @bug 6668231
44+
* @summary Presence of a critical subjectAltName causes JSSE's SunX509 to
45+
* fail trusted checks
46+
* @library /test/lib
47+
* @modules java.base/sun.security.x509 java.base/sun.security.util
48+
* @run main/othervm CriticalSubjectAltName TLSv1.3 SHA256withRSA
49+
* @author Xuelei Fan
4950
*/
50-
import java.io.*;
51-
import java.net.*;
52-
import javax.net.ssl.*;
53-
import java.security.Security;
51+
52+
53+
import jdk.test.lib.security.CertificateBuilder;
54+
import sun.security.x509.GeneralName;
55+
import sun.security.x509.GeneralNames;
56+
import sun.security.x509.OIDName;
57+
import sun.security.x509.RFC822Name;
58+
import sun.security.x509.SubjectAlternativeNameExtension;
59+
60+
61+
import javax.net.ssl.HostnameVerifier;
62+
import javax.net.ssl.HttpsURLConnection;
63+
import javax.net.ssl.KeyManagerFactory;
64+
import javax.net.ssl.SSLContext;
65+
import javax.net.ssl.SSLServerSocket;
66+
import javax.net.ssl.SSLServerSocketFactory;
67+
import javax.net.ssl.SSLSession;
68+
import javax.net.ssl.SSLSocket;
69+
import javax.net.ssl.TrustManagerFactory;
70+
import java.io.BufferedWriter;
71+
import java.io.OutputStream;
72+
import java.io.OutputStreamWriter;
73+
import java.net.URL;
74+
import java.security.KeyPair;
75+
import java.security.KeyPairGenerator;
76+
import java.security.KeyStore;
5477
import java.security.cert.Certificate;
78+
import java.security.cert.X509Certificate;
79+
import java.util.concurrent.CountDownLatch;
80+
import java.util.concurrent.TimeUnit;
81+
import java.util.List;
82+
83+
import jdk.test.lib.security.SecurityUtils;
5584

5685
public class CriticalSubjectAltName implements HostnameVerifier {
5786
/*
@@ -70,20 +99,18 @@ public class CriticalSubjectAltName implements HostnameVerifier {
7099
/*
71100
* Where do we find the keystores?
72101
*/
73-
static String pathToStores = "./";
74-
static String keyStoreFile = "crisubn.jks";
75-
static String trustStoreFile = "trusted.jks";
76-
static String passwd = "passphrase";
102+
public static final char[] PASSPHRASE = "passphrase".toCharArray();
77103

78104
/*
79105
* Is the server ready to serve?
80106
*/
81-
volatile static boolean serverReady = false;
107+
private final CountDownLatch serverReady = new CountDownLatch(1);
108+
private final int SERVER_WAIT_SECS = 10;
82109

83110
/*
84111
* Turn on SSL debugging?
85112
*/
86-
static boolean debug = false;
113+
static boolean debug = Boolean.getBoolean("test.debug");
87114

88115
/*
89116
* If the client or server is doing some kind of object creation
@@ -101,17 +128,17 @@ public class CriticalSubjectAltName implements HostnameVerifier {
101128
* to avoid infinite hangs.
102129
*/
103130
void doServerSide() throws Exception {
104-
SSLServerSocketFactory sslssf =
105-
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
131+
SSLContext ctx = createServerContext();
132+
SSLServerSocketFactory sslssf = ctx.getServerSocketFactory();
106133
SSLServerSocket sslServerSocket =
107134
(SSLServerSocket) sslssf.createServerSocket(serverPort);
108-
sslServerSocket.setEnabledProtocols(new String[]{"TLSv1.2"});
135+
sslServerSocket.setEnabledProtocols(new String[]{protocol});
109136
serverPort = sslServerSocket.getLocalPort();
110137

111138
/*
112139
* Signal Client, we're ready for his connect.
113140
*/
114-
serverReady = true;
141+
serverReady.countDown();
115142

116143
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
117144
OutputStream sslOS = sslSocket.getOutputStream();
@@ -122,6 +149,36 @@ void doServerSide() throws Exception {
122149
sslSocket.close();
123150
}
124151

152+
private SSLContext createServerContext() throws Exception {
153+
KeyStore ks = KeyStore.getInstance("PKCS12");
154+
ks.load(null, null);
155+
ks.setCertificateEntry("Trusted Cert", trustedCert);
156+
157+
Certificate[] chain = new Certificate[] {serverCert};
158+
ks.setKeyEntry("Server key", serverKeys.getPrivate(),
159+
PASSPHRASE, chain);
160+
161+
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
162+
tmf.init(ks);
163+
164+
SSLContext ctx = SSLContext.getInstance(protocol);
165+
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
166+
kmf.init(ks, PASSPHRASE);
167+
ctx.init(kmf.getKeyManagers(), null, null);
168+
return ctx;
169+
}
170+
171+
private SSLContext createClientContext() throws Exception {
172+
KeyStore ks = KeyStore.getInstance("PKCS12");
173+
ks.load(null, null);
174+
ks.setCertificateEntry("Trusted Cert", trustedCert);
175+
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
176+
tmf.init(ks);
177+
SSLContext ctx = SSLContext.getInstance(protocol);
178+
ctx.init(null, tmf.getTrustManagers(), null);
179+
return ctx;
180+
}
181+
125182
/*
126183
* Define the client side of the test.
127184
*
@@ -130,15 +187,12 @@ void doServerSide() throws Exception {
130187
*/
131188
void doClientSide() throws Exception {
132189

133-
/*
134-
* Wait for server to get started.
135-
*/
136-
while (!serverReady) {
137-
Thread.sleep(50);
138-
}
190+
serverReady.await();
139191

192+
SSLContext ctx = createClientContext();
140193
URL url = new URL("https://localhost:"+serverPort+"/index.html");
141194
HttpsURLConnection urlc = (HttpsURLConnection)url.openConnection();
195+
urlc.setSSLSocketFactory(ctx.getSocketFactory());
142196
urlc.setHostnameVerifier(this);
143197
urlc.getInputStream();
144198

@@ -159,42 +213,73 @@ void doClientSide() throws Exception {
159213
volatile Exception clientException = null;
160214

161215
public static void main(String[] args) throws Exception {
162-
// MD5 is used in this test case, don't disable MD5 algorithm.
163-
Security.setProperty("jdk.certpath.disabledAlgorithms",
164-
"MD2, RSA keySize < 1024");
165-
Security.setProperty("jdk.tls.disabledAlgorithms",
166-
"SSLv3, RC4, DH keySize < 768");
167-
168-
String keyFilename =
169-
System.getProperty("test.src", "./") + "/" + pathToStores +
170-
"/" + keyStoreFile;
171-
String trustFilename =
172-
System.getProperty("test.src", "./") + "/" + pathToStores +
173-
"/" + trustStoreFile;
174-
175-
System.setProperty("javax.net.ssl.keyStore", keyFilename);
176-
System.setProperty("javax.net.ssl.keyStorePassword", passwd);
177-
System.setProperty("javax.net.ssl.trustStore", trustFilename);
178-
System.setProperty("javax.net.ssl.trustStorePassword", passwd);
179-
180-
if (debug)
216+
if (args[1].contains("MD5")) {
217+
SecurityUtils.removeFromDisabledAlgs(
218+
"jdk.certpath.disabledAlgorithms", List.of("MD5"));
219+
SecurityUtils.removeFromDisabledTlsAlgs("MD5");
220+
}
221+
222+
if (debug) {
181223
System.setProperty("javax.net.debug", "all");
224+
}
182225

183226
/*
184227
* Start the tests.
185228
*/
186-
new CriticalSubjectAltName();
229+
new CriticalSubjectAltName(args[0], args[1]);
187230
}
188231

189232
Thread clientThread = null;
190233
Thread serverThread = null;
234+
private final String protocol;
235+
private KeyPair serverKeys;
236+
private X509Certificate trustedCert;
237+
private X509Certificate serverCert;
238+
239+
private void setupCertificates(String signatureAlg) throws Exception {
240+
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
241+
KeyPair caKeys = kpg.generateKeyPair();
242+
serverKeys = kpg.generateKeyPair();
243+
244+
trustedCert = CertificateBuilder.newCertificateBuilder(
245+
"CN=Someone, O=Some Org, ST=Some-State, C=US",
246+
caKeys.getPublic(), caKeys.getPublic())
247+
.addBasicConstraintsExt(true, true, -1)
248+
.setOneHourValidity()
249+
.build(null, caKeys.getPrivate(), signatureAlg);
250+
if (debug) {
251+
System.out.println("Trusted Certificate");
252+
CertificateBuilder.printCertificate(trustedCert, System.out);
253+
}
254+
255+
GeneralNames gns = new GeneralNames();
256+
gns.add(new GeneralName(new RFC822Name("example@openjdk.net")));
257+
gns.add(new GeneralName(new OIDName("1.2.3.4")));
258+
259+
serverCert = CertificateBuilder.newCertificateBuilder("",
260+
serverKeys.getPublic(), caKeys.getPublic())
261+
.setOneHourValidity()
262+
.addBasicConstraintsExt(false, false, -1)
263+
.addExtension(new SubjectAlternativeNameExtension(true, gns))
264+
.setOneHourValidity()
265+
.build(trustedCert, caKeys.getPrivate(), signatureAlg);
266+
if (debug) {
267+
System.out.println("Server Certificate");
268+
CertificateBuilder.printCertificate(serverCert, System.out);
269+
}
270+
}
271+
191272

192273
/*
193274
* Primary constructor, used to drive remainder of the test.
194275
*
195276
* Fork off the other side, then do your work.
196277
*/
197-
CriticalSubjectAltName() throws Exception {
278+
CriticalSubjectAltName(String protocol, String signatureAlg) throws Exception {
279+
this.protocol = protocol;
280+
281+
setupCertificates(signatureAlg);
282+
198283
if (separateServerThread) {
199284
startServer(true);
200285
startClient(false);
@@ -238,7 +323,7 @@ public void run() {
238323
* Release the client, if not active already...
239324
*/
240325
System.err.println("Server died...");
241-
serverReady = true;
326+
serverReady.countDown();
242327
serverException = e;
243328
}
244329
}
-2.73 KB
Binary file not shown.
-743 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)