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); }
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())); }
private Span<byte> HandleClientFinishedAbbreviated(ReadableBuffer messageBuffer) { var span = messageBuffer.ToSpan(); if (_secretSchedule.GenerateAndCompareClientVerify(span)) { } _state = HandshakeState.HandshakeCompleted; _secretSchedule.DisposeStore(); return span; }
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; }
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; } }
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(); } } }
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(); }
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); }
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(); } }
public AlertException(ReadableBuffer buffer) : this(buffer.ToSpan()) { }
private static void AssertResult(ReadableBuffer buffer) { var readerSpan = buffer.ToSpan(); Assert.Equal(s_clientFinishedDecrypted, readerSpan.ToArray()); }