mirror of
https://github.com/ansible-collections/community.crypto.git
synced 2026-05-06 13:22:58 +00:00
Make all module_utils and plugin_utils private (#887)
* Add leading underscore. Remove deprecated module utils. * Document module and plugin utils as private. Add changelog fragment. * Convert relative to absolute imports. * Remove unnecessary imports.
This commit is contained in:
434
tests/unit/plugins/module_utils/_openssh/test_cryptography.py
Normal file
434
tests/unit/plugins/module_utils/_openssh/test_cryptography.py
Normal file
@@ -0,0 +1,434 @@
|
||||
# Copyright (c) Ansible Project
|
||||
# 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
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os.path
|
||||
import typing as t
|
||||
from getpass import getuser
|
||||
from os import remove, rmdir
|
||||
from socket import gethostname
|
||||
from tempfile import mkdtemp
|
||||
|
||||
import pytest
|
||||
from ansible_collections.community.crypto.plugins.module_utils._openssh.cryptography import (
|
||||
HAS_OPENSSH_SUPPORT,
|
||||
InvalidCommentError,
|
||||
InvalidKeySizeError,
|
||||
InvalidKeyTypeError,
|
||||
InvalidPassphraseError,
|
||||
InvalidPrivateKeyFileError,
|
||||
InvalidPublicKeyFileError,
|
||||
OpensshKeypair,
|
||||
)
|
||||
|
||||
|
||||
if t.TYPE_CHECKING:
|
||||
from ansible_collections.community.crypto.plugins.module_utils._openssh.cryptography import (
|
||||
KeyType,
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_KEY_PARAMS: list[tuple[KeyType, int | None, bytes | None, str | None]] = [
|
||||
(
|
||||
"rsa",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
(
|
||||
"dsa",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
(
|
||||
"ecdsa",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
(
|
||||
"ed25519",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
]
|
||||
|
||||
VALID_USER_KEY_PARAMS: list[tuple[KeyType, int | None, bytes | None, str | None]] = [
|
||||
(
|
||||
"rsa",
|
||||
8192,
|
||||
"change_me".encode("UTF-8"),
|
||||
"comment",
|
||||
),
|
||||
(
|
||||
"dsa",
|
||||
1024,
|
||||
"change_me".encode("UTF-8"),
|
||||
"comment",
|
||||
),
|
||||
(
|
||||
"ecdsa",
|
||||
521,
|
||||
"change_me".encode("UTF-8"),
|
||||
"comment",
|
||||
),
|
||||
(
|
||||
"ed25519",
|
||||
256,
|
||||
"change_me".encode("UTF-8"),
|
||||
"comment",
|
||||
),
|
||||
]
|
||||
|
||||
INVALID_USER_KEY_PARAMS: list[tuple[KeyType, int | None, bytes | None, str | None]] = [
|
||||
(
|
||||
"dne", # type: ignore
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
(
|
||||
"rsa",
|
||||
None,
|
||||
[1, 2, 3], # type: ignore
|
||||
"comment",
|
||||
),
|
||||
(
|
||||
"ecdsa",
|
||||
None,
|
||||
None,
|
||||
[1, 2, 3], # type: ignore
|
||||
),
|
||||
]
|
||||
|
||||
INVALID_KEY_SIZES: list[tuple[KeyType, int | None, bytes | None, str | None]] = [
|
||||
(
|
||||
"rsa",
|
||||
1023,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
(
|
||||
"rsa",
|
||||
16385,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
(
|
||||
"dsa",
|
||||
256,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
(
|
||||
"ecdsa",
|
||||
1024,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
(
|
||||
"ed25519",
|
||||
1024,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("keytype,size,passphrase,comment", DEFAULT_KEY_PARAMS)
|
||||
@pytest.mark.skipif(not HAS_OPENSSH_SUPPORT, reason="requires cryptography")
|
||||
def test_default_key_params(
|
||||
keytype: KeyType, size: int | None, passphrase: bytes | None, comment: str | None
|
||||
) -> None:
|
||||
result = True
|
||||
|
||||
default_sizes = {
|
||||
"rsa": 2048,
|
||||
"dsa": 1024,
|
||||
"ecdsa": 256,
|
||||
"ed25519": 256,
|
||||
}
|
||||
|
||||
default_comment = f"{getuser()}@{gethostname()}"
|
||||
pair = OpensshKeypair.generate(
|
||||
keytype=keytype, size=size, passphrase=passphrase, comment=comment
|
||||
)
|
||||
try:
|
||||
pair = OpensshKeypair.generate(
|
||||
keytype=keytype, size=size, passphrase=passphrase, comment=comment
|
||||
)
|
||||
if pair.size != default_sizes[pair.key_type] or pair.comment != default_comment:
|
||||
result = False
|
||||
except Exception as e:
|
||||
print(e)
|
||||
result = False
|
||||
|
||||
assert result
|
||||
|
||||
|
||||
@pytest.mark.parametrize("keytype,size,passphrase,comment", VALID_USER_KEY_PARAMS)
|
||||
@pytest.mark.skipif(not HAS_OPENSSH_SUPPORT, reason="requires cryptography")
|
||||
def test_valid_user_key_params(
|
||||
keytype: KeyType, size: int | None, passphrase: bytes | None, comment: str | None
|
||||
) -> None:
|
||||
result = True
|
||||
|
||||
try:
|
||||
pair = OpensshKeypair.generate(
|
||||
keytype=keytype, size=size, passphrase=passphrase, comment=comment
|
||||
)
|
||||
if pair.key_type != keytype or pair.size != size or pair.comment != comment:
|
||||
result = False
|
||||
except Exception as e:
|
||||
print(e)
|
||||
result = False
|
||||
|
||||
assert result
|
||||
|
||||
|
||||
@pytest.mark.parametrize("keytype,size,passphrase,comment", INVALID_USER_KEY_PARAMS)
|
||||
@pytest.mark.skipif(not HAS_OPENSSH_SUPPORT, reason="requires cryptography")
|
||||
def test_invalid_user_key_params(
|
||||
keytype: KeyType, size: int | None, passphrase: bytes | None, comment: str | None
|
||||
) -> None:
|
||||
result = False
|
||||
|
||||
try:
|
||||
OpensshKeypair.generate(
|
||||
keytype=keytype, size=size, passphrase=passphrase, comment=comment
|
||||
)
|
||||
except (InvalidCommentError, InvalidKeyTypeError, InvalidPassphraseError):
|
||||
result = True
|
||||
except Exception as e:
|
||||
print(e)
|
||||
pass
|
||||
|
||||
assert result
|
||||
|
||||
|
||||
@pytest.mark.parametrize("keytype,size,passphrase,comment", INVALID_KEY_SIZES)
|
||||
@pytest.mark.skipif(not HAS_OPENSSH_SUPPORT, reason="requires cryptography")
|
||||
def test_invalid_key_sizes(
|
||||
keytype: KeyType, size: int | None, passphrase: bytes | None, comment: str | None
|
||||
) -> None:
|
||||
result = False
|
||||
|
||||
try:
|
||||
OpensshKeypair.generate(
|
||||
keytype=keytype, size=size, passphrase=passphrase, comment=comment
|
||||
)
|
||||
except InvalidKeySizeError:
|
||||
result = True
|
||||
except Exception as e:
|
||||
print(e)
|
||||
pass
|
||||
|
||||
assert result
|
||||
|
||||
|
||||
@pytest.mark.skipif(not HAS_OPENSSH_SUPPORT, reason="requires cryptography")
|
||||
def test_valid_comment_update() -> None:
|
||||
|
||||
pair = OpensshKeypair.generate()
|
||||
new_comment = "comment"
|
||||
try:
|
||||
pair.comment = new_comment
|
||||
except Exception as e:
|
||||
print(e)
|
||||
pass
|
||||
|
||||
assert (
|
||||
pair.comment == new_comment
|
||||
and pair.public_key.split(b" ", 2)[2].decode() == new_comment
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skipif(not HAS_OPENSSH_SUPPORT, reason="requires cryptography")
|
||||
def test_invalid_comment_update() -> None:
|
||||
result = False
|
||||
|
||||
pair = OpensshKeypair.generate()
|
||||
new_comment = [1, 2, 3]
|
||||
try:
|
||||
pair.comment = new_comment # type: ignore
|
||||
except InvalidCommentError:
|
||||
result = True
|
||||
|
||||
assert result
|
||||
|
||||
|
||||
@pytest.mark.skipif(not HAS_OPENSSH_SUPPORT, reason="requires cryptography")
|
||||
def test_valid_passphrase_update() -> None:
|
||||
result = False
|
||||
|
||||
passphrase = "change_me".encode("UTF-8")
|
||||
|
||||
try:
|
||||
tmpdir = mkdtemp()
|
||||
keyfilename = os.path.join(tmpdir, "id_rsa")
|
||||
|
||||
pair1 = OpensshKeypair.generate()
|
||||
pair1.update_passphrase(passphrase)
|
||||
|
||||
with open(keyfilename, "w+b") as keyfile:
|
||||
keyfile.write(pair1.private_key)
|
||||
|
||||
with open(keyfilename + ".pub", "w+b") as pubkeyfile:
|
||||
pubkeyfile.write(pair1.public_key)
|
||||
|
||||
pair2 = OpensshKeypair.load(path=keyfilename, passphrase=passphrase)
|
||||
|
||||
if pair1 == pair2:
|
||||
result = True
|
||||
finally:
|
||||
if os.path.exists(keyfilename):
|
||||
remove(keyfilename)
|
||||
if os.path.exists(keyfilename + ".pub"):
|
||||
remove(keyfilename + ".pub")
|
||||
if os.path.exists(tmpdir):
|
||||
rmdir(tmpdir)
|
||||
|
||||
assert result
|
||||
|
||||
|
||||
@pytest.mark.skipif(not HAS_OPENSSH_SUPPORT, reason="requires cryptography")
|
||||
def test_invalid_passphrase_update() -> None:
|
||||
result = False
|
||||
|
||||
passphrase = [1, 2, 3]
|
||||
pair = OpensshKeypair.generate()
|
||||
try:
|
||||
pair.update_passphrase(passphrase) # type: ignore
|
||||
except InvalidPassphraseError:
|
||||
result = True
|
||||
|
||||
assert result
|
||||
|
||||
|
||||
@pytest.mark.skipif(not HAS_OPENSSH_SUPPORT, reason="requires cryptography")
|
||||
def test_invalid_privatekey() -> None:
|
||||
result = False
|
||||
|
||||
try:
|
||||
tmpdir = mkdtemp()
|
||||
keyfilename = os.path.join(tmpdir, "id_rsa")
|
||||
|
||||
pair = OpensshKeypair.generate()
|
||||
|
||||
with open(keyfilename, "w+b") as keyfile:
|
||||
keyfile.write(pair.private_key[1:])
|
||||
|
||||
with open(keyfilename + ".pub", "w+b") as pubkeyfile:
|
||||
pubkeyfile.write(pair.public_key)
|
||||
|
||||
OpensshKeypair.load(path=keyfilename)
|
||||
except InvalidPrivateKeyFileError:
|
||||
result = True
|
||||
finally:
|
||||
if os.path.exists(keyfilename):
|
||||
remove(keyfilename)
|
||||
if os.path.exists(keyfilename + ".pub"):
|
||||
remove(keyfilename + ".pub")
|
||||
if os.path.exists(tmpdir):
|
||||
rmdir(tmpdir)
|
||||
|
||||
assert result
|
||||
|
||||
|
||||
@pytest.mark.skipif(not HAS_OPENSSH_SUPPORT, reason="requires cryptography")
|
||||
def test_mismatched_keypair() -> None:
|
||||
result = False
|
||||
|
||||
try:
|
||||
tmpdir = mkdtemp()
|
||||
keyfilename = os.path.join(tmpdir, "id_rsa")
|
||||
|
||||
pair1 = OpensshKeypair.generate()
|
||||
pair2 = OpensshKeypair.generate()
|
||||
|
||||
with open(keyfilename, "w+b") as keyfile:
|
||||
keyfile.write(pair1.private_key)
|
||||
|
||||
with open(keyfilename + ".pub", "w+b") as pubkeyfile:
|
||||
pubkeyfile.write(pair2.public_key)
|
||||
|
||||
OpensshKeypair.load(path=keyfilename)
|
||||
except InvalidPublicKeyFileError:
|
||||
result = True
|
||||
finally:
|
||||
if os.path.exists(keyfilename):
|
||||
remove(keyfilename)
|
||||
if os.path.exists(keyfilename + ".pub"):
|
||||
remove(keyfilename + ".pub")
|
||||
if os.path.exists(tmpdir):
|
||||
rmdir(tmpdir)
|
||||
|
||||
assert result
|
||||
|
||||
|
||||
@pytest.mark.skipif(not HAS_OPENSSH_SUPPORT, reason="requires cryptography")
|
||||
def test_keypair_comparison() -> None:
|
||||
assert OpensshKeypair.generate() != OpensshKeypair.generate()
|
||||
assert OpensshKeypair.generate() != OpensshKeypair.generate(keytype="dsa")
|
||||
assert OpensshKeypair.generate() != OpensshKeypair.generate(keytype="ed25519")
|
||||
assert OpensshKeypair.generate(keytype="ed25519") != OpensshKeypair.generate(
|
||||
keytype="ed25519"
|
||||
)
|
||||
try:
|
||||
tmpdir = mkdtemp()
|
||||
|
||||
keys: dict[str, dict[str, t.Any]] = {
|
||||
"rsa": {
|
||||
"pair": OpensshKeypair.generate(),
|
||||
"filename": os.path.join(tmpdir, "id_rsa"),
|
||||
},
|
||||
"dsa": {
|
||||
"pair": OpensshKeypair.generate(
|
||||
keytype="dsa", passphrase="change_me".encode("UTF-8")
|
||||
),
|
||||
"filename": os.path.join(tmpdir, "id_dsa"),
|
||||
},
|
||||
"ed25519": {
|
||||
"pair": OpensshKeypair.generate(keytype="ed25519"),
|
||||
"filename": os.path.join(tmpdir, "id_ed25519"),
|
||||
},
|
||||
}
|
||||
|
||||
for v in keys.values():
|
||||
with open(v["filename"], "w+b") as keyfile:
|
||||
keyfile.write(v["pair"].private_key)
|
||||
with open(v["filename"] + ".pub", "w+b") as pubkeyfile:
|
||||
pubkeyfile.write(v["pair"].public_key)
|
||||
|
||||
assert keys["rsa"]["pair"] == OpensshKeypair.load(path=keys["rsa"]["filename"])
|
||||
|
||||
loaded_dsa_key = OpensshKeypair.load(
|
||||
path=keys["dsa"]["filename"], passphrase="change_me".encode("UTF-8")
|
||||
)
|
||||
assert keys["dsa"]["pair"] == loaded_dsa_key
|
||||
|
||||
loaded_dsa_key.update_passphrase("change_me_again".encode("UTF-8"))
|
||||
assert keys["dsa"]["pair"] != loaded_dsa_key
|
||||
|
||||
loaded_dsa_key.update_passphrase("change_me".encode("UTF-8"))
|
||||
assert keys["dsa"]["pair"] == loaded_dsa_key
|
||||
|
||||
loaded_dsa_key.comment = "comment"
|
||||
assert keys["dsa"]["pair"] != loaded_dsa_key
|
||||
|
||||
assert keys["ed25519"]["pair"] == OpensshKeypair.load(
|
||||
path=keys["ed25519"]["filename"]
|
||||
)
|
||||
finally:
|
||||
for v in keys.values():
|
||||
if os.path.exists(v["filename"]):
|
||||
remove(v["filename"])
|
||||
if os.path.exists(v["filename"] + ".pub"):
|
||||
remove(v["filename"] + ".pub")
|
||||
if os.path.exists(tmpdir):
|
||||
rmdir(tmpdir)
|
||||
assert OpensshKeypair.generate() != []
|
||||
Reference in New Issue
Block a user