mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
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:
parent
563ce12127
commit
56b7960496
9 changed files with 283 additions and 168 deletions
|
@ -32,8 +32,7 @@ import java.security.interfaces.*;
|
||||||
import java.security.spec.*;
|
import java.security.spec.*;
|
||||||
|
|
||||||
import sun.security.action.GetPropertyAction;
|
import sun.security.action.GetPropertyAction;
|
||||||
import sun.security.x509.AlgorithmId;
|
import sun.security.rsa.RSAUtil.KeyType;
|
||||||
import static sun.security.rsa.RSAUtil.KeyType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KeyFactory for RSA keys, e.g. "RSA", "RSASSA-PSS".
|
* 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");
|
throw new InvalidKeyException("Key must not be null");
|
||||||
}
|
}
|
||||||
// ensure the key algorithm matches the current KeyFactory instance
|
// 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
|
// no translation needed if the key is already our own impl
|
||||||
if ((key instanceof RSAPrivateKeyImpl) ||
|
if ((key instanceof RSAPrivateKeyImpl) ||
|
||||||
|
@ -259,7 +258,7 @@ public class RSAKeyFactory extends KeyFactorySpi {
|
||||||
RSAPublicKey rsaKey = (RSAPublicKey)key;
|
RSAPublicKey rsaKey = (RSAPublicKey)key;
|
||||||
try {
|
try {
|
||||||
return new RSAPublicKeyImpl(
|
return new RSAPublicKeyImpl(
|
||||||
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
|
type, rsaKey.getParams(),
|
||||||
rsaKey.getModulus(),
|
rsaKey.getModulus(),
|
||||||
rsaKey.getPublicExponent());
|
rsaKey.getPublicExponent());
|
||||||
} catch (ProviderException e) {
|
} catch (ProviderException e) {
|
||||||
|
@ -269,7 +268,7 @@ public class RSAKeyFactory extends KeyFactorySpi {
|
||||||
} else if ("X.509".equals(key.getFormat())) {
|
} else if ("X.509".equals(key.getFormat())) {
|
||||||
RSAPublicKey translated = new RSAPublicKeyImpl(key.getEncoded());
|
RSAPublicKey translated = new RSAPublicKeyImpl(key.getEncoded());
|
||||||
// ensure the key algorithm matches the current KeyFactory instance
|
// ensure the key algorithm matches the current KeyFactory instance
|
||||||
checkKeyAlgo(translated, type.keyAlgo());
|
checkKeyAlgo(translated, type.keyAlgo);
|
||||||
return translated;
|
return translated;
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidKeyException("Public keys must be instance "
|
throw new InvalidKeyException("Public keys must be instance "
|
||||||
|
@ -284,7 +283,7 @@ public class RSAKeyFactory extends KeyFactorySpi {
|
||||||
RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;
|
RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;
|
||||||
try {
|
try {
|
||||||
return new RSAPrivateCrtKeyImpl(
|
return new RSAPrivateCrtKeyImpl(
|
||||||
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
|
type, rsaKey.getParams(),
|
||||||
rsaKey.getModulus(),
|
rsaKey.getModulus(),
|
||||||
rsaKey.getPublicExponent(),
|
rsaKey.getPublicExponent(),
|
||||||
rsaKey.getPrivateExponent(),
|
rsaKey.getPrivateExponent(),
|
||||||
|
@ -302,7 +301,7 @@ public class RSAKeyFactory extends KeyFactorySpi {
|
||||||
RSAPrivateKey rsaKey = (RSAPrivateKey)key;
|
RSAPrivateKey rsaKey = (RSAPrivateKey)key;
|
||||||
try {
|
try {
|
||||||
return new RSAPrivateKeyImpl(
|
return new RSAPrivateKeyImpl(
|
||||||
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
|
type, rsaKey.getParams(),
|
||||||
rsaKey.getModulus(),
|
rsaKey.getModulus(),
|
||||||
rsaKey.getPrivateExponent()
|
rsaKey.getPrivateExponent()
|
||||||
);
|
);
|
||||||
|
@ -314,7 +313,7 @@ public class RSAKeyFactory extends KeyFactorySpi {
|
||||||
RSAPrivateKey translated =
|
RSAPrivateKey translated =
|
||||||
RSAPrivateCrtKeyImpl.newKey(key.getEncoded());
|
RSAPrivateCrtKeyImpl.newKey(key.getEncoded());
|
||||||
// ensure the key algorithm matches the current KeyFactory instance
|
// ensure the key algorithm matches the current KeyFactory instance
|
||||||
checkKeyAlgo(translated, type.keyAlgo());
|
checkKeyAlgo(translated, type.keyAlgo);
|
||||||
return translated;
|
return translated;
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidKeyException("Private keys must be instance "
|
throw new InvalidKeyException("Private keys must be instance "
|
||||||
|
@ -329,13 +328,13 @@ public class RSAKeyFactory extends KeyFactorySpi {
|
||||||
X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec;
|
X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec;
|
||||||
RSAPublicKey generated = new RSAPublicKeyImpl(x509Spec.getEncoded());
|
RSAPublicKey generated = new RSAPublicKeyImpl(x509Spec.getEncoded());
|
||||||
// ensure the key algorithm matches the current KeyFactory instance
|
// ensure the key algorithm matches the current KeyFactory instance
|
||||||
checkKeyAlgo(generated, type.keyAlgo());
|
checkKeyAlgo(generated, type.keyAlgo);
|
||||||
return generated;
|
return generated;
|
||||||
} else if (keySpec instanceof RSAPublicKeySpec) {
|
} else if (keySpec instanceof RSAPublicKeySpec) {
|
||||||
RSAPublicKeySpec rsaSpec = (RSAPublicKeySpec)keySpec;
|
RSAPublicKeySpec rsaSpec = (RSAPublicKeySpec)keySpec;
|
||||||
try {
|
try {
|
||||||
return new RSAPublicKeyImpl(
|
return new RSAPublicKeyImpl(
|
||||||
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
|
type, rsaSpec.getParams(),
|
||||||
rsaSpec.getModulus(),
|
rsaSpec.getModulus(),
|
||||||
rsaSpec.getPublicExponent()
|
rsaSpec.getPublicExponent()
|
||||||
);
|
);
|
||||||
|
@ -355,13 +354,13 @@ public class RSAKeyFactory extends KeyFactorySpi {
|
||||||
PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec;
|
PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec;
|
||||||
RSAPrivateKey generated = RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded());
|
RSAPrivateKey generated = RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded());
|
||||||
// ensure the key algorithm matches the current KeyFactory instance
|
// ensure the key algorithm matches the current KeyFactory instance
|
||||||
checkKeyAlgo(generated, type.keyAlgo());
|
checkKeyAlgo(generated, type.keyAlgo);
|
||||||
return generated;
|
return generated;
|
||||||
} else if (keySpec instanceof RSAPrivateCrtKeySpec) {
|
} else if (keySpec instanceof RSAPrivateCrtKeySpec) {
|
||||||
RSAPrivateCrtKeySpec rsaSpec = (RSAPrivateCrtKeySpec)keySpec;
|
RSAPrivateCrtKeySpec rsaSpec = (RSAPrivateCrtKeySpec)keySpec;
|
||||||
try {
|
try {
|
||||||
return new RSAPrivateCrtKeyImpl(
|
return new RSAPrivateCrtKeyImpl(
|
||||||
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
|
type, rsaSpec.getParams(),
|
||||||
rsaSpec.getModulus(),
|
rsaSpec.getModulus(),
|
||||||
rsaSpec.getPublicExponent(),
|
rsaSpec.getPublicExponent(),
|
||||||
rsaSpec.getPrivateExponent(),
|
rsaSpec.getPrivateExponent(),
|
||||||
|
@ -378,7 +377,7 @@ public class RSAKeyFactory extends KeyFactorySpi {
|
||||||
RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec;
|
RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec;
|
||||||
try {
|
try {
|
||||||
return new RSAPrivateKeyImpl(
|
return new RSAPrivateKeyImpl(
|
||||||
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
|
type, rsaSpec.getParams(),
|
||||||
rsaSpec.getModulus(),
|
rsaSpec.getModulus(),
|
||||||
rsaSpec.getPrivateExponent()
|
rsaSpec.getPrivateExponent()
|
||||||
);
|
);
|
||||||
|
|
|
@ -32,10 +32,10 @@ import java.security.spec.AlgorithmParameterSpec;
|
||||||
import java.security.spec.RSAKeyGenParameterSpec;
|
import java.security.spec.RSAKeyGenParameterSpec;
|
||||||
|
|
||||||
import sun.security.jca.JCAUtil;
|
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_RSA_KEY_SIZE;
|
||||||
import static sun.security.util.SecurityProviderConstants.DEF_RSASSA_PSS_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.
|
* RSA keypair generation. Standard algorithm, minimum key length 512 bit.
|
||||||
|
@ -55,7 +55,7 @@ public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
private int keySize;
|
private int keySize;
|
||||||
|
|
||||||
private final KeyType type;
|
private final KeyType type;
|
||||||
private AlgorithmId rsaId;
|
private AlgorithmParameterSpec keyParams;
|
||||||
|
|
||||||
// PRNG to use
|
// PRNG to use
|
||||||
private SecureRandom random;
|
private SecureRandom random;
|
||||||
|
@ -116,7 +116,7 @@ public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.rsaId = RSAUtil.createAlgorithmId(type, tmpParams);
|
this.keyParams = RSAUtil.checkParamsAgainstType(type, tmpParams);
|
||||||
} catch (ProviderException e) {
|
} catch (ProviderException e) {
|
||||||
throw new InvalidAlgorithmParameterException(
|
throw new InvalidAlgorithmParameterException(
|
||||||
"Invalid key parameters", e);
|
"Invalid key parameters", e);
|
||||||
|
@ -177,9 +177,10 @@ public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
BigInteger coeff = q.modInverse(p);
|
BigInteger coeff = q.modInverse(p);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PublicKey publicKey = new RSAPublicKeyImpl(rsaId, n, e);
|
PublicKey publicKey = new RSAPublicKeyImpl(type, keyParams,
|
||||||
PrivateKey privateKey = new RSAPrivateCrtKeyImpl(
|
n, e);
|
||||||
rsaId, n, e, d, p, q, pe, qe, coeff);
|
PrivateKey privateKey = new RSAPrivateCrtKeyImpl(type,
|
||||||
|
keyParams, n, e, d, p, q, pe, qe, coeff);
|
||||||
return new KeyPair(publicKey, privateKey);
|
return new KeyPair(publicKey, privateKey);
|
||||||
} catch (InvalidKeyException exc) {
|
} catch (InvalidKeyException exc) {
|
||||||
// invalid key exception only thrown for keys < 512 bit,
|
// invalid key exception only thrown for keys < 512 bit,
|
||||||
|
|
|
@ -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.
|
* 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
|
||||||
|
@ -34,10 +34,9 @@ import java.security.interfaces.*;
|
||||||
|
|
||||||
import sun.security.util.*;
|
import sun.security.util.*;
|
||||||
|
|
||||||
import sun.security.x509.AlgorithmId;
|
|
||||||
import sun.security.pkcs.PKCS8Key;
|
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.
|
* 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 qe; // prime exponent q
|
||||||
private BigInteger coeff; // CRT coeffcient
|
private BigInteger coeff; // CRT coeffcient
|
||||||
|
|
||||||
|
private transient KeyType type;
|
||||||
|
|
||||||
// Optional parameters associated with this RSA key
|
// Optional parameters associated with this RSA key
|
||||||
// specified in the encoding of its AlgorithmId.
|
// specified in the encoding of its AlgorithmId.
|
||||||
// Must be null for "RSA" keys.
|
// Must be null for "RSA" keys.
|
||||||
@SuppressWarnings("serial") // Not statically typed as Serializable
|
private transient AlgorithmParameterSpec keyParams;
|
||||||
private AlgorithmParameterSpec keyParams;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a new key from its encoding. Returns a CRT key if possible
|
* 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.getPrimeQ().signum() == 0) ||
|
||||||
(key.getCrtCoefficient().signum() == 0)) {
|
(key.getCrtCoefficient().signum() == 0)) {
|
||||||
return new RSAPrivateKeyImpl(
|
return new RSAPrivateKeyImpl(
|
||||||
key.algid,
|
key.type, key.keyParams,
|
||||||
key.getModulus(),
|
key.getModulus(),
|
||||||
key.getPrivateExponent()
|
key.getPrivateExponent()
|
||||||
);
|
);
|
||||||
|
@ -109,14 +109,13 @@ public final class RSAPrivateCrtKeyImpl
|
||||||
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
|
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
|
||||||
BigInteger coeff) throws InvalidKeyException {
|
BigInteger coeff) throws InvalidKeyException {
|
||||||
RSAPrivateKey key;
|
RSAPrivateKey key;
|
||||||
AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params);
|
|
||||||
if ((e.signum() == 0) || (p.signum() == 0) ||
|
if ((e.signum() == 0) || (p.signum() == 0) ||
|
||||||
(q.signum() == 0) || (pe.signum() == 0) ||
|
(q.signum() == 0) || (pe.signum() == 0) ||
|
||||||
(qe.signum() == 0) || (coeff.signum() == 0)) {
|
(qe.signum() == 0) || (coeff.signum() == 0)) {
|
||||||
// if any component is missing, return a non-CRT key
|
// if any component is missing, return a non-CRT key
|
||||||
return new RSAPrivateKeyImpl(rsaId, n, d);
|
return new RSAPrivateKeyImpl(type, params, n, d);
|
||||||
} else {
|
} else {
|
||||||
return new RSAPrivateCrtKeyImpl(rsaId, n, e, d,
|
return new RSAPrivateCrtKeyImpl(type, params, n, e, d,
|
||||||
p, q, pe, qe, coeff);
|
p, q, pe, qe, coeff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,8 +131,10 @@ public final class RSAPrivateCrtKeyImpl
|
||||||
decode(encoded);
|
decode(encoded);
|
||||||
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
|
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
|
||||||
try {
|
try {
|
||||||
// this will check the validity of params
|
// check the validity of oid and params
|
||||||
this.keyParams = RSAUtil.getParamSpec(algid);
|
Object[] o = RSAUtil.getTypeAndParamSpec(algid);
|
||||||
|
this.type = (KeyType) o[0];
|
||||||
|
this.keyParams = (AlgorithmParameterSpec) o[1];
|
||||||
} catch (ProviderException e) {
|
} catch (ProviderException e) {
|
||||||
throw new InvalidKeyException(e);
|
throw new InvalidKeyException(e);
|
||||||
}
|
}
|
||||||
|
@ -143,7 +144,7 @@ public final class RSAPrivateCrtKeyImpl
|
||||||
* Construct a RSA key from its components. Used by the
|
* Construct a RSA key from its components. Used by the
|
||||||
* RSAKeyFactory and the RSAKeyPairGenerator.
|
* RSAKeyFactory and the RSAKeyPairGenerator.
|
||||||
*/
|
*/
|
||||||
RSAPrivateCrtKeyImpl(AlgorithmId rsaId,
|
RSAPrivateCrtKeyImpl(KeyType type, AlgorithmParameterSpec keyParams,
|
||||||
BigInteger n, BigInteger e, BigInteger d,
|
BigInteger n, BigInteger e, BigInteger d,
|
||||||
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
|
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
|
||||||
BigInteger coeff) throws InvalidKeyException {
|
BigInteger coeff) throws InvalidKeyException {
|
||||||
|
@ -157,11 +158,19 @@ public final class RSAPrivateCrtKeyImpl
|
||||||
this.pe = pe;
|
this.pe = pe;
|
||||||
this.qe = qe;
|
this.qe = qe;
|
||||||
this.coeff = coeff;
|
this.coeff = coeff;
|
||||||
this.keyParams = RSAUtil.getParamSpec(rsaId);
|
|
||||||
|
|
||||||
// generate the encoding
|
|
||||||
algid = rsaId;
|
|
||||||
try {
|
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();
|
DerOutputStream out = new DerOutputStream();
|
||||||
out.putInteger(0); // version must be 0
|
out.putInteger(0); // version must be 0
|
||||||
out.putInteger(n);
|
out.putInteger(n);
|
||||||
|
@ -184,7 +193,7 @@ public final class RSAPrivateCrtKeyImpl
|
||||||
// see JCA doc
|
// see JCA doc
|
||||||
@Override
|
@Override
|
||||||
public String getAlgorithm() {
|
public String getAlgorithm() {
|
||||||
return algid.getName();
|
return type.keyAlgo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// see JCA doc
|
// see JCA doc
|
||||||
|
@ -244,9 +253,9 @@ public final class RSAPrivateCrtKeyImpl
|
||||||
// return a string representation of this key for debugging
|
// return a string representation of this key for debugging
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SunRsaSign " + getAlgorithm() + " private CRT key, " + n.bitLength()
|
return "SunRsaSign " + type.keyAlgo + " private CRT key, "
|
||||||
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
|
+ n.bitLength() + " bits" + "\n params: " + keyParams
|
||||||
+ "\n private exponent: " + d;
|
+ "\n modulus: " + n + "\n private exponent: " + d;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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.
|
* 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
|
||||||
|
@ -33,9 +33,10 @@ import java.security.spec.AlgorithmParameterSpec;
|
||||||
import java.security.interfaces.*;
|
import java.security.interfaces.*;
|
||||||
|
|
||||||
import sun.security.util.*;
|
import sun.security.util.*;
|
||||||
import sun.security.x509.AlgorithmId;
|
|
||||||
import sun.security.pkcs.PKCS8Key;
|
import sun.security.pkcs.PKCS8Key;
|
||||||
|
|
||||||
|
import sun.security.rsa.RSAUtil.KeyType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RSA private key implementation for "RSA", "RSASSA-PSS" algorithms in non-CRT
|
* RSA private key implementation for "RSA", "RSASSA-PSS" algorithms in non-CRT
|
||||||
* form (modulus, private exponent only). For CRT private keys, see
|
* 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 n; // modulus
|
||||||
private final BigInteger d; // private exponent
|
private final BigInteger d; // private exponent
|
||||||
|
|
||||||
|
private transient final KeyType type;
|
||||||
|
|
||||||
// optional parameters associated with this RSA key
|
// optional parameters associated with this RSA key
|
||||||
// specified in the encoding of its AlgorithmId.
|
// specified in the encoding of its AlgorithmId.
|
||||||
// must be null for "RSA" keys.
|
// must be null for "RSA" keys.
|
||||||
@SuppressWarnings("serial") // Not statically typed as Serializable
|
private transient final AlgorithmParameterSpec keyParams;
|
||||||
private final AlgorithmParameterSpec keyParams;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a key from its components. Used by the
|
* Construct a key from its components. Used by the
|
||||||
* RSAKeyFactory and the RSAKeyPairGenerator.
|
* RSAKeyFactory and the RSAKeyPairGenerator.
|
||||||
*/
|
*/
|
||||||
RSAPrivateKeyImpl(AlgorithmId rsaId, BigInteger n, BigInteger d)
|
RSAPrivateKeyImpl(KeyType type, AlgorithmParameterSpec keyParams,
|
||||||
throws InvalidKeyException {
|
BigInteger n, BigInteger d) throws InvalidKeyException {
|
||||||
|
|
||||||
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), null);
|
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), null);
|
||||||
|
|
||||||
this.n = n;
|
this.n = n;
|
||||||
this.d = d;
|
this.d = d;
|
||||||
this.keyParams = RSAUtil.getParamSpec(rsaId);
|
|
||||||
|
|
||||||
// generate the encoding
|
|
||||||
algid = rsaId;
|
|
||||||
try {
|
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();
|
DerOutputStream out = new DerOutputStream();
|
||||||
out.putInteger(0); // version must be 0
|
out.putInteger(0); // version must be 0
|
||||||
out.putInteger(n);
|
out.putInteger(n);
|
||||||
|
@ -101,7 +112,7 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
|
||||||
// see JCA doc
|
// see JCA doc
|
||||||
@Override
|
@Override
|
||||||
public String getAlgorithm() {
|
public String getAlgorithm() {
|
||||||
return algid.getName();
|
return type.keyAlgo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// see JCA doc
|
// see JCA doc
|
||||||
|
@ -125,7 +136,7 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
|
||||||
// return a string representation of this key for debugging
|
// return a string representation of this key for debugging
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
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
|
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
|
||||||
+ "\n private exponent: " + d;
|
+ "\n private exponent: " + d;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
* 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
|
||||||
|
@ -34,9 +34,8 @@ import java.security.interfaces.*;
|
||||||
|
|
||||||
import sun.security.util.*;
|
import sun.security.util.*;
|
||||||
import sun.security.x509.X509Key;
|
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.
|
* 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 n; // modulus
|
||||||
private BigInteger e; // public exponent
|
private BigInteger e; // public exponent
|
||||||
|
|
||||||
|
private transient KeyType type;
|
||||||
|
|
||||||
// optional parameters associated with this RSA key
|
// optional parameters associated with this RSA key
|
||||||
// specified in the encoding of its AlgorithmId
|
// specified in the encoding of its AlgorithmId
|
||||||
// must be null for "RSA" keys.
|
// must be null for "RSA" keys.
|
||||||
@SuppressWarnings("serial") // Not statically typed as Serializable
|
private transient AlgorithmParameterSpec keyParams;
|
||||||
private AlgorithmParameterSpec keyParams;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a new RSAPublicKey from the specified encoding.
|
* 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,
|
public static RSAPublicKey newKey(KeyType type,
|
||||||
AlgorithmParameterSpec params, BigInteger n, BigInteger e)
|
AlgorithmParameterSpec params, BigInteger n, BigInteger e)
|
||||||
throws InvalidKeyException {
|
throws InvalidKeyException {
|
||||||
AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params);
|
return new RSAPublicKeyImpl(type, params, n, e);
|
||||||
return new RSAPublicKeyImpl(rsaId, 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.
|
* RSAKeyFactory and RSAKeyPairGenerator.
|
||||||
*/
|
*/
|
||||||
RSAPublicKeyImpl(AlgorithmId rsaId, BigInteger n, BigInteger e)
|
RSAPublicKeyImpl(KeyType type, AlgorithmParameterSpec keyParams,
|
||||||
throws InvalidKeyException {
|
BigInteger n, BigInteger e) throws InvalidKeyException {
|
||||||
|
|
||||||
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
|
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
|
||||||
checkExponentRange(n, e);
|
checkExponentRange(n, e);
|
||||||
|
|
||||||
this.n = n;
|
this.n = n;
|
||||||
this.e = e;
|
this.e = e;
|
||||||
this.keyParams = RSAUtil.getParamSpec(rsaId);
|
|
||||||
|
|
||||||
// generate the encoding
|
|
||||||
algid = rsaId;
|
|
||||||
try {
|
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();
|
DerOutputStream out = new DerOutputStream();
|
||||||
out.putInteger(n);
|
out.putInteger(n);
|
||||||
out.putInteger(e);
|
out.putInteger(e);
|
||||||
|
@ -126,8 +134,10 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
|
||||||
checkExponentRange(n, e);
|
checkExponentRange(n, e);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// this will check the validity of params
|
// check the validity of oid and params
|
||||||
this.keyParams = RSAUtil.getParamSpec(algid);
|
Object[] o = RSAUtil.getTypeAndParamSpec(algid);
|
||||||
|
this.type = (KeyType) o[0];
|
||||||
|
this.keyParams = (AlgorithmParameterSpec) o[1];
|
||||||
} catch (ProviderException e) {
|
} catch (ProviderException e) {
|
||||||
throw new InvalidKeyException(e);
|
throw new InvalidKeyException(e);
|
||||||
}
|
}
|
||||||
|
@ -150,7 +160,7 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
|
||||||
// see JCA doc
|
// see JCA doc
|
||||||
@Override
|
@Override
|
||||||
public String getAlgorithm() {
|
public String getAlgorithm() {
|
||||||
return algid.getName();
|
return type.keyAlgo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// see JCA doc
|
// see JCA doc
|
||||||
|
@ -195,7 +205,7 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
|
||||||
// return a string representation of this key for debugging
|
// return a string representation of this key for debugging
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
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
|
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
|
||||||
+ "\n public exponent: " + e;
|
+ "\n public exponent: " + e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
* 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
|
||||||
|
@ -40,52 +40,71 @@ import sun.security.x509.AlgorithmId;
|
||||||
public class RSAUtil {
|
public class RSAUtil {
|
||||||
|
|
||||||
public enum KeyType {
|
public enum KeyType {
|
||||||
RSA ("RSA"),
|
RSA ("RSA", AlgorithmId.RSAEncryption_oid, null),
|
||||||
PSS ("RSASSA-PSS")
|
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) {
|
KeyType(String keyAlgo, ObjectIdentifier oid,
|
||||||
this.algo = keyAlgo;
|
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 ProviderException {
|
||||||
}
|
|
||||||
public static KeyType lookup(String name)
|
requireNonNull(name, "Key algorithm should not be null");
|
||||||
throws InvalidKeyException, ProviderException {
|
|
||||||
if (name == null) {
|
// match loosely in order to work with 3rd party providers which
|
||||||
throw new InvalidKeyException("Null key algorithm");
|
// 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);
|
||||||
}
|
}
|
||||||
for (KeyType kt : KeyType.values()) {
|
|
||||||
if (kt.keyAlgo().equalsIgnoreCase(name)) {
|
|
||||||
return kt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 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 {
|
AlgorithmParameterSpec paramSpec) throws ProviderException {
|
||||||
switch (type) {
|
|
||||||
case RSA:
|
// currently no check for null parameter spec
|
||||||
if (paramSpec != null) {
|
// assumption is parameter spec is optional and can be null
|
||||||
throw new ProviderException("null params expected for " +
|
if (paramSpec == null) return null;
|
||||||
type.keyAlgo());
|
|
||||||
}
|
Class<? extends AlgorithmParameterSpec> expCls = type.paramSpecCls;
|
||||||
break;
|
if (expCls == null) {
|
||||||
case PSS:
|
throw new ProviderException("null params expected for " +
|
||||||
if ((paramSpec != null) &&
|
type.keyAlgo);
|
||||||
!(paramSpec instanceof PSSParameterSpec)) {
|
} else if (!expCls.isInstance(paramSpec)) {
|
||||||
throw new ProviderException
|
throw new ProviderException
|
||||||
("PSSParmeterSpec expected for " + type.keyAlgo());
|
(expCls + " expected for " + type.keyAlgo);
|
||||||
}
|
}
|
||||||
break;
|
return paramSpec;
|
||||||
default:
|
}
|
||||||
throw new ProviderException
|
|
||||||
("Unsupported RSA algorithm " + type);
|
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);
|
checkParamsAgainstType(type, paramSpec);
|
||||||
|
|
||||||
ObjectIdentifier oid = null;
|
ObjectIdentifier oid = type.oid;
|
||||||
AlgorithmParameters params = null;
|
AlgorithmParameters params = getParams(type, paramSpec);
|
||||||
try {
|
return new AlgorithmId(oid, params);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AlgorithmParameterSpec getParamSpec(AlgorithmId algid)
|
public static AlgorithmParameterSpec getParamSpec(
|
||||||
throws ProviderException {
|
AlgorithmParameters params) 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 {
|
|
||||||
if (params == null) return null;
|
if (params == null) return null;
|
||||||
|
|
||||||
|
String algName = params.getAlgorithm();
|
||||||
|
|
||||||
|
KeyType type = KeyType.lookup(algName);
|
||||||
|
Class<? extends AlgorithmParameterSpec> specCls = type.paramSpecCls;
|
||||||
|
if (specCls == null) {
|
||||||
|
throw new ProviderException("No params accepted for " +
|
||||||
|
type.keyAlgo);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
String algName = params.getAlgorithm();
|
|
||||||
KeyType type = KeyType.lookup(algName);
|
|
||||||
Class<? extends AlgorithmParameterSpec> specCls;
|
|
||||||
switch (type) {
|
|
||||||
case RSA:
|
|
||||||
throw new ProviderException("No params accepted for " +
|
|
||||||
type.keyAlgo());
|
|
||||||
case PSS:
|
|
||||||
specCls = PSSParameterSpec.class;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ProviderException("Unsupported RSA algorithm: " + algName);
|
|
||||||
}
|
|
||||||
return params.getParameterSpec(specCls);
|
return params.getParameterSpec(specCls);
|
||||||
} catch (ProviderException pe) {
|
} catch (InvalidParameterSpecException ex) {
|
||||||
// pass it up
|
throw new ProviderException(ex);
|
||||||
throw pe;
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new ProviderException(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result[1] = getParamSpec(algid.getParameters());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -355,6 +355,11 @@ public enum KnownOIDs {
|
||||||
boolean registerNames() { return false; }
|
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"),
|
SHA_1("1.3.14.3.2.26", "SHA-1", "SHA", "SHA1"),
|
||||||
|
|
||||||
OIW_SHA1withDSA("1.3.14.3.2.27", "SHA1withDSA") {
|
OIW_SHA1withDSA("1.3.14.3.2.27", "SHA1withDSA") {
|
||||||
|
|
78
test/jdk/sun/security/rsa/TestRSAOidSupport.java
Normal file
78
test/jdk/sun/security/rsa/TestRSAOidSupport.java
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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.
|
* 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
|
||||||
|
@ -29,8 +29,7 @@ import java.security.*;
|
||||||
import java.security.spec.AlgorithmParameterSpec;
|
import java.security.spec.AlgorithmParameterSpec;
|
||||||
import java.security.spec.RSAKeyGenParameterSpec;
|
import java.security.spec.RSAKeyGenParameterSpec;
|
||||||
|
|
||||||
import sun.security.x509.AlgorithmId;
|
import sun.security.rsa.RSAUtil.KeyType;
|
||||||
import static sun.security.rsa.RSAUtil.KeyType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A fake RSA keypair generation.
|
* A fake RSA keypair generation.
|
||||||
|
@ -44,7 +43,7 @@ public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
private int keySize;
|
private int keySize;
|
||||||
|
|
||||||
private final KeyType type;
|
private final KeyType type;
|
||||||
private AlgorithmId rsaId;
|
private AlgorithmParameterSpec keyParams;
|
||||||
|
|
||||||
RSAKeyPairGenerator(KeyType type, int defKeySize) {
|
RSAKeyPairGenerator(KeyType type, int defKeySize) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
@ -98,7 +97,7 @@ public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.rsaId = RSAUtil.createAlgorithmId(type, tmpParams);
|
this.keyParams = RSAUtil.checkParamsAgainstType(type, tmpParams);
|
||||||
} catch (ProviderException e) {
|
} catch (ProviderException e) {
|
||||||
throw new InvalidAlgorithmParameterException(
|
throw new InvalidAlgorithmParameterException(
|
||||||
"Invalid key parameters", e);
|
"Invalid key parameters", e);
|
||||||
|
@ -436,9 +435,9 @@ public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||||
BigInteger coeff = q.modInverse(p);
|
BigInteger coeff = q.modInverse(p);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PublicKey publicKey = new RSAPublicKeyImpl(rsaId, n, e);
|
PublicKey publicKey = new RSAPublicKeyImpl(type, keyParams, n, e);
|
||||||
PrivateKey privateKey = new RSAPrivateCrtKeyImpl(
|
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);
|
return new KeyPair(publicKey, privateKey);
|
||||||
} catch (InvalidKeyException exc) {
|
} catch (InvalidKeyException exc) {
|
||||||
// invalid key exception only thrown for keys < 512 bit,
|
// invalid key exception only thrown for keys < 512 bit,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue