Thread: [pgsqlclient-checkins] pgsqlclient_10/PgSqlClient.Security.Tls/source TlsCipherSuite.cs,1.4,1.5 TlsC
Status: Inactive
Brought to you by:
carlosga_fb
Update of /cvsroot/pgsqlclient/pgsqlclient_10/PgSqlClient.Security.Tls/source In directory sc8-pr-cvs1:/tmp/cvs-serv4681 Modified Files: TlsCipherSuite.cs TlsCipherSuiteCollection.cs TlsReader.cs TlsSession.cs TlsSessionState.cs TlsWriter.cs Log Message: - Update dencryption/decryption of CBC ciphers. - Converted TlsSession.hmac function into a class derived from KeyedHashAlgorithm. - Improved hmac generation. Index: TlsCipherSuite.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/PgSqlClient.Security.Tls/source/TlsCipherSuite.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** TlsCipherSuite.cs 24 Aug 2003 10:46:54 -0000 1.4 --- TlsCipherSuite.cs 24 Aug 2003 21:08:07 -0000 1.5 *************** *** 22,25 **** --- 22,26 ---- using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; + using PgSqlClient.Security.TLS.Cryptography; using Mono.Security; using Mono.Security.Cryptography; *************** *** 47,50 **** --- 48,53 ---- private SymmetricAlgorithm decryptionAlgorithm; private ICryptoTransform decryptionCipher; + private KeyedHashAlgorithm clientHMAC; + private KeyedHashAlgorithm serverHMAC; #endregion *************** *** 183,186 **** --- 186,213 ---- } + public void UpdateClientCipherIV(byte[] iv) + { + if (cipherMode == CipherMode.CBC) + { + // Set the new IV + encryptionAlgorithm.IV = iv; + + // Create encryption cipher with the new IV + encryptionCipher = encryptionAlgorithm.CreateEncryptor(); + } + } + + public void UpdateServerCipherIV(byte[] iv) + { + if (cipherMode == CipherMode.CBC) + { + // Set the new IV + decryptionAlgorithm.IV = iv; + + // Create encryption cipher with the new IV + decryptionCipher = decryptionAlgorithm.CreateDecryptor(); + } + } + public byte[] EncryptRecord(byte[] fragment, byte[] mac) { *************** *** 200,204 **** cs.WriteByte((byte)paddingLength); } - cs.Flush(); cs.Close(); --- 227,230 ---- *************** *** 231,234 **** --- 257,274 ---- } + public byte[] ComputeClientMAC(byte[] data) + { + clientHMAC.TransformFinalBlock(data, 0, data.Length); + + return clientHMAC.Hash; + } + + public byte[] ComputeServerMAC(byte[] data) + { + serverHMAC.TransformFinalBlock(data, 0, data.Length); + + return serverHMAC.Hash; + } + public int GetKeyBlockSize() { *************** *** 282,293 **** encryptionAlgorithm.BlockSize = this.blockSize * 8; } ! encryptionCipher = encryptionAlgorithm.CreateEncryptor( ! sessionState.ClientWriteKey, ! sessionState.ClientWriteIV); ! // Clear server keys ! sessionState.ClientWriteKey = null; ! sessionState.ClientWriteIV = null; } --- 322,335 ---- encryptionAlgorithm.BlockSize = this.blockSize * 8; } + + // Set the key and IV for the algorithm + encryptionAlgorithm.Key = sessionState.ClientWriteKey; + encryptionAlgorithm.IV = sessionState.ClientWriteIV; ! // Create encryption cipher ! encryptionCipher = encryptionAlgorithm.CreateEncryptor(); ! // Create the HMAC algorithm for the client ! clientHMAC = new HMAC(hashName, sessionState.ClientWriteMAC); } *************** *** 315,326 **** decryptionAlgorithm.BlockSize = this.blockSize * 8; } ! ! decryptionCipher = decryptionAlgorithm.CreateDecryptor( ! sessionState.ServerWriteKey, ! sessionState.ServerWriteIV); ! ! // Clear server keys ! sessionState.ServerWriteKey = null; ! sessionState.ServerWriteIV = null; } --- 357,370 ---- decryptionAlgorithm.BlockSize = this.blockSize * 8; } ! ! // Set the key and IV for the algorithm ! decryptionAlgorithm.Key = sessionState.ServerWriteKey; ! decryptionAlgorithm.IV = sessionState.ServerWriteIV; ! ! // Create decryption cipher ! decryptionCipher = decryptionAlgorithm.CreateDecryptor(); ! ! // Create the HMAC algorithm for the server ! serverHMAC = new HMAC(hashName, sessionState.ServerWriteMAC); } Index: TlsCipherSuiteCollection.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/PgSqlClient.Security.Tls/source/TlsCipherSuiteCollection.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** TlsCipherSuiteCollection.cs 20 Aug 2003 20:29:35 -0000 1.3 --- TlsCipherSuiteCollection.cs 24 Aug 2003 21:08:07 -0000 1.4 *************** *** 61,64 **** --- 61,65 ---- // scs.Add((0x00 << 0x08) | 0x02, "TLS_RSA_WITH_NULL_SHA", "", "SHA", true, false, 0, 0, 0, 0, 0); // scs.Add((0x00 << 0x08) | 0x03, "TLS_RSA_EXPORT_WITH_RC4_40_MD5", "RC4", "MD5", true, false, 5, 16, 40, 0, 0); + scs.Add((0x00 << 0x08) | 0x0A, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", "3DES", "SHA", false, true, 24, 24, 168, 8, 8); scs.Add((0x00 << 0x08) | 0x05, "TLS_RSA_WITH_RC4_128_SHA", "RC4", "SHA", false, false, 16, 16, 128, 0, 0); scs.Add((0x00 << 0x08) | 0x04, "TLS_RSA_WITH_RC4_128_MD5", "RC4", "MD5", false, false, 16, 16, 128, 0, 0); Index: TlsReader.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/PgSqlClient.Security.Tls/source/TlsReader.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** TlsReader.cs 24 Aug 2003 10:46:54 -0000 1.4 --- TlsReader.cs 24 Aug 2003 21:08:07 -0000 1.5 *************** *** 307,310 **** --- 307,318 ---- // Decrypt message session.State.Cipher.DecryptRecord(fragment, ref dcrFragment, ref dcrMAC); + + // Set new IV + if (session.State.Cipher.CipherMode == CipherMode.CBC) + { + byte[] iv = new byte[session.State.Cipher.IvSize]; + System.Array.Copy(fragment, fragment.Length - iv.Length, iv, 0, iv.Length); + session.State.Cipher.UpdateServerCipherIV(iv); + } // Check MAC code *************** *** 341,347 **** --- 349,358 ---- data.Write(fragment); + /* result = session.hmac(session.State.Cipher.HashName, session.State.ServerWriteMAC, data.GetBytes()); + */ + result = session.State.Cipher.ComputeServerMAC(data.GetBytes()); data.Reset(); Index: TlsSession.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/PgSqlClient.Security.Tls/source/TlsSession.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** TlsSession.cs 24 Aug 2003 10:46:54 -0000 1.4 --- TlsSession.cs 24 Aug 2003 21:08:07 -0000 1.5 *************** *** 23,26 **** --- 23,27 ---- using System.Security.Cryptography; + using PgSqlClient.Security.TLS.Cryptography; using PgSqlClient.Security.TLS.Alerts; using PgSqlClient.Security.TLS.Handshake; *************** *** 171,176 **** state.Cipher.InitializeCipher(); - #warning "Clear key info that is no more needed" - // Send certificate verify if requested if (state.ServerSettings.CertificateRequest) --- 172,175 ---- *************** *** 187,190 **** --- 186,192 ---- // Read server finished reader.ReadRecord(); + + // Clear Key Info + state.ClearKeyInfo(); } *************** *** 404,407 **** --- 406,410 ---- } + HMAC hmac = new HMAC(hashName, secret); TlsStreamWriter resMacs = new TlsStreamWriter(); *************** *** 411,418 **** { TlsStreamWriter hcseed = new TlsStreamWriter(); ! hmacs[i] = hmac(hashName, secret, hmacs[i-1]); hcseed.Write(hmacs[i]); hcseed.Write(seed); ! resMacs.Write(hmac(hashName, secret, hcseed.GetBytes())); hcseed.Reset(); } --- 414,423 ---- { TlsStreamWriter hcseed = new TlsStreamWriter(); ! hmac.TransformFinalBlock(hmacs[i-1], 0, hmacs[i-1].Length); ! hmacs[i] = hmac.Hash; hcseed.Write(hmacs[i]); hcseed.Write(seed); ! hmac.TransformFinalBlock(hcseed.GetBytes(), 0, hcseed.GetBytes().Length); ! resMacs.Write(hmac.Hash); hcseed.Reset(); } *************** *** 427,487 **** } - /* - * References: - * RFC 2104 - * RFC 2202 - */ - #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); - - byte[] tmp = new byte[64]; - byte[] buff = new byte[64]; - - /* if key is longer than 64 bytes reset it to key=Hash(key) */ - if (key.Length > 64) - { - hash.Initialize(); - key = hash.ComputeHash(key); - } - - /* Pad the key for inner digest */ - for (int i = 0 ; i < key.Length; ++i) - { - buff[i] = (byte)(key[i] ^ 0x36); - } - for (int i = key.Length; i < 64; ++i) - { - buff[i] = 0x36; - } - - byte[] hash1 = new byte[hash.HashSize]; - - /* First pass */ - hash.Initialize(); - hash.TransformBlock(buff, 0, 64, tmp, 0); - hash.TransformFinalBlock(text, 0, text.Length); - - /* Second pass */ - for (int i = 0 ; i < key.Length; ++i) - { - buff[i] = (byte)(key[i] ^ 0x5C); - } - for (int i = key.Length ; i < 64; ++i) - { - buff[i] = 0x5C; - } - - /* The result of the first pass */ - byte[] firstResult = hash.Hash; - - hash.Initialize(); - hash.TransformBlock(buff, 0, 64, tmp, 0); - hash.TransformFinalBlock(firstResult, 0, firstResult.Length); - - return hash.Hash; - } - #endregion --- 432,435 ---- *************** *** 502,557 **** #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; - } - */ } } --- 450,453 ---- Index: TlsSessionState.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/PgSqlClient.Security.Tls/source/TlsSessionState.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** TlsSessionState.cs 24 Aug 2003 10:46:54 -0000 1.2 --- TlsSessionState.cs 24 Aug 2003 21:08:07 -0000 1.3 *************** *** 156,159 **** --- 156,176 ---- #endregion + + #region METHODS + + public void ClearKeyInfo() + { + // Clear client keys + clientWriteKey = null; + clientWriteIV = null; + clientWriteMAC = null; + + // Clear server keys + serverWriteKey = null; + serverWriteIV = null; + serverWriteMAC = null; + } + + #endregion } } Index: TlsWriter.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/PgSqlClient.Security.Tls/source/TlsWriter.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** TlsWriter.cs 23 Aug 2003 19:25:31 -0000 1.4 --- TlsWriter.cs 24 Aug 2003 21:08:07 -0000 1.5 *************** *** 184,187 **** --- 184,195 ---- byte[] ecr = session.State.Cipher.EncryptRecord(fragment, mac); + // Set new IV + if (session.State.Cipher.CipherMode == CipherMode.CBC) + { + byte[] iv = new byte[session.State.Cipher.IvSize]; + System.Array.Copy(ecr, ecr.Length - iv.Length, iv, 0, iv.Length); + session.State.Cipher.UpdateClientCipherIV(iv); + } + // Update sequence number session.State.WriteSequenceNumber++; *************** *** 200,207 **** data.WriteShort((short)fragment.Length); data.Write(fragment); ! ! result = session.hmac(session.State.Cipher.HashName, ! session.State.ClientWriteMAC, ! data.GetBytes()); data.Reset(); --- 208,213 ---- data.WriteShort((short)fragment.Length); data.Write(fragment); ! ! result = session.State.Cipher.ComputeClientMAC(data.GetBytes()); data.Reset(); |