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