1/*
2 * Copyright (c) 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// SunJSSE does not support dynamic system properties, no way to re-use
26// system properties in samevm/agentvm mode.
27//
28
29import java.io.BufferedReader;
30import java.io.BufferedWriter;
31import java.io.IOException;
32import java.io.InputStreamReader;
33import java.io.OutputStreamWriter;
34
35import javax.net.ssl.SSLServerSocket;
36import javax.net.ssl.SSLServerSocketFactory;
37import javax.net.ssl.SSLSocket;
38import javax.net.ssl.SSLSocketFactory;
39
40/*
41 * @test
42 * @bug 8149169
43 * @summary Test for BufferOverflowException during read from SSLSocket when
44 *          large packet is coming from server after server initiated handshake
45 * @run main/othervm LargePacketAfterHandshakeTest
46 */
47public class LargePacketAfterHandshakeTest {
48    static String pathToStores = "../../../../javax/net/ssl/etc";
49    static String keyStoreFile = "keystore";
50    static String trustStoreFile = "truststore";
51    static String passwd = "passphrase";
52
53    volatile static int serverport = -1;
54    volatile static boolean serverReady = false;
55    volatile static boolean clientDone = false;
56    volatile static Exception serverException = null;
57
58    public static void runServer() {
59        try {
60            System.out.println("Server: Started server thread.");
61            SSLServerSocketFactory ssf =
62                (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
63            SSLServerSocket s = (SSLServerSocket)ssf.createServerSocket(0);
64            serverport = s.getLocalPort();
65            System.out.println("Server: Started, listening on port " +
66                    serverport + ".");
67            serverReady = true;
68            SSLSocket c = (SSLSocket)s.accept();
69            s.close();
70            System.out.println(
71                "Server: Accepted client connection and closed server socket.");
72            BufferedReader r = new BufferedReader(
73                    new InputStreamReader(c.getInputStream()));
74            BufferedWriter w = new BufferedWriter(
75                    new OutputStreamWriter(c.getOutputStream()));
76            String echostring = r.readLine();
77            System.out.println("Server: Read " + echostring.length() +
78                    " chars of input data.");
79            c.startHandshake();
80            System.out.println("Server: Kicked new handshake.");
81            w.write(echostring);
82            w.newLine();
83            w.flush();
84            System.out.println("Server: Echoed " + echostring.length() +
85                    " chars of input data.");
86            while (!clientDone) {
87                try {
88                    Thread.sleep(10);
89                } catch (InterruptedException e) {
90                    System.out.println("Server: Caught InterruptedException.");
91                }
92            }
93            r.close();
94            w.close();
95            c.close();
96            System.out.println(
97                    "Server: Closed streams and client socket, exiting.");
98        } catch (Exception e) {
99            System.out.println("Server: Caught Exception.");
100            e.printStackTrace();
101            serverReady = true;
102            serverException = e;
103        }
104    }
105
106    public static void runClient() throws IOException {
107        try {
108            SSLSocketFactory f =
109                    (SSLSocketFactory)SSLSocketFactory.getDefault();
110            System.out.println("Client: Initialized.");
111            while (!serverReady) {
112                try {
113                    Thread.sleep(10);
114                } catch (InterruptedException e) {
115                    System.out.println("Client: Caught InterruptedException.");
116                }
117            }
118            SSLSocket c = (SSLSocket)f.createSocket("localhost", serverport);
119            BufferedWriter w = new BufferedWriter(
120                    new OutputStreamWriter(c.getOutputStream()));
121            BufferedReader r = new BufferedReader(
122                    new InputStreamReader(c.getInputStream()));
123            System.out.println("Client: Connected.");
124            String echoPattern = "Otto";
125            StringBuilder echoBuilder =
126                    new StringBuilder(4500 + echoPattern.length());
127            while (echoBuilder.length() < 4500) {
128                echoBuilder.append(echoPattern);
129            }
130            String echostring = echoBuilder.toString();
131            w.write(echostring);
132            w.newLine();
133            w.flush();
134            System.out.println("Client: Sent " + echostring.length() +
135                    " chars of data.");
136            String echoresponse = r.readLine();
137            clientDone = true;
138            System.out.println("Client: Read " + echoresponse.length() +
139                    " chars of data.");
140            w.close();
141            r.close();
142            c.close();
143            System.out.println("Client: Closed streams and socket, exiting.");
144        } catch (IOException e) {
145            System.out.println("Client: Caught Exception.");
146            e.printStackTrace();
147            clientDone = true;
148            throw e;
149        }
150    }
151
152    public static void main(String[] args) throws Exception {
153        String keyFilename = System.getProperty("test.src", "./") + "/" +
154                pathToStores + "/" + keyStoreFile;
155        String trustFilename = System.getProperty("test.src", "./") + "/" +
156                pathToStores + "/" + trustStoreFile;
157
158        System.setProperty("javax.net.ssl.keyStore", keyFilename);
159        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
160        System.setProperty("javax.net.ssl.trustStore", trustFilename);
161        System.setProperty("javax.net.ssl.trustStorePassword", passwd);
162
163        Thread serverThread = new Thread() {
164            @Override
165            public void run() {
166                runServer();
167            }
168        };
169        serverThread.start();
170        runClient();
171        while (serverThread.isAlive()) {
172            try {
173                serverThread.join();
174            } catch (InterruptedException e) {
175                System.out.println("Main: Caught InterruptedException " +
176                        " waiting for server Thread.");
177            }
178        }
179        if (serverException != null) {
180            throw serverException;
181        }
182    }
183}
184