Skip to content
Permalink
Browse files

8247630: Use two key share entries

Reviewed-by: xuelei
  • Loading branch information
Jamil Nimeh
Jamil Nimeh committed Jul 28, 2020
1 parent f2e6915 commit 2aa291ad2c336fcb0238f1ca934ab3b4e5b02f5b
@@ -31,12 +31,15 @@
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import javax.net.ssl.SSLProtocolException;
import sun.security.ssl.KeyShareExtension.CHKeyShareSpec;
import sun.security.ssl.NamedGroup.NamedGroupSpec;
import sun.security.ssl.SSLExtension.ExtensionConsumer;
import sun.security.ssl.SSLExtension.SSLExtensionSpec;
import sun.security.ssl.SSLHandshake.HandshakeMessage;
@@ -248,33 +251,23 @@ private CHKeyShareProducer() {
}
}

// Go through the named groups and take the most-preferred
// group from two categories (i.e. XDH and ECDHE). Once we have
// the most preferred group from two types we can exit the loop.
List<KeyShareEntry> keyShares = new LinkedList<>();
EnumSet<NamedGroupSpec> ngTypes =
EnumSet.noneOf(NamedGroupSpec.class);
byte[] keyExchangeData;
for (NamedGroup ng : namedGroups) {
SSLKeyExchange ke = SSLKeyExchange.valueOf(ng);
if (ke == null) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.warning(
"No key exchange for named group " + ng.name);
}
continue;
}

SSLPossession[] poses = ke.createPossessions(chc);
for (SSLPossession pos : poses) {
// update the context
chc.handshakePossessions.add(pos);
if (!(pos instanceof NamedGroupPossession)) {
// May need more possesion types in the future.
continue;
if (!ngTypes.contains(ng.spec)) {
if ((keyExchangeData = getShare(chc, ng)) != null) {
keyShares.add(new KeyShareEntry(ng.id,
keyExchangeData));
ngTypes.add(ng.spec);
if (ngTypes.size() == 2) {
break;
}
}

keyShares.add(new KeyShareEntry(ng.id, pos.encode()));
}

// One key share entry only. Too much key share entries makes
// the ClientHello handshake message really big.
if (!keyShares.isEmpty()) {
break;
}
}

@@ -295,6 +288,29 @@ private CHKeyShareProducer() {

return extData;
}

private static byte[] getShare(ClientHandshakeContext chc,
NamedGroup ng) {
byte[] share = null;
SSLKeyExchange ke = SSLKeyExchange.valueOf(ng);
if (ke == null) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.warning(
"No key exchange for named group " + ng.name);
}
} else {
SSLPossession[] poses = ke.createPossessions(chc);
for (SSLPossession pos : poses) {
// update the context
chc.handshakePossessions.add(pos);
// May need more possesion types in the future.
if (pos instanceof NamedGroupPossession) {
return pos.encode();
}
}
}
return share;
}
}

/**
@@ -873,11 +889,33 @@ public void consume(ConnectionContext context,
NamedGroup.nameOf(spec.selectedGroup));
}

// The server-selected named group from a HelloRetryRequest must
// meet the following criteria:
// 1. It must be one of the named groups in the supported_groups
// extension in the client hello.
// 2. It cannot be one of the groups in the key_share extension
// from the client hello.
if (!chc.clientRequestedNamedGroups.contains(serverGroup)) {
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
"Unexpected HelloRetryRequest selected group: " +
serverGroup.name);
}
CHKeyShareSpec chKsSpec = (CHKeyShareSpec)
chc.handshakeExtensions.get(SSLExtension.CH_KEY_SHARE);
if (chKsSpec != null) {
for (KeyShareEntry kse : chKsSpec.clientShares) {
if (serverGroup.id == kse.namedGroupId) {
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
"Illegal HelloRetryRequest selected group: " +
serverGroup.name);
}
}
} else {
// Something has gone very wrong if we're here.
throw chc.conContext.fatal(Alert.INTERNAL_ERROR,
"Unable to retrieve ClientHello key_share extension " +
"during HRR processing");
}

// update the context

0 comments on commit 2aa291a

Please sign in to comment.