RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
Bug 2060343 - openssl-3.0.1-14.el9 creates invalid RSA PKCS1v1.5 SHA-1 signature
Summary: openssl-3.0.1-14.el9 creates invalid RSA PKCS1v1.5 SHA-1 signature
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 9
Classification: Red Hat
Component: python-cryptography
Version: 9.0
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: rc
: ---
Assignee: Christian Heimes
QA Contact: Kaleem
URL:
Whiteboard:
Depends On: 2059630
Blocks: 2062822
TreeView+ depends on / blocked
 
Reported: 2022-03-03 11:14 UTC by Christian Heimes
Modified: 2022-05-17 13:47 UTC (History)
5 users (show)

Fixed In Version: python-cryptography-36.0.1-1.el9_0
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
: 2062822 (view as bug list)
Environment:
Last Closed: 2022-05-17 13:45:50 UTC
Type: Bug
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
test script (2.55 KB, text/x-python3)
2022-03-03 11:14 UTC, Christian Heimes
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Github pyca cryptography issues 6927 0 None open Insufficient error check in RSA: EVP_PKEY_CTX_set_signature_md() can return < 0 2022-03-03 13:09:48 UTC
Red Hat Bugzilla 2031742 1 medium CLOSED Implement a new config option to enable SHA-1 signatures 2023-10-13 08:26:43 UTC
Red Hat Issue Tracker FREEIPA-7925 0 None None None 2022-03-03 13:21:33 UTC
Red Hat Issue Tracker RHELPLAN-114339 0 None None None 2022-03-03 11:18:08 UTC
Red Hat Product Errata RHBA-2022:2580 0 None None None 2022-05-17 13:46:06 UTC

Description Christian Heimes 2022-03-03 11:14:58 UTC
Created attachment 1863964 [details]
test script

Description of problem:
openssl-3.0.1-14.el9 creates invalid signatures for combination of RSA, PKCS#1 v1.5 and SHA-1 signature algorithm. The problem is self-contained, meaning signature verification with openssl-3.0.1-14.el9 succeeds. The signature does not match the signature

Version-Release number of selected component (if applicable):
openssl-3.0.1-14.el9.x86_64
crypto-policies-20220223-1.git5203b41.el9.noarch
python3-cryptography-3.4.7-8.el9.x86_64

How reproducible:
Always

Steps to Reproduce:
1. Run attached test script

Actual results:
958e6fd3db8c824c806f4fe7dd45f91f9e1c08d0992959cb5ef0b65bb57636173c1fd3284f4a5da530820436c94d4b9bc9f4932614242a01ceb1c16fee0b9e1acc7c36ec5bf0300d293f43046454cb3500a3d40c687da6e4cbb00985d14e752b67a8a9b6e51ab9104edb26b5a4b38afc76e096d04b6999d13b92eb5abfbc3c9e984ee83e65f4e1343925ff749eaec043871cfec64c2f88cac7e70417279964116ee7beb776987604a8fe2dd34ea1343b1248c48261e1dff9e4f2bf2d83101f6641eb1b9bd6211f834702e7d32174d918e032cbb589922f97bbdc796623a2d33d20b3f7ecbbb86b7fa26695cda4f73327db467572f90f7011051db03064e8b6c0

Expected results:
I expect that the code should either return expected signature or EVP_PKEY_CTX_set_signature_md() call at https://github.com/pyca/cryptography/blob/36.0.1/src/cryptography/hazmat/backends/openssl/rsa.py#L210 fails with an invalid signature error.

205a2e2780f00c4cad1cdb4277ee391163e56aa97c21b4949217c4120c69282a233b7f949f2d084099f851eafc828d6738bca7e2e4836d04a0ec1cf6048723de3f6143fe0ec20d2b9b8d8eee8b58a5d89119b610dc8d99d08c3b8a5e66288640dbc53ac6be47e6a68c2d84c676d70bdc48ece9e7725873b0e277520838154dfecff4f22186deb815080f1200892ca262917b90f7cedff3ec006465a0b629c666850430cd31f72d9eed1936f226bdfbc040ae3095030678db6723f62b0a7eb17e27671c6630ef092e98b66a69c7fc20b26a3abbb6a3db1b6224a766a25818b1b25e7e3196d45d9d9c3f836a82884ea0a5dd1705fdc95a917a41ddd987721c9d5c

Tested with Fedora 35 and RHEL-9.1.0-20220227.3

crypto-policies-20210819-1.gitd0fdcfb.fc35.noarch
openssl-1.1.1l-2.fc35.x86_64
python3-cryptography-3.4.7-5.fc35.x86_64

crypto-policies-20220203-1.gitf03e75e.el9.noarch
openssl-3.0.1-5.el9.x86_64
python3-cryptography-3.4.7-8.el9.x86_64

Additional info:
OpenSSL generated correct signature when I set the OPENSSL_ENABLE_SHA1_SIGNATURES env var.

OPENSSL_ENABLE_SHA1_SIGNATURES=yes python3 /tmp/testrsa.py 
b'205a2e2780f00c4cad1cdb4277ee391163e56aa97c21b4949217c4120c69282a233b7f949f2d084099f851eafc828d6738bca7e2e4836d04a0ec1cf6048723de3f6143fe0ec20d2b9b8d8eee8b58a5d89119b610dc8d99d08c3b8a5e66288640dbc53ac6be47e6a68c2d84c676d70bdc48ece9e7725873b0e277520838154dfecff4f22186deb815080f1200892ca262917b90f7cedff3ec006465a0b629c666850430cd31f72d9eed1936f226bdfbc040ae3095030678db6723f62b0a7eb17e27671c6630ef092e98b66a69c7fc20b26a3abbb6a3db1b6224a766a25818b1b25e7e3196d45d9d9c3f836a82884ea0a5dd1705fdc95a917a41ddd987721c9d5c'

Comment 1 Clemens Lang 2022-03-03 12:18:51 UTC
https://github.com/pyca/cryptography/blob/36.0.1/src/cryptography/hazmat/backends/openssl/rsa.py#L210-L211 compares the return value of EVP_PKEY_CTX_set_signature_md() for equality to 0.

The return value section of https://www.openssl.org/docs/man3.0/man3/EVP_PKEY_CTX_set_signature_md.html says this:

> All other functions described on this page return a positive value for success and 0 or a negative value for failure. In particular a return value of -2 indicates the operation is not supported by the public key algorithm.

python-cryptography should check for ret <= 0.


This explains the different result, in combination with a different section from the same manpage:

> Two RSA padding modes behave differently if EVP_PKEY_CTX_set_signature_md() is used. If this function is called for PKCS#1 padding the plaintext buffer is an actual digest value and is encapsulated in a DigestInfo structure according to PKCS#1 when signing and this structure is expected (and stripped off) when verifying. If this control is not used with RSA and PKCS#1 padding then the supplied data is used directly and not encapsulated. In the case of X9.31 padding for RSA the algorithm identifier byte is added or checked and removed if this control is called. If it is not called then the first byte of the plaintext buffer is expected to be the algorithm identifier byte.

The code then behaves as if EVP_PKEY_CTX_set_signature_md() was never called and signs the plaintext (which is the SHA1 hash of the message) with PKCS1v1.5 padding. The openssl-pkeyutl(1) manpage at https://www.openssl.org/docs/man3.0/man1/openssl-pkeyutl.html explains that:

> In PKCS#1 padding if the message digest is not set then the supplied data is signed or verified directly instead of using a DigestInfo structure. If a digest is set then the a DigestInfo structure is used and its the length must correspond to the digest type.

We can also see this in your case:

# echo -n "A message I want to sign" | openssl dgst -sha1
SHA1(stdin)= b4bc01a07dd7c18e7a51702b490e340a90e98156
# echo "958e6fd3db8c824c806f4fe7dd45f91f9e1c08d0992959cb5ef0b65bb57636173c1fd3284f4a5da530820436c94d4b9bc9f4932614242a01ceb1c16fee0b9e1acc7c36ec5bf0300d293f43046454cb3500a3d40c687da6e4cbb00985d14e752b67a8a9b6e51ab9104edb26b5a4b38afc76e096d04b6999d13b92eb5abfbc3c9e984ee83e65f4e1343925ff749eaec043871cfec64c2f88cac7e70417279964116ee7beb776987604a8fe2dd34ea1343b1248c48261e1dff9e4f2bf2d83101f6641eb1b9bd6211f834702e7d32174d918e032cbb589922f97bbdc796623a2d33d20b3f7ecbbb86b7fa26695cda4f73327db467572f90f7011051db03064e8b6c0" | xxd -ps -r > signature
# openssl pkeyutl -verifyrecover -in signature -inkey theirrsa.key -pkeyopt rsa_padding_mode:pkcs1 | xxd
Enter pass phrase for theirrsa.key:
00000000: b4bc 01a0 7dd7 c18e 7a51 702b 490e 340a  ....}...zQp+I.4.
00000010: 90e9 8156                                ...V


The correct signature wraps the hash in a DigestInfo structure:

# echo "205a2e2780f00c4cad1cdb4277ee391163e56aa97c21b4949217c4120c69282a233b7f949f2d084099f851eafc828d6738bca7e2e4836d04a0ec1cf6048723de3f6143fe0ec20d2b9b8d8eee8b58a5d89119b610dc8d99d08c3b8a5e66288640dbc53ac6be47e6a68c2d84c676d70bdc48ece9e7725873b0e277520838154dfecff4f22186deb815080f1200892ca262917b90f7cedff3ec006465a0b629c666850430cd31f72d9eed1936f226bdfbc040ae3095030678db6723f62b0a7eb17e27671c6630ef092e98b66a69c7fc20b26a3abbb6a3db1b6224a766a25818b1b25e7e3196d45d9d9c3f836a82884ea0a5dd1705fdc95a917a41ddd987721c9d5c" | xxd -ps -r > signature-correct
# openssl pkeyutl -verifyrecover -in signature-correct -inkey theirrsa.key -pkeyopt rsa_padding_mode:pkcs1 | xxd
Enter pass phrase for theirrsa.key:
00000000: 3021 3009 0605 2b0e 0302 1a05 0004 14b4  0!0...+.........
00000010: bc01 a07d d7c1 8e7a 5170 2b49 0e34 0a90  ...}...zQp+I.4..
00000020: e981 56                                  ..V


openssl can not refuse to sign payloads where it does not know the used hash algorithm, because from an API point of view this looks exactly the same as signing raw data, which users may still want to do.

I recommend to fix the error check in src/cryptography/hazmat/backends/openssl/rsa.py. Let me know if you agree so that I can move the ticket to python-cryptography.

Comment 2 Christian Heimes 2022-03-03 13:09:48 UTC
Good catch! Thanks for you analysis.

It's a python-cryptography bug. I have opened upstream bug https://github.com/pyca/cryptography/issues/6927 .

Comment 6 Christian Heimes 2022-03-07 15:18:00 UTC
I'm requestion exception+ so I'm able to attach the BZ to the RHEL 9.0.0 erratum. No additional work is required. The reported issue is fixed by rebase BZ https://bugzilla.redhat.com/show_bug.cgi?id=2059630, which has already exception+ and a successful build in pre-verification.

Comment 12 Sumedh Sidhaye 2022-03-14 10:29:34 UTC
[root@server ~]# rpm -q python3-cryptography openssl 
python3-cryptography-36.0.1-1.el9_0.x86_64
openssl-3.0.1-15.el9_0.1.x86_64
[root@server ~]# cat /etc/redhat-release 
Red Hat Enterprise Linux release 9.0 Beta (Plow)

[root@server ~]# python3
Python 3.9.10 (main, Feb  9 2022, 00:00:00) 
[GCC 11.2.1 20220127 (Red Hat 11.2.1-9)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from cryptography.hazmat.backends.openssl import backend
>>> backend._is_fips_enabled()
False
>>> from cryptography.hazmat.primitives.asymmetric import rsa
>>> from cryptography.hazmat.primitives import hashes
>>> from cryptography.hazmat.primitives.asymmetric import padding
>>> private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
>>> private_key.sign(b"message", padding.PKCS1v15(), hashes.SHA1())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.9/site-packages/cryptography/hazmat/backends/openssl/rsa.py", line 501, in sign
    return _rsa_sig_sign(self._backend, padding, algorithm, self, data)
  File "/usr/lib64/python3.9/site-packages/cryptography/hazmat/backends/openssl/rsa.py", line 244, in _rsa_sig_sign
    pkey_ctx = _rsa_sig_setup(
  File "/usr/lib64/python3.9/site-packages/cryptography/hazmat/backends/openssl/rsa.py", line 213, in _rsa_sig_setup
    raise UnsupportedAlgorithm(
cryptography.exceptions.UnsupportedAlgorithm: sha1 is not supported by this backend for RSA signing.
>>> 

Based on above observations marking bugzilla verified

Comment 14 errata-xmlrpc 2022-05-17 13:45:50 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (new packages: python-cryptography), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2022:2580


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