1/*
2 * Copyright (c) 2003, 2011, 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 4919147
27 * @summary Support for token-based KeyStores
28 * @run main/othervm GoodProvider
29 *
30 *     SunJSSE does not support dynamic system properties, no way to re-use
31 *     system properties in samevm/agentvm mode.
32 */
33
34import java.io.*;
35import java.net.*;
36import javax.net.ssl.*;
37
38public class GoodProvider {
39
40    /*
41     * =============================================================
42     * Set the various variables needed for the tests, then
43     * specify what tests to run on each side.
44     */
45
46    /*
47     * Should we run the client or server in a separate thread?
48     * Both sides can throw exceptions, but do you have a preference
49     * as to which side should be the main thread.
50     */
51    static boolean separateServerThread = false;
52
53    /*
54     * Where do we find the keystores?
55     */
56    static String pathToStores = "../../../../javax/net/ssl/etc";
57    static String keyStoreFile = "keystore";
58    static String trustStoreFile = "truststore";
59    static String passwd = "passphrase";
60
61    /*
62     * Is the server ready to serve?
63     */
64    volatile static boolean serverReady = false;
65
66    /*
67     * Turn on SSL debugging?
68     */
69    static boolean debug = false;
70
71    /*
72     * If the client or server is doing some kind of object creation
73     * that the other side depends on, and that thread prematurely
74     * exits, you may experience a hang.  The test harness will
75     * terminate all hung threads after its timeout has expired,
76     * currently 3 minutes by default, but you might try to be
77     * smart about it....
78     */
79
80    /*
81     * Define the server side of the test.
82     *
83     * If the server prematurely exits, serverReady will be set to true
84     * to avoid infinite hangs.
85     */
86    void doServerSide() throws Exception {
87        SSLServerSocketFactory sslssf =
88            (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
89        SSLServerSocket sslServerSocket =
90            (SSLServerSocket) sslssf.createServerSocket(serverPort);
91
92        serverPort = sslServerSocket.getLocalPort();
93
94        /*
95         * Signal Client, we're ready for his connect.
96         */
97        serverReady = true;
98
99        SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
100        InputStream sslIS = sslSocket.getInputStream();
101        OutputStream sslOS = sslSocket.getOutputStream();
102
103        sslIS.read();
104        sslOS.write(85);
105        sslOS.flush();
106
107        sslSocket.close();
108    }
109
110    /*
111     * Define the client side of the test.
112     *
113     * If the server prematurely exits, serverReady will be set to true
114     * to avoid infinite hangs.
115     */
116    void doClientSide() throws Exception {
117
118        /*
119         * Wait for server to get started.
120         */
121        while (!serverReady) {
122            Thread.sleep(50);
123        }
124
125        SSLSocketFactory sslsf =
126            (SSLSocketFactory) SSLSocketFactory.getDefault();
127        SSLSocket sslSocket = (SSLSocket)
128            sslsf.createSocket("localhost", serverPort);
129
130        InputStream sslIS = sslSocket.getInputStream();
131        OutputStream sslOS = sslSocket.getOutputStream();
132
133        sslOS.write(280);
134        sslOS.flush();
135        sslIS.read();
136
137        sslSocket.close();
138    }
139
140    /*
141     * =============================================================
142     * The remainder is just support stuff
143     */
144
145    // use any free port by default
146    volatile int serverPort = 0;
147
148    volatile Exception serverException = null;
149    volatile Exception clientException = null;
150
151    public static void main(String[] args) throws Exception {
152        String keyFilename =
153            System.getProperty("test.src", "./") + "/" + pathToStores +
154                "/" + keyStoreFile;
155        String trustFilename =
156            System.getProperty("test.src", "./") + "/" + pathToStores +
157                "/" + trustStoreFile;
158
159        // first test a good provider name
160
161        System.setProperty("javax.net.ssl.keyStore", keyFilename);
162        System.setProperty("javax.net.ssl.keyStoreProvider", "SUN");
163        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
164        System.setProperty("javax.net.ssl.trustStore", trustFilename);
165        System.setProperty("javax.net.ssl.trustStoreProvider", "SUN");
166        System.setProperty("javax.net.ssl.trustStorePassword", passwd);
167
168        if (debug)
169            System.setProperty("javax.net.debug", "ssl,defaultctx");
170
171        new GoodProvider();
172    }
173
174    Thread clientThread = null;
175    Thread serverThread = null;
176
177    /*
178     * Primary constructor, used to drive remainder of the test.
179     *
180     * Fork off the other side, then do your work.
181     */
182    GoodProvider() throws Exception {
183        try {
184            if (separateServerThread) {
185                startServer(true);
186                startClient(false);
187            } else {
188                startClient(true);
189                startServer(false);
190            }
191        } catch (Exception e) {
192            //swallow for now.  Show later
193        }
194
195        /*
196         * Wait for other side to close down.
197         */
198        if (separateServerThread) {
199            serverThread.join();
200        } else {
201            clientThread.join();
202        }
203
204        /*
205         * When we get here, the test is pretty much over.
206         * Which side threw the error?
207         */
208        Exception local;
209        Exception remote;
210        String whichRemote;
211
212        if (separateServerThread) {
213            remote = serverException;
214            local = clientException;
215            whichRemote = "server";
216        } else {
217            remote = clientException;
218            local = serverException;
219            whichRemote = "client";
220        }
221
222        /*
223         * If both failed, return the curthread's exception, but also
224         * print the remote side Exception
225         */
226        if ((local != null) && (remote != null)) {
227            System.out.println(whichRemote + " also threw:");
228            remote.printStackTrace();
229            System.out.println();
230            throw local;
231        }
232
233        if (remote != null) {
234            throw remote;
235        }
236
237        if (local != null) {
238            throw local;
239        }
240    }
241
242    void startServer(boolean newThread) throws Exception {
243        if (newThread) {
244            serverThread = new Thread() {
245                public void run() {
246                    try {
247                        doServerSide();
248                    } catch (Exception e) {
249                        /*
250                         * Our server thread just died.
251                         *
252                         * Release the client, if not active already...
253                         */
254                        System.err.println("Server died...");
255                        serverReady = true;
256                        serverException = e;
257                    }
258                }
259            };
260            serverThread.start();
261        } else {
262            try {
263                doServerSide();
264            } catch (Exception e) {
265                serverException = e;
266            } finally {
267                serverReady = true;
268            }
269        }
270    }
271
272    void startClient(boolean newThread) throws Exception {
273        if (newThread) {
274            clientThread = new Thread() {
275                public void run() {
276                    try {
277                        doClientSide();
278                    } catch (Exception e) {
279                        /*
280                         * Our client thread just died.
281                         */
282                        System.err.println("Client died...");
283                        clientException = e;
284                    }
285                }
286            };
287            clientThread.start();
288        } else {
289            try {
290                doClientSide();
291            } catch (Exception e) {
292                clientException = e;
293            }
294        }
295    }
296}
297