Thread: [pgsqlclient-checkins] pgsqlclient_10/PgSqlClient.Security.Tls/source TlsCipherSuiteCollection.cs,1.
Status: Inactive
Brought to you by:
carlosga_fb
From: <car...@us...> - 2003-08-25 23:07:45
|
Update of /cvsroot/pgsqlclient/pgsqlclient_10/PgSqlClient.Security.Tls/source In directory sc8-pr-cvs1:/tmp/cvs-serv20381 Modified Files: TlsCipherSuiteCollection.cs TlsSession.cs TlsSessionState.cs Log Message: Moved Key generation methods to TlsSessionState class Index: TlsCipherSuiteCollection.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/PgSqlClient.Security.Tls/source/TlsCipherSuiteCollection.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** TlsCipherSuiteCollection.cs 24 Aug 2003 21:08:07 -0000 1.4 --- TlsCipherSuiteCollection.cs 25 Aug 2003 16:40:43 -0000 1.5 *************** *** 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); --- 61,64 ---- Index: TlsSession.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/PgSqlClient.Security.Tls/source/TlsSession.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** TlsSession.cs 24 Aug 2003 21:08:07 -0000 1.5 --- TlsSession.cs 25 Aug 2003 16:40:43 -0000 1.6 *************** *** 258,437 **** #endregion - #region KEY_GENERATION_METODS - - internal byte[] CreatePremasterSecret() - { - TlsStreamWriter stream = new TlsStreamWriter(); - - // Write protocol version - stream.WriteShort((short)TlsProtocol.Tls1); - - // Generate random bytes - byte[] random = new byte[46]; - RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); - rng.GetNonZeroBytes(random); - stream.Write(random); - - byte[] preMasterSecret = stream.GetBytes(); - - stream.Reset(); - - return preMasterSecret; - } - - internal void CreateMasterSecret(byte[] preMasterSecret) - { - TlsCipherSuite cipherSuite = state.Cipher; - byte[] masterSecret = new byte[preMasterSecret.Length]; - - TlsStreamWriter seed = new TlsStreamWriter(); - - // Seed - seed.Write(this.State.ClientRandom); - seed.Write(this.State.ServerRandom); - - // Create master secret - this.State.MasterSecret = PRF(preMasterSecret, "master secret", seed.GetBytes(), 48); - - seed.Reset(); - } - - internal void CreateKeys() - { - TlsStreamWriter seed = new TlsStreamWriter(); - - // Seed - seed.Write(state.ServerRandom); - seed.Write(state.ClientRandom); - - // Create keyblock - TlsStreamReader keyBlock = new TlsStreamReader( - PRF(state.MasterSecret, - "key expansion", - seed.GetBytes(), - state.Cipher.GetKeyBlockSize())); - - state.ClientWriteMAC = keyBlock.ReadBytes(state.Cipher.HashSize); - state.ServerWriteMAC = keyBlock.ReadBytes(state.Cipher.HashSize); - byte[] clientWriteKey = keyBlock.ReadBytes(state.Cipher.KeyMaterialSize); - byte[] serverWriteKey = keyBlock.ReadBytes(state.Cipher.KeyMaterialSize); - - // Seed - seed.Reset(); - seed.Write(state.ClientRandom); - seed.Write(state.ServerRandom); - - if (!state.Cipher.IsExportable) - { - state.ClientWriteKey = clientWriteKey; - state.ServerWriteKey = serverWriteKey; - - if (state.Cipher.IvSize != 0) - { - state.ClientWriteIV = keyBlock.ReadBytes(state.Cipher.IvSize); - state.ServerWriteIV = keyBlock.ReadBytes(state.Cipher.IvSize); - } - } - else - { - // Generate final write keys - byte[] finalClientWriteKey = PRF(clientWriteKey, "client write key", seed.GetBytes(), state.Cipher.KeyMaterialSize); - byte[] finalServerWriteKey = PRF(serverWriteKey, "server write key", seed.GetBytes(), state.Cipher.KeyMaterialSize); - - state.ClientWriteKey = finalClientWriteKey; - state.ServerWriteKey = finalServerWriteKey; - - // Generate IV block - byte[] ivBlock = PRF(new byte[]{}, "IV block", seed.GetBytes(), state.Cipher.IvSize*2); - // Generate IV keys - byte[] clientWriteIV = new byte[state.Cipher.IvSize]; - System.Array.Copy(ivBlock, 0, clientWriteIV, 0, clientWriteIV.Length); - byte[] serverWriteIV = new byte[state.Cipher.IvSize]; - System.Array.Copy(ivBlock, state.Cipher.IvSize, serverWriteIV, 0, serverWriteIV.Length); - - state.ClientWriteIV = clientWriteIV; - state.ServerWriteIV = serverWriteIV; - } - - // Clear no more needed data - seed.Reset(); - keyBlock.Reset(); - } - - internal byte[] PRF(byte[] secret, string label, byte[] data, int length) - { - MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); - SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider(); - - int secretLen = secret.Length / 2; - - // Seed - TlsStreamWriter seedStream = new TlsStreamWriter(); - seedStream.Write(Encoding.ASCII.GetBytes(label)); - seedStream.Write(data); - byte[] seed = seedStream.GetBytes(); - seedStream.Reset(); - - // Secret 1 - byte[] secret1 = new byte[secretLen]; - System.Array.Copy(secret, 0, secret1, 0, secretLen); - - // Secret2 - byte[] secret2 = new byte[secretLen]; - System.Array.Copy(secret, 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; - } - - private 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++; - } - - HMAC hmac = new HMAC(hashName, secret); - TlsStreamWriter resMacs = new TlsStreamWriter(); - - byte[][] hmacs = new byte[iterations + 1][]; - hmacs[0] = seed; - for (int i = 1; i <= iterations; i++) - { - 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(); - } - - byte[] res = new byte[length]; - - System.Array.Copy(resMacs.GetBytes(), 0, res, 0, res.Length); - - resMacs.Reset(); - - return res; - } - - #endregion - #region INTERNAL_METHODS --- 258,261 ---- Index: TlsSessionState.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/PgSqlClient.Security.Tls/source/TlsSessionState.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** TlsSessionState.cs 24 Aug 2003 21:08:07 -0000 1.3 --- TlsSessionState.cs 25 Aug 2003 16:40:43 -0000 1.4 *************** *** 18,21 **** --- 18,25 ---- using System; + using System.Text; + using System.Security.Cryptography; + + using PgSqlClient.Security.TLS.Cryptography; namespace PgSqlClient.Security.TLS *************** *** 157,171 **** #endregion #region METHODS public void ClearKeyInfo() { // Clear client keys ! clientWriteKey = null; clientWriteIV = null; clientWriteMAC = null; // Clear server keys ! serverWriteKey = null; serverWriteIV = null; serverWriteMAC = null; --- 161,356 ---- #endregion + #region KEY_GENERATION_METODS + + public byte[] CreatePremasterSecret() + { + TlsStreamWriter stream = new TlsStreamWriter(); + + // Write protocol version + stream.WriteShort((short)TlsProtocol.Tls1); + + // Generate random bytes + byte[] random = new byte[46]; + RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); + rng.GetNonZeroBytes(random); + stream.Write(random); + + byte[] preMasterSecret = stream.GetBytes(); + + stream.Reset(); + + return preMasterSecret; + } + + public void CreateMasterSecret(byte[] preMasterSecret) + { + TlsCipherSuite cipherSuite = cipher; + TlsStreamWriter seed = new TlsStreamWriter(); + + // Seed + seed.Write(clientRandom); + seed.Write(serverRandom); + + // Create master secret + masterSecret = new byte[preMasterSecret.Length]; + masterSecret = PRF(preMasterSecret, "master secret", seed.GetBytes(), 48); + + seed.Reset(); + } + + public void CreateKeys() + { + TlsStreamWriter seed = new TlsStreamWriter(); + + // Seed + seed.Write(serverRandom); + seed.Write(clientRandom); + + // Create keyblock + TlsStreamReader keyBlock = new TlsStreamReader( + PRF(masterSecret, + "key expansion", + seed.GetBytes(), + cipher.GetKeyBlockSize())); + + clientWriteMAC = keyBlock.ReadBytes(cipher.HashSize); + serverWriteMAC = keyBlock.ReadBytes(cipher.HashSize); + clientWriteKey = keyBlock.ReadBytes(cipher.KeyMaterialSize); + serverWriteKey = keyBlock.ReadBytes(cipher.KeyMaterialSize); + + if (!cipher.IsExportable) + { + if (cipher.IvSize != 0) + { + clientWriteIV = keyBlock.ReadBytes(cipher.IvSize); + serverWriteIV = keyBlock.ReadBytes(cipher.IvSize); + } + else + { + clientWriteIV = new byte[0]; + serverWriteIV = new byte[0]; + } + } + else + { + // Seed + seed.Reset(); + seed.Write(clientRandom); + seed.Write(serverRandom); + + // Generate final write keys + byte[] finalClientWriteKey = PRF(clientWriteKey, "client write key", seed.GetBytes(), cipher.KeyMaterialSize); + byte[] finalServerWriteKey = PRF(serverWriteKey, "server write key", seed.GetBytes(), cipher.KeyMaterialSize); + + clientWriteKey = finalClientWriteKey; + serverWriteKey = finalServerWriteKey; + + // Generate IV block + byte[] ivBlock = PRF(new byte[]{}, "IV block", seed.GetBytes(), cipher.IvSize*2); + // Generate IV keys + clientWriteIV = new byte[cipher.IvSize]; + System.Array.Copy(ivBlock, 0, clientWriteIV, 0, clientWriteIV.Length); + serverWriteIV = new byte[cipher.IvSize]; + System.Array.Copy(ivBlock, cipher.IvSize, serverWriteIV, 0, serverWriteIV.Length); + } + + // Clear no more needed data + seed.Reset(); + keyBlock.Reset(); + } + + public byte[] PRF(byte[] secret, string label, byte[] data, int length) + { + MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); + SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider(); + + int secretLen = secret.Length / 2; + + // Seed + TlsStreamWriter seedStream = new TlsStreamWriter(); + seedStream.Write(Encoding.ASCII.GetBytes(label)); + seedStream.Write(data); + byte[] seed = seedStream.GetBytes(); + seedStream.Reset(); + + // Secret 1 + byte[] secret1 = new byte[secretLen]; + System.Array.Copy(secret, 0, secret1, 0, secretLen); + + // Secret2 + byte[] secret2 = new byte[secretLen]; + System.Array.Copy(secret, 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[] 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++; + } + + HMAC hmac = new HMAC(hashName, secret); + TlsStreamWriter resMacs = new TlsStreamWriter(); + + byte[][] hmacs = new byte[iterations + 1][]; + hmacs[0] = seed; + for (int i = 1; i <= iterations; i++) + { + 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(); + } + + byte[] res = new byte[length]; + + System.Array.Copy(resMacs.GetBytes(), 0, res, 0, res.Length); + + resMacs.Reset(); + + return res; + } + + #endregion + #region METHODS public void ClearKeyInfo() { + // Clear Master Secret + masterSecret = null; + + // Clear client and server random + clientRandom = null; + serverRandom = null; + // Clear client keys ! clientWriteKey = null; clientWriteIV = null; clientWriteMAC = null; // Clear server keys ! serverWriteKey = null; serverWriteIV = null; serverWriteMAC = null; |