Path: blob/master/test/jdk/javax/net/ssl/templates/TLSBase.java
41152 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import javax.net.ssl.SSLContext;24import javax.net.ssl.SSLServerSocket;25import javax.net.ssl.SSLServerSocketFactory;26import javax.net.ssl.SSLSession;27import javax.net.ssl.SSLSocket;28import java.io.BufferedReader;29import java.io.IOException;30import java.io.InputStreamReader;31import java.io.OutputStreamWriter;32import java.io.PrintWriter;33import java.net.InetSocketAddress;34import java.util.Arrays;35import java.util.concurrent.ConcurrentHashMap;3637/**38* This is a base setup for creating a server and clients. All clients will39* connect to the server on construction. The server constructor must be run40* first. The idea is for the test code to be minimal as possible without41* this library class being complicated.42*43* Server.done() must be called or the server will never exit and hang the test.44*45* After construction, reading and writing are allowed from either side,46* or a combination write/read from both sides for verifying text.47*48* The TLSBase.Server and TLSBase.Client classes are to allow full access to49* the SSLSession for verifying data.50*51* See SSLSession/CheckSessionContext.java for an example52*53*/5455abstract public class TLSBase {56static String pathToStores = "../etc";57static String keyStoreFile = "keystore";58static String trustStoreFile = "truststore";59static String passwd = "passphrase";6061SSLContext sslContext;62// Server's port63static int serverPort;64// Name shown during read and write ops65String name;6667TLSBase() {68String keyFilename =69System.getProperty("test.src", "./") + "/" + pathToStores +70"/" + keyStoreFile;71String trustFilename =72System.getProperty("test.src", "./") + "/" + pathToStores +73"/" + trustStoreFile;74System.setProperty("javax.net.ssl.keyStore", keyFilename);75System.setProperty("javax.net.ssl.keyStorePassword", passwd);76System.setProperty("javax.net.ssl.trustStore", trustFilename);77System.setProperty("javax.net.ssl.trustStorePassword", passwd);78}7980// Base read operation81byte[] read(SSLSocket sock) {82try {83BufferedReader reader = new BufferedReader(84new InputStreamReader(sock.getInputStream()));85String s = reader.readLine();86System.err.println("(read) " + name + ": " + s);87return s.getBytes();88} catch (Exception e) {89e.printStackTrace();90}91return null;92}9394// Base write operation95public void write(SSLSocket sock, byte[] data) {96try {97PrintWriter out = new PrintWriter(98new OutputStreamWriter(sock.getOutputStream()));99out.println(new String(data));100out.flush();101System.err.println("(write)" + name + ": " + new String(data));102} catch (Exception e) {103e.printStackTrace();104}105}106107/**108* Server constructor must be called before any client operation so the109* tls server is ready. There should be no timing problems as the110*/111static class Server extends TLSBase {112SSLServerSocketFactory fac;113SSLServerSocket ssock;114// Clients sockets are kept in a hash table with the port as the key.115ConcurrentHashMap<Integer, SSLSocket> clientMap =116new ConcurrentHashMap<>();117boolean exit = false;118Thread t;119120Server() {121super();122name = "server";123try {124sslContext = SSLContext.getDefault();125fac = sslContext.getServerSocketFactory();126ssock = (SSLServerSocket) fac.createServerSocket(0);127serverPort = ssock.getLocalPort();128} catch (Exception e) {129System.err.println(e.getMessage());130e.printStackTrace();131}132133// Thread to allow multiple clients to connect134t = new Thread(() -> {135try {136while (true) {137System.err.println("Server ready on port " +138serverPort);139SSLSocket c = (SSLSocket)ssock.accept();140clientMap.put(c.getPort(), c);141try {142write(c, read(c));143} catch (Exception e) {144e.printStackTrace();145}146}147} catch (Exception ex) {148System.err.println("Server Down");149ex.printStackTrace();150}151});152t.start();153}154155// Exit test to quit the test. This must be called at the end of the156// test or the test will never end.157void done() {158try {159t.interrupt();160ssock.close();161} catch (Exception e) {162System.err.println(e.getMessage());163e.printStackTrace();164}165}166167// Read from the client168byte[] read(Client client) {169SSLSocket s = clientMap.get(Integer.valueOf(client.getPort()));170if (s == null) {171System.err.println("No socket found, port " + client.getPort());172}173return read(s);174}175176// Write to the client177void write(Client client, byte[] data) {178write(clientMap.get(client.getPort()), data);179}180181// Server writes to the client, then reads from the client.182// Return true if the read & write data match, false if not.183boolean writeRead(Client client, String s) {184write(client, s.getBytes());185return (Arrays.compare(s.getBytes(), client.read()) == 0);186}187188// Get the SSLSession from the server side socket189SSLSession getSession(Client c) {190SSLSocket s = clientMap.get(Integer.valueOf(c.getPort()));191return s.getSession();192}193194// Close client socket195void close(Client c) throws IOException {196SSLSocket s = clientMap.get(Integer.valueOf(c.getPort()));197s.close();198}199}200201/**202* Client side will establish a connection from the constructor and wait.203* It must be run after the Server constructor is called.204*/205static class Client extends TLSBase {206SSLSocket sock;207208Client() {209super();210try {211sslContext = SSLContext.getDefault();212} catch (Exception e) {213System.err.println(e.getMessage());214e.printStackTrace();215}216connect();217}218219// Connect to server. Maybe runnable in the future220public SSLSocket connect() {221try {222sslContext = SSLContext.getDefault();223sock = (SSLSocket)sslContext.getSocketFactory().createSocket();224sock.connect(new InetSocketAddress("localhost", serverPort));225System.err.println("Client connected using port " +226sock.getLocalPort());227name = "client(" + sock.toString() + ")";228write("Hello");229read();230} catch (Exception ex) {231ex.printStackTrace();232}233return sock;234}235236// Read from the client socket237byte[] read() {238return read(sock);239}240241// Write to the client socket242void write(byte[] data) {243write(sock, data);244}245void write(String s) {246write(sock, s.getBytes());247}248249// Client writes to the server, then reads from the server.250// Return true if the read & write data match, false if not.251boolean writeRead(Server server, String s) {252write(s.getBytes());253return (Arrays.compare(s.getBytes(), server.read(this)) == 0);254}255256// Get port from the socket257int getPort() {258return sock.getLocalPort();259}260261// Close socket262void close() throws IOException {263sock.close();264}265}266}267268269