Skip to content

Commit

Permalink
More test update to support fips
Browse files Browse the repository at this point in the history
  • Loading branch information
dwoz authored and vzhestkov committed Jan 23, 2025
1 parent fdaedc2 commit 2df8b52
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 38 deletions.
4 changes: 2 additions & 2 deletions salt/cloud/clouds/ec2.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ def get_dependencies():
"""
deps = {
"requests": HAS_REQUESTS,
"pycrypto or m2crypto": salt.crypt.HAS_M2 or salt.crypt.HAS_CRYPTO,
"cryptography": salt.crypt.HAS_CRYPTOGRAPHY,
}
return config.check_driver_dependencies(__virtualname__, deps)

Expand Down Expand Up @@ -4930,7 +4930,7 @@ def get_password_data(
for item in data:
ret[next(iter(item.keys()))] = next(iter(item.values()))

if not salt.crypt.HAS_M2 and not salt.crypt.HAS_CRYPTO:
if not salt.crypt.HAS_CRYPTOGRAPHY:
if "key" in kwargs or "key_file" in kwargs:
log.warning("No crypto library is installed, can not decrypt password")
return ret
Expand Down
15 changes: 15 additions & 0 deletions tests/pytests/scenarios/multimaster/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from pytestshellutils.exceptions import FactoryTimeout

import salt.utils.platform
from tests.conftest import FIPS_TESTRUN

log = logging.getLogger(__name__)

Expand All @@ -20,6 +21,10 @@ def salt_mm_master_1(request, salt_factories):
}
config_overrides = {
"interface": "127.0.0.1",
"fips_mode": FIPS_TESTRUN,
"publish_signing_algorithm": (
"PKCS1v15-SHA224" if FIPS_TESTRUN else "PKCS1v15-SHA224"
),
}

factory = salt_factories.salt_master_daemon(
Expand Down Expand Up @@ -48,6 +53,10 @@ def salt_mm_master_2(salt_factories, salt_mm_master_1):
}
config_overrides = {
"interface": "127.0.0.2",
"fips_mode": FIPS_TESTRUN,
"publish_signing_algorithm": (
"PKCS1v15-SHA224" if FIPS_TESTRUN else "PKCS1v15-SHA224"
),
}

# Use the same ports for both masters, they are binding to different interfaces
Expand Down Expand Up @@ -95,6 +104,9 @@ def salt_mm_minion_1(salt_mm_master_1, salt_mm_master_2):
"{}:{}".format(mm_master_2_addr, mm_master_2_port),
],
"test.foo": "baz",
"fips_mode": FIPS_TESTRUN,
"encryption_algorithm": "OAEP-SHA224" if FIPS_TESTRUN else "OAEP-SHA1",
"signing_algorithm": "PKCS1v15-SHA224" if FIPS_TESTRUN else "PKCS1v15-SHA1",
}
factory = salt_mm_master_1.salt_minion_daemon(
"mm-minion-1",
Expand Down Expand Up @@ -122,6 +134,9 @@ def salt_mm_minion_2(salt_mm_master_1, salt_mm_master_2):
"{}:{}".format(mm_master_2_addr, mm_master_2_port),
],
"test.foo": "baz",
"fips_mode": FIPS_TESTRUN,
"encryption_algorithm": "OAEP-SHA224" if FIPS_TESTRUN else "OAEP-SHA1",
"signing_algorithm": "PKCS1v15-SHA224" if FIPS_TESTRUN else "PKCS1v15-SHA1",
}
factory = salt_mm_master_2.salt_minion_daemon(
"mm-minion-2",
Expand Down
2 changes: 1 addition & 1 deletion tests/pytests/unit/crypt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ def legacy_gen_keys(keydir, keyname, keysize, user=None, passphrase=None):
if HAS_M2:
gen = RSA.gen_key(keysize, 65537, lambda: None)
else:
salt.utils.crypt.reinit_crypto()
gen = RSA.generate(bits=keysize, e=65537)

if os.path.isfile(priv):
Expand Down Expand Up @@ -115,6 +114,7 @@ def legacy_gen_keys(keydir, keyname, keysize, user=None, passphrase=None):


class LegacyPrivateKey:

def __init__(self, path, passphrase=None):
if HAS_M2:
self.key = RSA.load_key(path, lambda x: bytes(passphrase))
Expand Down
62 changes: 62 additions & 0 deletions tests/pytests/unit/crypt/test_crypt_cryptodome.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import os

import pytest

import salt.crypt
from tests.support.mock import MagicMock, MockCall, mock_open, patch


@pytest.mark.slow_test
def test_gen_keys():
open_priv_wb = MockCall(f"/keydir{os.sep}keyname.pem", "wb+")
open_pub_wb = MockCall(f"/keydir{os.sep}keyname.pub", "wb+")

with patch.multiple(
os,
umask=MagicMock(),
chmod=MagicMock(),
access=MagicMock(return_value=True),
):
with patch("salt.utils.files.fopen", mock_open()) as m_open, patch(
"os.path.isfile", return_value=True
):
result = salt.crypt.gen_keys("/keydir", "keyname", 2048)
assert result == f"/keydir{os.sep}keyname.pem", result
assert open_priv_wb not in m_open.calls
assert open_pub_wb not in m_open.calls

with patch("salt.utils.files.fopen", mock_open()) as m_open, patch(
"os.path.isfile", return_value=False
):
salt.crypt.gen_keys("/keydir", "keyname", 2048)
assert open_priv_wb in m_open.calls
assert open_pub_wb in m_open.calls


@patch("os.umask", MagicMock())
@patch("os.chmod", MagicMock())
@patch("os.chown", MagicMock(), create=True)
@patch("os.access", MagicMock(return_value=True))
@pytest.mark.slow_test
def test_gen_keys_with_passphrase():
key_path = os.path.join(os.sep, "keydir")
open_priv_wb = MockCall(os.path.join(key_path, "keyname.pem"), "wb+")
open_pub_wb = MockCall(os.path.join(key_path, "keyname.pub"), "wb+")

with patch("salt.utils.files.fopen", mock_open()) as m_open, patch(
"os.path.isfile", return_value=True
):
assert salt.crypt.gen_keys(
key_path, "keyname", 2048, passphrase="password"
) == os.path.join(key_path, "keyname.pem")
result = salt.crypt.gen_keys(key_path, "keyname", 2048, passphrase="password")
assert result == os.path.join(key_path, "keyname.pem"), result
assert open_priv_wb not in m_open.calls
assert open_pub_wb not in m_open.calls

with patch("salt.utils.files.fopen", mock_open()) as m_open, patch(
"os.path.isfile", return_value=False
):
salt.crypt.gen_keys(key_path, "keyname", 2048)
assert open_priv_wb in m_open.calls
assert open_pub_wb in m_open.calls
33 changes: 0 additions & 33 deletions tests/pytests/unit/test_minion.py
Original file line number Diff line number Diff line change
Expand Up @@ -662,39 +662,6 @@ def compile_pillar(self):
minion.destroy()


def test_reinit_crypto_on_fork(minion_opts):
"""
Ensure salt.utils.crypt.reinit_crypto() is executed when forking for new job
"""
minion_opts["multiprocessing"] = True
with patch("salt.utils.process.default_signals"):

io_loop = salt.ext.tornado.ioloop.IOLoop()
io_loop.make_current()
minion = salt.minion.Minion(minion_opts, io_loop=io_loop)

job_data = {"jid": "test-jid", "fun": "test.ping"}

def mock_start(self):
# pylint: disable=comparison-with-callable
assert (
len(
[
x
for x in self._after_fork_methods
if x[0] == salt.utils.crypt.reinit_crypto
]
)
== 1
)
# pylint: enable=comparison-with-callable

with patch.object(
salt.utils.process.SignalHandlingProcess, "start", mock_start
):
io_loop.run_sync(lambda: minion._handle_decoded_payload(job_data))


def test_minion_manage_schedule(minion_opts):
"""
Tests that the manage_schedule will call the add function, adding
Expand Down
9 changes: 7 additions & 2 deletions tests/pytests/unit/transport/test_tcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,10 +403,11 @@ async def test_when_async_req_channel_with_syndic_role_should_use_syndic_master_
"transport": "tcp",
"acceptance_wait_time": 30,
"acceptance_wait_time_max": 30,
"signing_algorithm": "MOCK",
}
client = salt.channel.client.ReqChannel.factory(opts, io_loop=mockloop)
assert client.master_pubkey_path == expected_pubkey_path
with patch("salt.crypt.verify_signature") as mock:
with patch("salt.crypt.PublicKey", return_value=MagicMock()) as mock:
client.verify_signature("mockdata", "mocksig")
assert mock.call_args_list[0][0][0] == expected_pubkey_path

Expand All @@ -431,7 +432,11 @@ async def test_mixin_should_use_correct_path_when_syndic(
}
client = salt.channel.client.AsyncPubChannel.factory(opts, io_loop=mockloop)
client.master_pubkey_path = expected_pubkey_path
payload = {"sig": "abc", "load": {"foo": "bar"}}
payload = {
"sig": "abc",
"load": {"foo": "bar"},
"sig_algo": salt.crypt.PKCS1v15_SHA224,
}
with patch("salt.crypt.verify_signature") as mock:
client._verify_master_signature(payload)
assert mock.call_args_list[0][0][0] == expected_pubkey_path
Expand Down

0 comments on commit 2df8b52

Please sign in to comment.