1/*
2 * Copyright (c) 2001, 2013, 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// SunJSSE does not support dynamic system properties, no way to re-use
26// system properties in samevm/agentvm mode.
27//
28
29/*
30 * @test
31 * @bug 4361124 4325806
32 * @summary SSLServerSocket isn't throwing exceptions when negotiations are
33 *      failing & java.net.SocketException: occures in Auth and clientmode
34 * @run main/othervm SSLSocketImplThrowsWrongExceptions
35 * @author Brad Wetmore
36 */
37
38import java.io.*;
39import java.net.*;
40import javax.net.ssl.*;
41
42public class SSLSocketImplThrowsWrongExceptions {
43
44    /*
45     * =============================================================
46     * Set the various variables needed for the tests, then
47     * specify what tests to run on each side.
48     */
49
50    /*
51     * Should we run the client or server in a separate thread?
52     * Both sides can throw exceptions, but do you have a preference
53     * as to which side should be the main thread.
54     */
55    static boolean separateServerThread = true;
56
57    /*
58     * Where do we find the keystores?
59     */
60    static String pathToStores = "../../../../javax/net/ssl/etc";
61    static String keyStoreFile = "keystore";
62    static String passwd = "passphrase";
63
64    /*
65     * Is the server ready to serve?
66     */
67    volatile static boolean serverReady = false;
68
69    /*
70     * Turn on SSL debugging?
71     */
72    static boolean debug = false;
73
74
75    /*
76     * Define the server side of the test.
77     */
78    void doServerSide() throws Exception {
79        System.out.println("starting Server");
80        SSLServerSocketFactory sslssf =
81            (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
82        SSLServerSocket sslServerSocket =
83            (SSLServerSocket) sslssf.createServerSocket(serverPort);
84        serverPort = sslServerSocket.getLocalPort();
85        System.out.println("got server socket");
86
87        /*
88         * Signal Client, we're ready for his connect.
89         */
90        serverReady = true;
91
92        try {
93            System.out.println("Server socket accepting...");
94            SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
95            System.out.println("Server starting handshake");
96            sslSocket.startHandshake();
97            throw new Exception("Handshake was successful");
98        } catch (SSLException e) {
99            /*
100             * Caught the right Exeption.  Swallow it.
101             */
102            System.out.println("Server reported the right exception");
103            System.out.println(e.toString());
104        } catch (Exception e) {
105            /*
106             * Caught the wrong exception.  Rethrow it.
107             */
108            System.out.println("Server reported the wrong exception");
109            throw e;
110        }
111
112    }
113
114    /*
115     * Define the client side of the test.
116     */
117    void doClientSide() throws Exception {
118
119        System.out.println("    Client starting");
120
121        /*
122         * Wait for server to get started.
123         */
124        while (!serverReady) {
125            Thread.sleep(50);
126        }
127
128        SSLSocketFactory sslsf =
129            (SSLSocketFactory) SSLSocketFactory.getDefault();
130        try {
131            System.out.println("        Client creating socket");
132            SSLSocket sslSocket = (SSLSocket)
133                sslsf.createSocket("localhost", serverPort);
134            System.out.println("        Client starting handshake");
135            sslSocket.startHandshake();
136            throw new Exception("Handshake was successful");
137        } catch (SSLException e) {
138            /*
139             * Caught the right Exception.  Swallow it.
140             */
141             System.out.println("       Client reported correct exception");
142             System.out.println("       " + e.toString());
143        } catch (Exception e) {
144            /*
145             * Caught the wrong exception.  Rethrow it.
146             */
147            System.out.println("        Client reported the wrong exception");
148            throw e;
149        }
150    }
151
152    /*
153     * =============================================================
154     * The remainder is just support stuff
155     */
156
157    // use any free port by default
158    volatile int serverPort = 0;
159
160    volatile Exception serverException = null;
161    volatile Exception clientException = null;
162
163    public static void main(String[] args) throws Exception {
164        String keyFilename =
165            System.getProperty("test.src", "./") + "/" + pathToStores +
166                "/" + keyStoreFile;
167
168        System.setProperty("javax.net.ssl.keyStore", keyFilename);
169        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
170
171        if (debug)
172            System.setProperty("javax.net.debug", "all");
173
174        /*
175         * Start the tests.
176         */
177        new SSLSocketImplThrowsWrongExceptions();
178    }
179
180    Thread clientThread = null;
181    Thread serverThread = null;
182
183    /*
184     * Primary constructor, used to drive remainder of the test.
185     *
186     * Fork off the other side, then do your work.
187     */
188    SSLSocketImplThrowsWrongExceptions () throws Exception {
189        Exception startException = null;
190        try {
191            if (separateServerThread) {
192                startServer(true);
193                startClient(false);
194            } else {
195                startClient(true);
196                startServer(false);
197            }
198        } catch (Exception e) {
199            startException = e;
200        }
201
202        /*
203         * Wait for other side to close down.
204         */
205        if (separateServerThread) {
206            if (serverThread != null) {
207                serverThread.join();
208            }
209        } else {
210            if (clientThread != null) {
211                clientThread.join();
212            }
213        }
214
215        /*
216         * When we get here, the test is pretty much over.
217         * Which side threw the error?
218         */
219        Exception local;
220        Exception remote;
221
222        if (separateServerThread) {
223            remote = serverException;
224            local = clientException;
225        } else {
226            remote = clientException;
227            local = serverException;
228        }
229
230        Exception exception = null;
231
232        /*
233         * Check various exception conditions.
234         */
235        if ((local != null) && (remote != null)) {
236            // If both failed, return the curthread's exception.
237            local.initCause(remote);
238            exception = local;
239        } else if (local != null) {
240            exception = local;
241        } else if (remote != null) {
242            exception = remote;
243        } else if (startException != null) {
244            exception = startException;
245        }
246
247        /*
248         * If there was an exception *AND* a startException,
249         * output it.
250         */
251        if (exception != null) {
252            if (exception != startException && startException != null) {
253                exception.addSuppressed(startException);
254            }
255            throw exception;
256        }
257
258        // Fall-through: no exception to throw!
259    }
260
261    void startServer(boolean newThread) throws Exception {
262        if (newThread) {
263            serverThread = new Thread() {
264                public void run() {
265                    try {
266                        doServerSide();
267                    } catch (Exception e) {
268                        /*
269                         * Our server thread just died.
270                         *
271                         * Release the client, if not active already...
272                         */
273                        System.err.println("Server died...");
274                        serverReady = true;
275                        serverException = e;
276                    }
277                }
278            };
279            serverThread.start();
280        } else {
281            try {
282                doServerSide();
283            } catch (Exception e) {
284                serverException = e;
285            } finally {
286                serverReady = true;
287            }
288        }
289    }
290
291    void startClient(boolean newThread) throws Exception {
292        if (newThread) {
293            clientThread = new Thread() {
294                public void run() {
295                    try {
296                        doClientSide();
297                    } catch (Exception e) {
298                        /*
299                         * Our client thread just died.
300                         */
301                        System.err.println("Client died...");
302                        clientException = e;
303                    }
304                }
305            };
306            clientThread.start();
307        } else {
308            try {
309                doClientSide();
310            } catch (Exception e) {
311                clientException = e;
312            }
313        }
314    }
315}
316