Compile with OPENSSL_NO_DEPRECATED and fix memory leaks

This commit is contained in:
Tatsuhiro Tsujikawa 2021-10-17 16:41:10 +09:00
parent ba1dff187b
commit 8c36971ea9
7 changed files with 119 additions and 30 deletions

View File

@ -715,8 +715,18 @@ int main(int argc, char **argv) {
act.sa_handler = SIG_IGN; act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, 0); 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_load_error_strings();
SSL_library_init(); SSL_library_init();
OpenSSL_add_all_algorithms();
#endif /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) && \
!defined(OPENSSL_IS_BORINGSSL) */
rv = parse_uri(&uri, argv[1]); rv = parse_uri(&uri, argv[1]);
if (rv != 0) { if (rv != 0) {

View File

@ -617,8 +617,18 @@ int main(int argc, char **argv) {
act.sa_handler = SIG_IGN; act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, NULL); 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_load_error_strings();
SSL_library_init(); SSL_library_init();
OpenSSL_add_all_algorithms();
#endif /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) && \
!defined(OPENSSL_IS_BORINGSSL) */
run(argv[1]); run(argv[1]);
return 0; return 0;

View File

@ -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_COMPRESSION |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
#if OPENSSL_VERSION_NUMBER >= 0x30000000L #if OPENSSL_VERSION_NUMBER >= 0x30000000L
{ if (SSL_CTX_set1_curves_list(ssl_ctx, "P-256") != 1) {
EVP_PKEY *ecdh; errx(1, "SSL_CTX_set1_curves_list failed: %s",
ecdh = EVP_EC_gen("P-256"); ERR_error_string(ERR_get_error(), NULL));
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);
} }
#else /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */ #else /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
{ {
@ -822,8 +817,18 @@ int main(int argc, char **argv) {
act.sa_handler = SIG_IGN; act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, NULL); 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_load_error_strings();
SSL_library_init(); SSL_library_init();
OpenSSL_add_all_algorithms();
#endif /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) && \
!defined(OPENSSL_IS_BORINGSSL) */
run(argv[1], argv[2], argv[3]); run(argv[1], argv[2], argv[3]);
return 0; return 0;

View File

@ -2143,22 +2143,13 @@ int HttpServer::run() {
SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_SERVER); SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_SERVER);
#ifndef OPENSSL_NO_EC #ifndef OPENSSL_NO_EC
// Disabled SSL_CTX_set_ecdh_auto, because computational cost of # if !LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L
// chosen curve is much higher than P-256. if (SSL_CTX_set1_curves_list(ssl_ctx, "P-256") != 1) {
std::cerr << "SSL_CTX_set1_curves_list failed: "
// 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: "
<< ERR_error_string(ERR_get_error(), nullptr); << ERR_error_string(ERR_get_error(), nullptr);
return -1; return -1;
} }
SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh); # else // !(!LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L)
EVP_PKEY_free(ecdh);
# else // !OPENSSL_3_0_0_API
auto ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); auto ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
if (ecdh == nullptr) { if (ecdh == nullptr) {
std::cerr << "EC_KEY_new_by_curv_name failed: " std::cerr << "EC_KEY_new_by_curv_name failed: "
@ -2167,7 +2158,7 @@ int HttpServer::run() {
} }
SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh); SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
EC_KEY_free(ecdh); EC_KEY_free(ecdh);
# endif // !OPENSSL_3_0_0_API # endif // !(!LIBRESSL_LEGACY_API && OPENSSL_VERSION_NUMBER >= 0x10002000L)
#endif // OPENSSL_NO_EC #endif // OPENSSL_NO_EC
if (!config_->dh_param_file.empty()) { if (!config_->dh_param_file.empty()) {
@ -2191,8 +2182,11 @@ int HttpServer::run() {
return -1; return -1;
} }
SSL_CTX_set_tmp_dh(ssl_ctx, dh); if (SSL_CTX_set0_tmp_dh_pkey(ssl_ctx, dh) != 1) {
EVP_PKEY_free(dh); 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 #else // !OPENSSL_3_0_0_API
auto dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr); auto dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);

View File

@ -755,7 +755,11 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
std::tie(p, last) = copy('-', p, last); std::tie(p, last) = copy('-', p, last);
break; 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); auto x = SSL_get_peer_certificate(lgsp.ssl);
#endif // !OPENSSL_3_0_0_API
if (!x) { if (!x) {
std::tie(p, last) = copy('-', p, last); std::tie(p, last) = copy('-', p, last);
break; break;
@ -766,7 +770,9 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
lf.type == LogFragmentType::TLS_CLIENT_FINGERPRINT_SHA256 lf.type == LogFragmentType::TLS_CLIENT_FINGERPRINT_SHA256
? EVP_sha256() ? EVP_sha256()
: EVP_sha1()); : EVP_sha1());
#if !OPENSSL_3_0_0_API
X509_free(x); X509_free(x);
#endif // !OPENSSL_3_0_0_API
if (len <= 0) { if (len <= 0) {
std::tie(p, last) = copy('-', p, last); std::tie(p, last) = copy('-', p, last);
break; break;
@ -780,7 +786,11 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
std::tie(p, last) = copy('-', p, last); std::tie(p, last) = copy('-', p, last);
break; 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); auto x = SSL_get_peer_certificate(lgsp.ssl);
#endif // !OPENSSL_3_0_0_API
if (!x) { if (!x) {
std::tie(p, last) = copy('-', p, last); std::tie(p, last) = copy('-', p, last);
break; break;
@ -788,7 +798,9 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
auto name = lf.type == LogFragmentType::TLS_CLIENT_ISSUER_NAME auto name = lf.type == LogFragmentType::TLS_CLIENT_ISSUER_NAME
? tls::get_x509_issuer_name(balloc, x) ? tls::get_x509_issuer_name(balloc, x)
: tls::get_x509_subject_name(balloc, x); : tls::get_x509_subject_name(balloc, x);
#if !OPENSSL_3_0_0_API
X509_free(x); X509_free(x);
#endif // !OPENSSL_3_0_0_API
if (name.empty()) { if (name.empty()) {
std::tie(p, last) = copy('-', p, last); std::tie(p, last) = copy('-', p, last);
break; break;
@ -801,13 +813,19 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
std::tie(p, last) = copy('-', p, last); std::tie(p, last) = copy('-', p, last);
break; 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); auto x = SSL_get_peer_certificate(lgsp.ssl);
#endif // !OPENSSL_3_0_0_API
if (!x) { if (!x) {
std::tie(p, last) = copy('-', p, last); std::tie(p, last) = copy('-', p, last);
break; break;
} }
auto sn = tls::get_x509_serial(balloc, x); auto sn = tls::get_x509_serial(balloc, x);
#if !OPENSSL_3_0_0_API
X509_free(x); X509_free(x);
#endif // !OPENSSL_3_0_0_API
if (sn.empty()) { if (sn.empty()) {
std::tie(p, last) = copy('-', p, last); std::tie(p, last) = copy('-', p, last);
break; break;

View File

@ -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); 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); auto x = SSL_get_peer_certificate(ssl);
#endif // !OPENSSL_3_0_0_API
if (!x) { if (!x) {
return mrb_str_new_static(mrb, "", 0); 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. // Currently the largest hash value is SHA-256, which is 32 bytes.
std::array<uint8_t, 32> buf; std::array<uint8_t, 32> buf;
auto slen = tls::get_x509_fingerprint(buf.data(), buf.size(), x, md); auto slen = tls::get_x509_fingerprint(buf.data(), buf.size(), x, md);
#if !OPENSSL_3_0_0_API
X509_free(x); X509_free(x);
#endif // !OPENSSL_3_0_0_API
if (slen == -1) { if (slen == -1) {
mrb_raise(mrb, E_RUNTIME_ERROR, "could not compute client fingerprint"); 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); 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); auto x = SSL_get_peer_certificate(ssl);
#endif // !OPENSSL_3_0_0_API
if (!x) { if (!x) {
return mrb_str_new_static(mrb, "", 0); return mrb_str_new_static(mrb, "", 0);
} }
auto &balloc = downstream->get_block_allocator(); auto &balloc = downstream->get_block_allocator();
auto name = tls::get_x509_subject_name(balloc, x); auto name = tls::get_x509_subject_name(balloc, x);
#if !OPENSSL_3_0_0_API
X509_free(x); X509_free(x);
#endif // !OPENSSL_3_0_0_API
return mrb_str_new(mrb, name.c_str(), name.size()); return mrb_str_new(mrb, name.c_str(), name.size());
} }
} // namespace } // 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); 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); auto x = SSL_get_peer_certificate(ssl);
#endif // !OPENSSL_3_0_0_API
if (!x) { if (!x) {
return mrb_str_new_static(mrb, "", 0); return mrb_str_new_static(mrb, "", 0);
} }
auto &balloc = downstream->get_block_allocator(); auto &balloc = downstream->get_block_allocator();
auto name = tls::get_x509_issuer_name(balloc, x); auto name = tls::get_x509_issuer_name(balloc, x);
#if !OPENSSL_3_0_0_API
X509_free(x); X509_free(x);
#endif // !OPENSSL_3_0_0_API
return mrb_str_new(mrb, name.c_str(), name.size()); return mrb_str_new(mrb, name.c_str(), name.size());
} }
} // namespace } // 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); 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); auto x = SSL_get_peer_certificate(ssl);
#endif // !OPENSSL_3_0_0_API
if (!x) { if (!x) {
return mrb_str_new_static(mrb, "", 0); return mrb_str_new_static(mrb, "", 0);
} }
auto &balloc = downstream->get_block_allocator(); auto &balloc = downstream->get_block_allocator();
auto sn = tls::get_x509_serial(balloc, x); auto sn = tls::get_x509_serial(balloc, x);
#if !OPENSSL_3_0_0_API
X509_free(x); X509_free(x);
#endif // !OPENSSL_3_0_0_API
return mrb_str_new(mrb, sn.c_str(), sn.size()); return mrb_str_new(mrb, sn.c_str(), sn.size());
} }
} // namespace } // namespace
@ -271,16 +295,24 @@ mrb_value env_get_tls_client_not_before(mrb_state *mrb, mrb_value self) {
return mrb_fixnum_value(0); 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); auto x = SSL_get_peer_certificate(ssl);
#endif // !OPENSSL_3_0_0_API
if (!x) { if (!x) {
return mrb_fixnum_value(0); return mrb_fixnum_value(0);
} }
time_t t; time_t t;
if (tls::get_x509_not_before(t, x) != 0) { 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); return mrb_fixnum_value(t);
} }
} // namespace } // namespace
@ -297,16 +329,24 @@ mrb_value env_get_tls_client_not_after(mrb_state *mrb, mrb_value self) {
return mrb_fixnum_value(0); 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); auto x = SSL_get_peer_certificate(ssl);
#endif // !OPENSSL_3_0_0_API
if (!x) { if (!x) {
return mrb_fixnum_value(0); return mrb_fixnum_value(0);
} }
time_t t; time_t t;
if (tls::get_x509_not_after(t, x) != 0) { 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); return mrb_fixnum_value(t);
} }
} // namespace } // namespace

View File

@ -1031,8 +1031,11 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
DIE(); DIE();
} }
SSL_CTX_set_tmp_dh(ssl_ctx, dh); if (SSL_CTX_set0_tmp_dh_pkey(ssl_ctx, dh) != 1) {
EVP_PKEY_free(dh); LOG(FATAL) << "SSL_CTX_set0_tmp_dh_pkey failed: "
<< ERR_error_string(ERR_get_error(), nullptr);
DIE();
}
#else // !OPENSSL_3_0_0_API #else // !OPENSSL_3_0_0_API
auto dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr); auto dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);
if (dh == nullptr) { if (dh == nullptr) {
@ -1456,8 +1459,11 @@ SSL_CTX *create_quic_ssl_context(const char *private_key_file,
DIE(); DIE();
} }
SSL_CTX_set_tmp_dh(ssl_ctx, dh); if (SSL_CTX_set0_tmp_dh_pkey(ssl_ctx, dh) != 1) {
EVP_PKEY_free(dh); LOG(FATAL) << "SSL_CTX_set0_tmp_dh_pkey failed: "
<< ERR_error_string(ERR_get_error(), nullptr);
DIE();
}
# else // !OPENSSL_3_0_0_API # else // !OPENSSL_3_0_0_API
auto dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr); auto dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);
if (dh == nullptr) { if (dh == nullptr) {
@ -2064,14 +2070,20 @@ int verify_hostname(X509 *cert, const StringRef &hostname,
} // namespace } // namespace
int check_cert(SSL *ssl, const Address *addr, const StringRef &host) { 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); auto cert = SSL_get_peer_certificate(ssl);
#endif // !OPENSSL_3_0_0_API
if (!cert) { if (!cert) {
// By the protocol definition, TLS server always sends certificate // By the protocol definition, TLS server always sends certificate
// if it has. If certificate cannot be retrieved, authentication // if it has. If certificate cannot be retrieved, authentication
// without certificate is used, such as PSK. // without certificate is used, such as PSK.
return 0; return 0;
} }
#if !OPENSSL_3_0_0_API
auto cert_deleter = defer(X509_free, cert); auto cert_deleter = defer(X509_free, cert);
#endif // !OPENSSL_3_0_0_API
if (verify_hostname(cert, host, addr) != 0) { if (verify_hostname(cert, host, addr) != 0) {
LOG(ERROR) << "Certificate verification failed: hostname does not match"; LOG(ERROR) << "Certificate verification failed: hostname does not match";