public void ProcessFinished(byte[] payload) { if (m_HandshakePhase != HandshakeDataType.Finished) { throw new SslAlertException(AlertLevel.Fatal, AlertDescription.UnexpectedMessage); } byte[] data = GetAllHandshakeInBytes(); byte[] sha1data = (new SHA1Managed()).ComputeHash(data); byte[] md5data = (new MD5Managed()).ComputeHash(data); PrfDeriveBytes prf = new PrfDeriveBytes(m_SecurityParameters.MasterSecret, "server finished", ByteArray.Concat(md5data, sha1data)); byte[] result = prf.GetBytes(12); prf.Dispose(); if (!ByteArray.AreEqual(result, payload)) { throw new SslAlertException(AlertLevel.Fatal, AlertDescription.DecryptError); } else { /* Clear out list of handshake messages */ m_ListOfHandshakeMsgs.Clear(); throw new SslHandshakeCompleteException(); } }
public void ProcessServerHelloDone() { m_HandshakePhase = HandshakeDataType.ServerHelloDone; PreMasterSecret pms = new PreMasterSecret(); byte[] keyExchangeData = GenerateKeyExchangeData(pms.GetBytes()); /* Generate Master Secret */ PrfDeriveBytes prf = new PrfDeriveBytes(pms.GetBytes(), "master secret", ByteArray.Concat(m_SecurityParameters.ClientRandom, m_SecurityParameters.ServerRandom)); m_Session.MasterSecret = prf.GetBytes(48); m_SecurityParameters.MasterSecret = m_Session.MasterSecret; prf.Dispose(); /* clear pre-master secret from memory */ pms.Dispose(); /* Create handshake messages */ m_ProtocolQueue.Enqueue(CreateClientKeyExchange(keyExchangeData)); m_ProtocolQueue.Enqueue(CreateChangeCipherSpec()); m_ProtocolQueue.Enqueue(CreateFinishedMsg(m_SecurityParameters.MasterSecret)); ParametersReady(m_SecurityParameters); }
internal IProtocolMessage CreateFinishedMsg(byte[] masterSecret) { byte[] data = GetAllHandshakeInBytes(); byte[] md5data = (new MD5Managed()).ComputeHash(data); byte[] sha1data = (new SHA1Managed()).ComputeHash(data); PrfDeriveBytes prf = new PrfDeriveBytes(masterSecret, "client finished", ByteArray.Concat(md5data, sha1data)); byte[] result = prf.GetBytes(12); prf.Dispose(); HandshakeProtocolMessage hpm = new HandshakeProtocolMessage(new Finished(result)); m_ListOfHandshakeMsgs.Add(hpm); m_HandshakePhase = HandshakeDataType.Finished; return(hpm); }
public CipherSuite(TlsCipherSuite suite, byte[] master, byte[] clientRandom, byte[] serverRandom) { if (master == null) { throw new ArgumentNullException(); } if (clientRandom == null) { throw new ArgumentNullException(); } if (serverRandom == null) { throw new ArgumentNullException(); } CipherDefinition cipherDef = CipherSuites.GetCipherDefinition(suite); int size = cipherDef.HashSize * 2 + cipherDef.BulkKeySize * 2; if (cipherDef.BulkIVSize != 0) { size += cipherDef.BulkIVSize * 2; } PrfDeriveBytes prf = new PrfDeriveBytes(master, "key expansion", ByteArray.Concat(serverRandom, clientRandom)); byte[] keyBlock = prf.GetBytes(size); prf.Dispose(); int offset = 0; byte[] client_write_mac = new byte[cipherDef.HashSize]; System.Buffer.BlockCopy(keyBlock, offset, client_write_mac, 0, cipherDef.HashSize); offset += cipherDef.HashSize; byte[] server_write_mac = new byte[cipherDef.HashSize]; System.Buffer.BlockCopy(keyBlock, offset, server_write_mac, 0, cipherDef.HashSize); offset += cipherDef.HashSize; byte[] client_write_key = new byte[cipherDef.BulkKeySize]; System.Buffer.BlockCopy(keyBlock, offset, client_write_key, 0, cipherDef.BulkKeySize); offset += cipherDef.BulkKeySize; byte[] server_write_key = new byte[cipherDef.BulkKeySize]; System.Buffer.BlockCopy(keyBlock, offset, server_write_key, 0, cipherDef.BulkKeySize); offset += cipherDef.BulkKeySize; byte[] client_write_iv = null; byte[] server_write_iv = null; if (cipherDef.BulkIVSize != 0) { client_write_iv = new byte[cipherDef.BulkIVSize]; System.Buffer.BlockCopy(keyBlock, offset, client_write_iv, 0, cipherDef.BulkIVSize); offset += cipherDef.BulkIVSize; server_write_iv = new byte[cipherDef.BulkIVSize]; System.Buffer.BlockCopy(keyBlock, offset, server_write_iv, 0, cipherDef.BulkIVSize); offset += cipherDef.BulkIVSize; } prf.Dispose(); SymmetricAlgorithm sAlg = (SymmetricAlgorithm)Activator.CreateInstance(cipherDef.BulkCipherAlgorithm); sAlg.BlockSize = cipherDef.BulkIVSize * 8; if (cipherDef.Exportable) { //TODO: Make amends to support export cipher suites } m_Encryptor = sAlg.CreateEncryptor(client_write_key, client_write_iv); m_Decryptor = sAlg.CreateDecryptor(server_write_key, server_write_iv); m_ClientHasher = (KeyedHashAlgorithm)Activator.CreateInstance(cipherDef.HashAlgorithm, client_write_mac); m_ServerHasher = (KeyedHashAlgorithm)Activator.CreateInstance(cipherDef.HashAlgorithm, server_write_mac); /* clear up */ Array.Clear(client_write_mac, 0, client_write_mac.Length); Array.Clear(server_write_mac, 0, server_write_mac.Length); Array.Clear(client_write_key, 0, client_write_key.Length); Array.Clear(server_write_key, 0, server_write_key.Length); if (client_write_iv != null && server_write_iv != null) { Array.Clear(client_write_iv, 0, client_write_iv.Length); Array.Clear(server_write_iv, 0, server_write_iv.Length); } }