launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #28114
[Merge] ~cjwatson/lp-signing:log-message-hashes into lp-signing:master
Colin Watson has proposed merging ~cjwatson/lp-signing:log-message-hashes into lp-signing:master.
Commit message:
Log SHA-256 hashes of messages when signing them
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/lp-signing/+git/lp-signing/+merge/415561
Otherwise we have no way to trace back from logs to when a given message
was signed.
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/lp-signing:log-message-hashes into lp-signing:master.
diff --git a/lp_signing/model/key.py b/lp_signing/model/key.py
index ebcfc6a..a7e627a 100644
--- a/lp_signing/model/key.py
+++ b/lp_signing/model/key.py
@@ -677,8 +677,10 @@ class Key(Storm):
f"Signature mode {mode.name} not supported with "
f"{self.key_type.name}")
_log.info(
- "Making %s signature of %s with %s key %s",
- mode.name.lower(), message_name, self.key_type, self.fingerprint)
+ "Making %s signature of %s (SHA-256: %s) with %s key %s",
+ mode.name.lower(), message_name,
+ hashlib.sha256(message).hexdigest(), self.key_type,
+ self.fingerprint)
with _gpg_context(tmp) as ctx:
import_result = _gpg_key_import(ctx, self.getPrivateKey())
if not getattr(import_result, "secret_imported", 0):
@@ -759,8 +761,9 @@ class Key(Storm):
f"{self.key_type.name}")
_log.info(
- "Making %s signature of %s with %s key %s",
- mode.name.lower(), message_name, self.key_type,
+ "Making %s signature of %s (SHA-256: %s) with %s key %s",
+ mode.name.lower(), message_name,
+ hashlib.sha256(message).hexdigest(), self.key_type,
self.fingerprint)
try:
_log_subprocess_run(cmd, check=True)
diff --git a/lp_signing/model/tests/test_key.py b/lp_signing/model/tests/test_key.py
index 7f7f743..3a49a28 100644
--- a/lp_signing/model/tests/test_key.py
+++ b/lp_signing/model/tests/test_key.py
@@ -15,6 +15,7 @@ from tempfile import TemporaryDirectory
from fixtures import MockPatch
from flask_storm import store
import gpg
+from talisker.testing import TestContext
from testtools import TestCase
from testtools.matchers import (
AfterPreprocessing,
@@ -504,12 +505,14 @@ class TestKey(TestCase):
def test_sign_uefi_attached(self):
key = factory.create_key(KeyType.UEFI)
+ message = b"test data"
fake_sbsign = FakeSBSign(b"test signed data")
self.processes_fixture.add(fake_sbsign)
- self.assertEqual(
- b"test signed data",
- key.sign("t.efi", b"test data", SignatureMode.ATTACHED))
- self.assertEqual(b"test data", fake_sbsign.message_bytes)
+ with TestContext() as ctx:
+ self.assertEqual(
+ b"test signed data",
+ key.sign("t.efi", message, SignatureMode.ATTACHED))
+ self.assertEqual(message, fake_sbsign.message_bytes)
sbsign_args = [
"sbsign", "--key", EndsWith("uefi.key"),
"--cert", EndsWith("uefi.crt"), EndsWith("t.efi"),
@@ -517,6 +520,13 @@ class TestKey(TestCase):
self.assertThat(
self.processes_fixture.procs,
MatchesListwise([RanCommand(sbsign_args)]))
+ message_sha256 = hashlib.sha256(message).hexdigest()
+ ctx.assert_log(
+ level="info",
+ message=(
+ f"Making attached signature of t.efi "
+ f"(SHA-256: {message_sha256}) with UEFI key "
+ f"{key.fingerprint}"))
def test_sign_uefi_detached_unsupported(self):
key = factory.create_key(KeyType.UEFI)
@@ -538,12 +548,14 @@ class TestKey(TestCase):
def test_sign_kmod_detached(self):
key = factory.create_key(KeyType.KMOD)
+ message = b"test data"
fake_kmodsign = FakeKmodSign(b"test signed data")
self.processes_fixture.add(fake_kmodsign)
- self.assertEqual(
- b"test signed data",
- key.sign("t.ko", b"test data", SignatureMode.DETACHED))
- self.assertEqual(b"test data", fake_kmodsign.message_bytes)
+ with TestContext() as ctx:
+ self.assertEqual(
+ b"test signed data",
+ key.sign("t.ko", message, SignatureMode.DETACHED))
+ self.assertEqual(message, fake_kmodsign.message_bytes)
kmodsign_args = [
"kmodsign", "-D", "sha512",
EndsWith("kmod.key"), EndsWith("kmod.crt"),
@@ -552,6 +564,13 @@ class TestKey(TestCase):
self.assertThat(
self.processes_fixture.procs,
MatchesListwise([RanCommand(kmodsign_args)]))
+ message_sha256 = hashlib.sha256(message).hexdigest()
+ ctx.assert_log(
+ level="info",
+ message=(
+ f"Making detached signature of t.ko "
+ f"(SHA-256: {message_sha256}) with Kmod key "
+ f"{key.fingerprint}"))
def test_sign_kmod_clear_unsupported(self):
key = factory.create_key(KeyType.KMOD)
@@ -567,12 +586,14 @@ class TestKey(TestCase):
def test_sign_opal_detached(self):
key = factory.create_key(KeyType.OPAL)
+ message = b"test data"
fake_kmodsign = FakeKmodSign(b"test signed data")
self.processes_fixture.add(fake_kmodsign)
- self.assertEqual(
- b"test signed data",
- key.sign("t.opal", b"test data", SignatureMode.DETACHED))
- self.assertEqual(b"test data", fake_kmodsign.message_bytes)
+ with TestContext() as ctx:
+ self.assertEqual(
+ b"test signed data",
+ key.sign("t.opal", message, SignatureMode.DETACHED))
+ self.assertEqual(message, fake_kmodsign.message_bytes)
kmodsign_args = [
"kmodsign", "-D", "sha512",
EndsWith("opal.key"), EndsWith("opal.crt"),
@@ -581,6 +602,13 @@ class TestKey(TestCase):
self.assertThat(
self.processes_fixture.procs,
MatchesListwise([RanCommand(kmodsign_args)]))
+ message_sha256 = hashlib.sha256(message).hexdigest()
+ ctx.assert_log(
+ level="info",
+ message=(
+ f"Making detached signature of t.opal "
+ f"(SHA-256: {message_sha256}) with OPAL key "
+ f"{key.fingerprint}"))
def test_sign_opal_clear_unsupported(self):
key = factory.create_key(KeyType.OPAL)
@@ -596,12 +624,14 @@ class TestKey(TestCase):
def test_sign_sipl_detached(self):
key = factory.create_key(KeyType.SIPL)
+ message = b"test data"
fake_kmodsign = FakeKmodSign(b"test signed data")
self.processes_fixture.add(fake_kmodsign)
- self.assertEqual(
- b"test signed data",
- key.sign("t.sipl", b"test data", SignatureMode.DETACHED))
- self.assertEqual(b"test data", fake_kmodsign.message_bytes)
+ with TestContext() as ctx:
+ self.assertEqual(
+ b"test signed data",
+ key.sign("t.sipl", message, SignatureMode.DETACHED))
+ self.assertEqual(message, fake_kmodsign.message_bytes)
kmodsign_args = [
"kmodsign", "-D", "sha512",
EndsWith("sipl.key"), EndsWith("sipl.crt"),
@@ -610,6 +640,13 @@ class TestKey(TestCase):
self.assertThat(
self.processes_fixture.procs,
MatchesListwise([RanCommand(kmodsign_args)]))
+ message_sha256 = hashlib.sha256(message).hexdigest()
+ ctx.assert_log(
+ level="info",
+ message=(
+ f"Making detached signature of t.sipl "
+ f"(SHA-256: {message_sha256}) with SIPL key "
+ f"{key.fingerprint}"))
def test_sign_sipl_clear_unsupported(self):
key = factory.create_key(KeyType.SIPL)
@@ -619,12 +656,14 @@ class TestKey(TestCase):
def test_sign_fit_attached(self):
key = factory.create_key(KeyType.FIT)
+ message = b"test data"
fake_mkimage = FakeMkimage(b"test signed data")
self.processes_fixture.add(fake_mkimage)
- self.assertEqual(
- b"test signed data",
- key.sign("t.fit", b"test data", SignatureMode.ATTACHED))
- self.assertEqual(b"test data", fake_mkimage.message_bytes)
+ with TestContext() as ctx:
+ self.assertEqual(
+ b"test signed data",
+ key.sign("t.fit", message, SignatureMode.ATTACHED))
+ self.assertEqual(message, fake_mkimage.message_bytes)
mkimage_args = [
"mkimage", "-F", "-k", Not(Is(None)), "-r",
EndsWith("t.fit.signed"),
@@ -632,6 +671,13 @@ class TestKey(TestCase):
self.assertThat(
self.processes_fixture.procs,
MatchesListwise([RanCommand(mkimage_args)]))
+ message_sha256 = hashlib.sha256(message).hexdigest()
+ ctx.assert_log(
+ level="info",
+ message=(
+ f"Making attached signature of t.fit "
+ f"(SHA-256: {message_sha256}) with FIT key "
+ f"{key.fingerprint}"))
def test_sign_fit_detached_unsupported(self):
key = factory.create_key(KeyType.FIT)
@@ -649,37 +695,64 @@ class TestKey(TestCase):
key = Key.generate(
KeyType.OPENPGP, "~signing-owner/ubuntu/testing",
openpgp_key_algorithm=OpenPGPKeyAlgorithm.RSA, length=1024)
+ message = b"test data"
mock_sign = self.useFixture(MockPatch(
"gpg.Context.sign", return_value=(b"test signed data", None))).mock
- self.assertEqual(
- b"test signed data",
- key.sign("t.gpg", b"test data", SignatureMode.ATTACHED))
+ with TestContext() as ctx:
+ self.assertEqual(
+ b"test signed data",
+ key.sign("t.gpg", message, SignatureMode.ATTACHED))
mock_sign.assert_called_once_with(
- b"test data", mode=gpg.constants.SIG_MODE_NORMAL)
+ message, mode=gpg.constants.SIG_MODE_NORMAL)
+ message_sha256 = hashlib.sha256(message).hexdigest()
+ ctx.assert_log(
+ level="info",
+ message=(
+ f"Making attached signature of t.gpg "
+ f"(SHA-256: {message_sha256}) with OpenPGP key "
+ f"{key.fingerprint}"))
def test_sign_openpgp_detached(self):
key = Key.generate(
KeyType.OPENPGP, "~signing-owner/ubuntu/testing",
openpgp_key_algorithm=OpenPGPKeyAlgorithm.RSA, length=1024)
+ message = b"test data"
mock_sign = self.useFixture(MockPatch(
"gpg.Context.sign", return_value=(b"test signed data", None))).mock
- self.assertEqual(
- b"test signed data",
- key.sign("t.gpg", b"test data", SignatureMode.DETACHED))
+ with TestContext() as ctx:
+ self.assertEqual(
+ b"test signed data",
+ key.sign("t.gpg", message, SignatureMode.DETACHED))
mock_sign.assert_called_once_with(
- b"test data", mode=gpg.constants.SIG_MODE_DETACH)
+ message, mode=gpg.constants.SIG_MODE_DETACH)
+ message_sha256 = hashlib.sha256(message).hexdigest()
+ ctx.assert_log(
+ level="info",
+ message=(
+ f"Making detached signature of t.gpg "
+ f"(SHA-256: {message_sha256}) with OpenPGP key "
+ f"{key.fingerprint}"))
def test_sign_openpgp_clear(self):
key = Key.generate(
KeyType.OPENPGP, "~signing-owner/ubuntu/testing",
openpgp_key_algorithm=OpenPGPKeyAlgorithm.RSA, length=1024)
+ message = b"test data"
mock_sign = self.useFixture(MockPatch(
"gpg.Context.sign", return_value=(b"test signed data", None))).mock
- self.assertEqual(
- b"test signed data",
- key.sign("t.gpg", b"test data", SignatureMode.CLEAR))
+ with TestContext() as ctx:
+ self.assertEqual(
+ b"test signed data",
+ key.sign("t.gpg", message, SignatureMode.CLEAR))
mock_sign.assert_called_once_with(
- b"test data", mode=gpg.constants.SIG_MODE_CLEAR)
+ message, mode=gpg.constants.SIG_MODE_CLEAR)
+ message_sha256 = hashlib.sha256(message).hexdigest()
+ ctx.assert_log(
+ level="info",
+ message=(
+ f"Making clear signature of t.gpg "
+ f"(SHA-256: {message_sha256}) with OpenPGP key "
+ f"{key.fingerprint}"))
def test_sign_cv2_kernel_attached_unsupported(self):
key = factory.create_key(KeyType.CV2_KERNEL)
@@ -689,12 +762,14 @@ class TestKey(TestCase):
def test_sign_cv2_kernel_detached(self):
key = factory.create_key(KeyType.CV2_KERNEL)
+ message = b"test data"
fake_openssl_sign = FakeOpenSSLSign(b"test signed data")
self.processes_fixture.add(fake_openssl_sign)
- self.assertEqual(
- b"test signed data",
- key.sign("t.cv2_kernel", b"test data", SignatureMode.DETACHED))
- self.assertEqual(b"test data", fake_openssl_sign.message_bytes)
+ with TestContext() as ctx:
+ self.assertEqual(
+ b"test signed data",
+ key.sign("t.cv2_kernel", message, SignatureMode.DETACHED))
+ self.assertEqual(message, fake_openssl_sign.message_bytes)
openssl_sign_args = [
"openssl", "dgst", "-sha256", "-sign", EndsWith("cv2_kernel.priv"),
"-out", EndsWith("t.cv2_kernel.sig"), EndsWith("t.cv2_kernel"),
@@ -702,6 +777,13 @@ class TestKey(TestCase):
self.assertThat(
self.processes_fixture.procs,
MatchesListwise([RanCommand(openssl_sign_args)]))
+ message_sha256 = hashlib.sha256(message).hexdigest()
+ ctx.assert_log(
+ level="info",
+ message=(
+ f"Making detached signature of t.cv2_kernel "
+ f"(SHA-256: {message_sha256}) with CV2 Kernel key "
+ f"{key.fingerprint}"))
def test_sign_cv2_kernel_clear_unsupported(self):
key = factory.create_key(KeyType.CV2_KERNEL)
@@ -717,12 +799,14 @@ class TestKey(TestCase):
def test_sign_android_kernel_detached(self):
key = factory.create_key(KeyType.ANDROID_KERNEL)
+ message = b"test data"
fake_openssl_sign = FakeOpenSSLSign(b"test signed data")
self.processes_fixture.add(fake_openssl_sign)
- self.assertEqual(
- b"test signed data",
- key.sign("t.android_kernel", b"test data", SignatureMode.DETACHED))
- self.assertEqual(b"test data", fake_openssl_sign.message_bytes)
+ with TestContext() as ctx:
+ self.assertEqual(
+ b"test signed data",
+ key.sign("t.android_kernel", message, SignatureMode.DETACHED))
+ self.assertEqual(message, fake_openssl_sign.message_bytes)
openssl_sign_args = [
"openssl", "dgst", "-sha256", "-sign",
EndsWith("android_kernel.key"),
@@ -732,6 +816,13 @@ class TestKey(TestCase):
self.assertThat(
self.processes_fixture.procs,
MatchesListwise([RanCommand(openssl_sign_args)]))
+ message_sha256 = hashlib.sha256(message).hexdigest()
+ ctx.assert_log(
+ level="info",
+ message=(
+ f"Making detached signature of t.android_kernel "
+ f"(SHA-256: {message_sha256}) with Android Kernel key "
+ f"{key.fingerprint}"))
def test_sign_android_kernel_clear_unsupported(self):
key = factory.create_key(KeyType.ANDROID_KERNEL)