21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
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 |
22 * or visit www.oracle.com if you need additional information or have any |
23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 |
|
27 package sun.security.ssl; |
26 package sun.security.ssl; |
28 |
27 |
29 import java.io.*; |
28 import java.io.*; |
30 import java.math.BigInteger; |
29 import java.math.BigInteger; |
31 import java.security.*; |
30 import java.security.*; |
43 |
42 |
44 import javax.net.ssl.*; |
43 import javax.net.ssl.*; |
45 |
44 |
46 import javax.security.auth.Subject; |
45 import javax.security.auth.Subject; |
47 |
46 |
48 import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager; |
|
49 |
|
50 import sun.security.ssl.HandshakeMessage.*; |
47 import sun.security.ssl.HandshakeMessage.*; |
51 import sun.security.ssl.CipherSuite.*; |
48 import sun.security.ssl.CipherSuite.*; |
52 import static sun.security.ssl.CipherSuite.KeyExchange.*; |
49 import static sun.security.ssl.CipherSuite.KeyExchange.*; |
|
50 |
|
51 import sun.net.util.IPAddressUtil; |
53 |
52 |
54 /** |
53 /** |
55 * ClientHandshaker does the protocol handshaking from the point |
54 * ClientHandshaker does the protocol handshaking from the point |
56 * of view of a client. It is driven asychronously by handshake messages |
55 * of view of a client. It is driven asychronously by handshake messages |
57 * as delivered by the parent Handshaker class, and also uses |
56 * as delivered by the parent Handshaker class, and also uses |
86 * case of an initial handshake, it's the max version enabled, |
85 * case of an initial handshake, it's the max version enabled, |
87 * but in the case of a resumption attempt, it's the version |
86 * but in the case of a resumption attempt, it's the version |
88 * of the session we're trying to resume. |
87 * of the session we're trying to resume. |
89 */ |
88 */ |
90 private ProtocolVersion maxProtocolVersion; |
89 private ProtocolVersion maxProtocolVersion; |
|
90 |
|
91 // To switch off the SNI extension. |
|
92 private final static boolean enableSNIExtension = |
|
93 Debug.getBooleanProperty("jsse.enableSNIExtension", true); |
91 |
94 |
92 /* |
95 /* |
93 * Constructors |
96 * Constructors |
94 */ |
97 */ |
95 ClientHandshaker(SSLSocketImpl socket, SSLContextImpl context, |
98 ClientHandshaker(SSLSocketImpl socket, SSLContextImpl context, |
188 } catch (GeneralSecurityException e) { |
191 } catch (GeneralSecurityException e) { |
189 throwSSLException("Server key", e); |
192 throwSSLException("Server key", e); |
190 } |
193 } |
191 break; |
194 break; |
192 case K_DH_ANON: |
195 case K_DH_ANON: |
193 this.serverKeyExchange(new DH_ServerKeyExchange(input)); |
196 this.serverKeyExchange(new DH_ServerKeyExchange( |
|
197 input, protocolVersion)); |
194 break; |
198 break; |
195 case K_DHE_DSS: |
199 case K_DHE_DSS: |
196 case K_DHE_RSA: |
200 case K_DHE_RSA: |
197 try { |
201 try { |
198 this.serverKeyExchange(new DH_ServerKeyExchange( |
202 this.serverKeyExchange(new DH_ServerKeyExchange( |
199 input, serverKey, |
203 input, serverKey, |
200 clnt_random.random_bytes, svr_random.random_bytes, |
204 clnt_random.random_bytes, svr_random.random_bytes, |
201 messageLen)); |
205 messageLen, |
|
206 localSupportedSignAlgs, protocolVersion)); |
202 } catch (GeneralSecurityException e) { |
207 } catch (GeneralSecurityException e) { |
203 throwSSLException("Server key", e); |
208 throwSSLException("Server key", e); |
204 } |
209 } |
205 break; |
210 break; |
206 case K_ECDHE_ECDSA: |
211 case K_ECDHE_ECDSA: |
207 case K_ECDHE_RSA: |
212 case K_ECDHE_RSA: |
208 case K_ECDH_ANON: |
213 case K_ECDH_ANON: |
209 try { |
214 try { |
210 this.serverKeyExchange(new ECDH_ServerKeyExchange |
215 this.serverKeyExchange(new ECDH_ServerKeyExchange |
211 (input, serverKey, clnt_random.random_bytes, |
216 (input, serverKey, clnt_random.random_bytes, |
212 svr_random.random_bytes)); |
217 svr_random.random_bytes, |
|
218 localSupportedSignAlgs, protocolVersion)); |
213 } catch (GeneralSecurityException e) { |
219 } catch (GeneralSecurityException e) { |
214 throwSSLException("Server key", e); |
220 throwSSLException("Server key", e); |
215 } |
221 } |
216 break; |
222 break; |
217 case K_RSA: |
223 case K_RSA: |
218 case K_DH_RSA: |
224 case K_DH_RSA: |
219 case K_DH_DSS: |
225 case K_DH_DSS: |
220 case K_ECDH_ECDSA: |
226 case K_ECDH_ECDSA: |
221 case K_ECDH_RSA: |
227 case K_ECDH_RSA: |
222 throw new SSLProtocolException("Protocol violation: server sent" |
228 throw new SSLProtocolException( |
223 + " a server key exchange message for key exchange " + keyExchange); |
229 "Protocol violation: server sent a server key exchange" |
|
230 + "message for key exchange " + keyExchange); |
224 case K_KRB5: |
231 case K_KRB5: |
225 case K_KRB5_EXPORT: |
232 case K_KRB5_EXPORT: |
226 throw new SSLProtocolException( |
233 throw new SSLProtocolException( |
227 "unexpected receipt of server key exchange algorithm"); |
234 "unexpected receipt of server key exchange algorithm"); |
228 default: |
235 default: |
241 } else if (keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) { |
248 } else if (keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) { |
242 throw new SSLHandshakeException( |
249 throw new SSLHandshakeException( |
243 "Client certificate requested for "+ |
250 "Client certificate requested for "+ |
244 "kerberos cipher suite."); |
251 "kerberos cipher suite."); |
245 } |
252 } |
246 certRequest = new CertificateRequest(input); |
253 certRequest = new CertificateRequest(input, protocolVersion); |
247 if (debug != null && Debug.isOn("handshake")) { |
254 if (debug != null && Debug.isOn("handshake")) { |
248 certRequest.print(System.out); |
255 certRequest.print(System.out); |
249 } |
256 } |
|
257 |
|
258 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { |
|
259 Collection<SignatureAndHashAlgorithm> peerSignAlgs = |
|
260 certRequest.getSignAlgorithms(); |
|
261 if (peerSignAlgs == null || peerSignAlgs.isEmpty()) { |
|
262 throw new SSLHandshakeException( |
|
263 "No peer supported signature algorithms"); |
|
264 } |
|
265 |
|
266 Collection<SignatureAndHashAlgorithm> supportedPeerSignAlgs = |
|
267 SignatureAndHashAlgorithm.getSupportedAlgorithms( |
|
268 peerSignAlgs); |
|
269 if (supportedPeerSignAlgs.isEmpty()) { |
|
270 throw new SSLHandshakeException( |
|
271 "No supported signature and hash algorithm in common"); |
|
272 } |
|
273 |
|
274 setPeerSupportedSignAlgs(supportedPeerSignAlgs); |
|
275 session.setPeerSupportedSignatureAlgorithms( |
|
276 supportedPeerSignAlgs); |
|
277 } |
|
278 |
250 break; |
279 break; |
251 |
280 |
252 case HandshakeMessage.ht_server_hello_done: |
281 case HandshakeMessage.ht_server_hello_done: |
253 this.serverHelloDone(new ServerHelloDone(input)); |
282 this.serverHelloDone(new ServerHelloDone(input)); |
254 break; |
283 break; |
255 |
284 |
256 case HandshakeMessage.ht_finished: |
285 case HandshakeMessage.ht_finished: |
257 this.serverFinished(new Finished(protocolVersion, input)); |
286 this.serverFinished( |
|
287 new Finished(protocolVersion, input, cipherSuite)); |
258 break; |
288 break; |
259 |
289 |
260 default: |
290 default: |
261 throw new SSLProtocolException( |
291 throw new SSLProtocolException( |
262 "Illegal client handshake msg, " + type); |
292 "Illegal client handshake msg, " + type); |
349 throw new SSLHandshakeException( |
379 throw new SSLHandshakeException( |
350 "Server chose unsupported or disabled protocol: " + |
380 "Server chose unsupported or disabled protocol: " + |
351 mesgVersion); |
381 mesgVersion); |
352 } |
382 } |
353 |
383 |
|
384 handshakeHash.protocolDetermined( |
|
385 mesgVersion.v >= ProtocolVersion.TLS12.v); |
|
386 |
354 // Set protocolVersion and propagate to SSLSocket and the |
387 // Set protocolVersion and propagate to SSLSocket and the |
355 // Handshake streams |
388 // Handshake streams |
356 setVersion(mesgVersion); |
389 setVersion(mesgVersion); |
357 |
390 |
358 // check the "renegotiation_info" extension |
391 // check the "renegotiation_info" extension |
424 // |
457 // |
425 svr_random = mesg.svr_random; |
458 svr_random = mesg.svr_random; |
426 |
459 |
427 if (isNegotiable(mesg.cipherSuite) == false) { |
460 if (isNegotiable(mesg.cipherSuite) == false) { |
428 fatalSE(Alerts.alert_illegal_parameter, |
461 fatalSE(Alerts.alert_illegal_parameter, |
429 "Server selected improper ciphersuite " + cipherSuite); |
462 "Server selected improper ciphersuite " + mesg.cipherSuite); |
430 } |
463 } |
431 |
464 |
432 setCipherSuite(mesg.cipherSuite); |
465 setCipherSuite(mesg.cipherSuite); |
|
466 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { |
|
467 handshakeHash.setFinishedAlg(cipherSuite.prfAlg.getPRFHashAlg()); |
|
468 } |
433 |
469 |
434 if (mesg.compression_method != 0) { |
470 if (mesg.compression_method != 0) { |
435 fatalSE(Alerts.alert_illegal_parameter, |
471 fatalSE(Alerts.alert_illegal_parameter, |
436 "compression type not supported, " |
472 "compression type not supported, " |
437 + mesg.compression_method); |
473 + mesg.compression_method); |
506 state = HandshakeMessage.ht_finished - 1; |
542 state = HandshakeMessage.ht_finished - 1; |
507 calculateConnectionKeys(session.getMasterSecret()); |
543 calculateConnectionKeys(session.getMasterSecret()); |
508 if (debug != null && Debug.isOn("session")) { |
544 if (debug != null && Debug.isOn("session")) { |
509 System.out.println("%% Server resumed " + session); |
545 System.out.println("%% Server resumed " + session); |
510 } |
546 } |
511 return; |
|
512 } else { |
547 } else { |
513 // we wanted to resume, but the server refused |
548 // we wanted to resume, but the server refused |
514 session = null; |
549 session = null; |
515 if (!enableNewSession) { |
550 if (!enableNewSession) { |
516 throw new SSLException |
551 throw new SSLException |
517 ("New session creation is disabled"); |
552 ("New session creation is disabled"); |
518 } |
553 } |
519 } |
554 } |
520 } |
555 } |
521 |
556 |
|
557 if (resumingSession && session != null) { |
|
558 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { |
|
559 handshakeHash.setCertificateVerifyAlg(null); |
|
560 } |
|
561 |
|
562 setHandshakeSessionSE(session); |
|
563 return; |
|
564 } |
|
565 |
522 // check extensions |
566 // check extensions |
523 for (HelloExtension ext : mesg.extensions.list()) { |
567 for (HelloExtension ext : mesg.extensions.list()) { |
524 ExtensionType type = ext.type; |
568 ExtensionType type = ext.type; |
525 if ((type != ExtensionType.EXT_ELLIPTIC_CURVES) |
569 if ((type != ExtensionType.EXT_ELLIPTIC_CURVES) |
526 && (type != ExtensionType.EXT_EC_POINT_FORMATS) |
570 && (type != ExtensionType.EXT_EC_POINT_FORMATS) |
|
571 && (type != ExtensionType.EXT_SERVER_NAME) |
527 && (type != ExtensionType.EXT_RENEGOTIATION_INFO)) { |
572 && (type != ExtensionType.EXT_RENEGOTIATION_INFO)) { |
528 fatalSE(Alerts.alert_unsupported_extension, |
573 fatalSE(Alerts.alert_unsupported_extension, |
529 "Server sent an unsupported extension: " + type); |
574 "Server sent an unsupported extension: " + type); |
530 } |
575 } |
531 } |
576 } |
532 |
577 |
533 // Create a new session, we need to do the full handshake |
578 // Create a new session, we need to do the full handshake |
534 session = new SSLSessionImpl(protocolVersion, cipherSuite, |
579 session = new SSLSessionImpl(protocolVersion, cipherSuite, |
|
580 getLocalSupportedSignAlgs(), |
535 mesg.sessionId, getHostSE(), getPortSE()); |
581 mesg.sessionId, getHostSE(), getPortSE()); |
|
582 setHandshakeSessionSE(session); |
536 if (debug != null && Debug.isOn("handshake")) { |
583 if (debug != null && Debug.isOn("handshake")) { |
537 System.out.println("** " + cipherSuite); |
584 System.out.println("** " + cipherSuite); |
538 } |
585 } |
539 } |
586 } |
540 |
587 |
566 private void serverKeyExchange(DH_ServerKeyExchange mesg) |
613 private void serverKeyExchange(DH_ServerKeyExchange mesg) |
567 throws IOException { |
614 throws IOException { |
568 if (debug != null && Debug.isOn("handshake")) { |
615 if (debug != null && Debug.isOn("handshake")) { |
569 mesg.print(System.out); |
616 mesg.print(System.out); |
570 } |
617 } |
571 dh = new DHCrypt(mesg.getModulus(), mesg.getBase(), sslContext.getSecureRandom()); |
618 dh = new DHCrypt(mesg.getModulus(), mesg.getBase(), |
|
619 sslContext.getSecureRandom()); |
572 serverDH = mesg.getServerPublicKey(); |
620 serverDH = mesg.getServerPublicKey(); |
573 } |
621 } |
574 |
622 |
575 private void serverKeyExchange(ECDH_ServerKeyExchange mesg) throws IOException { |
623 private void serverKeyExchange(ECDH_ServerKeyExchange mesg) |
|
624 throws IOException { |
576 if (debug != null && Debug.isOn("handshake")) { |
625 if (debug != null && Debug.isOn("handshake")) { |
577 mesg.print(System.out); |
626 mesg.print(System.out); |
578 } |
627 } |
579 ECPublicKey key = mesg.getPublicKey(); |
628 ECPublicKey key = mesg.getPublicKey(); |
580 ecdh = new ECDHCrypt(key.getParams(), sslContext.getSecureRandom()); |
629 ecdh = new ECDHCrypt(key.getParams(), sslContext.getSecureRandom()); |
664 X509Certificate[] certs = km.getCertificateChain(alias); |
713 X509Certificate[] certs = km.getCertificateChain(alias); |
665 if ((certs != null) && (certs.length != 0)) { |
714 if ((certs != null) && (certs.length != 0)) { |
666 PublicKey publicKey = certs[0].getPublicKey(); |
715 PublicKey publicKey = certs[0].getPublicKey(); |
667 // for EC, make sure we use a supported named curve |
716 // for EC, make sure we use a supported named curve |
668 if (publicKey instanceof ECPublicKey) { |
717 if (publicKey instanceof ECPublicKey) { |
669 ECParameterSpec params = ((ECPublicKey)publicKey).getParams(); |
718 ECParameterSpec params = |
670 int index = SupportedEllipticCurvesExtension.getCurveIndex(params); |
719 ((ECPublicKey)publicKey).getParams(); |
671 if (!SupportedEllipticCurvesExtension.isSupported(index)) { |
720 int index = |
|
721 SupportedEllipticCurvesExtension.getCurveIndex( |
|
722 params); |
|
723 if (!SupportedEllipticCurvesExtension.isSupported( |
|
724 index)) { |
672 publicKey = null; |
725 publicKey = null; |
673 } |
726 } |
674 } |
727 } |
675 if (publicKey != null) { |
728 if (publicKey != null) { |
676 m1 = new CertificateMsg(certs); |
729 m1 = new CertificateMsg(certs); |
812 String hostname = getHostSE(); |
865 String hostname = getHostSE(); |
813 if (hostname == null) { |
866 if (hostname == null) { |
814 throw new IOException("Hostname is required" + |
867 throw new IOException("Hostname is required" + |
815 " to use Kerberos cipher suites"); |
868 " to use Kerberos cipher suites"); |
816 } |
869 } |
817 KerberosClientKeyExchange kerberosMsg = new KerberosClientKeyExchange |
870 KerberosClientKeyExchange kerberosMsg = |
818 (hostname, isLoopbackSE(), getAccSE(), protocolVersion, |
871 new KerberosClientKeyExchange( |
|
872 hostname, isLoopbackSE(), getAccSE(), protocolVersion, |
819 sslContext.getSecureRandom()); |
873 sslContext.getSecureRandom()); |
820 // Record the principals involved in exchange |
874 // Record the principals involved in exchange |
821 session.setPeerPrincipal(kerberosMsg.getPeerPrincipal()); |
875 session.setPeerPrincipal(kerberosMsg.getPeerPrincipal()); |
822 session.setLocalPrincipal(kerberosMsg.getLocalPrincipal()); |
876 session.setLocalPrincipal(kerberosMsg.getLocalPrincipal()); |
823 m2 = kerberosMsg; |
877 m2 = kerberosMsg; |
895 * computed. |
951 * computed. |
896 */ |
952 */ |
897 if (signingKey != null) { |
953 if (signingKey != null) { |
898 CertificateVerify m3; |
954 CertificateVerify m3; |
899 try { |
955 try { |
|
956 SignatureAndHashAlgorithm preferableSignatureAlgorithm = null; |
|
957 if (protocolVersion.v >= ProtocolVersion.TLS12.v) { |
|
958 preferableSignatureAlgorithm = |
|
959 SignatureAndHashAlgorithm.getPreferableAlgorithm( |
|
960 peerSupportedSignAlgs, signingKey.getAlgorithm()); |
|
961 |
|
962 if (preferableSignatureAlgorithm == null) { |
|
963 throw new SSLHandshakeException( |
|
964 "No supported signature algorithm"); |
|
965 } |
|
966 |
|
967 String hashAlg = |
|
968 SignatureAndHashAlgorithm.getHashAlgorithmName( |
|
969 preferableSignatureAlgorithm); |
|
970 if (hashAlg == null || hashAlg.length() == 0) { |
|
971 throw new SSLHandshakeException( |
|
972 "No supported hash algorithm"); |
|
973 } |
|
974 |
|
975 handshakeHash.setCertificateVerifyAlg(hashAlg); |
|
976 } |
|
977 |
900 m3 = new CertificateVerify(protocolVersion, handshakeHash, |
978 m3 = new CertificateVerify(protocolVersion, handshakeHash, |
901 signingKey, session.getMasterSecret(), |
979 signingKey, session.getMasterSecret(), |
902 sslContext.getSecureRandom()); |
980 sslContext.getSecureRandom(), |
|
981 preferableSignatureAlgorithm); |
903 } catch (GeneralSecurityException e) { |
982 } catch (GeneralSecurityException e) { |
904 fatalSE(Alerts.alert_handshake_failure, |
983 fatalSE(Alerts.alert_handshake_failure, |
905 "Error signing certificate verify", e); |
984 "Error signing certificate verify", e); |
906 // NOTREACHED, make compiler happy |
985 // NOTREACHED, make compiler happy |
907 m3 = null; |
986 m3 = null; |
929 private void serverFinished(Finished mesg) throws IOException { |
1012 private void serverFinished(Finished mesg) throws IOException { |
930 if (debug != null && Debug.isOn("handshake")) { |
1013 if (debug != null && Debug.isOn("handshake")) { |
931 mesg.print(System.out); |
1014 mesg.print(System.out); |
932 } |
1015 } |
933 |
1016 |
934 boolean verified = mesg.verify(protocolVersion, handshakeHash, |
1017 boolean verified = mesg.verify(handshakeHash, Finished.SERVER, |
935 Finished.SERVER, session.getMasterSecret()); |
1018 session.getMasterSecret()); |
936 |
1019 |
937 if (!verified) { |
1020 if (!verified) { |
938 fatalSE(Alerts.alert_illegal_parameter, |
1021 fatalSE(Alerts.alert_illegal_parameter, |
939 "server 'finished' message doesn't verify"); |
1022 "server 'finished' message doesn't verify"); |
940 // NOTREACHED |
1023 // NOTREACHED |
987 * long one, we wait for it now. |
1070 * long one, we wait for it now. |
988 */ |
1071 */ |
989 private void sendChangeCipherAndFinish(boolean finishedTag) |
1072 private void sendChangeCipherAndFinish(boolean finishedTag) |
990 throws IOException { |
1073 throws IOException { |
991 Finished mesg = new Finished(protocolVersion, handshakeHash, |
1074 Finished mesg = new Finished(protocolVersion, handshakeHash, |
992 Finished.CLIENT, session.getMasterSecret()); |
1075 Finished.CLIENT, session.getMasterSecret(), cipherSuite); |
993 |
1076 |
994 /* |
1077 /* |
995 * Send the change_cipher_spec message, then the Finished message |
1078 * Send the change_cipher_spec message, then the Finished message |
996 * which we just calculated (and protected using the keys we just |
1079 * which we just calculated (and protected using the keys we just |
997 * calculated). Server responds with its Finished message, except |
1080 * calculated). Server responds with its Finished message, except |
1132 |
1215 |
1133 if (!negotiable) { |
1216 if (!negotiable) { |
1134 throw new SSLHandshakeException("No negotiable cipher suite"); |
1217 throw new SSLHandshakeException("No negotiable cipher suite"); |
1135 } |
1218 } |
1136 |
1219 |
|
1220 // Not a TLS1.2+ handshake |
|
1221 // For SSLv2Hello, HandshakeHash.reset() will be called, so we |
|
1222 // cannot call HandshakeHash.protocolDetermined() here. As it does |
|
1223 // not follow the spec that HandshakeHash.reset() can be only be |
|
1224 // called before protocolDetermined. |
|
1225 // if (maxProtocolVersion.v < ProtocolVersion.TLS12.v) { |
|
1226 // handshakeHash.protocolDetermined(false); |
|
1227 // } |
|
1228 |
1137 // create the ClientHello message |
1229 // create the ClientHello message |
1138 ClientHello clientHelloMessage = new ClientHello( |
1230 ClientHello clientHelloMessage = new ClientHello( |
1139 sslContext.getSecureRandom(), maxProtocolVersion, |
1231 sslContext.getSecureRandom(), maxProtocolVersion, |
1140 sessionId, cipherSuites); |
1232 sessionId, cipherSuites); |
|
1233 |
|
1234 // add signature_algorithm extension |
|
1235 if (maxProtocolVersion.v >= ProtocolVersion.TLS12.v) { |
|
1236 // we will always send the signature_algorithm extension |
|
1237 Collection<SignatureAndHashAlgorithm> localSignAlgs = |
|
1238 getLocalSupportedSignAlgs(); |
|
1239 if (localSignAlgs.isEmpty()) { |
|
1240 throw new SSLHandshakeException( |
|
1241 "No supported signature algorithm"); |
|
1242 } |
|
1243 |
|
1244 clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs); |
|
1245 } |
|
1246 |
|
1247 // add server_name extension |
|
1248 if (enableSNIExtension) { |
|
1249 // We cannot use the hostname resolved from name services. For |
|
1250 // virtual hosting, multiple hostnames may be bound to the same IP |
|
1251 // address, so the hostname resolved from name services is not |
|
1252 // reliable. |
|
1253 String hostname = getRawHostnameSE(); |
|
1254 |
|
1255 // we only allow FQDN |
|
1256 if (hostname != null && hostname.indexOf('.') > 0 && |
|
1257 !IPAddressUtil.isIPv4LiteralAddress(hostname) && |
|
1258 !IPAddressUtil.isIPv6LiteralAddress(hostname)) { |
|
1259 clientHelloMessage.addServerNameIndicationExtension(hostname); |
|
1260 } |
|
1261 } |
1141 |
1262 |
1142 // reset the client random cookie |
1263 // reset the client random cookie |
1143 clnt_random = clientHelloMessage.clnt_random; |
1264 clnt_random = clientHelloMessage.clnt_random; |
1144 |
1265 |
1145 /* |
1266 /* |
1192 keyExchangeString = K_RSA.name; |
1313 keyExchangeString = K_RSA.name; |
1193 } else { |
1314 } else { |
1194 keyExchangeString = keyExchange.name; |
1315 keyExchangeString = keyExchange.name; |
1195 } |
1316 } |
1196 |
1317 |
1197 String identificator = getHostnameVerificationSE(); |
|
1198 if (tm instanceof X509ExtendedTrustManager) { |
1318 if (tm instanceof X509ExtendedTrustManager) { |
1199 ((X509ExtendedTrustManager)tm).checkServerTrusted( |
1319 if (conn != null) { |
1200 (peerCerts != null ? |
1320 ((X509ExtendedTrustManager)tm).checkServerTrusted( |
1201 peerCerts.clone() : |
1321 peerCerts.clone(), |
1202 null), |
|
1203 keyExchangeString, |
1322 keyExchangeString, |
1204 getHostSE(), |
1323 conn); |
1205 identificator); |
1324 } else { |
|
1325 ((X509ExtendedTrustManager)tm).checkServerTrusted( |
|
1326 peerCerts.clone(), |
|
1327 keyExchangeString, |
|
1328 engine); |
|
1329 } |
1206 } else { |
1330 } else { |
1207 if (identificator != null) { |
1331 // Unlikely to happen, because we have wrapped the old |
1208 throw new RuntimeException( |
1332 // X509TrustManager with the new X509ExtendedTrustManager. |
1209 "trust manager does not support peer identification"); |
1333 throw new CertificateException( |
1210 } |
1334 "Improper X509TrustManager implementation"); |
1211 |
|
1212 tm.checkServerTrusted( |
|
1213 (peerCerts != null ? |
|
1214 peerCerts.clone() : |
|
1215 peerCerts), |
|
1216 keyExchangeString); |
|
1217 } |
1335 } |
1218 } catch (CertificateException e) { |
1336 } catch (CertificateException e) { |
1219 // This will throw an exception, so include the original error. |
1337 // This will throw an exception, so include the original error. |
1220 fatalSE(Alerts.alert_certificate_unknown, e); |
1338 fatalSE(Alerts.alert_certificate_unknown, e); |
1221 } |
1339 } |