summary refs log tree commit diff
path: root/Crypto/src/crypto/tls/TlsDheKeyExchange.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Crypto/src/crypto/tls/TlsDheKeyExchange.cs')
-rw-r--r--Crypto/src/crypto/tls/TlsDheKeyExchange.cs56
1 files changed, 56 insertions, 0 deletions
diff --git a/Crypto/src/crypto/tls/TlsDheKeyExchange.cs b/Crypto/src/crypto/tls/TlsDheKeyExchange.cs
new file mode 100644
index 000000000..edadaeb38
--- /dev/null
+++ b/Crypto/src/crypto/tls/TlsDheKeyExchange.cs
@@ -0,0 +1,56 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Crypto.IO;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Crypto.Tls
+{
+	internal class TlsDheKeyExchange
+		: TlsDHKeyExchange
+	{
+		internal TlsDheKeyExchange(TlsClientContext context, KeyExchangeAlgorithm keyExchange)
+			: base(context, keyExchange)
+		{
+		}
+
+		public override void SkipServerKeyExchange()
+		{
+			throw new TlsFatalAlert(AlertDescription.unexpected_message);
+		}
+
+		public override void ProcessServerKeyExchange(Stream input)
+		{
+			SecurityParameters securityParameters = context.SecurityParameters;
+
+			ISigner signer = InitSigner(tlsSigner, securityParameters);
+			Stream sigIn = new SignerStream(input, signer, null);
+
+			byte[] pBytes = TlsUtilities.ReadOpaque16(sigIn);
+			byte[] gBytes = TlsUtilities.ReadOpaque16(sigIn);
+			byte[] YsBytes = TlsUtilities.ReadOpaque16(sigIn);
+
+			byte[] sigByte = TlsUtilities.ReadOpaque16(input);
+			if (!signer.VerifySignature(sigByte))
+			{
+				throw new TlsFatalAlert(AlertDescription.bad_certificate);
+			}
+
+			BigInteger p = new BigInteger(1, pBytes);
+			BigInteger g = new BigInteger(1, gBytes);
+			BigInteger Ys = new BigInteger(1, YsBytes);
+
+			this.dhAgreeServerPublicKey = ValidateDHPublicKey(
+				new DHPublicKeyParameters(Ys, new DHParameters(p, g)));
+		}
+
+		protected virtual ISigner InitSigner(TlsSigner tlsSigner, SecurityParameters securityParameters)
+		{
+			ISigner signer = tlsSigner.CreateVerifyer(this.serverPublicKey);
+			signer.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
+			signer.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
+			return signer;
+		}
+	}
+}