< prev index next >

src/java.base/share/classes/sun/security/ssl/ECDHServerKeyExchange.java

Print this page

        

*** 25,49 **** package sun.security.ssl; import java.io.IOException; import java.nio.ByteBuffer; ! import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.text.MessageFormat; import java.util.Locale; import sun.security.ssl.SSLHandshake.HandshakeMessage; import sun.security.ssl.SupportedGroupsExtension.SupportedGroups; import sun.security.ssl.X509Authentication.X509Credentials; import sun.security.ssl.X509Authentication.X509Possession; import sun.security.util.HexDumpEncoder; /** * Pack of the ServerKeyExchange handshake message. */ --- 25,60 ---- package sun.security.ssl; import java.io.IOException; import java.nio.ByteBuffer; ! import java.security.CryptoPrimitive; 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; /** * Pack of the ServerKeyExchange handshake message. */
*** 67,124 **** private final byte[] publicPoint; // signature bytes, or null if anonymous private final byte[] paramsSignature; 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); // This happens in server side only. ServerHandshakeContext shc = (ServerHandshakeContext)handshakeContext; ! // Find the Possessions needed ! NamedGroupPossession namedGroupPossession = null; X509Possession x509Possession = null; for (SSLPossession possession : shc.handshakePossessions) { ! if (possession instanceof NamedGroupPossession) { ! namedGroupPossession = (NamedGroupPossession)possession; if (x509Possession != null) { break; } } else if (possession instanceof X509Possession) { x509Possession = (X509Possession)possession; ! if (namedGroupPossession != null) { break; } } } ! if (namedGroupPossession == null) { // unlikely throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER, "No ECDHE credentials negotiated for server key exchange"); } ! // Find the NamedGroup used for the ephemeral keys. ! namedGroup = namedGroupPossession.getNamedGroup(); ! publicPoint = namedGroup.encodePossessionPublicKey( ! namedGroupPossession); if ((namedGroup == null) || (namedGroup.oid == null) ) { // unlikely throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER, ! "Missing Named Group"); } if (x509Possession == null) { // anonymous, no authentication, no signature paramsSignature = null; --- 78,135 ---- private final byte[] publicPoint; // 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; ECDHServerKeyExchangeMessage( HandshakeContext handshakeContext) throws IOException { super(handshakeContext); // This happens in server side only. ServerHandshakeContext shc = (ServerHandshakeContext)handshakeContext; ! ECDHEPossession ecdhePossession = null; X509Possession x509Possession = null; for (SSLPossession possession : shc.handshakePossessions) { ! if (possession instanceof ECDHEPossession) { ! ecdhePossession = (ECDHEPossession)possession; if (x509Possession != null) { break; } } else if (possession instanceof X509Possession) { x509Possession = (X509Possession)possession; ! if (ecdhePossession != null) { break; } } } ! if (ecdhePossession == 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()); + this.namedGroup = NamedGroup.valueOf(params); if ((namedGroup == null) || (namedGroup.oid == null) ) { // unlikely throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER, ! "Unnamed EC parameter spec: " + params); } if (x509Possession == null) { // anonymous, no authentication, no signature paramsSignature = null;
*** 203,229 **** if (!SupportedGroups.isSupported(namedGroup)) { throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER, "Unsupported named group: " + namedGroup); } publicPoint = Record.getBytes8(m); if (publicPoint.length == 0) { throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER, ! "Insufficient Point data: " + namedGroup); } try { ! 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)); } X509Credentials x509Credentials = null; for (SSLCredentials cd : chc.handshakeCredentials) { if (cd instanceof X509Credentials) { x509Credentials = (X509Credentials)cd; break; --- 214,256 ---- if (!SupportedGroups.isSupported(namedGroup)) { throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER, "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); } + 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); } + publicKey = ecPublicKey; + X509Credentials x509Credentials = null; for (SSLCredentials cd : chc.handshakeCredentials) { if (cd instanceof X509Credentials) { x509Credentials = (X509Credentials)cd; break;
*** 500,521 **** public void consume(ConnectionContext context, ByteBuffer message) throws IOException { // 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")) { SSLLogger.fine( "Consuming ECDH ServerKeyExchange handshake message", skem); } // // update // ! chc.handshakeCredentials.add(skem.sslCredentials); // // produce // // Need no new handshake message producers here. --- 527,560 ---- public void consume(ConnectionContext context, ByteBuffer message) throws IOException { // The consuming happens in client side only. ClientHandshakeContext chc = (ClientHandshakeContext)context; ECDHServerKeyExchangeMessage skem = new ECDHServerKeyExchangeMessage(chc, message); if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.fine( "Consuming ECDH ServerKeyExchange handshake message", skem); } // + // 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)); // // produce // // Need no new handshake message producers here.
< prev index next >