--- a/jdk/make/mapfiles/libsunec/mapfile-vers Wed Jul 12 14:30:00 2017 -0700
+++ b/jdk/make/mapfiles/libsunec/mapfile-vers Thu Jul 13 12:24:55 2017 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2017, 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
@@ -27,6 +27,7 @@
SUNWprivate_1.1 {
global:
+ Java_sun_security_ec_ECKeyPairGenerator_isCurveSupported;
Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair;
Java_sun_security_ec_ECDSASignature_signDigest;
Java_sun_security_ec_ECDSASignature_verifySignedDigest;
--- a/jdk/src/java.base/share/classes/sun/security/util/ECUtil.java Wed Jul 12 14:30:00 2017 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/util/ECUtil.java Thu Jul 13 12:24:55 2017 +0100
@@ -130,7 +130,7 @@
return (ECPrivateKey)keyFactory.generatePrivate(keySpec);
}
- private static AlgorithmParameters getECParameters(Provider p) {
+ public static AlgorithmParameters getECParameters(Provider p) {
try {
if (p != null) {
return AlgorithmParameters.getInstance("EC", p);
--- a/jdk/src/jdk.crypto.ec/share/classes/sun/security/ec/ECKeyPairGenerator.java Wed Jul 12 14:30:00 2017 -0700
+++ b/jdk/src/jdk.crypto.ec/share/classes/sun/security/ec/ECKeyPairGenerator.java Thu Jul 13 12:24:55 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, 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
@@ -25,12 +25,14 @@
package sun.security.ec;
+import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
+import java.security.spec.InvalidParameterSpecException;
import sun.security.ec.ECPrivateKeyImpl;
import sun.security.ec.ECPublicKeyImpl;
@@ -85,17 +87,19 @@
public void initialize(AlgorithmParameterSpec params, SecureRandom random)
throws InvalidAlgorithmParameterException {
+ ECParameterSpec ecSpec = null;
+
if (params instanceof ECParameterSpec) {
- this.params = ECUtil.getECParameterSpec(null,
+ ecSpec = ECUtil.getECParameterSpec(null,
(ECParameterSpec)params);
- if (this.params == null) {
+ if (ecSpec == null) {
throw new InvalidAlgorithmParameterException(
"Unsupported curve: " + params);
}
} else if (params instanceof ECGenParameterSpec) {
String name = ((ECGenParameterSpec)params).getName();
- this.params = ECUtil.getECParameterSpec(null, name);
- if (this.params == null) {
+ ecSpec = ECUtil.getECParameterSpec(null, name);
+ if (ecSpec == null) {
throw new InvalidAlgorithmParameterException(
"Unknown curve name: " + name);
}
@@ -103,11 +107,36 @@
throw new InvalidAlgorithmParameterException(
"ECParameterSpec or ECGenParameterSpec required for EC");
}
+
+ // Not all known curves are supported by the native implementation
+ ensureCurveIsSupported(ecSpec);
+ this.params = ecSpec;
+
this.keySize =
((ECParameterSpec)this.params).getCurve().getField().getFieldSize();
this.random = random;
}
+ private static void ensureCurveIsSupported(ECParameterSpec ecSpec)
+ throws InvalidAlgorithmParameterException {
+
+ AlgorithmParameters ecParams = ECUtil.getECParameters(null);
+ byte[] encodedParams;
+ try {
+ ecParams.init(ecSpec);
+ encodedParams = ecParams.getEncoded();
+ } catch (InvalidParameterSpecException ex) {
+ throw new InvalidAlgorithmParameterException(
+ "Unsupported curve: " + ecSpec.toString());
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ if (!isCurveSupported(encodedParams)) {
+ throw new InvalidAlgorithmParameterException(
+ "Unsupported curve: " + ecParams.toString());
+ }
+ }
+
// generate the keypair. See JCA doc
@Override
public KeyPair generateKeyPair() {
@@ -159,6 +188,17 @@
this.keySize = keySize;
}
+ /**
+ * Checks whether the curve in the encoded parameters is supported by the
+ * native implementation.
+ *
+ * @param encodedParams encoded parameters in the same form accepted
+ * by generateECKeyPair
+ * @return true if and only if generateECKeyPair will succeed for
+ * the supplied parameters
+ */
+ private static native boolean isCurveSupported(byte[] encodedParams);
+
/*
* Generates the keypair and returns a 2-element array of encoding bytes.
* The first one is for the private key, the second for the public key.
--- a/jdk/src/jdk.crypto.ec/share/native/libsunec/ECC_JNI.cpp Wed Jul 12 14:30:00 2017 -0700
+++ b/jdk/src/jdk.crypto.ec/share/native/libsunec/ECC_JNI.cpp Thu Jul 13 12:24:55 2017 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, 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
@@ -90,6 +90,50 @@
/*
* Class: sun_security_ec_ECKeyPairGenerator
+ * Method: isCurveSupported
+ * Signature: ([B)Z
+ */
+JNIEXPORT jboolean
+JNICALL Java_sun_security_ec_ECKeyPairGenerator_isCurveSupported
+ (JNIEnv *env, jclass clazz, jbyteArray encodedParams)
+{
+ SECKEYECParams params_item;
+ ECParams *ecparams = NULL;
+ jboolean result = JNI_FALSE;
+
+ // The curve is supported if we can get parameters for it
+ params_item.len = env->GetArrayLength(encodedParams);
+ params_item.data =
+ (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
+ if (params_item.data == NULL) {
+ goto cleanup;
+ }
+
+ // Fill a new ECParams using the supplied OID
+ if (EC_DecodeParams(¶ms_item, &ecparams, 0) != SECSuccess) {
+ /* bad curve OID */
+ goto cleanup;
+ }
+
+ // If we make it to here, then the curve is supported
+ result = JNI_TRUE;
+
+cleanup:
+ {
+ if (params_item.data) {
+ env->ReleaseByteArrayElements(encodedParams,
+ (jbyte *) params_item.data, JNI_ABORT);
+ }
+ if (ecparams) {
+ FreeECParams(ecparams, true);
+ }
+ }
+
+ return result;
+}
+
+/*
+ * Class: sun_security_ec_ECKeyPairGenerator
* Method: generateECKeyPair
* Signature: (I[B[B)[[B
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ec/InvalidCurve.java Thu Jul 13 12:24:55 2017 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8182999
+ * @summary Ensure that SunEC behaves correctly for unsupported curves.
+ * @run main InvalidCurve
+ */
+
+import java.security.*;
+import java.security.spec.*;
+import java.math.*;
+
+public class InvalidCurve {
+
+ public static void main(String[] args) {
+
+ KeyPairGenerator keyGen;
+ try {
+ keyGen = KeyPairGenerator.getInstance("EC", "SunEC");
+ ECGenParameterSpec brainpoolSpec =
+ new ECGenParameterSpec("brainpoolP256r1");
+ keyGen.initialize(brainpoolSpec);
+ } catch (InvalidAlgorithmParameterException ex) {
+ System.out.println(ex.getMessage());
+ // this is expected
+ return;
+ } catch (NoSuchAlgorithmException | NoSuchProviderException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ keyGen.generateKeyPair();
+
+ // If we make it to here, then the test is not working correctly.
+ throw new RuntimeException("The expected exception was not thrown.");
+
+ }
+
+}
+