mirror of
https://github.com/ansible-collections/community.crypto.git
synced 2026-05-07 22:03:01 +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:
@@ -21,52 +21,89 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto._asn1 impo
|
||||
|
||||
|
||||
TEST_CASES = [
|
||||
('UTF8:Hello World', b'\x0c\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64'),
|
||||
|
||||
('EXPLICIT:10,UTF8:Hello World', b'\xaa\x0d\x0c\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64'),
|
||||
('EXPLICIT:12U,UTF8:Hello World', b'\x0c\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64'),
|
||||
('EXPLICIT:10A,UTF8:Hello World', b'\x6a\x0d\x0c\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64'),
|
||||
('EXPLICIT:10P,UTF8:Hello World', b'\xea\x0d\x0c\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64'),
|
||||
('EXPLICIT:10C,UTF8:Hello World', b'\xaa\x0d\x0c\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64'),
|
||||
('EXPLICIT:1024P,UTF8:Hello World', b'\xff\x88\x00\x0d\x0c\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64'),
|
||||
|
||||
('IMPLICIT:10,UTF8:Hello World', b'\x8a\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64'),
|
||||
('IMPLICIT:12U,UTF8:Hello World', b'\x0c\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64'),
|
||||
('IMPLICIT:10A,UTF8:Hello World', b'\x4a\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64'),
|
||||
('IMPLICIT:10P,UTF8:Hello World', b'\xca\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64'),
|
||||
('IMPLICIT:10C,UTF8:Hello World', b'\x8a\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64'),
|
||||
('IMPLICIT:1024P,UTF8:Hello World', b'\xdf\x88\x00\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64'),
|
||||
|
||||
("UTF8:Hello World", b"\x0c\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64"),
|
||||
(
|
||||
"EXPLICIT:10,UTF8:Hello World",
|
||||
b"\xaa\x0d\x0c\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64",
|
||||
),
|
||||
(
|
||||
"EXPLICIT:12U,UTF8:Hello World",
|
||||
b"\x0c\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64",
|
||||
),
|
||||
(
|
||||
"EXPLICIT:10A,UTF8:Hello World",
|
||||
b"\x6a\x0d\x0c\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64",
|
||||
),
|
||||
(
|
||||
"EXPLICIT:10P,UTF8:Hello World",
|
||||
b"\xea\x0d\x0c\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64",
|
||||
),
|
||||
(
|
||||
"EXPLICIT:10C,UTF8:Hello World",
|
||||
b"\xaa\x0d\x0c\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64",
|
||||
),
|
||||
(
|
||||
"EXPLICIT:1024P,UTF8:Hello World",
|
||||
b"\xff\x88\x00\x0d\x0c\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64",
|
||||
),
|
||||
(
|
||||
"IMPLICIT:10,UTF8:Hello World",
|
||||
b"\x8a\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64",
|
||||
),
|
||||
(
|
||||
"IMPLICIT:12U,UTF8:Hello World",
|
||||
b"\x0c\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64",
|
||||
),
|
||||
(
|
||||
"IMPLICIT:10A,UTF8:Hello World",
|
||||
b"\x4a\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64",
|
||||
),
|
||||
(
|
||||
"IMPLICIT:10P,UTF8:Hello World",
|
||||
b"\xca\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64",
|
||||
),
|
||||
(
|
||||
"IMPLICIT:10C,UTF8:Hello World",
|
||||
b"\x8a\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64",
|
||||
),
|
||||
(
|
||||
"IMPLICIT:1024P,UTF8:Hello World",
|
||||
b"\xdf\x88\x00\x0b\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64",
|
||||
),
|
||||
# Tests large data lengths, special logic for the length octet encoding.
|
||||
('UTF8:' + ('A' * 600), b'\x0c\x82\x02\x58' + (b'\x41' * 600)),
|
||||
|
||||
("UTF8:" + ("A" * 600), b"\x0c\x82\x02\x58" + (b"\x41" * 600)),
|
||||
# This isn't valid with openssl asn1parse but has been validated against an ASN.1 parser. OpenSSL seems to read the
|
||||
# data u"café" encoded as UTF-8 bytes b"caf\xc3\xa9", decodes that internally with latin-1 (or similar variant) as
|
||||
# u"café" then encodes that to UTF-8 b"caf\xc3\x83\xc2\xa9" for the UTF8String. Ultimately openssl is wrong here
|
||||
# so we keep our assertion happening.
|
||||
(u'UTF8:café', b'\x0c\x05\x63\x61\x66\xc3\xa9'),
|
||||
(u"UTF8:café", b"\x0c\x05\x63\x61\x66\xc3\xa9"),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('value, expected', TEST_CASES)
|
||||
@pytest.mark.parametrize("value, expected", TEST_CASES)
|
||||
def test_serialize_asn1_string_as_der(value, expected):
|
||||
actual = serialize_asn1_string_as_der(value)
|
||||
print("%s | %s" % (value, base64.b16encode(actual).decode()))
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('value', [
|
||||
'invalid',
|
||||
'EXPLICIT,UTF:value',
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
"value",
|
||||
[
|
||||
"invalid",
|
||||
"EXPLICIT,UTF:value",
|
||||
],
|
||||
)
|
||||
def test_serialize_asn1_string_as_der_invalid_format(value):
|
||||
expected = "The ASN.1 serialized string must be in the format [modifier,]type[:value]"
|
||||
expected = (
|
||||
"The ASN.1 serialized string must be in the format [modifier,]type[:value]"
|
||||
)
|
||||
with pytest.raises(ValueError, match=re.escape(expected)):
|
||||
serialize_asn1_string_as_der(value)
|
||||
|
||||
|
||||
def test_serialize_asn1_string_as_der_invalid_type():
|
||||
expected = "The ASN.1 serialized string is not a known type \"OID\", only UTF8 types are supported"
|
||||
expected = 'The ASN.1 serialized string is not a known type "OID", only UTF8 types are supported'
|
||||
with pytest.raises(ValueError, match=re.escape(expected)):
|
||||
serialize_asn1_string_as_der("OID:1.2.3.4")
|
||||
|
||||
@@ -77,17 +114,23 @@ def test_pack_asn_invalid_class():
|
||||
|
||||
|
||||
@pytest.mark.skip() # This is to just to build the test case assertions and shouldn't run normally.
|
||||
@pytest.mark.parametrize('value, expected', TEST_CASES)
|
||||
@pytest.mark.parametrize("value, expected", TEST_CASES)
|
||||
def test_test_cases(value, expected, tmp_path):
|
||||
test_file = tmp_path / 'test.der'
|
||||
subprocess.run(['openssl', 'asn1parse', '-genstr', value, '-noout', '-out', test_file], check=True)
|
||||
test_file = tmp_path / "test.der"
|
||||
subprocess.run(
|
||||
["openssl", "asn1parse", "-genstr", value, "-noout", "-out", test_file],
|
||||
check=True,
|
||||
)
|
||||
|
||||
with open(test_file, mode='rb') as fd:
|
||||
with open(test_file, mode="rb") as fd:
|
||||
b_data = fd.read()
|
||||
|
||||
hex_str = base64.b16encode(b_data).decode().lower()
|
||||
print("%s | \\x%s" % (value, "\\x".join([hex_str[i:i + 2] for i in range(0, len(hex_str), 2)])))
|
||||
print(
|
||||
"%s | \\x%s"
|
||||
% (value, "\\x".join([hex_str[i : i + 2] for i in range(0, len(hex_str), 2)]))
|
||||
)
|
||||
|
||||
# This is a know edge case where openssl asn1parse does not work properly.
|
||||
if value != u'UTF8:café':
|
||||
if value != u"UTF8:café":
|
||||
assert b_data == expected
|
||||
|
||||
@@ -28,100 +28,147 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
from cryptography.x509 import NameAttribute, oid
|
||||
|
||||
|
||||
@pytest.mark.parametrize('unicode, idna, cycled_unicode', [
|
||||
(u'..', u'..', None),
|
||||
(u'foo.com', u'foo.com', None),
|
||||
(u'.foo.com.', u'.foo.com.', None),
|
||||
(u'*.foo.com', u'*.foo.com', None),
|
||||
(u'straße', u'xn--strae-oqa', None),
|
||||
(u'ffóò.ḃâŗ.çøṁ', u'xn--ff-3jad.xn--2ca8uh37e.xn--7ca8a981n', u'ffóò.ḃâŗ.çøṁ'),
|
||||
(u'*.☺.', u'*.xn--74h.', None),
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
"unicode, idna, cycled_unicode",
|
||||
[
|
||||
(u"..", u"..", None),
|
||||
(u"foo.com", u"foo.com", None),
|
||||
(u".foo.com.", u".foo.com.", None),
|
||||
(u"*.foo.com", u"*.foo.com", None),
|
||||
(u"straße", u"xn--strae-oqa", None),
|
||||
(u"ffóò.ḃâŗ.çøṁ", u"xn--ff-3jad.xn--2ca8uh37e.xn--7ca8a981n", u"ffóò.ḃâŗ.çøṁ"),
|
||||
(u"*.☺.", u"*.xn--74h.", None),
|
||||
],
|
||||
)
|
||||
def test_adjust_idn(unicode, idna, cycled_unicode):
|
||||
if cycled_unicode is None:
|
||||
cycled_unicode = unicode
|
||||
|
||||
result = _adjust_idn(unicode, 'ignore')
|
||||
result = _adjust_idn(unicode, "ignore")
|
||||
print(result, unicode)
|
||||
assert result == unicode
|
||||
|
||||
result = _adjust_idn(idna, 'ignore')
|
||||
result = _adjust_idn(idna, "ignore")
|
||||
print(result, idna)
|
||||
assert result == idna
|
||||
|
||||
result = _adjust_idn(unicode, 'unicode')
|
||||
result = _adjust_idn(unicode, "unicode")
|
||||
print(result, unicode)
|
||||
assert result == unicode
|
||||
|
||||
result = _adjust_idn(idna, 'unicode')
|
||||
result = _adjust_idn(idna, "unicode")
|
||||
print(result, cycled_unicode)
|
||||
assert result == cycled_unicode
|
||||
|
||||
result = _adjust_idn(unicode, 'idna')
|
||||
result = _adjust_idn(unicode, "idna")
|
||||
print(result, idna)
|
||||
assert result == idna
|
||||
|
||||
result = _adjust_idn(idna, 'idna')
|
||||
result = _adjust_idn(idna, "idna")
|
||||
print(result, idna)
|
||||
assert result == idna
|
||||
|
||||
|
||||
@pytest.mark.parametrize('value, idn_rewrite, message', [
|
||||
(u'bar', 'foo', re.escape(u'Invalid value for idn_rewrite: "foo"')),
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
"value, idn_rewrite, message",
|
||||
[
|
||||
(u"bar", "foo", re.escape(u'Invalid value for idn_rewrite: "foo"')),
|
||||
],
|
||||
)
|
||||
def test_adjust_idn_fail_valueerror(value, idn_rewrite, message):
|
||||
with pytest.raises(ValueError, match=message):
|
||||
_adjust_idn(value, idn_rewrite)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('value, idn_rewrite, message', [
|
||||
(
|
||||
u'xn--a',
|
||||
'unicode',
|
||||
u'''^Error while transforming part u?"xn\\-\\-a" of IDNA DNS name u?"xn\\-\\-a" to Unicode\\.'''
|
||||
u''' IDNA2008 transformation resulted in "Codepoint U\\+0080 at position 1 of u?'\\\\x80' not allowed",'''
|
||||
u''' IDNA2003 transformation resulted in "(decoding with 'idna' codec failed'''
|
||||
u''' \\(UnicodeError: |'idna' codec can't decode byte 0x78 in position 0: )?Invalid character u?'\\\\x80'\\)?"\\.$'''
|
||||
),
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
"value, idn_rewrite, message",
|
||||
[
|
||||
(
|
||||
u"xn--a",
|
||||
"unicode",
|
||||
u"""^Error while transforming part u?"xn\\-\\-a" of IDNA DNS name u?"xn\\-\\-a" to Unicode\\."""
|
||||
u""" IDNA2008 transformation resulted in "Codepoint U\\+0080 at position 1 of u?'\\\\x80' not allowed","""
|
||||
u""" IDNA2003 transformation resulted in "(decoding with 'idna' codec failed"""
|
||||
u""" \\(UnicodeError: |'idna' codec can't decode byte 0x78 in position 0: )?Invalid character u?'\\\\x80'\\)?"\\.$""",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_adjust_idn_fail_user_error(value, idn_rewrite, message):
|
||||
with pytest.raises(OpenSSLObjectError, match=message):
|
||||
_adjust_idn(value, idn_rewrite)
|
||||
|
||||
|
||||
def test_cryptography_get_name_invalid_prefix():
|
||||
with pytest.raises(OpenSSLObjectError, match="^Cannot parse Subject Alternative Name"):
|
||||
cryptography_get_name('fake:value')
|
||||
with pytest.raises(
|
||||
OpenSSLObjectError, match="^Cannot parse Subject Alternative Name"
|
||||
):
|
||||
cryptography_get_name("fake:value")
|
||||
|
||||
|
||||
def test_cryptography_get_name_other_name_no_oid():
|
||||
with pytest.raises(OpenSSLObjectError, match="Cannot parse Subject Alternative Name otherName"):
|
||||
cryptography_get_name('otherName:value')
|
||||
with pytest.raises(
|
||||
OpenSSLObjectError, match="Cannot parse Subject Alternative Name otherName"
|
||||
):
|
||||
cryptography_get_name("otherName:value")
|
||||
|
||||
|
||||
def test_cryptography_get_name_other_name_utfstring():
|
||||
actual = cryptography_get_name('otherName:1.3.6.1.4.1.311.20.2.3;UTF8:Hello World')
|
||||
assert actual.type_id.dotted_string == '1.3.6.1.4.1.311.20.2.3'
|
||||
assert actual.value == b'\x0c\x0bHello World'
|
||||
actual = cryptography_get_name("otherName:1.3.6.1.4.1.311.20.2.3;UTF8:Hello World")
|
||||
assert actual.type_id.dotted_string == "1.3.6.1.4.1.311.20.2.3"
|
||||
assert actual.value == b"\x0c\x0bHello World"
|
||||
|
||||
|
||||
@pytest.mark.parametrize('name, options, expected', [
|
||||
(b'CN=x ', {}, (NameAttribute(oid.NameOID.COMMON_NAME, u'x '), b'')),
|
||||
(b'CN=\\ ', {}, (NameAttribute(oid.NameOID.COMMON_NAME, u' '), b'')),
|
||||
(b'CN=\\#', {}, (NameAttribute(oid.NameOID.COMMON_NAME, u'#'), b'')),
|
||||
(b'CN=#402032', {}, (NameAttribute(oid.NameOID.COMMON_NAME, u'@ 2'), b'')),
|
||||
(b'CN = x ', {}, (NameAttribute(oid.NameOID.COMMON_NAME, u'x '), b'')),
|
||||
(b'CN = x\\, ', {}, (NameAttribute(oid.NameOID.COMMON_NAME, u'x, '), b'')),
|
||||
(b'CN = x\\40 ', {}, (NameAttribute(oid.NameOID.COMMON_NAME, u'x@ '), b'')),
|
||||
(b'CN = \\ , / ', {}, (NameAttribute(oid.NameOID.COMMON_NAME, u' '), b', / ')),
|
||||
(b'CN = \\ , / ', {'sep': b'/'}, (NameAttribute(oid.NameOID.COMMON_NAME, u' , '), b'/ ')),
|
||||
(b'CN = \\ , / ', {'decode_remainder': False}, (NameAttribute(oid.NameOID.COMMON_NAME, u'\\ , / '), b'')),
|
||||
# Some examples from https://datatracker.ietf.org/doc/html/rfc4514#section-4:
|
||||
(b'CN=James \\"Jim\\" Smith\\, III', {}, (NameAttribute(oid.NameOID.COMMON_NAME, u'James "Jim" Smith, III'), b'')),
|
||||
(b'CN=Before\\0dAfter', {}, (NameAttribute(oid.NameOID.COMMON_NAME, u'Before\x0dAfter'), b'')),
|
||||
(b'1.3.6.1.4.1.1466.0=#04024869', {}, (NameAttribute(oid.ObjectIdentifier(u'1.3.6.1.4.1.1466.0'), u'\x04\x02Hi'), b'')),
|
||||
(b'CN=Lu\\C4\\8Di\\C4\\87', {}, (NameAttribute(oid.NameOID.COMMON_NAME, u'Lučić'), b'')),
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
"name, options, expected",
|
||||
[
|
||||
(b"CN=x ", {}, (NameAttribute(oid.NameOID.COMMON_NAME, u"x "), b"")),
|
||||
(b"CN=\\ ", {}, (NameAttribute(oid.NameOID.COMMON_NAME, u" "), b"")),
|
||||
(b"CN=\\#", {}, (NameAttribute(oid.NameOID.COMMON_NAME, u"#"), b"")),
|
||||
(b"CN=#402032", {}, (NameAttribute(oid.NameOID.COMMON_NAME, u"@ 2"), b"")),
|
||||
(b"CN = x ", {}, (NameAttribute(oid.NameOID.COMMON_NAME, u"x "), b"")),
|
||||
(b"CN = x\\, ", {}, (NameAttribute(oid.NameOID.COMMON_NAME, u"x, "), b"")),
|
||||
(b"CN = x\\40 ", {}, (NameAttribute(oid.NameOID.COMMON_NAME, u"x@ "), b"")),
|
||||
(
|
||||
b"CN = \\ , / ",
|
||||
{},
|
||||
(NameAttribute(oid.NameOID.COMMON_NAME, u" "), b", / "),
|
||||
),
|
||||
(
|
||||
b"CN = \\ , / ",
|
||||
{"sep": b"/"},
|
||||
(NameAttribute(oid.NameOID.COMMON_NAME, u" , "), b"/ "),
|
||||
),
|
||||
(
|
||||
b"CN = \\ , / ",
|
||||
{"decode_remainder": False},
|
||||
(NameAttribute(oid.NameOID.COMMON_NAME, u"\\ , / "), b""),
|
||||
),
|
||||
# Some examples from https://datatracker.ietf.org/doc/html/rfc4514#section-4:
|
||||
(
|
||||
b'CN=James \\"Jim\\" Smith\\, III',
|
||||
{},
|
||||
(NameAttribute(oid.NameOID.COMMON_NAME, u'James "Jim" Smith, III'), b""),
|
||||
),
|
||||
(
|
||||
b"CN=Before\\0dAfter",
|
||||
{},
|
||||
(NameAttribute(oid.NameOID.COMMON_NAME, u"Before\x0dAfter"), b""),
|
||||
),
|
||||
(
|
||||
b"1.3.6.1.4.1.1466.0=#04024869",
|
||||
{},
|
||||
(
|
||||
NameAttribute(oid.ObjectIdentifier("1.3.6.1.4.1.1466.0"), u"\x04\x02Hi"),
|
||||
b"",
|
||||
),
|
||||
),
|
||||
(
|
||||
b"CN=Lu\\C4\\8Di\\C4\\87",
|
||||
{},
|
||||
(NameAttribute(oid.NameOID.COMMON_NAME, u"Lučić"), b""),
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_parse_dn_component(name, options, expected):
|
||||
result = _parse_dn_component(name, **options)
|
||||
print(result, expected)
|
||||
@@ -131,42 +178,77 @@ def test_parse_dn_component(name, options, expected):
|
||||
# Cryptography < 2.9 does not allow empty strings
|
||||
# (https://github.com/pyca/cryptography/commit/87b2749c52e688c809f1861e55d958c64147493c)
|
||||
# Cryptoraphy 43.0.0+ also doesn't allow this anymore
|
||||
if LooseVersion('2.9') <= LooseVersion(cryptography.__version__) < LooseVersion('43.0.0'):
|
||||
@pytest.mark.parametrize('name, options, expected', [
|
||||
(b'CN=', {}, (NameAttribute(oid.NameOID.COMMON_NAME, u''), b'')),
|
||||
(b'CN= ', {}, (NameAttribute(oid.NameOID.COMMON_NAME, u''), b'')),
|
||||
])
|
||||
if (
|
||||
LooseVersion("2.9")
|
||||
<= LooseVersion(cryptography.__version__)
|
||||
< LooseVersion("43.0.0")
|
||||
):
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"name, options, expected",
|
||||
[
|
||||
(b"CN=", {}, (NameAttribute(oid.NameOID.COMMON_NAME, u""), b"")),
|
||||
(b"CN= ", {}, (NameAttribute(oid.NameOID.COMMON_NAME, u""), b"")),
|
||||
],
|
||||
)
|
||||
def test_parse_dn_component_not_py26(name, options, expected):
|
||||
result = _parse_dn_component(name, **options)
|
||||
print(result, expected)
|
||||
assert result == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('name, options, message', [
|
||||
(b'CN=\\0', {}, u'Hex escape sequence "\\0" incomplete at end of string'),
|
||||
(b'CN=\\0,', {}, u'Hex escape sequence "\\0," has invalid second letter'),
|
||||
(b'CN=#0,', {}, u'Invalid hex sequence entry "0,"'),
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
"name, options, message",
|
||||
[
|
||||
(b"CN=\\0", {}, u'Hex escape sequence "\\0" incomplete at end of string'),
|
||||
(b"CN=\\0,", {}, u'Hex escape sequence "\\0," has invalid second letter'),
|
||||
(b"CN=#0,", {}, u'Invalid hex sequence entry "0,"'),
|
||||
],
|
||||
)
|
||||
def test_parse_dn_component_failure(name, options, message):
|
||||
with pytest.raises(OpenSSLObjectError, match=u'^%s$' % re.escape(message)):
|
||||
with pytest.raises(OpenSSLObjectError, match=u"^%s$" % re.escape(message)):
|
||||
_parse_dn_component(name, **options)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('name, expected', [
|
||||
(b'CN=foo', [NameAttribute(oid.NameOID.COMMON_NAME, u'foo')]),
|
||||
(b'CN=foo,CN=bar', [NameAttribute(oid.NameOID.COMMON_NAME, u'foo'), NameAttribute(oid.NameOID.COMMON_NAME, u'bar')]),
|
||||
(b'CN = foo , CN = bar', [NameAttribute(oid.NameOID.COMMON_NAME, u'foo '), NameAttribute(oid.NameOID.COMMON_NAME, u'bar')]),
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
"name, expected",
|
||||
[
|
||||
(b"CN=foo", [NameAttribute(oid.NameOID.COMMON_NAME, u"foo")]),
|
||||
(
|
||||
b"CN=foo,CN=bar",
|
||||
[
|
||||
NameAttribute(oid.NameOID.COMMON_NAME, u"foo"),
|
||||
NameAttribute(oid.NameOID.COMMON_NAME, u"bar"),
|
||||
],
|
||||
),
|
||||
(
|
||||
b"CN = foo , CN = bar",
|
||||
[
|
||||
NameAttribute(oid.NameOID.COMMON_NAME, u"foo "),
|
||||
NameAttribute(oid.NameOID.COMMON_NAME, u"bar"),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_parse_dn(name, expected):
|
||||
result = _parse_dn(name)
|
||||
print(result, expected)
|
||||
assert result == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('name, message', [
|
||||
(b'CN=\\0', u'Error while parsing distinguished name "CN=\\0": Hex escape sequence "\\0" incomplete at end of string'),
|
||||
(b'CN=x,', u'Error while parsing distinguished name "CN=x,": unexpected end of string'),
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
"name, message",
|
||||
[
|
||||
(
|
||||
b"CN=\\0",
|
||||
u'Error while parsing distinguished name "CN=\\0": Hex escape sequence "\\0" incomplete at end of string',
|
||||
),
|
||||
(
|
||||
b"CN=x,",
|
||||
u'Error while parsing distinguished name "CN=x,": unexpected end of string',
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_parse_dn_failure(name, message):
|
||||
with pytest.raises(OpenSSLObjectError, match=u'^%s$' % re.escape(message)):
|
||||
with pytest.raises(OpenSSLObjectError, match=u"^%s$" % re.escape(message)):
|
||||
_parse_dn(name)
|
||||
|
||||
@@ -20,98 +20,116 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.math impor
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('f, e, m, result', [
|
||||
(0, 0, 5, 1),
|
||||
(0, 1, 5, 0),
|
||||
(2, 1, 5, 2),
|
||||
(2, 2, 5, 4),
|
||||
(2, 3, 5, 3),
|
||||
(2, 10, 5, 4),
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
"f, e, m, result",
|
||||
[
|
||||
(0, 0, 5, 1),
|
||||
(0, 1, 5, 0),
|
||||
(2, 1, 5, 2),
|
||||
(2, 2, 5, 4),
|
||||
(2, 3, 5, 3),
|
||||
(2, 10, 5, 4),
|
||||
],
|
||||
)
|
||||
def test_binary_exp_mod(f, e, m, result):
|
||||
value = binary_exp_mod(f, e, m)
|
||||
print(value)
|
||||
assert value == result
|
||||
|
||||
|
||||
@pytest.mark.parametrize('a, b, result', [
|
||||
(0, -123, -123),
|
||||
(0, 123, 123),
|
||||
(-123, 0, -123),
|
||||
(123, 0, 123),
|
||||
(-123, 1, 1),
|
||||
(123, 1, 1),
|
||||
(1, -123, -1),
|
||||
(1, 123, 1),
|
||||
(1024, 10, 2),
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
"a, b, result",
|
||||
[
|
||||
(0, -123, -123),
|
||||
(0, 123, 123),
|
||||
(-123, 0, -123),
|
||||
(123, 0, 123),
|
||||
(-123, 1, 1),
|
||||
(123, 1, 1),
|
||||
(1, -123, -1),
|
||||
(1, 123, 1),
|
||||
(1024, 10, 2),
|
||||
],
|
||||
)
|
||||
def test_simple_gcd(a, b, result):
|
||||
value = simple_gcd(a, b)
|
||||
print(value)
|
||||
assert value == result
|
||||
|
||||
|
||||
@pytest.mark.parametrize('n, result', [
|
||||
(-2, True),
|
||||
(0, True),
|
||||
(1, True),
|
||||
(2, False),
|
||||
(3, False),
|
||||
(4, True),
|
||||
(5, False),
|
||||
(6, True),
|
||||
(7, False),
|
||||
(8, True),
|
||||
(9, True),
|
||||
(10, True),
|
||||
(211, False), # the smallest prime number >= 200
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
"n, result",
|
||||
[
|
||||
(-2, True),
|
||||
(0, True),
|
||||
(1, True),
|
||||
(2, False),
|
||||
(3, False),
|
||||
(4, True),
|
||||
(5, False),
|
||||
(6, True),
|
||||
(7, False),
|
||||
(8, True),
|
||||
(9, True),
|
||||
(10, True),
|
||||
(211, False), # the smallest prime number >= 200
|
||||
],
|
||||
)
|
||||
def test_quick_is_not_prime(n, result):
|
||||
value = quick_is_not_prime(n)
|
||||
print(value)
|
||||
assert value == result
|
||||
|
||||
|
||||
@pytest.mark.parametrize('no, count, result', [
|
||||
(0, None, b''),
|
||||
(0, 1, b'\x00'),
|
||||
(0, 2, b'\x00\x00'),
|
||||
(1, None, b'\x01'),
|
||||
(1, 2, b'\x00\x01'),
|
||||
(255, None, b'\xff'),
|
||||
(256, None, b'\x01\x00'),
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
"no, count, result",
|
||||
[
|
||||
(0, None, b""),
|
||||
(0, 1, b"\x00"),
|
||||
(0, 2, b"\x00\x00"),
|
||||
(1, None, b"\x01"),
|
||||
(1, 2, b"\x00\x01"),
|
||||
(255, None, b"\xff"),
|
||||
(256, None, b"\x01\x00"),
|
||||
],
|
||||
)
|
||||
def test_convert_int_to_bytes(no, count, result):
|
||||
value = convert_int_to_bytes(no, count=count)
|
||||
print(value)
|
||||
assert value == result
|
||||
|
||||
|
||||
@pytest.mark.parametrize('no, digits, result', [
|
||||
(0, None, '0'),
|
||||
(1, None, '1'),
|
||||
(16, None, '10'),
|
||||
(1, 3, '001'),
|
||||
(255, None, 'ff'),
|
||||
(256, None, '100'),
|
||||
(256, 2, '100'),
|
||||
(256, 3, '100'),
|
||||
(256, 4, '0100'),
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
"no, digits, result",
|
||||
[
|
||||
(0, None, "0"),
|
||||
(1, None, "1"),
|
||||
(16, None, "10"),
|
||||
(1, 3, "001"),
|
||||
(255, None, "ff"),
|
||||
(256, None, "100"),
|
||||
(256, 2, "100"),
|
||||
(256, 3, "100"),
|
||||
(256, 4, "0100"),
|
||||
],
|
||||
)
|
||||
def test_convert_int_to_hex(no, digits, result):
|
||||
value = convert_int_to_hex(no, digits=digits)
|
||||
print(value)
|
||||
assert value == result
|
||||
|
||||
|
||||
@pytest.mark.parametrize('data, result', [
|
||||
(b'', 0),
|
||||
(b'\x00', 0),
|
||||
(b'\x00\x01', 1),
|
||||
(b'\x01', 1),
|
||||
(b'\xff', 255),
|
||||
(b'\x01\x00', 256),
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
"data, result",
|
||||
[
|
||||
(b"", 0),
|
||||
(b"\x00", 0),
|
||||
(b"\x00\x01", 1),
|
||||
(b"\x01", 1),
|
||||
(b"\xff", 255),
|
||||
(b"\x01\x00", 256),
|
||||
],
|
||||
)
|
||||
def test_convert_bytes_to_int(data, result):
|
||||
value = convert_bytes_to_int(data)
|
||||
print(value)
|
||||
|
||||
@@ -19,48 +19,48 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.pem import
|
||||
|
||||
|
||||
PEM_TEST_CASES = [
|
||||
(b'', [], False, 'raw'),
|
||||
(b'random stuff\nblabla', [], False, 'raw'),
|
||||
(b'-----BEGIN PRIVATE KEY-----', [], False, 'raw'),
|
||||
(b"", [], False, "raw"),
|
||||
(b"random stuff\nblabla", [], False, "raw"),
|
||||
(b"-----BEGIN PRIVATE KEY-----", [], False, "raw"),
|
||||
(
|
||||
b'-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----',
|
||||
['-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----'],
|
||||
b"-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----",
|
||||
["-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"],
|
||||
True,
|
||||
'pkcs8',
|
||||
"pkcs8",
|
||||
),
|
||||
(
|
||||
b'foo=bar\n# random stuff\n-----BEGIN RSA PRIVATE KEY-----\nblabla\n-----END RSA PRIVATE KEY-----\nmore stuff\n',
|
||||
['-----BEGIN RSA PRIVATE KEY-----\nblabla\n-----END RSA PRIVATE KEY-----\n'],
|
||||
b"foo=bar\n# random stuff\n-----BEGIN RSA PRIVATE KEY-----\nblabla\n-----END RSA PRIVATE KEY-----\nmore stuff\n",
|
||||
["-----BEGIN RSA PRIVATE KEY-----\nblabla\n-----END RSA PRIVATE KEY-----\n"],
|
||||
True,
|
||||
'pkcs1',
|
||||
"pkcs1",
|
||||
),
|
||||
(
|
||||
b'foo=bar\n# random stuff\n-----BEGIN CERTIFICATE-----\nblabla\n-----END CERTIFICATE-----\nmore stuff\n'
|
||||
b'\n-----BEGIN CERTIFICATE-----\nfoobar\n-----END CERTIFICATE-----',
|
||||
b"foo=bar\n# random stuff\n-----BEGIN CERTIFICATE-----\nblabla\n-----END CERTIFICATE-----\nmore stuff\n"
|
||||
b"\n-----BEGIN CERTIFICATE-----\nfoobar\n-----END CERTIFICATE-----",
|
||||
[
|
||||
'-----BEGIN CERTIFICATE-----\nblabla\n-----END CERTIFICATE-----\n',
|
||||
'-----BEGIN CERTIFICATE-----\nfoobar\n-----END CERTIFICATE-----',
|
||||
"-----BEGIN CERTIFICATE-----\nblabla\n-----END CERTIFICATE-----\n",
|
||||
"-----BEGIN CERTIFICATE-----\nfoobar\n-----END CERTIFICATE-----",
|
||||
],
|
||||
True,
|
||||
'unknown-pem',
|
||||
"unknown-pem",
|
||||
),
|
||||
(
|
||||
b'-----BEGINCERTIFICATE-----\n-----BEGIN CERTIFICATE-----\n-----BEGINCERTIFICATE-----\n-----END CERTIFICATE-----\n-----BEGINCERTIFICATE-----\n',
|
||||
b"-----BEGINCERTIFICATE-----\n-----BEGIN CERTIFICATE-----\n-----BEGINCERTIFICATE-----\n-----END CERTIFICATE-----\n-----BEGINCERTIFICATE-----\n",
|
||||
[
|
||||
'-----BEGIN CERTIFICATE-----\n-----BEGINCERTIFICATE-----\n-----END CERTIFICATE-----\n',
|
||||
"-----BEGIN CERTIFICATE-----\n-----BEGINCERTIFICATE-----\n-----END CERTIFICATE-----\n",
|
||||
],
|
||||
True,
|
||||
'unknown-pem',
|
||||
"unknown-pem",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('data, pems, is_pem, private_key_type', PEM_TEST_CASES)
|
||||
@pytest.mark.parametrize("data, pems, is_pem, private_key_type", PEM_TEST_CASES)
|
||||
def test_pem_handling(data, pems, is_pem, private_key_type):
|
||||
assert identify_pem_format(data) == is_pem
|
||||
assert identify_private_key_format(data) == private_key_type
|
||||
try:
|
||||
text = data.decode('utf-8')
|
||||
text = data.decode("utf-8")
|
||||
assert split_pem_list(text) == pems
|
||||
first_pem = pems[0] if pems else None
|
||||
assert extract_first_pem(text) == first_pem
|
||||
|
||||
Reference in New Issue
Block a user