"""Actual age/archive checks using disposable custody, never estate material.""" import hashlib import io import json import os from pathlib import Path import shutil import subprocess import tarfile import pytest ROOT=Path(__file__).resolve().parents[1] @pytest.fixture def transport(tmp_path): checkout=tmp_path/'checkout' for relative in ['tools/bootstrap-recovery/verify-bundle.py', 'sso-mfa/bootstrap/sops-private.py']: target=checkout/relative;target.parent.mkdir(parents=True, exist_ok=True) shutil.copy(ROOT/relative,target) key=tmp_path/'fixture.key' subprocess.run(['age-keygen','-o',str(key)],capture_output=True,check=True) recipient=subprocess.check_output(['age-keygen','-y',str(key)],text=True).strip() (checkout/'keys').mkdir();(checkout/'keys/age.pub').write_text(recipient+'\n') env={'PATH':os.environ['PATH'],'HOME':str(tmp_path),'NETKINGDOM_CUSTODY_AGE_KEY_FILE':str(key), 'SOPS_AGE_KEY':'fixture-ambient-ignored','TMPDIR':str(checkout)} return checkout,key,recipient,env,tmp_path def archive_bytes(members): stream=io.BytesIO() with tarfile.open(fileobj=stream,mode='w') as tar: for name,content,kind in members: info=tarfile.TarInfo(name) if kind=='link':info.type=tarfile.SYMTYPE;info.linkname='/outside' elif kind=='hardlink':info.type=tarfile.LNKTYPE;info.linkname='secrets/lldap/secrets.env' else:info.size=len(content) tar.addfile(info,io.BytesIO(content) if kind=='file' else None) return stream.getvalue() def verify(transport, members, *, required='lldap/secrets.env', sha=None): checkout,_,recipient,env,root=transport cipher=subprocess.check_output(['age','-r',recipient],input=archive_bytes(members)) bundle=root/'input.tar.age';bundle.write_bytes(cipher) receipt=root/'receipt.json' result=subprocess.run(['python3',str(checkout/'tools/bootstrap-recovery/verify-bundle.py'), '--bundle',str(bundle),'--bundle-sha256',sha or hashlib.sha256(cipher).hexdigest(), '--required-file',required,'--receipt',str(receipt)],capture_output=True,env=env,timeout=20) assert b'fixture-private-payload' not in result.stdout+result.stderr assert not list(checkout.glob('netkingdom-recovery-*')) return result,receipt def test_native_ciphertext_is_restored_checked_and_removed_with_explicit_limits(transport): r,p=verify(transport,[('secrets/lldap/secrets.env',b'VALUE=fixture-private-payload\n','file')]) assert r.returncode==0 receipt=json.loads(p.read_text()) assert receipt['wrong_key_refused'] and receipt['registered_recipient_match'] assert receipt['isolated_restore_readback_passed'] and receipt['temporary_plaintext_cleanup_verified'] assert not receipt['native_consumer_recovery_proven'] assert not receipt['independent_custody_proven'] assert receipt['restored_files']==['lldap/secrets.env'] @pytest.mark.parametrize('members',[ [('../escape',b'fixture-private-payload','file')], [('secrets/lldap/secrets.env',b'', 'link')], [('secrets/lldap/secrets.env',b'', 'hardlink')], [('secrets/lldap/secrets.env',b'AGE-SECRET-KEY-fixture-private-payload','file')], [('secrets/lldap/secrets.env',b'one','file'),('secrets/lldap/secrets.env',b'two','file')], [('secrets/unreviewed/secrets.env',b'fixture-private-payload','file')], ]) def test_unsafe_archives_never_publish_acceptance(transport,members): r,p=verify(transport,members) assert r.returncode!=0 and not p.exists() def test_ciphertext_digest_is_bound_before_custody_use(transport): r,p=verify(transport,[('secrets/lldap/secrets.env',b'fixture-private-payload','file')],sha='0'*64) assert r.returncode!=0 and not p.exists() def test_missing_required_service_file_refuses_acceptance(transport): r,p=verify(transport,[('secrets/lldap/secrets.env',b'fixture-private-payload','file')],required='privacyidea/pi.enc') assert r.returncode!=0 and not p.exists()