public void WildcardOnlyMatchesNullServerNameDueToNoAlpn() { var sniDictionary = new Dictionary <string, SniConfig> { { "*", new SniConfig { Certificate = new CertificateConfig { Path = "WildcardOnly" } } } }; var mockCertificateConfigLoader = new MockCertificateConfigLoader(); var pathDictionary = mockCertificateConfigLoader.CertToPathDictionary; var sniOptionsSelector = new SniOptionsSelector( "TestEndpointName", sniDictionary, mockCertificateConfigLoader, fallbackHttpsOptions: new HttpsConnectionAdapterOptions(), fallbackHttpProtocols: HttpProtocols.Http1AndHttp2, logger: Mock.Of <ILogger <HttpsConnectionMiddleware> >()); var(options, _) = sniOptionsSelector.GetOptions(new MockConnectionContext(), null); Assert.Equal("WildcardOnly", pathDictionary[options.ServerCertificate]); }
public void ServerNameMatchingIsCaseInsensitive() { var sniDictionary = new Dictionary <string, SniConfig> { { "Www.Example.Org", new SniConfig { Certificate = new CertificateConfig { Path = "Exact" } } }, { "*.Example.Org", new SniConfig { Certificate = new CertificateConfig { Path = "WildcardPrefix" } } } }; var mockCertificateConfigLoader = new MockCertificateConfigLoader(); var pathDictionary = mockCertificateConfigLoader.CertToPathDictionary; var sniOptionsSelector = new SniOptionsSelector( "TestEndpointName", sniDictionary, mockCertificateConfigLoader, fallbackHttpsOptions: new HttpsConnectionAdapterOptions(), fallbackHttpProtocols: HttpProtocols.Http1AndHttp2, logger: Mock.Of <ILogger <HttpsConnectionMiddleware> >()); var wwwSubdomainOptions = sniOptionsSelector.GetOptions(new MockConnectionContext(), "wWw.eXample.oRg"); Assert.Equal("Exact", pathDictionary[wwwSubdomainOptions.ServerCertificate]); var baSubdomainOptions = sniOptionsSelector.GetOptions(new MockConnectionContext(), "B.a.eXample.oRg"); Assert.Equal("WildcardPrefix", pathDictionary[baSubdomainOptions.ServerCertificate]); var aSubdomainOptions = sniOptionsSelector.GetOptions(new MockConnectionContext(), "A.eXample.oRg"); Assert.Equal("WildcardPrefix", pathDictionary[aSubdomainOptions.ServerCertificate]); }
public void PerfersLongerWildcardPrefixOverShorterWildcardPrefix() { var sniDictionary = new Dictionary <string, SniConfig> { { "*.a.example.org", new SniConfig { Certificate = new CertificateConfig { Path = "Long" } } }, { "*.example.org", new SniConfig { Certificate = new CertificateConfig { Path = "Short" } } } }; var mockCertificateConfigLoader = new MockCertificateConfigLoader(); var pathDictionary = mockCertificateConfigLoader.CertToPathDictionary; var sniOptionsSelector = new SniOptionsSelector( "TestEndpointName", sniDictionary, mockCertificateConfigLoader, fallbackHttpsOptions: new HttpsConnectionAdapterOptions(), fallbackHttpProtocols: HttpProtocols.Http1AndHttp2, logger: Mock.Of <ILogger <HttpsConnectionMiddleware> >()); var baSubdomainOptions = sniOptionsSelector.GetOptions(new MockConnectionContext(), "b.a.example.org"); Assert.Equal("Long", pathDictionary[baSubdomainOptions.ServerCertificate]); // "*.a.example.org" is preferred over "*.example.org", but "a.example.org" doesn't match "*.a.example.org". var aSubdomainOptions = sniOptionsSelector.GetOptions(new MockConnectionContext(), "a.example.org"); Assert.Equal("Short", pathDictionary[aSubdomainOptions.ServerCertificate]); }
public void MultipleWildcardPrefixServerNamesOfSameLengthAreAllowed() { var sniDictionary = new Dictionary <string, SniConfig> { { "*.a.example.org", new SniConfig { Certificate = new CertificateConfig { Path = "a" } } }, { "*.b.example.org", new SniConfig { Certificate = new CertificateConfig { Path = "b" } } } }; var mockCertificateConfigLoader = new MockCertificateConfigLoader(); var pathDictionary = mockCertificateConfigLoader.CertToPathDictionary; var sniOptionsSelector = new SniOptionsSelector( "TestEndpointName", sniDictionary, mockCertificateConfigLoader, fallbackHttpsOptions: new HttpsConnectionAdapterOptions(), fallbackHttpProtocols: HttpProtocols.Http1AndHttp2, logger: Mock.Of <ILogger <HttpsConnectionMiddleware> >()); var(aSubdomainOptions, _) = sniOptionsSelector.GetOptions(new MockConnectionContext(), "c.a.example.org"); Assert.Equal("a", pathDictionary[aSubdomainOptions.ServerCertificate]); var(bSubdomainOptions, _) = sniOptionsSelector.GetOptions(new MockConnectionContext(), "c.b.example.org"); Assert.Equal("b", pathDictionary[bSubdomainOptions.ServerCertificate]); }
public void DuplicateWildcardPrefixServerNamesThrowsArgumentException() { var sniDictionary = new Dictionary <string, SniConfig> { { "*.example.org", new SniConfig { Certificate = new CertificateConfig { Path = "a" } } }, { "*.EXAMPLE.org", new SniConfig { Certificate = new CertificateConfig { Path = "b" } } } }; var mockCertificateConfigLoader = new MockCertificateConfigLoader(); var pathDictionary = mockCertificateConfigLoader.CertToPathDictionary; var exception = Assert.Throws <ArgumentException>(() => new SniOptionsSelector( "TestEndpointName", sniDictionary, mockCertificateConfigLoader, fallbackHttpsOptions: new HttpsConnectionAdapterOptions(), fallbackHttpProtocols: HttpProtocols.Http1AndHttp2, logger: Mock.Of <ILogger <HttpsConnectionMiddleware> >())); Assert.Equal("An item with the same key has already been added. Key: .EXAMPLE.org (Parameter 'key')", exception.Message); }
public void PrefersExactMatchOverWildcardPrefixOverWildcardOnly() { var sniDictionary = new Dictionary <string, SniConfig> { { "www.example.org", new SniConfig { Certificate = new CertificateConfig { Path = "Exact" } } }, { "*.example.org", new SniConfig { Certificate = new CertificateConfig { Path = "WildcardPrefix" } } }, { "*", new SniConfig { Certificate = new CertificateConfig { Path = "WildcardOnly" } } } }; var mockCertificateConfigLoader = new MockCertificateConfigLoader(); var pathDictionary = mockCertificateConfigLoader.CertToPathDictionary; var sniOptionsSelector = new SniOptionsSelector( "TestEndpointName", sniDictionary, mockCertificateConfigLoader, fallbackHttpsOptions: new HttpsConnectionAdapterOptions(), fallbackHttpProtocols: HttpProtocols.Http1AndHttp2, logger: Mock.Of <ILogger <HttpsConnectionMiddleware> >()); var(wwwSubdomainOptions, _) = sniOptionsSelector.GetOptions(new MockConnectionContext(), "www.example.org"); Assert.Equal("Exact", pathDictionary[wwwSubdomainOptions.ServerCertificate]); var(baSubdomainOptions, _) = sniOptionsSelector.GetOptions(new MockConnectionContext(), "b.a.example.org"); Assert.Equal("WildcardPrefix", pathDictionary[baSubdomainOptions.ServerCertificate]); var(aSubdomainOptions, _) = sniOptionsSelector.GetOptions(new MockConnectionContext(), "a.example.org"); Assert.Equal("WildcardPrefix", pathDictionary[aSubdomainOptions.ServerCertificate]); // "*.example.org" is preferred over "*", but "*.example.org" doesn't match "example.org". // REVIEW: Are we OK with "example.org" matching "*" instead of "*.example.org"? It feels annoying to me to have to configure example.org twice. // Unfortunately, the alternative would have "a.example.org" match "*.a.example.org" before "*.example.org", and that just seems wrong. var(noSubdomainOptions, _) = sniOptionsSelector.GetOptions(new MockConnectionContext(), "example.org"); Assert.Equal("WildcardOnly", pathDictionary[noSubdomainOptions.ServerCertificate]); var(anotherTldOptions, _) = sniOptionsSelector.GetOptions(new MockConnectionContext(), "dot.net"); Assert.Equal("WildcardOnly", pathDictionary[anotherTldOptions.ServerCertificate]); }
public void FullChainCertsCanBeLoaded() { var sniDictionary = new Dictionary <string, SniConfig> { { "Www.Example.Org", new SniConfig { Certificate = new CertificateConfig { Path = "Exact" } } }, { "*.Example.Org", new SniConfig { Certificate = new CertificateConfig { Path = "WildcardPrefix" } } } }; var mockCertificateConfigLoader = new MockCertificateConfigLoader(); var pathDictionary = mockCertificateConfigLoader.CertToPathDictionary; var fullChainDictionary = mockCertificateConfigLoader.CertToFullChain; var sniOptionsSelector = new SniOptionsSelector( "TestEndpointName", sniDictionary, mockCertificateConfigLoader, fallbackHttpsOptions: new HttpsConnectionAdapterOptions(), fallbackHttpProtocols: HttpProtocols.Http1AndHttp2, logger: Mock.Of <ILogger <HttpsConnectionMiddleware> >()); var(wwwSubdomainOptions, _) = sniOptionsSelector.GetOptions(new MockConnectionContext(), "wWw.eXample.oRg"); Assert.Equal("Exact", pathDictionary[wwwSubdomainOptions.ServerCertificate]); var(baSubdomainOptions, _) = sniOptionsSelector.GetOptions(new MockConnectionContext(), "B.a.eXample.oRg"); Assert.Equal("WildcardPrefix", pathDictionary[baSubdomainOptions.ServerCertificate]); var(aSubdomainOptions, _) = sniOptionsSelector.GetOptions(new MockConnectionContext(), "A.eXample.oRg"); Assert.Equal("WildcardPrefix", pathDictionary[aSubdomainOptions.ServerCertificate]); /* * Chain test certs were created using smallstep cli: https://github.com/smallstep/cli * root_ca(pwd: testroot) -> * intermediate_ca 1(pwd: inter) -> * intermediate_ca 2(pwd: inter) -> * leaf.com(pwd: leaf) (bundled) */ var fullChain = fullChainDictionary[aSubdomainOptions.ServerCertificate]; // Expect intermediate 2 cert and leaf.com Assert.Equal(2, fullChain.Count); Assert.Equal("CN=leaf.com", fullChain[0].Subject); Assert.Equal("CN=Test Intermediate CA 2", fullChain[0].IssuerName.Name); Assert.Equal("CN=Test Intermediate CA 2", fullChain[1].Subject); Assert.Equal("CN=Test Intermediate CA 1", fullChain[1].IssuerName.Name); }