public unsafe void EncryptSessionKey(ref WritableBuffer writer, Span <byte> ticketContent) { var tagLength = 16; var key = _keys.Take(); try { var contentLength = ticketContent.Length + tagLength + sizeof(long) + sizeof(Guid); var nonce = System.Threading.Interlocked.Increment(ref _nounceCounter); writer.WriteBigEndian((ushort)contentLength); writer.Ensure(contentLength); key.IV.Slice(4).Span.Write(nonce); key.Init(KeyMode.Encryption); writer.WriteBigEndian(_keyGuid); writer.WriteBigEndian(_nounceCounter); var amountWritten = key.Finish(ticketContent, writer.Buffer.Span); writer.Advance(amountWritten); key.GetTag(writer.Buffer.Span.Slice(0, tagLength)); writer.Advance(tagLength); } finally { _keys.Add(key); } }
public static void WriteSupportedVersion(ref WritableBuffer writer, IConnectionState connectionState) { writer.WriteBigEndian(ExtensionType.supported_versions); writer.WriteBigEndian((ushort)3); writer.WriteBigEndian((byte)2); writer.WriteBigEndian(connectionState.Version); }
public unsafe static WritableBuffer SendKeyExchange(WritableBuffer buffer, IConnectionStateTls12 connectionState) { var messageLength = 4 + connectionState.KeyShare.KeyExchangeSize; buffer.Ensure(messageLength); var bookMark = buffer.Memory; buffer.WriteBigEndian(ECCurveType.named_curve); buffer.WriteBigEndian(connectionState.KeyShare.NamedGroup); buffer.WriteBigEndian((byte)connectionState.KeyShare.KeyExchangeSize); connectionState.KeyShare.WritePublicKey(ref buffer); buffer.WriteBigEndian(connectionState.SignatureScheme); BufferExtensions.WriteVector <ushort>(ref buffer, (writer, state) => { var tempBuffer = stackalloc byte[connectionState.ClientRandom.Length * 2 + messageLength]; var tmpSpan = new Span <byte>(tempBuffer, connectionState.ClientRandom.Length * 2 + messageLength); connectionState.ClientRandom.CopyTo(tmpSpan); tmpSpan = tmpSpan.Slice(connectionState.ClientRandom.Length); connectionState.ServerRandom.CopyTo(tmpSpan); tmpSpan = tmpSpan.Slice(connectionState.ServerRandom.Length); bookMark.Span.Slice(0, messageLength).CopyTo(tmpSpan); connectionState.Certificate.SignHash(connectionState.CryptoProvider.HashProvider, connectionState.SignatureScheme, ref writer, tempBuffer, connectionState.ClientRandom.Length * 2 + messageLength); return(writer); }, connectionState); return(buffer); }
public static void WriteAlert(ref WritableBuffer output, AlertLevel level, AlertDescription description, State.IConnectionState connectionState) { connectionState.FrameWriter.StartFrame(RecordType.Alert, ref output); output.WriteBigEndian(level); output.WriteBigEndian(description); connectionState.FrameWriter.FinishFrame(ref output); }
public static WritableBuffer WriteExtensionList(WritableBuffer buffer, IConnectionState connection) { var connectionState = (IConnectionStateTls13)connection; if (connectionState.State == StateType.SendServerHello) { if (connectionState.PskIdentity != -1) { buffer.WriteBigEndian(ExtensionType.pre_shared_key); buffer.WriteBigEndian <ushort>(sizeof(ushort)); buffer.WriteBigEndian((ushort)connectionState.PskIdentity); } if (connectionState.KeyShare != null) { WriteServerKeyshare(ref buffer, connectionState); } } if (connectionState.State == StateType.WaitHelloRetry) { WriteRetryKeyshare(ref buffer, connectionState); } if (connectionState.State == StateType.SendClientHello) { WriteSupportedVersion(ref buffer, connectionState); WriteClientKeyshares(ref buffer, connectionState); WriteSignatureSchemes(ref buffer, connectionState); WriteSupportedGroups(ref buffer, connectionState); } if (connectionState.State == StateType.ServerAuthentication) { WriteServerEarlyData(ref buffer, connectionState); } return(buffer); }
public static void WriteServerName(ref WritableBuffer buffer, IConnectionStateTls13 connectionState) { buffer.WriteBigEndian(ExtensionType.server_name); buffer.WriteBigEndian((ushort)(sizeof(ushort) + connectionState.ServerName.Length)); buffer.WriteBigEndian((ushort)connectionState.ServerName.Length); buffer.Write(Encoding.UTF8.GetBytes(connectionState.ServerName)); }
public static void WriteServerEarlyData(ref WritableBuffer buffer, IConnectionStateTls13 connectionState) { if (connectionState.EarlyDataSupported) { buffer.WriteBigEndian(ExtensionType.early_data); buffer.WriteBigEndian <ushort>(0); } }
public static void WriteServerNameFromServer(ref WritableBuffer buffer, IConnectionState connectionState) { if (!string.IsNullOrWhiteSpace(connectionState.ServerName)) { buffer.WriteBigEndian(ExtensionType.server_name); buffer.WriteBigEndian((ushort)0); } }
public void WriteSupportedGroups(ref WritableBuffer buffer) { var length = _priorityOrderedKeyExchanges.Length * sizeof(NamedGroup); buffer.WriteBigEndian((ushort)length); for (int i = 0; i < _priorityOrderedKeyExchanges.Length; i++) { buffer.WriteBigEndian(_priorityOrderedKeyExchanges[i]); } }
public static void WriteSecureRenegotiation(ref WritableBuffer buffer, IConnectionState connectionState) { if (!connectionState.SecureRenegotiation) { return; } buffer.WriteBigEndian(ExtensionType.renegotiation_info); buffer.WriteBigEndian <ushort>(1); buffer.WriteBigEndian <byte>(0); }
public void WriteCipherSuites(ref WritableBuffer buffer) { var length = _priorityOrderedCipherSuitesTls13.Length * sizeof(ushort); buffer.WriteBigEndian((ushort)length); for (int i = 0; i < _priorityOrderedCipherSuitesTls13.Length; i++) { buffer.WriteBigEndian(_priorityOrderedCipherSuitesTls13[i].CipherCode); } }
public void WriteSignatureSchemes(ref WritableBuffer buffer) { var length = _prioritySignatureSchemes.Length * sizeof(SignatureScheme); buffer.WriteBigEndian((ushort)length); for (int i = 0; i < _prioritySignatureSchemes.Length; i++) { buffer.WriteBigEndian(_prioritySignatureSchemes[i]); } }
public static WritableBuffer SendServerHello13(WritableBuffer buffer, IConnectionStateTls13 connectionState) { buffer.Ensure(RandomLength + sizeof(ushort)); buffer.WriteBigEndian(connectionState.Version); var memoryToFill = buffer.Memory.Slice(0, RandomLength); connectionState.CryptoProvider.FillWithRandom(memoryToFill); buffer.Advance(RandomLength); buffer.WriteBigEndian(connectionState.CipherSuite.CipherCode); BufferExtensions.WriteVector <ushort>(ref buffer, ExtensionsWrite.WriteExtensionList, connectionState); return(buffer); }
internal void WriteSessionKey(ref WritableBuffer writer, IConnectionState state) { writer.WriteBigEndian(_randomServiceId); writer.WriteBigEndian(_randomId); var sequence = System.Threading.Interlocked.Increment(ref _sequence); writer.WriteBigEndian(_nounceStart ^ sequence); writer.Write(_nounceBase.Slice(8)); //Now we have to encrypt the data writer.WriteBigEndian(state.CipherSuite.CipherCode); writer.WriteBigEndian(state.Version); //writer.Write(state.KeySchedule.ResumptionSecret); }
public static WritableBuffer WriteClientHello(WritableBuffer buffer, IConnectionStateTls13 connectionState) { buffer.WriteBigEndian <ushort>(0x0303); buffer.Ensure(RandomLength); connectionState.CryptoProvider.FillWithRandom(buffer.Memory.Slice(0, RandomLength)); buffer.Advance(RandomLength); //legacy sessionid buffer.WriteBigEndian((byte)0); connectionState.CryptoProvider.WriteCipherSuites(ref buffer); //legacy compression buffer.WriteBigEndian((byte)1); buffer.WriteBigEndian((byte)0); connectionState.KeyShare = connectionState.CryptoProvider.GetDefaultKeyShare(); BufferExtensions.WriteVector <ushort>(ref buffer, ExtensionsWrite.WriteExtensionList, connectionState); return(buffer); }
public static WritableBuffer CreateNewSessionKey(WritableBuffer buffer, IConnectionStateTls13 state) { var lifetime = TicketLifeTimeInHours * 60 * 60; buffer.WriteBigEndian((uint)lifetime); buffer.Ensure(4); state.CryptoProvider.FillWithRandom(buffer.Memory.Slice(0, 4)); buffer.Advance(4); BufferExtensions.WriteVector <ushort>(ref buffer, (writer, conn) => { state.ResumptionProvider.GenerateSessionTicket(ref writer, conn); return(writer); }, state); BufferExtensions.WriteVector <ushort>(ref buffer, (writer, conn) => { writer.WriteBigEndian(ExtensionType.ticket_early_data_info); writer.WriteBigEndian <ushort>(sizeof(uint)); uint maxData = 1024 * 2; writer.WriteBigEndian(maxData); return(writer); }, state); return(buffer); }
public void WriteTo(ref WritableBuffer buffer) { buffer.WriteBigEndian((ushort)Status); if (!string.IsNullOrEmpty(Description)) { buffer.WriteUtf8String(Description); } }
public static void WriteCertificateEntry(ref WritableBuffer writer, byte[] certificate) { writer.Ensure(3); writer.Memory.Write24BitNumber(certificate.Length); writer.Advance(3); writer.Write(certificate); writer.WriteBigEndian <ushort>(0); }
public static void WriteSignatureSchemes(ref WritableBuffer buffer, IConnectionStateTls13 connectionState) { buffer.WriteBigEndian(ExtensionType.signature_algorithms); BufferExtensions.WriteVector <ushort>(ref buffer, (writer, state) => { connectionState.CryptoProvider.WriteSignatureSchemes(ref writer); return(writer); }, connectionState); }
public static void WriteServerKeyshare(ref WritableBuffer buffer, IConnectionState connectionState) { buffer.WriteBigEndian(ExtensionType.key_share); BufferExtensions.WriteVector <ushort>(ref buffer, (writer, state) => { WriteKeyShare(ref writer, state.KeyShare); return(writer); }, connectionState); }
public static void WriteSupportedGroups(ref WritableBuffer buffer, IConnectionStateTls13 connectionState) { buffer.WriteBigEndian(ExtensionType.supported_groups); BufferExtensions.WriteVector <ushort>(ref buffer, (writer, state) => { connectionState.CryptoProvider.WriteSupportedGroups(ref writer); return(writer); }, connectionState); }
public static WritableBuffer SendHelloRetry(WritableBuffer buffer, IConnectionStateTls13 connectionState) { if (connectionState.State == StateType.WaitHelloRetry) { Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.handshake_failure, "need to send a hello retry but have already sent one"); } buffer.WriteBigEndian(connectionState.Version); BufferExtensions.WriteVector <ushort>(ref buffer, ExtensionsWrite.WriteExtensionList, connectionState); return(buffer); }
public unsafe void WritePublicKey(ref WritableBuffer keyBuffer) { var tmpBuffer = stackalloc byte[_keyExchangeSize + 8]; int resultSize; ExceptionHelper.CheckReturnCode(BCryptExportKey(_key, IntPtr.Zero, KeyBlobType.BCRYPT_ECCPUBLIC_BLOB, (IntPtr)tmpBuffer, _keyExchangeSize + 8, out resultSize, 0)); var keySpan = new Span <byte>(tmpBuffer + 8, resultSize - 8); keyBuffer.WriteBigEndian((byte)4); keyBuffer.Write(keySpan); }
public void StartFrame(RecordType recordType, ref WritableBuffer buffer) { if (_frameStarted) { ExceptionHelper.ThrowException(new InvalidOperationException("Already writing a frame and started another")); } _frameStarted = true; _recordType = recordType; buffer.Ensure(RecordProcessor.RecordHeaderLength); buffer.WriteBigEndian(recordType); buffer.WriteBigEndian(_state.TlsRecordVersion); _bookmark = buffer.Memory; buffer.WriteBigEndian <ushort>(0); _messageBodySize = buffer.BytesWritten; if (_state.WriteKey == null) { return; } _state.WriteKey.WriteNonce(ref buffer); _plainTextSize = buffer.BytesWritten; }
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 static void WriteClientKeyshares(ref WritableBuffer buffer, IConnectionStateTls13 connectionState) { buffer.WriteBigEndian(ExtensionType.key_share); BufferExtensions.WriteVector <ushort>(ref buffer, (innerWriter, innerState) => { BufferExtensions.WriteVector <ushort>(ref innerWriter, (writer, state) => { WriteKeyShare(ref writer, state.KeyShare); return(writer); }, innerState); return(innerWriter); }, connectionState); }
public unsafe static WritableBuffer SendCertificateVerify(WritableBuffer writer, IConnectionStateTls13 state) { writer.WriteBigEndian(state.SignatureScheme); var bookMark = writer.Memory; writer.WriteBigEndian((ushort)0); var hash = new byte[state.HandshakeHash.HashSize + Tls1_3Consts.SignatureDigestPrefix.Length + Tls1_3Consts.ServerCertificateVerify.Length]; Tls1_3Consts.SignatureDigestPrefix.CopyTo(hash, 0); Tls1_3Consts.ServerCertificateVerify.CopyTo(hash, Tls1_3Consts.SignatureDigestPrefix.Length); fixed(byte *hPtr = hash) { var sigPtr = hPtr + Tls1_3Consts.SignatureDigestPrefix.Length + Tls1_3Consts.ServerCertificateVerify.Length; state.HandshakeHash.InterimHash(sigPtr, state.HandshakeHash.HashSize); var sigSize = state.Certificate.SignHash(state.CryptoProvider.HashProvider, state.SignatureScheme, ref writer, hPtr, hash.Length); bookMark.Span.Write16BitNumber((ushort)sigSize); } return(writer); }
public static WritableBuffer WriteCertificate(WritableBuffer writer, IConnectionStateTls13 connectionState) { writer.WriteBigEndian <byte>(0); BufferExtensions.WriteVector24Bit(ref writer, (buffer, state) => { WriteCertificateEntry(ref buffer, state.Certificate.CertificateData); for (int i = 0; i < state.Certificate.CertificateChain.Length; i++) { WriteCertificateEntry(ref buffer, state.Certificate.CertificateChain[i]); } return(buffer); }, connectionState); return(writer); }
public static void WriteVector <[Primitive] T>(ref WritableBuffer buffer, Func <WritableBuffer, IConnectionState, WritableBuffer> writeContent, IConnectionState state) where T : struct { var bookMark = buffer.Memory; if (typeof(T) == typeof(ushort)) { buffer.WriteBigEndian((ushort)0); } else if (typeof(T) == typeof(byte)) { buffer.WriteBigEndian((byte)0); } else if (typeof(T) == typeof(UInt24)) { buffer.WriteBigEndian((UInt24)0); } else { Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.internal_error, $"Unkown vector type {typeof(T).Name}"); } var sizeofVector = buffer.BytesWritten; buffer = writeContent(buffer, state); sizeofVector = buffer.BytesWritten - sizeofVector; if (typeof(T) == typeof(ushort)) { bookMark.Span.Write16BitNumber((ushort)sizeofVector); } else if (typeof(T) == typeof(UInt24)) { bookMark.Write24BitNumber(sizeofVector); } else { bookMark.Span.Write((byte)sizeofVector); } }