Skip to content
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
15 changes: 9 additions & 6 deletions sigstore/_internal/key_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,23 @@ def _get_key_details(certificate: Certificate) -> PublicKeyDetails:
else:
raise ValueError(f"Unsupported EC curve: {public_key.curve.name}")
elif isinstance(public_key, rsa.RSAPublicKey):
if public_key.key_size == 3072:
if public_key.key_size == 2048:
if isinstance(params, padding.PKCS1v15):
key_details = PublicKeyDetails.PKIX_RSA_PKCS1V15_2048_SHA256
else:
raise ValueError(
f"Unsupported public key type, size, and padding: {type(public_key)}, {public_key.key_size}, {params}"
)
elif public_key.key_size == 3072:
if isinstance(params, padding.PKCS1v15):
key_details = PublicKeyDetails.PKIX_RSA_PKCS1V15_3072_SHA256
elif isinstance(params, padding.PSS):
key_details = PublicKeyDetails.PKIX_RSA_PSS_3072_SHA256
else:
raise ValueError(
f"Unsupported public key type, size, and padding: {type(public_key)}, {public_key.key_size}, {params}"
)
elif public_key.key_size == 4096:
if isinstance(params, padding.PKCS1v15):
key_details = PublicKeyDetails.PKIX_RSA_PKCS1V15_3072_SHA256
elif isinstance(params, padding.PSS):
key_details = PublicKeyDetails.PKIX_RSA_PSS_3072_SHA256
key_details = PublicKeyDetails.PKIX_RSA_PKCS1V15_4096_SHA256
else:
raise ValueError(
f"Unsupported public key type, size, and padding: {type(public_key)}, {public_key.key_size}, {params}"
Expand Down
135 changes: 87 additions & 48 deletions test/unit/internal/test_key_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,18 @@
from unittest.mock import Mock

import pytest
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import dsa, ec, ed25519, padding, rsa
from sigstore_models.common.v1 import PublicKeyDetails

from sigstore._internal.key_details import _get_key_details


# The algorithms tested below are from https://github.com/sigstore/fulcio/blob/4a86d8bf45972b58051ba44d91cd96664cf74711/cmd/app/serve.go#L125-L133
@pytest.mark.parametrize(
"mock_certificate",
[
# ec
pytest.param(
Mock(
public_key=Mock(
return_value=ec.generate_private_key(ec.SECP192R1()).public_key()
)
),
marks=[pytest.mark.xfail(strict=True)],
),
Mock(
public_key=Mock(
return_value=ec.generate_private_key(ec.SECP256R1()).public_key()
Expand All @@ -49,16 +43,13 @@
)
),
# rsa pkcs1
pytest.param(
Mock(
public_key=Mock(
return_value=rsa.generate_private_key(
public_exponent=65537, key_size=2048
).public_key()
),
signature_algorithm_parameters=padding.PKCS1v15(),
Mock(
public_key=Mock(
return_value=rsa.generate_private_key(
public_exponent=65537, key_size=2048
).public_key()
),
marks=[pytest.mark.xfail(strict=True)],
signature_algorithm_parameters=padding.PKCS1v15(),
),
Mock(
public_key=Mock(
Expand All @@ -76,56 +67,104 @@
),
signature_algorithm_parameters=padding.PKCS1v15(),
),
# rsa pss
pytest.param(
# ed25519
Mock(
public_key=Mock(
return_value=ed25519.Ed25519PrivateKey.generate().public_key(),
signature_algorithm_parameters=None,
)
),
],
)
def test_get_key_details(mock_certificate):
"""
Ensures that we return a PublicKeyDetails for supported key types and schemes.
"""
key_details = _get_key_details(mock_certificate)
assert isinstance(key_details, PublicKeyDetails)


@pytest.mark.parametrize(
"mock_certificate, error_msg",
[
# Unsupported EC curve
(
Mock(
public_key=Mock(
return_value=ec.generate_private_key(ec.SECT163K1()).public_key()
)
),
"Unsupported EC curve: sect163k1",
),
# Unsupported RSA padding
(
Mock(
public_key=Mock(
return_value=rsa.generate_private_key(
public_exponent=65537, key_size=2048
).public_key()
),
signature_algorithm_parameters=padding.PSS(None, 0),
signature_algorithm_parameters=padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH,
),
),
marks=[pytest.mark.xfail(strict=True)],
"Unsupported public key type, size, and padding",
),
Mock(
public_key=Mock(
return_value=rsa.generate_private_key(
public_exponent=65537, key_size=3072
).public_key()
(
Mock(
public_key=Mock(
return_value=rsa.generate_private_key(
public_exponent=65537, key_size=3072
).public_key()
),
signature_algorithm_parameters=padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH,
),
),
signature_algorithm_parameters=padding.PSS(None, 0),
"Unsupported public key type, size, and padding",
),
Mock(
public_key=Mock(
return_value=rsa.generate_private_key(
public_exponent=65537, key_size=4096
).public_key()
(
Mock(
public_key=Mock(
return_value=rsa.generate_private_key(
public_exponent=65537, key_size=4096
).public_key()
),
signature_algorithm_parameters=padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH,
),
),
signature_algorithm_parameters=padding.PSS(None, 0),
"Unsupported public key type, size, and padding",
),
# ed25519
Mock(
public_key=Mock(
return_value=ed25519.Ed25519PrivateKey.generate().public_key(),
signature_algorithm_parameters=None,
)
# Unsupported RSA key size
(
Mock(
public_key=Mock(
return_value=rsa.generate_private_key(
public_exponent=65537, key_size=1024
).public_key()
),
signature_algorithm_parameters=padding.PKCS1v15(),
),
"Unsupported RSA key size: 1024",
),
# unsupported
pytest.param(
# Unsupported key type
(
Mock(
public_key=Mock(
return_value=dsa.generate_private_key(key_size=1024).public_key()
),
signature_algorithm_parameters=None,
)
),
marks=[pytest.mark.xfail(strict=True)],
"Unsupported public key type",
),
],
)
def test_get_key_details(mock_certificate):
def test_get_key_details_unsupported(mock_certificate, error_msg):
"""
Ensures that we return a PublicKeyDetails for supported key types and schemes.
Ensures that we raise a ValueError for unsupported key types and schemes.
"""
key_details = _get_key_details(mock_certificate)
assert isinstance(key_details, PublicKeyDetails)
with pytest.raises(ValueError, match=error_msg):
_get_key_details(mock_certificate)