Skip to content

Commit 56b7960

Browse files
author
Valerie Peng
committedJun 3, 2020
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
1 parent 563ce12 commit 56b7960

File tree

9 files changed

+281
-166
lines changed

9 files changed

+281
-166
lines changed
 

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

+12-13
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

+8-7
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

+28-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, 2019, 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.
@@ -67,11 +66,12 @@ public final class RSAPrivateCrtKeyImpl
6766
private BigInteger qe; // prime exponent q
6867
private BigInteger coeff; // CRT coeffcient
6968

69+
private transient KeyType type;
70+
7071
// Optional parameters associated with this RSA key
7172
// specified in the encoding of its AlgorithmId.
7273
// Must be null for "RSA" keys.
73-
@SuppressWarnings("serial") // Not statically typed as Serializable
74-
private AlgorithmParameterSpec keyParams;
74+
private transient AlgorithmParameterSpec keyParams;
7575

7676
/**
7777
* Generate a new key from its encoding. Returns a CRT key if possible
@@ -89,7 +89,7 @@ public static RSAPrivateKey newKey(byte[] encoded)
8989
(key.getPrimeQ().signum() == 0) ||
9090
(key.getCrtCoefficient().signum() == 0)) {
9191
return new RSAPrivateKeyImpl(
92-
key.algid,
92+
key.type, key.keyParams,
9393
key.getModulus(),
9494
key.getPrivateExponent()
9595
);
@@ -109,14 +109,13 @@ public static RSAPrivateKey newKey(KeyType type,
109109
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
110110
BigInteger coeff) throws InvalidKeyException {
111111
RSAPrivateKey key;
112-
AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params);
113112
if ((e.signum() == 0) || (p.signum() == 0) ||
114113
(q.signum() == 0) || (pe.signum() == 0) ||
115114
(qe.signum() == 0) || (coeff.signum() == 0)) {
116115
// if any component is missing, return a non-CRT key
117-
return new RSAPrivateKeyImpl(rsaId, n, d);
116+
return new RSAPrivateKeyImpl(type, params, n, d);
118117
} else {
119-
return new RSAPrivateCrtKeyImpl(rsaId, n, e, d,
118+
return new RSAPrivateCrtKeyImpl(type, params, n, e, d,
120119
p, q, pe, qe, coeff);
121120
}
122121
}
@@ -132,8 +131,10 @@ public static RSAPrivateKey newKey(KeyType type,
132131
decode(encoded);
133132
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
134133
try {
135-
// this will check the validity of params
136-
this.keyParams = RSAUtil.getParamSpec(algid);
134+
// check the validity of oid and params
135+
Object[] o = RSAUtil.getTypeAndParamSpec(algid);
136+
this.type = (KeyType) o[0];
137+
this.keyParams = (AlgorithmParameterSpec) o[1];
137138
} catch (ProviderException e) {
138139
throw new InvalidKeyException(e);
139140
}
@@ -143,7 +144,7 @@ public static RSAPrivateKey newKey(KeyType type,
143144
* Construct a RSA key from its components. Used by the
144145
* RSAKeyFactory and the RSAKeyPairGenerator.
145146
*/
146-
RSAPrivateCrtKeyImpl(AlgorithmId rsaId,
147+
RSAPrivateCrtKeyImpl(KeyType type, AlgorithmParameterSpec keyParams,
147148
BigInteger n, BigInteger e, BigInteger d,
148149
BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,
149150
BigInteger coeff) throws InvalidKeyException {
@@ -157,11 +158,19 @@ public static RSAPrivateKey newKey(KeyType type,
157158
this.pe = pe;
158159
this.qe = qe;
159160
this.coeff = coeff;
160-
this.keyParams = RSAUtil.getParamSpec(rsaId);
161161

162-
// generate the encoding
163-
algid = rsaId;
164162
try {
163+
// validate and generate the algid encoding
164+
algid = RSAUtil.createAlgorithmId(type, keyParams);
165+
} catch (ProviderException exc) {
166+
throw new InvalidKeyException(exc);
167+
}
168+
169+
this.type = type;
170+
this.keyParams = keyParams;
171+
172+
try {
173+
// generate the key encoding
165174
DerOutputStream out = new DerOutputStream();
166175
out.putInteger(0); // version must be 0
167176
out.putInteger(n);
@@ -184,7 +193,7 @@ public static RSAPrivateKey newKey(KeyType type,
184193
// see JCA doc
185194
@Override
186195
public String getAlgorithm() {
187-
return algid.getName();
196+
return type.keyAlgo;
188197
}
189198

190199
// see JCA doc
@@ -244,9 +253,9 @@ public AlgorithmParameterSpec getParams() {
244253
// return a string representation of this key for debugging
245254
@Override
246255
public String toString() {
247-
return "SunRsaSign " + getAlgorithm() + " private CRT key, " + n.bitLength()
248-
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
249-
+ "\n private exponent: " + d;
256+
return "SunRsaSign " + type.keyAlgo + " private CRT key, "
257+
+ n.bitLength() + " bits" + "\n params: " + keyParams
258+
+ "\n modulus: " + n + "\n private exponent: " + d;
250259
}
251260

252261
/**

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

+22-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, 2019, 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
@@ -58,27 +59,37 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
5859
private final BigInteger n; // modulus
5960
private final BigInteger d; // private exponent
6061

62+
private transient final KeyType type;
63+
6164
// optional parameters associated with this RSA key
6265
// specified in the encoding of its AlgorithmId.
6366
// must be null for "RSA" keys.
64-
@SuppressWarnings("serial") // Not statically typed as Serializable
65-
private final AlgorithmParameterSpec keyParams;
67+
private transient final AlgorithmParameterSpec keyParams;
6668

6769
/**
6870
* Construct a key from its components. Used by the
6971
* RSAKeyFactory and the RSAKeyPairGenerator.
7072
*/
71-
RSAPrivateKeyImpl(AlgorithmId rsaId, BigInteger n, BigInteger d)
72-
throws InvalidKeyException {
73+
RSAPrivateKeyImpl(KeyType type, AlgorithmParameterSpec keyParams,
74+
BigInteger n, BigInteger d) throws InvalidKeyException {
75+
7376
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), null);
7477

7578
this.n = n;
7679
this.d = d;
77-
this.keyParams = RSAUtil.getParamSpec(rsaId);
7880

79-
// generate the encoding
80-
algid = rsaId;
8181
try {
82+
// validate and generate the algid encoding
83+
algid = RSAUtil.createAlgorithmId(type, keyParams);
84+
} catch (ProviderException pe) {
85+
throw new InvalidKeyException(pe);
86+
}
87+
88+
this.type = type;
89+
this.keyParams = keyParams;
90+
91+
try {
92+
// generate the key encoding
8293
DerOutputStream out = new DerOutputStream();
8394
out.putInteger(0); // version must be 0
8495
out.putInteger(n);
@@ -101,7 +112,7 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
101112
// see JCA doc
102113
@Override
103114
public String getAlgorithm() {
104-
return algid.getName();
115+
return type.keyAlgo;
105116
}
106117

107118
// see JCA doc
@@ -125,7 +136,7 @@ public AlgorithmParameterSpec getParams() {
125136
// return a string representation of this key for debugging
126137
@Override
127138
public String toString() {
128-
return "Sun " + getAlgorithm() + " private key, " + n.bitLength()
139+
return "Sun " + type.keyAlgo + " private key, " + n.bitLength()
129140
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
130141
+ "\n private exponent: " + d;
131142
}

‎src/java.base/share/classes/sun/security/rsa/RSAPublicKeyImpl.java

+27-17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, 2019, 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,9 +34,8 @@
3434

3535
import sun.security.util.*;
3636
import sun.security.x509.X509Key;
37-
import sun.security.x509.AlgorithmId;
3837

39-
import static sun.security.rsa.RSAUtil.KeyType;
38+
import sun.security.rsa.RSAUtil.KeyType;
4039

4140
/**
4241
* RSA public key implementation for "RSA", "RSASSA-PSS" algorithms.
@@ -59,11 +58,12 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
5958
private BigInteger n; // modulus
6059
private BigInteger e; // public exponent
6160

61+
private transient KeyType type;
62+
6263
// optional parameters associated with this RSA key
6364
// specified in the encoding of its AlgorithmId
6465
// must be null for "RSA" keys.
65-
@SuppressWarnings("serial") // Not statically typed as Serializable
66-
private AlgorithmParameterSpec keyParams;
66+
private transient AlgorithmParameterSpec keyParams;
6767

6868
/**
6969
* Generate a new RSAPublicKey from the specified encoding.
@@ -81,26 +81,34 @@ public static RSAPublicKey newKey(byte[] encoded)
8181
public static RSAPublicKey newKey(KeyType type,
8282
AlgorithmParameterSpec params, BigInteger n, BigInteger e)
8383
throws InvalidKeyException {
84-
AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params);
85-
return new RSAPublicKeyImpl(rsaId, n, e);
84+
return new RSAPublicKeyImpl(type, params, n, e);
8685
}
8786

8887
/**
89-
* Construct a RSA key from AlgorithmId and its components. Used by
88+
* Construct a RSA key from the specified type and components. Used by
9089
* RSAKeyFactory and RSAKeyPairGenerator.
9190
*/
92-
RSAPublicKeyImpl(AlgorithmId rsaId, BigInteger n, BigInteger e)
93-
throws InvalidKeyException {
91+
RSAPublicKeyImpl(KeyType type, AlgorithmParameterSpec keyParams,
92+
BigInteger n, BigInteger e) throws InvalidKeyException {
93+
9494
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
9595
checkExponentRange(n, e);
9696

9797
this.n = n;
9898
this.e = e;
99-
this.keyParams = RSAUtil.getParamSpec(rsaId);
10099

101-
// generate the encoding
102-
algid = rsaId;
103100
try {
101+
// validate and generate algid encoding
102+
algid = RSAUtil.createAlgorithmId(type, keyParams);
103+
} catch (ProviderException pe) {
104+
throw new InvalidKeyException(pe);
105+
}
106+
107+
this.type = type;
108+
this.keyParams = keyParams;
109+
110+
try {
111+
// generate the key encoding
104112
DerOutputStream out = new DerOutputStream();
105113
out.putInteger(n);
106114
out.putInteger(e);
@@ -126,8 +134,10 @@ public static RSAPublicKey newKey(KeyType type,
126134
checkExponentRange(n, e);
127135

128136
try {
129-
// this will check the validity of params
130-
this.keyParams = RSAUtil.getParamSpec(algid);
137+
// check the validity of oid and params
138+
Object[] o = RSAUtil.getTypeAndParamSpec(algid);
139+
this.type = (KeyType) o[0];
140+
this.keyParams = (AlgorithmParameterSpec) o[1];
131141
} catch (ProviderException e) {
132142
throw new InvalidKeyException(e);
133143
}
@@ -150,7 +160,7 @@ static void checkExponentRange(BigInteger mod, BigInteger exp)
150160
// see JCA doc
151161
@Override
152162
public String getAlgorithm() {
153-
return algid.getName();
163+
return type.keyAlgo;
154164
}
155165

156166
// see JCA doc
@@ -195,7 +205,7 @@ protected void parseKeyBits() throws InvalidKeyException {
195205
// return a string representation of this key for debugging
196206
@Override
197207
public String toString() {
198-
return "Sun " + getAlgorithm() + " public key, " + n.bitLength()
208+
return "Sun " + type.keyAlgo + " public key, " + n.bitLength()
199209
+ " bits" + "\n params: " + keyParams + "\n modulus: " + n
200210
+ "\n public exponent: " + e;
201211
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 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
@@ -40,52 +40,71 @@
4040
public class RSAUtil {
4141

4242
public enum KeyType {
43-
RSA ("RSA"),
44-
PSS ("RSASSA-PSS")
43+
RSA ("RSA", AlgorithmId.RSAEncryption_oid, null),
44+
PSS ("RSASSA-PSS", AlgorithmId.RSASSA_PSS_oid, PSSParameterSpec.class)
4545
;
4646

47-
private final String algo;
47+
final String keyAlgo;
48+
final ObjectIdentifier oid;
49+
final Class<? extends AlgorithmParameterSpec> paramSpecCls;
4850

49-
KeyType(String keyAlgo) {
50-
this.algo = keyAlgo;
51+
KeyType(String keyAlgo, ObjectIdentifier oid,
52+
Class<? extends AlgorithmParameterSpec> paramSpecCls) {
53+
this.keyAlgo = keyAlgo;
54+
this.oid = oid;
55+
this.paramSpecCls = paramSpecCls;
5156
}
52-
public String keyAlgo() {
53-
return algo;
54-
}
55-
public static KeyType lookup(String name)
56-
throws InvalidKeyException, ProviderException {
57-
if (name == null) {
58-
throw new InvalidKeyException("Null key algorithm");
59-
}
60-
for (KeyType kt : KeyType.values()) {
61-
if (kt.keyAlgo().equalsIgnoreCase(name)) {
62-
return kt;
63-
}
57+
58+
public static KeyType lookup(String name) throws ProviderException {
59+
60+
requireNonNull(name, "Key algorithm should not be null");
61+
62+
// match loosely in order to work with 3rd party providers which
63+
// may not follow the standard names
64+
if (name.indexOf("PSS") != -1) {
65+
return PSS;
66+
} else if (name.indexOf("RSA") != -1) {
67+
return RSA;
68+
} else { // no match
69+
throw new ProviderException("Unsupported algorithm " + name);
6470
}
65-
// no match
66-
throw new ProviderException("Unsupported algorithm " + name);
6771
}
6872
}
6973

70-
public static void checkParamsAgainstType(KeyType type,
74+
private static void requireNonNull(Object obj, String msg) {
75+
if (obj == null) throw new ProviderException(msg);
76+
}
77+
78+
public static AlgorithmParameterSpec checkParamsAgainstType(KeyType type,
7179
AlgorithmParameterSpec paramSpec) throws ProviderException {
72-
switch (type) {
73-
case RSA:
74-
if (paramSpec != null) {
75-
throw new ProviderException("null params expected for " +
76-
type.keyAlgo());
77-
}
78-
break;
79-
case PSS:
80-
if ((paramSpec != null) &&
81-
!(paramSpec instanceof PSSParameterSpec)) {
82-
throw new ProviderException
83-
("PSSParmeterSpec expected for " + type.keyAlgo());
84-
}
85-
break;
86-
default:
87-
throw new ProviderException
88-
("Unsupported RSA algorithm " + type);
80+
81+
// currently no check for null parameter spec
82+
// assumption is parameter spec is optional and can be null
83+
if (paramSpec == null) return null;
84+
85+
Class<? extends AlgorithmParameterSpec> expCls = type.paramSpecCls;
86+
if (expCls == null) {
87+
throw new ProviderException("null params expected for " +
88+
type.keyAlgo);
89+
} else if (!expCls.isInstance(paramSpec)) {
90+
throw new ProviderException
91+
(expCls + " expected for " + type.keyAlgo);
92+
}
93+
return paramSpec;
94+
}
95+
96+
public static AlgorithmParameters getParams(KeyType type,
97+
AlgorithmParameterSpec spec) throws ProviderException {
98+
99+
if (spec == null) return null;
100+
101+
try {
102+
AlgorithmParameters params =
103+
AlgorithmParameters.getInstance(type.keyAlgo);
104+
params.init(spec);
105+
return params;
106+
} catch (NoSuchAlgorithmException | InvalidParameterSpecException ex) {
107+
throw new ProviderException(ex);
89108
}
90109
}
91110

@@ -94,69 +113,53 @@ public static AlgorithmId createAlgorithmId(KeyType type,
94113

95114
checkParamsAgainstType(type, paramSpec);
96115

97-
ObjectIdentifier oid = null;
98-
AlgorithmParameters params = null;
99-
try {
100-
switch (type) {
101-
case RSA:
102-
oid = AlgorithmId.RSAEncryption_oid;
103-
break;
104-
case PSS:
105-
if (paramSpec != null) {
106-
params = AlgorithmParameters.getInstance(type.keyAlgo());
107-
params.init(paramSpec);
108-
}
109-
oid = AlgorithmId.RSASSA_PSS_oid;
110-
break;
111-
default:
112-
throw new ProviderException
113-
("Unsupported RSA algorithm " + type);
114-
}
115-
AlgorithmId result;
116-
if (params == null) {
117-
result = new AlgorithmId(oid);
118-
} else {
119-
result = new AlgorithmId(oid, params);
120-
}
121-
return result;
122-
} catch (NoSuchAlgorithmException | InvalidParameterSpecException e) {
123-
// should not happen
124-
throw new ProviderException(e);
125-
}
116+
ObjectIdentifier oid = type.oid;
117+
AlgorithmParameters params = getParams(type, paramSpec);
118+
return new AlgorithmId(oid, params);
126119
}
127120

128-
public static AlgorithmParameterSpec getParamSpec(AlgorithmId algid)
129-
throws ProviderException {
130-
if (algid == null) {
131-
throw new ProviderException("AlgorithmId should not be null");
121+
public static AlgorithmParameterSpec getParamSpec(
122+
AlgorithmParameters params) throws ProviderException {
123+
124+
if (params == null) return null;
125+
126+
String algName = params.getAlgorithm();
127+
128+
KeyType type = KeyType.lookup(algName);
129+
Class<? extends AlgorithmParameterSpec> specCls = type.paramSpecCls;
130+
if (specCls == null) {
131+
throw new ProviderException("No params accepted for " +
132+
type.keyAlgo);
133+
}
134+
try {
135+
return params.getParameterSpec(specCls);
136+
} catch (InvalidParameterSpecException ex) {
137+
throw new ProviderException(ex);
132138
}
133-
return getParamSpec(algid.getParameters());
134139
}
135140

136-
public static AlgorithmParameterSpec getParamSpec(AlgorithmParameters params)
141+
public static Object[] getTypeAndParamSpec(AlgorithmId algid)
137142
throws ProviderException {
138-
if (params == null) return null;
139143

144+
requireNonNull(algid, "AlgorithmId should not be null");
145+
146+
Object[] result = new Object[2];
147+
148+
String algName = algid.getName();
140149
try {
141-
String algName = params.getAlgorithm();
142-
KeyType type = KeyType.lookup(algName);
143-
Class<? extends AlgorithmParameterSpec> specCls;
144-
switch (type) {
145-
case RSA:
146-
throw new ProviderException("No params accepted for " +
147-
type.keyAlgo());
148-
case PSS:
149-
specCls = PSSParameterSpec.class;
150-
break;
151-
default:
152-
throw new ProviderException("Unsupported RSA algorithm: " + algName);
153-
}
154-
return params.getParameterSpec(specCls);
150+
result[0] = KeyType.lookup(algName);
155151
} catch (ProviderException pe) {
156-
// pass it up
157-
throw pe;
158-
} catch (Exception e) {
159-
throw new ProviderException(e);
152+
// accommodate RSA keys encoded with various RSA signature oids
153+
// for backward compatibility
154+
if (algName.indexOf("RSA") != -1) {
155+
result[0] = KeyType.RSA;
156+
} else {
157+
// pass it up
158+
throw pe;
159+
}
160160
}
161+
162+
result[1] = getParamSpec(algid.getParameters());
163+
return result;
161164
}
162165
}

‎src/java.base/share/classes/sun/security/util/KnownOIDs.java

+5
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,11 @@ public enum KnownOIDs {
355355
boolean registerNames() { return false; }
356356
},
357357

358+
OIW_SHA1withRSA_Odd("1.3.14.3.2.15", "SHA1withRSA") {
359+
@Override
360+
boolean registerNames() { return false; }
361+
},
362+
358363
SHA_1("1.3.14.3.2.26", "SHA-1", "SHA", "SHA1"),
359364

360365
OIW_SHA1withDSA("1.3.14.3.2.27", "SHA1withDSA") {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/**
25+
* @test
26+
* @bug 8242897
27+
* @summary Ensure that RSA key factory can parse X.509 encodings containing
28+
* non-standard RSA oid as in older JDK releases before JDK-8146293
29+
* @run main TestRSAOidSupport
30+
*/
31+
32+
import java.security.KeyFactory;
33+
import java.security.interfaces.RSAPublicKey;
34+
import java.security.spec.X509EncodedKeySpec;
35+
import java.security.spec.InvalidKeySpecException;
36+
37+
public class TestRSAOidSupport {
38+
39+
// SubjectKeyInfo DER encoding w/ Algorithm id 1.3.14.3.2.15
40+
// which can be used to generate RSA Public Key before PSS
41+
// support is added
42+
private static String DER_BYTES =
43+
"3058300906052b0e03020f0500034b003048024100d7157c65e8f22557d8" +
44+
"a857122cfe85bddfaba3064c21b345e2a7cdd8a6751e519ab861c5109fb8" +
45+
"8cce45d161b9817bc0eccdc30fda69e62cc577775f2c1d66bd0203010001";
46+
47+
// utility method for converting hex string to byte array
48+
static byte[] toByteArray(String s) {
49+
byte[] bytes = new byte[s.length() / 2];
50+
for (int i = 0; i < bytes.length; i++) {
51+
int index = i * 2;
52+
int v = Integer.parseInt(s.substring(index, index + 2), 16);
53+
bytes[i] = (byte) v;
54+
}
55+
return bytes;
56+
}
57+
58+
public static void main(String[] args) throws Exception {
59+
X509EncodedKeySpec x509Spec = new X509EncodedKeySpec
60+
(toByteArray(DER_BYTES));
61+
String keyAlgo = "RSA";
62+
KeyFactory kf = KeyFactory.getInstance(keyAlgo, "SunRsaSign");
63+
RSAPublicKey rsaKey = (RSAPublicKey) kf.generatePublic(x509Spec);
64+
65+
if (rsaKey.getAlgorithm() != keyAlgo) {
66+
throw new RuntimeException("Key algo should be " + keyAlgo +
67+
", but got " + rsaKey.getAlgorithm());
68+
}
69+
kf = KeyFactory.getInstance("RSASSA-PSS", "SunRsaSign");
70+
try {
71+
kf.generatePublic(x509Spec);
72+
throw new RuntimeException("Should throw IKSE");
73+
} catch (InvalidKeySpecException ikse) {
74+
System.out.println("Expected IKSE exception thrown");
75+
}
76+
}
77+
}
78+

‎test/jdk/sun/security/tools/keytool/fakegen/java.base/sun/security/rsa/RSAKeyPairGenerator.java

+6-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 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
@@ -29,8 +29,7 @@
2929
import java.security.spec.AlgorithmParameterSpec;
3030
import java.security.spec.RSAKeyGenParameterSpec;
3131

32-
import sun.security.x509.AlgorithmId;
33-
import static sun.security.rsa.RSAUtil.KeyType;
32+
import sun.security.rsa.RSAUtil.KeyType;
3433

3534
/**
3635
* A fake RSA keypair generation.
@@ -44,7 +43,7 @@ public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
4443
private int keySize;
4544

4645
private final KeyType type;
47-
private AlgorithmId rsaId;
46+
private AlgorithmParameterSpec keyParams;
4847

4948
RSAKeyPairGenerator(KeyType type, int defKeySize) {
5049
this.type = type;
@@ -98,7 +97,7 @@ public void initialize(AlgorithmParameterSpec params, SecureRandom random)
9897
}
9998

10099
try {
101-
this.rsaId = RSAUtil.createAlgorithmId(type, tmpParams);
100+
this.keyParams = RSAUtil.checkParamsAgainstType(type, tmpParams);
102101
} catch (ProviderException e) {
103102
throw new InvalidAlgorithmParameterException(
104103
"Invalid key parameters", e);
@@ -436,9 +435,9 @@ public KeyPair generateKeyPair() {
436435
BigInteger coeff = q.modInverse(p);
437436

438437
try {
439-
PublicKey publicKey = new RSAPublicKeyImpl(rsaId, n, e);
438+
PublicKey publicKey = new RSAPublicKeyImpl(type, keyParams, n, e);
440439
PrivateKey privateKey = new RSAPrivateCrtKeyImpl(
441-
rsaId, n, e, d, p, q, pe, qe, coeff);
440+
type, keyParams, n, e, d, p, q, pe, qe, coeff);
442441
return new KeyPair(publicKey, privateKey);
443442
} catch (InvalidKeyException exc) {
444443
// invalid key exception only thrown for keys < 512 bit,

0 commit comments

Comments
 (0)
Please sign in to comment.