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);
            }
        }
예제 #2
0
 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);
 }
예제 #3
0
        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);
        }
예제 #4
0
 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);
 }
예제 #5
0
        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);
        }
예제 #6
0
 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));
 }
예제 #7
0
 public static void WriteServerEarlyData(ref WritableBuffer buffer, IConnectionStateTls13 connectionState)
 {
     if (connectionState.EarlyDataSupported)
     {
         buffer.WriteBigEndian(ExtensionType.early_data);
         buffer.WriteBigEndian <ushort>(0);
     }
 }
예제 #8
0
 public static void WriteServerNameFromServer(ref WritableBuffer buffer, IConnectionState connectionState)
 {
     if (!string.IsNullOrWhiteSpace(connectionState.ServerName))
     {
         buffer.WriteBigEndian(ExtensionType.server_name);
         buffer.WriteBigEndian((ushort)0);
     }
 }
예제 #9
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]);
            }
        }
예제 #10
0
 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);
 }
예제 #11
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);
            }
        }
예제 #12
0
        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]);
            }
        }
예제 #13
0
파일: Hello.cs 프로젝트: vcsjones/Leto
        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);
        }
예제 #14
0
        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);
        }
예제 #15
0
파일: Hello.cs 프로젝트: vcsjones/Leto
 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);
 }
예제 #16
0
        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);
        }
예제 #17
0
 public void WriteTo(ref WritableBuffer buffer)
 {
     buffer.WriteBigEndian((ushort)Status);
     if (!string.IsNullOrEmpty(Description))
     {
         buffer.WriteUtf8String(Description);
     }
 }
예제 #18
0
 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);
 }
예제 #19
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);
 }
예제 #20
0
 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);
 }
예제 #21
0
 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);
 }
예제 #22
0
파일: Hello.cs 프로젝트: vcsjones/Leto
 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);
 }
예제 #23
0
        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);
        }
예제 #24
0
 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;
 }
예제 #25
0
        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);
            }
        }
예제 #26
0
        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);
            }
        }
예제 #27
0
 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);
 }
예제 #28
0
        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);
        }
예제 #29
0
 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);
 }
예제 #30
0
        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);
            }
        }