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))); }
internal TlsClientContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters) { this.secureRandom = secureRandom; this.securityParameters = securityParameters; }
public virtual void Connect(TlsClient tlsClient) { if (tlsClient == null) { throw new ArgumentNullException("tlsClient"); } if (this.tlsClient != null) { throw new InvalidOperationException("Connect can only be called once"); } /* * Send Client hello * * First, generate some random data. */ this.securityParameters = new SecurityParameters(); this.securityParameters.clientRandom = new byte[32]; random.NextBytes(securityParameters.clientRandom, 4, 28); TlsUtilities.WriteGmtUnixTime(securityParameters.clientRandom, 0); this.tlsClientContext = new TlsClientContextImpl(random, securityParameters); this.tlsClient = tlsClient; this.tlsClient.Init(tlsClientContext); MemoryStream outStr = new MemoryStream(); TlsUtilities.WriteVersion(outStr); outStr.Write(securityParameters.clientRandom, 0, 32); /* * Length of Session id */ TlsUtilities.WriteUint8(0, outStr); this.offeredCipherSuites = this.tlsClient.GetCipherSuites(); // ExtensionType -> byte[] this.clientExtensions = this.tlsClient.GetClientExtensions(); // Cipher Suites (and SCSV) { /* * RFC 5746 3.4. * The client MUST include either an empty "renegotiation_info" * extension, or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling * cipher suite value in the ClientHello. Including both is NOT * RECOMMENDED. */ bool noRenegExt = clientExtensions == null || !clientExtensions.Contains(ExtensionType.renegotiation_info); int count = offeredCipherSuites.Length; if (noRenegExt) { // Note: 1 extra slot for TLS_EMPTY_RENEGOTIATION_INFO_SCSV ++count; } TlsUtilities.WriteUint16(2 * count, outStr); for (int i = 0; i < offeredCipherSuites.Length; ++i) { TlsUtilities.WriteUint16((int)offeredCipherSuites[i], outStr); } if (noRenegExt) { TlsUtilities.WriteUint16((int)CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV, outStr); } } /* * Compression methods, just the null method. */ this.offeredCompressionMethods = tlsClient.GetCompressionMethods(); { TlsUtilities.WriteUint8((byte)offeredCompressionMethods.Length, outStr); for (int i = 0; i < offeredCompressionMethods.Length; ++i) { TlsUtilities.WriteUint8((byte)offeredCompressionMethods[i], outStr); } } // Extensions if (clientExtensions != null) { MemoryStream ext = new MemoryStream(); foreach (ExtensionType extType in clientExtensions.Keys) { WriteExtension(ext, extType, (byte[])clientExtensions[extType]); } TlsUtilities.WriteOpaque16(ext.ToArray(), outStr); } MemoryStream bos = new MemoryStream(); TlsUtilities.WriteUint8((byte)HandshakeType.client_hello, bos); TlsUtilities.WriteUint24((int)outStr.Length, bos); byte[] outBytes = outStr.ToArray(); bos.Write(outBytes, 0, outBytes.Length); byte[] message = bos.ToArray(); SafeWriteMessage(ContentType.handshake, message, 0, message.Length); connection_state = CS_CLIENT_HELLO_SEND; /* * We will now read data, until we have completed the handshake. */ while (connection_state != CS_DONE) { SafeReadData(); } this.tlsStream = new TlsStream(this); }