diff --git a/plugins/module_utils/_acme/backend_openssl_cli.py b/plugins/module_utils/_acme/backend_openssl_cli.py index 4045cc2e..3baf099f 100644 --- a/plugins/module_utils/_acme/backend_openssl_cli.py +++ b/plugins/module_utils/_acme/backend_openssl_cli.py @@ -120,6 +120,94 @@ def _extract_octets( raise BackendException(f"No '{name}' octet string found") +def _extract_rsa_key(out_text: str, *, key_file: str | None = None) -> dict[str, t.Any]: + matcher = re.search( + r"modulus:\n\s+(?:00:)?([a-f0-9\:\s]+?)\npublicExponent", + out_text, + re.MULTILINE | re.DOTALL, + ) + if matcher is None: + raise KeyParsingError("cannot parse RSA key: modulus not found") + pub_hex = matcher.group(1) + + matcher = re.search( + r"\npublicExponent: ([0-9]+)", out_text, re.MULTILINE | re.DOTALL + ) + if matcher is None: + raise KeyParsingError("cannot parse RSA key: public exponent not found") + pub_exp = matcher.group(1) + pub_exp = f"{int(pub_exp):x}" + if len(pub_exp) % 2: + pub_exp = f"0{pub_exp}" + + return { + "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", + } + + +def _extract_ec_key(out_text: str, *, key_file: str | None = None) -> dict[str, t.Any]: + 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") + 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": + bits = 256 + alg = "ES256" + hashalg = "sha256" + point_size = 32 + curve = "P-256" + elif asn1_oid_curve == "secp384r1" or nist_curve == "p-384": + bits = 384 + alg = "ES384" + hashalg = "sha384" + point_size = 48 + 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" + point_size = 66 + curve = "P-521" + else: + raise KeyParsingError( + f"unknown elliptic curve: {asn1_oid_curve} / {nist_curve}" + ) + num_bytes = (bits + 7) // 8 + if len(pub_hex) != 2 * num_bytes: + raise KeyParsingError( + f"bad elliptic curve point ({asn1_oid_curve} / {nist_curve})" + ) + return { + "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, + } + + class OpenSSLCLIBackend(CryptoBackend): def __init__( self, *, module: AnsibleModule, openssl_binary: str | None = None @@ -204,89 +292,13 @@ class OpenSSLCLIBackend(CryptoBackend): out_text = to_text(out, errors="surrogate_or_strict") if account_key_type == "rsa": - matcher = re.search( - r"modulus:\n\s+00:([a-f0-9\:\s]+?)\npublicExponent", - out_text, - re.MULTILINE | re.DOTALL, + return _extract_rsa_key( + out_text, key_file=str(key_file) if key_file is not None else None ) - if matcher is None: - raise KeyParsingError("cannot parse RSA key: modulus not found") - pub_hex = matcher.group(1) - - matcher = re.search( - r"\npublicExponent: ([0-9]+)", out_text, re.MULTILINE | re.DOTALL - ) - if matcher is None: - raise KeyParsingError("cannot parse RSA key: public exponent not found") - pub_exp = matcher.group(1) - pub_exp = f"{int(pub_exp):x}" - if len(pub_exp) % 2: - pub_exp = f"0{pub_exp}" - - return { - "key_file": str(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", - } if 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, + return _extract_ec_key( + out_text, key_file=str(key_file) if key_file is not None else None ) - if pub_data is None: - 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": - bits = 256 - alg = "ES256" - hashalg = "sha256" - point_size = 32 - curve = "P-256" - elif asn1_oid_curve == "secp384r1" or nist_curve == "p-384": - bits = 384 - alg = "ES384" - hashalg = "sha384" - point_size = 48 - 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" - point_size = 66 - curve = "P-521" - else: - raise KeyParsingError( - f"unknown elliptic curve: {asn1_oid_curve} / {nist_curve}" - ) - num_bytes = (bits + 7) // 8 - if len(pub_hex) != 2 * num_bytes: - raise KeyParsingError( - f"bad elliptic curve point ({asn1_oid_curve} / {nist_curve})" - ) - return { - "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, - } raise KeyParsingError( f"Internal error: unexpected account_key_type = {account_key_type!r}" ) diff --git a/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2-3.6.2.txt b/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2-3.6.2.txt new file mode 100644 index 00000000..5b50962f --- /dev/null +++ b/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2-3.6.2.txt @@ -0,0 +1,169 @@ +Private-Key: (4096 bit, 2 primes) +modulus: + 00:e8:19:b0:47:ad:1b:4d:0a:a8:ef:ec:e5:14:1c: + fa:18:9c:27:2f:92:e1:5c:d5:5c:23:fd:5e:44:5f: + bf:a0:a2:1f:75:0c:3e:c3:76:5e:f9:15:01:36:4e: + 6c:90:9c:77:a8:3c:dd:9f:4f:51:5c:0d:d7:4f:b5: + d4:cd:d4:b6:1e:83:9b:70:fc:90:34:bf:7d:e8:66: + a0:f5:57:fb:25:8c:3d:a5:67:ff:da:3b:cf:56:a4: + f7:e3:d4:00:1b:62:b2:36:90:11:0e:51:71:c1:18: + 36:0c:4e:af:8b:82:35:5d:2f:5d:2e:3e:29:ec:99: + 76:eb:98:1c:f7:ac:bd:71:de:d7:70:8c:3e:86:ab: + d0:e8:2c:78:1c:da:6d:6e:9e:13:3e:2f:cd:4a:de: + 32:32:e7:52:17:55:0d:42:fa:51:44:7c:ed:06:46: + 9e:50:18:45:a5:f8:5c:5e:69:66:5f:78:7f:5b:0a: + ae:da:0a:94:cb:37:25:9d:64:d3:53:bf:52:40:c0: + 4d:ac:8c:f0:f4:3a:5a:eb:af:d7:e3:d9:c9:a3:56: + 47:3e:ee:94:fa:e1:27:7d:c0:5a:d7:65:ed:d3:b7: + d5:de:d9:c7:c7:12:91:fb:e9:22:53:7f:21:84:7f: + 89:72:ba:9e:65:3e:e4:c5:14:07:12:62:a5:36:6a: + 3b:7d:3d:84:de:07:1b:06:bb:2e:58:de:5e:50:97: + 39:e8:f6:01:b3:89:df:df:0a:f1:62:ca:4a:a6:67: + 37:ed:8a:77:89:f6:ad:f5:54:f3:41:59:c1:5c:b1: + bc:ed:78:07:96:44:1c:3d:dd:41:74:45:7c:f8:77: + b1:73:71:8d:30:22:e7:8f:57:bc:ee:b0:c6:89:06: + 87:e7:9b:ca:e9:a6:9b:4b:97:22:f6:0a:ba:16:01: + 1c:26:97:eb:57:4d:29:1d:aa:34:9d:ee:ba:24:83: + b6:b5:c9:39:37:0d:69:52:4e:25:7d:92:76:99:ec: + e6:39:ad:c5:be:76:ee:4f:09:e9:4f:6a:14:63:80: + 62:1e:ed:07:0e:e5:ab:60:7d:3c:cf:4e:d7:c8:d1: + fc:45:da:fc:f0:f1:3c:49:6e:4c:72:23:ad:6b:84: + b2:2d:1d:9b:c5:ac:cc:f4:d8:2f:54:aa:0a:0a:e9: + c3:55:35:7e:11:c7:de:57:d0:8d:fe:32:50:68:7b: + be:af:d1:7b:7a:e0:ae:52:e1:40:64:b1:6f:1b:91: + a5:70:08:8a:81:97:19:49:a2:c1:44:f9:39:e1:0c: + f8:94:af:8a:12:f9:0a:96:7c:37:98:73:dc:5f:df: + 32:f5:58:3d:bf:ea:cc:c3:6d:0e:e8:2f:ca:40:96: + 98:1a:f5 +publicExponent: 65537 (0x10001) +privateExponent: + 66:47:df:c3:8e:58:e0:18:08:ff:86:0d:23:52:6b: + b2:09:aa:49:10:38:a8:f0:cb:24:7f:04:9a:2b:f9: + a5:df:9b:ee:38:41:b6:60:45:15:0d:f9:15:45:f5: + 18:bb:23:0d:ec:18:9c:1a:57:97:b1:ef:c6:cc:31: + e5:ac:cd:be:df:af:51:d8:b2:f1:d3:cb:37:ed:76: + 13:f8:3c:10:3d:5f:73:33:43:f0:17:78:54:cd:e9: + 01:a8:cc:8d:44:ee:95:15:e2:b6:45:14:d4:8b:87: + 51:e0:21:02:e1:14:04:27:19:b0:85:ab:72:fc:e4: + 07:89:66:86:8c:c4:85:58:36:e7:7d:9e:16:39:c4: + 1b:74:71:50:01:bf:c4:c5:fb:63:e5:ab:d9:c8:d6: + 25:51:83:ff:0d:37:85:63:0b:0a:1b:e5:55:e5:2b: + e1:ce:f8:6e:5d:e6:d2:a2:2e:ff:76:79:e5:14:6d: + 9e:5f:98:57:7f:4b:5f:b3:6d:5f:54:09:fa:c7:e3: + d2:dc:df:58:39:19:15:10:ce:1a:36:40:e1:ee:65: + 02:2a:20:53:f8:81:af:2c:63:bb:d5:4a:bb:88:a1: + 42:8e:05:38:48:8a:35:91:74:d3:87:cc:2c:f8:09: + 09:9a:8c:af:c0:4a:0f:41:36:a6:96:fb:08:62:43: + 29:24:2a:ff:e4:d1:bf:04:e8:d6:8f:7f:8b:b2:fb: + 41:24:ee:a7:61:20:e8:08:3a:ab:e5:5f:95:9e:30: + 63:e3:b7:6c:78:d2:15:70:14:d3:91:08:13:9d:dc: + 23:5c:1a:3e:85:88:40:0d:a3:e9:d2:a4:e8:2f:55: + cc:4f:ca:02:b2:3c:69:95:de:20:91:e7:09:eb:6b: + 7e:78:a5:44:ef:cb:c0:8d:3a:db:67:12:d0:12:b3: + f4:27:ef:25:0a:a4:79:7d:5f:31:65:c1:19:76:94: + a7:b5:dd:af:68:5f:cc:e6:d2:53:d0:c3:b1:18:37: + 93:10:f4:7a:25:bd:12:61:78:82:c9:10:37:d5:f7: + 91:a8:0e:74:6b:14:4a:ab:16:d3:25:ea:6d:20:d5: + df:5c:53:f8:f8:a5:c6:8e:72:68:67:ad:9a:c0:8e: + 9b:d1:ab:af:83:73:cb:cf:25:70:79:02:1f:bf:f3: + 82:3b:78:5f:45:f7:8c:58:b7:a4:91:4b:24:b8:39: + 7f:13:9d:7c:de:a7:d2:b7:06:70:73:b9:cb:23:39: + db:97:67:1d:61:95:8e:ff:a1:c0:73:f6:b2:ae:07: + 1c:0a:ef:fd:00:8b:00:d2:c3:84:27:4f:7d:cb:9d: + 5b:21:2b:ea:9a:2e:9e:c9:4c:96:e2:38:0c:84:20: + ec:97 +prime1: + 00:ff:ca:92:5b:b5:e5:1e:96:7c:99:cf:9f:70:26: + 42:d5:87:29:61:c0:dd:49:96:7d:8c:51:c5:f4:fd: + 5f:02:7c:2d:7e:a6:0c:16:d0:8b:89:6c:b0:c5:71: + 6d:d7:93:cc:52:ab:f9:f5:32:bb:be:e1:2c:31:fe: + 2e:26:af:c4:b9:23:d0:7a:c7:88:9d:e8:07:f5:18: + 20:47:ed:58:62:e1:ce:2e:d6:95:73:a2:69:5c:ea: + f2:8a:fa:2a:b0:e3:98:3f:39:01:ff:e1:05:e3:a2: + 06:77:70:b4:3d:fe:78:4a:37:0e:40:76:38:29:4d: + 69:a0:ad:94:58:cd:27:dc:81:c9:c5:66:8f:bc:94: + de:3b:c9:1c:fe:5f:ab:27:5e:dc:73:ae:0c:d2:ac: + f2:bb:83:06:4c:5a:c4:58:d0:61:fa:0c:6e:40:81: + 8f:1d:b0:e9:56:00:87:ed:78:51:c0:60:15:0d:62: + 6f:b4:bc:7f:e0:86:36:fb:55:0e:49:00:60:1d:1f: + 53:4a:cc:6d:38:84:a2:b8:cd:f6:16:c1:fd:2f:b1: + aa:49:aa:19:b8:42:13:c0:82:be:b1:03:b8:12:75: + 00:e7:9b:89:9f:d9:b3:ca:98:bf:ea:b3:e8:9c:96: + 06:d3:e7:b0:54:9a:82:07:48:99:77:90:b5:4e:e2: + 17:6f +prime2: + 00:e8:4a:2b:1f:41:b1:aa:5a:00:a2:5f:cc:91:b0: + b6:05:e3:5c:06:7f:3b:f6:f7:c4:59:f4:d3:6f:89: + d5:0e:bb:39:26:ee:c1:c3:d2:60:bc:bf:a7:d9:bc: + 52:cd:a1:ba:fd:c8:a9:6f:de:8a:4d:aa:fc:f4:cd: + 56:b6:ce:06:f5:59:ed:67:f5:93:99:7a:85:e2:d8: + fd:fe:eb:27:c7:f1:c6:1e:b1:0a:9a:c0:5e:d5:01: + b2:86:53:17:86:4c:1b:24:9a:c7:93:6f:de:a2:39: + 90:da:73:78:7f:0d:b2:3b:6d:74:d4:1b:de:e9:af: + 3c:84:3f:f5:84:21:9f:2c:c6:a7:63:67:56:14:36: + a1:f2:c2:94:31:19:d5:0c:3f:04:77:8b:04:82:02: + dd:95:42:75:c5:09:a9:e2:c0:4e:08:89:ff:16:25: + 81:d2:97:3b:08:7c:5c:cb:25:c7:dc:49:7f:b3:99: + ee:56:13:12:c3:41:6e:ef:c9:ca:bd:83:5f:9e:c8: + 91:69:b0:4f:eb:56:7a:c8:b9:fc:e0:4d:3a:59:46: + 39:3e:20:c1:b5:fe:d0:89:e6:fb:58:14:d7:d1:16: + e3:ab:1a:fc:73:fb:91:ae:ad:d4:d3:e2:bc:41:ec: + b9:6a:8d:f3:7c:91:74:d0:86:b8:1b:54:a1:76:03: + 61:db +exponent1: + 00:dc:59:1d:0b:73:fe:14:03:7f:02:e1:20:6f:f4: + 05:ce:fb:c8:62:35:4a:6b:82:00:55:48:7c:47:37: + 9d:08:ff:00:12:01:e8:98:1e:be:95:7b:d4:2b:c2: + 32:e5:6a:a4:b0:f3:05:38:7c:a3:cf:23:1a:77:56: + 87:5b:3c:3f:33:5d:ee:d2:55:e1:12:66:37:b4:a3: + 3b:eb:ba:42:51:ac:43:79:85:d0:e8:f4:17:df:bb: + 65:84:e3:4c:b3:64:dc:5a:5a:39:a6:bb:a9:df:16: + 4c:8b:c7:c2:fd:44:a1:4b:0d:72:71:85:65:8b:ee: + eb:f7:46:90:6c:8f:0e:af:9d:fe:ba:d6:47:2c:24: + f1:ec:7e:ab:43:56:16:92:ab:dd:2c:a9:da:d2:01: + ba:78:5d:be:a7:37:e9:bc:b8:86:2e:69:56:f0:aa: + ab:26:e0:a7:a1:36:83:e1:c5:ac:67:14:5e:0e:51: + a5:f9:04:09:04:d9:99:b3:98:e9:dd:69:3d:62:d9: + 01:5f:86:0a:f0:8d:11:c0:31:6c:b4:de:17:c5:66: + 3f:53:85:fc:f2:05:ba:0e:34:93:20:da:1b:4f:8b: + 0b:64:79:50:6d:2b:94:fe:09:e8:09:bf:41:ba:e2: + 62:af:58:ff:45:62:74:70:e1:d1:92:76:4e:39:cd: + fa:71 +exponent2: + 00:e6:37:5b:b5:86:ae:46:5f:1c:f1:d0:70:36:94: + 24:52:81:9a:da:f5:8e:c0:9d:9e:84:69:18:84:1a: + de:85:d3:18:39:75:b7:a4:14:04:bc:0c:56:96:7d: + 06:b3:b5:ee:55:47:62:65:f4:f0:ad:39:21:aa:9d: + 37:ab:c5:55:30:25:08:1d:58:4e:08:76:5d:eb:0d: + 93:ed:e9:b1:6b:80:3b:12:7f:f4:3a:9b:1d:61:8e: + 65:18:ab:91:4d:10:70:76:3e:d0:3d:57:4a:17:0d: + 66:7a:9a:a6:79:85:61:77:74:6b:ad:2c:52:28:d7: + fb:ea:36:59:65:b2:cc:c6:db:bb:59:d1:38:86:9f: + fe:b1:52:16:fc:f2:d5:2b:65:e9:4f:70:ff:ee:ba: + 58:51:6d:a4:ba:bb:71:1b:c1:eb:94:9a:ef:ad:4b: + 4e:f7:1f:da:e9:f6:17:21:5f:38:4d:22:aa:e5:9d: + 51:91:0d:26:33:4d:ce:5c:e8:69:7e:99:8d:53:19: + 04:c4:f2:70:c2:94:da:eb:c5:28:d2:44:b7:e7:72: + a9:98:e1:6e:1a:a9:88:94:a3:cf:c6:e4:21:60:a0: + 86:d3:35:d3:ae:3f:4d:8b:09:cd:3c:92:22:72:53: + e3:0f:af:cf:f9:4d:4f:b0:bb:54:0c:02:3c:63:71: + c6:b1 +coefficient: + 43:f6:a7:bc:5c:ce:ee:bb:fa:6c:a9:33:92:0a:6f: + 79:16:6d:e9:d4:5b:f1:b5:0e:62:ac:5d:7d:ca:a3: + 0d:11:9d:0b:62:05:ba:db:d2:db:20:72:f2:49:86: + 94:b2:e7:da:46:42:e1:3c:e9:64:9f:5d:10:63:58: + 34:f2:ca:d1:82:df:3d:41:62:50:38:15:e2:07:7f: + bf:78:73:25:14:8d:41:b2:00:46:4e:36:b5:6f:a1: + 5c:db:f5:9d:3e:a4:28:cf:28:4e:07:56:88:82:d4: + 81:62:28:9a:71:b3:e4:77:06:10:ab:ff:a4:a9:92: + 87:49:c5:5e:8a:c8:e2:4c:90:7d:ce:d3:17:be:e8: + 51:36:eb:2e:f0:d5:9e:f8:ef:05:93:db:cf:c0:a2: + c3:fa:7d:ae:66:4c:51:af:58:76:7c:45:47:07:d0: + 08:f6:66:ec:d5:c8:32:fd:f4:5c:93:41:db:96:3f: + 52:ad:92:a6:44:fa:da:95:a8:fc:d0:7c:97:a4:97: + fb:a5:3b:f3:2f:ec:9d:73:c9:fb:c7:0e:d3:06:07: + 18:b8:51:9a:05:8d:48:b2:86:62:ad:fd:7c:c7:5e: + 86:04:f6:0d:57:aa:ac:b0:4f:85:09:98:8f:b8:22: + 21:81:81:80:47:31:e3:4e:56:c4:a4:eb:7b:a4:f7: + 64 diff --git a/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2-3.6.2.txt.license b/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2-3.6.2.txt.license new file mode 100644 index 00000000..edff8c76 --- /dev/null +++ b/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2-3.6.2.txt.license @@ -0,0 +1,3 @@ +GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +SPDX-License-Identifier: GPL-3.0-or-later +SPDX-FileCopyrightText: Ansible Project diff --git a/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2-4.0.0.txt b/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2-4.0.0.txt new file mode 100644 index 00000000..dc8ecf8e --- /dev/null +++ b/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2-4.0.0.txt @@ -0,0 +1,153 @@ +Private-Key: (4096 bit, 2 primes) +modulus: + e8:19:b0:47:ad:1b:4d:0a:a8:ef:ec:e5:14:1c:fa:18: + 9c:27:2f:92:e1:5c:d5:5c:23:fd:5e:44:5f:bf:a0:a2: + 1f:75:0c:3e:c3:76:5e:f9:15:01:36:4e:6c:90:9c:77: + a8:3c:dd:9f:4f:51:5c:0d:d7:4f:b5:d4:cd:d4:b6:1e: + 83:9b:70:fc:90:34:bf:7d:e8:66:a0:f5:57:fb:25:8c: + 3d:a5:67:ff:da:3b:cf:56:a4:f7:e3:d4:00:1b:62:b2: + 36:90:11:0e:51:71:c1:18:36:0c:4e:af:8b:82:35:5d: + 2f:5d:2e:3e:29:ec:99:76:eb:98:1c:f7:ac:bd:71:de: + d7:70:8c:3e:86:ab:d0:e8:2c:78:1c:da:6d:6e:9e:13: + 3e:2f:cd:4a:de:32:32:e7:52:17:55:0d:42:fa:51:44: + 7c:ed:06:46:9e:50:18:45:a5:f8:5c:5e:69:66:5f:78: + 7f:5b:0a:ae:da:0a:94:cb:37:25:9d:64:d3:53:bf:52: + 40:c0:4d:ac:8c:f0:f4:3a:5a:eb:af:d7:e3:d9:c9:a3: + 56:47:3e:ee:94:fa:e1:27:7d:c0:5a:d7:65:ed:d3:b7: + d5:de:d9:c7:c7:12:91:fb:e9:22:53:7f:21:84:7f:89: + 72:ba:9e:65:3e:e4:c5:14:07:12:62:a5:36:6a:3b:7d: + 3d:84:de:07:1b:06:bb:2e:58:de:5e:50:97:39:e8:f6: + 01:b3:89:df:df:0a:f1:62:ca:4a:a6:67:37:ed:8a:77: + 89:f6:ad:f5:54:f3:41:59:c1:5c:b1:bc:ed:78:07:96: + 44:1c:3d:dd:41:74:45:7c:f8:77:b1:73:71:8d:30:22: + e7:8f:57:bc:ee:b0:c6:89:06:87:e7:9b:ca:e9:a6:9b: + 4b:97:22:f6:0a:ba:16:01:1c:26:97:eb:57:4d:29:1d: + aa:34:9d:ee:ba:24:83:b6:b5:c9:39:37:0d:69:52:4e: + 25:7d:92:76:99:ec:e6:39:ad:c5:be:76:ee:4f:09:e9: + 4f:6a:14:63:80:62:1e:ed:07:0e:e5:ab:60:7d:3c:cf: + 4e:d7:c8:d1:fc:45:da:fc:f0:f1:3c:49:6e:4c:72:23: + ad:6b:84:b2:2d:1d:9b:c5:ac:cc:f4:d8:2f:54:aa:0a: + 0a:e9:c3:55:35:7e:11:c7:de:57:d0:8d:fe:32:50:68: + 7b:be:af:d1:7b:7a:e0:ae:52:e1:40:64:b1:6f:1b:91: + a5:70:08:8a:81:97:19:49:a2:c1:44:f9:39:e1:0c:f8: + 94:af:8a:12:f9:0a:96:7c:37:98:73:dc:5f:df:32:f5: + 58:3d:bf:ea:cc:c3:6d:0e:e8:2f:ca:40:96:98:1a:f5 +publicExponent: 65537 (0x10001) +privateExponent: + 66:47:df:c3:8e:58:e0:18:08:ff:86:0d:23:52:6b:b2: + 09:aa:49:10:38:a8:f0:cb:24:7f:04:9a:2b:f9:a5:df: + 9b:ee:38:41:b6:60:45:15:0d:f9:15:45:f5:18:bb:23: + 0d:ec:18:9c:1a:57:97:b1:ef:c6:cc:31:e5:ac:cd:be: + df:af:51:d8:b2:f1:d3:cb:37:ed:76:13:f8:3c:10:3d: + 5f:73:33:43:f0:17:78:54:cd:e9:01:a8:cc:8d:44:ee: + 95:15:e2:b6:45:14:d4:8b:87:51:e0:21:02:e1:14:04: + 27:19:b0:85:ab:72:fc:e4:07:89:66:86:8c:c4:85:58: + 36:e7:7d:9e:16:39:c4:1b:74:71:50:01:bf:c4:c5:fb: + 63:e5:ab:d9:c8:d6:25:51:83:ff:0d:37:85:63:0b:0a: + 1b:e5:55:e5:2b:e1:ce:f8:6e:5d:e6:d2:a2:2e:ff:76: + 79:e5:14:6d:9e:5f:98:57:7f:4b:5f:b3:6d:5f:54:09: + fa:c7:e3:d2:dc:df:58:39:19:15:10:ce:1a:36:40:e1: + ee:65:02:2a:20:53:f8:81:af:2c:63:bb:d5:4a:bb:88: + a1:42:8e:05:38:48:8a:35:91:74:d3:87:cc:2c:f8:09: + 09:9a:8c:af:c0:4a:0f:41:36:a6:96:fb:08:62:43:29: + 24:2a:ff:e4:d1:bf:04:e8:d6:8f:7f:8b:b2:fb:41:24: + ee:a7:61:20:e8:08:3a:ab:e5:5f:95:9e:30:63:e3:b7: + 6c:78:d2:15:70:14:d3:91:08:13:9d:dc:23:5c:1a:3e: + 85:88:40:0d:a3:e9:d2:a4:e8:2f:55:cc:4f:ca:02:b2: + 3c:69:95:de:20:91:e7:09:eb:6b:7e:78:a5:44:ef:cb: + c0:8d:3a:db:67:12:d0:12:b3:f4:27:ef:25:0a:a4:79: + 7d:5f:31:65:c1:19:76:94:a7:b5:dd:af:68:5f:cc:e6: + d2:53:d0:c3:b1:18:37:93:10:f4:7a:25:bd:12:61:78: + 82:c9:10:37:d5:f7:91:a8:0e:74:6b:14:4a:ab:16:d3: + 25:ea:6d:20:d5:df:5c:53:f8:f8:a5:c6:8e:72:68:67: + ad:9a:c0:8e:9b:d1:ab:af:83:73:cb:cf:25:70:79:02: + 1f:bf:f3:82:3b:78:5f:45:f7:8c:58:b7:a4:91:4b:24: + b8:39:7f:13:9d:7c:de:a7:d2:b7:06:70:73:b9:cb:23: + 39:db:97:67:1d:61:95:8e:ff:a1:c0:73:f6:b2:ae:07: + 1c:0a:ef:fd:00:8b:00:d2:c3:84:27:4f:7d:cb:9d:5b: + 21:2b:ea:9a:2e:9e:c9:4c:96:e2:38:0c:84:20:ec:97 +prime1: + ff:ca:92:5b:b5:e5:1e:96:7c:99:cf:9f:70:26:42:d5: + 87:29:61:c0:dd:49:96:7d:8c:51:c5:f4:fd:5f:02:7c: + 2d:7e:a6:0c:16:d0:8b:89:6c:b0:c5:71:6d:d7:93:cc: + 52:ab:f9:f5:32:bb:be:e1:2c:31:fe:2e:26:af:c4:b9: + 23:d0:7a:c7:88:9d:e8:07:f5:18:20:47:ed:58:62:e1: + ce:2e:d6:95:73:a2:69:5c:ea:f2:8a:fa:2a:b0:e3:98: + 3f:39:01:ff:e1:05:e3:a2:06:77:70:b4:3d:fe:78:4a: + 37:0e:40:76:38:29:4d:69:a0:ad:94:58:cd:27:dc:81: + c9:c5:66:8f:bc:94:de:3b:c9:1c:fe:5f:ab:27:5e:dc: + 73:ae:0c:d2:ac:f2:bb:83:06:4c:5a:c4:58:d0:61:fa: + 0c:6e:40:81:8f:1d:b0:e9:56:00:87:ed:78:51:c0:60: + 15:0d:62:6f:b4:bc:7f:e0:86:36:fb:55:0e:49:00:60: + 1d:1f:53:4a:cc:6d:38:84:a2:b8:cd:f6:16:c1:fd:2f: + b1:aa:49:aa:19:b8:42:13:c0:82:be:b1:03:b8:12:75: + 00:e7:9b:89:9f:d9:b3:ca:98:bf:ea:b3:e8:9c:96:06: + d3:e7:b0:54:9a:82:07:48:99:77:90:b5:4e:e2:17:6f +prime2: + e8:4a:2b:1f:41:b1:aa:5a:00:a2:5f:cc:91:b0:b6:05: + e3:5c:06:7f:3b:f6:f7:c4:59:f4:d3:6f:89:d5:0e:bb: + 39:26:ee:c1:c3:d2:60:bc:bf:a7:d9:bc:52:cd:a1:ba: + fd:c8:a9:6f:de:8a:4d:aa:fc:f4:cd:56:b6:ce:06:f5: + 59:ed:67:f5:93:99:7a:85:e2:d8:fd:fe:eb:27:c7:f1: + c6:1e:b1:0a:9a:c0:5e:d5:01:b2:86:53:17:86:4c:1b: + 24:9a:c7:93:6f:de:a2:39:90:da:73:78:7f:0d:b2:3b: + 6d:74:d4:1b:de:e9:af:3c:84:3f:f5:84:21:9f:2c:c6: + a7:63:67:56:14:36:a1:f2:c2:94:31:19:d5:0c:3f:04: + 77:8b:04:82:02:dd:95:42:75:c5:09:a9:e2:c0:4e:08: + 89:ff:16:25:81:d2:97:3b:08:7c:5c:cb:25:c7:dc:49: + 7f:b3:99:ee:56:13:12:c3:41:6e:ef:c9:ca:bd:83:5f: + 9e:c8:91:69:b0:4f:eb:56:7a:c8:b9:fc:e0:4d:3a:59: + 46:39:3e:20:c1:b5:fe:d0:89:e6:fb:58:14:d7:d1:16: + e3:ab:1a:fc:73:fb:91:ae:ad:d4:d3:e2:bc:41:ec:b9: + 6a:8d:f3:7c:91:74:d0:86:b8:1b:54:a1:76:03:61:db +exponent1: + dc:59:1d:0b:73:fe:14:03:7f:02:e1:20:6f:f4:05:ce: + fb:c8:62:35:4a:6b:82:00:55:48:7c:47:37:9d:08:ff: + 00:12:01:e8:98:1e:be:95:7b:d4:2b:c2:32:e5:6a:a4: + b0:f3:05:38:7c:a3:cf:23:1a:77:56:87:5b:3c:3f:33: + 5d:ee:d2:55:e1:12:66:37:b4:a3:3b:eb:ba:42:51:ac: + 43:79:85:d0:e8:f4:17:df:bb:65:84:e3:4c:b3:64:dc: + 5a:5a:39:a6:bb:a9:df:16:4c:8b:c7:c2:fd:44:a1:4b: + 0d:72:71:85:65:8b:ee:eb:f7:46:90:6c:8f:0e:af:9d: + fe:ba:d6:47:2c:24:f1:ec:7e:ab:43:56:16:92:ab:dd: + 2c:a9:da:d2:01:ba:78:5d:be:a7:37:e9:bc:b8:86:2e: + 69:56:f0:aa:ab:26:e0:a7:a1:36:83:e1:c5:ac:67:14: + 5e:0e:51:a5:f9:04:09:04:d9:99:b3:98:e9:dd:69:3d: + 62:d9:01:5f:86:0a:f0:8d:11:c0:31:6c:b4:de:17:c5: + 66:3f:53:85:fc:f2:05:ba:0e:34:93:20:da:1b:4f:8b: + 0b:64:79:50:6d:2b:94:fe:09:e8:09:bf:41:ba:e2:62: + af:58:ff:45:62:74:70:e1:d1:92:76:4e:39:cd:fa:71 +exponent2: + e6:37:5b:b5:86:ae:46:5f:1c:f1:d0:70:36:94:24:52: + 81:9a:da:f5:8e:c0:9d:9e:84:69:18:84:1a:de:85:d3: + 18:39:75:b7:a4:14:04:bc:0c:56:96:7d:06:b3:b5:ee: + 55:47:62:65:f4:f0:ad:39:21:aa:9d:37:ab:c5:55:30: + 25:08:1d:58:4e:08:76:5d:eb:0d:93:ed:e9:b1:6b:80: + 3b:12:7f:f4:3a:9b:1d:61:8e:65:18:ab:91:4d:10:70: + 76:3e:d0:3d:57:4a:17:0d:66:7a:9a:a6:79:85:61:77: + 74:6b:ad:2c:52:28:d7:fb:ea:36:59:65:b2:cc:c6:db: + bb:59:d1:38:86:9f:fe:b1:52:16:fc:f2:d5:2b:65:e9: + 4f:70:ff:ee:ba:58:51:6d:a4:ba:bb:71:1b:c1:eb:94: + 9a:ef:ad:4b:4e:f7:1f:da:e9:f6:17:21:5f:38:4d:22: + aa:e5:9d:51:91:0d:26:33:4d:ce:5c:e8:69:7e:99:8d: + 53:19:04:c4:f2:70:c2:94:da:eb:c5:28:d2:44:b7:e7: + 72:a9:98:e1:6e:1a:a9:88:94:a3:cf:c6:e4:21:60:a0: + 86:d3:35:d3:ae:3f:4d:8b:09:cd:3c:92:22:72:53:e3: + 0f:af:cf:f9:4d:4f:b0:bb:54:0c:02:3c:63:71:c6:b1 +coefficient: + 43:f6:a7:bc:5c:ce:ee:bb:fa:6c:a9:33:92:0a:6f:79: + 16:6d:e9:d4:5b:f1:b5:0e:62:ac:5d:7d:ca:a3:0d:11: + 9d:0b:62:05:ba:db:d2:db:20:72:f2:49:86:94:b2:e7: + da:46:42:e1:3c:e9:64:9f:5d:10:63:58:34:f2:ca:d1: + 82:df:3d:41:62:50:38:15:e2:07:7f:bf:78:73:25:14: + 8d:41:b2:00:46:4e:36:b5:6f:a1:5c:db:f5:9d:3e:a4: + 28:cf:28:4e:07:56:88:82:d4:81:62:28:9a:71:b3:e4: + 77:06:10:ab:ff:a4:a9:92:87:49:c5:5e:8a:c8:e2:4c: + 90:7d:ce:d3:17:be:e8:51:36:eb:2e:f0:d5:9e:f8:ef: + 05:93:db:cf:c0:a2:c3:fa:7d:ae:66:4c:51:af:58:76: + 7c:45:47:07:d0:08:f6:66:ec:d5:c8:32:fd:f4:5c:93: + 41:db:96:3f:52:ad:92:a6:44:fa:da:95:a8:fc:d0:7c: + 97:a4:97:fb:a5:3b:f3:2f:ec:9d:73:c9:fb:c7:0e:d3: + 06:07:18:b8:51:9a:05:8d:48:b2:86:62:ad:fd:7c:c7: + 5e:86:04:f6:0d:57:aa:ac:b0:4f:85:09:98:8f:b8:22: + 21:81:81:80:47:31:e3:4e:56:c4:a4:eb:7b:a4:f7:64 diff --git a/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2-4.0.0.txt.license b/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2-4.0.0.txt.license new file mode 100644 index 00000000..edff8c76 --- /dev/null +++ b/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2-4.0.0.txt.license @@ -0,0 +1,3 @@ +GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +SPDX-License-Identifier: GPL-3.0-or-later +SPDX-FileCopyrightText: Ansible Project diff --git a/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2.pem b/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2.pem new file mode 100644 index 00000000..d73382bd --- /dev/null +++ b/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +T4UJmI+4IiGBgYBHMeNOVsSk63uk92Q= +-----END PRIVATE KEY----- diff --git a/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2.pem.license b/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2.pem.license new file mode 100644 index 00000000..edff8c76 --- /dev/null +++ b/tests/unit/plugins/module_utils/_acme/fixtures/privatekey_2.pem.license @@ -0,0 +1,3 @@ +GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +SPDX-License-Identifier: GPL-3.0-or-later +SPDX-FileCopyrightText: Ansible Project diff --git a/tests/unit/plugins/module_utils/_acme/test_backend_openssl_cli.py b/tests/unit/plugins/module_utils/_acme/test_backend_openssl_cli.py index 4ee1283f..aba6ccf2 100644 --- a/tests/unit/plugins/module_utils/_acme/test_backend_openssl_cli.py +++ b/tests/unit/plugins/module_utils/_acme/test_backend_openssl_cli.py @@ -16,6 +16,7 @@ from freezegun import freeze_time from ansible_collections.community.crypto.plugins.module_utils._acme.backend_openssl_cli import ( OpenSSLCLIBackend, + _extract_rsa_key, ) from ansible_collections.community.crypto.plugins.module_utils._time import ( UTC, @@ -31,6 +32,7 @@ from .backend_data import ( TEST_INTERPOLATE_TIMESTAMP, TEST_KEYS, TEST_PARSE_ACME_TIMESTAMP, + load_fixture, ) if t.TYPE_CHECKING: @@ -180,3 +182,36 @@ def test_interpolate_timestamp( ts_start, ts_end, percentage=percentage ) assert ts_expected == timestamp + + +def test_openssl400() -> None: + expected = { + "key_file": None, + "type": "rsa", + "alg": "RS256", + "jwk": { + "kty": "RSA", + "e": "AQAB", + "n": ( + "6BmwR60bTQqo7-zlFBz6GJwnL5LhXNVcI_1eRF-_oKIfdQw-w3Ze-RUBNk5skJx3qDzdn" + "09RXA3XT7XUzdS2HoObcPyQNL996Gag9Vf7JYw9pWf_2jvPVqT349QAG2KyNpARDlFxwR" + "g2DE6vi4I1XS9dLj4p7Jl265gc96y9cd7XcIw-hqvQ6Cx4HNptbp4TPi_NSt4yMudSF1U" + "NQvpRRHztBkaeUBhFpfhcXmlmX3h_Wwqu2gqUyzclnWTTU79SQMBNrIzw9Dpa66_X49nJ" + "o1ZHPu6U-uEnfcBa12Xt07fV3tnHxxKR--kiU38hhH-JcrqeZT7kxRQHEmKlNmo7fT2E3" + "gcbBrsuWN5eUJc56PYBs4nf3wrxYspKpmc37Yp3ifat9VTzQVnBXLG87XgHlkQcPd1BdE" + "V8-Hexc3GNMCLnj1e87rDGiQaH55vK6aabS5ci9gq6FgEcJpfrV00pHao0ne66JIO2tck" + "5Nw1pUk4lfZJ2mezmOa3FvnbuTwnpT2oUY4BiHu0HDuWrYH08z07XyNH8Rdr88PE8SW5M" + "ciOta4SyLR2bxazM9NgvVKoKCunDVTV-EcfeV9CN_jJQaHu-r9F7euCuUuFAZLFvG5Glc" + "AiKgZcZSaLBRPk54Qz4lK-KEvkKlnw3mHPcX98y9Vg9v-rMw20O6C_KQJaYGvU" + ), + }, + "hash": "sha256", + } + pk1 = load_fixture("privatekey_2-3.6.2.txt") + pk1parsed = _extract_rsa_key(pk1) + print(repr(pk1parsed)) + assert pk1parsed == expected + pk2 = load_fixture("privatekey_2-4.0.0.txt") + pk2parsed = _extract_rsa_key(pk2) + print(repr(pk2parsed)) + assert pk2parsed == expected