public override void ComputeKeys() { // Create keyblock TlsStream keyBlock = new TlsStream(this.PRF(this.Context.MasterSecret, "key expansion", this.Context.RandomSC, this.KeyBlockSize)); this.Context.Negotiating.ClientWriteMAC = keyBlock.ReadBytes(this.HashSize); this.Context.Negotiating.ServerWriteMAC = keyBlock.ReadBytes(this.HashSize); this.Context.ClientWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize); this.Context.ServerWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize); if (this.IvSize != 0) { this.Context.ClientWriteIV = keyBlock.ReadBytes(this.IvSize); this.Context.ServerWriteIV = keyBlock.ReadBytes(this.IvSize); } else { this.Context.ClientWriteIV = CipherSuite.EmptyArray; this.Context.ServerWriteIV = CipherSuite.EmptyArray; } DebugHelper.WriteLine(">>>> KeyBlock", keyBlock.ToArray()); DebugHelper.WriteLine(">>>> ClientWriteKey", this.Context.ClientWriteKey); DebugHelper.WriteLine(">>>> ClientWriteIV", this.Context.ClientWriteIV); DebugHelper.WriteLine(">>>> ClientWriteMAC", this.Context.Negotiating.ClientWriteMAC); DebugHelper.WriteLine(">>>> ServerWriteKey", this.Context.ServerWriteKey); DebugHelper.WriteLine(">>>> ServerWriteIV", this.Context.ServerWriteIV); DebugHelper.WriteLine(">>>> ServerWriteMAC", this.Context.Negotiating.ServerWriteMAC); ClientSessionCache.SetContextInCache(this.Context); // Clear no more needed data keyBlock.Reset(); }
public override void ComputeKeys() { // Compute KeyBlock TlsStream tmp = new TlsStream(); char labelChar = 'A'; int count = 1; while (tmp.Length < this.KeyBlockSize) { string label = String.Empty; for (int i = 0; i < count; i++) { label += labelChar.ToString(); } byte[] block = this.prf(this.Context.MasterSecret, label.ToString(), this.Context.RandomSC); int size = (tmp.Length + block.Length) > this.KeyBlockSize ? (this.KeyBlockSize - (int)tmp.Length) : block.Length; tmp.Write(block, 0, size); labelChar++; count++; } // Create keyblock TlsStream keyBlock = new TlsStream(tmp.ToArray()); this.Context.Negotiating.ClientWriteMAC = keyBlock.ReadBytes(this.HashSize); this.Context.Negotiating.ServerWriteMAC = keyBlock.ReadBytes(this.HashSize); this.Context.ClientWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize); this.Context.ServerWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize); if (this.IvSize != 0) { this.Context.ClientWriteIV = keyBlock.ReadBytes(this.IvSize); this.Context.ServerWriteIV = keyBlock.ReadBytes(this.IvSize); } else { this.Context.ClientWriteIV = CipherSuite.EmptyArray; this.Context.ServerWriteIV = CipherSuite.EmptyArray; } DebugHelper.WriteLine(">>>> KeyBlock", keyBlock.ToArray()); DebugHelper.WriteLine(">>>> ClientWriteKey", this.Context.ClientWriteKey); DebugHelper.WriteLine(">>>> ClientWriteIV", this.Context.ClientWriteIV); DebugHelper.WriteLine(">>>> ClientWriteMAC", this.Context.Negotiating.ClientWriteMAC); DebugHelper.WriteLine(">>>> ServerWriteKey", this.Context.ServerWriteKey); DebugHelper.WriteLine(">>>> ServerWriteIV", this.Context.ServerWriteIV); DebugHelper.WriteLine(">>>> ServerWriteMAC", this.Context.Negotiating.ServerWriteMAC); ClientSessionCache.SetContextInCache(this.Context); // Clear no more needed data keyBlock.Reset(); tmp.Reset(); }
public static bool SetContextInCache(Context context) { lock (ClientSessionCache.locker) { ClientSessionInfo clientSessionInfo = ClientSessionCache.FromContext(context, false); if (clientSessionInfo == null) { return(false); } clientSessionInfo.GetContext(context); clientSessionInfo.KeepAlive(); return(true); } }
internal override void OnNegotiateHandshakeCallback(IAsyncResult asyncResult) { this.protocol.EndSendRecord(asyncResult); while (this.context.LastHandshakeMsg != HandshakeType.ServerHelloDone) { this.SafeReceiveRecord(this.innerStream); if (this.context.AbbreviatedHandshake && this.context.LastHandshakeMsg == HandshakeType.ServerHello) { break; } } if (this.context.AbbreviatedHandshake) { ClientSessionCache.SetContextFromCache(this.context); this.context.Negotiating.Cipher.ComputeKeys(); this.context.Negotiating.Cipher.InitializeCipher(); this.protocol.SendChangeCipherSpec(); while (this.context.HandshakeState != HandshakeState.Finished) { this.SafeReceiveRecord(this.innerStream); } this.protocol.SendRecord(HandshakeType.Finished); } else { bool flag = this.context.ServerSettings.CertificateRequest; if (this.context.SecurityProtocol == SecurityProtocolType.Ssl3) { flag = (this.context.ClientSettings.Certificates != null && this.context.ClientSettings.Certificates.Count > 0); } if (flag) { this.protocol.SendRecord(HandshakeType.Certificate); } this.protocol.SendRecord(HandshakeType.ClientKeyExchange); this.context.Negotiating.Cipher.InitializeCipher(); if (flag && this.context.ClientSettings.ClientCertificate != null) { this.protocol.SendRecord(HandshakeType.CertificateVerify); } this.protocol.SendChangeCipherSpec(); this.protocol.SendRecord(HandshakeType.Finished); while (this.context.HandshakeState != HandshakeState.Finished) { this.SafeReceiveRecord(this.innerStream); } } this.context.HandshakeMessages.Reset(); this.context.ClearKeyInfo(); }
public override void ComputeKeys() { TlsStream tlsStream = new TlsStream(this.PRF(this.Context.MasterSecret, "key expansion", this.Context.RandomSC, this.KeyBlockSize)); this.Context.Negotiating.ClientWriteMAC = tlsStream.ReadBytes(this.HashSize); this.Context.Negotiating.ServerWriteMAC = tlsStream.ReadBytes(this.HashSize); this.Context.ClientWriteKey = tlsStream.ReadBytes((int)this.KeyMaterialSize); this.Context.ServerWriteKey = tlsStream.ReadBytes((int)this.KeyMaterialSize); if (!this.IsExportable) { if (this.IvSize != (byte)0) { this.Context.ClientWriteIV = tlsStream.ReadBytes((int)this.IvSize); this.Context.ServerWriteIV = tlsStream.ReadBytes((int)this.IvSize); } else { this.Context.ClientWriteIV = CipherSuite.EmptyArray; this.Context.ServerWriteIV = CipherSuite.EmptyArray; } } else { byte[] numArray1 = this.PRF(this.Context.ClientWriteKey, "client write key", this.Context.RandomCS, (int)this.ExpandedKeyMaterialSize); byte[] numArray2 = this.PRF(this.Context.ServerWriteKey, "server write key", this.Context.RandomCS, (int)this.ExpandedKeyMaterialSize); this.Context.ClientWriteKey = numArray1; this.Context.ServerWriteKey = numArray2; if (this.IvSize > (byte)0) { byte[] numArray3 = this.PRF(CipherSuite.EmptyArray, "IV block", this.Context.RandomCS, (int)this.IvSize * 2); this.Context.ClientWriteIV = new byte[(int)this.IvSize]; Buffer.BlockCopy((Array)numArray3, 0, (Array)this.Context.ClientWriteIV, 0, this.Context.ClientWriteIV.Length); this.Context.ServerWriteIV = new byte[(int)this.IvSize]; Buffer.BlockCopy((Array)numArray3, (int)this.IvSize, (Array)this.Context.ServerWriteIV, 0, this.Context.ServerWriteIV.Length); } else { this.Context.ClientWriteIV = CipherSuite.EmptyArray; this.Context.ServerWriteIV = CipherSuite.EmptyArray; } } ClientSessionCache.SetContextInCache(this.Context); tlsStream.Reset(); }
public override void ComputeKeys() { TlsStream tlsStream = new TlsStream(PRF(base.Context.MasterSecret, "key expansion", base.Context.RandomSC, base.KeyBlockSize)); base.Context.Negotiating.ClientWriteMAC = tlsStream.ReadBytes(base.HashSize); base.Context.Negotiating.ServerWriteMAC = tlsStream.ReadBytes(base.HashSize); base.Context.ClientWriteKey = tlsStream.ReadBytes(base.KeyMaterialSize); base.Context.ServerWriteKey = tlsStream.ReadBytes(base.KeyMaterialSize); if (!base.IsExportable) { if (base.IvSize != 0) { base.Context.ClientWriteIV = tlsStream.ReadBytes(base.IvSize); base.Context.ServerWriteIV = tlsStream.ReadBytes(base.IvSize); } else { base.Context.ClientWriteIV = CipherSuite.EmptyArray; base.Context.ServerWriteIV = CipherSuite.EmptyArray; } } else { byte[] clientWriteKey = PRF(base.Context.ClientWriteKey, "client write key", base.Context.RandomCS, base.ExpandedKeyMaterialSize); byte[] serverWriteKey = PRF(base.Context.ServerWriteKey, "server write key", base.Context.RandomCS, base.ExpandedKeyMaterialSize); base.Context.ClientWriteKey = clientWriteKey; base.Context.ServerWriteKey = serverWriteKey; if (base.IvSize > 0) { byte[] src = PRF(CipherSuite.EmptyArray, "IV block", base.Context.RandomCS, base.IvSize * 2); base.Context.ClientWriteIV = new byte[base.IvSize]; Buffer.BlockCopy(src, 0, base.Context.ClientWriteIV, 0, base.Context.ClientWriteIV.Length); base.Context.ServerWriteIV = new byte[base.IvSize]; Buffer.BlockCopy(src, base.IvSize, base.Context.ServerWriteIV, 0, base.Context.ServerWriteIV.Length); } else { base.Context.ClientWriteIV = CipherSuite.EmptyArray; base.Context.ServerWriteIV = CipherSuite.EmptyArray; } } ClientSessionCache.SetContextInCache(base.Context); tlsStream.Reset(); }
public static bool SetContextInCache(Context context) { object obj = ClientSessionCache.locker; bool result; lock (obj) { ClientSessionInfo clientSessionInfo = ClientSessionCache.FromContext(context, false); if (clientSessionInfo == null) { result = false; } else { clientSessionInfo.GetContext(context); clientSessionInfo.KeepAlive(); result = true; } } return(result); }
private void NegotiateAsyncWorker(IAsyncResult result) { NegotiateAsyncResult negotiate = result.AsyncState as NegotiateAsyncResult; try { switch (negotiate.State) { case NegotiateState.SentClientHello: this.protocol.EndSendRecord(result); // we are now ready to ready the receive the hello response. negotiate.State = NegotiateState.ReceiveClientHelloResponse; // Start reading the client hello response this.protocol.BeginReceiveRecord(this.innerStream, NegotiateAsyncWorker, negotiate); break; case NegotiateState.ReceiveClientHelloResponse: this.SafeEndReceiveRecord(result, true); if (this.context.LastHandshakeMsg != HandshakeType.ServerHelloDone && (!this.context.AbbreviatedHandshake || this.context.LastHandshakeMsg != HandshakeType.ServerHello)) { // Read next record (skip empty, e.g. warnings alerts) this.protocol.BeginReceiveRecord(this.innerStream, NegotiateAsyncWorker, negotiate); break; } // special case for abbreviated handshake where no ServerHelloDone is sent from the server if (this.context.AbbreviatedHandshake) { ClientSessionCache.SetContextFromCache(this.context); this.context.Negotiating.Cipher.ComputeKeys(); this.context.Negotiating.Cipher.InitializeCipher(); negotiate.State = NegotiateState.SentCipherSpec; // Send Change Cipher Spec message with the current cipher // or as plain text if this is the initial negotiation this.protocol.BeginSendChangeCipherSpec(NegotiateAsyncWorker, negotiate); } else { // Send client certificate if requested // even if the server ask for it it _may_ still be optional bool clientCertificate = this.context.ServerSettings.CertificateRequest; using (var memstream = new MemoryStream()) { // NOTE: sadly SSL3 and TLS1 differs in how they handle this and // the current design doesn't allow a very cute way to handle // SSL3 alert warning for NoCertificate (41). if (this.context.SecurityProtocol == SecurityProtocolType.Ssl3) { clientCertificate = ((this.context.ClientSettings.Certificates != null) && (this.context.ClientSettings.Certificates.Count > 0)); // this works well with OpenSSL (but only for SSL3) } byte[] record = null; if (clientCertificate) { record = this.protocol.EncodeHandshakeRecord(HandshakeType.Certificate); memstream.Write(record, 0, record.Length); } // Send Client Key Exchange record = this.protocol.EncodeHandshakeRecord(HandshakeType.ClientKeyExchange); memstream.Write(record, 0, record.Length); // Now initialize session cipher with the generated keys this.context.Negotiating.Cipher.InitializeCipher(); // Send certificate verify if requested (optional) if (clientCertificate && (this.context.ClientSettings.ClientCertificate != null)) { record = this.protocol.EncodeHandshakeRecord(HandshakeType.CertificateVerify); memstream.Write(record, 0, record.Length); } // send the chnage cipher spec. this.protocol.SendChangeCipherSpec(memstream); // Send Finished message record = this.protocol.EncodeHandshakeRecord(HandshakeType.Finished); memstream.Write(record, 0, record.Length); negotiate.State = NegotiateState.SentKeyExchange; // send all the records. this.innerStream.BeginWrite(memstream.GetBuffer(), 0, (int)memstream.Length, NegotiateAsyncWorker, negotiate); } } break; case NegotiateState.SentKeyExchange: this.innerStream.EndWrite(result); negotiate.State = NegotiateState.ReceiveFinishResponse; this.protocol.BeginReceiveRecord(this.innerStream, NegotiateAsyncWorker, negotiate); break; case NegotiateState.ReceiveFinishResponse: this.SafeEndReceiveRecord(result); // Read record until server finished is received if (this.context.HandshakeState != HandshakeState.Finished) { // If all goes well this will process messages: // Change Cipher Spec // Server finished this.protocol.BeginReceiveRecord(this.innerStream, NegotiateAsyncWorker, negotiate); } else { // Reset Handshake messages information this.context.HandshakeMessages.Reset(); // Clear Key Info this.context.ClearKeyInfo(); negotiate.SetComplete(); } break; case NegotiateState.SentCipherSpec: this.protocol.EndSendChangeCipherSpec(result); negotiate.State = NegotiateState.ReceiveCipherSpecResponse; // Start reading the cipher spec response this.protocol.BeginReceiveRecord(this.innerStream, NegotiateAsyncWorker, negotiate); break; case NegotiateState.ReceiveCipherSpecResponse: this.SafeEndReceiveRecord(result, true); if (this.context.HandshakeState != HandshakeState.Finished) { this.protocol.BeginReceiveRecord(this.innerStream, NegotiateAsyncWorker, negotiate); } else { negotiate.State = NegotiateState.SentFinished; this.protocol.BeginSendRecord(HandshakeType.Finished, NegotiateAsyncWorker, negotiate); } break; case NegotiateState.SentFinished: this.protocol.EndSendRecord(result); // Reset Handshake messages information this.context.HandshakeMessages.Reset(); // Clear Key Info this.context.ClearKeyInfo(); negotiate.SetComplete(); break; } } catch (TlsException ex) { try { Exception e = ex; this.protocol.SendAlert(ref e); } catch { } negotiate.SetComplete(new IOException("The authentication or decryption has failed.", ex)); } catch (Exception ex) { try { this.protocol.SendAlert(AlertDescription.InternalError); } catch { } negotiate.SetComplete(new IOException("The authentication or decryption has failed.", ex)); } }
internal override void OnNegotiateHandshakeCallback(IAsyncResult asyncResult) { this.protocol.EndSendRecord(asyncResult); // Read server response while (this.context.LastHandshakeMsg != HandshakeType.ServerHelloDone) { // Read next record SafeReceiveRecord(this.innerStream); // special case for abbreviated handshake where no ServerHelloDone is sent from the server if (this.context.AbbreviatedHandshake && (this.context.LastHandshakeMsg == HandshakeType.ServerHello)) { break; } } // the handshake is much easier if we can reuse a previous session settings if (this.context.AbbreviatedHandshake) { ClientSessionCache.SetContextFromCache(this.context); this.context.Negotiating.Cipher.ComputeKeys(); this.context.Negotiating.Cipher.InitializeCipher(); // Send Cipher Spec protocol this.protocol.SendChangeCipherSpec(); // Read record until server finished is received while (this.context.HandshakeState != HandshakeState.Finished) { // If all goes well this will process messages: // Change Cipher Spec // Server finished SafeReceiveRecord(this.innerStream); } // Send Finished message this.protocol.SendRecord(HandshakeType.Finished); } else { // Send client certificate if requested // even if the server ask for it it _may_ still be optional bool clientCertificate = this.context.ServerSettings.CertificateRequest; // NOTE: sadly SSL3 and TLS1 differs in how they handle this and // the current design doesn't allow a very cute way to handle // SSL3 alert warning for NoCertificate (41). if (this.context.SecurityProtocol == SecurityProtocolType.Ssl3) { clientCertificate = ((this.context.ClientSettings.Certificates != null) && (this.context.ClientSettings.Certificates.Count > 0)); // this works well with OpenSSL (but only for SSL3) } if (clientCertificate) { this.protocol.SendRecord(HandshakeType.Certificate); } // Send Client Key Exchange this.protocol.SendRecord(HandshakeType.ClientKeyExchange); // Now initialize session cipher with the generated keys this.context.Negotiating.Cipher.InitializeCipher(); // Send certificate verify if requested (optional) if (clientCertificate && (this.context.ClientSettings.ClientCertificate != null)) { this.protocol.SendRecord(HandshakeType.CertificateVerify); } // Send Cipher Spec protocol this.protocol.SendChangeCipherSpec(); // Send Finished message this.protocol.SendRecord(HandshakeType.Finished); // Read record until server finished is received while (this.context.HandshakeState != HandshakeState.Finished) { // If all goes well this will process messages: // Change Cipher Spec // Server finished SafeReceiveRecord(this.innerStream); } } // Reset Handshake messages information this.context.HandshakeMessages.Reset(); // Clear Key Info this.context.ClearKeyInfo(); }
public override void ComputeKeys() { // Compute KeyBlock TlsStream tmp = new TlsStream(); char labelChar = 'A'; int count = 1; while (tmp.Length < this.KeyBlockSize) { string label = String.Empty; for (int i = 0; i < count; i++) { label += labelChar.ToString(); } byte[] block = this.prf(this.Context.MasterSecret, label.ToString(), this.Context.RandomSC); int size = (tmp.Length + block.Length) > this.KeyBlockSize ? (this.KeyBlockSize - (int)tmp.Length) : block.Length; tmp.Write(block, 0, size); labelChar++; count++; } // Create keyblock TlsStream keyBlock = new TlsStream(tmp.ToArray()); this.Context.Negotiating.ClientWriteMAC = keyBlock.ReadBytes(this.HashSize); this.Context.Negotiating.ServerWriteMAC = keyBlock.ReadBytes(this.HashSize); this.Context.ClientWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize); this.Context.ServerWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize); if (!this.IsExportable) { if (this.IvSize != 0) { this.Context.ClientWriteIV = keyBlock.ReadBytes(this.IvSize); this.Context.ServerWriteIV = keyBlock.ReadBytes(this.IvSize); } else { this.Context.ClientWriteIV = CipherSuite.EmptyArray; this.Context.ServerWriteIV = CipherSuite.EmptyArray; } } else { HashAlgorithm md5 = MD5.Create(); int keySize = (md5.HashSize >> 3); //in bytes not bits byte[] temp = new byte [keySize]; // Generate final write keys md5.TransformBlock(this.Context.ClientWriteKey, 0, this.Context.ClientWriteKey.Length, temp, 0); md5.TransformFinalBlock(this.Context.RandomCS, 0, this.Context.RandomCS.Length); byte[] finalClientWriteKey = new byte[this.ExpandedKeyMaterialSize]; Buffer.BlockCopy(md5.Hash, 0, finalClientWriteKey, 0, this.ExpandedKeyMaterialSize); md5.Initialize(); md5.TransformBlock(this.Context.ServerWriteKey, 0, this.Context.ServerWriteKey.Length, temp, 0); md5.TransformFinalBlock(this.Context.RandomSC, 0, this.Context.RandomSC.Length); byte[] finalServerWriteKey = new byte[this.ExpandedKeyMaterialSize]; Buffer.BlockCopy(md5.Hash, 0, finalServerWriteKey, 0, this.ExpandedKeyMaterialSize); this.Context.ClientWriteKey = finalClientWriteKey; this.Context.ServerWriteKey = finalServerWriteKey; // Generate IV keys if (this.IvSize > 0) { md5.Initialize(); temp = md5.ComputeHash(this.Context.RandomCS, 0, this.Context.RandomCS.Length); this.Context.ClientWriteIV = new byte[this.IvSize]; Buffer.BlockCopy(temp, 0, this.Context.ClientWriteIV, 0, this.IvSize); md5.Initialize(); temp = md5.ComputeHash(this.Context.RandomSC, 0, this.Context.RandomSC.Length); this.Context.ServerWriteIV = new byte[this.IvSize]; Buffer.BlockCopy(temp, 0, this.Context.ServerWriteIV, 0, this.IvSize); } else { this.Context.ClientWriteIV = CipherSuite.EmptyArray; this.Context.ServerWriteIV = CipherSuite.EmptyArray; } } DebugHelper.WriteLine(">>>> KeyBlock", keyBlock.ToArray()); DebugHelper.WriteLine(">>>> ClientWriteKey", this.Context.ClientWriteKey); DebugHelper.WriteLine(">>>> ClientWriteIV", this.Context.ClientWriteIV); DebugHelper.WriteLine(">>>> ClientWriteMAC", this.Context.Negotiating.ClientWriteMAC); DebugHelper.WriteLine(">>>> ServerWriteKey", this.Context.ServerWriteKey); DebugHelper.WriteLine(">>>> ServerWriteIV", this.Context.ServerWriteIV); DebugHelper.WriteLine(">>>> ServerWriteMAC", this.Context.Negotiating.ServerWriteMAC); ClientSessionCache.SetContextInCache(this.Context); // Clear no more needed data keyBlock.Reset(); tmp.Reset(); }
public override void ComputeKeys() { TlsStream tlsStream = new TlsStream(); char c = 'A'; int num = 1; while (tlsStream.Length < base.KeyBlockSize) { string text = string.Empty; for (int i = 0; i < num; i++) { text += c.ToString(); } byte[] array = prf(base.Context.MasterSecret, text.ToString(), base.Context.RandomSC); int count = (tlsStream.Length + array.Length <= base.KeyBlockSize) ? array.Length : (base.KeyBlockSize - (int)tlsStream.Length); tlsStream.Write(array, 0, count); c = (char)(c + 1); num++; } TlsStream tlsStream2 = new TlsStream(tlsStream.ToArray()); base.Context.Negotiating.ClientWriteMAC = tlsStream2.ReadBytes(base.HashSize); base.Context.Negotiating.ServerWriteMAC = tlsStream2.ReadBytes(base.HashSize); base.Context.ClientWriteKey = tlsStream2.ReadBytes(base.KeyMaterialSize); base.Context.ServerWriteKey = tlsStream2.ReadBytes(base.KeyMaterialSize); if (!base.IsExportable) { if (base.IvSize != 0) { base.Context.ClientWriteIV = tlsStream2.ReadBytes(base.IvSize); base.Context.ServerWriteIV = tlsStream2.ReadBytes(base.IvSize); } else { base.Context.ClientWriteIV = CipherSuite.EmptyArray; base.Context.ServerWriteIV = CipherSuite.EmptyArray; } } else { HashAlgorithm hashAlgorithm = MD5.Create(); int num2 = hashAlgorithm.HashSize >> 3; byte[] outputBuffer = new byte[num2]; hashAlgorithm.TransformBlock(base.Context.ClientWriteKey, 0, base.Context.ClientWriteKey.Length, outputBuffer, 0); hashAlgorithm.TransformFinalBlock(base.Context.RandomCS, 0, base.Context.RandomCS.Length); byte[] array2 = new byte[base.ExpandedKeyMaterialSize]; Buffer.BlockCopy(hashAlgorithm.Hash, 0, array2, 0, base.ExpandedKeyMaterialSize); hashAlgorithm.Initialize(); hashAlgorithm.TransformBlock(base.Context.ServerWriteKey, 0, base.Context.ServerWriteKey.Length, outputBuffer, 0); hashAlgorithm.TransformFinalBlock(base.Context.RandomSC, 0, base.Context.RandomSC.Length); byte[] array3 = new byte[base.ExpandedKeyMaterialSize]; Buffer.BlockCopy(hashAlgorithm.Hash, 0, array3, 0, base.ExpandedKeyMaterialSize); base.Context.ClientWriteKey = array2; base.Context.ServerWriteKey = array3; if (base.IvSize > 0) { hashAlgorithm.Initialize(); outputBuffer = hashAlgorithm.ComputeHash(base.Context.RandomCS, 0, base.Context.RandomCS.Length); base.Context.ClientWriteIV = new byte[base.IvSize]; Buffer.BlockCopy(outputBuffer, 0, base.Context.ClientWriteIV, 0, base.IvSize); hashAlgorithm.Initialize(); outputBuffer = hashAlgorithm.ComputeHash(base.Context.RandomSC, 0, base.Context.RandomSC.Length); base.Context.ServerWriteIV = new byte[base.IvSize]; Buffer.BlockCopy(outputBuffer, 0, base.Context.ServerWriteIV, 0, base.IvSize); } else { base.Context.ClientWriteIV = CipherSuite.EmptyArray; base.Context.ServerWriteIV = CipherSuite.EmptyArray; } } ClientSessionCache.SetContextInCache(base.Context); tlsStream2.Reset(); tlsStream.Reset(); }
public override void ComputeKeys() { // Create keyblock TlsStream keyBlock = new TlsStream( this.PRF( this.Context.MasterSecret, "key expansion", this.Context.RandomSC, this.KeyBlockSize)); this.Context.Negotiating.ClientWriteMAC = keyBlock.ReadBytes(this.HashSize); this.Context.Negotiating.ServerWriteMAC = keyBlock.ReadBytes(this.HashSize); this.Context.ClientWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize); this.Context.ServerWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize); if (!this.IsExportable) { if (this.IvSize != 0) { this.Context.ClientWriteIV = keyBlock.ReadBytes(this.IvSize); this.Context.ServerWriteIV = keyBlock.ReadBytes(this.IvSize); } else { this.Context.ClientWriteIV = CipherSuite.EmptyArray; this.Context.ServerWriteIV = CipherSuite.EmptyArray; } } else { // Generate final write keys byte[] finalClientWriteKey = PRF(this.Context.ClientWriteKey, "client write key", this.Context.RandomCS, this.ExpandedKeyMaterialSize); byte[] finalServerWriteKey = PRF(this.Context.ServerWriteKey, "server write key", this.Context.RandomCS, this.ExpandedKeyMaterialSize); this.Context.ClientWriteKey = finalClientWriteKey; this.Context.ServerWriteKey = finalServerWriteKey; if (this.IvSize > 0) { // Generate IV block byte[] ivBlock = PRF(CipherSuite.EmptyArray, "IV block", this.Context.RandomCS, this.IvSize * 2); // Generate IV keys this.Context.ClientWriteIV = new byte[this.IvSize]; Buffer.BlockCopy(ivBlock, 0, this.Context.ClientWriteIV, 0, this.Context.ClientWriteIV.Length); this.Context.ServerWriteIV = new byte[this.IvSize]; Buffer.BlockCopy(ivBlock, this.IvSize, this.Context.ServerWriteIV, 0, this.Context.ServerWriteIV.Length); } else { this.Context.ClientWriteIV = CipherSuite.EmptyArray; this.Context.ServerWriteIV = CipherSuite.EmptyArray; } } DebugHelper.WriteLine(">>>> KeyBlock", keyBlock.ToArray()); DebugHelper.WriteLine(">>>> ClientWriteKey", this.Context.ClientWriteKey); DebugHelper.WriteLine(">>>> ClientWriteIV", this.Context.ClientWriteIV); DebugHelper.WriteLine(">>>> ClientWriteMAC", this.Context.Negotiating.ClientWriteMAC); DebugHelper.WriteLine(">>>> ServerWriteKey", this.Context.ServerWriteKey); DebugHelper.WriteLine(">>>> ServerWriteIV", this.Context.ServerWriteIV); DebugHelper.WriteLine(">>>> ServerWriteMAC", this.Context.Negotiating.ServerWriteMAC); ClientSessionCache.SetContextInCache(this.Context); // Clear no more needed data keyBlock.Reset(); }