Files
systemd/mkosi/keyring-setup-test-ca.py
Christian Brauner f9c9576b79 mkosi: install mkosi.crt into the VOA hierarchy of the test images
Place the certificate the test images are signed with below
/usr/share/voa/<ID>/kernel-keyring/{dm-verity,fs-verity}/x509/ in the
host image and in the initrd so systemd-keyring-setup enrolls it into
the .dm-verity and .fs-verity keyrings at boot. The initrd mirrors the
copy mkosi installs there for userspace verification.

Add a test CA in keyring-setup-ca.{crt,key} and install its certificate
among the trust anchors for .dm-verity so trust anchors are enrolled as
well. keyring-setup-ca.py mints the certificates without a subject key
identifier that the tests need for the serial number fallback. OpenSSL's
x509 tool adds that extension to every certificate it signs so they
can't be produced with it.

systemd-keyring-setup.service isn't enabled by default but the
integration tests rely on it provisioning the keyrings from the initrd.
So enable it via the mkosi presets.

machine_supports_verity_keyring() looked for the mkosi certificate
anywhere in /proc/keys. Now that .fs-verity holds it as well that
doesn't imply dm-verity signature support anymore. So only look at the
keyrings dm-verity actually consults.

With the service enabled, VMs booted with dm_verity.keyring_unsealed=1
come up with the .dm-verity keyring provisioned and sealed already and
the manual provisioning in TEST-90 fails. So TEST-90 now looks at the
state of the keyring first:

- sealed at boot: the certificate is in place already, check that a
  self-signed stranger is refused
- sealed empty: systemd-keyring-setup enrolled nothing, fail
- left open although the kernel left it unsealed and
  systemd-keyring-setup is enabled: the service didn't provision it,
  fail
- otherwise provision it by hand like before and skip when the kernel
  sealed it at boot

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-26 18:55:53 +01:00

42 lines
1.9 KiB
Python

#!/usr/bin/env python3
# SPDX-License-Identifier: LGPL-2.1-or-later
"""Mint the extension-less test certificates embedded in TEST-98-KEYRING-SETUP.unsealed.sh.
The subtests for the serial-number fallback of certificate_description_suffix() need certificates without
a subjectKeyIdentifier extension. OpenSSL's x509 tool adds one to every certificate it signs, no
matter what, so they cannot be produced with it. python-cryptography only adds what is asked for.
The issuing CA pair next to this script was created with
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes \
-subj /CN=keyring-setup-ca -days 36500 \
-keyout keyring-setup-test-ca.key -out keyring-setup-test-ca.crt
and is installed into the trust-anchor hierarchy of the test images by mkosi.finalize. After
rotating the pair, rerun this script and paste the output over the embedded blobs.
"""
import pathlib
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.x509.oid import NameOID
here = pathlib.Path(__file__).parent
ca_cert = x509.load_pem_x509_certificate((here / 'keyring-setup-test-ca.crt').read_bytes())
ca_key = serialization.load_pem_private_key((here / 'keyring-setup-test-ca.key').read_bytes(), password=None)
for cn, serial in (('noskid', 0x8112131415161718), ('noskid2', 0x11121314)):
key = ec.generate_private_key(ec.SECP256R1())
cert = (
x509.CertificateBuilder()
.subject_name(x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, cn)]))
.issuer_name(ca_cert.subject)
.public_key(key.public_key())
.serial_number(serial)
.not_valid_before(ca_cert.not_valid_before_utc)
.not_valid_after(ca_cert.not_valid_after_utc)
.sign(ca_key, hashes.SHA256())
)
print(f'# {cn}, serial {serial:#x}')
print(cert.public_bytes(serialization.Encoding.PEM).decode(), end='')