1 /*
   2  * Copyright (c) 2018, 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 // Please run in othervm mode.  SunJSSE does not support dynamic system
  26 // properties, no way to re-use system properties in samevm/agentvm mode.
  27 //
  28 
  29 /*
  30  * @test
  31  * @bug 8214339
  32  * @summary SSLSocketImpl erroneously wraps SocketException
  33  * @library /javax/net/ssl/templates
  34  * @run main/othervm SSLExceptionForIOIssue
  35  */
  36 
  37 import javax.net.ssl.*;
  38 import java.io.*;
  39 import java.net.*;
  40 
  41 public class SSLExceptionForIOIssue implements SSLContextTemplate {
  42 
  43     public static void main(String[] args) throws Exception {
  44         System.err.println("===================================");
  45         new SSLExceptionForIOIssue().test();
  46     }
  47 
  48     private void test() throws Exception {
  49         SSLServerSocket listenSocket = null;
  50         SSLSocket serverSocket = null;
  51         ClientSocket clientSocket = null;
  52         try {
  53             SSLServerSocketFactory serversocketfactory =
  54                     createServerSSLContext().getServerSocketFactory();
  55             listenSocket =
  56                     (SSLServerSocket)serversocketfactory.createServerSocket(0);
  57             listenSocket.setNeedClientAuth(false);
  58             listenSocket.setEnableSessionCreation(true);
  59             listenSocket.setUseClientMode(false);
  60 
  61             System.err.println("Starting client");
  62             clientSocket = new ClientSocket(listenSocket.getLocalPort());
  63             clientSocket.start();
  64 
  65             System.err.println("Accepting client requests");
  66             serverSocket = (SSLSocket)listenSocket.accept();
  67 
  68             if (!clientSocket.isDone) {
  69                 System.err.println("Waiting 3 seconds for client ");
  70                 Thread.sleep(3000);
  71             }
  72 
  73             System.err.println("Sending data to client ...");
  74             String serverData = "Hi, I am server";
  75             BufferedWriter os = new BufferedWriter(
  76                     new OutputStreamWriter(serverSocket.getOutputStream()));
  77             os.write(serverData, 0, serverData.length());
  78             os.newLine();
  79             os.flush();
  80         } catch (SSLProtocolException | SSLHandshakeException sslhe) {
  81             throw sslhe;
  82         } catch (SSLException ssle) {
  83             // the expected exception, ignore it
  84             System.err.println("server exception: " + ssle);
  85         } finally {
  86             if (listenSocket != null) {
  87                 listenSocket.close();
  88             }
  89 
  90             if (serverSocket != null) {
  91                 serverSocket.close();
  92             }
  93         }
  94 
  95         if (clientSocket != null && clientSocket.clientException != null) {
  96             throw clientSocket.clientException;
  97         }
  98     }
  99 
 100 
 101 
 102     private class ClientSocket extends Thread{
 103         boolean isDone = false;
 104         int serverPort = 0;
 105         Exception clientException;
 106 
 107         public ClientSocket(int serverPort) {
 108             this.serverPort = serverPort;
 109         }
 110 
 111         @Override
 112         public void run() {
 113             SSLSocket clientSocket = null;
 114             String clientData = "Hi, I am client";
 115             try {
 116                 System.err.println(
 117                         "Connecting to server at port " + serverPort);
 118                 SSLSocketFactory sslSocketFactory =
 119                         createClientSSLContext().getSocketFactory();
 120                 clientSocket = (SSLSocket)sslSocketFactory.createSocket(
 121                         InetAddress.getLocalHost(), serverPort);
 122                 clientSocket.setSoLinger(true, 3);
 123                 clientSocket.setSoTimeout(100);
 124 
 125 
 126                 System.err.println("Sending data to server ...");
 127 
 128                 BufferedWriter os = new BufferedWriter(
 129                         new OutputStreamWriter(clientSocket.getOutputStream()));
 130                 os.write(clientData, 0, clientData.length());
 131                 os.newLine();
 132                 os.flush();
 133 
 134                 System.err.println("Reading data from server");
 135                 BufferedReader is = new BufferedReader(
 136                         new InputStreamReader(clientSocket.getInputStream()));
 137                 String data = is.readLine();
 138                 System.err.println("Received Data from server: " + data);
 139             } catch (SSLProtocolException | SSLHandshakeException sslhe) {
 140                 clientException = sslhe;
 141                 System.err.println("unexpected client exception: " + sslhe);
 142             } catch (SSLException | SocketTimeoutException ssle) {
 143                 // the expected exception, ignore it
 144                 System.err.println("expected client exception: " + ssle);
 145             } catch (Exception e) {
 146                 clientException = e;
 147                 System.err.println("unexpected client exception: " + e);
 148             } finally {
 149                 if (clientSocket != null) {
 150                     try {
 151                         clientSocket.close();
 152                         System.err.println("client socket closed");
 153                     } catch (IOException ioe) {
 154                         clientException = ioe;
 155                     }
 156                 }
 157 
 158                 isDone = true;
 159             }
 160         }
 161     }
 162 }