8242897: KeyFactory.generatePublic( x509Spec ) failed with java.security.InvalidKeyException

Changed SunRsaSign provider to accept RSA signature oid in RSA key encoding for backward compatibility

Reviewed-by: weijun
This commit is contained in:
Valerie Peng 2020-06-03 04:29:04 +00:00
parent 563ce12127
commit 56b7960496
9 changed files with 283 additions and 168 deletions

View file

@ -32,8 +32,7 @@ import java.security.interfaces.*;
import java.security.spec.*;
import sun.security.action.GetPropertyAction;
import sun.security.x509.AlgorithmId;
import static sun.security.rsa.RSAUtil.KeyType;
import sun.security.rsa.RSAUtil.KeyType;
/**
* KeyFactory for RSA keys, e.g. "RSA", "RSASSA-PSS".
@ -211,7 +210,7 @@ public class RSAKeyFactory extends KeyFactorySpi {
throw new InvalidKeyException("Key must not be null");
}
// ensure the key algorithm matches the current KeyFactory instance
checkKeyAlgo(key, type.keyAlgo());
checkKeyAlgo(key, type.keyAlgo);
// no translation needed if the key is already our own impl
if ((key instanceof RSAPrivateKeyImpl) ||
@ -259,7 +258,7 @@ public class RSAKeyFactory extends KeyFactorySpi {
RSAPublicKey rsaKey = (RSAPublicKey)key;
try {
return new RSAPublicKeyImpl(
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
type, rsaKey.getParams(),
rsaKey.getModulus(),
rsaKey.getPublicExponent());
} catch (ProviderException e) {
@ -269,7 +268,7 @@ public class RSAKeyFactory extends KeyFactorySpi {
} else if ("X.509".equals(key.getFormat())) {
RSAPublicKey translated = new RSAPublicKeyImpl(key.getEncoded());
// ensure the key algorithm matches the current KeyFactory instance
checkKeyAlgo(translated, type.keyAlgo());
checkKeyAlgo(translated, type.keyAlgo);
return translated;
} else {
throw new InvalidKeyException("Public keys must be instance "
@ -284,7 +283,7 @@ public class RSAKeyFactory extends KeyFactorySpi {
RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;
try {
return new RSAPrivateCrtKeyImpl(
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
type, rsaKey.getParams(),
rsaKey.getModulus(),
rsaKey.getPublicExponent(),
rsaKey.getPrivateExponent(),
@ -302,7 +301,7 @@ public class RSAKeyFactory extends KeyFactorySpi {
RSAPrivateKey rsaKey = (RSAPrivateKey)key;
try {
return new RSAPrivateKeyImpl(
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
type, rsaKey.getParams(),
rsaKey.getModulus(),
rsaKey.getPrivateExponent()
);
@ -314,7 +313,7 @@ public class RSAKeyFactory extends KeyFactorySpi {
RSAPrivateKey translated =
RSAPrivateCrtKeyImpl.newKey(key.getEncoded());
// ensure the key algorithm matches the current KeyFactory instance
checkKeyAlgo(translated, type.keyAlgo());
checkKeyAlgo(translated, type.keyAlgo);
return translated;
} else {
throw new InvalidKeyException("Private keys must be instance "
@ -329,13 +328,13 @@ public class RSAKeyFactory extends KeyFactorySpi {
X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec;
RSAPublicKey generated = new RSAPublicKeyImpl(x509Spec.getEncoded());
// ensure the key algorithm matches the current KeyFactory instance
checkKeyAlgo(generated, type.keyAlgo());
checkKeyAlgo(generated, type.keyAlgo);
return generated;
} else if (keySpec instanceof RSAPublicKeySpec) {
RSAPublicKeySpec rsaSpec = (RSAPublicKeySpec)keySpec;
try {
return new RSAPublicKeyImpl(
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
type, rsaSpec.getParams(),
rsaSpec.getModulus(),
rsaSpec.getPublicExponent()
);
@ -355,13 +354,13 @@ public class RSAKeyFactory extends KeyFactorySpi {
PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec;
RSAPrivateKey generated = RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded());
// ensure the key algorithm matches the current KeyFactory instance
checkKeyAlgo(generated, type.keyAlgo());
checkKeyAlgo(generated, type.keyAlgo);
return generated;
} else if (keySpec instanceof RSAPrivateCrtKeySpec) {
RSAPrivateCrtKeySpec rsaSpec = (RSAPrivateCrtKeySpec)keySpec;
try {
return new RSAPrivateCrtKeyImpl(
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
type, rsaSpec.getParams(),
rsaSpec.getModulus(),
rsaSpec.getPublicExponent(),
rsaSpec.getPrivateExponent(),
@ -378,7 +377,7 @@ public class RSAKeyFactory extends KeyFactorySpi {
RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec;
try {
return new RSAPrivateKeyImpl(
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
type, rsaSpec.getParams(),
rsaSpec.getModulus(),
rsaSpec.getPrivateExponent()
);

View file

@ -32,10 +32,10 @@ import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
import sun.security.jca.JCAUtil;
import sun.security.rsa.RSAUtil.KeyType;
import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
import static sun.security.util.SecurityProviderConstants.DEF_RSASSA_PSS_KEY_SIZE;
import sun.security.x509.AlgorithmId;
import static sun.security.rsa.RSAUtil.KeyType;
/**
* RSA keypair generation. Standard algorithm, minimum key length 512 bit.
@ -55,7 +55,7 @@ public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
private int keySize;
private final KeyType type;
private AlgorithmId rsaId;
private AlgorithmParameterSpec keyParams;
// PRNG to use
private SecureRandom random;
@ -116,7 +116,7 @@ public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
}
try {
this.rsaId = RSAUtil.createAlgorithmId(type, tmpParams);
this.keyParams = RSAUtil.checkParamsAgainstType(type, tmpParams);
} catch (ProviderException e) {
throw new InvalidAlgorithmParameterException(
"Invalid key parameters", e);
@ -177,9 +177,10 @@ public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
BigInteger coeff = q.modInverse(p);
try {
PublicKey publicKey = new RSAPublicKeyImpl(rsaId, n, e);
PrivateKey privateKey = new RSAPrivateCrtKeyImpl(
rsaId, n, e, d, p, q, pe, qe, coeff);
PublicKey publicKey = new RSAPublicKeyImpl(type, keyParams,
n, e);
PrivateKey privateKey = new RSAPrivateCrtKeyImpl(type,
keyParams, n, e, d, p, q, pe, qe, coeff);
return new KeyPair(publicKey, privateKey);
} catch (InvalidKeyException exc) {
// invalid key exception only thrown for keys < 512 bit,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -34,10 +34,9 @@ import java.security.interfaces.*;
import sun.security.util.*;
import sun.security.x509.AlgorithmId;
import sun.security.pkcs.PKCS8Key;
import static sun.security.rsa.RSAUtil.KeyType;
import sun.security.rsa.RSAUtil.KeyType;
/**
* RSA private key implementation for "RSA", "RSASSA-PSS" algorithms in CRT form.
@ -67,11 +66,12 @@ public final class RSAPrivateCrtKeyImpl
private BigInteger qe; // prime exponent q
private BigInteger coeff; // CRT coeffcient
private transient KeyType type;
// Optional parameters associated with this RSA key
// specified in the encoding of its AlgorithmId.
// Must be null for "RSA" keys.
@SuppressWarnings("serial") // Not statically typed as Serializable
private AlgorithmParameterSpec keyParams;
private transient AlgorithmParameterSpec keyParams;
/**
* Generate a new key from its encoding. Returns a CRT key if possible
@ -89,7 +89,7 @@ public final class RSAPrivateCrtKeyImpl
(key.getPrimeQ().signum() == 0) ||
(key.getCrtCoefficient().signum() == 0)) {
return new RSAPrivateKeyImpl(
key.algid,
key.type, key.keyParams,
key.getModulus(),
key.getPrivateExponent()
);
@ -109,14 +109,13 @@ public final class RSAPrivateCrtKeyImpl
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
BigInteger coeff) throws InvalidKeyException {
RSAPrivateKey key;
AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params);
if ((e.signum() == 0) || (p.signum() == 0) ||
(q.signum() == 0) || (pe.signum() == 0) ||
(qe.signum() == 0) || (coeff.signum() == 0)) {
// if any component is missing, return a non-CRT key
return new RSAPrivateKeyImpl(rsaId, n, d);
return new RSAPrivateKeyImpl(type, params, n, d);
} else {
return new RSAPrivateCrtKeyImpl(rsaId, n, e, d,
return new RSAPrivateCrtKeyImpl(type, params, n, e, d,
p, q, pe, qe, coeff);
}
}
@ -132,8 +131,10 @@ public final class RSAPrivateCrtKeyImpl
decode(encoded);
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
try {
// this will check the validity of params
this.keyParams = RSAUtil.getParamSpec(algid);
// check the validity of oid and params
Object[] o = RSAUtil.getTypeAndParamSpec(algid);
this.type = (KeyType) o[0];
this.keyParams = (AlgorithmParameterSpec) o[1];
} catch (ProviderException e) {
throw new InvalidKeyException(e);
}
@ -143,7 +144,7 @@ public final class RSAPrivateCrtKeyImpl
* Construct a RSA key from its components. Used by the
* RSAKeyFactory and the RSAKeyPairGenerator.
*/
RSAPrivateCrtKeyImpl(AlgorithmId rsaId,
RSAPrivateCrtKeyImpl(KeyType type, AlgorithmParameterSpec keyParams,
BigInteger n, BigInteger e, BigInteger d,
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
BigInteger coeff) throws InvalidKeyException {
@ -157,11 +158,19 @@ public final class RSAPrivateCrtKeyImpl
this.pe = pe;
this.qe = qe;
this.coeff = coeff;
this.keyParams = RSAUtil.getParamSpec(rsaId);
// generate the encoding
algid = rsaId;
try {
// validate and generate the algid encoding
algid = RSAUtil.createAlgorithmId(type, keyParams);
} catch (ProviderException exc) {
throw new InvalidKeyException(exc);
}
this.type = type;
this.keyParams = keyParams;
try {
// generate the key encoding
DerOutputStream out = new DerOutputStream();
out.putInteger(0); // version must be 0
out.putInteger(n);
@ -184,7 +193,7 @@ public final class RSAPrivateCrtKeyImpl
// see JCA doc
@Override
public String getAlgorithm() {
return algid.getName();
return type.keyAlgo;
}
// see JCA doc
@ -244,9 +253,9 @@ public final class RSAPrivateCrtKeyImpl
// return a string representation of this key for debugging
@Override
public String toString() {
return "SunRsaSign " + getAlgorithm() + " private CRT key, " + n.bitLength()
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
+ "\n private exponent: " + d;
return "SunRsaSign " + type.keyAlgo + " private CRT key, "
+ n.bitLength() + " bits" + "\n params: " + keyParams
+ "\n modulus: " + n + "\n private exponent: " + d;
}
/**

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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,9 +33,10 @@ import java.security.spec.AlgorithmParameterSpec;
import java.security.interfaces.*;
import sun.security.util.*;
import sun.security.x509.AlgorithmId;
import sun.security.pkcs.PKCS8Key;
import sun.security.rsa.RSAUtil.KeyType;
/**
* RSA private key implementation for "RSA", "RSASSA-PSS" algorithms in non-CRT
* form (modulus, private exponent only). For CRT private keys, see
@ -58,27 +59,37 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
private final BigInteger n; // modulus
private final BigInteger d; // private exponent
private transient final KeyType type;
// optional parameters associated with this RSA key
// specified in the encoding of its AlgorithmId.
// must be null for "RSA" keys.
@SuppressWarnings("serial") // Not statically typed as Serializable
private final AlgorithmParameterSpec keyParams;
private transient final AlgorithmParameterSpec keyParams;
/**
* Construct a key from its components. Used by the
* RSAKeyFactory and the RSAKeyPairGenerator.
*/
RSAPrivateKeyImpl(AlgorithmId rsaId, BigInteger n, BigInteger d)
throws InvalidKeyException {
RSAPrivateKeyImpl(KeyType type, AlgorithmParameterSpec keyParams,
BigInteger n, BigInteger d) throws InvalidKeyException {
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), null);
this.n = n;
this.d = d;
this.keyParams = RSAUtil.getParamSpec(rsaId);
// generate the encoding
algid = rsaId;
try {
// validate and generate the algid encoding
algid = RSAUtil.createAlgorithmId(type, keyParams);
} catch (ProviderException pe) {
throw new InvalidKeyException(pe);
}
this.type = type;
this.keyParams = keyParams;
try {
// generate the key encoding
DerOutputStream out = new DerOutputStream();
out.putInteger(0); // version must be 0
out.putInteger(n);
@ -101,7 +112,7 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
// see JCA doc
@Override
public String getAlgorithm() {
return algid.getName();
return type.keyAlgo;
}
// see JCA doc
@ -125,7 +136,7 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
// return a string representation of this key for debugging
@Override
public String toString() {
return "Sun " + getAlgorithm() + " private key, " + n.bitLength()
return "Sun " + type.keyAlgo + " private key, " + n.bitLength()
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
+ "\n private exponent: " + d;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -34,9 +34,8 @@ import java.security.interfaces.*;
import sun.security.util.*;
import sun.security.x509.X509Key;
import sun.security.x509.AlgorithmId;
import static sun.security.rsa.RSAUtil.KeyType;
import sun.security.rsa.RSAUtil.KeyType;
/**
* RSA public key implementation for "RSA", "RSASSA-PSS" algorithms.
@ -59,11 +58,12 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
private BigInteger n; // modulus
private BigInteger e; // public exponent
private transient KeyType type;
// optional parameters associated with this RSA key
// specified in the encoding of its AlgorithmId
// must be null for "RSA" keys.
@SuppressWarnings("serial") // Not statically typed as Serializable
private AlgorithmParameterSpec keyParams;
private transient AlgorithmParameterSpec keyParams;
/**
* Generate a new RSAPublicKey from the specified encoding.
@ -81,26 +81,34 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
public static RSAPublicKey newKey(KeyType type,
AlgorithmParameterSpec params, BigInteger n, BigInteger e)
throws InvalidKeyException {
AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params);
return new RSAPublicKeyImpl(rsaId, n, e);
return new RSAPublicKeyImpl(type, params, n, e);
}
/**
* Construct a RSA key from AlgorithmId and its components. Used by
* Construct a RSA key from the specified type and components. Used by
* RSAKeyFactory and RSAKeyPairGenerator.
*/
RSAPublicKeyImpl(AlgorithmId rsaId, BigInteger n, BigInteger e)
throws InvalidKeyException {
RSAPublicKeyImpl(KeyType type, AlgorithmParameterSpec keyParams,
BigInteger n, BigInteger e) throws InvalidKeyException {
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
checkExponentRange(n, e);
this.n = n;
this.e = e;
this.keyParams = RSAUtil.getParamSpec(rsaId);
// generate the encoding
algid = rsaId;
try {
// validate and generate algid encoding
algid = RSAUtil.createAlgorithmId(type, keyParams);
} catch (ProviderException pe) {
throw new InvalidKeyException(pe);
}
this.type = type;
this.keyParams = keyParams;
try {
// generate the key encoding
DerOutputStream out = new DerOutputStream();
out.putInteger(n);
out.putInteger(e);
@ -126,8 +134,10 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
checkExponentRange(n, e);
try {
// this will check the validity of params
this.keyParams = RSAUtil.getParamSpec(algid);
// check the validity of oid and params
Object[] o = RSAUtil.getTypeAndParamSpec(algid);
this.type = (KeyType) o[0];
this.keyParams = (AlgorithmParameterSpec) o[1];
} catch (ProviderException e) {
throw new InvalidKeyException(e);
}
@ -150,7 +160,7 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
// see JCA doc
@Override
public String getAlgorithm() {
return algid.getName();
return type.keyAlgo;
}
// see JCA doc
@ -195,7 +205,7 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
// return a string representation of this key for debugging
@Override
public String toString() {
return "Sun " + getAlgorithm() + " public key, " + n.bitLength()
return "Sun " + type.keyAlgo + " public key, " + n.bitLength()
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
+ "\n public exponent: " + e;
}

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
@ -40,52 +40,71 @@ import sun.security.x509.AlgorithmId;
public class RSAUtil {
public enum KeyType {
RSA ("RSA"),
PSS ("RSASSA-PSS")
RSA ("RSA", AlgorithmId.RSAEncryption_oid, null),
PSS ("RSASSA-PSS", AlgorithmId.RSASSA_PSS_oid, PSSParameterSpec.class)
;
private final String algo;
final String keyAlgo;
final ObjectIdentifier oid;
final Class<? extends AlgorithmParameterSpec> paramSpecCls;
KeyType(String keyAlgo) {
this.algo = keyAlgo;
KeyType(String keyAlgo, ObjectIdentifier oid,
Class<? extends AlgorithmParameterSpec> paramSpecCls) {
this.keyAlgo = keyAlgo;
this.oid = oid;
this.paramSpecCls = paramSpecCls;
}
public String keyAlgo() {
return algo;
}
public static KeyType lookup(String name)
throws InvalidKeyException, ProviderException {
if (name == null) {
throw new InvalidKeyException("Null key algorithm");
}
for (KeyType kt : KeyType.values()) {
if (kt.keyAlgo().equalsIgnoreCase(name)) {
return kt;
}
}
// no match
public static KeyType lookup(String name) throws ProviderException {
requireNonNull(name, "Key algorithm should not be null");
// match loosely in order to work with 3rd party providers which
// may not follow the standard names
if (name.indexOf("PSS") != -1) {
return PSS;
} else if (name.indexOf("RSA") != -1) {
return RSA;
} else { // no match
throw new ProviderException("Unsupported algorithm " + name);
}
}
}
public static void checkParamsAgainstType(KeyType type,
private static void requireNonNull(Object obj, String msg) {
if (obj == null) throw new ProviderException(msg);
}
public static AlgorithmParameterSpec checkParamsAgainstType(KeyType type,
AlgorithmParameterSpec paramSpec) throws ProviderException {
switch (type) {
case RSA:
if (paramSpec != null) {
// currently no check for null parameter spec
// assumption is parameter spec is optional and can be null
if (paramSpec == null) return null;
Class<? extends AlgorithmParameterSpec> expCls = type.paramSpecCls;
if (expCls == null) {
throw new ProviderException("null params expected for " +
type.keyAlgo());
}
break;
case PSS:
if ((paramSpec != null) &&
!(paramSpec instanceof PSSParameterSpec)) {
type.keyAlgo);
} else if (!expCls.isInstance(paramSpec)) {
throw new ProviderException
("PSSParmeterSpec expected for " + type.keyAlgo());
(expCls + " expected for " + type.keyAlgo);
}
break;
default:
throw new ProviderException
("Unsupported RSA algorithm " + type);
return paramSpec;
}
public static AlgorithmParameters getParams(KeyType type,
AlgorithmParameterSpec spec) throws ProviderException {
if (spec == null) return null;
try {
AlgorithmParameters params =
AlgorithmParameters.getInstance(type.keyAlgo);
params.init(spec);
return params;
} catch (NoSuchAlgorithmException | InvalidParameterSpecException ex) {
throw new ProviderException(ex);
}
}
@ -94,69 +113,53 @@ public class RSAUtil {
checkParamsAgainstType(type, paramSpec);
ObjectIdentifier oid = null;
AlgorithmParameters params = null;
try {
switch (type) {
case RSA:
oid = AlgorithmId.RSAEncryption_oid;
break;
case PSS:
if (paramSpec != null) {
params = AlgorithmParameters.getInstance(type.keyAlgo());
params.init(paramSpec);
}
oid = AlgorithmId.RSASSA_PSS_oid;
break;
default:
throw new ProviderException
("Unsupported RSA algorithm " + type);
}
AlgorithmId result;
if (params == null) {
result = new AlgorithmId(oid);
} else {
result = new AlgorithmId(oid, params);
}
return result;
} catch (NoSuchAlgorithmException | InvalidParameterSpecException e) {
// should not happen
throw new ProviderException(e);
}
ObjectIdentifier oid = type.oid;
AlgorithmParameters params = getParams(type, paramSpec);
return new AlgorithmId(oid, params);
}
public static AlgorithmParameterSpec getParamSpec(AlgorithmId algid)
throws ProviderException {
if (algid == null) {
throw new ProviderException("AlgorithmId should not be null");
}
return getParamSpec(algid.getParameters());
}
public static AlgorithmParameterSpec getParamSpec(
AlgorithmParameters params) throws ProviderException {
public static AlgorithmParameterSpec getParamSpec(AlgorithmParameters params)
throws ProviderException {
if (params == null) return null;
try {
String algName = params.getAlgorithm();
KeyType type = KeyType.lookup(algName);
Class<? extends AlgorithmParameterSpec> specCls;
switch (type) {
case RSA:
Class<? extends AlgorithmParameterSpec> specCls = type.paramSpecCls;
if (specCls == null) {
throw new ProviderException("No params accepted for " +
type.keyAlgo());
case PSS:
specCls = PSSParameterSpec.class;
break;
default:
throw new ProviderException("Unsupported RSA algorithm: " + algName);
type.keyAlgo);
}
try {
return params.getParameterSpec(specCls);
} catch (InvalidParameterSpecException ex) {
throw new ProviderException(ex);
}
}
public static Object[] getTypeAndParamSpec(AlgorithmId algid)
throws ProviderException {
requireNonNull(algid, "AlgorithmId should not be null");
Object[] result = new Object[2];
String algName = algid.getName();
try {
result[0] = KeyType.lookup(algName);
} catch (ProviderException pe) {
// accommodate RSA keys encoded with various RSA signature oids
// for backward compatibility
if (algName.indexOf("RSA") != -1) {
result[0] = KeyType.RSA;
} else {
// pass it up
throw pe;
} catch (Exception e) {
throw new ProviderException(e);
}
}
result[1] = getParamSpec(algid.getParameters());
return result;
}
}

View file

@ -355,6 +355,11 @@ public enum KnownOIDs {
boolean registerNames() { return false; }
},
OIW_SHA1withRSA_Odd("1.3.14.3.2.15", "SHA1withRSA") {
@Override
boolean registerNames() { return false; }
},
SHA_1("1.3.14.3.2.26", "SHA-1", "SHA", "SHA1"),
OIW_SHA1withDSA("1.3.14.3.2.27", "SHA1withDSA") {

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 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
* 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 8242897
* @summary Ensure that RSA key factory can parse X.509 encodings containing
* non-standard RSA oid as in older JDK releases before JDK-8146293
* @run main TestRSAOidSupport
*/
import java.security.KeyFactory;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
public class TestRSAOidSupport {
// SubjectKeyInfo DER encoding w/ Algorithm id 1.3.14.3.2.15
// which can be used to generate RSA Public Key before PSS
// support is added
private static String DER_BYTES =
"3058300906052b0e03020f0500034b003048024100d7157c65e8f22557d8" +
"a857122cfe85bddfaba3064c21b345e2a7cdd8a6751e519ab861c5109fb8" +
"8cce45d161b9817bc0eccdc30fda69e62cc577775f2c1d66bd0203010001";
// utility method for converting hex string to byte array
static byte[] toByteArray(String s) {
byte[] bytes = new byte[s.length() / 2];
for (int i = 0; i < bytes.length; i++) {
int index = i * 2;
int v = Integer.parseInt(s.substring(index, index + 2), 16);
bytes[i] = (byte) v;
}
return bytes;
}
public static void main(String[] args) throws Exception {
X509EncodedKeySpec x509Spec = new X509EncodedKeySpec
(toByteArray(DER_BYTES));
String keyAlgo = "RSA";
KeyFactory kf = KeyFactory.getInstance(keyAlgo, "SunRsaSign");
RSAPublicKey rsaKey = (RSAPublicKey) kf.generatePublic(x509Spec);
if (rsaKey.getAlgorithm() != keyAlgo) {
throw new RuntimeException("Key algo should be " + keyAlgo +
", but got " + rsaKey.getAlgorithm());
}
kf = KeyFactory.getInstance("RSASSA-PSS", "SunRsaSign");
try {
kf.generatePublic(x509Spec);
throw new RuntimeException("Should throw IKSE");
} catch (InvalidKeySpecException ikse) {
System.out.println("Expected IKSE exception thrown");
}
}
}

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
@ -29,8 +29,7 @@ import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
import sun.security.x509.AlgorithmId;
import static sun.security.rsa.RSAUtil.KeyType;
import sun.security.rsa.RSAUtil.KeyType;
/**
* A fake RSA keypair generation.
@ -44,7 +43,7 @@ public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
private int keySize;
private final KeyType type;
private AlgorithmId rsaId;
private AlgorithmParameterSpec keyParams;
RSAKeyPairGenerator(KeyType type, int defKeySize) {
this.type = type;
@ -98,7 +97,7 @@ public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
}
try {
this.rsaId = RSAUtil.createAlgorithmId(type, tmpParams);
this.keyParams = RSAUtil.checkParamsAgainstType(type, tmpParams);
} catch (ProviderException e) {
throw new InvalidAlgorithmParameterException(
"Invalid key parameters", e);
@ -436,9 +435,9 @@ public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
BigInteger coeff = q.modInverse(p);
try {
PublicKey publicKey = new RSAPublicKeyImpl(rsaId, n, e);
PublicKey publicKey = new RSAPublicKeyImpl(type, keyParams, n, e);
PrivateKey privateKey = new RSAPrivateCrtKeyImpl(
rsaId, n, e, d, p, q, pe, qe, coeff);
type, keyParams, n, e, d, p, q, pe, qe, coeff);
return new KeyPair(publicKey, privateKey);
} catch (InvalidKeyException exc) {
// invalid key exception only thrown for keys < 512 bit,