Spaces:
Running
Running
File size: 6,471 Bytes
a6a5d8e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | # SPDX-License-Identifier: Apache-2.0
# © 2026 Lutar, Stephen P. — SZL Holdings · ORCID 0009-0001-0110-4173
# Authored by Yachay (CTO). Co-Authored-By: Perplexity Computer Agent.
# Doctrine v11 LOCKED 749/14/163 · Λ Conjecture 1 · SLSA L1+L2
"""
tests/test_dsse_real_signing.py — proves the DSSE signer flips from
`signatures: []` (honest UNSIGNED) to a REAL ECDSA-P256-SHA256 signature
the moment the SZL_COSIGN_PRIVATE_KEY_PEM secret is present, and that the
resulting signature verifies against the matching public key.
HONESTY / SAFETY
- No real org private key is ever required, embedded, or baked into CI.
- The "present-secret" test GENERATES its own ephemeral P-256 key at runtime,
sets the env var to it, signs, and verifies against THAT key's public half.
- The real-org-secret round-trip is `skipif`-guarded: it runs ONLY if a real
SZL_COSIGN_PRIVATE_KEY_PEM / SZL_COSIGN_PRIVATE_PEM is already in the env
(e.g. a developer's local shell). It is never satisfied by CI defaults.
"""
from __future__ import annotations
import base64
import importlib
import os
import sys
import pytest
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if REPO_ROOT not in sys.path:
sys.path.insert(0, REPO_ROOT)
cryptography = pytest.importorskip("cryptography")
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes
from cryptography.exceptions import InvalidSignature
import szl_dsse
_PRIV_ENV = "SZL_COSIGN_PRIVATE_KEY_PEM"
_LEGACY_ENV = "SZL_COSIGN_PRIVATE_PEM"
def _gen_ephemeral_keypair():
"""Generate a fresh, test-only ECDSA P-256 keypair (plain PKCS#8 PEM)."""
priv = ec.generate_private_key(ec.SECP256R1())
priv_pem = priv.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption(),
).decode("utf-8")
pub_pem = priv.public_key().public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo,
).decode("utf-8")
return priv_pem, pub_pem
@pytest.fixture(autouse=True)
def _clean_env(monkeypatch):
"""Ensure no ambient secret leaks between tests unless a test sets one."""
yield
def test_unsigned_fallback_when_secret_absent(monkeypatch):
"""No secret -> signatures:[] + honesty:UNSIGNED, never fabricated."""
monkeypatch.delenv(_PRIV_ENV, raising=False)
monkeypatch.delenv(_LEGACY_ENV, raising=False)
importlib.reload(szl_dsse)
env = szl_dsse.sign_payload({"hello": "world"})
assert env["signatures"] == []
assert env["signed"] is False
assert "UNSIGNED" in env["honesty"]
assert szl_dsse.signing_available() is False
def test_real_signature_with_ephemeral_key_verifies(monkeypatch):
"""Secret present (ephemeral test key) -> REAL signature that verifies
against the matching public key via raw cryptography AND via the module's
own verify path when the embedded public key is swapped to the test key."""
priv_pem, pub_pem = _gen_ephemeral_keypair()
monkeypatch.delenv(_LEGACY_ENV, raising=False)
monkeypatch.setenv(_PRIV_ENV, priv_pem)
importlib.reload(szl_dsse)
assert szl_dsse.signing_available() is True
env = szl_dsse.sign_payload({"hello": "world", "n": 42})
# Flipped from [] to a real signature
assert env["signed"] is True
assert len(env["signatures"]) == 1
sig_entry = env["signatures"][0]
assert sig_entry["keyid"] == szl_dsse.KEYID
assert "REAL" in env["honesty"]
# 1) Verify the signature against the test public key with raw cryptography,
# reconstructing the exact DSSE PAE bytes the signer used.
body = base64.b64decode(env["payload"])
msg = szl_dsse.pae(env["payloadType"], body)
pub = serialization.load_pem_public_key(pub_pem.encode("utf-8"))
sig = base64.b64decode(sig_entry["sig"])
pub.verify(sig, msg, ec.ECDSA(hashes.SHA256())) # raises InvalidSignature on failure
# 2) Module verify path: point the embedded public key at the test public
# key and confirm verify_envelope() validates the just-made signature.
monkeypatch.setattr(szl_dsse, "COSIGN_PUBLIC_PEM", pub_pem, raising=True)
verdict = szl_dsse.verify_envelope(env)
assert verdict["verified"] is True
def test_tampered_payload_fails_verification(monkeypatch):
"""A tampered payload must NOT verify (signature binds the payload)."""
priv_pem, pub_pem = _gen_ephemeral_keypair()
monkeypatch.delenv(_LEGACY_ENV, raising=False)
monkeypatch.setenv(_PRIV_ENV, priv_pem)
importlib.reload(szl_dsse)
env = szl_dsse.sign_payload({"amount": 1})
body = szl_dsse.canonical_json({"amount": 1000000}) # tamper
msg = szl_dsse.pae(env["payloadType"], body)
pub = serialization.load_pem_public_key(pub_pem.encode("utf-8"))
sig = base64.b64decode(env["signatures"][0]["sig"])
with pytest.raises(InvalidSignature):
pub.verify(sig, msg, ec.ECDSA(hashes.SHA256()))
def test_legacy_env_var_still_works(monkeypatch):
"""Backward-compat: the legacy SZL_COSIGN_PRIVATE_PEM name still signs."""
priv_pem, _pub_pem = _gen_ephemeral_keypair()
monkeypatch.delenv(_PRIV_ENV, raising=False)
monkeypatch.setenv(_LEGACY_ENV, priv_pem)
importlib.reload(szl_dsse)
env = szl_dsse.sign_payload({"compat": True})
assert env["signed"] is True
assert len(env["signatures"]) == 1
@pytest.mark.skipif(
not (os.environ.get(_PRIV_ENV) or os.environ.get(_LEGACY_ENV)),
reason="real cosign private key not present in env; skip real-key round-trip "
"(the private key is never baked into CI)",
)
def test_real_org_key_roundtrip_if_present():
"""OPT-IN: if a real org private key is in the env, the produced signature
must verify against the module's embedded (published) public key."""
importlib.reload(szl_dsse)
assert szl_dsse.signing_available() is True
env = szl_dsse.sign_payload({"real": "org-key-roundtrip"})
assert env["signed"] is True
verdict = szl_dsse.verify_envelope(env)
assert verdict["verified"] is True, verdict
@pytest.fixture(autouse=True)
def _restore_module():
yield
# Restore a clean module state for any downstream tests
for _n in (_PRIV_ENV, _LEGACY_ENV):
os.environ.pop(_n, None)
importlib.reload(szl_dsse)
|