Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        public void RegisterSessionTicket(ReadableBuffer buffer)
        {
            //slice off the head first
            buffer = buffer.Slice(HandshakeProcessor.HandshakeHeaderSize);
            uint ticketAge, ageRandom;

            buffer = buffer.SliceBigEndian(out ticketAge);
            buffer = buffer.SliceBigEndian(out ageRandom);
            var ticketData = BufferExtensions.SliceVector <ushort>(ref buffer);

            if (buffer.Length > 0)
            {
                //Extensions
                buffer = BufferExtensions.SliceVector <ushort>(ref buffer);
                if (buffer.Length > 0)
                {
                    //seems we can resume data
                    ExtensionType type;
                    buffer = buffer.SliceBigEndian(out type);
                    if (type != ExtensionType.ticket_early_data_info)
                    {
                        Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.illegal_parameter, "Early session ticket received had an invalid extension");
                    }
                }
            }
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
0
        private static TlsVersion GetVersion(ref ReadableBuffer buffer)
        {
            //Jump the version header and the randoms
            buffer = buffer.Slice(HandshakeProcessor.HandshakeHeaderSize);
            TlsVersion version;

            buffer = buffer.SliceBigEndian(out version);
            if (!_supportedVersion.Contains(version))
            {
                Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.protocol_version, $"The version was not in the supported list {version}");
            }
            //Slice out the random
            buffer = buffer.Slice(Hello.RandomLength);
            //No sessions slice and dump
            BufferExtensions.SliceVector <byte>(ref buffer);
            //Skip the cipher suites if we find a version we are happy with
            //then the cipher suite is dealt with by that version
            BufferExtensions.SliceVector <ushort>(ref buffer);
            //Skip compression, we don't care about that either, we just want to get to the end
            BufferExtensions.SliceVector <byte>(ref buffer);
            //And here we are at the end, if we have no extensions then we must be the header version that
            //we accepted earlier
            if (buffer.Length == 0)
            {
                return(version);
            }
            buffer = BufferExtensions.SliceVector <ushort>(ref buffer);
            while (buffer.Length >= 8)
            {
                ExtensionType type;
                buffer = buffer.SliceBigEndian(out type);
                var ext = BufferExtensions.SliceVector <ushort>(ref buffer);
                if (type == ExtensionType.supported_versions)
                {
                    //Scan the version for supported ones
                    return(ExtensionsRead.ReadSupportedVersion(ext, _supportedVersion));
                }
            }
            return(version);
        }
Ejemplo n.º 5
0
        public unsafe IKeyshareInstance GetKeyshareFromKeyshare(ReadableBuffer buffer)
        {
            var originalBuffer = buffer;

            int keyshareCount = 0;

            //loop through to find the count of keyshares
            while (buffer.Length > 1)
            {
                buffer = buffer.Slice(sizeof(NamedGroup));
                BufferExtensions.SliceVector <ushort>(ref buffer);
                keyshareCount += 2;
            }

            buffer = originalBuffer;
            var peerKeyshareList = stackalloc ushort[keyshareCount];
            int currentIndex     = 0;

            while (buffer.Length > 1)
            {
                NamedGroup namedGroup;
                buffer = buffer.SliceBigEndian(out namedGroup);
                var index = (ushort)(originalBuffer.Length - buffer.Length);
                BufferExtensions.SliceVector <ushort>(ref buffer);
                peerKeyshareList[currentIndex]     = (ushort)namedGroup;
                peerKeyshareList[currentIndex + 1] = index;
                currentIndex += 2;
            }

            for (var i = 0; i < _priorityOrderedKeyExchanges.Length; i++)
            {
                for (var x = 0; x < keyshareCount; x += 2)
                {
                    if (peerKeyshareList[x] == (ushort)_priorityOrderedKeyExchanges[i])
                    {
                        var instance = _keyShareProvider.GetKeyShareInstance((NamedGroup)peerKeyshareList[x]);
                        if (instance == null)
                        {
                            continue;
                        }
                        originalBuffer = originalBuffer.Slice(peerKeyshareList[x + 1]);
                        originalBuffer = BufferExtensions.SliceVector <ushort>(ref originalBuffer);
                        instance.SetPeerKey(originalBuffer);
                        return(instance);
                    }
                }
            }
            return(null);
        }
Ejemplo n.º 6
0
 public static void ReadSignatureScheme(ReadableBuffer buffer, IConnectionState connectionState)
 {
     buffer = BufferExtensions.SliceVector <ushort>(ref buffer);
     while (buffer.Length > 1)
     {
         SignatureScheme scheme;
         buffer = buffer.SliceBigEndian(out scheme);
         var cert = connectionState.CertificateList.GetCertificate(connectionState.ServerName, scheme);
         if (cert != null)
         {
             connectionState.Certificate     = cert;
             connectionState.SignatureScheme = scheme;
             return;
         }
     }
     Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.handshake_failure, "Failed to find a signature scheme that matches");
 }
Ejemplo n.º 7
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;
         }
     }
 }
Ejemplo n.º 8
0
        public static TlsVersion ReadSupportedVersion(ReadableBuffer buffer, TlsVersion[] supportedVersions)
        {
            TlsVersion returnVersion = 0;

            buffer = BufferExtensions.SliceVector <byte>(ref buffer);
            while (buffer.Length > 1)
            {
                TlsVersion version;
                buffer = buffer.SliceBigEndian(out version);
                if (supportedVersions.Contains(version))
                {
                    if (version > returnVersion)
                    {
                        returnVersion = version;
                    }
                }
            }
            return(returnVersion);
        }