ClientHandshaker.java revision 12745:f068a4ffddd2
1/*
2 * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  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
26package sun.security.ssl;
27
28import java.io.*;
29import java.math.BigInteger;
30import java.security.*;
31import java.util.*;
32
33import java.security.interfaces.ECPublicKey;
34import java.security.interfaces.RSAPublicKey;
35import java.security.spec.ECParameterSpec;
36
37import java.security.cert.X509Certificate;
38import java.security.cert.CertificateException;
39import java.security.cert.CertificateParsingException;
40import java.security.cert.CertPathValidatorException;
41import java.security.cert.CertPathValidatorException.Reason;
42import java.security.cert.CertPathValidatorException.BasicReason;
43import javax.security.auth.x500.X500Principal;
44
45import javax.crypto.SecretKey;
46
47import javax.net.ssl.*;
48
49import sun.security.ssl.HandshakeMessage.*;
50import static sun.security.ssl.CipherSuite.KeyExchange.*;
51
52/**
53 * ClientHandshaker does the protocol handshaking from the point
54 * of view of a client.  It is driven asychronously by handshake messages
55 * as delivered by the parent Handshaker class, and also uses
56 * common functionality (e.g. key generation) that is provided there.
57 *
58 * @author David Brownell
59 */
60final class ClientHandshaker extends Handshaker {
61
62    // constants for subject alt names of type DNS and IP
63    private static final int ALTNAME_DNS = 2;
64    private static final int ALTNAME_IP  = 7;
65
66    // the server's public key from its certificate.
67    private PublicKey serverKey;
68
69    // the server's ephemeral public key from the server key exchange message
70    // for ECDHE/ECDH_anon and RSA_EXPORT.
71    private PublicKey ephemeralServerKey;
72
73    // server's ephemeral public value for DHE/DH_anon key exchanges
74    private BigInteger          serverDH;
75
76    private DHCrypt             dh;
77
78    private ECDHCrypt ecdh;
79
80    private CertificateRequest  certRequest;
81
82    private boolean serverKeyExchangeReceived;
83
84    private final boolean enableStatusRequestExtension =
85            Debug.getBooleanProperty(
86                    "jdk.tls.client.enableStatusRequestExtension", true);
87    private boolean staplingActive = false;
88    private X509Certificate[] deferredCerts;
89
90    /*
91     * The RSA PreMasterSecret needs to know the version of
92     * ClientHello that was used on this handshake.  This represents
93     * the "max version" this client is supporting.  In the
94     * case of an initial handshake, it's the max version enabled,
95     * but in the case of a resumption attempt, it's the version
96     * of the session we're trying to resume.
97     */
98    private ProtocolVersion maxProtocolVersion;
99
100    // To switch off the SNI extension.
101    private static final boolean enableSNIExtension =
102            Debug.getBooleanProperty("jsse.enableSNIExtension", true);
103
104    /*
105     * Allow unsafe server certificate change?
106     *
107     * Server certificate change during SSL/TLS renegotiation may be considered
108     * unsafe, as described in the Triple Handshake attacks:
109     *
110     *     https://secure-resumption.com/tlsauth.pdf
111     *
112     * Endpoint identification (See
113     * SSLParameters.getEndpointIdentificationAlgorithm()) is a pretty nice
114     * guarantee that the server certificate change in renegotiation is legal.
115     * However, endpoing identification is only enabled for HTTPS and LDAP
116     * over SSL/TLS by default.  It is not enough to protect SSL/TLS
117     * connections other than HTTPS and LDAP.
118     *
119     * The renegotiation indication extension (See RFC 5764) is a pretty
120     * strong guarantee that the endpoints on both client and server sides
121     * are identical on the same connection.  However, the Triple Handshake
122     * attacks can bypass this guarantee if there is a session-resumption
123     * handshake between the initial full handshake and the renegotiation
124     * full handshake.
125     *
126     * Server certificate change may be unsafe and should be restricted if
127     * endpoint identification is not enabled and the previous handshake is
128     * a session-resumption abbreviated initial handshake, unless the
129     * identities represented by both certificates can be regraded as the
130     * same (See isIdentityEquivalent()).
131     *
132     * Considering the compatibility impact and the actual requirements to
133     * support server certificate change in practice, the system property,
134     * jdk.tls.allowUnsafeServerCertChange, is used to define whether unsafe
135     * server certificate change in renegotiation is allowed or not.  The
136     * default value of the system property is "false".  To mitigate the
137     * compactibility impact, applications may want to set the system
138     * property to "true" at their own risk.
139     *
140     * If the value of the system property is "false", server certificate
141     * change in renegotiation after a session-resumption abbreviated initial
142     * handshake is restricted (See isIdentityEquivalent()).
143     *
144     * If the system property is set to "true" explicitly, the restriction on
145     * server certificate change in renegotiation is disabled.
146     */
147    private static final boolean allowUnsafeServerCertChange =
148        Debug.getBooleanProperty("jdk.tls.allowUnsafeServerCertChange", false);
149
150    // To switch off the max_fragment_length extension.
151    private static final boolean enableMFLExtension =
152            Debug.getBooleanProperty("jsse.enableMFLExtension", false);
153
154    private List<SNIServerName> requestedServerNames =
155            Collections.<SNIServerName>emptyList();
156
157    // maximum fragment length
158    private int requestedMFLength = -1;     // -1: no fragment length limit
159
160    private boolean serverNamesAccepted = false;
161
162    private ClientHello initialClientHelloMsg = null;   // DTLS only
163
164    /*
165     * the reserved server certificate chain in previous handshaking
166     *
167     * The server certificate chain is only reserved if the previous
168     * handshake is a session-resumption abbreviated initial handshake.
169     */
170    private X509Certificate[] reservedServerCerts = null;
171
172    /*
173     * Constructors
174     */
175    ClientHandshaker(SSLSocketImpl socket, SSLContextImpl context,
176            ProtocolList enabledProtocols,
177            ProtocolVersion activeProtocolVersion,
178            boolean isInitialHandshake, boolean secureRenegotiation,
179            byte[] clientVerifyData, byte[] serverVerifyData) {
180
181        super(socket, context, enabledProtocols, true, true,
182            activeProtocolVersion, isInitialHandshake, secureRenegotiation,
183            clientVerifyData, serverVerifyData);
184    }
185
186    ClientHandshaker(SSLEngineImpl engine, SSLContextImpl context,
187            ProtocolList enabledProtocols,
188            ProtocolVersion activeProtocolVersion,
189            boolean isInitialHandshake, boolean secureRenegotiation,
190            byte[] clientVerifyData, byte[] serverVerifyData,
191            boolean isDTLS) {
192
193        super(engine, context, enabledProtocols, true, true,
194            activeProtocolVersion, isInitialHandshake, secureRenegotiation,
195            clientVerifyData, serverVerifyData, isDTLS);
196    }
197
198    /*
199     * This routine handles all the client side handshake messages, one at
200     * a time.  Given the message type (and in some cases the pending cipher
201     * spec) it parses the type-specific message.  Then it calls a function
202     * that handles that specific message.
203     *
204     * It updates the state machine (need to verify it) as each message
205     * is processed, and writes responses as needed using the connection
206     * in the constructor.
207     */
208    @Override
209    void processMessage(byte type, int messageLen) throws IOException {
210        // check the handshake state
211        List<Byte> ignoredOptStates = handshakeState.check(type);
212
213        // If the state machine has skipped over certificate status
214        // and stapling was enabled, we need to check the chain immediately
215        // because it was deferred, waiting for CertificateStatus.
216        if (staplingActive && ignoredOptStates.contains(
217                HandshakeMessage.ht_certificate_status)) {
218            checkServerCerts(deferredCerts);
219            serverKey = session.getPeerCertificates()[0].getPublicKey();
220        }
221
222        switch (type) {
223        case HandshakeMessage.ht_hello_request:
224            HelloRequest helloRequest = new HelloRequest(input);
225            handshakeState.update(helloRequest, resumingSession);
226            this.serverHelloRequest(helloRequest);
227            break;
228
229        case HandshakeMessage.ht_hello_verify_request:
230            if (!isDTLS) {
231                throw new SSLProtocolException(
232                    "hello_verify_request is not a SSL/TLS handshake message");
233            }
234
235            HelloVerifyRequest helloVerifyRequest =
236                        new HelloVerifyRequest(input, messageLen);
237            handshakeState.update(helloVerifyRequest, resumingSession);
238            this.helloVerifyRequest(helloVerifyRequest);
239            break;
240
241        case HandshakeMessage.ht_server_hello:
242            ServerHello serverHello = new ServerHello(input, messageLen);
243            this.serverHello(serverHello);
244
245            // This handshake state update needs the resumingSession value
246            // set by serverHello().
247            handshakeState.update(serverHello, resumingSession);
248            break;
249
250        case HandshakeMessage.ht_certificate:
251            if (keyExchange == K_DH_ANON || keyExchange == K_ECDH_ANON
252                    || ClientKeyExchangeService.find(keyExchange.name) != null) {
253                // No external key exchange provider needs a cert now.
254                fatalSE(Alerts.alert_unexpected_message,
255                    "unexpected server cert chain");
256                // NOTREACHED
257            }
258            CertificateMsg certificateMsg = new CertificateMsg(input);
259            handshakeState.update(certificateMsg, resumingSession);
260            this.serverCertificate(certificateMsg);
261            if (!staplingActive) {
262                // If we are not doing stapling, we can set serverKey right
263                // away.  Otherwise, we will wait until verification of the
264                // chain has completed after CertificateStatus;
265                serverKey = session.getPeerCertificates()[0].getPublicKey();
266            }
267            break;
268
269        case HandshakeMessage.ht_certificate_status:
270            CertificateStatus certStatusMsg = new CertificateStatus(input);
271            handshakeState.update(certStatusMsg, resumingSession);
272            this.certificateStatus(certStatusMsg);
273            serverKey = session.getPeerCertificates()[0].getPublicKey();
274            break;
275
276        case HandshakeMessage.ht_server_key_exchange:
277            serverKeyExchangeReceived = true;
278            switch (keyExchange) {
279            case K_RSA_EXPORT:
280                /**
281                 * The server key exchange message is sent by the server only
282                 * when the server certificate message does not contain the
283                 * proper amount of data to allow the client to exchange a
284                 * premaster secret, such as when RSA_EXPORT is used and the
285                 * public key in the server certificate is longer than 512 bits.
286                 */
287                if (serverKey == null) {
288                    throw new SSLProtocolException
289                        ("Server did not send certificate message");
290                }
291
292                if (!(serverKey instanceof RSAPublicKey)) {
293                    throw new SSLProtocolException("Protocol violation:" +
294                        " the certificate type must be appropriate for the" +
295                        " selected cipher suite's key exchange algorithm");
296                }
297
298                if (JsseJce.getRSAKeyLength(serverKey) <= 512) {
299                    throw new SSLProtocolException("Protocol violation:" +
300                        " server sent a server key exchange message for" +
301                        " key exchange " + keyExchange +
302                        " when the public key in the server certificate" +
303                        " is less than or equal to 512 bits in length");
304                }
305
306                try {
307                    RSA_ServerKeyExchange rsaSrvKeyExchange =
308                                    new RSA_ServerKeyExchange(input);
309                    handshakeState.update(rsaSrvKeyExchange, resumingSession);
310                    this.serverKeyExchange(rsaSrvKeyExchange);
311                } catch (GeneralSecurityException e) {
312                    throw new SSLException("Server key", e);
313                }
314                break;
315            case K_DH_ANON:
316                try {
317                    DH_ServerKeyExchange dhSrvKeyExchange =
318                            new DH_ServerKeyExchange(input, protocolVersion);
319                    handshakeState.update(dhSrvKeyExchange, resumingSession);
320                    this.serverKeyExchange(dhSrvKeyExchange);
321                } catch (GeneralSecurityException e) {
322                    throw new SSLException("Server key", e);
323                }
324                break;
325            case K_DHE_DSS:
326            case K_DHE_RSA:
327                try {
328                    DH_ServerKeyExchange dhSrvKeyExchange =
329                        new DH_ServerKeyExchange(
330                            input, serverKey,
331                            clnt_random.random_bytes, svr_random.random_bytes,
332                            messageLen,
333                            localSupportedSignAlgs, protocolVersion);
334                    handshakeState.update(dhSrvKeyExchange, resumingSession);
335                    this.serverKeyExchange(dhSrvKeyExchange);
336                } catch (GeneralSecurityException e) {
337                    throw new SSLException("Server key", e);
338                }
339                break;
340            case K_ECDHE_ECDSA:
341            case K_ECDHE_RSA:
342            case K_ECDH_ANON:
343                try {
344                    ECDH_ServerKeyExchange ecdhSrvKeyExchange =
345                        new ECDH_ServerKeyExchange
346                            (input, serverKey, clnt_random.random_bytes,
347                            svr_random.random_bytes,
348                            localSupportedSignAlgs, protocolVersion);
349                    handshakeState.update(ecdhSrvKeyExchange, resumingSession);
350                    this.serverKeyExchange(ecdhSrvKeyExchange);
351                } catch (GeneralSecurityException e) {
352                    throw new SSLException("Server key", e);
353                }
354                break;
355            case K_RSA:
356            case K_DH_RSA:
357            case K_DH_DSS:
358            case K_ECDH_ECDSA:
359            case K_ECDH_RSA:
360                throw new SSLProtocolException(
361                    "Protocol violation: server sent a server key exchange"
362                    + " message for key exchange " + keyExchange);
363            default:
364                throw new SSLProtocolException(
365                    "unsupported or unexpected key exchange algorithm = "
366                    + keyExchange);
367            }
368            break;
369
370        case HandshakeMessage.ht_certificate_request:
371            // save for later, it's handled by serverHelloDone
372            if ((keyExchange == K_DH_ANON) || (keyExchange == K_ECDH_ANON)) {
373                throw new SSLHandshakeException(
374                    "Client authentication requested for "+
375                    "anonymous cipher suite.");
376            } else if (ClientKeyExchangeService.find(keyExchange.name) != null) {
377                // No external key exchange provider needs a cert now.
378                throw new SSLHandshakeException(
379                    "Client certificate requested for "+
380                    "external cipher suite: " + keyExchange);
381            }
382            certRequest = new CertificateRequest(input, protocolVersion);
383            if (debug != null && Debug.isOn("handshake")) {
384                certRequest.print(System.out);
385            }
386            handshakeState.update(certRequest, resumingSession);
387
388            if (protocolVersion.useTLS12PlusSpec()) {
389                Collection<SignatureAndHashAlgorithm> peerSignAlgs =
390                                        certRequest.getSignAlgorithms();
391                if (peerSignAlgs == null || peerSignAlgs.isEmpty()) {
392                    throw new SSLHandshakeException(
393                        "No peer supported signature algorithms");
394                }
395
396                Collection<SignatureAndHashAlgorithm> supportedPeerSignAlgs =
397                    SignatureAndHashAlgorithm.getSupportedAlgorithms(
398                                                            peerSignAlgs);
399                if (supportedPeerSignAlgs.isEmpty()) {
400                    throw new SSLHandshakeException(
401                        "No supported signature and hash algorithm in common");
402                }
403
404                setPeerSupportedSignAlgs(supportedPeerSignAlgs);
405                session.setPeerSupportedSignatureAlgorithms(
406                                                supportedPeerSignAlgs);
407            }
408
409            break;
410
411        case HandshakeMessage.ht_server_hello_done:
412            ServerHelloDone serverHelloDone = new ServerHelloDone(input);
413            handshakeState.update(serverHelloDone, resumingSession);
414            this.serverHelloDone(serverHelloDone);
415
416            break;
417
418        case HandshakeMessage.ht_finished:
419            Finished serverFinished =
420                    new Finished(protocolVersion, input, cipherSuite);
421            handshakeState.update(serverFinished, resumingSession);
422            this.serverFinished(serverFinished);
423
424            break;
425
426        default:
427            throw new SSLProtocolException(
428                "Illegal client handshake msg, " + type);
429        }
430    }
431
432    /*
433     * Used by the server to kickstart negotiations -- this requests a
434     * "client hello" to renegotiate current cipher specs (e.g. maybe lots
435     * of data has been encrypted with the same keys, or the server needs
436     * the client to present a certificate).
437     */
438    private void serverHelloRequest(HelloRequest mesg) throws IOException {
439        if (debug != null && Debug.isOn("handshake")) {
440            mesg.print(System.out);
441        }
442
443        //
444        // Could be (e.g. at connection setup) that we already
445        // sent the "client hello" but the server's not seen it.
446        //
447        if (!clientHelloDelivered) {
448            if (!secureRenegotiation && !allowUnsafeRenegotiation) {
449                // renegotiation is not allowed.
450                if (activeProtocolVersion.useTLS10PlusSpec()) {
451                    // response with a no_renegotiation warning,
452                    warningSE(Alerts.alert_no_renegotiation);
453
454                    // invalidate the handshake so that the caller can
455                    // dispose this object.
456                    invalidated = true;
457
458                    // If there is still unread block in the handshake
459                    // input stream, it would be truncated with the disposal
460                    // and the next handshake message will become incomplete.
461                    //
462                    // However, according to SSL/TLS specifications, no more
463                    // handshake message should immediately follow ClientHello
464                    // or HelloRequest. So just let it be.
465                } else {
466                    // For SSLv3, send the handshake_failure fatal error.
467                    // Note that SSLv3 does not define a no_renegotiation
468                    // alert like TLSv1. However we cannot ignore the message
469                    // simply, otherwise the other side was waiting for a
470                    // response that would never come.
471                    fatalSE(Alerts.alert_handshake_failure,
472                        "Renegotiation is not allowed");
473                }
474            } else {
475                if (!secureRenegotiation) {
476                    if (debug != null && Debug.isOn("handshake")) {
477                        System.out.println(
478                            "Warning: continue with insecure renegotiation");
479                    }
480                }
481                kickstart();
482            }
483        }
484    }
485
486    private void helloVerifyRequest(
487            HelloVerifyRequest mesg) throws IOException {
488
489        if (debug != null && Debug.isOn("handshake")) {
490            mesg.print(System.out);
491        }
492
493        //
494        // Note that HelloVerifyRequest.server_version is used solely to
495        // indicate packet formatting, and not as part of version negotiation.
496        // Need not to check version values match for HelloVerifyRequest
497        // message.
498        //
499        initialClientHelloMsg.cookie = mesg.cookie.clone();
500
501        if (debug != null && Debug.isOn("handshake")) {
502            initialClientHelloMsg.print(System.out);
503        }
504
505        // deliver the ClientHello message with cookie
506        initialClientHelloMsg.write(output);
507        handshakeState.update(initialClientHelloMsg, resumingSession);
508    }
509
510    /*
511     * Server chooses session parameters given options created by the
512     * client -- basically, cipher options, session id, and someday a
513     * set of compression options.
514     *
515     * There are two branches of the state machine, decided by the
516     * details of this message.  One is the "fast" handshake, where we
517     * can resume the pre-existing session we asked resume.  The other
518     * is a more expensive "full" handshake, with key exchange and
519     * probably authentication getting done.
520     */
521    private void serverHello(ServerHello mesg) throws IOException {
522        // Dispose the reserved ClientHello message (if exists).
523        initialClientHelloMsg = null;
524
525        serverKeyExchangeReceived = false;
526        if (debug != null && Debug.isOn("handshake")) {
527            mesg.print(System.out);
528        }
529
530        // check if the server selected protocol version is OK for us
531        ProtocolVersion mesgVersion = mesg.protocolVersion;
532        if (!isNegotiable(mesgVersion)) {
533            throw new SSLHandshakeException(
534                "Server chose " + mesgVersion +
535                ", but that protocol version is not enabled or not supported " +
536                "by the client.");
537        }
538
539        handshakeHash.protocolDetermined(mesgVersion);
540
541        // Set protocolVersion and propagate to SSLSocket and the
542        // Handshake streams
543        setVersion(mesgVersion);
544
545        // check the "renegotiation_info" extension
546        RenegotiationInfoExtension serverHelloRI = (RenegotiationInfoExtension)
547                    mesg.extensions.get(ExtensionType.EXT_RENEGOTIATION_INFO);
548        if (serverHelloRI != null) {
549            if (isInitialHandshake) {
550                // verify the length of the "renegotiated_connection" field
551                if (!serverHelloRI.isEmpty()) {
552                    // abort the handshake with a fatal handshake_failure alert
553                    fatalSE(Alerts.alert_handshake_failure,
554                        "The renegotiation_info field is not empty");
555                }
556
557                secureRenegotiation = true;
558            } else {
559                // For a legacy renegotiation, the client MUST verify that
560                // it does not contain the "renegotiation_info" extension.
561                if (!secureRenegotiation) {
562                    fatalSE(Alerts.alert_handshake_failure,
563                        "Unexpected renegotiation indication extension");
564                }
565
566                // verify the client_verify_data and server_verify_data values
567                byte[] verifyData =
568                    new byte[clientVerifyData.length + serverVerifyData.length];
569                System.arraycopy(clientVerifyData, 0, verifyData,
570                        0, clientVerifyData.length);
571                System.arraycopy(serverVerifyData, 0, verifyData,
572                        clientVerifyData.length, serverVerifyData.length);
573                if (!MessageDigest.isEqual(verifyData,
574                                serverHelloRI.getRenegotiatedConnection())) {
575                    fatalSE(Alerts.alert_handshake_failure,
576                        "Incorrect verify data in ServerHello " +
577                        "renegotiation_info message");
578                }
579            }
580        } else {
581            // no renegotiation indication extension
582            if (isInitialHandshake) {
583                if (!allowLegacyHelloMessages) {
584                    // abort the handshake with a fatal handshake_failure alert
585                    fatalSE(Alerts.alert_handshake_failure,
586                        "Failed to negotiate the use of secure renegotiation");
587                }
588
589                secureRenegotiation = false;
590                if (debug != null && Debug.isOn("handshake")) {
591                    System.out.println("Warning: No renegotiation " +
592                                    "indication extension in ServerHello");
593                }
594            } else {
595                // For a secure renegotiation, the client must abort the
596                // handshake if no "renegotiation_info" extension is present.
597                if (secureRenegotiation) {
598                    fatalSE(Alerts.alert_handshake_failure,
599                        "No renegotiation indication extension");
600                }
601
602                // we have already allowed unsafe renegotation before request
603                // the renegotiation.
604            }
605        }
606
607        //
608        // Save server nonce, we always use it to compute connection
609        // keys and it's also used to create the master secret if we're
610        // creating a new session (i.e. in the full handshake).
611        //
612        svr_random = mesg.svr_random;
613
614        if (isNegotiable(mesg.cipherSuite) == false) {
615            fatalSE(Alerts.alert_illegal_parameter,
616                "Server selected improper ciphersuite " + mesg.cipherSuite);
617        }
618
619        setCipherSuite(mesg.cipherSuite);
620        if (protocolVersion.useTLS12PlusSpec()) {
621            handshakeHash.setFinishedAlg(cipherSuite.prfAlg.getPRFHashAlg());
622        }
623
624        if (mesg.compression_method != 0) {
625            fatalSE(Alerts.alert_illegal_parameter,
626                "compression type not supported, "
627                + mesg.compression_method);
628            // NOTREACHED
629        }
630
631        // so far so good, let's look at the session
632        if (session != null) {
633            // we tried to resume, let's see what the server decided
634            if (session.getSessionId().equals(mesg.sessionId)) {
635                // server resumed the session, let's make sure everything
636                // checks out
637
638                // Verify that the session ciphers are unchanged.
639                CipherSuite sessionSuite = session.getSuite();
640                if (cipherSuite != sessionSuite) {
641                    throw new SSLProtocolException
642                        ("Server returned wrong cipher suite for session");
643                }
644
645                // verify protocol version match
646                ProtocolVersion sessionVersion = session.getProtocolVersion();
647                if (protocolVersion != sessionVersion) {
648                    throw new SSLProtocolException
649                        ("Server resumed session with wrong protocol version");
650                }
651
652                // validate subject identity
653                ClientKeyExchangeService p =
654                        ClientKeyExchangeService.find(sessionSuite.keyExchange.name);
655                if (p != null) {
656                    Principal localPrincipal = session.getLocalPrincipal();
657
658                    if (p.isRelated(true, getAccSE(), localPrincipal)) {
659                        if (debug != null && Debug.isOn("session"))
660                            System.out.println("Subject identity is same");
661                    } else {
662                        throw new SSLProtocolException("Server resumed" +
663                                " session with wrong subject identity or no subject");
664                    }
665                }
666
667                // looks fine; resume it.
668                resumingSession = true;
669                calculateConnectionKeys(session.getMasterSecret());
670                if (debug != null && Debug.isOn("session")) {
671                    System.out.println("%% Server resumed " + session);
672                }
673            } else {
674                // we wanted to resume, but the server refused
675                session = null;
676                if (!enableNewSession) {
677                    throw new SSLException("New session creation is disabled");
678                }
679            }
680        }
681
682        // check the "max_fragment_length" extension
683        MaxFragmentLengthExtension maxFragLenExt = (MaxFragmentLengthExtension)
684                mesg.extensions.get(ExtensionType.EXT_MAX_FRAGMENT_LENGTH);
685        if (maxFragLenExt != null) {
686            if ((requestedMFLength == -1) ||
687                    maxFragLenExt.getMaxFragLen() != requestedMFLength) {
688                // If the client did not request this extension, or the
689                // response value is different from the length it requested,
690                // abort the handshake with a fatal illegal_parameter alert.
691                fatalSE(Alerts.alert_illegal_parameter,
692                        "Failed to negotiate the max_fragment_length");
693            }
694        } else if (!resumingSession) {
695            // no "max_fragment_length" extension
696            requestedMFLength = -1;
697        }   // Otherwise, using the value negotiated during the original
698            // session initiation
699
700        if (resumingSession && session != null) {
701            setHandshakeSessionSE(session);
702            // Reserve the handshake state if this is a session-resumption
703            // abbreviated initial handshake.
704            if (isInitialHandshake) {
705                session.setAsSessionResumption(true);
706            }
707
708            return;
709        }
710
711        // check extensions
712        for (HelloExtension ext : mesg.extensions.list()) {
713            ExtensionType type = ext.type;
714            if (type == ExtensionType.EXT_SERVER_NAME) {
715                serverNamesAccepted = true;
716            } else if (type == ExtensionType.EXT_STATUS_REQUEST ||
717                    type == ExtensionType.EXT_STATUS_REQUEST_V2) {
718                // Only enable the stapling feature if the client asserted
719                // these extensions.
720                if (enableStatusRequestExtension) {
721                    staplingActive = true;
722                } else {
723                    fatalSE(Alerts.alert_unexpected_message, "Server set " +
724                            type + " extension when not requested by client");
725                }
726            } else if ((type != ExtensionType.EXT_ELLIPTIC_CURVES)
727                    && (type != ExtensionType.EXT_EC_POINT_FORMATS)
728                    && (type != ExtensionType.EXT_SERVER_NAME)
729                    && (type != ExtensionType.EXT_RENEGOTIATION_INFO)
730                    && (type != ExtensionType.EXT_STATUS_REQUEST)
731                    && (type != ExtensionType.EXT_STATUS_REQUEST_V2)) {
732                fatalSE(Alerts.alert_unsupported_extension,
733                    "Server sent an unsupported extension: " + type);
734            }
735        }
736
737        // Create a new session, we need to do the full handshake
738        session = new SSLSessionImpl(protocolVersion, cipherSuite,
739                            getLocalSupportedSignAlgs(),
740                            mesg.sessionId, getHostSE(), getPortSE());
741        session.setRequestedServerNames(requestedServerNames);
742        session.setNegotiatedMaxFragSize(requestedMFLength);
743        session.setMaximumPacketSize(maximumPacketSize);
744        setHandshakeSessionSE(session);
745        if (debug != null && Debug.isOn("handshake")) {
746            System.out.println("** " + cipherSuite);
747        }
748    }
749
750    /*
751     * Server's own key was either a signing-only key, or was too
752     * large for export rules ... this message holds an ephemeral
753     * RSA key to use for key exchange.
754     */
755    private void serverKeyExchange(RSA_ServerKeyExchange mesg)
756            throws IOException, GeneralSecurityException {
757        if (debug != null && Debug.isOn("handshake")) {
758            mesg.print(System.out);
759        }
760        if (!mesg.verify(serverKey, clnt_random, svr_random)) {
761            fatalSE(Alerts.alert_handshake_failure,
762                "server key exchange invalid");
763            // NOTREACHED
764        }
765        ephemeralServerKey = mesg.getPublicKey();
766
767        // check constraints of RSA PublicKey
768        if (!algorithmConstraints.permits(
769            EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), ephemeralServerKey)) {
770
771            throw new SSLHandshakeException("RSA ServerKeyExchange " +
772                    "does not comply to algorithm constraints");
773        }
774    }
775
776    /*
777     * Diffie-Hellman key exchange.  We save the server public key and
778     * our own D-H algorithm object so we can defer key calculations
779     * until after we've sent the client key exchange message (which
780     * gives client and server some useful parallelism).
781     */
782    private void serverKeyExchange(DH_ServerKeyExchange mesg)
783            throws IOException {
784        if (debug != null && Debug.isOn("handshake")) {
785            mesg.print(System.out);
786        }
787        dh = new DHCrypt(mesg.getModulus(), mesg.getBase(),
788                                            sslContext.getSecureRandom());
789        serverDH = mesg.getServerPublicKey();
790
791        // check algorithm constraints
792        dh.checkConstraints(algorithmConstraints, serverDH);
793    }
794
795    private void serverKeyExchange(ECDH_ServerKeyExchange mesg)
796            throws IOException {
797        if (debug != null && Debug.isOn("handshake")) {
798            mesg.print(System.out);
799        }
800        ECPublicKey key = mesg.getPublicKey();
801        ecdh = new ECDHCrypt(key.getParams(), sslContext.getSecureRandom());
802        ephemeralServerKey = key;
803
804        // check constraints of EC PublicKey
805        if (!algorithmConstraints.permits(
806            EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), ephemeralServerKey)) {
807
808            throw new SSLHandshakeException("ECDH ServerKeyExchange " +
809                    "does not comply to algorithm constraints");
810        }
811    }
812
813    /*
814     * The server's "Hello Done" message is the client's sign that
815     * it's time to do all the hard work.
816     */
817    private void serverHelloDone(ServerHelloDone mesg) throws IOException {
818        if (debug != null && Debug.isOn("handshake")) {
819            mesg.print(System.out);
820        }
821
822        /*
823         * FIRST ... if requested, send an appropriate Certificate chain
824         * to authenticate the client, and remember the associated private
825         * key to sign the CertificateVerify message.
826         */
827        PrivateKey signingKey = null;
828
829        if (certRequest != null) {
830            X509ExtendedKeyManager km = sslContext.getX509KeyManager();
831
832            ArrayList<String> keytypesTmp = new ArrayList<>(4);
833
834            for (int i = 0; i < certRequest.types.length; i++) {
835                String typeName;
836
837                switch (certRequest.types[i]) {
838                case CertificateRequest.cct_rsa_sign:
839                    typeName = "RSA";
840                    break;
841
842                case CertificateRequest.cct_dss_sign:
843                    typeName = "DSA";
844                    break;
845
846                case CertificateRequest.cct_ecdsa_sign:
847                    // ignore if we do not have EC crypto available
848                    typeName = JsseJce.isEcAvailable() ? "EC" : null;
849                    break;
850
851                // Fixed DH/ECDH client authentication not supported
852                case CertificateRequest.cct_rsa_fixed_dh:
853                case CertificateRequest.cct_dss_fixed_dh:
854                case CertificateRequest.cct_rsa_fixed_ecdh:
855                case CertificateRequest.cct_ecdsa_fixed_ecdh:
856                // Any other values (currently not used in TLS)
857                case CertificateRequest.cct_rsa_ephemeral_dh:
858                case CertificateRequest.cct_dss_ephemeral_dh:
859                default:
860                    typeName = null;
861                    break;
862                }
863
864                if ((typeName != null) && (!keytypesTmp.contains(typeName))) {
865                    keytypesTmp.add(typeName);
866                }
867            }
868
869            String alias = null;
870            int keytypesTmpSize = keytypesTmp.size();
871            if (keytypesTmpSize != 0) {
872                String[] keytypes =
873                        keytypesTmp.toArray(new String[keytypesTmpSize]);
874
875                if (conn != null) {
876                    alias = km.chooseClientAlias(keytypes,
877                        certRequest.getAuthorities(), conn);
878                } else {
879                    alias = km.chooseEngineClientAlias(keytypes,
880                        certRequest.getAuthorities(), engine);
881                }
882            }
883
884            CertificateMsg m1 = null;
885            if (alias != null) {
886                X509Certificate[] certs = km.getCertificateChain(alias);
887                if ((certs != null) && (certs.length != 0)) {
888                    PublicKey publicKey = certs[0].getPublicKey();
889                    // for EC, make sure we use a supported named curve
890                    if (publicKey instanceof ECPublicKey) {
891                        ECParameterSpec params =
892                            ((ECPublicKey)publicKey).getParams();
893                        int index =
894                            SupportedEllipticCurvesExtension.getCurveIndex(
895                                params);
896                        if (!SupportedEllipticCurvesExtension.isSupported(
897                                index)) {
898                            publicKey = null;
899                        }
900                    }
901                    if (publicKey != null) {
902                        m1 = new CertificateMsg(certs);
903                        signingKey = km.getPrivateKey(alias);
904                        session.setLocalPrivateKey(signingKey);
905                        session.setLocalCertificates(certs);
906                    }
907                }
908            }
909            if (m1 == null) {
910                //
911                // No appropriate cert was found ... report this to the
912                // server.  For SSLv3, send the no_certificate alert;
913                // TLS uses an empty cert chain instead.
914                //
915                if (protocolVersion.useTLS10PlusSpec()) {
916                    m1 = new CertificateMsg(new X509Certificate [0]);
917                } else {
918                    warningSE(Alerts.alert_no_certificate);
919                }
920                if (debug != null && Debug.isOn("handshake")) {
921                    System.out.println(
922                        "Warning: no suitable certificate found - " +
923                        "continuing without client authentication");
924                }
925            }
926
927            //
928            // At last ... send any client certificate chain.
929            //
930            if (m1 != null) {
931                if (debug != null && Debug.isOn("handshake")) {
932                    m1.print(System.out);
933                }
934                m1.write(output);
935                handshakeState.update(m1, resumingSession);
936            }
937        }
938
939        /*
940         * SECOND ... send the client key exchange message.  The
941         * procedure used is a function of the cipher suite selected;
942         * one is always needed.
943         */
944        HandshakeMessage m2;
945
946        switch (keyExchange) {
947
948        case K_RSA:
949        case K_RSA_EXPORT:
950            if (serverKey == null) {
951                throw new SSLProtocolException
952                        ("Server did not send certificate message");
953            }
954
955            if (!(serverKey instanceof RSAPublicKey)) {
956                throw new SSLProtocolException
957                        ("Server certificate does not include an RSA key");
958            }
959
960            /*
961             * For RSA key exchange, we randomly generate a new
962             * pre-master secret and encrypt it with the server's
963             * public key.  Then we save that pre-master secret
964             * so that we can calculate the keying data later;
965             * it's a performance speedup not to do that until
966             * the client's waiting for the server response, but
967             * more of a speedup for the D-H case.
968             *
969             * If the RSA_EXPORT scheme is active, when the public
970             * key in the server certificate is less than or equal
971             * to 512 bits in length, use the cert's public key,
972             * otherwise, the ephemeral one.
973             */
974            PublicKey key;
975            if (keyExchange == K_RSA) {
976                key = serverKey;
977            } else {    // K_RSA_EXPORT
978                if (JsseJce.getRSAKeyLength(serverKey) <= 512) {
979                    // extraneous ephemeralServerKey check done
980                    // above in processMessage()
981                    key = serverKey;
982                } else {
983                    if (ephemeralServerKey == null) {
984                        throw new SSLProtocolException("Server did not send" +
985                            " a RSA_EXPORT Server Key Exchange message");
986                    }
987                    key = ephemeralServerKey;
988                }
989            }
990
991            m2 = new RSAClientKeyExchange(protocolVersion, maxProtocolVersion,
992                                sslContext.getSecureRandom(), key);
993            break;
994        case K_DH_RSA:
995        case K_DH_DSS:
996            /*
997             * For DH Key exchange, we only need to make sure the server
998             * knows our public key, so we calculate the same pre-master
999             * secret.
1000             *
1001             * For certs that had DH keys in them, we send an empty
1002             * handshake message (no key) ... we flag this case by
1003             * passing a null "dhPublic" value.
1004             *
1005             * Otherwise we send ephemeral DH keys, unsigned.
1006             */
1007            // if (useDH_RSA || useDH_DSS)
1008            m2 = new DHClientKeyExchange();
1009            break;
1010        case K_DHE_RSA:
1011        case K_DHE_DSS:
1012        case K_DH_ANON:
1013            if (dh == null) {
1014                throw new SSLProtocolException
1015                    ("Server did not send a DH Server Key Exchange message");
1016            }
1017            m2 = new DHClientKeyExchange(dh.getPublicKey());
1018            break;
1019        case K_ECDHE_RSA:
1020        case K_ECDHE_ECDSA:
1021        case K_ECDH_ANON:
1022            if (ecdh == null) {
1023                throw new SSLProtocolException
1024                    ("Server did not send a ECDH Server Key Exchange message");
1025            }
1026            m2 = new ECDHClientKeyExchange(ecdh.getPublicKey());
1027            break;
1028        case K_ECDH_RSA:
1029        case K_ECDH_ECDSA:
1030            if (serverKey == null) {
1031                throw new SSLProtocolException
1032                        ("Server did not send certificate message");
1033            }
1034            if (serverKey instanceof ECPublicKey == false) {
1035                throw new SSLProtocolException
1036                        ("Server certificate does not include an EC key");
1037            }
1038            ECParameterSpec params = ((ECPublicKey)serverKey).getParams();
1039            ecdh = new ECDHCrypt(params, sslContext.getSecureRandom());
1040            m2 = new ECDHClientKeyExchange(ecdh.getPublicKey());
1041            break;
1042        default:
1043            ClientKeyExchangeService p =
1044                    ClientKeyExchangeService.find(keyExchange.name);
1045            if (p == null) {
1046                // somethings very wrong
1047                throw new RuntimeException
1048                        ("Unsupported key exchange: " + keyExchange);
1049            }
1050            String sniHostname = null;
1051            for (SNIServerName serverName : requestedServerNames) {
1052                if (serverName instanceof SNIHostName) {
1053                    sniHostname = ((SNIHostName) serverName).getAsciiName();
1054                    break;
1055                }
1056            }
1057
1058            ClientKeyExchange exMsg = null;
1059            if (sniHostname != null) {
1060                // use first requested SNI hostname
1061                try {
1062                    exMsg = p.createClientExchange(
1063                            sniHostname, getAccSE(), protocolVersion,
1064                            sslContext.getSecureRandom());
1065                } catch(IOException e) {
1066                    if (serverNamesAccepted) {
1067                        // server accepted requested SNI hostname,
1068                        // so it must be used
1069                        throw e;
1070                    }
1071                    // fallback to using hostname
1072                    if (debug != null && Debug.isOn("handshake")) {
1073                        System.out.println(
1074                            "Warning, cannot use Server Name Indication: "
1075                                + e.getMessage());
1076                    }
1077                }
1078            }
1079
1080            if (exMsg == null) {
1081                String hostname = getHostSE();
1082                if (hostname == null) {
1083                    throw new IOException("Hostname is required" +
1084                        " to use " + keyExchange + " key exchange");
1085                }
1086                exMsg = p.createClientExchange(
1087                        hostname, getAccSE(), protocolVersion,
1088                        sslContext.getSecureRandom());
1089            }
1090
1091            // Record the principals involved in exchange
1092            session.setPeerPrincipal(exMsg.getPeerPrincipal());
1093            session.setLocalPrincipal(exMsg.getLocalPrincipal());
1094            m2 = exMsg;
1095            break;
1096        }
1097        if (debug != null && Debug.isOn("handshake")) {
1098            m2.print(System.out);
1099        }
1100        m2.write(output);
1101        handshakeState.update(m2, resumingSession);
1102
1103        /*
1104         * THIRD, send a "change_cipher_spec" record followed by the
1105         * "Finished" message.  We flush the messages we've queued up, to
1106         * get concurrency between client and server.  The concurrency is
1107         * useful as we calculate the master secret, which is needed both
1108         * to compute the "Finished" message, and to compute the keys used
1109         * to protect all records following the change_cipher_spec.
1110         */
1111        output.flush();
1112
1113        /*
1114         * We deferred calculating the master secret and this connection's
1115         * keying data; we do it now.  Deferring this calculation is good
1116         * from a performance point of view, since it lets us do it during
1117         * some time that network delays and the server's own calculations
1118         * would otherwise cause to be "dead" in the critical path.
1119         */
1120        SecretKey preMasterSecret;
1121        switch (keyExchange) {
1122        case K_RSA:
1123        case K_RSA_EXPORT:
1124            preMasterSecret = ((RSAClientKeyExchange)m2).preMaster;
1125            break;
1126        case K_DHE_RSA:
1127        case K_DHE_DSS:
1128        case K_DH_ANON:
1129            preMasterSecret = dh.getAgreedSecret(serverDH, true);
1130            break;
1131        case K_ECDHE_RSA:
1132        case K_ECDHE_ECDSA:
1133        case K_ECDH_ANON:
1134            preMasterSecret = ecdh.getAgreedSecret(ephemeralServerKey);
1135            break;
1136        case K_ECDH_RSA:
1137        case K_ECDH_ECDSA:
1138            preMasterSecret = ecdh.getAgreedSecret(serverKey);
1139            break;
1140        default:
1141            if (ClientKeyExchangeService.find(keyExchange.name) != null) {
1142                preMasterSecret =
1143                        ((ClientKeyExchange) m2).clientKeyExchange();
1144            } else {
1145                throw new IOException("Internal error: unknown key exchange "
1146                        + keyExchange);
1147            }
1148        }
1149
1150        calculateKeys(preMasterSecret, null);
1151
1152        /*
1153         * FOURTH, if we sent a Certificate, we need to send a signed
1154         * CertificateVerify (unless the key in the client's certificate
1155         * was a Diffie-Hellman key).).
1156         *
1157         * This uses a hash of the previous handshake messages ... either
1158         * a nonfinal one (if the particular implementation supports it)
1159         * or else using the third element in the arrays of hashes being
1160         * computed.
1161         */
1162        if (signingKey != null) {
1163            CertificateVerify m3;
1164            try {
1165                SignatureAndHashAlgorithm preferableSignatureAlgorithm = null;
1166                if (protocolVersion.useTLS12PlusSpec()) {
1167                    preferableSignatureAlgorithm =
1168                        SignatureAndHashAlgorithm.getPreferableAlgorithm(
1169                            peerSupportedSignAlgs, signingKey.getAlgorithm(),
1170                            signingKey);
1171
1172                    if (preferableSignatureAlgorithm == null) {
1173                        throw new SSLHandshakeException(
1174                            "No supported signature algorithm");
1175                    }
1176
1177                    String hashAlg =
1178                        SignatureAndHashAlgorithm.getHashAlgorithmName(
1179                                preferableSignatureAlgorithm);
1180                    if (hashAlg == null || hashAlg.length() == 0) {
1181                        throw new SSLHandshakeException(
1182                                "No supported hash algorithm");
1183                    }
1184                }
1185
1186                m3 = new CertificateVerify(protocolVersion, handshakeHash,
1187                    signingKey, session.getMasterSecret(),
1188                    sslContext.getSecureRandom(),
1189                    preferableSignatureAlgorithm);
1190            } catch (GeneralSecurityException e) {
1191                fatalSE(Alerts.alert_handshake_failure,
1192                    "Error signing certificate verify", e);
1193                // NOTREACHED, make compiler happy
1194                m3 = null;
1195            }
1196            if (debug != null && Debug.isOn("handshake")) {
1197                m3.print(System.out);
1198            }
1199            m3.write(output);
1200            handshakeState.update(m3, resumingSession);
1201            output.flush();
1202        }
1203
1204        /*
1205         * OK, that's that!
1206         */
1207        sendChangeCipherAndFinish(false);
1208
1209        // expecting the final ChangeCipherSpec and Finished messages
1210        expectingFinishFlightSE();
1211    }
1212
1213
1214    /*
1215     * "Finished" is the last handshake message sent.  If we got this
1216     * far, the MAC has been validated post-decryption.  We validate
1217     * the two hashes here as an additional sanity check, protecting
1218     * the handshake against various active attacks.
1219     */
1220    private void serverFinished(Finished mesg) throws IOException {
1221        if (debug != null && Debug.isOn("handshake")) {
1222            mesg.print(System.out);
1223        }
1224
1225        boolean verified = mesg.verify(handshakeHash, Finished.SERVER,
1226            session.getMasterSecret());
1227
1228        if (!verified) {
1229            fatalSE(Alerts.alert_illegal_parameter,
1230                       "server 'finished' message doesn't verify");
1231            // NOTREACHED
1232        }
1233
1234        /*
1235         * save server verify data for secure renegotiation
1236         */
1237        if (secureRenegotiation) {
1238            serverVerifyData = mesg.getVerifyData();
1239        }
1240
1241        /*
1242         * Reset the handshake state if this is not an initial handshake.
1243         */
1244        if (!isInitialHandshake) {
1245            session.setAsSessionResumption(false);
1246        }
1247
1248        /*
1249         * OK, it verified.  If we're doing the fast handshake, add that
1250         * "Finished" message to the hash of handshake messages, then send
1251         * our own change_cipher_spec and Finished message for the server
1252         * to verify in turn.  These are the last handshake messages.
1253         *
1254         * In any case, update the session cache.  We're done handshaking,
1255         * so there are no threats any more associated with partially
1256         * completed handshakes.
1257         */
1258        if (resumingSession) {
1259            sendChangeCipherAndFinish(true);
1260        } else {
1261            handshakeFinished = true;
1262        }
1263        session.setLastAccessedTime(System.currentTimeMillis());
1264
1265        if (!resumingSession) {
1266            if (session.isRejoinable()) {
1267                ((SSLSessionContextImpl) sslContext
1268                        .engineGetClientSessionContext())
1269                        .put(session);
1270                if (debug != null && Debug.isOn("session")) {
1271                    System.out.println("%% Cached client session: " + session);
1272                }
1273            } else if (debug != null && Debug.isOn("session")) {
1274                System.out.println(
1275                    "%% Didn't cache non-resumable client session: "
1276                    + session);
1277            }
1278        }
1279    }
1280
1281
1282    /*
1283     * Send my change-cipher-spec and Finished message ... done as the
1284     * last handshake act in either the short or long sequences.  In
1285     * the short one, we've already seen the server's Finished; in the
1286     * long one, we wait for it now.
1287     */
1288    private void sendChangeCipherAndFinish(boolean finishedTag)
1289            throws IOException {
1290
1291        // Reload if this message has been reserved.
1292        handshakeHash.reload();
1293
1294        Finished mesg = new Finished(protocolVersion, handshakeHash,
1295            Finished.CLIENT, session.getMasterSecret(), cipherSuite);
1296
1297        /*
1298         * Send the change_cipher_spec message, then the Finished message
1299         * which we just calculated (and protected using the keys we just
1300         * calculated).  Server responds with its Finished message, except
1301         * in the "fast handshake" (resume session) case.
1302         */
1303        sendChangeCipherSpec(mesg, finishedTag);
1304
1305        /*
1306         * save client verify data for secure renegotiation
1307         */
1308        if (secureRenegotiation) {
1309            clientVerifyData = mesg.getVerifyData();
1310        }
1311    }
1312
1313
1314    /*
1315     * Returns a ClientHello message to kickstart renegotiations
1316     */
1317    @Override
1318    HandshakeMessage getKickstartMessage() throws SSLException {
1319        // session ID of the ClientHello message
1320        SessionId sessionId = SSLSessionImpl.nullSession.getSessionId();
1321
1322        // a list of cipher suites sent by the client
1323        CipherSuiteList cipherSuites = getActiveCipherSuites();
1324
1325        // set the max protocol version this client is supporting.
1326        maxProtocolVersion = protocolVersion;
1327
1328        //
1329        // Try to resume an existing session.  This might be mandatory,
1330        // given certain API options.
1331        //
1332        session = ((SSLSessionContextImpl)sslContext
1333                        .engineGetClientSessionContext())
1334                        .get(getHostSE(), getPortSE());
1335        if (debug != null && Debug.isOn("session")) {
1336            if (session != null) {
1337                System.out.println("%% Client cached "
1338                    + session
1339                    + (session.isRejoinable() ? "" : " (not rejoinable)"));
1340            } else {
1341                System.out.println("%% No cached client session");
1342            }
1343        }
1344        if (session != null) {
1345            // If unsafe server certificate change is not allowed, reserve
1346            // current server certificates if the previous handshake is a
1347            // session-resumption abbreviated initial handshake.
1348            if (!allowUnsafeServerCertChange && session.isSessionResumption()) {
1349                try {
1350                    // If existing, peer certificate chain cannot be null.
1351                    reservedServerCerts =
1352                        (X509Certificate[])session.getPeerCertificates();
1353                } catch (SSLPeerUnverifiedException puve) {
1354                    // Maybe not certificate-based, ignore the exception.
1355                }
1356            }
1357
1358            if (!session.isRejoinable()) {
1359                session = null;
1360            }
1361        }
1362
1363        if (session != null) {
1364            CipherSuite sessionSuite = session.getSuite();
1365            ProtocolVersion sessionVersion = session.getProtocolVersion();
1366            if (isNegotiable(sessionSuite) == false) {
1367                if (debug != null && Debug.isOn("session")) {
1368                    System.out.println("%% can't resume, unavailable cipher");
1369                }
1370                session = null;
1371            }
1372
1373            if ((session != null) && !isNegotiable(sessionVersion)) {
1374                if (debug != null && Debug.isOn("session")) {
1375                    System.out.println("%% can't resume, protocol disabled");
1376                }
1377                session = null;
1378            }
1379
1380            if (session != null) {
1381                if (debug != null) {
1382                    if (Debug.isOn("handshake") || Debug.isOn("session")) {
1383                        System.out.println("%% Try resuming " + session
1384                            + " from port " + getLocalPortSE());
1385                    }
1386                }
1387
1388                sessionId = session.getSessionId();
1389                maxProtocolVersion = sessionVersion;
1390
1391                // Update SSL version number in underlying SSL socket and
1392                // handshake output stream, so that the output records (at the
1393                // record layer) have the correct version
1394                setVersion(sessionVersion);
1395            }
1396
1397            /*
1398             * Force use of the previous session ciphersuite, and
1399             * add the SCSV if enabled.
1400             */
1401            if (!enableNewSession) {
1402                if (session == null) {
1403                    throw new SSLHandshakeException(
1404                        "Can't reuse existing SSL client session");
1405                }
1406
1407                Collection<CipherSuite> cipherList = new ArrayList<>(2);
1408                cipherList.add(sessionSuite);
1409                if (!secureRenegotiation &&
1410                        cipherSuites.contains(CipherSuite.C_SCSV)) {
1411                    cipherList.add(CipherSuite.C_SCSV);
1412                }   // otherwise, renegotiation_info extension will be used
1413
1414                cipherSuites = new CipherSuiteList(cipherList);
1415            }
1416        }
1417
1418        if (session == null && !enableNewSession) {
1419            throw new SSLHandshakeException("No existing session to resume");
1420        }
1421
1422        // exclude SCSV for secure renegotiation
1423        if (secureRenegotiation && cipherSuites.contains(CipherSuite.C_SCSV)) {
1424            Collection<CipherSuite> cipherList =
1425                        new ArrayList<>(cipherSuites.size() - 1);
1426            for (CipherSuite suite : cipherSuites.collection()) {
1427                if (suite != CipherSuite.C_SCSV) {
1428                    cipherList.add(suite);
1429                }
1430            }
1431
1432            cipherSuites = new CipherSuiteList(cipherList);
1433        }
1434
1435        // make sure there is a negotiable cipher suite.
1436        boolean negotiable = false;
1437        for (CipherSuite suite : cipherSuites.collection()) {
1438            if (isNegotiable(suite)) {
1439                negotiable = true;
1440                break;
1441            }
1442        }
1443
1444        if (!negotiable) {
1445            throw new SSLHandshakeException("No negotiable cipher suite");
1446        }
1447
1448        // Not a TLS1.2+ handshake
1449        // For SSLv2Hello, HandshakeHash.reset() will be called, so we
1450        // cannot call HandshakeHash.protocolDetermined() here. As it does
1451        // not follow the spec that HandshakeHash.reset() can be only be
1452        // called before protocolDetermined.
1453        // if (maxProtocolVersion.v < ProtocolVersion.TLS12.v) {
1454        //     handshakeHash.protocolDetermined(maxProtocolVersion);
1455        // }
1456
1457        // create the ClientHello message
1458        ClientHello clientHelloMessage = new ClientHello(
1459                sslContext.getSecureRandom(), maxProtocolVersion,
1460                sessionId, cipherSuites, isDTLS);
1461
1462        // add signature_algorithm extension
1463        if (maxProtocolVersion.useTLS12PlusSpec()) {
1464            // we will always send the signature_algorithm extension
1465            Collection<SignatureAndHashAlgorithm> localSignAlgs =
1466                                                getLocalSupportedSignAlgs();
1467            if (localSignAlgs.isEmpty()) {
1468                throw new SSLHandshakeException(
1469                            "No supported signature algorithm");
1470            }
1471
1472            clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs);
1473        }
1474
1475        // add server_name extension
1476        if (enableSNIExtension) {
1477            if (session != null) {
1478                requestedServerNames = session.getRequestedServerNames();
1479            } else {
1480                requestedServerNames = serverNames;
1481            }
1482
1483            if (!requestedServerNames.isEmpty()) {
1484                clientHelloMessage.addSNIExtension(requestedServerNames);
1485            }
1486        }
1487
1488        // add max_fragment_length extension
1489        if (enableMFLExtension) {
1490            if (session != null) {
1491                // The same extension should be sent for resumption.
1492                requestedMFLength = session.getNegotiatedMaxFragSize();
1493            } else if (maximumPacketSize != 0) {
1494                // Maybe we can calculate the fragment size more accurate
1495                // by condering the enabled cipher suites in the future.
1496                requestedMFLength = maximumPacketSize;
1497                if (isDTLS) {
1498                    requestedMFLength -= DTLSRecord.maxPlaintextPlusSize;
1499                } else {
1500                    requestedMFLength -= SSLRecord.maxPlaintextPlusSize;
1501                }
1502            } else {
1503                // Need no max_fragment_length extension.
1504                requestedMFLength = -1;
1505            }
1506
1507            if ((requestedMFLength > 0) &&
1508                MaxFragmentLengthExtension.needFragLenNego(requestedMFLength)) {
1509
1510                requestedMFLength =
1511                        MaxFragmentLengthExtension.getValidMaxFragLen(
1512                                                        requestedMFLength);
1513                clientHelloMessage.addMFLExtension(requestedMFLength);
1514            } else {
1515                requestedMFLength = -1;
1516            }
1517        }
1518
1519        // Add status_request and status_request_v2 extensions
1520        if (enableStatusRequestExtension) {
1521            clientHelloMessage.addCertStatusReqListV2Extension();
1522            clientHelloMessage.addCertStatusRequestExtension();
1523        }
1524
1525        // reset the client random cookie
1526        clnt_random = clientHelloMessage.clnt_random;
1527
1528        /*
1529         * need to set the renegotiation_info extension for:
1530         * 1: secure renegotiation
1531         * 2: initial handshake and no SCSV in the ClientHello
1532         * 3: insecure renegotiation and no SCSV in the ClientHello
1533         */
1534        if (secureRenegotiation ||
1535                !cipherSuites.contains(CipherSuite.C_SCSV)) {
1536            clientHelloMessage.addRenegotiationInfoExtension(clientVerifyData);
1537        }
1538
1539        if (isDTLS) {
1540            // Cookie exchange need to reserve the initial ClientHello message.
1541            initialClientHelloMsg = clientHelloMessage;
1542        }
1543
1544        return clientHelloMessage;
1545    }
1546
1547    /*
1548     * Fault detected during handshake.
1549     */
1550    @Override
1551    void handshakeAlert(byte description) throws SSLProtocolException {
1552        String message = Alerts.alertDescription(description);
1553
1554        if (debug != null && Debug.isOn("handshake")) {
1555            System.out.println("SSL - handshake alert: " + message);
1556        }
1557        throw new SSLProtocolException("handshake alert:  " + message);
1558    }
1559
1560    /*
1561     * Unless we are using an anonymous ciphersuite, the server always
1562     * sends a certificate message (for the CipherSuites we currently
1563     * support). The trust manager verifies the chain for us.
1564     */
1565    private void serverCertificate(CertificateMsg mesg) throws IOException {
1566        if (debug != null && Debug.isOn("handshake")) {
1567            mesg.print(System.out);
1568        }
1569        X509Certificate[] peerCerts = mesg.getCertificateChain();
1570        if (peerCerts.length == 0) {
1571            fatalSE(Alerts.alert_bad_certificate, "empty certificate chain");
1572        }
1573
1574        // Allow server certificate change in client side during renegotiation
1575        // after a session-resumption abbreviated initial handshake?
1576        //
1577        // DO NOT need to check allowUnsafeServerCertChange here. We only
1578        // reserve server certificates when allowUnsafeServerCertChange is
1579        // flase.
1580        if (reservedServerCerts != null) {
1581            // It is not necessary to check the certificate update if endpoint
1582            // identification is enabled.
1583            String identityAlg = getEndpointIdentificationAlgorithmSE();
1584            if ((identityAlg == null || identityAlg.length() == 0) &&
1585                !isIdentityEquivalent(peerCerts[0], reservedServerCerts[0])) {
1586
1587                fatalSE(Alerts.alert_bad_certificate,
1588                        "server certificate change is restricted " +
1589                        "during renegotiation");
1590            }
1591        }
1592
1593        // ask the trust manager to verify the chain
1594        if (staplingActive) {
1595            // Defer the certificate check until after we've received the
1596            // CertificateStatus message.  If that message doesn't come in
1597            // immediately following this message we will execute the check
1598            // directly from processMessage before any other SSL/TLS processing.
1599            deferredCerts = peerCerts;
1600        } else {
1601            // We're not doing stapling, so perform the check right now
1602            checkServerCerts(peerCerts);
1603        }
1604    }
1605
1606    /**
1607     * If certificate status stapling has been enabled, the server will send
1608     * one or more status messages to the client.
1609     *
1610     * @param mesg a {@code CertificateStatus} object built from the data
1611     *      sent by the server.
1612     *
1613     * @throws IOException if any parsing errors occur.
1614     */
1615    private void certificateStatus(CertificateStatus mesg) throws IOException {
1616        if (debug != null && Debug.isOn("handshake")) {
1617            mesg.print(System.out);
1618        }
1619
1620        // Perform the certificate check using the deferred certificates
1621        // and responses that we have obtained.
1622        session.setStatusResponses(mesg.getResponses());
1623        checkServerCerts(deferredCerts);
1624    }
1625
1626    /*
1627     * Whether the certificates can represent the same identity?
1628     *
1629     * The certificates can be used to represent the same identity:
1630     *     1. If the subject alternative names of IP address are present in
1631     *        both certificates, they should be identical; otherwise,
1632     *     2. if the subject alternative names of DNS name are present in
1633     *        both certificates, they should be identical; otherwise,
1634     *     3. if the subject fields are present in both certificates, the
1635     *        certificate subjects and issuers should be identical.
1636     */
1637    private static boolean isIdentityEquivalent(X509Certificate thisCert,
1638            X509Certificate prevCert) {
1639        if (thisCert.equals(prevCert)) {
1640            return true;
1641        }
1642
1643        // check subject alternative names
1644        Collection<List<?>> thisSubjectAltNames = null;
1645        try {
1646            thisSubjectAltNames = thisCert.getSubjectAlternativeNames();
1647        } catch (CertificateParsingException cpe) {
1648            if (debug != null && Debug.isOn("handshake")) {
1649                System.out.println(
1650                        "Attempt to obtain subjectAltNames extension failed!");
1651            }
1652        }
1653
1654        Collection<List<?>> prevSubjectAltNames = null;
1655        try {
1656            prevSubjectAltNames = prevCert.getSubjectAlternativeNames();
1657        } catch (CertificateParsingException cpe) {
1658            if (debug != null && Debug.isOn("handshake")) {
1659                System.out.println(
1660                        "Attempt to obtain subjectAltNames extension failed!");
1661            }
1662        }
1663
1664        if ((thisSubjectAltNames != null) && (prevSubjectAltNames != null)) {
1665            // check the iPAddress field in subjectAltName extension
1666            Collection<String> thisSubAltIPAddrs =
1667                        getSubjectAltNames(thisSubjectAltNames, ALTNAME_IP);
1668            Collection<String> prevSubAltIPAddrs =
1669                        getSubjectAltNames(prevSubjectAltNames, ALTNAME_IP);
1670            if ((thisSubAltIPAddrs != null) && (prevSubAltIPAddrs != null) &&
1671                (isEquivalent(thisSubAltIPAddrs, prevSubAltIPAddrs))) {
1672
1673                return true;
1674            }
1675
1676            // check the dNSName field in subjectAltName extension
1677            Collection<String> thisSubAltDnsNames =
1678                        getSubjectAltNames(thisSubjectAltNames, ALTNAME_DNS);
1679            Collection<String> prevSubAltDnsNames =
1680                        getSubjectAltNames(prevSubjectAltNames, ALTNAME_DNS);
1681            if ((thisSubAltDnsNames != null) && (prevSubAltDnsNames != null) &&
1682                (isEquivalent(thisSubAltDnsNames, prevSubAltDnsNames))) {
1683
1684                return true;
1685            }
1686        }
1687
1688        // check the certificate subject and issuer
1689        X500Principal thisSubject = thisCert.getSubjectX500Principal();
1690        X500Principal prevSubject = prevCert.getSubjectX500Principal();
1691        X500Principal thisIssuer = thisCert.getIssuerX500Principal();
1692        X500Principal prevIssuer = prevCert.getIssuerX500Principal();
1693        if (!thisSubject.getName().isEmpty() &&
1694                !prevSubject.getName().isEmpty() &&
1695                thisSubject.equals(prevSubject) &&
1696                thisIssuer.equals(prevIssuer)) {
1697            return true;
1698        }
1699
1700        return false;
1701    }
1702
1703    /*
1704     * Returns the subject alternative name of the specified type in the
1705     * subjectAltNames extension of a certificate.
1706     *
1707     * Note that only those subjectAltName types that use String data
1708     * should be passed into this function.
1709     */
1710    private static Collection<String> getSubjectAltNames(
1711            Collection<List<?>> subjectAltNames, int type) {
1712
1713        HashSet<String> subAltDnsNames = null;
1714        for (List<?> subjectAltName : subjectAltNames) {
1715            int subjectAltNameType = (Integer)subjectAltName.get(0);
1716            if (subjectAltNameType == type) {
1717                String subAltDnsName = (String)subjectAltName.get(1);
1718                if ((subAltDnsName != null) && !subAltDnsName.isEmpty()) {
1719                    if (subAltDnsNames == null) {
1720                        subAltDnsNames =
1721                                new HashSet<>(subjectAltNames.size());
1722                    }
1723                    subAltDnsNames.add(subAltDnsName);
1724                }
1725            }
1726        }
1727
1728        return subAltDnsNames;
1729    }
1730
1731    private static boolean isEquivalent(Collection<String> thisSubAltNames,
1732            Collection<String> prevSubAltNames) {
1733
1734        for (String thisSubAltName : thisSubAltNames) {
1735            for (String prevSubAltName : prevSubAltNames) {
1736                // Only allow the exactly match.  Check no wildcard character.
1737                if (thisSubAltName.equalsIgnoreCase(prevSubAltName)) {
1738                    return true;
1739                }
1740            }
1741        }
1742
1743        return false;
1744    }
1745
1746    /**
1747     * Perform client-side checking of server certificates.
1748     *
1749     * @param certs an array of {@code X509Certificate} objects presented
1750     *      by the server in the ServerCertificate message.
1751     *
1752     * @throws IOException if a failure occurs during validation or
1753     *      the trust manager associated with the {@code SSLContext} is not
1754     *      an {@code X509ExtendedTrustManager}.
1755     */
1756    private void checkServerCerts(X509Certificate[] certs)
1757            throws IOException {
1758        X509TrustManager tm = sslContext.getX509TrustManager();
1759
1760        // find out the key exchange algorithm used
1761        // use "RSA" for non-ephemeral "RSA_EXPORT"
1762        String keyExchangeString;
1763        if (keyExchange == K_RSA_EXPORT && !serverKeyExchangeReceived) {
1764            keyExchangeString = K_RSA.name;
1765        } else {
1766            keyExchangeString = keyExchange.name;
1767        }
1768
1769        try {
1770            if (tm instanceof X509ExtendedTrustManager) {
1771                if (conn != null) {
1772                    ((X509ExtendedTrustManager)tm).checkServerTrusted(
1773                        certs.clone(),
1774                        keyExchangeString,
1775                        conn);
1776                } else {
1777                    ((X509ExtendedTrustManager)tm).checkServerTrusted(
1778                        certs.clone(),
1779                        keyExchangeString,
1780                        engine);
1781                }
1782            } else {
1783                // Unlikely to happen, because we have wrapped the old
1784                // X509TrustManager with the new X509ExtendedTrustManager.
1785                throw new CertificateException(
1786                        "Improper X509TrustManager implementation");
1787            }
1788
1789            // Once the server certificate chain has been validated, set
1790            // the certificate chain in the TLS session.
1791            session.setPeerCertificates(certs);
1792        } catch (CertificateException ce) {
1793            fatalSE(getCertificateAlert(ce), ce);
1794        }
1795    }
1796
1797    /**
1798     * When a failure happens during certificate checking from an
1799     * {@link X509TrustManager}, determine what TLS alert description to use.
1800     *
1801     * @param cexc The exception thrown by the {@link X509TrustManager}
1802     *
1803     * @return A byte value corresponding to a TLS alert description number.
1804     */
1805    private byte getCertificateAlert(CertificateException cexc) {
1806        // The specific reason for the failure will determine how to
1807        // set the alert description value
1808        byte alertDesc = Alerts.alert_certificate_unknown;
1809
1810        Throwable baseCause = cexc.getCause();
1811        if (baseCause instanceof CertPathValidatorException) {
1812            CertPathValidatorException cpve =
1813                    (CertPathValidatorException)baseCause;
1814            Reason reason = cpve.getReason();
1815            if (reason == BasicReason.REVOKED) {
1816                alertDesc = staplingActive ?
1817                        Alerts.alert_bad_certificate_status_response :
1818                        Alerts.alert_certificate_revoked;
1819            } else if (reason == BasicReason.UNDETERMINED_REVOCATION_STATUS) {
1820                alertDesc = staplingActive ?
1821                        Alerts.alert_bad_certificate_status_response :
1822                        Alerts.alert_certificate_unknown;
1823            }
1824        }
1825
1826        return alertDesc;
1827    }
1828}
1829
1830