1/* 2 * Copyright (c) 2013, 2017, 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// SunJSSE does not support dynamic system properties, no way to re-use 26// system properties in samevm/agentvm mode. 27// 28 29/* 30 * @test 31 * @bug 6956398 32 * @summary make ephemeral DH key match the length of the certificate key 33 * @run main/othervm 34 * DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1639 267 35 * @run main/othervm -Djsse.enableFFDHE=false 36 * DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1255 75 37 * @run main/othervm -Djsse.enableFFDHE=false 38 * -Djdk.tls.ephemeralDHKeySize=matched 39 * DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1255 75 40 * @run main/othervm -Djsse.enableFFDHE=false 41 * -Djdk.tls.ephemeralDHKeySize=legacy 42 * DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1255 75 43 * @run main/othervm -Djsse.enableFFDHE=false 44 * -Djdk.tls.ephemeralDHKeySize=1024 45 * DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1255 75 46 * 47 * @run main/othervm -Djsse.enableFFDHE=false 48 * DHEKeySizing SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA true 229 75 49 * 50 * @run main/othervm -Djsse.enableFFDHE=false 51 * DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1383 139 52 * @run main/othervm -Djsse.enableFFDHE=false 53 * -Djdk.tls.ephemeralDHKeySize=legacy 54 * DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1319 107 55 * @run main/othervm -Djsse.enableFFDHE=false 56 * -Djdk.tls.ephemeralDHKeySize=matched 57 * DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1639 267 58 * @run main/othervm -Djsse.enableFFDHE=false 59 * -Djdk.tls.ephemeralDHKeySize=1024 60 * DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1383 139 61 * 62 * @run main/othervm -Djsse.enableFFDHE=false 63 * DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 357 139 64 * @run main/othervm -Djsse.enableFFDHE=false 65 * -Djdk.tls.ephemeralDHKeySize=legacy 66 * DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 293 107 67 * @run main/othervm -Djsse.enableFFDHE=false 68 * -Djdk.tls.ephemeralDHKeySize=matched 69 * DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 357 139 70 * @run main/othervm -Djsse.enableFFDHE=false 71 * -Djdk.tls.ephemeralDHKeySize=1024 72 * DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 357 139 73 */ 74 75/* 76 * This is a simple hack to test key sizes of Diffie-Hellman key exchanging 77 * during SSL/TLS handshaking. 78 * 79 * The record length of DH ServerKeyExchange and ClientKeyExchange. 80 * ServerKeyExchange message are wrapped in ServerHello series messages, which 81 * contains ServerHello, Certificate and ServerKeyExchange message. 82 * 83 * struct { 84 * opaque dh_p<1..2^16-1>; 85 * opaque dh_g<1..2^16-1>; 86 * opaque dh_Ys<1..2^16-1>; 87 * } ServerDHParams; // Ephemeral DH parameters 88 * 89 * struct { 90 * select (PublicValueEncoding) { 91 * case implicit: struct { }; 92 * case explicit: opaque dh_Yc<1..2^16-1>; 93 * } dh_public; 94 * } ClientDiffieHellmanPublic; 95 * 96 * Fomr above structures, it is clear that if the DH key size increasing 128 97 * bits (16 bytes), the ServerHello series messages increases 48 bytes 98 * (becuase dh_p, dh_g and dh_Ys each increase 16 bytes) and ClientKeyExchange 99 * increases 16 bytes (because of the size increasing of dh_Yc). 100 * 101 * Here is a summary of the record length in the test case. 102 * 103 * | ServerHello Series | ClientKeyExchange | ServerHello Anon 104 * 512-bit | 1255 bytes | 75 bytes | 229 bytes 105 * 768-bit | 1319 bytes | 107 bytes | 293 bytes 106 * 1024-bit | 1383 bytes | 139 bytes | 357 bytes 107 * 2048-bit | 1639 bytes | 267 bytes | 357 bytes 108 */ 109 110import javax.net.ssl.*; 111import javax.net.ssl.SSLEngineResult.*; 112import java.io.*; 113import java.nio.*; 114import java.security.KeyStore; 115import java.security.KeyFactory; 116import java.security.Security; 117import java.security.cert.Certificate; 118import java.security.cert.CertificateFactory; 119import java.security.spec.PKCS8EncodedKeySpec; 120import java.security.interfaces.*; 121import java.util.Base64; 122 123public class DHEKeySizing { 124 125 private final static boolean debug = true; 126 127 // key length bias because of the stripping of leading zero bytes of 128 // negotiated DH keys. 129 // 130 // This is an effort to mimum intermittent failure when we cannot 131 // estimate what's the exact number of leading zero bytes of 132 // negotiated DH keys. 133 private final static int KEY_LEN_BIAS = 6; 134 135 private SSLContext sslc; 136 private SSLEngine ssle1; // client 137 private SSLEngine ssle2; // server 138 139 private ByteBuffer appOut1; // write side of ssle1 140 private ByteBuffer appIn1; // read side of ssle1 141 private ByteBuffer appOut2; // write side of ssle2 142 private ByteBuffer appIn2; // read side of ssle2 143 144 private ByteBuffer oneToTwo; // "reliable" transport ssle1->ssle2 145 private ByteBuffer twoToOne; // "reliable" transport ssle2->ssle1 146 147 /* 148 * Where do we find the keystores? 149 */ 150 // Certificates and key used in the test. 151 static String trustedCertStr = 152 "-----BEGIN CERTIFICATE-----\n" + 153 "MIIC8jCCAdqgAwIBAgIEUjkuRzANBgkqhkiG9w0BAQUFADA7MR0wGwYDVQQLExRT\n" + 154 "dW5KU1NFIFRlc3QgU2VyaXZjZTENMAsGA1UEChMESmF2YTELMAkGA1UEBhMCVVMw\n" + 155 "HhcNMTMwOTE4MDQzODMxWhcNMTMxMjE3MDQzODMxWjA7MR0wGwYDVQQLExRTdW5K\n" + 156 "U1NFIFRlc3QgU2VyaXZjZTENMAsGA1UEChMESmF2YTELMAkGA1UEBhMCVVMwggEi\n" + 157 "MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCO+IGeaskJAvEcYc7pCl9neK3E\n" + 158 "a28fwWLtChufYNaC9hQfZlUdETWYjV7fZJVJKT/oLzdDNMWuVA0LKXArpI3thLNK\n" + 159 "QLXisdF9hKPlZRDazACL9kWUUtJ0FzpEySK4e8wW/z9FuU6e6iO19FbjxAfInJqk\n" + 160 "3EDiEhB5g73S2vtvPCxgq2DvWw9TDl/LIqdKG2JCS93koXCCaHmQ7MrIOqHPd+8r\n" + 161 "RbGpatXT9qyHKppUv9ATxVygO4rA794mgCFxpT+fkhz+NEB0twTkM65T1hnnOv5n\n" + 162 "ZIxkcjBggt85UlZtnP3b9P7SYxsWIa46Oc38Od2f3YejfVg6B+PqPgWNl3+/AgMB\n" + 163 "AAEwDQYJKoZIhvcNAQEFBQADggEBAAlrP6DFLRPSy0IgQhcI2i56tR/na8pezSte\n" + 164 "ZHcCdaCZPDy4UP8mpLJ9QCjEB5VJv8hPm4xdK7ULnKGOGHgYqDpV2ZHvQlhV1woQ\n" + 165 "TZGb/LM3c6kAs0j4j9KM2fq3iYUYexjIkS1KzsziflxMM6igS9BRMBR2LQyU+cYq\n" + 166 "YEsFzkF7Aj2ET4v/+tgot9mRr2NioJcaJkdsPDpMU3IKB1cczfu+OuLQ/GCG0Fqu\n" + 167 "6ijCeCqfnaAbemHbJeVZZ6Qgka3uC2YMntLBmLkhqEo1d9zGYLoh7oWL77y5ibQZ\n" + 168 "LK5/H/zikcu579TWjlDHcqL3arCwBcrtsjSaPrRSWMrWV/6c0qw=\n" + 169 "-----END CERTIFICATE-----"; 170 171 // Private key in the format of PKCS#8 172 static String targetPrivateKey = 173 "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCO+IGeaskJAvEc\n" + 174 "Yc7pCl9neK3Ea28fwWLtChufYNaC9hQfZlUdETWYjV7fZJVJKT/oLzdDNMWuVA0L\n" + 175 "KXArpI3thLNKQLXisdF9hKPlZRDazACL9kWUUtJ0FzpEySK4e8wW/z9FuU6e6iO1\n" + 176 "9FbjxAfInJqk3EDiEhB5g73S2vtvPCxgq2DvWw9TDl/LIqdKG2JCS93koXCCaHmQ\n" + 177 "7MrIOqHPd+8rRbGpatXT9qyHKppUv9ATxVygO4rA794mgCFxpT+fkhz+NEB0twTk\n" + 178 "M65T1hnnOv5nZIxkcjBggt85UlZtnP3b9P7SYxsWIa46Oc38Od2f3YejfVg6B+Pq\n" + 179 "PgWNl3+/AgMBAAECggEAPdb5Ycc4m4A9QBSCRcRpzbyiFLKPh0HDg1n65q4hOtYr\n" + 180 "kAVYTVFTSF/lqGS+Ob3w2YIKujQKSUQrvCc5UHdFuHXMgxKIWbymK0+DAMb9SlYw\n" + 181 "6lkkcWp9gx9E4dnJ/df2SAAxovvrKMuHlL1SFASHhVtPfH2URvSfUaANLDXxyYOs\n" + 182 "8BX0Nr6wazhWjLjXo9yIGnKSvFfB8XisYcA78kEgas43zhmIGCDPqaYyyffOfRbx\n" + 183 "pM1KNwGmlN86iWR1CbwA/wwhcMySWQueS+s7cHbpRqZIYJF9jEeELiwi0vxjealS\n" + 184 "EMuHYedIRFMWaDIq9XyjrvXamHb0Z25jlXBNZHaM0QKBgQDE9adl+zAezR/n79vw\n" + 185 "0XiX2Fx1UEo3ApZHuoA2Q/PcBk+rlKqqQ3IwTcy6Wo648wK7v6Nq7w5nEWcsf0dU\n" + 186 "QA2Ng/AJEev/IfF34x7sKGYxtk1gcE0EuSBA3R+ocEZxnNw1Ryd5nUU24s8d4jCP\n" + 187 "Mkothnyaim+zE2raDlEtVc0CaQKBgQC509av+02Uq5oMjzbQp5PBJfQFjATOQT15\n" + 188 "eefYnVYurkQ1kcVfixkrO2ORhg4SjmI2Z5hJDgGtXdwgidpzkad+R2epS5qLMyno\n" + 189 "lQVpY6bMpEZ7Mos0yQygxnm8uNohEcTExOe+nP5fNJVpzBsGmfeyYOhnPQlf6oqf\n" + 190 "0cHizedb5wKBgQC/l5LyMil6HOGHlhzmIm3jj7VI7QR0hJC5T6N+phVml8ESUDjA\n" + 191 "DYHbmSKouISTRtkG14FY+RiSjCxH7bvuKazFV2289PETquogTA/9e8MFYqfcQwG4\n" + 192 "sXi9gBxWlnj/9a2EKiYtOB5nKLR/BlNkSHA93tAA6N+FXEMZwMmYhxk42QKBgAuY\n" + 193 "HQgD3PZOsqDf+qKQIhbmAFCsSMx5o5VFtuJ8BpmJA/Z3ruHkMuDQpsi4nX4o5hXQ\n" + 194 "5t6AAjjH52kcUMXvK40kdWJJtk3DFnVNfvXxYsHX6hHbuHXFqYUKfSP6QJnZmvZP\n" + 195 "9smcz/4usLfWJUWHK740b6upUkFqx9Vq5/b3s9y3AoGAdM5TW7LkkOFsdMGVAUzR\n" + 196 "9iXmCWElHTK2Pcp/3yqDBHSfiQx6Yp5ANyPnE9NBM0yauCfOyBB2oxLO4Rdv3Rqk\n" + 197 "9V9kyR/YAGr7dJaPcQ7pZX0OpkzgueAOJYPrx5VUzPYUtklYV1ycFZTfKlpFCxT+\n" + 198 "Ei6KUo0NXSdUIcB4yib1J10="; 199 200 static char passphrase[] = "passphrase".toCharArray(); 201 202 /* 203 * Majority of the test case is here, setup is done below. 204 */ 205 206 private void createSSLEngines() throws Exception { 207 ssle1 = sslc.createSSLEngine("client", 1); 208 ssle1.setUseClientMode(true); 209 210 ssle2 = sslc.createSSLEngine("server", 2); 211 ssle2.setUseClientMode(false); 212 } 213 214 private boolean isHandshaking(SSLEngine e) { 215 return (e.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING); 216 } 217 218 private void checkResult(ByteBuffer bbIn, ByteBuffer bbOut, 219 SSLEngineResult result, 220 Status status, HandshakeStatus hsStatus, 221 int consumed, int produced) 222 throws Exception { 223 224 if ((status != null) && (result.getStatus() != status)) { 225 throw new Exception("Unexpected Status: need = " + status + 226 " got = " + result.getStatus()); 227 } 228 229 if ((hsStatus != null) && (result.getHandshakeStatus() != hsStatus)) { 230 throw new Exception("Unexpected hsStatus: need = " + hsStatus + 231 " got = " + result.getHandshakeStatus()); 232 } 233 234 if ((consumed != -1) && (consumed != result.bytesConsumed())) { 235 throw new Exception("Unexpected consumed: need = " + consumed + 236 " got = " + result.bytesConsumed()); 237 } 238 239 if ((produced != -1) && (produced != result.bytesProduced())) { 240 throw new Exception("Unexpected produced: need = " + produced + 241 " got = " + result.bytesProduced()); 242 } 243 244 if ((consumed != -1) && (bbIn.position() != result.bytesConsumed())) { 245 throw new Exception("Consumed " + bbIn.position() + 246 " != " + consumed); 247 } 248 249 if ((produced != -1) && (bbOut.position() != result.bytesProduced())) { 250 throw new Exception("produced " + bbOut.position() + 251 " != " + produced); 252 } 253 } 254 255 private void test(String cipherSuite, boolean exportable, 256 int lenServerKeyEx, int lenClientKeyEx) throws Exception { 257 258 createSSLEngines(); 259 createBuffers(); 260 261 SSLEngineResult result1; // ssle1's results from last operation 262 SSLEngineResult result2; // ssle2's results from last operation 263 264 String[] suites = new String [] {cipherSuite}; 265 266 ssle1.setEnabledCipherSuites(suites); 267 ssle2.setEnabledCipherSuites(suites); 268 269 log("======================================"); 270 log("==================="); 271 log("client hello"); 272 result1 = ssle1.wrap(appOut1, oneToTwo); 273 checkResult(appOut1, oneToTwo, result1, 274 Status.OK, HandshakeStatus.NEED_UNWRAP, 0, -1); 275 oneToTwo.flip(); 276 277 result2 = ssle2.unwrap(oneToTwo, appIn2); 278 checkResult(oneToTwo, appIn2, result2, 279 Status.OK, HandshakeStatus.NEED_TASK, result1.bytesProduced(), 0); 280 runDelegatedTasks(ssle2); 281 oneToTwo.compact(); 282 283 log("==================="); 284 log("ServerHello"); 285 result2 = ssle2.wrap(appOut2, twoToOne); 286 checkResult(appOut2, twoToOne, result2, 287 Status.OK, HandshakeStatus.NEED_UNWRAP, 0, -1); 288 twoToOne.flip(); 289 290 log("Message length of ServerHello series: " + twoToOne.remaining()); 291 if (twoToOne.remaining() < (lenServerKeyEx - KEY_LEN_BIAS) || 292 twoToOne.remaining() > lenServerKeyEx) { 293 throw new Exception( 294 "Expected to generate ServerHello series messages of " + 295 lenServerKeyEx + " bytes, but not " + twoToOne.remaining()); 296 } 297 298 result1 = ssle1.unwrap(twoToOne, appIn1); 299 checkResult(twoToOne, appIn1, result1, 300 Status.OK, HandshakeStatus.NEED_TASK, result2.bytesProduced(), 0); 301 runDelegatedTasks(ssle1); 302 twoToOne.compact(); 303 304 log("==================="); 305 log("Key Exchange"); 306 result1 = ssle1.wrap(appOut1, oneToTwo); 307 checkResult(appOut1, oneToTwo, result1, 308 Status.OK, HandshakeStatus.NEED_WRAP, 0, -1); 309 oneToTwo.flip(); 310 311 log("Message length of ClientKeyExchange: " + oneToTwo.remaining()); 312 if (oneToTwo.remaining() < (lenClientKeyEx - KEY_LEN_BIAS) || 313 oneToTwo.remaining() > lenClientKeyEx) { 314 throw new Exception( 315 "Expected to generate ClientKeyExchange message of " + 316 lenClientKeyEx + " bytes, but not " + oneToTwo.remaining()); 317 } 318 result2 = ssle2.unwrap(oneToTwo, appIn2); 319 checkResult(oneToTwo, appIn2, result2, 320 Status.OK, HandshakeStatus.NEED_TASK, result1.bytesProduced(), 0); 321 runDelegatedTasks(ssle2); 322 oneToTwo.compact(); 323 324 log("==================="); 325 log("Client CCS"); 326 result1 = ssle1.wrap(appOut1, oneToTwo); 327 checkResult(appOut1, oneToTwo, result1, 328 Status.OK, HandshakeStatus.NEED_WRAP, 0, -1); 329 oneToTwo.flip(); 330 331 result2 = ssle2.unwrap(oneToTwo, appIn2); 332 checkResult(oneToTwo, appIn2, result2, 333 Status.OK, HandshakeStatus.NEED_UNWRAP, 334 result1.bytesProduced(), 0); 335 oneToTwo.compact(); 336 337 log("==================="); 338 log("Client Finished"); 339 result1 = ssle1.wrap(appOut1, oneToTwo); 340 checkResult(appOut1, oneToTwo, result1, 341 Status.OK, HandshakeStatus.NEED_UNWRAP, 0, -1); 342 oneToTwo.flip(); 343 344 result2 = ssle2.unwrap(oneToTwo, appIn2); 345 checkResult(oneToTwo, appIn2, result2, 346 Status.OK, HandshakeStatus.NEED_WRAP, 347 result1.bytesProduced(), 0); 348 oneToTwo.compact(); 349 350 log("==================="); 351 log("Server CCS"); 352 result2 = ssle2.wrap(appOut2, twoToOne); 353 checkResult(appOut2, twoToOne, result2, 354 Status.OK, HandshakeStatus.NEED_WRAP, 0, -1); 355 twoToOne.flip(); 356 357 result1 = ssle1.unwrap(twoToOne, appIn1); 358 checkResult(twoToOne, appIn1, result1, 359 Status.OK, HandshakeStatus.NEED_UNWRAP, result2.bytesProduced(), 0); 360 twoToOne.compact(); 361 362 log("==================="); 363 log("Server Finished"); 364 result2 = ssle2.wrap(appOut2, twoToOne); 365 checkResult(appOut2, twoToOne, result2, 366 Status.OK, HandshakeStatus.FINISHED, 0, -1); 367 twoToOne.flip(); 368 369 result1 = ssle1.unwrap(twoToOne, appIn1); 370 checkResult(twoToOne, appIn1, result1, 371 Status.OK, HandshakeStatus.FINISHED, result2.bytesProduced(), 0); 372 twoToOne.compact(); 373 374 log("==================="); 375 log("Check Session/Ciphers"); 376 String cs = ssle1.getSession().getCipherSuite(); 377 if (!cs.equals(suites[0])) { 378 throw new Exception("suites not equal: " + cs + "/" + suites[0]); 379 } 380 381 cs = ssle2.getSession().getCipherSuite(); 382 if (!cs.equals(suites[0])) { 383 throw new Exception("suites not equal: " + cs + "/" + suites[0]); 384 } 385 386 log("==================="); 387 log("Done with SSL/TLS handshaking"); 388 } 389 390 public static void main(String args[]) throws Exception { 391 // reset security properties to make sure that the algorithms 392 // and keys used in this test are not disabled. 393 Security.setProperty("jdk.tls.disabledAlgorithms", ""); 394 Security.setProperty("jdk.certpath.disabledAlgorithms", ""); 395 396 if (args.length != 4) { 397 System.out.println( 398 "Usage: java DHEKeySizing cipher-suite " + 399 "exportable(true|false)\n" + 400 " size-of-server-hello-record size-of-client-key-exchange"); 401 throw new Exception("Incorrect usage!"); 402 } 403 404 (new DHEKeySizing()).test(args[0], 405 Boolean.parseBoolean(args[1]), 406 Integer.parseInt(args[2]), 407 Integer.parseInt(args[3])); 408 System.out.println("Test Passed."); 409 } 410 411 /* 412 * ********************************************************** 413 * Majority of the test case is above, below is just setup stuff 414 * ********************************************************** 415 */ 416 417 public DHEKeySizing() throws Exception { 418 sslc = getSSLContext(); 419 } 420 421 /* 422 * Create an initialized SSLContext to use for this test. 423 */ 424 private SSLContext getSSLContext() throws Exception { 425 426 // generate certificate from cert string 427 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 428 429 // create a key store 430 KeyStore ts = KeyStore.getInstance("JKS"); 431 KeyStore ks = KeyStore.getInstance("JKS"); 432 ts.load(null, null); 433 ks.load(null, null); 434 435 // import the trused cert 436 ByteArrayInputStream is = 437 new ByteArrayInputStream(trustedCertStr.getBytes()); 438 Certificate trusedCert = cf.generateCertificate(is); 439 is.close(); 440 ts.setCertificateEntry("rsa-trusted-2048", trusedCert); 441 442 // generate the private key. 443 String keySpecStr = targetPrivateKey; 444 PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( 445 Base64.getMimeDecoder().decode(keySpecStr)); 446 KeyFactory kf = KeyFactory.getInstance("RSA"); 447 RSAPrivateKey priKey = (RSAPrivateKey)kf.generatePrivate(priKeySpec); 448 449 Certificate[] chain = new Certificate[1]; 450 chain[0] = trusedCert; 451 452 // import the key entry. 453 ks.setKeyEntry("rsa-key-2048", priKey, passphrase, chain); 454 455 // create SSL context 456 KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 457 kmf.init(ks, passphrase); 458 459 TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); 460 tmf.init(ts); 461 462 SSLContext sslCtx = SSLContext.getInstance("TLSv1"); 463 sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 464 465 return sslCtx; 466 } 467 468 private void createBuffers() { 469 // Size the buffers as appropriate. 470 471 SSLSession session = ssle1.getSession(); 472 int appBufferMax = session.getApplicationBufferSize(); 473 int netBufferMax = session.getPacketBufferSize(); 474 475 appIn1 = ByteBuffer.allocateDirect(appBufferMax + 50); 476 appIn2 = ByteBuffer.allocateDirect(appBufferMax + 50); 477 478 oneToTwo = ByteBuffer.allocateDirect(netBufferMax); 479 twoToOne = ByteBuffer.allocateDirect(netBufferMax); 480 481 appOut1 = ByteBuffer.wrap("Hi Engine2, I'm SSLEngine1".getBytes()); 482 appOut2 = ByteBuffer.wrap("Hello Engine1, I'm SSLEngine2".getBytes()); 483 484 log("AppOut1 = " + appOut1); 485 log("AppOut2 = " + appOut2); 486 log(""); 487 } 488 489 private static void runDelegatedTasks(SSLEngine engine) throws Exception { 490 491 Runnable runnable; 492 while ((runnable = engine.getDelegatedTask()) != null) { 493 log("running delegated task..."); 494 runnable.run(); 495 } 496 } 497 498 private static void log(String str) { 499 if (debug) { 500 System.out.println(str); 501 } 502 } 503} 504