public byte[] Expand(string hashName, byte[] secret, byte[] seed, int length) { int num1 = !(hashName == "MD5") ? 20 : 16; int num2 = length / num1; if (length % num1 > 0) { ++num2; } Mono.Security.Cryptography.HMAC hmac = new Mono.Security.Cryptography.HMAC(hashName, secret); TlsStream tlsStream1 = new TlsStream(); byte[][] numArray1 = new byte[num2 + 1][]; numArray1[0] = seed; for (int index = 1; index <= num2; ++index) { TlsStream tlsStream2 = new TlsStream(); hmac.TransformFinalBlock(numArray1[index - 1], 0, numArray1[index - 1].Length); numArray1[index] = hmac.Hash; tlsStream2.Write(numArray1[index]); tlsStream2.Write(seed); hmac.TransformFinalBlock(tlsStream2.ToArray(), 0, (int)tlsStream2.Length); tlsStream1.Write(hmac.Hash); tlsStream2.Reset(); } byte[] numArray2 = new byte[length]; Buffer.BlockCopy((Array)tlsStream1.ToArray(), 0, (Array)numArray2, 0, numArray2.Length); tlsStream1.Reset(); return(numArray2); }
public byte[] PRF(byte[] secret, string label, byte[] data, int length) { int num = secret.Length >> 1; if ((secret.Length & 1) == 1) { num++; } TlsStream tlsStream = new TlsStream(); tlsStream.Write(Encoding.ASCII.GetBytes(label)); tlsStream.Write(data); byte[] seed = tlsStream.ToArray(); tlsStream.Reset(); byte[] array = new byte[num]; Buffer.BlockCopy(secret, 0, array, 0, num); byte[] array2 = new byte[num]; Buffer.BlockCopy(secret, secret.Length - num, array2, 0, num); byte[] array3 = Expand("MD5", array, seed, length); byte[] array4 = Expand("SHA1", array2, seed, length); byte[] array5 = new byte[length]; for (int i = 0; i < array5.Length; i++) { array5[i] = (byte)(array3[i] ^ array4[i]); } return(array5); }
protected override void ProcessHandshakeMessage(TlsStream handMsg) { HandshakeType handshakeType = (HandshakeType)handMsg.ReadByte(); HandshakeMessage message = null; DebugHelper.WriteLine(">>>> Processing Handshake record ({0})", handshakeType); // Read message length int length = handMsg.ReadInt24(); // Read message data byte[] data = new byte[length]; handMsg.Read(data, 0, length); // Create and process the server message message = this.createServerHandshakeMessage(handshakeType, data); message.Process(); // Update the last handshake message this.Context.LastHandshakeMsg = handshakeType; // Update session if (message != null) { message.Update(); } }
public byte[] PRF(byte[] secret, string label, byte[] data, int length) { int count = secret.Length >> 1; if ((secret.Length & 1) == 1) { ++count; } TlsStream tlsStream = new TlsStream(); tlsStream.Write(Encoding.ASCII.GetBytes(label)); tlsStream.Write(data); byte[] array = tlsStream.ToArray(); tlsStream.Reset(); byte[] secret1 = new byte[count]; Buffer.BlockCopy((Array)secret, 0, (Array)secret1, 0, count); byte[] secret2 = new byte[count]; Buffer.BlockCopy((Array)secret, secret.Length - count, (Array)secret2, 0, count); byte[] numArray1 = this.Expand("MD5", secret1, array, length); byte[] numArray2 = this.Expand("SHA1", secret2, array, length); byte[] numArray3 = new byte[length]; for (int index = 0; index < numArray3.Length; ++index) { numArray3[index] = (byte)((uint)numArray1[index] ^ (uint)numArray2[index]); } return(numArray3); }
public byte[] EncodeRecord(ContentType contentType, byte[] recordData, int offset, int count) { if (this.context.SentConnectionEnd) { throw new TlsException(AlertDescription.InternalError, "The session is finished and it's no longer valid."); } TlsStream tlsStream = new TlsStream(); short num; for (int srcOffset = offset; srcOffset < offset + count; srcOffset += (int)num) { num = count + offset - srcOffset <= 16384 ? (short)(count + offset - srcOffset) : (short)16384; byte[] numArray = new byte[(int)num]; Buffer.BlockCopy((Array)recordData, srcOffset, (Array)numArray, 0, (int)num); if (this.Context.Write != null && this.Context.Write.Cipher != null) { numArray = this.encryptRecordFragment(contentType, numArray); } tlsStream.Write((byte)contentType); tlsStream.Write(this.context.Protocol); tlsStream.Write((short)numArray.Length); tlsStream.Write(numArray); } return(tlsStream.ToArray()); }
private void ProcessCipherSpecV2Buffer(SecurityProtocolType protocol, byte[] buffer) { TlsStream tlsStream = new TlsStream(buffer); string prefix = protocol != SecurityProtocolType.Ssl3 ? "TLS_" : "SSL_"; while (tlsStream.Position < tlsStream.Length) { byte num = tlsStream.ReadByte(); if (num == (byte)0) { int index = this.Context.SupportedCiphers.IndexOf(tlsStream.ReadInt16()); if (index != -1) { this.Context.Negotiating.Cipher = this.Context.SupportedCiphers[index]; break; } } else { byte[] buffer1 = new byte[2]; tlsStream.Read(buffer1, 0, buffer1.Length); int code = ((int)num & (int)byte.MaxValue) << 16 | ((int)buffer1[0] & (int)byte.MaxValue) << 8 | (int)buffer1[1] & (int)byte.MaxValue; CipherSuite cipherSuite = this.MapV2CipherCode(prefix, code); if (cipherSuite != null) { this.Context.Negotiating.Cipher = cipherSuite; break; } } } if (this.Context.Negotiating == null) { throw new TlsException(AlertDescription.InsuficientSecurity, "Insuficient Security"); } }
public override byte[] ComputeServerRecordMAC(ContentType contentType, byte[] fragment) { HashAlgorithm hash = HashAlgorithm.Create(this.HashAlgorithmName); TlsStream block = new TlsStream(); block.Write(this.Context.ServerWriteMAC); block.Write(this.pad1); if (this.Context is ClientContext) { block.Write(this.Context.ReadSequenceNumber); } else { block.Write(this.Context.WriteSequenceNumber); } block.Write((byte)contentType); block.Write((short)fragment.Length); block.Write(fragment); hash.ComputeHash(block.ToArray(), 0, (int)block.Length); byte[] blockHash = hash.Hash; block.Reset(); block.Write(this.Context.ServerWriteMAC); block.Write(this.pad2); block.Write(blockHash); hash.ComputeHash(block.ToArray(), 0, (int)block.Length); block.Reset(); return hash.Hash; }
public override byte[] ComputeClientRecordMAC(ContentType contentType, byte[] fragment) { TlsStream data = new TlsStream(); byte[] result = null; if (this.Context is ClientContext) { data.Write(this.Context.WriteSequenceNumber); } else { data.Write(this.Context.ReadSequenceNumber); } data.Write((byte)contentType); data.Write(this.Context.Protocol); data.Write((short)fragment.Length); data.Write(fragment); result = this.ClientHMAC.ComputeHash(data.ToArray()); data.Reset(); return result; }
protected override void ProcessHandshakeMessage(TlsStream handMsg) { HandshakeType type = (HandshakeType)handMsg.ReadByte(); int count = handMsg.ReadInt24(); byte[] buffer = (byte[])null; if (count > 0) { buffer = new byte[count]; handMsg.Read(buffer, 0, count); } HandshakeMessage handshakeMessage = this.createServerHandshakeMessage(type, buffer); handshakeMessage?.Process(); this.Context.LastHandshakeMsg = type; if (handshakeMessage == null) { return; } handshakeMessage.Update(); this.Context.HandshakeMessages.WriteByte((byte)type); this.Context.HandshakeMessages.WriteInt24(count); if (count <= 0) { return; } this.Context.HandshakeMessages.Write(buffer, 0, buffer.Length); }
protected override void ProcessHandshakeMessage(TlsStream handMsg) { HandshakeType handshakeType = (HandshakeType)handMsg.ReadByte(); HandshakeMessage message = null; // Read message length int length = handMsg.ReadInt24(); // Read message data byte[] data = new byte[length]; handMsg.Read(data, 0, length); // Create and process the server message message = this.createClientHandshakeMessage(handshakeType, data); message.Process(); // Update the last handshake message this.Context.LastHandshakeMsg = handshakeType; // Update session if (message != null) { message.Update(); this.Context.HandshakeMessages.WriteByte ((byte) handshakeType); this.Context.HandshakeMessages.WriteInt24 (length); this.Context.HandshakeMessages.Write (data, 0, data.Length); } }
protected override void ProcessHandshakeMessage(TlsStream handMsg) { HandshakeType handshakeType = (HandshakeType)handMsg.ReadByte(); HandshakeMessage handshakeMessage = null; int num = handMsg.ReadInt24(); byte[] array = null; if (num > 0) { array = new byte[num]; handMsg.Read(array, 0, num); } handshakeMessage = createServerHandshakeMessage(handshakeType, array); handshakeMessage?.Process(); base.Context.LastHandshakeMsg = handshakeType; if (handshakeMessage != null) { handshakeMessage.Update(); base.Context.HandshakeMessages.WriteByte((byte)handshakeType); base.Context.HandshakeMessages.WriteInt24(num); if (num > 0) { base.Context.HandshakeMessages.Write(array, 0, array.Length); } } }
public byte[] Expand(string hashName, byte[] secret, byte[] seed, int length) { int num = (!(hashName == "MD5")) ? 20 : 16; int num2 = length / num; if (length % num > 0) { num2++; } Mono.Security.Cryptography.HMAC hMAC = new Mono.Security.Cryptography.HMAC(hashName, secret); TlsStream tlsStream = new TlsStream(); byte[][] array = new byte[num2 + 1][]; array[0] = seed; for (int i = 1; i <= num2; i++) { TlsStream tlsStream2 = new TlsStream(); hMAC.TransformFinalBlock(array[i - 1], 0, array[i - 1].Length); array[i] = hMAC.Hash; tlsStream2.Write(array[i]); tlsStream2.Write(seed); hMAC.TransformFinalBlock(tlsStream2.ToArray(), 0, (int)tlsStream2.Length); tlsStream.Write(hMAC.Hash); tlsStream2.Reset(); } byte[] array2 = new byte[length]; Buffer.BlockCopy(tlsStream.ToArray(), 0, array2, 0, array2.Length); tlsStream.Reset(); return(array2); }
private void ProcessCipherSpecV2Buffer(SecurityProtocolType protocol, byte[] buffer) { TlsStream tlsStream = new TlsStream(buffer); string prefix = (protocol != SecurityProtocolType.Ssl3) ? "TLS_" : "SSL_"; while (tlsStream.Position < tlsStream.Length) { byte b = tlsStream.ReadByte(); if (b == 0) { short code = tlsStream.ReadInt16(); int num = Context.SupportedCiphers.IndexOf(code); if (num != -1) { Context.Negotiating.Cipher = Context.SupportedCiphers[num]; break; } continue; } byte[] array = new byte[2]; tlsStream.Read(array, 0, array.Length); int code2 = ((b & 0xFF) << 16) | ((array[0] & 0xFF) << 8) | (array[1] & 0xFF); CipherSuite cipherSuite = MapV2CipherCode(prefix, code2); if (cipherSuite == null) { continue; } Context.Negotiating.Cipher = cipherSuite; break; } if (Context.Negotiating == null) { throw new TlsException(AlertDescription.InsuficientSecurity, "Insuficient Security"); } }
public byte[] EncodeRecord(ContentType contentType, byte[] recordData, int offset, int count) { if (context.SentConnectionEnd) { throw new TlsException(AlertDescription.InternalError, "The session is finished and it's no longer valid."); } TlsStream tlsStream = new TlsStream(); short num; for (int i = offset; i < offset + count; i += num) { num = 0; num = (short)((count + offset - i <= 16384) ? ((short)(count + offset - i)) : 16384); byte[] array = new byte[num]; Buffer.BlockCopy(recordData, i, array, 0, num); if (Context.Write != null && Context.Write.Cipher != null) { array = encryptRecordFragment(contentType, array); } tlsStream.Write((byte)contentType); tlsStream.Write(context.Protocol); tlsStream.Write((short)array.Length); tlsStream.Write(array); } return(tlsStream.ToArray()); }
private byte[] prf(byte[] secret, string label, byte[] random) { HashAlgorithm md5 = MD5.Create(); HashAlgorithm sha = SHA1.Create(); // Compute SHA hash TlsStream block = new TlsStream(); block.Write(Encoding.ASCII.GetBytes(label)); block.Write(secret); block.Write(random); byte[] shaHash = sha.ComputeHash(block.ToArray(), 0, (int)block.Length); block.Reset(); // Compute MD5 hash block.Write(secret); block.Write(shaHash); byte[] result = md5.ComputeHash(block.ToArray(), 0, (int)block.Length); // Free resources block.Reset(); return(result); }
protected override void ProcessHandshakeMessage(TlsStream handMsg) { HandshakeType handshakeType = (HandshakeType)handMsg.ReadByte(); HandshakeMessage message = null; // Read message length int length = handMsg.ReadInt24(); // Read message data byte[] data = new byte[length]; handMsg.Read(data, 0, length); // Create and process the server message message = this.createClientHandshakeMessage(handshakeType, data); message.Process(); // Update the last handshake message this.Context.LastHandshakeMsg = handshakeType; // Update session if (message != null) { message.Update(); this.Context.HandshakeMessages.WriteByte((byte)handshakeType); this.Context.HandshakeMessages.WriteInt24(length); this.Context.HandshakeMessages.Write(data, 0, data.Length); } }
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 byte[] Expand(HashAlgorithm hash, byte[] secret, byte[] seed, int length) { int hashLength = hash.HashSize / 8; int iterations = (int)(length / hashLength); if ((length % hashLength) > 0) { iterations++; } M.HMAC hmac = new M.HMAC(hash, secret); TlsStream resMacs = new TlsStream(); byte[][] hmacs = new byte[iterations + 1][]; hmacs[0] = seed; for (int i = 1; i <= iterations; i++) { TlsStream hcseed = new TlsStream(); hmac.TransformFinalBlock(hmacs[i - 1], 0, hmacs[i - 1].Length); hmacs[i] = hmac.Hash; hcseed.Write(hmacs[i]); hcseed.Write(seed); hmac.TransformFinalBlock(hcseed.ToArray(), 0, (int)hcseed.Length); resMacs.Write(hmac.Hash); hcseed.Reset(); } byte[] res = new byte[length]; Buffer.BlockCopy(resMacs.ToArray(), 0, res, 0, res.Length); resMacs.Reset(); return(res); }
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 override void ComputeMasterSecret(byte[] preMasterSecret) { TlsStream tlsStream = new TlsStream(); tlsStream.Write(prf(preMasterSecret, "A", base.Context.RandomCS)); tlsStream.Write(prf(preMasterSecret, "BB", base.Context.RandomCS)); tlsStream.Write(prf(preMasterSecret, "CCC", base.Context.RandomCS)); base.Context.MasterSecret = tlsStream.ToArray(); }
public byte[] PRF(byte[] secret, string label, byte[] data, int length) { /* Secret Length calc exmplain from the RFC2246. Section 5 * * S1 and S2 are the two halves of the secret and each is the same * length. S1 is taken from the first half of the secret, S2 from the * second half. Their length is created by rounding up the length of the * overall secret divided by two; thus, if the original secret is an odd * number of bytes long, the last byte of S1 will be the same as the * first byte of S2. */ // split secret in 2 var secretLen = secret.Length >> 1; // rounding up if ((secret.Length & 0x1) == 0x1) { secretLen++; } // Seed var seedStream = new TlsStream(); seedStream.Write(Encoding.ASCII.GetBytes(label)); seedStream.Write(data); var seed = seedStream.ToArray(); seedStream.Reset(); // Secret 1 var secret1 = new byte[secretLen]; Buffer.BlockCopy(secret, 0, secret1, 0, secretLen); // Secret2 var secret2 = new byte[secretLen]; Buffer.BlockCopy(secret, secret.Length - secretLen, secret2, 0, secretLen); // Secret 1 processing var p_md5 = Expand(MD5.Create(), secret1, seed, length); // Secret 2 processing var p_sha = Expand(SHA1.Create(), secret2, seed, length); // Perfor XOR of both results var masterSecret = new byte[length]; for (var i = 0; i < masterSecret.Length; i++) { masterSecret[i] = (byte)(p_md5[i] ^ p_sha[i]); } return(masterSecret); }
public virtual void Clear() { compressionMethod = SecurityCompressionType.None; serverSettings = new TlsServerSettings(); clientSettings = new TlsClientSettings(); handshakeMessages = new TlsStream(); sessionId = null; handshakeState = HandshakeState.None; ClearKeyInfo(); }
public virtual void Clear() { this.compressionMethod = SecurityCompressionType.None; this.serverSettings = new TlsServerSettings(); this.clientSettings = new TlsClientSettings(); this.handshakeMessages = new TlsStream(); this.sessionId = (byte[])null; this.handshakeState = HandshakeState.None; this.ClearKeyInfo(); }
public byte[] EncodeRecord( ContentType contentType, byte[] recordData, int offset, int count) { if (this.context.SentConnectionEnd) { throw new TlsException( AlertDescription.InternalError, "The session is finished and it's no longer valid."); } TlsStream record = new TlsStream(); int position = offset; while (position < (offset + count)) { short fragmentLength = 0; byte[] fragment; if ((count + offset - position) > Context.MAX_FRAGMENT_SIZE) { fragmentLength = Context.MAX_FRAGMENT_SIZE; } else { fragmentLength = (short)(count + offset - position); } // Fill the fragment data fragment = new byte[fragmentLength]; Buffer.BlockCopy(recordData, position, fragment, 0, fragmentLength); if ((this.Context.Write != null) && (this.Context.Write.Cipher != null)) { // Encrypt fragment fragment = this.encryptRecordFragment(contentType, fragment); } // Write tls message record.Write((byte)contentType); record.Write(this.context.Protocol); record.Write((short)fragment.Length); record.Write(fragment); DebugHelper.WriteLine("Record data", fragment); // Update buffer position position += fragmentLength; } return(record.ToArray()); }
public Context(SecurityProtocolType securityProtocolType) { this.SecurityProtocol = securityProtocolType; this.compressionMethod = SecurityCompressionType.None; this.serverSettings = new TlsServerSettings(); this.clientSettings = new TlsClientSettings(); this.handshakeMessages = new TlsStream(); this.sessionId = null; this.handshakeState = HandshakeState.None; this.random = RandomNumberGenerator.Create(); }
public override void ComputeMasterSecret(byte[] preMasterSecret) { TlsStream masterSecret = new TlsStream(); masterSecret.Write(this.prf(preMasterSecret, "A", this.Context.RandomCS)); masterSecret.Write(this.prf(preMasterSecret, "BB", this.Context.RandomCS)); masterSecret.Write(this.prf(preMasterSecret, "CCC", this.Context.RandomCS)); this.Context.MasterSecret = masterSecret.ToArray(); DebugHelper.WriteLine(">>>> MasterSecret", this.Context.MasterSecret); }
private byte[] prf(byte[] secret, string label, byte[] random) { HashAlgorithm hashAlgorithm = MD5.Create(); HashAlgorithm hashAlgorithm2 = SHA1.Create(); TlsStream tlsStream = new TlsStream(); tlsStream.Write(Encoding.ASCII.GetBytes(label)); tlsStream.Write(secret); tlsStream.Write(random); byte[] buffer = hashAlgorithm2.ComputeHash(tlsStream.ToArray(), 0, (int)tlsStream.Length); tlsStream.Reset(); tlsStream.Write(secret); tlsStream.Write(buffer); byte[] result = hashAlgorithm.ComputeHash(tlsStream.ToArray(), 0, (int)tlsStream.Length); tlsStream.Reset(); return(result); }
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 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(); }
private void ProcessCipherSpecV2Buffer(SecurityProtocolType protocol, byte[] buffer) { TlsStream codes = new TlsStream(buffer); string prefix = (protocol == SecurityProtocolType.Ssl3) ? "SSL_" : "TLS_"; while (codes.Position < codes.Length) { byte check = codes.ReadByte(); if (check == 0) { // SSL/TLS cipher spec short code = codes.ReadInt16(); int index = this.Context.SupportedCiphers.IndexOf(code); if (index != -1) { this.Context.Negotiating.Cipher = this.Context.SupportedCiphers[index]; break; } } else { byte[] tmp = new byte[2]; codes.Read(tmp, 0, tmp.Length); int tmpCode = ((check & 0xff) << 16) | ((tmp[0] & 0xff) << 8) | (tmp[1] & 0xff); CipherSuite cipher = this.MapV2CipherCode(prefix, tmpCode); if (cipher != null) { this.Context.Negotiating.Cipher = cipher; break; } } } if (this.Context.Negotiating == null) { throw new TlsException(AlertDescription.InsuficientSecurity, "Insuficient Security"); } }
protected override void ProcessHandshakeMessage(TlsStream handMsg) { HandshakeType handshakeType = (HandshakeType)handMsg.ReadByte(); HandshakeMessage message = null; DebugHelper.WriteLine(">>>> Processing Handshake record ({0})", handshakeType); // Read message length int length = handMsg.ReadInt24(); // Read message data byte[] data = null; if (length > 0) { data = new byte[length]; handMsg.Read(data, 0, length); } // Create and process the server message message = this.createServerHandshakeMessage(handshakeType, data); if (message != null) { message.Process(); } // Update the last handshake message this.Context.LastHandshakeMsg = handshakeType; // Update session if (message != null) { message.Update(); this.Context.HandshakeMessages.WriteByte((byte)handshakeType); this.Context.HandshakeMessages.WriteInt24(length); if (length > 0) { this.Context.HandshakeMessages.Write(data, 0, data.Length); } } }
public byte[] Expand(string hashName, byte[] secret, byte[] seed, int length) { int hashLength = hashName == "MD5" ? 16 : 20; int iterations = (int)(length / hashLength); if ((length % hashLength) > 0) { iterations++; } M.HMAC hmac = new M.HMAC(hashName, secret); TlsStream resMacs = new TlsStream(); byte[][] hmacs = new byte[iterations + 1][]; hmacs[0] = seed; for (int i = 1; i <= iterations; i++) { TlsStream hcseed = new TlsStream(); hmac.TransformFinalBlock(hmacs[i-1], 0, hmacs[i-1].Length); hmacs[i] = hmac.Hash; hcseed.Write(hmacs[i]); hcseed.Write(seed); hmac.TransformFinalBlock(hcseed.ToArray(), 0, (int)hcseed.Length); resMacs.Write(hmac.Hash); hcseed.Reset(); } byte[] res = new byte[length]; Buffer.BlockCopy(resMacs.ToArray(), 0, res, 0, res.Length); resMacs.Reset(); return res; }
public override void ComputeMasterSecret(byte[] preMasterSecret) { TlsStream masterSecret = new TlsStream(); masterSecret.Write(this.prf(preMasterSecret, "A", this.Context.RandomCS)); masterSecret.Write(this.prf(preMasterSecret, "BB", this.Context.RandomCS)); masterSecret.Write(this.prf(preMasterSecret, "CCC", this.Context.RandomCS)); this.Context.MasterSecret = masterSecret.ToArray(); DebugHelper.WriteLine(">>>> MasterSecret", this.Context.MasterSecret); }
public byte[] PRF(byte[] secret, string label, byte[] data, int length) { /* Secret Length calc exmplain from the RFC2246. Section 5 * * S1 and S2 are the two halves of the secret and each is the same * length. S1 is taken from the first half of the secret, S2 from the * second half. Their length is created by rounding up the length of the * overall secret divided by two; thus, if the original secret is an odd * number of bytes long, the last byte of S1 will be the same as the * first byte of S2. */ // split secret in 2 int secretLen = secret.Length >> 1; // rounding up if ((secret.Length & 0x1) == 0x1) secretLen++; // Seed TlsStream seedStream = new TlsStream(); seedStream.Write(Encoding.ASCII.GetBytes(label)); seedStream.Write(data); byte[] seed = seedStream.ToArray(); seedStream.Reset(); // Secret 1 byte[] secret1 = new byte[secretLen]; Buffer.BlockCopy(secret, 0, secret1, 0, secretLen); // Secret2 byte[] secret2 = new byte[secretLen]; Buffer.BlockCopy(secret, (secret.Length - secretLen), secret2, 0, secretLen); // Secret 1 processing byte[] p_md5 = Expand("MD5", secret1, seed, length); // Secret 2 processing byte[] p_sha = Expand("SHA1", secret2, seed, length); // Perfor XOR of both results byte[] masterSecret = new byte[length]; for (int i = 0; i < masterSecret.Length; i++) { masterSecret[i] = (byte)(p_md5[i] ^ p_sha[i]); } return masterSecret; }
public byte[] CreatePremasterSecret() { TlsStream stream = new TlsStream(); ClientContext context = (ClientContext)this.context; // Write protocol version // We need to send here the protocol version used in // the ClientHello message, that can be different than the actual // protocol version stream.Write(context.ClientHelloProtocol); // Generate random bytes stream.Write(this.context.GetSecureRandomBytes(46)); byte[] preMasterSecret = stream.ToArray(); stream.Reset(); return preMasterSecret; }
protected abstract void ProcessHandshakeMessage(TlsStream handMsg);
protected override void ProcessAsTls1() { #warning "Client certificate selection is unfinished" ClientContext context = (ClientContext)this.Context; string msg = "Client certificate requested by the server and no client certificate specified."; if (context.ClientSettings.Certificates == null || context.ClientSettings.Certificates.Count == 0) { throw new TlsException(AlertDescription.UserCancelled, msg); } // Select a valid certificate X509Certificate clientCert = this.Context.ClientSettings.Certificates[0]; clientCert = context.SslStream.RaiseClientCertificateSelection( this.Context.ClientSettings.Certificates, new X509Certificate(this.Context.ServerSettings.Certificates[0].RawData), this.Context.ClientSettings.TargetHost, null); if (clientCert == null) { throw new TlsException(AlertDescription.UserCancelled, msg); } // Update the selected client certificate context.ClientSettings.ClientCertificate = clientCert; // Write client certificates information to a stream TlsStream stream = new TlsStream(); stream.WriteInt24(clientCert.GetRawCertData().Length); stream.Write(clientCert.GetRawCertData()); // Compose the message this.WriteInt24((int)stream.Length); this.Write(stream.ToArray()); }
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(); }
private void SendCertificates () { TlsStream chain = new TlsStream (); X509Certificate currentCert = this.ClientCertificate; while (currentCert != null) { byte[] rawCert = currentCert.GetRawCertData (); chain.WriteInt24 (rawCert.Length); chain.Write(rawCert); currentCert = FindParentCertificate (currentCert); } this.WriteInt24 ((int)chain.Length); this.Write (chain.ToArray ()); }
protected abstract void ProcessHandshakeMessage(TlsStream handMsg);
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(); }
private void InternalReceiveRecordCallback(IAsyncResult asyncResult) { ReceiveRecordAsyncResult internalResult = asyncResult.AsyncState as ReceiveRecordAsyncResult; Stream record = internalResult.Record; try { int bytesRead = internalResult.Record.EndRead(asyncResult); //We're at the end of the stream. Time to bail. if (bytesRead == 0) { internalResult.SetComplete((byte[])null); return; } // Try to read the Record Content Type int type = internalResult.InitialBuffer[0]; // Set last handshake message received to None this.context.LastHandshakeMsg = HandshakeType.ClientHello; ContentType contentType = (ContentType)type; byte[] buffer = this.ReadRecordBuffer(type, record); if (buffer == null) { // record incomplete (at the moment) internalResult.SetComplete((byte[])null); return; } // Decrypt message contents if needed if (contentType == ContentType.Alert && buffer.Length == 2) { } else if ((this.Context.Read != null) && (this.Context.Read.Cipher != null)) { buffer = this.decryptRecordFragment (contentType, buffer); DebugHelper.WriteLine ("Decrypted record data", buffer); } // Process record switch (contentType) { case ContentType.Alert: this.ProcessAlert((AlertLevel)buffer [0], (AlertDescription)buffer [1]); if (record.CanSeek) { // don't reprocess that memory block record.SetLength (0); } buffer = null; break; case ContentType.ChangeCipherSpec: this.ProcessChangeCipherSpec(); break; case ContentType.ApplicationData: break; case ContentType.Handshake: TlsStream message = new TlsStream (buffer); while (!message.EOF) { this.ProcessHandshakeMessage(message); } break; case (ContentType)0x80: this.context.HandshakeMessages.Write (buffer); break; default: throw new TlsException( AlertDescription.UnexpectedMessage, "Unknown record received from server."); } internalResult.SetComplete(buffer); } catch (Exception ex) { internalResult.SetComplete(ex); } }
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() { // 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(); }
private void InternalReceiveRecordCallback(IAsyncResult asyncResult) { ReceiveRecordAsyncResult internalResult = asyncResult.AsyncState as ReceiveRecordAsyncResult; Stream record = internalResult.Record; try { int bytesRead = internalResult.Record.EndRead(asyncResult); //We're at the end of the stream. Time to bail. if (bytesRead == 0) { internalResult.SetComplete((byte[])null); return; } // Try to read the Record Content Type int type = internalResult.InitialBuffer[0]; // Set last handshake message received to None this.context.LastHandshakeMsg = HandshakeType.ClientHello; ContentType contentType = (ContentType)type; byte[] buffer = this.ReadRecordBuffer(type, record); if (buffer == null) { // record incomplete (at the moment) internalResult.SetComplete((byte[])null); return; } // Decrypt message contents if needed if (contentType == ContentType.Alert && buffer.Length == 2) { } else if ((this.Context.Read != null) && (this.Context.Read.Cipher != null)) { buffer = this.decryptRecordFragment(contentType, buffer); DebugHelper.WriteLine("Decrypted record data", buffer); } // Process record switch (contentType) { case ContentType.Alert: this.ProcessAlert((AlertLevel)buffer [0], (AlertDescription)buffer [1]); if (record.CanSeek) { // don't reprocess that memory block record.SetLength(0); } buffer = null; break; case ContentType.ChangeCipherSpec: this.ProcessChangeCipherSpec(); break; case ContentType.ApplicationData: break; case ContentType.Handshake: TlsStream message = new TlsStream(buffer); while (!message.EOF) { this.ProcessHandshakeMessage(message); } break; case (ContentType)0x80: this.context.HandshakeMessages.Write(buffer); break; default: throw new TlsException( AlertDescription.UnexpectedMessage, "Unknown record received from server."); } internalResult.SetComplete(buffer); } catch (Exception ex) { internalResult.SetComplete(ex); } }
public byte[] ReceiveRecord(Stream record) { if (this.context.ReceivedConnectionEnd) { throw new TlsException( AlertDescription.InternalError, "The session is finished and it's no longer valid."); } record_processing.Reset (); byte[] recordTypeBuffer = new byte[1]; int bytesRead = record.Read(recordTypeBuffer, 0, recordTypeBuffer.Length); //We're at the end of the stream. Time to bail. if (bytesRead == 0) { return null; } // Try to read the Record Content Type int type = recordTypeBuffer[0]; // Set last handshake message received to None this.context.LastHandshakeMsg = HandshakeType.ClientHello; ContentType contentType = (ContentType)type; byte[] buffer = this.ReadRecordBuffer(type, record); if (buffer == null) { // record incomplete (at the moment) return null; } // Decrypt message contents if needed if (contentType == ContentType.Alert && buffer.Length == 2) { } else if ((this.Context.Read != null) && (this.Context.Read.Cipher != null)) { buffer = this.decryptRecordFragment (contentType, buffer); DebugHelper.WriteLine ("Decrypted record data", buffer); } // Process record switch (contentType) { case ContentType.Alert: this.ProcessAlert((AlertLevel)buffer [0], (AlertDescription)buffer [1]); if (record.CanSeek) { // don't reprocess that memory block record.SetLength (0); } buffer = null; break; case ContentType.ChangeCipherSpec: this.ProcessChangeCipherSpec(); break; case ContentType.ApplicationData: break; case ContentType.Handshake: TlsStream message = new TlsStream (buffer); while (!message.EOF) { this.ProcessHandshakeMessage(message); } break; case (ContentType)0x80: this.context.HandshakeMessages.Write (buffer); break; default: throw new TlsException( AlertDescription.UnexpectedMessage, "Unknown record received from server."); } record_processing.Set (); return buffer; }
private byte[] prf(byte[] secret, string label, byte[] random) { HashAlgorithm md5 = MD5.Create(); HashAlgorithm sha = SHA1.Create(); // Compute SHA hash TlsStream block = new TlsStream(); block.Write(Encoding.ASCII.GetBytes(label)); block.Write(secret); block.Write(random); byte[] shaHash = sha.ComputeHash(block.ToArray(), 0, (int)block.Length); block.Reset(); // Compute MD5 hash block.Write(secret); block.Write(shaHash); byte[] result = md5.ComputeHash(block.ToArray(), 0, (int)block.Length); // Free resources block.Reset(); return result; }
public byte[] EncodeRecord( ContentType contentType, byte[] recordData, int offset, int count) { if (this.context.ConnectionEnd) { throw new TlsException( AlertDescription.InternalError, "The session is finished and it's no longer valid."); } TlsStream record = new TlsStream(); int position = offset; while (position < ( offset + count )) { short fragmentLength = 0; byte[] fragment; if ((count + offset - position) > Context.MAX_FRAGMENT_SIZE) { fragmentLength = Context.MAX_FRAGMENT_SIZE; } else { fragmentLength = (short)(count + offset - position); } // Fill the fragment data fragment = new byte[fragmentLength]; Buffer.BlockCopy(recordData, position, fragment, 0, fragmentLength); if ((this.Context.Write != null) && (this.Context.Write.Cipher != null)) { // Encrypt fragment fragment = this.encryptRecordFragment (contentType, fragment); } // Write tls message record.Write((byte)contentType); record.Write(this.context.Protocol); record.Write((short)fragment.Length); record.Write(fragment); DebugHelper.WriteLine("Record data", fragment); // Update buffer position position += fragmentLength; } return record.ToArray(); }
public Context(SecurityProtocolType securityProtocolType) { this.SecurityProtocol = securityProtocolType; this.compressionMethod = SecurityCompressionType.None; this.serverSettings = new TlsServerSettings(); this.clientSettings = new TlsClientSettings(); this.handshakeMessages = new TlsStream(); this.sessionId = null; this.handshakeState = HandshakeState.None; this.random = RandomNumberGenerator.Create(); }
private void ProcessCipherSpecV2Buffer (SecurityProtocolType protocol, byte[] buffer) { TlsStream codes = new TlsStream(buffer); string prefix = (protocol == SecurityProtocolType.Ssl3) ? "SSL_" : "TLS_"; while (codes.Position < codes.Length) { byte check = codes.ReadByte(); if (check == 0) { // SSL/TLS cipher spec short code = codes.ReadInt16(); int index = this.Context.SupportedCiphers.IndexOf(code); if (index != -1) { this.Context.Negotiating.Cipher = this.Context.SupportedCiphers[index]; break; } } else { byte[] tmp = new byte[2]; codes.Read(tmp, 0, tmp.Length); int tmpCode = ((check & 0xff) << 16) | ((tmp[0] & 0xff) << 8) | (tmp[1] & 0xff); CipherSuite cipher = this.MapV2CipherCode(prefix, tmpCode); if (cipher != null) { this.Context.Negotiating.Cipher = cipher; break; } } } if (this.Context.Negotiating == null) { throw new TlsException(AlertDescription.InsuficientSecurity, "Insuficient Security"); } }
public virtual void Clear() { this.compressionMethod = SecurityCompressionType.None; this.serverSettings = new TlsServerSettings(); this.clientSettings = new TlsClientSettings(); this.handshakeMessages = new TlsStream(); this.sessionId = null; this.handshakeState = HandshakeState.None; this.ClearKeyInfo(); }