8237219: Disable native SunEC implementation by default

Reviewed-by: weijun, mullan
This commit is contained in:
Anthony Scarpino 2020-03-25 12:41:14 -07:00
parent b8f2b3264c
commit b0245c2b54
16 changed files with 160 additions and 62 deletions

View File

@ -284,6 +284,7 @@ module java.base {
exports sun.security.action to
java.desktop,
java.security.jgss,
jdk.crypto.ec,
jdk.incubator.foreign;
exports sun.security.internal.interfaces to
jdk.crypto.cryptoki;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2020, 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
@ -35,7 +35,9 @@ import javax.crypto.*;
import javax.crypto.spec.*;
import sun.security.util.ArrayUtil;
import sun.security.util.CurveDB;
import sun.security.util.ECUtil;
import sun.security.util.NamedCurve;
import sun.security.util.math.*;
import sun.security.ec.point.*;
@ -165,11 +167,24 @@ public final class ECDHKeyAgreement extends KeyAgreementSpi {
if ((privateKey == null) || (publicKey == null)) {
throw new IllegalStateException("Not initialized correctly");
}
byte[] result;
Optional<byte[]> resultOpt = deriveKeyImpl(privateKey, publicKey);
byte[] result = resultOpt.orElseGet(
() -> deriveKeyNative(privateKey, publicKey)
);
if (resultOpt.isPresent()) {
result = resultOpt.get();
} else {
if (SunEC.isNativeDisabled()) {
NamedCurve privNC = CurveDB.lookup(privateKey.getParams());
NamedCurve pubNC = CurveDB.lookup(publicKey.getParams());
throw new IllegalStateException(
new InvalidAlgorithmParameterException("Legacy SunEC " +
"curve disabled, one or both keys: " +
"Private: " + ((privNC != null) ?
privNC.toString() : " unknown") +
", PublicKey:" + ((pubNC != null) ?
pubNC.toString() : " unknown")));
}
result = deriveKeyNative(privateKey, publicKey);
}
publicKey = null;
return result;
}

View File

@ -463,6 +463,14 @@ abstract class ECDSASignature extends SignatureSpi {
if (sigOpt.isPresent()) {
sig = sigOpt.get();
} else {
if (SunEC.isNativeDisabled()) {
NamedCurve nc = CurveDB.lookup(privateKey.getParams());
throw new SignatureException(
new InvalidAlgorithmParameterException(
"Legacy SunEC curve disabled: " +
(nc != null ? nc.toString()
: "unknown")));
}
sig = signDigestNative(privateKey, digest, random);
}
@ -491,6 +499,15 @@ abstract class ECDSASignature extends SignatureSpi {
if (verifyOpt.isPresent()) {
return verifyOpt.get();
} else {
if (SunEC.isNativeDisabled()) {
NamedCurve nc = CurveDB.lookup(publicKey.getParams());
throw new SignatureException(
new InvalidAlgorithmParameterException(
"Legacy SunEC curve disabled: " +
(nc != null ? nc.toString()
: "unknown")));
}
byte[] w;
ECParameterSpec params = publicKey.getParams();
// DER OID

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2020, 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,7 +33,6 @@ import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.*;
import java.util.Optional;
import sun.security.jca.JCAUtil;
@ -121,14 +120,29 @@ public final class ECKeyPairGenerator extends KeyPairGeneratorSpi {
private static void ensureCurveIsSupported(ECParameterSpec ecSpec)
throws InvalidAlgorithmParameterException {
// Check if ecSpec is a valid curve
AlgorithmParameters ecParams = ECUtil.getECParameters(null);
byte[] encodedParams;
try {
ecParams.init(ecSpec);
encodedParams = ecParams.getEncoded();
} catch (InvalidParameterSpecException ex) {
throw new InvalidAlgorithmParameterException(
"Unsupported curve: " + ecSpec.toString());
}
// Check if the java implementation supports this curve
if (ECOperations.forParameters(ecSpec).isPresent()) {
return;
}
// Check if the native library supported this curve, if available
if (SunEC.isNativeDisabled()) {
throw new InvalidAlgorithmParameterException(
"Unsupported curve: " + ecSpec.toString());
}
byte[] encodedParams;
try {
encodedParams = ecParams.getEncoded();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
@ -151,6 +165,14 @@ public final class ECKeyPairGenerator extends KeyPairGeneratorSpi {
if (kp.isPresent()) {
return kp.get();
}
} catch (Exception ex) {
throw new ProviderException(ex);
}
if (SunEC.isNativeDisabled()) {
throw new ProviderException("Legacy SunEC curve disabled: " +
params.toString());
}
try {
return generateKeyPairNative(random);
} catch (Exception ex) {
throw new ProviderException(ex);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2020, 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,8 +25,17 @@
package sun.security.ec;
import java.util.*;
import java.security.*;
import java.security.AccessController;
import java.security.InvalidParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedAction;
import java.security.Provider;
import java.security.ProviderException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;
import sun.security.util.CurveDB;
import sun.security.util.NamedCurve;
@ -53,20 +62,34 @@ public final class SunEC extends Provider {
private static final long serialVersionUID = -2279741672933606418L;
// flag indicating whether the full EC implementation is present
// (when native library is absent then fewer EC algorithms are available)
private static boolean useFullImplementation = true;
// This flag is true if the native library is disabled or not loaded.
private static boolean disableNative = true;
static {
try {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
System.loadLibrary("sunec"); // check for native library
return null;
}
});
} catch (UnsatisfiedLinkError e) {
useFullImplementation = false;
String s = sun.security.action.GetPropertyAction.privilegedGetProperty(
"jdk.sunec.disableNative");
if (s != null && s.equalsIgnoreCase("false")) {
disableNative = false;
}
// If native is enabled, verify the library is available.
if (!disableNative) {
try {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
System.loadLibrary("sunec"); // check for native library
return null;
}
});
} catch (UnsatisfiedLinkError e) {
disableNative = true;
}
}
}
// Check if native library support is disabled.
static boolean isNativeDisabled() {
return SunEC.disableNative;
}
private static class ProviderService extends Provider.Service {
@ -165,13 +188,13 @@ public final class SunEC extends Provider {
"Sun Elliptic Curve provider (EC, ECDSA, ECDH)");
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
putEntries(useFullImplementation);
putEntries();
return null;
}
});
}
void putEntries(boolean useFullImplementation) {
void putEntries() {
HashMap<String, String> ATTRS = new HashMap<>(3);
ATTRS.put("ImplementedIn", "Software");
String ecKeyClasses = "java.security.interfaces.ECPublicKey" +
@ -194,8 +217,16 @@ public final class SunEC extends Provider {
StringBuilder names = new StringBuilder();
Pattern nameSplitPattern = Pattern.compile(CurveDB.SPLIT_PATTERN);
Collection<? extends NamedCurve> supportedCurves =
CurveDB.getSupportedCurves();
Collection<? extends NamedCurve> supportedCurves;
if (SunEC.isNativeDisabled()) {
supportedCurves = Collections.unmodifiableList(List.of(
CurveDB.lookup("secp256r1"),
CurveDB.lookup("secp384r1"),
CurveDB.lookup("secp521r1")));
} else {
supportedCurves = CurveDB.getSupportedCurves();
}
for (NamedCurve namedCurve : supportedCurves) {
if (!firstCurve) {
names.append("|");
@ -225,14 +256,6 @@ public final class SunEC extends Provider {
putXDHEntries();
/*
* Register the algorithms below only when the full ECC implementation
* is available
*/
if (!useFullImplementation) {
return;
}
/*
* Signature engines
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020 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
@ -31,6 +31,8 @@
* this test file was covered before with JDK-4936763.
* @run main/othervm -Djdk.crypto.KeyAgreement.legacyKDF=true KeyAgreementTest
* DiffieHellman DH SunJCE
* @run main/othervm -Djdk.sunec.disableNative=false KeyAgreementTest
* ECDHNative EC SunEC
* @run main KeyAgreementTest ECDH EC SunEC
* @run main KeyAgreementTest XDH XDH SunEC
*/
@ -52,7 +54,12 @@ public class KeyAgreementTest {
String kaAlgo = args[0];
String kpgAlgo = args[1];
String provider = args[2];
System.out.println("Testing " + kaAlgo);
AlgoSpec aSpec = AlgoSpec.valueOf(AlgoSpec.class, kaAlgo);
// Switch kaAlgo to ECDH as it is used for algorithm names
if (kaAlgo.equals("ECDHNative")) {
kaAlgo = "ECDH";
}
List<AlgorithmParameterSpec> specs = aSpec.getAlgorithmParameterSpecs();
for (AlgorithmParameterSpec spec : specs) {
testKeyAgreement(provider, kaAlgo, kpgAlgo, spec);
@ -69,7 +76,7 @@ public class KeyAgreementTest {
// "java.base/share/classes/sun/security/util/CurveDB.java"
// and
// "jdk.crypto.ec/share/native/libsunec/impl/ecdecode.c"
ECDH(
ECDHNative(
// SEC2 prime curves
"secp112r1", "secp112r2", "secp128r1", "secp128r2", "secp160k1",
"secp160r1", "secp192k1", "secp192r1", "secp224k1", "secp224r1",
@ -87,6 +94,7 @@ public class KeyAgreementTest {
"X9.62 c2tnb239v1", "X9.62 c2tnb239v2", "X9.62 c2tnb239v3",
"X9.62 c2tnb359v1", "X9.62 c2tnb431r1"
),
ECDH("secp256r1", "secp384r1", "secp521r1"),
XDH("X25519", "X448", "x25519"),
// There is no curve for DiffieHellman
DiffieHellman(new String[]{});
@ -97,6 +105,7 @@ public class KeyAgreementTest {
// Generate AlgorithmParameterSpec for each KeyExchangeAlgorithm
for (String crv : curves) {
switch (this.name()) {
case "ECDHNative":
case "ECDH":
specs.add(new ECGenParameterSpec(crv));
break;
@ -126,6 +135,13 @@ public class KeyAgreementTest {
KeyPairGenerator kpg = KeyPairGenerator.getInstance(kpgAlgo, provider);
kpg.initialize(spec);
if (spec instanceof ECGenParameterSpec) {
System.out.println("Testing curve: " +
((ECGenParameterSpec)spec).getName());
} else if (spec instanceof NamedParameterSpec) {
System.out.println("Testing curve: " +
((NamedParameterSpec)spec).getName());
}
KeyPair kp1 = kpg.generateKeyPair();
KeyPair kp2 = kpg.generateKeyPair();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020, 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
@ -37,9 +37,9 @@
* @run main KeySizeTest DiffieHellman SunJCE DiffieHellman 4096
* @run main KeySizeTest DiffieHellman SunJCE DiffieHellman 6144
* @run main KeySizeTest DiffieHellman SunJCE DiffieHellman 8192
* @run main KeySizeTest ECDH SunEC EC 128
* @run main KeySizeTest ECDH SunEC EC 192
* @run main KeySizeTest ECDH SunEC EC 256
* @run main/othervm -Djdk.sunec.disableNative=false KeySizeTest ECDH SunEC EC 128
* @run main/othervm -Djdk.sunec.disableNative=false KeySizeTest ECDH SunEC EC 192
* @run main/othervm KeySizeTest ECDH SunEC EC 256
* @run main KeySizeTest XDH SunEC XDH 255
* @run main KeySizeTest XDH SunEC XDH 448
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2020, 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
@ -31,7 +31,7 @@
* jdk.jartool
* jdk.crypto.ec
* @build jdk.test.lib.util.JarUtils
* @run main Spec
* @run main/othervm -Djdk.sunec.disableNative=false Spec
*/
import com.sun.jarsigner.ContentSigner;

View File

@ -100,7 +100,8 @@ public class ECDSAJavaVerify {
= launchingConnector.defaultArguments();
arguments.get("main").setValue(ECDSAJavaVerify.class.getName());
arguments.get("options").setValue(
"-cp " + System.getProperty("test.classes"));
"-cp " + System.getProperty("test.classes") +
" -Djdk.sunec.disableNative=false");
VirtualMachine vm = launchingConnector.launch(arguments);
MethodEntryRequest req = vm.eventRequestManager()

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2020, 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,7 +25,7 @@
* @test
* @bug 8182999
* @summary Ensure that SunEC behaves correctly for unsupported curves.
* @run main InvalidCurve
* @run main/othervm -Djdk.sunec.disableNative=false InvalidCurve
*/
import java.security.*;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, 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
@ -36,7 +36,7 @@ import java.util.*;
* group order.
* @library /test/lib
* @build jdk.test.lib.Convert
* @run main SignatureDigestTruncate
* @run main/othervm -Djdk.sunec.disableNative=false SignatureDigestTruncate
*/
public class SignatureDigestTruncate {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2020, 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
@ -37,8 +37,8 @@
* @library ../../../java/security/testlibrary
* @library ../../../javax/net/ssl/TLSCommon
* @modules jdk.crypto.cryptoki/sun.security.pkcs11.wrapper
* @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1" TestEC
* @run main/othervm/java.security.policy=TestEC.policy -Djdk.tls.namedGroups="secp256r1,sect193r1" TestEC
* @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1" -Djdk.sunec.disableNative=false TestEC
* @run main/othervm -Djava.security.policy=TestEC.policy -Djdk.tls.namedGroups="secp256r1,sect193r1" -Djdk.sunec.disableNative=false TestEC
*/
import java.security.NoSuchProviderException;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2020, 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
@ -30,8 +30,8 @@
* @library ../../../../java/security/testlibrary
* @key randomness
* @modules jdk.crypto.cryptoki
* @run main/othervm ReadPKCS12
* @run main/othervm ReadPKCS12 sm policy
* @run main/othervm -Djdk.sunec.disableNative=false ReadPKCS12
* @run main/othervm -Djdk.sunec.disableNative=false ReadPKCS12 sm policy
*/
import java.io.BufferedReader;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020, 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
@ -65,7 +65,7 @@ public class GroupName {
.shouldNotContain("Specifying -keysize for generating EC keys is deprecated");
checkCurveName("e", "secp256r1");
gen("f", "-keyalg EC -groupname brainpoolP256r1")
gen("f", "-J-Djdk.sunec.disableNative=false -keyalg EC -groupname brainpoolP256r1")
.shouldHaveExitValue(0)
.shouldNotContain("Specifying -keysize for generating EC keys is deprecated");
checkCurveName("f", "brainpoolP256r1");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2020, 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
@ -41,7 +41,9 @@ public class KeyAlg {
keytool("-printcert -file user.crt")
.shouldMatch("Signature algorithm name:.*SHA1withECDSA")
.shouldMatch("Subject Public Key Algorithm:.*1024.*RSA");
keytool("-genkeypair -alias e -dname CN=e -keyalg EC -groupname brainpoolP256r1")
keytool("-genkeypair -alias e -dname CN=e " +
"-J-Djdk.sunec.disableNative=false -keyalg EC " +
"-groupname brainpoolP256r1")
.shouldContain("Generating 256 bit EC (brainpoolP256r1) key pair");
keytool("-genkeypair -alias f -dname CN=f -keyalg EC")
.shouldContain("Generating 256 bit EC (secp256r1) key pair");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, 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,12 +87,13 @@ public class DefaultSignatureAlgorithm {
static OutputAnalyzer genkeypair(String alias, String options)
throws Exception {
String patchArg = "-J--patch-module=java.base="
String patchArg = "-J-Djdk.sunec.disableNative=false " +
"-J--patch-module=java.base="
+ System.getProperty("test.classes")
+ File.separator + "patches" + File.separator + "java.base"
+ " -J--patch-module=jdk.crypto.ec="
+ System.getProperty("test.classes")
+ File.separator + "patches" + File.separator + "jdk.crypto.ec";;
+ File.separator + "patches" + File.separator + "jdk.crypto.ec";
return kt(patchArg + " -genkeypair -alias " + alias
+ " -dname CN=" + alias + " " + options);
}