8236070: Backout fix for JDK-8234465

Reviewed-by: mullan
This commit is contained in:
Weijun Wang 2019-12-17 20:56:53 +08:00
parent bd6ab22a59
commit 010ac54044
4 changed files with 21 additions and 106 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2012, 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
@ -201,7 +201,6 @@ public final class ECKeyFactory extends KeyFactorySpi {
ECPrivateKey ecKey = (ECPrivateKey)key;
return new ECPrivateKeyImpl(
ecKey.getS(),
null,
ecKey.getParams()
);
} else if ("PKCS#8".equals(key.getFormat())) {
@ -238,7 +237,7 @@ public final class ECKeyFactory extends KeyFactorySpi {
return new ECPrivateKeyImpl(pkcsSpec.getEncoded());
} else if (keySpec instanceof ECPrivateKeySpec) {
ECPrivateKeySpec ecSpec = (ECPrivateKeySpec)keySpec;
return new ECPrivateKeyImpl(ecSpec.getS(), null, ecSpec.getParams());
return new ECPrivateKeyImpl(ecSpec.getS(), ecSpec.getParams());
} else {
throw new InvalidKeySpecException("Only ECPrivateKeySpec "
+ "and PKCS8EncodedKeySpec supported for EC private keys");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2018, 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
@ -199,10 +199,11 @@ public final class ECKeyPairGenerator extends KeyPairGeneratorSpi {
AffinePoint affGen = new AffinePoint(x, y);
Point pub = ops.multiply(affGen, privArr);
AffinePoint affPub = pub.asAffine();
PrivateKey privateKey = new ECPrivateKeyImpl(privArr, ecParams);
ECPoint w = new ECPoint(affPub.getX().asBigInteger(),
affPub.getY().asBigInteger());
PrivateKey privateKey = new ECPrivateKeyImpl(privArr, w, ecParams);
PublicKey publicKey = new ECPublicKeyImpl(w, ecParams);
return Optional.of(new KeyPair(publicKey, privateKey));
@ -224,12 +225,11 @@ public final class ECKeyPairGenerator extends KeyPairGeneratorSpi {
// keyBytes[0] is the encoding of the native private key
BigInteger s = new BigInteger(1, (byte[]) keyBytes[0]);
PrivateKey privateKey = new ECPrivateKeyImpl(s, ecParams);
// keyBytes[1] is the encoding of the native public key
byte[] pubKey = (byte[]) keyBytes[1];
ECPoint w = ECUtil.decodePoint(pubKey, ecParams.getCurve());
PrivateKey privateKey = new ECPrivateKeyImpl(s, w, ecParams);
PublicKey publicKey = new ECPublicKeyImpl(w, ecParams);
return new KeyPair(publicKey, privateKey);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2018, 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
@ -52,8 +52,8 @@ import sun.security.pkcs.PKCS8Key;
* }
* </pre>
*
* We currently ignore the optional parameters. We require that the
* parameters are encoded as part of the AlgorithmIdentifier,
* We currently ignore the optional parameters and publicKey fields. We
* require that the parameters are encoded as part of the AlgorithmIdentifier,
* not in the private key structure.
*
* @since 1.6
@ -66,7 +66,6 @@ public final class ECPrivateKeyImpl extends PKCS8Key implements ECPrivateKey {
private BigInteger s; // private value
private byte[] arrayS; // private value as a little-endian array
private ECParameterSpec params;
private ECPoint pub; // the optional public key
/**
* Construct a key from its encoding. Called by the ECKeyFactory.
@ -79,20 +78,18 @@ public final class ECPrivateKeyImpl extends PKCS8Key implements ECPrivateKey {
* Construct a key from its components. Used by the
* KeyFactory.
*/
ECPrivateKeyImpl(BigInteger s, ECPoint pub, ECParameterSpec params)
ECPrivateKeyImpl(BigInteger s, ECParameterSpec params)
throws InvalidKeyException {
this.s = s;
this.params = params;
this.pub = pub;
makeEncoding(s);
}
ECPrivateKeyImpl(byte[] s, ECPoint pub, ECParameterSpec params)
ECPrivateKeyImpl(byte[] s, ECParameterSpec params)
throws InvalidKeyException {
this.arrayS = s.clone();
this.params = params;
this.pub = pub;
makeEncoding(s);
}
@ -105,12 +102,6 @@ public final class ECPrivateKeyImpl extends PKCS8Key implements ECPrivateKey {
byte[] privBytes = s.clone();
ArrayUtil.reverse(privBytes);
out.putOctetString(privBytes);
if (pub != null) {
DerOutputStream pubDer = new DerOutputStream();
pubDer.putBitString(ECUtil.encodePoint(pub, params.getCurve()));
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x01), pubDer);
}
DerValue val =
new DerValue(DerValue.tag_Sequence, out.toByteArray());
key = val.toByteArray();
@ -195,25 +186,22 @@ public final class ECPrivateKeyImpl extends PKCS8Key implements ECPrivateKey {
byte[] privData = data.getOctetString();
ArrayUtil.reverse(privData);
arrayS = privData;
AlgorithmParameters algParams = this.algid.getParameters();
if (algParams == null) {
throw new InvalidKeyException("EC domain parameters must be "
+ "encoded in the algorithm identifier");
}
params = algParams.getParameterSpec(ECParameterSpec.class);
while (data.available() != 0) {
DerValue value = data.getDerValue();
if (value.isContextSpecific((byte) 0)) {
// ignore for now. Usually not encoded because
// pkcs8 already has the params
// ignore for now
} else if (value.isContextSpecific((byte) 1)) {
pub = ECUtil.decodePoint(
value.data.getUnalignedBitString().toByteArray(),
params.getCurve());
// ignore for now
} else {
throw new InvalidKeyException("Unexpected value: " + value);
}
}
AlgorithmParameters algParams = this.algid.getParameters();
if (algParams == null) {
throw new InvalidKeyException("EC domain parameters must be "
+ "encoded in the algorithm identifier");
}
params = algParams.getParameterSpec(ECParameterSpec.class);
} catch (IOException e) {
throw new InvalidKeyException("Invalid EC private key", e);
} catch (InvalidParameterSpecException e) {

View File

@ -1,72 +0,0 @@
/*
* Copyright (c) 2019, 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.
*/
import jdk.test.lib.Asserts;
import jdk.test.lib.security.DerUtils;
import sun.security.util.DerValue;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Arrays;
/*
* @test
* @bug 8234465
* @library /test/lib
* @modules java.base/sun.security.util
* @summary Encoded elliptic curve private keys should include the public point
*/
public class PublicKeyInPrivateKey {
public static void main(String[] args) throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
kpg.initialize(new ECGenParameterSpec("secp256r1"));
KeyPair kp = kpg.generateKeyPair();
byte[] pubBytes = kp.getPublic().getEncoded();
byte[] privBytes = kp.getPrivate().getEncoded();
// https://tools.ietf.org/html/rfc5480#section-2.
// subjectPublicKey is 2nd in SubjectPublicKeyInfo
DerValue pubPoint = DerUtils.innerDerValue(pubBytes, "1");
// https://tools.ietf.org/html/rfc5208#section-5.
// privateKey as an OCTET STRING is 3rd in PrivateKeyInfo
// https://tools.ietf.org/html/rfc5915#section-3
// publicKey as [1] is 3rd (we do not have parameters) in ECPrivateKey
DerValue pubPointInPriv = DerUtils.innerDerValue(privBytes, "2c20");
// The two public keys should be the same
Asserts.assertEQ(pubPoint, pubPointInPriv);
// And it's reloadable
KeyFactory kf = KeyFactory.getInstance("EC");
byte[] privBytes2 = kf.generatePrivate(
new PKCS8EncodedKeySpec(privBytes)).getEncoded();
Asserts.assertTrue(Arrays.equals(privBytes, privBytes2));
}
}