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