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; } } }