Merge branch 'nghttpx-fix-cert-selection'

This commit is contained in:
Tatsuhiro Tsujikawa 2017-05-21 11:26:12 +09:00
commit 52a4d6ac31
2 changed files with 22 additions and 15 deletions

View File

@ -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,
<CERTPATH> must be absolute path.
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) && \
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;
}