certauth/tests/test_signing.py
Jarian Cottingham c759597ad0 fix: pass YubiKey PIN via stdin instead of CLI arg (#18, #31)
--pin-source stdin prevents PIN visibility in `ps` output.
Use tempfile.mkstemp for all temp files (unpredictable names, 0600 perms).
Clean up temp files in finally block.
Add tests for PIN not in args and mkstemp usage.
2026-07-04 04:49:56 +00:00

52 lines
2.0 KiB
Python

import os
import sys
import unittest
from unittest import mock
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "api"))
class TestSigningSecurity(unittest.TestCase):
@mock.patch("signing.subprocess.run")
@mock.patch("signing._make_temp_file")
def test_pin_not_in_cli_args(self, mock_mkstemp, mock_run):
"""PIN must NOT appear in subprocess command-line args."""
mock_mkstemp.return_value = "/tmp/test_file"
mock_run.return_value = mock.MagicMock(returncode=0)
import signing
signing.sign_tbs_with_yk(b"\x00" * 100, "test-pin-123")
cmd = mock_run.call_args[0][0]
self.assertNotIn("test-pin-123", cmd, "PIN must not appear in command args")
self.assertIn("--pin-source", cmd)
self.assertIn("stdin", cmd)
self.assertNotIn("--pin", cmd) or cmd.index("--pin-source") < cmd.index("--pin")
@mock.patch("signing.subprocess.run")
def test_temp_files_use_mkstemp(self, mock_run):
"""Temp files must use mkstemp, not predictable names."""
mock_run.return_value = mock.MagicMock(returncode=0)
with mock.patch("signing.tempfile.mkstemp") as mock_mkstemp:
mock_mkstemp.return_value = (0, "/tmp/unpredictable_name")
import signing
try:
signing.sign_tbs_with_yk(b"\x00" * 100, "pin")
except Exception:
pass
calls = [c[0][1] for c in mock_mkstemp.call_args_list]
self.assertTrue(all("/tmp/unpredictable_name" in c for c in calls),
"All temp files should use mkstemp")
def test_no_hardcoded_pin_default(self):
"""YK PIN must fail if env var not set."""
os.environ.pop("YK_ROOT_PIN", None)
os.environ.pop("YK_INT_PIN", None)
if "config" in sys.modules:
del sys.modules["config"]
with self.assertRaises(RuntimeError):
__import__("config")
if __name__ == "__main__":
unittest.main()