Path: blob/master/test/jdk/javax/net/ssl/TLSCommon/ConcurrentClientAccessTest.java
41152 views
/*1* Copyright (c) 2018, 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. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24import java.io.ByteArrayInputStream;25import java.io.IOException;26import java.io.InputStream;27import java.io.OutputStream;28import java.net.SocketException;29import java.net.SocketTimeoutException;30import java.security.KeyFactory;31import java.security.KeyStore;32import java.security.PrivateKey;33import java.security.Security;34import java.security.cert.Certificate;35import java.security.cert.CertificateFactory;36import java.security.spec.PKCS8EncodedKeySpec;37import java.util.Base64;38import java.util.concurrent.CountDownLatch;39import java.util.concurrent.ExecutorService;40import java.util.concurrent.Executors;41import javax.net.ssl.KeyManagerFactory;42import javax.net.ssl.SSLContext;43import javax.net.ssl.SSLServerSocket;44import javax.net.ssl.SSLServerSocketFactory;45import javax.net.ssl.SSLSocket;46import javax.net.ssl.SSLSocketFactory;47import javax.net.ssl.TrustManagerFactory;4849/*50* @test51* @bug 820849652* @summary Test to verify concurrent behavior of TLS.53* @run main/othervm ConcurrentClientAccessTest54*/55public class ConcurrentClientAccessTest {5657private static final int THREADS = 50;5859public static void main(String[] args) throws Exception {6061Security.setProperty("jdk.tls.disabledAlgorithms", "");62for (String tlsProtocol : new String[]{"TLSv1.3", "TLSv1.2",63"TLSv1.1", "TLSv1"}) {64System.out.printf("Protocol: %s%n", tlsProtocol);65CountDownLatch tillServerReady = new CountDownLatch(1);66Server server = new Server(tlsProtocol, tillServerReady);67server.start();6869// Wait till server is ready to accept connection.70tillServerReady.await();71CountDownLatch tillClientComplete = new CountDownLatch(THREADS);72ExecutorService executor = null;73try {74executor = newExecutorService();75// Run 50 TLS clients for concurrent access to TLS Port.76for (int count = 1; count <= THREADS; count++) {77Client client = new Client(tlsProtocol, server.port,78tillClientComplete);79executor.execute(client);80// If Client has any Exception indicates problem81if (client.exception != null) {82throw new RuntimeException(client.exception);83}84}85// Wait till all client thread complete execution86tillClientComplete.await();87System.out.println("All client processed successfully.");88} finally {89if (executor != null) {90executor.shutdown();91}92// Fail Safe: Shutdown the server93server.stopServer();94}95// If Sever has any Exception indicates problem96if (server.exception != null) {97throw new RuntimeException(server.exception);98}99System.out.println();100}101}102103public static class Server implements Runnable {104105private volatile int port = 0;106private final String tlsProtocol;107private final CountDownLatch tillServerReady;108private volatile Exception exception;109private SSLServerSocket sslServerSocket;110111public Server(String tlsProtocol, CountDownLatch tillServerReady) {112this.tlsProtocol = tlsProtocol;113this.tillServerReady = tillServerReady;114}115116public void start() {117118ExecutorService executor = null;119try {120executor = newExecutorService();121executor.execute(this);122} finally {123if (executor != null) {124executor.shutdown();125}126}127}128129/*130* Define the server side operation.131*/132void doServerSide() throws Exception {133134SSLContext ctx = getSSLContext(tlsProtocol);135SSLServerSocketFactory sslssf = ctx.getServerSocketFactory();136sslServerSocket = (SSLServerSocket) sslssf.createServerSocket(port);137port = sslServerSocket.getLocalPort();138System.out.println("Server listening on port: " + port);139sslServerSocket.setEnabledProtocols(new String[]{tlsProtocol});140// ServerSocket will timeout after waiting for 20 seconds141// before accepting a connection142sslServerSocket.setSoTimeout(20000);143// Signal Client, the server is ready to accept client request.144tillServerReady.countDown();145while (sslServerSocket != null && !sslServerSocket.isClosed()) {146try (SSLSocket sslSocket147= (SSLSocket) sslServerSocket.accept()) {148try (InputStream sslIS = sslSocket.getInputStream();149OutputStream sslOS150= sslSocket.getOutputStream();) {151sslIS.read();152sslOS.write(85);153sslOS.flush();154}155} catch (SocketTimeoutException | SocketException e) {156// Let the server exit157return;158}159}160}161162@Override163public void run() {164try {165doServerSide();166} catch (Exception e) {167this.exception = e;168} finally {169// Stop server170stopServer();171}172}173174public void stopServer() {175if (sslServerSocket != null && !sslServerSocket.isClosed()) {176System.out.println("Stopping Server.");177try {178sslServerSocket.close();179} catch (IOException e) {180throw new RuntimeException(e);181}182}183}184}185186/*187* Define the client side of the test.188*/189public static class Client implements Runnable {190191private final int serverPort;192private final String tlsProtocol;193private final CountDownLatch tillClientComplete;194private volatile Exception exception;195196public Client(String tlsProtocol, int serverPort,197CountDownLatch tillClientComplete) {198this.tlsProtocol = tlsProtocol;199this.serverPort = serverPort;200this.tillClientComplete = tillClientComplete;201}202203void doClientSide() throws Exception {204205SSLContext ctx = getSSLContext(this.tlsProtocol);206SSLSocketFactory sslsf = ctx.getSocketFactory();207try (SSLSocket sslSocket208= (SSLSocket) sslsf.createSocket("localhost", serverPort)) {209sslSocket.setEnabledProtocols(new String[]{this.tlsProtocol});210try (InputStream sslIS = sslSocket.getInputStream();211OutputStream sslOS = sslSocket.getOutputStream()) {212sslOS.write(86);213sslOS.flush();214sslIS.read();215}216} finally {217tillClientComplete.countDown();218}219}220221@Override222public void run() {223try {224doClientSide();225} catch (Exception e) {226// Print the exception for debug purpose.227e.printStackTrace(System.out);228this.exception = e;229}230}231}232233// Get the ssl context234protected static SSLContext getSSLContext(String tlsProtocol)235throws Exception {236237// Generate certificate from cert string238CertificateFactory cf = CertificateFactory.getInstance("X.509");239240// Create a key store241KeyStore ts = KeyStore.getInstance("PKCS12");242KeyStore ks = KeyStore.getInstance("PKCS12");243ts.load(null, null);244ks.load(null, null);245char passphrase[] = "passphrase".toCharArray();246247// Import the trusted cert248ts.setCertificateEntry("trusted-cert-"249+ KeyType.rsa_pkcs1_sha256.getKeyType(),250cf.generateCertificate(new ByteArrayInputStream(251KeyType.rsa_pkcs1_sha256.getTrustedCert().getBytes())));252253boolean hasKeyMaterials = KeyType.rsa_pkcs1_sha256.getEndCert() != null254&& KeyType.rsa_pkcs1_sha256.getPrivateKey() != null;255if (hasKeyMaterials) {256257// Generate the private key.258PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(259Base64.getMimeDecoder().decode(260KeyType.rsa_pkcs1_sha256.getPrivateKey()));261KeyFactory kf = KeyFactory.getInstance(262KeyType.rsa_pkcs1_sha256.getKeyType());263PrivateKey priKey = kf.generatePrivate(priKeySpec);264265// Generate certificate chain266Certificate keyCert = cf.generateCertificate(267new ByteArrayInputStream(268KeyType.rsa_pkcs1_sha256.getEndCert().getBytes()));269Certificate[] chain = new Certificate[]{keyCert};270271// Import the key entry.272ks.setKeyEntry("cert-" + KeyType.rsa_pkcs1_sha256.getKeyType(),273priKey, passphrase, chain);274}275276// Create SSL context277TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");278tmf.init(ts);279280SSLContext context = SSLContext.getInstance(tlsProtocol);281if (hasKeyMaterials) {282KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");283kmf.init(ks, passphrase);284context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);285} else {286context.init(null, tmf.getTrustManagers(), null);287}288return context;289}290291private static ExecutorService newExecutorService() {292return Executors.newCachedThreadPool((Runnable r) -> {293Thread t = Executors.defaultThreadFactory()294.newThread(r);295t.setDaemon(true);296return t;297});298}299}300301enum KeyType {302303rsa_pkcs1_sha256(304"RSA",305/**306* Signature Algorithm: sha256WithRSAEncryption307* Issuer: CN = localhost308* Validity Not Before: Jun 4 15:22:04 2018 GMT309* Not After: May 30 15:22:04 2038 GMT310* Subject: CN = localhost311* Public Key Algorithm: rsaEncryption312*/313"-----BEGIN CERTIFICATE-----\n"314+ "MIIDBjCCAe6gAwIBAgIUc8yTYekR2LuXkkCJYqWlS/pBMKIwDQYJKoZIhvcNAQEL\n"315+ "BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTE4MDYwNDE1MjIwNFoXDTM4MDUz\n"316+ "MDE1MjIwNFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF\n"317+ "AAOCAQ8AMIIBCgKCAQEA2jDPGMogc9dq2w5b+FHqbfaGPokRmyObiU8y/l/dqkM5\n"318+ "9IV+qj8VQUI4NtpdCTWr16812z4AjXrk5HIBrECfQbHPUcm1rme5YVZ0WxV0+Ufy\n"319+ "hDmrGwDLhkxGqc3hOhRrlF2wdXeUfjIzhvS9+S/401++t/jvq+cqFF1BHnzYOu+l\n"320+ "nbi/o95Oqo8MlwiRqg3xy3fNRfqXk7DWy+QT8s+Vc3Pcj1EW6K0iJJ23BVTdv6YT\n"321+ "Ja5IKiWL4XsLht3fWvZwF+PoYfKb+JYflt0rafpxg9xkowe7GnGh2SpV7bJaH/QN\n"322+ "3PTFEKQWgWHjWwjR171GOzSaEgaklvKde6+zNWeYKwIDAQABo1AwTjAdBgNVHQ4E\n"323+ "FgQUqCtGe8/Ky4O6pH7xeTUy9yrv4n0wHwYDVR0jBBgwFoAUqCtGe8/Ky4O6pH7x\n"324+ "eTUy9yrv4n0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAuqch30im\n"325+ "M09sARarbfK3OExqYK2xoyuUscgTqQNDpNL2gMdXY9e0lTmGVgw9pVYtNZPZRxem\n"326+ "jR5an2XegvG9qVU6vLENDwLCqZgsTb2gvmXngiG8NVcYd81GNqD228mkgBosNJku\n"327+ "6BR+C8zlURzsNEt657eVvIp9ObGomdAbWhpdqihBD180PP18DIBWopyfHfJtT5FA\n"328+ "U2kSPBp+P1EtdceW0zfwv3rF8hwRbnQBzuoYrZfn2PiMYaGUqOgbqUltCMD/Dp9G\n"329+ "xK0nfAXEwIqHWWnijGwAd6YrszMjBUcSGmlehdF+XZK6jHNlw64RB4WTfavr+rY0\n"330+ "dTe6g4o5GYr9nQ==\n"331+ "-----END CERTIFICATE-----\n",332//333// Private key.334//335"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDaMM8YyiBz12rb\n"336+ "Dlv4Uept9oY+iRGbI5uJTzL+X92qQzn0hX6qPxVBQjg22l0JNavXrzXbPgCNeuTk\n"337+ "cgGsQJ9Bsc9RybWuZ7lhVnRbFXT5R/KEOasbAMuGTEapzeE6FGuUXbB1d5R+MjOG\n"338+ "9L35L/jTX763+O+r5yoUXUEefNg676WduL+j3k6qjwyXCJGqDfHLd81F+peTsNbL\n"339+ "5BPyz5Vzc9yPURborSIknbcFVN2/phMlrkgqJYvhewuG3d9a9nAX4+hh8pv4lh+W\n"340+ "3Stp+nGD3GSjB7sacaHZKlXtslof9A3c9MUQpBaBYeNbCNHXvUY7NJoSBqSW8p17\n"341+ "r7M1Z5grAgMBAAECggEAHs/7vw10TcejEHJTrJqs14CT7qresKDzqw1jLycMn6nE\n"342+ "unJLs/EaqE+Yrq5hqxZIQTo+CcsUuuYbAuPStqedleJtW6h3nryJImTaI67BCR8O\n"343+ "8XtPXY3cMAf/hqVLZC9UDey5Ka2Ma9HdEvbnCRSsN/VycnqWJhmMCLouowaQZqoE\n"344+ "VopscUix8GqELv0vEo2CszZfUjtSVbNTlNgwDf5U7eSKXMuFsnSn/LE7AMvHsEyo\n"345+ "HatxogwlM/WjpTnf/WIeJY3VhaK10IsP6OEgUn/p4VtI2DQ/TJdgYrvD5vhjY8ip\n"346+ "XuUPuPILRvJWo8dRXJqa4diXB12q5YhP8iiOp4BgkQKBgQD1GtlOR+JVgOzpQ11h\n"347+ "s5/iJOsczee80pQscbSRJnzSsIaP9WM8CyJgvbPxIQxLUQeYnxM/bxNKkpJtzxRK\n"348+ "pob+v4NoRn8PTpqbOp1obmWJT7uHTaoeavQo7r7uZI4i3eEgHCCQkMzpqzz7UFTY\n"349+ "2Yst7bBTPUivlSVQQBEc8bLpeQKBgQDj47EjpAlh8DmJRTElg58t+XJehXGTqmlx\n"350+ "nYu8DQLSzGbOQ/Z4srakC1mkM0LHCmULIIWk3KhV1GBCeArv7DlZ9A1SkI95bsq9\n"351+ "GBeQpovL0PXKkOOWMJBklP/CTECO4eyA8r6c1d8wytBb6MrJ8bi74DdT+JlFjK5A\n"352+ "zNoeNx6JwwKBgQCehIPABeuSYvRVlDTDqFkh98B6+4wBaatc5xjhuyOFW5dbaVeJ\n"353+ "kKXmLSpAK6B44WnpQhA/uUWfuBWtoPy9nt+1yARjnxwzuSFyfUEqNiPC32coBYmd\n"354+ "bIyGIIopQa1PTXJ4wtgoxw1PnmitHHITYPaLeKrN2te0fuAH+7dVodeU+QKBgAct\n"355+ "VJbaw7Dh7+3yz+lui8TW5lMzwK/13fxGCfCSOFSLO3Gjkk+a0UW5VclmE+RQ333K\n"356+ "OGtIx8RsO9vcC/wiZGwA06qWAu7AHoJ2D8fudtikbBlFFuXUAbgpOSTVYfMeCmTF\n"357+ "QFuQIMdYm9dJLZnOkxLXrOZoHeui0poX2Ya6FawhAoGAAI/QCyDbuvnJzGmjSbvl\n"358+ "5Ndr9lNAansCXaUzXuVLp6dD6PnB8HVCE8tdETZrcXseyTBeltaxAhj+tCybJvDO\n"359+ "sV8UmPR0w9ibExmUIVGX5BpoRlB/KWxEG3ar/wJbUZVZ2oSdIAZvCvdbN956SLDg\n"360+ "Pg5M5wrRqs71s2EiIJd0HrU="361);362private final String keyType;363private final String trustedCert;364private final String endCert;365private final String privateKey;366367private KeyType(String keyType, String selfCert, String privateKey) {368this.keyType = keyType;369this.trustedCert = selfCert;370this.endCert = selfCert;371this.privateKey = privateKey;372}373374public String getKeyType() {375return keyType;376}377378public String getTrustedCert() {379return trustedCert;380}381382public String getEndCert() {383return endCert;384}385386public String getPrivateKey() {387return privateKey;388}389}390391392