示例#1
0
 public static void SendFlightOne3(ref WritableBuffer writer, IConnectionStateTls13 connectionState)
 {
     if (connectionState.PskIdentity == -1)
     {
         connectionState.WriteHandshake(ref writer, HandshakeType.certificate_verify, SendCertificateVerify);
     }
 }
示例#2
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));
 }
示例#3
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);
        }
示例#4
0
文件: Hello.cs 项目: vcsjones/Leto
        public static void ReadServerHello(ReadableBuffer readable, IConnectionStateTls13 connectionState)
        {
            var    original = readable;
            ushort version, cipherCode;

            readable = readable.Slice(HandshakeProcessor.HandshakeHeaderSize);
            readable = readable.SliceBigEndian(out version);
            //skip random
            readable = readable.Slice(RandomLength);
            readable = readable.SliceBigEndian(out cipherCode);
            connectionState.CipherSuite = connectionState.CryptoProvider.GetCipherSuiteFromCode(cipherCode, connectionState.Version);
            if (connectionState.CipherSuite == null)
            {
                Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.illegal_parameter, "Could not get a cipher suite during server hello");
            }
            connectionState.StartHandshakeHash(original);
            readable = BufferExtensions.SliceVector <ushort>(ref readable);
            ExtensionType ext;

            readable = readable.SliceBigEndian(out ext);
            if (ext != ExtensionType.key_share)
            {
                Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.illegal_parameter, "There was no keyshare on the server hello");
            }
            readable = BufferExtensions.SliceVector <ushort>(ref readable);
            NamedGroup group;

            readable = readable.SliceBigEndian(out group);
            if (group != connectionState.KeyShare.NamedGroup)
            {
                Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.illegal_parameter, "The named group didn't match the keyshare during server hello");
            }
            readable = BufferExtensions.SliceVector <ushort>(ref readable);
            connectionState.KeyShare.SetPeerKey(readable);
        }
示例#5
0
        public unsafe KeySchedule(IConnectionStateTls13 state, EphemeralBufferPoolWindows pool, ReadableBuffer resumptionSecret)
        {
            _pool      = pool;
            _stateData = pool.Rent();
            _state     = state;
            _hashSize  = CryptoProvider.HashProvider.HashSize(CipherSuite.HashType);

            _stateData.Memory.TryGetPointer(out _secret);
            _clientHandshakeTrafficSecret = ((byte *)_secret) + _hashSize;
            _serverHandshakeTrafficSecret = _clientHandshakeTrafficSecret + _hashSize;
            _masterSecret = _serverHandshakeTrafficSecret + _hashSize;
            _clientApplicationTrafficSecret = _masterSecret + _hashSize;
            _serverApplicationTrafficSecret = _clientApplicationTrafficSecret + _hashSize;

            void *resumptionPointer = null;
            int   secretLength      = 0;

            if (resumptionSecret.Length > 0)
            {
                var stackSecret = stackalloc byte[resumptionSecret.Length];
                resumptionSecret.CopyTo(new Span <byte>(stackSecret, resumptionSecret.Length));
                secretLength      = resumptionSecret.Length;
                resumptionPointer = stackSecret;
            }
            HkdfFunctions.HkdfExtract(CryptoProvider.HashProvider, CipherSuite.HashType, null, 0, resumptionPointer, secretLength, _secret, _hashSize);
        }
示例#6
0
 public static void SendFlightOne(ref WritableBuffer writer, IConnectionStateTls13 connectionState)
 {
     connectionState.WriteHandshake(ref writer, HandshakeType.encrypted_extensions, (buffer, state) =>
     {
         BufferExtensions.WriteVector <ushort>(ref buffer, ExtensionsWrite.WriteExtensionList, state);
         return(buffer);
     });
 }
示例#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
文件: Hello.cs 项目: vcsjones/Leto
 public static void ReadClientHelloTls13(ReadableBuffer readable, IConnectionStateTls13 connectionState)
 {
     ReadClientHello(ref readable, connectionState);
     if (readable.Length == 0)
     {
         Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.protocol_version, "There is no extensions but we need them for Tls 1.3");
     }
     ExtensionsRead.ReadExtensionListTls13(ref readable, connectionState);
 }
示例#9
0
 public static void ReadSupportedGroups(ReadableBuffer buffer, IConnectionStateTls13 connectionState)
 {
     if (connectionState.KeyShare != null)
     {
         return;
     }
     buffer = BufferExtensions.SliceVector <ushort>(ref buffer);
     connectionState.KeyShare = connectionState.CryptoProvider.GetKeyshareFromNamedGroups(buffer);
 }
示例#10
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);
 }
示例#11
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);
 }
示例#12
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);
 }
示例#13
0
        public static void ReadKeyshare(ReadableBuffer buffer, IConnectionStateTls13 connectionState)
        {
            if (connectionState.KeyShare?.HasPeerKey == true)
            {
                return;
            }
            buffer = BufferExtensions.SliceVector <ushort>(ref buffer);
            var ks = connectionState.CryptoProvider.GetKeyshareFromKeyshare(buffer);

            connectionState.KeyShare = ks ?? connectionState.KeyShare;
        }
示例#14
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);
        }
示例#15
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);
            }
        }
示例#16
0
        public void DecryptSession(ref ReadableBuffer buffer, IConnectionStateTls13 state)
        {
            var nounce = buffer.Slice(0, 12).ToArray();

            buffer = buffer.Slice(12);
            ushort cipherCode, version;

            buffer            = buffer.SliceBigEndian(out cipherCode);
            buffer            = buffer.SliceBigEndian(out version);
            state.CipherSuite = state.CryptoProvider.GetCipherSuiteFromCode(cipherCode, state.Version);
            state.KeySchedule = new KeySchedule13(state, state.Listener.KeyScheduleProvider.BufferPool, buffer);
        }
示例#17
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);
 }
示例#18
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);
 }
示例#19
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);
 }
示例#20
0
 public static void ReadPskKeyExchangeMode(ReadableBuffer buffer, IConnectionStateTls13 connectionState)
 {
     buffer = BufferExtensions.SliceVector <byte>(ref buffer);
     while (buffer.Length > 0)
     {
         PskKeyExchangeMode mode;
         buffer = buffer.SliceBigEndian(out mode);
         if (connectionState.PskKeyExchangeMode == PskKeyExchangeMode.none)
         {
             connectionState.PskKeyExchangeMode = mode;
         }
         else
         {
             connectionState.PskKeyExchangeMode |= mode;
         }
     }
 }
示例#21
0
        public static unsafe void ServerFinished(ref WritableBuffer writer, IConnectionStateTls13 connectionState, byte[] finishedKey)
        {
            var hash = new byte[connectionState.HandshakeHash.HashSize];

            fixed(byte *hPtr = hash)
            fixed(byte *kPtr = finishedKey)
            {
                connectionState.HandshakeHash.InterimHash(hPtr, hash.Length);
                connectionState.CryptoProvider.HashProvider.HmacData(connectionState.CipherSuite.HashType, kPtr, finishedKey.Length,
                                                                     hPtr, hash.Length, hPtr, hash.Length);
            }
            connectionState.WriteHandshake(ref writer, HandshakeType.finished, (buffer, state) =>
            {
                buffer.Write(hash);
                return(buffer);
            });
        }
示例#22
0
 public bool TryToResume(long serviceId, long keyId, ReadableBuffer identity, IConnectionStateTls13 state)
 {
     for (int i = 0; i < _keyset.Length; i++)
     {
         var key = _keyset[i];
         if (key == null)
         {
             continue;
         }
         if (key.ServiceId != serviceId || key.KeyId != keyId)
         {
             continue;
         }
         state.PskIdentity = 0;
         key.DecryptSession(ref identity, state);
         return(true);
     }
     return(false);
 }
示例#23
0
        public static void ReadPskKey(ReadableBuffer pskBuffer, IConnectionStateTls13 connectionState)
        {
            var identities = BufferExtensions.SliceVector <ushort>(ref pskBuffer);

            while (identities.Length > 0)
            {
                var  identity = BufferExtensions.SliceVector <ushort>(ref identities);
                long serviceId, keyId;
                identity = identity.SliceBigEndian(out serviceId);
                identity = identity.SliceBigEndian(out keyId);
                int ticketAge;
                identities = identities.SliceBigEndian(out ticketAge);
                if (!connectionState.ResumptionProvider.TryToResume(serviceId, keyId, identity, connectionState))
                {
                    continue;
                }
                if ((connectionState.PskKeyExchangeMode & PskKeyExchangeMode.psk_dhe_ke) == 0)
                {
                    connectionState.KeyShare?.Dispose();
                    connectionState.KeyShare = null;
                }
                return;
            }
        }
示例#24
0
 public KeySchedule GetKeySchedule(IConnectionStateTls13 state)
 {
     return(new KeySchedule(state, _bufferPool, default(ReadableBuffer)));
 }
示例#25
0
 public static void WriteRetryKeyshare(ref WritableBuffer buffer, IConnectionStateTls13 connectionState)
 {
     buffer.WriteBigEndian(ExtensionType.key_share);
     buffer.WriteBigEndian((ushort)sizeof(NamedGroup));
     buffer.WriteBigEndian(connectionState.KeyShare.NamedGroup);
 }
示例#26
0
 private static void ReadEarlyData(ReadableBuffer earlyData, IConnectionStateTls13 connectionState)
 {
     connectionState.EarlyDataSupported = true;
 }
示例#27
0
        public static void ReadExtensionListTls13(ref ReadableBuffer buffer, IConnectionStateTls13 connectionState)
        {
            ReadableBuffer signatureAlgoBuffer = default(ReadableBuffer);
            ReadableBuffer pskBuffer           = default(ReadableBuffer);

            if (buffer.Length < sizeof(ushort))
            {
                Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.decode_error, $"Extension list is not at least the size of a ushort");
            }
            var listLength = buffer.ReadBigEndian <ushort>();

            buffer = buffer.Slice(sizeof(ushort));
            if (buffer.Length < listLength)
            {
                Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.decode_error, "The extension list is not as long as the header says");
            }
            var currentbuffer = buffer.Slice(0, listLength);

            buffer = buffer.Slice(currentbuffer.End);
            while (currentbuffer.Length > 3)
            {
                var extensionType   = currentbuffer.ReadBigEndian <ExtensionType>();
                var extensionLength = currentbuffer.Slice(sizeof(ExtensionType)).ReadBigEndian <ushort>();
                currentbuffer = currentbuffer.Slice(sizeof(ExtensionType) + sizeof(ushort));
                if (currentbuffer.Length < extensionLength)
                {
                    Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.decode_error, $"The extension of type {extensionType} is too long for the remaining buffer");
                }
                var extensionBuffer = currentbuffer.Slice(0, extensionLength);
                currentbuffer = currentbuffer.Slice(extensionLength);
                switch (extensionType)
                {
                case ExtensionType.server_name:
                    ReadServerName(extensionBuffer, connectionState);
                    break;

                case ExtensionType.key_share:
                    ReadKeyshare(extensionBuffer, connectionState);
                    break;

                case ExtensionType.supported_groups:
                    ReadSupportedGroups(extensionBuffer, connectionState);
                    break;

                case ExtensionType.signature_algorithms:
                    signatureAlgoBuffer = extensionBuffer;
                    break;

                case ExtensionType.application_layer_protocol_negotiation:
                    ReadApplicationProtocolExtension(extensionBuffer, connectionState);
                    break;

                case ExtensionType.pre_shared_key:
                    pskBuffer = extensionBuffer;
                    break;

                case ExtensionType.psk_key_exchange_modes:
                    ReadPskKeyExchangeMode(extensionBuffer, connectionState);
                    break;

                case ExtensionType.certificate_authorities:
                    break;

                case ExtensionType.early_data:
                    ReadEarlyData(extensionBuffer, connectionState);
                    break;
                }
            }
            //Wait until the end to check the signature, here we select the
            //certificate and this could depend on the server name indication
            //as well as the trusted CA roots.
            if (signatureAlgoBuffer.Length != 0)
            {
                ReadSignatureScheme(signatureAlgoBuffer, connectionState);
            }
            //We only check if we want to use a PSK at the end because we need the
            //entire state (ciphers okay, and all the other information is correct
            //before we bother
            if (pskBuffer.Length != 0)
            {
                ReadPskKey(pskBuffer, connectionState);
            }
            if (currentbuffer.Length != 0)
            {
                Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.decode_error, "there was data after the extension list which is invalid");
            }
        }
示例#28
0
        public static void WriteVector24Bit(ref WritableBuffer buffer, Func <WritableBuffer, IConnectionStateTls13, WritableBuffer> writeContent, IConnectionStateTls13 state)
        {
            buffer.Ensure(3);
            var bookmark = buffer.Memory;

            buffer.Advance(3);
            int currentSize = buffer.BytesWritten;

            buffer      = writeContent(buffer, state);
            currentSize = buffer.BytesWritten - currentSize;
            bookmark.Write24BitNumber(currentSize);
        }
示例#29
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);
        }
示例#30
0
 public KeySchedule GetKeySchedule(IConnectionStateTls13 state, ReadableBuffer resumptionSecret)
 {
     return(new KeySchedule(state, _bufferPool, resumptionSecret));
 }