1 /*
   2  * Copyright (c) 2003, 2015, 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  * @test
  26  * @bug 4948079
  27  * @summary SSLEngineResult needs updating [none yet]
  28  *
  29  * This is a simple hack to test a bunch of conditions and check
  30  * their return codes.
  31  *
  32  * @run main/othervm -Djsse.enableCBCProtection=false CheckStatus
  33  *
  34  * @author Brad Wetmore
  35  */
  36 
  37 import javax.net.ssl.*;
  38 import javax.net.ssl.SSLEngineResult.*;
  39 import java.io.*;
  40 import java.security.*;
  41 import java.nio.*;
  42 
  43 public class CheckStatus {
  44 
  45     private static boolean debug = true;
  46 
  47     private SSLContext sslc;
  48     private SSLEngine ssle1;    // client
  49     private SSLEngine ssle2;    // server
  50 
  51     private static String pathToStores = "../etc";
  52     private static String keyStoreFile = "keystore";
  53     private static String trustStoreFile = "truststore";
  54     private static String passwd = "passphrase";
  55 
  56     private static String keyFilename =
  57             System.getProperty("test.src", "./") + "/" + pathToStores +
  58                 "/" + keyStoreFile;
  59     private static String trustFilename =
  60             System.getProperty("test.src", "./") + "/" + pathToStores +
  61                 "/" + trustStoreFile;
  62 
  63     private ByteBuffer appOut1;         // write side of ssle1
  64     private ByteBuffer appIn1;          // read side of ssle1
  65     private ByteBuffer appOut2;         // write side of ssle2
  66     private ByteBuffer appIn2;          // read side of ssle2
  67 
  68     private ByteBuffer oneToTwo;        // "reliable" transport ssle1->ssle2
  69     private ByteBuffer twoToOne;        // "reliable" transport ssle2->ssle1
  70 
  71     /*
  72      * Majority of the test case is here, setup is done below.
  73      */
  74 
  75     private void createSSLEngines() throws Exception {
  76         ssle1 = sslc.createSSLEngine("client", 1);
  77         ssle1.setUseClientMode(true);
  78 
  79         ssle2 = sslc.createSSLEngine("server", 2);
  80         ssle2.setUseClientMode(false);
  81     }
  82 
  83     private boolean isHandshaking(SSLEngine e) {
  84         return (e.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING);
  85     }
  86 
  87     private void checkResult(ByteBuffer bbIn, ByteBuffer bbOut,
  88             SSLEngineResult result,
  89             Status status, HandshakeStatus hsStatus,
  90             int consumed, int produced)
  91             throws Exception {
  92 
  93         if ((status != null) && (result.getStatus() != status)) {
  94             throw new Exception("Unexpected Status: need = " + status +
  95                 " got = " + result.getStatus());
  96         }
  97 
  98         if ((hsStatus != null) && (result.getHandshakeStatus() != hsStatus)) {
  99             throw new Exception("Unexpected hsStatus: need = " + hsStatus +
 100                 " got = " + result.getHandshakeStatus());
 101         }
 102 
 103         if ((consumed != -1) && (consumed != result.bytesConsumed())) {
 104             throw new Exception("Unexpected consumed: need = " + consumed +
 105                 " got = " + result.bytesConsumed());
 106         }
 107 
 108         if ((produced != -1) && (produced != result.bytesProduced())) {
 109             throw new Exception("Unexpected produced: need = " + produced +
 110                 " got = " + result.bytesProduced());
 111         }
 112 
 113         if ((consumed != -1) && (bbIn.position() != result.bytesConsumed())) {
 114             throw new Exception("Consumed " + bbIn.position() +
 115                 " != " + consumed);
 116         }
 117 
 118         if ((produced != -1) && (bbOut.position() != result.bytesProduced())) {
 119             throw new Exception("produced " + bbOut.position() +
 120                 " != " + produced);
 121         }
 122     }
 123 
 124     private void test() throws Exception {
 125         createSSLEngines();
 126         createBuffers();
 127 
 128         SSLEngineResult result1;        // ssle1's results from last operation
 129         SSLEngineResult result2;        // ssle2's results from last operation
 130 
 131         String [] suite1 = new String [] {
 132             "SSL_RSA_WITH_RC4_128_MD5" };
 133         String [] suite2 = new String [] {
 134             "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA" };
 135 
 136         ssle1.setEnabledCipherSuites(suite1);
 137         ssle2.setEnabledCipherSuites(suite1);
 138 
 139         log("================");
 140 
 141         log("unexpected empty unwrap");
 142         twoToOne.limit(0);
 143         result1 = ssle1.unwrap(twoToOne, appIn1);
 144         checkResult(twoToOne, appIn1, result1,
 145             Status.OK, HandshakeStatus.NEED_WRAP, 0, 0);
 146         twoToOne.limit(twoToOne.capacity());
 147 
 148         log("======================================");
 149         log("client hello");
 150         result1 = ssle1.wrap(appOut1, oneToTwo);
 151         checkResult(appOut1, oneToTwo, result1,
 152              Status.OK, HandshakeStatus.NEED_UNWRAP, 0, -1);
 153 
 154         oneToTwo.flip();
 155         result2 = ssle2.unwrap(oneToTwo, appIn2);
 156 
 157         checkResult(oneToTwo, appIn2, result2,
 158              Status.OK, HandshakeStatus.NEED_TASK, result1.bytesProduced(), 0);
 159         runDelegatedTasks(ssle2);
 160 
 161         oneToTwo.compact();
 162 
 163         log("Check for unwrap when wrap needed");
 164         result2 = ssle2.unwrap(oneToTwo, appIn2);
 165         checkResult(oneToTwo, appIn2, result2,
 166             Status.OK, HandshakeStatus.NEED_WRAP, 0, 0);
 167 
 168         log("======================================");
 169         log("ServerHello");
 170 
 171         result2 = ssle2.wrap(appOut2, twoToOne);
 172         checkResult(appOut2, twoToOne, result2,
 173             Status.OK, HandshakeStatus.NEED_UNWRAP, 0, -1);
 174         twoToOne.flip();
 175 
 176         result1 = ssle1.unwrap(twoToOne, appIn1);
 177         checkResult(twoToOne, appIn1, result1,
 178             Status.OK, HandshakeStatus.NEED_TASK, result2.bytesProduced(), 0);
 179         twoToOne.compact();
 180 
 181         runDelegatedTasks(ssle1);
 182 
 183         log("======================================");
 184         log("Key Exchange");
 185         result1 = ssle1.wrap(appOut1, oneToTwo);
 186         checkResult(appOut1, oneToTwo, result1,
 187              Status.OK, HandshakeStatus.NEED_WRAP, 0, -1);
 188 
 189         oneToTwo.flip();
 190         result2 = ssle2.unwrap(oneToTwo, appIn2);
 191 
 192         checkResult(oneToTwo, appIn2, result2,
 193              Status.OK, HandshakeStatus.NEED_TASK, result1.bytesProduced(), 0);
 194         runDelegatedTasks(ssle2);
 195 
 196         oneToTwo.compact();
 197 
 198         log("======================================");
 199         log("CCS");
 200         result1 = ssle1.wrap(appOut1, oneToTwo);
 201         checkResult(appOut1, oneToTwo, result1,
 202              Status.OK, HandshakeStatus.NEED_WRAP, 0, -1);
 203 
 204         oneToTwo.flip();
 205         result2 = ssle2.unwrap(oneToTwo, appIn2);
 206 
 207         checkResult(oneToTwo, appIn2, result2,
 208              Status.OK, HandshakeStatus.NEED_UNWRAP,
 209              result1.bytesProduced(), 0);
 210 
 211         oneToTwo.compact();
 212 
 213         log("======================================");
 214         log("Finished");
 215         result1 = ssle1.wrap(appOut1, oneToTwo);
 216         checkResult(appOut1, oneToTwo, result1,
 217              Status.OK, HandshakeStatus.NEED_UNWRAP, 0, -1);
 218 
 219         oneToTwo.flip();
 220         result2 = ssle2.unwrap(oneToTwo, appIn2);
 221 
 222         checkResult(oneToTwo, appIn2, result2,
 223              Status.OK, HandshakeStatus.NEED_WRAP, result1.bytesProduced(), 0);
 224 
 225         oneToTwo.compact();
 226 
 227         log("======================================");
 228         log("CCS");
 229 
 230         result2 = ssle2.wrap(appOut2, twoToOne);
 231         checkResult(appOut2, twoToOne, result2,
 232             Status.OK, HandshakeStatus.NEED_WRAP, 0, -1);
 233         twoToOne.flip();
 234 
 235         result1 = ssle1.unwrap(twoToOne, appIn1);
 236         checkResult(twoToOne, appIn1, result1,
 237             Status.OK, HandshakeStatus.NEED_UNWRAP, result2.bytesProduced(), 0);
 238         twoToOne.compact();
 239 
 240         log("======================================");
 241         log("FINISHED");
 242 
 243         result2 = ssle2.wrap(appOut2, twoToOne);
 244         checkResult(appOut2, twoToOne, result2,
 245             Status.OK, HandshakeStatus.FINISHED, 0, -1);
 246         twoToOne.flip();
 247 
 248         result1 = ssle1.unwrap(twoToOne, appIn1);
 249         checkResult(twoToOne, appIn1, result1,
 250             Status.OK, HandshakeStatus.FINISHED, result2.bytesProduced(), 0);
 251         twoToOne.compact();
 252 
 253         log("======================================");
 254         log("Check Session/Ciphers");
 255 
 256         String suite = ssle1.getSession().getCipherSuite();
 257         if (!suite.equals(suite1[0])) {
 258             throw new Exception("suites not equal: " + suite + "/" +
 259                 suite1[0]);
 260         }
 261 
 262         suite = ssle2.getSession().getCipherSuite();
 263         if (!suite.equals(suite1[0])) {
 264             throw new Exception("suites not equal: " + suite + "/" +
 265                 suite1[0]);
 266         }
 267 
 268         log("======================================");
 269         log("DATA");
 270 
 271         result1 = ssle1.wrap(appOut1, oneToTwo);
 272         checkResult(appOut1, oneToTwo, result1,
 273             Status.OK, HandshakeStatus.NOT_HANDSHAKING,
 274             appOut1.capacity(), -1);
 275         oneToTwo.flip();
 276 
 277         result2 = ssle2.wrap(appOut2, twoToOne);
 278         checkResult(appOut2, twoToOne, result2,
 279             Status.OK, HandshakeStatus.NOT_HANDSHAKING,
 280             appOut2.capacity(), -1);
 281         twoToOne.flip();
 282 
 283         SSLEngineResult result3 = ssle1.unwrap(twoToOne, appIn1);
 284         checkResult(twoToOne, appIn1, result3,
 285             Status.OK, HandshakeStatus.NOT_HANDSHAKING,
 286             result2.bytesProduced(), result2.bytesConsumed());
 287         twoToOne.compact();
 288 
 289         SSLEngineResult result4 = ssle2.unwrap(oneToTwo, appIn2);
 290         checkResult(oneToTwo, appIn2, result4,
 291             Status.OK, HandshakeStatus.NOT_HANDSHAKING,
 292             result1.bytesProduced(), result1.bytesConsumed());
 293         oneToTwo.compact();
 294 
 295         appIn1.clear();
 296         appIn2.clear();
 297         appOut1.rewind();
 298         appOut2.rewind();
 299 
 300         log("======================================");
 301         log("RENEGOTIATE");
 302 
 303         ssle2.getSession().invalidate();
 304         ssle2.setNeedClientAuth(true);
 305 
 306         ssle1.setEnabledCipherSuites(suite2);
 307         ssle2.setEnabledCipherSuites(suite2);
 308 
 309         ssle2.beginHandshake();
 310 
 311         log("======================================");
 312         log("HelloRequest");
 313 
 314         result2 = ssle2.wrap(appOut2, twoToOne);
 315         checkResult(appOut2, twoToOne, result2,
 316             Status.OK, HandshakeStatus.NEED_UNWRAP, 0, -1);
 317         twoToOne.flip();
 318 
 319         result1 = ssle1.unwrap(twoToOne, appIn1);
 320         checkResult(twoToOne, appIn1, result1,
 321             Status.OK, HandshakeStatus.NEED_TASK, result2.bytesProduced(), 0);
 322         twoToOne.compact();
 323 
 324         runDelegatedTasks(ssle1);
 325 
 326         log("======================================");
 327         log("ClientHello");
 328 
 329         result1 = ssle1.wrap(appOut1, oneToTwo);
 330         checkResult(appOut1, oneToTwo, result1,
 331              Status.OK, HandshakeStatus.NEED_UNWRAP, 0, -1);
 332 
 333         oneToTwo.flip();
 334         result2 = ssle2.unwrap(oneToTwo, appIn2);
 335 
 336         checkResult(oneToTwo, appIn2, result2,
 337              Status.OK, HandshakeStatus.NEED_TASK, result1.bytesProduced(), 0);
 338         runDelegatedTasks(ssle2);
 339 
 340         oneToTwo.compact();
 341 
 342         log("======================================");
 343         log("CLIENT->SERVER DATA IN MIDDLE OF HANDSHAKE");
 344 
 345         result1 = ssle1.wrap(appOut1, oneToTwo);
 346         checkResult(appOut1, oneToTwo, result1,
 347             Status.OK, HandshakeStatus.NEED_UNWRAP,
 348             appOut1.capacity(), -1);
 349         oneToTwo.flip();
 350 
 351         result4 = ssle2.unwrap(oneToTwo, appIn2);
 352         checkResult(oneToTwo, appIn2, result4,
 353             Status.OK, HandshakeStatus.NEED_WRAP,
 354             result1.bytesProduced(), result1.bytesConsumed());
 355         oneToTwo.compact();
 356 
 357         appIn2.clear();
 358         appOut1.rewind();
 359 
 360         log("======================================");
 361         log("ServerHello");
 362 
 363         result2 = ssle2.wrap(appOut2, twoToOne);
 364         checkResult(appOut2, twoToOne, result2,
 365             Status.OK, HandshakeStatus.NEED_UNWRAP, 0, -1);
 366         twoToOne.flip();
 367 
 368         result1 = ssle1.unwrap(twoToOne, appIn1);
 369         checkResult(twoToOne, appIn1, result1,
 370             Status.OK, HandshakeStatus.NEED_TASK, result2.bytesProduced(), 0);
 371         twoToOne.compact();
 372 
 373         runDelegatedTasks(ssle1);
 374 
 375         log("======================================");
 376         log("SERVER->CLIENT DATA IN MIDDLE OF HANDSHAKE");
 377 
 378         result2 = ssle2.wrap(appOut2, twoToOne);
 379         checkResult(appOut2, twoToOne, result2,
 380             Status.OK, HandshakeStatus.NEED_UNWRAP,
 381             appOut2.capacity(), -1);
 382         twoToOne.flip();
 383 
 384         result3 = ssle1.unwrap(twoToOne, appIn1);
 385         checkResult(twoToOne, appIn1, result3,
 386             Status.OK, HandshakeStatus.NEED_WRAP,
 387             result2.bytesProduced(), result2.bytesConsumed());
 388         twoToOne.compact();
 389 
 390         appIn1.clear();
 391         appOut2.rewind();
 392 
 393         log("======================================");
 394         log("Client Cert");
 395         result1 = ssle1.wrap(appOut1, oneToTwo);
 396         checkResult(appOut1, oneToTwo, result1,
 397              Status.OK, HandshakeStatus.NEED_WRAP, 0, -1);
 398 
 399         oneToTwo.flip();
 400         result2 = ssle2.unwrap(oneToTwo, appIn2);
 401 
 402         checkResult(oneToTwo, appIn2, result2,
 403              Status.OK, HandshakeStatus.NEED_TASK, result1.bytesProduced(), 0);
 404         runDelegatedTasks(ssle2);
 405 
 406         oneToTwo.compact();
 407 
 408         log("======================================");
 409         log("Key Exchange");
 410         result1 = ssle1.wrap(appOut1, oneToTwo);
 411         checkResult(appOut1, oneToTwo, result1,
 412              Status.OK, HandshakeStatus.NEED_WRAP, 0, -1);
 413 
 414         oneToTwo.flip();
 415         result2 = ssle2.unwrap(oneToTwo, appIn2);
 416 
 417         checkResult(oneToTwo, appIn2, result2,
 418              Status.OK, HandshakeStatus.NEED_TASK,
 419              result1.bytesProduced(), 0);
 420         runDelegatedTasks(ssle2);
 421 
 422         oneToTwo.compact();
 423 
 424         log("======================================");
 425         log("CCS");
 426         result1 = ssle1.wrap(appOut1, oneToTwo);
 427         checkResult(appOut1, oneToTwo, result1,
 428              Status.OK, HandshakeStatus.NEED_WRAP, 0, -1);
 429 
 430         oneToTwo.flip();
 431         result2 = ssle2.unwrap(oneToTwo, appIn2);
 432 
 433         checkResult(oneToTwo, appIn2, result2,
 434              Status.OK, HandshakeStatus.NEED_UNWRAP,
 435              result1.bytesProduced(), 0);
 436 
 437         oneToTwo.compact();
 438 
 439         log("======================================");
 440         log("Finished");
 441         result1 = ssle1.wrap(appOut1, oneToTwo);
 442         checkResult(appOut1, oneToTwo, result1,
 443              Status.OK, HandshakeStatus.NEED_UNWRAP, 0, -1);
 444 
 445         oneToTwo.flip();
 446         result2 = ssle2.unwrap(oneToTwo, appIn2);
 447 
 448         checkResult(oneToTwo, appIn2, result2,
 449              Status.OK, HandshakeStatus.NEED_WRAP, result1.bytesProduced(), 0);
 450 
 451         oneToTwo.compact();
 452 
 453         log("======================================");
 454         log("CCS");
 455 
 456         result2 = ssle2.wrap(appOut2, twoToOne);
 457         checkResult(appOut2, twoToOne, result2,
 458             Status.OK, HandshakeStatus.NEED_WRAP, 0, -1);
 459         twoToOne.flip();
 460 
 461         result1 = ssle1.unwrap(twoToOne, appIn1);
 462         checkResult(twoToOne, appIn1, result1,
 463             Status.OK, HandshakeStatus.NEED_UNWRAP, result2.bytesProduced(), 0);
 464         twoToOne.compact();
 465 
 466         log("======================================");
 467         log("FINISHED");
 468 
 469         result2 = ssle2.wrap(appOut2, twoToOne);
 470         checkResult(appOut2, twoToOne, result2,
 471             Status.OK, HandshakeStatus.FINISHED, 0, -1);
 472         twoToOne.flip();
 473 
 474         result1 = ssle1.unwrap(twoToOne, appIn1);
 475         checkResult(twoToOne, appIn1, result1,
 476             Status.OK, HandshakeStatus.FINISHED, result2.bytesProduced(), 0);
 477         twoToOne.compact();
 478 
 479         log("======================================");
 480         log("Check Session/Ciphers");
 481 
 482         suite = ssle1.getSession().getCipherSuite();
 483         if (!suite.equals(suite2[0])) {
 484             throw new Exception("suites not equal: " + suite + "/" +
 485                 suite2[0]);
 486         }
 487 
 488         suite = ssle2.getSession().getCipherSuite();
 489         if (!suite.equals(suite2[0])) {
 490             throw new Exception("suites not equal: " + suite + "/" +
 491                 suite2[0]);
 492         }
 493 
 494         log("======================================");
 495         log("DATA USING NEW SESSION");
 496 
 497         result1 = ssle1.wrap(appOut1, oneToTwo);
 498         checkResult(appOut1, oneToTwo, result1,
 499             Status.OK, HandshakeStatus.NOT_HANDSHAKING,
 500             appOut1.capacity(), -1);
 501         oneToTwo.flip();
 502 
 503         result2 = ssle2.wrap(appOut2, twoToOne);
 504         checkResult(appOut2, twoToOne, result2,
 505             Status.OK, HandshakeStatus.NOT_HANDSHAKING,
 506             appOut2.capacity(), -1);
 507         twoToOne.flip();
 508 
 509         result3 = ssle1.unwrap(twoToOne, appIn1);
 510         checkResult(twoToOne, appIn1, result3,
 511             Status.OK, HandshakeStatus.NOT_HANDSHAKING,
 512             result2.bytesProduced(), result2.bytesConsumed());
 513         twoToOne.compact();
 514 
 515         result4 = ssle2.unwrap(oneToTwo, appIn2);
 516         checkResult(oneToTwo, appIn2, result4,
 517             Status.OK, HandshakeStatus.NOT_HANDSHAKING,
 518             result1.bytesProduced(), result1.bytesConsumed());
 519         oneToTwo.compact();
 520 
 521         appIn1.clear();
 522         appIn2.clear();
 523         appOut1.rewind();
 524         appOut2.rewind();
 525 
 526         log("======================================");
 527         log("CN");
 528 
 529         if (isHandshaking(ssle1)) {
 530             throw new Exception("ssle1 IS handshaking");
 531         }
 532 
 533         if (isHandshaking(ssle2)) {
 534             throw new Exception("ssle2 IS handshaking");
 535         }
 536 
 537         ssle2.closeOutbound();
 538 
 539         if (!isHandshaking(ssle2)) {
 540             throw new Exception("ssle1 IS NOT handshaking");
 541         }
 542 
 543         appOut1.rewind();
 544         appOut2.rewind();
 545 
 546         result2 = ssle2.wrap(appOut2, twoToOne);
 547         checkResult(appOut2, twoToOne, result2,
 548             Status.CLOSED, HandshakeStatus.NEED_UNWRAP, 0, -1);
 549         twoToOne.flip();
 550 
 551         if (ssle1.isInboundDone()) {
 552             throw new Exception("ssle1 inboundDone");
 553         }
 554 
 555         result1 = ssle1.unwrap(twoToOne, appIn1);
 556         checkResult(twoToOne, appIn1, result1,
 557             Status.CLOSED, HandshakeStatus.NEED_WRAP,
 558             result2.bytesProduced(), 0);
 559         twoToOne.compact();
 560 
 561         if (!ssle1.isInboundDone()) {
 562             throw new Exception("ssle1 inboundDone");
 563         }
 564 
 565         if (!isHandshaking(ssle1)) {
 566             throw new Exception("ssle1 IS NOT handshaking");
 567         }
 568 
 569         result2 = ssle2.wrap(appOut2, twoToOne);
 570         checkResult(appOut2, twoToOne, result2,
 571             Status.CLOSED, HandshakeStatus.NEED_UNWRAP, 0, 0);
 572         twoToOne.flip();
 573 
 574         log("======================================");
 575         log("CN response");
 576 
 577         if (ssle1.isOutboundDone()) {
 578             throw new Exception("ssle1 outboundDone");
 579         }
 580 
 581         result1 = ssle1.wrap(appOut1, oneToTwo);
 582         checkResult(appOut1, oneToTwo, result1,
 583              Status.CLOSED, HandshakeStatus.NOT_HANDSHAKING, 0, -1);
 584 
 585         if (!ssle1.isOutboundDone()) {
 586             throw new Exception("ssle1 outboundDone is NOT done");
 587         }
 588 
 589         if (isHandshaking(ssle1)) {
 590             throw new Exception("ssle1 IS handshaking");
 591         }
 592 
 593         oneToTwo.flip();
 594 
 595         if (!ssle2.isOutboundDone()) {
 596             throw new Exception("ssle1 outboundDone");
 597         }
 598 
 599         if (ssle2.isInboundDone()) {
 600             throw new Exception("ssle1 inboundDone");
 601         }
 602 
 603         result2 = ssle2.unwrap(oneToTwo, appIn2);
 604 
 605         checkResult(oneToTwo, appIn2, result2,
 606              Status.CLOSED, HandshakeStatus.NOT_HANDSHAKING,
 607              result1.bytesProduced(), 0);
 608 
 609         if (!ssle2.isOutboundDone()) {
 610             throw new Exception("ssle1 outboundDone is NOT done");
 611         }
 612 
 613         if (!ssle2.isInboundDone()) {
 614             throw new Exception("ssle1 inboundDone is NOT done");
 615         }
 616 
 617         if (isHandshaking(ssle2)) {
 618             throw new Exception("ssle1 IS handshaking");
 619         }
 620 
 621         oneToTwo.compact();
 622     }
 623 
 624     public static void main(String args[]) throws Exception {
 625         // reset the security property to make sure that the algorithms
 626         // and keys used in this test are not disabled.
 627         Security.setProperty("jdk.tls.disabledAlgorithms", "");
 628 
 629         CheckStatus cs;
 630 
 631         cs = new CheckStatus();
 632 
 633         cs.createSSLEngines();
 634 
 635         cs.test();
 636 
 637         System.out.println("Test Passed.");
 638     }
 639 
 640     /*
 641      * **********************************************************
 642      * Majority of the test case is above, below is just setup stuff
 643      * **********************************************************
 644      */
 645 
 646     public CheckStatus() throws Exception {
 647         sslc = getSSLContext(keyFilename, trustFilename);
 648     }
 649 
 650     /*
 651      * Create an initialized SSLContext to use for this test.
 652      */
 653     private SSLContext getSSLContext(String keyFile, String trustFile)
 654             throws Exception {
 655 
 656         KeyStore ks = KeyStore.getInstance("JKS");
 657         KeyStore ts = KeyStore.getInstance("JKS");
 658 
 659         char[] passphrase = "passphrase".toCharArray();
 660 
 661         ks.load(new FileInputStream(keyFile), passphrase);
 662         ts.load(new FileInputStream(trustFile), passphrase);
 663 
 664         KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
 665         kmf.init(ks, passphrase);
 666 
 667         TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
 668         tmf.init(ts);
 669 
 670         SSLContext sslCtx = SSLContext.getInstance("TLS");
 671 
 672         sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
 673 
 674         return sslCtx;
 675     }
 676 
 677     private void createBuffers() {
 678         // Size the buffers as appropriate.
 679 
 680         SSLSession session = ssle1.getSession();
 681         int appBufferMax = session.getApplicationBufferSize();
 682         int netBufferMax = session.getPacketBufferSize();
 683 
 684         appIn1 = ByteBuffer.allocateDirect(appBufferMax + 50);
 685         appIn2 = ByteBuffer.allocateDirect(appBufferMax + 50);
 686 
 687         oneToTwo = ByteBuffer.allocateDirect(netBufferMax);
 688         twoToOne = ByteBuffer.allocateDirect(netBufferMax);
 689 
 690         appOut1 = ByteBuffer.wrap("Hi Engine2, I'm SSLEngine1".getBytes());
 691         appOut2 = ByteBuffer.wrap("Hello Engine1, I'm SSLEngine2".getBytes());
 692 
 693         log("AppOut1 = " + appOut1);
 694         log("AppOut2 = " + appOut2);
 695         log("");
 696     }
 697 
 698     private static void runDelegatedTasks(SSLEngine engine) throws Exception {
 699 
 700         Runnable runnable;
 701         while ((runnable = engine.getDelegatedTask()) != null) {
 702             log("running delegated task...");
 703             runnable.run();
 704         }
 705     }
 706 
 707     private static void checkTransfer(ByteBuffer a, ByteBuffer b)
 708             throws Exception {
 709         a.flip();
 710         b.flip();
 711 
 712         if (!a.equals(b)) {
 713             throw new Exception("Data didn't transfer cleanly");
 714         } else {
 715             log("Data transferred cleanly");
 716         }
 717 
 718         a.position(a.limit());
 719         b.position(b.limit());
 720         a.limit(a.capacity());
 721         b.limit(b.capacity());
 722     }
 723 
 724     private static void log(String str) {
 725         if (debug) {
 726             System.out.println(str);
 727         }
 728     }
 729 }