diff --git a/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java b/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java index b974c3ca86cc4b505e04efd6c2ebd98436c9a00f..552a15d82e5ea0d7b26e870086b74e5ec524ef57 100644 --- a/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java +++ b/src/share/classes/sun/security/ec/ECPrivateKeyImpl.java @@ -69,7 +69,7 @@ public final class ECPrivateKeyImpl extends PKCS8Key implements ECPrivateKey { /** * Construct a key from its encoding. Called by the ECKeyFactory. */ - ECPrivateKeyImpl(byte[] encoded) throws InvalidKeyException { + public ECPrivateKeyImpl(byte[] encoded) throws InvalidKeyException { decode(encoded); } @@ -77,7 +77,7 @@ public final class ECPrivateKeyImpl extends PKCS8Key implements ECPrivateKey { * Construct a key from its components. Used by the * KeyFactory. */ - ECPrivateKeyImpl(BigInteger s, ECParameterSpec params) + public ECPrivateKeyImpl(BigInteger s, ECParameterSpec params) throws InvalidKeyException { this.s = s; this.params = params; diff --git a/src/share/classes/sun/security/ec/ECPublicKeyImpl.java b/src/share/classes/sun/security/ec/ECPublicKeyImpl.java index 0e82e734e4aed479d8f6a8f692f85c177749b06e..8bc51f4b5e25085bf23f0ce74bf4bf590bbc418b 100644 --- a/src/share/classes/sun/security/ec/ECPublicKeyImpl.java +++ b/src/share/classes/sun/security/ec/ECPublicKeyImpl.java @@ -52,7 +52,7 @@ public final class ECPublicKeyImpl extends X509Key implements ECPublicKey { * ECKeyFactory. */ @SuppressWarnings("deprecation") - ECPublicKeyImpl(ECPoint w, ECParameterSpec params) + public ECPublicKeyImpl(ECPoint w, ECParameterSpec params) throws InvalidKeyException { this.w = w; this.params = params; @@ -65,7 +65,7 @@ public final class ECPublicKeyImpl extends X509Key implements ECPublicKey { /** * Construct a key from its encoding. */ - ECPublicKeyImpl(byte[] encoded) throws InvalidKeyException { + public ECPublicKeyImpl(byte[] encoded) throws InvalidKeyException { decode(encoded); } diff --git a/src/share/classes/sun/security/pkcs11/P11ECKeyFactory.java b/src/share/classes/sun/security/pkcs11/P11ECKeyFactory.java index 257164ab60f18a5e7f831e8e3ba8f88977c1a96d..494ab00f0d5ece874fb5ee5123ead763d233bf3b 100644 --- a/src/share/classes/sun/security/pkcs11/P11ECKeyFactory.java +++ b/src/share/classes/sun/security/pkcs11/P11ECKeyFactory.java @@ -116,7 +116,7 @@ final class P11ECKeyFactory extends P11KeyFactory { byte[] encoded = key.getEncoded(); try { - key = ECUtil.decodeX509ECPublicKey(encoded); + key = P11ECUtil.decodeX509ECPublicKey(encoded); } catch (InvalidKeySpecException ikse) { throw new InvalidKeyException(ikse); } @@ -145,7 +145,7 @@ final class P11ECKeyFactory extends P11KeyFactory { byte[] encoded = key.getEncoded(); try { - key = ECUtil.decodePKCS8ECPrivateKey(encoded); + key = P11ECUtil.decodePKCS8ECPrivateKey(encoded); } catch (InvalidKeySpecException ikse) { throw new InvalidKeyException(ikse); } @@ -167,7 +167,7 @@ final class P11ECKeyFactory extends P11KeyFactory { if (keySpec instanceof X509EncodedKeySpec) { try { byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded(); - PublicKey key = ECUtil.decodeX509ECPublicKey(encoded); + PublicKey key = P11ECUtil.decodeX509ECPublicKey(encoded); return implTranslatePublicKey(key); } catch (InvalidKeyException e) { throw new InvalidKeySpecException @@ -197,7 +197,7 @@ final class P11ECKeyFactory extends P11KeyFactory { if (keySpec instanceof PKCS8EncodedKeySpec) { try { byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded(); - PrivateKey key = ECUtil.decodePKCS8ECPrivateKey(encoded); + PrivateKey key = P11ECUtil.decodePKCS8ECPrivateKey(encoded); return implTranslatePrivateKey(key); } catch (GeneralSecurityException e) { throw new InvalidKeySpecException diff --git a/src/share/classes/sun/security/pkcs11/P11ECUtil.java b/src/share/classes/sun/security/pkcs11/P11ECUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..35ff32611a2f97e4f8fdfeb40bbac21067ad63c0 --- /dev/null +++ b/src/share/classes/sun/security/pkcs11/P11ECUtil.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package sun.security.pkcs11; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.*; +import java.security.interfaces.*; +import java.security.spec.*; + +import sun.security.ec.ECPublicKeyImpl; +import sun.security.ec.ECPrivateKeyImpl; +import sun.security.x509.X509Key; + +final class P11ECUtil { + + static ECPublicKey decodeX509ECPublicKey(byte[] encoded) + throws InvalidKeySpecException { + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded); + + return (ECPublicKey)ECGeneratePublic(keySpec); + } + + static byte[] x509EncodeECPublicKey(ECPoint w, + ECParameterSpec params) throws InvalidKeySpecException { + ECPublicKeySpec keySpec = new ECPublicKeySpec(w, params); + X509Key key = (X509Key)ECGeneratePublic(keySpec); + + return key.getEncoded(); + } + + static ECPrivateKey decodePKCS8ECPrivateKey(byte[] encoded) + throws InvalidKeySpecException { + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded); + + return (ECPrivateKey)ECGeneratePrivate(keySpec); + } + + static ECPrivateKey generateECPrivateKey(BigInteger s, + ECParameterSpec params) throws InvalidKeySpecException { + ECPrivateKeySpec keySpec = new ECPrivateKeySpec(s, params); + + return (ECPrivateKey)ECGeneratePrivate(keySpec); + } + + private static PublicKey ECGeneratePublic(KeySpec keySpec) + throws InvalidKeySpecException { + try { + if (keySpec instanceof X509EncodedKeySpec) { + X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec; + return new ECPublicKeyImpl(x509Spec.getEncoded()); + } else if (keySpec instanceof ECPublicKeySpec) { + ECPublicKeySpec ecSpec = (ECPublicKeySpec)keySpec; + return new ECPublicKeyImpl( + ecSpec.getW(), + ecSpec.getParams() + ); + } else { + throw new InvalidKeySpecException("Only ECPublicKeySpec " + + "and X509EncodedKeySpec supported for EC public keys"); + } + } catch (InvalidKeySpecException e) { + throw e; + } catch (GeneralSecurityException e) { + throw new InvalidKeySpecException(e); + } + } + + private static PrivateKey ECGeneratePrivate(KeySpec keySpec) + throws InvalidKeySpecException { + try { + if (keySpec instanceof PKCS8EncodedKeySpec) { + PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec; + return new ECPrivateKeyImpl(pkcsSpec.getEncoded()); + } else if (keySpec instanceof ECPrivateKeySpec) { + ECPrivateKeySpec ecSpec = (ECPrivateKeySpec)keySpec; + return new ECPrivateKeyImpl(ecSpec.getS(), ecSpec.getParams()); + } else { + throw new InvalidKeySpecException("Only ECPrivateKeySpec " + + "and PKCS8EncodedKeySpec supported for EC private keys"); + } + } catch (InvalidKeySpecException e) { + throw e; + } catch (GeneralSecurityException e) { + throw new InvalidKeySpecException(e); + } + } + + private P11ECUtil() {} + +} diff --git a/src/share/classes/sun/security/pkcs11/P11Key.java b/src/share/classes/sun/security/pkcs11/P11Key.java index 235c1488a4457ff5eeddee2c4b13b07680c90ce1..bfca0fdcb61d5cf55171ec5d669c630d63b385e9 100644 --- a/src/share/classes/sun/security/pkcs11/P11Key.java +++ b/src/share/classes/sun/security/pkcs11/P11Key.java @@ -47,7 +47,6 @@ import static sun.security.pkcs11.wrapper.PKCS11Constants.*; import sun.security.util.DerValue; import sun.security.util.Length; -import sun.security.util.ECUtil; /** * Key implementation classes. @@ -993,7 +992,7 @@ abstract class P11Key implements Key, Length { if (encoded == null) { fetchValues(); try { - Key key = ECUtil.generateECPrivateKey(s, params); + Key key = P11ECUtil.generateECPrivateKey(s, params); encoded = key.getEncoded(); } catch (InvalidKeySpecException e) { throw new ProviderException(e); @@ -1067,7 +1066,7 @@ abstract class P11Key implements Key, Length { if (encoded == null) { fetchValues(); try { - return ECUtil.x509EncodeECPublicKey(w, params); + return P11ECUtil.x509EncodeECPublicKey(w, params); } catch (InvalidKeySpecException e) { throw new ProviderException(e); } diff --git a/src/share/classes/sun/security/util/ECUtil.java b/src/share/classes/sun/security/util/ECUtil.java index dc6b02be611a3c09d1b712df639151db5ba10c60..8bdc575fbb6a497a6ec6efc3b3fd6bcf048c53bf 100644 --- a/src/share/classes/sun/security/util/ECUtil.java +++ b/src/share/classes/sun/security/util/ECUtil.java @@ -89,47 +89,6 @@ public class ECUtil { return Arrays.copyOfRange(b, i, b.length); } - private static KeyFactory getKeyFactory() { - try { - return KeyFactory.getInstance("EC", "SunEC"); - } catch (NoSuchAlgorithmException | NoSuchProviderException e) { - throw new RuntimeException(e); - } - } - - public static ECPublicKey decodeX509ECPublicKey(byte[] encoded) - throws InvalidKeySpecException { - KeyFactory keyFactory = getKeyFactory(); - X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded); - - return (ECPublicKey)keyFactory.generatePublic(keySpec); - } - - public static byte[] x509EncodeECPublicKey(ECPoint w, - ECParameterSpec params) throws InvalidKeySpecException { - KeyFactory keyFactory = getKeyFactory(); - ECPublicKeySpec keySpec = new ECPublicKeySpec(w, params); - X509Key key = (X509Key)keyFactory.generatePublic(keySpec); - - return key.getEncoded(); - } - - public static ECPrivateKey decodePKCS8ECPrivateKey(byte[] encoded) - throws InvalidKeySpecException { - KeyFactory keyFactory = getKeyFactory(); - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded); - - return (ECPrivateKey)keyFactory.generatePrivate(keySpec); - } - - public static ECPrivateKey generateECPrivateKey(BigInteger s, - ECParameterSpec params) throws InvalidKeySpecException { - KeyFactory keyFactory = getKeyFactory(); - ECPrivateKeySpec keySpec = new ECPrivateKeySpec(s, params); - - return (ECPrivateKey)keyFactory.generatePrivate(keySpec); - } - private static AlgorithmParameters getECParameters(Provider p) { try { if (p != null) { diff --git a/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java b/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java index d6d788a31799bd765b0f38d1730ae1158f30987d..9af80e5bbd3b176f9f07359577f6301c4237cedd 100644 --- a/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java +++ b/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java @@ -28,7 +28,7 @@ /* * @test - * @bug 6405536 + * @bug 6405536 8080102 * @summary Verify that all ciphersuites work (incl. ECC using NSS crypto) * @author Andreas Sterbenz * @library .. @@ -49,13 +49,29 @@ public class ClientJSSEServerJSSE extends PKCS11Test { cmdArgs = args; main(new ClientJSSEServerJSSE()); + // now test without SunEC Provider + System.setProperty("testWithoutSunEC", "true"); + main(new ClientJSSEServerJSSE()); + } public void main(Provider p) throws Exception { + String testWithoutSunEC = System.getProperty("testWithoutSunEC"); if (p.getService("KeyFactory", "EC") == null) { System.out.println("Provider does not support EC, skipping"); return; } + + + if (testWithoutSunEC != null) { + Provider sunec = Security.getProvider("SunEC"); + if (sunec == null) { + System.out.println("SunEC provider not present. Skipping test"); + return; + } + Security.removeProvider(sunec.getName()); + } + Providers.setAt(p, 1); CipherTest.main(new JSSEFactory(), cmdArgs); Security.removeProvider(p.getName());