1package org.bouncycastle.jcajce.provider.asymmetric.dh;
2
3import java.security.InvalidAlgorithmParameterException;
4import java.security.KeyPair;
5import java.security.SecureRandom;
6import java.security.spec.AlgorithmParameterSpec;
7import java.util.Hashtable;
8
9import javax.crypto.spec.DHParameterSpec;
10
11import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
12import org.bouncycastle.crypto.generators.DHBasicKeyPairGenerator;
13import org.bouncycastle.crypto.generators.DHParametersGenerator;
14import org.bouncycastle.crypto.params.DHKeyGenerationParameters;
15import org.bouncycastle.crypto.params.DHParameters;
16import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
17import org.bouncycastle.crypto.params.DHPublicKeyParameters;
18import org.bouncycastle.jce.provider.BouncyCastleProvider;
19
20public class KeyPairGeneratorSpi
21    extends java.security.KeyPairGenerator
22{
23    private static Hashtable params = new Hashtable();
24
25    DHKeyGenerationParameters param;
26    DHBasicKeyPairGenerator engine = new DHBasicKeyPairGenerator();
27    int strength = 1024;
28    int certainty = 20;
29    SecureRandom random = new SecureRandom();
30    boolean initialised = false;
31
32    public KeyPairGeneratorSpi()
33    {
34        super("DH");
35    }
36
37    public void initialize(
38        int strength,
39        SecureRandom random)
40    {
41        this.strength = strength;
42        this.random = random;
43    }
44
45    public void initialize(
46        AlgorithmParameterSpec params,
47        SecureRandom random)
48        throws InvalidAlgorithmParameterException
49    {
50        if (!(params instanceof DHParameterSpec))
51        {
52            throw new InvalidAlgorithmParameterException("parameter object not a DHParameterSpec");
53        }
54        DHParameterSpec dhParams = (DHParameterSpec)params;
55
56        param = new DHKeyGenerationParameters(random, new DHParameters(dhParams.getP(), dhParams.getG(), null, dhParams.getL()));
57
58        engine.init(param);
59        initialised = true;
60    }
61
62    public KeyPair generateKeyPair()
63    {
64        if (!initialised)
65        {
66            // BEGIN android-changed
67            Integer paramStrength = Integer.valueOf(strength);
68            // END android-changed
69
70            if (params.containsKey(paramStrength))
71            {
72                param = (DHKeyGenerationParameters)params.get(paramStrength);
73            }
74            else
75            {
76                DHParameterSpec dhParams = BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters();
77
78                if (dhParams != null && dhParams.getP().bitLength() == strength)
79                {
80                    param = new DHKeyGenerationParameters(random, new DHParameters(dhParams.getP(), dhParams.getG(), null, dhParams.getL()));
81                }
82                else
83                {
84                    DHParametersGenerator pGen = new DHParametersGenerator();
85
86                    pGen.init(strength, certainty, random);
87
88                    param = new DHKeyGenerationParameters(random, pGen.generateParameters());
89
90                    params.put(paramStrength, param);
91                }
92            }
93
94            engine.init(param);
95
96            initialised = true;
97        }
98
99        AsymmetricCipherKeyPair pair = engine.generateKeyPair();
100        DHPublicKeyParameters pub = (DHPublicKeyParameters)pair.getPublic();
101        DHPrivateKeyParameters priv = (DHPrivateKeyParameters)pair.getPrivate();
102
103        return new KeyPair(new BCDHPublicKey(pub),
104            new BCDHPrivateKey(priv));
105    }
106}
107