Commit c2de0057 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

nghttpx: Create QUIC SSL_CTX

We choose an easier route to duplicate SSL_CTX for QUIC.
parent 81089e7e
...@@ -156,6 +156,17 @@ ConnectionHandler::~ConnectionHandler() { ...@@ -156,6 +156,17 @@ ConnectionHandler::~ConnectionHandler() {
ev_timer_stop(loop_, &ocsp_timer_); ev_timer_stop(loop_, &ocsp_timer_);
ev_timer_stop(loop_, &disable_acceptor_timer_); ev_timer_stop(loop_, &disable_acceptor_timer_);
for (auto ssl_ctx : quic_all_ssl_ctx_) {
if (ssl_ctx == nullptr) {
continue;
}
auto tls_ctx_data =
static_cast<tls::TLSContextData *>(SSL_CTX_get_app_data(ssl_ctx));
delete tls_ctx_data;
SSL_CTX_free(ssl_ctx);
}
for (auto ssl_ctx : all_ssl_ctx_) { for (auto ssl_ctx : all_ssl_ctx_) {
auto tls_ctx_data = auto tls_ctx_data =
static_cast<tls::TLSContextData *>(SSL_CTX_get_app_data(ssl_ctx)); static_cast<tls::TLSContextData *>(SSL_CTX_get_app_data(ssl_ctx));
...@@ -209,6 +220,16 @@ int ConnectionHandler::create_single_worker() { ...@@ -209,6 +220,16 @@ int ConnectionHandler::create_single_worker() {
nb_ nb_
#endif // HAVE_NEVERBLEED #endif // HAVE_NEVERBLEED
); );
quic_cert_tree_ = tls::create_cert_lookup_tree();
tls::setup_quic_server_ssl_context(quic_all_ssl_ctx_, quic_indexed_ssl_ctx_,
quic_cert_tree_.get()
#ifdef HAVE_NEVERBLEED
,
nb_
#endif // HAVE_NEVERBLEED
);
auto cl_ssl_ctx = tls::setup_downstream_client_ssl_context( auto cl_ssl_ctx = tls::setup_downstream_client_ssl_context(
#ifdef HAVE_NEVERBLEED #ifdef HAVE_NEVERBLEED
nb_ nb_
...@@ -217,6 +238,7 @@ int ConnectionHandler::create_single_worker() { ...@@ -217,6 +238,7 @@ int ConnectionHandler::create_single_worker() {
if (cl_ssl_ctx) { if (cl_ssl_ctx) {
all_ssl_ctx_.push_back(cl_ssl_ctx); all_ssl_ctx_.push_back(cl_ssl_ctx);
quic_all_ssl_ctx_.push_back(nullptr);
} }
auto config = get_config(); auto config = get_config();
...@@ -233,6 +255,7 @@ int ConnectionHandler::create_single_worker() { ...@@ -233,6 +255,7 @@ int ConnectionHandler::create_single_worker() {
tlsconf.cacert, memcachedconf.cert_file, tlsconf.cacert, memcachedconf.cert_file,
memcachedconf.private_key_file, nullptr); memcachedconf.private_key_file, nullptr);
all_ssl_ctx_.push_back(session_cache_ssl_ctx); all_ssl_ctx_.push_back(session_cache_ssl_ctx);
quic_all_ssl_ctx_.push_back(nullptr);
} }
} }
...@@ -263,6 +286,16 @@ int ConnectionHandler::create_worker_thread(size_t num) { ...@@ -263,6 +286,16 @@ int ConnectionHandler::create_worker_thread(size_t num) {
nb_ nb_
# endif // HAVE_NEVERBLEED # endif // HAVE_NEVERBLEED
); );
quic_cert_tree_ = tls::create_cert_lookup_tree();
tls::setup_quic_server_ssl_context(quic_all_ssl_ctx_, quic_indexed_ssl_ctx_,
quic_cert_tree_.get()
# ifdef HAVE_NEVERBLEED
,
nb_
# endif // HAVE_NEVERBLEED
);
auto cl_ssl_ctx = tls::setup_downstream_client_ssl_context( auto cl_ssl_ctx = tls::setup_downstream_client_ssl_context(
# ifdef HAVE_NEVERBLEED # ifdef HAVE_NEVERBLEED
nb_ nb_
...@@ -271,6 +304,7 @@ int ConnectionHandler::create_worker_thread(size_t num) { ...@@ -271,6 +304,7 @@ int ConnectionHandler::create_worker_thread(size_t num) {
if (cl_ssl_ctx) { if (cl_ssl_ctx) {
all_ssl_ctx_.push_back(cl_ssl_ctx); all_ssl_ctx_.push_back(cl_ssl_ctx);
quic_all_ssl_ctx_.push_back(nullptr);
} }
auto config = get_config(); auto config = get_config();
...@@ -294,6 +328,7 @@ int ConnectionHandler::create_worker_thread(size_t num) { ...@@ -294,6 +328,7 @@ int ConnectionHandler::create_worker_thread(size_t num) {
tlsconf.cacert, memcachedconf.cert_file, tlsconf.cacert, memcachedconf.cert_file,
memcachedconf.private_key_file, nullptr); memcachedconf.private_key_file, nullptr);
all_ssl_ctx_.push_back(session_cache_ssl_ctx); all_ssl_ctx_.push_back(session_cache_ssl_ctx);
quic_all_ssl_ctx_.push_back(nullptr);
} }
} }
...@@ -608,6 +643,7 @@ void ConnectionHandler::handle_ocsp_complete() { ...@@ -608,6 +643,7 @@ void ConnectionHandler::handle_ocsp_complete() {
ev_child_stop(loop_, &ocsp_.chldev); ev_child_stop(loop_, &ocsp_.chldev);
assert(ocsp_.next < all_ssl_ctx_.size()); assert(ocsp_.next < all_ssl_ctx_.size());
assert(all_ssl_ctx_.size() == quic_all_ssl_ctx_.size());
auto ssl_ctx = all_ssl_ctx_[ocsp_.next]; auto ssl_ctx = all_ssl_ctx_[ocsp_.next];
auto tls_ctx_data = auto tls_ctx_data =
...@@ -635,6 +671,29 @@ void ConnectionHandler::handle_ocsp_complete() { ...@@ -635,6 +671,29 @@ void ConnectionHandler::handle_ocsp_complete() {
if (tlsconf.ocsp.no_verify || if (tlsconf.ocsp.no_verify ||
tls::verify_ocsp_response(ssl_ctx, ocsp_.resp.data(), tls::verify_ocsp_response(ssl_ctx, ocsp_.resp.data(),
ocsp_.resp.size()) == 0) { ocsp_.resp.size()) == 0) {
// We have list of SSL_CTX with the same certificate in
// quic_all_ssl_ctx_ as well. Some SSL_CTXs are missing there in
// that case we get nullptr.
auto quic_ssl_ctx = quic_all_ssl_ctx_[ocsp_.next];
if (quic_ssl_ctx) {
auto quic_tls_ctx_data = static_cast<tls::TLSContextData *>(
SSL_CTX_get_app_data(quic_ssl_ctx));
#ifndef OPENSSL_IS_BORINGSSL
# ifdef HAVE_ATOMIC_STD_SHARED_PTR
std::atomic_store_explicit(
&quic_tls_ctx_data->ocsp_data,
std::make_shared<std::vector<uint8_t>>(ocsp_.resp),
std::memory_order_release);
# else // !HAVE_ATOMIC_STD_SHARED_PTR
std::lock_guard<std::mutex> g(quic_tls_ctx_data->mu);
quic_tls_ctx_data->ocsp_data =
std::make_shared<std::vector<uint8_t>>(ocsp_.resp);
# endif // !HAVE_ATOMIC_STD_SHARED_PTR
#else // OPENSSL_IS_BORINGSSL
SSL_CTX_set_ocsp_response(ssl_ctx, ocsp_.resp.data(), ocsp_.resp.size());
#endif // OPENSSL_IS_BORINGSSL
}
#ifndef OPENSSL_IS_BORINGSSL #ifndef OPENSSL_IS_BORINGSSL
# ifdef HAVE_ATOMIC_STD_SHARED_PTR # ifdef HAVE_ATOMIC_STD_SHARED_PTR
std::atomic_store_explicit( std::atomic_store_explicit(
...@@ -815,6 +874,7 @@ SSL_CTX *ConnectionHandler::create_tls_ticket_key_memcached_ssl_ctx() { ...@@ -815,6 +874,7 @@ SSL_CTX *ConnectionHandler::create_tls_ticket_key_memcached_ssl_ctx() {
nullptr); nullptr);
all_ssl_ctx_.push_back(ssl_ctx); all_ssl_ctx_.push_back(ssl_ctx);
quic_all_ssl_ctx_.push_back(nullptr);
return ssl_ctx; return ssl_ctx;
} }
...@@ -877,6 +937,11 @@ ConnectionHandler::get_indexed_ssl_ctx(size_t idx) const { ...@@ -877,6 +937,11 @@ ConnectionHandler::get_indexed_ssl_ctx(size_t idx) const {
return indexed_ssl_ctx_[idx]; return indexed_ssl_ctx_[idx];
} }
const std::vector<SSL_CTX *> &
ConnectionHandler::get_quic_indexed_ssl_ctx(size_t idx) const {
return quic_indexed_ssl_ctx_[idx];
}
void ConnectionHandler::set_enable_acceptor_on_ocsp_completion(bool f) { void ConnectionHandler::set_enable_acceptor_on_ocsp_completion(bool f) {
enable_acceptor_on_ocsp_completion_ = f; enable_acceptor_on_ocsp_completion_ = f;
} }
......
...@@ -159,6 +159,7 @@ public: ...@@ -159,6 +159,7 @@ public:
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; const std::vector<SSL_CTX *> &get_indexed_ssl_ctx(size_t idx) const;
const std::vector<SSL_CTX *> &get_quic_indexed_ssl_ctx(size_t idx) const;
#ifdef HAVE_NEVERBLEED #ifdef HAVE_NEVERBLEED
void set_neverbleed(neverbleed_t *nb); void set_neverbleed(neverbleed_t *nb);
...@@ -187,6 +188,8 @@ private: ...@@ -187,6 +188,8 @@ private:
// selection among them are performed by hostname presented by SNI, // selection among them are performed by hostname presented by SNI,
// and signature algorithm presented by client. // and signature algorithm presented by client.
std::vector<std::vector<SSL_CTX *>> indexed_ssl_ctx_; std::vector<std::vector<SSL_CTX *>> indexed_ssl_ctx_;
std::vector<SSL_CTX *> quic_all_ssl_ctx_;
std::vector<std::vector<SSL_CTX *>> quic_indexed_ssl_ctx_;
OCSPUpdateContext ocsp_; OCSPUpdateContext ocsp_;
std::mt19937 &gen_; std::mt19937 &gen_;
// ev_loop for each worker // ev_loop for each worker
...@@ -203,6 +206,7 @@ private: ...@@ -203,6 +206,7 @@ private:
// Otherwise, nullptr and workers_ has instances of Worker instead. // Otherwise, nullptr and workers_ has instances of Worker instead.
std::unique_ptr<Worker> single_worker_; std::unique_ptr<Worker> single_worker_;
std::unique_ptr<tls::CertLookupTree> cert_tree_; std::unique_ptr<tls::CertLookupTree> cert_tree_;
std::unique_ptr<tls::CertLookupTree> quic_cert_tree_;
std::unique_ptr<MemcachedDispatcher> tls_ticket_key_memcached_dispatcher_; std::unique_ptr<MemcachedDispatcher> tls_ticket_key_memcached_dispatcher_;
// Current TLS session ticket keys. Note that TLS connection does // Current TLS session ticket keys. Note that TLS connection does
// not refer to this field directly. They use TicketKeys object in // not refer to this field directly. They use TicketKeys object in
......
...@@ -30,7 +30,8 @@ ...@@ -30,7 +30,8 @@
namespace shrpx { namespace shrpx {
Http3Upstream::Http3Upstream(ClientHandler *handler) : handler_{handler} {} Http3Upstream::Http3Upstream(ClientHandler *handler)
: handler_{handler}, tls_alert_{0} {}
Http3Upstream::~Http3Upstream() {} Http3Upstream::~Http3Upstream() {}
...@@ -129,4 +130,21 @@ int Http3Upstream::on_read(const UpstreamAddr *faddr, ...@@ -129,4 +130,21 @@ int Http3Upstream::on_read(const UpstreamAddr *faddr,
return 0; return 0;
} }
int Http3Upstream::on_rx_secret(ngtcp2_crypto_level level,
const uint8_t *secret, size_t secretlen) {
return 0;
}
int Http3Upstream::on_tx_secret(ngtcp2_crypto_level level,
const uint8_t *secret, size_t secretlen) {
return 0;
}
int Http3Upstream::add_crypto_data(ngtcp2_crypto_level level,
const uint8_t *data, size_t datalen) {
return 0;
}
void Http3Upstream::set_tls_alert(uint8_t alert) { tls_alert_ = alert; }
} // namespace shrpx } // namespace shrpx
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
#define SHRPX_HTTP3_UPSTREAM_H #define SHRPX_HTTP3_UPSTREAM_H
#include "shrpx.h" #include "shrpx.h"
#include <ngtcp2/ngtcp2.h>
#include "shrpx_upstream.h" #include "shrpx_upstream.h"
#include "network.h" #include "network.h"
...@@ -84,8 +87,19 @@ public: ...@@ -84,8 +87,19 @@ public:
int on_read(const UpstreamAddr *faddr, const Address &remote_addr, int on_read(const UpstreamAddr *faddr, const Address &remote_addr,
const Address &local_addr, const uint8_t *data, size_t datalen); const Address &local_addr, const uint8_t *data, size_t datalen);
int on_rx_secret(ngtcp2_crypto_level level, const uint8_t *secret,
size_t secretlen);
int on_tx_secret(ngtcp2_crypto_level level, const uint8_t *secret,
size_t secretlen);
int add_crypto_data(ngtcp2_crypto_level level, const uint8_t *data,
size_t datalen);
void set_tls_alert(uint8_t alert);
private: private:
ClientHandler *handler_; ClientHandler *handler_;
uint8_t tls_alert_;
}; };
} // namespace shrpx } // namespace shrpx
......
This diff is collapsed.
...@@ -100,6 +100,16 @@ SSL_CTX *create_ssl_client_context( ...@@ -100,6 +100,16 @@ SSL_CTX *create_ssl_client_context(
unsigned char *outlen, const unsigned char *in, unsigned char *outlen, const unsigned char *in,
unsigned int inlen, void *arg)); unsigned int inlen, void *arg));
SSL_CTX *create_quic_ssl_client_context(
#ifdef HAVE_NEVERBLEED
neverbleed_t *nb,
#endif // HAVE_NEVERBLEED
const StringRef &cacert, const StringRef &cert_file,
const StringRef &private_key_file,
int (*next_proto_select_cb)(SSL *s, unsigned char **out,
unsigned char *outlen, const unsigned char *in,
unsigned int inlen, void *arg));
ClientHandler *accept_connection(Worker *worker, int fd, sockaddr *addr, ClientHandler *accept_connection(Worker *worker, int fd, sockaddr *addr,
int addrlen, const UpstreamAddr *faddr); int addrlen, const UpstreamAddr *faddr);
...@@ -217,6 +227,16 @@ setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx, ...@@ -217,6 +227,16 @@ setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
#endif // HAVE_NEVERBLEED #endif // HAVE_NEVERBLEED
); );
SSL_CTX *setup_quic_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
,
neverbleed_t *nb
#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(
#ifdef HAVE_NEVERBLEED #ifdef HAVE_NEVERBLEED
......
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