Hello people. I need some help from the good folks who maintain the Fedora servers responsible for building a bootchain securely, i.e. GRUB2 or the kernel. For instance, the bkernel01.iad2.fedoraproject.org server.
Let's take a look at the build logs of a recent GRUB2 build (https://koji.fedoraproject.org/koji/buildinfo?buildID=2185557) here: https://kojipkgs.fedoraproject.org//packages/grub2/2.06/95.fc38/data/logs/x8... As far as I can see, this server has a smart-card with a private key attached and during the building procedure, the critical components are being signed with Red Hat Bootloader Team's `pesign` software (version +115) running in client-server mode rather than standalone mode. By this I mean e.g. line number 7074 from the log file: ``` + /usr/bin/pesign-client -t 'OpenSC Card (Fedora Signer)' -c '/CN=Fedora Secure Boot Signer' -s -i grubx64.efi.orig -o grubx64.efi.onesig ```
I'd like to replicate the setup Fedora has to rebuild bootchain components on my own. My question is: how did you make `pesign-client` work fine? Is there a procedure of some sort that works just fine that I don't know about?
Here's what I attempted on a Fedora 38 machine:
- ensured that I have a recent version of `pesign` that Fedora Project ships:
``` $ rpm -qa --qf '%{NEVRA}\n' pesign pesign-116-2.fc38.x86_64 ```
- added myself to the `pesign` Unix group and rebooted the machine just to be sure it's there alright:
``` $ usermod -a -G pesign user ```
- created a DNSSEC's SoftHSM token:
``` $ mkdir -p $HOME/.config/softhsm2/tokens $ echo "directories.tokendir = $HOME/.config/softhsm2/tokens" > $HOME/.config/softhsm2/softhsm2.conf $ softhsm2-util --init-token --label HSM --so-pin Secret.123 --pin Secret.123 --free ```
- generated a key to be used with `pesign`:
``` $ efikeygen -d /etc/pki/pesign -n example --self-sign --common-name "CN=example,OU=example,O=example" --kernel ```
- exported the key to a .pk12 file:
``` $ pk12util -d /etc/pki/pesign -o my-ca.pk12 -n example Enter password for PKCS12 file: Re-enter password: pk12util: PKCS12 EXPORT SUCCESSFUL ```
- imported the file to a SoftHSM token:
``` $ pk12util -i my-ca.pk12 -d /etc/pki/pesign -h HSM Enter Password or Pin for "HSM": Secret.123 Enter password for PKCS12 file: pk12util: PKCS12 IMPORT SUCCESSFUL ```
- verified that the operation succeeded:
``` $ pkcs11-tool --module p11-kit-proxy.so -l --pin Secret.123 -O Using slot 0 with a present token (0x11) Public Key Object; RSA 2048 bits label: ID: 3b378e192bb341ca96c2254e30948f55fe3285d0 Usage: encrypt, verify, wrap Access: none Certificate Object; type = X.509 cert label: example subject: DN: O=example, OU=example, CN=example serial: 2BE5E980432B464C8EE366B3F76914A4 ID: 3b378e192bb341ca96c2254e30948f55fe3285d0 Private Key Object; RSA label: example ID: 3b378e192bb341ca96c2254e30948f55fe3285d0 Usage: decrypt, sign, unwrap Access: sensitive Public Key Object; RSA 2048 bits label: ID: 3b378e192bb341ca96c2254e30948f55fe3285d0 Usage: encrypt, verify, wrap Access: none
$ certutil -d /etc/pki/pesign -L -h HSM
Certificate Nickname Trust Attributes SSL,S/MIME,JAR/XPI
Enter Password or Pin for "HSM": HSM:example u,u,u ```
- removed `example` from NSS database:
``` $ certutil -d /etc/pki/pesign -D -n example ```
- ensured the building process will be using `pesign` in client-server mode rather than standalone:
``` $ sudo systemctl enable pesign --now Created symlink /etc/systemd/system/multi-user.target.wants/pesign.service → /usr/lib/systemd/system/pesign.service. ```
- and at last attempted to rebuild a bootchain component like GRUB2:
``` $ dnf download --source grub2 $ rpmdev-setuptree $ rpmdev-extract -C ~/rpmbuild/SOURCES/ grub2-2.06-95.fc38.src.rpm [...] $ cd ~/rpmbuild/SOURCES/ && mv */* . $ rpmbuild -bb -D 'pe_signing_token HSM' -D 'pe_signing_cert example' *.spec [...] + /usr/bin/pesign-client -t HSM -c example -s -i grubx64.efi.orig -o grubx64.efi.onesig pesign-client: signing failed: "pesignd starting (pid 1806)" error: Bad exit status from /var/tmp/rpm-tmp.hha8Hd (%build) ```
So it looks like there is an error of some kind on my Fedora 38 machine. Let's try unlocking some tokens:
``` $ pesign-client --unlock --token "NSS Certificate DB" Enter passphrase for private key: $ pesign-client --is-unlocked --token "NSS Certificate DB" token "NSS Certificate DB" is unlocked ```
Good. Let's try the same with SoftHSM:
``` $ pesign-client --unlock --token "HSM" Enter passphrase for private key: Secret.123 pesign-client: pesignd starting (pid 1806) $ pesign-client --is-unlocked --token "HSM" token "HSM" is locked ```
Why? Just why?
On the other hand, the **only** configuration of building GRUB2 and the kernel that worked for me was with pesign 113 in standalone mode and only when typing the password manually (this was some time ago on Fedora 35). Yes, there's an issue with version +114, which I filed at https://github.com/rhboot/pesign/issues/105, but this doesn't prevent the software being used in noninteractive mode (by specifying the password in a `--pinfile <FILE>` option). However, I don't know, how to accomplish this in a stock configuration of performing a build with rpmbuild -bb -D 'pe_signing_token HSM' -D 'pe_signing_cert example' *.spec - I don't think I'm supposed to write custom RPM macros for this. There has to be a more obvious solution.
Please, give me a helping hand with this. What procedure do I have to follow to replicate what's on Fedora Koji instances? What is there that I'm missing?