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