1 /* 2 * Copyright (c) 2017, 2019, 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 import java.io.File; 25 import java.io.FileWriter; 26 import java.io.IOException; 27 import java.io.InputStream; 28 import java.io.OutputStream; 29 30 import javax.net.ssl.SSLContext; 31 import javax.net.ssl.SSLParameters; 32 import javax.net.ssl.SSLServerSocket; 33 import javax.net.ssl.SSLServerSocketFactory; 34 import javax.net.ssl.SSLSocket; 35 36 /* 37 * A simple SSL socket server. 38 */ 39 public class Server { 40 41 private final SSLServerSocket serverSocket; 42 43 public Server(SSLContext context, int port) throws Exception { 44 SSLServerSocketFactory serverFactory = context.getServerSocketFactory(); 45 serverSocket = (SSLServerSocket) serverFactory.createServerSocket(port); 46 serverSocket.setSoTimeout(Utils.TIMEOUT); 47 } 48 49 public Server(Cert[] certs, int port) throws Exception { 50 this(Utils.createSSLContext(certs), port); 51 } 52 53 public Server(Cert[] certs) throws Exception { 54 this(certs, 0); 55 } 56 57 private void setEnabledCipherSuites(String... cipherSuites) { 58 serverSocket.setEnabledCipherSuites(cipherSuites); 59 } 60 61 private void setEnabledProtocols(String... protocols) { 62 serverSocket.setEnabledProtocols(protocols); 63 } 64 65 private void setNeedClientAuth(boolean needClientAuth) { 66 serverSocket.setNeedClientAuth(needClientAuth); 67 } 68 69 private void setApplicationProtocols(String... protocols) { 70 SSLParameters params = serverSocket.getSSLParameters(); 71 params.setApplicationProtocols(protocols); 72 serverSocket.setSSLParameters(params); 73 } 74 75 public int getPort() { 76 return serverSocket.getLocalPort(); 77 } 78 79 private void accept() throws IOException { 80 SSLSocket socket = null; 81 try { 82 socket = (SSLSocket) serverSocket.accept(); 83 84 InputStream in = socket.getInputStream(); 85 in.read(); 86 87 OutputStream out = socket.getOutputStream(); 88 out.write('S'); 89 out.flush(); 90 } finally { 91 if (socket != null) { 92 socket.close(); 93 } 94 } 95 } 96 97 public void close() throws IOException { 98 serverSocket.close(); 99 } 100 101 public static void main(String[] args) throws IOException { 102 System.out.println("----- Server start -----"); 103 String protocol = System.getProperty(Utils.PROP_PROTOCOL); 104 String cipherSuite = System.getProperty(Utils.PROP_CIPHER_SUITE); 105 boolean clientAuth 106 = Utils.getBoolProperty(Utils.PROP_CLIENT_AUTH); 107 String appProtocols = System.getProperty(Utils.PROP_APP_PROTOCOLS); 108 boolean supportsALPN 109 = Utils.getBoolProperty(Utils.PROP_SUPPORTS_ALPN_ON_SERVER); 110 boolean negativeCase 111 = Utils.getBoolProperty(Utils.PROP_NEGATIVE_CASE_ON_SERVER); 112 113 System.out.println(Utils.join(Utils.PARAM_DELIMITER, 114 "ServerJDK=" + System.getProperty(Utils.PROP_SERVER_JDK), 115 "Protocol=" + protocol, 116 "CipherSuite=" + cipherSuite, 117 "ClientAuth=" + clientAuth, 118 "AppProtocols=" + appProtocols)); 119 120 Status status = Status.SUCCESS; 121 Server server = null; 122 try { 123 server = new Server(Cert.getCerts(CipherSuite.cipherSuite(cipherSuite))); 124 System.out.println("port=" + server.getPort()); 125 server.setNeedClientAuth(clientAuth); 126 server.setEnabledProtocols(protocol); 127 server.setEnabledCipherSuites(cipherSuite); 128 if (appProtocols != null) { 129 if (supportsALPN) { 130 server.setApplicationProtocols( 131 Utils.split(appProtocols, Utils.VALUE_DELIMITER)); 132 } else { 133 System.out.println( 134 "Ignored due to server doesn't support ALPN."); 135 } 136 } 137 138 savePort(server.getPort()); 139 server.accept(); 140 141 status = negativeCase ? Status.UNEXPECTED_SUCCESS : Status.SUCCESS; 142 } catch (Exception exception) { 143 status = Utils.handleException(exception, negativeCase); 144 } finally { 145 if (server != null) { 146 server.close(); 147 } 148 149 deletePortFile(); 150 } 151 152 System.out.println("STATUS: " + status); 153 System.out.println("----- Server end -----"); 154 } 155 156 private static void deletePortFile() { 157 File portFile = new File(Utils.PORT_LOG); 158 if (portFile.exists() && !portFile.delete()) { 159 throw new RuntimeException("Cannot delete port log"); 160 } 161 } 162 163 private static void savePort(int port) throws IOException { 164 FileWriter writer = null; 165 try { 166 writer = new FileWriter(new File(Utils.PORT_LOG)); 167 writer.write(port + ""); 168 } finally { 169 if (writer != null) { 170 writer.close(); 171 } 172 } 173 } 174 }