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 ;
5477import 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
5685public 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 }
0 commit comments