Parse DNSNames from CSR into Lemur Certificate

This commit is contained in:
Javier Ramos 2019-03-15 09:18:33 +01:00
parent cfe0595918
commit f7452e8379
2 changed files with 48 additions and 0 deletions

View File

@ -10,6 +10,7 @@ from marshmallow import fields, validate, validates_schema, post_load, pre_load
from marshmallow.exceptions import ValidationError from marshmallow.exceptions import ValidationError
from lemur.authorities.schemas import AuthorityNestedOutputSchema from lemur.authorities.schemas import AuthorityNestedOutputSchema
from lemur.certificates import utils as cert_utils
from lemur.common import missing, utils, validators from lemur.common import missing, utils, validators
from lemur.common.fields import ArrowDateTime, Hex from lemur.common.fields import ArrowDateTime, Hex
from lemur.common.schema import LemurInputSchema, LemurOutputSchema from lemur.common.schema import LemurInputSchema, LemurOutputSchema
@ -107,6 +108,11 @@ class CertificateInputSchema(CertificateCreationSchema):
def load_data(self, data): def load_data(self, data):
if data.get('replacements'): if data.get('replacements'):
data['replaces'] = data['replacements'] # TODO remove when field is deprecated data['replaces'] = data['replacements'] # TODO remove when field is deprecated
if data['csr']:
dns_names = cert_utils.get_dns_names_from_csr(data['csr'])
if not data['extensions']['subAltNames']['names']:
data['extensions']['subAltNames']['names'] = []
data['extensions']['subAltNames']['names'] += dns_names
return missing.convert_validity_years(data) return missing.convert_validity_years(data)

View File

@ -0,0 +1,42 @@
"""
Utils to parse certificate data.
.. module: lemur.certificates.hooks
:platform: Unix
:copyright: (c) 2019 by Javier Ramos, see AUTHORS for more
:license: Apache, see LICENSE for more details.
.. moduleauthor:: Javier Ramos <javier.ramos@booking.com>
"""
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from marshmallow.exceptions import ValidationError
def get_dns_names_from_csr(data):
"""
Fetches DNSNames from CSR.
Potentially extendable to any kind of SubjectAlternativeName
:param data: PEM-encoded string with CSR
:return:
"""
dns_names = []
try:
request = x509.load_pem_x509_csr(data.encode('utf-8'), default_backend())
except Exception:
raise ValidationError('CSR presented is not valid.')
try:
alt_names = request.extensions.get_extension_for_class(x509.SubjectAlternativeName)
for name in alt_names.value.get_values_for_type(x509.DNSName):
dns_name = {
'nameType': 'DNSName',
'value': name
}
dns_names.append(dns_name)
except x509.ExtensionNotFound:
pass
return dns_names