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