public static void WriteHandshake(this IConnectionStateTls13 state, ref WritableBuffer writer, HandshakeType handshakeType, Func <WritableBuffer, IConnectionStateTls13, WritableBuffer> contentWriter) { var dataWritten = writer.BytesWritten; writer.WriteBigEndian(handshakeType); BufferExtensions.WriteVector24Bit(ref writer, contentWriter, state); if (state.HandshakeHash != null) { var hashBuffer = writer.AsReadableBuffer().Slice(dataWritten); state.HandshakeHash.HashData(hashBuffer); } }
public static void WriteHandshake <T>(this T state, ref WritableBuffer writer, HandshakeType handshakeType, Func <WritableBuffer, T, WritableBuffer> contentWriter) where T : IConnectionState { state.Logger?.LogTrace("Writing handshake {handshake type}", handshakeType); var dataWritten = writer.BytesWritten; writer.WriteBigEndian(handshakeType); BufferExtensions.WriteVector24Bit <T>(ref writer, contentWriter, state); if (state.HandshakeHash != null) { var hashBuffer = writer.AsReadableBuffer().Slice(dataWritten); state.HandshakeHash.HashData(hashBuffer); } }
public unsafe void Encrypt(ref WritableBuffer buffer, RecordType recordType) { int outLength; GCHandle inHandle; ThrowOnError(EVP_CipherInit_ex(_ctx, _cipherType, IntPtr.Zero, (void *)_keyPointer, (void *)_ivPointer, (int)KeyMode.Encryption)); foreach (var b in buffer.AsReadableBuffer()) { if (b.Length == 0) { continue; } var inPtr = b.GetPointer(out inHandle); try { outLength = buffer.Memory.Length; ThrowOnError(EVP_CipherUpdate(_ctx, inPtr, ref outLength, inPtr, b.Length)); buffer.Advance(outLength); } finally { if (inHandle.IsAllocated) { inHandle.Free(); } } } buffer.Ensure(Overhead + sizeof(RecordType)); var writePtr = buffer.Memory.GetPointer(out inHandle); outLength = buffer.Memory.Length; ThrowOnError(EVP_CipherUpdate(_ctx, writePtr, ref outLength, &recordType, sizeof(RecordType))); buffer.Advance(outLength); if (_paddingSize > 0) { outLength = _paddingSize; writePtr = buffer.Memory.GetPointer(out inHandle); ThrowOnError(EVP_CipherUpdate(_ctx, writePtr, ref outLength, (byte *)s_zeroBuffer, _paddingSize)); buffer.Advance(outLength); } writePtr = buffer.Memory.GetPointer(out inHandle); outLength = 0; ThrowOnError(EVP_CipherFinal_ex(_ctx, null, ref outLength)); ThrowOnError(EVP_CIPHER_CTX_ctrl(_ctx, EVP_CIPHER_CTRL.EVP_CTRL_GCM_GET_TAG, _overhead, writePtr)); buffer.Advance(_overhead); IncrementSequence(); }
public unsafe void EncryptWithAuthData(ref WritableBuffer buffer, RecordType recordType, ushort tlsVersion, int plaintextLength) { var additionalData = stackalloc byte[13]; var additionalSpan = new Span <byte>(additionalData, 13); additionalSpan.Write64BitNumber(_sequenceNumber); additionalSpan = additionalSpan.Slice(8); additionalSpan.Write(recordType); additionalSpan = additionalSpan.Slice(1); additionalSpan.Write(tlsVersion); additionalSpan = additionalSpan.Slice(2); additionalSpan.Write16BitNumber((ushort)plaintextLength); var plainText = buffer.AsReadableBuffer(); plainText = plainText.Slice(plainText.Length - plaintextLength); ThrowOnError(EVP_CipherInit_ex(_ctx, _cipherType, IntPtr.Zero, (byte *)_keyPointer, (void *)_ivPointer, (int)KeyMode.Encryption)); int outSize = 0; ThrowOnError(EVP_CipherUpdate(_ctx, null, ref outSize, additionalData, 13)); void *inPointer; foreach (var b in plainText) { if (b.Length == 0) { continue; } b.TryGetPointer(out inPointer); outSize = b.Length; ThrowOnError(EVP_CipherUpdate(_ctx, inPointer, ref outSize, inPointer, outSize)); } buffer.Ensure(_overhead); buffer.Memory.TryGetPointer(out inPointer); ThrowOnError(EVP_CipherFinal_ex(_ctx, null, ref outSize)); ThrowOnError(EVP_CIPHER_CTX_ctrl(_ctx, EVP_CIPHER_CTRL.EVP_CTRL_GCM_GET_TAG, _overhead, inPointer)); buffer.Advance(_overhead); _sequenceNumber++; IncrementSequence(); }
private string ToHex(WritableBuffer wb) { var readable = wb.AsReadableBuffer(); if (readable.IsEmpty) { return(""); } var sb = new StringBuilder(readable.Length * 2); foreach (var mem in readable) { var span = mem.Span; int len = span.Length; for (int i = 0; i < len; i++) { sb.Append(span[i].ToString("x2")); } } return(sb.ToString()); }
public void StartHandshake(ref WritableBuffer writer) { this.WriteHandshake(ref writer, HandshakeType.client_hello, Hello.WriteClientHello); _helloBuffer = writer.AsReadableBuffer().ToArray(); State = StateType.WaitServerHello; }