116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropackage org.bouncycastle.jcajce.provider.asymmetric.dh; 216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.security.InvalidAlgorithmParameterException; 416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.security.KeyPair; 516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.security.SecureRandom; 616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.security.spec.AlgorithmParameterSpec; 716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.util.Hashtable; 816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport javax.crypto.spec.DHParameterSpec; 1016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 1116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.AsymmetricCipherKeyPair; 1216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.generators.DHBasicKeyPairGenerator; 1316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.generators.DHParametersGenerator; 1416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.params.DHKeyGenerationParameters; 1516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.params.DHParameters; 1616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.params.DHPrivateKeyParameters; 1716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.params.DHPublicKeyParameters; 18823ad5bac1616941ae772fe6b69560b49c89d7b3Adam Vartanianimport org.bouncycastle.jcajce.provider.asymmetric.util.PrimeCertaintyCalculator; 1916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.jce.provider.BouncyCastleProvider; 2016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.util.Integers; 2116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 2216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropublic class KeyPairGeneratorSpi 2316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro extends java.security.KeyPairGenerator 2416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro{ 2516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private static Hashtable params = new Hashtable(); 2616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private static Object lock = new Object(); 2716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 2816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro DHKeyGenerationParameters param; 2916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro DHBasicKeyPairGenerator engine = new DHBasicKeyPairGenerator(); 30823ad5bac1616941ae772fe6b69560b49c89d7b3Adam Vartanian int strength = 2048; 3116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro SecureRandom random = new SecureRandom(); 3216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro boolean initialised = false; 3316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 3416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public KeyPairGeneratorSpi() 3516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 3616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro super("DH"); 3716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 3816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 3916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public void initialize( 4016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int strength, 4116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro SecureRandom random) 4216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 4316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.strength = strength; 4416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.random = random; 454caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro this.initialised = false; 4616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 4716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 4816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public void initialize( 4916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro AlgorithmParameterSpec params, 5016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro SecureRandom random) 5116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws InvalidAlgorithmParameterException 5216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 5316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (!(params instanceof DHParameterSpec)) 5416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 5516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new InvalidAlgorithmParameterException("parameter object not a DHParameterSpec"); 5616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 5716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro DHParameterSpec dhParams = (DHParameterSpec)params; 5816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 5916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro param = new DHKeyGenerationParameters(random, new DHParameters(dhParams.getP(), dhParams.getG(), null, dhParams.getL())); 6016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 6116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro engine.init(param); 6216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro initialised = true; 6316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 6416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 6516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public KeyPair generateKeyPair() 6616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 6716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (!initialised) 6816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 6916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro Integer paramStrength = Integers.valueOf(strength); 7016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 7116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (params.containsKey(paramStrength)) 7216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 7316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro param = (DHKeyGenerationParameters)params.get(paramStrength); 7416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 7516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 7616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 7716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro DHParameterSpec dhParams = BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(strength); 7816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 7916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (dhParams != null) 8016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 8116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro param = new DHKeyGenerationParameters(random, new DHParameters(dhParams.getP(), dhParams.getG(), null, dhParams.getL())); 8216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 8316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 8416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 8516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro synchronized (lock) 8616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 8716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // we do the check again in case we were blocked by a generator for 8816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // our key size. 8916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (params.containsKey(paramStrength)) 9016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 9116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro param = (DHKeyGenerationParameters)params.get(paramStrength); 9216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 9316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 9416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 9516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 9616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro DHParametersGenerator pGen = new DHParametersGenerator(); 9716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 98823ad5bac1616941ae772fe6b69560b49c89d7b3Adam Vartanian pGen.init(strength, PrimeCertaintyCalculator.getDefaultCertainty(strength), random); 9916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 10016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro param = new DHKeyGenerationParameters(random, pGen.generateParameters()); 10116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 10216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro params.put(paramStrength, param); 10316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 10416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 10516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 10616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 10716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 10816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro engine.init(param); 10916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 11016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro initialised = true; 11116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 11216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 11316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro AsymmetricCipherKeyPair pair = engine.generateKeyPair(); 11416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro DHPublicKeyParameters pub = (DHPublicKeyParameters)pair.getPublic(); 11516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro DHPrivateKeyParameters priv = (DHPrivateKeyParameters)pair.getPrivate(); 11616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 1174caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro return new KeyPair(new BCDHPublicKey(pub), new BCDHPrivateKey(priv)); 11816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 11916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro} 120