Commit dbbf3a4a authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

nghttpx: Refactor TLS hostname match

parent f25fd09b
......@@ -69,6 +69,8 @@ int main(int argc, char *argv[]) {
shrpx::test_shrpx_ssl_create_lookup_tree) ||
!CU_add_test(pSuite, "ssl_cert_lookup_tree_add_cert_from_file",
shrpx::test_shrpx_ssl_cert_lookup_tree_add_cert_from_file) ||
!CU_add_test(pSuite, "ssl_tls_hostname_match",
shrpx::test_shrpx_ssl_tls_hostname_match) ||
!CU_add_test(pSuite, "http2_add_header", shrpx::test_http2_add_header) ||
!CU_add_test(pSuite, "http2_get_header", shrpx::test_http2_get_header) ||
!CU_add_test(pSuite, "http2_copy_headers_to_nva",
......
This diff is collapsed.
......@@ -108,10 +108,16 @@ void get_altnames(X509 *cert, std::vector<std::string> &dns_names,
// them. If there is a match, its SSL_CTX is returned. If none
// matches, query is continued to the next character.
struct WildcardCert {
SSL_CTX *ssl_ctx;
char *hostname;
size_t hostnamelen;
};
struct CertNode {
// list of wildcard domain name and its SSL_CTX pair, the wildcard
// '*' appears in this position.
std::vector<std::pair<char *, SSL_CTX *>> wildcard_certs;
std::vector<WildcardCert> wildcard_certs;
// Next CertNode index of CertLookupTree::nodes
std::vector<std::unique_ptr<CertNode>> next;
// SSL_CTX for exact match
......@@ -198,6 +204,13 @@ SSL *create_ssl(SSL_CTX *ssl_ctx);
// Returns true if SSL/TLS is enabled on downstream
bool downstream_tls_enabled();
// Performs TLS hostname match. |pattern| of length |plen| can
// contain wildcard character '*', which matches prefix of target
// hostname. There are several restrictions to make wildcard work.
// The matching algorithm is based on RFC 6125.
bool tls_hostname_match(const char *pattern, size_t plen, const char *hostname,
size_t hlen);
} // namespace ssl
} // namespace shrpx
......
......@@ -115,4 +115,37 @@ void test_shrpx_ssl_cert_lookup_tree_add_cert_from_file(void) {
SSL_CTX_free(ssl_ctx);
}
template <size_t N, size_t M>
bool tls_hostname_match_wrapper(const char(&pattern)[N],
const char(&hostname)[M]) {
return ssl::tls_hostname_match(pattern, N, hostname, M);
}
void test_shrpx_ssl_tls_hostname_match(void) {
CU_ASSERT(tls_hostname_match_wrapper("example.com", "example.com"));
CU_ASSERT(tls_hostname_match_wrapper("example.com", "EXAMPLE.com"));
// check wildcard
CU_ASSERT(tls_hostname_match_wrapper("*.example.com", "www.example.com"));
CU_ASSERT(tls_hostname_match_wrapper("*w.example.com", "www.example.com"));
CU_ASSERT(tls_hostname_match_wrapper("www*.example.com", "www1.example.com"));
CU_ASSERT(
tls_hostname_match_wrapper("www*.example.com", "WWW12.EXAMPLE.com"));
// at least 2 dots are required after '*'
CU_ASSERT(!tls_hostname_match_wrapper("*.com", "example.com"));
CU_ASSERT(!tls_hostname_match_wrapper("*", "example.com"));
// '*' must be in left most label
CU_ASSERT(
!tls_hostname_match_wrapper("blog.*.example.com", "blog.my.example.com"));
// prefix is wrong
CU_ASSERT(
!tls_hostname_match_wrapper("client*.example.com", "server.example.com"));
// '*' must match at least one character
CU_ASSERT(!tls_hostname_match_wrapper("www*.example.com", "www.example.com"));
CU_ASSERT(!tls_hostname_match_wrapper("example.com", "nghttp2.org"));
CU_ASSERT(!tls_hostname_match_wrapper("www.example.com", "example.com"));
CU_ASSERT(!tls_hostname_match_wrapper("example.com", "www.example.com"));
}
} // namespace shrpx
......@@ -33,6 +33,7 @@ namespace shrpx {
void test_shrpx_ssl_create_lookup_tree(void);
void test_shrpx_ssl_cert_lookup_tree_add_cert_from_file(void);
void test_shrpx_ssl_tls_hostname_match(void);
} // namespace shrpx
......
......@@ -258,6 +258,15 @@ bool strieq(InputIt1 a, size_t alen, InputIt2 b, size_t blen) {
return std::equal(a, a + alen, b, CaseCmp());
}
template <typename InputIt1, typename InputIt2>
bool strieq(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2) {
if (std::distance(first1, last1) != std::distance(first2, last2)) {
return false;
}
return std::equal(first1, last1, first2, CaseCmp());
}
inline bool strieq(const std::string &a, const std::string &b) {
return strieq(std::begin(a), a.size(), std::begin(b), b.size());
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment