Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 42 additions & 48 deletions salt/runners/digicertapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,16 @@
import tempfile
from collections.abc import Sequence

from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa

import salt.cache
import salt.syspaths as syspaths
import salt.utils.files
import salt.utils.http
import salt.utils.json
from salt.exceptions import CommandExecutionError, SaltRunnerError

try:
from M2Crypto import RSA

HAS_M2 = True
except ImportError:
HAS_M2 = False
try:
from Cryptodome.PublicKey import RSA
except ImportError:
from Crypto.PublicKey import RSA # nosec

__virtualname__ = "digicert"
log = logging.getLogger(__name__)

Expand Down Expand Up @@ -112,7 +104,7 @@ def _paginate(url, topkey, *args, **kwargs):
aggregate_ret = ret["dict"][topkey]
url = args[0]
for p in range(2, numpages):
param_url = url + "?offset={}".format(lim * (p - 1))
param_url = url + f"?offset={lim * (p - 1)}"
next_ret = salt.utils.http.query(param_url, kwargs)
aggregate_ret[topkey].extend(next_ret["dict"][topkey])

Expand All @@ -131,9 +123,9 @@ def list_domains(container_id=None):
salt-run digicert.list_domains
"""
if container_id:
url = "{}/domain?{}".format(_base_url(), container_id)
url = f"{_base_url()}/domain?{container_id}"
else:
url = "{}/domain".format(_base_url())
url = f"{_base_url()}/domain"

orgs = _paginate(
url,
Expand All @@ -160,9 +152,9 @@ def list_requests(status=None):
salt-run digicert.list_requests pending
"""
if status:
url = "{}/request?status={}".format(_base_url(), status)
url = f"{_base_url()}/request?status={status}"
else:
url = "{}/request".format(_base_url())
url = f"{_base_url()}/request"

reqs = _paginate(
url,
Expand All @@ -188,7 +180,7 @@ def list_orders(status=None):

salt-run digicert.list_orders
"""
url = "{}/order/certificate".format(_base_url())
url = f"{_base_url()}/order/certificate"

reqs = _paginate(
url,
Expand Down Expand Up @@ -238,7 +230,7 @@ def get_certificate(

if order_id:
order_cert = salt.utils.http.query(
"{}/order/certificate/{}".format(_base_url(), order_id),
f"{_base_url()}/order/certificate/{order_id}",
method="GET",
raise_error=False,
decode=True,
Expand Down Expand Up @@ -372,7 +364,7 @@ def list_organizations(container_id=None, include_validation=True):
"""

orgs = _paginate(
"{}/organization".format(_base_url()),
f"{_base_url()}/organization",
"organizations",
method="GET",
decode=True,
Expand Down Expand Up @@ -495,7 +487,7 @@ def order_certificate(
encoded_body = salt.utils.json.dumps(body)

qdata = salt.utils.http.query(
"{}/order/certificate/ssl".format(_base_url()),
f"{_base_url()}/order/certificate/ssl",
method="POST",
data=encoded_body,
decode=True,
Expand Down Expand Up @@ -533,28 +525,30 @@ def gen_key(minion_id, dns_name=None, password=None, key_len=2048):

salt-run digicert.gen_key <minion_id> [dns_name] [password]
"""
keygen_type = "RSA"

if keygen_type == "RSA":
if HAS_M2:
gen = RSA.gen_key(key_len, 65537)
private_key = gen.as_pem(
cipher="des_ede3_cbc", callback=lambda x: bytes(password)
)
else:
gen = RSA.generate(bits=key_len)
private_key = gen.exportKey("PEM", password)
if dns_name is not None:
bank = "digicert/domains"
cache = salt.cache.Cache(__opts__, syspaths.CACHE_DIR)
try:
data = cache.fetch(bank, dns_name)
data["private_key"] = private_key
data["minion_id"] = minion_id
except TypeError:
data = {"private_key": private_key, "minion_id": minion_id}
cache.store(bank, dns_name, data)
return private_key
private_key = rsa.generate_private_key(public_exponent=65537, key_size=key_len)
encryption = (
serialization.BestAvailableEncryption(bytes(password, encoding="utf-8"))
if password
else serialization.NoEncryption()
)
serialized_private_key = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=encryption,
)
if dns_name is not None:
bank = "digicert/domains"
cache = salt.cache.Cache(__opts__, syspaths.CACHE_DIR)
try:
data = cache.fetch(bank, dns_name)
data["private_key"] = serialized_private_key
data["minion_id"] = minion_id
except TypeError:
data = {"private_key": serialized_private_key, "minion_id": minion_id}
cache.store(bank, dns_name, data)

return serialized_private_key


def get_org_details(organization_id):
Expand All @@ -571,7 +565,7 @@ def get_org_details(organization_id):
"""

qdata = salt.utils.http.query(
"{}/organization/{}".format(_base_url(), organization_id),
f"{_base_url()}/organization/{organization_id}",
method="GET",
decode=True,
decode_type="json",
Expand Down Expand Up @@ -623,8 +617,8 @@ def gen_csr(
if "private_key" not in data:
data["private_key"] = gen_key(minion_id, dns_name, password, key_len=key_len)

tmppriv = "{}/priv".format(tmpdir)
tmpcsr = "{}/csr".format(tmpdir)
tmppriv = f"{tmpdir}/priv"
tmpcsr = f"{tmpdir}/csr"
with salt.utils.files.fopen(tmppriv, "w") as if_:
if_.write(salt.utils.stringutils.to_str(data["private_key"]))

Expand All @@ -636,9 +630,9 @@ def gen_csr(
)

if ou_name:
subject = subject + "/OU={}".format(ou_name)
subject = subject + f"/OU={ou_name}"

subject = subject + "/CN={}".format(dns_name)
subject = subject + f"/CN={dns_name}"

cmd = "openssl req -new -{} -key {} -out {} -subj '{}'".format(
shatype, tmppriv, tmpcsr, subject
Expand Down Expand Up @@ -689,7 +683,7 @@ def show_organization(domain):
salt-run digicert.show_company example.com
"""
data = salt.utils.http.query(
"{}/companies/domain/{}".format(_base_url(), domain),
f"{_base_url()}/companies/domain/{domain}",
status=True,
decode=True,
decode_type="json",
Expand All @@ -712,7 +706,7 @@ def show_csrs():
salt-run digicert.show_csrs
"""
data = salt.utils.http.query(
"{}/certificaterequests".format(_base_url()),
f"{_base_url()}/certificaterequests",
status=True,
decode=True,
decode_type="json",
Expand Down