mirror of
https://github.com/ansible-collections/community.crypto.git
synced 2026-05-08 22:33:53 +00:00
Reformat everything with black.
I had to undo the u string prefix removals to not drop Python 2 compatibility. That's why black isn't enabled in antsibull-nox.toml yet.
This commit is contained in:
@@ -45,7 +45,7 @@ except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
_OPENSSL_ENVIRONMENT_UPDATE = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C', LC_CTYPE='C')
|
||||
_OPENSSL_ENVIRONMENT_UPDATE = dict(LANG="C", LC_ALL="C", LC_MESSAGES="C", LC_CTYPE="C")
|
||||
|
||||
|
||||
def _extract_date(out_text, name, cert_filename_suffix=""):
|
||||
@@ -55,11 +55,17 @@ def _extract_date(out_text, name, cert_filename_suffix=""):
|
||||
# even though the information is there and a supported timezone for all supported
|
||||
# Python implementations (GMT). So we have to modify the datetime object by
|
||||
# replacing it by UTC.
|
||||
return ensure_utc_timezone(datetime.datetime.strptime(date_str, '%b %d %H:%M:%S %Y %Z'))
|
||||
return ensure_utc_timezone(
|
||||
datetime.datetime.strptime(date_str, "%b %d %H:%M:%S %Y %Z")
|
||||
)
|
||||
except AttributeError:
|
||||
raise BackendException("No '{0}' date found{1}".format(name, cert_filename_suffix))
|
||||
raise BackendException(
|
||||
"No '{0}' date found{1}".format(name, cert_filename_suffix)
|
||||
)
|
||||
except ValueError as exc:
|
||||
raise BackendException("Failed to parse '{0}' date{1}: {2}".format(name, cert_filename_suffix, exc))
|
||||
raise BackendException(
|
||||
"Failed to parse '{0}' date{1}: {2}".format(name, cert_filename_suffix, exc)
|
||||
)
|
||||
|
||||
|
||||
def _decode_octets(octets_text):
|
||||
@@ -69,7 +75,11 @@ def _decode_octets(octets_text):
|
||||
def _extract_octets(out_text, name, required=True, potential_prefixes=None):
|
||||
regexp = r"\s+%s:\s*\n\s+%s([A-Fa-f0-9]{2}(?::[A-Fa-f0-9]{2})*)\s*\n" % (
|
||||
name,
|
||||
('(?:%s)' % '|'.join(re.escape(pp) for pp in potential_prefixes)) if potential_prefixes else '',
|
||||
(
|
||||
("(?:%s)" % "|".join(re.escape(pp) for pp in potential_prefixes))
|
||||
if potential_prefixes
|
||||
else ""
|
||||
),
|
||||
)
|
||||
match = re.search(regexp, out_text, re.MULTILINE | re.DOTALL)
|
||||
if match is not None:
|
||||
@@ -83,36 +93,41 @@ class OpenSSLCLIBackend(CryptoBackend):
|
||||
def __init__(self, module, openssl_binary=None):
|
||||
super(OpenSSLCLIBackend, self).__init__(module, with_timezone=True)
|
||||
if openssl_binary is None:
|
||||
openssl_binary = module.get_bin_path('openssl', True)
|
||||
openssl_binary = module.get_bin_path("openssl", True)
|
||||
self.openssl_binary = openssl_binary
|
||||
|
||||
def parse_key(self, key_file=None, key_content=None, passphrase=None):
|
||||
'''
|
||||
"""
|
||||
Parses an RSA or Elliptic Curve key file in PEM format and returns key_data.
|
||||
Raises KeyParsingError in case of errors.
|
||||
'''
|
||||
"""
|
||||
if passphrase is not None:
|
||||
raise KeyParsingError('openssl backend does not support key passphrases')
|
||||
raise KeyParsingError("openssl backend does not support key passphrases")
|
||||
# If key_file is not given, but key_content, write that to a temporary file
|
||||
if key_file is None:
|
||||
fd, tmpsrc = tempfile.mkstemp()
|
||||
self.module.add_cleanup_file(tmpsrc) # Ansible will delete the file on exit
|
||||
f = os.fdopen(fd, 'wb')
|
||||
f = os.fdopen(fd, "wb")
|
||||
try:
|
||||
f.write(key_content.encode('utf-8'))
|
||||
f.write(key_content.encode("utf-8"))
|
||||
key_file = tmpsrc
|
||||
except Exception as err:
|
||||
try:
|
||||
f.close()
|
||||
except Exception:
|
||||
pass
|
||||
raise KeyParsingError("failed to create temporary content file: %s" % to_native(err), exception=traceback.format_exc())
|
||||
raise KeyParsingError(
|
||||
"failed to create temporary content file: %s" % to_native(err),
|
||||
exception=traceback.format_exc(),
|
||||
)
|
||||
f.close()
|
||||
# Parse key
|
||||
account_key_type = None
|
||||
with open(key_file, "rt") as f:
|
||||
for line in f:
|
||||
m = re.match(r"^\s*-{5,}BEGIN\s+(EC|RSA)\s+PRIVATE\s+KEY-{5,}\s*$", line)
|
||||
m = re.match(
|
||||
r"^\s*-{5,}BEGIN\s+(EC|RSA)\s+PRIVATE\s+KEY-{5,}\s*$", line
|
||||
)
|
||||
if m is not None:
|
||||
account_key_type = m.group(1).lower()
|
||||
break
|
||||
@@ -125,111 +140,162 @@ class OpenSSLCLIBackend(CryptoBackend):
|
||||
if account_key_type not in ("rsa", "ec"):
|
||||
raise KeyParsingError('unknown key type "%s"' % account_key_type)
|
||||
|
||||
openssl_keydump_cmd = [self.openssl_binary, account_key_type, "-in", key_file, "-noout", "-text"]
|
||||
openssl_keydump_cmd = [
|
||||
self.openssl_binary,
|
||||
account_key_type,
|
||||
"-in",
|
||||
key_file,
|
||||
"-noout",
|
||||
"-text",
|
||||
]
|
||||
rc, out, err = self.module.run_command(
|
||||
openssl_keydump_cmd, check_rc=False, environ_update=_OPENSSL_ENVIRONMENT_UPDATE)
|
||||
openssl_keydump_cmd,
|
||||
check_rc=False,
|
||||
environ_update=_OPENSSL_ENVIRONMENT_UPDATE,
|
||||
)
|
||||
if rc != 0:
|
||||
raise BackendException('Error while running {cmd}: {stderr}'.format(cmd=' '.join(openssl_keydump_cmd), stderr=to_text(err)))
|
||||
raise BackendException(
|
||||
"Error while running {cmd}: {stderr}".format(
|
||||
cmd=" ".join(openssl_keydump_cmd), stderr=to_text(err)
|
||||
)
|
||||
)
|
||||
|
||||
out_text = to_text(out, errors='surrogate_or_strict')
|
||||
out_text = to_text(out, errors="surrogate_or_strict")
|
||||
|
||||
if account_key_type == 'rsa':
|
||||
pub_hex = re.search(r"modulus:\n\s+00:([a-f0-9\:\s]+?)\npublicExponent", out_text, re.MULTILINE | re.DOTALL).group(1)
|
||||
if account_key_type == "rsa":
|
||||
pub_hex = re.search(
|
||||
r"modulus:\n\s+00:([a-f0-9\:\s]+?)\npublicExponent",
|
||||
out_text,
|
||||
re.MULTILINE | re.DOTALL,
|
||||
).group(1)
|
||||
|
||||
pub_exp = re.search(r"\npublicExponent: ([0-9]+)", out_text, re.MULTILINE | re.DOTALL).group(1)
|
||||
pub_exp = re.search(
|
||||
r"\npublicExponent: ([0-9]+)", out_text, re.MULTILINE | re.DOTALL
|
||||
).group(1)
|
||||
pub_exp = "{0:x}".format(int(pub_exp))
|
||||
if len(pub_exp) % 2:
|
||||
pub_exp = "0{0}".format(pub_exp)
|
||||
|
||||
return {
|
||||
'key_file': key_file,
|
||||
'type': 'rsa',
|
||||
'alg': 'RS256',
|
||||
'jwk': {
|
||||
"key_file": key_file,
|
||||
"type": "rsa",
|
||||
"alg": "RS256",
|
||||
"jwk": {
|
||||
"kty": "RSA",
|
||||
"e": nopad_b64(binascii.unhexlify(pub_exp.encode("utf-8"))),
|
||||
"n": nopad_b64(_decode_octets(pub_hex)),
|
||||
},
|
||||
'hash': 'sha256',
|
||||
"hash": "sha256",
|
||||
}
|
||||
elif account_key_type == 'ec':
|
||||
elif account_key_type == "ec":
|
||||
pub_data = re.search(
|
||||
r"pub:\s*\n\s+04:([a-f0-9\:\s]+?)\nASN1 OID: (\S+)(?:\nNIST CURVE: (\S+))?",
|
||||
out_text,
|
||||
re.MULTILINE | re.DOTALL,
|
||||
)
|
||||
if pub_data is None:
|
||||
raise KeyParsingError('cannot parse elliptic curve key')
|
||||
raise KeyParsingError("cannot parse elliptic curve key")
|
||||
pub_hex = _decode_octets(pub_data.group(1))
|
||||
asn1_oid_curve = pub_data.group(2).lower()
|
||||
nist_curve = pub_data.group(3).lower() if pub_data.group(3) else None
|
||||
if asn1_oid_curve == 'prime256v1' or nist_curve == 'p-256':
|
||||
if asn1_oid_curve == "prime256v1" or nist_curve == "p-256":
|
||||
bits = 256
|
||||
alg = 'ES256'
|
||||
hashalg = 'sha256'
|
||||
alg = "ES256"
|
||||
hashalg = "sha256"
|
||||
point_size = 32
|
||||
curve = 'P-256'
|
||||
elif asn1_oid_curve == 'secp384r1' or nist_curve == 'p-384':
|
||||
curve = "P-256"
|
||||
elif asn1_oid_curve == "secp384r1" or nist_curve == "p-384":
|
||||
bits = 384
|
||||
alg = 'ES384'
|
||||
hashalg = 'sha384'
|
||||
alg = "ES384"
|
||||
hashalg = "sha384"
|
||||
point_size = 48
|
||||
curve = 'P-384'
|
||||
elif asn1_oid_curve == 'secp521r1' or nist_curve == 'p-521':
|
||||
curve = "P-384"
|
||||
elif asn1_oid_curve == "secp521r1" or nist_curve == "p-521":
|
||||
# Not yet supported on Let's Encrypt side, see
|
||||
# https://github.com/letsencrypt/boulder/issues/2217
|
||||
bits = 521
|
||||
alg = 'ES512'
|
||||
hashalg = 'sha512'
|
||||
alg = "ES512"
|
||||
hashalg = "sha512"
|
||||
point_size = 66
|
||||
curve = 'P-521'
|
||||
curve = "P-521"
|
||||
else:
|
||||
raise KeyParsingError('unknown elliptic curve: %s / %s' % (asn1_oid_curve, nist_curve))
|
||||
raise KeyParsingError(
|
||||
"unknown elliptic curve: %s / %s" % (asn1_oid_curve, nist_curve)
|
||||
)
|
||||
num_bytes = (bits + 7) // 8
|
||||
if len(pub_hex) != 2 * num_bytes:
|
||||
raise KeyParsingError('bad elliptic curve point (%s / %s)' % (asn1_oid_curve, nist_curve))
|
||||
raise KeyParsingError(
|
||||
"bad elliptic curve point (%s / %s)" % (asn1_oid_curve, nist_curve)
|
||||
)
|
||||
return {
|
||||
'key_file': key_file,
|
||||
'type': 'ec',
|
||||
'alg': alg,
|
||||
'jwk': {
|
||||
"key_file": key_file,
|
||||
"type": "ec",
|
||||
"alg": alg,
|
||||
"jwk": {
|
||||
"kty": "EC",
|
||||
"crv": curve,
|
||||
"x": nopad_b64(pub_hex[:num_bytes]),
|
||||
"y": nopad_b64(pub_hex[num_bytes:]),
|
||||
},
|
||||
'hash': hashalg,
|
||||
'point_size': point_size,
|
||||
"hash": hashalg,
|
||||
"point_size": point_size,
|
||||
}
|
||||
|
||||
def sign(self, payload64, protected64, key_data):
|
||||
sign_payload = "{0}.{1}".format(protected64, payload64).encode('utf8')
|
||||
if key_data['type'] == 'hmac':
|
||||
hex_key = to_native(binascii.hexlify(base64.urlsafe_b64decode(key_data['jwk']['k'])))
|
||||
cmd_postfix = ["-mac", "hmac", "-macopt", "hexkey:{0}".format(hex_key), "-binary"]
|
||||
sign_payload = "{0}.{1}".format(protected64, payload64).encode("utf8")
|
||||
if key_data["type"] == "hmac":
|
||||
hex_key = to_native(
|
||||
binascii.hexlify(base64.urlsafe_b64decode(key_data["jwk"]["k"]))
|
||||
)
|
||||
cmd_postfix = [
|
||||
"-mac",
|
||||
"hmac",
|
||||
"-macopt",
|
||||
"hexkey:{0}".format(hex_key),
|
||||
"-binary",
|
||||
]
|
||||
else:
|
||||
cmd_postfix = ["-sign", key_data['key_file']]
|
||||
openssl_sign_cmd = [self.openssl_binary, "dgst", "-{0}".format(key_data['hash'])] + cmd_postfix
|
||||
cmd_postfix = ["-sign", key_data["key_file"]]
|
||||
openssl_sign_cmd = [
|
||||
self.openssl_binary,
|
||||
"dgst",
|
||||
"-{0}".format(key_data["hash"]),
|
||||
] + cmd_postfix
|
||||
|
||||
rc, out, err = self.module.run_command(
|
||||
openssl_sign_cmd, data=sign_payload, check_rc=False, binary_data=True, environ_update=_OPENSSL_ENVIRONMENT_UPDATE)
|
||||
openssl_sign_cmd,
|
||||
data=sign_payload,
|
||||
check_rc=False,
|
||||
binary_data=True,
|
||||
environ_update=_OPENSSL_ENVIRONMENT_UPDATE,
|
||||
)
|
||||
if rc != 0:
|
||||
raise BackendException('Error while running {cmd}: {stderr}'.format(cmd=' '.join(openssl_sign_cmd), stderr=to_text(err)))
|
||||
raise BackendException(
|
||||
"Error while running {cmd}: {stderr}".format(
|
||||
cmd=" ".join(openssl_sign_cmd), stderr=to_text(err)
|
||||
)
|
||||
)
|
||||
|
||||
if key_data['type'] == 'ec':
|
||||
if key_data["type"] == "ec":
|
||||
dummy, der_out, dummy = self.module.run_command(
|
||||
[self.openssl_binary, "asn1parse", "-inform", "DER"],
|
||||
data=out, binary_data=True, environ_update=_OPENSSL_ENVIRONMENT_UPDATE)
|
||||
expected_len = 2 * key_data['point_size']
|
||||
data=out,
|
||||
binary_data=True,
|
||||
environ_update=_OPENSSL_ENVIRONMENT_UPDATE,
|
||||
)
|
||||
expected_len = 2 * key_data["point_size"]
|
||||
sig = re.findall(
|
||||
r"prim:\s+INTEGER\s+:([0-9A-F]{1,%s})\n" % expected_len,
|
||||
to_text(der_out, errors='surrogate_or_strict'))
|
||||
to_text(der_out, errors="surrogate_or_strict"),
|
||||
)
|
||||
if len(sig) != 2:
|
||||
raise BackendException(
|
||||
"failed to generate Elliptic Curve signature; cannot parse DER output: {0}".format(
|
||||
to_text(der_out, errors='surrogate_or_strict')))
|
||||
sig[0] = (expected_len - len(sig[0])) * '0' + sig[0]
|
||||
sig[1] = (expected_len - len(sig[1])) * '0' + sig[1]
|
||||
to_text(der_out, errors="surrogate_or_strict")
|
||||
)
|
||||
)
|
||||
sig[0] = (expected_len - len(sig[0])) * "0" + sig[0]
|
||||
sig[1] = (expected_len - len(sig[1])) * "0" + sig[1]
|
||||
out = binascii.unhexlify(sig[0]) + binascii.unhexlify(sig[1])
|
||||
|
||||
return {
|
||||
@@ -239,30 +305,35 @@ class OpenSSLCLIBackend(CryptoBackend):
|
||||
}
|
||||
|
||||
def create_mac_key(self, alg, key):
|
||||
'''Create a MAC key.'''
|
||||
if alg == 'HS256':
|
||||
hashalg = 'sha256'
|
||||
"""Create a MAC key."""
|
||||
if alg == "HS256":
|
||||
hashalg = "sha256"
|
||||
hashbytes = 32
|
||||
elif alg == 'HS384':
|
||||
hashalg = 'sha384'
|
||||
elif alg == "HS384":
|
||||
hashalg = "sha384"
|
||||
hashbytes = 48
|
||||
elif alg == 'HS512':
|
||||
hashalg = 'sha512'
|
||||
elif alg == "HS512":
|
||||
hashalg = "sha512"
|
||||
hashbytes = 64
|
||||
else:
|
||||
raise BackendException('Unsupported MAC key algorithm for OpenSSL backend: {0}'.format(alg))
|
||||
raise BackendException(
|
||||
"Unsupported MAC key algorithm for OpenSSL backend: {0}".format(alg)
|
||||
)
|
||||
key_bytes = base64.urlsafe_b64decode(key)
|
||||
if len(key_bytes) < hashbytes:
|
||||
raise BackendException(
|
||||
'{0} key must be at least {1} bytes long (after Base64 decoding)'.format(alg, hashbytes))
|
||||
"{0} key must be at least {1} bytes long (after Base64 decoding)".format(
|
||||
alg, hashbytes
|
||||
)
|
||||
)
|
||||
return {
|
||||
'type': 'hmac',
|
||||
'alg': alg,
|
||||
'jwk': {
|
||||
'kty': 'oct',
|
||||
'k': key,
|
||||
"type": "hmac",
|
||||
"alg": alg,
|
||||
"jwk": {
|
||||
"kty": "oct",
|
||||
"k": key,
|
||||
},
|
||||
'hash': hashalg,
|
||||
"hash": hashalg,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
@@ -274,25 +345,41 @@ class OpenSSLCLIBackend(CryptoBackend):
|
||||
return ip
|
||||
|
||||
def get_ordered_csr_identifiers(self, csr_filename=None, csr_content=None):
|
||||
'''
|
||||
"""
|
||||
Return a list of requested identifiers (CN and SANs) for the CSR.
|
||||
Each identifier is a pair (type, identifier), where type is either
|
||||
'dns' or 'ip'.
|
||||
|
||||
The list is deduplicated, and if a CNAME is present, it will be returned
|
||||
as the first element in the result.
|
||||
'''
|
||||
"""
|
||||
filename = csr_filename
|
||||
data = None
|
||||
if csr_content is not None:
|
||||
filename = '/dev/stdin'
|
||||
data = csr_content.encode('utf-8')
|
||||
filename = "/dev/stdin"
|
||||
data = csr_content.encode("utf-8")
|
||||
|
||||
openssl_csr_cmd = [self.openssl_binary, "req", "-in", filename, "-noout", "-text"]
|
||||
openssl_csr_cmd = [
|
||||
self.openssl_binary,
|
||||
"req",
|
||||
"-in",
|
||||
filename,
|
||||
"-noout",
|
||||
"-text",
|
||||
]
|
||||
rc, out, err = self.module.run_command(
|
||||
openssl_csr_cmd, data=data, check_rc=False, binary_data=True, environ_update=_OPENSSL_ENVIRONMENT_UPDATE)
|
||||
openssl_csr_cmd,
|
||||
data=data,
|
||||
check_rc=False,
|
||||
binary_data=True,
|
||||
environ_update=_OPENSSL_ENVIRONMENT_UPDATE,
|
||||
)
|
||||
if rc != 0:
|
||||
raise BackendException('Error while running {cmd}: {stderr}'.format(cmd=' '.join(openssl_csr_cmd), stderr=to_text(err)))
|
||||
raise BackendException(
|
||||
"Error while running {cmd}: {stderr}".format(
|
||||
cmd=" ".join(openssl_csr_cmd), stderr=to_text(err)
|
||||
)
|
||||
)
|
||||
|
||||
identifiers = set()
|
||||
result = []
|
||||
@@ -303,61 +390,90 @@ class OpenSSLCLIBackend(CryptoBackend):
|
||||
identifiers.add(identifier)
|
||||
result.append(identifier)
|
||||
|
||||
common_name = re.search(r"Subject:.* CN\s?=\s?([^\s,;/]+)", to_text(out, errors='surrogate_or_strict'))
|
||||
common_name = re.search(
|
||||
r"Subject:.* CN\s?=\s?([^\s,;/]+)",
|
||||
to_text(out, errors="surrogate_or_strict"),
|
||||
)
|
||||
if common_name is not None:
|
||||
add_identifier(('dns', common_name.group(1)))
|
||||
add_identifier(("dns", common_name.group(1)))
|
||||
subject_alt_names = re.search(
|
||||
r"X509v3 Subject Alternative Name: (?:critical)?\n +([^\n]+)\n",
|
||||
to_text(out, errors='surrogate_or_strict'), re.MULTILINE | re.DOTALL)
|
||||
to_text(out, errors="surrogate_or_strict"),
|
||||
re.MULTILINE | re.DOTALL,
|
||||
)
|
||||
if subject_alt_names is not None:
|
||||
for san in subject_alt_names.group(1).split(", "):
|
||||
if san.lower().startswith("dns:"):
|
||||
add_identifier(('dns', san[4:]))
|
||||
add_identifier(("dns", san[4:]))
|
||||
elif san.lower().startswith("ip:"):
|
||||
add_identifier(('ip', self._normalize_ip(san[3:])))
|
||||
add_identifier(("ip", self._normalize_ip(san[3:])))
|
||||
elif san.lower().startswith("ip address:"):
|
||||
add_identifier(('ip', self._normalize_ip(san[11:])))
|
||||
add_identifier(("ip", self._normalize_ip(san[11:])))
|
||||
else:
|
||||
raise BackendException('Found unsupported SAN identifier "{0}"'.format(san))
|
||||
raise BackendException(
|
||||
'Found unsupported SAN identifier "{0}"'.format(san)
|
||||
)
|
||||
return result
|
||||
|
||||
def get_csr_identifiers(self, csr_filename=None, csr_content=None):
|
||||
'''
|
||||
"""
|
||||
Return a set of requested identifiers (CN and SANs) for the CSR.
|
||||
Each identifier is a pair (type, identifier), where type is either
|
||||
'dns' or 'ip'.
|
||||
'''
|
||||
return set(self.get_ordered_csr_identifiers(csr_filename=csr_filename, csr_content=csr_content))
|
||||
"""
|
||||
return set(
|
||||
self.get_ordered_csr_identifiers(
|
||||
csr_filename=csr_filename, csr_content=csr_content
|
||||
)
|
||||
)
|
||||
|
||||
def get_cert_days(self, cert_filename=None, cert_content=None, now=None):
|
||||
'''
|
||||
"""
|
||||
Return the days the certificate in cert_filename remains valid and -1
|
||||
if the file was not found. If cert_filename contains more than one
|
||||
certificate, only the first one will be considered.
|
||||
|
||||
If now is not specified, datetime.datetime.now() is used.
|
||||
'''
|
||||
"""
|
||||
filename = cert_filename
|
||||
data = None
|
||||
if cert_content is not None:
|
||||
filename = '/dev/stdin'
|
||||
data = cert_content.encode('utf-8')
|
||||
cert_filename_suffix = ''
|
||||
filename = "/dev/stdin"
|
||||
data = cert_content.encode("utf-8")
|
||||
cert_filename_suffix = ""
|
||||
elif cert_filename is not None:
|
||||
if not os.path.exists(cert_filename):
|
||||
return -1
|
||||
cert_filename_suffix = ' in {0}'.format(cert_filename)
|
||||
cert_filename_suffix = " in {0}".format(cert_filename)
|
||||
else:
|
||||
return -1
|
||||
|
||||
openssl_cert_cmd = [self.openssl_binary, "x509", "-in", filename, "-noout", "-text"]
|
||||
openssl_cert_cmd = [
|
||||
self.openssl_binary,
|
||||
"x509",
|
||||
"-in",
|
||||
filename,
|
||||
"-noout",
|
||||
"-text",
|
||||
]
|
||||
rc, out, err = self.module.run_command(
|
||||
openssl_cert_cmd, data=data, check_rc=False, binary_data=True, environ_update=_OPENSSL_ENVIRONMENT_UPDATE)
|
||||
openssl_cert_cmd,
|
||||
data=data,
|
||||
check_rc=False,
|
||||
binary_data=True,
|
||||
environ_update=_OPENSSL_ENVIRONMENT_UPDATE,
|
||||
)
|
||||
if rc != 0:
|
||||
raise BackendException('Error while running {cmd}: {stderr}'.format(cmd=' '.join(openssl_cert_cmd), stderr=to_text(err)))
|
||||
raise BackendException(
|
||||
"Error while running {cmd}: {stderr}".format(
|
||||
cmd=" ".join(openssl_cert_cmd), stderr=to_text(err)
|
||||
)
|
||||
)
|
||||
|
||||
out_text = to_text(out, errors='surrogate_or_strict')
|
||||
not_after = _extract_date(out_text, 'Not After', cert_filename_suffix=cert_filename_suffix)
|
||||
out_text = to_text(out, errors="surrogate_or_strict")
|
||||
not_after = _extract_date(
|
||||
out_text, "Not After", cert_filename_suffix=cert_filename_suffix
|
||||
)
|
||||
if now is None:
|
||||
now = self.get_now()
|
||||
else:
|
||||
@@ -365,45 +481,76 @@ class OpenSSLCLIBackend(CryptoBackend):
|
||||
return (not_after - now).days
|
||||
|
||||
def create_chain_matcher(self, criterium):
|
||||
'''
|
||||
"""
|
||||
Given a Criterium object, creates a ChainMatcher object.
|
||||
'''
|
||||
raise BackendException('Alternate chain matching can only be used with the "cryptography" backend.')
|
||||
"""
|
||||
raise BackendException(
|
||||
'Alternate chain matching can only be used with the "cryptography" backend.'
|
||||
)
|
||||
|
||||
def get_cert_information(self, cert_filename=None, cert_content=None):
|
||||
'''
|
||||
"""
|
||||
Return some information on a X.509 certificate as a CertificateInformation object.
|
||||
'''
|
||||
"""
|
||||
filename = cert_filename
|
||||
data = None
|
||||
if cert_filename is not None:
|
||||
cert_filename_suffix = ' in {0}'.format(cert_filename)
|
||||
cert_filename_suffix = " in {0}".format(cert_filename)
|
||||
else:
|
||||
filename = '/dev/stdin'
|
||||
filename = "/dev/stdin"
|
||||
data = to_bytes(cert_content)
|
||||
cert_filename_suffix = ''
|
||||
cert_filename_suffix = ""
|
||||
|
||||
openssl_cert_cmd = [self.openssl_binary, "x509", "-in", filename, "-noout", "-text"]
|
||||
openssl_cert_cmd = [
|
||||
self.openssl_binary,
|
||||
"x509",
|
||||
"-in",
|
||||
filename,
|
||||
"-noout",
|
||||
"-text",
|
||||
]
|
||||
rc, out, err = self.module.run_command(
|
||||
openssl_cert_cmd, data=data, check_rc=False, binary_data=True, environ_update=_OPENSSL_ENVIRONMENT_UPDATE)
|
||||
openssl_cert_cmd,
|
||||
data=data,
|
||||
check_rc=False,
|
||||
binary_data=True,
|
||||
environ_update=_OPENSSL_ENVIRONMENT_UPDATE,
|
||||
)
|
||||
if rc != 0:
|
||||
raise BackendException('Error while running {cmd}: {stderr}'.format(cmd=' '.join(openssl_cert_cmd), stderr=to_text(err)))
|
||||
raise BackendException(
|
||||
"Error while running {cmd}: {stderr}".format(
|
||||
cmd=" ".join(openssl_cert_cmd), stderr=to_text(err)
|
||||
)
|
||||
)
|
||||
|
||||
out_text = to_text(out, errors='surrogate_or_strict')
|
||||
out_text = to_text(out, errors="surrogate_or_strict")
|
||||
|
||||
not_after = _extract_date(out_text, 'Not After', cert_filename_suffix=cert_filename_suffix)
|
||||
not_before = _extract_date(out_text, 'Not Before', cert_filename_suffix=cert_filename_suffix)
|
||||
not_after = _extract_date(
|
||||
out_text, "Not After", cert_filename_suffix=cert_filename_suffix
|
||||
)
|
||||
not_before = _extract_date(
|
||||
out_text, "Not Before", cert_filename_suffix=cert_filename_suffix
|
||||
)
|
||||
|
||||
sn = re.search(
|
||||
r" Serial Number: ([0-9]+)",
|
||||
to_text(out, errors='surrogate_or_strict'), re.MULTILINE | re.DOTALL)
|
||||
to_text(out, errors="surrogate_or_strict"),
|
||||
re.MULTILINE | re.DOTALL,
|
||||
)
|
||||
if sn:
|
||||
serial = int(sn.group(1))
|
||||
else:
|
||||
serial = convert_bytes_to_int(_extract_octets(out_text, 'Serial Number', required=True))
|
||||
serial = convert_bytes_to_int(
|
||||
_extract_octets(out_text, "Serial Number", required=True)
|
||||
)
|
||||
|
||||
ski = _extract_octets(out_text, 'X509v3 Subject Key Identifier', required=False)
|
||||
aki = _extract_octets(out_text, 'X509v3 Authority Key Identifier', required=False, potential_prefixes=['keyid:', ''])
|
||||
ski = _extract_octets(out_text, "X509v3 Subject Key Identifier", required=False)
|
||||
aki = _extract_octets(
|
||||
out_text,
|
||||
"X509v3 Authority Key Identifier",
|
||||
required=False,
|
||||
potential_prefixes=["keyid:", ""],
|
||||
)
|
||||
|
||||
return CertificateInformation(
|
||||
not_valid_after=not_after,
|
||||
|
||||
Reference in New Issue
Block a user