Skip to content

Commit

Permalink
contrib/zbm-sign.pl: add hook to sign ZBM EFI images for Secure Boot
Browse files Browse the repository at this point in the history
Closes: #419 [via git-merge-pr]
  • Loading branch information
KorewaKiyo authored and ahesford committed Mar 30, 2023
1 parent da94578 commit dacce21
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
3 changes: 3 additions & 0 deletions contrib/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,6 @@ review the scripts themselves for more thorough descriptions of their use.
new kernel. This teardown hook unbinds all detected XHCI controllers from the
ZFSBootMenu kernel before jumping into the new kernel, allowing devices to be
properly initialized.

- `zbm-sign.pl` - A Perl script, suitable for use as a generate-zbm post-run
hook, that will sign ZFSBootMenu EFI images for use with Secure Boot.
88 changes: 88 additions & 0 deletions contrib/zbm-sign.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/env perl
# vim: softtabstop=2 shiftwidth=2 expandtab

# This script can be used to sign ZFSBootMenu EFI images for use with Secure
# Boot. It works with both `sbctl` and `sbsigntools`.
#
# Installing this script as a post-run hook for generate-zbm(5) will allow
# automatic signing of new images as they are produced by generate-zbm(8). To
# do so, make sure that the `Global` section of the generate-zbm configuration
# file includes a `PostHooksDir` key with a value that refers to an existing
# directory in your filesystem. Then, save this script in the named directory
# and set its executable bit.
#
# Run-time configuration for this hook is loaded from the ZFSBootMenu
# configuration file at `/etc/zfsbootmenu/config.yaml`. Add a `SecureBoot`
# section, which will be ignored by `generate-zbm`, to the file:
#
# SecureBoot:
# SignBackup: true
# DeleteUnsigned: false
# SignMethod: sbctl
# KeyDir: /etc/sbkeys
#
# The configuration keys should be self-explanatory.

print "---------- ZBM-Sign ----------\n";
use feature 'say';
use strict;
use warnings;
use File::Find;
use YAML::PP;

my @EFIBins;
my $Unsigned;
my $SignMethod;

my $ypp = YAML::PP->new( boolean => 'boolean' );
my $config = $ypp->load_file('/etc/zfsbootmenu/config.yaml');
my $EFI = $config->{EFI};
my $EFI_Enabled = $EFI->{Enabled};
if ( !$EFI_Enabled ) {
die "EFI images are disabled! Nothing to sign!";
}

my $Global = $config->{Global};
my $ESP = $Global->{BootMountPoint};

my $SecureBoot = $config->{SecureBoot} or die "No config found, please edit /etc/zfsbootmenu/config.yaml";
my $ZBM = "$ESP/EFI/zbm";
my $KeyDir = $SecureBoot->{KeyDir};
my $DeleteUnsigned = $SecureBoot->{DeleteUnsigned};
my $SignBackups = $SecureBoot->{SignBackup};
$SignMethod = $SecureBoot->{SignMethod};

opendir my $ZBM_dir, $ZBM
or die "Cannot open ZBM dir: $ZBM";

if ($SignBackups) {
@EFIBins = grep { !/signed\.efi$/i and /\.efi/i } readdir $ZBM_dir;
} else {
@EFIBins = grep { !/signed\.efi$/i and !/backup/i and /\.efi/i } readdir $ZBM_dir;
}

say "Found: @EFIBins";
if ( !$SignMethod ) {
die "No sign method found";
}
for (@EFIBins) {

say "\nSigning $_";

if ( $SignMethod eq "sbctl" ) {
system "sbctl sign $ZBM/$_";
} elsif ( $SignMethod eq "sbsign" ) {
$Unsigned = substr( $_, 0, -4 );
system "sbsign --key $KeyDir/DB.key --cert $KeyDir/DB.crt $ZBM/$_ --output $ZBM/$Unsigned-signed.efi";
} else {
die "Sign method $SignMethod not valid.";
}

if ( $DeleteUnsigned && $SignMethod eq "sbctl" ) {
say "sbctl signs in place, not deleting $_";
} elsif ( $DeleteUnsigned && $SignMethod ne "sbctl" ) {
say "Deleting unsigned $_";
system "rm $ZBM/$_";
}
}
print "---------- FINISHED ----------\n";

0 comments on commit dacce21

Please sign in to comment.