diff options
author | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2015-02-10 02:01:19 +0000 |
---|---|---|
committer | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2015-02-10 02:01:19 +0000 |
commit | a09acb2a1f9dc481c980ab38e19f510581e43ea8 (patch) | |
tree | 9d92ed44029bb9fbaa368fa9df681f11bb809e31 | |
parent | 55c5097f9ce57cb5ebdbec6383c6c89ad4933348 (diff) | |
download | classpath-a09acb2a1f9dc481c980ab38e19f510581e43ea8.tar.gz |
PR64902: Keys returned by KeyPairGenerator don't use standardised algorithm names
PR64904: KeyPairGenerator.genKeyPair() fails if not explicitly initialised
2015-02-02 Andrew John Hughes <gnu_andrew@member.fsf.org>
PR classpath/64902
PR classpath/64904
* NEWS: Updated.
* gnu/java/security/jce/sig/KeyPairGeneratorAdapter.java:
(KeyPairGeneratorAdapter(String)): Filter incoming generator
names so all standardised names are handled (e.g. the
DiffieHellman alias for DH.
(generateKeyPair()): Check whether the generator has been
initialized and initialize it with defaults if not.
(getAlgorithm()): Return the standardised name, not the
internal one.
(localiseName(String)): Convert requested standardised
name to the internal equivalent.
* gnu/java/security/key/IKeyPairGenerator.java:
(isInitialized()): New method to check whether the generator
has been initialized.
(getDefaultKeySize()): Return the default key size used
by the generator.
* gnu/java/security/key/dss/DSSKey.java:
(getAlgorithm()): Return standard "DSA" rather than "dsa".
* gnu/java/security/key/dss/DSSKeyPairGenerator.java:
(initialized): Flag to indicate whether the generator has
been initialized or not.
(initLock): Lock to prevent multiple concurrent initializations.
(setup(Map)): Wrap initialization in a lock and set initialized
flag when done.
(isInitialized()): Returns the value of the initialized flag.
(getDefaultKeySize()): Returns the default key size.
* gnu/java/security/key/rsa/GnuRSAKey.java:
(getAlgorithm()): Return standard "RSA" rather than "rsa".
* gnu/java/security/key/rsa/RSAKeyPairGenerator.java:
(initialized): Flag to indicate whether the generator has
been initialized or not.
(initLock): Lock to prevent multiple concurrent initializations.
(setup(Map)): Wrap initialization in a lock and set initialized
flag when done.
(isInitialized()): Returns the value of the initialized flag.
(getDefaultKeySize()): Returns the default key size.
* gnu/javax/crypto/key/dh/GnuDHKey.java:
(getAlgorithm()): Return standard "DH" rather than "dh".
* gnu/javax/crypto/key/dh/GnuDHKeyPairGenerator.java:
(initialized): Flag to indicate whether the generator has
been initialized or not.
(initLock): Lock to prevent multiple concurrent initializations.
(setup(Map)): Wrap initialization in a lock and set initialized
flag when done.
(isInitialized()): Returns the value of the initialized flag.
(getDefaultKeySize()): Returns the default key size.
* gnu/javax/crypto/key/srp6/SRPKeyPairGenerator.java:
(initialized): Flag to indicate whether the generator has
been initialized or not.
(initLock): Lock to prevent multiple concurrent initializations.
(setup(Map)): Wrap initialization in a lock and set initialized
flag when done.
(isInitialized()): Returns the value of the initialized flag.
(getDefaultKeySize()): Returns the default key size.
-rw-r--r-- | ChangeLog | 59 | ||||
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | gnu/java/security/jce/sig/KeyPairGeneratorAdapter.java | 58 | ||||
-rw-r--r-- | gnu/java/security/key/IKeyPairGenerator.java | 17 | ||||
-rw-r--r-- | gnu/java/security/key/dss/DSSKey.java | 2 | ||||
-rw-r--r-- | gnu/java/security/key/dss/DSSKeyPairGenerator.java | 180 | ||||
-rw-r--r-- | gnu/java/security/key/rsa/GnuRSAKey.java | 2 | ||||
-rw-r--r-- | gnu/java/security/key/rsa/RSAKeyPairGenerator.java | 80 | ||||
-rw-r--r-- | gnu/javax/crypto/key/dh/GnuDHKey.java | 4 | ||||
-rw-r--r-- | gnu/javax/crypto/key/dh/GnuDHKeyPairGenerator.java | 122 | ||||
-rw-r--r-- | gnu/javax/crypto/key/srp6/SRPKeyPairGenerator.java | 172 |
11 files changed, 497 insertions, 201 deletions
@@ -1,3 +1,62 @@ +2015-02-02 Andrew John Hughes <gnu_andrew@member.fsf.org> + + PR classpath/64902 + PR classpath/64904 + * NEWS: Updated. + * gnu/java/security/jce/sig/KeyPairGeneratorAdapter.java: + (KeyPairGeneratorAdapter(String)): Filter incoming generator + names so all standardised names are handled (e.g. the + DiffieHellman alias for DH. + (generateKeyPair()): Check whether the generator has been + initialized and initialize it with defaults if not. + (getAlgorithm()): Return the standardised name, not the + internal one. + (localiseName(String)): Convert requested standardised + name to the internal equivalent. + * gnu/java/security/key/IKeyPairGenerator.java: + (isInitialized()): New method to check whether the generator + has been initialized. + (getDefaultKeySize()): Return the default key size used + by the generator. + * gnu/java/security/key/dss/DSSKey.java: + (getAlgorithm()): Return standard "DSA" rather than "dsa". + * gnu/java/security/key/dss/DSSKeyPairGenerator.java: + (initialized): Flag to indicate whether the generator has + been initialized or not. + (initLock): Lock to prevent multiple concurrent initializations. + (setup(Map)): Wrap initialization in a lock and set initialized + flag when done. + (isInitialized()): Returns the value of the initialized flag. + (getDefaultKeySize()): Returns the default key size. + * gnu/java/security/key/rsa/GnuRSAKey.java: + (getAlgorithm()): Return standard "RSA" rather than "rsa". + * gnu/java/security/key/rsa/RSAKeyPairGenerator.java: + (initialized): Flag to indicate whether the generator has + been initialized or not. + (initLock): Lock to prevent multiple concurrent initializations. + (setup(Map)): Wrap initialization in a lock and set initialized + flag when done. + (isInitialized()): Returns the value of the initialized flag. + (getDefaultKeySize()): Returns the default key size. + * gnu/javax/crypto/key/dh/GnuDHKey.java: + (getAlgorithm()): Return standard "DH" rather than "dh". + * gnu/javax/crypto/key/dh/GnuDHKeyPairGenerator.java: + (initialized): Flag to indicate whether the generator has + been initialized or not. + (initLock): Lock to prevent multiple concurrent initializations. + (setup(Map)): Wrap initialization in a lock and set initialized + flag when done. + (isInitialized()): Returns the value of the initialized flag. + (getDefaultKeySize()): Returns the default key size. + * gnu/javax/crypto/key/srp6/SRPKeyPairGenerator.java: + (initialized): Flag to indicate whether the generator has + been initialized or not. + (initLock): Lock to prevent multiple concurrent initializations. + (setup(Map)): Wrap initialization in a lock and set initialized + flag when done. + (isInitialized()): Returns the value of the initialized flag. + (getDefaultKeySize()): Returns the default key size. + 2015-01-30 Andrew John Hughes <gnu_andrew@member.fsf.org> PR classpath/64881 @@ -32,6 +32,8 @@ New in release 0.99.1 (XXX XX, 2012) - PR64109: Missing symbol in libjavautil.so - PR64176: Week of year field during end of year transition is incorrect - PR64881: KeyPairGenerator.genKeyPair() ends up calling the default generateKeyPair method which returns a DSA generator + - PR64902: Keys returned by KeyPairGenerator don't use standardised algorithm names + - PR64904: KeyPairGenerator.genKeyPair() fails if not explicitly initialised New in release 0.99 (Feb 15, 2012) diff --git a/gnu/java/security/jce/sig/KeyPairGeneratorAdapter.java b/gnu/java/security/jce/sig/KeyPairGeneratorAdapter.java index 9d3e5efdd..cd612aaa5 100644 --- a/gnu/java/security/jce/sig/KeyPairGeneratorAdapter.java +++ b/gnu/java/security/jce/sig/KeyPairGeneratorAdapter.java @@ -1,5 +1,5 @@ /* KeyPairGeneratorAdapter.java -- - Copyright 2001, 2002, 2006 Free Software Foundation, Inc. + Copyright 2001, 2002, 2006, 2015 Free Software Foundation, Inc. This file is a part of GNU Classpath. @@ -38,6 +38,7 @@ exception statement from your version. */ package gnu.java.security.jce.sig; +import gnu.java.security.Registry; import gnu.java.security.key.IKeyPairGenerator; import gnu.java.security.key.KeyPairGeneratorFactory; @@ -79,7 +80,7 @@ public abstract class KeyPairGeneratorAdapter { super(kpgName); - this.adaptee = KeyPairGeneratorFactory.getInstance(kpgName); + this.adaptee = KeyPairGeneratorFactory.getInstance(localiseName(kpgName)); } public abstract void initialize(int keysize, SecureRandom random); @@ -90,6 +91,59 @@ public abstract class KeyPairGeneratorAdapter public KeyPair generateKeyPair() { + if (!adaptee.isInitialized()) + initialize(adaptee.getDefaultKeySize()); + return adaptee.generate(); } + + /** + * The {@code java.security.*} methods are expected to return + * standard algorithm names, as listed in + * <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator"> + * the on-line Oracle documentation</a>. + * + * @return the name specified by the Oracle documentation. + */ + @Override + public String getAlgorithm() + { + String alg = super.getAlgorithm(); + + if ("dh".equals(alg)) + return "DH"; + if ("dsa".equals(alg)) + return "DSA"; + if ("dss".equals(alg)) + return "DSA"; + if ("rsa".equals(alg)) + return "RSA"; + return alg; + } + + /** + * The user may specify an algorithm using the names specified in + * <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator"> + * the on-line Oracle documentation</a>. We should translate them + * to names recognised by the GNU registry. + * + * @param kpgName the generator name, which may be its standardised + * name. + * @return the name specified by the GNU registry. + */ + private static String localiseName(String kpgName) + { + /** + if ("DiffieHellman".equals(kpgName)) + return Registry.DH_KPG; + if ("DH".equals(kpgName)) + return Registry.DH_KPG; + if ("DSA".equals(kpgName)) + return Registry.DSA_KPG; + if ("RSA".equals(kpgName)) + return Registry.RSA_KPG; + */ + return kpgName; + } + } diff --git a/gnu/java/security/key/IKeyPairGenerator.java b/gnu/java/security/key/IKeyPairGenerator.java index e7d96b22a..55c62da7a 100644 --- a/gnu/java/security/key/IKeyPairGenerator.java +++ b/gnu/java/security/key/IKeyPairGenerator.java @@ -1,5 +1,5 @@ /* IKeyPairGenerator.java -- - Copyright 2001, 2002, 2006, 2014 Free Software Foundation, Inc. + Copyright 2001, 2002, 2006, 2014, 2015 Free Software Foundation, Inc. This file is a part of GNU Classpath. @@ -70,4 +70,19 @@ public interface IKeyPairGenerator * @return a new keypair. */ KeyPair generate(); + + /** + * Returns true if this instance has been initialized. + * + * @return true if this instance has been initialized. + */ + boolean isInitialized(); + + /** + * Returns the default key size used by this generator. + * + * @return the default key size of this generator. + */ + int getDefaultKeySize(); + } diff --git a/gnu/java/security/key/dss/DSSKey.java b/gnu/java/security/key/dss/DSSKey.java index 0641ff872..ed356ef38 100644 --- a/gnu/java/security/key/dss/DSSKey.java +++ b/gnu/java/security/key/dss/DSSKey.java @@ -135,7 +135,7 @@ public abstract class DSSKey public String getAlgorithm() { - return Registry.DSS_KPG; + return "DSA"; } /** @deprecated see getEncoded(int). */ diff --git a/gnu/java/security/key/dss/DSSKeyPairGenerator.java b/gnu/java/security/key/dss/DSSKeyPairGenerator.java index 9a19947fe..fe1eeb683 100644 --- a/gnu/java/security/key/dss/DSSKeyPairGenerator.java +++ b/gnu/java/security/key/dss/DSSKeyPairGenerator.java @@ -1,5 +1,5 @@ /* DSSKeyPairGenerator.java -- - Copyright 2001, 2002, 2003, 2006, 2010, 2014 Free Software Foundation, Inc. + Copyright 2001, 2002, 2003, 2006, 2010, 2014, 2015 Free Software Foundation, Inc. This file is a part of GNU Classpath. @@ -51,6 +51,9 @@ import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.DSAParameterSpec; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Logger; /** @@ -211,6 +214,12 @@ public class DSSKeyPairGenerator /** Preferred encoding format of generated keys. */ private int preferredFormat; + /** Flag to indicate whether the generator has been initialized */ + private AtomicBoolean initialized = new AtomicBoolean(false); + + /** Lock to prevent concurrent initialization */ + private Lock initLock = new ReentrantLock(); + @Override public String name() { @@ -228,77 +237,88 @@ public class DSSKeyPairGenerator @Override public void setup(Map<String,Object> attributes) { - // find out the modulus length - Integer l = (Integer) attributes.get(MODULUS_LENGTH); - L = (l == null ? DEFAULT_MODULUS_LENGTH : l.intValue()); - if ((L % 64) != 0 || L < 512 || L > 1024) - throw new IllegalArgumentException(MODULUS_LENGTH); - - // should we use the default pre-computed params? - Boolean useDefaults = (Boolean) attributes.get(USE_DEFAULTS); - if (useDefaults == null) - useDefaults = Boolean.TRUE; - - Boolean strictDefaults = (Boolean) attributes.get(STRICT_DEFAULTS); - if (strictDefaults == null) - strictDefaults = Boolean.FALSE; - - // are we given a set of DSA params or we shall use/generate our own? - DSAParameterSpec params = (DSAParameterSpec) attributes.get(DSS_PARAMETERS); - if (params != null) + initLock.lock(); + try { - p = params.getP(); - q = params.getQ(); - g = params.getG(); - } - else if (useDefaults.equals(Boolean.TRUE)) - { - switch (L) - { - case 512: - p = KEY_PARAMS_512.getP(); - q = KEY_PARAMS_512.getQ(); - g = KEY_PARAMS_512.getG(); - break; - case 768: - p = KEY_PARAMS_768.getP(); - q = KEY_PARAMS_768.getQ(); - g = KEY_PARAMS_768.getG(); - break; - case 1024: - p = KEY_PARAMS_1024.getP(); - q = KEY_PARAMS_1024.getQ(); - g = KEY_PARAMS_1024.getG(); - break; - default: - if (strictDefaults.equals(Boolean.TRUE)) - throw new IllegalArgumentException( - "Does not provide default parameters for " + L - + "-bit modulus length"); - else - { - p = null; - q = null; - g = null; - } - } + // find out the modulus length + Integer l = (Integer) attributes.get(MODULUS_LENGTH); + L = (l == null ? DEFAULT_MODULUS_LENGTH : l.intValue()); + if ((L % 64) != 0 || L < 512 || L > 1024) + throw new IllegalArgumentException("The modulus length must be a " + + "factor of 64 between 512 and 1024"); + + // should we use the default pre-computed params? + Boolean useDefaults = (Boolean) attributes.get(USE_DEFAULTS); + if (useDefaults == null) + useDefaults = Boolean.TRUE; + + Boolean strictDefaults = (Boolean) attributes.get(STRICT_DEFAULTS); + if (strictDefaults == null) + strictDefaults = Boolean.FALSE; + + // are we given a set of DSA params or we shall use/generate our own? + DSAParameterSpec params = (DSAParameterSpec) attributes.get(DSS_PARAMETERS); + if (params != null) + { + p = params.getP(); + q = params.getQ(); + g = params.getG(); + } + else if (useDefaults.equals(Boolean.TRUE)) + { + switch (L) + { + case 512: + p = KEY_PARAMS_512.getP(); + q = KEY_PARAMS_512.getQ(); + g = KEY_PARAMS_512.getG(); + break; + case 768: + p = KEY_PARAMS_768.getP(); + q = KEY_PARAMS_768.getQ(); + g = KEY_PARAMS_768.getG(); + break; + case 1024: + p = KEY_PARAMS_1024.getP(); + q = KEY_PARAMS_1024.getQ(); + g = KEY_PARAMS_1024.getG(); + break; + default: + if (strictDefaults.equals(Boolean.TRUE)) + throw new IllegalArgumentException( + "Does not provide default parameters for " + L + + "-bit modulus length"); + else + { + p = null; + q = null; + g = null; + } + } + } + else + { + p = null; + q = null; + g = null; + } + // do we have a SecureRandom, or should we use our own? + rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS); + // what is the preferred encoding format + Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT); + preferredFormat = formatID == null ? DEFAULT_ENCODING_FORMAT + : formatID.intValue(); + // set the seed-key + byte[] kb = new byte[20]; // we need 160 bits of randomness + nextRandomBytes(kb); + XKEY = new BigInteger(1, kb).setBit(159).setBit(0); + + initialized.set(false); } - else + finally { - p = null; - q = null; - g = null; + initLock.unlock(); } - // do we have a SecureRandom, or should we use our own? - rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS); - // what is the preferred encoding format - Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT); - preferredFormat = formatID == null ? DEFAULT_ENCODING_FORMAT - : formatID.intValue(); - // set the seed-key - byte[] kb = new byte[20]; // we need 160 bits of randomness - nextRandomBytes(kb); - XKEY = new BigInteger(1, kb).setBit(159).setBit(0); } @Override @@ -306,6 +326,7 @@ public class DSSKeyPairGenerator { if (p == null) { + System.err.println("Attempting to generate parameters for modulus of length " + L); BigInteger[] params = new FIPS186(L, rnd).generateParameters(); seed = params[FIPS186.DSA_PARAMS_SEED]; counter = params[FIPS186.DSA_PARAMS_COUNTER]; @@ -383,4 +404,27 @@ public class DSSKeyPairGenerator return prng; } + + @Override + public boolean isInitialized() + { + boolean initFlag = false; + + initLock.lock(); + try + { + initFlag = initialized.get(); + } + finally + { + initLock.unlock(); + } + return initFlag; + } + + @Override + public int getDefaultKeySize() + { + return DEFAULT_MODULUS_LENGTH; + } } diff --git a/gnu/java/security/key/rsa/GnuRSAKey.java b/gnu/java/security/key/rsa/GnuRSAKey.java index f8d89af38..543ebdc56 100644 --- a/gnu/java/security/key/rsa/GnuRSAKey.java +++ b/gnu/java/security/key/rsa/GnuRSAKey.java @@ -97,7 +97,7 @@ public abstract class GnuRSAKey public String getAlgorithm() { - return Registry.RSA_KPG; + return "RSA"; } /** @deprecated see getEncoded(int). */ diff --git a/gnu/java/security/key/rsa/RSAKeyPairGenerator.java b/gnu/java/security/key/rsa/RSAKeyPairGenerator.java index a7fc21efe..5f321ce5b 100644 --- a/gnu/java/security/key/rsa/RSAKeyPairGenerator.java +++ b/gnu/java/security/key/rsa/RSAKeyPairGenerator.java @@ -1,5 +1,5 @@ /* RSAKeyPairGenerator.java -- - Copyright 2001, 2002, 2003, 2006, 2010, 2014 Free Software Foundation, Inc. + Copyright 2001, 2002, 2003, 2006, 2010, 2014, 2015 Free Software Foundation, Inc. This file is a part of GNU Classpath. @@ -50,6 +50,9 @@ import java.security.PublicKey; import java.security.SecureRandom; import java.security.spec.RSAKeyGenParameterSpec; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Logger; /** @@ -127,6 +130,12 @@ public class RSAKeyPairGenerator /** Preferred encoding format of generated keys. */ private int preferredFormat; + /** Flag to indicate whether the generator has been initialized */ + private AtomicBoolean initialized = new AtomicBoolean(false); + + /** Lock to prevent concurrent initialization */ + private Lock initLock = new ReentrantLock(); + // implicit 0-arguments constructor @Override @@ -147,28 +156,38 @@ public class RSAKeyPairGenerator { if (Configuration.DEBUG) log.entering(this.getClass().getName(), "setup", attributes); - // do we have a SecureRandom, or should we use our own? - rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS); - // are we given a set of RSA params or we shall use our own? - RSAKeyGenParameterSpec params = (RSAKeyGenParameterSpec) attributes.get(RSA_PARAMETERS); - // find out the modulus length - if (params != null) + initLock.lock(); + try { - L = params.getKeysize(); - e = params.getPublicExponent(); + // do we have a SecureRandom, or should we use our own? + rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS); + // are we given a set of RSA params or we shall use our own? + RSAKeyGenParameterSpec params = (RSAKeyGenParameterSpec) attributes.get(RSA_PARAMETERS); + // find out the modulus length + if (params != null) + { + L = params.getKeysize(); + e = params.getPublicExponent(); + } + else + { + Integer l = (Integer) attributes.get(MODULUS_LENGTH); + L = (l == null ? DEFAULT_MODULUS_LENGTH : l.intValue()); + } + if (L < 1024) + throw new IllegalArgumentException("Invalid modulus size"); + + // what is the preferred encoding format + Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT); + preferredFormat = formatID == null ? DEFAULT_ENCODING_FORMAT + : formatID.intValue(); + + initialized.set(true); } - else + finally { - Integer l = (Integer) attributes.get(MODULUS_LENGTH); - L = (l == null ? DEFAULT_MODULUS_LENGTH : l.intValue()); + initLock.unlock(); } - if (L < 1024) - throw new IllegalArgumentException(MODULUS_LENGTH); - - // what is the preferred encoding format - Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT); - preferredFormat = formatID == null ? DEFAULT_ENCODING_FORMAT - : formatID.intValue(); if (Configuration.DEBUG) log.exiting(this.getClass().getName(), "setup"); } @@ -247,4 +266,27 @@ public class RSAKeyPairGenerator return prng; } + + @Override + public boolean isInitialized() + { + boolean initFlag = false; + + initLock.lock(); + try + { + initFlag = initialized.get(); + } + finally + { + initLock.unlock(); + } + return initFlag; + } + + @Override + public int getDefaultKeySize() + { + return DEFAULT_MODULUS_LENGTH; + } } diff --git a/gnu/javax/crypto/key/dh/GnuDHKey.java b/gnu/javax/crypto/key/dh/GnuDHKey.java index 03a18c310..196d1f8de 100644 --- a/gnu/javax/crypto/key/dh/GnuDHKey.java +++ b/gnu/javax/crypto/key/dh/GnuDHKey.java @@ -1,5 +1,5 @@ /* GnuDHKey.java -- - Copyright (C) 2003, 2006 Free Software Foundation, Inc. + Copyright (C) 2003, 2006, 2015 Free Software Foundation, Inc. This file is a part of GNU Classpath. @@ -113,7 +113,7 @@ public abstract class GnuDHKey public String getAlgorithm() { - return Registry.DH_KPG; + return "DH"; } /** @deprecated see getEncoded(int). */ diff --git a/gnu/javax/crypto/key/dh/GnuDHKeyPairGenerator.java b/gnu/javax/crypto/key/dh/GnuDHKeyPairGenerator.java index a1a19c3b3..7923a534d 100644 --- a/gnu/javax/crypto/key/dh/GnuDHKeyPairGenerator.java +++ b/gnu/javax/crypto/key/dh/GnuDHKeyPairGenerator.java @@ -1,5 +1,5 @@ /* GnuDHKeyPairGenerator.java -- - Copyright (C) 2003, 2006, 2010 Free Software Foundation, Inc. + Copyright (C) 2003, 2006, 2010, 2015 Free Software Foundation, Inc. This file is a part of GNU Classpath. @@ -49,6 +49,9 @@ import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Logger; import javax.crypto.spec.DHGenParameterSpec; @@ -112,6 +115,10 @@ public class GnuDHKeyPairGenerator private PRNG prng = null; /** Preferred encoding format of generated keys. */ private int preferredFormat; + /** Flag to indicate whether the generator has been initialized */ + private AtomicBoolean initialized = new AtomicBoolean(false); + /** Lock to prevent concurrent initialization */ + private Lock initLock = new ReentrantLock(); // default 0-arguments constructor @@ -122,50 +129,60 @@ public class GnuDHKeyPairGenerator public void setup(Map attributes) { - // do we have a SecureRandom, or should we use our own? - rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS); - // are we given a set of Diffie-Hellman generation parameters or we shall - // use our own? - Object params = attributes.get(DH_PARAMETERS); - // find out the desired sizes - if (params instanceof DHGenParameterSpec) + initLock.lock(); + try { - DHGenParameterSpec jceSpec = (DHGenParameterSpec) params; - l = jceSpec.getPrimeSize(); - m = jceSpec.getExponentSize(); - } - else if (params instanceof DHParameterSpec) - { - // FIXME: I'm not sure this is correct. It seems to behave the - // same way as Sun's RI, but I don't know if this behavior is - // documented anywhere. - DHParameterSpec jceSpec = (DHParameterSpec) params; - p = jceSpec.getP(); - g = jceSpec.getG(); - l = p.bitLength(); - m = jceSpec.getL(); - // If no exponent size was given, generate an exponent as - // large as the prime. - if (m == 0) - m = l; + // do we have a SecureRandom, or should we use our own? + rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS); + // are we given a set of Diffie-Hellman generation parameters or we shall + // use our own? + Object params = attributes.get(DH_PARAMETERS); + // find out the desired sizes + if (params instanceof DHGenParameterSpec) + { + DHGenParameterSpec jceSpec = (DHGenParameterSpec) params; + l = jceSpec.getPrimeSize(); + m = jceSpec.getExponentSize(); + } + else if (params instanceof DHParameterSpec) + { + // FIXME: I'm not sure this is correct. It seems to behave the + // same way as Sun's RI, but I don't know if this behavior is + // documented anywhere. + DHParameterSpec jceSpec = (DHParameterSpec) params; + p = jceSpec.getP(); + g = jceSpec.getG(); + l = p.bitLength(); + m = jceSpec.getL(); + // If no exponent size was given, generate an exponent as + // large as the prime. + if (m == 0) + m = l; + } + else + { + Integer bi = (Integer) attributes.get(PRIME_SIZE); + l = (bi == null ? DEFAULT_PRIME_SIZE : bi.intValue()); + bi = (Integer) attributes.get(EXPONENT_SIZE); + m = (bi == null ? DEFAULT_EXPONENT_SIZE : bi.intValue()); + } + if ((l % 256) != 0 || l < DEFAULT_PRIME_SIZE) + throw new IllegalArgumentException("invalid modulus size"); + if ((m % 8) != 0 || m < DEFAULT_EXPONENT_SIZE) + throw new IllegalArgumentException("invalid exponent size"); + if (m > l) + throw new IllegalArgumentException("exponent size > modulus size"); + // what is the preferred encoding format + Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT); + preferredFormat = formatID == null ? DEFAULT_ENCODING_FORMAT + : formatID.intValue(); + + initialized.set(true); } - else + finally { - Integer bi = (Integer) attributes.get(PRIME_SIZE); - l = (bi == null ? DEFAULT_PRIME_SIZE : bi.intValue()); - bi = (Integer) attributes.get(EXPONENT_SIZE); - m = (bi == null ? DEFAULT_EXPONENT_SIZE : bi.intValue()); + initLock.unlock(); } - if ((l % 256) != 0 || l < DEFAULT_PRIME_SIZE) - throw new IllegalArgumentException("invalid modulus size"); - if ((m % 8) != 0 || m < DEFAULT_EXPONENT_SIZE) - throw new IllegalArgumentException("invalid exponent size"); - if (m > l) - throw new IllegalArgumentException("exponent size > modulus size"); - // what is the preferred encoding format - Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT); - preferredFormat = formatID == null ? DEFAULT_ENCODING_FORMAT - : formatID.intValue(); } public KeyPair generate() @@ -231,4 +248,27 @@ public class GnuDHKeyPairGenerator return prng; } + + @Override + public boolean isInitialized() + { + boolean initFlag = false; + + initLock.lock(); + try + { + initFlag = initialized.get(); + } + finally + { + initLock.unlock(); + } + return initFlag; + } + + @Override + public int getDefaultKeySize() + { + return DEFAULT_PRIME_SIZE; + } } diff --git a/gnu/javax/crypto/key/srp6/SRPKeyPairGenerator.java b/gnu/javax/crypto/key/srp6/SRPKeyPairGenerator.java index 25f3d8425..f0db4a4e1 100644 --- a/gnu/javax/crypto/key/srp6/SRPKeyPairGenerator.java +++ b/gnu/javax/crypto/key/srp6/SRPKeyPairGenerator.java @@ -1,5 +1,5 @@ /* SRPKeyPairGenerator.java -- - Copyright (C) 2003, 2006, 2010 Free Software Foundation, Inc. + Copyright (C) 2003, 2006, 2010, 2015 Free Software Foundation, Inc. This file is a part of GNU Classpath. @@ -47,6 +47,9 @@ import java.math.BigInteger; import java.security.KeyPair; import java.security.SecureRandom; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Logger; /** @@ -68,7 +71,7 @@ public class SRPKeyPairGenerator private static final BigInteger THREE = BigInteger.valueOf(3L); /** Property name of the length (Integer) of the modulus (N) of an SRP key. */ public static final String MODULUS_LENGTH = "gnu.crypto.srp.L"; - /** Property name of the Boolean indicating wether or not to use defaults. */ + /** Property name of the Boolean indicating whether or not to use defaults. */ public static final String USE_DEFAULTS = "gnu.crypto.srp.use.defaults"; /** Property name of the modulus (N) of an SRP key. */ public static final String SHARED_MODULUS = "gnu.crypto.srp.N"; @@ -95,6 +98,10 @@ public class SRPKeyPairGenerator private BigInteger v; /** Our default source of randomness. */ private PRNG prng = null; + /** Flag to indicate whether the generator has been initialized */ + private AtomicBoolean initialized = new AtomicBoolean(false); + /** Lock to prevent concurrent initialization */ + private Lock initLock = new ReentrantLock(); // implicit 0-arguments constructor @@ -105,73 +112,83 @@ public class SRPKeyPairGenerator public void setup(Map attributes) { - // do we have a SecureRandom, or should we use our own? - rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS); - N = (BigInteger) attributes.get(SHARED_MODULUS); - if (N != null) + initLock.lock(); + try { - l = N.bitLength(); - g = (BigInteger) attributes.get(GENERATOR); - if (g == null) - g = TWO; - SRPAlgorithm.checkParams(N, g); + // do we have a SecureRandom, or should we use our own? + rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS); + N = (BigInteger) attributes.get(SHARED_MODULUS); + if (N != null) + { + l = N.bitLength(); + g = (BigInteger) attributes.get(GENERATOR); + if (g == null) + g = TWO; + SRPAlgorithm.checkParams(N, g); + } + else + { // generate or use default values for N and g + Boolean useDefaults = (Boolean) attributes.get(USE_DEFAULTS); + if (useDefaults == null) + useDefaults = Boolean.TRUE; + Integer L = (Integer) attributes.get(MODULUS_LENGTH); + l = DEFAULT_MODULUS_LENGTH; + if (useDefaults.equals(Boolean.TRUE)) + { + if (L != null) + { + l = L.intValue(); + switch (l) + { + case 512: + N = SRPAlgorithm.N_512; + break; + case 640: + N = SRPAlgorithm.N_640; + break; + case 768: + N = SRPAlgorithm.N_768; + break; + case 1024: + N = SRPAlgorithm.N_1024; + break; + case 1280: + N = SRPAlgorithm.N_1280; + break; + case 1536: + N = SRPAlgorithm.N_1536; + break; + case 2048: + N = SRPAlgorithm.N_2048; + break; + default: + throw new IllegalArgumentException( + "unknown default shared modulus bit length"); + } + g = TWO; + l = N.bitLength(); + } + } + else // generate new N and g + { + if (L != null) + { + l = L.intValue(); + if ((l % 256) != 0 || l < 512 || l > 2048) + throw new IllegalArgumentException( + "invalid shared modulus bit length"); + } + } + } + // are we using this generator on the server side, or the client side? + v = (BigInteger) attributes.get(USER_VERIFIER); + + initialized.set(true); } - else - { // generate or use default values for N and g - Boolean useDefaults = (Boolean) attributes.get(USE_DEFAULTS); - if (useDefaults == null) - useDefaults = Boolean.TRUE; - Integer L = (Integer) attributes.get(MODULUS_LENGTH); - l = DEFAULT_MODULUS_LENGTH; - if (useDefaults.equals(Boolean.TRUE)) - { - if (L != null) - { - l = L.intValue(); - switch (l) - { - case 512: - N = SRPAlgorithm.N_512; - break; - case 640: - N = SRPAlgorithm.N_640; - break; - case 768: - N = SRPAlgorithm.N_768; - break; - case 1024: - N = SRPAlgorithm.N_1024; - break; - case 1280: - N = SRPAlgorithm.N_1280; - break; - case 1536: - N = SRPAlgorithm.N_1536; - break; - case 2048: - N = SRPAlgorithm.N_2048; - break; - default: - throw new IllegalArgumentException( - "unknown default shared modulus bit length"); - } - g = TWO; - l = N.bitLength(); - } - } - else // generate new N and g - { - if (L != null) - { - l = L.intValue(); - if ((l % 256) != 0 || l < 512 || l > 2048) - throw new IllegalArgumentException( - "invalid shared modulus bit length"); - } - } + finally + { + initLock.unlock(); } - // are we using this generator on the server side, or the client side? - v = (BigInteger) attributes.get(USER_VERIFIER); } public KeyPair generate() @@ -281,4 +298,27 @@ public class SRPKeyPairGenerator return prng; } + + @Override + public boolean isInitialized() + { + boolean initFlag = false; + + initLock.lock(); + try + { + initFlag = initialized.get(); + } + finally + { + initLock.unlock(); + } + return initFlag; + } + + @Override + public int getDefaultKeySize() + { + return DEFAULT_MODULUS_LENGTH; + } } |