66 lines
1.6 KiB
Python
66 lines
1.6 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
import shutil
|
|
import subprocess
|
|
import tempfile
|
|
import unittest
|
|
|
|
from scripts.release_lib import ReleaseToolError, sign_file, verify_signature
|
|
|
|
|
|
class SigningTests(unittest.TestCase):
|
|
def test_ed25519_metadata_signatures_and_tamper_rejection(self) -> None:
|
|
openssl = shutil.which("openssl")
|
|
if openssl is None:
|
|
self.skipTest("OpenSSL is required")
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
root = Path(temporary)
|
|
private_key = root / "manifest-ed25519-private.pem"
|
|
public_key = root / "manifest-ed25519-public.pem"
|
|
generated = subprocess.run(
|
|
[
|
|
openssl,
|
|
"genpkey",
|
|
"-algorithm",
|
|
"ED25519",
|
|
"-out",
|
|
str(private_key),
|
|
],
|
|
capture_output=True,
|
|
text=True,
|
|
check=False,
|
|
)
|
|
if generated.returncode != 0:
|
|
self.skipTest("installed OpenSSL does not support Ed25519")
|
|
subprocess.run(
|
|
[
|
|
openssl,
|
|
"pkey",
|
|
"-in",
|
|
str(private_key),
|
|
"-pubout",
|
|
"-out",
|
|
str(public_key),
|
|
],
|
|
capture_output=True,
|
|
text=True,
|
|
check=True,
|
|
)
|
|
private_key.chmod(0o600)
|
|
source = root / "manifest.json"
|
|
signature = root / "manifest.json.sig"
|
|
source.write_text('{"schema":1}\n', encoding="utf-8")
|
|
|
|
sign_file(source, signature, private_key)
|
|
verify_signature(source, signature, public_key)
|
|
self.assertEqual(signature.stat().st_mode & 0o777, 0o644)
|
|
|
|
source.write_text('{"schema":2}\n', encoding="utf-8")
|
|
with self.assertRaisesRegex(ReleaseToolError, "verification failed"):
|
|
verify_signature(source, signature, public_key)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|