nghttpx: Fix certificate selection based on pub key algorithm
This commit is contained in:
parent
ed1fad3bd4
commit
796ab87b14
12
src/shrpx.cc
12
src/shrpx.cc
|
@ -2084,12 +2084,12 @@ SSL/TLS:
|
||||||
Specify additional certificate and private key file.
|
Specify additional certificate and private key file.
|
||||||
nghttpx will choose certificates based on the hostname
|
nghttpx will choose certificates based on the hostname
|
||||||
indicated by client using TLS SNI extension. If nghttpx
|
indicated by client using TLS SNI extension. If nghttpx
|
||||||
is built with OpenSSL >= 1.0.2, signature algorithms
|
is built with OpenSSL >= 1.0.2, the shared elliptic
|
||||||
(e.g., ECDSA+SHA256, RSA+SHA256) presented by client are
|
curves (e.g., P-256) between client and server are also
|
||||||
also taken into consideration. This allows nghttpx to
|
taken into consideration. This allows nghttpx to send
|
||||||
send ECDSA certificate to modern clients, while sending
|
ECDSA certificate to modern clients, while sending RSA
|
||||||
RSA based certificate to older clients. This option can
|
based certificate to older clients. This option can be
|
||||||
be used multiple times. To make OCSP stapling work,
|
used multiple times. To make OCSP stapling work,
|
||||||
<CERTPATH> must be absolute path.
|
<CERTPATH> must be absolute path.
|
||||||
|
|
||||||
Additional parameter can be specified in <PARAM>. The
|
Additional parameter can be specified in <PARAM>. The
|
||||||
|
|
|
@ -186,19 +186,26 @@ int servername_callback(SSL *ssl, int *al, void *arg) {
|
||||||
|
|
||||||
#if !defined(OPENSSL_IS_BORINGSSL) && !defined(LIBRESSL_VERSION_NUMBER) && \
|
#if !defined(OPENSSL_IS_BORINGSSL) && !defined(LIBRESSL_VERSION_NUMBER) && \
|
||||||
OPENSSL_VERSION_NUMBER >= 0x10002000L
|
OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
// boringssl removed SSL_get_sigalgs.
|
auto num_shared_curves = SSL_get_shared_curve(ssl, -1);
|
||||||
auto num_sigalg =
|
|
||||||
SSL_get_sigalgs(ssl, 0, nullptr, nullptr, nullptr, nullptr, nullptr);
|
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) {
|
for (auto ssl_ctx : ssl_ctx_list) {
|
||||||
auto cert = SSL_CTX_get0_certificate(ssl_ctx);
|
auto cert = SSL_CTX_get0_certificate(ssl_ctx);
|
||||||
// X509_get_signature_nid is available since OpenSSL 1.0.2.
|
auto pubkey = X509_get0_pubkey(cert);
|
||||||
auto cert_sigalg = X509_get_signature_nid(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);
|
SSL_set_SSL_CTX(ssl, ssl_ctx);
|
||||||
return SSL_TLSEXT_ERR_OK;
|
return SSL_TLSEXT_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue