提交 17a9da6b 编写于 作者: W wetmore

6497740: Limit the size of RSA public keys

Reviewed-by: andreas, valeriep, vinnie
上级 b214a3f2
/* /*
* Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2008 Sun Microsystems, Inc. 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
...@@ -38,6 +38,8 @@ import static sun.security.pkcs11.TemplateManager.*; ...@@ -38,6 +38,8 @@ import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*; import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import sun.security.rsa.RSAKeyFactory;
/** /**
* KeyPairGenerator implementation class. This class currently supports * KeyPairGenerator implementation class. This class currently supports
* RSA, DSA, DH, and EC. * RSA, DSA, DH, and EC.
...@@ -66,7 +68,7 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -66,7 +68,7 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
private AlgorithmParameterSpec params; private AlgorithmParameterSpec params;
// for RSA, selected or default value of public exponent, always valid // for RSA, selected or default value of public exponent, always valid
private BigInteger rsaPublicExponent; private BigInteger rsaPublicExponent = RSAKeyGenParameterSpec.F4;
// SecureRandom instance, if specified in init // SecureRandom instance, if specified in init
private SecureRandom random; private SecureRandom random;
...@@ -88,19 +90,19 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -88,19 +90,19 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
public void initialize(int keySize, SecureRandom random) { public void initialize(int keySize, SecureRandom random) {
token.ensureValid(); token.ensureValid();
try { try {
checkKeySize(keySize); checkKeySize(keySize, null);
} catch (InvalidAlgorithmParameterException e) { } catch (InvalidAlgorithmParameterException e) {
throw new InvalidParameterException(e.getMessage()); throw new InvalidParameterException(e.getMessage());
} }
this.keySize = keySize; this.keySize = keySize;
this.params = null; this.params = null;
this.random = random; this.random = random;
this.rsaPublicExponent = RSAKeyGenParameterSpec.F4;
if (algorithm.equals("EC")) { if (algorithm.equals("EC")) {
params = P11ECKeyFactory.getECParameterSpec(keySize); params = P11ECKeyFactory.getECParameterSpec(keySize);
if (params == null) { if (params == null) {
throw new InvalidParameterException throw new InvalidParameterException(
("No EC parameters available for key size " + keySize + " bits"); "No EC parameters available for key size "
+ keySize + " bits");
} }
} }
} }
...@@ -115,8 +117,10 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -115,8 +117,10 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
("DHParameterSpec required for Diffie-Hellman"); ("DHParameterSpec required for Diffie-Hellman");
} }
DHParameterSpec dhParams = (DHParameterSpec)params; DHParameterSpec dhParams = (DHParameterSpec)params;
this.keySize = dhParams.getP().bitLength(); int tmpKeySize = dhParams.getP().bitLength();
this.params = params; checkKeySize(tmpKeySize, dhParams);
this.keySize = tmpKeySize;
this.params = dhParams;
// XXX sanity check params // XXX sanity check params
} else if (algorithm.equals("RSA")) { } else if (algorithm.equals("RSA")) {
if (params instanceof RSAKeyGenParameterSpec == false) { if (params instanceof RSAKeyGenParameterSpec == false) {
...@@ -124,7 +128,9 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -124,7 +128,9 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
("RSAKeyGenParameterSpec required for RSA"); ("RSAKeyGenParameterSpec required for RSA");
} }
RSAKeyGenParameterSpec rsaParams = (RSAKeyGenParameterSpec)params; RSAKeyGenParameterSpec rsaParams = (RSAKeyGenParameterSpec)params;
this.keySize = rsaParams.getKeysize(); int tmpKeySize = rsaParams.getKeysize();
checkKeySize(tmpKeySize, rsaParams);
this.keySize = tmpKeySize;
this.params = null; this.params = null;
this.rsaPublicExponent = rsaParams.getPublicExponent(); this.rsaPublicExponent = rsaParams.getPublicExponent();
// XXX sanity check params // XXX sanity check params
...@@ -134,13 +140,16 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -134,13 +140,16 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
("DSAParameterSpec required for DSA"); ("DSAParameterSpec required for DSA");
} }
DSAParameterSpec dsaParams = (DSAParameterSpec)params; DSAParameterSpec dsaParams = (DSAParameterSpec)params;
this.keySize = dsaParams.getP().bitLength(); int tmpKeySize = dsaParams.getP().bitLength();
this.params = params; checkKeySize(tmpKeySize, dsaParams);
this.keySize = tmpKeySize;
this.params = dsaParams;
// XXX sanity check params // XXX sanity check params
} else if (algorithm.equals("EC")) { } else if (algorithm.equals("EC")) {
ECParameterSpec ecParams; ECParameterSpec ecParams;
if (params instanceof ECParameterSpec) { if (params instanceof ECParameterSpec) {
ecParams = P11ECKeyFactory.getECParameterSpec((ECParameterSpec)params); ecParams = P11ECKeyFactory.getECParameterSpec(
(ECParameterSpec)params);
if (ecParams == null) { if (ecParams == null) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("Unsupported curve: " + params); ("Unsupported curve: " + params);
...@@ -156,16 +165,17 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -156,16 +165,17 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("ECParameterSpec or ECGenParameterSpec required for EC"); ("ECParameterSpec or ECGenParameterSpec required for EC");
} }
this.keySize = ecParams.getCurve().getField().getFieldSize(); int tmpKeySize = ecParams.getCurve().getField().getFieldSize();
checkKeySize(tmpKeySize, ecParams);
this.keySize = tmpKeySize;
this.params = ecParams; this.params = ecParams;
} else { } else {
throw new ProviderException("Unknown algorithm: " + algorithm); throw new ProviderException("Unknown algorithm: " + algorithm);
} }
this.random = random; this.random = random;
checkKeySize(keySize);
} }
private void checkKeySize(int keySize) private void checkKeySize(int keySize, AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException { throws InvalidAlgorithmParameterException {
if (algorithm.equals("EC")) { if (algorithm.equals("EC")) {
if (keySize < 112) { if (keySize < 112) {
...@@ -178,13 +188,28 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -178,13 +188,28 @@ final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
("Key size must be at most 2048 bit"); ("Key size must be at most 2048 bit");
} }
return; return;
} else if (algorithm.equals("RSA")) {
BigInteger tmpExponent = rsaPublicExponent;
if (params != null) {
// Already tested for instanceof RSAKeyGenParameterSpec above
tmpExponent =
((RSAKeyGenParameterSpec)params).getPublicExponent();
}
try {
// This provider supports 64K or less.
RSAKeyFactory.checkKeyLengths(keySize, tmpExponent,
512, 64 * 1024);
} catch (InvalidKeyException e) {
throw new InvalidAlgorithmParameterException(e.getMessage());
}
return;
} }
if (keySize < 512) { if (keySize < 512) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("Key size must be at least 512 bit"); ("Key size must be at least 512 bit");
} }
if (algorithm.equals("RSA") || if (algorithm.equals("DH") && (params != null)) {
(algorithm.equals("DH") && (params != null))) {
// sanity check, nobody really wants keys this large // sanity check, nobody really wants keys this large
if (keySize > 64 * 1024) { if (keySize > 64 * 1024) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
......
...@@ -80,6 +80,8 @@ import static sun.security.pkcs11.P11Util.*; ...@@ -80,6 +80,8 @@ import static sun.security.pkcs11.P11Util.*;
import sun.security.pkcs11.wrapper.*; import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import sun.security.rsa.RSAKeyFactory;
final class P11KeyStore extends KeyStoreSpi { final class P11KeyStore extends KeyStoreSpi {
private static final CK_ATTRIBUTE ATTR_CLASS_CERT = private static final CK_ATTRIBUTE ATTR_CLASS_CERT =
...@@ -1328,6 +1330,15 @@ final class P11KeyStore extends KeyStoreSpi { ...@@ -1328,6 +1330,15 @@ final class P11KeyStore extends KeyStoreSpi {
BigInteger modulus = attrs[0].getBigInteger(); BigInteger modulus = attrs[0].getBigInteger();
keyLength = modulus.bitLength(); keyLength = modulus.bitLength();
// This check will combine our "don't care" values here
// with the system-wide min/max values.
try {
RSAKeyFactory.checkKeyLengths(keyLength, null,
-1, Integer.MAX_VALUE);
} catch (InvalidKeyException e) {
throw new KeyStoreException(e.getMessage());
}
return P11Key.privateKey(session, return P11Key.privateKey(session,
oHandle, oHandle,
keyType, keyType,
......
/* /*
* Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2008 Sun Microsystems, Inc. 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
...@@ -35,6 +35,8 @@ import static sun.security.pkcs11.TemplateManager.*; ...@@ -35,6 +35,8 @@ import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*; import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import sun.security.rsa.RSAKeyFactory;
/** /**
* RSA KeyFactory implemenation. * RSA KeyFactory implemenation.
* *
...@@ -131,6 +133,9 @@ final class P11RSAKeyFactory extends P11KeyFactory { ...@@ -131,6 +133,9 @@ final class P11RSAKeyFactory extends P11KeyFactory {
} catch (PKCS11Exception e) { } catch (PKCS11Exception e) {
throw new InvalidKeySpecException throw new InvalidKeySpecException
("Could not create RSA public key", e); ("Could not create RSA public key", e);
} catch (InvalidKeyException e) {
throw new InvalidKeySpecException
("Could not create RSA public key", e);
} }
} }
...@@ -175,11 +180,15 @@ final class P11RSAKeyFactory extends P11KeyFactory { ...@@ -175,11 +180,15 @@ final class P11RSAKeyFactory extends P11KeyFactory {
} catch (PKCS11Exception e) { } catch (PKCS11Exception e) {
throw new InvalidKeySpecException throw new InvalidKeySpecException
("Could not create RSA private key", e); ("Could not create RSA private key", e);
} catch (InvalidKeyException e) {
throw new InvalidKeySpecException
("Could not create RSA private key", e);
} }
} }
private PublicKey generatePublic(BigInteger n, BigInteger e) private PublicKey generatePublic(BigInteger n, BigInteger e)
throws PKCS11Exception { throws PKCS11Exception, InvalidKeyException {
RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024);
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY), new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA), new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
...@@ -200,7 +209,8 @@ final class P11RSAKeyFactory extends P11KeyFactory { ...@@ -200,7 +209,8 @@ final class P11RSAKeyFactory extends P11KeyFactory {
} }
private PrivateKey generatePrivate(BigInteger n, BigInteger d) private PrivateKey generatePrivate(BigInteger n, BigInteger d)
throws PKCS11Exception { throws PKCS11Exception, InvalidKeyException {
RSAKeyFactory.checkKeyLengths(n.bitLength(), null, -1, 64 * 1024);
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY), new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA), new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
...@@ -222,7 +232,9 @@ final class P11RSAKeyFactory extends P11KeyFactory { ...@@ -222,7 +232,9 @@ final class P11RSAKeyFactory extends P11KeyFactory {
private PrivateKey generatePrivate(BigInteger n, BigInteger e, private PrivateKey generatePrivate(BigInteger n, BigInteger e,
BigInteger d, BigInteger p, BigInteger q, BigInteger pe, BigInteger d, BigInteger p, BigInteger q, BigInteger pe,
BigInteger qe, BigInteger coeff) throws PKCS11Exception { BigInteger qe, BigInteger coeff) throws PKCS11Exception,
InvalidKeyException {
RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024);
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY), new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA), new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
......
...@@ -120,11 +120,13 @@ public final class SunPKCS11 extends AuthProvider { ...@@ -120,11 +120,13 @@ public final class SunPKCS11 extends AuthProvider {
} }
/** /**
* @deprecated use new SunPKCS11(String) or new SunPKCS11(InputStream) instead * @deprecated use new SunPKCS11(String) or new SunPKCS11(InputStream)
* instead
*/ */
@Deprecated @Deprecated
public SunPKCS11(String configName, InputStream configStream) { public SunPKCS11(String configName, InputStream configStream) {
super("SunPKCS11-" + Config.getConfig(configName, configStream).getName(), super("SunPKCS11-" +
Config.getConfig(configName, configStream).getName(),
1.7d, Config.getConfig(configName, configStream).getDescription()); 1.7d, Config.getConfig(configName, configStream).getDescription());
this.configName = configName; this.configName = configName;
this.config = Config.removeConfig(configName); this.config = Config.removeConfig(configName);
...@@ -153,7 +155,8 @@ public final class SunPKCS11 extends AuthProvider { ...@@ -153,7 +155,8 @@ public final class SunPKCS11 extends AuthProvider {
// //
// If we are in Secmod mode and configured to use either the // If we are in Secmod mode and configured to use either the
// nssKeyStore or the nssTrustAnchors module, we automatically // nssKeyStore or the nssTrustAnchors module, we automatically
// switch to using the NSS trust attributes for trusted certs (KeyStore). // switch to using the NSS trust attributes for trusted certs
// (KeyStore).
// //
if (useSecmod) { if (useSecmod) {
...@@ -168,33 +171,40 @@ public final class SunPKCS11 extends AuthProvider { ...@@ -168,33 +171,40 @@ public final class SunPKCS11 extends AuthProvider {
if (secmod.isInitialized()) { if (secmod.isInitialized()) {
if (nssSecmodDirectory != null) { if (nssSecmodDirectory != null) {
String s = secmod.getConfigDir(); String s = secmod.getConfigDir();
if ((s != null) && (s.equals(nssSecmodDirectory) == false)) { if ((s != null) &&
(s.equals(nssSecmodDirectory) == false)) {
throw new ProviderException("Secmod directory " throw new ProviderException("Secmod directory "
+ nssSecmodDirectory + nssSecmodDirectory
+ " invalid, NSS already initialized with " + s); + " invalid, NSS already initialized with "
+ s);
} }
} }
if (nssLibraryDirectory != null) { if (nssLibraryDirectory != null) {
String s = secmod.getLibDir(); String s = secmod.getLibDir();
if ((s != null) && (s.equals(nssLibraryDirectory) == false)) { if ((s != null) &&
(s.equals(nssLibraryDirectory) == false)) {
throw new ProviderException("NSS library directory " throw new ProviderException("NSS library directory "
+ nssLibraryDirectory + nssLibraryDirectory
+ " invalid, NSS already initialized with " + s); + " invalid, NSS already initialized with "
+ s);
} }
} }
} else { } else {
if (nssDbMode != DbMode.NO_DB) { if (nssDbMode != DbMode.NO_DB) {
if (nssSecmodDirectory == null) { if (nssSecmodDirectory == null) {
throw new ProviderException("Secmod not initialized and " throw new ProviderException(
+ "nssSecmodDirectory not specified"); "Secmod not initialized and "
+ "nssSecmodDirectory not specified");
} }
} else { } else {
if (nssSecmodDirectory != null) { if (nssSecmodDirectory != null) {
throw new ProviderException throw new ProviderException(
("nssSecmodDirectory must not be specified in noDb mode"); "nssSecmodDirectory must not be "
+ "specified in noDb mode");
} }
} }
secmod.initialize(nssDbMode, nssSecmodDirectory, nssLibraryDirectory); secmod.initialize(nssDbMode, nssSecmodDirectory,
nssLibraryDirectory);
} }
} catch (IOException e) { } catch (IOException e) {
// XXX which exception to throw // XXX which exception to throw
...@@ -211,7 +221,8 @@ public final class SunPKCS11 extends AuthProvider { ...@@ -211,7 +221,8 @@ public final class SunPKCS11 extends AuthProvider {
if (nssModule != null) { if (nssModule != null) {
moduleName = "fips"; moduleName = "fips";
} else { } else {
moduleName = (nssDbMode == DbMode.NO_DB) ? "crypto" : "keystore"; moduleName = (nssDbMode == DbMode.NO_DB) ?
"crypto" : "keystore";
} }
} }
if (moduleName.equals("fips")) { if (moduleName.equals("fips")) {
...@@ -253,10 +264,12 @@ public final class SunPKCS11 extends AuthProvider { ...@@ -253,10 +264,12 @@ public final class SunPKCS11 extends AuthProvider {
+ ": only " + k + " external NSS modules available"); + ": only " + k + " external NSS modules available");
} }
} else { } else {
throw new ProviderException("Unknown NSS module: " + moduleName); throw new ProviderException(
"Unknown NSS module: " + moduleName);
} }
if (nssModule == null) { if (nssModule == null) {
throw new ProviderException("NSS module not available: " + moduleName); throw new ProviderException(
"NSS module not available: " + moduleName);
} }
if (nssModule.hasInitializedProvider()) { if (nssModule.hasInitializedProvider()) {
throw new ProviderException("Secmod module already configured"); throw new ProviderException("Secmod module already configured");
...@@ -296,8 +309,9 @@ public final class SunPKCS11 extends AuthProvider { ...@@ -296,8 +309,9 @@ public final class SunPKCS11 extends AuthProvider {
initArgs.flags = CKF_OS_LOCKING_OK; initArgs.flags = CKF_OS_LOCKING_OK;
PKCS11 tmpPKCS11; PKCS11 tmpPKCS11;
try { try {
tmpPKCS11 = PKCS11.getInstance tmpPKCS11 = PKCS11.getInstance(
(library, functionList, initArgs, config.getOmitInitialize()); library, functionList, initArgs,
config.getOmitInitialize());
} catch (PKCS11Exception e) { } catch (PKCS11Exception e) {
if (debug != null) { if (debug != null) {
debug.println("Multi-threaded initialization failed: " + e); debug.println("Multi-threaded initialization failed: " + e);
...@@ -312,8 +326,8 @@ public final class SunPKCS11 extends AuthProvider { ...@@ -312,8 +326,8 @@ public final class SunPKCS11 extends AuthProvider {
} else { } else {
initArgs.flags = 0; initArgs.flags = 0;
} }
tmpPKCS11 = PKCS11.getInstance tmpPKCS11 = PKCS11.getInstance(library,
(library, functionList, initArgs, config.getOmitInitialize()); functionList, initArgs, config.getOmitInitialize());
} }
p11 = tmpPKCS11; p11 = tmpPKCS11;
...@@ -336,8 +350,10 @@ public final class SunPKCS11 extends AuthProvider { ...@@ -336,8 +350,10 @@ public final class SunPKCS11 extends AuthProvider {
System.out.println("Slots with tokens: " + toString(slots)); System.out.println("Slots with tokens: " + toString(slots));
} }
if (slotID < 0) { if (slotID < 0) {
if ((slotListIndex < 0) || (slotListIndex >= slots.length)) { if ((slotListIndex < 0)
throw new ProviderException("slotListIndex is " + slotListIndex || (slotListIndex >= slots.length)) {
throw new ProviderException("slotListIndex is "
+ slotListIndex
+ " but token only has " + slots.length + " slots"); + " but token only has " + slots.length + " slots");
} }
slotID = slots[slotListIndex]; slotID = slots[slotListIndex];
...@@ -575,12 +591,15 @@ public final class SunPKCS11 extends AuthProvider { ...@@ -575,12 +591,15 @@ public final class SunPKCS11 extends AuthProvider {
d(KF, "DH", P11DHKeyFactory, s("DiffieHellman"), d(KF, "DH", P11DHKeyFactory, s("DiffieHellman"),
m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE)); m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE));
d(KF, "EC", P11DHKeyFactory, d(KF, "EC", P11DHKeyFactory,
m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE, CKM_ECDSA, CKM_ECDSA_SHA1)); m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE,
CKM_ECDSA, CKM_ECDSA_SHA1));
// AlgorithmParameters for EC. // AlgorithmParameters for EC.
// Only needed until we have an EC implementation in the SUN provider. // Only needed until we have an EC implementation in the SUN provider.
d(AGP, "EC", "sun.security.ec.ECParameters", s("1.2.840.10045.2.1"), d(AGP, "EC", "sun.security.ec.ECParameters",
m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE, CKM_ECDSA, CKM_ECDSA_SHA1)); s("1.2.840.10045.2.1"),
m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE,
CKM_ECDSA, CKM_ECDSA_SHA1));
d(KA, "DH", P11KeyAgreement, s("DiffieHellman"), d(KA, "DH", P11KeyAgreement, s("DiffieHellman"),
m(CKM_DH_PKCS_DERIVE)); m(CKM_DH_PKCS_DERIVE));
...@@ -654,12 +673,16 @@ public final class SunPKCS11 extends AuthProvider { ...@@ -654,12 +673,16 @@ public final class SunPKCS11 extends AuthProvider {
d(SIG, "SHA512withRSA", P11Signature, d(SIG, "SHA512withRSA", P11Signature,
m(CKM_SHA512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); m(CKM_SHA512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
d(KG, "SunTlsRsaPremasterSecret", "sun.security.pkcs11.P11TlsRsaPremasterSecretGenerator", d(KG, "SunTlsRsaPremasterSecret",
"sun.security.pkcs11.P11TlsRsaPremasterSecretGenerator",
m(CKM_SSL3_PRE_MASTER_KEY_GEN, CKM_TLS_PRE_MASTER_KEY_GEN)); m(CKM_SSL3_PRE_MASTER_KEY_GEN, CKM_TLS_PRE_MASTER_KEY_GEN));
d(KG, "SunTlsMasterSecret", "sun.security.pkcs11.P11TlsMasterSecretGenerator", d(KG, "SunTlsMasterSecret",
"sun.security.pkcs11.P11TlsMasterSecretGenerator",
m(CKM_SSL3_MASTER_KEY_DERIVE, CKM_TLS_MASTER_KEY_DERIVE, m(CKM_SSL3_MASTER_KEY_DERIVE, CKM_TLS_MASTER_KEY_DERIVE,
CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_MASTER_KEY_DERIVE_DH)); CKM_SSL3_MASTER_KEY_DERIVE_DH,
d(KG, "SunTlsKeyMaterial", "sun.security.pkcs11.P11TlsKeyMaterialGenerator", CKM_TLS_MASTER_KEY_DERIVE_DH));
d(KG, "SunTlsKeyMaterial",
"sun.security.pkcs11.P11TlsKeyMaterialGenerator",
m(CKM_SSL3_KEY_AND_MAC_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE)); m(CKM_SSL3_KEY_AND_MAC_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE));
d(KG, "SunTlsPrf", "sun.security.pkcs11.P11TlsPrfGenerator", d(KG, "SunTlsPrf", "sun.security.pkcs11.P11TlsPrfGenerator",
m(CKM_TLS_PRF, CKM_NSS_TLS_PRF_GENERAL)); m(CKM_TLS_PRF, CKM_NSS_TLS_PRF_GENERAL));
...@@ -773,6 +796,13 @@ public final class SunPKCS11 extends AuthProvider { ...@@ -773,6 +796,13 @@ public final class SunPKCS11 extends AuthProvider {
System.out.println(token.tokenInfo); System.out.println(token.tokenInfo);
} }
long[] supportedMechanisms = p11.C_GetMechanismList(slotID); long[] supportedMechanisms = p11.C_GetMechanismList(slotID);
// Create a map from the various Descriptors to the "most
// preferred" mechanism that was defined during the
// static initialization. For example, DES/CBC/PKCS5Padding
// could be mapped to CKM_DES_CBC_PAD or CKM_DES_CBC. Prefer
// the earliest entry. When asked for "DES/CBC/PKCS5Padding", we
// return a CKM_DES_CBC_PAD.
final Map<Descriptor,Integer> supportedAlgs = final Map<Descriptor,Integer> supportedAlgs =
new HashMap<Descriptor,Integer>(); new HashMap<Descriptor,Integer>();
for (int i = 0; i < supportedMechanisms.length; i++) { for (int i = 0; i < supportedMechanisms.length; i++) {
...@@ -807,6 +837,9 @@ public final class SunPKCS11 extends AuthProvider { ...@@ -807,6 +837,9 @@ public final class SunPKCS11 extends AuthProvider {
supportedAlgs.put(d, integerMech); supportedAlgs.put(d, integerMech);
continue; continue;
} }
// See if there is something "more preferred"
// than what we currently have in the supportedAlgs
// map.
int intOldMech = oldMech.intValue(); int intOldMech = oldMech.intValue();
for (int j = 0; j < d.mechanisms.length; j++) { for (int j = 0; j < d.mechanisms.length; j++) {
int nextMech = d.mechanisms[j]; int nextMech = d.mechanisms[j];
......
/* /*
* Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2008 Sun Microsystems, Inc. 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
...@@ -31,6 +31,8 @@ import java.security.*; ...@@ -31,6 +31,8 @@ import java.security.*;
import java.security.interfaces.*; import java.security.interfaces.*;
import java.security.spec.*; import java.security.spec.*;
import sun.security.action.GetPropertyAction;
/** /**
* KeyFactory for RSA keys. Keys must be instances of PublicKey or PrivateKey * KeyFactory for RSA keys. Keys must be instances of PublicKey or PrivateKey
* and getAlgorithm() must return "RSA". For such keys, it supports conversion * and getAlgorithm() must return "RSA". For such keys, it supports conversion
...@@ -68,6 +70,24 @@ public final class RSAKeyFactory extends KeyFactorySpi { ...@@ -68,6 +70,24 @@ public final class RSAKeyFactory extends KeyFactorySpi {
private final static Class<?> x509KeySpecClass = X509EncodedKeySpec.class; private final static Class<?> x509KeySpecClass = X509EncodedKeySpec.class;
private final static Class<?> pkcs8KeySpecClass = PKCS8EncodedKeySpec.class; private final static Class<?> pkcs8KeySpecClass = PKCS8EncodedKeySpec.class;
public final static int MIN_MODLEN = 512;
public final static int MAX_MODLEN = 16384;
/*
* If the modulus length is above this value, restrict the size of
* the exponent to something that can be reasonably computed. We
* could simply hardcode the exp len to something like 64 bits, but
* this approach allows flexibility in case impls would like to use
* larger module and exponent values.
*/
public final static int MAX_MODLEN_RESTRICT_EXP = 3072;
public final static int MAX_RESTRICTED_EXPLEN = 64;
private static final boolean restrictExpLen =
"true".equalsIgnoreCase(AccessController.doPrivileged(
new GetPropertyAction(
"sun.security.rsa.restrictRSAExponent", "true")));
// instance used for static translateKey(); // instance used for static translateKey();
private final static RSAKeyFactory INSTANCE = new RSAKeyFactory(); private final static RSAKeyFactory INSTANCE = new RSAKeyFactory();
...@@ -76,74 +96,79 @@ public final class RSAKeyFactory extends KeyFactorySpi { ...@@ -76,74 +96,79 @@ public final class RSAKeyFactory extends KeyFactorySpi {
} }
/** /**
* Static method to convert Key into a useable instance of * Static method to convert Key into an instance of RSAPublicKeyImpl
* RSAPublicKey or RSAPrivate(Crt)Key. Check the key and convert it * or RSAPrivate(Crt)KeyImpl. If the key is not an RSA key or cannot be
* to a SunRsaSign key if necessary. If the key is not an RSA key * used, throw an InvalidKeyException.
* or cannot be used, throw an InvalidKeyException.
*
* The difference between this method and engineTranslateKey() is that
* we do not convert keys of other providers that are already an
* instance of RSAPublicKey or RSAPrivate(Crt)Key.
* *
* Used by RSASignature and RSACipher. * Used by RSASignature and RSACipher.
*/ */
public static RSAKey toRSAKey(Key key) throws InvalidKeyException { public static RSAKey toRSAKey(Key key) throws InvalidKeyException {
if (key instanceof RSAKey) { if ((key instanceof RSAPrivateKeyImpl) ||
RSAKey rsaKey = (RSAKey)key; (key instanceof RSAPrivateCrtKeyImpl) ||
checkKey(rsaKey); (key instanceof RSAPublicKeyImpl)) {
return rsaKey; return (RSAKey)key;
} else { } else {
return (RSAKey)INSTANCE.engineTranslateKey(key); return (RSAKey)INSTANCE.engineTranslateKey(key);
} }
} }
/** /*
* Check that the given RSA key is valid. * Single test entry point for all of the mechanisms in the SunRsaSign
* provider (RSA*KeyImpls). All of the tests are the same.
*
* For compatibility, we round up to the nearest byte here:
* some Key impls might pass in a value within a byte of the
* real value.
*/ */
private static void checkKey(RSAKey key) throws InvalidKeyException { static void checkRSAProviderKeyLengths(int modulusLen, BigInteger exponent)
// check for subinterfaces, omit additional checks for our keys throws InvalidKeyException {
if (key instanceof RSAPublicKey) { checkKeyLengths(((modulusLen + 7) & ~7), exponent,
if (key instanceof RSAPublicKeyImpl) { RSAKeyFactory.MIN_MODLEN, Integer.MAX_VALUE);
return;
}
} else if (key instanceof RSAPrivateKey) {
if ((key instanceof RSAPrivateCrtKeyImpl)
|| (key instanceof RSAPrivateKeyImpl)) {
return;
}
} else {
throw new InvalidKeyException("Neither a public nor a private key");
}
// RSAKey does not extend Key, so we need to do a cast
String keyAlg = ((Key)key).getAlgorithm();
if (keyAlg.equals("RSA") == false) {
throw new InvalidKeyException("Not an RSA key: " + keyAlg);
}
BigInteger modulus;
// some providers implement RSAKey for keys where the values are
// not accessible (although they should). Detect those here
// for a more graceful failure.
try {
modulus = key.getModulus();
if (modulus == null) {
throw new InvalidKeyException("Modulus is missing");
}
} catch (RuntimeException e) {
throw new InvalidKeyException(e);
}
checkKeyLength(modulus);
} }
/** /**
* Check the length of the modulus of an RSA key. We only support keys * Check the length of an RSA key modulus/exponent to make sure it
* at least 505 bits long. * is not too short or long. Some impls have their own min and
* max key sizes that may or may not match with a system defined value.
*
* @param modulusLen the bit length of the RSA modulus.
* @param exponent the RSA exponent
* @param minModulusLen if > 0, check to see if modulusLen is at
* least this long, otherwise unused.
* @param maxModulusLen caller will allow this max number of bits.
* Allow the smaller of the system-defined maximum and this param.
*
* @throws InvalidKeyException if any of the values are unacceptable.
*/ */
static void checkKeyLength(BigInteger modulus) throws InvalidKeyException { public static void checkKeyLengths(int modulusLen, BigInteger exponent,
if (modulus.bitLength() < 505) { int minModulusLen, int maxModulusLen) throws InvalidKeyException {
// some providers may generate slightly shorter keys
// accept them if the encoding is at least 64 bytes long if ((minModulusLen > 0) && (modulusLen < (minModulusLen))) {
throw new InvalidKeyException throw new InvalidKeyException( "RSA keys must be at least " +
("RSA keys must be at least 512 bits long"); minModulusLen + " bits long");
}
// Even though our policy file may allow this, we don't want
// either value (mod/exp) to be too big.
int maxLen = Math.min(maxModulusLen, MAX_MODLEN);
// If a RSAPrivateKey/RSAPublicKey, make sure the
// modulus len isn't too big.
if (modulusLen > maxLen) {
throw new InvalidKeyException(
"RSA keys must be no longer than " + maxLen + " bits");
}
// If a RSAPublicKey, make sure the exponent isn't too big.
if (restrictExpLen && (exponent != null) &&
(modulusLen > MAX_MODLEN_RESTRICT_EXP) &&
(exponent.bitLength() > MAX_RESTRICTED_EXPLEN)) {
throw new InvalidKeyException(
"RSA exponents can be no longer than " +
MAX_RESTRICTED_EXPLEN + " bits " +
" if modulus is greater than " +
MAX_MODLEN_RESTRICT_EXP + " bits");
} }
} }
......
/* /*
* Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2008 Sun Microsystems, Inc. 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
...@@ -47,7 +47,7 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -47,7 +47,7 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
// public exponent to use // public exponent to use
private BigInteger publicExponent; private BigInteger publicExponent;
// size of the key to generate, >= 512 // size of the key to generate, >= RSAKeyFactory.MIN_MODLEN
private int keySize; private int keySize;
// PRNG to use // PRNG to use
...@@ -60,15 +60,16 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -60,15 +60,16 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
// initialize the generator. See JCA doc // initialize the generator. See JCA doc
public void initialize(int keySize, SecureRandom random) { public void initialize(int keySize, SecureRandom random) {
if (keySize < 512) {
throw new InvalidParameterException // do not allow unreasonably small or large key sizes,
("Key size must be at least 512 bits"); // probably user error
} try {
if (keySize > 64 * 1024) { RSAKeyFactory.checkKeyLengths(keySize, RSAKeyGenParameterSpec.F4,
// do not allow unreasonably large key sizes, probably user error 512, 64 * 1024);
throw new InvalidParameterException } catch (InvalidKeyException e) {
("Key size must be 65536 bits or less"); throw new InvalidParameterException(e.getMessage());
} }
this.keySize = keySize; this.keySize = keySize;
this.random = random; this.random = random;
this.publicExponent = RSAKeyGenParameterSpec.F4; this.publicExponent = RSAKeyGenParameterSpec.F4;
...@@ -77,35 +78,41 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -77,35 +78,41 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
// second initialize method. See JCA doc. // second initialize method. See JCA doc.
public void initialize(AlgorithmParameterSpec params, SecureRandom random) public void initialize(AlgorithmParameterSpec params, SecureRandom random)
throws InvalidAlgorithmParameterException { throws InvalidAlgorithmParameterException {
if (params instanceof RSAKeyGenParameterSpec == false) { if (params instanceof RSAKeyGenParameterSpec == false) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("Params must be instance of RSAKeyGenParameterSpec"); ("Params must be instance of RSAKeyGenParameterSpec");
} }
RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params; RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params;
keySize = rsaSpec.getKeysize(); int tmpKeySize = rsaSpec.getKeysize();
publicExponent = rsaSpec.getPublicExponent(); BigInteger tmpPublicExponent = rsaSpec.getPublicExponent();
this.random = random;
if (keySize < 512) { if (tmpPublicExponent == null) {
throw new InvalidAlgorithmParameterException tmpPublicExponent = RSAKeyGenParameterSpec.F4;
("Key size must be at least 512 bits");
}
if (keySize > 64 * 1024) {
// do not allow unreasonably large key sizes, probably user error
throw new InvalidAlgorithmParameterException
("Key size must be 65536 bits or less");
}
if (publicExponent == null) {
publicExponent = RSAKeyGenParameterSpec.F4;
} else { } else {
if (publicExponent.compareTo(RSAKeyGenParameterSpec.F0) < 0) { if (tmpPublicExponent.compareTo(RSAKeyGenParameterSpec.F0) < 0) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("Public exponent must be 3 or larger"); ("Public exponent must be 3 or larger");
} }
if (publicExponent.bitLength() > keySize) { if (tmpPublicExponent.bitLength() > tmpKeySize) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("Public exponent must be smaller than key size"); ("Public exponent must be smaller than key size");
} }
} }
// do not allow unreasonably large key sizes, probably user error
try {
RSAKeyFactory.checkKeyLengths(tmpKeySize, tmpPublicExponent,
512, 64 * 1024);
} catch (InvalidKeyException e) {
throw new InvalidAlgorithmParameterException(
"Invalid key sizes", e);
}
this.keySize = tmpKeySize;
this.publicExponent = tmpPublicExponent;
this.random = random;
} }
// generate the keypair. See JCA doc // generate the keypair. See JCA doc
......
/* /*
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2008 Sun Microsystems, Inc. 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
...@@ -89,7 +89,7 @@ public final class RSAPrivateCrtKeyImpl ...@@ -89,7 +89,7 @@ public final class RSAPrivateCrtKeyImpl
*/ */
RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException { RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException {
decode(encoded); decode(encoded);
RSAKeyFactory.checkKeyLength(n); RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
} }
/** /**
...@@ -107,7 +107,8 @@ public final class RSAPrivateCrtKeyImpl ...@@ -107,7 +107,8 @@ public final class RSAPrivateCrtKeyImpl
this.pe = pe; this.pe = pe;
this.qe = qe; this.qe = qe;
this.coeff = coeff; this.coeff = coeff;
RSAKeyFactory.checkKeyLength(n); RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
// generate the encoding // generate the encoding
algid = rsaId; algid = rsaId;
try { try {
......
/* /*
* Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2008 Sun Microsystems, Inc. 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
...@@ -61,7 +61,7 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey { ...@@ -61,7 +61,7 @@ public final class RSAPrivateKeyImpl extends PKCS8Key implements RSAPrivateKey {
RSAPrivateKeyImpl(BigInteger n, BigInteger d) throws InvalidKeyException { RSAPrivateKeyImpl(BigInteger n, BigInteger d) throws InvalidKeyException {
this.n = n; this.n = n;
this.d = d; this.d = d;
RSAKeyFactory.checkKeyLength(n); RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), null);
// generate the encoding // generate the encoding
algid = RSAPrivateCrtKeyImpl.rsaId; algid = RSAPrivateCrtKeyImpl.rsaId;
try { try {
......
/* /*
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2008 Sun Microsystems, Inc. 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
...@@ -56,10 +56,11 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey { ...@@ -56,10 +56,11 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
* 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.
*/ */
public RSAPublicKeyImpl(BigInteger n, BigInteger e) throws InvalidKeyException { public RSAPublicKeyImpl(BigInteger n, BigInteger e)
throws InvalidKeyException {
this.n = n; this.n = n;
this.e = e; this.e = e;
RSAKeyFactory.checkKeyLength(n); RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
// generate the encoding // generate the encoding
algid = RSAPrivateCrtKeyImpl.rsaId; algid = RSAPrivateCrtKeyImpl.rsaId;
try { try {
...@@ -80,7 +81,7 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey { ...@@ -80,7 +81,7 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
*/ */
public RSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException { public RSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException {
decode(encoded); decode(encoded);
RSAKeyFactory.checkKeyLength(n); RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
} }
// see JCA doc // see JCA doc
......
/* /*
* Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2005-2008 Sun Microsystems, Inc. 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
...@@ -31,6 +31,7 @@ import java.security.spec.AlgorithmParameterSpec; ...@@ -31,6 +31,7 @@ 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.RSAKeyFactory;
/** /**
* RSA keypair generator. * RSA keypair generator.
...@@ -43,8 +44,8 @@ import sun.security.jca.JCAUtil; ...@@ -43,8 +44,8 @@ import sun.security.jca.JCAUtil;
public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi { public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
// Supported by Microsoft Base, Strong and Enhanced Cryptographic Providers // Supported by Microsoft Base, Strong and Enhanced Cryptographic Providers
private static final int KEY_SIZE_MIN = 512; // disallow MSCAPI min. of 384 static final int KEY_SIZE_MIN = 512; // disallow MSCAPI min. of 384
private static final int KEY_SIZE_MAX = 16384; static final int KEY_SIZE_MAX = 16384;
private static final int KEY_SIZE_DEFAULT = 1024; private static final int KEY_SIZE_DEFAULT = 1024;
// size of the key to generate, KEY_SIZE_MIN <= keySize <= KEY_SIZE_MAX // size of the key to generate, KEY_SIZE_MIN <= keySize <= KEY_SIZE_MAX
...@@ -59,7 +60,14 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -59,7 +60,14 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
// random is always ignored // random is always ignored
public void initialize(int keySize, SecureRandom random) { public void initialize(int keySize, SecureRandom random) {
checkKeySize(keySize); try {
RSAKeyFactory.checkKeyLengths(keySize, null,
KEY_SIZE_MIN, KEY_SIZE_MAX);
} catch (InvalidKeyException e) {
throw new InvalidParameterException(e.getMessage());
}
this.keySize = keySize;
} }
// second initialize method. See JCA doc // second initialize method. See JCA doc
...@@ -67,21 +75,31 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -67,21 +75,31 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
public void initialize(AlgorithmParameterSpec params, SecureRandom random) public void initialize(AlgorithmParameterSpec params, SecureRandom random)
throws InvalidAlgorithmParameterException { throws InvalidAlgorithmParameterException {
int tmpSize;
if (params == null) { if (params == null) {
checkKeySize(KEY_SIZE_DEFAULT); tmpSize = KEY_SIZE_DEFAULT;
} else if (params instanceof RSAKeyGenParameterSpec) { } else if (params instanceof RSAKeyGenParameterSpec) {
if (((RSAKeyGenParameterSpec) params).getPublicExponent() != null) { if (((RSAKeyGenParameterSpec) params).getPublicExponent() != null) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("Exponent parameter is not supported"); ("Exponent parameter is not supported");
} }
checkKeySize(((RSAKeyGenParameterSpec) params).getKeysize()); tmpSize = ((RSAKeyGenParameterSpec) params).getKeysize();
} else { } else {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("Params must be an instance of RSAKeyGenParameterSpec"); ("Params must be an instance of RSAKeyGenParameterSpec");
} }
try {
RSAKeyFactory.checkKeyLengths(tmpSize, null,
KEY_SIZE_MIN, KEY_SIZE_MAX);
} catch (InvalidKeyException e) {
throw new InvalidAlgorithmParameterException(
"Invalid Key sizes", e);
}
this.keySize = tmpSize;
} }
// generate the keypair. See JCA doc // generate the keypair. See JCA doc
...@@ -95,18 +113,6 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -95,18 +113,6 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
return new KeyPair(keys.getPublic(), keys.getPrivate()); return new KeyPair(keys.getPublic(), keys.getPrivate());
} }
private void checkKeySize(int keySize) throws InvalidParameterException {
if (keySize < KEY_SIZE_MIN) {
throw new InvalidParameterException
("Key size must be at least " + KEY_SIZE_MIN + " bits");
}
if (keySize > KEY_SIZE_MAX) {
throw new InvalidParameterException
("Key size must be " + KEY_SIZE_MAX + " bits or less");
}
this.keySize = keySize;
}
private static native RSAKeyPair generateRSAKeyPair(int keySize, private static native RSAKeyPair generateRSAKeyPair(int keySize,
String keyContainerName); String keyContainerName);
} }
/* /*
* Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2005-2008 Sun Microsystems, Inc. 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
...@@ -38,6 +38,9 @@ import java.security.SecureRandom; ...@@ -38,6 +38,9 @@ import java.security.SecureRandom;
import java.security.Signature; import java.security.Signature;
import java.security.SignatureSpi; import java.security.SignatureSpi;
import java.security.SignatureException; import java.security.SignatureException;
import java.math.BigInteger;
import sun.security.rsa.RSAKeyFactory;
/** /**
* RSA signature implementation. Supports RSA signing using PKCS#1 v1.5 padding. * RSA signature implementation. Supports RSA signing using PKCS#1 v1.5 padding.
...@@ -124,7 +127,16 @@ abstract class RSASignature extends java.security.SignatureSpi ...@@ -124,7 +127,16 @@ abstract class RSASignature extends java.security.SignatureSpi
// convert key to MSCAPI format // convert key to MSCAPI format
byte[] modulusBytes = rsaKey.getModulus().toByteArray(); BigInteger modulus = rsaKey.getModulus();
BigInteger exponent = rsaKey.getPublicExponent();
// Check against the local and global values to make sure
// the sizes are ok. Round up to the nearest byte.
RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7),
exponent, -1, RSAKeyPairGenerator.KEY_SIZE_MAX);
byte[] modulusBytes = modulus.toByteArray();
byte[] exponentBytes = exponent.toByteArray();
// Adjust key length due to sign bit // Adjust key length due to sign bit
int keyBitLength = (modulusBytes[0] == 0) int keyBitLength = (modulusBytes[0] == 0)
...@@ -132,8 +144,7 @@ abstract class RSASignature extends java.security.SignatureSpi ...@@ -132,8 +144,7 @@ abstract class RSASignature extends java.security.SignatureSpi
: modulusBytes.length * 8; : modulusBytes.length * 8;
byte[] keyBlob = generatePublicKeyBlob( byte[] keyBlob = generatePublicKeyBlob(
keyBitLength, modulusBytes, keyBitLength, modulusBytes, exponentBytes);
rsaKey.getPublicExponent().toByteArray());
publicKey = importPublicKey(keyBlob, keyBitLength); publicKey = importPublicKey(keyBlob, keyBitLength);
...@@ -166,12 +177,11 @@ abstract class RSASignature extends java.security.SignatureSpi ...@@ -166,12 +177,11 @@ abstract class RSASignature extends java.security.SignatureSpi
} }
privateKey = (sun.security.mscapi.RSAPrivateKey) key; privateKey = (sun.security.mscapi.RSAPrivateKey) key;
// Determine byte length from bit length // Check against the local and global values to make sure
int keySize = (privateKey.bitLength() + 7) >> 3; // the sizes are ok. Round up to nearest byte.
RSAKeyFactory.checkKeyLengths(((privateKey.bitLength() + 7) & ~7),
if (keySize < 64) null, RSAKeyPairGenerator.KEY_SIZE_MIN,
throw new InvalidKeyException( RSAKeyPairGenerator.KEY_SIZE_MAX);
"RSA keys must be at least 512 bits long");
if (needsReset) { if (needsReset) {
messageDigest.reset(); messageDigest.reset();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册