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