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