From 52cb1453337f632858ea7d3e5b55500d5ad584e3 Mon Sep 17 00:00:00 2001 From: Will Bengtson Date: Tue, 10 Apr 2018 16:54:17 -0700 Subject: [PATCH] ecc: add the support for ECC (#1191) * ecc: add the support for ECC update generate_private_key to support ECC. Move key types to constant. Update UI for the new key types * ecc: Remove extra line to fix linting * ecc: Fix flake8 lint problems * Update options.tpl.html --- lemur/common/utils.py | 42 ++++++++++++++++--- lemur/constants.py | 23 ++++++++++ lemur/plugins/lemur_digicert/plugin.py | 5 +++ .../authorities/authority/options.tpl.html | 3 +- .../certificates/certificate/options.tpl.html | 5 ++- lemur/tests/test_utils.py | 20 ++++++++- 6 files changed, 90 insertions(+), 8 deletions(-) diff --git a/lemur/common/utils.py b/lemur/common/utils.py index 4db31a4e..02f55340 100644 --- a/lemur/common/utils.py +++ b/lemur/common/utils.py @@ -14,10 +14,11 @@ from sqlalchemy import and_, func from cryptography import x509 from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives.asymmetric import rsa +from cryptography.hazmat.primitives.asymmetric import rsa, ec from flask_restful.reqparse import RequestParser +from lemur.constants import CERTIFICATE_KEY_TYPES from lemur.exceptions import InvalidConfiguration paginated_parser = RequestParser() @@ -78,17 +79,43 @@ def generate_private_key(key_type): """ Generates a new private key based on key_type. - Valid key types: RSA2048, RSA4096 + Valid key types: RSA2048, RSA4096', 'ECCPRIME192V1', 'ECCPRIME256V1', 'ECCSECP192R1', + 'ECCSECP224R1', 'ECCSECP256R1', 'ECCSECP384R1', 'ECCSECP521R1', 'ECCSECP256K1', + 'ECCSECT163K1', 'ECCSECT233K1', 'ECCSECT283K1', 'ECCSECT409K1', 'ECCSECT571K1', + 'ECCSECT163R2', 'ECCSECT233R1', 'ECCSECT283R1', 'ECCSECT409R1', 'ECCSECT571R2' :param key_type: :return: """ - valid_key_types = ['RSA2048', 'RSA4096'] - if key_type not in valid_key_types: + _CURVE_TYPES = { + "ECCPRIME192V1": ec.SECP192R1(), + "ECCPRIME256V1": ec.SECP256R1(), + + "ECCSECP192R1": ec.SECP192R1(), + "ECCSECP224R1": ec.SECP224R1(), + "ECCSECP256R1": ec.SECP256R1(), + "ECCSECP384R1": ec.SECP384R1(), + "ECCSECP521R1": ec.SECP521R1(), + "ECCSECP256K1": ec.SECP256K1(), + + "ECCSECT163K1": ec.SECT163K1(), + "ECCSECT233K1": ec.SECT233K1(), + "ECCSECT283K1": ec.SECT283K1(), + "ECCSECT409K1": ec.SECT409K1(), + "ECCSECT571K1": ec.SECT571K1(), + + "ECCSECT163R2": ec.SECT163R2(), + "ECCSECT233R1": ec.SECT233R1(), + "ECCSECT283R1": ec.SECT283R1(), + "ECCSECT409R1": ec.SECT409R1(), + "ECCSECT571R2": ec.SECT571R1(), + } + + if key_type not in CERTIFICATE_KEY_TYPES: raise Exception("Invalid key type: {key_type}. Supported key types: {choices}".format( key_type=key_type, - choices=",".join(valid_key_types) + choices=",".join(CERTIFICATE_KEY_TYPES) )) if 'RSA' in key_type: @@ -98,6 +125,11 @@ def generate_private_key(key_type): key_size=key_size, backend=default_backend() ) + elif 'ECC' in key_type: + return ec.generate_private_key( + curve=_CURVE_TYPES[key_type], + backend=default_backend() + ) def is_weekend(date): diff --git a/lemur/constants.py b/lemur/constants.py index 04824c12..0ee9bc40 100644 --- a/lemur/constants.py +++ b/lemur/constants.py @@ -9,3 +9,26 @@ NONSTANDARD_NAMING_TEMPLATE = "{issuer}-{not_before}-{not_after}" SUCCESS_METRIC_STATUS = 'success' FAILURE_METRIC_STATUS = 'failure' + +CERTIFICATE_KEY_TYPES = [ + 'RSA2048', + 'RSA4096', + 'ECCPRIME192V1', + 'ECCPRIME256V1', + 'ECCSECP192R1', + 'ECCSECP224R1', + 'ECCSECP256R1', + 'ECCSECP384R1', + 'ECCSECP521R1', + 'ECCSECP256K1', + 'ECCSECT163K1', + 'ECCSECT233K1', + 'ECCSECT283K1', + 'ECCSECT409K1', + 'ECCSECT571K1', + 'ECCSECT163R2', + 'ECCSECT233R1', + 'ECCSECT283R1', + 'ECCSECT409R1', + 'ECCSECT571R2' +] diff --git a/lemur/plugins/lemur_digicert/plugin.py b/lemur/plugins/lemur_digicert/plugin.py index 5692af86..ae6a5924 100644 --- a/lemur/plugins/lemur_digicert/plugin.py +++ b/lemur/plugins/lemur_digicert/plugin.py @@ -491,6 +491,11 @@ class DigiCertCISIssuerPlugin(IssuerPlugin): self.session.headers.pop('Accept') end_entity = pem.parse(certificate_pem)[0] + + if 'ECC' in issuer_options['key_type']: + return "\n".join(str(end_entity).splitlines()), current_app.config.get('DIGICERT_ECC_CIS_INTERMEDIATE'), data['id'] + + # By default return RSA return "\n".join(str(end_entity).splitlines()), current_app.config.get('DIGICERT_CIS_INTERMEDIATE'), data['id'] def revoke_certificate(self, certificate, comments): diff --git a/lemur/static/app/angular/authorities/authority/options.tpl.html b/lemur/static/app/angular/authorities/authority/options.tpl.html index 57fc29e6..245716cb 100644 --- a/lemur/static/app/angular/authorities/authority/options.tpl.html +++ b/lemur/static/app/angular/authorities/authority/options.tpl.html @@ -20,7 +20,8 @@ Key Type
- +
diff --git a/lemur/static/app/angular/certificates/certificate/options.tpl.html b/lemur/static/app/angular/certificates/certificate/options.tpl.html index a52ee387..fb1d59a1 100644 --- a/lemur/static/app/angular/certificates/certificate/options.tpl.html +++ b/lemur/static/app/angular/certificates/certificate/options.tpl.html @@ -32,7 +32,10 @@
diff --git a/lemur/tests/test_utils.py b/lemur/tests/test_utils.py index cc03fcd5..62d021a4 100644 --- a/lemur/tests/test_utils.py +++ b/lemur/tests/test_utils.py @@ -6,9 +6,27 @@ def test_generate_private_key(): assert generate_private_key('RSA2048') assert generate_private_key('RSA4096') + assert generate_private_key('ECCPRIME192V1') + assert generate_private_key('ECCPRIME256V1') + assert generate_private_key('ECCSECP192R1') + assert generate_private_key('ECCSECP224R1') + assert generate_private_key('ECCSECP256R1') + assert generate_private_key('ECCSECP384R1') + assert generate_private_key('ECCSECP521R1') + assert generate_private_key('ECCSECP256K1') + assert generate_private_key('ECCSECT163K1') + assert generate_private_key('ECCSECT233K1') + assert generate_private_key('ECCSECT283K1') + assert generate_private_key('ECCSECT409K1') + assert generate_private_key('ECCSECT571K1') + assert generate_private_key('ECCSECT163R2') + assert generate_private_key('ECCSECT233R1') + assert generate_private_key('ECCSECT283R1') + assert generate_private_key('ECCSECT409R1') + assert generate_private_key('ECCSECT571R2') with pytest.raises(Exception): - generate_private_key('ECC') + generate_private_key('LEMUR') def test_get_authority_key():