From a5119c3a1a0a081660f41f829e18e6345bd06125 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Fri, 20 Mar 2020 16:15:45 +0100 Subject: [PATCH] Revamp OpenSSL tls cipher log message The new message will look like this: SSL Handshake: peer certificate: CN=OpenVPN Server, 4096 bit RSA, cipher: ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD compared to the old message SSL Handshake: CN=OpenVPN Access Server, TLSv1.2, cipher TLSv1/SSLv3 ECDHE-RSA-AES256-GCM-SHA384, 3072 bit RSA The new message uses the SSL_CIPHER_description method and its formatting instead out homegrown format. It also moves the xxx bit RSA part closer to the certificate to make it more obvious that those belong together Signed-off-by: Arne Schwabe --- openvpn/openssl/compat.hpp | 17 +++++++++ openvpn/openssl/ssl/sslctx.hpp | 70 +++++++++++++++++++++++++++------- 2 files changed, 74 insertions(+), 13 deletions(-) diff --git a/openvpn/openssl/compat.hpp b/openvpn/openssl/compat.hpp index 19928e3b..5bf7e813 100644 --- a/openvpn/openssl/compat.hpp +++ b/openvpn/openssl/compat.hpp @@ -307,6 +307,23 @@ inline void RSA_get0_key(const RSA *rsa, const BIGNUM **n, const BIGNUM **e, con *d = rsa->d; } +inline EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_EC) { + return NULL; + } + return pkey->pkey.ec; +} + +inline int EC_GROUP_order_bits(const EC_GROUP *group) +{ + BIGNUM *order = BN_new(); + EC_GROUP_get_order(group, order, NULL); + int bits = BN_num_bits(order); + BN_free(order); + return bits; +} + /* Renamed in OpenSSL 1.1 */ #define X509_get0_pubkey X509_get_pubkey #define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT RSA_F_RSA_EAY_PRIVATE_ENCRYPT diff --git a/openvpn/openssl/ssl/sslctx.hpp b/openvpn/openssl/ssl/sslctx.hpp index 61472f11..75f0aec0 100644 --- a/openvpn/openssl/ssl/sslctx.hpp +++ b/openvpn/openssl/ssl/sslctx.hpp @@ -34,8 +34,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -865,29 +867,71 @@ namespace openvpn { ::X509 *cert = SSL_get_peer_certificate (c_ssl); if (cert) - os << "CN=" << OpenSSLPKI::x509_get_field(cert, NID_commonName) << ", "; - - os << SSL_get_version (c_ssl); - - const SSL_CIPHER *ciph = SSL_get_current_cipher (c_ssl); - if (ciph) - os << ", cipher " << SSL_CIPHER_get_version (ciph) << ' ' << SSL_CIPHER_get_name (ciph); + os << "peer certificate: CN=" << OpenSSLPKI::x509_get_field(cert, NID_commonName); if (cert != nullptr) { EVP_PKEY *pkey = X509_get_pubkey (cert); if (pkey != nullptr) { - if (EVP_PKEY_id (pkey) == EVP_PKEY_RSA && EVP_PKEY_get0_RSA (pkey) != nullptr && RSA_get0_n(EVP_PKEY_get0_RSA (pkey)) != nullptr) - os << ", " << BN_num_bits (RSA_get0_n(EVP_PKEY_get0_RSA (pkey))) << " bit RSA"; -#ifndef OPENSSL_NO_DSA - else if (EVP_PKEY_id (pkey) == EVP_PKEY_DSA && EVP_PKEY_get0_DSA (pkey) != nullptr && DSA_get0_p(EVP_PKEY_get0_DSA (pkey))!= nullptr) - os << ", " << BN_num_bits (DSA_get0_p(EVP_PKEY_get0_DSA (pkey))) << " bit DSA"; +#ifndef OPENSSL_NO_EC + if ((EVP_PKEY_id(pkey) == EVP_PKEY_EC) && (EVP_PKEY_get0_EC_KEY(pkey) != nullptr && + EVP_PKEY_get0_EC_KEY(pkey) != nullptr)) + { + EC_KEY* ec = EVP_PKEY_get0_EC_KEY(pkey); + const EC_GROUP* group = EC_KEY_get0_group(ec); + const char* curve = nullptr; + + int nid = EC_GROUP_get_curve_name(group); + + if (nid != 0) + { + curve = OBJ_nid2sn(nid); + } + + if(!curve) + { + curve = "Error getting curve name"; + } + + os << ", " << EC_GROUP_order_bits(group) << " bit EC, curve:" << curve; + } + + else #endif - EVP_PKEY_free (pkey); + { + int pkeyId = EVP_PKEY_id(pkey); + const char* pkeySN = OBJ_nid2sn(pkeyId); + if (!pkeySN) + pkeySN = "Unknown"; + + // Nicer names instead of rsaEncryption and dsaEncryption + if (pkeyId == EVP_PKEY_RSA) + pkeySN = "RSA"; + else if (pkeyId == EVP_PKEY_DSA) + pkeySN = "DSA"; + + os << ", " << EVP_PKEY_bits(pkey) << " bit " << pkeySN; + } + EVP_PKEY_free(pkey); } X509_free (cert); } + + const SSL_CIPHER *ciph = SSL_get_current_cipher (c_ssl); + if (ciph) + { + char* desc = SSL_CIPHER_description(ciph, nullptr, 0); + if (!desc) + { + os << ", cipher: Error getting TLS cipher description from SSL_CIPHER_description"; + } + else + { + os << ", cipher: " << desc; + OPENSSL_free(desc); + } + } // This has been changed in upstream SSL to have a const // parameter, so we cast away const for older versions compatibility // (Upstream commit: c04b66b18d1a90f0c6326858e4b8367be5444582)