From 8c36971ea9679f1e7b05a4a3e6db654a6d9d9019 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 17 Oct 2021 16:41:10 +0900 Subject: [PATCH] Compile with OPENSSL_NO_DEPRECATED and fix memory leaks --- examples/client.c | 10 ++++++++ examples/libevent-client.c | 10 ++++++++ examples/libevent-server.c | 21 ++++++++++------- src/HttpServer.cc | 26 ++++++++------------- src/shrpx_log.cc | 18 ++++++++++++++ src/shrpx_mruby_module_env.cc | 44 +++++++++++++++++++++++++++++++++-- src/shrpx_tls.cc | 20 ++++++++++++---- 7 files changed, 119 insertions(+), 30 deletions(-) diff --git a/examples/client.c b/examples/client.c index 2d3c4c5d..22f585f7 100644 --- a/examples/client.c +++ b/examples/client.c @@ -715,8 +715,18 @@ int main(int argc, char **argv) { act.sa_handler = SIG_IGN; sigaction(SIGPIPE, &act, 0); +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + /* No explicit initialization is required. */ +#elif defined(OPENSSL_IS_BORINGSSL) + CRYPTO_library_init(); +#else /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) && \ + !defined(OPENSSL_IS_BORINGSSL) */ + OPENSSL_config(NULL); SSL_load_error_strings(); SSL_library_init(); + OpenSSL_add_all_algorithms(); +#endif /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) && \ + !defined(OPENSSL_IS_BORINGSSL) */ rv = parse_uri(&uri, argv[1]); if (rv != 0) { diff --git a/examples/libevent-client.c b/examples/libevent-client.c index f42cbdb3..e7c78cf5 100644 --- a/examples/libevent-client.c +++ b/examples/libevent-client.c @@ -617,8 +617,18 @@ int main(int argc, char **argv) { act.sa_handler = SIG_IGN; sigaction(SIGPIPE, &act, NULL); +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + /* No explicit initialization is required. */ +#elif defined(OPENSSL_IS_BORINGSSL) + CRYPTO_library_init(); +#else /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) && \ + !defined(OPENSSL_IS_BORINGSSL) */ + OPENSSL_config(NULL); SSL_load_error_strings(); SSL_library_init(); + OpenSSL_add_all_algorithms(); +#endif /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) && \ + !defined(OPENSSL_IS_BORINGSSL) */ run(argv[1]); return 0; diff --git a/examples/libevent-server.c b/examples/libevent-server.c index 0465a785..a30a5e89 100644 --- a/examples/libevent-server.c +++ b/examples/libevent-server.c @@ -153,14 +153,9 @@ static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) { SSL_OP_NO_COMPRESSION | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); #if OPENSSL_VERSION_NUMBER >= 0x30000000L - { - EVP_PKEY *ecdh; - ecdh = EVP_EC_gen("P-256"); - if (!ecdh) { - errx(1, "EVP_EC_gen failed: %s", ERR_error_string(ERR_get_error(), NULL)); - } - SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh); - EVP_PKEY_free(ecdh); + if (SSL_CTX_set1_curves_list(ssl_ctx, "P-256") != 1) { + errx(1, "SSL_CTX_set1_curves_list failed: %s", + ERR_error_string(ERR_get_error(), NULL)); } #else /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */ { @@ -822,8 +817,18 @@ int main(int argc, char **argv) { act.sa_handler = SIG_IGN; sigaction(SIGPIPE, &act, NULL); +#if OPENSSL_VERSION_NUMBER >= 0x1010000fL + /* No explicit initialization is required. */ +#elif defined(OPENSSL_IS_BORINGSSL) + CRYPTO_library_init(); +#else /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) && \ + !defined(OPENSSL_IS_BORINGSSL) */ + OPENSSL_config(NULL); SSL_load_error_strings(); SSL_library_init(); + OpenSSL_add_all_algorithms(); +#endif /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) && \ + !defined(OPENSSL_IS_BORINGSSL) */ run(argv[1], argv[2], argv[3]); return 0; diff --git a/src/HttpServer.cc b/src/HttpServer.cc index 67bc87aa..dacb4b15 100644 --- a/src/HttpServer.cc +++ b/src/HttpServer.cc @@ -2143,22 +2143,13 @@ int HttpServer::run() { SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_SERVER); #ifndef OPENSSL_NO_EC - // Disabled SSL_CTX_set_ecdh_auto, because computational cost of - // chosen curve is much higher than P-256. - - // SSL_CTX_set_ecdh_auto(ssl_ctx, 1); - // Use P-256, which is sufficiently secure at the time of this - // writing. -# if OPENSSL_3_0_0_API - auto ecdh = EVP_EC_gen("P-256"); - if (ecdh == nullptr) { - std::cerr << "EC_KEY_new_by_curv_name failed: " +# if !LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L + if (SSL_CTX_set1_curves_list(ssl_ctx, "P-256") != 1) { + std::cerr << "SSL_CTX_set1_curves_list failed: " << ERR_error_string(ERR_get_error(), nullptr); return -1; } - SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh); - EVP_PKEY_free(ecdh); -# else // !OPENSSL_3_0_0_API +# else // !(!LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L) auto ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if (ecdh == nullptr) { std::cerr << "EC_KEY_new_by_curv_name failed: " @@ -2167,7 +2158,7 @@ int HttpServer::run() { } SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh); EC_KEY_free(ecdh); -# endif // !OPENSSL_3_0_0_API +# endif // !(!LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L) #endif // OPENSSL_NO_EC if (!config_->dh_param_file.empty()) { @@ -2191,8 +2182,11 @@ int HttpServer::run() { return -1; } - SSL_CTX_set_tmp_dh(ssl_ctx, dh); - EVP_PKEY_free(dh); + if (SSL_CTX_set0_tmp_dh_pkey(ssl_ctx, dh) != 1) { + std::cerr << "SSL_CTX_set0_tmp_dh_pkey failed: " + << ERR_error_string(ERR_get_error(), nullptr) << std::endl; + return -1; + } #else // !OPENSSL_3_0_0_API auto dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr); diff --git a/src/shrpx_log.cc b/src/shrpx_log.cc index 3a5af823..fe626d6b 100644 --- a/src/shrpx_log.cc +++ b/src/shrpx_log.cc @@ -755,7 +755,11 @@ void upstream_accesslog(const std::vector &lfv, std::tie(p, last) = copy('-', p, last); break; } +#if OPENSSL_3_0_0_API + auto x = SSL_get0_peer_certificate(lgsp.ssl); +#else // !OPENSSL_3_0_0_API auto x = SSL_get_peer_certificate(lgsp.ssl); +#endif // !OPENSSL_3_0_0_API if (!x) { std::tie(p, last) = copy('-', p, last); break; @@ -766,7 +770,9 @@ void upstream_accesslog(const std::vector &lfv, lf.type == LogFragmentType::TLS_CLIENT_FINGERPRINT_SHA256 ? EVP_sha256() : EVP_sha1()); +#if !OPENSSL_3_0_0_API X509_free(x); +#endif // !OPENSSL_3_0_0_API if (len <= 0) { std::tie(p, last) = copy('-', p, last); break; @@ -780,7 +786,11 @@ void upstream_accesslog(const std::vector &lfv, std::tie(p, last) = copy('-', p, last); break; } +#if OPENSSL_3_0_0_API + auto x = SSL_get0_peer_certificate(lgsp.ssl); +#else // !OPENSSL_3_0_0_API auto x = SSL_get_peer_certificate(lgsp.ssl); +#endif // !OPENSSL_3_0_0_API if (!x) { std::tie(p, last) = copy('-', p, last); break; @@ -788,7 +798,9 @@ void upstream_accesslog(const std::vector &lfv, auto name = lf.type == LogFragmentType::TLS_CLIENT_ISSUER_NAME ? tls::get_x509_issuer_name(balloc, x) : tls::get_x509_subject_name(balloc, x); +#if !OPENSSL_3_0_0_API X509_free(x); +#endif // !OPENSSL_3_0_0_API if (name.empty()) { std::tie(p, last) = copy('-', p, last); break; @@ -801,13 +813,19 @@ void upstream_accesslog(const std::vector &lfv, std::tie(p, last) = copy('-', p, last); break; } +#if OPENSSL_3_0_0_API + auto x = SSL_get0_peer_certificate(lgsp.ssl); +#else // !OPENSSL_3_0_0_API auto x = SSL_get_peer_certificate(lgsp.ssl); +#endif // !OPENSSL_3_0_0_API if (!x) { std::tie(p, last) = copy('-', p, last); break; } auto sn = tls::get_x509_serial(balloc, x); +#if !OPENSSL_3_0_0_API X509_free(x); +#endif // !OPENSSL_3_0_0_API if (sn.empty()) { std::tie(p, last) = copy('-', p, last); break; diff --git a/src/shrpx_mruby_module_env.cc b/src/shrpx_mruby_module_env.cc index b3ed365d..5ebd9c05 100644 --- a/src/shrpx_mruby_module_env.cc +++ b/src/shrpx_mruby_module_env.cc @@ -153,7 +153,11 @@ mrb_value env_get_tls_client_fingerprint_md(mrb_state *mrb, const EVP_MD *md) { return mrb_str_new_static(mrb, "", 0); } +#if OPENSSL_3_0_0_API + auto x = SSL_get0_peer_certificate(ssl); +#else // !OPENSSL_3_0_0_API auto x = SSL_get_peer_certificate(ssl); +#endif // !OPENSSL_3_0_0_API if (!x) { return mrb_str_new_static(mrb, "", 0); } @@ -161,7 +165,9 @@ mrb_value env_get_tls_client_fingerprint_md(mrb_state *mrb, const EVP_MD *md) { // Currently the largest hash value is SHA-256, which is 32 bytes. std::array buf; auto slen = tls::get_x509_fingerprint(buf.data(), buf.size(), x, md); +#if !OPENSSL_3_0_0_API X509_free(x); +#endif // !OPENSSL_3_0_0_API if (slen == -1) { mrb_raise(mrb, E_RUNTIME_ERROR, "could not compute client fingerprint"); } @@ -199,14 +205,20 @@ mrb_value env_get_tls_client_subject_name(mrb_state *mrb, mrb_value self) { return mrb_str_new_static(mrb, "", 0); } +#if OPENSSL_3_0_0_API + auto x = SSL_get0_peer_certificate(ssl); +#else // !OPENSSL_3_0_0_API auto x = SSL_get_peer_certificate(ssl); +#endif // !OPENSSL_3_0_0_API if (!x) { return mrb_str_new_static(mrb, "", 0); } auto &balloc = downstream->get_block_allocator(); auto name = tls::get_x509_subject_name(balloc, x); +#if !OPENSSL_3_0_0_API X509_free(x); +#endif // !OPENSSL_3_0_0_API return mrb_str_new(mrb, name.c_str(), name.size()); } } // namespace @@ -223,14 +235,20 @@ mrb_value env_get_tls_client_issuer_name(mrb_state *mrb, mrb_value self) { return mrb_str_new_static(mrb, "", 0); } +#if OPENSSL_3_0_0_API + auto x = SSL_get0_peer_certificate(ssl); +#else // !OPENSSL_3_0_0_API auto x = SSL_get_peer_certificate(ssl); +#endif // !OPENSSL_3_0_0_API if (!x) { return mrb_str_new_static(mrb, "", 0); } auto &balloc = downstream->get_block_allocator(); auto name = tls::get_x509_issuer_name(balloc, x); +#if !OPENSSL_3_0_0_API X509_free(x); +#endif // !OPENSSL_3_0_0_API return mrb_str_new(mrb, name.c_str(), name.size()); } } // namespace @@ -247,14 +265,20 @@ mrb_value env_get_tls_client_serial(mrb_state *mrb, mrb_value self) { return mrb_str_new_static(mrb, "", 0); } +#if OPENSSL_3_0_0_API + auto x = SSL_get0_peer_certificate(ssl); +#else // !OPENSSL_3_0_0_API auto x = SSL_get_peer_certificate(ssl); +#endif // !OPENSSL_3_0_0_API if (!x) { return mrb_str_new_static(mrb, "", 0); } auto &balloc = downstream->get_block_allocator(); auto sn = tls::get_x509_serial(balloc, x); +#if !OPENSSL_3_0_0_API X509_free(x); +#endif // !OPENSSL_3_0_0_API return mrb_str_new(mrb, sn.c_str(), sn.size()); } } // namespace @@ -271,16 +295,24 @@ mrb_value env_get_tls_client_not_before(mrb_state *mrb, mrb_value self) { return mrb_fixnum_value(0); } +#if OPENSSL_3_0_0_API + auto x = SSL_get0_peer_certificate(ssl); +#else // !OPENSSL_3_0_0_API auto x = SSL_get_peer_certificate(ssl); +#endif // !OPENSSL_3_0_0_API if (!x) { return mrb_fixnum_value(0); } time_t t; if (tls::get_x509_not_before(t, x) != 0) { - return mrb_fixnum_value(0); + t = 0; } +#if !OPENSSL_3_0_0_API + X509_free(x); +#endif // !OPENSSL_3_0_0_API + return mrb_fixnum_value(t); } } // namespace @@ -297,16 +329,24 @@ mrb_value env_get_tls_client_not_after(mrb_state *mrb, mrb_value self) { return mrb_fixnum_value(0); } +#if OPENSSL_3_0_0_API + auto x = SSL_get0_peer_certificate(ssl); +#else // !OPENSSL_3_0_0_API auto x = SSL_get_peer_certificate(ssl); +#endif // !OPENSSL_3_0_0_API if (!x) { return mrb_fixnum_value(0); } time_t t; if (tls::get_x509_not_after(t, x) != 0) { - return mrb_fixnum_value(0); + t = 0; } +#if !OPENSSL_3_0_0_API + X509_free(x); +#endif // !OPENSSL_3_0_0_API + return mrb_fixnum_value(t); } } // namespace diff --git a/src/shrpx_tls.cc b/src/shrpx_tls.cc index 8d352727..e332ba63 100644 --- a/src/shrpx_tls.cc +++ b/src/shrpx_tls.cc @@ -1031,8 +1031,11 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file, DIE(); } - SSL_CTX_set_tmp_dh(ssl_ctx, dh); - EVP_PKEY_free(dh); + if (SSL_CTX_set0_tmp_dh_pkey(ssl_ctx, dh) != 1) { + LOG(FATAL) << "SSL_CTX_set0_tmp_dh_pkey failed: " + << ERR_error_string(ERR_get_error(), nullptr); + DIE(); + } #else // !OPENSSL_3_0_0_API auto dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr); if (dh == nullptr) { @@ -1456,8 +1459,11 @@ SSL_CTX *create_quic_ssl_context(const char *private_key_file, DIE(); } - SSL_CTX_set_tmp_dh(ssl_ctx, dh); - EVP_PKEY_free(dh); + if (SSL_CTX_set0_tmp_dh_pkey(ssl_ctx, dh) != 1) { + LOG(FATAL) << "SSL_CTX_set0_tmp_dh_pkey failed: " + << ERR_error_string(ERR_get_error(), nullptr); + DIE(); + } # else // !OPENSSL_3_0_0_API auto dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr); if (dh == nullptr) { @@ -2064,14 +2070,20 @@ int verify_hostname(X509 *cert, const StringRef &hostname, } // namespace int check_cert(SSL *ssl, const Address *addr, const StringRef &host) { +#if OPENSSL_3_0_0_API + auto cert = SSL_get0_peer_certificate(ssl); +#else // !OPENSSL_3_0_0_API auto cert = SSL_get_peer_certificate(ssl); +#endif // !OPENSSL_3_0_0_API if (!cert) { // By the protocol definition, TLS server always sends certificate // if it has. If certificate cannot be retrieved, authentication // without certificate is used, such as PSK. return 0; } +#if !OPENSSL_3_0_0_API auto cert_deleter = defer(X509_free, cert); +#endif // !OPENSSL_3_0_0_API if (verify_hostname(cert, host, addr) != 0) { LOG(ERROR) << "Certificate verification failed: hostname does not match";