From 9acb9b5507f714ca19e75fbbc45a044fcae743fd Mon Sep 17 00:00:00 2001 From: Jun Aruga Date: Thu, 16 Mar 2023 21:36:43 +0100 Subject: [PATCH] Fix the fips_mode_get on OpenSSL 3. This commit only fixes the issue that the `OpenSSL.fips_mode` returns `false` on OpenSSL 3 FIPS mode enabled environment, while other tests fail on the environment. I believe that this minimal fix is a good start to make Ruby OpenSSL work on the OpenSSL 3 FIPS mode enabled environment with the CI case. It seems that the `OPENSSL_FIPS` macro is not used on the FIPS mode case any more on OpenSSL 3. The API `FIPS_mode` also was removed in OpenSSL 3. See the document the section OPENSSL 3.0 > Main Changes from OpenSSL 1.1.1 > Other notable deprecations and changes - Removed FIPS_mode() and FIPS_mode_set() . The `TEST_RUBY_OPENSSL_FIPS_ENABLED` is set on the FIPS mode case on the CI. Because I want to test that the `OpenSSL.fips_mode` returning the `true` or 'false' in the CI. Right now we don't find a reliable way to get the capability of OpenSSL 3 for the FIPS mode. --- ext/openssl/ossl.c | 6 +++++- test/openssl/test_fips.rb | 27 ++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index 6c532aca9..c1e1ba80e 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; diff --git a/test/openssl/test_fips.rb b/test/openssl/test_fips.rb index 03f7761a0..803480a4e 100644 --- a/test/openssl/test_fips.rb +++ b/test/openssl/test_fips.rb @@ -4,12 +4,37 @@ if defined?(OpenSSL) class OpenSSL::TestFIPS < OpenSSL::TestCase + def test_fips_mode_get_is_true_on_fips_mode_enabled + unless ENV["CI"] && ENV["TEST_RUBY_OPENSSL_FIPS_ENABLED"] + omit "Only for on FIPS mode environment on CI" + end + + assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;") + assert OpenSSL.fips_mode == true, ".fips_mode returns true on FIPS mode enabled" + end; + end + + def test_fips_mode_get_is_false_on_fips_mode_disabled + unless ENV["CI"] && !ENV["TEST_RUBY_OPENSSL_FIPS_ENABLED"] + omit "Only for non-FIPS mode environment on CI" + end + + assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;") + assert OpenSSL.fips_mode == false, ".fips_mode returns false on FIPS mode disabled" + end; + end + def test_fips_mode_is_reentrant OpenSSL.fips_mode = false OpenSSL.fips_mode = false end - def test_fips_mode_get + def test_fips_mode_get_with_fips_mode_set + if openssl?(3, 0, 0) + pend('OpenSSL::OPENSSL_FIPS and fips_mode_set are not properly ' \ + 'implemented in OpenSSL 3') + end + return unless OpenSSL::OPENSSL_FIPS assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;") begin