8076328: Enforce key exchange constraints
Reviewed-by: wetmore, igerasim, ahgross, asmotrak
--- a/jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java Tue Apr 21 20:33:34 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java Wed Apr 22 05:09:54 2015 +0000
@@ -723,6 +723,14 @@
// NOTREACHED
}
ephemeralServerKey = mesg.getPublicKey();
+
+ // check constraints of RSA PublicKey
+ if (!algorithmConstraints.permits(
+ EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), ephemeralServerKey)) {
+
+ throw new SSLHandshakeException("RSA ServerKeyExchange " +
+ "does not comply to algorithm constraints");
+ }
}
/*
@@ -739,6 +747,9 @@
dh = new DHCrypt(mesg.getModulus(), mesg.getBase(),
sslContext.getSecureRandom());
serverDH = mesg.getServerPublicKey();
+
+ // check algorithm constraints
+ dh.checkConstraints(algorithmConstraints, serverDH);
}
private void serverKeyExchange(ECDH_ServerKeyExchange mesg)
@@ -749,6 +760,14 @@
ECPublicKey key = mesg.getPublicKey();
ecdh = new ECDHCrypt(key.getParams(), sslContext.getSecureRandom());
ephemeralServerKey = key;
+
+ // check constraints of EC PublicKey
+ if (!algorithmConstraints.permits(
+ EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), ephemeralServerKey)) {
+
+ throw new SSLHandshakeException("ECDH ServerKeyExchange " +
+ "does not comply to algorithm constraints");
+ }
}
/*
--- a/jdk/src/java.base/share/classes/sun/security/ssl/DHCrypt.java Tue Apr 21 20:33:34 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/DHCrypt.java Wed Apr 22 05:09:54 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@
import javax.crypto.KeyAgreement;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.*;
+import java.util.EnumSet;
import sun.security.util.KeyUtil;
@@ -216,6 +217,28 @@
}
}
+ // Check constraints of the specified DH public key.
+ void checkConstraints(AlgorithmConstraints constraints,
+ BigInteger peerPublicValue) throws SSLHandshakeException {
+
+ try {
+ KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman");
+ DHPublicKeySpec spec =
+ new DHPublicKeySpec(peerPublicValue, modulus, base);
+ DHPublicKey publicKey = (DHPublicKey)kf.generatePublic(spec);
+
+ // check constraints of DHPublicKey
+ if (!constraints.permits(
+ EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), publicKey)) {
+ throw new SSLHandshakeException(
+ "DHPublicKey does not comply to algorithm constraints");
+ }
+ } catch (GeneralSecurityException gse) {
+ throw (SSLHandshakeException) new SSLHandshakeException(
+ "Could not generate DHPublicKey").initCause(gse);
+ }
+ }
+
// Generate and validate DHPublicKeySpec
private DHPublicKeySpec generateDHPublicKeySpec(KeyPairGenerator kpg)
throws GeneralSecurityException {
--- a/jdk/src/java.base/share/classes/sun/security/ssl/ECDHCrypt.java Tue Apr 21 20:33:34 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ECDHCrypt.java Wed Apr 22 05:09:54 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
import java.security.interfaces.ECPublicKey;
import java.security.spec.*;
+import java.util.EnumSet;
import javax.crypto.SecretKey;
import javax.crypto.KeyAgreement;
import javax.net.ssl.SSLHandshakeException;
@@ -88,8 +89,11 @@
return publicKey;
}
- // called by ClientHandshaker with either the server's static or ephemeral public key
- SecretKey getAgreedSecret(PublicKey peerPublicKey) throws SSLHandshakeException {
+ // called by ClientHandshaker with either the server's static or
+ // ephemeral public key
+ SecretKey getAgreedSecret(
+ PublicKey peerPublicKey) throws SSLHandshakeException {
+
try {
KeyAgreement ka = JsseJce.getKeyAgreement("ECDH");
ka.init(privateKey);
@@ -102,10 +106,13 @@
}
// called by ServerHandshaker
- SecretKey getAgreedSecret(byte[] encodedPoint) throws SSLHandshakeException {
+ SecretKey getAgreedSecret(
+ byte[] encodedPoint) throws SSLHandshakeException {
+
try {
ECParameterSpec params = publicKey.getParams();
- ECPoint point = JsseJce.decodePoint(encodedPoint, params.getCurve());
+ ECPoint point =
+ JsseJce.decodePoint(encodedPoint, params.getCurve());
KeyFactory kf = JsseJce.getKeyFactory("EC");
ECPublicKeySpec spec = new ECPublicKeySpec(point, params);
PublicKey peerPublicKey = kf.generatePublic(spec);
@@ -116,4 +123,30 @@
}
}
+ // Check constraints of the specified EC public key.
+ void checkConstraints(AlgorithmConstraints constraints,
+ byte[] encodedPoint) throws SSLHandshakeException {
+
+ try {
+
+ ECParameterSpec params = publicKey.getParams();
+ ECPoint point =
+ JsseJce.decodePoint(encodedPoint, params.getCurve());
+ ECPublicKeySpec spec = new ECPublicKeySpec(point, params);
+
+ KeyFactory kf = JsseJce.getKeyFactory("EC");
+ ECPublicKey publicKey = (ECPublicKey)kf.generatePublic(spec);
+
+ // check constraints of ECPublicKey
+ if (!constraints.permits(
+ EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), publicKey)) {
+ throw new SSLHandshakeException(
+ "ECPublicKey does not comply to algorithm constraints");
+ }
+ } catch (GeneralSecurityException | java.io.IOException e) {
+ throw (SSLHandshakeException) new SSLHandshakeException(
+ "Could not generate ECPublicKey").initCause(e);
+ }
+ }
+
}
--- a/jdk/src/java.base/share/classes/sun/security/ssl/Handshaker.java Tue Apr 21 20:33:34 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/Handshaker.java Wed Apr 22 05:09:54 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -87,7 +87,7 @@
String identificationProtocol;
// The cryptographic algorithm constraints
- private AlgorithmConstraints algorithmConstraints = null;
+ AlgorithmConstraints algorithmConstraints = null;
// Local supported signature and algorithms
Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs;
--- a/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java Tue Apr 21 20:33:34 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java Wed Apr 22 05:09:54 2015 +0000
@@ -32,6 +32,7 @@
import java.security.cert.*;
import java.security.interfaces.*;
import java.security.spec.ECParameterSpec;
+import java.math.BigInteger;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
@@ -1571,7 +1572,13 @@
if (debug != null && Debug.isOn("handshake")) {
mesg.print(System.out);
}
- return dh.getAgreedSecret(mesg.getClientPublicKey(), false);
+
+ BigInteger publicKeyValue = mesg.getClientPublicKey();
+
+ // check algorithm constraints
+ dh.checkConstraints(algorithmConstraints, publicKeyValue);
+
+ return dh.getAgreedSecret(publicKeyValue, false);
}
private SecretKey clientKeyExchange(ECDHClientKeyExchange mesg)
@@ -1580,7 +1587,13 @@
if (debug != null && Debug.isOn("handshake")) {
mesg.print(System.out);
}
- return ecdh.getAgreedSecret(mesg.getEncodedPoint());
+
+ byte[] publicPoint = mesg.getEncodedPoint();
+
+ // check algorithm constraints
+ ecdh.checkConstraints(algorithmConstraints, publicPoint);
+
+ return ecdh.getAgreedSecret(publicPoint);
}
/*
--- a/jdk/src/java.base/share/conf/security/java.security Tue Apr 21 20:33:34 2015 +0100
+++ b/jdk/src/java.base/share/conf/security/java.security Wed Apr 22 05:09:54 2015 +0000
@@ -541,7 +541,7 @@
#
# Example:
# jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
-jdk.tls.disabledAlgorithms=SSLv3, RC4
+jdk.tls.disabledAlgorithms=SSLv3, RC4, DH keySize < 768
# Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
# processing in JSSE implementation.
@@ -580,7 +580,7 @@
# 1. JSSE cipher suite name, e.g., TLS_RSA_WITH_AES_128_CBC_SHA
# 2. JSSE key exchange algorithm name, e.g., RSA
# 3. JSSE cipher (encryption) algorithm name, e.g., AES_128_CBC
-# 4. JSSE message digest algorithm name, e.g., SHA-1
+# 4. JSSE message digest algorithm name, e.g., SHA
#
# See SSL/TLS specifications and "Java Cryptography Architecture Standard
# Algorithm Name Documentation" for information about the algorithm names.
@@ -598,4 +598,4 @@
DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \
DH_RSA_EXPORT, RSA_EXPORT, \
DH_anon, ECDH_anon, \
- RC4_128, RC4_40, DES_CBC, DES40_CBC
\ No newline at end of file
+ RC4_128, RC4_40, DES_CBC, DES40_CBC
--- a/jdk/test/javax/net/ssl/sanity/interop/ClientJSSEServerJSSE.java Tue Apr 21 20:33:34 2015 +0100
+++ b/jdk/test/javax/net/ssl/sanity/interop/ClientJSSEServerJSSE.java Wed Apr 22 05:09:54 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,13 +33,10 @@
public class ClientJSSEServerJSSE {
public static void main(String[] args) throws Exception {
- // reset the security property to make sure that the algorithms
+ // reset security properties to make sure that the algorithms
// and keys used in this test are not disabled.
Security.setProperty("jdk.tls.disabledAlgorithms", "");
-
- // MD5 is used in this test case, don't disable MD5 algorithm.
- Security.setProperty(
- "jdk.certpath.disabledAlgorithms", "MD2, RSA keySize < 1024");
+ Security.setProperty("jdk.certpath.disabledAlgorithms", "");
CipherTest.main(new JSSEFactory(), args);
}
--- a/jdk/test/sun/security/ec/TestEC.java Tue Apr 21 20:33:34 2015 +0100
+++ b/jdk/test/sun/security/ec/TestEC.java Wed Apr 22 05:09:54 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -60,13 +60,10 @@
public class TestEC {
public static void main(String[] args) throws Exception {
- // reset the security property to make sure that the algorithms
+ // reset security properties to make sure that the algorithms
// and keys used in this test are not disabled.
Security.setProperty("jdk.tls.disabledAlgorithms", "");
-
- // MD5 is used in this test case, don't disable MD5 algorithm.
- Security.setProperty(
- "jdk.certpath.disabledAlgorithms", "MD2, RSA keySize < 1024");
+ Security.setProperty("jdk.certpath.disabledAlgorithms", "");
ProvidersSnapshot snapshot = ProvidersSnapshot.create();
try {
--- a/jdk/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java Tue Apr 21 20:33:34 2015 +0100
+++ b/jdk/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java Wed Apr 22 05:09:54 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,18 +43,15 @@
private static String[] cmdArgs;
public static void main(String[] args) throws Exception {
- // reset the security property to make sure that the algorithms
- // and keys used in this test are not disabled.
- Security.setProperty("jdk.tls.disabledAlgorithms", "");
-
cmdArgs = args;
main(new ClientJSSEServerJSSE());
}
public void main(Provider p) throws Exception {
- // MD5 is used in this test case, don't disable MD5 algorithm.
- Security.setProperty(
- "jdk.certpath.disabledAlgorithms", "MD2, RSA keySize < 1024");
+ // reset security properties to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+ Security.setProperty("jdk.certpath.disabledAlgorithms", "");
if (p.getService("KeyFactory", "EC") == null) {
System.out.println("Provider does not support EC, skipping");
--- a/jdk/test/sun/security/ssl/DHKeyExchange/DHEKeySizing.java Tue Apr 21 20:33:34 2015 +0100
+++ b/jdk/test/sun/security/ssl/DHKeyExchange/DHEKeySizing.java Wed Apr 22 05:09:54 2015 +0000
@@ -377,9 +377,10 @@
}
public static void main(String args[]) throws Exception {
- // reset the security property to make sure that the algorithms
+ // reset security properties to make sure that the algorithms
// and keys used in this test are not disabled.
Security.setProperty("jdk.tls.disabledAlgorithms", "");
+ Security.setProperty("jdk.certpath.disabledAlgorithms", "");
if (args.length != 4) {
System.out.println(
--- a/jdk/test/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java Tue Apr 21 20:33:34 2015 +0100
+++ b/jdk/test/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java Wed Apr 22 05:09:54 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,19 +21,22 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 4392475
* @summary Calling setWantClientAuth(true) disables anonymous suites
* @run main/othervm/timeout=180 AnonCipherWithWantClientAuth
- *
- * SunJSSE does not support dynamic system properties, no way to re-use
- * system properties in samevm/agentvm mode.
*/
import java.io.*;
import java.net.*;
import javax.net.ssl.*;
+import java.security.Security;
public class AnonCipherWithWantClientAuth {
@@ -156,6 +159,11 @@
volatile Exception clientException = null;
public static void main(String[] args) throws Exception {
+ // reset security properties to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+ Security.setProperty("jdk.certpath.disabledAlgorithms", "");
+
String keyFilename =
System.getProperty("test.src", "./") + "/" + pathToStores +
"/" + keyStoreFile;