public static CipherSuite InitializeCipherSuite(byte[] master, byte[] clientrnd, byte[] serverrnd, CipherDefinition definition, ConnectionEnd entity) { CipherSuite ret = new CipherSuite(); SymmetricAlgorithm bulk = (SymmetricAlgorithm)Activator.CreateInstance(definition.BulkCipherAlgorithm); if (definition.BulkIVSize > 0) bulk.Mode = CipherMode.CBC; bulk.Padding = PaddingMode.None; bulk.BlockSize = definition.BulkIVSize * 8; // get the keys and IVs byte[] client_mac, server_mac, client_key, server_key, client_iv, server_iv; byte[] random = new byte[64]; Array.Copy(serverrnd, 0, random, 0, 32); Array.Copy(clientrnd, 0, random, 32, 32); PseudoRandomDeriveBytes prf = new PseudoRandomDeriveBytes(master, "key expansion", random); client_mac = prf.GetBytes(definition.HashSize); server_mac = prf.GetBytes(definition.HashSize); client_key = prf.GetBytes(definition.BulkKeySize); server_key = prf.GetBytes(definition.BulkKeySize); client_iv = prf.GetBytes(definition.BulkIVSize); server_iv = prf.GetBytes(definition.BulkIVSize); prf.Dispose(); if (definition.Exportable) { // make some extra modifications if the keys are exportable Array.Copy(clientrnd, 0, random, 0, 32); Array.Copy(serverrnd, 0, random, 32, 32); prf = new PseudoRandomDeriveBytes(client_key, "client write key", random); client_key = prf.GetBytes(definition.BulkExpandedSize); prf.Dispose(); prf = new PseudoRandomDeriveBytes(server_key, "server write key", random); server_key = prf.GetBytes(definition.BulkExpandedSize); prf.Dispose(); prf = new PseudoRandomDeriveBytes(new byte[0], "IV block", random); client_iv = prf.GetBytes(definition.BulkIVSize); server_iv = prf.GetBytes(definition.BulkIVSize); prf.Dispose(); } // generate the cipher objects if (entity == ConnectionEnd.Client) { ret.Encryptor = bulk.CreateEncryptor(client_key, client_iv); ret.Decryptor = bulk.CreateDecryptor(server_key, server_iv); ret.LocalHasher = new HMAC((HashAlgorithm)Activator.CreateInstance(definition.HashAlgorithm), client_mac); ret.RemoteHasher = new HMAC((HashAlgorithm)Activator.CreateInstance(definition.HashAlgorithm), server_mac); } else { ret.Encryptor = bulk.CreateEncryptor(server_key, server_iv); ret.Decryptor = bulk.CreateDecryptor(client_key, client_iv); ret.LocalHasher = new HMAC((HashAlgorithm)Activator.CreateInstance(definition.HashAlgorithm), server_mac); ret.RemoteHasher = new HMAC((HashAlgorithm)Activator.CreateInstance(definition.HashAlgorithm), client_mac); } // clear sensitive data Array.Clear(client_mac, 0, client_mac.Length); Array.Clear(server_mac, 0, server_mac.Length); Array.Clear(client_key, 0, client_key.Length); Array.Clear(server_key, 0, server_key.Length); Array.Clear(client_iv, 0, client_iv.Length); Array.Clear(server_iv, 0, server_iv.Length); Array.Clear(random, 0, random.Length); return ret; }
public static byte[] GenerateMasterSecret(byte[] premaster, byte[] clientRandom, byte[] serverRandom) { byte[] random = new byte[64]; Array.Copy(clientRandom, 0, random, 0, 32); Array.Copy(serverRandom, 0, random, 32, 32); PseudoRandomDeriveBytes prf = new PseudoRandomDeriveBytes(premaster, "master secret", random); random = prf.GetBytes(48); prf.Dispose(); return random; }
public static byte[] GenerateMasterSecret(byte[] premaster, byte[] clientRandom, byte[] serverRandom) { byte[] random = new byte[64]; Array.Copy(clientRandom, 0, random, 0, 32); Array.Copy(serverRandom, 0, random, 32, 32); PseudoRandomDeriveBytes prf = new PseudoRandomDeriveBytes(premaster, "master secret", random); random = prf.GetBytes(48); prf.Dispose(); return(random); }
protected override byte[] GetFinishedMessage() { byte[] temp, hash = new byte[36]; m_LocalMD5Hash.TransformFinalBlock(new byte[0], 0, 0); m_LocalSHA1Hash.TransformFinalBlock(new byte[0], 0, 0); Array.Copy(m_LocalMD5Hash.Hash, 0, hash, 0, 16); Array.Copy(m_LocalSHA1Hash.Hash, 0, hash, 16, 20); PseudoRandomDeriveBytes prf = new PseudoRandomDeriveBytes(m_MasterSecret, "server finished", hash); HandshakeMessage hm = new HandshakeMessage(HandshakeType.Finished, prf.GetBytes(12)); temp = hm.ToBytes(); prf.Dispose(); return temp; }
protected override byte[] GetFinishedMessage() { HandshakeMessage hm = new HandshakeMessage(HandshakeType.Finished, null); byte[] hash = new byte[36]; m_LocalMD5Hash.TransformFinalBlock(new byte[0], 0, 0); m_LocalSHA1Hash.TransformFinalBlock(new byte[0], 0, 0); Array.Copy(m_LocalMD5Hash.Hash, 0, hash, 0, 16); Array.Copy(m_LocalSHA1Hash.Hash, 0, hash, 16, 20); PseudoRandomDeriveBytes prf = new PseudoRandomDeriveBytes(m_MasterSecret, "client finished", hash); hm.fragment = prf.GetBytes(12); prf.Dispose(); return hm.ToBytes(); }
protected override byte[] GetFinishedMessage() { byte[] temp, hash = new byte[36]; m_LocalMD5Hash.TransformFinalBlock(new byte[0], 0, 0); m_LocalSHA1Hash.TransformFinalBlock(new byte[0], 0, 0); Array.Copy(m_LocalMD5Hash.Hash, 0, hash, 0, 16); Array.Copy(m_LocalSHA1Hash.Hash, 0, hash, 16, 20); PseudoRandomDeriveBytes prf = new PseudoRandomDeriveBytes(m_MasterSecret, "server finished", hash); HandshakeMessage hm = new HandshakeMessage(HandshakeType.Finished, prf.GetBytes(12)); temp = hm.ToBytes(); prf.Dispose(); return(temp); }
protected override byte[] GetFinishedMessage() { HandshakeMessage hm = new HandshakeMessage(HandshakeType.Finished, null); byte[] hash = new byte[36]; m_LocalMD5Hash.TransformFinalBlock(new byte[0], 0, 0); m_LocalSHA1Hash.TransformFinalBlock(new byte[0], 0, 0); Array.Copy(m_LocalMD5Hash.Hash, 0, hash, 0, 16); Array.Copy(m_LocalSHA1Hash.Hash, 0, hash, 16, 20); PseudoRandomDeriveBytes prf = new PseudoRandomDeriveBytes(m_MasterSecret, "client finished", hash); hm.fragment = prf.GetBytes(12); prf.Dispose(); return(hm.ToBytes()); }
protected override void VerifyFinishedMessage(byte[] peerFinished) { if (peerFinished.Length != 12) { throw new SslException(AlertDescription.IllegalParameter, "The ServerHelloDone message is invalid."); } byte[] hash = new byte[36]; m_RemoteMD5Hash.TransformFinalBlock(new byte[0], 0, 0); m_RemoteSHA1Hash.TransformFinalBlock(new byte[0], 0, 0); Array.Copy(m_RemoteMD5Hash.Hash, 0, hash, 0, 16); Array.Copy(m_RemoteSHA1Hash.Hash, 0, hash, 16, 20); PseudoRandomDeriveBytes prf = new PseudoRandomDeriveBytes(m_MasterSecret, "server finished", hash); byte[] prfBytes = prf.GetBytes(12); prf.Dispose(); for (int i = 0; i < prfBytes.Length; i++) { if (prfBytes[i] != peerFinished[i]) { throw new SslException(AlertDescription.HandshakeFailure, "The computed hash verification does not correspond with the one of the client."); } } }
protected override void VerifyFinishedMessage(byte[] peerFinished) { if (peerFinished.Length != 12) throw new SslException(AlertDescription.IllegalParameter, "The ServerHelloDone message is invalid."); byte[] hash = new byte[36]; m_RemoteMD5Hash.TransformFinalBlock(new byte[0], 0, 0); m_RemoteSHA1Hash.TransformFinalBlock(new byte[0], 0, 0); Buffer.BlockCopy(m_RemoteMD5Hash.Hash, 0, hash, 0, 16); Buffer.BlockCopy(m_RemoteSHA1Hash.Hash, 0, hash, 16, 20); PseudoRandomDeriveBytes prf = new PseudoRandomDeriveBytes(m_MasterSecret, "server finished", hash); byte[] prfBytes = prf.GetBytes(12); prf.Dispose(); for(int i = 0; i < prfBytes.Length; i++) { if (prfBytes[i] != peerFinished[i]) throw new SslException(AlertDescription.HandshakeFailure, "The computed hash verification does not correspond with the one of the client."); } }
public static CipherSuite InitializeCipherSuite(byte[] master, byte[] clientrnd, byte[] serverrnd, CipherDefinition definition, ConnectionEnd entity) { CipherSuite ret = new CipherSuite(); SymmetricAlgorithm bulk = (SymmetricAlgorithm)Activator.CreateInstance(definition.BulkCipherAlgorithm); if (definition.BulkIVSize > 0) { bulk.Mode = CipherMode.CBC; } bulk.Padding = PaddingMode.None; bulk.BlockSize = definition.BulkIVSize * 8; // get the keys and IVs byte[] client_mac, server_mac, client_key, server_key, client_iv, server_iv; byte[] random = new byte[64]; Array.Copy(serverrnd, 0, random, 0, 32); Array.Copy(clientrnd, 0, random, 32, 32); PseudoRandomDeriveBytes prf = new PseudoRandomDeriveBytes(master, "key expansion", random); client_mac = prf.GetBytes(definition.HashSize); server_mac = prf.GetBytes(definition.HashSize); client_key = prf.GetBytes(definition.BulkKeySize); server_key = prf.GetBytes(definition.BulkKeySize); client_iv = prf.GetBytes(definition.BulkIVSize); server_iv = prf.GetBytes(definition.BulkIVSize); prf.Dispose(); if (definition.Exportable) // make some extra modifications if the keys are exportable { Array.Copy(clientrnd, 0, random, 0, 32); Array.Copy(serverrnd, 0, random, 32, 32); prf = new PseudoRandomDeriveBytes(client_key, "client write key", random); client_key = prf.GetBytes(definition.BulkExpandedSize); prf.Dispose(); prf = new PseudoRandomDeriveBytes(server_key, "server write key", random); server_key = prf.GetBytes(definition.BulkExpandedSize); prf.Dispose(); prf = new PseudoRandomDeriveBytes(new byte[0], "IV block", random); client_iv = prf.GetBytes(definition.BulkIVSize); server_iv = prf.GetBytes(definition.BulkIVSize); prf.Dispose(); } // generate the cipher objects if (entity == ConnectionEnd.Client) { ret.Encryptor = bulk.CreateEncryptor(client_key, client_iv); ret.Decryptor = bulk.CreateDecryptor(server_key, server_iv); ret.LocalHasher = new Org.Mentalis.Security.Cryptography.HMAC((HashAlgorithm)Activator.CreateInstance(definition.HashAlgorithm), client_mac); ret.RemoteHasher = new Org.Mentalis.Security.Cryptography.HMAC((HashAlgorithm)Activator.CreateInstance(definition.HashAlgorithm), server_mac); } else { ret.Encryptor = bulk.CreateEncryptor(server_key, server_iv); ret.Decryptor = bulk.CreateDecryptor(client_key, client_iv); ret.LocalHasher = new Org.Mentalis.Security.Cryptography.HMAC((HashAlgorithm)Activator.CreateInstance(definition.HashAlgorithm), server_mac); ret.RemoteHasher = new Org.Mentalis.Security.Cryptography.HMAC((HashAlgorithm)Activator.CreateInstance(definition.HashAlgorithm), client_mac); } // clear sensitive data Array.Clear(client_mac, 0, client_mac.Length); Array.Clear(server_mac, 0, server_mac.Length); Array.Clear(client_key, 0, client_key.Length); Array.Clear(server_key, 0, server_key.Length); Array.Clear(client_iv, 0, client_iv.Length); Array.Clear(server_iv, 0, server_iv.Length); Array.Clear(random, 0, random.Length); return(ret); }