From d3d6cd3ecad19602a894bbe046253ae924d278d4 Mon Sep 17 00:00:00 2001 From: Gireesh Punathil Date: Mon, 24 Sep 2018 04:58:29 -0400 Subject: [PATCH] src: improve SSL version extraction logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The openssl version as defined in ssl libraries is complex. The current logic to extract the major.minor.patch format uses C semantics to loop through the text and search for specific patterns. Use C++ string to tidy it up. PR-URL: https://github.com/nodejs/node/pull/23050 Reviewed-By: Anna Henningsen Reviewed-By: Tobias Nießen Reviewed-By: Colin Ihrig Reviewed-By: Richard Lau Reviewed-By: Refael Ackermann Reviewed-By: Sakthipriyan Vairamani Reviewed-By: James M Snell Reviewed-By: Luigi Pinca Reviewed-By: Michael Dawson --- src/node.cc | 43 +++++-------------------------------------- src/node_crypto.cc | 15 +++++++++++++++ src/node_crypto.h | 1 + 3 files changed, 21 insertions(+), 38 deletions(-) diff --git a/src/node.cc b/src/node.cc index e85fab676083cd..f703b4abf6a498 100644 --- a/src/node.cc +++ b/src/node.cc @@ -232,24 +232,7 @@ class NodeTraceStateObserver : trace_process->SetString("napi", node_napi_version); #if HAVE_OPENSSL - // Stupid code to slice out the version string. - { // NOLINT(whitespace/braces) - size_t i, j, k; - int c; - for (i = j = 0, k = sizeof(OPENSSL_VERSION_TEXT) - 1; i < k; ++i) { - c = OPENSSL_VERSION_TEXT[i]; - if ('0' <= c && c <= '9') { - for (j = i + 1; j < k; ++j) { - c = OPENSSL_VERSION_TEXT[j]; - if (c == ' ') - break; - } - break; - } - } - trace_process->SetString("openssl", - std::string(&OPENSSL_VERSION_TEXT[i], j - i)); - } + trace_process->SetString("openssl", crypto::GetOpenSSLVersion()); #endif trace_process->EndDictionary(); @@ -1762,26 +1745,10 @@ void SetupProcessObject(Environment* env, FIXED_ONE_BYTE_STRING(env->isolate(), node_napi_version)); #if HAVE_OPENSSL - // Stupid code to slice out the version string. - { // NOLINT(whitespace/braces) - size_t i, j, k; - int c; - for (i = j = 0, k = sizeof(OPENSSL_VERSION_TEXT) - 1; i < k; ++i) { - c = OPENSSL_VERSION_TEXT[i]; - if ('0' <= c && c <= '9') { - for (j = i + 1; j < k; ++j) { - c = OPENSSL_VERSION_TEXT[j]; - if (c == ' ') - break; - } - break; - } - } - READONLY_PROPERTY( - versions, - "openssl", - OneByteString(env->isolate(), &OPENSSL_VERSION_TEXT[i], j - i)); - } + READONLY_PROPERTY( + versions, + "openssl", + OneByteString(env->isolate(), crypto::GetOpenSSLVersion().c_str())); #endif // process.arch diff --git a/src/node_crypto.cc b/src/node_crypto.cc index dd7e0c84681438..96f4cf2ba7076d 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -5734,6 +5734,21 @@ void Initialize(Local target, #endif // OPENSSL_NO_SCRYPT } +constexpr int search(const char* s, int n, int c) { + return *s == c ? n : search(s + 1, n + 1, c); +} + +std::string GetOpenSSLVersion() { + // sample openssl version string format + // for reference: "OpenSSL 1.1.0i 14 Aug 2018" + char buf[128]; + const int start = search(OPENSSL_VERSION_TEXT, 0, ' ') + 1; + const int end = search(OPENSSL_VERSION_TEXT + start, start, ' ') + 1; + const int len = end - start; + snprintf(buf, len, "%.*s\n", len, &OPENSSL_VERSION_TEXT[start]); + return std::string(buf); +} + } // namespace crypto } // namespace node diff --git a/src/node_crypto.h b/src/node_crypto.h index 2ca333f3c22d12..f4afd2fdaf5758 100644 --- a/src/node_crypto.h +++ b/src/node_crypto.h @@ -93,6 +93,7 @@ extern int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx); extern void UseExtraCaCerts(const std::string& file); void InitCryptoOnce(); +std::string GetOpenSSLVersion(); class SecureContext : public BaseObject { public: