1 /* 2 * Copyright (c) 2016, 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 package jdk.test.lib.security; 25 26 import java.io.ByteArrayInputStream; 27 import java.io.InputStream; 28 import java.io.IOException; 29 import java.io.OutputStream; 30 import javax.net.ssl.KeyManagerFactory; 31 import javax.net.ssl.SSLContext; 32 import javax.net.ssl.SSLServerSocket; 33 import javax.net.ssl.SSLServerSocketFactory; 34 import javax.net.ssl.SSLSocket; 35 import javax.net.ssl.SSLSocketFactory; 36 import javax.net.ssl.TrustManagerFactory; 37 import java.net.InetSocketAddress; 38 import java.net.SocketTimeoutException; 39 import java.security.KeyStore; 40 import java.security.PrivateKey; 41 import java.security.KeyFactory; 42 import java.security.cert.Certificate; 43 import java.security.cert.CertificateFactory; 44 import java.security.spec.PKCS8EncodedKeySpec; 45 import java.util.Base64; 46 47 import java.util.concurrent.CountDownLatch; 48 import java.util.concurrent.TimeUnit; 49 50 /** 51 * Template to help speed up your client/server tests. 52 * 53 * Two examples that use this template: 54 * test/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java 55 * test/sun/net/www/protocol/https/HttpsClient/ServerIdentityTest.java 56 */ 57 public abstract class SSLSocketTest { 58 59 /* 60 * Run the test case. 61 */ 62 public void run() throws Exception { 63 bootup(); 64 } 65 66 /* 67 * Define the server side application of the test for the specified socket. 68 */ 69 protected abstract void runServerApplication(SSLSocket socket) throws Exception; 70 71 /* 72 * Define the client side application of the test for the specified socket. 73 * This method is used if the returned value of 74 * isCustomizedClientConnection() is false. 75 * 76 * @param socket may be null is no client socket is generated. 77 * 78 * @see #isCustomizedClientConnection() 79 */ 80 protected abstract void runClientApplication(SSLSocket socket) throws Exception; 81 82 /* 83 * Define the client side application of the test for the specified 84 * server port. This method is used if the returned value of 85 * isCustomizedClientConnection() is true. 86 * 87 * Note that the client need to connect to the server port by itself 88 * for the actual message exchange. 89 * 90 * @see #isCustomizedClientConnection() 91 */ 92 protected void runClientApplication(int serverPort) throws Exception { 93 // blank 94 } 95 96 /* 97 * Create an instance of SSLContext for client use. 98 */ 99 protected SSLContext createClientSSLContext() throws Exception { 100 return createSSLContext(trustedCertStrs, 101 endEntityCertStrs, endEntityPrivateKeys, 102 endEntityPrivateKeyAlgs, 103 endEntityPrivateKeyNames, 104 getClientContextParameters()); 105 } 106 107 /* 108 * Create an instance of SSLContext for server use. 109 */ 110 protected SSLContext createServerSSLContext() throws Exception { 111 return createSSLContext(trustedCertStrs, 112 endEntityCertStrs, endEntityPrivateKeys, 113 endEntityPrivateKeyAlgs, 114 endEntityPrivateKeyNames, 115 getServerContextParameters()); 116 } 117 118 /* 119 * The parameters used to configure SSLContext. 120 */ 121 protected static final class ContextParameters { 122 final String contextProtocol; 123 final String tmAlgorithm; 124 final String kmAlgorithm; 125 126 ContextParameters(String contextProtocol, 127 String tmAlgorithm, String kmAlgorithm) { 128 129 this.contextProtocol = contextProtocol; 130 this.tmAlgorithm = tmAlgorithm; 131 this.kmAlgorithm = kmAlgorithm; 132 } 133 } 134 135 /* 136 * Get the client side parameters of SSLContext. 137 */ 138 protected ContextParameters getClientContextParameters() { 139 return new ContextParameters("TLS", "PKIX", "NewSunX509"); 140 } 141 142 /* 143 * Get the server side parameters of SSLContext. 144 */ 145 protected ContextParameters getServerContextParameters() { 146 return new ContextParameters("TLS", "PKIX", "NewSunX509"); 147 } 148 149 /* 150 * Does the client side use customized connection other than 151 * explicit Socket.connect(), for example, URL.openConnection()? 152 */ 153 protected boolean isCustomizedClientConnection() { 154 return false; 155 } 156 157 /* 158 * Configure the server side socket. 159 */ 160 protected void configureServerSocket(SSLServerSocket socket) { 161 162 } 163 164 /* 165 * ============================================= 166 * Define the client and server side operations. 167 * 168 * If the client or server is doing some kind of object creation 169 * that the other side depends on, and that thread prematurely 170 * exits, you may experience a hang. The test harness will 171 * terminate all hung threads after its timeout has expired, 172 * currently 3 minutes by default, but you might try to be 173 * smart about it.... 174 */ 175 176 /* 177 * Is the server ready to serve? 178 */ 179 private final CountDownLatch serverCondition = new CountDownLatch(1); 180 181 /* 182 * Is the client ready to handshake? 183 */ 184 private final CountDownLatch clientCondition = new CountDownLatch(1); 185 186 /* 187 * What's the server port? Use any free port by default 188 */ 189 private volatile int serverPort = 0; 190 191 /* 192 * Define the server side of the test. 193 */ 194 private void doServerSide() throws Exception { 195 // kick start the server side service 196 SSLContext context = createServerSSLContext(); 197 SSLServerSocketFactory sslssf = context.getServerSocketFactory(); 198 SSLServerSocket sslServerSocket = 199 (SSLServerSocket)sslssf.createServerSocket(serverPort); 200 configureServerSocket(sslServerSocket); 201 serverPort = sslServerSocket.getLocalPort(); 202 203 // Signal the client, the server is ready to accept connection. 204 serverCondition.countDown(); 205 206 // Try to accept a connection in 30 seconds. 207 SSLSocket sslSocket; 208 try { 209 sslServerSocket.setSoTimeout(30000); 210 sslSocket = (SSLSocket)sslServerSocket.accept(); 211 } catch (SocketTimeoutException ste) { 212 // Ignore the test case if no connection within 30 seconds. 213 System.out.println( 214 "No incoming client connection in 30 seconds. " + 215 "Ignore in server side."); 216 return; 217 } finally { 218 sslServerSocket.close(); 219 } 220 221 // handle the connection 222 try { 223 // Is it the expected client connection? 224 // 225 // Naughty test cases or third party routines may try to 226 // connection to this server port unintentionally. In 227 // order to mitigate the impact of unexpected client 228 // connections and avoid intermittent failure, it should 229 // be checked that the accepted connection is really linked 230 // to the expected client. 231 boolean clientIsReady = 232 clientCondition.await(30L, TimeUnit.SECONDS); 233 234 if (clientIsReady) { 235 // Run the application in server side. 236 runServerApplication(sslSocket); 237 } else { // Otherwise, ignore 238 // We don't actually care about plain socket connections 239 // for TLS communication testing generally. Just ignore 240 // the test if the accepted connection is not linked to 241 // the expected client or the client connection timeout 242 // in 30 seconds. 243 System.out.println( 244 "The client is not the expected one or timeout. " + 245 "Ignore in server side."); 246 } 247 } finally { 248 sslSocket.close(); 249 } 250 } 251 252 /* 253 * Define the client side of the test. 254 */ 255 private void doClientSide() throws Exception { 256 257 // Wait for server to get started. 258 // 259 // The server side takes care of the issue if the server cannot 260 // get started in 90 seconds. The client side would just ignore 261 // the test case if the serer is not ready. 262 boolean serverIsReady = 263 serverCondition.await(90L, TimeUnit.SECONDS); 264 if (!serverIsReady) { 265 System.out.println( 266 "The server is not ready yet in 90 seconds. " + 267 "Ignore in client side."); 268 return; 269 } 270 271 if (isCustomizedClientConnection()) { 272 // Signal the server, the client is ready to communicate. 273 clientCondition.countDown(); 274 275 // Run the application in client side. 276 runClientApplication(serverPort); 277 278 return; 279 } 280 281 SSLContext context = createClientSSLContext(); 282 SSLSocketFactory sslsf = context.getSocketFactory(); 283 284 try (SSLSocket sslSocket = (SSLSocket)sslsf.createSocket()) { 285 try { 286 sslSocket.connect( 287 new InetSocketAddress("localhost", serverPort), 15000); 288 } catch (IOException ioe) { 289 // The server side may be impacted by naughty test cases or 290 // third party routines, and cannot accept connections. 291 // 292 // Just ignore the test if the connection cannot be 293 // established. 294 System.out.println( 295 "Cannot make a connection in 15 seconds. " + 296 "Ignore in client side."); 297 return; 298 } 299 300 // OK, here the client and server get connected. 301 302 // Signal the server, the client is ready to communicate. 303 clientCondition.countDown(); 304 305 // There is still a chance in theory that the server thread may 306 // wait client-ready timeout and then quit. The chance should 307 // be really rare so we don't consider it until it becomes a 308 // real problem. 309 310 // Run the application in client side. 311 runClientApplication(sslSocket); 312 } 313 } 314 315 /* 316 * ============================================= 317 * Stuffs to customize the SSLContext instances. 318 */ 319 320 /* 321 * ======================================= 322 * Certificates and keys used in the test. 323 */ 324 // Trusted certificates. 325 private final static String[] trustedCertStrs = { 326 // SHA256withECDSA, curve prime256v1 327 // Validity 328 // Not Before: May 22 07:18:16 2018 GMT 329 // Not After : May 17 07:18:16 2038 GMT 330 // Subject Key Identifier: 331 // 60:CF:BD:73:FF:FA:1A:30:D2:A4:EC:D3:49:71:46:EF:1A:35:A0:86 332 "-----BEGIN CERTIFICATE-----\n" + 333 "MIIBvjCCAWOgAwIBAgIJAIvFG6GbTroCMAoGCCqGSM49BAMCMDsxCzAJBgNVBAYT\n" + 334 "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" + 335 "ZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMDsxCzAJBgNVBAYTAlVT\n" + 336 "MQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZjZTBZ\n" + 337 "MBMGByqGSM49AgEGCCqGSM49AwEHA0IABBz1WeVb6gM2mh85z3QlvaB/l11b5h0v\n" + 338 "LIzmkC3DKlVukZT+ltH2Eq1oEkpXuf7QmbM0ibrUgtjsWH3mULfmcWmjUDBOMB0G\n" + 339 "A1UdDgQWBBRgz71z//oaMNKk7NNJcUbvGjWghjAfBgNVHSMEGDAWgBRgz71z//oa\n" + 340 "MNKk7NNJcUbvGjWghjAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQCG\n" + 341 "6wluh1r2/T6L31mZXRKf9JxeSf9pIzoLj+8xQeUChQIhAJ09wAi1kV8yePLh2FD9\n" + 342 "2YEHlSQUAbwwqCDEVB5KxaqP\n" + 343 "-----END CERTIFICATE-----", 344 // -----BEGIN PRIVATE KEY----- 345 // MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg/HcHdoLJCdq3haVd 346 // XZTSKP00YzM3xX97l98vGL/RI1KhRANCAAQc9VnlW+oDNpofOc90Jb2gf5ddW+Yd 347 // LyyM5pAtwypVbpGU/pbR9hKtaBJKV7n+0JmzNIm61ILY7Fh95lC35nFp 348 // -----END PRIVATE KEY----- 349 350 // SHA256withRSA, 2048 bits 351 // Validity 352 // Not Before: May 22 07:18:16 2018 GMT 353 // Not After : May 17 07:18:16 2038 GMT 354 // Subject Key Identifier: 355 // 0D:DD:93:C9:FE:4B:BD:35:B7:E8:99:78:90:FB:DB:5A:3D:DB:15:4C 356 "-----BEGIN CERTIFICATE-----\n" + 357 "MIIDSTCCAjGgAwIBAgIJAI4ZF3iy8zG+MA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNV\n" + 358 "BAYTAlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2Vy\n" + 359 "aXZjZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMDsxCzAJBgNVBAYT\n" + 360 "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" + 361 "ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALpMcY7aWieXDEM1/YJf\n" + 362 "JW27b4nRIFZyEYhEloyGsKTuQiiQjc8cqRZFNXe2vwziDB4IyTEl0Hjl5QF6ZaQE\n" + 363 "huPzzwvQm1pv64KrRXrmj3FisQK8B5OWLty9xp6xDqsaMRoyObLK+oIb20T5fSlE\n" + 364 "evmo1vYjnh8CX0Yzx5Gr5ye6YSEHQvYOWEws8ad17OlyToR2KMeC8w4qo6rs59pW\n" + 365 "g7Mxn9vo22ImDzrtAbTbXbCias3xlE0Bp0h5luyf+5U4UgksoL9B9r2oP4GrLNEV\n" + 366 "oJk57t8lwaR0upiv3CnS8LcJELpegZub5ggqLY8ZPYFQPjlK6IzLOm6rXPgZiZ3m\n" + 367 "RL0CAwEAAaNQME4wHQYDVR0OBBYEFA3dk8n+S701t+iZeJD721o92xVMMB8GA1Ud\n" + 368 "IwQYMBaAFA3dk8n+S701t+iZeJD721o92xVMMAwGA1UdEwQFMAMBAf8wDQYJKoZI\n" + 369 "hvcNAQELBQADggEBAJTRC3rKUUhVH07/1+stUungSYgpM08dY4utJq0BDk36BbmO\n" + 370 "0AnLDMbkwFdHEoqF6hQIfpm7SQTmXk0Fss6Eejm8ynYr6+EXiRAsaXOGOBCzF918\n" + 371 "/RuKOzqABfgSU4UBKECLM5bMfQTL60qx+HdbdVIpnikHZOFfmjCDVxoHsGyXc1LW\n" + 372 "Jhkht8IGOgc4PMGvyzTtRFjz01kvrVQZ75aN2E0GQv6dCxaEY0i3ypSzjUWAKqDh\n" + 373 "3e2OLwUSvumcdaxyCdZAOUsN6pDBQ+8VRG7KxnlRlY1SMEk46QgQYLbPDe/+W/yH\n" + 374 "ca4PejicPeh+9xRAwoTpiE2gulfT7Lm+fVM7Ruc=\n" + 375 "-----END CERTIFICATE-----", 376 // -----BEGIN PRIVATE KEY----- 377 // MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC6THGO2lonlwxD 378 // Nf2CXyVtu2+J0SBWchGIRJaMhrCk7kIokI3PHKkWRTV3tr8M4gweCMkxJdB45eUB 379 // emWkBIbj888L0Jtab+uCq0V65o9xYrECvAeTli7cvcaesQ6rGjEaMjmyyvqCG9tE 380 // +X0pRHr5qNb2I54fAl9GM8eRq+cnumEhB0L2DlhMLPGndezpck6EdijHgvMOKqOq 381 // 7OfaVoOzMZ/b6NtiJg867QG0212womrN8ZRNAadIeZbsn/uVOFIJLKC/Qfa9qD+B 382 // qyzRFaCZOe7fJcGkdLqYr9wp0vC3CRC6XoGbm+YIKi2PGT2BUD45SuiMyzpuq1z4 383 // GYmd5kS9AgMBAAECggEAFHSoU2MuWwJ+2jJnb5U66t2V1bAcuOE1g5zkWvG/G5z9 384 // rq6Qo5kmB8f5ovdx6tw3MGUOklLwnRXBG3RxDJ1iokz3AvkY1clMNsDPlDsUrQKF 385 // JSO4QUBQTPSZhnsyfR8XHSU+qJ8Y+ohMfzpVv95BEoCzebtXdVgxVegBlcEmVHo2 386 // kMmkRN+bYNsr8eb2r+b0EpyumS39ZgKYh09+cFb78y3T6IFMGcVJTP6nlGBFkmA/ 387 // 25pYeCF2tSki08qtMJZQAvKfw0Kviibk7ZxRbJqmc7B1yfnOEHP6ftjuvKl2+RP/ 388 // +5P5f8CfIP6gtA0LwSzAqQX/hfIKrGV5j0pCqrD0kQKBgQDeNR6Xi4sXVq79lihO 389 // a1bSeV7r8yoQrS8x951uO+ox+UIZ1MsAULadl7zB/P0er92p198I9M/0Jth3KBuS 390 // zj45mucvpiiGvmQlMKMEfNq4nN7WHOu55kufPswQB2mR4J3xmwI+4fM/nl1zc82h 391 // De8JSazRldJXNhfx0RGFPmgzbwKBgQDWoVXrXLbCAn41oVnWB8vwY9wjt92ztDqJ 392 // HMFA/SUohjePep9UDq6ooHyAf/Lz6oE5NgeVpPfTDkgvrCFVKnaWdwALbYoKXT2W 393 // 9FlyJox6eQzrtHAacj3HJooXWuXlphKSizntfxj3LtMR9BmrmRJOfK+SxNOVJzW2 394 // +MowT20EkwKBgHmpB8jdZBgxI7o//m2BI5Y1UZ1KE5vx1kc7VXzHXSBjYqeV9FeF 395 // 2ZZLP9POWh/1Fh4pzTmwIDODGT2UPhSQy0zq3O0fwkyT7WzXRknsuiwd53u/dejg 396 // iEL2NPAJvulZ2+AuiHo5Z99LK8tMeidV46xoJDDUIMgTG+UQHNGhK5gNAoGAZn/S 397 // Cn7SgMC0CWSvBHnguULXZO9wH1wZAFYNLL44OqwuaIUFBh2k578M9kkke7woTmwx 398 // HxQTjmWpr6qimIuY6q6WBN8hJ2Xz/d1fwhYKzIp20zHuv5KDUlJjbFfqpsuy3u1C 399 // kts5zwI7pr1ObRbDGVyOdKcu7HI3QtR5qqyjwaUCgYABo7Wq6oHva/9V34+G3Goh 400 // 63bYGUnRw2l5BD11yhQv8XzGGZFqZVincD8gltNThB0Dc/BI+qu3ky4YdgdZJZ7K 401 // z51GQGtaHEbrHS5caV79yQ8QGY5mUVH3E+VXSxuIqb6pZq2DH4sTAEFHyncddmOH 402 // zoXBInYwRG9KE/Bw5elhUw== 403 // -----END PRIVATE KEY----- 404 405 // SHA256withDSA, 2048 bits 406 // Validity 407 // Not Before: May 22 07:18:18 2018 GMT 408 // Not After : May 17 07:18:18 2038 GMT 409 // Subject Key Identifier: 410 // 76:66:9E:F7:3B:DD:45:E5:3B:D9:72:3C:3F:F0:54:39:86:31:26:53 411 "-----BEGIN CERTIFICATE-----\n" + 412 "MIIErjCCBFSgAwIBAgIJAOktYLNCbr02MAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n" + 413 "EwJVUzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2\n" + 414 "Y2UwHhcNMTgwNTIyMDcxODE4WhcNMzgwNTE3MDcxODE4WjA7MQswCQYDVQQGEwJV\n" + 415 "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Uw\n" + 416 "ggNHMIICOQYHKoZIzjgEATCCAiwCggEBAO5GyPhSm0ze3LSu+gicdULLj05iOfTL\n" + 417 "UvZQ29sYz41zmqrLBQbdKiHqgJu2Re9sgTb5suLNjF047TOLPnU3jhPtWm2X8Xzi\n" + 418 "VGIcHym/Q/MeZxStt/88seqroI3WOKzIML2GcrishT+lcGrtH36Tf1+ue2Snn3PS\n" + 419 "WyxygNqPjllP5uUjYmFLvAf4QLMldkd/D2VxcwsHjB8y5iUZsXezc/LEhRZS/02m\n" + 420 "ivqlRw3AMkq/OVe/ZtxFWsP0nsfxEGdZuaUFpppGfixxFvymrB3+J51cTt+pZBDq\n" + 421 "D2y0DYfc+88iCs4jwHTfcDIpLb538HBjBj2rEgtQESQmB0ooD/+wsPsCIQC1bYch\n" + 422 "gElNtDYL3FgpLgNSUYp7gIWv9ehaC7LO2z7biQKCAQBitvFOnDkUja8NAF7lDpOV\n" + 423 "b5ipQ8SicBLW3kQamxhyuyxgZyy/PojZ/oPorkqW/T/A0rhnG6MssEpAtdiwVB+c\n" + 424 "rBYGo3bcwmExJhdOJ6dYuKFppPWhCwKMHs9npK+lqBMl8l5j58xlcFeC7ZfGf8GY\n" + 425 "GkhFW0c44vEQhMMbac6ZTTP4mw+1t7xJfmDMlLEyIpTXaAAk8uoVLWzQWnR40sHi\n" + 426 "ybvS0u3JxQkb7/y8tOOZu8qlz/YOS7lQ6UxUGX27Ce1E0+agfPphetoRAlS1cezq\n" + 427 "Wa7r64Ga0nkj1kwkcRqjgTiJx0NwnUXr78VAXFhVF95+O3lfqhvdtEGtkhDGPg7N\n" + 428 "A4IBBgACggEBAMmSHQK0w2i+iqUjOPzn0yNEZrzepLlLeQ1tqtn0xnlv5vBAeefD\n" + 429 "Pm9dd3tZOjufVWP7hhEz8xPobb1CS4e3vuQiv5UBfhdPL3f3l9T7JMAKPH6C9Vve\n" + 430 "OQXE5eGqbjsySbcmseHoYUt1WCSnSda1opX8zchX04e7DhGfE2/L9flpYEoSt8lI\n" + 431 "vMNjgOwvKdW3yvPt1/eBBHYNFG5gWPv/Q5KoyCtHS03uqGm4rNc/wZTIEEfd66C+\n" + 432 "QRaUltjOaHmtwOdDHaNqwhYZSVOip+Mo+TfyzHFREcdHLapo7ZXqbdYkRGxRR3d+\n" + 433 "3DfHaraJO0OKoYlPkr3JMvM/MSGR9AnZOcejUDBOMB0GA1UdDgQWBBR2Zp73O91F\n" + 434 "5TvZcjw/8FQ5hjEmUzAfBgNVHSMEGDAWgBR2Zp73O91F5TvZcjw/8FQ5hjEmUzAM\n" + 435 "BgNVHRMEBTADAQH/MAsGCWCGSAFlAwQDAgNHADBEAiBzriYE41M2y9Hy5ppkL0Qn\n" + 436 "dIlNc8JhXT/PHW7GDtViagIgMko8Qoj9gDGPK3+O9E8DC3wGiiF9CObM4LN387ok\n" + 437 "J+g=\n" + 438 "-----END CERTIFICATE-----" 439 // -----BEGIN PRIVATE KEY----- 440 // MIICZQIBADCCAjkGByqGSM44BAEwggIsAoIBAQDuRsj4UptM3ty0rvoInHVCy49O 441 // Yjn0y1L2UNvbGM+Nc5qqywUG3Soh6oCbtkXvbIE2+bLizYxdOO0ziz51N44T7Vpt 442 // l/F84lRiHB8pv0PzHmcUrbf/PLHqq6CN1jisyDC9hnK4rIU/pXBq7R9+k39frntk 443 // p59z0lsscoDaj45ZT+blI2JhS7wH+ECzJXZHfw9lcXMLB4wfMuYlGbF3s3PyxIUW 444 // Uv9Npor6pUcNwDJKvzlXv2bcRVrD9J7H8RBnWbmlBaaaRn4scRb8pqwd/iedXE7f 445 // qWQQ6g9stA2H3PvPIgrOI8B033AyKS2+d/BwYwY9qxILUBEkJgdKKA//sLD7AiEA 446 // tW2HIYBJTbQ2C9xYKS4DUlGKe4CFr/XoWguyzts+24kCggEAYrbxTpw5FI2vDQBe 447 // 5Q6TlW+YqUPEonAS1t5EGpsYcrssYGcsvz6I2f6D6K5Klv0/wNK4ZxujLLBKQLXY 448 // sFQfnKwWBqN23MJhMSYXTienWLihaaT1oQsCjB7PZ6SvpagTJfJeY+fMZXBXgu2X 449 // xn/BmBpIRVtHOOLxEITDG2nOmU0z+JsPtbe8SX5gzJSxMiKU12gAJPLqFS1s0Fp0 450 // eNLB4sm70tLtycUJG+/8vLTjmbvKpc/2Dku5UOlMVBl9uwntRNPmoHz6YXraEQJU 451 // tXHs6lmu6+uBmtJ5I9ZMJHEao4E4icdDcJ1F6+/FQFxYVRfefjt5X6ob3bRBrZIQ 452 // xj4OzQQjAiEAsceWOM8do4etxp2zgnoNXV8PUUyqWhz1+0srcKV7FR4= 453 // -----END PRIVATE KEY----- 454 }; 455 456 // End entity certificate. 457 private final static String[] endEntityCertStrs = { 458 // SHA256withECDSA, curve prime256v1 459 // Validity 460 // Not Before: May 22 07:18:16 2018 GMT 461 // Not After : May 17 07:18:16 2038 GMT 462 // Authority Key Identifier: 463 // 60:CF:BD:73:FF:FA:1A:30:D2:A4:EC:D3:49:71:46:EF:1A:35:A0:86 464 "-----BEGIN CERTIFICATE-----\n" + 465 "MIIBqjCCAVCgAwIBAgIJAPLY8qZjgNRAMAoGCCqGSM49BAMCMDsxCzAJBgNVBAYT\n" + 466 "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" + 467 "ZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMFUxCzAJBgNVBAYTAlVT\n" + 468 "MQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZjZTEY\n" + 469 "MBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD\n" + 470 "QgAEb+9n05qfXnfHUb0xtQJNS4JeSi6IjOfW5NqchvKnfJey9VkJzR7QHLuOESdf\n" + 471 "xlR7q8YIWgih3iWLGfB+wxHiOqMjMCEwHwYDVR0jBBgwFoAUYM+9c//6GjDSpOzT\n" + 472 "SXFG7xo1oIYwCgYIKoZIzj0EAwIDSAAwRQIgWpRegWXMheiD3qFdd8kMdrkLxRbq\n" + 473 "1zj8nQMEwFTUjjQCIQDRIrAjZX+YXHN9b0SoWWLPUq0HmiFIi8RwMnO//wJIGQ==\n" + 474 "-----END CERTIFICATE-----", 475 476 // SHA256withRSA, 2048 bits 477 // Validity 478 // Not Before: May 22 07:18:16 2018 GMT 479 // Not After : May 17 07:18:16 2038 GMT 480 // Authority Key Identifier: 481 // 0D:DD:93:C9:FE:4B:BD:35:B7:E8:99:78:90:FB:DB:5A:3D:DB:15:4C 482 "-----BEGIN CERTIFICATE-----\n" + 483 "MIIDNjCCAh6gAwIBAgIJAO2+yPcFryUTMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNV\n" + 484 "BAYTAlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2Vy\n" + 485 "aXZjZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMFUxCzAJBgNVBAYT\n" + 486 "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" + 487 "ZTEYMBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOC\n" + 488 "AQ8AMIIBCgKCAQEAszfBobWfZIp8AgC6PiWDDavP65mSvgCXUGxACbxVNAfkLhNR\n" + 489 "QOsHriRB3X1Q3nvO9PetC6wKlvE9jlnDDj7D+1j1r1CHO7ms1fq8rfcQYdkanDtu\n" + 490 "4AlHo8v+SSWX16MIXFRYDj2VVHmyPtgbltcg4zGAuwT746FdLI94uXjJjq1IOr/v\n" + 491 "0VIlwE5ORWH5Xc+5Tj+oFWK0E4a4GHDgtKKhn2m72hN56/GkPKGkguP5NRS1qYYV\n" + 492 "/EFkdyQMOV8J1M7HaicSft4OL6eKjTrgo93+kHk+tv0Dc6cpVBnalX3TorG8QI6B\n" + 493 "cHj1XQd78oAlAC+/jF4pc0mwi0un49kdK9gRfQIDAQABoyMwITAfBgNVHSMEGDAW\n" + 494 "gBQN3ZPJ/ku9NbfomXiQ+9taPdsVTDANBgkqhkiG9w0BAQsFAAOCAQEApXS0nKwm\n" + 495 "Kp8gpmO2yG1rpd1+2wBABiMU4JZaTqmma24DQ3RzyS+V2TeRb29dl5oTUEm98uc0\n" + 496 "GPZvhK8z5RFr4YE17dc04nI/VaNDCw4y1NALXGs+AHkjoPjLyGbWpi1S+gfq2sNB\n" + 497 "Ekkjp6COb/cb9yiFXOGVls7UOIjnVZVd0r7KaPFjZhYh82/f4PA/A1SnIKd1+nfH\n" + 498 "2yk7mSJNC7Z3qIVDL8MM/jBVwiC3uNe5GPB2uwhd7k5LGAVN3j4HQQGB0Sz+VC1h\n" + 499 "92oi6xDa+YBva2fvHuCd8P50DDjxmp9CemC7rnZ5j8egj88w14X44Xjb/Fd/ApG9\n" + 500 "e57NnbT7KM+Grw==\n" + 501 "-----END CERTIFICATE-----", 502 503 // SHA256withRSA, curv prime256v1 504 // Validity 505 // Not Before: May 22 07:18:16 2018 GMT 506 // Not After : May 21 07:18:16 2028 GMT 507 // Authority Key Identifier: 508 // 0D:DD:93:C9:FE:4B:BD:35:B7:E8:99:78:90:FB:DB:5A:3D:DB:15:4C 509 "-----BEGIN CERTIFICATE-----\n" + 510 "MIICazCCAVOgAwIBAgIJAO2+yPcFryUUMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNV\n" + 511 "BAYTAlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2Vy\n" + 512 "aXZjZTAeFw0xODA1MjIwNzE4MTZaFw0yODA1MjEwNzE4MTZaMFUxCzAJBgNVBAYT\n" + 513 "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" + 514 "ZTEYMBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" + 515 "AQcDQgAE59MERNTlVZ1eeps8Z3Oue5ZkgQdPtD+WIE6tj3PbIKpxGPDxvfNP959A\n" + 516 "yQjEK/ehWQVrCMmNoEkIzY+IIBgB06MjMCEwHwYDVR0jBBgwFoAUDd2Tyf5LvTW3\n" + 517 "6Jl4kPvbWj3bFUwwDQYJKoZIhvcNAQELBQADggEBAFOTVEqs70ykhZiIdrEsF1Ra\n" + 518 "I3B2rLvwXZk52uSltk2/bzVvewA577ZCoxQ1pL7ynkisPfBN1uVYtHjM1VA3RC+4\n" + 519 "+TAK78dnI7otYjWoHp5rvs4l6c/IbOspS290IlNuDUxMErEm5wxIwj+Aukx/1y68\n" + 520 "hOyCvHBLMY2c1LskH1MMBbDuS1aI+lnGpToi+MoYObxGcV458vxuT8+wwV8Fkpvd\n" + 521 "ll8IIFmeNPRv+1E+lXbES6CSNCVaZ/lFhPgdgYKleN7sfspiz50DG4dqafuEAaX5\n" + 522 "xaK1NWXJxTRz0ROH/IUziyuDW6jphrlgit4+3NCzp6vP9hAJQ8Vhcj0n15BKHIQ=\n" + 523 "-----END CERTIFICATE-----", 524 525 // SHA256withDSA, 2048 bits 526 // Validity 527 // Not Before: May 22 07:18:20 2018 GMT 528 // Not After : May 17 07:18:20 2038 GMT 529 // Authority Key Identifier: 530 // 76:66:9E:F7:3B:DD:45:E5:3B:D9:72:3C:3F:F0:54:39:86:31:26:53 531 "-----BEGIN CERTIFICATE-----\n" + 532 "MIIEnDCCBEGgAwIBAgIJAP/jh1qVhNVjMAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n" + 533 "EwJVUzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2\n" + 534 "Y2UwHhcNMTgwNTIyMDcxODIwWhcNMzgwNTE3MDcxODIwWjBVMQswCQYDVQQGEwJV\n" + 535 "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" + 536 "GDAWBgNVBAMMD1JlZ3Jlc3Npb24gVGVzdDCCA0cwggI6BgcqhkjOOAQBMIICLQKC\n" + 537 "AQEAmlavgoJrMcjqWRVcDE2dmWAPREgnzQvneEDef68cprDzjSwvOs5QeFyx75ib\n" + 538 "ado1e6jO/rW1prCGWHDD1oA/Tn4Pk3vu0nUxzvl1qATc+aJbpUU5Op0bvp6LbCsQ\n" + 539 "QslV9FeRh7Eb7bP6gpc/kHCBzEgC1VCK7prccXWy+t6SMOHbND3h+UbckfSaUuaV\n" + 540 "sVJNTD1D6GElfRj4Nmz1BGPfSYvKorwNZEU3gXwFgtDoAcGx7tcyClLpDHfqRfw/\n" + 541 "7yiqLyeiP7D4hl5lMNouJWDlAdMFp0FMgS3s9VDFinIcr6VtBWMTG7+4+czHAB+3\n" + 542 "fvrwlqNzhBn3uFHrekN/w8fNxwIhAJo7Sae1za7IMW0Q6hE5B4b+s2B/FaKPoA4E\n" + 543 "jtZu13B9AoIBAQCOZqLMKfvqZWUgT0PQ3QjR7dAFdd06I9Y3+TOQzZk1+j+vw/6E\n" + 544 "X4vFItX4gihb/u5Q9CdmpwhVGi7bvo+7+/IKeTgoQ6f5+PSug7SrWWUQ5sPwaZui\n" + 545 "zXZJ5nTeZDucFc2yFx0wgnjbPwiUxZklOT7xGiOMtzOTa2koCz5KuIBL+/wPKKxm\n" + 546 "ypo9VoY9xfbdU6LMXZv/lpD5XTM9rYHr/vUTNkukvV6Hpm0YMEWhVZKUJiqCqTqG\n" + 547 "XHaleOxSw6uQWB/+TznifcC7gB48UOQjCqOKf5VuwQneJLhlhU/jhRV3xtr+hLZa\n" + 548 "hW1wYhVi8cjLDrZFKlgEQqhB4crnJU0mJY+tA4IBBQACggEAID0ezl00/X8mv7eb\n" + 549 "bzovum1+DEEP7FM57k6HZEG2N3ve4CW+0m9Cd+cWPz8wkZ+M0j/Eqa6F0IdbkXEc\n" + 550 "Q7CuzvUyJ57xQ3L/WCgXsiS+Bh8O4Mz7GwW22CGmHqafbVv+hKBfr8MkskO6GJUt\n" + 551 "SUF/CVLzB4gMIvZMH26tBP2xK+i7FeEK9kT+nGdzQSZBAhFYpEVCBplHZO24/OYq\n" + 552 "1DNoU327nUuXIhmsfA8N0PjiWbIZIjTPwBGr9H0LpATI7DIDNcvRRvtROP+pBU9y\n" + 553 "fuykPkptg9C0rCM9t06bukpOSaEz/2VIQdLE8fHYFA6pHZ6CIc2+5cfvMgTPhcjz\n" + 554 "W2jCt6MjMCEwHwYDVR0jBBgwFoAUdmae9zvdReU72XI8P/BUOYYxJlMwCwYJYIZI\n" + 555 "AWUDBAMCA0gAMEUCIQCeI5fN08b9BpOaHdc3zQNGjp24FOL/RxlBLeBAorswJgIg\n" + 556 "JEZ8DhYxQy1O7mmZ2UIT7op6epWMB4dENjs0qWPmcKo=\n" + 557 "-----END CERTIFICATE-----" 558 }; 559 560 // Private key in the format of PKCS#8. 561 private final static String[] endEntityPrivateKeys = { 562 // 563 // EC private key related to cert endEntityCertStrs[0]. 564 // 565 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgn5K03bpTLjEtFQRa\n" + 566 "JUtx22gtmGEvvSUSQdimhGthdtihRANCAARv72fTmp9ed8dRvTG1Ak1Lgl5KLoiM\n" + 567 "59bk2pyG8qd8l7L1WQnNHtAcu44RJ1/GVHurxghaCKHeJYsZ8H7DEeI6", 568 569 // 570 // RSA private key related to cert endEntityCertStrs[1]. 571 // 572 "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCzN8GhtZ9kinwC\n" + 573 "ALo+JYMNq8/rmZK+AJdQbEAJvFU0B+QuE1FA6weuJEHdfVDee870960LrAqW8T2O\n" + 574 "WcMOPsP7WPWvUIc7uazV+ryt9xBh2RqcO27gCUejy/5JJZfXowhcVFgOPZVUebI+\n" + 575 "2BuW1yDjMYC7BPvjoV0sj3i5eMmOrUg6v+/RUiXATk5FYfldz7lOP6gVYrQThrgY\n" + 576 "cOC0oqGfabvaE3nr8aQ8oaSC4/k1FLWphhX8QWR3JAw5XwnUzsdqJxJ+3g4vp4qN\n" + 577 "OuCj3f6QeT62/QNzpylUGdqVfdOisbxAjoFwePVdB3vygCUAL7+MXilzSbCLS6fj\n" + 578 "2R0r2BF9AgMBAAECggEASIkPkMCuw4WdTT44IwERus3IOIYOs2IP3BgEDyyvm4B6\n" + 579 "JP/iihDWKfA4zEl1Gqcni1RXMHswSglXra682J4kui02Ov+vzEeJIY37Ibn2YnP5\n" + 580 "ZjRT2s9GtI/S2o4hl8A/mQb2IMViFC+xKehTukhV4j5d6NPKk0XzLR7gcMjnYxwn\n" + 581 "l21fS6D2oM1xRG/di7sL+uLF8EXLRzfiWDNi12uQv4nwtxPKvuKhH6yzHt7YqMH0\n" + 582 "46pmDKDaxV4w1JdycjCb6NrCJOYZygoQobuZqOQ30UZoZsPJrtovkncFr1e+lNcO\n" + 583 "+aWDfOLCtTH046dEQh5oCShyXMybNlry/QHsOtHOwQKBgQDh2iIjs+FPpQy7Z3EX\n" + 584 "DGEvHYqPjrYO9an2KSRr1m9gzRlWYxKY46WmPKwjMerYtra0GP+TBHrgxsfO8tD2\n" + 585 "wUAII6sd1qup0a/Sutgf2JxVilLykd0+Ge4/Cs51tCdJ8EqDV2B6WhTewOY2EGvg\n" + 586 "JiKYkeNwgRX/9M9CFSAMAk0hUQKBgQDLJAartL3DoGUPjYtpJnfgGM23yAGl6G5r\n" + 587 "NSXDn80BiYIC1p0bG3N0xm3yAjqOtJAUj9jZbvDNbCe3GJfLARMr23legX4tRrgZ\n" + 588 "nEdKnAFKAKL01oM+A5/lHdkwaZI9yyv+hgSVdYzUjB8rDmzeVQzo1BT7vXypt2yV\n" + 589 "6O1OnUpCbQKBgA/0rzDChopv6KRcvHqaX0tK1P0rYeVQqb9ATNhpf9jg5Idb3HZ8\n" + 590 "rrk91BNwdVz2G5ZBpdynFl9G69rNAMJOCM4KZw5mmh4XOEq09Ivba8AHU7DbaTv3\n" + 591 "7QL7KnbaUWRB26HHzIMYVh0el6T+KADf8NXCiMTr+bfpfbL3dxoiF3zhAoGAbCJD\n" + 592 "Qse1dBs/cKYCHfkSOsI5T6kx52Tw0jS6Y4X/FOBjyqr/elyEexbdk8PH9Ar931Qr\n" + 593 "NKMvn8oA4iA/PRrXX7M2yi3YQrWwbkGYWYjtzrzEAdzmg+5eARKAeJrZ8/bg9l3U\n" + 594 "ttKaItJsDPlizn8rngy3FsJpR9aSAMK6/+wOiYkCgYEA1tZkI1rD1W9NYZtbI9BE\n" + 595 "qlJVFi2PBOJMKNuWdouPX3HLQ72GJSQff2BFzLTELjweVVJ0SvY4IipzpQOHQOBy\n" + 596 "5qh/p6izXJZh3IHtvwVBjHoEVplg1b2+I5e3jDCfqnwcQw82dW5SxOJMg1h/BD0I\n" + 597 "qAL3go42DYeYhu/WnECMeis=", 598 599 // 600 // EC private key related to cert endEntityCertStrs[2]. 601 // 602 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgGVc7hICpmp91jbYe\n" + 603 "nrr8nYHD37RZP3VENY+szuA7WjuhRANCAATn0wRE1OVVnV56mzxnc657lmSBB0+0\n" + 604 "P5YgTq2Pc9sgqnEY8PG980/3n0DJCMQr96FZBWsIyY2gSQjNj4ggGAHT", 605 606 // 607 // DSA private key related to cert endEntityCertStrs[3]. 608 // 609 "MIICZQIBADCCAjoGByqGSM44BAEwggItAoIBAQCaVq+CgmsxyOpZFVwMTZ2ZYA9E\n" + 610 "SCfNC+d4QN5/rxymsPONLC86zlB4XLHvmJtp2jV7qM7+tbWmsIZYcMPWgD9Ofg+T\n" + 611 "e+7SdTHO+XWoBNz5olulRTk6nRu+notsKxBCyVX0V5GHsRvts/qClz+QcIHMSALV\n" + 612 "UIrumtxxdbL63pIw4ds0PeH5RtyR9JpS5pWxUk1MPUPoYSV9GPg2bPUEY99Ji8qi\n" + 613 "vA1kRTeBfAWC0OgBwbHu1zIKUukMd+pF/D/vKKovJ6I/sPiGXmUw2i4lYOUB0wWn\n" + 614 "QUyBLez1UMWKchyvpW0FYxMbv7j5zMcAH7d++vCWo3OEGfe4Uet6Q3/Dx83HAiEA\n" + 615 "mjtJp7XNrsgxbRDqETkHhv6zYH8Voo+gDgSO1m7XcH0CggEBAI5moswp++plZSBP\n" + 616 "Q9DdCNHt0AV13Toj1jf5M5DNmTX6P6/D/oRfi8Ui1fiCKFv+7lD0J2anCFUaLtu+\n" + 617 "j7v78gp5OChDp/n49K6DtKtZZRDmw/Bpm6LNdknmdN5kO5wVzbIXHTCCeNs/CJTF\n" + 618 "mSU5PvEaI4y3M5NraSgLPkq4gEv7/A8orGbKmj1Whj3F9t1Tosxdm/+WkPldMz2t\n" + 619 "gev+9RM2S6S9XoembRgwRaFVkpQmKoKpOoZcdqV47FLDq5BYH/5POeJ9wLuAHjxQ\n" + 620 "5CMKo4p/lW7BCd4kuGWFT+OFFXfG2v6EtlqFbXBiFWLxyMsOtkUqWARCqEHhyucl\n" + 621 "TSYlj60EIgIgLfA75+8KcKxdN8mr6gzGjQe7jPFGG42Ejhd7Q2F4wuw=" 622 }; 623 624 // Private key algorithm of endEntityPrivateKeys. 625 private final static String[] endEntityPrivateKeyAlgs = { 626 "EC", 627 "RSA", 628 "EC", 629 "DSA", 630 }; 631 632 // Private key names of endEntityPrivateKeys. 633 private final static String[] endEntityPrivateKeyNames = { 634 "ecdsa", 635 "rsa", 636 "ec-rsa", 637 "dsa", 638 }; 639 640 /* 641 * Create an instance of SSLContext with the specified trust/key materials. 642 */ 643 private SSLContext createSSLContext( 644 String[] trustedMaterials, 645 String[] keyMaterialCerts, 646 String[] keyMaterialKeys, 647 String[] keyMaterialKeyAlgs, 648 String[] keyMaterialKeyNames, 649 ContextParameters params) throws Exception { 650 651 KeyStore ts = null; // trust store 652 KeyStore ks = null; // key store 653 char passphrase[] = "passphrase".toCharArray(); 654 655 // Generate certificate from cert string. 656 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 657 658 // Import the trused certs. 659 ByteArrayInputStream is; 660 if (trustedMaterials != null && trustedMaterials.length != 0) { 661 ts = KeyStore.getInstance("JKS"); 662 ts.load(null, null); 663 664 Certificate[] trustedCert = 665 new Certificate[trustedMaterials.length]; 666 for (int i = 0; i < trustedMaterials.length; i++) { 667 String trustedCertStr = trustedMaterials[i]; 668 669 is = new ByteArrayInputStream(trustedCertStr.getBytes()); 670 try { 671 trustedCert[i] = cf.generateCertificate(is); 672 } finally { 673 is.close(); 674 } 675 676 ts.setCertificateEntry("trusted-cert-" + i, trustedCert[i]); 677 } 678 } 679 680 // Import the key materials. 681 // 682 // Note that certification pathes bigger than one are not supported yet. 683 boolean hasKeyMaterials = 684 (keyMaterialCerts != null) && (keyMaterialCerts.length != 0) && 685 (keyMaterialKeys != null) && (keyMaterialKeys.length != 0) && 686 (keyMaterialKeyAlgs != null) && (keyMaterialKeyAlgs.length != 0) && 687 (keyMaterialCerts.length == keyMaterialKeys.length) && 688 (keyMaterialCerts.length == keyMaterialKeyAlgs.length); 689 if (hasKeyMaterials) { 690 ks = KeyStore.getInstance("JKS"); 691 ks.load(null, null); 692 693 for (int i = 0; i < keyMaterialCerts.length; i++) { 694 String keyCertStr = keyMaterialCerts[i]; 695 696 // generate the private key. 697 PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( 698 Base64.getMimeDecoder().decode(keyMaterialKeys[i])); 699 KeyFactory kf = 700 KeyFactory.getInstance(keyMaterialKeyAlgs[i]); 701 PrivateKey priKey = kf.generatePrivate(priKeySpec); 702 703 // generate certificate chain 704 is = new ByteArrayInputStream(keyCertStr.getBytes()); 705 Certificate keyCert = null; 706 try { 707 keyCert = cf.generateCertificate(is); 708 } finally { 709 is.close(); 710 } 711 712 Certificate[] chain = new Certificate[] { keyCert }; 713 714 // import the key entry. 715 ks.setKeyEntry("cert-" + keyMaterialKeyNames[i], 716 priKey, passphrase, chain); 717 } 718 } 719 720 // Create an SSLContext object. 721 TrustManagerFactory tmf = 722 TrustManagerFactory.getInstance(params.tmAlgorithm); 723 tmf.init(ts); 724 725 SSLContext context = SSLContext.getInstance(params.contextProtocol); 726 if (hasKeyMaterials && ks != null) { 727 KeyManagerFactory kmf = 728 KeyManagerFactory.getInstance(params.kmAlgorithm); 729 kmf.init(ks, passphrase); 730 731 context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 732 } else { 733 context.init(null, tmf.getTrustManagers(), null); 734 } 735 736 return context; 737 } 738 739 /* 740 * ================================================= 741 * Stuffs to boot up the client-server mode testing. 742 */ 743 private Thread clientThread = null; 744 private Thread serverThread = null; 745 private volatile Exception serverException = null; 746 private volatile Exception clientException = null; 747 748 /* 749 * Should we run the client or server in a separate thread? 750 * Both sides can throw exceptions, but do you have a preference 751 * as to which side should be the main thread. 752 */ 753 private static final boolean separateServerThread = false; 754 755 /* 756 * Boot up the testing, used to drive remainder of the test. 757 */ 758 private void bootup() throws Exception { 759 Exception startException = null; 760 try { 761 if (separateServerThread) { 762 startServer(true); 763 startClient(false); 764 } else { 765 startClient(true); 766 startServer(false); 767 } 768 } catch (Exception e) { 769 startException = e; 770 } 771 772 /* 773 * Wait for other side to close down. 774 */ 775 if (separateServerThread) { 776 if (serverThread != null) { 777 serverThread.join(); 778 } 779 } else { 780 if (clientThread != null) { 781 clientThread.join(); 782 } 783 } 784 785 /* 786 * When we get here, the test is pretty much over. 787 * Which side threw the error? 788 */ 789 Exception local; 790 Exception remote; 791 792 if (separateServerThread) { 793 remote = serverException; 794 local = clientException; 795 } else { 796 remote = clientException; 797 local = serverException; 798 } 799 800 Exception exception = null; 801 802 /* 803 * Check various exception conditions. 804 */ 805 if ((local != null) && (remote != null)) { 806 // If both failed, return the curthread's exception. 807 local.initCause(remote); 808 exception = local; 809 } else if (local != null) { 810 exception = local; 811 } else if (remote != null) { 812 exception = remote; 813 } else if (startException != null) { 814 exception = startException; 815 } 816 817 /* 818 * If there was an exception *AND* a startException, 819 * output it. 820 */ 821 if (exception != null) { 822 if (exception != startException && startException != null) { 823 exception.addSuppressed(startException); 824 } 825 throw exception; 826 } 827 828 // Fall-through: no exception to throw! 829 } 830 831 private void startServer(boolean newThread) throws Exception { 832 if (newThread) { 833 serverThread = new Thread() { 834 @Override 835 public void run() { 836 try { 837 doServerSide(); 838 } catch (Exception e) { 839 /* 840 * Our server thread just died. 841 * 842 * Release the client, if not active already... 843 */ 844 logException("Server died", e); 845 serverException = e; 846 } 847 } 848 }; 849 serverThread.start(); 850 } else { 851 try { 852 doServerSide(); 853 } catch (Exception e) { 854 logException("Server failed", e); 855 serverException = e; 856 } 857 } 858 } 859 860 private void startClient(boolean newThread) throws Exception { 861 if (newThread) { 862 clientThread = new Thread() { 863 @Override 864 public void run() { 865 try { 866 doClientSide(); 867 } catch (Exception e) { 868 /* 869 * Our client thread just died. 870 */ 871 logException("Client died", e); 872 clientException = e; 873 } 874 } 875 }; 876 clientThread.start(); 877 } else { 878 try { 879 doClientSide(); 880 } catch (Exception e) { 881 logException("Client failed", e); 882 clientException = e; 883 } 884 } 885 } 886 887 private synchronized void logException(String prefix, Throwable cause) { 888 System.out.println(prefix + ": " + cause); 889 cause.printStackTrace(System.out); 890 } 891 }