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