Enabling RSA2048 and RSA4096 as available key types (#551)

* Enabling RSA2048 and RSA4096 as available key types

* Fixing re-issuance
This commit is contained in:
kevgliss 2016-12-01 15:41:53 -08:00 committed by GitHub
parent 41b59c5445
commit 81bf98c746
6 changed files with 38 additions and 16 deletions

View File

@ -51,7 +51,7 @@ def mint(**kwargs):
elif len(values) == 4: elif len(values) == 4:
body, private_key, chain, roles = values 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 return body, private_key, chain, roles

View File

@ -9,6 +9,8 @@ import arrow
from flask import current_app from flask import current_app
from cryptography.hazmat.primitives.asymmetric import rsa
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from sqlalchemy.sql.expression import case from sqlalchemy.sql.expression import case
from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.ext.hybrid import hybrid_property
@ -148,6 +150,12 @@ class Certificate(db.Model):
cert = lemur.common.utils.parse_certificate(self.body) cert = lemur.common.utils.parse_certificate(self.body)
return defaults.location(cert) 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 @hybrid_property
def expired(self): def expired(self):
if self.not_after <= arrow.utcnow(): if self.not_after <= arrow.utcnow():

View File

@ -6,7 +6,7 @@
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com> .. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
""" """
from flask import current_app 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 marshmallow.exceptions import ValidationError
from lemur.schemas import AssociatedAuthoritySchema, AssociatedDestinationSchema, AssociatedCertificateSchema, \ from lemur.schemas import AssociatedAuthoritySchema, AssociatedDestinationSchema, AssociatedCertificateSchema, \
@ -58,6 +58,7 @@ class CertificateInputSchema(CertificateCreationSchema):
roles = fields.Nested(AssociatedRoleSchema, missing=[], many=True) roles = fields.Nested(AssociatedRoleSchema, missing=[], many=True)
csr = fields.String(validate=validators.csr) csr = fields.String(validate=validators.csr)
key_type = fields.String(validate=validate.OneOf(['RSA2048', 'RSA4096']), missing='RSA2048')
notify = fields.Boolean(default=True) notify = fields.Boolean(default=True)

View File

@ -316,11 +316,14 @@ def create_csr(**csr_config):
:param csr_config: :param csr_config:
""" """
private_key = rsa.generate_private_key(
public_exponent=65537, if 'RSA' in csr_config.get('key_type'):
key_size=2048, key_size = int(csr_config.get('key_type')[3:])
backend=default_backend() 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 # TODO When we figure out a better way to validate these options they should be parsed as str
builder = x509.CertificateSigningRequestBuilder() builder = x509.CertificateSigningRequestBuilder()
@ -512,7 +515,8 @@ def get_certificate_primitives(certificate):
organizational_unit=certificate.organizational_unit, organizational_unit=certificate.organizational_unit,
country=certificate.country, country=certificate.country,
state=certificate.state, state=certificate.state,
location=certificate.location location=certificate.location,
key_type=certificate.key_type
) )

View File

@ -8,7 +8,7 @@
<div class="col-sm-3"> <div class="col-sm-3">
<select class="form-control" ng-model="certificate.subAltType" ng-options="item for item in ['DNSName', 'IPAddress', 'uniformResourceIdentifier', 'directoryName','rfc822Name', 'registeredID', 'otherName', 'x400Address', 'EDIPartyName']"></select> <select class="form-control" ng-model="certificate.subAltType" ng-options="item for item in ['DNSName', 'IPAddress', 'uniformResourceIdentifier', 'directoryName','rfc822Name', 'registeredID', 'otherName', 'x400Address', 'EDIPartyName']"></select>
</div> </div>
<div class="col-sm-5"> <div class="col-sm-6">
<div class="input-group"> <div class="input-group">
<input tooltip-trigger="focus" tooltip-placement="top" uib-tooltip="String or Base64-encoded DER ASN.1 structure for the value" class="form-control" name="value" ng-model="certificate.subAltValue" placeholder="Value" class="form-control" required/> <input tooltip-trigger="focus" tooltip-placement="top" uib-tooltip="String or Base64-encoded DER ASN.1 structure for the value" class="form-control" name="value" ng-model="certificate.subAltValue" placeholder="Value" class="form-control" required/>
<span class="input-group-btn"> <span class="input-group-btn">
@ -18,7 +18,7 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-8 col-sm-offset-2"> <div class="col-sm-10 col-sm-offset-2">
<table class="table"> <table class="table">
<tr ng-repeat="alt in certificate.extensions.subAltNames.names track by $index"> <tr ng-repeat="alt in certificate.extensions.subAltNames.names track by $index">
<td>{{ alt.nameType }}</td> <td>{{ alt.nameType }}</td>
@ -30,6 +30,14 @@
</table> </table>
</div> </div>
</div> </div>
<div class="form-group">
<label class="control-label col-sm-2">
Key Type
</label>
<div class="col-sm-10">
<select class="form-control" ng-model="certificate.keyType" ng-options="option for option in ['RSA2048', 'RSA4096']" ng-init="certificate.keyType = 'RSA2048'"></select>
</div>
</div>
<div class="form-group"> <div class="form-group">
<label class="control-label col-sm-2"> <label class="control-label col-sm-2">
Key Usage Key Usage
@ -178,7 +186,7 @@
<label class="control-label col-sm-2"> <label class="control-label col-sm-2">
cRL Distribution Points cRL Distribution Points
</label> </label>
<div class="col-sm-8"> <div class="col-sm-10">
<select class="form-control" ng-model="certificate.extensions.cRLDistributionPoints.includeCRLDP" ng-options="item for item in ['yes', 'no', 'default']"></select> <select class="form-control" ng-model="certificate.extensions.cRLDistributionPoints.includeCRLDP" ng-options="item for item in ['yes', 'no', 'default']"></select>
</div> </div>
</div> </div>
@ -210,7 +218,7 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-8 col-sm-offset-2"> <div class="col-sm-10 col-sm-offset-2">
<table class="table"> <table class="table">
<tr ng-repeat="custom in certificate.extensions.custom track by $index"> <tr ng-repeat="custom in certificate.extensions.custom track by $index">
<td>{{ custom.oid }}</td> <td>{{ custom.oid }}</td>

View File

@ -41,7 +41,7 @@ def test_get_certificate_primitives(certificate):
with freeze_time(datetime.date(year=2016, month=10, day=30)): with freeze_time(datetime.date(year=2016, month=10, day=30)):
primitives = get_certificate_primitives(certificate) primitives = get_certificate_primitives(certificate)
assert len(primitives) == 14 assert len(primitives) == 15
def test_certificate_edit_schema(session): def test_certificate_edit_schema(session):
@ -153,7 +153,7 @@ def test_certificate_input_schema(client, authority):
assert data['country'] == 'US' assert data['country'] == 'US'
assert data['location'] == 'Los Gatos' assert data['location'] == 'Los Gatos'
assert len(data.keys()) == 15 assert len(data.keys()) == 16
def test_certificate_input_with_extensions(client, authority): def test_certificate_input_with_extensions(client, authority):
@ -332,6 +332,7 @@ def test_create_basic_csr(client):
state='CA', state='CA',
location='A place', location='A place',
owner='joe@example.com', owner='joe@example.com',
key_type='RSA2048',
extensions=dict(names=dict(sub_alt_names=['test.example.com', 'test2.example.com'])) extensions=dict(names=dict(sub_alt_names=['test.example.com', 'test2.example.com']))
) )
csr, pem = create_csr(**csr_config) csr, pem = create_csr(**csr_config)
@ -381,13 +382,13 @@ def test_create_csr():
from lemur.certificates.service import 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', 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 csr
assert private_key assert private_key
extensions = {'sub_alt_names': {'names': [{'name_type': 'DNSName', 'value': 'AnotherCommonName'}]}} 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', 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 csr
assert private_key assert private_key