Merge branch 'nghttpx-certs-per-sigalg'

This commit is contained in:
Tatsuhiro Tsujikawa 2017-02-08 23:36:23 +09:00
commit a231874e1e
10 changed files with 181 additions and 83 deletions

View File

@ -72,8 +72,8 @@ int main(int argc, char *argv[]) {
// add the tests to the suite // add the tests to the suite
if (!CU_add_test(pSuite, "ssl_create_lookup_tree", if (!CU_add_test(pSuite, "ssl_create_lookup_tree",
shrpx::test_shrpx_ssl_create_lookup_tree) || shrpx::test_shrpx_ssl_create_lookup_tree) ||
!CU_add_test(pSuite, "ssl_cert_lookup_tree_add_cert_from_x509", !CU_add_test(pSuite, "ssl_cert_lookup_tree_add_ssl_ctx",
shrpx::test_shrpx_ssl_cert_lookup_tree_add_cert_from_x509) || shrpx::test_shrpx_ssl_cert_lookup_tree_add_ssl_ctx) ||
!CU_add_test(pSuite, "ssl_tls_hostname_match", !CU_add_test(pSuite, "ssl_tls_hostname_match",
shrpx::test_shrpx_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_add_header", shrpx::test_http2_add_header) ||

View File

@ -1943,9 +1943,14 @@ SSL/TLS:
--subcert=<KEYPATH>:<CERTPATH>[[;<PARAM>]...] --subcert=<KEYPATH>:<CERTPATH>[[;<PARAM>]...]
Specify additional certificate and private key file. Specify additional certificate and private key file.
nghttpx will choose certificates based on the hostname nghttpx will choose certificates based on the hostname
indicated by client using TLS SNI extension. This indicated by client using TLS SNI extension. If nghttpx
option can be used multiple times. To make OCSP is built with OpenSSL >= 1.0.2, signature algorithms
stapling work, <CERTPATH> must be absolute path. (e.g., ECDSA+SHA256, RSA+SHA256) presented by client are
also taken into consideration. This allows nghttpx to
send ECDSA certificate to modern clients, while sending
RSA based certificate to older clients. This option can
be used multiple times. To make OCSP stapling work,
<CERTPATH> must be absolute path.
Additional parameter can be specified in <PARAM>. The Additional parameter can be specified in <PARAM>. The
available <PARAM> is "sct-dir=<DIR>". available <PARAM> is "sct-dir=<DIR>".

View File

@ -199,12 +199,13 @@ void ConnectionHandler::worker_replace_downstream(
int ConnectionHandler::create_single_worker() { int ConnectionHandler::create_single_worker() {
cert_tree_ = ssl::create_cert_lookup_tree(); cert_tree_ = ssl::create_cert_lookup_tree();
auto sv_ssl_ctx = ssl::setup_server_ssl_context(all_ssl_ctx_, cert_tree_.get() auto sv_ssl_ctx = ssl::setup_server_ssl_context(
all_ssl_ctx_, indexed_ssl_ctx_, cert_tree_.get()
#ifdef HAVE_NEVERBLEED #ifdef HAVE_NEVERBLEED
, ,
nb_.get() nb_.get()
#endif // HAVE_NEVERBLEED #endif // HAVE_NEVERBLEED
); );
auto cl_ssl_ctx = ssl::setup_downstream_client_ssl_context( auto cl_ssl_ctx = ssl::setup_downstream_client_ssl_context(
#ifdef HAVE_NEVERBLEED #ifdef HAVE_NEVERBLEED
nb_.get() nb_.get()
@ -247,12 +248,13 @@ int ConnectionHandler::create_worker_thread(size_t num) {
assert(workers_.size() == 0); assert(workers_.size() == 0);
cert_tree_ = ssl::create_cert_lookup_tree(); cert_tree_ = ssl::create_cert_lookup_tree();
auto sv_ssl_ctx = ssl::setup_server_ssl_context(all_ssl_ctx_, cert_tree_.get() auto sv_ssl_ctx = ssl::setup_server_ssl_context(
all_ssl_ctx_, indexed_ssl_ctx_, cert_tree_.get()
#ifdef HAVE_NEVERBLEED #ifdef HAVE_NEVERBLEED
, ,
nb_.get() nb_.get()
#endif // HAVE_NEVERBLEED #endif // HAVE_NEVERBLEED
); );
auto cl_ssl_ctx = ssl::setup_downstream_client_ssl_context( auto cl_ssl_ctx = ssl::setup_downstream_client_ssl_context(
#ifdef HAVE_NEVERBLEED #ifdef HAVE_NEVERBLEED
nb_.get() nb_.get()
@ -841,4 +843,9 @@ SSL_CTX *ConnectionHandler::get_ssl_ctx(size_t idx) const {
return all_ssl_ctx_[idx]; return all_ssl_ctx_[idx];
} }
const std::vector<SSL_CTX *> &
ConnectionHandler::get_indexed_ssl_ctx(size_t idx) const {
return indexed_ssl_ctx_[idx];
}
} // namespace shrpx } // namespace shrpx

View File

@ -156,6 +156,8 @@ public:
// array bound checking. // array bound checking.
SSL_CTX *get_ssl_ctx(size_t idx) const; SSL_CTX *get_ssl_ctx(size_t idx) const;
const std::vector<SSL_CTX *> &get_indexed_ssl_ctx(size_t idx) const;
#ifdef HAVE_NEVERBLEED #ifdef HAVE_NEVERBLEED
void set_neverbleed(std::unique_ptr<neverbleed_t> nb); void set_neverbleed(std::unique_ptr<neverbleed_t> nb);
neverbleed_t *get_neverbleed() const; neverbleed_t *get_neverbleed() const;
@ -175,6 +177,12 @@ public:
private: private:
// Stores all SSL_CTX objects. // Stores all SSL_CTX objects.
std::vector<SSL_CTX *> all_ssl_ctx_; std::vector<SSL_CTX *> all_ssl_ctx_;
// Stores all SSL_CTX objects in a way that its index is stored in
// cert_tree. The SSL_CTXs stored in the same index share the same
// hostname, but could have different signature algorithm. The
// selection among them are performed by hostname presented by SNI,
// and signature algorithm presented by client.
std::vector<std::vector<SSL_CTX *>> indexed_ssl_ctx_;
OCSPUpdateContext ocsp_; OCSPUpdateContext ocsp_;
std::mt19937 gen_; std::mt19937 gen_;
// ev_loop for each worker // ev_loop for each worker

View File

@ -69,7 +69,7 @@ void Router::add_node(RNode *node, const char *pattern, size_t patlen,
add_next_node(node, std::move(new_node)); add_next_node(node, std::move(new_node));
} }
bool Router::add_route(const StringRef &pattern, size_t index) { size_t Router::add_route(const StringRef &pattern, size_t index) {
auto node = &root_; auto node = &root_;
size_t i = 0; size_t i = 0;
@ -77,7 +77,7 @@ bool Router::add_route(const StringRef &pattern, size_t index) {
auto next_node = find_next_node(node, pattern[i]); auto next_node = find_next_node(node, pattern[i]);
if (next_node == nullptr) { if (next_node == nullptr) {
add_node(node, pattern.c_str() + i, pattern.size() - i, index); add_node(node, pattern.c_str() + i, pattern.size() - i, index);
return true; return index;
} }
node = next_node; node = next_node;
@ -93,11 +93,11 @@ bool Router::add_route(const StringRef &pattern, size_t index) {
if (slen == node->len) { if (slen == node->len) {
// Complete match // Complete match
if (node->index != -1) { if (node->index != -1) {
// Don't allow duplicate // Return the existing index for duplicates.
return false; return node->index;
} }
node->index = index; node->index = index;
return true; return index;
} }
if (slen > node->len) { if (slen > node->len) {
@ -122,7 +122,7 @@ bool Router::add_route(const StringRef &pattern, size_t index) {
if (slen == j) { if (slen == j) {
node->index = index; node->index = index;
return true; return index;
} }
} }
@ -131,7 +131,7 @@ bool Router::add_route(const StringRef &pattern, size_t index) {
assert(pattern.size() > i); assert(pattern.size() > i);
add_node(node, pattern.c_str() + i, pattern.size() - i, index); add_node(node, pattern.c_str() + i, pattern.size() - i, index);
return true; return index;
} }
} }

View File

@ -63,8 +63,9 @@ public:
Router &operator=(Router &&) = default; Router &operator=(Router &&) = default;
Router &operator=(const Router &) = delete; Router &operator=(const Router &) = delete;
// Adds route |pattern| with its |index|. // Adds route |pattern| with its |index|. If same pattern has
bool add_route(const StringRef &pattern, size_t index); // already been added, the existing index is returned.
size_t add_route(const StringRef &pattern, size_t index);
// Returns the matched index of pattern. -1 if there is no match. // Returns the matched index of pattern. -1 if there is no match.
ssize_t match(const StringRef &host, const StringRef &path) const; ssize_t match(const StringRef &host, const StringRef &path) const;
// Returns the matched index of pattern |s|. -1 if there is no // Returns the matched index of pattern |s|. -1 if there is no

View File

@ -183,9 +183,34 @@ int servername_callback(SSL *ssl, int *al, void *arg) {
} }
auto conn_handler = worker->get_connection_handler(); auto conn_handler = worker->get_connection_handler();
auto ssl_ctx = conn_handler->get_ssl_ctx(idx);
SSL_set_SSL_CTX(ssl, ssl_ctx); const auto &ssl_ctx_list = conn_handler->get_indexed_ssl_ctx(idx);
assert(!ssl_ctx_list.empty());
#if !defined(OPENSSL_IS_BORINGSSL) && !defined(LIBRESSL_VERSION_NUMBER) && \
OPENSSL_VERSION_NUMBER >= 0x10002000L
// boringssl removed SSL_get_sigalgs.
auto num_sigalg =
SSL_get_sigalgs(ssl, 0, nullptr, nullptr, nullptr, nullptr, nullptr);
for (auto i = 0; i < num_sigalg; ++i) {
int sigalg;
SSL_get_sigalgs(ssl, i, nullptr, nullptr, &sigalg, nullptr, nullptr);
for (auto ssl_ctx : ssl_ctx_list) {
auto cert = SSL_CTX_get0_certificate(ssl_ctx);
// X509_get_signature_nid is available since OpenSSL 1.0.2.
auto cert_sigalg = X509_get_signature_nid(cert);
if (sigalg == cert_sigalg) {
SSL_set_SSL_CTX(ssl, ssl_ctx);
return SSL_TLSEXT_ERR_OK;
}
}
}
#endif // !defined(OPENSSL_IS_BORINGSSL) && !defined(LIBRESSL_VERSION_NUMBER) &&
// OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_set_SSL_CTX(ssl, ssl_ctx_list[0]);
return SSL_TLSEXT_ERR_OK; return SSL_TLSEXT_ERR_OK;
} }
@ -1239,12 +1264,12 @@ int check_cert(SSL *ssl, const DownstreamAddr *addr, const Address *raddr) {
CertLookupTree::CertLookupTree() {} CertLookupTree::CertLookupTree() {}
void CertLookupTree::add_cert(const StringRef &hostname, size_t idx) { ssize_t CertLookupTree::add_cert(const StringRef &hostname, size_t idx) {
std::array<uint8_t, NI_MAXHOST> buf; std::array<uint8_t, NI_MAXHOST> buf;
// NI_MAXHOST includes terminal NULL byte // NI_MAXHOST includes terminal NULL byte
if (hostname.empty() || hostname.size() + 1 > buf.size()) { if (hostname.empty() || hostname.size() + 1 > buf.size()) {
return; return -1;
} }
auto wildcard_it = std::find(std::begin(hostname), std::end(hostname), '*'); auto wildcard_it = std::find(std::begin(hostname), std::end(hostname), '*');
@ -1260,8 +1285,8 @@ void CertLookupTree::add_cert(const StringRef &hostname, size_t idx) {
WildcardPattern *wpat; WildcardPattern *wpat;
if (!rev_wildcard_router_.add_route(rev_suffix, if (wildcard_patterns_.size() !=
wildcard_patterns_.size())) { rev_wildcard_router_.add_route(rev_suffix, wildcard_patterns_.size())) {
auto wcidx = rev_wildcard_router_.match(rev_suffix); auto wcidx = rev_wildcard_router_.match(rev_suffix);
assert(wcidx != -1); assert(wcidx != -1);
@ -1277,12 +1302,18 @@ void CertLookupTree::add_cert(const StringRef &hostname, size_t idx) {
std::end(wildcard_prefix), std::end(wildcard_prefix),
std::begin(buf))}; std::begin(buf))};
for (auto &p : wpat->rev_prefix) {
if (p.prefix == rev_prefix) {
return p.idx;
}
}
wpat->rev_prefix.emplace_back(rev_prefix, idx); wpat->rev_prefix.emplace_back(rev_prefix, idx);
return; return idx;
} }
router_.add_route(hostname, idx); return router_.add_route(hostname, idx);
} }
ssize_t CertLookupTree::lookup(const StringRef &hostname) { ssize_t CertLookupTree::lookup(const StringRef &hostname) {
@ -1357,10 +1388,24 @@ void CertLookupTree::dump() const {
rev_wildcard_router_.dump(); rev_wildcard_router_.dump();
} }
int cert_lookup_tree_add_cert_from_x509(CertLookupTree *lt, size_t idx, int cert_lookup_tree_add_ssl_ctx(
X509 *cert) { CertLookupTree *lt, std::vector<std::vector<SSL_CTX *>> &indexed_ssl_ctx,
SSL_CTX *ssl_ctx) {
std::array<uint8_t, NI_MAXHOST> buf; std::array<uint8_t, NI_MAXHOST> buf;
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10002000L
auto cert = SSL_CTX_get0_certificate(ssl_ctx);
#else // defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER <
// 0x10002000L
auto tls_ctx_data =
static_cast<TLSContextData *>(SSL_CTX_get_app_data(ssl_ctx));
auto cert = load_certificate(tls_ctx_data->cert_file);
auto cert_deleter = defer(X509_free, cert);
#endif // defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER <
// 0x10002000L
auto idx = indexed_ssl_ctx.size();
auto altnames = static_cast<GENERAL_NAMES *>( auto altnames = static_cast<GENERAL_NAMES *>(
X509_get_ext_d2i(cert, NID_subject_alt_name, nullptr, nullptr)); X509_get_ext_d2i(cert, NID_subject_alt_name, nullptr, nullptr));
if (altnames) { if (altnames) {
@ -1403,7 +1448,17 @@ int cert_lookup_tree_add_cert_from_x509(CertLookupTree *lt, size_t idx,
auto end_buf = std::copy_n(name, len, std::begin(buf)); auto end_buf = std::copy_n(name, len, std::begin(buf));
util::inp_strlower(std::begin(buf), end_buf); util::inp_strlower(std::begin(buf), end_buf);
lt->add_cert(StringRef{std::begin(buf), end_buf}, idx); auto nidx = lt->add_cert(StringRef{std::begin(buf), end_buf}, idx);
if (nidx == -1) {
continue;
}
idx = nidx;
if (idx < indexed_ssl_ctx.size()) {
indexed_ssl_ctx[idx].push_back(ssl_ctx);
} else {
assert(idx == indexed_ssl_ctx.size());
indexed_ssl_ctx.emplace_back(std::vector<SSL_CTX *>{ssl_ctx});
}
} }
// Don't bother CN if we have dNSName. // Don't bother CN if we have dNSName.
@ -1433,7 +1488,17 @@ int cert_lookup_tree_add_cert_from_x509(CertLookupTree *lt, size_t idx,
util::inp_strlower(std::begin(buf), end_buf); util::inp_strlower(std::begin(buf), end_buf);
lt->add_cert(StringRef{std::begin(buf), end_buf}, idx); auto nidx = lt->add_cert(StringRef{std::begin(buf), end_buf}, idx);
if (nidx == -1) {
return 0;
}
idx = nidx;
if (idx < indexed_ssl_ctx.size()) {
indexed_ssl_ctx[idx].push_back(ssl_ctx);
} else {
assert(idx == indexed_ssl_ctx.size());
indexed_ssl_ctx.emplace_back(std::vector<SSL_CTX *>{ssl_ctx});
}
return 0; return 0;
} }
@ -1474,13 +1539,15 @@ X509 *load_certificate(const char *filename) {
return cert; return cert;
} }
SSL_CTX *setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx, SSL_CTX *
CertLookupTree *cert_tree setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
std::vector<std::vector<SSL_CTX *>> &indexed_ssl_ctx,
CertLookupTree *cert_tree
#ifdef HAVE_NEVERBLEED #ifdef HAVE_NEVERBLEED
, ,
neverbleed_t *nb neverbleed_t *nb
#endif // HAVE_NEVERBLEED #endif // HAVE_NEVERBLEED
) { ) {
if (!upstream_tls_enabled()) { if (!upstream_tls_enabled()) {
return nullptr; return nullptr;
} }
@ -1508,17 +1575,8 @@ SSL_CTX *setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
return ssl_ctx; return ssl_ctx;
} }
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10002000L if (ssl::cert_lookup_tree_add_ssl_ctx(cert_tree, indexed_ssl_ctx, ssl_ctx) ==
auto cert = SSL_CTX_get0_certificate(ssl_ctx); -1) {
#else // defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER <
// 0x10002000L
auto cert = load_certificate(tlsconf.cert_file.c_str());
auto cert_deleter = defer(X509_free, cert);
#endif // defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER <
// 0x10002000L
if (ssl::cert_lookup_tree_add_cert_from_x509(
cert_tree, all_ssl_ctx.size() - 1, cert) == -1) {
LOG(FATAL) << "Failed to add default certificate."; LOG(FATAL) << "Failed to add default certificate.";
DIE(); DIE();
} }
@ -1533,17 +1591,8 @@ SSL_CTX *setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
); );
all_ssl_ctx.push_back(ssl_ctx); all_ssl_ctx.push_back(ssl_ctx);
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10002000L if (ssl::cert_lookup_tree_add_ssl_ctx(cert_tree, indexed_ssl_ctx,
auto cert = SSL_CTX_get0_certificate(ssl_ctx); ssl_ctx) == -1) {
#else // defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER <
// 0x10002000L
auto cert = load_certificate(c.cert_file.c_str());
auto cert_deleter = defer(X509_free, cert);
#endif // defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER <
// 0x10002000L
if (ssl::cert_lookup_tree_add_cert_from_x509(
cert_tree, all_ssl_ctx.size() - 1, cert) == -1) {
LOG(FATAL) << "Failed to add sub certificate."; LOG(FATAL) << "Failed to add sub certificate.";
DIE(); DIE();
} }

View File

@ -136,13 +136,20 @@ public:
// |index| is returned. We support wildcard pattern. The left most // |index| is returned. We support wildcard pattern. The left most
// '*' is considered as wildcard character, and it must match at // '*' is considered as wildcard character, and it must match at
// least one character. If the same pattern has been already added, // least one character. If the same pattern has been already added,
// this function is noop. // this function does not alter the tree, and returns the existing
// matching index.
// //
// The caller should lower-case |hostname| since this function does // The caller should lower-case |hostname| since this function does
// do that, and lookup function performs case-sensitive match. // do that, and lookup function performs case-sensitive match.
// //
// TODO Treat wildcard pattern described as RFC 6125. // TODO Treat wildcard pattern described as RFC 6125.
void add_cert(const StringRef &hostname, size_t index); //
// This function returns the index. It returns -1 if it fails
// (e.g., hostname is too long). If the returned index equals to
// |index|, then hostname is added to the tree with the value
// |index|. If it is not -1, and does not equal to |index|, same
// hostname has already been added to the tree.
ssize_t add_cert(const StringRef &hostname, size_t index);
// Looks up index using the given |hostname|. The exact match takes // Looks up index using the given |hostname|. The exact match takes
// precedence over wildcard match. For wildcard match, longest // precedence over wildcard match. For wildcard match, longest
@ -166,12 +173,14 @@ private:
std::vector<WildcardPattern> wildcard_patterns_; std::vector<WildcardPattern> wildcard_patterns_;
}; };
// Adds hostnames in |cert| to lookup tree |lt|. The subjectAltNames // Adds hostnames in certificate in |ssl_ctx| to lookup tree |lt|.
// and commonName are considered as eligible hostname. If there is at // The subjectAltNames and commonName are considered as eligible
// least one dNSName in subjectAltNames, commonName is not considered. // hostname. If there is at least one dNSName in subjectAltNames,
// This function returns 0 if it succeeds, or -1. // commonName is not considered. |ssl_ctx| is also added to
int cert_lookup_tree_add_cert_from_x509(CertLookupTree *lt, size_t idx, // |indexed_ssl_ctx|. This function returns 0 if it succeeds, or -1.
X509 *cert); int cert_lookup_tree_add_ssl_ctx(
CertLookupTree *lt, std::vector<std::vector<SSL_CTX *>> &indexed_ssl_ctx,
SSL_CTX *ssl_ctx);
// Returns true if |proto| is included in the // Returns true if |proto| is included in the
// protocol list |protos|. // protocol list |protos|.
@ -194,14 +203,18 @@ int set_alpn_prefs(std::vector<unsigned char> &out,
// construct default SSL_CTX. If subcerts are available // construct default SSL_CTX. If subcerts are available
// (get_config()->subcerts), caller should provide CertLookupTree // (get_config()->subcerts), caller should provide CertLookupTree
// object as |cert_tree| parameter, otherwise SNI does not work. All // object as |cert_tree| parameter, otherwise SNI does not work. All
// the created SSL_CTX is stored into |all_ssl_ctx|. // the created SSL_CTX is stored into |all_ssl_ctx|. They are also
SSL_CTX *setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx, // added to |indexed_ssl_ctx|. |cert_tree| uses its index to
CertLookupTree *cert_tree // associate hostname to the SSL_CTX.
SSL_CTX *
setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
std::vector<std::vector<SSL_CTX *>> &indexed_ssl_ctx,
CertLookupTree *cert_tree
#ifdef HAVE_NEVERBLEED #ifdef HAVE_NEVERBLEED
, ,
neverbleed_t *nb neverbleed_t *nb
#endif // HAVE_NEVERBLEED #endif // HAVE_NEVERBLEED
); );
// Setups client side SSL_CTX. // Setups client side SSL_CTX.
SSL_CTX *setup_downstream_client_ssl_context( SSL_CTX *setup_downstream_client_ssl_context(

View File

@ -115,24 +115,39 @@ void test_shrpx_ssl_create_lookup_tree(void) {
// -config=ca-config.json -profile=server test.example.com.csr | // -config=ca-config.json -profile=server test.example.com.csr |
// cfssljson -bare test.example.com // cfssljson -bare test.example.com
// //
void test_shrpx_ssl_cert_lookup_tree_add_cert_from_x509(void) { void test_shrpx_ssl_cert_lookup_tree_add_ssl_ctx(void) {
int rv; int rv;
constexpr char nghttp2_certfile[] = NGHTTP2_SRC_DIR "/test.nghttp2.org.pem"; constexpr char nghttp2_certfile[] = NGHTTP2_SRC_DIR "/test.nghttp2.org.pem";
auto nghttp2_cert = ssl::load_certificate(nghttp2_certfile); auto nghttp2_ssl_ctx = SSL_CTX_new(SSLv23_server_method());
auto nghttp2_cert_deleter = defer(X509_free, nghttp2_cert); auto nghttp2_ssl_ctx_del = defer(SSL_CTX_free, nghttp2_ssl_ctx);
auto nghttp2_tls_ctx_data = make_unique<ssl::TLSContextData>();
nghttp2_tls_ctx_data->cert_file = nghttp2_certfile;
SSL_CTX_set_app_data(nghttp2_ssl_ctx, nghttp2_tls_ctx_data.get());
rv = SSL_CTX_use_certificate_chain_file(nghttp2_ssl_ctx, nghttp2_certfile);
CU_ASSERT(1 == rv);
constexpr char examples_certfile[] = NGHTTP2_SRC_DIR "/test.example.com.pem"; constexpr char examples_certfile[] = NGHTTP2_SRC_DIR "/test.example.com.pem";
auto examples_cert = ssl::load_certificate(examples_certfile); auto examples_ssl_ctx = SSL_CTX_new(SSLv23_server_method());
auto examples_cert_deleter = defer(X509_free, examples_cert); auto examples_ssl_ctx_del = defer(SSL_CTX_free, examples_ssl_ctx);
auto examples_tls_ctx_data = make_unique<ssl::TLSContextData>();
examples_tls_ctx_data->cert_file = examples_certfile;
SSL_CTX_set_app_data(examples_ssl_ctx, examples_tls_ctx_data.get());
rv = SSL_CTX_use_certificate_chain_file(examples_ssl_ctx, examples_certfile);
CU_ASSERT(1 == rv);
ssl::CertLookupTree tree; ssl::CertLookupTree tree;
std::vector<std::vector<SSL_CTX *>> indexed_ssl_ctx;
rv = ssl::cert_lookup_tree_add_cert_from_x509(&tree, 0, nghttp2_cert); rv = ssl::cert_lookup_tree_add_ssl_ctx(&tree, indexed_ssl_ctx,
nghttp2_ssl_ctx);
CU_ASSERT(0 == rv); CU_ASSERT(0 == rv);
rv = ssl::cert_lookup_tree_add_cert_from_x509(&tree, 1, examples_cert); rv = ssl::cert_lookup_tree_add_ssl_ctx(&tree, indexed_ssl_ctx,
examples_ssl_ctx);
CU_ASSERT(0 == rv); CU_ASSERT(0 == rv);

View File

@ -32,7 +32,7 @@
namespace shrpx { namespace shrpx {
void test_shrpx_ssl_create_lookup_tree(void); void test_shrpx_ssl_create_lookup_tree(void);
void test_shrpx_ssl_cert_lookup_tree_add_cert_from_x509(void); void test_shrpx_ssl_cert_lookup_tree_add_ssl_ctx(void);
void test_shrpx_ssl_tls_hostname_match(void); void test_shrpx_ssl_tls_hostname_match(void);
} // namespace shrpx } // namespace shrpx