[pgsqlclient-checkins] pgsqlclient_10/PgSqlClient.Security.Tls/source TlsCipherSuite.cs,1.2,1.3 TlsR
Status: Inactive
Brought to you by:
carlosga_fb
From: <car...@us...> - 2003-08-23 19:25:34
|
Update of /cvsroot/pgsqlclient/pgsqlclient_10/PgSqlClient.Security.Tls/source In directory sc8-pr-cvs1:/tmp/cvs-serv5194 Modified Files: TlsCipherSuite.cs TlsReader.cs TlsSession.cs TlsWriter.cs Log Message: Added changes for correct encryption/decryption of TLS records Index: TlsCipherSuite.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/PgSqlClient.Security.Tls/source/TlsCipherSuite.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** TlsCipherSuite.cs 20 Aug 2003 15:44:47 -0000 1.2 --- TlsCipherSuite.cs 23 Aug 2003 19:25:31 -0000 1.3 *************** *** 18,21 **** --- 18,22 ---- using System; + using System.IO; using System.Text; using System.Security.Cryptography; *************** *** 42,46 **** private byte blockSize; private TlsSessionState sessionState; ! #endregion --- 43,51 ---- private byte blockSize; private TlsSessionState sessionState; ! private SymmetricAlgorithm encryptionAlgorithm; ! private ICryptoTransform encryptionCipher; ! private SymmetricAlgorithm decryptionAlgorithm; ! private ICryptoTransform decryptionCipher; ! #endregion *************** *** 172,202 **** } ! public SymmetricAlgorithm CreateCipherAlgorithm() { ! SymmetricAlgorithm cipher; ! // Create and configure the symmetric algorithm ! switch (this.algName) { ! case "RC4": ! cipher = new ARC4Managed(); ! break; ! default: ! cipher = SymmetricAlgorithm.Create(algName); ! break; } ! // If it's a block cipher if (cipherMode == CipherMode.CBC) { ! // Configure encrypt algorithm ! cipher.Mode = this.cipherMode; ! cipher.Padding = PaddingMode.PKCS7; ! cipher.KeySize = this.keyMaterialSize * 8; ! cipher.BlockSize = this.blockSize * 8; } ! return cipher; } --- 177,232 ---- } ! public void InitializeCipher() { ! createEncryptionCipher(); ! createDecryptionCipher(); ! } ! public byte[] EncryptRecord(byte[] fragment, byte[] mac) ! { ! // Encryption ( fragment + mac [+ padding + padding_length] ) ! MemoryStream ms = new MemoryStream(); ! CryptoStream cs = new CryptoStream(ms, encryptionCipher, CryptoStreamMode.Write); ! ! cs.Write(fragment, 0, fragment.Length); ! cs.Write(mac, 0, mac.Length); ! if (cipherMode == CipherMode.CBC) { ! // Calculate padding_length ! int fragmentLength = fragment.Length + mac.Length + 1; ! int paddingLength = (((fragmentLength/blockSize)*8) + blockSize) - fragmentLength; ! // Write padding length byte ! cs.WriteByte((byte)paddingLength); } + // cs.FlushFinalBlock(); + cs.Close(); ! return ms.ToArray(); ! } ! ! public void DecryptRecord(byte[] fragment, ref byte[] dcrFragment, ref byte[] dcrMAC) ! { ! int fragmentSize = 0; ! ! // Decrypt message fragment ( fragment + mac [+ padding + padding_length] ) ! byte[] buffer = new byte[fragment.Length]; ! decryptionCipher.TransformBlock(fragment, 0, fragment.Length, buffer, 0); ! ! // Calculate fragment size if (cipherMode == CipherMode.CBC) + { + fragmentSize = (buffer.Length - 1) - HashSize; + } + else { ! fragmentSize = buffer.Length - HashSize; } ! dcrFragment = new byte[fragmentSize]; ! dcrMAC = new byte[HashSize]; ! ! System.Array.Copy(buffer, 0, dcrFragment, 0, dcrFragment.Length); ! System.Array.Copy(buffer, dcrFragment.Length, dcrMAC, 0, dcrMAC.Length); } *************** *** 227,230 **** --- 257,319 ---- return integer; } + } + + + private void createEncryptionCipher() + { + // Create and configure the symmetric algorithm + switch (this.algName) + { + case "RC4": + encryptionAlgorithm = new ARC4Managed(); + break; + + default: + encryptionAlgorithm = SymmetricAlgorithm.Create(algName); + break; + } + + // If it's a block cipher + if (cipherMode == CipherMode.CBC) + { + // Configure encrypt algorithm + encryptionAlgorithm.Mode = this.cipherMode; + encryptionAlgorithm.Padding = PaddingMode.PKCS7; + encryptionAlgorithm.KeySize = this.keyMaterialSize * 8; + encryptionAlgorithm.BlockSize = this.blockSize * 8; + } + + encryptionCipher = encryptionAlgorithm.CreateEncryptor( + sessionState.ClientWriteKey, + sessionState.ClientWriteIV); + } + + private void createDecryptionCipher() + { + // Create and configure the symmetric algorithm + switch (this.algName) + { + case "RC4": + decryptionAlgorithm = new ARC4Managed(); + break; + + default: + decryptionAlgorithm = SymmetricAlgorithm.Create(algName); + break; + } + + // If it's a block cipher + if (cipherMode == CipherMode.CBC) + { + // Configure encrypt algorithm + decryptionAlgorithm.Mode = this.cipherMode; + decryptionAlgorithm.Padding = PaddingMode.PKCS7; + decryptionAlgorithm.KeySize = this.keyMaterialSize * 8; + decryptionAlgorithm.BlockSize = this.blockSize * 8; + } + + decryptionCipher = decryptionAlgorithm.CreateDecryptor( + sessionState.ServerWriteKey, + sessionState.ServerWriteIV); } Index: TlsReader.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/PgSqlClient.Security.Tls/source/TlsReader.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** TlsReader.cs 20 Aug 2003 15:15:50 -0000 1.2 --- TlsReader.cs 23 Aug 2003 19:25:31 -0000 1.3 *************** *** 302,333 **** byte[] fragment) { - TlsSessionState state = session.State; - int fragmentSize = 0; byte[] dcrFragment = null; byte[] dcrMAC = null; ! SymmetricAlgorithm cipher = session.State.Cipher.CreateCipherAlgorithm(); ! ICryptoTransform decryptor = cipher.CreateDecryptor( ! state.ServerWriteKey, ! state.ServerWriteIV); ! ! // Decrypt message fragment ( fragment + mac [+ padding + padding_length] ) ! byte[] buffer = decryptor.TransformFinalBlock(fragment, 0, fragment.Length); ! ! if (session.State.Cipher.CipherMode == CipherMode.CBC) ! { ! fragmentSize = (buffer.Length - 1) - session.State.Cipher.HashSize; ! } ! else ! { ! fragmentSize = buffer.Length - session.State.Cipher.HashSize; ! } ! ! dcrFragment = new byte[fragmentSize]; ! dcrMAC = new byte[session.State.Cipher.HashSize]; ! ! System.Array.Copy(buffer, 0, dcrFragment, 0, dcrFragment.Length); ! System.Array.Copy(buffer, dcrFragment.Length, dcrMAC, 0, dcrMAC.Length); ! // Check MAC code byte[] mac = encodeRecordMAC(contentType, dcrFragment); --- 302,311 ---- byte[] fragment) { byte[] dcrFragment = null; byte[] dcrMAC = null; ! // Decrypt message ! session.State.Cipher.DecryptRecord(fragment, ref dcrFragment, ref dcrMAC); ! // Check MAC code byte[] mac = encodeRecordMAC(contentType, dcrFragment); *************** *** 348,354 **** // Update sequence number session.State.ReadSequenceNumber++; - - // Clear resources - cipher.Clear(); return dcrFragment; --- 326,329 ---- Index: TlsSession.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/PgSqlClient.Security.Tls/source/TlsSession.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** TlsSession.cs 20 Aug 2003 15:44:47 -0000 1.2 --- TlsSession.cs 23 Aug 2003 19:25:31 -0000 1.3 *************** *** 168,171 **** --- 168,176 ---- writer.WriteRecord(TlsHandshakeType.ClientKeyExchange); + // Now initialize session cipher with the generated keys + state.Cipher.InitializeCipher(); + + #warning "Clear key info that is no more needed" + // Send certificate verify if requested if (state.ServerSettings.CertificateRequest) *************** *** 350,353 **** --- 355,359 ---- } + // Clear no more needed data seed.Reset(); keyBlock.Reset(); *************** *** 430,434 **** */ #warning "Think on implement this as a class derived from KeyedHashAlgorithm" ! internal byte[] hmac(string hashName, byte[] key, byte[] text) { HashAlgorithm hash = HashAlgorithm.Create(hashName); --- 436,440 ---- */ #warning "Think on implement this as a class derived from KeyedHashAlgorithm" ! public byte[] hmac(string hashName, byte[] key, byte[] text) { HashAlgorithm hash = HashAlgorithm.Create(hashName); *************** *** 499,502 **** --- 505,560 ---- #endregion + + /* + public void PrintArray(string text, byte[] array) + { + Console.WriteLine(text); + int count = 0; + for (int i = 0; i < array.Length; i++) + { + Console.Write("{0} ", array[i].ToString("x2").ToUpper()); + if (count == 15) + { + count = 0; + Console.WriteLine(""); + } + else + { + count++; + } + } + Console.WriteLine(""); + } + + public static void SaveToFile(string file, byte[] data) + { + string fileName = "d:\\test\\" + file; + + FileStream stream = new FileStream( + fileName, FileMode.Create, FileAccess.Write); + if (data != null) + { + stream.Write(data, 0, data.Length); + } + else + { + stream.Write(new byte[0], 0, 0); + } + stream.Close(); + } + + public static byte[] ReadFromFile(string file) + { + string fileName = "d:\\test\\" + file; + + FileStream stream = new FileStream( + fileName, FileMode.Open, FileAccess.Read); + byte[] data = new byte[stream.Length]; + stream.Read(data, 0, data.Length); + stream.Close(); + + return data; + } + */ } } Index: TlsWriter.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/PgSqlClient.Security.Tls/source/TlsWriter.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** TlsWriter.cs 20 Aug 2003 20:29:35 -0000 1.3 --- TlsWriter.cs 23 Aug 2003 19:25:31 -0000 1.4 *************** *** 178,216 **** private byte[] encodeCipherTextRecord(TlsContentType contentType, byte[] fragment) { ! TlsSessionState state = session.State; ! ! byte[] mac = encodeRecordMAC(contentType, fragment); ! ! SymmetricAlgorithm cipher = session.State.Cipher.CreateCipherAlgorithm(); ! ICryptoTransform encryptor = cipher.CreateEncryptor( ! state.ClientWriteKey, ! state.ClientWriteIV); ! ! // Encryption ( fragment + mac [+ padding + padding_length] ) ! MemoryStream ms = new MemoryStream(); ! CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write); ! ! cs.Write(fragment, 0, fragment.Length); ! cs.Write(mac, 0, mac.Length); ! if (session.State.Cipher.CipherMode == CipherMode.CBC) ! { ! // Calculate padding_length ! int fragmentLength = fragment.Length + mac.Length + 1; ! int blockSize = session.State.Cipher.BlockSize; ! int paddingLength = (((fragmentLength/blockSize)*8) + blockSize) - fragmentLength; ! // Write padding length byte ! cs.WriteByte((byte)paddingLength); ! } ! cs.FlushFinalBlock(); ! cs.Close(); // Update sequence number session.State.WriteSequenceNumber++; ! // Clear resources ! cipher.Clear(); ! ! return ms.ToArray(); } --- 178,191 ---- private byte[] encodeCipherTextRecord(TlsContentType contentType, byte[] fragment) { ! // Calculate message MAC ! byte[] mac = encodeRecordMAC(contentType, fragment); ! // Encrypt the message ! byte[] ecr = session.State.Cipher.EncryptRecord(fragment, mac); // Update sequence number session.State.WriteSequenceNumber++; ! return ecr; } *************** *** 224,229 **** data.WriteShort((short)TlsProtocol.Tls1); data.WriteShort((short)fragment.Length); ! data.Write(fragment); ! result = session.hmac(session.State.Cipher.HashName, session.State.ClientWriteMAC, --- 199,204 ---- data.WriteShort((short)TlsProtocol.Tls1); data.WriteShort((short)fragment.Length); ! data.Write(fragment); ! result = session.hmac(session.State.Cipher.HashName, session.State.ClientWriteMAC, |