1 /*
2  * Copyright (c) 2001, 2016, 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 /*
25  * @test
26  * @bug 4414843
27  * @summary This test tries all the different ways in which an SSL
28  * connection can be established to exercise different SSLSocketImpl
29  * constructors.
30  * @run main/othervm/timeout=300 SocketCreation
31  *
32  *     SunJSSE does not support dynamic system properties, no way to re-use
33  *     system properties in samevm/agentvm mode.
34  */
35 
36 import java.io.*;
37 import java.net.*;
38 import javax.net.ssl.*;
39 
40 /**
41  * This test has been adapted from JSSEClientServerTemplate.java. It runs
42  * the client and server multiple times while it iterates through the
43  * different ways in which an SSL connection can be established.
44  *
45  * The meat of this test is contained in doClientSide() and
46  * doServerSide(). The loop is contained in the constructor
47  * SocketCreation().
48  */
49 public class SocketCreation {
50 
51     /*
52      * =============================================================
53      * Set the various variables needed for the tests, then
54      * specify what tests to run on each side.
55      */
56 
57     /*
58      * Should we run the client or server in a separate thread?
59      * Both sides can throw exceptions, but do you have a preference
60      * as to which side should be the main thread.
61      */
62     static boolean separateServerThread = true;
63 
64     /*
65      * Where do we find the keystores?
66      */
67     static String pathToStores = "../../../../javax/net/ssl/etc";
68     static String keyStoreFile = "keystore";
69     static String trustStoreFile = "truststore";
70     static String passwd = "passphrase";
71 
72     /*
73      * Is the server ready to serve?
74      */
75     volatile static boolean serverReady = false;
76 
77     /*
78      * Turn on SSL debugging?
79      */
80     static boolean debug = false;
81 
82     /*
83      * If the client or server is doing some kind of object creation
84      * that the other side depends on, and that thread prematurely
85      * exits, you may experience a hang.  The test harness will
86      * terminate all hung threads after its timeout has expired,
87      * currently 3 minutes by default, but you might try to be
88      * smart about it....
89      */
90 
91     /*
92      * Accepts a connection from a client and exchanges an int with it. The
93      * connection can be established in one of three different ways:
94      *    1. As a regular SSL server socket
95      *    2. As an SSL server socket that is first unbound
96      *    3. As an SSL socket layered over a regular TCP/IP socket
97      *
98      * If the server prematurely exits, serverReady will be set to true
99      * to avoid infinite hangs.
100      */
doServerSide(int style)101     void doServerSide(int style) throws Exception {
102 
103         Socket sslSocket = null;
104 
105         // Change the for loop in SocketCreation() if you add more cases
106         switch (style) {
107         case 0:
108             sslSocket = acceptNormally0();
109             break;
110         case 1:
111             sslSocket = acceptNormally1();
112             break;
113         case 2:
114             sslSocket = acceptNormally2();
115             break;
116         case 3:
117             sslSocket = acceptUnbound();
118             break;
119         case 4:
120             sslSocket = acceptLayered();
121             break;
122         default:
123             throw new Exception("Incorrectly written test for server side!");
124         }
125 
126         InputStream sslIS = sslSocket.getInputStream();
127         OutputStream sslOS = sslSocket.getOutputStream();
128 
129         System.out.println("Server read: " + sslIS.read());
130         sslOS.write(85);
131         sslOS.flush();
132 
133         sslSocket.close();
134     }
135 
acceptNormally0()136     private Socket acceptNormally0() throws Exception {
137 
138         SSLServerSocketFactory sslssf =
139             (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
140 
141         System.out.println("Server: Will call createServerSocket(int)");
142         ServerSocket sslServerSocket = sslssf.createServerSocket(0);
143         serverPort = sslServerSocket.getLocalPort();
144 
145         System.out.println("Server: Will accept on SSL server socket...");
146 
147         serverReady = true;
148 
149         Socket sslSocket = sslServerSocket.accept();
150         sslServerSocket.close();
151         return sslSocket;
152     }
153 
acceptNormally1()154     private Socket acceptNormally1() throws Exception {
155 
156         SSLServerSocketFactory sslssf =
157             (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
158 
159         System.out.println("Server: Will call createServerSocket(int, int)");
160         ServerSocket sslServerSocket = sslssf.createServerSocket(0,
161                                                                  1);
162         serverPort = sslServerSocket.getLocalPort();
163 
164         System.out.println("Server: Will accept on SSL server socket...");
165 
166         serverReady = true;
167 
168         Socket sslSocket = sslServerSocket.accept();
169         sslServerSocket.close();
170         return sslSocket;
171     }
172 
acceptNormally2()173     private Socket acceptNormally2() throws Exception {
174 
175         SSLServerSocketFactory sslssf =
176             (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
177 
178         System.out.println("Server: Will call createServerSocket(int, " +
179                            " int, InetAddress)");
180         ServerSocket sslServerSocket = sslssf.createServerSocket(0,
181                                          1,
182                                          InetAddress.getByName("localhost"));
183         serverPort = sslServerSocket.getLocalPort();
184 
185         System.out.println("Server: Will accept on SSL server socket...");
186 
187         serverReady = true;
188 
189         Socket sslSocket = sslServerSocket.accept();
190         sslServerSocket.close();
191         return sslSocket;
192     }
193 
acceptUnbound()194     private Socket acceptUnbound() throws Exception {
195 
196         SSLServerSocketFactory sslssf =
197             (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
198 
199         System.out.println("Server: Will create unbound SSL server socket...");
200 
201         ServerSocket sslServerSocket = sslssf.createServerSocket();
202 
203         if (sslServerSocket.isBound())
204             throw new Exception("Server socket is already bound!");
205 
206         sslServerSocket.bind(new java.net.InetSocketAddress(0));
207 
208         if (!sslServerSocket.isBound())
209             throw new Exception("Server socket is not bound!");
210 
211         serverPort = sslServerSocket.getLocalPort();
212         System.out.println("Server: Bound SSL server socket to port " +
213                 serverPort + "...");
214 
215         serverReady = true;
216 
217         System.out.println("Server: Will accept on SSL server socket...");
218         Socket sslSocket = sslServerSocket.accept();
219         sslServerSocket.close();
220         return sslSocket;
221     }
222 
acceptLayered()223     private Socket acceptLayered() throws Exception {
224 
225         SSLSocketFactory sslsf =
226             (SSLSocketFactory) SSLSocketFactory.getDefault();
227 
228         ServerSocket ss = new ServerSocket(0);
229         serverPort = ss.getLocalPort();
230         System.out.println("Server: Created normal server socket bound"
231                 + " to port " + serverPort + "...");
232         System.out.println("Server: Will accept on server socket...");
233         serverReady = true;
234         Socket s = ss.accept();
235         ss.close();
236         System.out.println("Server: Will layer SSLSocket on top of" +
237                            " server socket...");
238         SSLSocket sslSocket =
239             (SSLSocket) sslsf.createSocket(s,
240                                             s.getInetAddress().getHostName(),
241                                             s.getPort(),
242                                             true);
243         sslSocket.setUseClientMode(false);
244 
245         return sslSocket;
246     }
247 
248     /*
249      * Connects to a server and exchanges an int with it. The
250      * connection can be established in one of three different ways:
251      *    1. As a regular SSL socket
252      *    2. As an SSL socket that is first unconnected
253      *    3. As an SSL socket layered over a regular TCP/IP socket
254      *
255      * If the server prematurely exits, serverReady will be set to true
256      * to avoid infinite hangs.
257      */
doClientSide(int style)258     void doClientSide(int style) throws Exception {
259 
260         Socket sslSocket = null;
261 
262         /*
263          * Wait for server to get started.
264          */
265         while (!serverReady) {
266             Thread.sleep(50);
267         }
268 
269         // Change the for loop in SocketCreation() if you add more cases
270         switch (style) {
271         case 0:
272             sslSocket = connectNormally0();
273             break;
274         case 1:
275             sslSocket = connectNormally1();
276             break;
277         case 2:
278             sslSocket = connectNormally2();
279             break;
280         case 3:
281             sslSocket = connectNormally3();
282             break;
283         case 4:
284             sslSocket = connectUnconnected();
285             break;
286         case 5:
287             sslSocket = connectLayered();
288             break;
289         default:
290             throw new Exception("Incorrectly written test for client side!");
291         }
292 
293         InputStream sslIS = sslSocket.getInputStream();
294         OutputStream sslOS = sslSocket.getOutputStream();
295 
296         sslOS.write(280);
297         sslOS.flush();
298         System.out.println("Client read: " + sslIS.read());
299 
300         sslSocket.close();
301     }
302 
connectNormally0()303     private Socket connectNormally0() throws Exception {
304 
305         SSLSocketFactory sslsf =
306             (SSLSocketFactory) SSLSocketFactory.getDefault();
307 
308         System.out.println("Client: Will call createSocket(String, int)");
309         return sslsf.createSocket("localhost", serverPort);
310     }
311 
connectNormally1()312     private Socket connectNormally1() throws Exception {
313 
314         SSLSocketFactory sslsf =
315             (SSLSocketFactory) SSLSocketFactory.getDefault();
316 
317         System.out.println("Client: Will call createSocket(InetAddress, int)");
318         return sslsf.createSocket(InetAddress.getByName("localhost"),
319                                   serverPort);
320     }
321 
connectNormally2()322     private Socket connectNormally2() throws Exception {
323 
324         SSLSocketFactory sslsf =
325             (SSLSocketFactory) SSLSocketFactory.getDefault();
326 
327         System.out.println("Client: Will call createSocket(String," +
328                            " int, InetAddress, int)");
329         return sslsf.createSocket("localhost", serverPort,
330                                   InetAddress.getByName("localhost"),
331                                   0);
332     }
333 
connectNormally3()334     private Socket connectNormally3() throws Exception {
335 
336         SSLSocketFactory sslsf =
337             (SSLSocketFactory) SSLSocketFactory.getDefault();
338 
339         System.out.println("Client: Will call createSocket(InetAddress," +
340                            " int, InetAddress, int)");
341         return sslsf.createSocket(InetAddress.getByName("localhost"),
342                                   serverPort,
343                                   InetAddress.getByName("localhost"),
344                                   0);
345     }
346 
connectUnconnected()347     private Socket connectUnconnected() throws Exception {
348 
349         SSLSocketFactory sslsf =
350             (SSLSocketFactory) SSLSocketFactory.getDefault();
351 
352         System.out.println("Client: Will call createSocket()");
353         Socket sslSocket = sslsf.createSocket();
354 
355         if (sslSocket.isConnected())
356             throw new Exception("Client socket is already connected!");
357 
358         System.out.println("Client: Will connect to server on port " +
359                            serverPort + "...");
360         sslSocket.connect(new java.net.InetSocketAddress("localhost",
361                                                          serverPort));
362 
363         if (!sslSocket.isConnected())
364             throw new Exception("Client socket is not connected!");
365 
366         return sslSocket;
367     }
368 
connectLayered()369     private Socket connectLayered() throws Exception {
370 
371         SSLSocketFactory sslsf =
372             (SSLSocketFactory) SSLSocketFactory.getDefault();
373 
374         System.out.println("Client: Will connect to server on port " +
375                            serverPort + "...");
376         Socket s = new Socket("localhost", serverPort);
377 
378         System.out.println("Client: Will layer SSL socket on top...");
379         return sslsf.createSocket(s, "localhost", serverPort, true);
380 
381     }
382 
383     /*
384      * =============================================================
385      * The remainder is just support stuff
386      */
387 
388     // use any free port by default
389     volatile int serverPort = 0;
390 
391     volatile Exception serverException = null;
392     volatile Exception clientException = null;
393 
main(String[] args)394     public static void main(String[] args) throws Exception {
395         String keyFilename =
396             System.getProperty("test.src", "./") + "/" + pathToStores +
397                 "/" + keyStoreFile;
398         String trustFilename =
399             System.getProperty("test.src", "./") + "/" + pathToStores +
400                 "/" + trustStoreFile;
401 
402         System.setProperty("javax.net.ssl.keyStore", keyFilename);
403         System.setProperty("javax.net.ssl.keyStorePassword", passwd);
404         System.setProperty("javax.net.ssl.trustStore", trustFilename);
405         System.setProperty("javax.net.ssl.trustStorePassword", passwd);
406 
407         if (debug)
408             System.setProperty("javax.net.debug", "all");
409 
410         /*
411          * Start the tests.
412          */
413         new SocketCreation();
414     }
415 
416     Thread clientThread = null;
417     Thread serverThread = null;
418 
419     /*
420      * Primary constructor, used to drive remainder of the test.
421      *
422      * Performs a loop where each iteration establishes one client-server
423      * connection using a particular way of socket creation. There are
424      * three ways in each side can create a socket:
425      *   1. Normal (The client has 4 variations of this and the server 3)
426      *   2. Unbound/Unconnected
427      *   3. Layered
428      * Each side goes through all three of them giving us a total of 5x6
429      * possibilites.
430      */
SocketCreation()431     SocketCreation() throws Exception {
432 
433         for (int serverStyle = 0; serverStyle < 5; serverStyle++) {
434             System.out.println("-------------------------------------");
435             for (int clientStyle = 0; clientStyle < 6; clientStyle++) {
436 
437                 serverReady = false;
438 
439                 startServer(separateServerThread, serverStyle);
440                 startClient(!separateServerThread, clientStyle);
441 
442                 /*
443                  * Wait for other side to close down.
444                  */
445                 if (separateServerThread) {
446                     serverThread.join();
447                 } else {
448                     clientThread.join();
449                 }
450 
451                 /*
452                  * When we get here, the test is pretty much over.
453                  *
454                  * If the main thread excepted, that propagates back
455                  * immediately.  If the other thread threw an exception, we
456                  * should report back.
457                  */
458                 if (serverException != null)
459                     throw serverException;
460                 if (clientException != null)
461                     throw clientException;
462                 System.out.println();
463             }
464         }
465     }
466 
startServer(boolean newThread, final int style)467     void startServer(boolean newThread, final int style) throws Exception {
468         if (newThread) {
469             serverThread = new Thread() {
470                 public void run() {
471                     try {
472                         doServerSide(style);
473                     } catch (Exception e) {
474                         /*
475                          * Our server thread just died.
476                          *
477                          * Release the client, if not active already...
478                          */
479                         System.err.println("Server died..." + e);
480                         serverReady = true;
481                         serverException = e;
482                     }
483                 }
484             };
485             serverThread.start();
486         } else {
487             doServerSide(style);
488         }
489     }
490 
startClient(boolean newThread, final int style)491     void startClient(boolean newThread, final int style) throws Exception {
492         if (newThread) {
493             clientThread = new Thread() {
494                 public void run() {
495                     try {
496                         doClientSide(style);
497                     } catch (Exception e) {
498                         /*
499                          * Our client thread just died.
500                          */
501                         System.err.println("Client died...");
502                         clientException = e;
503                     }
504                 }
505             };
506             clientThread.start();
507         } else {
508             doClientSide(style);
509         }
510     }
511 }
512