public override void ProcessServerKeyExchange(Stream input)
        {
			SecurityParameters securityParameters = context.SecurityParameters;

            ISigner signer = InitSigner(tlsSigner, securityParameters);
            Stream sigIn = new SignerStream(input, signer, null);

            ECCurveType curveType = (ECCurveType)TlsUtilities.ReadUint8(sigIn);
            ECDomainParameters curve_params;

            //  Currently, we only support named curves
            if (curveType == ECCurveType.named_curve)
            {
                NamedCurve namedCurve = (NamedCurve)TlsUtilities.ReadUint16(sigIn);

                // TODO Check namedCurve is one we offered?

                curve_params = NamedCurveHelper.GetECParameters(namedCurve);
            }
            else
            {
                // TODO Add support for explicit curve parameters (read from sigIn)

                throw new TlsFatalAlert(AlertDescription.handshake_failure);
            }

            byte[] publicBytes = TlsUtilities.ReadOpaque8(sigIn);

            byte[] sigByte = TlsUtilities.ReadOpaque16(input);
            if (!signer.VerifySignature(sigByte))
            {
                throw new TlsFatalAlert(AlertDescription.bad_certificate);
            }

            // TODO Check curve_params not null

            ECPoint Q = curve_params.Curve.DecodePoint(publicBytes);

			this.ecAgreeServerPublicKey = ValidateECPublicKey(new ECPublicKeyParameters(Q, curve_params));
        }
		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)));
		}
		public virtual void ProcessServerKeyExchange(Stream input)
		{
			SecurityParameters securityParameters = context.SecurityParameters;

			Stream sigIn = input;
			ISigner signer = null;

			if (tlsSigner != null)
			{
				signer = InitSigner(tlsSigner, securityParameters);
				sigIn = new SignerStream(input, signer, null);
			}

			byte[] NBytes = TlsUtilities.ReadOpaque16(sigIn);
			byte[] gBytes = TlsUtilities.ReadOpaque16(sigIn);
			byte[] sBytes = TlsUtilities.ReadOpaque8(sigIn);
			byte[] BBytes = TlsUtilities.ReadOpaque16(sigIn);

			if (signer != null)
			{
				byte[] sigByte = TlsUtilities.ReadOpaque16(input);

				if (!signer.VerifySignature(sigByte))
				{
					throw new TlsFatalAlert(AlertDescription.bad_certificate);
				}
			}

			BigInteger N = new BigInteger(1, NBytes);
			BigInteger g = new BigInteger(1, gBytes);

			// TODO Validate group parameters (see RFC 5054)
			//throw new TlsFatalAlert(AlertDescription.insufficient_security);

			this.s = sBytes;

			/*
			* RFC 5054 2.5.3: The client MUST abort the handshake with an "illegal_parameter"
			* alert if B % N = 0.
			*/
			try
			{
				this.B = Srp6Utilities.ValidatePublicValue(N, new BigInteger(1, BBytes));
			}
			catch (CryptoException)
			{
				throw new TlsFatalAlert(AlertDescription.illegal_parameter);
			}

			this.srpClient.Init(N, g, new Sha1Digest(), context.SecureRandom);
		}