summary refs log tree commit diff
path: root/Crypto/src/crypto/tls/TlsDHUtilities.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Crypto/src/crypto/tls/TlsDHUtilities.cs')
-rw-r--r--Crypto/src/crypto/tls/TlsDHUtilities.cs70
1 files changed, 70 insertions, 0 deletions
diff --git a/Crypto/src/crypto/tls/TlsDHUtilities.cs b/Crypto/src/crypto/tls/TlsDHUtilities.cs
new file mode 100644

index 000000000..733749ea1 --- /dev/null +++ b/Crypto/src/crypto/tls/TlsDHUtilities.cs
@@ -0,0 +1,70 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Crypto.Agreement; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public abstract class TlsDHUtilities + { + public static byte[] CalculateDHBasicAgreement(DHPublicKeyParameters publicKey, + DHPrivateKeyParameters privateKey) + { + DHBasicAgreement dhAgree = new DHBasicAgreement(); + dhAgree.Init(privateKey); + BigInteger agreement = dhAgree.CalculateAgreement(publicKey); + return BigIntegers.AsUnsignedByteArray(agreement); + } + + 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, Stream output) + { + AsymmetricCipherKeyPair dhAgreeClientKeyPair = GenerateDHKeyPair(random, dhParams); + DHPrivateKeyParameters dhAgreeClientPrivateKey = + (DHPrivateKeyParameters)dhAgreeClientKeyPair.Private; + + BigInteger Yc = ((DHPublicKeyParameters)dhAgreeClientKeyPair.Public).Y; + byte[] keData = BigIntegers.AsUnsignedByteArray(Yc); + TlsUtilities.WriteOpaque16(keData, output); + + return dhAgreeClientPrivateKey; + } + + public static DHPublicKeyParameters ValidateDHPublicKey(DHPublicKeyParameters key) + { + BigInteger Y = key.Y; + DHParameters parameters = key.Parameters; + BigInteger p = parameters.P; + BigInteger g = parameters.G; + + if (!p.IsProbablePrime(2)) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + if (g.CompareTo(BigInteger.Two) < 0 || g.CompareTo(p.Subtract(BigInteger.Two)) > 0) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + if (Y.CompareTo(BigInteger.Two) < 0 || Y.CompareTo(p.Subtract(BigInteger.One)) > 0) + { + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + + // TODO See RFC 2631 for more discussion of Diffie-Hellman validation + + return key; + } + } +} \ No newline at end of file