nghttpx: Fix certificate selection based on pub key algorithm

This commit is contained in:
Tatsuhiro Tsujikawa 2017-05-21 10:29:27 +09:00
parent ed1fad3bd4
commit 796ab87b14
2 changed files with 22 additions and 15 deletions

View File

@ -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

View File

@ -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;
} }