com.fitbur.bouncycastle.crypto.tls.TlsDHUtils Maven / Gradle / Ivy
package com.fitbur.bouncycastle.crypto.tls;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.security.SecureRandom;
import com.fitbur.bouncycastle.crypto.AsymmetricCipherKeyPair;
import com.fitbur.bouncycastle.crypto.agreement.DHBasicAgreement;
import com.fitbur.bouncycastle.crypto.generators.DHBasicKeyPairGenerator;
import com.fitbur.bouncycastle.crypto.params.DHKeyGenerationParameters;
import com.fitbur.bouncycastle.crypto.params.DHParameters;
import com.fitbur.bouncycastle.crypto.params.DHPrivateKeyParameters;
import com.fitbur.bouncycastle.crypto.params.DHPublicKeyParameters;
import com.fitbur.bouncycastle.util.BigIntegers;
public class TlsDHUtils
{
static final BigInteger ONE = BigInteger.valueOf(1);
static final BigInteger TWO = BigInteger.valueOf(2);
public static boolean areCompatibleParameters(DHParameters a, DHParameters b)
{
return a.getP().equals(b.getP()) && a.getG().equals(b.getG());
}
public static byte[] calculateDHBasicAgreement(DHPublicKeyParameters publicKey, DHPrivateKeyParameters privateKey)
{
DHBasicAgreement basicAgreement = new DHBasicAgreement();
basicAgreement.init(privateKey);
BigInteger agreementValue = basicAgreement.calculateAgreement(publicKey);
/*
* RFC 5246 8.1.2. Leading bytes of Z that contain all zero bits are stripped before it is
* used as the pre_master_secret.
*/
return BigIntegers.asUnsignedByteArray(agreementValue);
}
public static AsymmetricCipherKeyPair generateDHKeyPair(SecureRandom random, DHParameters dhParams)
{
DHBasicKeyPairGenerator dhGen = new DHBasicKeyPairGenerator();
dhGen.init(new DHKeyGenerationParameters(random, dhParams));
return dhGen.generateKeyPair();
}
public static DHPrivateKeyParameters generateEphemeralClientKeyExchange(SecureRandom random, DHParameters dhParams,
OutputStream output) throws IOException
{
AsymmetricCipherKeyPair kp = generateDHKeyPair(random, dhParams);
DHPublicKeyParameters dh_public = (DHPublicKeyParameters) kp.getPublic();
writeDHParameter(dh_public.getY(), output);
return (DHPrivateKeyParameters) kp.getPrivate();
}
public static DHPrivateKeyParameters generateEphemeralServerKeyExchange(SecureRandom random, DHParameters dhParams,
OutputStream output) throws IOException
{
AsymmetricCipherKeyPair kp = TlsDHUtils.generateDHKeyPair(random, dhParams);
DHPublicKeyParameters dhPublicKey = (DHPublicKeyParameters)kp.getPublic();
ServerDHParams params = new ServerDHParams(dhPublicKey);
params.encode(output);
return (DHPrivateKeyParameters)kp.getPrivate();
}
public static DHPublicKeyParameters validateDHPublicKey(DHPublicKeyParameters key) throws IOException
{
BigInteger Y = key.getY();
DHParameters params = key.getParameters();
BigInteger p = params.getP();
BigInteger g = params.getG();
if (!p.isProbablePrime(2))
{
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
}
if (g.com.fitburpareTo(TWO) < 0 || g.com.fitburpareTo(p.subtract(TWO)) > 0)
{
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
}
if (Y.com.fitburpareTo(TWO) < 0 || Y.com.fitburpareTo(p.subtract(ONE)) > 0)
{
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
}
// TODO See RFC 2631 for more discussion of Diffie-Hellman validation
return key;
}
public static BigInteger readDHParameter(InputStream input) throws IOException
{
return new BigInteger(1, TlsUtils.readOpaque16(input));
}
public static void writeDHParameter(BigInteger x, OutputStream output) throws IOException
{
TlsUtils.writeOpaque16(BigIntegers.asUnsignedByteArray(x), output);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy