Skip to content

Commit 00fb72f

Browse files
committed
Implement the 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. Right now I don't find a better way to get the status of the FIPS mode enabled or disabled of OpenSSL 3 for this purpose. I am afraid of the possibility that the FIPS tests are unintentionally skipped.
1 parent f4c0fc2 commit 00fb72f

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

ext/openssl/ossl.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,11 @@ static VALUE
418418
ossl_fips_mode_get(VALUE self)
419419
{
420420

421-
#ifdef OPENSSL_FIPS
421+
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
422+
VALUE enabled;
423+
enabled = EVP_default_properties_is_fips_enabled(NULL) ? Qtrue : Qfalse;
424+
return enabled;
425+
#elif OPENSSL_FIPS
422426
VALUE enabled;
423427
enabled = FIPS_mode() ? Qtrue : Qfalse;
424428
return enabled;
@@ -442,8 +446,18 @@ ossl_fips_mode_get(VALUE self)
442446
static VALUE
443447
ossl_fips_mode_set(VALUE self, VALUE enabled)
444448
{
445-
446-
#ifdef OPENSSL_FIPS
449+
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
450+
if (RTEST(enabled)) {
451+
if (!EVP_default_properties_enable_fips(NULL, 1)) {
452+
ossl_raise(eOSSLError, "Turning on FIPS mode failed");
453+
}
454+
} else {
455+
if (!EVP_default_properties_enable_fips(NULL, 0)) {
456+
ossl_raise(eOSSLError, "Turning off FIPS mode failed");
457+
}
458+
}
459+
return enabled;
460+
#elif OPENSSL_FIPS
447461
if (RTEST(enabled)) {
448462
int mode = FIPS_mode();
449463
if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */
@@ -1198,7 +1212,10 @@ Init_openssl(void)
11981212
* Boolean indicating whether OpenSSL is FIPS-capable or not
11991213
*/
12001214
rb_define_const(mOSSL, "OPENSSL_FIPS",
1201-
#ifdef OPENSSL_FIPS
1215+
/* OpenSSL 3 is FIPS-capable even when it is installed without fips option */
1216+
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
1217+
Qtrue
1218+
#elif OPENSSL_FIPS
12021219
Qtrue
12031220
#else
12041221
Qfalse

test/openssl/test_fips.rb

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,34 @@
44
if defined?(OpenSSL)
55

66
class OpenSSL::TestFIPS < OpenSSL::TestCase
7+
def test_fips_mode_get_is_true_on_fips_mode_enabled
8+
unless ENV["CI"] && ENV["TEST_RUBY_OPENSSL_FIPS_ENABLED"]
9+
omit "Only for on FIPS mode environment on CI"
10+
end
11+
12+
assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;")
13+
assert OpenSSL.fips_mode == true, ".fips_mode returns true on FIPS mode enabled"
14+
end;
15+
end
16+
17+
def test_fips_mode_get_is_false_on_fips_mode_disabled
18+
unless ENV["CI"] && !ENV["TEST_RUBY_OPENSSL_FIPS_ENABLED"]
19+
omit "Only for non-FIPS mode environment on CI"
20+
end
21+
22+
assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;")
23+
assert OpenSSL.fips_mode == false, ".fips_mode returns false on FIPS mode disabled"
24+
end;
25+
end
26+
727
def test_fips_mode_is_reentrant
828
OpenSSL.fips_mode = false
929
OpenSSL.fips_mode = false
1030
end
1131

12-
def test_fips_mode_get
13-
return unless OpenSSL::OPENSSL_FIPS
32+
def test_fips_mode_get_with_fips_mode_set
33+
omit('OpenSSL is not FIPS-capable') unless OpenSSL::OPENSSL_FIPS
34+
1435
assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;")
1536
begin
1637
OpenSSL.fips_mode = true

0 commit comments

Comments
 (0)