Skip to content

Commit d7701cd

Browse files
committed
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: mbaesken Backport-of: 56b7960
1 parent ad283ae commit d7701cd

File tree

9 files changed

+280
-162
lines changed

9 files changed

+280
-162
lines changed

src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@
3232
import java.security.spec.*;
3333

3434
import sun.security.action.GetPropertyAction;
35-
import sun.security.x509.AlgorithmId;
36-
import static sun.security.rsa.RSAUtil.KeyType;
35+
import sun.security.rsa.RSAUtil.KeyType;
3736

3837
/**
3938
* KeyFactory for RSA keys, e.g. "RSA", "RSASSA-PSS".
@@ -211,7 +210,7 @@ protected Key engineTranslateKey(Key key) throws InvalidKeyException {
211210
throw new InvalidKeyException("Key must not be null");
212211
}
213212
// ensure the key algorithm matches the current KeyFactory instance
214-
checkKeyAlgo(key, type.keyAlgo());
213+
checkKeyAlgo(key, type.keyAlgo);
215214

216215
// no translation needed if the key is already our own impl
217216
if ((key instanceof RSAPrivateKeyImpl) ||
@@ -259,7 +258,7 @@ private PublicKey translatePublicKey(PublicKey key)
259258
RSAPublicKey rsaKey = (RSAPublicKey)key;
260259
try {
261260
return new RSAPublicKeyImpl(
262-
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
261+
type, rsaKey.getParams(),
263262
rsaKey.getModulus(),
264263
rsaKey.getPublicExponent());
265264
} catch (ProviderException e) {
@@ -269,7 +268,7 @@ private PublicKey translatePublicKey(PublicKey key)
269268
} else if ("X.509".equals(key.getFormat())) {
270269
RSAPublicKey translated = new RSAPublicKeyImpl(key.getEncoded());
271270
// ensure the key algorithm matches the current KeyFactory instance
272-
checkKeyAlgo(translated, type.keyAlgo());
271+
checkKeyAlgo(translated, type.keyAlgo);
273272
return translated;
274273
} else {
275274
throw new InvalidKeyException("Public keys must be instance "
@@ -284,7 +283,7 @@ private PrivateKey translatePrivateKey(PrivateKey key)
284283
RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;
285284
try {
286285
return new RSAPrivateCrtKeyImpl(
287-
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
286+
type, rsaKey.getParams(),
288287
rsaKey.getModulus(),
289288
rsaKey.getPublicExponent(),
290289
rsaKey.getPrivateExponent(),
@@ -302,7 +301,7 @@ private PrivateKey translatePrivateKey(PrivateKey key)
302301
RSAPrivateKey rsaKey = (RSAPrivateKey)key;
303302
try {
304303
return new RSAPrivateKeyImpl(
305-
RSAUtil.createAlgorithmId(type, rsaKey.getParams()),
304+
type, rsaKey.getParams(),
306305
rsaKey.getModulus(),
307306
rsaKey.getPrivateExponent()
308307
);
@@ -314,7 +313,7 @@ private PrivateKey translatePrivateKey(PrivateKey key)
314313
RSAPrivateKey translated =
315314
RSAPrivateCrtKeyImpl.newKey(key.getEncoded());
316315
// ensure the key algorithm matches the current KeyFactory instance
317-
checkKeyAlgo(translated, type.keyAlgo());
316+
checkKeyAlgo(translated, type.keyAlgo);
318317
return translated;
319318
} else {
320319
throw new InvalidKeyException("Private keys must be instance "
@@ -329,13 +328,13 @@ private PublicKey generatePublic(KeySpec keySpec)
329328
X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec;
330329
RSAPublicKey generated = new RSAPublicKeyImpl(x509Spec.getEncoded());
331330
// ensure the key algorithm matches the current KeyFactory instance
332-
checkKeyAlgo(generated, type.keyAlgo());
331+
checkKeyAlgo(generated, type.keyAlgo);
333332
return generated;
334333
} else if (keySpec instanceof RSAPublicKeySpec) {
335334
RSAPublicKeySpec rsaSpec = (RSAPublicKeySpec)keySpec;
336335
try {
337336
return new RSAPublicKeyImpl(
338-
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
337+
type, rsaSpec.getParams(),
339338
rsaSpec.getModulus(),
340339
rsaSpec.getPublicExponent()
341340
);
@@ -355,13 +354,13 @@ private PrivateKey generatePrivate(KeySpec keySpec)
355354
PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec;
356355
RSAPrivateKey generated = RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded());
357356
// ensure the key algorithm matches the current KeyFactory instance
358-
checkKeyAlgo(generated, type.keyAlgo());
357+
checkKeyAlgo(generated, type.keyAlgo);
359358
return generated;
360359
} else if (keySpec instanceof RSAPrivateCrtKeySpec) {
361360
RSAPrivateCrtKeySpec rsaSpec = (RSAPrivateCrtKeySpec)keySpec;
362361
try {
363362
return new RSAPrivateCrtKeyImpl(
364-
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
363+
type, rsaSpec.getParams(),
365364
rsaSpec.getModulus(),
366365
rsaSpec.getPublicExponent(),
367366
rsaSpec.getPrivateExponent(),
@@ -378,7 +377,7 @@ private PrivateKey generatePrivate(KeySpec keySpec)
378377
RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec;
379378
try {
380379
return new RSAPrivateKeyImpl(
381-
RSAUtil.createAlgorithmId(type, rsaSpec.getParams()),
380+
type, rsaSpec.getParams(),
382381
rsaSpec.getModulus(),
383382
rsaSpec.getPrivateExponent()
384383
);

src/java.base/share/classes/sun/security/rsa/RSAKeyPairGenerator.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@
3232
import java.security.spec.RSAKeyGenParameterSpec;
3333

3434
import sun.security.jca.JCAUtil;
35+
import sun.security.rsa.RSAUtil.KeyType;
36+
3537
import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
3638
import static sun.security.util.SecurityProviderConstants.DEF_RSASSA_PSS_KEY_SIZE;
37-
import sun.security.x509.AlgorithmId;
38-
import static sun.security.rsa.RSAUtil.KeyType;
3939

4040
/**
4141
* RSA keypair generation. Standard algorithm, minimum key length 512 bit.
@@ -55,7 +55,7 @@ public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
5555
private int keySize;
5656

5757
private final KeyType type;
58-
private AlgorithmId rsaId;
58+
private AlgorithmParameterSpec keyParams;
5959

6060
// PRNG to use
6161
private SecureRandom random;
@@ -116,7 +116,7 @@ public void initialize(AlgorithmParameterSpec params, SecureRandom random)
116116
}
117117

118118
try {
119-
this.rsaId = RSAUtil.createAlgorithmId(type, tmpParams);
119+
this.keyParams = RSAUtil.checkParamsAgainstType(type, tmpParams);
120120
} catch (ProviderException e) {
121121
throw new InvalidAlgorithmParameterException(
122122
"Invalid key parameters", e);
@@ -177,9 +177,10 @@ public KeyPair generateKeyPair() {
177177
BigInteger coeff = q.modInverse(p);
178178

179179
try {
180-
PublicKey publicKey = new RSAPublicKeyImpl(rsaId, n, e);
181-
PrivateKey privateKey = new RSAPrivateCrtKeyImpl(
182-
rsaId, n, e, d, p, q, pe, qe, coeff);
180+
PublicKey publicKey = new RSAPublicKeyImpl(type, keyParams,
181+
n, e);
182+
PrivateKey privateKey = new RSAPrivateCrtKeyImpl(type,
183+
keyParams, n, e, d, p, q, pe, qe, coeff);
183184
return new KeyPair(publicKey, privateKey);
184185
} catch (InvalidKeyException exc) {
185186
// invalid key exception only thrown for keys < 512 bit,

src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -34,10 +34,9 @@
3434

3535
import sun.security.util.*;
3636

37-
import sun.security.x509.AlgorithmId;
3837
import sun.security.pkcs.PKCS8Key;
3938

40-
import static sun.security.rsa.RSAUtil.KeyType;
39+
import sun.security.rsa.RSAUtil.KeyType;
4140

4241
/**
4342
* RSA private key implementation for "RSA", "RSASSA-PSS" algorithms in CRT form.
@@ -66,10 +65,12 @@ public final class RSAPrivateCrtKeyImpl
6665
private BigInteger qe; // prime exponent q
6766
private BigInteger coeff; // CRT coeffcient
6867

68+
private transient KeyType type;
69+
6970
// Optional parameters associated with this RSA key
7071
// specified in the encoding of its AlgorithmId.
7172
// Must be null for "RSA" keys.
72-
private AlgorithmParameterSpec keyParams;
73+
private transient AlgorithmParameterSpec keyParams;
7374

7475
/**
7576
* Generate a new key from its encoding. Returns a CRT key if possible
@@ -84,7 +85,7 @@ public static RSAPrivateKey newKey(byte[] encoded)
8485
return key;
8586
} else {
8687
return new RSAPrivateKeyImpl(
87-
key.algid,
88+
key.type, key.keyParams,
8889
key.getModulus(),
8990
key.getPrivateExponent());
9091
}
@@ -113,14 +114,13 @@ public static RSAPrivateKey newKey(KeyType type,
113114
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
114115
BigInteger coeff) throws InvalidKeyException {
115116
RSAPrivateKey key;
116-
AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params);
117117
if ((e.signum() == 0) || (p.signum() == 0) ||
118118
(q.signum() == 0) || (pe.signum() == 0) ||
119119
(qe.signum() == 0) || (coeff.signum() == 0)) {
120120
// if any component is missing, return a non-CRT key
121-
return new RSAPrivateKeyImpl(rsaId, n, d);
121+
return new RSAPrivateKeyImpl(type, params, n, d);
122122
} else {
123-
return new RSAPrivateCrtKeyImpl(rsaId, n, e, d,
123+
return new RSAPrivateCrtKeyImpl(type, params, n, e, d,
124124
p, q, pe, qe, coeff);
125125
}
126126
}
@@ -136,8 +136,10 @@ public static RSAPrivateKey newKey(KeyType type,
136136
decode(encoded);
137137
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
138138
try {
139-
// this will check the validity of params
140-
this.keyParams = RSAUtil.getParamSpec(algid);
139+
// check the validity of oid and params
140+
Object[] o = RSAUtil.getTypeAndParamSpec(algid);
141+
this.type = (KeyType) o[0];
142+
this.keyParams = (AlgorithmParameterSpec) o[1];
141143
} catch (ProviderException e) {
142144
throw new InvalidKeyException(e);
143145
}
@@ -147,7 +149,7 @@ public static RSAPrivateKey newKey(KeyType type,
147149
* Construct a RSA key from its components. Used by the
148150
* RSAKeyFactory and the RSAKeyPairGenerator.
149151
*/
150-
RSAPrivateCrtKeyImpl(AlgorithmId rsaId,
152+
RSAPrivateCrtKeyImpl(KeyType type, AlgorithmParameterSpec keyParams,
151153
BigInteger n, BigInteger e, BigInteger d,
152154
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
153155
BigInteger coeff) throws InvalidKeyException {
@@ -161,11 +163,19 @@ public static RSAPrivateKey newKey(KeyType type,
161163
this.pe = pe;
162164
this.qe = qe;
163165
this.coeff = coeff;
164-
this.keyParams = RSAUtil.getParamSpec(rsaId);
165166

166-
// generate the encoding
167-
algid = rsaId;
168167
try {
168+
// validate and generate the algid encoding
169+
algid = RSAUtil.createAlgorithmId(type, keyParams);
170+
} catch (ProviderException exc) {
171+
throw new InvalidKeyException(exc);
172+
}
173+
174+
this.type = type;
175+
this.keyParams = keyParams;
176+
177+
try {
178+
// generate the key encoding
169179
DerOutputStream out = new DerOutputStream();
170180
out.putInteger(0); // version must be 0
171181
out.putInteger(n);
@@ -188,7 +198,7 @@ public static RSAPrivateKey newKey(KeyType type,
188198
// see JCA doc
189199
@Override
190200
public String getAlgorithm() {
191-
return algid.getName();
201+
return type.keyAlgo;
192202
}
193203

194204
// see JCA doc
@@ -248,9 +258,9 @@ public AlgorithmParameterSpec getParams() {
248258
// return a string representation of this key for debugging
249259
@Override
250260
public String toString() {
251-
return "SunRsaSign " + getAlgorithm() + " private CRT key, " + n.bitLength()
252-
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
253-
+ "\n private exponent: " + d;
261+
return "SunRsaSign " + type.keyAlgo + " private CRT key, "
262+
+ n.bitLength() + " bits" + "\n params: " + keyParams
263+
+ "\n modulus: " + n + "\n private exponent: " + d;
254264
}
255265

256266
/**

src/java.base/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -33,9 +33,10 @@
3333
import java.security.interfaces.*;
3434

3535
import sun.security.util.*;
36-
import sun.security.x509.AlgorithmId;
3736
import sun.security.pkcs.PKCS8Key;
3837

38+
import sun.security.rsa.RSAUtil.KeyType;
39+
3940
/**
4041
* RSA private key implementation for "RSA", "RSASSA-PSS" algorithms in non-CRT
4142
* form (modulus, private exponent only). For CRT private keys, see
@@ -57,26 +58,37 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
5758
private final BigInteger n; // modulus
5859
private final BigInteger d; // private exponent
5960

61+
private transient final KeyType type;
62+
6063
// optional parameters associated with this RSA key
6164
// specified in the encoding of its AlgorithmId.
6265
// must be null for "RSA" keys.
63-
private final AlgorithmParameterSpec keyParams;
66+
private transient final AlgorithmParameterSpec keyParams;
6467

6568
/**
6669
* Construct a key from its components. Used by the
6770
* RSAKeyFactory and the RSAKeyPairGenerator.
6871
*/
69-
RSAPrivateKeyImpl(AlgorithmId rsaId, BigInteger n, BigInteger d)
70-
throws InvalidKeyException {
72+
RSAPrivateKeyImpl(KeyType type, AlgorithmParameterSpec keyParams,
73+
BigInteger n, BigInteger d) throws InvalidKeyException {
74+
7175
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), null);
7276

7377
this.n = n;
7478
this.d = d;
75-
this.keyParams = RSAUtil.getParamSpec(rsaId);
7679

77-
// generate the encoding
78-
algid = rsaId;
7980
try {
81+
// validate and generate the algid encoding
82+
algid = RSAUtil.createAlgorithmId(type, keyParams);
83+
} catch (ProviderException pe) {
84+
throw new InvalidKeyException(pe);
85+
}
86+
87+
this.type = type;
88+
this.keyParams = keyParams;
89+
90+
try {
91+
// generate the key encoding
8092
DerOutputStream out = new DerOutputStream();
8193
out.putInteger(0); // version must be 0
8294
out.putInteger(n);
@@ -99,7 +111,7 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
99111
// see JCA doc
100112
@Override
101113
public String getAlgorithm() {
102-
return algid.getName();
114+
return type.keyAlgo;
103115
}
104116

105117
// see JCA doc
@@ -123,7 +135,7 @@ public AlgorithmParameterSpec getParams() {
123135
// return a string representation of this key for debugging
124136
@Override
125137
public String toString() {
126-
return "Sun " + getAlgorithm() + " private key, " + n.bitLength()
138+
return "Sun " + type.keyAlgo + " private key, " + n.bitLength()
127139
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
128140
+ "\n private exponent: " + d;
129141
}

0 commit comments

Comments
 (0)