public static bool VerifyMAC(CipherSuiteInfo cipher, KeyedHashAlgorithm hasher, ulong seqNum, ERecordType recordType, byte[] buffer, out byte[] bufferWithoutMac) { bufferWithoutMac = null; if (cipher.CipherType == ECipherType.Stream || cipher.CipherType == ECipherType.Block) { if (buffer.Length < cipher.MACLength) { return(false); } bufferWithoutMac = new byte[buffer.Length - cipher.MACLength]; Buffer.BlockCopy(buffer, 0, bufferWithoutMac, 0, bufferWithoutMac.Length); byte[] hash = CreateMAC(EProtocol.SSLv30, hasher, seqNum, recordType, bufferWithoutMac, 0); for (int i = 1; i <= cipher.MACLength; i++) { if (buffer[buffer.Length - i] != hash[hash.Length - i]) { byte[] originalMac = new byte[16]; Buffer.BlockCopy(buffer, buffer.Length - cipher.MACLength, originalMac, 0, cipher.MACLength); throw new HttpsException($"MAC verification fail:\n{BufferFormat.AsHexString(originalMac, cipher.MACLength)}{BufferFormat.AsHexString(hash, cipher.MACLength)}"); } } return(true); } return(false); }
protected override void BeforeCompile(INetState ns) { if (ns?.Https.IsServerEncrypting ?? false) { EncryptAndAddHash(ns); } FixupLength16Bit(3, (int)Length - 5); if (Config.DebugShowHttpsPackets) { Console.WriteLine($"Sent:"); Console.Write(BufferFormat.AsHexString(this.UnderlyingStream.GetBuffer(), (int)Length)); } }
// === Https ================================================================================================== // ============================================================================================================ public void ReceiveHttps(INetState ns, byte[] buffer, int length) { if (Config.DebugShowHttpsPackets) { Console.WriteLine($"Received from {ns}:"); Console.Write(BufferFormat.AsHexString(buffer, length)); } try { while (length > 0) { if (ns.Https == null) { ns.Https = new HttpsSession(EProtocol.SSLv30); } if (TryGetReader(ns.Https, ref buffer, ref length, out HttpsReader reader)) { switch (reader.RecordType) { case ERecordType.ChangeCipherSpec: ns.Https.ReceiveChangeCipherSpec(ns, reader); break; case ERecordType.Handshake: ns.Https.ReceiveHandshake(this, ns, reader); break; case ERecordType.ApplicationData: ReceiveApplicationData(ns, reader.Buffer, reader.Length); break; default: throw new HttpsException($"sent unknown TlsRecord type 0x{reader.RecordType:X}", reader); } } else { // save fragment ?? throw new HttpsException($"Did not save fragment!"); } } } catch (Exception e) { Console.WriteLine($"{TypeName}: {ns} {e.Message}"); ns.DisposeAfterNextFlush(); return; } }
public HttpsException(string message, byte[] buffer) : base($"{message}{Environment.NewLine}{BufferFormat.AsHexString(buffer, buffer.Length)}") { }
public HttpsException(string message, PacketReader reader) : base($"{message}{Environment.NewLine}{BufferFormat.AsHexString(reader)}") { }