1 /*
   2  * Copyright (c) 1996, 2012, 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.cert.*;
  33 import java.security.interfaces.*;
  34 import java.security.spec.ECParameterSpec;
  35 
  36 import javax.crypto.SecretKey;
  37 import javax.crypto.spec.SecretKeySpec;
  38 
  39 import javax.net.ssl.*;
  40 
  41 import javax.security.auth.Subject;
  42 
  43 import sun.security.ssl.HandshakeMessage.*;
  44 import sun.security.ssl.CipherSuite.*;
  45 import sun.security.ssl.SignatureAndHashAlgorithm.*;
  46 import static sun.security.ssl.CipherSuite.*;
  47 import static sun.security.ssl.CipherSuite.KeyExchange.*;
  48 
  49 /**
  50  * ServerHandshaker does the protocol handshaking from the point
  51  * of view of a server.  It is driven asychronously by handshake messages
  52  * as delivered by the parent Handshaker class, and also uses
  53  * common functionality (e.g. key generation) that is provided there.
  54  *
  55  * @author David Brownell
  56  */
  57 final class ServerHandshaker extends Handshaker {
  58 
  59     // is the server going to require the client to authenticate?
  60     private byte                doClientAuth;
  61 
  62     // our authentication info
  63     private X509Certificate[]   certs;
  64     private PrivateKey          privateKey;
  65 
  66     private SecretKey[]       kerberosKeys;
  67 
  68     // flag to check for clientCertificateVerify message
  69     private boolean             needClientVerify = false;
  70 
  71     /*
  72      * For exportable ciphersuites using non-exportable key sizes, we use
  73      * ephemeral RSA keys. We could also do anonymous RSA in the same way
  74      * but there are no such ciphersuites currently defined.
  75      */
  76     private PrivateKey          tempPrivateKey;
  77     private PublicKey           tempPublicKey;
  78 
  79     /*
  80      * For anonymous and ephemeral Diffie-Hellman key exchange, we use
  81      * ephemeral Diffie-Hellman keys.
  82      */
  83     private DHCrypt dh;
  84 
  85     // Helper for ECDH based key exchanges
  86     private ECDHCrypt ecdh;
  87 
  88     // version request by the client in its ClientHello
  89     // we remember it for the RSA premaster secret version check
  90     private ProtocolVersion clientRequestedVersion;
  91 
  92     private SupportedEllipticCurvesExtension supportedCurves;
  93 
  94     // the preferable signature algorithm used by ServerKeyExchange message
  95     SignatureAndHashAlgorithm preferableSignatureAlgorithm;
  96 
  97     /*
  98      * Constructor ... use the keys found in the auth context.
  99      */
 100     ServerHandshaker(SSLSocketImpl socket, SSLContextImpl context,
 101             ProtocolList enabledProtocols, byte clientAuth,
 102             ProtocolVersion activeProtocolVersion, boolean isInitialHandshake,
 103             boolean secureRenegotiation,
 104             byte[] clientVerifyData, byte[] serverVerifyData) {
 105 
 106         super(socket, context, enabledProtocols,
 107                 (clientAuth != SSLEngineImpl.clauth_none), false,
 108                 activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 109                 clientVerifyData, serverVerifyData);
 110         doClientAuth = clientAuth;
 111     }
 112 
 113     /*
 114      * Constructor ... use the keys found in the auth context.
 115      */
 116     ServerHandshaker(SSLEngineImpl engine, SSLContextImpl context,
 117             ProtocolList enabledProtocols, byte clientAuth,
 118             ProtocolVersion activeProtocolVersion,
 119             boolean isInitialHandshake, boolean secureRenegotiation,
 120             byte[] clientVerifyData, byte[] serverVerifyData) {
 121 
 122         super(engine, context, enabledProtocols,
 123                 (clientAuth != SSLEngineImpl.clauth_none), false,
 124                 activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 125                 clientVerifyData, serverVerifyData);
 126         doClientAuth = clientAuth;
 127     }
 128 
 129     /*
 130      * As long as handshaking has not started, we can change
 131      * whether client authentication is required.  Otherwise,
 132      * we will need to wait for the next handshake.
 133      */
 134     void setClientAuth(byte clientAuth) {
 135         doClientAuth = clientAuth;
 136     }
 137 
 138     /*
 139      * This routine handles all the server side handshake messages, one at
 140      * a time.  Given the message type (and in some cases the pending cipher
 141      * spec) it parses the type-specific message.  Then it calls a function
 142      * that handles that specific message.
 143      *
 144      * It updates the state machine as each message is processed, and writes
 145      * responses as needed using the connection in the constructor.
 146      */
 147     void processMessage(byte type, int message_len)
 148             throws IOException {
 149         //
 150         // In SSLv3 and TLS, messages follow strictly increasing
 151         // numerical order _except_ for one annoying special case.
 152         //
 153         if ((state > type)
 154                 && (state != HandshakeMessage.ht_client_key_exchange
 155                     && type != HandshakeMessage.ht_certificate_verify)) {
 156             throw new SSLProtocolException(
 157                     "Handshake message sequence violation, state = " + state
 158                     + ", type = " + type);
 159         }
 160 
 161         switch (type) {
 162             case HandshakeMessage.ht_client_hello:
 163                 ClientHello ch = new ClientHello(input, message_len);
 164                 /*
 165                  * send it off for processing.
 166                  */
 167                 this.clientHello(ch);
 168                 break;
 169 
 170             case HandshakeMessage.ht_certificate:
 171                 if (doClientAuth == SSLEngineImpl.clauth_none) {
 172                     fatalSE(Alerts.alert_unexpected_message,
 173                                 "client sent unsolicited cert chain");
 174                     // NOTREACHED
 175                 }
 176                 this.clientCertificate(new CertificateMsg(input));
 177                 break;
 178 
 179             case HandshakeMessage.ht_client_key_exchange:
 180                 SecretKey preMasterSecret;
 181                 switch (keyExchange) {
 182                 case K_RSA:
 183                 case K_RSA_EXPORT:
 184                     /*
 185                      * The client's pre-master secret is decrypted using
 186                      * either the server's normal private RSA key, or the
 187                      * temporary one used for non-export or signing-only
 188                      * certificates/keys.
 189                      */
 190                     RSAClientKeyExchange pms = new RSAClientKeyExchange(
 191                             protocolVersion, clientRequestedVersion,
 192                             sslContext.getSecureRandom(), input,
 193                             message_len, privateKey);
 194                     preMasterSecret = this.clientKeyExchange(pms);
 195                     break;
 196                 case K_KRB5:
 197                 case K_KRB5_EXPORT:
 198                     preMasterSecret = this.clientKeyExchange(
 199                         new KerberosClientKeyExchange(protocolVersion,
 200                             clientRequestedVersion,
 201                             sslContext.getSecureRandom(),
 202                             input,
 203                             kerberosKeys));
 204                     break;
 205                 case K_DHE_RSA:
 206                 case K_DHE_DSS:
 207                 case K_DH_ANON:
 208                     /*
 209                      * The pre-master secret is derived using the normal
 210                      * Diffie-Hellman calculation.   Note that the main
 211                      * protocol difference in these five flavors is in how
 212                      * the ServerKeyExchange message was constructed!
 213                      */
 214                     preMasterSecret = this.clientKeyExchange(
 215                             new DHClientKeyExchange(input));
 216                     break;
 217                 case K_ECDH_RSA:
 218                 case K_ECDH_ECDSA:
 219                 case K_ECDHE_RSA:
 220                 case K_ECDHE_ECDSA:
 221                 case K_ECDH_ANON:
 222                     preMasterSecret = this.clientKeyExchange
 223                                             (new ECDHClientKeyExchange(input));
 224                     break;
 225                 default:
 226                     throw new SSLProtocolException
 227                         ("Unrecognized key exchange: " + keyExchange);
 228                 }
 229 
 230                 //
 231                 // All keys are calculated from the premaster secret
 232                 // and the exchanged nonces in the same way.
 233                 //
 234                 calculateKeys(preMasterSecret, clientRequestedVersion);
 235                 break;
 236 
 237             case HandshakeMessage.ht_certificate_verify:
 238                 this.clientCertificateVerify(new CertificateVerify(input,
 239                             localSupportedSignAlgs, protocolVersion));
 240                 break;
 241 
 242             case HandshakeMessage.ht_finished:
 243                 this.clientFinished(
 244                     new Finished(protocolVersion, input, cipherSuite));
 245                 break;
 246 
 247             default:
 248                 throw new SSLProtocolException(
 249                         "Illegal server handshake msg, " + type);
 250         }
 251 
 252         //
 253         // Move the state machine forward except for that annoying
 254         // special case.  This means that clients could send extra
 255         // cert verify messages; not a problem so long as all of
 256         // them actually check out.
 257         //
 258         if (state < type && type != HandshakeMessage.ht_certificate_verify) {
 259             state = type;
 260         }
 261     }
 262 
 263 
 264     /*
 265      * ClientHello presents the server with a bunch of options, to which the
 266      * server replies with a ServerHello listing the ones which this session
 267      * will use.  If needed, it also writes its Certificate plus in some cases
 268      * a ServerKeyExchange message.  It may also write a CertificateRequest,
 269      * to elicit a client certificate.
 270      *
 271      * All these messages are terminated by a ServerHelloDone message.  In
 272      * most cases, all this can be sent in a single Record.
 273      */
 274     private void clientHello(ClientHello mesg) throws IOException {
 275         if (debug != null && Debug.isOn("handshake")) {
 276             mesg.print(System.out);
 277         }
 278 
 279         // Does the message include security renegotiation indication?
 280         boolean renegotiationIndicated = false;
 281 
 282         // check the TLS_EMPTY_RENEGOTIATION_INFO_SCSV
 283         CipherSuiteList cipherSuites = mesg.getCipherSuites();
 284         if (cipherSuites.contains(CipherSuite.C_SCSV)) {
 285             renegotiationIndicated = true;
 286             if (isInitialHandshake) {
 287                 secureRenegotiation = true;
 288             } else {
 289                 // abort the handshake with a fatal handshake_failure alert
 290                 if (secureRenegotiation) {
 291                     fatalSE(Alerts.alert_handshake_failure,
 292                         "The SCSV is present in a secure renegotiation");
 293                 } else {
 294                     fatalSE(Alerts.alert_handshake_failure,
 295                         "The SCSV is present in a insecure renegotiation");
 296                 }
 297             }
 298         }
 299 
 300         // check the "renegotiation_info" extension
 301         RenegotiationInfoExtension clientHelloRI = (RenegotiationInfoExtension)
 302                     mesg.extensions.get(ExtensionType.EXT_RENEGOTIATION_INFO);
 303         if (clientHelloRI != null) {
 304             renegotiationIndicated = true;
 305             if (isInitialHandshake) {
 306                 // verify the length of the "renegotiated_connection" field
 307                 if (!clientHelloRI.isEmpty()) {
 308                     // abort the handshake with a fatal handshake_failure alert
 309                     fatalSE(Alerts.alert_handshake_failure,
 310                         "The renegotiation_info field is not empty");
 311                 }
 312 
 313                 secureRenegotiation = true;
 314             } else {
 315                 if (!secureRenegotiation) {
 316                     // unexpected RI extension for insecure renegotiation,
 317                     // abort the handshake with a fatal handshake_failure alert
 318                     fatalSE(Alerts.alert_handshake_failure,
 319                         "The renegotiation_info is present in a insecure " +
 320                         "renegotiation");
 321                 }
 322 
 323                 // verify the client_verify_data value
 324                 if (!Arrays.equals(clientVerifyData,
 325                                 clientHelloRI.getRenegotiatedConnection())) {
 326                     fatalSE(Alerts.alert_handshake_failure,
 327                         "Incorrect verify data in ClientHello " +
 328                         "renegotiation_info message");
 329                 }
 330             }
 331         } else if (!isInitialHandshake && secureRenegotiation) {
 332            // if the connection's "secure_renegotiation" flag is set to TRUE
 333            // and the "renegotiation_info" extension is not present, abort
 334            // the handshake.
 335             fatalSE(Alerts.alert_handshake_failure,
 336                         "Inconsistent secure renegotiation indication");
 337         }
 338 
 339         // if there is no security renegotiation indication or the previous
 340         // handshake is insecure.
 341         if (!renegotiationIndicated || !secureRenegotiation) {
 342             if (isInitialHandshake) {
 343                 if (!allowLegacyHelloMessages) {
 344                     // abort the handshake with a fatal handshake_failure alert
 345                     fatalSE(Alerts.alert_handshake_failure,
 346                         "Failed to negotiate the use of secure renegotiation");
 347                 }
 348 
 349                 // continue with legacy ClientHello
 350                 if (debug != null && Debug.isOn("handshake")) {
 351                     System.out.println("Warning: No renegotiation " +
 352                         "indication in ClientHello, allow legacy ClientHello");
 353                 }
 354             } else if (!allowUnsafeRenegotiation) {
 355                 // abort the handshake
 356                 if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) {
 357                     // response with a no_renegotiation warning,
 358                     warningSE(Alerts.alert_no_renegotiation);
 359 
 360                     // invalidate the handshake so that the caller can
 361                     // dispose this object.
 362                     invalidated = true;
 363 
 364                     // If there is still unread block in the handshake
 365                     // input stream, it would be truncated with the disposal
 366                     // and the next handshake message will become incomplete.
 367                     //
 368                     // However, according to SSL/TLS specifications, no more
 369                     // handshake message could immediately follow ClientHello
 370                     // or HelloRequest. But in case of any improper messages,
 371                     // we'd better check to ensure there is no remaining bytes
 372                     // in the handshake input stream.
 373                     if (input.available() > 0) {
 374                         fatalSE(Alerts.alert_unexpected_message,
 375                             "ClientHello followed by an unexpected  " +
 376                             "handshake message");
 377                     }
 378 
 379                     return;
 380                 } else {
 381                     // For SSLv3, send the handshake_failure fatal error.
 382                     // Note that SSLv3 does not define a no_renegotiation
 383                     // alert like TLSv1. However we cannot ignore the message
 384                     // simply, otherwise the other side was waiting for a
 385                     // response that would never come.
 386                     fatalSE(Alerts.alert_handshake_failure,
 387                         "Renegotiation is not allowed");
 388                 }
 389             } else {   // !isInitialHandshake && allowUnsafeRenegotiation
 390                 // continue with unsafe renegotiation.
 391                 if (debug != null && Debug.isOn("handshake")) {
 392                     System.out.println(
 393                             "Warning: continue with insecure renegotiation");
 394                 }
 395             }
 396         }
 397 
 398         /*
 399          * Always make sure this entire record has been digested before we
 400          * start emitting output, to ensure correct digesting order.
 401          */
 402         input.digestNow();
 403 
 404         /*
 405          * FIRST, construct the ServerHello using the options and priorities
 406          * from the ClientHello.  Update the (pending) cipher spec as we do
 407          * so, and save the client's version to protect against rollback
 408          * attacks.
 409          *
 410          * There are a bunch of minor tasks here, and one major one: deciding
 411          * if the short or the full handshake sequence will be used.
 412          */
 413         ServerHello m1 = new ServerHello();
 414 
 415         clientRequestedVersion = mesg.protocolVersion;
 416 
 417         // select a proper protocol version.
 418         ProtocolVersion selectedVersion =
 419                selectProtocolVersion(clientRequestedVersion);
 420         if (selectedVersion == null ||
 421                 selectedVersion.v == ProtocolVersion.SSL20Hello.v) {
 422             fatalSE(Alerts.alert_handshake_failure,
 423                 "Client requested protocol " + clientRequestedVersion +
 424                 " not enabled or not supported");
 425         }
 426 
 427         handshakeHash.protocolDetermined(selectedVersion);
 428         setVersion(selectedVersion);
 429 
 430         m1.protocolVersion = protocolVersion;
 431 
 432         //
 433         // random ... save client and server values for later use
 434         // in computing the master secret (from pre-master secret)
 435         // and thence the other crypto keys.
 436         //
 437         // NOTE:  this use of three inputs to generating _each_ set
 438         // of ciphers slows things down, but it does increase the
 439         // security since each connection in the session can hold
 440         // its own authenticated (and strong) keys.  One could make
 441         // creation of a session a rare thing...
 442         //
 443         clnt_random = mesg.clnt_random;
 444         svr_random = new RandomCookie(sslContext.getSecureRandom());
 445         m1.svr_random = svr_random;
 446 
 447         session = null; // forget about the current session
 448         //
 449         // Here we go down either of two paths:  (a) the fast one, where
 450         // the client's asked to rejoin an existing session, and the server
 451         // permits this; (b) the other one, where a new session is created.
 452         //
 453         if (mesg.sessionId.length() != 0) {
 454             // client is trying to resume a session, let's see...
 455 
 456             SSLSessionImpl previous = ((SSLSessionContextImpl)sslContext
 457                         .engineGetServerSessionContext())
 458                         .get(mesg.sessionId.getId());
 459             //
 460             // Check if we can use the fast path, resuming a session.  We
 461             // can do so iff we have a valid record for that session, and
 462             // the cipher suite for that session was on the list which the
 463             // client requested, and if we're not forgetting any needed
 464             // authentication on the part of the client.
 465             //
 466             if (previous != null) {
 467                 resumingSession = previous.isRejoinable();
 468 
 469                 if (resumingSession) {
 470                     ProtocolVersion oldVersion = previous.getProtocolVersion();
 471                     // cannot resume session with different version
 472                     if (oldVersion != protocolVersion) {
 473                         resumingSession = false;
 474                     }
 475                 }
 476 
 477                 if (resumingSession &&
 478                         (doClientAuth == SSLEngineImpl.clauth_required)) {
 479                     try {
 480                         previous.getPeerPrincipal();
 481                     } catch (SSLPeerUnverifiedException e) {
 482                         resumingSession = false;
 483                     }
 484                 }
 485 
 486                 // validate subject identity
 487                 if (resumingSession) {
 488                     CipherSuite suite = previous.getSuite();
 489                     if (suite.keyExchange == K_KRB5 ||
 490                         suite.keyExchange == K_KRB5_EXPORT) {
 491                         Principal localPrincipal = previous.getLocalPrincipal();
 492 
 493                         Subject subject = null;
 494                         try {
 495                             subject = AccessController.doPrivileged(
 496                                 new PrivilegedExceptionAction<Subject>() {
 497                                 public Subject run() throws Exception {
 498                                     return
 499                                         Krb5Helper.getServerSubject(getAccSE());
 500                             }});
 501                         } catch (PrivilegedActionException e) {
 502                             subject = null;
 503                             if (debug != null && Debug.isOn("session")) {
 504                                 System.out.println("Attempt to obtain" +
 505                                                 " subject failed!");
 506                             }
 507                         }
 508 
 509                         if (subject != null) {
 510                             // Eliminate dependency on KerberosPrincipal
 511                             Set<Principal> principals =
 512                                 subject.getPrincipals(Principal.class);
 513                             if (!principals.contains(localPrincipal)) {
 514                                 resumingSession = false;
 515                                 if (debug != null && Debug.isOn("session")) {
 516                                     System.out.println("Subject identity" +
 517                                                         " is not the same");
 518                                 }
 519                             } else {
 520                                 if (debug != null && Debug.isOn("session"))
 521                                     System.out.println("Subject identity" +
 522                                                         " is same");
 523                             }
 524                         } else {
 525                             resumingSession = false;
 526                             if (debug != null && Debug.isOn("session"))
 527                                 System.out.println("Kerberos credentials are" +
 528                                     " not present in the current Subject;" +
 529                                     " check if " +
 530                                     " javax.security.auth.useSubjectAsCreds" +
 531                                     " system property has been set to false");
 532                         }
 533                     }
 534                 }
 535 
 536                 if (resumingSession) {
 537                     CipherSuite suite = previous.getSuite();
 538                     // verify that the ciphersuite from the cached session
 539                     // is in the list of client requested ciphersuites and
 540                     // we have it enabled
 541                     if ((isNegotiable(suite) == false) ||
 542                             (mesg.getCipherSuites().contains(suite) == false)) {
 543                         resumingSession = false;
 544                     } else {
 545                         // everything looks ok, set the ciphersuite
 546                         // this should be done last when we are sure we
 547                         // will resume
 548                         setCipherSuite(suite);
 549                     }
 550                 }
 551 
 552                 if (resumingSession) {
 553                     session = previous;
 554                     if (debug != null &&
 555                         (Debug.isOn("handshake") || Debug.isOn("session"))) {
 556                         System.out.println("%% Resuming " + session);
 557                     }
 558                 }
 559             }
 560         } // else client did not try to resume
 561 
 562         //
 563         // If client hasn't specified a session we can resume, start a
 564         // new one and choose its cipher suite and compression options.
 565         // Unless new session creation is disabled for this connection!
 566         //
 567         if (session == null) {
 568             if (!enableNewSession) {
 569                 throw new SSLException("Client did not resume a session");
 570             }
 571 
 572             supportedCurves = (SupportedEllipticCurvesExtension)
 573                         mesg.extensions.get(ExtensionType.EXT_ELLIPTIC_CURVES);
 574 
 575             // We only need to handle the "signature_algorithm" extension
 576             // for full handshakes and TLS 1.2 or later.
 577             if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
 578                 SignatureAlgorithmsExtension signAlgs =
 579                     (SignatureAlgorithmsExtension)mesg.extensions.get(
 580                                     ExtensionType.EXT_SIGNATURE_ALGORITHMS);
 581                 if (signAlgs != null) {
 582                     Collection<SignatureAndHashAlgorithm> peerSignAlgs =
 583                                             signAlgs.getSignAlgorithms();
 584                     if (peerSignAlgs == null || peerSignAlgs.isEmpty()) {
 585                         throw new SSLHandshakeException(
 586                             "No peer supported signature algorithms");
 587                     }
 588 
 589                     Collection<SignatureAndHashAlgorithm>
 590                         supportedPeerSignAlgs =
 591                             SignatureAndHashAlgorithm.getSupportedAlgorithms(
 592                                                             peerSignAlgs);
 593                     if (supportedPeerSignAlgs.isEmpty()) {
 594                         throw new SSLHandshakeException(
 595                             "No supported signature and hash algorithm " +
 596                             "in common");
 597                     }
 598 
 599                     setPeerSupportedSignAlgs(supportedPeerSignAlgs);
 600                 } // else, need to use peer implicit supported signature algs
 601             }
 602 
 603             session = new SSLSessionImpl(protocolVersion, CipherSuite.C_NULL,
 604                         getLocalSupportedSignAlgs(),
 605                         sslContext.getSecureRandom(),
 606                         getHostAddressSE(), getPortSE());
 607 
 608             if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
 609                 if (peerSupportedSignAlgs != null) {
 610                     session.setPeerSupportedSignatureAlgorithms(
 611                             peerSupportedSignAlgs);
 612                 }   // else, we will set the implicit peer supported signature
 613                     // algorithms in chooseCipherSuite()
 614             }
 615 
 616             // set the handshake session
 617             setHandshakeSessionSE(session);
 618 
 619             // choose cipher suite and corresponding private key
 620             chooseCipherSuite(mesg);
 621 
 622             session.setSuite(cipherSuite);
 623             session.setLocalPrivateKey(privateKey);
 624 
 625             // chooseCompression(mesg);
 626         } else {
 627             // set the handshake session
 628             setHandshakeSessionSE(session);
 629         }
 630 
 631         if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
 632             if (resumingSession) {
 633                 handshakeHash.setCertificateVerifyAlg(null);
 634             }
 635             handshakeHash.setFinishedAlg(cipherSuite.prfAlg.getPRFHashAlg());
 636         }
 637 
 638         m1.cipherSuite = cipherSuite;
 639         m1.sessionId = session.getSessionId();
 640         m1.compression_method = session.getCompression();
 641 
 642         if (secureRenegotiation) {
 643             // For ServerHellos that are initial handshakes, then the
 644             // "renegotiated_connection" field in "renegotiation_info"
 645             // extension is of zero length.
 646             //
 647             // For ServerHellos that are renegotiating, this field contains
 648             // the concatenation of client_verify_data and server_verify_data.
 649             //
 650             // Note that for initial handshakes, both the clientVerifyData
 651             // variable and serverVerifyData variable are of zero length.
 652             HelloExtension serverHelloRI = new RenegotiationInfoExtension(
 653                                         clientVerifyData, serverVerifyData);
 654             m1.extensions.add(serverHelloRI);
 655         }
 656 
 657         if (debug != null && Debug.isOn("handshake")) {
 658             m1.print(System.out);
 659             System.out.println("Cipher suite:  " + session.getSuite());
 660         }
 661         m1.write(output);
 662 
 663         //
 664         // If we are resuming a session, we finish writing handshake
 665         // messages right now and then finish.
 666         //
 667         if (resumingSession) {
 668             calculateConnectionKeys(session.getMasterSecret());
 669             sendChangeCipherAndFinish(false);
 670             return;
 671         }
 672 
 673 
 674         /*
 675          * SECOND, write the server Certificate(s) if we need to.
 676          *
 677          * NOTE:  while an "anonymous RSA" mode is explicitly allowed by
 678          * the protocol, we can't support it since all of the SSL flavors
 679          * defined in the protocol spec are explicitly stated to require
 680          * using RSA certificates.
 681          */
 682         if (keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
 683             // Server certificates are omitted for Kerberos ciphers
 684 
 685         } else if ((keyExchange != K_DH_ANON) && (keyExchange != K_ECDH_ANON)) {
 686             if (certs == null) {
 687                 throw new RuntimeException("no certificates");
 688             }
 689 
 690             CertificateMsg m2 = new CertificateMsg(certs);
 691 
 692             /*
 693              * Set local certs in the SSLSession, output
 694              * debug info, and then actually write to the client.
 695              */
 696             session.setLocalCertificates(certs);
 697             if (debug != null && Debug.isOn("handshake")) {
 698                 m2.print(System.out);
 699             }
 700             m2.write(output);
 701 
 702             // XXX has some side effects with OS TCP buffering,
 703             // leave it out for now
 704 
 705             // let client verify chain in the meantime...
 706             // output.flush();
 707         } else {
 708             if (certs != null) {
 709                 throw new RuntimeException("anonymous keyexchange with certs");
 710             }
 711         }
 712 
 713         /*
 714          * THIRD, the ServerKeyExchange message ... iff it's needed.
 715          *
 716          * It's usually needed unless there's an encryption-capable
 717          * RSA cert, or a D-H cert.  The notable exception is that
 718          * exportable ciphers used with big RSA keys need to downgrade
 719          * to use short RSA keys, even when the key/cert encrypts OK.
 720          */
 721 
 722         ServerKeyExchange m3;
 723         switch (keyExchange) {
 724         case K_RSA:
 725         case K_KRB5:
 726         case K_KRB5_EXPORT:
 727             // no server key exchange for RSA or KRB5 ciphersuites
 728             m3 = null;
 729             break;
 730         case K_RSA_EXPORT:
 731             if (JsseJce.getRSAKeyLength(certs[0].getPublicKey()) > 512) {
 732                 try {
 733                     m3 = new RSA_ServerKeyExchange(
 734                         tempPublicKey, privateKey,
 735                         clnt_random, svr_random,
 736                         sslContext.getSecureRandom());
 737                     privateKey = tempPrivateKey;
 738                 } catch (GeneralSecurityException e) {
 739                     throwSSLException
 740                         ("Error generating RSA server key exchange", e);
 741                     m3 = null; // make compiler happy
 742                 }
 743             } else {
 744                 // RSA_EXPORT with short key, don't need ServerKeyExchange
 745                 m3 = null;
 746             }
 747             break;
 748         case K_DHE_RSA:
 749         case K_DHE_DSS:
 750             try {
 751                 m3 = new DH_ServerKeyExchange(dh,
 752                     privateKey,
 753                     clnt_random.random_bytes,
 754                     svr_random.random_bytes,
 755                     sslContext.getSecureRandom(),
 756                     preferableSignatureAlgorithm,
 757                     protocolVersion);
 758             } catch (GeneralSecurityException e) {
 759                 throwSSLException("Error generating DH server key exchange", e);
 760                 m3 = null; // make compiler happy
 761             }
 762             break;
 763         case K_DH_ANON:
 764             m3 = new DH_ServerKeyExchange(dh, protocolVersion);
 765             break;
 766         case K_ECDHE_RSA:
 767         case K_ECDHE_ECDSA:
 768         case K_ECDH_ANON:
 769             try {
 770                 m3 = new ECDH_ServerKeyExchange(ecdh,
 771                     privateKey,
 772                     clnt_random.random_bytes,
 773                     svr_random.random_bytes,
 774                     sslContext.getSecureRandom(),
 775                     preferableSignatureAlgorithm,
 776                     protocolVersion);
 777             } catch (GeneralSecurityException e) {
 778                 throwSSLException(
 779                     "Error generating ECDH server key exchange", e);
 780                 m3 = null; // make compiler happy
 781             }
 782             break;
 783         case K_ECDH_RSA:
 784         case K_ECDH_ECDSA:
 785             // ServerKeyExchange not used for fixed ECDH
 786             m3 = null;
 787             break;
 788         default:
 789             throw new RuntimeException("internal error: " + keyExchange);
 790         }
 791         if (m3 != null) {
 792             if (debug != null && Debug.isOn("handshake")) {
 793                 m3.print(System.out);
 794             }
 795             m3.write(output);
 796         }
 797 
 798         //
 799         // FOURTH, the CertificateRequest message.  The details of
 800         // the message can be affected by the key exchange algorithm
 801         // in use.  For example, certs with fixed Diffie-Hellman keys
 802         // are only useful with the DH_DSS and DH_RSA key exchange
 803         // algorithms.
 804         //
 805         // Needed only if server requires client to authenticate self.
 806         // Illegal for anonymous flavors, so we need to check that.
 807         //
 808         // CertificateRequest is omitted for Kerberos ciphers
 809         if (doClientAuth != SSLEngineImpl.clauth_none &&
 810                 keyExchange != K_DH_ANON && keyExchange != K_ECDH_ANON &&
 811                 keyExchange != K_KRB5 && keyExchange != K_KRB5_EXPORT) {
 812 
 813             CertificateRequest m4;
 814             X509Certificate caCerts[];
 815 
 816             Collection<SignatureAndHashAlgorithm> localSignAlgs = null;
 817             if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
 818                 // We currently use all local upported signature and hash
 819                 // algorithms. However, to minimize the computation cost
 820                 // of requested hash algorithms, we may use a restricted
 821                 // set of signature algorithms in the future.
 822                 localSignAlgs = getLocalSupportedSignAlgs();
 823                 if (localSignAlgs.isEmpty()) {
 824                     throw new SSLHandshakeException(
 825                             "No supported signature algorithm");
 826                 }
 827 
 828                 Set<String> localHashAlgs =
 829                     SignatureAndHashAlgorithm.getHashAlgorithmNames(
 830                         localSignAlgs);
 831                 if (localHashAlgs.isEmpty()) {
 832                     throw new SSLHandshakeException(
 833                             "No supported signature algorithm");
 834                 }
 835                 handshakeHash.restrictCertificateVerifyAlgs(localHashAlgs);
 836             }
 837 
 838             caCerts = sslContext.getX509TrustManager().getAcceptedIssuers();
 839             m4 = new CertificateRequest(caCerts, keyExchange,
 840                                             localSignAlgs, protocolVersion);
 841 
 842             if (debug != null && Debug.isOn("handshake")) {
 843                 m4.print(System.out);
 844             }
 845             m4.write(output);
 846         } else {
 847             if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
 848                 handshakeHash.setCertificateVerifyAlg(null);
 849             }
 850         }
 851 
 852         /*
 853          * FIFTH, say ServerHelloDone.
 854          */
 855         ServerHelloDone m5 = new ServerHelloDone();
 856 
 857         if (debug != null && Debug.isOn("handshake")) {
 858             m5.print(System.out);
 859         }
 860         m5.write(output);
 861 
 862         /*
 863          * Flush any buffered messages so the client will see them.
 864          * Ideally, all the messages above go in a single network level
 865          * message to the client.  Without big Certificate chains, it's
 866          * going to be the common case.
 867          */
 868         output.flush();
 869     }
 870 
 871     /*
 872      * Choose cipher suite from among those supported by client. Sets
 873      * the cipherSuite and keyExchange variables.
 874      */
 875     private void chooseCipherSuite(ClientHello mesg) throws IOException {
 876         for (CipherSuite suite : mesg.getCipherSuites().collection()) {
 877             if (isNegotiable(suite) == false) {
 878                 continue;
 879             }
 880 
 881             if (doClientAuth == SSLEngineImpl.clauth_required) {
 882                 if ((suite.keyExchange == K_DH_ANON) ||
 883                     (suite.keyExchange == K_ECDH_ANON)) {
 884                     continue;
 885                 }
 886             }
 887             if (trySetCipherSuite(suite) == false) {
 888                 continue;
 889             }
 890             return;
 891         }
 892         fatalSE(Alerts.alert_handshake_failure,
 893                     "no cipher suites in common");
 894     }
 895 
 896     /**
 897      * Set the given CipherSuite, if possible. Return the result.
 898      * The call succeeds if the CipherSuite is available and we have
 899      * the necessary certificates to complete the handshake. We don't
 900      * check if the CipherSuite is actually enabled.
 901      *
 902      * If successful, this method also generates ephemeral keys if
 903      * required for this ciphersuite. This may take some time, so this
 904      * method should only be called if you really want to use the
 905      * CipherSuite.
 906      *
 907      * This method is called from chooseCipherSuite() in this class.
 908      */
 909     boolean trySetCipherSuite(CipherSuite suite) {
 910         /*
 911          * If we're resuming a session we know we can
 912          * support this key exchange algorithm and in fact
 913          * have already cached the result of it in
 914          * the session state.
 915          */
 916         if (resumingSession) {
 917             return true;
 918         }
 919 
 920         if (suite.isNegotiable() == false) {
 921             return false;
 922         }
 923 
 924         // must not negotiate the obsoleted weak cipher suites.
 925         if (protocolVersion.v >= suite.obsoleted) {
 926             return false;
 927         }
 928 
 929         // must not negotiate unsupported cipher suites.
 930         if (protocolVersion.v < suite.supported) {
 931             return false;
 932         }
 933 
 934         KeyExchange keyExchange = suite.keyExchange;
 935 
 936         // null out any existing references
 937         privateKey = null;
 938         certs = null;
 939         dh = null;
 940         tempPrivateKey = null;
 941         tempPublicKey = null;
 942 
 943         Collection<SignatureAndHashAlgorithm> supportedSignAlgs = null;
 944         if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
 945             if (peerSupportedSignAlgs != null) {
 946                 supportedSignAlgs = peerSupportedSignAlgs;
 947             } else {
 948                 SignatureAndHashAlgorithm algorithm = null;
 949 
 950                 // we may optimize the performance
 951                 switch (keyExchange) {
 952                     // If the negotiated key exchange algorithm is one of
 953                     // (RSA, DHE_RSA, DH_RSA, RSA_PSK, ECDH_RSA, ECDHE_RSA),
 954                     // behave as if client had sent the value {sha1,rsa}.
 955                     case K_RSA:
 956                     case K_DHE_RSA:
 957                     case K_DH_RSA:
 958                     // case K_RSA_PSK:
 959                     case K_ECDH_RSA:
 960                     case K_ECDHE_RSA:
 961                         algorithm = SignatureAndHashAlgorithm.valueOf(
 962                                 HashAlgorithm.SHA1.value,
 963                                 SignatureAlgorithm.RSA.value, 0);
 964                         break;
 965                     // If the negotiated key exchange algorithm is one of
 966                     // (DHE_DSS, DH_DSS), behave as if the client had
 967                     // sent the value {sha1,dsa}.
 968                     case K_DHE_DSS:
 969                     case K_DH_DSS:
 970                         algorithm = SignatureAndHashAlgorithm.valueOf(
 971                                 HashAlgorithm.SHA1.value,
 972                                 SignatureAlgorithm.DSA.value, 0);
 973                         break;
 974                     // If the negotiated key exchange algorithm is one of
 975                     // (ECDH_ECDSA, ECDHE_ECDSA), behave as if the client
 976                     // had sent value {sha1,ecdsa}.
 977                     case K_ECDH_ECDSA:
 978                     case K_ECDHE_ECDSA:
 979                         algorithm = SignatureAndHashAlgorithm.valueOf(
 980                                 HashAlgorithm.SHA1.value,
 981                                 SignatureAlgorithm.ECDSA.value, 0);
 982                         break;
 983                     default:
 984                         // no peer supported signature algorithms
 985                 }
 986 
 987                 if (algorithm == null) {
 988                     supportedSignAlgs =
 989                         Collections.<SignatureAndHashAlgorithm>emptySet();
 990                 } else {
 991                     supportedSignAlgs =
 992                         new ArrayList<SignatureAndHashAlgorithm>(1);
 993                     supportedSignAlgs.add(algorithm);
 994                 }
 995 
 996                 // Sets the peer supported signature algorithm to use in KM
 997                 // temporarily.
 998                 session.setPeerSupportedSignatureAlgorithms(supportedSignAlgs);
 999             }
1000         }
1001 
1002         switch (keyExchange) {
1003         case K_RSA:
1004             // need RSA certs for authentication
1005             if (setupPrivateKeyAndChain("RSA") == false) {
1006                 return false;
1007             }
1008             break;
1009         case K_RSA_EXPORT:
1010             // need RSA certs for authentication
1011             if (setupPrivateKeyAndChain("RSA") == false) {
1012                 return false;
1013             }
1014 
1015             try {
1016                if (JsseJce.getRSAKeyLength(certs[0].getPublicKey()) > 512) {
1017                     if (!setupEphemeralRSAKeys(suite.exportable)) {
1018                         return false;
1019                     }
1020                }
1021             } catch (RuntimeException e) {
1022                 // could not determine keylength, ignore key
1023                 return false;
1024             }
1025             break;
1026         case K_DHE_RSA:
1027             // need RSA certs for authentication
1028             if (setupPrivateKeyAndChain("RSA") == false) {
1029                 return false;
1030             }
1031 
1032             // get preferable peer signature algorithm for server key exchange
1033             if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1034                 preferableSignatureAlgorithm =
1035                     SignatureAndHashAlgorithm.getPreferableAlgorithm(
1036                                         supportedSignAlgs, "RSA", privateKey);
1037                 if (preferableSignatureAlgorithm == null) {
1038                     return false;
1039                 }
1040             }
1041 
1042             setupEphemeralDHKeys(suite.exportable);
1043             break;
1044         case K_ECDHE_RSA:
1045             // need RSA certs for authentication
1046             if (setupPrivateKeyAndChain("RSA") == false) {
1047                 return false;
1048             }
1049 
1050             // get preferable peer signature algorithm for server key exchange
1051             if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1052                 preferableSignatureAlgorithm =
1053                     SignatureAndHashAlgorithm.getPreferableAlgorithm(
1054                                         supportedSignAlgs, "RSA", privateKey);
1055                 if (preferableSignatureAlgorithm == null) {
1056                     return false;
1057                 }
1058             }
1059 
1060             if (setupEphemeralECDHKeys() == false) {
1061                 return false;
1062             }
1063             break;
1064         case K_DHE_DSS:
1065             // get preferable peer signature algorithm for server key exchange
1066             if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1067                 preferableSignatureAlgorithm =
1068                     SignatureAndHashAlgorithm.getPreferableAlgorithm(
1069                                                 supportedSignAlgs, "DSA");
1070                 if (preferableSignatureAlgorithm == null) {
1071                     return false;
1072                 }
1073             }
1074 
1075             // need DSS certs for authentication
1076             if (setupPrivateKeyAndChain("DSA") == false) {
1077                 return false;
1078             }
1079             setupEphemeralDHKeys(suite.exportable);
1080             break;
1081         case K_ECDHE_ECDSA:
1082             // get preferable peer signature algorithm for server key exchange
1083             if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1084                 preferableSignatureAlgorithm =
1085                     SignatureAndHashAlgorithm.getPreferableAlgorithm(
1086                                             supportedSignAlgs, "ECDSA");
1087                 if (preferableSignatureAlgorithm == null) {
1088                     return false;
1089                 }
1090             }
1091 
1092             // need EC cert signed using EC
1093             if (setupPrivateKeyAndChain("EC_EC") == false) {
1094                 return false;
1095             }
1096             if (setupEphemeralECDHKeys() == false) {
1097                 return false;
1098             }
1099             break;
1100         case K_ECDH_RSA:
1101             // need EC cert signed using RSA
1102             if (setupPrivateKeyAndChain("EC_RSA") == false) {
1103                 return false;
1104             }
1105             setupStaticECDHKeys();
1106             break;
1107         case K_ECDH_ECDSA:
1108             // need EC cert signed using EC
1109             if (setupPrivateKeyAndChain("EC_EC") == false) {
1110                 return false;
1111             }
1112             setupStaticECDHKeys();
1113             break;
1114         case K_KRB5:
1115         case K_KRB5_EXPORT:
1116             // need Kerberos Key
1117             if (!setupKerberosKeys()) {
1118                 return false;
1119             }
1120             break;
1121         case K_DH_ANON:
1122             // no certs needed for anonymous
1123             setupEphemeralDHKeys(suite.exportable);
1124             break;
1125         case K_ECDH_ANON:
1126             // no certs needed for anonymous
1127             if (setupEphemeralECDHKeys() == false) {
1128                 return false;
1129             }
1130             break;
1131         default:
1132             // internal error, unknown key exchange
1133             throw new RuntimeException("Unrecognized cipherSuite: " + suite);
1134         }
1135         setCipherSuite(suite);
1136 
1137         // set the peer implicit supported signature algorithms
1138         if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1139             if (peerSupportedSignAlgs == null) {
1140                 setPeerSupportedSignAlgs(supportedSignAlgs);
1141                 // we had alreay update the session
1142             }
1143         }
1144         return true;
1145     }
1146 
1147     /*
1148      * Get some "ephemeral" RSA keys for this context. This means
1149      * generating them if it's not already been done.
1150      *
1151      * Note that we currently do not implement any ciphersuites that use
1152      * strong ephemeral RSA. (We do not support the EXPORT1024 ciphersuites
1153      * and standard RSA ciphersuites prohibit ephemeral mode for some reason)
1154      * This means that export is always true and 512 bit keys are generated.
1155      */
1156     private boolean setupEphemeralRSAKeys(boolean export) {
1157         KeyPair kp = sslContext.getEphemeralKeyManager().
1158                         getRSAKeyPair(export, sslContext.getSecureRandom());
1159         if (kp == null) {
1160             return false;
1161         } else {
1162             tempPublicKey = kp.getPublic();
1163             tempPrivateKey = kp.getPrivate();
1164             return true;
1165         }
1166     }
1167 
1168     /*
1169      * Acquire some "ephemeral" Diffie-Hellman  keys for this handshake.
1170      * We don't reuse these, for improved forward secrecy.
1171      */
1172     private void setupEphemeralDHKeys(boolean export) {
1173         /*
1174          * Diffie-Hellman keys ... we use 768 bit private keys due
1175          * to the "use twice as many key bits as bits you want secret"
1176          * rule of thumb, assuming we want the same size premaster
1177          * secret with Diffie-Hellman and RSA key exchanges.  Except
1178          * that exportable ciphers max out at 512 bits modulus values.
1179          */
1180         dh = new DHCrypt((export ? 512 : 768), sslContext.getSecureRandom());
1181     }
1182 
1183     // Setup the ephemeral ECDH parameters.
1184     // If we cannot continue because we do not support any of the curves that
1185     // the client requested, return false. Otherwise (all is well), return true.
1186     private boolean setupEphemeralECDHKeys() {
1187         int index = -1;
1188         if (supportedCurves != null) {
1189             // if the client sent the supported curves extension, pick the
1190             // first one that we support;
1191             for (int curveId : supportedCurves.curveIds()) {
1192                 if (SupportedEllipticCurvesExtension.isSupported(curveId)) {
1193                     index = curveId;
1194                     break;
1195                 }
1196             }
1197             if (index < 0) {
1198                 // no match found, cannot use this ciphersuite
1199                 return false;
1200             }
1201         } else {
1202             // pick our preference
1203             index = SupportedEllipticCurvesExtension.DEFAULT.curveIds()[0];
1204         }
1205         String oid = SupportedEllipticCurvesExtension.getCurveOid(index);
1206         ecdh = new ECDHCrypt(oid, sslContext.getSecureRandom());
1207         return true;
1208     }
1209 
1210     private void setupStaticECDHKeys() {
1211         // don't need to check whether the curve is supported, already done
1212         // in setupPrivateKeyAndChain().
1213         ecdh = new ECDHCrypt(privateKey, certs[0].getPublicKey());
1214     }
1215 
1216     /**
1217      * Retrieve the server key and certificate for the specified algorithm
1218      * from the KeyManager and set the instance variables.
1219      *
1220      * @return true if successful, false if not available or invalid
1221      */
1222     private boolean setupPrivateKeyAndChain(String algorithm) {
1223         X509ExtendedKeyManager km = sslContext.getX509KeyManager();
1224         String alias;
1225         if (conn != null) {
1226             alias = km.chooseServerAlias(algorithm, null, conn);
1227         } else {
1228             alias = km.chooseEngineServerAlias(algorithm, null, engine);
1229         }
1230         if (alias == null) {
1231             return false;
1232         }
1233         PrivateKey tempPrivateKey = km.getPrivateKey(alias);
1234         if (tempPrivateKey == null) {
1235             return false;
1236         }
1237         X509Certificate[] tempCerts = km.getCertificateChain(alias);
1238         if ((tempCerts == null) || (tempCerts.length == 0)) {
1239             return false;
1240         }
1241         String keyAlgorithm = algorithm.split("_")[0];
1242         PublicKey publicKey = tempCerts[0].getPublicKey();
1243         if ((tempPrivateKey.getAlgorithm().equals(keyAlgorithm) == false)
1244                 || (publicKey.getAlgorithm().equals(keyAlgorithm) == false)) {
1245             return false;
1246         }
1247         // For ECC certs, check whether we support the EC domain parameters.
1248         // If the client sent a SupportedEllipticCurves ClientHello extension,
1249         // check against that too.
1250         if (keyAlgorithm.equals("EC")) {
1251             if (publicKey instanceof ECPublicKey == false) {
1252                 return false;
1253             }
1254             ECParameterSpec params = ((ECPublicKey)publicKey).getParams();
1255             int index = SupportedEllipticCurvesExtension.getCurveIndex(params);
1256             if (SupportedEllipticCurvesExtension.isSupported(index) == false) {
1257                 return false;
1258             }
1259             if ((supportedCurves != null) && !supportedCurves.contains(index)) {
1260                 return false;
1261             }
1262         }
1263         this.privateKey = tempPrivateKey;
1264         this.certs = tempCerts;
1265         return true;
1266     }
1267 
1268     /**
1269      * Retrieve the Kerberos key for the specified server principal
1270      * from the JAAS configuration file.
1271      *
1272      * @return true if successful, false if not available or invalid
1273      */
1274     private boolean setupKerberosKeys() {
1275         if (kerberosKeys != null) {
1276             return true;
1277         }
1278         try {
1279             final AccessControlContext acc = getAccSE();
1280             kerberosKeys = AccessController.doPrivileged(
1281                 // Eliminate dependency on KerberosKey
1282                 new PrivilegedExceptionAction<SecretKey[]>() {
1283                 public SecretKey[] run() throws Exception {
1284                     // get kerberos key for the default principal
1285                     return Krb5Helper.getServerKeys(acc);
1286                         }});
1287 
1288             // check permission to access and use the secret key of the
1289             // Kerberized "host" service
1290             if (kerberosKeys != null && kerberosKeys.length > 0) {
1291                 if (debug != null && Debug.isOn("handshake")) {
1292                     for (SecretKey k: kerberosKeys) {
1293                         System.out.println("Using Kerberos key: " +
1294                             k);
1295                     }
1296                 }
1297 
1298                 String serverPrincipal =
1299                     Krb5Helper.getServerPrincipalName(kerberosKeys[0]);
1300                 SecurityManager sm = System.getSecurityManager();
1301                 try {
1302                    if (sm != null) {
1303                       // Eliminate dependency on ServicePermission
1304                       sm.checkPermission(Krb5Helper.getServicePermission(
1305                           serverPrincipal, "accept"), acc);
1306                    }
1307                 } catch (SecurityException se) {
1308                    kerberosKeys = null;
1309                    // %%% destroy keys? or will that affect Subject?
1310                    if (debug != null && Debug.isOn("handshake"))
1311                       System.out.println("Permission to access Kerberos"
1312                                 + " secret key denied");
1313                    return false;
1314                 }
1315             }
1316             return (kerberosKeys != null && kerberosKeys.length > 0);
1317         } catch (PrivilegedActionException e) {
1318             // Likely exception here is LoginExceptin
1319             if (debug != null && Debug.isOn("handshake")) {
1320                 System.out.println("Attempt to obtain Kerberos key failed: "
1321                                 + e.toString());
1322             }
1323             return false;
1324         }
1325     }
1326 
1327     /*
1328      * For Kerberos ciphers, the premaster secret is encrypted using
1329      * the session key. See RFC 2712.
1330      */
1331     private SecretKey clientKeyExchange(KerberosClientKeyExchange mesg)
1332         throws IOException {
1333 
1334         if (debug != null && Debug.isOn("handshake")) {
1335             mesg.print(System.out);
1336         }
1337 
1338         // Record the principals involved in exchange
1339         session.setPeerPrincipal(mesg.getPeerPrincipal());
1340         session.setLocalPrincipal(mesg.getLocalPrincipal());
1341 
1342         byte[] b = mesg.getUnencryptedPreMasterSecret();
1343         return new SecretKeySpec(b, "TlsPremasterSecret");
1344     }
1345 
1346     /*
1347      * Diffie Hellman key exchange is used when the server presented
1348      * D-H parameters in its certificate (signed using RSA or DSS/DSA),
1349      * or else the server presented no certificate but sent D-H params
1350      * in a ServerKeyExchange message.  Use of D-H is specified by the
1351      * cipher suite chosen.
1352      *
1353      * The message optionally contains the client's D-H public key (if
1354      * it wasn't not sent in a client certificate).  As always with D-H,
1355      * if a client and a server have each other's D-H public keys and
1356      * they use common algorithm parameters, they have a shared key
1357      * that's derived via the D-H calculation.  That key becomes the
1358      * pre-master secret.
1359      */
1360     private SecretKey clientKeyExchange(DHClientKeyExchange mesg)
1361             throws IOException {
1362 
1363         if (debug != null && Debug.isOn("handshake")) {
1364             mesg.print(System.out);
1365         }
1366         return dh.getAgreedSecret(mesg.getClientPublicKey());
1367     }
1368 
1369     private SecretKey clientKeyExchange(ECDHClientKeyExchange mesg)
1370             throws IOException {
1371 
1372         if (debug != null && Debug.isOn("handshake")) {
1373             mesg.print(System.out);
1374         }
1375         return ecdh.getAgreedSecret(mesg.getEncodedPoint());
1376     }
1377 
1378     /*
1379      * Client wrote a message to verify the certificate it sent earlier.
1380      *
1381      * Note that this certificate isn't involved in key exchange.  Client
1382      * authentication messages are included in the checksums used to
1383      * validate the handshake (e.g. Finished messages).  Other than that,
1384      * the _exact_ identity of the client is less fundamental to protocol
1385      * security than its role in selecting keys via the pre-master secret.
1386      */
1387     private void clientCertificateVerify(CertificateVerify mesg)
1388             throws IOException {
1389 
1390         if (debug != null && Debug.isOn("handshake")) {
1391             mesg.print(System.out);
1392         }
1393 
1394         if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1395             SignatureAndHashAlgorithm signAlg =
1396                 mesg.getPreferableSignatureAlgorithm();
1397             if (signAlg == null) {
1398                 throw new SSLHandshakeException(
1399                         "Illegal CertificateVerify message");
1400             }
1401 
1402             String hashAlg =
1403                 SignatureAndHashAlgorithm.getHashAlgorithmName(signAlg);
1404             if (hashAlg == null || hashAlg.length() == 0) {
1405                 throw new SSLHandshakeException(
1406                         "No supported hash algorithm");
1407             }
1408 
1409             handshakeHash.setCertificateVerifyAlg(hashAlg);
1410         }
1411 
1412         try {
1413             PublicKey publicKey =
1414                 session.getPeerCertificates()[0].getPublicKey();
1415 
1416             boolean valid = mesg.verify(protocolVersion, handshakeHash,
1417                                         publicKey, session.getMasterSecret());
1418             if (valid == false) {
1419                 fatalSE(Alerts.alert_bad_certificate,
1420                             "certificate verify message signature error");
1421             }
1422         } catch (GeneralSecurityException e) {
1423             fatalSE(Alerts.alert_bad_certificate,
1424                 "certificate verify format error", e);
1425         }
1426 
1427         // reset the flag for clientCertificateVerify message
1428         needClientVerify = false;
1429     }
1430 
1431 
1432     /*
1433      * Client writes "finished" at the end of its handshake, after cipher
1434      * spec is changed.   We verify it and then send ours.
1435      *
1436      * When we're resuming a session, we'll have already sent our own
1437      * Finished message so just the verification is needed.
1438      */
1439     private void clientFinished(Finished mesg) throws IOException {
1440         if (debug != null && Debug.isOn("handshake")) {
1441             mesg.print(System.out);
1442         }
1443 
1444         /*
1445          * Verify if client did send the certificate when client
1446          * authentication was required, otherwise server should not proceed
1447          */
1448         if (doClientAuth == SSLEngineImpl.clauth_required) {
1449            // get X500Principal of the end-entity certificate for X509-based
1450            // ciphersuites, or Kerberos principal for Kerberos ciphersuites
1451            session.getPeerPrincipal();
1452         }
1453 
1454         /*
1455          * Verify if client did send clientCertificateVerify message following
1456          * the client Certificate, otherwise server should not proceed
1457          */
1458         if (needClientVerify) {
1459                 fatalSE(Alerts.alert_handshake_failure,
1460                         "client did not send certificate verify message");
1461         }
1462 
1463         /*
1464          * Verify the client's message with the "before" digest of messages,
1465          * and forget about continuing to use that digest.
1466          */
1467         boolean verified = mesg.verify(handshakeHash, Finished.CLIENT,
1468             session.getMasterSecret());
1469 
1470         if (!verified) {
1471             fatalSE(Alerts.alert_handshake_failure,
1472                         "client 'finished' message doesn't verify");
1473             // NOTREACHED
1474         }
1475 
1476         /*
1477          * save client verify data for secure renegotiation
1478          */
1479         if (secureRenegotiation) {
1480             clientVerifyData = mesg.getVerifyData();
1481         }
1482 
1483         /*
1484          * OK, it verified.  If we're doing the full handshake, add that
1485          * "Finished" message to the hash of handshake messages, then send
1486          * the change_cipher_spec and Finished message.
1487          */
1488         if (!resumingSession) {
1489             input.digestNow();
1490             sendChangeCipherAndFinish(true);
1491         }
1492 
1493         /*
1494          * Update the session cache only after the handshake completed, else
1495          * we're open to an attack against a partially completed handshake.
1496          */
1497         session.setLastAccessedTime(System.currentTimeMillis());
1498         if (!resumingSession && session.isRejoinable()) {
1499             ((SSLSessionContextImpl)sslContext.engineGetServerSessionContext())
1500                 .put(session);
1501             if (debug != null && Debug.isOn("session")) {
1502                 System.out.println(
1503                     "%% Cached server session: " + session);
1504             }
1505         } else if (!resumingSession &&
1506                 debug != null && Debug.isOn("session")) {
1507             System.out.println(
1508                 "%% Didn't cache non-resumable server session: "
1509                 + session);
1510         }
1511     }
1512 
1513     /*
1514      * Compute finished message with the "server" digest (and then forget
1515      * about that digest, it can't be used again).
1516      */
1517     private void sendChangeCipherAndFinish(boolean finishedTag)
1518             throws IOException {
1519 
1520         output.flush();
1521 
1522         Finished mesg = new Finished(protocolVersion, handshakeHash,
1523             Finished.SERVER, session.getMasterSecret(), cipherSuite);
1524 
1525         /*
1526          * Send the change_cipher_spec record; then our Finished handshake
1527          * message will be the last handshake message.  Flush, and now we
1528          * are ready for application data!!
1529          */
1530         sendChangeCipherSpec(mesg, finishedTag);
1531 
1532         /*
1533          * save server verify data for secure renegotiation
1534          */
1535         if (secureRenegotiation) {
1536             serverVerifyData = mesg.getVerifyData();
1537         }
1538 
1539         /*
1540          * Update state machine so client MUST send 'finished' next
1541          * The update should only take place if it is not in the fast
1542          * handshake mode since the server has to wait for a finished
1543          * message from the client.
1544          */
1545         if (finishedTag) {
1546             state = HandshakeMessage.ht_finished;
1547         }
1548     }
1549 
1550 
1551     /*
1552      * Returns a HelloRequest message to kickstart renegotiations
1553      */
1554     HandshakeMessage getKickstartMessage() {
1555         return new HelloRequest();
1556     }
1557 
1558 
1559     /*
1560      * Fault detected during handshake.
1561      */
1562     void handshakeAlert(byte description) throws SSLProtocolException {
1563 
1564         String message = Alerts.alertDescription(description);
1565 
1566         if (debug != null && Debug.isOn("handshake")) {
1567             System.out.println("SSL -- handshake alert:  "
1568                 + message);
1569         }
1570 
1571         /*
1572          * It's ok to get a no_certificate alert from a client of which
1573          * we *requested* authentication information.
1574          * However, if we *required* it, then this is not acceptable.
1575          *
1576          * Anyone calling getPeerCertificates() on the
1577          * session will get an SSLPeerUnverifiedException.
1578          */
1579         if ((description == Alerts.alert_no_certificate) &&
1580                 (doClientAuth == SSLEngineImpl.clauth_requested)) {
1581             return;
1582         }
1583 
1584         throw new SSLProtocolException("handshake alert: " + message);
1585     }
1586 
1587     /*
1588      * RSA key exchange is normally used.  The client encrypts a "pre-master
1589      * secret" with the server's public key, from the Certificate (or else
1590      * ServerKeyExchange) message that was sent to it by the server.  That's
1591      * decrypted using the private key before we get here.
1592      */
1593     private SecretKey clientKeyExchange(RSAClientKeyExchange mesg)
1594             throws IOException {
1595 
1596         if (debug != null && Debug.isOn("handshake")) {
1597             mesg.print(System.out);
1598         }
1599         return mesg.preMaster;
1600     }
1601 
1602     /*
1603      * Verify the certificate sent by the client. We'll only get one if we
1604      * sent a CertificateRequest to request client authentication. If we
1605      * are in TLS mode, the client may send a message with no certificates
1606      * to indicate it does not have an appropriate chain. (In SSLv3 mode,
1607      * it would send a no certificate alert).
1608      */
1609     private void clientCertificate(CertificateMsg mesg) throws IOException {
1610         if (debug != null && Debug.isOn("handshake")) {
1611             mesg.print(System.out);
1612         }
1613 
1614         X509Certificate[] peerCerts = mesg.getCertificateChain();
1615 
1616         if (peerCerts.length == 0) {
1617             /*
1618              * If the client authentication is only *REQUESTED* (e.g.
1619              * not *REQUIRED*, this is an acceptable condition.)
1620              */
1621             if (doClientAuth == SSLEngineImpl.clauth_requested) {
1622                 // Smart (aka stupid) to forecast that no CertificateVerify
1623                 // message will be received.
1624                 if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1625                     handshakeHash.setCertificateVerifyAlg(null);
1626                 }
1627                 return;
1628             } else {
1629                 fatalSE(Alerts.alert_bad_certificate,
1630                     "null cert chain");
1631             }
1632         }
1633 
1634         // ask the trust manager to verify the chain
1635         X509TrustManager tm = sslContext.getX509TrustManager();
1636 
1637         try {
1638             // find out the types of client authentication used
1639             PublicKey key = peerCerts[0].getPublicKey();
1640             String keyAlgorithm = key.getAlgorithm();
1641             String authType;
1642             if (keyAlgorithm.equals("RSA")) {
1643                 authType = "RSA";
1644             } else if (keyAlgorithm.equals("DSA")) {
1645                 authType = "DSA";
1646             } else if (keyAlgorithm.equals("EC")) {
1647                 authType = "EC";
1648             } else {
1649                 // unknown public key type
1650                 authType = "UNKNOWN";
1651             }
1652 
1653             if (tm instanceof X509ExtendedTrustManager) {
1654                 if (conn != null) {
1655                     ((X509ExtendedTrustManager)tm).checkClientTrusted(
1656                         peerCerts.clone(),
1657                         authType,
1658                         conn);
1659                 } else {
1660                     ((X509ExtendedTrustManager)tm).checkClientTrusted(
1661                         peerCerts.clone(),
1662                         authType,
1663                         engine);
1664                 }
1665             } else {
1666                 // Unlikely to happen, because we have wrapped the old
1667                 // X509TrustManager with the new X509ExtendedTrustManager.
1668                 throw new CertificateException(
1669                     "Improper X509TrustManager implementation");
1670             }
1671         } catch (CertificateException e) {
1672             // This will throw an exception, so include the original error.
1673             fatalSE(Alerts.alert_certificate_unknown, e);
1674         }
1675         // set the flag for clientCertificateVerify message
1676         needClientVerify = true;
1677 
1678         session.setPeerCertificates(peerCerts);
1679     }
1680 }