mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8286908: ECDSA signature should not return parameters
Reviewed-by: ascarpino, hchao, valeriep
This commit is contained in:
parent
689f80cbad
commit
8040aa0073
4 changed files with 73 additions and 49 deletions
|
@ -151,17 +151,10 @@ public class SignatureUtil {
|
||||||
createAlgorithmParameters(sigName, paramBytes);
|
createAlgorithmParameters(sigName, paramBytes);
|
||||||
paramSpec = RSAUtil.getParamSpec(params);
|
paramSpec = RSAUtil.getParamSpec(params);
|
||||||
} else if (sigName.contains("ECDSA")) {
|
} else if (sigName.contains("ECDSA")) {
|
||||||
try {
|
// Some certificates have params in an ECDSA algorithmID.
|
||||||
Provider p = Signature.getInstance(sigName).getProvider();
|
// According to RFC 3279 2.2.3 and RFC 5758 3.2,
|
||||||
paramSpec = ECUtil.getECParameterSpec(p, paramBytes);
|
// they are useless and should be ignored.
|
||||||
} catch (Exception e) {
|
return null;
|
||||||
throw new ProviderException("Error handling EC parameters", e);
|
|
||||||
}
|
|
||||||
// ECUtil discards exception and returns null, so we need to check
|
|
||||||
// the returned value
|
|
||||||
if (paramSpec == null) {
|
|
||||||
throw new ProviderException("Error handling EC parameters");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
throw new ProviderException
|
throw new ProviderException
|
||||||
("Unrecognized algorithm for signature parameters " +
|
("Unrecognized algorithm for signature parameters " +
|
||||||
|
|
|
@ -213,10 +213,14 @@ public class AlgorithmId implements Serializable, DerEncoder {
|
||||||
|| algid.equals(ed25519_oid)
|
|| algid.equals(ed25519_oid)
|
||||||
|| algid.equals(x448_oid)
|
|| algid.equals(x448_oid)
|
||||||
|| algid.equals(x25519_oid)
|
|| algid.equals(x25519_oid)
|
||||||
|
|| algid.equals(SHA1withECDSA_oid)
|
||||||
|| algid.equals(SHA224withECDSA_oid)
|
|| algid.equals(SHA224withECDSA_oid)
|
||||||
|| algid.equals(SHA256withECDSA_oid)
|
|| algid.equals(SHA256withECDSA_oid)
|
||||||
|| algid.equals(SHA384withECDSA_oid)
|
|| algid.equals(SHA384withECDSA_oid)
|
||||||
|| algid.equals(SHA512withECDSA_oid)) {
|
|| algid.equals(SHA512withECDSA_oid)) {
|
||||||
|
// RFC 3279 2.2.3: When the ecdsa-with-SHA1 algorithm identifier
|
||||||
|
// appears as the algorithm field in an AlgorithmIdentifier,
|
||||||
|
// the encoding MUST omit the parameters field.
|
||||||
// RFC 4055 3.3: when an RSASSA-PSS key does not require
|
// RFC 4055 3.3: when an RSASSA-PSS key does not require
|
||||||
// parameter validation, field is absent.
|
// parameter validation, field is absent.
|
||||||
// RFC 8410 3: for id-X25519, id-X448, id-Ed25519, and
|
// RFC 8410 3: for id-X25519, id-X448, id-Ed25519, and
|
||||||
|
@ -692,6 +696,8 @@ public class AlgorithmId implements Serializable, DerEncoder {
|
||||||
public static final ObjectIdentifier x448_oid =
|
public static final ObjectIdentifier x448_oid =
|
||||||
ObjectIdentifier.of(KnownOIDs.X448);
|
ObjectIdentifier.of(KnownOIDs.X448);
|
||||||
|
|
||||||
|
public static final ObjectIdentifier SHA1withECDSA_oid =
|
||||||
|
ObjectIdentifier.of(KnownOIDs.SHA1withECDSA);
|
||||||
public static final ObjectIdentifier SHA224withECDSA_oid =
|
public static final ObjectIdentifier SHA224withECDSA_oid =
|
||||||
ObjectIdentifier.of(KnownOIDs.SHA224withECDSA);
|
ObjectIdentifier.of(KnownOIDs.SHA224withECDSA);
|
||||||
public static final ObjectIdentifier SHA256withECDSA_oid =
|
public static final ObjectIdentifier SHA256withECDSA_oid =
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -80,9 +80,6 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||||
// public key, if initialized for verifying
|
// public key, if initialized for verifying
|
||||||
private ECPublicKey publicKey;
|
private ECPublicKey publicKey;
|
||||||
|
|
||||||
// signature parameters
|
|
||||||
private ECParameterSpec sigParams = null;
|
|
||||||
|
|
||||||
// The format. true for the IEEE P1363 format. false (default) for ASN.1
|
// The format. true for the IEEE P1363 format. false (default) for ASN.1
|
||||||
private final boolean p1363Format;
|
private final boolean p1363Format;
|
||||||
|
|
||||||
|
@ -347,10 +344,6 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||||
protected void engineInitVerify(PublicKey publicKey)
|
protected void engineInitVerify(PublicKey publicKey)
|
||||||
throws InvalidKeyException {
|
throws InvalidKeyException {
|
||||||
ECPublicKey key = (ECPublicKey) ECKeyFactory.toECKey(publicKey);
|
ECPublicKey key = (ECPublicKey) ECKeyFactory.toECKey(publicKey);
|
||||||
if (!isCompatible(this.sigParams, key.getParams())) {
|
|
||||||
throw new InvalidKeyException("Key params does not match signature params");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should check that the supplied key is appropriate for signature
|
// Should check that the supplied key is appropriate for signature
|
||||||
// algorithm (e.g. P-256 for SHA256withECDSA)
|
// algorithm (e.g. P-256 for SHA256withECDSA)
|
||||||
this.publicKey = key;
|
this.publicKey = key;
|
||||||
|
@ -370,10 +363,6 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||||
protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
|
protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
|
||||||
throws InvalidKeyException {
|
throws InvalidKeyException {
|
||||||
ECPrivateKey key = (ECPrivateKey) ECKeyFactory.toECKey(privateKey);
|
ECPrivateKey key = (ECPrivateKey) ECKeyFactory.toECKey(privateKey);
|
||||||
if (!isCompatible(this.sigParams, key.getParams())) {
|
|
||||||
throw new InvalidKeyException("Key params does not match signature params");
|
|
||||||
}
|
|
||||||
|
|
||||||
ECUtil.checkPrivateKey(key);
|
ECUtil.checkPrivateKey(key);
|
||||||
// Should check that the supplied key is appropriate for signature
|
// Should check that the supplied key is appropriate for signature
|
||||||
// algorithm (e.g. P-256 for SHA256withECDSA)
|
// algorithm (e.g. P-256 for SHA256withECDSA)
|
||||||
|
@ -430,15 +419,6 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||||
needsReset = true;
|
needsReset = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isCompatible(ECParameterSpec sigParams,
|
|
||||||
ECParameterSpec keyParams) {
|
|
||||||
if (sigParams == null) {
|
|
||||||
// no restriction on key param
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return ECUtil.equals(sigParams, keyParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] signDigestImpl(ECDSAOperations ops, int seedBits,
|
private byte[] signDigestImpl(ECDSAOperations ops, int seedBits,
|
||||||
byte[] digest, ECPrivateKey priv, SecureRandom random)
|
byte[] digest, ECPrivateKey priv, SecureRandom random)
|
||||||
throws SignatureException {
|
throws SignatureException {
|
||||||
|
@ -528,17 +508,21 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void engineSetParameter(AlgorithmParameterSpec params)
|
protected void engineSetParameter(AlgorithmParameterSpec params)
|
||||||
throws InvalidAlgorithmParameterException {
|
throws InvalidAlgorithmParameterException {
|
||||||
if (params != null && !(params instanceof ECParameterSpec)) {
|
// Interop: some certificates include parameters in an ECDSA
|
||||||
throw new InvalidAlgorithmParameterException("No parameter accepted");
|
// algorithm identifier. We only accept one matching the key.
|
||||||
|
if (params == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!(params instanceof ECParameterSpec ecparams)) {
|
||||||
|
throw new InvalidAlgorithmParameterException(
|
||||||
|
"Parameters must be of type ECParameterSpec");
|
||||||
}
|
}
|
||||||
ECKey key = (this.privateKey == null? this.publicKey : this.privateKey);
|
ECKey key = (this.privateKey == null? this.publicKey : this.privateKey);
|
||||||
if ((key != null) && !isCompatible((ECParameterSpec)params, key.getParams())) {
|
if ((key != null) && !ECUtil.equals(ecparams, key.getParams())) {
|
||||||
throw new InvalidAlgorithmParameterException
|
throw new InvalidAlgorithmParameterException
|
||||||
("Signature params does not match key params");
|
("Signature params does not match key params");
|
||||||
}
|
}
|
||||||
|
|
||||||
sigParams = (ECParameterSpec) params;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get parameter, not supported. See JCA doc
|
// get parameter, not supported. See JCA doc
|
||||||
|
@ -551,16 +535,9 @@ abstract class ECDSASignature extends SignatureSpi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AlgorithmParameters engineGetParameters() {
|
protected AlgorithmParameters engineGetParameters() {
|
||||||
if (sigParams == null) {
|
// Always return null even if setParameter is called before.
|
||||||
return null;
|
// According to RFC 3279 2.2.3 and RFC 5758 3.2, no parameters is
|
||||||
}
|
// defined for ECDSA AlgorithmIdentifiers.
|
||||||
try {
|
return null;
|
||||||
AlgorithmParameters ap = AlgorithmParameters.getInstance("EC");
|
|
||||||
ap.init(sigParams);
|
|
||||||
return ap;
|
|
||||||
} catch (Exception e) {
|
|
||||||
// should never happen
|
|
||||||
throw new ProviderException("Error retrieving EC parameters", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
48
test/jdk/sun/security/ec/SignatureParameters.java
Normal file
48
test/jdk/sun/security/ec/SignatureParameters.java
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, 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 8286908
|
||||||
|
* @summary ECDSA signature should not return parameters
|
||||||
|
* @library /test/lib
|
||||||
|
* @modules jdk.crypto.ec
|
||||||
|
*/
|
||||||
|
|
||||||
|
import jdk.test.lib.Asserts;
|
||||||
|
|
||||||
|
import java.security.*;
|
||||||
|
import java.security.interfaces.ECPrivateKey;
|
||||||
|
import java.security.spec.ECGenParameterSpec;
|
||||||
|
|
||||||
|
public class SignatureParameters {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
|
||||||
|
kpg.initialize(new ECGenParameterSpec("secp384r1"));
|
||||||
|
ECPrivateKey key = (ECPrivateKey) kpg.generateKeyPair().getPrivate();
|
||||||
|
Signature s = Signature.getInstance("SHA384withECDSA");
|
||||||
|
s.initSign(key);
|
||||||
|
s.setParameter(key.getParams());
|
||||||
|
Asserts.assertEQ(s.getParameters(), null);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue