|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.security.provider; |
|
|
|
import java.math.BigInteger; |
|
|
|
import java.security.*; |
|
import java.security.SecureRandom; |
|
import java.security.interfaces.DSAParams; |
|
import java.security.spec.AlgorithmParameterSpec; |
|
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; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
class DSAKeyPairGenerator extends KeyPairGenerator { |
|
|
|
|
|
private int plen; |
|
private int qlen; |
|
|
|
|
|
boolean forceNewParameters; |
|
|
|
|
|
private DSAParameterSpec params; |
|
|
|
|
|
private SecureRandom random; |
|
|
|
DSAKeyPairGenerator(int defaultKeySize) { |
|
super("DSA"); |
|
initialize(defaultKeySize, null); |
|
} |
|
|
|
private static void checkStrength(int sizeP, int sizeQ) { |
|
if ((sizeP >= 512) && (sizeP <= 1024) && (sizeP % 64 == 0) |
|
&& sizeQ == 160) { |
|
// traditional - allow for backward compatibility |
|
// L=multiples of 64 and between 512 and 1024 (inclusive) |
|
// N=160 |
|
} else if (sizeP == 2048 && (sizeQ == 224 || sizeQ == 256)) { |
|
// L=2048, N=224 or 256 |
|
} else if (sizeP == 3072 && sizeQ == 256) { |
|
// L=3072, N=256 |
|
} else { |
|
throw new InvalidParameterException |
|
("Unsupported prime and subprime size combination: " + |
|
sizeP + ", " + sizeQ); |
|
} |
|
} |
|
|
|
public void initialize(int modlen, SecureRandom random) { |
|
init(modlen, random, false); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void initialize(AlgorithmParameterSpec params, SecureRandom random) |
|
throws InvalidAlgorithmParameterException { |
|
if (!(params instanceof DSAParameterSpec)) { |
|
throw new InvalidAlgorithmParameterException |
|
("Inappropriate parameter"); |
|
} |
|
init((DSAParameterSpec)params, random, false); |
|
} |
|
|
|
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); |
|
this.plen = sizeP; |
|
this.qlen = sizeQ; |
|
this.params = params; |
|
this.random = random; |
|
this.forceNewParameters = forceNew; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public KeyPair generateKeyPair() { |
|
if (random == null) { |
|
random = JCAUtil.getSecureRandom(); |
|
} |
|
DSAParameterSpec spec; |
|
try { |
|
if (forceNewParameters) { |
|
|
|
spec = ParameterCache.getNewDSAParameterSpec(plen, qlen, random); |
|
} else { |
|
if (params == null) { |
|
params = |
|
ParameterCache.getDSAParameterSpec(plen, qlen, random); |
|
} |
|
spec = params; |
|
} |
|
} catch (GeneralSecurityException e) { |
|
throw new ProviderException(e); |
|
} |
|
return generateKeyPair(spec.getP(), spec.getQ(), spec.getG(), random); |
|
} |
|
|
|
private KeyPair generateKeyPair(BigInteger p, BigInteger q, BigInteger g, |
|
SecureRandom random) { |
|
|
|
BigInteger x = generateX(random, q); |
|
BigInteger y = generateY(x, p, g); |
|
|
|
try { |
|
|
|
// See the comments in DSAKeyFactory, 4532506, and 6232513. |
|
|
|
DSAPublicKey pub; |
|
if (DSAKeyFactory.SERIAL_INTEROP) { |
|
pub = new DSAPublicKey(y, p, q, g); |
|
} else { |
|
pub = new DSAPublicKeyImpl(y, p, q, g); |
|
} |
|
DSAPrivateKey priv = new DSAPrivateKey(x, p, q, g); |
|
|
|
KeyPair pair = new KeyPair(pub, priv); |
|
return pair; |
|
} catch (InvalidKeyException e) { |
|
throw new ProviderException(e); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private BigInteger generateX(SecureRandom random, BigInteger q) { |
|
BigInteger x = null; |
|
byte[] temp = new byte[qlen]; |
|
while (true) { |
|
random.nextBytes(temp); |
|
x = new BigInteger(1, temp).mod(q); |
|
if (x.signum() > 0 && (x.compareTo(q) < 0)) { |
|
return x; |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
BigInteger generateY(BigInteger x, BigInteger p, BigInteger g) { |
|
BigInteger y = g.modPow(x, p); |
|
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); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
@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); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
@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); |
|
} |
|
} |
|
} |