44 import java.util.Queue; |
44 import java.util.Queue; |
45 import javax.crypto.SecretKey; |
45 import javax.crypto.SecretKey; |
46 import javax.net.ssl.SNIServerName; |
46 import javax.net.ssl.SNIServerName; |
47 import javax.net.ssl.SSLHandshakeException; |
47 import javax.net.ssl.SSLHandshakeException; |
48 import javax.security.auth.x500.X500Principal; |
48 import javax.security.auth.x500.X500Principal; |
49 import sun.security.ssl.SupportedGroupsExtension.NamedGroup; |
49 import sun.security.ssl.NamedGroup.NamedGroupSpec; |
50 import sun.security.ssl.SupportedGroupsExtension.NamedGroupType; |
50 import static sun.security.ssl.NamedGroup.NamedGroupSpec.*; |
51 import static sun.security.ssl.SupportedGroupsExtension.NamedGroupType.*; |
|
52 import sun.security.ssl.SupportedGroupsExtension.SupportedGroups; |
51 import sun.security.ssl.SupportedGroupsExtension.SupportedGroups; |
53 |
52 |
54 abstract class HandshakeContext implements ConnectionContext { |
53 abstract class HandshakeContext implements ConnectionContext { |
55 // System properties |
54 // System properties |
56 |
55 |
100 boolean kickstartMessageDelivered; |
99 boolean kickstartMessageDelivered; |
101 |
100 |
102 // Resumption |
101 // Resumption |
103 boolean isResumption; |
102 boolean isResumption; |
104 SSLSessionImpl resumingSession; |
103 SSLSessionImpl resumingSession; |
|
104 // Session is using stateless resumption |
|
105 boolean statelessResumption = false; |
105 |
106 |
106 final Queue<Map.Entry<Byte, ByteBuffer>> delegatedActions; |
107 final Queue<Map.Entry<Byte, ByteBuffer>> delegatedActions; |
107 volatile boolean taskDelegated = false; |
108 volatile boolean taskDelegated = false; |
108 volatile Exception delegatedThrown = null; |
109 volatile Exception delegatedThrown = null; |
109 |
110 |
280 // Ignore disabled protocol. |
281 // Ignore disabled protocol. |
281 continue; |
282 continue; |
282 } |
283 } |
283 |
284 |
284 boolean found = false; |
285 boolean found = false; |
285 Map<NamedGroupType, Boolean> cachedStatus = |
286 Map<NamedGroupSpec, Boolean> cachedStatus = |
286 new EnumMap<>(NamedGroupType.class); |
287 new EnumMap<>(NamedGroupSpec.class); |
287 for (CipherSuite suite : enabledCipherSuites) { |
288 for (CipherSuite suite : enabledCipherSuites) { |
288 if (suite.isAvailable() && suite.supports(protocol)) { |
289 if (suite.isAvailable() && suite.supports(protocol)) { |
289 if (isActivatable(suite, |
290 if (isActivatable(suite, |
290 algorithmConstraints, cachedStatus)) { |
291 algorithmConstraints, cachedStatus)) { |
291 protocols.add(protocol); |
292 protocols.add(protocol); |
320 List<CipherSuite> enabledCipherSuites, |
321 List<CipherSuite> enabledCipherSuites, |
321 AlgorithmConstraints algorithmConstraints) { |
322 AlgorithmConstraints algorithmConstraints) { |
322 |
323 |
323 List<CipherSuite> suites = new LinkedList<>(); |
324 List<CipherSuite> suites = new LinkedList<>(); |
324 if (enabledProtocols != null && !enabledProtocols.isEmpty()) { |
325 if (enabledProtocols != null && !enabledProtocols.isEmpty()) { |
325 Map<NamedGroupType, Boolean> cachedStatus = |
326 Map<NamedGroupSpec, Boolean> cachedStatus = |
326 new EnumMap<>(NamedGroupType.class); |
327 new EnumMap<>(NamedGroupSpec.class); |
327 for (CipherSuite suite : enabledCipherSuites) { |
328 for (CipherSuite suite : enabledCipherSuites) { |
328 if (!suite.isAvailable()) { |
329 if (!suite.isAvailable()) { |
329 continue; |
330 continue; |
330 } |
331 } |
331 |
332 |
506 this.conContext.protocolVersion = protocolVersion; |
507 this.conContext.protocolVersion = protocolVersion; |
507 } |
508 } |
508 |
509 |
509 private static boolean isActivatable(CipherSuite suite, |
510 private static boolean isActivatable(CipherSuite suite, |
510 AlgorithmConstraints algorithmConstraints, |
511 AlgorithmConstraints algorithmConstraints, |
511 Map<NamedGroupType, Boolean> cachedStatus) { |
512 Map<NamedGroupSpec, Boolean> cachedStatus) { |
512 |
513 |
513 if (algorithmConstraints.permits( |
514 if (algorithmConstraints.permits( |
514 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), suite.name, null)) { |
515 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), suite.name, null)) { |
515 if (suite.keyExchange == null) { |
516 if (suite.keyExchange == null) { |
516 // TLS 1.3, no definition of key exchange in cipher suite. |
517 // TLS 1.3, no definition of key exchange in cipher suite. |
517 return true; |
518 return true; |
518 } |
519 } |
519 |
520 |
520 boolean available; |
521 // Is at least one of the group types available? |
521 NamedGroupType groupType = suite.keyExchange.groupType; |
522 boolean groupAvailable, retval = false; |
522 if (groupType != NAMED_GROUP_NONE) { |
523 NamedGroupSpec[] groupTypes = suite.keyExchange.groupTypes; |
523 Boolean checkedStatus = cachedStatus.get(groupType); |
524 for (NamedGroupSpec groupType : groupTypes) { |
524 if (checkedStatus == null) { |
525 if (groupType != NAMED_GROUP_NONE) { |
525 available = SupportedGroups.isActivatable( |
526 Boolean checkedStatus = cachedStatus.get(groupType); |
526 algorithmConstraints, groupType); |
527 if (checkedStatus == null) { |
527 cachedStatus.put(groupType, available); |
528 groupAvailable = SupportedGroups.isActivatable( |
528 |
529 algorithmConstraints, groupType); |
529 if (!available && |
530 cachedStatus.put(groupType, groupAvailable); |
530 SSLLogger.isOn && SSLLogger.isOn("verbose")) { |
531 |
531 SSLLogger.fine("No activated named group"); |
532 if (!groupAvailable && |
|
533 SSLLogger.isOn && SSLLogger.isOn("verbose")) { |
|
534 SSLLogger.fine( |
|
535 "No activated named group in " + groupType); |
|
536 } |
|
537 } else { |
|
538 groupAvailable = checkedStatus; |
532 } |
539 } |
|
540 |
|
541 retval |= groupAvailable; |
533 } else { |
542 } else { |
534 available = checkedStatus; |
543 retval |= true; |
535 } |
544 } |
536 |
545 } |
537 if (!available && SSLLogger.isOn && SSLLogger.isOn("verbose")) { |
546 |
538 SSLLogger.fine( |
547 if (!retval && SSLLogger.isOn && SSLLogger.isOn("verbose")) { |
539 "No active named group, ignore " + suite); |
548 SSLLogger.fine("No active named group(s), ignore " + suite); |
540 } |
549 } |
541 return available; |
550 |
542 } else { |
551 return retval; |
543 return true; |
552 |
544 } |
|
545 } else if (SSLLogger.isOn && SSLLogger.isOn("verbose")) { |
553 } else if (SSLLogger.isOn && SSLLogger.isOn("verbose")) { |
546 SSLLogger.fine("Ignore disabled cipher suite: " + suite); |
554 SSLLogger.fine("Ignore disabled cipher suite: " + suite); |
547 } |
555 } |
548 |
556 |
549 return false; |
557 return false; |
550 } |
558 } |
551 |
559 |
552 List<SNIServerName> getRequestedServerNames() { |
560 List<SNIServerName> getRequestedServerNames() { |
553 if (requestedServerNames == null) { |
561 if (requestedServerNames == null) { |
554 return Collections.<SNIServerName>emptyList(); |
562 return Collections.emptyList(); |
555 } |
563 } |
556 return requestedServerNames; |
564 return requestedServerNames; |
557 } |
565 } |
558 } |
566 } |
559 |
567 |