143 lines
5.3 KiB
Diff
143 lines
5.3 KiB
Diff
From 29920ec109751459a65c6478525f2e59c644891f Mon Sep 17 00:00:00 2001
|
|
From: Jun Aruga <jaruga@redhat.com>
|
|
Date: Thu, 16 Mar 2023 21:36:43 +0100
|
|
Subject: [PATCH] [ruby/openssl] Implement FIPS functions on OpenSSL 3.
|
|
|
|
This commit is to implement the `OpenSSL::OPENSSL_FIPS`, `ossl_fips_mode_get`
|
|
and `ossl_fips_mode_set` to pass the test `test/openssl/test_fips.rb`.
|
|
|
|
It seems that the `OPENSSL_FIPS` macro is not used on the FIPS mode case any
|
|
more, and some FIPS related APIs also were removed in OpenSSL 3.
|
|
|
|
See the document <https://github.com/openssl/openssl/blob/master/doc/man7/migration_guide.pod#removed-fips_mode-and-fips_mode_set>
|
|
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 `OpenSSL::OPENSSL_FIPS` returns always true in OpenSSL 3 because the used
|
|
functions `EVP_default_properties_enable_fips` and `EVP_default_properties_is_fips_enabled`
|
|
works with the OpenSSL installed without FIPS option.
|
|
|
|
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` returns the `true` or
|
|
'false' surely in the CI. You can test the FIPS mode case by setting
|
|
`TEST_RUBY_OPENSSL_FIPS_ENABLED` on local too. Right now I don't find a better
|
|
way to get the status of the FIPS mode enabled or disabled for this purpose. I
|
|
am afraid of the possibility that the FIPS test case is unintentionally skipped.
|
|
|
|
I also replaced the ambiguous "returns" with "should return" in the tests.
|
|
|
|
https://github.com/ruby/openssl/commit/c5b2bc1268
|
|
---
|
|
ext/openssl/ossl.c | 25 +++++++++++++++++++++----
|
|
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 6c532aca94..fcf3744c65 100644
|
|
--- a/ext/openssl/ossl.c
|
|
+++ b/ext/openssl/ossl.c
|
|
@@ -405,7 +405,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;
|
|
@@ -429,8 +433,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 */
|
|
@@ -1185,7 +1199,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 8cd474f9a3..56a12a94ce 100644
|
|
--- a/test/openssl/test_fips.rb
|
|
+++ b/test/openssl/test_fips.rb
|
|
@@ -4,22 +4,46 @@
|
|
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;")
|
|
require #{__FILE__.dump}
|
|
|
|
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
|
|
--
|
|
2.41.0
|
|
|