internal SniEndPointResolver(IDnsResolver dns, SniOptions sniOptions, IRandom rand) { _dns = dns; _sniOptions = sniOptions; _random = rand; if (sniOptions.IsIp) { _endPoint = new IPEndPoint(sniOptions.Ip, sniOptions.Port); } }
internal SniEndPointResolver(IDnsResolver dns, SniOptions sniOptions, IRandom rand) { _dns = dns ?? throw new ArgumentNullException(nameof(dns)); _sniOptions = sniOptions ?? throw new ArgumentNullException(nameof(sniOptions)); _random = rand ?? throw new ArgumentNullException(nameof(rand)); if (sniOptions.IsIp) { _endPoint = new IPEndPoint(sniOptions.Ip, sniOptions.Port); } }
public SniEndPointResolver(IDnsResolver dns, SniOptions sniOptions) : this(dns, sniOptions, new DefaultRandom()) { }
public SniOptionsSelector( string endpointName, Dictionary <string, SniConfig> sniDictionary, ICertificateConfigLoader certifcateConfigLoader, HttpsConnectionAdapterOptions fallbackHttpsOptions, HttpProtocols fallbackHttpProtocols, ILogger <HttpsConnectionMiddleware> logger) { _endpointName = endpointName; _fallbackServerCertificateSelector = fallbackHttpsOptions.ServerCertificateSelector; _onAuthenticateCallback = fallbackHttpsOptions.OnAuthenticate; foreach (var(name, sniConfig) in sniDictionary) { var sslOptions = new SslServerAuthenticationOptions { ServerCertificate = certifcateConfigLoader.LoadCertificate(sniConfig.Certificate, $"{endpointName}:Sni:{name}"), EnabledSslProtocols = sniConfig.SslProtocols ?? fallbackHttpsOptions.SslProtocols, CertificateRevocationCheckMode = fallbackHttpsOptions.CheckCertificateRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck, }; if (sslOptions.ServerCertificate is null) { if (fallbackHttpsOptions.ServerCertificate is null && _fallbackServerCertificateSelector is null) { throw new InvalidOperationException(CoreStrings.NoCertSpecifiedNoDevelopmentCertificateFound); } if (_fallbackServerCertificateSelector is null) { // Cache the fallback ServerCertificate since there's no fallback ServerCertificateSelector taking precedence. sslOptions.ServerCertificate = fallbackHttpsOptions.ServerCertificate; } } if (sslOptions.ServerCertificate != null) { // This might be do blocking IO but it'll resolve the certificate chain up front before any connections are // made to the server sslOptions.ServerCertificateContext = SslStreamCertificateContext.Create((X509Certificate2)sslOptions.ServerCertificate, additionalCertificates: null); } if (!certifcateConfigLoader.IsTestMock && sslOptions.ServerCertificate is X509Certificate2 cert2) { HttpsConnectionMiddleware.EnsureCertificateIsAllowedForServerAuth(cert2); } var clientCertificateMode = sniConfig.ClientCertificateMode ?? fallbackHttpsOptions.ClientCertificateMode; if (clientCertificateMode != ClientCertificateMode.NoCertificate) { sslOptions.ClientCertificateRequired = clientCertificateMode == ClientCertificateMode.AllowCertificate || clientCertificateMode == ClientCertificateMode.RequireCertificate; sslOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => HttpsConnectionMiddleware.RemoteCertificateValidationCallback( clientCertificateMode, fallbackHttpsOptions.ClientCertificateValidation, certificate, chain, sslPolicyErrors); } var httpProtocols = sniConfig.Protocols ?? fallbackHttpProtocols; httpProtocols = HttpsConnectionMiddleware.ValidateAndNormalizeHttpProtocols(httpProtocols, logger); HttpsConnectionMiddleware.ConfigureAlpn(sslOptions, httpProtocols); var sniOptions = new SniOptions(sslOptions, httpProtocols, clientCertificateMode); if (name.Equals(WildcardHost, StringComparison.Ordinal)) { _wildcardOptions = sniOptions; } else if (name.StartsWith(WildcardPrefix, StringComparison.Ordinal)) { // Only slice off 1 character, the `*`. We want to match the leading `.` also. _wildcardPrefixOptions.Add(name.Substring(1), sniOptions); } else { _exactNameOptions.Add(name, sniOptions); } } }
public SslServerAuthenticationOptions GetOptions(ConnectionContext connection, string serverName) { SniOptions sniOptions = null; if (!string.IsNullOrEmpty(serverName) && !_exactNameOptions.TryGetValue(serverName, out sniOptions)) { foreach (var(suffix, options) in _wildcardPrefixOptions) { if (serverName.EndsWith(suffix, StringComparison.OrdinalIgnoreCase)) { sniOptions = options; break; } } } // Fully wildcarded ("*") options can be used even when given an empty server name. sniOptions ??= _wildcardOptions; if (sniOptions is null) { if (serverName is null) { // There was no ALPN throw new AuthenticationException(CoreStrings.FormatSniNotConfiguredToAllowNoServerName(_endpointName)); } else { throw new AuthenticationException(CoreStrings.FormatSniNotConfiguredForServerName(serverName, _endpointName)); } } connection.Features.Set(new HttpProtocolsFeature(sniOptions.HttpProtocols)); var sslOptions = sniOptions.SslOptions; if (sslOptions.ServerCertificate is null) { Debug.Assert(_fallbackServerCertificateSelector != null, "The cached SniOptions ServerCertificate can only be null if there's a fallback certificate selector."); // If a ServerCertificateSelector doesn't return a cert, HttpsConnectionMiddleware doesn't fallback to the ServerCertificate. sslOptions = CloneSslOptions(sslOptions); var fallbackCertificate = _fallbackServerCertificateSelector(connection, serverName); if (fallbackCertificate != null) { HttpsConnectionMiddleware.EnsureCertificateIsAllowedForServerAuth(fallbackCertificate); } sslOptions.ServerCertificate = fallbackCertificate; } if (_onAuthenticateCallback != null) { // From doc comments: "This is called after all of the other settings have already been applied." sslOptions = CloneSslOptions(sslOptions); _onAuthenticateCallback(connection, sslOptions); } return(sslOptions); }