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() {
ev_timer_stop(loop_, &ocsp_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_) {
auto tls_ctx_data =
static_cast<tls::TLSContextData *>(SSL_CTX_get_app_data(ssl_ctx));
......@@ -209,6 +220,16 @@ int ConnectionHandler::create_single_worker() {
nb_
#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(
#ifdef HAVE_NEVERBLEED
nb_
......@@ -217,6 +238,7 @@ int ConnectionHandler::create_single_worker() {
if (cl_ssl_ctx) {
all_ssl_ctx_.push_back(cl_ssl_ctx);
quic_all_ssl_ctx_.push_back(nullptr);
}
auto config = get_config();
......@@ -233,6 +255,7 @@ int ConnectionHandler::create_single_worker() {
tlsconf.cacert, memcachedconf.cert_file,
memcachedconf.private_key_file, nullptr);
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) {
nb_
# 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(
# ifdef HAVE_NEVERBLEED
nb_
......@@ -271,6 +304,7 @@ int ConnectionHandler::create_worker_thread(size_t num) {
if (cl_ssl_ctx) {
all_ssl_ctx_.push_back(cl_ssl_ctx);
quic_all_ssl_ctx_.push_back(nullptr);
}
auto config = get_config();
......@@ -294,6 +328,7 @@ int ConnectionHandler::create_worker_thread(size_t num) {
tlsconf.cacert, memcachedconf.cert_file,
memcachedconf.private_key_file, nullptr);
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() {
ev_child_stop(loop_, &ocsp_.chldev);
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 tls_ctx_data =
......@@ -635,6 +671,29 @@ void ConnectionHandler::handle_ocsp_complete() {
if (tlsconf.ocsp.no_verify ||
tls::verify_ocsp_response(ssl_ctx, ocsp_.resp.data(),
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
# ifdef HAVE_ATOMIC_STD_SHARED_PTR
std::atomic_store_explicit(
......@@ -815,6 +874,7 @@ SSL_CTX *ConnectionHandler::create_tls_ticket_key_memcached_ssl_ctx() {
nullptr);
all_ssl_ctx_.push_back(ssl_ctx);
quic_all_ssl_ctx_.push_back(nullptr);
return ssl_ctx;
}
......@@ -877,6 +937,11 @@ ConnectionHandler::get_indexed_ssl_ctx(size_t idx) const {
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) {
enable_acceptor_on_ocsp_completion_ = f;
}
......
......@@ -159,6 +159,7 @@ public:
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_quic_indexed_ssl_ctx(size_t idx) const;
#ifdef HAVE_NEVERBLEED
void set_neverbleed(neverbleed_t *nb);
......@@ -187,6 +188,8 @@ private:
// 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_;
std::vector<SSL_CTX *> quic_all_ssl_ctx_;
std::vector<std::vector<SSL_CTX *>> quic_indexed_ssl_ctx_;
OCSPUpdateContext ocsp_;
std::mt19937 &gen_;
// ev_loop for each worker
......@@ -203,6 +206,7 @@ private:
// Otherwise, nullptr and workers_ has instances of Worker instead.
std::unique_ptr<Worker> single_worker_;
std::unique_ptr<tls::CertLookupTree> cert_tree_;
std::unique_ptr<tls::CertLookupTree> quic_cert_tree_;
std::unique_ptr<MemcachedDispatcher> tls_ticket_key_memcached_dispatcher_;
// Current TLS session ticket keys. Note that TLS connection does
// not refer to this field directly. They use TicketKeys object in
......
......@@ -30,7 +30,8 @@
namespace shrpx {
Http3Upstream::Http3Upstream(ClientHandler *handler) : handler_{handler} {}
Http3Upstream::Http3Upstream(ClientHandler *handler)
: handler_{handler}, tls_alert_{0} {}
Http3Upstream::~Http3Upstream() {}
......@@ -129,4 +130,21 @@ int Http3Upstream::on_read(const UpstreamAddr *faddr,
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
......@@ -26,6 +26,9 @@
#define SHRPX_HTTP3_UPSTREAM_H
#include "shrpx.h"
#include <ngtcp2/ngtcp2.h>
#include "shrpx_upstream.h"
#include "network.h"
......@@ -84,8 +87,19 @@ public:
int on_read(const UpstreamAddr *faddr, const Address &remote_addr,
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:
ClientHandler *handler_;
uint8_t tls_alert_;
};
} // namespace shrpx
......
This diff is collapsed.
......@@ -100,6 +100,16 @@ SSL_CTX *create_ssl_client_context(
unsigned char *outlen, const unsigned char *in,
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,
int addrlen, const UpstreamAddr *faddr);
......@@ -217,6 +227,16 @@ setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
#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.
SSL_CTX *setup_downstream_client_ssl_context(
#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