124 * same (See isIdentityEquivalent()).
125 *
126 * Considering the compatibility impact and the actual requirements to
127 * support server certificate change in practice, the system property,
128 * jdk.tls.allowUnsafeServerCertChange, is used to define whether unsafe
129 * server certificate change in renegotiation is allowed or not. The
130 * default value of the system property is "false". To mitigate the
131 * compactibility impact, applications may want to set the system
132 * property to "true" at their own risk.
133 *
134 * If the value of the system property is "false", server certificate
135 * change in renegotiation after a session-resumption abbreviated initial
136 * handshake is restricted (See isIdentityEquivalent()).
137 *
138 * If the system property is set to "true" explicitly, the restriction on
139 * server certificate change in renegotiation is disabled.
140 */
141 private final static boolean allowUnsafeServerCertChange =
142 Debug.getBooleanProperty("jdk.tls.allowUnsafeServerCertChange", false);
143
144 private List<SNIServerName> requestedServerNames =
145 Collections.<SNIServerName>emptyList();
146
147 private boolean serverNamesAccepted = false;
148
149 /*
150 * the reserved server certificate chain in previous handshaking
151 *
152 * The server certificate chain is only reserved if the previous
153 * handshake is a session-resumption abbreviated initial handshake.
154 */
155 private X509Certificate[] reservedServerCerts = null;
156
157 /*
158 * Constructors
159 */
160 ClientHandshaker(SSLSocketImpl socket, SSLContextImpl context,
161 ProtocolList enabledProtocols,
162 ProtocolVersion activeProtocolVersion,
163 boolean isInitialHandshake, boolean secureRenegotiation,
164 byte[] clientVerifyData, byte[] serverVerifyData) {
165
166 super(socket, context, enabledProtocols, true, true,
167 activeProtocolVersion, isInitialHandshake, secureRenegotiation,
168 clientVerifyData, serverVerifyData);
169 }
170
171 ClientHandshaker(SSLEngineImpl engine, SSLContextImpl context,
172 ProtocolList enabledProtocols,
173 ProtocolVersion activeProtocolVersion,
174 boolean isInitialHandshake, boolean secureRenegotiation,
175 byte[] clientVerifyData, byte[] serverVerifyData) {
176
177 super(engine, context, enabledProtocols, true, true,
178 activeProtocolVersion, isInitialHandshake, secureRenegotiation,
179 clientVerifyData, serverVerifyData);
180 }
181
182 /*
183 * This routine handles all the client side handshake messages, one at
184 * a time. Given the message type (and in some cases the pending cipher
185 * spec) it parses the type-specific message. Then it calls a function
186 * that handles that specific message.
187 *
188 * It updates the state machine (need to verify it) as each message
189 * is processed, and writes responses as needed using the connection
190 * in the constructor.
191 */
192 @Override
193 void processMessage(byte type, int messageLen) throws IOException {
194 if (state >= type
195 && (type != HandshakeMessage.ht_hello_request)) {
196 throw new SSLProtocolException(
197 "Handshake message sequence violation, " + type);
198 }
199
200 switch (type) {
201 case HandshakeMessage.ht_hello_request:
202 this.serverHelloRequest(new HelloRequest(input));
203 break;
204
205 case HandshakeMessage.ht_server_hello:
206 this.serverHello(new ServerHello(input, messageLen));
207 break;
208
209 case HandshakeMessage.ht_certificate:
210 if (keyExchange == K_DH_ANON || keyExchange == K_ECDH_ANON
211 || keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
212 fatalSE(Alerts.alert_unexpected_message,
213 "unexpected server cert chain");
214 // NOTREACHED
215 }
216 this.serverCertificate(new CertificateMsg(input));
217 serverKey =
218 session.getPeerCertificates()[0].getPublicKey();
219 break;
220
221 case HandshakeMessage.ht_server_key_exchange:
222 serverKeyExchangeReceived = true;
223 switch (keyExchange) {
224 case K_RSA_EXPORT:
225 /**
226 * The server key exchange message is sent by the server only
227 * when the server certificate message does not contain the
228 * proper amount of data to allow the client to exchange a
229 * premaster secret, such as when RSA_EXPORT is used and the
230 * public key in the server certificate is longer than 512 bits.
231 */
232 if (serverKey == null) {
233 throw new SSLProtocolException
234 ("Server did not send certificate message");
235 }
236
237 if (!(serverKey instanceof RSAPublicKey)) {
238 throw new SSLProtocolException("Protocol violation:" +
239 " the certificate type must be appropriate for the" +
240 " selected cipher suite's key exchange algorithm");
241 }
242
243 if (JsseJce.getRSAKeyLength(serverKey) <= 512) {
244 throw new SSLProtocolException("Protocol violation:" +
245 " server sent a server key exchange message for" +
246 " key exchange " + keyExchange +
247 " when the public key in the server certificate" +
248 " is less than or equal to 512 bits in length");
249 }
250
251 try {
252 this.serverKeyExchange(new RSA_ServerKeyExchange(input));
253 } catch (GeneralSecurityException e) {
254 throwSSLException("Server key", e);
255 }
256 break;
257 case K_DH_ANON:
258 try {
259 this.serverKeyExchange(new DH_ServerKeyExchange(
260 input, protocolVersion));
261 } catch (GeneralSecurityException e) {
262 throwSSLException("Server key", e);
263 }
264 break;
265 case K_DHE_DSS:
266 case K_DHE_RSA:
267 try {
268 this.serverKeyExchange(new DH_ServerKeyExchange(
269 input, serverKey,
270 clnt_random.random_bytes, svr_random.random_bytes,
271 messageLen,
272 localSupportedSignAlgs, protocolVersion));
273 } catch (GeneralSecurityException e) {
274 throwSSLException("Server key", e);
275 }
276 break;
277 case K_ECDHE_ECDSA:
278 case K_ECDHE_RSA:
279 case K_ECDH_ANON:
280 try {
281 this.serverKeyExchange(new ECDH_ServerKeyExchange
282 (input, serverKey, clnt_random.random_bytes,
283 svr_random.random_bytes,
284 localSupportedSignAlgs, protocolVersion));
285 } catch (GeneralSecurityException e) {
286 throwSSLException("Server key", e);
287 }
288 break;
289 case K_RSA:
290 case K_DH_RSA:
291 case K_DH_DSS:
292 case K_ECDH_ECDSA:
293 case K_ECDH_RSA:
294 throw new SSLProtocolException(
295 "Protocol violation: server sent a server key exchange"
296 + " message for key exchange " + keyExchange);
297 case K_KRB5:
298 case K_KRB5_EXPORT:
299 throw new SSLProtocolException(
300 "unexpected receipt of server key exchange algorithm");
301 default:
302 throw new SSLProtocolException(
303 "unsupported key exchange algorithm = "
304 + keyExchange);
305 }
306 break;
307
308 case HandshakeMessage.ht_certificate_request:
309 // save for later, it's handled by serverHelloDone
310 if ((keyExchange == K_DH_ANON) || (keyExchange == K_ECDH_ANON)) {
311 throw new SSLHandshakeException(
312 "Client authentication requested for "+
313 "anonymous cipher suite.");
314 } else if (keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
315 throw new SSLHandshakeException(
316 "Client certificate requested for "+
317 "kerberos cipher suite.");
318 }
319 certRequest = new CertificateRequest(input, protocolVersion);
320 if (debug != null && Debug.isOn("handshake")) {
321 certRequest.print(System.out);
322 }
323
324 if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
325 Collection<SignatureAndHashAlgorithm> peerSignAlgs =
326 certRequest.getSignAlgorithms();
327 if (peerSignAlgs == null || peerSignAlgs.isEmpty()) {
328 throw new SSLHandshakeException(
329 "No peer supported signature algorithms");
330 }
331
332 Collection<SignatureAndHashAlgorithm> supportedPeerSignAlgs =
333 SignatureAndHashAlgorithm.getSupportedAlgorithms(
334 peerSignAlgs);
335 if (supportedPeerSignAlgs.isEmpty()) {
336 throw new SSLHandshakeException(
337 "No supported signature and hash algorithm in common");
338 }
339
340 setPeerSupportedSignAlgs(supportedPeerSignAlgs);
341 session.setPeerSupportedSignatureAlgorithms(
342 supportedPeerSignAlgs);
343 }
344
345 break;
346
347 case HandshakeMessage.ht_server_hello_done:
348 this.serverHelloDone(new ServerHelloDone(input));
349 break;
350
351 case HandshakeMessage.ht_finished:
352 // A ChangeCipherSpec record must have been received prior to
353 // reception of the Finished message (RFC 5246, 7.4.9).
354 if (!receivedChangeCipherSpec()) {
355 fatalSE(Alerts.alert_handshake_failure,
356 "Received Finished message before ChangeCipherSpec");
357 }
358
359 this.serverFinished(
360 new Finished(protocolVersion, input, cipherSuite));
361 break;
362
363 default:
364 throw new SSLProtocolException(
365 "Illegal client handshake msg, " + type);
366 }
367
368 //
369 // Move state machine forward if the message handling
370 // code didn't already do so
371 //
372 if (state < type) {
373 state = type;
374 }
375 }
376
377 /*
378 * Used by the server to kickstart negotiations -- this requests a
379 * "client hello" to renegotiate current cipher specs (e.g. maybe lots
380 * of data has been encrypted with the same keys, or the server needs
381 * the client to present a certificate).
382 */
383 private void serverHelloRequest(HelloRequest mesg) throws IOException {
384 if (debug != null && Debug.isOn("handshake")) {
385 mesg.print(System.out);
386 }
387
388 //
389 // Could be (e.g. at connection setup) that we already
390 // sent the "client hello" but the server's not seen it.
391 //
392 if (state < HandshakeMessage.ht_client_hello) {
393 if (!secureRenegotiation && !allowUnsafeRenegotiation) {
394 // renegotiation is not allowed.
395 if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) {
396 // response with a no_renegotiation warning,
397 warningSE(Alerts.alert_no_renegotiation);
398
399 // invalidate the handshake so that the caller can
400 // dispose this object.
401 invalidated = true;
402
403 // If there is still unread block in the handshake
404 // input stream, it would be truncated with the disposal
405 // and the next handshake message will become incomplete.
406 //
407 // However, according to SSL/TLS specifications, no more
408 // handshake message should immediately follow ClientHello
409 // or HelloRequest. So just let it be.
410 } else {
411 // For SSLv3, send the handshake_failure fatal error.
412 // Note that SSLv3 does not define a no_renegotiation
413 // alert like TLSv1. However we cannot ignore the message
414 // simply, otherwise the other side was waiting for a
415 // response that would never come.
416 fatalSE(Alerts.alert_handshake_failure,
417 "Renegotiation is not allowed");
418 }
419 } else {
420 if (!secureRenegotiation) {
421 if (debug != null && Debug.isOn("handshake")) {
422 System.out.println(
423 "Warning: continue with insecure renegotiation");
424 }
425 }
426 kickstart();
427 }
428 }
429 }
430
431
432 /*
433 * Server chooses session parameters given options created by the
434 * client -- basically, cipher options, session id, and someday a
435 * set of compression options.
436 *
437 * There are two branches of the state machine, decided by the
438 * details of this message. One is the "fast" handshake, where we
439 * can resume the pre-existing session we asked resume. The other
440 * is a more expensive "full" handshake, with key exchange and
441 * probably authentication getting done.
442 */
443 private void serverHello(ServerHello mesg) throws IOException {
444 serverKeyExchangeReceived = false;
445 if (debug != null && Debug.isOn("handshake")) {
446 mesg.print(System.out);
447 }
448
449 // check if the server selected protocol version is OK for us
450 ProtocolVersion mesgVersion = mesg.protocolVersion;
451 if (!isNegotiable(mesgVersion)) {
452 throw new SSLHandshakeException(
453 "Server chose " + mesgVersion +
454 ", but that protocol version is not enabled or not supported " +
455 "by the client.");
456 }
457
458 handshakeHash.protocolDetermined(mesgVersion);
459
460 // Set protocolVersion and propagate to SSLSocket and the
461 // Handshake streams
462 setVersion(mesgVersion);
463
519 }
520
521 // we have already allowed unsafe renegotation before request
522 // the renegotiation.
523 }
524 }
525
526 //
527 // Save server nonce, we always use it to compute connection
528 // keys and it's also used to create the master secret if we're
529 // creating a new session (i.e. in the full handshake).
530 //
531 svr_random = mesg.svr_random;
532
533 if (isNegotiable(mesg.cipherSuite) == false) {
534 fatalSE(Alerts.alert_illegal_parameter,
535 "Server selected improper ciphersuite " + mesg.cipherSuite);
536 }
537
538 setCipherSuite(mesg.cipherSuite);
539 if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
540 handshakeHash.setFinishedAlg(cipherSuite.prfAlg.getPRFHashAlg());
541 }
542
543 if (mesg.compression_method != 0) {
544 fatalSE(Alerts.alert_illegal_parameter,
545 "compression type not supported, "
546 + mesg.compression_method);
547 // NOTREACHED
548 }
549
550 // so far so good, let's look at the session
551 if (session != null) {
552 // we tried to resume, let's see what the server decided
553 if (session.getSessionId().equals(mesg.sessionId)) {
554 // server resumed the session, let's make sure everything
555 // checks out
556
557 // Verify that the session ciphers are unchanged.
558 CipherSuite sessionSuite = session.getSuite();
559 if (cipherSuite != sessionSuite) {
594 Set<Principal> principals =
595 subject.getPrincipals(Principal.class);
596 if (!principals.contains(localPrincipal)) {
597 throw new SSLProtocolException("Server resumed" +
598 " session with wrong subject identity");
599 } else {
600 if (debug != null && Debug.isOn("session"))
601 System.out.println("Subject identity is same");
602 }
603 } else {
604 if (debug != null && Debug.isOn("session"))
605 System.out.println("Kerberos credentials are not" +
606 " present in the current Subject; check if " +
607 " javax.security.auth.useSubjectAsCreds" +
608 " system property has been set to false");
609 throw new SSLProtocolException
610 ("Server resumed session with no subject");
611 }
612 }
613
614 // looks fine; resume it, and update the state machine.
615 resumingSession = true;
616 state = HandshakeMessage.ht_finished - 1;
617 calculateConnectionKeys(session.getMasterSecret());
618 if (debug != null && Debug.isOn("session")) {
619 System.out.println("%% Server resumed " + session);
620 }
621 } else {
622 // we wanted to resume, but the server refused
623 session = null;
624 if (!enableNewSession) {
625 throw new SSLException("New session creation is disabled");
626 }
627 }
628 }
629
630 if (resumingSession && session != null) {
631 setHandshakeSessionSE(session);
632 // Reserve the handshake state if this is a session-resumption
633 // abbreviated initial handshake.
634 if (isInitialHandshake) {
635 session.setAsSessionResumption(true);
636 }
637
638 return;
639 }
640
641 // check extensions
642 for (HelloExtension ext : mesg.extensions.list()) {
643 ExtensionType type = ext.type;
644 if (type == ExtensionType.EXT_SERVER_NAME) {
645 serverNamesAccepted = true;
646 } else if ((type != ExtensionType.EXT_ELLIPTIC_CURVES)
647 && (type != ExtensionType.EXT_EC_POINT_FORMATS)
648 && (type != ExtensionType.EXT_SERVER_NAME)
649 && (type != ExtensionType.EXT_RENEGOTIATION_INFO)) {
650 fatalSE(Alerts.alert_unsupported_extension,
651 "Server sent an unsupported extension: " + type);
652 }
653 }
654
655 // Create a new session, we need to do the full handshake
656 session = new SSLSessionImpl(protocolVersion, cipherSuite,
657 getLocalSupportedSignAlgs(),
658 mesg.sessionId, getHostSE(), getPortSE());
659 session.setRequestedServerNames(requestedServerNames);
660 setHandshakeSessionSE(session);
661 if (debug != null && Debug.isOn("handshake")) {
662 System.out.println("** " + cipherSuite);
663 }
664 }
665
666 /*
667 * Server's own key was either a signing-only key, or was too
668 * large for export rules ... this message holds an ephemeral
669 * RSA key to use for key exchange.
670 */
671 private void serverKeyExchange(RSA_ServerKeyExchange mesg)
672 throws IOException, GeneralSecurityException {
673 if (debug != null && Debug.isOn("handshake")) {
674 mesg.print(System.out);
675 }
676 if (!mesg.verify(serverKey, clnt_random, svr_random)) {
677 fatalSE(Alerts.alert_handshake_failure,
678 "server key exchange invalid");
679 // NOTREACHED
680 }
681 ephemeralServerKey = mesg.getPublicKey();
682 }
683
684
685 /*
686 * Diffie-Hellman key exchange. We save the server public key and
687 * our own D-H algorithm object so we can defer key calculations
688 * until after we've sent the client key exchange message (which
689 * gives client and server some useful parallelism).
690 */
691 private void serverKeyExchange(DH_ServerKeyExchange mesg)
692 throws IOException {
693 if (debug != null && Debug.isOn("handshake")) {
694 mesg.print(System.out);
695 }
696 dh = new DHCrypt(mesg.getModulus(), mesg.getBase(),
697 sslContext.getSecureRandom());
698 serverDH = mesg.getServerPublicKey();
699 }
700
701 private void serverKeyExchange(ECDH_ServerKeyExchange mesg)
702 throws IOException {
703 if (debug != null && Debug.isOn("handshake")) {
704 mesg.print(System.out);
705 }
706 ECPublicKey key = mesg.getPublicKey();
707 ecdh = new ECDHCrypt(key.getParams(), sslContext.getSecureRandom());
708 ephemeralServerKey = key;
709 }
710
711 /*
712 * The server's "Hello Done" message is the client's sign that
713 * it's time to do all the hard work.
714 */
715 private void serverHelloDone(ServerHelloDone mesg) throws IOException {
716 if (debug != null && Debug.isOn("handshake")) {
717 mesg.print(System.out);
718 }
719 /*
720 * Always make sure the input has been digested before we
721 * start emitting data, to ensure the hashes are correctly
722 * computed for the Finished and CertificateVerify messages
723 * which we send (here).
724 */
725 input.digestNow();
726
727 /*
728 * FIRST ... if requested, send an appropriate Certificate chain
729 * to authenticate the client, and remember the associated private
730 * key to sign the CertificateVerify message.
731 */
732 PrivateKey signingKey = null;
733
734 if (certRequest != null) {
735 X509ExtendedKeyManager km = sslContext.getX509KeyManager();
736
737 ArrayList<String> keytypesTmp = new ArrayList<>(4);
738
739 for (int i = 0; i < certRequest.types.length; i++) {
740 String typeName;
741
742 switch (certRequest.types[i]) {
743 case CertificateRequest.cct_rsa_sign:
744 typeName = "RSA";
745 break;
800 params);
801 if (!SupportedEllipticCurvesExtension.isSupported(
802 index)) {
803 publicKey = null;
804 }
805 }
806 if (publicKey != null) {
807 m1 = new CertificateMsg(certs);
808 signingKey = km.getPrivateKey(alias);
809 session.setLocalPrivateKey(signingKey);
810 session.setLocalCertificates(certs);
811 }
812 }
813 }
814 if (m1 == null) {
815 //
816 // No appropriate cert was found ... report this to the
817 // server. For SSLv3, send the no_certificate alert;
818 // TLS uses an empty cert chain instead.
819 //
820 if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
821 m1 = new CertificateMsg(new X509Certificate [0]);
822 } else {
823 warningSE(Alerts.alert_no_certificate);
824 }
825 if (debug != null && Debug.isOn("handshake")) {
826 System.out.println(
827 "Warning: no suitable certificate found - " +
828 "continuing without client authentication");
829 }
830 }
831
832 //
833 // At last ... send any client certificate chain.
834 //
835 if (m1 != null) {
836 if (debug != null && Debug.isOn("handshake")) {
837 m1.print(System.out);
838 }
839 m1.write(output);
840 }
841 }
842
843 /*
844 * SECOND ... send the client key exchange message. The
845 * procedure used is a function of the cipher suite selected;
846 * one is always needed.
847 */
848 HandshakeMessage m2;
849
850 switch (keyExchange) {
851
852 case K_RSA:
853 case K_RSA_EXPORT:
854 if (serverKey == null) {
855 throw new SSLProtocolException
856 ("Server did not send certificate message");
857 }
858
859 if (!(serverKey instanceof RSAPublicKey)) {
983 }
984 kerberosMsg = new KerberosClientKeyExchange(
985 hostname, getAccSE(), protocolVersion,
986 sslContext.getSecureRandom());
987 }
988
989 // Record the principals involved in exchange
990 session.setPeerPrincipal(kerberosMsg.getPeerPrincipal());
991 session.setLocalPrincipal(kerberosMsg.getLocalPrincipal());
992 m2 = kerberosMsg;
993 break;
994 default:
995 // somethings very wrong
996 throw new RuntimeException
997 ("Unsupported key exchange: " + keyExchange);
998 }
999 if (debug != null && Debug.isOn("handshake")) {
1000 m2.print(System.out);
1001 }
1002 m2.write(output);
1003
1004
1005 /*
1006 * THIRD, send a "change_cipher_spec" record followed by the
1007 * "Finished" message. We flush the messages we've queued up, to
1008 * get concurrency between client and server. The concurrency is
1009 * useful as we calculate the master secret, which is needed both
1010 * to compute the "Finished" message, and to compute the keys used
1011 * to protect all records following the change_cipher_spec.
1012 */
1013
1014 output.doHashes();
1015 output.flush();
1016
1017 /*
1018 * We deferred calculating the master secret and this connection's
1019 * keying data; we do it now. Deferring this calculation is good
1020 * from a performance point of view, since it lets us do it during
1021 * some time that network delays and the server's own calculations
1022 * would otherwise cause to be "dead" in the critical path.
1023 */
1024 SecretKey preMasterSecret;
1025 switch (keyExchange) {
1026 case K_RSA:
1027 case K_RSA_EXPORT:
1028 preMasterSecret = ((RSAClientKeyExchange)m2).preMaster;
1029 break;
1030 case K_KRB5:
1031 case K_KRB5_EXPORT:
1032 byte[] secretBytes =
1033 ((KerberosClientKeyExchange)m2).getUnencryptedPreMasterSecret();
1034 preMasterSecret = new SecretKeySpec(secretBytes,
1052 throw new IOException("Internal error: unknown key exchange "
1053 + keyExchange);
1054 }
1055
1056 calculateKeys(preMasterSecret, null);
1057
1058 /*
1059 * FOURTH, if we sent a Certificate, we need to send a signed
1060 * CertificateVerify (unless the key in the client's certificate
1061 * was a Diffie-Hellman key).).
1062 *
1063 * This uses a hash of the previous handshake messages ... either
1064 * a nonfinal one (if the particular implementation supports it)
1065 * or else using the third element in the arrays of hashes being
1066 * computed.
1067 */
1068 if (signingKey != null) {
1069 CertificateVerify m3;
1070 try {
1071 SignatureAndHashAlgorithm preferableSignatureAlgorithm = null;
1072 if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
1073 preferableSignatureAlgorithm =
1074 SignatureAndHashAlgorithm.getPreferableAlgorithm(
1075 peerSupportedSignAlgs, signingKey.getAlgorithm(),
1076 signingKey);
1077
1078 if (preferableSignatureAlgorithm == null) {
1079 throw new SSLHandshakeException(
1080 "No supported signature algorithm");
1081 }
1082
1083 String hashAlg =
1084 SignatureAndHashAlgorithm.getHashAlgorithmName(
1085 preferableSignatureAlgorithm);
1086 if (hashAlg == null || hashAlg.length() == 0) {
1087 throw new SSLHandshakeException(
1088 "No supported hash algorithm");
1089 }
1090 }
1091
1092 m3 = new CertificateVerify(protocolVersion, handshakeHash,
1093 signingKey, session.getMasterSecret(),
1094 sslContext.getSecureRandom(),
1095 preferableSignatureAlgorithm);
1096 } catch (GeneralSecurityException e) {
1097 fatalSE(Alerts.alert_handshake_failure,
1098 "Error signing certificate verify", e);
1099 // NOTREACHED, make compiler happy
1100 m3 = null;
1101 }
1102 if (debug != null && Debug.isOn("handshake")) {
1103 m3.print(System.out);
1104 }
1105 m3.write(output);
1106 output.doHashes();
1107 }
1108
1109 /*
1110 * OK, that's that!
1111 */
1112 sendChangeCipherAndFinish(false);
1113 }
1114
1115
1116 /*
1117 * "Finished" is the last handshake message sent. If we got this
1118 * far, the MAC has been validated post-decryption. We validate
1119 * the two hashes here as an additional sanity check, protecting
1120 * the handshake against various active attacks.
1121 */
1122 private void serverFinished(Finished mesg) throws IOException {
1123 if (debug != null && Debug.isOn("handshake")) {
1124 mesg.print(System.out);
1125 }
1126
1127 boolean verified = mesg.verify(handshakeHash, Finished.SERVER,
1128 session.getMasterSecret());
1129
1130 if (!verified) {
1131 fatalSE(Alerts.alert_illegal_parameter,
1132 "server 'finished' message doesn't verify");
1141 }
1142
1143 /*
1144 * Reset the handshake state if this is not an initial handshake.
1145 */
1146 if (!isInitialHandshake) {
1147 session.setAsSessionResumption(false);
1148 }
1149
1150 /*
1151 * OK, it verified. If we're doing the fast handshake, add that
1152 * "Finished" message to the hash of handshake messages, then send
1153 * our own change_cipher_spec and Finished message for the server
1154 * to verify in turn. These are the last handshake messages.
1155 *
1156 * In any case, update the session cache. We're done handshaking,
1157 * so there are no threats any more associated with partially
1158 * completed handshakes.
1159 */
1160 if (resumingSession) {
1161 input.digestNow();
1162 sendChangeCipherAndFinish(true);
1163 }
1164 session.setLastAccessedTime(System.currentTimeMillis());
1165
1166 if (!resumingSession) {
1167 if (session.isRejoinable()) {
1168 ((SSLSessionContextImpl) sslContext
1169 .engineGetClientSessionContext())
1170 .put(session);
1171 if (debug != null && Debug.isOn("session")) {
1172 System.out.println("%% Cached client session: " + session);
1173 }
1174 } else if (debug != null && Debug.isOn("session")) {
1175 System.out.println(
1176 "%% Didn't cache non-resumable client session: "
1177 + session);
1178 }
1179 }
1180 }
1181
1182
1183 /*
1184 * Send my change-cipher-spec and Finished message ... done as the
1185 * last handshake act in either the short or long sequences. In
1186 * the short one, we've already seen the server's Finished; in the
1187 * long one, we wait for it now.
1188 */
1189 private void sendChangeCipherAndFinish(boolean finishedTag)
1190 throws IOException {
1191 Finished mesg = new Finished(protocolVersion, handshakeHash,
1192 Finished.CLIENT, session.getMasterSecret(), cipherSuite);
1193
1194 /*
1195 * Send the change_cipher_spec message, then the Finished message
1196 * which we just calculated (and protected using the keys we just
1197 * calculated). Server responds with its Finished message, except
1198 * in the "fast handshake" (resume session) case.
1199 */
1200 sendChangeCipherSpec(mesg, finishedTag);
1201
1202 /*
1203 * save client verify data for secure renegotiation
1204 */
1205 if (secureRenegotiation) {
1206 clientVerifyData = mesg.getVerifyData();
1207 }
1208
1209 /*
1210 * Update state machine so server MUST send 'finished' next.
1211 * (In "long" handshake case; in short case, we're responding
1212 * to its message.)
1213 */
1214 state = HandshakeMessage.ht_finished - 1;
1215 }
1216
1217
1218 /*
1219 * Returns a ClientHello message to kickstart renegotiations
1220 */
1221 @Override
1222 HandshakeMessage getKickstartMessage() throws SSLException {
1223 // session ID of the ClientHello message
1224 SessionId sessionId = SSLSessionImpl.nullSession.getSessionId();
1225
1226 // a list of cipher suites sent by the client
1227 CipherSuiteList cipherSuites = getActiveCipherSuites();
1228
1229 // set the max protocol version this client is supporting.
1230 maxProtocolVersion = protocolVersion;
1231
1232 //
1233 // Try to resume an existing session. This might be mandatory,
1234 // given certain API options.
1344 break;
1345 }
1346 }
1347
1348 if (!negotiable) {
1349 throw new SSLHandshakeException("No negotiable cipher suite");
1350 }
1351
1352 // Not a TLS1.2+ handshake
1353 // For SSLv2Hello, HandshakeHash.reset() will be called, so we
1354 // cannot call HandshakeHash.protocolDetermined() here. As it does
1355 // not follow the spec that HandshakeHash.reset() can be only be
1356 // called before protocolDetermined.
1357 // if (maxProtocolVersion.v < ProtocolVersion.TLS12.v) {
1358 // handshakeHash.protocolDetermined(maxProtocolVersion);
1359 // }
1360
1361 // create the ClientHello message
1362 ClientHello clientHelloMessage = new ClientHello(
1363 sslContext.getSecureRandom(), maxProtocolVersion,
1364 sessionId, cipherSuites);
1365
1366 // add signature_algorithm extension
1367 if (maxProtocolVersion.v >= ProtocolVersion.TLS12.v) {
1368 // we will always send the signature_algorithm extension
1369 Collection<SignatureAndHashAlgorithm> localSignAlgs =
1370 getLocalSupportedSignAlgs();
1371 if (localSignAlgs.isEmpty()) {
1372 throw new SSLHandshakeException(
1373 "No supported signature algorithm");
1374 }
1375
1376 clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs);
1377 }
1378
1379 // add server_name extension
1380 if (enableSNIExtension) {
1381 if (session != null) {
1382 requestedServerNames = session.getRequestedServerNames();
1383 } else {
1384 requestedServerNames = serverNames;
1385 }
1386
1387 if (!requestedServerNames.isEmpty()) {
1388 clientHelloMessage.addSNIExtension(requestedServerNames);
1389 }
1390 }
1391
1392 // reset the client random cookie
1393 clnt_random = clientHelloMessage.clnt_random;
1394
1395 /*
1396 * need to set the renegotiation_info extension for:
1397 * 1: secure renegotiation
1398 * 2: initial handshake and no SCSV in the ClientHello
1399 * 3: insecure renegotiation and no SCSV in the ClientHello
1400 */
1401 if (secureRenegotiation ||
1402 !cipherSuites.contains(CipherSuite.C_SCSV)) {
1403 clientHelloMessage.addRenegotiationInfoExtension(clientVerifyData);
1404 }
1405
1406 return clientHelloMessage;
1407 }
1408
1409 /*
1410 * Fault detected during handshake.
1411 */
1412 @Override
1413 void handshakeAlert(byte description) throws SSLProtocolException {
1414 String message = Alerts.alertDescription(description);
1415
1416 if (debug != null && Debug.isOn("handshake")) {
1417 System.out.println("SSL - handshake alert: " + message);
1418 }
1419 throw new SSLProtocolException("handshake alert: " + message);
1420 }
1421
1422 /*
1423 * Unless we are using an anonymous ciphersuite, the server always
1424 * sends a certificate message (for the CipherSuites we currently
1425 * support). The trust manager verifies the chain for us.
|
124 * same (See isIdentityEquivalent()).
125 *
126 * Considering the compatibility impact and the actual requirements to
127 * support server certificate change in practice, the system property,
128 * jdk.tls.allowUnsafeServerCertChange, is used to define whether unsafe
129 * server certificate change in renegotiation is allowed or not. The
130 * default value of the system property is "false". To mitigate the
131 * compactibility impact, applications may want to set the system
132 * property to "true" at their own risk.
133 *
134 * If the value of the system property is "false", server certificate
135 * change in renegotiation after a session-resumption abbreviated initial
136 * handshake is restricted (See isIdentityEquivalent()).
137 *
138 * If the system property is set to "true" explicitly, the restriction on
139 * server certificate change in renegotiation is disabled.
140 */
141 private final static boolean allowUnsafeServerCertChange =
142 Debug.getBooleanProperty("jdk.tls.allowUnsafeServerCertChange", false);
143
144 // To switch off the max_fragment_length extension.
145 private final static boolean enableMFLExtension =
146 Debug.getBooleanProperty("jsse.enableMFLExtension", false);
147
148 private List<SNIServerName> requestedServerNames =
149 Collections.<SNIServerName>emptyList();
150
151 // maximum fragment length
152 private int requestedMFLength = -1; // -1: no fragment length limit
153
154 private boolean serverNamesAccepted = false;
155
156 private ClientHello initialClientHelloMsg = null; // DTLS only
157
158 /*
159 * the reserved server certificate chain in previous handshaking
160 *
161 * The server certificate chain is only reserved if the previous
162 * handshake is a session-resumption abbreviated initial handshake.
163 */
164 private X509Certificate[] reservedServerCerts = null;
165
166 /*
167 * Constructors
168 */
169 ClientHandshaker(SSLSocketImpl socket, SSLContextImpl context,
170 ProtocolList enabledProtocols,
171 ProtocolVersion activeProtocolVersion,
172 boolean isInitialHandshake, boolean secureRenegotiation,
173 byte[] clientVerifyData, byte[] serverVerifyData) {
174
175 super(socket, context, enabledProtocols, true, true,
176 activeProtocolVersion, isInitialHandshake, secureRenegotiation,
177 clientVerifyData, serverVerifyData);
178 }
179
180 ClientHandshaker(SSLEngineImpl engine, SSLContextImpl context,
181 ProtocolList enabledProtocols,
182 ProtocolVersion activeProtocolVersion,
183 boolean isInitialHandshake, boolean secureRenegotiation,
184 byte[] clientVerifyData, byte[] serverVerifyData,
185 boolean isDTLS) {
186
187 super(engine, context, enabledProtocols, true, true,
188 activeProtocolVersion, isInitialHandshake, secureRenegotiation,
189 clientVerifyData, serverVerifyData, isDTLS);
190 }
191
192 /*
193 * This routine handles all the client side handshake messages, one at
194 * a time. Given the message type (and in some cases the pending cipher
195 * spec) it parses the type-specific message. Then it calls a function
196 * that handles that specific message.
197 *
198 * It updates the state machine (need to verify it) as each message
199 * is processed, and writes responses as needed using the connection
200 * in the constructor.
201 */
202 @Override
203 void processMessage(byte type, int messageLen) throws IOException {
204 // check the handshake state
205 handshakeState.check(type);
206
207 switch (type) {
208 case HandshakeMessage.ht_hello_request:
209 HelloRequest helloRequest = new HelloRequest(input);
210 handshakeState.update(helloRequest, resumingSession);
211 this.serverHelloRequest(helloRequest);
212 break;
213
214 case HandshakeMessage.ht_hello_verify_request:
215 if (!isDTLS) {
216 throw new SSLProtocolException(
217 "hello_verify_request is not a SSL/TLS handshake message");
218 }
219
220 HelloVerifyRequest helloVerifyRequest =
221 new HelloVerifyRequest(input, messageLen);
222 handshakeState.update(helloVerifyRequest, resumingSession);
223 this.helloVerifyRequest(helloVerifyRequest);
224 break;
225
226 case HandshakeMessage.ht_server_hello:
227 ServerHello serverHello = new ServerHello(input, messageLen);
228 this.serverHello(serverHello);
229
230 // This handshake state update needs the resumingSession value
231 // set by serverHello().
232 handshakeState.update(serverHello, resumingSession);
233 break;
234
235 case HandshakeMessage.ht_certificate:
236 if (keyExchange == K_DH_ANON || keyExchange == K_ECDH_ANON
237 || keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
238 fatalSE(Alerts.alert_unexpected_message,
239 "unexpected server cert chain");
240 // NOTREACHED
241 }
242 CertificateMsg certificateMsg = new CertificateMsg(input);
243 handshakeState.update(certificateMsg, resumingSession);
244 this.serverCertificate(certificateMsg);
245 serverKey =
246 session.getPeerCertificates()[0].getPublicKey();
247 break;
248
249 case HandshakeMessage.ht_server_key_exchange:
250 serverKeyExchangeReceived = true;
251 switch (keyExchange) {
252 case K_RSA_EXPORT:
253 /**
254 * The server key exchange message is sent by the server only
255 * when the server certificate message does not contain the
256 * proper amount of data to allow the client to exchange a
257 * premaster secret, such as when RSA_EXPORT is used and the
258 * public key in the server certificate is longer than 512 bits.
259 */
260 if (serverKey == null) {
261 throw new SSLProtocolException
262 ("Server did not send certificate message");
263 }
264
265 if (!(serverKey instanceof RSAPublicKey)) {
266 throw new SSLProtocolException("Protocol violation:" +
267 " the certificate type must be appropriate for the" +
268 " selected cipher suite's key exchange algorithm");
269 }
270
271 if (JsseJce.getRSAKeyLength(serverKey) <= 512) {
272 throw new SSLProtocolException("Protocol violation:" +
273 " server sent a server key exchange message for" +
274 " key exchange " + keyExchange +
275 " when the public key in the server certificate" +
276 " is less than or equal to 512 bits in length");
277 }
278
279 try {
280 RSA_ServerKeyExchange rsaSrvKeyExchange =
281 new RSA_ServerKeyExchange(input);
282 handshakeState.update(rsaSrvKeyExchange, resumingSession);
283 this.serverKeyExchange(rsaSrvKeyExchange);
284 } catch (GeneralSecurityException e) {
285 throw new SSLException("Server key", e);
286 }
287 break;
288 case K_DH_ANON:
289 try {
290 DH_ServerKeyExchange dhSrvKeyExchange =
291 new DH_ServerKeyExchange(input, protocolVersion);
292 handshakeState.update(dhSrvKeyExchange, resumingSession);
293 this.serverKeyExchange(dhSrvKeyExchange);
294 } catch (GeneralSecurityException e) {
295 throw new SSLException("Server key", e);
296 }
297 break;
298 case K_DHE_DSS:
299 case K_DHE_RSA:
300 try {
301 DH_ServerKeyExchange dhSrvKeyExchange =
302 new DH_ServerKeyExchange(
303 input, serverKey,
304 clnt_random.random_bytes, svr_random.random_bytes,
305 messageLen,
306 localSupportedSignAlgs, protocolVersion);
307 handshakeState.update(dhSrvKeyExchange, resumingSession);
308 this.serverKeyExchange(dhSrvKeyExchange);
309 } catch (GeneralSecurityException e) {
310 throw new SSLException("Server key", e);
311 }
312 break;
313 case K_ECDHE_ECDSA:
314 case K_ECDHE_RSA:
315 case K_ECDH_ANON:
316 try {
317 ECDH_ServerKeyExchange ecdhSrvKeyExchange =
318 new ECDH_ServerKeyExchange
319 (input, serverKey, clnt_random.random_bytes,
320 svr_random.random_bytes,
321 localSupportedSignAlgs, protocolVersion);
322 handshakeState.update(ecdhSrvKeyExchange, resumingSession);
323 this.serverKeyExchange(ecdhSrvKeyExchange);
324 } catch (GeneralSecurityException e) {
325 throw new SSLException("Server key", e);
326 }
327 break;
328 case K_RSA:
329 case K_DH_RSA:
330 case K_DH_DSS:
331 case K_ECDH_ECDSA:
332 case K_ECDH_RSA:
333 throw new SSLProtocolException(
334 "Protocol violation: server sent a server key exchange"
335 + " message for key exchange " + keyExchange);
336 case K_KRB5:
337 case K_KRB5_EXPORT:
338 throw new SSLProtocolException(
339 "unexpected receipt of server key exchange algorithm");
340 default:
341 throw new SSLProtocolException(
342 "unsupported key exchange algorithm = "
343 + keyExchange);
344 }
345 break;
346
347 case HandshakeMessage.ht_certificate_request:
348 // save for later, it's handled by serverHelloDone
349 if ((keyExchange == K_DH_ANON) || (keyExchange == K_ECDH_ANON)) {
350 throw new SSLHandshakeException(
351 "Client authentication requested for "+
352 "anonymous cipher suite.");
353 } else if (keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
354 throw new SSLHandshakeException(
355 "Client certificate requested for "+
356 "kerberos cipher suite.");
357 }
358 certRequest = new CertificateRequest(input, protocolVersion);
359 if (debug != null && Debug.isOn("handshake")) {
360 certRequest.print(System.out);
361 }
362 handshakeState.update(certRequest, resumingSession);
363
364 if (protocolVersion.useTLS12PlusSpec()) {
365 Collection<SignatureAndHashAlgorithm> peerSignAlgs =
366 certRequest.getSignAlgorithms();
367 if (peerSignAlgs == null || peerSignAlgs.isEmpty()) {
368 throw new SSLHandshakeException(
369 "No peer supported signature algorithms");
370 }
371
372 Collection<SignatureAndHashAlgorithm> supportedPeerSignAlgs =
373 SignatureAndHashAlgorithm.getSupportedAlgorithms(
374 peerSignAlgs);
375 if (supportedPeerSignAlgs.isEmpty()) {
376 throw new SSLHandshakeException(
377 "No supported signature and hash algorithm in common");
378 }
379
380 setPeerSupportedSignAlgs(supportedPeerSignAlgs);
381 session.setPeerSupportedSignatureAlgorithms(
382 supportedPeerSignAlgs);
383 }
384
385 break;
386
387 case HandshakeMessage.ht_server_hello_done:
388 ServerHelloDone serverHelloDone = new ServerHelloDone(input);
389 handshakeState.update(serverHelloDone, resumingSession);
390 this.serverHelloDone(serverHelloDone);
391
392 break;
393
394 case HandshakeMessage.ht_finished:
395 Finished serverFinished =
396 new Finished(protocolVersion, input, cipherSuite);
397 handshakeState.update(serverFinished, resumingSession);
398 this.serverFinished(serverFinished);
399
400 break;
401
402 default:
403 throw new SSLProtocolException(
404 "Illegal client handshake msg, " + type);
405 }
406 }
407
408 /*
409 * Used by the server to kickstart negotiations -- this requests a
410 * "client hello" to renegotiate current cipher specs (e.g. maybe lots
411 * of data has been encrypted with the same keys, or the server needs
412 * the client to present a certificate).
413 */
414 private void serverHelloRequest(HelloRequest mesg) throws IOException {
415 if (debug != null && Debug.isOn("handshake")) {
416 mesg.print(System.out);
417 }
418
419 //
420 // Could be (e.g. at connection setup) that we already
421 // sent the "client hello" but the server's not seen it.
422 //
423 if (!clientHelloDelivered) {
424 if (!secureRenegotiation && !allowUnsafeRenegotiation) {
425 // renegotiation is not allowed.
426 if (activeProtocolVersion.useTLS10PlusSpec()) {
427 // response with a no_renegotiation warning,
428 warningSE(Alerts.alert_no_renegotiation);
429
430 // invalidate the handshake so that the caller can
431 // dispose this object.
432 invalidated = true;
433
434 // If there is still unread block in the handshake
435 // input stream, it would be truncated with the disposal
436 // and the next handshake message will become incomplete.
437 //
438 // However, according to SSL/TLS specifications, no more
439 // handshake message should immediately follow ClientHello
440 // or HelloRequest. So just let it be.
441 } else {
442 // For SSLv3, send the handshake_failure fatal error.
443 // Note that SSLv3 does not define a no_renegotiation
444 // alert like TLSv1. However we cannot ignore the message
445 // simply, otherwise the other side was waiting for a
446 // response that would never come.
447 fatalSE(Alerts.alert_handshake_failure,
448 "Renegotiation is not allowed");
449 }
450 } else {
451 if (!secureRenegotiation) {
452 if (debug != null && Debug.isOn("handshake")) {
453 System.out.println(
454 "Warning: continue with insecure renegotiation");
455 }
456 }
457 kickstart();
458 }
459 }
460 }
461
462 private void helloVerifyRequest(
463 HelloVerifyRequest mesg) throws IOException {
464
465 if (debug != null && Debug.isOn("handshake")) {
466 mesg.print(System.out);
467 }
468
469 //
470 // Note that HelloVerifyRequest.server_version is used solely to
471 // indicate packet formatting, and not as part of version negotiation.
472 // Need not to check version values match for HelloVerifyRequest
473 // message.
474 //
475 initialClientHelloMsg.cookie = mesg.cookie.clone();
476
477 if (debug != null && Debug.isOn("handshake")) {
478 initialClientHelloMsg.print(System.out);
479 }
480
481 // deliver the ClientHello message with cookie
482 initialClientHelloMsg.write(output);
483 handshakeState.update(initialClientHelloMsg, resumingSession);
484 }
485
486 /*
487 * Server chooses session parameters given options created by the
488 * client -- basically, cipher options, session id, and someday a
489 * set of compression options.
490 *
491 * There are two branches of the state machine, decided by the
492 * details of this message. One is the "fast" handshake, where we
493 * can resume the pre-existing session we asked resume. The other
494 * is a more expensive "full" handshake, with key exchange and
495 * probably authentication getting done.
496 */
497 private void serverHello(ServerHello mesg) throws IOException {
498 // Dispose the reserved ClientHello message (if exists).
499 initialClientHelloMsg = null;
500
501 serverKeyExchangeReceived = false;
502 if (debug != null && Debug.isOn("handshake")) {
503 mesg.print(System.out);
504 }
505
506 // check if the server selected protocol version is OK for us
507 ProtocolVersion mesgVersion = mesg.protocolVersion;
508 if (!isNegotiable(mesgVersion)) {
509 throw new SSLHandshakeException(
510 "Server chose " + mesgVersion +
511 ", but that protocol version is not enabled or not supported " +
512 "by the client.");
513 }
514
515 handshakeHash.protocolDetermined(mesgVersion);
516
517 // Set protocolVersion and propagate to SSLSocket and the
518 // Handshake streams
519 setVersion(mesgVersion);
520
576 }
577
578 // we have already allowed unsafe renegotation before request
579 // the renegotiation.
580 }
581 }
582
583 //
584 // Save server nonce, we always use it to compute connection
585 // keys and it's also used to create the master secret if we're
586 // creating a new session (i.e. in the full handshake).
587 //
588 svr_random = mesg.svr_random;
589
590 if (isNegotiable(mesg.cipherSuite) == false) {
591 fatalSE(Alerts.alert_illegal_parameter,
592 "Server selected improper ciphersuite " + mesg.cipherSuite);
593 }
594
595 setCipherSuite(mesg.cipherSuite);
596 if (protocolVersion.useTLS12PlusSpec()) {
597 handshakeHash.setFinishedAlg(cipherSuite.prfAlg.getPRFHashAlg());
598 }
599
600 if (mesg.compression_method != 0) {
601 fatalSE(Alerts.alert_illegal_parameter,
602 "compression type not supported, "
603 + mesg.compression_method);
604 // NOTREACHED
605 }
606
607 // so far so good, let's look at the session
608 if (session != null) {
609 // we tried to resume, let's see what the server decided
610 if (session.getSessionId().equals(mesg.sessionId)) {
611 // server resumed the session, let's make sure everything
612 // checks out
613
614 // Verify that the session ciphers are unchanged.
615 CipherSuite sessionSuite = session.getSuite();
616 if (cipherSuite != sessionSuite) {
651 Set<Principal> principals =
652 subject.getPrincipals(Principal.class);
653 if (!principals.contains(localPrincipal)) {
654 throw new SSLProtocolException("Server resumed" +
655 " session with wrong subject identity");
656 } else {
657 if (debug != null && Debug.isOn("session"))
658 System.out.println("Subject identity is same");
659 }
660 } else {
661 if (debug != null && Debug.isOn("session"))
662 System.out.println("Kerberos credentials are not" +
663 " present in the current Subject; check if " +
664 " javax.security.auth.useSubjectAsCreds" +
665 " system property has been set to false");
666 throw new SSLProtocolException
667 ("Server resumed session with no subject");
668 }
669 }
670
671 // looks fine; resume it.
672 resumingSession = true;
673 calculateConnectionKeys(session.getMasterSecret());
674 if (debug != null && Debug.isOn("session")) {
675 System.out.println("%% Server resumed " + session);
676 }
677 } else {
678 // we wanted to resume, but the server refused
679 session = null;
680 if (!enableNewSession) {
681 throw new SSLException("New session creation is disabled");
682 }
683 }
684 }
685
686 // check the "max_fragment_length" extension
687 MaxFragmentLengthExtension maxFragLenExt = (MaxFragmentLengthExtension)
688 mesg.extensions.get(ExtensionType.EXT_MAX_FRAGMENT_LENGTH);
689 if (maxFragLenExt != null) {
690 if ((requestedMFLength == -1) ||
691 maxFragLenExt.getMaxFragLen() != requestedMFLength) {
692 // If the client did not request this extension, or the
693 // response value is different from the length it requested,
694 // abort the handshake with a fatal illegal_parameter alert.
695 fatalSE(Alerts.alert_illegal_parameter,
696 "Failed to negotiate the max_fragment_length");
697 }
698 } else if (!resumingSession) {
699 // no "max_fragment_length" extension
700 requestedMFLength = -1;
701 } // Otherwise, using the value negotiated during the original
702 // session initiation
703
704 if (resumingSession && session != null) {
705 setHandshakeSessionSE(session);
706 // Reserve the handshake state if this is a session-resumption
707 // abbreviated initial handshake.
708 if (isInitialHandshake) {
709 session.setAsSessionResumption(true);
710 }
711
712 return;
713 }
714
715 // check extensions
716 for (HelloExtension ext : mesg.extensions.list()) {
717 ExtensionType type = ext.type;
718 if (type == ExtensionType.EXT_SERVER_NAME) {
719 serverNamesAccepted = true;
720 } else if ((type != ExtensionType.EXT_ELLIPTIC_CURVES)
721 && (type != ExtensionType.EXT_EC_POINT_FORMATS)
722 && (type != ExtensionType.EXT_SERVER_NAME)
723 && (type != ExtensionType.EXT_RENEGOTIATION_INFO)) {
724 fatalSE(Alerts.alert_unsupported_extension,
725 "Server sent an unsupported extension: " + type);
726 }
727 }
728
729 // Create a new session, we need to do the full handshake
730 session = new SSLSessionImpl(protocolVersion, cipherSuite,
731 getLocalSupportedSignAlgs(),
732 mesg.sessionId, getHostSE(), getPortSE());
733 session.setRequestedServerNames(requestedServerNames);
734 session.setNegotiatedMaxFragSize(requestedMFLength);
735 session.setMaximumPacketSize(maximumPacketSize);
736 setHandshakeSessionSE(session);
737 if (debug != null && Debug.isOn("handshake")) {
738 System.out.println("** " + cipherSuite);
739 }
740 }
741
742 /*
743 * Server's own key was either a signing-only key, or was too
744 * large for export rules ... this message holds an ephemeral
745 * RSA key to use for key exchange.
746 */
747 private void serverKeyExchange(RSA_ServerKeyExchange mesg)
748 throws IOException, GeneralSecurityException {
749 if (debug != null && Debug.isOn("handshake")) {
750 mesg.print(System.out);
751 }
752 if (!mesg.verify(serverKey, clnt_random, svr_random)) {
753 fatalSE(Alerts.alert_handshake_failure,
754 "server key exchange invalid");
755 // NOTREACHED
756 }
757 ephemeralServerKey = mesg.getPublicKey();
758 }
759
760 /*
761 * Diffie-Hellman key exchange. We save the server public key and
762 * our own D-H algorithm object so we can defer key calculations
763 * until after we've sent the client key exchange message (which
764 * gives client and server some useful parallelism).
765 */
766 private void serverKeyExchange(DH_ServerKeyExchange mesg)
767 throws IOException {
768 if (debug != null && Debug.isOn("handshake")) {
769 mesg.print(System.out);
770 }
771 dh = new DHCrypt(mesg.getModulus(), mesg.getBase(),
772 sslContext.getSecureRandom());
773 serverDH = mesg.getServerPublicKey();
774 }
775
776 private void serverKeyExchange(ECDH_ServerKeyExchange mesg)
777 throws IOException {
778 if (debug != null && Debug.isOn("handshake")) {
779 mesg.print(System.out);
780 }
781 ECPublicKey key = mesg.getPublicKey();
782 ecdh = new ECDHCrypt(key.getParams(), sslContext.getSecureRandom());
783 ephemeralServerKey = key;
784 }
785
786 /*
787 * The server's "Hello Done" message is the client's sign that
788 * it's time to do all the hard work.
789 */
790 private void serverHelloDone(ServerHelloDone mesg) throws IOException {
791 if (debug != null && Debug.isOn("handshake")) {
792 mesg.print(System.out);
793 }
794
795 /*
796 * FIRST ... if requested, send an appropriate Certificate chain
797 * to authenticate the client, and remember the associated private
798 * key to sign the CertificateVerify message.
799 */
800 PrivateKey signingKey = null;
801
802 if (certRequest != null) {
803 X509ExtendedKeyManager km = sslContext.getX509KeyManager();
804
805 ArrayList<String> keytypesTmp = new ArrayList<>(4);
806
807 for (int i = 0; i < certRequest.types.length; i++) {
808 String typeName;
809
810 switch (certRequest.types[i]) {
811 case CertificateRequest.cct_rsa_sign:
812 typeName = "RSA";
813 break;
868 params);
869 if (!SupportedEllipticCurvesExtension.isSupported(
870 index)) {
871 publicKey = null;
872 }
873 }
874 if (publicKey != null) {
875 m1 = new CertificateMsg(certs);
876 signingKey = km.getPrivateKey(alias);
877 session.setLocalPrivateKey(signingKey);
878 session.setLocalCertificates(certs);
879 }
880 }
881 }
882 if (m1 == null) {
883 //
884 // No appropriate cert was found ... report this to the
885 // server. For SSLv3, send the no_certificate alert;
886 // TLS uses an empty cert chain instead.
887 //
888 if (protocolVersion.useTLS10PlusSpec()) {
889 m1 = new CertificateMsg(new X509Certificate [0]);
890 } else {
891 warningSE(Alerts.alert_no_certificate);
892 }
893 if (debug != null && Debug.isOn("handshake")) {
894 System.out.println(
895 "Warning: no suitable certificate found - " +
896 "continuing without client authentication");
897 }
898 }
899
900 //
901 // At last ... send any client certificate chain.
902 //
903 if (m1 != null) {
904 if (debug != null && Debug.isOn("handshake")) {
905 m1.print(System.out);
906 }
907 m1.write(output);
908 handshakeState.update(m1, resumingSession);
909 }
910 }
911
912 /*
913 * SECOND ... send the client key exchange message. The
914 * procedure used is a function of the cipher suite selected;
915 * one is always needed.
916 */
917 HandshakeMessage m2;
918
919 switch (keyExchange) {
920
921 case K_RSA:
922 case K_RSA_EXPORT:
923 if (serverKey == null) {
924 throw new SSLProtocolException
925 ("Server did not send certificate message");
926 }
927
928 if (!(serverKey instanceof RSAPublicKey)) {
1052 }
1053 kerberosMsg = new KerberosClientKeyExchange(
1054 hostname, getAccSE(), protocolVersion,
1055 sslContext.getSecureRandom());
1056 }
1057
1058 // Record the principals involved in exchange
1059 session.setPeerPrincipal(kerberosMsg.getPeerPrincipal());
1060 session.setLocalPrincipal(kerberosMsg.getLocalPrincipal());
1061 m2 = kerberosMsg;
1062 break;
1063 default:
1064 // somethings very wrong
1065 throw new RuntimeException
1066 ("Unsupported key exchange: " + keyExchange);
1067 }
1068 if (debug != null && Debug.isOn("handshake")) {
1069 m2.print(System.out);
1070 }
1071 m2.write(output);
1072 handshakeState.update(m2, resumingSession);
1073
1074 /*
1075 * THIRD, send a "change_cipher_spec" record followed by the
1076 * "Finished" message. We flush the messages we've queued up, to
1077 * get concurrency between client and server. The concurrency is
1078 * useful as we calculate the master secret, which is needed both
1079 * to compute the "Finished" message, and to compute the keys used
1080 * to protect all records following the change_cipher_spec.
1081 */
1082 output.flush();
1083
1084 /*
1085 * We deferred calculating the master secret and this connection's
1086 * keying data; we do it now. Deferring this calculation is good
1087 * from a performance point of view, since it lets us do it during
1088 * some time that network delays and the server's own calculations
1089 * would otherwise cause to be "dead" in the critical path.
1090 */
1091 SecretKey preMasterSecret;
1092 switch (keyExchange) {
1093 case K_RSA:
1094 case K_RSA_EXPORT:
1095 preMasterSecret = ((RSAClientKeyExchange)m2).preMaster;
1096 break;
1097 case K_KRB5:
1098 case K_KRB5_EXPORT:
1099 byte[] secretBytes =
1100 ((KerberosClientKeyExchange)m2).getUnencryptedPreMasterSecret();
1101 preMasterSecret = new SecretKeySpec(secretBytes,
1119 throw new IOException("Internal error: unknown key exchange "
1120 + keyExchange);
1121 }
1122
1123 calculateKeys(preMasterSecret, null);
1124
1125 /*
1126 * FOURTH, if we sent a Certificate, we need to send a signed
1127 * CertificateVerify (unless the key in the client's certificate
1128 * was a Diffie-Hellman key).).
1129 *
1130 * This uses a hash of the previous handshake messages ... either
1131 * a nonfinal one (if the particular implementation supports it)
1132 * or else using the third element in the arrays of hashes being
1133 * computed.
1134 */
1135 if (signingKey != null) {
1136 CertificateVerify m3;
1137 try {
1138 SignatureAndHashAlgorithm preferableSignatureAlgorithm = null;
1139 if (protocolVersion.useTLS12PlusSpec()) {
1140 preferableSignatureAlgorithm =
1141 SignatureAndHashAlgorithm.getPreferableAlgorithm(
1142 peerSupportedSignAlgs, signingKey.getAlgorithm(),
1143 signingKey);
1144
1145 if (preferableSignatureAlgorithm == null) {
1146 throw new SSLHandshakeException(
1147 "No supported signature algorithm");
1148 }
1149
1150 String hashAlg =
1151 SignatureAndHashAlgorithm.getHashAlgorithmName(
1152 preferableSignatureAlgorithm);
1153 if (hashAlg == null || hashAlg.length() == 0) {
1154 throw new SSLHandshakeException(
1155 "No supported hash algorithm");
1156 }
1157 }
1158
1159 m3 = new CertificateVerify(protocolVersion, handshakeHash,
1160 signingKey, session.getMasterSecret(),
1161 sslContext.getSecureRandom(),
1162 preferableSignatureAlgorithm);
1163 } catch (GeneralSecurityException e) {
1164 fatalSE(Alerts.alert_handshake_failure,
1165 "Error signing certificate verify", e);
1166 // NOTREACHED, make compiler happy
1167 m3 = null;
1168 }
1169 if (debug != null && Debug.isOn("handshake")) {
1170 m3.print(System.out);
1171 }
1172 m3.write(output);
1173 handshakeState.update(m3, resumingSession);
1174 output.flush();
1175 }
1176
1177 /*
1178 * OK, that's that!
1179 */
1180 sendChangeCipherAndFinish(false);
1181
1182 // expecting the final ChangeCipherSpec and Finished messages
1183 expectingFinishFlightSE();
1184 }
1185
1186
1187 /*
1188 * "Finished" is the last handshake message sent. If we got this
1189 * far, the MAC has been validated post-decryption. We validate
1190 * the two hashes here as an additional sanity check, protecting
1191 * the handshake against various active attacks.
1192 */
1193 private void serverFinished(Finished mesg) throws IOException {
1194 if (debug != null && Debug.isOn("handshake")) {
1195 mesg.print(System.out);
1196 }
1197
1198 boolean verified = mesg.verify(handshakeHash, Finished.SERVER,
1199 session.getMasterSecret());
1200
1201 if (!verified) {
1202 fatalSE(Alerts.alert_illegal_parameter,
1203 "server 'finished' message doesn't verify");
1212 }
1213
1214 /*
1215 * Reset the handshake state if this is not an initial handshake.
1216 */
1217 if (!isInitialHandshake) {
1218 session.setAsSessionResumption(false);
1219 }
1220
1221 /*
1222 * OK, it verified. If we're doing the fast handshake, add that
1223 * "Finished" message to the hash of handshake messages, then send
1224 * our own change_cipher_spec and Finished message for the server
1225 * to verify in turn. These are the last handshake messages.
1226 *
1227 * In any case, update the session cache. We're done handshaking,
1228 * so there are no threats any more associated with partially
1229 * completed handshakes.
1230 */
1231 if (resumingSession) {
1232 sendChangeCipherAndFinish(true);
1233 } else {
1234 handshakeFinished = true;
1235 }
1236 session.setLastAccessedTime(System.currentTimeMillis());
1237
1238 if (!resumingSession) {
1239 if (session.isRejoinable()) {
1240 ((SSLSessionContextImpl) sslContext
1241 .engineGetClientSessionContext())
1242 .put(session);
1243 if (debug != null && Debug.isOn("session")) {
1244 System.out.println("%% Cached client session: " + session);
1245 }
1246 } else if (debug != null && Debug.isOn("session")) {
1247 System.out.println(
1248 "%% Didn't cache non-resumable client session: "
1249 + session);
1250 }
1251 }
1252 }
1253
1254
1255 /*
1256 * Send my change-cipher-spec and Finished message ... done as the
1257 * last handshake act in either the short or long sequences. In
1258 * the short one, we've already seen the server's Finished; in the
1259 * long one, we wait for it now.
1260 */
1261 private void sendChangeCipherAndFinish(boolean finishedTag)
1262 throws IOException {
1263
1264 // Reload if this message has been reserved.
1265 handshakeHash.reload();
1266
1267 Finished mesg = new Finished(protocolVersion, handshakeHash,
1268 Finished.CLIENT, session.getMasterSecret(), cipherSuite);
1269
1270 /*
1271 * Send the change_cipher_spec message, then the Finished message
1272 * which we just calculated (and protected using the keys we just
1273 * calculated). Server responds with its Finished message, except
1274 * in the "fast handshake" (resume session) case.
1275 */
1276 sendChangeCipherSpec(mesg, finishedTag);
1277
1278 /*
1279 * save client verify data for secure renegotiation
1280 */
1281 if (secureRenegotiation) {
1282 clientVerifyData = mesg.getVerifyData();
1283 }
1284 }
1285
1286
1287 /*
1288 * Returns a ClientHello message to kickstart renegotiations
1289 */
1290 @Override
1291 HandshakeMessage getKickstartMessage() throws SSLException {
1292 // session ID of the ClientHello message
1293 SessionId sessionId = SSLSessionImpl.nullSession.getSessionId();
1294
1295 // a list of cipher suites sent by the client
1296 CipherSuiteList cipherSuites = getActiveCipherSuites();
1297
1298 // set the max protocol version this client is supporting.
1299 maxProtocolVersion = protocolVersion;
1300
1301 //
1302 // Try to resume an existing session. This might be mandatory,
1303 // given certain API options.
1413 break;
1414 }
1415 }
1416
1417 if (!negotiable) {
1418 throw new SSLHandshakeException("No negotiable cipher suite");
1419 }
1420
1421 // Not a TLS1.2+ handshake
1422 // For SSLv2Hello, HandshakeHash.reset() will be called, so we
1423 // cannot call HandshakeHash.protocolDetermined() here. As it does
1424 // not follow the spec that HandshakeHash.reset() can be only be
1425 // called before protocolDetermined.
1426 // if (maxProtocolVersion.v < ProtocolVersion.TLS12.v) {
1427 // handshakeHash.protocolDetermined(maxProtocolVersion);
1428 // }
1429
1430 // create the ClientHello message
1431 ClientHello clientHelloMessage = new ClientHello(
1432 sslContext.getSecureRandom(), maxProtocolVersion,
1433 sessionId, cipherSuites, isDTLS);
1434
1435 // add signature_algorithm extension
1436 if (maxProtocolVersion.useTLS12PlusSpec()) {
1437 // we will always send the signature_algorithm extension
1438 Collection<SignatureAndHashAlgorithm> localSignAlgs =
1439 getLocalSupportedSignAlgs();
1440 if (localSignAlgs.isEmpty()) {
1441 throw new SSLHandshakeException(
1442 "No supported signature algorithm");
1443 }
1444
1445 clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs);
1446 }
1447
1448 // add server_name extension
1449 if (enableSNIExtension) {
1450 if (session != null) {
1451 requestedServerNames = session.getRequestedServerNames();
1452 } else {
1453 requestedServerNames = serverNames;
1454 }
1455
1456 if (!requestedServerNames.isEmpty()) {
1457 clientHelloMessage.addSNIExtension(requestedServerNames);
1458 }
1459 }
1460
1461 // add max_fragment_length extension
1462 if (enableMFLExtension) {
1463 if (session != null) {
1464 // The same extension should be sent for resumption.
1465 requestedMFLength = session.getNegotiatedMaxFragSize();
1466 } else if (maximumPacketSize != 0) {
1467 // Maybe we can calculate the fragment size more accurate
1468 // by condering the enabled cipher suites in the future.
1469 requestedMFLength = maximumPacketSize;
1470 if (isDTLS) {
1471 requestedMFLength -= DTLSRecord.maxPlaintextPlusSize;
1472 } else {
1473 requestedMFLength -= SSLRecord.maxPlaintextPlusSize;
1474 }
1475 } else {
1476 // Need no max_fragment_length extension.
1477 requestedMFLength = -1;
1478 }
1479
1480 if ((requestedMFLength > 0) &&
1481 MaxFragmentLengthExtension.needFragLenNego(requestedMFLength)) {
1482
1483 requestedMFLength =
1484 MaxFragmentLengthExtension.getValidMaxFragLen(
1485 requestedMFLength);
1486 clientHelloMessage.addMFLExtension(requestedMFLength);
1487 } else {
1488 requestedMFLength = -1;
1489 }
1490 }
1491
1492 // reset the client random cookie
1493 clnt_random = clientHelloMessage.clnt_random;
1494
1495 /*
1496 * need to set the renegotiation_info extension for:
1497 * 1: secure renegotiation
1498 * 2: initial handshake and no SCSV in the ClientHello
1499 * 3: insecure renegotiation and no SCSV in the ClientHello
1500 */
1501 if (secureRenegotiation ||
1502 !cipherSuites.contains(CipherSuite.C_SCSV)) {
1503 clientHelloMessage.addRenegotiationInfoExtension(clientVerifyData);
1504 }
1505
1506 if (isDTLS) {
1507 // Cookie exchange need to reserve the initial ClientHello message.
1508 initialClientHelloMsg = clientHelloMessage;
1509 }
1510
1511 return clientHelloMessage;
1512 }
1513
1514 /*
1515 * Fault detected during handshake.
1516 */
1517 @Override
1518 void handshakeAlert(byte description) throws SSLProtocolException {
1519 String message = Alerts.alertDescription(description);
1520
1521 if (debug != null && Debug.isOn("handshake")) {
1522 System.out.println("SSL - handshake alert: " + message);
1523 }
1524 throw new SSLProtocolException("handshake alert: " + message);
1525 }
1526
1527 /*
1528 * Unless we are using an anonymous ciphersuite, the server always
1529 * sends a certificate message (for the CipherSuites we currently
1530 * support). The trust manager verifies the chain for us.
|