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/64659.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix ``certutil.add_store`` and ``certutil.del_store`` states ignoring ``saltenv`` when resolving the certificate serial, causing "Invalid certificate file" errors when the certificate lives in a non-``base`` saltenv.
8 changes: 4 additions & 4 deletions salt/states/win_certutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def add_store(name, store, saltenv="base"):
ret["result"] = False
return ret

cert_serial = __salt__["certutil.get_cert_serial"](name)
cert_serial = __salt__["certutil.get_cert_serial"](name, saltenv=saltenv)
if cert_serial is None:
ret["comment"] = f"Invalid certificate file: {name}"
ret["result"] = False
Expand All @@ -81,7 +81,7 @@ def add_store(name, store, saltenv="base"):
ret["result"] = None
return ret

retcode = __salt__["certutil.add_store"](name, store, retcode=True)
retcode = __salt__["certutil.add_store"](name, store, saltenv=saltenv, retcode=True)
if retcode != 0:
ret["comment"] = f"Error adding certificate: {name}"
ret["result"] = False
Expand Down Expand Up @@ -135,7 +135,7 @@ def del_store(name, store, saltenv="base"):
ret["result"] = False
return ret

cert_serial = __salt__["certutil.get_cert_serial"](name)
cert_serial = __salt__["certutil.get_cert_serial"](name, saltenv=saltenv)
if cert_serial is None:
ret["comment"] = f"Invalid certificate file: {name}"
ret["result"] = False
Expand All @@ -151,7 +151,7 @@ def del_store(name, store, saltenv="base"):
ret["result"] = None
return ret

retcode = __salt__["certutil.del_store"](name, store, retcode=True)
retcode = __salt__["certutil.del_store"](name, store, saltenv=saltenv, retcode=True)
if retcode != 0:
ret["comment"] = f"Error removing certificate: {name}"
ret["result"] = False
Expand Down
54 changes: 54 additions & 0 deletions tests/pytests/unit/states/test_win_certutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,57 @@ def test_del_store_fail_check():
):
out = certutil.del_store("/path/to/cert.cer", "TrustedPublisher")
assert expected == out


def test_add_store_saltenv_passed_to_get_cert_serial():
"""
Test that saltenv is forwarded to certutil.get_cert_serial in add_store
so that certificates in non-base saltenvs can be found.
"""
cache_mock = MagicMock(return_value="/tmp/cert.cer")
get_cert_serial_mock = MagicMock(return_value="ABCDEF")
get_store_serials_mock = MagicMock(return_value=["123456"])
add_mock = MagicMock(return_value=0)
with patch.dict(
certutil.__salt__,
{
"cp.cache_file": cache_mock,
"certutil.get_cert_serial": get_cert_serial_mock,
"certutil.get_stored_cert_serials": get_store_serials_mock,
"certutil.add_store": add_mock,
},
):
certutil.add_store("/path/to/cert.cer", "TrustedPublisher", saltenv="test")
get_cert_serial_mock.assert_called_once_with(
"/path/to/cert.cer", saltenv="test"
)
add_mock.assert_called_once_with(
"/path/to/cert.cer", "TrustedPublisher", saltenv="test", retcode=True
)


def test_del_store_saltenv_passed_to_get_cert_serial():
"""
Test that saltenv is forwarded to certutil.get_cert_serial in del_store
so that certificates in non-base saltenvs can be found.
"""
cache_mock = MagicMock(return_value="/tmp/cert.cer")
get_cert_serial_mock = MagicMock(return_value="ABCDEF")
get_store_serials_mock = MagicMock(return_value=["123456", "ABCDEF"])
del_mock = MagicMock(return_value=0)
with patch.dict(
certutil.__salt__,
{
"cp.cache_file": cache_mock,
"certutil.get_cert_serial": get_cert_serial_mock,
"certutil.get_stored_cert_serials": get_store_serials_mock,
"certutil.del_store": del_mock,
},
):
certutil.del_store("/path/to/cert.cer", "TrustedPublisher", saltenv="test")
get_cert_serial_mock.assert_called_once_with(
"/path/to/cert.cer", saltenv="test"
)
del_mock.assert_called_once_with(
"/path/to/cert.cer", "TrustedPublisher", saltenv="test", retcode=True
)
Loading