Bug 2100926 - python3-paramiko packages fails with for load md5 crypto module on FIPS enabled system [NEEDINFO]
Summary: python3-paramiko packages fails with for load md5 crypto module on FIPS enabl...
Keywords:
Status: NEW
Alias: None
Product: Red Hat OpenStack
Classification: Red Hat
Component: python-paramiko
Version: 16.2 (Train)
Hardware: All
OS: Linux
unspecified
medium
Target Milestone: ga
: ---
Assignee: Ade Lee
QA Contact: Nobody
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2022-06-24 17:32 UTC by Ameya Patil
Modified: 2023-08-03 15:46 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed:
Target Upstream Version:
Embargoed:
dwilde: needinfo? (alee)
ifrangs: needinfo? (alee)


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Issue Tracker OSP-16008 0 None None None 2022-06-24 17:34:08 UTC

Description Ameya Patil 2022-06-24 17:32:32 UTC
Description of problem:

python3-paramiko packages fails with for load md5 crypto module on FIPS enabled system 

I test with both versions - `2.4.2-7.el8ost.1` and `2.4.2-2.el8ost` for the python3-paramiko package and they both fail with the same error.
I have tested this on RHEL 8.6 installation instead of directly on top of RHEL OpenStack.

While trying to load the md5 function we see error 
~~~
  File "/usr/lib/python3.6/site-packages/paramiko/pkey.py", line 151, in get_fingerprint
    return md5(self.asbytes()).digest()
ValueError: [digital envelope routines: EVP_DigestInit_ex] disabled for FIPS
~~~

On system with FIPS disabled we dont see this issue.


Version-Release number of selected component (if applicable):

# rpm -q python3-paramiko
python3-paramiko-2.4.2-7.el8ost.1.noarch



How reproducible:
Everytime with FIPS enabled.

Steps to Reproduce:
1. Ensure the system is booted with FIPS enabled 
~~~
#  fips-mode-setup --check
FIPS mode is enabled.
~~~

2. Generate ssh keys
~~~
# ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
~~~

3. Convert SSH keys to PEM format otherwise it does not recognize Private keys and fails with an error `paramiko.ssh_exception.SSHException: not a valid RSA private key file` 
~~~
# ssh-keygen -p -f /root/.ssh/id_rsa -m pem
Key has comment 'root.example.local'
Enter new passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved with the new passphrase.
~~~

4. Copy the ssh keys to the target host.

   # ssh-copy-id root.122.201


5. Connect to the system with paramiko fails with error while executing function `md5(self.asbytes()).digest()` with error for `EVP_DigestInit_ex` disabled for FIPS.
~~~
$ python3  -c "import paramiko; client=paramiko.SSHClient() ; client.load_system_host_keys() ; client.connect('192.168.122.201')"
/usr/lib/python3.6/site-packages/paramiko/ecdsakey.py:164: CryptographyDeprecationWarning: Support for unsafe construction of public numbers from encoded data will be removed in a future version. Please use EllipticCurvePublicKey.from_encoded_point
  self.ecdsa_curve.curve_class(), pointinfo
/usr/lib/python3.6/site-packages/paramiko/kex_ecdh_nist.py:39: CryptographyDeprecationWarning: encode_point has been deprecated on EllipticCurvePublicNumbers and will be removed in a future version. Please use EllipticCurvePublicKey.public_bytes to obtain both compressed and uncompressed point encoding.
  m.add_string(self.Q_C.public_numbers().encode_point())
/usr/lib/python3.6/site-packages/paramiko/kex_ecdh_nist.py:96: CryptographyDeprecationWarning: Support for unsafe construction of public numbers from encoded data will be removed in a future version. Please use EllipticCurvePublicKey.from_encoded_point
  self.curve, Q_S_bytes
/usr/lib/python3.6/site-packages/paramiko/kex_ecdh_nist.py:111: CryptographyDeprecationWarning: encode_point has been deprecated on EllipticCurvePublicNumbers and will be removed in a future version. Please use EllipticCurvePublicKey.public_bytes to obtain both compressed and uncompressed point encoding.
  hm.add_string(self.Q_C.public_numbers().encode_point())
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.6/site-packages/paramiko/client.py", line 437, in connect
    passphrase,
  File "/usr/lib/python3.6/site-packages/paramiko/client.py", line 720, in _auth
    filename, pkey_class, passphrase
  File "/usr/lib/python3.6/site-packages/paramiko/client.py", line 576, in _key_from_filepath
    hexlify(key.get_fingerprint()), key_path
  File "/usr/lib/python3.6/site-packages/paramiko/pkey.py", line 151, in get_fingerprint
    return md5(self.asbytes()).digest()
ValueError: [digital envelope routines: EVP_DigestInit_ex] disabled for FIPS
~~~

Actual results:
System fails to connect with python3-paramiko with FIPS enabled.

Expected results:
System should be able to connect with FIPS enabled.


Additional info:

I see this package tagged to the Openstack 16.2 repository hence marking this bug under RHEL Openstack

Comment 1 Ade Lee 2022-06-27 21:38:54 UTC
This is a known issue in paramiko for which I have submitted a patch to upstream paramiko, but which, unfortunately, has not yet been acted on.

https://github.com/paramiko/paramiko/pull/1928

Merging fixes into paramiko is incredibly slow, so we've had to resort to monkey-patching paramiko to get things working.

https://review.opendev.org/c/openstack/manila/+/819375/7/manila/utils.py#74

is an example - where we use the usedforsecurity flag to allow the md5 to be permitted in FIPS mode.

Ultimately, though, you should keep in mind that paramiko has many problems when it comes to FIPS compliance.  There are places where it uses
non-FIPS compliant crypto libraries, or implements its own crypto etc.  In OpenStack, we may end up completely replacing paramiko to make sure
we are using something that is FIPS compliant.  Doing that is a long process though.

For now, doing a simple monkey-patch as above should get you pretty much working.


Note You need to log in before you can comment on or make changes to this bug.