signature_utils: handle ECC curve unavailability

Some ECC curves are unavailable on some platforms (like Fedora, RHEL,
and CentOS) because of legal concerns. See the bug report for more
details and history.

The cryptography backend has a elliptic_curve_supported() method
which we can use to avoid curves which are unavailable on the current
platform.

If an image signature uses one of these curves, we will return an
"Invalid signature key type" error.

Use the warnings module in the unit tests to avoid silently ignoring
this issue during testing. This warning will be captured from the
test's stderr and reported by testr.

Closes-Bug: #1528393

Change-Id: Ie25311c48b276f300fadaf1815fc4df4cb89cf8d
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
This commit is contained in:
Mark McLoughlin 2015-12-21 23:54:17 +00:00
parent 7bba58d0ad
commit 291e71990a
2 changed files with 16 additions and 4 deletions

View File

@ -51,6 +51,7 @@ RSA_PSS = 'RSA-PSS'
DSA = 'DSA'
# ECC curves -- note that only those with key sizes >=384 are included
# Note also that some of these may not be supported by the cryptography backend
ECC_CURVES = (
ec.SECT571K1(),
ec.SECT409K1(),
@ -178,10 +179,12 @@ def create_verifier_for_dsa(signature, hash_method, public_key,
SignatureKeyType.register(RSA_PSS, rsa.RSAPublicKey, create_verifier_for_pss)
SignatureKeyType.register(DSA, dsa.DSAPublicKey, create_verifier_for_dsa)
# Register the elliptic curves which are supported by the backend
for curve in ECC_CURVES:
SignatureKeyType.register('ECC_' + curve.name.upper(),
ec.EllipticCurvePublicKey,
create_verifier_for_ecc)
if default_backend().elliptic_curve_supported(curve):
SignatureKeyType.register('ECC_' + curve.name.upper(),
ec.EllipticCurvePublicKey,
create_verifier_for_ecc)
def should_verify_signature(image_properties):

View File

@ -34,6 +34,7 @@ TEST_RSA_PRIVATE_KEY = rsa.generate_private_key(public_exponent=3,
key_size=1024,
backend=default_backend())
# secp521r1 is assumed to be available on all supported platforms
TEST_ECC_PRIVATE_KEY = ec.generate_private_key(ec.SECP521R1(),
default_backend())
@ -163,6 +164,14 @@ class TestSignatureUtils(test.NoDBTestCase):
data = b'224626ae19824466f2a7f39ab7b80f7f'
# test every ECC curve
for curve in signature_utils.ECC_CURVES:
key_type_name = 'ECC_' + curve.name.upper()
try:
signature_utils.SignatureKeyType.lookup(key_type_name)
except exception.SignatureVerificationError:
import warnings
warnings.warn("ECC curve '%s' not supported" % curve.name)
continue
# Create a private key to use
private_key = ec.generate_private_key(curve,
default_backend())
@ -176,7 +185,7 @@ class TestSignatureUtils(test.NoDBTestCase):
image_props = {CERT_UUID:
'fea14bc2-d75f-4ba5-bccc-b5c924ad0693',
HASH_METHOD: hash_name,
KEY_TYPE: 'ECC_' + curve.name.upper(),
KEY_TYPE: key_type_name,
SIGNATURE: signature}
verifier = signature_utils.get_verifier(None, image_props)
verifier.update(data)