diff --git a/lemur/authorities/service.py b/lemur/authorities/service.py index 5b312e11..70b6e875 100644 --- a/lemur/authorities/service.py +++ b/lemur/authorities/service.py @@ -51,7 +51,7 @@ def mint(**kwargs): elif len(values) == 4: body, private_key, chain, roles = values - roles = create_authority_roles(roles, kwargs['owner'], kwargs['plugin']['plugin_object'].title, None) + roles = create_authority_roles(roles, kwargs['owner'], kwargs['plugin']['plugin_object'].title, kwargs['creator']) return body, private_key, chain, roles diff --git a/lemur/certificates/models.py b/lemur/certificates/models.py index 7e73cbe9..31f3c6cc 100644 --- a/lemur/certificates/models.py +++ b/lemur/certificates/models.py @@ -9,6 +9,8 @@ import arrow from flask import current_app +from cryptography.hazmat.primitives.asymmetric import rsa + from sqlalchemy.orm import relationship from sqlalchemy.sql.expression import case from sqlalchemy.ext.hybrid import hybrid_property @@ -148,6 +150,12 @@ class Certificate(db.Model): cert = lemur.common.utils.parse_certificate(self.body) return defaults.location(cert) + @property + def key_type(self): + cert = lemur.common.utils.parse_certificate(self.body) + if isinstance(cert.public_key(), rsa.RSAPublicKey): + return 'RSA{key_size}'.format(key_size=cert.public_key().key_size) + @hybrid_property def expired(self): if self.not_after <= arrow.utcnow(): diff --git a/lemur/certificates/schemas.py b/lemur/certificates/schemas.py index 523400de..59b220aa 100644 --- a/lemur/certificates/schemas.py +++ b/lemur/certificates/schemas.py @@ -6,7 +6,7 @@ .. moduleauthor:: Kevin Glisson """ from flask import current_app -from marshmallow import fields, validates_schema, post_load, pre_load +from marshmallow import fields, validate, validates_schema, post_load, pre_load from marshmallow.exceptions import ValidationError from lemur.schemas import AssociatedAuthoritySchema, AssociatedDestinationSchema, AssociatedCertificateSchema, \ @@ -58,6 +58,7 @@ class CertificateInputSchema(CertificateCreationSchema): roles = fields.Nested(AssociatedRoleSchema, missing=[], many=True) csr = fields.String(validate=validators.csr) + key_type = fields.String(validate=validate.OneOf(['RSA2048', 'RSA4096']), missing='RSA2048') notify = fields.Boolean(default=True) diff --git a/lemur/certificates/service.py b/lemur/certificates/service.py index 46b2672e..9e78e870 100644 --- a/lemur/certificates/service.py +++ b/lemur/certificates/service.py @@ -316,11 +316,14 @@ def create_csr(**csr_config): :param csr_config: """ - private_key = rsa.generate_private_key( - public_exponent=65537, - key_size=2048, - backend=default_backend() - ) + + if 'RSA' in csr_config.get('key_type'): + key_size = int(csr_config.get('key_type')[3:]) + private_key = rsa.generate_private_key( + public_exponent=65537, + key_size=key_size, + backend=default_backend() + ) # TODO When we figure out a better way to validate these options they should be parsed as str builder = x509.CertificateSigningRequestBuilder() @@ -512,7 +515,8 @@ def get_certificate_primitives(certificate): organizational_unit=certificate.organizational_unit, country=certificate.country, state=certificate.state, - location=certificate.location + location=certificate.location, + key_type=certificate.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 b517ebde..20e821cb 100644 --- a/lemur/static/app/angular/certificates/certificate/options.tpl.html +++ b/lemur/static/app/angular/certificates/certificate/options.tpl.html @@ -8,7 +8,7 @@
-
+
@@ -18,7 +18,7 @@
-
+
@@ -30,6 +30,14 @@
{{ alt.nameType }}
+
+ +
+ +
+
-
+
diff --git a/lemur/tests/test_certificates.py b/lemur/tests/test_certificates.py index eedd6356..43ffd8a5 100644 --- a/lemur/tests/test_certificates.py +++ b/lemur/tests/test_certificates.py @@ -41,7 +41,7 @@ def test_get_certificate_primitives(certificate): with freeze_time(datetime.date(year=2016, month=10, day=30)): primitives = get_certificate_primitives(certificate) - assert len(primitives) == 14 + assert len(primitives) == 15 def test_certificate_edit_schema(session): @@ -153,7 +153,7 @@ def test_certificate_input_schema(client, authority): assert data['country'] == 'US' assert data['location'] == 'Los Gatos' - assert len(data.keys()) == 15 + assert len(data.keys()) == 16 def test_certificate_input_with_extensions(client, authority): @@ -332,6 +332,7 @@ def test_create_basic_csr(client): state='CA', location='A place', owner='joe@example.com', + key_type='RSA2048', extensions=dict(names=dict(sub_alt_names=['test.example.com', 'test2.example.com'])) ) csr, pem = create_csr(**csr_config) @@ -381,13 +382,13 @@ def test_create_csr(): from lemur.certificates.service import create_csr csr, private_key = create_csr(owner='joe@example.com', common_name='ACommonName', organization='test', organizational_unit='Meters', country='US', - state='CA', location='Here') + state='CA', location='Here', key_type='RSA2048') assert csr assert private_key extensions = {'sub_alt_names': {'names': [{'name_type': 'DNSName', 'value': 'AnotherCommonName'}]}} csr, private_key = create_csr(owner='joe@example.com', common_name='ACommonName', organization='test', organizational_unit='Meters', country='US', - state='CA', location='Here', extensions=extensions) + state='CA', location='Here', extensions=extensions, key_type='RSA2048') assert csr assert private_key
{{ custom.oid }}