Black lint all the things
This commit is contained in:
@ -1,5 +1,4 @@
|
||||
try:
|
||||
VERSION = __import__('pkg_resources') \
|
||||
.get_distribution(__name__).version
|
||||
VERSION = __import__("pkg_resources").get_distribution(__name__).version
|
||||
except Exception as e:
|
||||
VERSION = 'unknown'
|
||||
VERSION = "unknown"
|
||||
|
@ -40,7 +40,7 @@ def log_status_code(r, *args, **kwargs):
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
metrics.send('digicert_status_code_{}'.format(r.status_code), 'counter', 1)
|
||||
metrics.send("digicert_status_code_{}".format(r.status_code), "counter", 1)
|
||||
|
||||
|
||||
def signature_hash(signing_algorithm):
|
||||
@ -50,18 +50,18 @@ def signature_hash(signing_algorithm):
|
||||
:return: str digicert specific algorithm string
|
||||
"""
|
||||
if not signing_algorithm:
|
||||
return current_app.config.get('DIGICERT_DEFAULT_SIGNING_ALGORITHM', 'sha256')
|
||||
return current_app.config.get("DIGICERT_DEFAULT_SIGNING_ALGORITHM", "sha256")
|
||||
|
||||
if signing_algorithm == 'sha256WithRSA':
|
||||
return 'sha256'
|
||||
if signing_algorithm == "sha256WithRSA":
|
||||
return "sha256"
|
||||
|
||||
elif signing_algorithm == 'sha384WithRSA':
|
||||
return 'sha384'
|
||||
elif signing_algorithm == "sha384WithRSA":
|
||||
return "sha384"
|
||||
|
||||
elif signing_algorithm == 'sha512WithRSA':
|
||||
return 'sha512'
|
||||
elif signing_algorithm == "sha512WithRSA":
|
||||
return "sha512"
|
||||
|
||||
raise Exception('Unsupported signing algorithm.')
|
||||
raise Exception("Unsupported signing algorithm.")
|
||||
|
||||
|
||||
def determine_validity_years(end_date):
|
||||
@ -79,8 +79,9 @@ def determine_validity_years(end_date):
|
||||
elif end_date < now.replace(years=+3):
|
||||
return 3
|
||||
|
||||
raise Exception("DigiCert issued certificates cannot exceed three"
|
||||
" years in validity")
|
||||
raise Exception(
|
||||
"DigiCert issued certificates cannot exceed three" " years in validity"
|
||||
)
|
||||
|
||||
|
||||
def get_additional_names(options):
|
||||
@ -92,8 +93,8 @@ def get_additional_names(options):
|
||||
"""
|
||||
names = []
|
||||
# add SANs if present
|
||||
if options.get('extensions'):
|
||||
for san in options['extensions']['sub_alt_names']['names']:
|
||||
if options.get("extensions"):
|
||||
for san in options["extensions"]["sub_alt_names"]["names"]:
|
||||
if isinstance(san, x509.DNSName):
|
||||
names.append(san.value)
|
||||
return names
|
||||
@ -106,31 +107,33 @@ def map_fields(options, csr):
|
||||
:param csr:
|
||||
:return: dict or valid DigiCert options
|
||||
"""
|
||||
if not options.get('validity_years'):
|
||||
if not options.get('validity_end'):
|
||||
options['validity_years'] = current_app.config.get('DIGICERT_DEFAULT_VALIDITY', 1)
|
||||
if not options.get("validity_years"):
|
||||
if not options.get("validity_end"):
|
||||
options["validity_years"] = current_app.config.get(
|
||||
"DIGICERT_DEFAULT_VALIDITY", 1
|
||||
)
|
||||
|
||||
data = dict(certificate={
|
||||
"common_name": options['common_name'],
|
||||
"csr": csr,
|
||||
"signature_hash":
|
||||
signature_hash(options.get('signing_algorithm')),
|
||||
}, organization={
|
||||
"id": current_app.config.get("DIGICERT_ORG_ID")
|
||||
})
|
||||
data = dict(
|
||||
certificate={
|
||||
"common_name": options["common_name"],
|
||||
"csr": csr,
|
||||
"signature_hash": signature_hash(options.get("signing_algorithm")),
|
||||
},
|
||||
organization={"id": current_app.config.get("DIGICERT_ORG_ID")},
|
||||
)
|
||||
|
||||
data['certificate']['dns_names'] = get_additional_names(options)
|
||||
data["certificate"]["dns_names"] = get_additional_names(options)
|
||||
|
||||
if options.get('validity_years'):
|
||||
data['validity_years'] = options['validity_years']
|
||||
if options.get("validity_years"):
|
||||
data["validity_years"] = options["validity_years"]
|
||||
else:
|
||||
data['custom_expiration_date'] = options['validity_end'].format('YYYY-MM-DD')
|
||||
data["custom_expiration_date"] = options["validity_end"].format("YYYY-MM-DD")
|
||||
|
||||
if current_app.config.get('DIGICERT_PRIVATE', False):
|
||||
if 'product' in data:
|
||||
data['product']['type_hint'] = 'private'
|
||||
if current_app.config.get("DIGICERT_PRIVATE", False):
|
||||
if "product" in data:
|
||||
data["product"]["type_hint"] = "private"
|
||||
else:
|
||||
data['product'] = dict(type_hint='private')
|
||||
data["product"] = dict(type_hint="private")
|
||||
|
||||
return data
|
||||
|
||||
@ -143,26 +146,30 @@ def map_cis_fields(options, csr):
|
||||
:param csr:
|
||||
:return:
|
||||
"""
|
||||
if not options.get('validity_years'):
|
||||
if not options.get('validity_end'):
|
||||
options['validity_end'] = arrow.utcnow().replace(years=current_app.config.get('DIGICERT_DEFAULT_VALIDITY', 1))
|
||||
options['validity_years'] = determine_validity_years(options['validity_end'])
|
||||
if not options.get("validity_years"):
|
||||
if not options.get("validity_end"):
|
||||
options["validity_end"] = arrow.utcnow().replace(
|
||||
years=current_app.config.get("DIGICERT_DEFAULT_VALIDITY", 1)
|
||||
)
|
||||
options["validity_years"] = determine_validity_years(options["validity_end"])
|
||||
else:
|
||||
options['validity_end'] = arrow.utcnow().replace(years=options['validity_years'])
|
||||
options["validity_end"] = arrow.utcnow().replace(
|
||||
years=options["validity_years"]
|
||||
)
|
||||
|
||||
data = {
|
||||
"profile_name": current_app.config.get('DIGICERT_CIS_PROFILE_NAME'),
|
||||
"common_name": options['common_name'],
|
||||
"profile_name": current_app.config.get("DIGICERT_CIS_PROFILE_NAME"),
|
||||
"common_name": options["common_name"],
|
||||
"additional_dns_names": get_additional_names(options),
|
||||
"csr": csr,
|
||||
"signature_hash": signature_hash(options.get('signing_algorithm')),
|
||||
"signature_hash": signature_hash(options.get("signing_algorithm")),
|
||||
"validity": {
|
||||
"valid_to": options['validity_end'].format('YYYY-MM-DDTHH:MM') + 'Z'
|
||||
"valid_to": options["validity_end"].format("YYYY-MM-DDTHH:MM") + "Z"
|
||||
},
|
||||
"organization": {
|
||||
"name": options['organization'],
|
||||
"units": [options['organizational_unit']]
|
||||
}
|
||||
"name": options["organization"],
|
||||
"units": [options["organizational_unit"]],
|
||||
},
|
||||
}
|
||||
|
||||
return data
|
||||
@ -175,7 +182,7 @@ def handle_response(response):
|
||||
:return:
|
||||
"""
|
||||
if response.status_code > 399:
|
||||
raise Exception(response.json()['errors'][0]['message'])
|
||||
raise Exception(response.json()["errors"][0]["message"])
|
||||
|
||||
return response.json()
|
||||
|
||||
@ -197,19 +204,17 @@ def get_certificate_id(session, base_url, order_id):
|
||||
"""Retrieve certificate order id from Digicert API."""
|
||||
order_url = "{0}/services/v2/order/certificate/{1}".format(base_url, order_id)
|
||||
response_data = handle_response(session.get(order_url))
|
||||
if response_data['status'] != 'issued':
|
||||
if response_data["status"] != "issued":
|
||||
raise Exception("Order not in issued state.")
|
||||
|
||||
return response_data['certificate']['id']
|
||||
return response_data["certificate"]["id"]
|
||||
|
||||
|
||||
@retry(stop_max_attempt_number=10, wait_fixed=10000)
|
||||
def get_cis_certificate(session, base_url, order_id):
|
||||
"""Retrieve certificate order id from Digicert API."""
|
||||
certificate_url = '{0}/platform/cis/certificate/{1}'.format(base_url, order_id)
|
||||
session.headers.update(
|
||||
{'Accept': 'application/x-pem-file'}
|
||||
)
|
||||
certificate_url = "{0}/platform/cis/certificate/{1}".format(base_url, order_id)
|
||||
session.headers.update({"Accept": "application/x-pem-file"})
|
||||
response = session.get(certificate_url)
|
||||
|
||||
if response.status_code == 404:
|
||||
@ -220,29 +225,30 @@ def get_cis_certificate(session, base_url, order_id):
|
||||
|
||||
class DigiCertSourcePlugin(SourcePlugin):
|
||||
"""Wrap the Digicert Certifcate API."""
|
||||
title = 'DigiCert'
|
||||
slug = 'digicert-source'
|
||||
|
||||
title = "DigiCert"
|
||||
slug = "digicert-source"
|
||||
description = "Enables the use of Digicert as a source of existing certificates."
|
||||
version = digicert.VERSION
|
||||
|
||||
author = 'Kevin Glisson'
|
||||
author_url = 'https://github.com/netflix/lemur.git'
|
||||
author = "Kevin Glisson"
|
||||
author_url = "https://github.com/netflix/lemur.git"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize source with appropriate details."""
|
||||
required_vars = [
|
||||
'DIGICERT_API_KEY',
|
||||
'DIGICERT_URL',
|
||||
'DIGICERT_ORG_ID',
|
||||
'DIGICERT_ROOT',
|
||||
"DIGICERT_API_KEY",
|
||||
"DIGICERT_URL",
|
||||
"DIGICERT_ORG_ID",
|
||||
"DIGICERT_ROOT",
|
||||
]
|
||||
validate_conf(current_app, required_vars)
|
||||
|
||||
self.session = requests.Session()
|
||||
self.session.headers.update(
|
||||
{
|
||||
'X-DC-DEVKEY': current_app.config['DIGICERT_API_KEY'],
|
||||
'Content-Type': 'application/json'
|
||||
"X-DC-DEVKEY": current_app.config["DIGICERT_API_KEY"],
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
)
|
||||
|
||||
@ -256,22 +262,23 @@ class DigiCertSourcePlugin(SourcePlugin):
|
||||
|
||||
class DigiCertIssuerPlugin(IssuerPlugin):
|
||||
"""Wrap the Digicert Issuer API."""
|
||||
title = 'DigiCert'
|
||||
slug = 'digicert-issuer'
|
||||
|
||||
title = "DigiCert"
|
||||
slug = "digicert-issuer"
|
||||
description = "Enables the creation of certificates by the DigiCert REST API."
|
||||
version = digicert.VERSION
|
||||
|
||||
author = 'Kevin Glisson'
|
||||
author_url = 'https://github.com/netflix/lemur.git'
|
||||
author = "Kevin Glisson"
|
||||
author_url = "https://github.com/netflix/lemur.git"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the issuer with the appropriate details."""
|
||||
required_vars = [
|
||||
'DIGICERT_API_KEY',
|
||||
'DIGICERT_URL',
|
||||
'DIGICERT_ORG_ID',
|
||||
'DIGICERT_ORDER_TYPE',
|
||||
'DIGICERT_ROOT',
|
||||
"DIGICERT_API_KEY",
|
||||
"DIGICERT_URL",
|
||||
"DIGICERT_ORG_ID",
|
||||
"DIGICERT_ORDER_TYPE",
|
||||
"DIGICERT_ROOT",
|
||||
]
|
||||
|
||||
validate_conf(current_app, required_vars)
|
||||
@ -279,8 +286,8 @@ class DigiCertIssuerPlugin(IssuerPlugin):
|
||||
self.session = requests.Session()
|
||||
self.session.headers.update(
|
||||
{
|
||||
'X-DC-DEVKEY': current_app.config['DIGICERT_API_KEY'],
|
||||
'Content-Type': 'application/json'
|
||||
"X-DC-DEVKEY": current_app.config["DIGICERT_API_KEY"],
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
)
|
||||
|
||||
@ -295,69 +302,93 @@ class DigiCertIssuerPlugin(IssuerPlugin):
|
||||
:param issuer_options:
|
||||
:return: :raise Exception:
|
||||
"""
|
||||
base_url = current_app.config.get('DIGICERT_URL')
|
||||
cert_type = current_app.config.get('DIGICERT_ORDER_TYPE')
|
||||
base_url = current_app.config.get("DIGICERT_URL")
|
||||
cert_type = current_app.config.get("DIGICERT_ORDER_TYPE")
|
||||
|
||||
# make certificate request
|
||||
determinator_url = "{0}/services/v2/order/certificate/{1}".format(base_url, cert_type)
|
||||
determinator_url = "{0}/services/v2/order/certificate/{1}".format(
|
||||
base_url, cert_type
|
||||
)
|
||||
data = map_fields(issuer_options, csr)
|
||||
response = self.session.post(determinator_url, data=json.dumps(data))
|
||||
|
||||
if response.status_code > 399:
|
||||
raise Exception(response.json()['errors'][0]['message'])
|
||||
raise Exception(response.json()["errors"][0]["message"])
|
||||
|
||||
order_id = response.json()['id']
|
||||
order_id = response.json()["id"]
|
||||
|
||||
certificate_id = get_certificate_id(self.session, base_url, order_id)
|
||||
|
||||
# retrieve certificate
|
||||
certificate_url = "{0}/services/v2/certificate/{1}/download/format/pem_all".format(base_url, certificate_id)
|
||||
end_entity, intermediate, root = pem.parse(self.session.get(certificate_url).content)
|
||||
return "\n".join(str(end_entity).splitlines()), "\n".join(str(intermediate).splitlines()), certificate_id
|
||||
certificate_url = "{0}/services/v2/certificate/{1}/download/format/pem_all".format(
|
||||
base_url, certificate_id
|
||||
)
|
||||
end_entity, intermediate, root = pem.parse(
|
||||
self.session.get(certificate_url).content
|
||||
)
|
||||
return (
|
||||
"\n".join(str(end_entity).splitlines()),
|
||||
"\n".join(str(intermediate).splitlines()),
|
||||
certificate_id,
|
||||
)
|
||||
|
||||
def revoke_certificate(self, certificate, comments):
|
||||
"""Revoke a Digicert certificate."""
|
||||
base_url = current_app.config.get('DIGICERT_URL')
|
||||
base_url = current_app.config.get("DIGICERT_URL")
|
||||
|
||||
# make certificate revoke request
|
||||
create_url = '{0}/services/v2/certificate/{1}/revoke'.format(base_url, certificate.external_id)
|
||||
metrics.send('digicert_revoke_certificate', 'counter', 1)
|
||||
response = self.session.put(create_url, data=json.dumps({'comments': comments}))
|
||||
create_url = "{0}/services/v2/certificate/{1}/revoke".format(
|
||||
base_url, certificate.external_id
|
||||
)
|
||||
metrics.send("digicert_revoke_certificate", "counter", 1)
|
||||
response = self.session.put(create_url, data=json.dumps({"comments": comments}))
|
||||
return handle_response(response)
|
||||
|
||||
def get_ordered_certificate(self, pending_cert):
|
||||
""" Retrieve a certificate via order id """
|
||||
order_id = pending_cert.external_id
|
||||
base_url = current_app.config.get('DIGICERT_URL')
|
||||
base_url = current_app.config.get("DIGICERT_URL")
|
||||
try:
|
||||
certificate_id = get_certificate_id(self.session, base_url, order_id)
|
||||
except Exception as ex:
|
||||
return None
|
||||
certificate_url = "{0}/services/v2/certificate/{1}/download/format/pem_all".format(base_url, certificate_id)
|
||||
end_entity, intermediate, root = pem.parse(self.session.get(certificate_url).content)
|
||||
cert = {'body': "\n".join(str(end_entity).splitlines()),
|
||||
'chain': "\n".join(str(intermediate).splitlines()),
|
||||
'external_id': str(certificate_id)}
|
||||
certificate_url = "{0}/services/v2/certificate/{1}/download/format/pem_all".format(
|
||||
base_url, certificate_id
|
||||
)
|
||||
end_entity, intermediate, root = pem.parse(
|
||||
self.session.get(certificate_url).content
|
||||
)
|
||||
cert = {
|
||||
"body": "\n".join(str(end_entity).splitlines()),
|
||||
"chain": "\n".join(str(intermediate).splitlines()),
|
||||
"external_id": str(certificate_id),
|
||||
}
|
||||
return cert
|
||||
|
||||
def cancel_ordered_certificate(self, pending_cert, **kwargs):
|
||||
""" Set the certificate order to canceled """
|
||||
base_url = current_app.config.get('DIGICERT_URL')
|
||||
api_url = "{0}/services/v2/order/certificate/{1}/status".format(base_url, pending_cert.external_id)
|
||||
payload = {
|
||||
'status': 'CANCELED',
|
||||
'note': kwargs.get('note')
|
||||
}
|
||||
base_url = current_app.config.get("DIGICERT_URL")
|
||||
api_url = "{0}/services/v2/order/certificate/{1}/status".format(
|
||||
base_url, pending_cert.external_id
|
||||
)
|
||||
payload = {"status": "CANCELED", "note": kwargs.get("note")}
|
||||
response = self.session.put(api_url, data=json.dumps(payload))
|
||||
if response.status_code == 404:
|
||||
# not well documented by Digicert, but either the certificate does not exist or we
|
||||
# don't own that order (someone else's order id!). Either way, we can just ignore it
|
||||
# and have it removed from Lemur
|
||||
current_app.logger.warning(
|
||||
"Digicert Plugin tried to cancel pending certificate {0} but it does not exist!".format(pending_cert.name))
|
||||
"Digicert Plugin tried to cancel pending certificate {0} but it does not exist!".format(
|
||||
pending_cert.name
|
||||
)
|
||||
)
|
||||
elif response.status_code != 204:
|
||||
current_app.logger.debug("{0} code {1}".format(response.status_code, response.content))
|
||||
raise Exception("Failed to cancel pending certificate {0}".format(pending_cert.name))
|
||||
current_app.logger.debug(
|
||||
"{0} code {1}".format(response.status_code, response.content)
|
||||
)
|
||||
raise Exception(
|
||||
"Failed to cancel pending certificate {0}".format(pending_cert.name)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def create_authority(options):
|
||||
@ -370,72 +401,81 @@ class DigiCertIssuerPlugin(IssuerPlugin):
|
||||
:param options:
|
||||
:return:
|
||||
"""
|
||||
role = {'username': '', 'password': '', 'name': 'digicert'}
|
||||
return current_app.config.get('DIGICERT_ROOT'), "", [role]
|
||||
role = {"username": "", "password": "", "name": "digicert"}
|
||||
return current_app.config.get("DIGICERT_ROOT"), "", [role]
|
||||
|
||||
|
||||
class DigiCertCISSourcePlugin(SourcePlugin):
|
||||
"""Wrap the Digicert CIS Certifcate API."""
|
||||
title = 'DigiCert'
|
||||
slug = 'digicert-cis-source'
|
||||
|
||||
title = "DigiCert"
|
||||
slug = "digicert-cis-source"
|
||||
description = "Enables the use of Digicert as a source of existing certificates."
|
||||
version = digicert.VERSION
|
||||
|
||||
author = 'Kevin Glisson'
|
||||
author_url = 'https://github.com/netflix/lemur.git'
|
||||
author = "Kevin Glisson"
|
||||
author_url = "https://github.com/netflix/lemur.git"
|
||||
|
||||
additional_options = []
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize source with appropriate details."""
|
||||
required_vars = [
|
||||
'DIGICERT_CIS_API_KEY',
|
||||
'DIGICERT_CIS_URL',
|
||||
'DIGICERT_CIS_ROOT',
|
||||
'DIGICERT_CIS_INTERMEDIATE',
|
||||
'DIGICERT_CIS_PROFILE_NAME'
|
||||
"DIGICERT_CIS_API_KEY",
|
||||
"DIGICERT_CIS_URL",
|
||||
"DIGICERT_CIS_ROOT",
|
||||
"DIGICERT_CIS_INTERMEDIATE",
|
||||
"DIGICERT_CIS_PROFILE_NAME",
|
||||
]
|
||||
validate_conf(current_app, required_vars)
|
||||
|
||||
self.session = requests.Session()
|
||||
self.session.headers.update(
|
||||
{
|
||||
'X-DC-DEVKEY': current_app.config['DIGICERT_CIS_API_KEY'],
|
||||
'Content-Type': 'application/json'
|
||||
"X-DC-DEVKEY": current_app.config["DIGICERT_CIS_API_KEY"],
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
)
|
||||
|
||||
self.session.hooks = dict(response=log_status_code)
|
||||
|
||||
a = requests.adapters.HTTPAdapter(max_retries=3)
|
||||
self.session.mount('https://', a)
|
||||
self.session.mount("https://", a)
|
||||
|
||||
super(DigiCertCISSourcePlugin, self).__init__(*args, **kwargs)
|
||||
|
||||
def get_certificates(self, options, **kwargs):
|
||||
"""Fetch all Digicert certificates."""
|
||||
base_url = current_app.config.get('DIGICERT_CIS_URL')
|
||||
base_url = current_app.config.get("DIGICERT_CIS_URL")
|
||||
|
||||
# make request
|
||||
search_url = '{0}/platform/cis/certificate/search'.format(base_url)
|
||||
search_url = "{0}/platform/cis/certificate/search".format(base_url)
|
||||
|
||||
certs = []
|
||||
page = 1
|
||||
|
||||
while True:
|
||||
response = self.session.get(search_url, params={'status': ['issued'], 'page': page})
|
||||
response = self.session.get(
|
||||
search_url, params={"status": ["issued"], "page": page}
|
||||
)
|
||||
data = handle_cis_response(response)
|
||||
|
||||
for c in data['certificates']:
|
||||
download_url = '{0}/platform/cis/certificate/{1}'.format(base_url, c['id'])
|
||||
for c in data["certificates"]:
|
||||
download_url = "{0}/platform/cis/certificate/{1}".format(
|
||||
base_url, c["id"]
|
||||
)
|
||||
certificate = self.session.get(download_url)
|
||||
|
||||
# normalize serial
|
||||
serial = str(int(c['serial_number'], 16))
|
||||
cert = {'body': certificate.content, 'serial': serial, 'external_id': c['id']}
|
||||
serial = str(int(c["serial_number"], 16))
|
||||
cert = {
|
||||
"body": certificate.content,
|
||||
"serial": serial,
|
||||
"external_id": c["id"],
|
||||
}
|
||||
certs.append(cert)
|
||||
|
||||
if page == data['total_pages']:
|
||||
if page == data["total_pages"]:
|
||||
break
|
||||
|
||||
page += 1
|
||||
@ -444,22 +484,23 @@ class DigiCertCISSourcePlugin(SourcePlugin):
|
||||
|
||||
class DigiCertCISIssuerPlugin(IssuerPlugin):
|
||||
"""Wrap the Digicert Certificate Issuing API."""
|
||||
title = 'DigiCert CIS'
|
||||
slug = 'digicert-cis-issuer'
|
||||
|
||||
title = "DigiCert CIS"
|
||||
slug = "digicert-cis-issuer"
|
||||
description = "Enables the creation of certificates by the DigiCert CIS REST API."
|
||||
version = digicert.VERSION
|
||||
|
||||
author = 'Kevin Glisson'
|
||||
author_url = 'https://github.com/netflix/lemur.git'
|
||||
author = "Kevin Glisson"
|
||||
author_url = "https://github.com/netflix/lemur.git"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the issuer with the appropriate details."""
|
||||
required_vars = [
|
||||
'DIGICERT_CIS_API_KEY',
|
||||
'DIGICERT_CIS_URL',
|
||||
'DIGICERT_CIS_ROOT',
|
||||
'DIGICERT_CIS_INTERMEDIATE',
|
||||
'DIGICERT_CIS_PROFILE_NAME'
|
||||
"DIGICERT_CIS_API_KEY",
|
||||
"DIGICERT_CIS_URL",
|
||||
"DIGICERT_CIS_ROOT",
|
||||
"DIGICERT_CIS_INTERMEDIATE",
|
||||
"DIGICERT_CIS_PROFILE_NAME",
|
||||
]
|
||||
|
||||
validate_conf(current_app, required_vars)
|
||||
@ -467,8 +508,8 @@ class DigiCertCISIssuerPlugin(IssuerPlugin):
|
||||
self.session = requests.Session()
|
||||
self.session.headers.update(
|
||||
{
|
||||
'X-DC-DEVKEY': current_app.config['DIGICERT_CIS_API_KEY'],
|
||||
'Content-Type': 'application/json'
|
||||
"X-DC-DEVKEY": current_app.config["DIGICERT_CIS_API_KEY"],
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
)
|
||||
|
||||
@ -478,41 +519,51 @@ class DigiCertCISIssuerPlugin(IssuerPlugin):
|
||||
|
||||
def create_certificate(self, csr, issuer_options):
|
||||
"""Create a DigiCert certificate."""
|
||||
base_url = current_app.config.get('DIGICERT_CIS_URL')
|
||||
base_url = current_app.config.get("DIGICERT_CIS_URL")
|
||||
|
||||
# make certificate request
|
||||
create_url = '{0}/platform/cis/certificate'.format(base_url)
|
||||
create_url = "{0}/platform/cis/certificate".format(base_url)
|
||||
|
||||
data = map_cis_fields(issuer_options, csr)
|
||||
response = self.session.post(create_url, data=json.dumps(data))
|
||||
data = handle_cis_response(response)
|
||||
|
||||
# retrieve certificate
|
||||
certificate_pem = get_cis_certificate(self.session, base_url, data['id'])
|
||||
certificate_pem = get_cis_certificate(self.session, base_url, data["id"])
|
||||
|
||||
self.session.headers.pop('Accept')
|
||||
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']
|
||||
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']
|
||||
return (
|
||||
"\n".join(str(end_entity).splitlines()),
|
||||
current_app.config.get("DIGICERT_CIS_INTERMEDIATE"),
|
||||
data["id"],
|
||||
)
|
||||
|
||||
def revoke_certificate(self, certificate, comments):
|
||||
"""Revoke a Digicert certificate."""
|
||||
base_url = current_app.config.get('DIGICERT_CIS_URL')
|
||||
base_url = current_app.config.get("DIGICERT_CIS_URL")
|
||||
|
||||
# make certificate revoke request
|
||||
revoke_url = '{0}/platform/cis/certificate/{1}/revoke'.format(base_url, certificate.external_id)
|
||||
metrics.send('digicert_revoke_certificate_success', 'counter', 1)
|
||||
response = self.session.put(revoke_url, data=json.dumps({'comments': comments}))
|
||||
revoke_url = "{0}/platform/cis/certificate/{1}/revoke".format(
|
||||
base_url, certificate.external_id
|
||||
)
|
||||
metrics.send("digicert_revoke_certificate_success", "counter", 1)
|
||||
response = self.session.put(revoke_url, data=json.dumps({"comments": comments}))
|
||||
|
||||
if response.status_code != 204:
|
||||
metrics.send('digicert_revoke_certificate_failure', 'counter', 1)
|
||||
raise Exception('Failed to revoke certificate.')
|
||||
metrics.send("digicert_revoke_certificate_failure", "counter", 1)
|
||||
raise Exception("Failed to revoke certificate.")
|
||||
|
||||
metrics.send('digicert_revoke_certificate_success', 'counter', 1)
|
||||
metrics.send("digicert_revoke_certificate_success", "counter", 1)
|
||||
|
||||
@staticmethod
|
||||
def create_authority(options):
|
||||
@ -525,5 +576,5 @@ class DigiCertCISIssuerPlugin(IssuerPlugin):
|
||||
:param options:
|
||||
:return:
|
||||
"""
|
||||
role = {'username': '', 'password': '', 'name': 'digicert'}
|
||||
return current_app.config.get('DIGICERT_CIS_ROOT'), "", [role]
|
||||
role = {"username": "", "password": "", "name": "digicert"}
|
||||
return current_app.config.get("DIGICERT_CIS_ROOT"), "", [role]
|
||||
|
@ -13,144 +13,129 @@ from cryptography import x509
|
||||
def test_map_fields_with_validity_end_and_start(app):
|
||||
from lemur.plugins.lemur_digicert.plugin import map_fields
|
||||
|
||||
names = [u'one.example.com', u'two.example.com', u'three.example.com']
|
||||
names = [u"one.example.com", u"two.example.com", u"three.example.com"]
|
||||
|
||||
options = {
|
||||
'common_name': 'example.com',
|
||||
'owner': 'bob@example.com',
|
||||
'description': 'test certificate',
|
||||
'extensions': {
|
||||
'sub_alt_names': {
|
||||
'names': [x509.DNSName(x) for x in names]
|
||||
}
|
||||
},
|
||||
'validity_end': arrow.get(2017, 5, 7),
|
||||
'validity_start': arrow.get(2016, 10, 30)
|
||||
"common_name": "example.com",
|
||||
"owner": "bob@example.com",
|
||||
"description": "test certificate",
|
||||
"extensions": {"sub_alt_names": {"names": [x509.DNSName(x) for x in names]}},
|
||||
"validity_end": arrow.get(2017, 5, 7),
|
||||
"validity_start": arrow.get(2016, 10, 30),
|
||||
}
|
||||
|
||||
data = map_fields(options, CSR_STR)
|
||||
|
||||
assert data == {
|
||||
'certificate': {
|
||||
'csr': CSR_STR,
|
||||
'common_name': 'example.com',
|
||||
'dns_names': names,
|
||||
'signature_hash': 'sha256'
|
||||
"certificate": {
|
||||
"csr": CSR_STR,
|
||||
"common_name": "example.com",
|
||||
"dns_names": names,
|
||||
"signature_hash": "sha256",
|
||||
},
|
||||
'organization': {'id': 111111},
|
||||
'custom_expiration_date': arrow.get(2017, 5, 7).format('YYYY-MM-DD')
|
||||
"organization": {"id": 111111},
|
||||
"custom_expiration_date": arrow.get(2017, 5, 7).format("YYYY-MM-DD"),
|
||||
}
|
||||
|
||||
|
||||
def test_map_fields_with_validity_years(app):
|
||||
from lemur.plugins.lemur_digicert.plugin import map_fields
|
||||
|
||||
names = [u'one.example.com', u'two.example.com', u'three.example.com']
|
||||
names = [u"one.example.com", u"two.example.com", u"three.example.com"]
|
||||
|
||||
options = {
|
||||
'common_name': 'example.com',
|
||||
'owner': 'bob@example.com',
|
||||
'description': 'test certificate',
|
||||
'extensions': {
|
||||
'sub_alt_names': {
|
||||
'names': [x509.DNSName(x) for x in names]
|
||||
}
|
||||
},
|
||||
'validity_years': 2,
|
||||
'validity_end': arrow.get(2017, 10, 30)
|
||||
"common_name": "example.com",
|
||||
"owner": "bob@example.com",
|
||||
"description": "test certificate",
|
||||
"extensions": {"sub_alt_names": {"names": [x509.DNSName(x) for x in names]}},
|
||||
"validity_years": 2,
|
||||
"validity_end": arrow.get(2017, 10, 30),
|
||||
}
|
||||
|
||||
data = map_fields(options, CSR_STR)
|
||||
|
||||
assert data == {
|
||||
'certificate': {
|
||||
'csr': CSR_STR,
|
||||
'common_name': 'example.com',
|
||||
'dns_names': names,
|
||||
'signature_hash': 'sha256'
|
||||
"certificate": {
|
||||
"csr": CSR_STR,
|
||||
"common_name": "example.com",
|
||||
"dns_names": names,
|
||||
"signature_hash": "sha256",
|
||||
},
|
||||
'organization': {'id': 111111},
|
||||
'validity_years': 2
|
||||
"organization": {"id": 111111},
|
||||
"validity_years": 2,
|
||||
}
|
||||
|
||||
|
||||
def test_map_cis_fields(app):
|
||||
from lemur.plugins.lemur_digicert.plugin import map_cis_fields
|
||||
|
||||
names = [u'one.example.com', u'two.example.com', u'three.example.com']
|
||||
names = [u"one.example.com", u"two.example.com", u"three.example.com"]
|
||||
|
||||
options = {
|
||||
'common_name': 'example.com',
|
||||
'owner': 'bob@example.com',
|
||||
'description': 'test certificate',
|
||||
'extensions': {
|
||||
'sub_alt_names': {
|
||||
'names': [x509.DNSName(x) for x in names]
|
||||
}
|
||||
},
|
||||
'organization': 'Example, Inc.',
|
||||
'organizational_unit': 'Example Org',
|
||||
'validity_end': arrow.get(2017, 5, 7),
|
||||
'validity_start': arrow.get(2016, 10, 30)
|
||||
"common_name": "example.com",
|
||||
"owner": "bob@example.com",
|
||||
"description": "test certificate",
|
||||
"extensions": {"sub_alt_names": {"names": [x509.DNSName(x) for x in names]}},
|
||||
"organization": "Example, Inc.",
|
||||
"organizational_unit": "Example Org",
|
||||
"validity_end": arrow.get(2017, 5, 7),
|
||||
"validity_start": arrow.get(2016, 10, 30),
|
||||
}
|
||||
|
||||
data = map_cis_fields(options, CSR_STR)
|
||||
|
||||
assert data == {
|
||||
'common_name': 'example.com',
|
||||
'csr': CSR_STR,
|
||||
'additional_dns_names': names,
|
||||
'signature_hash': 'sha256',
|
||||
'organization': {'name': 'Example, Inc.', 'units': ['Example Org']},
|
||||
'validity': {
|
||||
'valid_to': arrow.get(2017, 5, 7).format('YYYY-MM-DDTHH:MM') + 'Z'
|
||||
"common_name": "example.com",
|
||||
"csr": CSR_STR,
|
||||
"additional_dns_names": names,
|
||||
"signature_hash": "sha256",
|
||||
"organization": {"name": "Example, Inc.", "units": ["Example Org"]},
|
||||
"validity": {
|
||||
"valid_to": arrow.get(2017, 5, 7).format("YYYY-MM-DDTHH:MM") + "Z"
|
||||
},
|
||||
'profile_name': None
|
||||
"profile_name": None,
|
||||
}
|
||||
|
||||
options = {
|
||||
'common_name': 'example.com',
|
||||
'owner': 'bob@example.com',
|
||||
'description': 'test certificate',
|
||||
'extensions': {
|
||||
'sub_alt_names': {
|
||||
'names': [x509.DNSName(x) for x in names]
|
||||
}
|
||||
},
|
||||
'organization': 'Example, Inc.',
|
||||
'organizational_unit': 'Example Org',
|
||||
'validity_years': 2
|
||||
"common_name": "example.com",
|
||||
"owner": "bob@example.com",
|
||||
"description": "test certificate",
|
||||
"extensions": {"sub_alt_names": {"names": [x509.DNSName(x) for x in names]}},
|
||||
"organization": "Example, Inc.",
|
||||
"organizational_unit": "Example Org",
|
||||
"validity_years": 2,
|
||||
}
|
||||
|
||||
with freeze_time(time_to_freeze=arrow.get(2016, 11, 3).datetime):
|
||||
data = map_cis_fields(options, CSR_STR)
|
||||
|
||||
assert data == {
|
||||
'common_name': 'example.com',
|
||||
'csr': CSR_STR,
|
||||
'additional_dns_names': names,
|
||||
'signature_hash': 'sha256',
|
||||
'organization': {'name': 'Example, Inc.', 'units': ['Example Org']},
|
||||
'validity': {
|
||||
'valid_to': arrow.get(2018, 11, 3).format('YYYY-MM-DDTHH:MM') + 'Z'
|
||||
"common_name": "example.com",
|
||||
"csr": CSR_STR,
|
||||
"additional_dns_names": names,
|
||||
"signature_hash": "sha256",
|
||||
"organization": {"name": "Example, Inc.", "units": ["Example Org"]},
|
||||
"validity": {
|
||||
"valid_to": arrow.get(2018, 11, 3).format("YYYY-MM-DDTHH:MM") + "Z"
|
||||
},
|
||||
'profile_name': None
|
||||
"profile_name": None,
|
||||
}
|
||||
|
||||
|
||||
def test_signature_hash(app):
|
||||
from lemur.plugins.lemur_digicert.plugin import signature_hash
|
||||
|
||||
assert signature_hash(None) == 'sha256'
|
||||
assert signature_hash('sha256WithRSA') == 'sha256'
|
||||
assert signature_hash('sha384WithRSA') == 'sha384'
|
||||
assert signature_hash('sha512WithRSA') == 'sha512'
|
||||
assert signature_hash(None) == "sha256"
|
||||
assert signature_hash("sha256WithRSA") == "sha256"
|
||||
assert signature_hash("sha384WithRSA") == "sha384"
|
||||
assert signature_hash("sha512WithRSA") == "sha512"
|
||||
|
||||
with pytest.raises(Exception):
|
||||
signature_hash('sdfdsf')
|
||||
signature_hash("sdfdsf")
|
||||
|
||||
|
||||
def test_issuer_plugin_create_certificate(certificate_="""\
|
||||
def test_issuer_plugin_create_certificate(
|
||||
certificate_="""\
|
||||
-----BEGIN CERTIFICATE-----
|
||||
abc
|
||||
-----END CERTIFICATE-----
|
||||
@ -160,7 +145,8 @@ def
|
||||
-----BEGIN CERTIFICATE-----
|
||||
ghi
|
||||
-----END CERTIFICATE-----
|
||||
"""):
|
||||
"""
|
||||
):
|
||||
import requests_mock
|
||||
from lemur.plugins.lemur_digicert.plugin import DigiCertIssuerPlugin
|
||||
|
||||
@ -168,12 +154,26 @@ ghi
|
||||
|
||||
subject = DigiCertIssuerPlugin()
|
||||
adapter = requests_mock.Adapter()
|
||||
adapter.register_uri('POST', 'mock://www.digicert.com/services/v2/order/certificate/ssl_plus', text=json.dumps({'id': 'id123'}))
|
||||
adapter.register_uri('GET', 'mock://www.digicert.com/services/v2/order/certificate/id123', text=json.dumps({'status': 'issued', 'certificate': {'id': 'cert123'}}))
|
||||
adapter.register_uri('GET', 'mock://www.digicert.com/services/v2/certificate/cert123/download/format/pem_all', text=pem_fixture)
|
||||
subject.session.mount('mock', adapter)
|
||||
adapter.register_uri(
|
||||
"POST",
|
||||
"mock://www.digicert.com/services/v2/order/certificate/ssl_plus",
|
||||
text=json.dumps({"id": "id123"}),
|
||||
)
|
||||
adapter.register_uri(
|
||||
"GET",
|
||||
"mock://www.digicert.com/services/v2/order/certificate/id123",
|
||||
text=json.dumps({"status": "issued", "certificate": {"id": "cert123"}}),
|
||||
)
|
||||
adapter.register_uri(
|
||||
"GET",
|
||||
"mock://www.digicert.com/services/v2/certificate/cert123/download/format/pem_all",
|
||||
text=pem_fixture,
|
||||
)
|
||||
subject.session.mount("mock", adapter)
|
||||
|
||||
cert, intermediate, external_id = subject.create_certificate("", {'common_name': 'test.com'})
|
||||
cert, intermediate, external_id = subject.create_certificate(
|
||||
"", {"common_name": "test.com"}
|
||||
)
|
||||
|
||||
assert cert == "-----BEGIN CERTIFICATE-----\nabc\n-----END CERTIFICATE-----"
|
||||
assert intermediate == "-----BEGIN CERTIFICATE-----\ndef\n-----END CERTIFICATE-----"
|
||||
@ -187,10 +187,18 @@ def test_cancel_ordered_certificate(mock_pending_cert):
|
||||
mock_pending_cert.external_id = 1234
|
||||
subject = DigiCertIssuerPlugin()
|
||||
adapter = requests_mock.Adapter()
|
||||
adapter.register_uri('PUT', 'mock://www.digicert.com/services/v2/order/certificate/1234/status', status_code=204)
|
||||
adapter.register_uri('PUT', 'mock://www.digicert.com/services/v2/order/certificate/111/status', status_code=404)
|
||||
subject.session.mount('mock', adapter)
|
||||
data = {'note': 'Test'}
|
||||
adapter.register_uri(
|
||||
"PUT",
|
||||
"mock://www.digicert.com/services/v2/order/certificate/1234/status",
|
||||
status_code=204,
|
||||
)
|
||||
adapter.register_uri(
|
||||
"PUT",
|
||||
"mock://www.digicert.com/services/v2/order/certificate/111/status",
|
||||
status_code=404,
|
||||
)
|
||||
subject.session.mount("mock", adapter)
|
||||
data = {"note": "Test"}
|
||||
subject.cancel_ordered_certificate(mock_pending_cert, **data)
|
||||
|
||||
# A non-existing order id, does not raise exception because if it doesn't exist, then it doesn't matter
|
||||
|
Reference in New Issue
Block a user