public override byte[] GetMasterSecret(PseudoRandomFunction prf, byte[] seed) { var masterSecret = prf.CreateDeriveBytes(preMasterSecret, "master secret", seed).GetBytes(48); this.logger?.Debug("Master Secret: " + BitConverter.ToString(masterSecret)); return(masterSecret); }
public static void ClientFinish(TlsConnection connection, int length) { Log.Info("Recv ClientFinish"); var sha256 = SHA256.Create(); var handshakeData = connection.HandshakeMessages.GetRange(0, connection.HandshakeMessages.Count - length - 4).ToArray(); var handshakeHash = sha256.ComputeHash(handshakeData); var prfClient = new PseudoRandomFunction(connection.MasterSecretBytes, "client finished", handshakeHash); byte[] clientVerifyData = prfClient.GenerateBytes(12); byte[] data = connection.Buffer.Read(12); for (uint i = 0; i < 12; i++) { if (clientVerifyData[i] != data[i]) { Log.Error("Invalid ClientFinish!"); return; } } HandshakeResponse.ServerChangeCipherSpec(connection); connection.SendEncrypted = true; HandshakeResponse.ServerServerFinish(connection); }
protected override void ProcessFinished(HandshakeMessage finished) { if (_state != HandshakeState.ReceivedChangeCipherSpec) { throw new AlertException(AlertDescription.UnexpectedMessage, "Finished received at the wrong time"); } byte[] allMessages = _handshakeStream.ToArray(); byte[] handshakeMessages = new byte[allMessages.Length - finished.Encode().Length]; Buffer.BlockCopy(allMessages, 0, handshakeMessages, 0, handshakeMessages.Length); PseudoRandomFunction prf = _cipherSuite.PseudoRandomFunction; HashAlgorithm verifyHash = prf.CreateVerifyHashAlgorithm(_connectionState.MasterSecret); verifyHash.TransformBlock(handshakeMessages, 0, handshakeMessages.Length, handshakeMessages, 0); byte[] ourVerifyData; if (_version == ProtocolVersion.SSL3_0) { byte[] senderBytes = Encoding.ASCII.GetBytes("CLNT"); verifyHash.TransformFinalBlock(senderBytes, 0, senderBytes.Length); ourVerifyData = verifyHash.Hash; } else { verifyHash.TransformFinalBlock(new byte[0], 0, 0); byte[] hash = verifyHash.Hash; int length = _cipherSuite.PseudoRandomFunction.VerifyDataLength; ourVerifyData = _cipherSuite.PseudoRandomFunction.GetBytes(_connectionState.MasterSecret, "client finished", hash, length); } // Verify that the received data matches ours bool verifyOk = false; if (ourVerifyData.Length == finished.Data.Length) { verifyOk = true; for (int i = 0; i < ourVerifyData.Length; i++) { if (ourVerifyData[i] != finished.Data[i]) { verifyOk = false; } } } if (!verifyOk) { throw new AlertException(AlertDescription.DecryptError, "Finished packet contents incorrect"); } _connectionState.ClientVerifyData = ourVerifyData; // Send our own change cipher spec _state = HandshakeState.SendChangeCipherSpec; }
public override byte[] GetMasterSecret(PseudoRandomFunction prf, byte[] seed) { if (_preMasterSecret == null) { throw new CryptographicException("Premaster secret not defined"); } return(prf.CreateDeriveBytes(_preMasterSecret, "master secret", seed).GetBytes(48)); }
public static void ServerServerFinish(TlsConnection connection) { Log.Info("Send ServerServerFinish"); var sha256 = SHA256.Create(); var handshakeHash = sha256.ComputeHash(connection.HandshakeMessages.ToArray()); var prfClient = new PseudoRandomFunction(connection.MasterSecretBytes, "server finished", handshakeHash); byte[] servVerData = prfClient.GenerateBytes(12); TlsResponse.Handshake(connection, 20, ref servVerData); }
public void SendFinished(Stream stream) { Record record; /* change cipher spec */ record = new Record(20, VERSION); record.Fragment = new byte[] { 0x01 }; _recordHandler.ProcessOutputRecord(record); SendRecord(stream, record); /* change our own cipher spec */ _recordHandler.ChangeLocalState(); ProtocolVersion version = VERSION; byte[] handshakeMessages = _handshakeStream.ToArray(); Console.WriteLine("handshake messages length " + handshakeMessages.Length); PseudoRandomFunction prf = _cipherSuite.PseudoRandomFunction; HashAlgorithm verifyHash = prf.CreateVerifyHashAlgorithm(_masterSecret); verifyHash.TransformBlock(handshakeMessages, 0, handshakeMessages.Length, handshakeMessages, 0); byte[] verifyData; if (version == ProtocolVersion.SSL3_0) { byte[] senderBytes = Encoding.ASCII.GetBytes("CLNT"); verifyHash.TransformFinalBlock(senderBytes, 0, senderBytes.Length); verifyData = verifyHash.Hash; } else { verifyHash.TransformFinalBlock(new byte[0], 0, 0); byte[] hash = verifyHash.Hash; int length = _cipherSuite.PseudoRandomFunction.VerifyDataLength; verifyData = _cipherSuite.PseudoRandomFunction.GetBytes(_masterSecret, "client finished", hash, length); } HandshakeMessage finished = new HandshakeMessage(HandshakeMessageType.Finished, VERSION, verifyData); PrintBytes("verify data", finished.Data); record = new Record(22, VERSION); record.Fragment = finished.Encode(); _recordHandler.ProcessOutputRecord(record); SendRecord(stream, record); Console.WriteLine("encrypted finished sent"); }
public override byte[] GetMasterSecret(PseudoRandomFunction prf, byte[] seed) { // TODO: Add more PRF IDs and their respective master secrets byte[] prfID = prf.CreateDeriveBytes(new byte[0], new byte[0]).GetBytes(48); if (CompareArrays(prfID, SSLv3ID)) { return(GetSSLv3MasterSecret(seed)); } else if (CompareArrays(prfID, TLSv1ID)) { return(GetTLSv1MasterSecret(seed)); } else { throw new Exception("Unidentified PRF while getting ECDHE master secret"); } }
protected override void ProcessLocalChangeCipherSpec() { if (_state != HandshakeState.SendChangeCipherSpec) { throw new AlertException(AlertDescription.UnexpectedMessage, "Change cipher spec not after server hello done"); } byte[] handshakeMessages = _handshakeStream.ToArray(); PseudoRandomFunction prf = _cipherSuite.PseudoRandomFunction; HashAlgorithm verifyHash = prf.CreateVerifyHashAlgorithm(_connectionState.MasterSecret); verifyHash.TransformBlock(handshakeMessages, 0, handshakeMessages.Length, handshakeMessages, 0); byte[] verifyData; if (_version == ProtocolVersion.SSL3_0) { byte[] senderBytes = Encoding.ASCII.GetBytes("SRVR"); verifyHash.TransformFinalBlock(senderBytes, 0, senderBytes.Length); verifyData = verifyHash.Hash; } else { verifyHash.TransformFinalBlock(new byte[0], 0, 0); byte[] hash = verifyHash.Hash; int length = _cipherSuite.PseudoRandomFunction.VerifyDataLength; verifyData = _cipherSuite.PseudoRandomFunction.GetBytes(_connectionState.MasterSecret, "server finished", hash, length); } _connectionState.ServerVerifyData = verifyData; HandshakeMessage finished = new HandshakeMessage(HandshakeMessageType.Finished, _version, verifyData); OutputMessage(finished); // Cleanup the handshake stream used for verify hashes _handshakeStream = new MemoryStream(); // Everything done and handshake finished _state = HandshakeState.Finished; }
public void InitCipher() { byte[] preMasterSecretBytes = PreMasterSecret.ToByteArrayUnsigned(); var prf = new PseudoRandomFunction(preMasterSecretBytes, "master secret", ClientRandom.Concat(ServerRandom)); MasterSecretBytes = prf.GenerateBytes(48); prf = new PseudoRandomFunction(MasterSecretBytes, "key expansion", ServerRandom.Concat(ClientRandom)); byte[] keyBlock = prf.GenerateBytes(72); using (var memoryStream = new MemoryStream(keyBlock)) { using (var reader = new BinaryReader(memoryStream)) { ClientWriteMacKey = reader.ReadBytes(20); ServerWriteMacKey = reader.ReadBytes(20); ClientWriteKey = reader.ReadBytes(16); ServerWriteKey = reader.ReadBytes(16); } } }
public override byte[] GetMasterSecret(PseudoRandomFunction prf, byte[] seed) { return(prf.CreateDeriveBytes(_preMasterSecret, "master secret", seed).GetBytes(48)); }