예제 #1
0
        private bool ParsePreface(ReadableBuffer readableBuffer, out ReadCursor consumed, out ReadCursor examined)
        {
            consumed = readableBuffer.Start;
            examined = readableBuffer.End;

            if (readableBuffer.Length < ClientPreface.Length)
            {
                return(false);
            }

            var span = readableBuffer.IsSingleSpan
                ? readableBuffer.First.Span
                : readableBuffer.ToSpan();

            for (var i = 0; i < ClientPreface.Length; i++)
            {
                if (ClientPreface[i] != span[i])
                {
                    throw new Exception("Invalid HTTP/2 connection preface.");
                }
            }

            consumed = examined = readableBuffer.Move(readableBuffer.Start, ClientPreface.Length);
            return(true);
        }
예제 #2
0
        public bool GenerateAndCompareServerVerify(ReadableBuffer buffer)
        {
            buffer = buffer.Slice(Unsafe.SizeOf <HandshakeHeader>());
            var hashResult = new byte[_state.HandshakeHash.HashSize];

            _state.HandshakeHash.FinishHash(hashResult);
            _cryptoProvider.HashProvider.Tls12Prf(_state.CipherSuite.HashType, _masterSecret.Span, Tls12.Label_ServerFinished, hashResult, _serverVerify.Span);
            return(CompareFunctions.ConstantTimeEquals(_serverVerify.Span, buffer.ToSpan()));
        }
예제 #3
0
 private Span<byte> HandleClientFinishedAbbreviated(ReadableBuffer messageBuffer)
 {
     var span = messageBuffer.ToSpan();
     if (_secretSchedule.GenerateAndCompareClientVerify(span))
     {
     }
     _state = HandshakeState.HandshakeCompleted;
     _secretSchedule.DisposeStore();
     return span;
 }
예제 #4
0
 private Span<byte> HandleClientKeyExchange(ReadableBuffer messageBuffer)
 {
     var span = messageBuffer.ToSpan();
     HandshakeHash.HashData(span);
     span = span.Slice(HandshakeFraming.HeaderSize);
     KeyExchange.SetPeerKey(new BigEndianAdvancingSpan(span), _certificate, _signatureScheme);
     _secretSchedule.GenerateMasterSecret(dispose: true);
     _state = HandshakeState.WaitingForChangeCipherSpec;
     return span;
 }
예제 #5
0
        public ExternalCertificate(ReadableBuffer buffer)
        {
            var reader = new BigEndianAdvancingSpan(buffer.ToSpan());

            reader.Read <HandshakeHeader>();
            reader       = reader.ReadVector <UInt24>();
            _certificate = new X509Certificate2(reader.ReadVector <UInt24>().ToArray());

            if (reader.Length > 0)
            {
                _collection = new X509Certificate2Collection();
                while (reader.Length > 0)
                {
                    var cert = new X509Certificate2(reader.ReadVector <UInt24>().ToArray());
                    _collection.Add(cert);
                }
            }
            Debug.Assert(reader.Length == 0);

            _rsaPublicKey = _certificate.GetRSAPublicKey();
            if (_rsaPublicKey != null)
            {
                _certificateType = CertificateType.rsa;
                _signatureSize   = _rsaPublicKey.KeySize / 8;
                _certificateType = CertificateType.rsa;
                return;
            }
            _ecdsaPublicKey = _certificate.GetECDsaPublicKey();
            if (_ecdsaPublicKey != null)
            {
                _certificateType = CertificateType.ecdsa;
                switch (_ecdsaPublicKey.KeySize)
                {
                case 256:
                    _signatureScheme = SignatureScheme.ecdsa_secp256r1_sha256;
                    _signatureSize   = 72;
                    break;

                case 384:
                    _signatureScheme = SignatureScheme.ecdsa_secp384r1_sha384;
                    throw new NotImplementedException();

                case 521:
                    _signatureSize   = 132;
                    _signatureScheme = SignatureScheme.ecdsa_secp521r1_sha512;
                    break;

                default:
                    throw new InvalidOperationException($"Unsupported Ecdsa Keysize {_ecdsaPublicKey.KeySize}");
                }
                return;
            }
        }
예제 #6
0
        public ServerHelloParser(ReadableBuffer buffer, SecurePipeConnection secureConnection)
        {
            _originalMessage = buffer.ToSpan();
            var span = new BigEndianAdvancingSpan(_originalMessage);

            span.Read <HandshakeHeader>();
            _tlsVersion   = span.Read <TlsVersion>();
            _serverRandom = span.TakeSlice(TlsConstants.RandomLength).ToSpan();
            _sessionId    = span.ReadVector <byte>().ToSpan();
            _cipherSuite  = span.Read <ushort>();

            var compression = span.Read <byte>(); //Dump compression

            if (compression != 0)
            {
                Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.handshake_failure, "Compression is not supported");
            }

            _supportedGroups = default;
            if (span.Length == 0)
            {
                return;
            }

            span = span.ReadVector <ushort>();
            while (span.Length > 0)
            {
                var extType   = span.Read <ExtensionType>();
                var extBuffer = span.ReadVector <ushort>();

                switch (extType)
                {
                case ExtensionType.supported_groups:
                    throw new NotImplementedException();

                case ExtensionType.application_layer_protocol_negotiation:
                    throw new NotImplementedException();

                case ExtensionType.server_name:
                    throw new NotImplementedException();

                case ExtensionType.SessionTicket:
                    throw new NotImplementedException();

                case ExtensionType.signature_algorithms:
                    throw new NotImplementedException();

                case ExtensionType.renegotiation_info:
                    throw new NotImplementedException();
                }
            }
        }
예제 #7
0
 private void HandleClientFinished(out bool hasWritten, ReadableBuffer messageBuffer, out Span<byte> span)
 {
     span = messageBuffer.ToSpan();
     if (_secretSchedule.GenerateAndCompareClientVerify(span))
     {
         _state = HandshakeState.HandshakeCompleted;
     }
     if (_requiresTicket)
     {
         _secretSchedule.WriteSessionTicket();
         hasWritten = true;
         RecordHandler.WriteRecords(Connection.HandshakeOutput.Reader, RecordType.Handshake);
     }
     WriteChangeCipherSpec();
     _writeKey = _storedKey;
     _secretSchedule.GenerateAndWriteServerVerify();
     RecordHandler.WriteRecords(Connection.HandshakeOutput.Reader, RecordType.Handshake);
     hasWritten = true;
     _secretSchedule.DisposeStore();
 }
예제 #8
0
        public ServerKeyExchangeParser(ReadableBuffer reader)
        {
            var originalSpan = reader.ToSpan();
            var span         = new BigEndianAdvancingSpan(originalSpan);

            span.Read <HandshakeHeader>();
            _curveType = span.Read <ECCurveType>();
            if (_curveType != ECCurveType.named_curve)
            {
                Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.handshake_failure, "We only support named curves");
            }

            _namedGroup = span.Read <NamedGroup>();
            _key        = span;
            span.ReadVector <byte>();
            var dataLength = originalSpan.Length - span.Length;

            _data = originalSpan.Slice(4, dataLength - 4);

            _signatureScheme = span.Read <SignatureScheme>();
            _signature       = span.ReadVector <ushort>().ToSpan();
            Debug.Assert(span.Length == 0);
        }
예제 #9
0
        public ClientHelloParser(ReadableBuffer buffer, SecurePipeConnection secureConnection)
        {
            _originalMessage = buffer.ToSpan();
            var span = new BigEndianAdvancingSpan(_originalMessage);

            span.Read <HandshakeHeader>();
            _tlsVersion         = span.Read <TlsVersion>();
            _clientRandom       = span.TakeSlice(TlsConstants.RandomLength).ToSpan();
            _sessionId          = span.ReadVector <byte>().ToSpan();
            _cipherSuite        = span.ReadVector <ushort>();
            _compressionMethods = span.ReadVector <byte>().ToSpan();

            _negotiatedAlpn = ApplicationLayerProtocolType.None;
            _hostName       = null;

            if (span.Length == 0)
            {
                return;
            }

            var extensionSpan = new BigEndianAdvancingSpan(span.ReadVector <ushort>().ToSpan());

            while (extensionSpan.Length > 0)
            {
                var extType   = extensionSpan.Read <ExtensionType>();
                var extBuffer = extensionSpan.ReadVector <ushort>();
                switch (extType)
                {
                case ExtensionType.application_layer_protocol_negotiation:
                    _negotiatedAlpn = secureConnection.Listener.AlpnProvider.ProcessExtension(extBuffer);
                    break;

                case ExtensionType.server_name:
                    _hostName = secureConnection.Listener.HostNameProvider.ProcessHostNameExtension(extBuffer);
                    break;

                case ExtensionType.signature_algorithms:
                    _signatureAlgos = extBuffer;
                    break;

                case ExtensionType.supported_groups:
                    _supportedGroups = extBuffer;
                    break;

                case ExtensionType.SessionTicket:
                    _sessionTicket = extBuffer;
                    break;

                case ExtensionType.psk_key_exchange_modes:
                case ExtensionType.pre_shared_key:
                case ExtensionType.supported_versions:
                case ExtensionType.key_share:
                    break;
                }
            }

            if (span.Length > 0)
            {
                ThrowBytesLeftOver();
            }
        }
예제 #10
0
 public AlertException(ReadableBuffer buffer)
     : this(buffer.ToSpan())
 {
 }
예제 #11
0
        private static void AssertResult(ReadableBuffer buffer)
        {
            var readerSpan = buffer.ToSpan();

            Assert.Equal(s_clientFinishedDecrypted, readerSpan.ToArray());
        }