Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8242897: KeyFactory.generatePublic( x509Spec ) failed with java.secur…
…ity.InvalidKeyException

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

Reviewed-by: weijun
  • Loading branch information
Valerie Peng committed Jun 3, 2020
1 parent 563ce12 commit 56b79604966ba6670e0370467405c71f474bfd72
@@ -32,8 +32,7 @@
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 @@ protected Key engineTranslateKey(Key key) throws InvalidKeyException {
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 @@ private PublicKey translatePublicKey(PublicKey key)
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 @@ private PublicKey translatePublicKey(PublicKey key)
} 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 @@ private PrivateKey translatePrivateKey(PrivateKey key)
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 @@ private PrivateKey translatePrivateKey(PrivateKey key)
RSAPrivateKey rsaKey = (RSAPrivateKey)key;
try {
return new RSAPrivateKeyImpl(
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
type, rsaKey.getParams(),
rsaKey.getModulus(),
rsaKey.getPrivateExponent()
);
@@ -314,7 +313,7 @@ private PrivateKey translatePrivateKey(PrivateKey key)
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 @@ private PublicKey generatePublic(KeySpec keySpec)
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 @@ private PrivateKey generatePrivate(KeySpec keySpec)
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 @@ private PrivateKey generatePrivate(KeySpec keySpec)
RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec;
try {
return new RSAPrivateKeyImpl(
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
type, rsaSpec.getParams(),
rsaSpec.getModulus(),
rsaSpec.getPrivateExponent()
);
@@ -32,10 +32,10 @@
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 void initialize(AlgorithmParameterSpec params, SecureRandom random)
}

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 KeyPair generateKeyPair() {
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,
@@ -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 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 @@
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 static RSAPrivateKey newKey(byte[] encoded)
(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 static RSAPrivateKey newKey(KeyType type,
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 static RSAPrivateKey newKey(KeyType type,
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 static RSAPrivateKey newKey(KeyType type,
* 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 static RSAPrivateKey newKey(KeyType type,
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 static RSAPrivateKey newKey(KeyType type,
// see JCA doc
@Override
public String getAlgorithm() {
return algid.getName();
return type.keyAlgo;
}

// see JCA doc
@@ -244,9 +253,9 @@ public AlgorithmParameterSpec getParams() {
// 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;
}

/**
@@ -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.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 AlgorithmParameterSpec getParams() {
// 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;
}

0 comments on commit 56b7960

Please sign in to comment.