14c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrompackage org.bouncycastle.jcajce.provider.asymmetric.dh;
24c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
34c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.InvalidAlgorithmParameterException;
44c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.KeyPair;
54c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.SecureRandom;
64c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.spec.AlgorithmParameterSpec;
74c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.util.Hashtable;
84c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
94c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport javax.crypto.spec.DHParameterSpec;
104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.crypto.AsymmetricCipherKeyPair;
124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.crypto.generators.DHBasicKeyPairGenerator;
134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.crypto.generators.DHParametersGenerator;
144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.crypto.params.DHKeyGenerationParameters;
154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.crypto.params.DHParameters;
164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.crypto.params.DHPrivateKeyParameters;
174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.crypto.params.DHPublicKeyParameters;
184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.jce.provider.BouncyCastleProvider;
1970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstromimport org.bouncycastle.util.Integers;
204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrompublic class KeyPairGeneratorSpi
224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    extends java.security.KeyPairGenerator
234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom{
244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private static Hashtable params = new Hashtable();
2570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom    private static Object    lock = new Object();
264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    DHKeyGenerationParameters param;
284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    DHBasicKeyPairGenerator engine = new DHBasicKeyPairGenerator();
294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    int strength = 1024;
304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    int certainty = 20;
314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    SecureRandom random = new SecureRandom();
324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    boolean initialised = false;
334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public KeyPairGeneratorSpi()
354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        super("DH");
374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public void initialize(
404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int strength,
414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        SecureRandom random)
424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.strength = strength;
444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.random = random;
454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public void initialize(
484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        AlgorithmParameterSpec params,
494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        SecureRandom random)
504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        throws InvalidAlgorithmParameterException
514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (!(params instanceof DHParameterSpec))
534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            throw new InvalidAlgorithmParameterException("parameter object not a DHParameterSpec");
554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        DHParameterSpec dhParams = (DHParameterSpec)params;
574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        param = new DHKeyGenerationParameters(random, new DHParameters(dhParams.getP(), dhParams.getG(), null, dhParams.getL()));
594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        engine.init(param);
614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        initialised = true;
624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public KeyPair generateKeyPair()
654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (!initialised)
674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
6870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom            Integer paramStrength = Integers.valueOf(strength);
694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (params.containsKey(paramStrength))
714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                param = (DHKeyGenerationParameters)params.get(paramStrength);
734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            else
754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
7670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                DHParameterSpec dhParams = BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(strength);
774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
7870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                if (dhParams != null)
794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                {
804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    param = new DHKeyGenerationParameters(random, new DHParameters(dhParams.getP(), dhParams.getG(), null, dhParams.getL()));
814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                }
824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                else
834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                {
8470c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                    synchronized (lock)
8570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                    {
8670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                        // we do the check again in case we were blocked by a generator for
8770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                        // our key size.
8870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                        if (params.containsKey(paramStrength))
8970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                        {
9070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                            param = (DHKeyGenerationParameters)params.get(paramStrength);
9170c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                        }
9270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                        else
9370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                        {
9470c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom
9570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                            DHParametersGenerator pGen = new DHParametersGenerator();
9670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom
9770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                            pGen.init(strength, certainty, random);
9870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom
9970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                            param = new DHKeyGenerationParameters(random, pGen.generateParameters());
10070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom
10170c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                            params.put(paramStrength, param);
10270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                        }
10370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom                    }
1044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                }
1054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
1064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            engine.init(param);
1084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            initialised = true;
1104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        AsymmetricCipherKeyPair pair = engine.generateKeyPair();
1134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        DHPublicKeyParameters pub = (DHPublicKeyParameters)pair.getPublic();
1144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        DHPrivateKeyParameters priv = (DHPrivateKeyParameters)pair.getPrivate();
1154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return new KeyPair(new BCDHPublicKey(pub),
1174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            new BCDHPrivateKey(priv));
1184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom}
120