Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/68930.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed gen_signature() signing raw pub key content instead of clean_key'd content, causing master_use_pubkey_signature verification to always fail.
2 changes: 1 addition & 1 deletion salt/crypt.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ def gen_signature(priv_path, pub_path, sign_path, passphrase=None):
"""

with salt.utils.files.fopen(pub_path) as fp_:
mpub_64 = fp_.read()
mpub_64 = clean_key(fp_.read())

mpub_sig = sign_message(priv_path, mpub_64, passphrase)
mpub_sig_64 = binascii.b2a_base64(mpub_sig)
Expand Down
42 changes: 41 additions & 1 deletion tests/pytests/unit/test_crypt.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import salt.crypt as crypt
import salt.exceptions
from tests.support.mock import patch
from tests.support.mock import mock_open, patch


@pytest.fixture
Expand Down Expand Up @@ -243,3 +243,43 @@ def test_async_auth_cache_token(minion_root, io_loop):
auth.gen_token("salt")
auth.gen_token("salt")
moc.assert_called_once()


@pytest.mark.parametrize("linesep", ["\r\n", "\r", "\n"])
def test_gen_signature_signs_clean_key(key_data, linesep):
"""
Regression test for https://github.com/saltstack/salt/issues/68930

gen_signature() must apply clean_key() before signing so the signed
content matches what get_pub_str() sends to minions.
"""
raw_pub_on_disk = linesep.join(key_data)
expected = crypt.clean_key(raw_pub_on_disk)

with patch("salt.utils.files.fopen", mock_open(read_data=raw_pub_on_disk)), \
patch("os.path.isfile", return_value=False), \
patch("salt.crypt.sign_message", return_value=b"fakesig") as mock_sign:
crypt.gen_signature("priv_path", "pub_path", "sig_path")

_, signed_content, _ = mock_sign.call_args[0]
assert signed_content == expected


@pytest.mark.parametrize("linesep", ["\r\n", "\r", "\n"])
def test_gen_signature_signs_clean_key_trailing_newline(key_data, linesep):
"""
Same as above but with a trailing newline, which is the common case
because the cryptography library writes PEM files with one.
"""
raw_pub_on_disk = linesep.join(key_data) + linesep
expected = crypt.clean_key(raw_pub_on_disk)

assert raw_pub_on_disk != expected

with patch("salt.utils.files.fopen", mock_open(read_data=raw_pub_on_disk)), \
patch("os.path.isfile", return_value=False), \
patch("salt.crypt.sign_message", return_value=b"fakesig") as mock_sign:
crypt.gen_signature("priv_path", "pub_path", "sig_path")

_, signed_content, _ = mock_sign.call_args[0]
assert signed_content == expected
Loading