You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by ab...@apache.org on 2020/11/02 14:37:15 UTC

[kudu] branch master updated: KUDU-3210 Add option to enforce FIPS approved mode

This is an automated email from the ASF dual-hosted git repository.

abukor pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git


The following commit(s) were added to refs/heads/master by this push:
     new 6d2c79a  KUDU-3210 Add option to enforce FIPS approved mode
6d2c79a is described below

commit 6d2c79a4f266932b644f1cf7165ad3b6ccc49404
Author: Attila Bukor <ab...@apache.org>
AuthorDate: Tue Oct 20 19:58:25 2020 +0200

    KUDU-3210 Add option to enforce FIPS approved mode
    
    If KUDU_REQUIRE_FIPS_MODE is set to "1", "true" or "yes", Kudu checks if
    FIPS mode is enabled and crashes when initializing OpenSSL if not. This
    is also true for Kudu C++ client applications.
    
    On initializing OpenSSL, Kudu now also verbose logs (level 2) if FIPS
    mode is enabled regardless of whether it's required or not.
    
    Change-Id: I98a6a8b3330ea0b372b188690fadd4d312d8bf93
    Reviewed-on: http://gerrit.cloudera.org:8080/16657
    Reviewed-by: Alexey Serbin <as...@cloudera.com>
    Tested-by: Kudu Jenkins
---
 src/kudu/security/openssl_util.cc | 36 ++++++++++++++++++++++--------------
 src/kudu/util/flags.cc            | 22 ++++++++++++++++++++++
 src/kudu/util/flags.h             |  2 ++
 src/kudu/util/test_util.cc        | 29 ++---------------------------
 4 files changed, 48 insertions(+), 41 deletions(-)

diff --git a/src/kudu/security/openssl_util.cc b/src/kudu/security/openssl_util.cc
index e6a693b..8967557 100644
--- a/src/kudu/security/openssl_util.cc
+++ b/src/kudu/security/openssl_util.cc
@@ -37,6 +37,7 @@
 #include "kudu/util/debug/leakcheck_disabler.h"
 #endif
 #include "kudu/util/errno.h"
+#include "kudu/util/flags.h"
 #if OPENSSL_VERSION_NUMBER < 0x10100000L
 #include "kudu/util/mutex.h"
 #endif
@@ -86,6 +87,18 @@ void LockingCB(int mode, int type, const char* /*file*/, int /*line*/) {
 }
 #endif
 
+void CheckFIPSMode() {
+  auto fips_mode = FIPS_mode();
+  // If the environment variable KUDU_REQUIRE_FIPS_MODE is set to "1", we
+  // check if FIPS approved mode is enabled. If not, we crash the process.
+  // As this is used in clients as well, we can't use gflags to set this.
+  if (GetBooleanEnvironmentVariable("KUDU_REQUIRE_FIPS_MODE")) {
+    CHECK(fips_mode) << "FIPS mode required by environment variable "
+                        "KUDU_REQUIRE_FIPS_MODE, but it is not enabled.";
+  }
+  VLOG(2) << "FIPS mode is " << (fips_mode ? "enabled" : "disabled.");
+}
+
 Status CheckOpenSSLInitialized() {
 #if OPENSSL_VERSION_NUMBER < 0x10100000L
   // Starting with OpenSSL 1.1.0, the old thread API became obsolete
@@ -117,10 +130,18 @@ Status CheckOpenSSLInitialized() {
         "SSL library appears uninitialized (cannot create SSL_CTX)");
   }
 #endif
+  CheckFIPSMode();
   return Status::OK();
 }
 
 void DoInitializeOpenSSL() {
+  // In case the user's thread has left some error around, clear it.
+  ERR_clear_error();
+  SCOPED_OPENSSL_NO_PENDING_ERRORS;
+  if (g_disable_ssl_init) {
+    VLOG(2) << "Not initializing OpenSSL (disabled by application)";
+    return;
+  }
 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
   // The OPENSSL_init_ssl manpage [1] says "As of version 1.1.0 OpenSSL will
   // automatically allocate all resources it needs so no explicit initialisation
@@ -136,21 +157,8 @@ void DoInitializeOpenSSL() {
   //
   // 1. https://www.openssl.org/docs/man1.1.0/ssl/OPENSSL_init_ssl.html
   // 2. https://github.com/openssl/openssl/issues/5899
-  if (g_disable_ssl_init) {
-    VLOG(2) << "Not initializing OpenSSL (disabled by application)";
-    return;
-  }
   CHECK_EQ(1, OPENSSL_init_ssl(0, nullptr));
-  SCOPED_OPENSSL_NO_PENDING_ERRORS;
 #else
-  // In case the user's thread has left some error around, clear it.
-  ERR_clear_error();
-  SCOPED_OPENSSL_NO_PENDING_ERRORS;
-  if (g_disable_ssl_init) {
-    VLOG(2) << "Not initializing OpenSSL (disabled by application)";
-    return;
-  }
-
   // Check that OpenSSL isn't already initialized. If it is, it's likely
   // we are embedded in (or embedding) another application/library which
   // initializes OpenSSL, and we risk installing conflicting callbacks
@@ -191,7 +199,7 @@ void DoInitializeOpenSSL() {
     CRYPTO_set_locking_callback(LockingCB);
   }
 #endif
-
+  CheckFIPSMode();
   g_ssl_is_initialized = true;
 }
 
diff --git a/src/kudu/util/flags.cc b/src/kudu/util/flags.cc
index 4e6c98e..13643fa 100644
--- a/src/kudu/util/flags.cc
+++ b/src/kudu/util/flags.cc
@@ -17,10 +17,12 @@
 
 #include "kudu/util/flags.h"
 
+#include <strings.h>
 #include <sys/stat.h>
 #include <unistd.h> // IWYU pragma: keep
 
 #include <cstdlib>
+#include <cstring>
 #include <functional>
 #include <iostream>
 #include <map>
@@ -607,4 +609,24 @@ Status ParseTriState(const char* flag_name, const std::string& flag_value,
   return Status::OK();
 }
 
+// Get the value of an environment variable that has boolean semantics.
+bool GetBooleanEnvironmentVariable(const char* env_var_name) {
+  const char* const e = getenv(env_var_name);
+  if ((e == nullptr) ||
+      (strlen(e) == 0) ||
+      (strcasecmp(e, "false") == 0) ||
+      (strcasecmp(e, "0") == 0) ||
+      (strcasecmp(e, "no") == 0)) {
+    return false;
+  }
+  if ((strcasecmp(e, "true") == 0) ||
+      (strcasecmp(e, "1") == 0) ||
+      (strcasecmp(e, "yes") == 0)) {
+    return true;
+  }
+  LOG(FATAL) << Substitute("$0: invalid value for environment variable $0",
+                           e, env_var_name);
+  return false;  // unreachable
+}
+
 } // namespace kudu
diff --git a/src/kudu/util/flags.h b/src/kudu/util/flags.h
index 033a57f..98f8cb8 100644
--- a/src/kudu/util/flags.h
+++ b/src/kudu/util/flags.h
@@ -90,5 +90,7 @@ Status ParseTriState(const char* flag_name, const std::string& flag_value,
 
 std::string CheckFlagAndRedact(const google::CommandLineFlagInfo& flag, EscapeMode mode);
 
+bool GetBooleanEnvironmentVariable(const char* env_var_name);
+
 } // namespace kudu
 #endif /* KUDU_UTIL_FLAGS_H */
diff --git a/src/kudu/util/test_util.cc b/src/kudu/util/test_util.cc
index 48fa73a..13a5e3d 100644
--- a/src/kudu/util/test_util.cc
+++ b/src/kudu/util/test_util.cc
@@ -18,12 +18,10 @@
 #include "kudu/util/test_util.h"
 
 #include <limits.h>
-#include <strings.h>
 #include <unistd.h>
 
 #include <cerrno>
 #include <cstdlib>
-#include <cstring>
 #include <limits>
 #include <map>
 #include <memory>
@@ -51,6 +49,7 @@
 #include "kudu/gutil/walltime.h"
 #include "kudu/util/env.h"
 #include "kudu/util/faststring.h"
+#include "kudu/util/flags.h"
 #include "kudu/util/oid_generator.h"
 #include "kudu/util/path_util.h"
 #include "kudu/util/scoped_cleanup.h"
@@ -180,31 +179,7 @@ void KuduTest::OverrideKrb5Environment() {
 // Test utility functions
 ///////////////////////////////////////////////////
 
-namespace {
-// Get the value of an environment variable that has boolean semantics.
-bool GetBooleanEnvironmentVariable(const char* env_var_name) {
-  const char* const e = getenv(env_var_name);
-  if ((e == nullptr) ||
-      (strlen(e) == 0) ||
-      (strcasecmp(e, "false") == 0) ||
-      (strcasecmp(e, "0") == 0) ||
-      (strcasecmp(e, "no") == 0)) {
-    return false;
-  }
-  if ((strcasecmp(e, "true") == 0) ||
-      (strcasecmp(e, "1") == 0) ||
-      (strcasecmp(e, "yes") == 0)) {
-    return true;
-  }
-  LOG(FATAL) << Substitute("$0: invalid value for environment variable $0",
-                           e, env_var_name);
-  return false;  // unreachable
-}
-} // anonymous namespace
-
-bool AllowSlowTests() {
-  return GetBooleanEnvironmentVariable(kSlowTestsEnvVar);
-}
+bool AllowSlowTests() { return GetBooleanEnvironmentVariable(kSlowTestsEnvVar); }
 
 void OverrideFlagForSlowTests(const std::string& flag_name,
                               const std::string& new_value) {