In order to initiate HTTP/2 connection over TLS, application protocol must be negotiated (References: rfc7540 section-3.3,rfc7301). ALPN support is available in SChannel for Windows Server 2012 R2, Windows 8.1 or later. Support in SslStream is a popular feature request: See here and #15077.
Client and server applications need a way to specify their supported application protocol list and be able to query the negotiated protocol.
Proposed API changepublic partial class SslStream : AuthenticatedStream { ... public virtual void AuthenticateAsClient(string targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, System.Security.Authentication.SslProtocols enabledSslProtocols, bool checkCertificateRevocation, string[] applicationProtocols); public virtual System.Threading.Tasks.Task AuthenticateAsClientAsync(string targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, System.Security.Authentication.SslProtocols enabledSslProtocols, bool checkCertificateRevocation, string[] applicationProtocols); public virtual void AuthenticateAsServer(System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate, bool clientCertificateRequired, System.Security.Authentication.SslProtocols enabledSslProtocols, bool checkCertificateRevocation, string[] applicationProtocols); public virtual System.Threading.Tasks.Task AuthenticateAsServerAsync(System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate, bool clientCertificateRequired, System.Security.Authentication.SslProtocols enabledSslProtocols, bool checkCertificateRevocation, string[] applicationProtocols); public virtual string NegotiatedApplicationProtocol; }
(New method overloads of AuthenticateAsClient
/AuthenticateAsServer
(+their async versions) are being added having new parameter string[] applicationProtocols
. New property string NegotiatedApplicationProtocol
is added as well).
Full view of SslStream API containing the proposed changes is in PR.
Example usageClient:
SslStream sslStream = new SslStream(serverStream); string[] applicationProtocols = new[] { "h2", "http/1.1" }; sslStream.AuthenticateAsClient(certificate.Subject, new X509CertificateCollection(), SslProtocols.Tls12, false, applicationProtocols); string protocol = sslStream.NegotiatedApplicationProtocol;
Server:
SslStream sslStream = new SslStream(serverStream) string[] applicationProtocols = new[] { "h2", "http/1.1" }; sslStream.AuthenticateAsServer(certificate, false, SslProtocols.Tls12, false, applicationProtocols); string protocol = sslStream.NegotiatedApplicationProtocol;Details
Client advertises list of protocols in descending order of preference. After the TLS handshake is complete the client queries the TLS stack for negotiated application protocol.
Similar way server side application provides its own list of supported protocols (again in descending order of preference). The TLS stack makes the application protocol match internally. After the handshake completes the server application queries the negotiated application protocol. Note: This behavior is supported by SChannel and is compatible with OpenSSL ALPN API. Unlike OpenSSL the SChannel does not expose possibility of querying client's advertised list of protocols therefore this API proposal does not contain server side protocol selecting based on callback.
AuthenticateAsClient
/AuthenticateAsServer
methods
applicationProtocols
parameter means the caller is not requesting application protocol negotiation. This is also the behavior of existing method overloads.AuthenticateAsServer
throws AuthenticationException
with inner exception having OS native error code. At this point the TLS handshake is aborted so the client gets IOException
due to server application closing the transport connection.AuthenticateAs…
methods could be as parameter of SslStream constructor.ArgumentException
is thrown:
NegotiatedApplicationProtocol
property
applicationProtocols
was null then this property returns null.InvalidOperationException
if calling before AuthenticateAsClient
or AuthenticateAsServer
completes.Examples of API behavior are in functional tests of PR.
Pull requestneilcawse, dcworldwide, caleblloyd, StephenLujan, MrZoidberg and 10 more
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4