Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/org/spongycastle/crypto/tls/TlsDHUtils.java')
-rw-r--r--core/src/main/java/org/spongycastle/crypto/tls/TlsDHUtils.java105
1 files changed, 105 insertions, 0 deletions
diff --git a/core/src/main/java/org/spongycastle/crypto/tls/TlsDHUtils.java b/core/src/main/java/org/spongycastle/crypto/tls/TlsDHUtils.java
new file mode 100644
index 00000000..9a7a2218
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/crypto/tls/TlsDHUtils.java
@@ -0,0 +1,105 @@
+package org.spongycastle.crypto.tls;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import org.spongycastle.crypto.AsymmetricCipherKeyPair;
+import org.spongycastle.crypto.agreement.DHBasicAgreement;
+import org.spongycastle.crypto.generators.DHBasicKeyPairGenerator;
+import org.spongycastle.crypto.params.DHKeyGenerationParameters;
+import org.spongycastle.crypto.params.DHParameters;
+import org.spongycastle.crypto.params.DHPrivateKeyParameters;
+import org.spongycastle.crypto.params.DHPublicKeyParameters;
+import org.spongycastle.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.compareTo(TWO) < 0 || g.compareTo(p.subtract(TWO)) > 0)
+ {
+ throw new TlsFatalAlert(AlertDescription.illegal_parameter);
+ }
+ if (Y.compareTo(TWO) < 0 || Y.compareTo(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);
+ }
+}