diff options
-rw-r--r-- | ext/openssl/ossl.c | 25 | ||||
-rw-r--r-- | test/openssl/test_fips.rb | 32 |
2 files changed, 49 insertions, 8 deletions
diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index 71ddcb9f02..be97b97a1a 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -418,7 +418,11 @@ static VALUE ossl_fips_mode_get(VALUE self) { -#ifdef OPENSSL_FIPS +#if OSSL_OPENSSL_PREREQ(3, 0, 0) + VALUE enabled; + enabled = EVP_default_properties_is_fips_enabled(NULL) ? Qtrue : Qfalse; + return enabled; +#elif OPENSSL_FIPS VALUE enabled; enabled = FIPS_mode() ? Qtrue : Qfalse; return enabled; @@ -442,8 +446,18 @@ ossl_fips_mode_get(VALUE self) static VALUE ossl_fips_mode_set(VALUE self, VALUE enabled) { - -#ifdef OPENSSL_FIPS +#if OSSL_OPENSSL_PREREQ(3, 0, 0) + if (RTEST(enabled)) { + if (!EVP_default_properties_enable_fips(NULL, 1)) { + ossl_raise(eOSSLError, "Turning on FIPS mode failed"); + } + } else { + if (!EVP_default_properties_enable_fips(NULL, 0)) { + ossl_raise(eOSSLError, "Turning off FIPS mode failed"); + } + } + return enabled; +#elif OPENSSL_FIPS if (RTEST(enabled)) { int mode = FIPS_mode(); if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */ @@ -1198,7 +1212,10 @@ Init_openssl(void) * Boolean indicating whether OpenSSL is FIPS-capable or not */ rb_define_const(mOSSL, "OPENSSL_FIPS", -#ifdef OPENSSL_FIPS +/* OpenSSL 3 is FIPS-capable even when it is installed without fips option */ +#if OSSL_OPENSSL_PREREQ(3, 0, 0) + Qtrue +#elif OPENSSL_FIPS Qtrue #else Qfalse diff --git a/test/openssl/test_fips.rb b/test/openssl/test_fips.rb index 03f7761a03..dfc1729b35 100644 --- a/test/openssl/test_fips.rb +++ b/test/openssl/test_fips.rb @@ -4,20 +4,44 @@ require_relative 'utils' if defined?(OpenSSL) class OpenSSL::TestFIPS < OpenSSL::TestCase + def test_fips_mode_get_is_true_on_fips_mode_enabled + unless ENV["TEST_RUBY_OPENSSL_FIPS_ENABLED"] + omit "Only for FIPS mode environment" + end + + assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;") + assert OpenSSL.fips_mode == true, ".fips_mode should return true on FIPS mode enabled" + end; + end + + def test_fips_mode_get_is_false_on_fips_mode_disabled + if ENV["TEST_RUBY_OPENSSL_FIPS_ENABLED"] + omit "Only for non-FIPS mode environment" + end + + assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;") + message = ".fips_mode should return false on FIPS mode disabled. " \ + "If you run the test on FIPS mode, please set " \ + "TEST_RUBY_OPENSSL_FIPS_ENABLED=true" + assert OpenSSL.fips_mode == false, message + end; + end + def test_fips_mode_is_reentrant OpenSSL.fips_mode = false OpenSSL.fips_mode = false end - def test_fips_mode_get - return unless OpenSSL::OPENSSL_FIPS + def test_fips_mode_get_with_fips_mode_set + omit('OpenSSL is not FIPS-capable') unless OpenSSL::OPENSSL_FIPS + assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;") begin OpenSSL.fips_mode = true - assert OpenSSL.fips_mode == true, ".fips_mode returns true when .fips_mode=true" + assert OpenSSL.fips_mode == true, ".fips_mode should return true when .fips_mode=true" OpenSSL.fips_mode = false - assert OpenSSL.fips_mode == false, ".fips_mode returns false when .fips_mode=false" + assert OpenSSL.fips_mode == false, ".fips_mode should return false when .fips_mode=false" rescue OpenSSL::OpenSSLError pend "Could not set FIPS mode (OpenSSL::OpenSSLError: \#$!); skipping" end |