Beispiel #1
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;
            }
        }
Beispiel #2
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();
                }
            }
        }
Beispiel #3
0
        //This can be extended to check that we match a list of servernames
        //or any other logic that is required
        public string ProcessHostNameExtension(BigEndianAdvancingSpan buffer)
        {
            buffer = buffer.ReadVector <ushort>();
            var type = buffer.Read <byte>();

            if (type != 0)
            {
                Alerts.AlertException.ThrowDecode("Unknown host type");
            }

            buffer = buffer.ReadVector <ushort>();
            return(string.Empty);// Ascii.ToUtf16String(buffer.ToSpan());
        }
Beispiel #4
0
 public SignatureScheme SelectAlgorithm(BigEndianAdvancingSpan buffer)
 {
     if (_certificateType == CertificateType.ecdsa)
     {
         return(_ecDsaSignatureScheme);
     }
     if (buffer.Length == 0)
     {
         return(DefaultSignatureScheme);
     }
     buffer = buffer.ReadVector <ushort>();
     while (buffer.Length > 0)
     {
         var scheme   = buffer.Read <SignatureScheme>();
         var lastByte = 0x00FF & (ushort)scheme;
         switch (_certificateType)
         {
         case CertificateType.rsa:
             if (lastByte == 1)
             {
                 return(scheme);
             }
             if ((0xFF00 & (ushort)scheme) == 0x0800 && lastByte > 3 && lastByte < 7)
             {
                 return(scheme);
             }
             break;
         }
     }
     Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.handshake_failure, "Failed to find an appropriate signature scheme");
     return(SignatureScheme.none);
 }
Beispiel #5
0
        public void SetPeerKey(BigEndianAdvancingSpan peerKey, ICertificate certificate, SignatureScheme scheme)
        {
            peerKey = peerKey.ReadVector <ushort>();
            var decryptedLength = certificate.Decrypt(scheme, peerKey.ToSpan(), peerKey.ToSpan());

            peerKey          = peerKey.TakeSlice(decryptedLength);
            _premasterSecret = peerKey.ToArray();
        }
 public void SetPeerKey(BigEndianAdvancingSpan peerKey, ICertificate certificate, SignatureScheme scheme)
 {
     peerKey = peerKey.ReadVector <byte>();
     if (peerKey.Length != _keyExchangeSize)
     {
         Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.illegal_parameter, $"The peer key is not the length of the keyexchange size {peerKey.Length} - {_keyExchangeSize}");
     }
     InternalSetPeerKey(peerKey.ToSpan());
 }
 public void SetPeerKey(BigEndianAdvancingSpan peerKey, ICertificate certificate, SignatureScheme scheme)
 {
     peerKey = peerKey.ReadVector <byte>();
     if (peerKey.Length != _keyExchangeSize)
     {
         Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.decode_error, "Peer key is bad");
     }
     InternalSetPeerKey(peerKey.ToSpan());
 }
        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);
        }
Beispiel #9
0
 public (ICertificate, SignatureScheme) GetCertificate(BigEndianAdvancingSpan buffer)
 {
     buffer = buffer.ReadVector <ushort>();
     while (buffer.Length > 0)
     {
         var scheme = buffer.Read <SignatureScheme>();
         for (var i = 0; i < _certificates.Count; i++)
         {
             if (_certificates[i].SupportsScheme(scheme))
             {
                 return(_certificates[i], scheme);
             }
         }
     }
     Alerts.AlertException.ThrowFailedHandshake("Failed to find a certificate and scheme that matches");
     return(null, SignatureScheme.none);
 }
 private IKeyExchange EcdheKeyExchange(BigEndianAdvancingSpan supportedGroups)
 {
     if (supportedGroups.Length == 0)
     {
         return(GetEcdheKeyExchange(DefaultNamedGroup));
     }
     supportedGroups = supportedGroups.ReadVector <ushort>();
     while (supportedGroups.Length > 0)
     {
         var namedGroup = supportedGroups.Read <NamedGroup>();
         if (!_supportedNamedGroups.Contains(namedGroup))
         {
             continue;
         }
         var key = GetEcdheKeyExchange(namedGroup);
         if (key != null)
         {
             return(key);
         }
     }
     Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.handshake_failure, "Unable to match key exchange");
     return(null);
 }
Beispiel #11
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();
            }
        }