ipa/SOURCES/0019-Vault-add-support-for-RSA-OAEP-wrapping-algo.patch

128 lines
4.7 KiB
Diff
Raw Permalink Normal View History

From 163f06cab678d517ab30ab6da59ae339f39ee7cf Mon Sep 17 00:00:00 2001
From: Francisco Trivino <ftrivino@redhat.com>
Date: Fri, 27 May 2022 17:31:40 +0200
Subject: [PATCH] Vault: add support for RSA-OAEP wrapping algo
None of the FIPS certified modules in RHEL support PKCS#1 v1.5 as FIPS
approved mechanism. This commit adds support for RSA-OAEP padding as a
fallback.
Fixes: https://pagure.io/freeipa/issue/9191
Signed-off-by: Francisco Trivino <ftrivino@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
(cherry picked from commit b1fb31fd20c900c9ff1d5d28dfe136439f6bf605)
---
ipaclient/plugins/vault.py | 57 ++++++++++++++++++++++++++++++--------
1 file changed, 45 insertions(+), 12 deletions(-)
diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
index d4c84eb6b..ed16c73ae 100644
--- a/ipaclient/plugins/vault.py
+++ b/ipaclient/plugins/vault.py
@@ -119,8 +119,8 @@ def encrypt(data, symmetric_key=None, public_key=None):
return public_key_obj.encrypt(
data,
padding.OAEP(
- mgf=padding.MGF1(algorithm=hashes.SHA1()),
- algorithm=hashes.SHA1(),
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
+ algorithm=hashes.SHA256(),
label=None
)
)
@@ -154,8 +154,8 @@ def decrypt(data, symmetric_key=None, private_key=None):
return private_key_obj.decrypt(
data,
padding.OAEP(
- mgf=padding.MGF1(algorithm=hashes.SHA1()),
- algorithm=hashes.SHA1(),
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
+ algorithm=hashes.SHA256(),
label=None
)
)
@@ -705,14 +705,39 @@ class ModVaultData(Local):
return transport_cert, wrapping_algo
def _do_internal(self, algo, transport_cert, raise_unexpected,
- *args, **options):
+ use_oaep=False, *args, **options):
public_key = transport_cert.public_key()
# wrap session key with transport certificate
- wrapped_session_key = public_key.encrypt(
- algo.key,
- padding.PKCS1v15()
- )
+ # KRA may be configured using either the default PKCS1v15 or RSA-OAEP.
+ # there is no way to query this info using the REST interface.
+ if not use_oaep:
+ # PKCS1v15() causes an OpenSSL exception when FIPS is enabled
+ # if so, we fallback to RSA-OAEP
+ try:
+ wrapped_session_key = public_key.encrypt(
+ algo.key,
+ padding.PKCS1v15()
+ )
+ except ValueError:
+ wrapped_session_key = public_key.encrypt(
+ algo.key,
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
+ algorithm=hashes.SHA256(),
+ label=None
+ )
+ )
+ else:
+ wrapped_session_key = public_key.encrypt(
+ algo.key,
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
+ algorithm=hashes.SHA256(),
+ label=None
+ )
+ )
+
options['session_key'] = wrapped_session_key
name = self.name + '_internal'
@@ -723,7 +748,7 @@ class ModVaultData(Local):
errors.ExecutionError,
errors.GenericError):
_kra_config_cache.remove(self.api.env.domain)
- if raise_unexpected:
+ if raise_unexpected and use_oaep:
raise
return None
@@ -733,15 +758,23 @@ class ModVaultData(Local):
"""
# try call with cached transport certificate
result = self._do_internal(algo, transport_cert, False,
- *args, **options)
+ False, *args, **options)
if result is not None:
return result
# retrieve transport certificate (cached by vaultconfig_show)
transport_cert = self._get_vaultconfig(force_refresh=True)[0]
+
# call with the retrieved transport certificate
+ result = self._do_internal(algo, transport_cert, True,
+ False, *args, **options)
+
+ if result is not None:
+ return result
+
+ # call and use_oaep this time, last attempt
return self._do_internal(algo, transport_cert, True,
- *args, **options)
+ True, *args, **options)
@register(no_fail=True)
--
2.43.0