diff --git a/src/shrpx.cc b/src/shrpx.cc index 760db27b..c6f6a322 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -2084,12 +2084,12 @@ SSL/TLS: Specify additional certificate and private key file. nghttpx will choose certificates based on the hostname indicated by client using TLS SNI extension. If nghttpx - is built with OpenSSL >= 1.0.2, signature algorithms - (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, + is built with OpenSSL >= 1.0.2, the shared elliptic + curves (e.g., P-256) between client and server 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, must be absolute path. Additional parameter can be specified in . The diff --git a/src/shrpx_tls.cc b/src/shrpx_tls.cc index d9fc7bd3..3523fc25 100644 --- a/src/shrpx_tls.cc +++ b/src/shrpx_tls.cc @@ -186,19 +186,26 @@ int servername_callback(SSL *ssl, int *al, void *arg) { #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); + auto num_shared_curves = SSL_get_shared_curve(ssl, -1); + + for (auto i = 0; i < num_shared_curves; ++i) { + auto shared_curve = SSL_get_shared_curve(ssl, i); - 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); + auto pubkey = X509_get0_pubkey(cert); + if (EVP_PKEY_base_id(pubkey) != EVP_PKEY_EC) { + continue; + } + auto eckey = EVP_PKEY_get0_EC_KEY(pubkey); + if (eckey == nullptr) { + continue; + } - if (sigalg == cert_sigalg) { + auto ecgroup = EC_KEY_get0_group(eckey); + auto cert_curve = EC_GROUP_get_curve_name(ecgroup); + + if (shared_curve == cert_curve) { SSL_set_SSL_CTX(ssl, ssl_ctx); return SSL_TLSEXT_ERR_OK; }