--- a/src/java.base/share/classes/sun/security/ssl/ECDHServerKeyExchange.java Wed Jun 12 23:21:24 2019 +0200
+++ b/src/java.base/share/classes/sun/security/ssl/ECDHServerKeyExchange.java Wed Jun 12 18:58:00 2019 -0700
@@ -27,32 +27,21 @@
import java.io.IOException;
import java.nio.ByteBuffer;
-import java.security.CryptoPrimitive;
+import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
-import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
-import java.security.spec.ECPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
import java.text.MessageFormat;
-import java.util.EnumSet;
import java.util.Locale;
-import sun.security.ssl.ECDHKeyExchange.ECDHECredentials;
-import sun.security.ssl.ECDHKeyExchange.ECDHEPossession;
import sun.security.ssl.SSLHandshake.HandshakeMessage;
-import sun.security.ssl.SupportedGroupsExtension.NamedGroup;
import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
import sun.security.ssl.X509Authentication.X509Credentials;
import sun.security.ssl.X509Authentication.X509Possession;
-import sun.security.util.ECUtil;
import sun.security.util.HexDumpEncoder;
/**
@@ -80,14 +69,14 @@
// signature bytes, or null if anonymous
private final byte[] paramsSignature;
- // public key object encapsulated in this message
- private final ECPublicKey publicKey;
-
private final boolean useExplicitSigAlgorithm;
// the signature algorithm used by this ServerKeyExchange message
private final SignatureScheme signatureScheme;
+ // the parsed credential object
+ private SSLCredentials sslCredentials;
+
ECDHServerKeyExchangeMessage(
HandshakeContext handshakeContext) throws IOException {
super(handshakeContext);
@@ -96,38 +85,38 @@
ServerHandshakeContext shc =
(ServerHandshakeContext)handshakeContext;
- ECDHEPossession ecdhePossession = null;
+ // Find the Possessions needed
+ NamedGroupPossession namedGroupPossession = null;
X509Possession x509Possession = null;
for (SSLPossession possession : shc.handshakePossessions) {
- if (possession instanceof ECDHEPossession) {
- ecdhePossession = (ECDHEPossession)possession;
+ if (possession instanceof NamedGroupPossession) {
+ namedGroupPossession = (NamedGroupPossession)possession;
if (x509Possession != null) {
break;
}
} else if (possession instanceof X509Possession) {
x509Possession = (X509Possession)possession;
- if (ecdhePossession != null) {
+ if (namedGroupPossession != null) {
break;
}
}
}
- if (ecdhePossession == null) {
+ if (namedGroupPossession == null) {
// unlikely
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
"No ECDHE credentials negotiated for server key exchange");
}
- publicKey = ecdhePossession.publicKey;
- ECParameterSpec params = publicKey.getParams();
- ECPoint point = publicKey.getW();
- publicPoint = ECUtil.encodePoint(point, params.getCurve());
+ // Find the NamedGroup used for the ephemeral keys.
+ namedGroup = namedGroupPossession.getNamedGroup();
+ publicPoint = namedGroup.encodePossessionPublicKey(
+ namedGroupPossession);
- this.namedGroup = NamedGroup.valueOf(params);
if ((namedGroup == null) || (namedGroup.oid == null) ) {
// unlikely
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
- "Unnamed EC parameter spec: " + params);
+ "Missing Named Group");
}
if (x509Possession == null) {
@@ -216,39 +205,23 @@
"Unsupported named group: " + namedGroup);
}
- if (namedGroup.oid == null) {
- throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
- "Unknown named EC curve: " + namedGroup);
- }
-
- ECParameterSpec parameters =
- ECUtil.getECParameterSpec(null, namedGroup.oid);
- if (parameters == null) {
- throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
- "No supported EC parameter: " + namedGroup);
- }
-
publicPoint = Record.getBytes8(m);
if (publicPoint.length == 0) {
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
- "Insufficient ECPoint data: " + namedGroup);
+ "Insufficient Point data: " + namedGroup);
}
- ECPublicKey ecPublicKey = null;
try {
- ECPoint point =
- ECUtil.decodePoint(publicPoint, parameters.getCurve());
- KeyFactory factory = KeyFactory.getInstance("EC");
- ecPublicKey = (ECPublicKey)factory.generatePublic(
- new ECPublicKeySpec(point, parameters));
- } catch (NoSuchAlgorithmException |
- InvalidKeySpecException | IOException ex) {
- throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
- "Invalid ECPoint: " + namedGroup, ex);
+ sslCredentials = namedGroup.decodeCredentials(
+ publicPoint, handshakeContext.algorithmConstraints,
+ s -> chc.conContext.fatal(Alert.INSUFFICIENT_SECURITY,
+ "ServerKeyExchange " + namedGroup + ": " + (s)));
+ } catch (GeneralSecurityException ex) {
+ throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
+ "Cannot decode named group: " +
+ NamedGroup.nameOf(namedGroupId));
}
- publicKey = ecPublicKey;
-
X509Credentials x509Credentials = null;
for (SSLCredentials cd : chc.handshakeCredentials) {
if (cd instanceof X509Credentials) {
@@ -529,6 +502,7 @@
// The consuming happens in client side only.
ClientHandshakeContext chc = (ClientHandshakeContext)context;
+ // AlgorithmConstraints are checked during decoding
ECDHServerKeyExchangeMessage skem =
new ECDHServerKeyExchangeMessage(chc, message);
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
@@ -537,22 +511,9 @@
}
//
- // validate
- //
- // check constraints of EC PublicKey
- if (!chc.algorithmConstraints.permits(
- EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
- skem.publicKey)) {
- throw chc.conContext.fatal(Alert.INSUFFICIENT_SECURITY,
- "ECDH ServerKeyExchange does not comply " +
- "to algorithm constraints");
- }
-
- //
// update
//
- chc.handshakeCredentials.add(
- new ECDHECredentials(skem.publicKey, skem.namedGroup));
+ chc.handshakeCredentials.add(skem.sslCredentials);
//
// produce