8181048: Refactor existing providers to refer to the same constants for default values for key length

Reviewed-by: mullan, ahgross
This commit is contained in:
Valerie Peng 2017-07-13 20:41:59 +00:00
parent 7cf3c0ff14
commit b3f1165f7d
16 changed files with 378 additions and 136 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,7 @@ import javax.crypto.spec.DHParameterSpec;
import javax.crypto.spec.DHGenParameterSpec;
import sun.security.provider.ParameterCache;
import static sun.security.util.SecurityProviderConstants.DEF_DH_KEY_SIZE;
/**
* This class represents the key pair generator for Diffie-Hellman key pairs.
@ -42,8 +43,7 @@ import sun.security.provider.ParameterCache;
* <ul>
* <li>By providing the size in bits of the prime modulus -
* This will be used to create a prime modulus and base generator, which will
* then be used to create the Diffie-Hellman key pair. The default size of the
* prime modulus is 2048 bits.
* then be used to create the Diffie-Hellman key pair.
* <li>By providing a prime modulus and base generator
* </ul>
*
@ -68,7 +68,7 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
public DHKeyPairGenerator() {
super();
initialize(2048, null);
initialize(DEF_DH_KEY_SIZE, null);
}
private static void checkKeySize(int keysize)

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -31,6 +31,8 @@ import java.security.spec.*;
import javax.crypto.spec.DHParameterSpec;
import javax.crypto.spec.DHGenParameterSpec;
import static sun.security.util.SecurityProviderConstants.DEF_DH_KEY_SIZE;
/*
* This class generates parameters for the Diffie-Hellman algorithm.
* The parameters are a prime, a base, and optionally the length in bits of
@ -38,7 +40,6 @@ import javax.crypto.spec.DHGenParameterSpec;
*
* <p>The Diffie-Hellman parameter generation accepts the size in bits of the
* prime modulus and the size in bits of the random exponent as input.
* The size of the prime modulus defaults to 2048 bits.
*
* @author Jan Luehe
*
@ -50,7 +51,7 @@ import javax.crypto.spec.DHGenParameterSpec;
public final class DHParameterGenerator extends AlgorithmParameterGeneratorSpi {
// The size in bits of the prime modulus
private int primeSize = 2048;
private int primeSize = DEF_DH_KEY_SIZE;
// The size in bits of the random exponent (private value)
private int exponentSize = 0;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -35,6 +35,8 @@ import java.security.spec.InvalidParameterSpecException;
import java.security.spec.DSAParameterSpec;
import sun.security.jca.JCAUtil;
import static sun.security.util.SecurityProviderConstants.DEF_DSA_KEY_SIZE;
import static sun.security.util.SecurityProviderConstants.getDefDSASubprimeSize;
/**
* This class generates DSA key parameters and public/private key
@ -45,15 +47,14 @@ import sun.security.jca.JCAUtil;
* @author Andreas Sterbenz
*
*/
public class DSAKeyPairGenerator extends KeyPairGenerator
implements java.security.interfaces.DSAKeyPairGenerator {
class DSAKeyPairGenerator extends KeyPairGenerator {
/* Length for prime P and subPrime Q in bits */
private int plen;
private int qlen;
/* whether to force new parameters to be generated for each KeyPair */
private boolean forceNewParameters;
boolean forceNewParameters;
/* preset algorithm parameters. */
private DSAParameterSpec params;
@ -61,9 +62,9 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
/* The source of random bits to use */
private SecureRandom random;
public DSAKeyPairGenerator() {
DSAKeyPairGenerator(int defaultKeySize) {
super("DSA");
initialize(1024, null);
initialize(defaultKeySize, null);
}
private static void checkStrength(int sizeP, int sizeQ) {
@ -84,61 +85,7 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
}
public void initialize(int modlen, SecureRandom random) {
// generate new parameters when no precomputed ones available.
initialize(modlen, true, random);
this.forceNewParameters = false;
}
/**
* Initializes the DSA key pair generator. If <code>genParams</code>
* is false, a set of pre-computed parameters is used.
*/
@Override
public void initialize(int modlen, boolean genParams, SecureRandom random)
throws InvalidParameterException {
int subPrimeLen = -1;
if (modlen <= 1024) {
subPrimeLen = 160;
} else if (modlen == 2048) {
subPrimeLen = 224;
} else if (modlen == 3072) {
subPrimeLen = 256;
}
checkStrength(modlen, subPrimeLen);
if (genParams) {
params = null;
} else {
params = ParameterCache.getCachedDSAParameterSpec(modlen,
subPrimeLen);
if (params == null) {
throw new InvalidParameterException
("No precomputed parameters for requested modulus size "
+ "available");
}
}
this.plen = modlen;
this.qlen = subPrimeLen;
this.random = random;
this.forceNewParameters = genParams;
}
/**
* Initializes the DSA object using a DSA parameter object.
*
* @param params a fully initialized DSA parameter object.
*/
@Override
public void initialize(DSAParams params, SecureRandom random)
throws InvalidParameterException {
if (params == null) {
throw new InvalidParameterException("Params must not be null");
}
DSAParameterSpec spec = new DSAParameterSpec
(params.getP(), params.getQ(), params.getG());
initialize0(spec, random);
init(modlen, random, false);
}
/**
@ -157,10 +104,21 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
throw new InvalidAlgorithmParameterException
("Inappropriate parameter");
}
initialize0((DSAParameterSpec)params, random);
init((DSAParameterSpec)params, random, false);
}
private void initialize0(DSAParameterSpec params, SecureRandom random) {
void init(int modlen, SecureRandom random, boolean forceNew) {
int subPrimeLen = getDefDSASubprimeSize(modlen);
checkStrength(modlen, subPrimeLen);
this.plen = modlen;
this.qlen = subPrimeLen;
this.params = null;
this.random = random;
this.forceNewParameters = forceNew;
}
void init(DSAParameterSpec params, SecureRandom random,
boolean forceNew) {
int sizeP = params.getP().bitLength();
int sizeQ = params.getQ().bitLength();
checkStrength(sizeP, sizeQ);
@ -168,7 +126,7 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
this.qlen = sizeQ;
this.params = params;
this.random = random;
this.forceNewParameters = false;
this.forceNewParameters = forceNew;
}
/**
@ -197,7 +155,7 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
return generateKeyPair(spec.getP(), spec.getQ(), spec.getG(), random);
}
public KeyPair generateKeyPair(BigInteger p, BigInteger q, BigInteger g,
private KeyPair generateKeyPair(BigInteger p, BigInteger q, BigInteger g,
SecureRandom random) {
BigInteger x = generateX(random, q);
@ -252,4 +210,55 @@ public class DSAKeyPairGenerator extends KeyPairGenerator
return y;
}
public static final class Current extends DSAKeyPairGenerator {
public Current() {
super(DEF_DSA_KEY_SIZE);
}
}
public static final class Legacy extends DSAKeyPairGenerator
implements java.security.interfaces.DSAKeyPairGenerator {
public Legacy() {
super(1024);
}
/**
* Initializes the DSA key pair generator. If <code>genParams</code>
* is false, a set of pre-computed parameters is used.
*/
@Override
public void initialize(int modlen, boolean genParams,
SecureRandom random) throws InvalidParameterException {
if (genParams) {
super.init(modlen, random, true);
} else {
DSAParameterSpec cachedParams =
ParameterCache.getCachedDSAParameterSpec(modlen,
getDefDSASubprimeSize(modlen));
if (cachedParams == null) {
throw new InvalidParameterException
("No precomputed parameters for requested modulus" +
" size available");
}
super.init(cachedParams, random, false);
}
}
/**
* Initializes the DSA object using a DSA parameter object.
*
* @param params a fully initialized DSA parameter object.
*/
@Override
public void initialize(DSAParams params, SecureRandom random)
throws InvalidParameterException {
if (params == null) {
throw new InvalidParameterException("Params must not be null");
}
DSAParameterSpec spec = new DSAParameterSpec
(params.getP(), params.getQ(), params.getG());
super.init(spec, random, false);
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -34,15 +34,18 @@ import java.security.NoSuchProviderException;
import java.security.InvalidParameterException;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.security.ProviderException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.DSAParameterSpec;
import java.security.spec.DSAGenParameterSpec;
import static sun.security.util.SecurityProviderConstants.DEF_DSA_KEY_SIZE;
import static sun.security.util.SecurityProviderConstants.getDefDSASubprimeSize;
/**
* This class generates parameters for the DSA algorithm. It uses a default
* prime modulus size of 1024 bits, which can be overwritten during
* initialization.
* This class generates parameters for the DSA algorithm.
*
* @author Jan Luehe
*
@ -56,10 +59,6 @@ import java.security.spec.DSAGenParameterSpec;
public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
// the default parameters
private static final DSAGenParameterSpec DEFAULTS =
new DSAGenParameterSpec(1024, 160, 160);
// the length of prime P, subPrime Q, and seed in bits
private int valueL = -1;
private int valueN = -1;
@ -80,18 +79,14 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
*/
@Override
protected void engineInit(int strength, SecureRandom random) {
if ((strength >= 512) && (strength <= 1024) && (strength % 64 == 0)) {
this.valueN = 160;
} else if (strength == 2048) {
this.valueN = 224;
} else if (strength == 3072) {
this.valueN = 256;
} else {
if ((strength != 2048) && (strength != 3072) &&
((strength < 512) || (strength > 1024) || (strength % 64 != 0))) {
throw new InvalidParameterException(
"Unexpected strength (size of prime): " + strength + ". " +
"Prime size should be 512 - 1024, or 2048, 3072");
"Unexpected strength (size of prime): " + strength +
". Prime size should be 512-1024, 2048, or 3072");
}
this.valueL = strength;
this.valueN = getDefDSASubprimeSize(strength);
this.seedLen = valueN;
this.random = random;
}
@ -110,7 +105,6 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
@Override
protected void engineInit(AlgorithmParameterSpec genParamSpec,
SecureRandom random) throws InvalidAlgorithmParameterException {
if (!(genParamSpec instanceof DSAGenParameterSpec)) {
throw new InvalidAlgorithmParameterException("Invalid parameter");
}
@ -136,11 +130,7 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
this.random = new SecureRandom();
}
if (valueL == -1) {
try {
engineInit(DEFAULTS, this.random);
} catch (InvalidAlgorithmParameterException iape) {
// should never happen
}
engineInit(DEF_DSA_KEY_SIZE, this.random);
}
BigInteger[] pAndQ = generatePandQ(this.random, valueL,
valueN, seedLen);
@ -206,13 +196,17 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
int b = (valueL - 1) % outLen;
byte[] seedBytes = new byte[seedLen/8];
BigInteger twoSl = BigInteger.TWO.pow(seedLen);
int primeCertainty = 80; // for 1024-bit prime P
if (valueL == 2048) {
int primeCertainty = -1;
if (valueL <= 1024) {
primeCertainty = 80;
} else if (valueL == 2048) {
primeCertainty = 112;
} else if (valueL == 3072) {
primeCertainty = 128;
}
if (primeCertainty < 0) {
throw new ProviderException("Invalid valueL: " + valueL);
}
BigInteger resultP, resultQ, seed = null;
int counter;
while (true) {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,7 @@ import java.io.*;
import java.net.*;
import java.util.Map;
import java.security.*;
import sun.security.action.GetPropertyAction;
/**
* Defines the entries of the SUN provider.
@ -74,6 +75,10 @@ import java.security.*;
final class SunEntries {
private static final boolean useLegacyDSA =
Boolean.parseBoolean(GetPropertyAction.privilegedGetProperty
("jdk.security.legacyDSAKeyPairGenerator"));
private SunEntries() {
// empty
}
@ -174,8 +179,9 @@ final class SunEntries {
/*
* Key Pair Generator engines
*/
map.put("KeyPairGenerator.DSA",
"sun.security.provider.DSAKeyPairGenerator");
String dsaKPGImplClass = "sun.security.provider.DSAKeyPairGenerator$";
dsaKPGImplClass += (useLegacyDSA? "Legacy" : "Current");
map.put("KeyPairGenerator.DSA", dsaKPGImplClass);
map.put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSA");
map.put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA");
map.put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA");

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -32,6 +32,7 @@ import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
import sun.security.jca.JCAUtil;
import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
/**
* RSA keypair generation. Standard algorithm, minimum key length 512 bit.
@ -55,7 +56,7 @@ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
public RSAKeyPairGenerator() {
// initialize to default in case the app does not call initialize()
initialize(2048, null);
initialize(DEF_RSA_KEY_SIZE, null);
}
// initialize the generator. See JCA doc

View file

@ -74,6 +74,7 @@ import sun.security.pkcs10.PKCS10Attribute;
import sun.security.provider.X509Factory;
import sun.security.provider.certpath.ssl.SSLServerCertStore;
import sun.security.util.Password;
import sun.security.util.SecurityProviderConstants;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
@ -1817,9 +1818,12 @@ public final class Main {
{
if (keysize == -1) {
if ("EC".equalsIgnoreCase(keyAlgName)) {
keysize = 256;
} else {
keysize = 2048; // RSA and DSA
keysize = SecurityProviderConstants.DEF_EC_KEY_SIZE;
} else if ("RSA".equalsIgnoreCase(keyAlgName)) {
keysize = SecurityProviderConstants.DEF_RSA_KEY_SIZE;
} else if ("DSA".equalsIgnoreCase(keyAlgName)) {
// hardcode for now as DEF_DSA_KEY_SIZE is still 1024
keysize = 2048; // SecurityProviderConstants.DEF_DSA_KEY_SIZE;
}
}

View file

@ -0,0 +1,131 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.util.regex.PatternSyntaxException;
import java.security.InvalidParameterException;
import sun.security.action.GetPropertyAction;
/**
* Various constants such as version number, default key length, used by
* the JDK security/crypto providers.
*/
public final class SecurityProviderConstants {
private static final Debug debug =
Debug.getInstance("jca", "ProviderConfig");
// Cannot create one of these
private SecurityProviderConstants () {
}
public static final int getDefDSASubprimeSize(int primeSize) {
if (primeSize <= 1024) {
return 160;
} else if (primeSize == 2048) {
return 224;
} else if (primeSize == 3072) {
return 256;
} else {
throw new InvalidParameterException("Invalid DSA Prime Size: " +
primeSize);
}
}
public static final int DEF_DSA_KEY_SIZE;
public static final int DEF_RSA_KEY_SIZE;
public static final int DEF_DH_KEY_SIZE;
public static final int DEF_EC_KEY_SIZE;
private static final String KEY_LENGTH_PROP =
"jdk.security.defaultKeySize";
static {
String keyLengthStr = GetPropertyAction.privilegedGetProperty
(KEY_LENGTH_PROP);
int dsaKeySize = 1024;
int rsaKeySize = 2048;
int dhKeySize = 2048;
int ecKeySize = 256;
if (keyLengthStr != null) {
try {
String[] pairs = keyLengthStr.split(",");
for (String p : pairs) {
String[] algoAndValue = p.split(":");
if (algoAndValue.length != 2) {
// invalid pair, skip to next pair
if (debug != null) {
debug.println("Ignoring invalid pair in " +
KEY_LENGTH_PROP + " property: " + p);
}
continue;
}
String algoName = algoAndValue[0].trim().toUpperCase();
int value = -1;
try {
value = Integer.parseInt(algoAndValue[1].trim());
} catch (NumberFormatException nfe) {
// invalid value, skip to next pair
if (debug != null) {
debug.println("Ignoring invalid value in " +
KEY_LENGTH_PROP + " property: " + p);
}
continue;
}
if (algoName.equals("DSA")) {
dsaKeySize = value;
} else if (algoName.equals("RSA")) {
rsaKeySize = value;
} else if (algoName.equals("DH")) {
dhKeySize = value;
} else if (algoName.equals("EC")) {
ecKeySize = value;
} else {
if (debug != null) {
debug.println("Ignoring unsupported algo in " +
KEY_LENGTH_PROP + " property: " + p);
}
continue;
}
if (debug != null) {
debug.println("Overriding default " + algoName +
" keysize with value from " +
KEY_LENGTH_PROP + " property: " + value);
}
}
} catch (PatternSyntaxException pse) {
// if property syntax is not followed correctly
if (debug != null) {
debug.println("Unexpected exception while parsing " +
KEY_LENGTH_PROP + " property: " + pse);
}
}
}
DEF_DSA_KEY_SIZE = dsaKeySize;
DEF_RSA_KEY_SIZE = rsaKeySize;
DEF_DH_KEY_SIZE = dhKeySize;
DEF_EC_KEY_SIZE = ecKeySize;
}
}