Skip to content

Fix RSA PSS salt lengths #422

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@
# 3. Use this command to remove per-version files
# `rm requirements-?.?.txt`
#
cryptography >= 3.3.2; python_version >= '3'
cryptography >= 37.0.0; python_version >= '3'
pynacl
colorama
11 changes: 6 additions & 5 deletions securesystemslib/rsa_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,10 +326,11 @@ def create_rsa_signature(private_key, data, scheme='rsassa-pss-sha256'):
if scheme.startswith('rsassa-pss'):
# Generate an RSSA-PSS signature. Raise
# 'securesystemslib.exceptions.CryptoError' for any of the expected
# exceptions raised by pyca/cryptography.
# exceptions raised by pyca/cryptography. 'salt_length' is set to
# the maximum length available.
signature = private_key_object.sign(
data, padding.PSS(mgf=padding.MGF1(digest_obj.algorithm),
salt_length=digest_obj.algorithm.digest_size), digest_obj.algorithm)
salt_length=padding.PSS.MAX_LENGTH), digest_obj.algorithm)

elif scheme.startswith('rsa-pkcs1v15'):
# Generate an RSA-PKCS1v15 signature. Raise
Expand Down Expand Up @@ -453,13 +454,13 @@ def verify_rsa_signature(signature, signature_scheme, public_key, data):
digest_obj = digest_from_rsa_scheme(signature_scheme, 'pyca_crypto')

# verify() raises 'cryptography.exceptions.InvalidSignature' if the
# signature is invalid. 'salt_length' is set to the digest size of the
# hashing algorithm.
# signature is invalid. 'salt_length' is automatically
# determined when verifying the signature.
try:
if signature_scheme.startswith('rsassa-pss'):
public_key_object.verify(signature, data,
padding.PSS(mgf=padding.MGF1(digest_obj.algorithm),
salt_length=digest_obj.algorithm.digest_size),
salt_length=padding.PSS.AUTO),
digest_obj.algorithm)

elif signature_scheme.startswith('rsa-pkcs1v15'):
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
python_requires = "~=3.7",
extras_require = {
'colors': ['colorama>=0.3.9'],
'crypto': ['cryptography>=3.3.2'],
'crypto': ['cryptography>=37.0.0'],
'pynacl': ['pynacl>1.2.0']},
packages = find_packages(exclude=['tests', 'debian']),
scripts = []
Expand Down
28 changes: 27 additions & 1 deletion tests/test_rsa_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@
import securesystemslib.formats
import securesystemslib.keys
import securesystemslib.rsa_keys
import securesystemslib.hash

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.serialization import load_pem_private_key

public_rsa, private_rsa = securesystemslib.rsa_keys.generate_rsa_public_and_private()
FORMAT_ERROR_MSG = 'securesystemslib.exceptions.FormatError raised. Check object\'s format.'
Expand Down Expand Up @@ -154,6 +157,29 @@ def test_verify_rsa_signature(self):
scheme, public_rsa, data))


def test_verify_rsa_pss_sha256(self):
rsa_scheme = 'rsassa-pss-sha256'
data = 'The ancients say the longer the salt, the more provable the security'.encode('utf-8')

private_key = load_pem_private_key(private_rsa.encode('utf-8'),
password=None, backend=default_backend())
digest = securesystemslib.hash.digest_from_rsa_scheme(rsa_scheme, 'pyca_crypto')

# Old-style signature: use the hash length as the salt length.
old_signature = private_key.sign(data,
padding.PSS(mgf=padding.MGF1(digest.algorithm), salt_length=padding.PSS.DIGEST_LENGTH),
digest.algorithm)

# New-style signature: use the automatic salt length.
new_signature, _ = securesystemslib.rsa_keys.create_rsa_signature(private_rsa, data)

# Verify both old-style and new-style signatures.
for signature in (old_signature, new_signature):
verified = securesystemslib.rsa_keys.verify_rsa_signature(signature, rsa_scheme,
public_rsa, data)
self.assertTrue(verified)


def test_create_rsa_encrypted_pem(self):
global public_rsa
global private_rsa
Expand Down