Commit Graph
116 Commits
Author SHA1 Message Date
Frantisek Sumsal 338ed5bea4 ukify: make the test happy with the latest OpenSSL
Which dropped some whitespaces in the output:

$ openssl version
OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2023)
$ openssl x509 -in cert.pem -text -noout | grep Issuer
        Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd

$ openssl version
OpenSSL 3.0.9 30 May 2023 (Library: OpenSSL 3.0.9 30 May 2023)
$ openssl x509 -in cert.pem -text -noout | grep Issuer
        Issuer: C = XX, L = Default City, O = Default Company Ltd

Making test-ukify unhappy:

>       assert 'Issuer: CN = SecureBoot signing key on host' in out
E       AssertionError: assert 'Issuer: CN = SecureBoot signing key on host' in '<...snip...>Issuer: CN=SecureBoot signing key on host archlinux2\n...'
2023-12-23 12:32:31 +01:00
Zbigniew Jędrzejewski-Szmek 0b4cf0a540 Merge pull request #30232 from keszybz/ukify-imports
Use exec() to import ukify
2023-12-13 14:38:03 +01:00
Zbigniew Jędrzejewski-Szmek 6bc99ec29b test_ukify: raise timeout
With a sufficiently large initrd, the tests take 25 s on my laptop.
Normally, they'd be quicker, but since we use what we find on the
system, we don't control this. Let's raise the timeout to reduce the
chances of a spurious failure.
2023-12-08 19:17:40 +01:00
Zbigniew Jędrzejewski-Szmek fd9ccc07a6 test_ukify: formatting 2023-12-08 19:17:40 +01:00
Zbigniew Jędrzejewski-Szmek ef0a69eb90 test_ukify: explicitly remove big temporary directories
pytest intentionally keeps around a limited number of the previous test
temporary directories [1]. This is generally OK, but in our tests that generate
initrds, we create a few very large files (both the initrd and kernel in a few
copies), which quickly adds up. I had a particularly large initrd (because of
some mkosi-initrd shenanigans), and I unded up with dozens of gigabytes of
temporary files from the tests. Let's just nuke the dirs where we write
kernel data.

[1] https://github.com/pytest-dev/pytest/issues/543
2023-12-08 19:17:40 +01:00
Zbigniew Jędrzejewski-Szmek 6f1df1ff3c test_ukify: use Path-based fixtures
Quoting https://docs.pytest.org/en/stable/how-to/tmp_path.html#the-default-base-temporary-directory:
> The tmpdir and tmpdir_factory fixtures are similar to tmp_path and
> tmp_path_factory, but use/return legacy py.path.local objects rather than
> standard pathlib.Path objects.
>
> These days, it is preferred to use tmp_path and tmp_path_factory.
2023-12-08 19:17:40 +01:00
Zbigniew Jędrzejewski-Szmek f3d50fb2c6 ukify: raise error if genkey is called with no output arguments
The idea is that genkey is called with either
--secureboot-private-key= + --secureboot-certificate=, and then it
writes those, or with --pcr-private-key + optionally --pcr-public-key
and then it writes those, or both. But when called with no arguments
whatsover, it did nothing.

There is no implicit value for any of those parameters as input (unlike in
mkosi), so we also don't want to have implicit values when used as output.
But we shouldn't return success if no work was done, this is quite confusing.
2023-12-06 11:46:04 +01:00
Zbigniew Jędrzejewski-Szmek 7b0760ca9c ukify: remove stray line
As requested in review.
2023-12-06 11:44:40 +01:00
Zbigniew Jędrzejewski-Szmek b6ecab8541 ukify: add test for --secureboot-certificate-validity=
Follow-up for bf35f9c835.
2023-12-06 11:44:40 +01:00
Roland Singer bf35f9c835 ukify: fix handling of --secureboot-certificate-validity= (#30315)
Before:
$ python src/ukify/ukify.py genkey --secureboot-private-key=sb2.key --secureboot-certificate=sb2.cert --secureboot-certificate-validity=111
Traceback (most recent call last):
  File "/home/zbyszek/src/systemd-work/src/ukify/ukify.py", line 1660, in <module>
    main()
  File "/home/zbyszek/src/systemd-work/src/ukify/ukify.py", line 1652, in main
    generate_keys(opts)
  File "/home/zbyszek/src/systemd-work/src/ukify/ukify.py", line 943, in generate_keys
    key_pem, cert_pem = generate_key_cert_pair(
                        ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/zbyszek/src/systemd-work/src/ukify/ukify.py", line 891, in generate_key_cert_pair
    now + ONE_DAY * valid_days
          ~~~~~~~~^~~~~~~~~~~~
TypeError: can't multiply sequence by non-int of type 'datetime.timedelta'

Now:
$ python src/ukify/ukify.py genkey --secureboot-private-key=sb2.key --secureboot-certificate=sb2.cert --secureboot-certificate-validity=111
Writing SecureBoot private key to sb2.key
Writing SecureBoot certificate to sb2.cert

The new code is also clearer.
2023-12-06 10:49:47 +01:00
Zbigniew Jędrzejewski-Szmek 8244f394da tests: fix section mapping in test_ukify.py
The regexp only worked if the sections were small enough for the size to
start with "0". I have an initrd that is 0x1078ec7e bytes, so the tests
would spuriously fail.
2023-12-03 12:34:43 +00:00
Zbigniew Jędrzejewski-Szmek 24baee3370 ukify: avoid deprecated datetime call
DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for
                    removal in a future version. Use timezone-aware objects to
                    represent datetimes in UTC: datetime.datetime.now(datetime.UTC).

The difference between the two is that .now(datetime.UTC) returns an object with
a timezone attached, "the numbers" are the same.

>>> datetime.datetime.utcnow(), datetime.datetime.now(datetime.UTC)
(datetime.datetime(2023, 12, 1, 9, 37, 53, 891669),
 datetime.datetime(2023, 12, 1, 9, 37, 53, 891688, tzinfo=datetime.timezone.utc))

This value is fed to cryptography's x509.CertificateBuilder object, so as long
as it can accept a datetime object with tzinfo, the result should be identical.
2023-12-01 12:44:08 +00:00
Zbigniew Jędrzejewski-Szmek 34c2fc8505 ukify: simplify import 2023-12-01 10:30:16 +01:00
Zbigniew Jędrzejewski-Szmek f99304fe23 ukify: show .sbom sections as binary
Fixup for e87dec82be:
I misunderstood the format. It's actually CBOR, i.e. some binary format.
When trying to show show text we would first check if it's valid UTF-8,
so we would handle this gracefully, i.e. emit a warning and not print
the contents.
2023-11-13 16:33:07 +00:00
Zbigniew Jędrzejewski-Szmek e87dec82be ukify: show .sbom sections as text
There are draft proposals to embed SBOM metadata in the .sbom section of PE
binaries [1], in the coSWID XML format. Some details of how this is actually
implemented might change, but it seems very likely that both section name and
it being text will stay. Let's show the section as text to make such binaries
easier to inspect. ([1] recommends using 'objcopy -j .sbom' which isn't
particularly readable.)  Once there's more standarization of the actual
format, we can add pretty-printing and/or syntax highlighting.

[1] https://uefi.org/blog/firmware-sbom-proposal
[2] https://www.ietf.org/archive/id/draft-ietf-sacm-coswid-21.html
2023-11-13 10:59:30 +01:00
Zbigniew Jędrzejewski-Szmek 51faf83696 ukify: print a more readable synopsis in --help
The details of formatting are copied from mkosi. This results in the following:

   usage:
     ukify build [--linux=LINUX] [--initrd=INITRD] [options…]
     ukify genkey [options…]
     ukify inspect FILE… [options…]

  Build and sign Unified Kernel Images

  options:
    --version             show program's version number and exit
    ...

I put "[options…]" at the end, because that's what one would generally do
with long options like "--cmdline" and others.
2023-11-13 10:59:30 +01:00
Yu Watanabe d19434fbf8 tree-wide: fix typo 2023-10-31 14:35:33 +09:00
Luca Boccassi 6cd1f6546c Merge pull request #29332 from esposem/ukify_simplify
ukify: automatically infer --signtool from the parameters given
2023-10-27 00:10:28 +01:00
Zbigniew Jędrzejewski-Szmek e3696e6f63 ukify: fix .dtb section name in 'inspect'
Fixup for df4a46733a.
2023-10-11 17:34:43 +02:00
Emanuele Giuseppe Esposito 1277575408 ukify: override default option value with config file
If an option like SecureBootCertificateDir is given, it should override
the default '/etc/pki/pesign'. Until now the config file option were
always ignored if they had a default.

So from now on, every ConfigItem with a config_key and default field
should also give config_push = ConfigItem.config_set.
2023-10-10 07:06:24 -04:00
Emanuele Giuseppe Esposito 5c52078162 ukify: automatically infer --signtool from the parameters given
--signtool is actually useless: it can be inferred depending on if
--secureboot-certificate-name (pesign) is given, or
--secureboot-private-key and --secureboot-certificate (sbsign) is given.

Leave the option just for backwards compatibility.
2023-10-10 07:06:23 -04:00
Valentin Lefebvre 750674da0d ukify: explicitly import attribute
* Explicitly import attributes rsa and serialization from cryptography.hazmat

Signed-off-by: Valentin Lefebvre <valentin.lefebvre@suse.com>
2023-09-29 11:31:12 +02:00
Joerg Behrmann 7c52d5236a treewide: split commandline into command line 2023-09-20 16:37:23 +01:00
Alvin Alvarado a05fa30f88 ukify/man: Look for a config file in systemd folders if not specified
If the user does not specify a config file to use, ukify will try looking for one at {/run,/etc,/usr/local/lib,/usr/lib}/systemd/ukify.conf in order and then use the first one found. Also made sure the --config input is a pathlib.Path by specifying its type in its CONFIG_ITEMS entry.
Big cheers to Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> for helping!
2023-09-08 16:21:28 +02:00
Zbigniew Jędrzejewski-Szmek 594e27b0bc ukify: fail if the config file was not read
Inspired by https://github.com/systemd/systemd/pull/28997.
Noticed by Alvin Alvarado <alvin@striczkof.io>.
2023-08-29 15:16:35 +03:00
Daan De Meyer c1e704626a ukify: Use length= instead of ignore_padding= in inspect
ignore_padding= was only added in a recent version of pefile. Let's
set length= to the virtual size instead which is what ignore_padding
does behind the scenes so we're compatible with older versions of
pefile.
2023-08-10 19:35:21 +01:00
Luca Boccassi bd95029c3e Merge pull request #28743 from mrc0mmand/lint-python-scripts
tools: lint Python scripts
2023-08-10 19:13:45 +01:00
Frantisek Sumsal 79f902eb09 Add .pylintrc to globally suppress warnings we don't really care about
Also, drop the respective disable directives from existing files.
2023-08-10 18:13:29 +02:00
Zbigniew Jędrzejewski-Szmek 4d8c16b166 test: use pytest.raises wrapper
This way we check that the appropriate exception is raised,
not just ignore it.

Follow-up for e3c04a5c84.
2023-08-09 13:56:07 +02:00
Frantisek Sumsal 0be1de7ffc ukify: don't panic when prepending to an undefined list
Handle the case when all the arguments are passed in through a
configuration file:

$ cat ukify.conf
[UKI]
Linux = /boot/vmlinuz-linux
Initrd = /boot/initramfs-linux.img

Before:
$ src/ukify/ukify.py --config ukify.conf build
Traceback (most recent call last):
  File "/root/systemd/src/ukify/ukify.py", line 1604, in <module>
    main()
  File "/root/systemd/src/ukify/ukify.py", line 1590, in main
    opts = parse_args()
           ^^^^^^^^^^^^
  File "/root/systemd/src/ukify/ukify.py", line 1584, in parse_args
    apply_config(opts)
  File "/root/systemd/src/ukify/ukify.py", line 1431, in apply_config
    item.apply_config(namespace, section_name, group, key, value)
  File "/root/systemd/src/ukify/ukify.py", line 1123, in apply_config
    self.config_push(namespace, group, dest, value)
  File "/root/systemd/src/ukify/ukify.py", line 1019, in config_list_prepend
    setattr(namespace, dest, value + old)
                             ~~~~~~^~~~~
TypeError: can only concatenate list (not "NoneType") to list

After:
$ src/ukify/ukify.py --config ukify.conf build
Kernel version not specified, starting autodetection 😖.
Found uname version: 6.4.7-arch1-3
Wrote unsigned vmlinuz-linux.unsigned.efi

Resolves: #28688
2023-08-05 22:38:46 +01:00
Yu Watanabe dc4a00555a meson: set suite for all tests, and adjust suite for some tests 2023-08-03 20:37:16 +09:00
Daan De Meyer d713104abe ukify: Only run systemd-measure after adding all sections
We were running systemd-measure before adding the sbat section,
let's fix that.

Also make sure we only pass --linux to systemd-measure once instead
of twice.
2023-08-01 21:11:15 +01:00
Yu Watanabe e3c04a5c84 test-ukify: add tests for an empty argument 2023-07-29 19:57:35 +09:00
Yu Watanabe f0876c7ab9 ukify: check option length
Follow-up for df4a46733a.
2023-07-29 18:48:32 +09:00
Luca Boccassi 1a1a691ba7 Merge pull request #27621 from esposem/ukify_read
ukify: add an option to read the PE sections
2023-07-28 09:55:03 +01:00
Luca Boccassi 5a945fab7a ukify: fix armv7 architecture mapping
$ uname -m
armv7l

Traceback (most recent call last):
  File "/<<PKGBUILDDIR>>/obj-arm-linux-gnueabihf/src/kernel-install/60-ukify.install", line 223, in <module>
    main()
  File "/<<PKGBUILDDIR>>/obj-arm-linux-gnueabihf/src/kernel-install/60-ukify.install", line 219, in main
    call_ukify(opts)
  File "/<<PKGBUILDDIR>>/obj-arm-linux-gnueabihf/src/kernel-install/60-ukify.install", line 205, in call_ukify
    ukify['finalize_options'](opts2)
  File "/<<PKGBUILDDIR>>/obj-arm-linux-gnueabihf/ukify", line 1423, in finalize_options
    opts.efi_arch = guess_efi_arch()
                    ^^^^^^^^^^^^^^^^
  File "/<<PKGBUILDDIR>>/obj-arm-linux-gnueabihf/ukify", line 78, in guess_efi_arch
    raise ValueError(f'Unsupported architecture {arch}')
ValueError: Unsupported architecture armv7l
2023-07-24 21:10:48 +02:00
Yu Watanabe dc8b82a5b4 test-ukify: use systemd-measure and bootctl in build directory
And skip tests if systemd-measure is not found.
Then, we can safely run test_ukify.py directly.
2023-07-21 15:32:02 +02:00
Yu Watanabe 4fc925a026 test: fix a syntax error in test-ukify
Follow-up for d7d36252e5.

Fixes #28464.
2023-07-20 09:55:32 +02:00
Emanuele Giuseppe EspositoandZbigniew Jędrzejewski-Szmek 805d41e279 ukify/test_ukify: test display verb
Co-authored-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
2023-07-15 19:41:51 +02:00
Emanuele Giuseppe EspositoandZbigniew Jędrzejewski-Szmek df4a46733a ukify: add a verb to inspect the PE sections
Since PE can't be read with a normal editor, provide functionality to read PE
sections and output their name and when possible the content too.

ukify inspect <file> describes the sections and print the content of the
well-known sections to stdout.

Co-authored-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
2023-07-15 19:41:51 +02:00
Daan De Meyer d7d36252e5 ukify: Derive public key from private key if not specified 2023-07-13 16:31:05 +01:00
Emanuele Giuseppe Esposito b708789dc4 ukify: refactor signing code
When ukify is not signing, it should not check if sbsign/pesign are
installed, nor print if they are missing or not.
2023-07-10 02:41:37 -04:00
Luca Boccassi 635c6ea622 ukify: measure sbat section too 2023-07-05 21:31:08 +01:00
Luca Boccassi a8b645dec8 ukify: enable --sbat for UKIs too
For confidential computing they want to be able to revoke initrds too, so allow
passing a specific --sbat section when building a UKI too, not just an addon.
Merge it with the stub and kernel sections.
2023-07-05 21:31:08 +01:00
Luca Boccassi c3f7501c4d ukify: merge .sbat sections from stub and kernel
If the kernel contains a .sbat section (they should start soon) then merge
it with the stub's so that revocations can apply to either component.

Fixes https://github.com/systemd/systemd/issues/27866
2023-06-30 17:17:56 +01:00
Frantisek Sumsal 9a27ef092e tree-wide: fix a couple of typos
As reported by Fossies.org.
2023-06-15 20:52:45 +02:00
Zbigniew Jędrzejewski-Szmek 814e4d7a67 ukify: make the certficate validity configurable
Requested in https://github.com/systemd/systemd/pull/27946/commits/4cc743319ae378d458050d6e0cfdeaa03addd379#r1228592001
2023-06-14 13:18:00 +02:00
Zbigniew Jędrzejewski-Szmek 13a29b0efb test_ukify: skip test requiring cryptography
I'll add the dep in Fedora spec so it does get tested at least
in some cases.
2023-06-14 13:18:00 +02:00
Zbigniew Jędrzejewski-Szmek ff7580e280 test_ukify: cleanups suggested by pylint 2023-06-14 13:18:00 +02:00
Zbigniew Jędrzejewski-Szmek a1c80efddc ukify: add 'genkey' verb
The idea is to make it easy to generate all the signing key and certs
that can be used for local signing. The verb is the modeled after
'mkosi genkey', but there are some important differences: we generate
the keys to the paths where they will be read from, both pcr signing
keys and the SecureBoot certificate+key.

If any of the outputs exist, operation is refused. Maybe we could add a
--force option in the future, but this operation should be rare, so I think
it's better to refuse to overwrite anything initially.

I'm only doing a token man page change here.
https://github.com/systemd/systemd/pull/27621 reworks the man page,
and the changes done here would conflict heavily with that work. I'll
submit a follow-up patch later.
2023-06-14 13:17:33 +02:00