1 /*
   2  * Copyright (c) 1996, 2013, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 
  27 package sun.security.ssl;
  28 
  29 import java.io.*;
  30 import java.util.*;
  31 import java.security.*;
  32 import java.security.NoSuchAlgorithmException;
  33 import java.security.AccessController;
  34 import java.security.AlgorithmConstraints;
  35 import java.security.AccessControlContext;
  36 import java.security.PrivilegedExceptionAction;
  37 import java.security.PrivilegedActionException;
  38 
  39 import javax.crypto.*;
  40 import javax.crypto.spec.*;
  41 
  42 import javax.net.ssl.*;
  43 import sun.misc.HexDumpEncoder;
  44 
  45 import sun.security.internal.spec.*;
  46 import sun.security.internal.interfaces.TlsMasterSecret;
  47 
  48 import sun.security.ssl.HandshakeMessage.*;
  49 import sun.security.ssl.CipherSuite.*;
  50 
  51 import static sun.security.ssl.CipherSuite.PRF.*;
  52 import static sun.security.ssl.CipherSuite.CipherType.*;
  53 
  54 /**
  55  * Handshaker ... processes handshake records from an SSL V3.0
  56  * data stream, handling all the details of the handshake protocol.
  57  *
  58  * Note that the real protocol work is done in two subclasses, the  base
  59  * class just provides the control flow and key generation framework.
  60  *
  61  * @author David Brownell
  62  */
  63 abstract class Handshaker {
  64 
  65     // protocol version being established using this Handshaker
  66     ProtocolVersion protocolVersion;
  67 
  68     // the currently active protocol version during a renegotiation
  69     ProtocolVersion     activeProtocolVersion;
  70 
  71     // security parameters for secure renegotiation.
  72     boolean             secureRenegotiation;
  73     byte[]              clientVerifyData;
  74     byte[]              serverVerifyData;
  75 
  76     // Is it an initial negotiation  or a renegotiation?
  77     boolean                     isInitialHandshake;
  78 
  79     // List of enabled protocols
  80     private ProtocolList        enabledProtocols;
  81 
  82     // List of enabled CipherSuites
  83     private CipherSuiteList     enabledCipherSuites;
  84 
  85     // The endpoint identification protocol
  86     String              identificationProtocol;
  87 
  88     // The cryptographic algorithm constraints
  89     private AlgorithmConstraints    algorithmConstraints = null;
  90 
  91     // Local supported signature and algorithms
  92     Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs;
  93 
  94     // Peer supported signature and algorithms
  95     Collection<SignatureAndHashAlgorithm> peerSupportedSignAlgs;
  96 
  97     /*
  98 
  99     /*
 100      * List of active protocols
 101      *
 102      * Active protocols is a subset of enabled protocols, and will
 103      * contain only those protocols that have vaild cipher suites
 104      * enabled.
 105      */
 106     private ProtocolList       activeProtocols;
 107 
 108     /*
 109      * List of active cipher suites
 110      *
 111      * Active cipher suites is a subset of enabled cipher suites, and will
 112      * contain only those cipher suites available for the active protocols.
 113      */
 114     private CipherSuiteList    activeCipherSuites;
 115 
 116     // The server name indication and matchers
 117     List<SNIServerName>         serverNames =
 118                                     Collections.<SNIServerName>emptyList();
 119     Collection<SNIMatcher>      sniMatchers =
 120                                     Collections.<SNIMatcher>emptyList();
 121 
 122     private boolean             isClient;
 123     private boolean             needCertVerify;
 124 
 125     SSLSocketImpl               conn = null;
 126     SSLEngineImpl               engine = null;
 127 
 128     HandshakeHash               handshakeHash;
 129     HandshakeInStream           input;
 130     HandshakeOutStream          output;
 131     int                         state;
 132     SSLContextImpl              sslContext;
 133     RandomCookie                clnt_random, svr_random;
 134     SSLSessionImpl              session;
 135 
 136     // current CipherSuite. Never null, initially SSL_NULL_WITH_NULL_NULL
 137     CipherSuite         cipherSuite;
 138 
 139     // current key exchange. Never null, initially K_NULL
 140     KeyExchange         keyExchange;
 141 
 142     /* True if this session is being resumed (fast handshake) */
 143     boolean             resumingSession;
 144 
 145     /* True if it's OK to start a new SSL session */
 146     boolean             enableNewSession;
 147 
 148     // Temporary storage for the individual keys. Set by
 149     // calculateConnectionKeys() and cleared once the ciphers are
 150     // activated.
 151     private SecretKey clntWriteKey, svrWriteKey;
 152     private IvParameterSpec clntWriteIV, svrWriteIV;
 153     private SecretKey clntMacSecret, svrMacSecret;
 154 
 155     /*
 156      * Delegated task subsystem data structures.
 157      *
 158      * If thrown is set, we need to propagate this back immediately
 159      * on entry into processMessage().
 160      *
 161      * Data is protected by the SSLEngine.this lock.
 162      */
 163     private volatile boolean taskDelegated = false;
 164     private volatile DelegatedTask<?> delegatedTask = null;
 165     private volatile Exception thrown = null;
 166 
 167     // Could probably use a java.util.concurrent.atomic.AtomicReference
 168     // here instead of using this lock.  Consider changing.
 169     private Object thrownLock = new Object();
 170 
 171     /* Class and subclass dynamic debugging support */
 172     static final Debug debug = Debug.getInstance("ssl");
 173 
 174     // By default, disable the unsafe legacy session renegotiation
 175     static final boolean allowUnsafeRenegotiation = Debug.getBooleanProperty(
 176                     "sun.security.ssl.allowUnsafeRenegotiation", false);
 177 
 178     // For maximum interoperability and backward compatibility, RFC 5746
 179     // allows server (or client) to accept ClientHello (or ServerHello)
 180     // message without the secure renegotiation_info extension or SCSV.
 181     //
 182     // For maximum security, RFC 5746 also allows server (or client) to
 183     // reject such message with a fatal "handshake_failure" alert.
 184     //
 185     // By default, allow such legacy hello messages.
 186     static final boolean allowLegacyHelloMessages = Debug.getBooleanProperty(
 187                     "sun.security.ssl.allowLegacyHelloMessages", true);
 188 
 189     // need to dispose the object when it is invalidated
 190     boolean invalidated;
 191 
 192     Handshaker(SSLSocketImpl c, SSLContextImpl context,
 193             ProtocolList enabledProtocols, boolean needCertVerify,
 194             boolean isClient, ProtocolVersion activeProtocolVersion,
 195             boolean isInitialHandshake, boolean secureRenegotiation,
 196             byte[] clientVerifyData, byte[] serverVerifyData) {
 197         this.conn = c;
 198         init(context, enabledProtocols, needCertVerify, isClient,
 199             activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 200             clientVerifyData, serverVerifyData);
 201     }
 202 
 203     Handshaker(SSLEngineImpl engine, SSLContextImpl context,
 204             ProtocolList enabledProtocols, boolean needCertVerify,
 205             boolean isClient, ProtocolVersion activeProtocolVersion,
 206             boolean isInitialHandshake, boolean secureRenegotiation,
 207             byte[] clientVerifyData, byte[] serverVerifyData) {
 208         this.engine = engine;
 209         init(context, enabledProtocols, needCertVerify, isClient,
 210             activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 211             clientVerifyData, serverVerifyData);
 212     }
 213 
 214     private void init(SSLContextImpl context, ProtocolList enabledProtocols,
 215             boolean needCertVerify, boolean isClient,
 216             ProtocolVersion activeProtocolVersion,
 217             boolean isInitialHandshake, boolean secureRenegotiation,
 218             byte[] clientVerifyData, byte[] serverVerifyData) {
 219 
 220         if (debug != null && Debug.isOn("handshake")) {
 221             System.out.println(
 222                 "Allow unsafe renegotiation: " + allowUnsafeRenegotiation +
 223                 "\nAllow legacy hello messages: " + allowLegacyHelloMessages +
 224                 "\nIs initial handshake: " + isInitialHandshake +
 225                 "\nIs secure renegotiation: " + secureRenegotiation);
 226         }
 227 
 228         this.sslContext = context;
 229         this.isClient = isClient;
 230         this.needCertVerify = needCertVerify;
 231         this.activeProtocolVersion = activeProtocolVersion;
 232         this.isInitialHandshake = isInitialHandshake;
 233         this.secureRenegotiation = secureRenegotiation;
 234         this.clientVerifyData = clientVerifyData;
 235         this.serverVerifyData = serverVerifyData;
 236         enableNewSession = true;
 237         invalidated = false;
 238 
 239         setCipherSuite(CipherSuite.C_NULL);
 240         setEnabledProtocols(enabledProtocols);
 241 
 242         if (conn != null) {
 243             algorithmConstraints = new SSLAlgorithmConstraints(conn, true);
 244         } else {        // engine != null
 245             algorithmConstraints = new SSLAlgorithmConstraints(engine, true);
 246         }
 247 
 248 
 249         //
 250         // In addition to the connection state machine, controlling
 251         // how the connection deals with the different sorts of records
 252         // that get sent (notably handshake transitions!), there's
 253         // also a handshaking state machine that controls message
 254         // sequencing.
 255         //
 256         // It's a convenient artifact of the protocol that this can,
 257         // with only a couple of minor exceptions, be driven by the
 258         // type constant for the last message seen:  except for the
 259         // client's cert verify, those constants are in a convenient
 260         // order to drastically simplify state machine checking.
 261         //
 262         state = -2;  // initialized but not activated
 263     }
 264 
 265     /*
 266      * Reroutes calls to the SSLSocket or SSLEngine (*SE).
 267      *
 268      * We could have also done it by extra classes
 269      * and letting them override, but this seemed much
 270      * less involved.
 271      */
 272     void fatalSE(byte b, String diagnostic) throws IOException {
 273         fatalSE(b, diagnostic, null);
 274     }
 275 
 276     void fatalSE(byte b, Throwable cause) throws IOException {
 277         fatalSE(b, null, cause);
 278     }
 279 
 280     void fatalSE(byte b, String diagnostic, Throwable cause)
 281             throws IOException {
 282         if (conn != null) {
 283             conn.fatal(b, diagnostic, cause);
 284         } else {
 285             engine.fatal(b, diagnostic, cause);
 286         }
 287     }
 288 
 289     void warningSE(byte b) {
 290         if (conn != null) {
 291             conn.warning(b);
 292         } else {
 293             engine.warning(b);
 294         }
 295     }
 296 
 297     // ONLY used by ClientHandshaker to setup the peer host in SSLSession.
 298     String getHostSE() {
 299         if (conn != null) {
 300             return conn.getHost();
 301         } else {
 302             return engine.getPeerHost();
 303         }
 304     }
 305 
 306     // ONLY used by ServerHandshaker to setup the peer host in SSLSession.
 307     String getHostAddressSE() {
 308         if (conn != null) {
 309             return conn.getInetAddress().getHostAddress();
 310         } else {
 311             /*
 312              * This is for caching only, doesn't matter that's is really
 313              * a hostname.  The main thing is that it doesn't do
 314              * a reverse DNS lookup, potentially slowing things down.
 315              */
 316             return engine.getPeerHost();
 317         }
 318     }
 319 
 320     boolean isLoopbackSE() {
 321         if (conn != null) {
 322             return conn.getInetAddress().isLoopbackAddress();
 323         } else {
 324             return false;
 325         }
 326     }
 327 
 328     int getPortSE() {
 329         if (conn != null) {
 330             return conn.getPort();
 331         } else {
 332             return engine.getPeerPort();
 333         }
 334     }
 335 
 336     int getLocalPortSE() {
 337         if (conn != null) {
 338             return conn.getLocalPort();
 339         } else {
 340             return -1;
 341         }
 342     }
 343 
 344     AccessControlContext getAccSE() {
 345         if (conn != null) {
 346             return conn.getAcc();
 347         } else {
 348             return engine.getAcc();
 349         }
 350     }
 351 
 352     private void setVersionSE(ProtocolVersion protocolVersion) {
 353         if (conn != null) {
 354             conn.setVersion(protocolVersion);
 355         } else {
 356             engine.setVersion(protocolVersion);
 357         }
 358     }
 359 
 360     /**
 361      * Set the active protocol version and propagate it to the SSLSocket
 362      * and our handshake streams. Called from ClientHandshaker
 363      * and ServerHandshaker with the negotiated protocol version.
 364      */
 365     void setVersion(ProtocolVersion protocolVersion) {
 366         this.protocolVersion = protocolVersion;
 367         setVersionSE(protocolVersion);
 368 
 369         output.r.setVersion(protocolVersion);
 370     }
 371 
 372     /**
 373      * Set the enabled protocols. Called from the constructor or
 374      * SSLSocketImpl/SSLEngineImpl.setEnabledProtocols() (if the
 375      * handshake is not yet in progress).
 376      */
 377     void setEnabledProtocols(ProtocolList enabledProtocols) {
 378         activeCipherSuites = null;
 379         activeProtocols = null;
 380 
 381         this.enabledProtocols = enabledProtocols;
 382     }
 383 
 384     /**
 385      * Set the enabled cipher suites. Called from
 386      * SSLSocketImpl/SSLEngineImpl.setEnabledCipherSuites() (if the
 387      * handshake is not yet in progress).
 388      */
 389     void setEnabledCipherSuites(CipherSuiteList enabledCipherSuites) {
 390         activeCipherSuites = null;
 391         activeProtocols = null;
 392         this.enabledCipherSuites = enabledCipherSuites;
 393     }
 394 
 395     /**
 396      * Set the algorithm constraints. Called from the constructor or
 397      * SSLSocketImpl/SSLEngineImpl.setAlgorithmConstraints() (if the
 398      * handshake is not yet in progress).
 399      */
 400     void setAlgorithmConstraints(AlgorithmConstraints algorithmConstraints) {
 401         activeCipherSuites = null;
 402         activeProtocols = null;
 403 
 404         this.algorithmConstraints =
 405             new SSLAlgorithmConstraints(algorithmConstraints);
 406         this.localSupportedSignAlgs = null;
 407     }
 408 
 409     Collection<SignatureAndHashAlgorithm> getLocalSupportedSignAlgs() {
 410         if (localSupportedSignAlgs == null) {
 411             localSupportedSignAlgs =
 412                 SignatureAndHashAlgorithm.getSupportedAlgorithms(
 413                                                     algorithmConstraints);
 414         }
 415 
 416         return localSupportedSignAlgs;
 417     }
 418 
 419     void setPeerSupportedSignAlgs(
 420             Collection<SignatureAndHashAlgorithm> algorithms) {
 421         peerSupportedSignAlgs =
 422             new ArrayList<SignatureAndHashAlgorithm>(algorithms);
 423     }
 424 
 425     Collection<SignatureAndHashAlgorithm> getPeerSupportedSignAlgs() {
 426         return peerSupportedSignAlgs;
 427     }
 428 
 429 
 430     /**
 431      * Set the identification protocol. Called from the constructor or
 432      * SSLSocketImpl/SSLEngineImpl.setIdentificationProtocol() (if the
 433      * handshake is not yet in progress).
 434      */
 435     void setIdentificationProtocol(String protocol) {
 436         this.identificationProtocol = protocol;
 437     }
 438 
 439     /**
 440      * Sets the server name indication of the handshake.
 441      */
 442     void setSNIServerNames(List<SNIServerName> serverNames) {
 443         // The serverNames parameter is unmodifiable.
 444         this.serverNames = serverNames;
 445     }
 446 
 447     /**
 448      * Sets the server name matchers of the handshaking.
 449      */
 450     void setSNIMatchers(Collection<SNIMatcher> sniMatchers) {
 451         // The sniMatchers parameter is unmodifiable.
 452         this.sniMatchers = sniMatchers;
 453     }
 454 
 455     /**
 456      * Prior to handshaking, activate the handshake and initialize the version,
 457      * input stream and output stream.
 458      */
 459     void activate(ProtocolVersion helloVersion) throws IOException {
 460         if (activeProtocols == null) {
 461             activeProtocols = getActiveProtocols();
 462         }
 463 
 464         if (activeProtocols.collection().isEmpty() ||
 465                 activeProtocols.max.v == ProtocolVersion.NONE.v) {
 466             throw new SSLHandshakeException("No appropriate protocol");
 467         }
 468 
 469         if (activeCipherSuites == null) {
 470             activeCipherSuites = getActiveCipherSuites();
 471         }
 472 
 473         if (activeCipherSuites.collection().isEmpty()) {
 474             throw new SSLHandshakeException("No appropriate cipher suite");
 475         }
 476 
 477         // temporary protocol version until the actual protocol version
 478         // is negotiated in the Hello exchange. This affects the record
 479         // version we sent with the ClientHello.
 480         if (!isInitialHandshake) {
 481             protocolVersion = activeProtocolVersion;
 482         } else {
 483             protocolVersion = activeProtocols.max;
 484         }
 485 
 486         if (helloVersion == null || helloVersion.v == ProtocolVersion.NONE.v) {
 487             helloVersion = activeProtocols.helloVersion;
 488         }
 489 
 490         // We accumulate digests of the handshake messages so that
 491         // we can read/write CertificateVerify and Finished messages,
 492         // getting assurance against some particular active attacks.
 493         handshakeHash = new HandshakeHash(needCertVerify);
 494 
 495         // Generate handshake input/output stream.
 496         input = new HandshakeInStream(handshakeHash);
 497         if (conn != null) {
 498             output = new HandshakeOutStream(protocolVersion, helloVersion,
 499                                         handshakeHash, conn);
 500             conn.getAppInputStream().r.setHandshakeHash(handshakeHash);
 501             conn.getAppInputStream().r.setHelloVersion(helloVersion);
 502             conn.getAppOutputStream().r.setHelloVersion(helloVersion);
 503         } else {
 504             output = new HandshakeOutStream(protocolVersion, helloVersion,
 505                                         handshakeHash, engine);
 506             engine.inputRecord.setHandshakeHash(handshakeHash);
 507             engine.inputRecord.setHelloVersion(helloVersion);
 508             engine.outputRecord.setHelloVersion(helloVersion);
 509         }
 510 
 511         // move state to activated
 512         state = -1;
 513     }
 514 
 515     /**
 516      * Set cipherSuite and keyExchange to the given CipherSuite.
 517      * Does not perform any verification that this is a valid selection,
 518      * this must be done before calling this method.
 519      */
 520     void setCipherSuite(CipherSuite s) {
 521         this.cipherSuite = s;
 522         this.keyExchange = s.keyExchange;
 523     }
 524 
 525     /**
 526      * Check if the given ciphersuite is enabled and available.
 527      * Does not check if the required server certificates are available.
 528      */
 529     boolean isNegotiable(CipherSuite s) {
 530         if (activeCipherSuites == null) {
 531             activeCipherSuites = getActiveCipherSuites();
 532         }
 533 
 534         return activeCipherSuites.contains(s) && s.isNegotiable();
 535     }
 536 
 537     /**
 538      * Check if the given protocol version is enabled and available.
 539      */
 540     boolean isNegotiable(ProtocolVersion protocolVersion) {
 541         if (activeProtocols == null) {
 542             activeProtocols = getActiveProtocols();
 543         }
 544 
 545         return activeProtocols.contains(protocolVersion);
 546     }
 547 
 548     /**
 549      * Select a protocol version from the list. Called from
 550      * ServerHandshaker to negotiate protocol version.
 551      *
 552      * Return the lower of the protocol version suggested in the
 553      * clien hello and the highest supported by the server.
 554      */
 555     ProtocolVersion selectProtocolVersion(ProtocolVersion protocolVersion) {
 556         if (activeProtocols == null) {
 557             activeProtocols = getActiveProtocols();
 558         }
 559 
 560         return activeProtocols.selectProtocolVersion(protocolVersion);
 561     }
 562 
 563     /**
 564      * Get the active cipher suites.
 565      *
 566      * In TLS 1.1, many weak or vulnerable cipher suites were obsoleted,
 567      * such as TLS_RSA_EXPORT_WITH_RC4_40_MD5. The implementation MUST NOT
 568      * negotiate these cipher suites in TLS 1.1 or later mode.
 569      *
 570      * Therefore, when the active protocols only include TLS 1.1 or later,
 571      * the client cannot request to negotiate those obsoleted cipher
 572      * suites.  That is, the obsoleted suites should not be included in the
 573      * client hello. So we need to create a subset of the enabled cipher
 574      * suites, the active cipher suites, which does not contain obsoleted
 575      * cipher suites of the minimum active protocol.
 576      *
 577      * Return empty list instead of null if no active cipher suites.
 578      */
 579     CipherSuiteList getActiveCipherSuites() {
 580         if (activeCipherSuites == null) {
 581             if (activeProtocols == null) {
 582                 activeProtocols = getActiveProtocols();
 583             }
 584 
 585             ArrayList<CipherSuite> suites = new ArrayList<>();
 586             if (!(activeProtocols.collection().isEmpty()) &&
 587                     activeProtocols.min.v != ProtocolVersion.NONE.v) {
 588                 for (CipherSuite suite : enabledCipherSuites.collection()) {
 589                     if (suite.obsoleted > activeProtocols.min.v &&
 590                             suite.supported <= activeProtocols.max.v) {
 591                         if (algorithmConstraints.permits(
 592                                 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
 593                                 suite.name, null)) {
 594                             suites.add(suite);
 595                         }
 596                     } else if (debug != null && Debug.isOn("verbose")) {
 597                         if (suite.obsoleted <= activeProtocols.min.v) {
 598                             System.out.println(
 599                                 "Ignoring obsoleted cipher suite: " + suite);
 600                         } else {
 601                             System.out.println(
 602                                 "Ignoring unsupported cipher suite: " + suite);
 603                         }
 604                     }
 605                 }
 606             }
 607             activeCipherSuites = new CipherSuiteList(suites);
 608         }
 609 
 610         return activeCipherSuites;
 611     }
 612 
 613     /*
 614      * Get the active protocol versions.
 615      *
 616      * In TLS 1.1, many weak or vulnerable cipher suites were obsoleted,
 617      * such as TLS_RSA_EXPORT_WITH_RC4_40_MD5. The implementation MUST NOT
 618      * negotiate these cipher suites in TLS 1.1 or later mode.
 619      *
 620      * For example, if "TLS_RSA_EXPORT_WITH_RC4_40_MD5" is the
 621      * only enabled cipher suite, the client cannot request TLS 1.1 or
 622      * later, even though TLS 1.1 or later is enabled.  We need to create a
 623      * subset of the enabled protocols, called the active protocols, which
 624      * contains protocols appropriate to the list of enabled Ciphersuites.
 625      *
 626      * Return empty list instead of null if no active protocol versions.
 627      */
 628     ProtocolList getActiveProtocols() {
 629         if (activeProtocols == null) {
 630             ArrayList<ProtocolVersion> protocols = new ArrayList<>(4);
 631             for (ProtocolVersion protocol : enabledProtocols.collection()) {
 632                 boolean found = false;
 633                 for (CipherSuite suite : enabledCipherSuites.collection()) {
 634                     if (suite.isAvailable() && suite.obsoleted > protocol.v &&
 635                                                suite.supported <= protocol.v) {
 636                         if (algorithmConstraints.permits(
 637                                 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
 638                                 suite.name, null)) {
 639                             protocols.add(protocol);
 640                             found = true;
 641                             break;
 642                         } else if (debug != null && Debug.isOn("verbose")) {
 643                             System.out.println(
 644                                 "Ignoring disabled cipher suite: " + suite +
 645                                  " for " + protocol);
 646                         }
 647                     } else if (debug != null && Debug.isOn("verbose")) {
 648                         System.out.println(
 649                             "Ignoring unsupported cipher suite: " + suite +
 650                                  " for " + protocol);
 651                     }
 652                 }
 653                 if (!found && (debug != null) && Debug.isOn("handshake")) {
 654                     System.out.println(
 655                         "No available cipher suite for " + protocol);
 656                 }
 657             }
 658             activeProtocols = new ProtocolList(protocols);
 659         }
 660 
 661         return activeProtocols;
 662     }
 663 
 664     /**
 665      * As long as handshaking has not activated, we can
 666      * change whether session creations are allowed.
 667      *
 668      * Callers should do their own checking if handshaking
 669      * has activated.
 670      */
 671     void setEnableSessionCreation(boolean newSessions) {
 672         enableNewSession = newSessions;
 673     }
 674 
 675     /**
 676      * Create a new read cipher and return it to caller.
 677      */
 678     CipherBox newReadCipher() throws NoSuchAlgorithmException {
 679         BulkCipher cipher = cipherSuite.cipher;
 680         CipherBox box;
 681         if (isClient) {
 682             box = cipher.newCipher(protocolVersion, svrWriteKey, svrWriteIV,
 683                                    sslContext.getSecureRandom(), false);
 684             svrWriteKey = null;
 685             svrWriteIV = null;
 686         } else {
 687             box = cipher.newCipher(protocolVersion, clntWriteKey, clntWriteIV,
 688                                    sslContext.getSecureRandom(), false);
 689             clntWriteKey = null;
 690             clntWriteIV = null;
 691         }
 692         return box;
 693     }
 694 
 695     /**
 696      * Create a new write cipher and return it to caller.
 697      */
 698     CipherBox newWriteCipher() throws NoSuchAlgorithmException {
 699         BulkCipher cipher = cipherSuite.cipher;
 700         CipherBox box;
 701         if (isClient) {
 702             box = cipher.newCipher(protocolVersion, clntWriteKey, clntWriteIV,
 703                                    sslContext.getSecureRandom(), true);
 704             clntWriteKey = null;
 705             clntWriteIV = null;
 706         } else {
 707             box = cipher.newCipher(protocolVersion, svrWriteKey, svrWriteIV,
 708                                    sslContext.getSecureRandom(), true);
 709             svrWriteKey = null;
 710             svrWriteIV = null;
 711         }
 712         return box;
 713     }
 714 
 715     /**
 716      * Create a new read MAC and return it to caller.
 717      */
 718     Authenticator newReadAuthenticator()
 719             throws NoSuchAlgorithmException, InvalidKeyException {
 720 
 721         Authenticator authenticator = null;
 722         if (cipherSuite.cipher.cipherType == AEAD_CIPHER) {
 723             authenticator = new Authenticator(protocolVersion);
 724         } else {
 725             MacAlg macAlg = cipherSuite.macAlg;
 726             if (isClient) {
 727                 authenticator = macAlg.newMac(protocolVersion, svrMacSecret);
 728                 svrMacSecret = null;
 729             } else {
 730                 authenticator = macAlg.newMac(protocolVersion, clntMacSecret);
 731                 clntMacSecret = null;
 732             }
 733         }
 734 
 735         return authenticator;
 736     }
 737 
 738     /**
 739      * Create a new write MAC and return it to caller.
 740      */
 741     Authenticator newWriteAuthenticator()
 742             throws NoSuchAlgorithmException, InvalidKeyException {
 743 
 744         Authenticator authenticator = null;
 745         if (cipherSuite.cipher.cipherType == AEAD_CIPHER) {
 746             authenticator = new Authenticator(protocolVersion);
 747         } else {
 748             MacAlg macAlg = cipherSuite.macAlg;
 749             if (isClient) {
 750                 authenticator = macAlg.newMac(protocolVersion, clntMacSecret);
 751                 clntMacSecret = null;
 752             } else {
 753                 authenticator = macAlg.newMac(protocolVersion, svrMacSecret);
 754                 svrMacSecret = null;
 755             }
 756         }
 757 
 758         return authenticator;
 759     }
 760 
 761     /*
 762      * Returns true iff the handshake sequence is done, so that
 763      * this freshly created session can become the current one.
 764      */
 765     boolean isDone() {
 766         return state == HandshakeMessage.ht_finished;
 767     }
 768 
 769 
 770     /*
 771      * Returns the session which was created through this
 772      * handshake sequence ... should be called after isDone()
 773      * returns true.
 774      */
 775     SSLSessionImpl getSession() {
 776         return session;
 777     }
 778 
 779     /*
 780      * Set the handshake session
 781      */
 782     void setHandshakeSessionSE(SSLSessionImpl handshakeSession) {
 783         if (conn != null) {
 784             conn.setHandshakeSession(handshakeSession);
 785         } else {
 786             engine.setHandshakeSession(handshakeSession);
 787         }
 788     }
 789 
 790     /*
 791      * Returns true if renegotiation is in use for this connection.
 792      */
 793     boolean isSecureRenegotiation() {
 794         return secureRenegotiation;
 795     }
 796 
 797     /*
 798      * Returns the verify_data from the Finished message sent by the client.
 799      */
 800     byte[] getClientVerifyData() {
 801         return clientVerifyData;
 802     }
 803 
 804     /*
 805      * Returns the verify_data from the Finished message sent by the server.
 806      */
 807     byte[] getServerVerifyData() {
 808         return serverVerifyData;
 809     }
 810 
 811     /*
 812      * This routine is fed SSL handshake records when they become available,
 813      * and processes messages found therein.
 814      */
 815     void process_record(InputRecord r, boolean expectingFinished)
 816             throws IOException {
 817 
 818         checkThrown();
 819 
 820         /*
 821          * Store the incoming handshake data, then see if we can
 822          * now process any completed handshake messages
 823          */
 824         input.incomingRecord(r);
 825 
 826         /*
 827          * We don't need to create a separate delegatable task
 828          * for finished messages.
 829          */
 830         if ((conn != null) || expectingFinished) {
 831             processLoop();
 832         } else {
 833             delegateTask(new PrivilegedExceptionAction<Void>() {
 834                 @Override
 835                 public Void run() throws Exception {
 836                     processLoop();
 837                     return null;
 838                 }
 839             });
 840         }
 841     }
 842 
 843     /*
 844      * On input, we hash messages one at a time since servers may need
 845      * to access an intermediate hash to validate a CertificateVerify
 846      * message.
 847      *
 848      * Note that many handshake messages can come in one record (and often
 849      * do, to reduce network resource utilization), and one message can also
 850      * require multiple records (e.g. very large Certificate messages).
 851      */
 852     void processLoop() throws IOException {
 853 
 854         // need to read off 4 bytes at least to get the handshake
 855         // message type and length.
 856         while (input.available() >= 4) {
 857             byte messageType;
 858             int messageLen;
 859 
 860             /*
 861              * See if we can read the handshake message header, and
 862              * then the entire handshake message.  If not, wait till
 863              * we can read and process an entire message.
 864              */
 865             input.mark(4);
 866 
 867             messageType = (byte)input.getInt8();
 868             messageLen = input.getInt24();
 869 
 870             if (input.available() < messageLen) {
 871                 input.reset();
 872                 return;
 873             }
 874 
 875             /*
 876              * Process the messsage.  We require
 877              * that processMessage() consumes the entire message.  In
 878              * lieu of explicit error checks (how?!) we assume that the
 879              * data will look like garbage on encoding/processing errors,
 880              * and that other protocol code will detect such errors.
 881              *
 882              * Note that digesting is normally deferred till after the
 883              * message has been processed, though to process at least the
 884              * client's Finished message (i.e. send the server's) we need
 885              * to acccelerate that digesting.
 886              *
 887              * Also, note that hello request messages are never hashed;
 888              * that includes the hello request header, too.
 889              */
 890             if (messageType == HandshakeMessage.ht_hello_request) {
 891                 input.reset();
 892                 processMessage(messageType, messageLen);
 893                 input.ignore(4 + messageLen);
 894             } else {
 895                 input.mark(messageLen);
 896                 processMessage(messageType, messageLen);
 897                 input.digestNow();
 898             }
 899         }
 900     }
 901 
 902 
 903     /**
 904      * Returns true iff the handshaker has been activated.
 905      *
 906      * In activated state, the handshaker may not send any messages out.
 907      */
 908     boolean activated() {
 909         return state >= -1;
 910     }
 911 
 912     /**
 913      * Returns true iff the handshaker has sent any messages.
 914      */
 915     boolean started() {
 916         return state >= 0;  // 0: HandshakeMessage.ht_hello_request
 917                             // 1: HandshakeMessage.ht_client_hello
 918     }
 919 
 920 
 921     /*
 922      * Used to kickstart the negotiation ... either writing a
 923      * ClientHello or a HelloRequest as appropriate, whichever
 924      * the subclass returns.  NOP if handshaking's already started.
 925      */
 926     void kickstart() throws IOException {
 927         if (state >= 0) {
 928             return;
 929         }
 930 
 931         HandshakeMessage m = getKickstartMessage();
 932 
 933         if (debug != null && Debug.isOn("handshake")) {
 934             m.print(System.out);
 935         }
 936         m.write(output);
 937         output.flush();
 938 
 939         state = m.messageType();
 940     }
 941 
 942     /**
 943      * Both client and server modes can start handshaking; but the
 944      * message they send to do so is different.
 945      */
 946     abstract HandshakeMessage getKickstartMessage() throws SSLException;
 947 
 948     /*
 949      * Client and Server side protocols are each driven though this
 950      * call, which processes a single message and drives the appropriate
 951      * side of the protocol state machine (depending on the subclass).
 952      */
 953     abstract void processMessage(byte messageType, int messageLen)
 954         throws IOException;
 955 
 956     /*
 957      * Most alerts in the protocol relate to handshaking problems.
 958      * Alerts are detected as the connection reads data.
 959      */
 960     abstract void handshakeAlert(byte description) throws SSLProtocolException;
 961 
 962     /*
 963      * Sends a change cipher spec message and updates the write side
 964      * cipher state so that future messages use the just-negotiated spec.
 965      */
 966     void sendChangeCipherSpec(Finished mesg, boolean lastMessage)
 967             throws IOException {
 968 
 969         output.flush(); // i.e. handshake data
 970 
 971         /*
 972          * The write cipher state is protected by the connection write lock
 973          * so we must grab it while making the change. We also
 974          * make sure no writes occur between sending the ChangeCipherSpec
 975          * message, installing the new cipher state, and sending the
 976          * Finished message.
 977          *
 978          * We already hold SSLEngine/SSLSocket "this" by virtue
 979          * of this being called from the readRecord code.
 980          */
 981         OutputRecord r;
 982         if (conn != null) {
 983             r = new OutputRecord(Record.ct_change_cipher_spec);
 984         } else {
 985             r = new EngineOutputRecord(Record.ct_change_cipher_spec, engine);
 986         }
 987 
 988         r.setVersion(protocolVersion);
 989         r.write(1);     // single byte of data
 990 
 991         if (conn != null) {
 992             conn.writeLock.lock();
 993             try {
 994                 conn.writeRecord(r);
 995                 conn.changeWriteCiphers();
 996                 if (debug != null && Debug.isOn("handshake")) {
 997                     mesg.print(System.out);
 998                 }
 999                 mesg.write(output);
1000                 output.flush();
1001             } finally {
1002                 conn.writeLock.unlock();
1003             }
1004         } else {
1005             synchronized (engine.writeLock) {
1006                 engine.writeRecord((EngineOutputRecord)r);
1007                 engine.changeWriteCiphers();
1008                 if (debug != null && Debug.isOn("handshake")) {
1009                     mesg.print(System.out);
1010                 }
1011                 mesg.write(output);
1012 
1013                 if (lastMessage) {
1014                     output.setFinishedMsg();
1015                 }
1016                 output.flush();
1017             }
1018         }
1019     }
1020 
1021     /*
1022      * Single access point to key calculation logic.  Given the
1023      * pre-master secret and the nonces from client and server,
1024      * produce all the keying material to be used.
1025      */
1026     void calculateKeys(SecretKey preMasterSecret, ProtocolVersion version) {
1027         SecretKey master = calculateMasterSecret(preMasterSecret, version);
1028         session.setMasterSecret(master);
1029         calculateConnectionKeys(master);
1030     }
1031 
1032 
1033     /*
1034      * Calculate the master secret from its various components.  This is
1035      * used for key exchange by all cipher suites.
1036      *
1037      * The master secret is the catenation of three MD5 hashes, each
1038      * consisting of the pre-master secret and a SHA1 hash.  Those three
1039      * SHA1 hashes are of (different) constant strings, the pre-master
1040      * secret, and the nonces provided by the client and the server.
1041      */
1042     private SecretKey calculateMasterSecret(SecretKey preMasterSecret,
1043             ProtocolVersion requestedVersion) {
1044 
1045         if (debug != null && Debug.isOn("keygen")) {
1046             HexDumpEncoder      dump = new HexDumpEncoder();
1047 
1048             System.out.println("SESSION KEYGEN:");
1049 
1050             System.out.println("PreMaster Secret:");
1051             printHex(dump, preMasterSecret.getEncoded());
1052 
1053             // Nonces are dumped with connection keygen, no
1054             // benefit to doing it twice
1055         }
1056 
1057         // What algs/params do we need to use?
1058         String masterAlg;
1059         PRF prf;
1060 
1061         if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1062             masterAlg = "SunTls12MasterSecret";
1063             prf = cipherSuite.prfAlg;
1064         } else {
1065             masterAlg = "SunTlsMasterSecret";
1066             prf = P_NONE;
1067         }
1068 
1069         String prfHashAlg = prf.getPRFHashAlg();
1070         int prfHashLength = prf.getPRFHashLength();
1071         int prfBlockSize = prf.getPRFBlockSize();
1072 
1073         TlsMasterSecretParameterSpec spec = new TlsMasterSecretParameterSpec(
1074                 preMasterSecret, protocolVersion.major, protocolVersion.minor,
1075                 clnt_random.random_bytes, svr_random.random_bytes,
1076                 prfHashAlg, prfHashLength, prfBlockSize);
1077 
1078         SecretKey masterSecret;
1079         try {
1080             KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg);
1081             kg.init(spec);
1082             masterSecret = kg.generateKey();
1083         } catch (GeneralSecurityException e) {
1084             // For RSA premaster secrets, do not signal a protocol error
1085             // due to the Bleichenbacher attack. See comments further down.
1086             if (!preMasterSecret.getAlgorithm().equals(
1087                     "TlsRsaPremasterSecret")) {
1088                 throw new ProviderException(e);
1089             }
1090 
1091             if (debug != null && Debug.isOn("handshake")) {
1092                 System.out.println("RSA master secret generation error:");
1093                 e.printStackTrace(System.out);
1094             }
1095 
1096             if (requestedVersion != null) {
1097                 preMasterSecret =
1098                     RSAClientKeyExchange.generateDummySecret(requestedVersion);
1099             } else {
1100                 preMasterSecret =
1101                     RSAClientKeyExchange.generateDummySecret(protocolVersion);
1102             }
1103 
1104             // recursive call with new premaster secret
1105             return calculateMasterSecret(preMasterSecret, null);
1106         }
1107 
1108         // if no version check requested (client side handshake), or version
1109         // information is not available (not an RSA premaster secret),
1110         // return master secret immediately.
1111         if ((requestedVersion == null) ||
1112                 !(masterSecret instanceof TlsMasterSecret)) {
1113             return masterSecret;
1114         }
1115 
1116         // we have checked the ClientKeyExchange message when reading TLS
1117         // record, the following check is necessary to ensure that
1118         // JCE provider does not ignore the checking, or the previous
1119         // checking process bypassed the premaster secret version checking.
1120         TlsMasterSecret tlsKey = (TlsMasterSecret)masterSecret;
1121         int major = tlsKey.getMajorVersion();
1122         int minor = tlsKey.getMinorVersion();
1123         if ((major < 0) || (minor < 0)) {
1124             return masterSecret;
1125         }
1126 
1127         // check if the premaster secret version is ok
1128         // the specification says that it must be the maximum version supported
1129         // by the client from its ClientHello message. However, many
1130         // implementations send the negotiated version, so accept both
1131         // for SSL v3.0 and TLS v1.0.
1132         // NOTE that we may be comparing two unsupported version numbers, which
1133         // is why we cannot use object reference equality in this special case.
1134         ProtocolVersion premasterVersion =
1135                                     ProtocolVersion.valueOf(major, minor);
1136         boolean versionMismatch = (premasterVersion.v != requestedVersion.v);
1137 
1138         /*
1139          * we never checked the client_version in server side
1140          * for TLS v1.0 and SSL v3.0. For compatibility, we
1141          * maintain this behavior.
1142          */
1143         if (versionMismatch && requestedVersion.v <= ProtocolVersion.TLS10.v) {
1144             versionMismatch = (premasterVersion.v != protocolVersion.v);
1145         }
1146 
1147         if (versionMismatch == false) {
1148             // check passed, return key
1149             return masterSecret;
1150         }
1151 
1152         // Due to the Bleichenbacher attack, do not signal a protocol error.
1153         // Generate a random premaster secret and continue with the handshake,
1154         // which will fail when verifying the finished messages.
1155         // For more information, see comments in PreMasterSecret.
1156         if (debug != null && Debug.isOn("handshake")) {
1157             System.out.println("RSA PreMasterSecret version error: expected"
1158                 + protocolVersion + " or " + requestedVersion + ", decrypted: "
1159                 + premasterVersion);
1160         }
1161         preMasterSecret =
1162             RSAClientKeyExchange.generateDummySecret(requestedVersion);
1163 
1164         // recursive call with new premaster secret
1165         return calculateMasterSecret(preMasterSecret, null);
1166     }
1167 
1168     /*
1169      * Calculate the keys needed for this connection, once the session's
1170      * master secret has been calculated.  Uses the master key and nonces;
1171      * the amount of keying material generated is a function of the cipher
1172      * suite that's been negotiated.
1173      *
1174      * This gets called both on the "full handshake" (where we exchanged
1175      * a premaster secret and started a new session) as well as on the
1176      * "fast handshake" (where we just resumed a pre-existing session).
1177      */
1178     void calculateConnectionKeys(SecretKey masterKey) {
1179         /*
1180          * For both the read and write sides of the protocol, we use the
1181          * master to generate MAC secrets and cipher keying material.  Block
1182          * ciphers need initialization vectors, which we also generate.
1183          *
1184          * First we figure out how much keying material is needed.
1185          */
1186         int hashSize = cipherSuite.macAlg.size;
1187         boolean is_exportable = cipherSuite.exportable;
1188         BulkCipher cipher = cipherSuite.cipher;
1189         int expandedKeySize = is_exportable ? cipher.expandedKeySize : 0;
1190 
1191         // Which algs/params do we need to use?
1192         String keyMaterialAlg;
1193         PRF prf;
1194 
1195         if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1196             keyMaterialAlg = "SunTls12KeyMaterial";
1197             prf = cipherSuite.prfAlg;
1198         } else {
1199             keyMaterialAlg = "SunTlsKeyMaterial";
1200             prf = P_NONE;
1201         }
1202 
1203         String prfHashAlg = prf.getPRFHashAlg();
1204         int prfHashLength = prf.getPRFHashLength();
1205         int prfBlockSize = prf.getPRFBlockSize();
1206 
1207         // TLS v1.1 or later uses an explicit IV in CBC cipher suites to
1208         // protect against the CBC attacks.  AEAD/GCM cipher suites in TLS
1209         // v1.2 or later use a fixed IV as the implicit part of the partially
1210         // implicit nonce technique described in RFC 5116.
1211         int ivSize = cipher.ivSize;
1212         if (cipher.cipherType == AEAD_CIPHER) {
1213             ivSize = cipher.fixedIvSize;
1214         } else if (protocolVersion.v >= ProtocolVersion.TLS11.v &&
1215                 cipher.cipherType == BLOCK_CIPHER) {
1216             ivSize = 0;
1217         }
1218 
1219         TlsKeyMaterialParameterSpec spec = new TlsKeyMaterialParameterSpec(
1220             masterKey, protocolVersion.major, protocolVersion.minor,
1221             clnt_random.random_bytes, svr_random.random_bytes,
1222             cipher.algorithm, cipher.keySize, expandedKeySize,
1223             ivSize, hashSize,
1224             prfHashAlg, prfHashLength, prfBlockSize);
1225 
1226         try {
1227             KeyGenerator kg = JsseJce.getKeyGenerator(keyMaterialAlg);
1228             kg.init(spec);
1229             TlsKeyMaterialSpec keySpec = (TlsKeyMaterialSpec)kg.generateKey();
1230 
1231             // Return null if cipher keys are not supposed to be generated.
1232             clntWriteKey = keySpec.getClientCipherKey();
1233             svrWriteKey = keySpec.getServerCipherKey();
1234 
1235             // Return null if IVs are not supposed to be generated.
1236             clntWriteIV = keySpec.getClientIv();
1237             svrWriteIV = keySpec.getServerIv();
1238 
1239             // Return null if MAC keys are not supposed to be generated.
1240             clntMacSecret = keySpec.getClientMacKey();
1241             svrMacSecret = keySpec.getServerMacKey();
1242         } catch (GeneralSecurityException e) {
1243             throw new ProviderException(e);
1244         }
1245 
1246         //
1247         // Dump the connection keys as they're generated.
1248         //
1249         if (debug != null && Debug.isOn("keygen")) {
1250             synchronized (System.out) {
1251                 HexDumpEncoder  dump = new HexDumpEncoder();
1252 
1253                 System.out.println("CONNECTION KEYGEN:");
1254 
1255                 // Inputs:
1256                 System.out.println("Client Nonce:");
1257                 printHex(dump, clnt_random.random_bytes);
1258                 System.out.println("Server Nonce:");
1259                 printHex(dump, svr_random.random_bytes);
1260                 System.out.println("Master Secret:");
1261                 printHex(dump, masterKey.getEncoded());
1262 
1263                 // Outputs:
1264                 if (clntMacSecret != null) {
1265                     System.out.println("Client MAC write Secret:");
1266                     printHex(dump, clntMacSecret.getEncoded());
1267                     System.out.println("Server MAC write Secret:");
1268                     printHex(dump, svrMacSecret.getEncoded());
1269                 } else {
1270                     System.out.println("... no MAC keys used for this cipher");
1271                 }
1272 
1273                 if (clntWriteKey != null) {
1274                     System.out.println("Client write key:");
1275                     printHex(dump, clntWriteKey.getEncoded());
1276                     System.out.println("Server write key:");
1277                     printHex(dump, svrWriteKey.getEncoded());
1278                 } else {
1279                     System.out.println("... no encryption keys used");
1280                 }
1281 
1282                 if (clntWriteIV != null) {
1283                     System.out.println("Client write IV:");
1284                     printHex(dump, clntWriteIV.getIV());
1285                     System.out.println("Server write IV:");
1286                     printHex(dump, svrWriteIV.getIV());
1287                 } else {
1288                     if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
1289                         System.out.println(
1290                                 "... no IV derived for this protocol");
1291                     } else {
1292                         System.out.println("... no IV used for this cipher");
1293                     }
1294                 }
1295                 System.out.flush();
1296             }
1297         }
1298     }
1299 
1300     private static void printHex(HexDumpEncoder dump, byte[] bytes) {
1301         if (bytes == null) {
1302             System.out.println("(key bytes not available)");
1303         } else {
1304             try {
1305                 dump.encodeBuffer(bytes, System.out);
1306             } catch (IOException e) {
1307                 // just for debugging, ignore this
1308             }
1309         }
1310     }
1311 
1312     /**
1313      * Throw an SSLException with the specified message and cause.
1314      * Shorthand until a new SSLException constructor is added.
1315      * This method never returns.
1316      */
1317     static void throwSSLException(String msg, Throwable cause)
1318             throws SSLException {
1319         SSLException e = new SSLException(msg);
1320         e.initCause(cause);
1321         throw e;
1322     }
1323 
1324 
1325     /*
1326      * Implement a simple task delegator.
1327      *
1328      * We are currently implementing this as a single delegator, may
1329      * try for parallel tasks later.  Client Authentication could
1330      * benefit from this, where ClientKeyExchange/CertificateVerify
1331      * could be carried out in parallel.
1332      */
1333     class DelegatedTask<E> implements Runnable {
1334 
1335         private PrivilegedExceptionAction<E> pea;
1336 
1337         DelegatedTask(PrivilegedExceptionAction<E> pea) {
1338             this.pea = pea;
1339         }
1340 
1341         public void run() {
1342             synchronized (engine) {
1343                 try {
1344                     AccessController.doPrivileged(pea, engine.getAcc());
1345                 } catch (PrivilegedActionException pae) {
1346                     thrown = pae.getException();
1347                 } catch (RuntimeException rte) {
1348                     thrown = rte;
1349                 }
1350                 delegatedTask = null;
1351                 taskDelegated = false;
1352             }
1353         }
1354     }
1355 
1356     private <T> void delegateTask(PrivilegedExceptionAction<T> pea) {
1357         delegatedTask = new DelegatedTask<T>(pea);
1358         taskDelegated = false;
1359         thrown = null;
1360     }
1361 
1362     DelegatedTask<?> getTask() {
1363         if (!taskDelegated) {
1364             taskDelegated = true;
1365             return delegatedTask;
1366         } else {
1367             return null;
1368         }
1369     }
1370 
1371     /*
1372      * See if there are any tasks which need to be delegated
1373      *
1374      * Locked by SSLEngine.this.
1375      */
1376     boolean taskOutstanding() {
1377         return (delegatedTask != null);
1378     }
1379 
1380     /*
1381      * The previous caller failed for some reason, report back the
1382      * Exception.  We won't worry about Error's.
1383      *
1384      * Locked by SSLEngine.this.
1385      */
1386     void checkThrown() throws SSLException {
1387         synchronized (thrownLock) {
1388             if (thrown != null) {
1389 
1390                 String msg = thrown.getMessage();
1391 
1392                 if (msg == null) {
1393                     msg = "Delegated task threw Exception/Error";
1394                 }
1395 
1396                 /*
1397                  * See what the underlying type of exception is.  We should
1398                  * throw the same thing.  Chain thrown to the new exception.
1399                  */
1400                 Exception e = thrown;
1401                 thrown = null;
1402 
1403                 if (e instanceof RuntimeException) {
1404                     throw new RuntimeException(msg, e);
1405                 } else if (e instanceof SSLHandshakeException) {
1406                     throw (SSLHandshakeException)
1407                         new SSLHandshakeException(msg).initCause(e);
1408                 } else if (e instanceof SSLKeyException) {
1409                     throw (SSLKeyException)
1410                         new SSLKeyException(msg).initCause(e);
1411                 } else if (e instanceof SSLPeerUnverifiedException) {
1412                     throw (SSLPeerUnverifiedException)
1413                         new SSLPeerUnverifiedException(msg).initCause(e);
1414                 } else if (e instanceof SSLProtocolException) {
1415                     throw (SSLProtocolException)
1416                         new SSLProtocolException(msg).initCause(e);
1417                 } else {
1418                     /*
1419                      * If it's SSLException or any other Exception,
1420                      * we'll wrap it in an SSLException.
1421                      */
1422                     throw new SSLException(msg, e);
1423                 }
1424             }
1425         }
1426     }
1427 }