PESIGN(1)

✨ NAME ✨

pesign β€” tool for signing UEFI applications. And yes bestie, pesign(1) is literally the manual page you're reading, so buckle up πŸ’….

🌸 SYNOPSIS 🌸

pesign -i file [-o file] [-f] [-n directory] [-t token] [-c nickname]
       [-u number] [-m file] [-e file] [-I file] [-E file] [-R file]
       [-K file] [-C file] [-a] [-l] [-S] [-v]
       [--pinfile file | --pwfile file]  ⟨-s | -D [-N] | -r | -h
       [-d digest] [-P | -p]⟩

πŸ¦‹ DESCRIPTION πŸ¦‹

okay so pesign is a command line tool for manipulating signatures and cryptographic digests of UEFI applications. That's the whole vibe: signatures, digests, UEFI apps, handled from the command line ✨.

πŸ’– OPTIONS πŸ’–

  • -i file, --in file β€” Input PE file for signing. This is the file you're bringing to the function, bestie.
  • -o file, --out file β€” Output PE file for signing. This is where the signed result goes.
  • -f, --force β€” Overwrite the existing file specified with --out. No cap, it will absolutely replace it.
  • -n directory, --certdir directory β€” Use the NSS Database in directory (default: /etc/pki/pesign).
  • -t token, --token token β€” Use the NSS token named token.
  • -c nickname, --certificate nickname β€” Use the certificate called nickname in the NSS Database.
  • -u number, --signature-number number β€” Signature number, indexed from 0, for use with --remove-signature, --export-signature, or --show-signature (default: 0).
  • -m file, --import-signature file β€” Import Authenticode signature from file.
  • -e file, --export-signature file β€” Export Authenticode signature to file.
  • -I file, --import-signed-attributes file β€” Import PKCS-7 SignedAttributes (with no signature) from file.
  • -E file, --export-signed-attributes file β€” Export PKCS-7 SignedAttributes (with no signature) to file.
  • -R file, --import-raw-signature file β€” Import signature digest from file.
  • -K file, --export-pubkey file β€” Export public key from the NSS Database specified by --token and --certificate to file.
  • -C file, --export-cert file β€” Export certificate from the NSS Database specified by --token and --certificate to file.
  • -a, --ascii-armor β€” When exporting certificates, encode them in ascii-armor.
  • -l, --list-signatures β€” List signatures.
  • -S, --show-signature β€” Show information about signatures.
  • -v, --verbose β€” Be more verbose.
  • -s, --sign β€” Create a new signature.
  • -D, --daemonize β€” Run as a daemon.
  • -N, --nofork β€” Do not fork when daemonizing (daemon runs in foreground).
  • -r, --remove-signature β€” Remove signature.
  • -h, --hash β€” Display the Authenticode hash of the binary.
  • -d digest, --digest-type digest β€” Use the cryptographic digest with --hash (use help to list options) (default: sha256).
  • -P, --padding | -p, --nopadding β€” Do or do not pad the binary according to PE 9.3 rules before signing or hashing (default: --padding).

Padding is recommended (and in many circumstances required) even for binaries which predate the current PE spec, and is enabled by default as of pesign 113. This is one of those "trust the process" moments 🫢.

  • --pinfile file | --pwfile file β€” Read token's password from file rather than from interactive prompt.

(the same can be accomplished by exporting the environment variable PESIGN_TOKEN_PIN)

πŸŽ€ EXAMPLES πŸŽ€

Keep in mind that the following examples assume that /etc/pki/pesign is the certificate database. To make use of it as a regular user, add yourself to the pesign Unix group with

sudo usermod -a -G pesign $USER

πŸ’… Signing with the certificate and private key in individual files

If you have a certificate file and private key file, the following steps may be used to sign a PE image:

# Create a pkcs12 file from private key and certificate file.
host:~$ openssl pkcs12 -export -out foo_key.p12 \
        -inkey signing_key.pem -in xyz_cert.x509.pem

# Import pkcs12 file into pesign db
host:~$ pk12util -i foo_key.p12 -d /etc/pki/pesign

# Do the signing
host:~$ pesign -c my-signing-cert -s \
        -i foo.unsigned.efi -o foo.signed.efi

Please note that this is just an example, and that recommended best practice is to always store private keys in a FIPS 140-2 Hardware Security Module (HSM), level 2 or higher. Like, genuinely, bestie β€” protect those keys πŸ”.

πŸ”₯ Signing using an HSM

If you have a key pair in your HSM and your HSM vendor provides a PKCS-11 library, you can use it with NSS directly:

# Add the HSM PKCS-11 library to the NSS database
host:~$ modutil -dbdir /etc/pki/pesign -add vendor-engine \
        -libfile /usr/lib64/pkcs11/vendor-engine.so
WARNING: Performing this operation while the browser is running
could cause corruption of your security databases. If the browser
is currently running, you should exit browser before continuing
this operation. Type
'q <enter>' to abort, or <enter> to continue: <type enter here>

Module "vendor-engine" added to database.

# List the added module
host:~$ modutil -dbdir /etc/pki/pesign -list
-----------------------------------------------------------
  1. NSS Internal PKCS #11 Module
           uri: pkcs11:library-manufacturer=Mozilla%20Foundation;library-description=NSS%20Internal%20Crypto%20Services;library-version=3.52
         slots: 2 slots attached
        status: loaded

         slot: NSS Internal Cryptographic Services
        token: NSS Generic Crypto Services
          uri: pkcs11:token=NSS%20Generic%20Crypto%20Services;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203

         slot: NSS User Private Key and Certificate Services
        token: NSS Certificate DB
          uri: pkcs11:token=NSS%20Certificate%20DB;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203

  2. opensc-pkcs11.so
        library name: /usr/lib64/pkcs11/opensc-pkcs11.so
           uri: pkcs11:library-manufacturer=OpenSC%20Project;library-description=OpenSC%20smartcard%20framework;library-version=0.20
         slots: 1 slot attached
        status: loaded

         slot: Generic Smart Card Reader Interface [Smart Card Reader Interf...
        token: OpenSC Card (myorg-sb-signer)
          uri: pkcs11:token=OpenSC%20Card%20(myorg-sb-signer);manufacturer=OpenSC%20Project;serial=56516a130f35;model=PKCS%2315
-----------------------------------------------------------

# List certs in tokens
host:~$ certutil -d /etc/pki/pesign \
        -h "OpenSC Card (myorg-sb-signer)" -L
Certificate Nickname                             Trust Attributes
                                                 SSL,S/MIME,JAR/XPI

Enter Password or Pin for "OpenSC Card (myorg-sb-signer)": <type the PIN here>
OpenSC Card (myorg-sb-signer):/CN=My Org's SB Signer    u,u,u

# Sign with private key in HSM
host:~$ pesign -t "OpenSC Card (myorg-sb-signer)" \
        -c "OpenSC Card (myorg-sb-signer):/CN=My Org's SB Signer" \
        -s -i foo.unsigned.efi -o foo.efi

🧚 Example with OpenDNSSEC's SoftHSM

The OpenDNSSEC project provides a software implementation of a generic cryptographic device with a PKCS#11 interface - SoftHSM.

SoftHSM, OpenDNSSEC, https://www.opendnssec.org/softhsm/ .

This project may come in handy as one can practice how HSMs work without the need to have a physical HSM.

In this example we'll initialize one token, generate a CA certificate directly in it and make pesign ask it for the generated object to sign a shimx64 binary.

Please note that this is just an example and was written purely for demonstration purposes. Use hardware tokens, strong passwords and don't store these in plaintext directly in filesystem. That part is not a vibe, bestie 😭.

https://www.opendnssec.org/softhsm/

# Initialize a SoftHSM token
host:~$ mkdir -p $HOME/.config/softhsm2/tokens
host:~$ echo "directories.tokendir = $HOME/.config/softhsm2/tokens" > $HOME/.config/softhsm2/softhsm2.conf
host:~$ softhsm2-util --init-token --label HSM --so-pin Secret.123 --pin Secret.123 --free

# Store this PIN in a file
host:~$ cat ~/pwfile.txt
Secret.123

# Generate a CA directly in this token
host:~$ efikeygen -t HSM -d /etc/pki/pesign -n example \
        --ca --self-sign --common-name "CN=example,OU=example,O=example" --kernel

# Confirm the certificate is really in there
host:~$ certutil -d /etc/pki/pesign -h HSM -L

Certificate Nickname                                         Trust Attributes
                                                             SSL,S/MIME,JAR/XPI

Enter Password or Pin for "HSM": <type the PIN 'Secret.123' here>
HSM:example                                                  u,u,u

# Do the signing
host:~$ pesign -t HSM -n /etc/pki/pesign -c example \
        -i ~/shimx64.efi.unsigned -o ~/shimx64.efi.signed \
        --pinfile ~/pwfile.txt -s

🌈 Signing using an HSM with an OpenSSL Engine

If you have a key pair in your HSM but can't access it directly, but do have access to the openssl command line tool configured with your vendor's libraries, you can still use pesign to sign your PE binaries:

# Import the public certificate into the NSS Database
host:~$ certutil -d /etc/pki/pesign -A -n myorg-sb-signer \
        -t ,,u -i myorg-sb-signer.cer

# Export the PKCS-7 SignedAttributes section pesign generates
host:~$ pesign -i foo.unsigned.efi -E foo.sattrs.bin

# Generate a signature using OpenSSL
host:~$ openssl dgst -sha256 -sign $KEY \
        --keyform ENGINE --engine $ENGINEID \
        -out foo.sattrs.sig foo.sattrs.bin

# Import the signature with the original SignedAttributes into
# the PE binary
host:~$ pesign -c myorg-sb-signer \
        -R foo.sattrs.sig -I foo.sattrs.bin \
        -i foo.unsigned.efi -o foo.efi

⭐ STANDARDS ⭐

the receipts, periodt:

✨ SEE ALSO ✨

Okay bestie, if you wanna go deeper down the rabbit hole (and honestly, why wouldn't you πŸ’…), go check out these icons:


🫢 AUTHORS 🫢

Gotta give credit where it's due, periodt:

  • Peter Jones
  • Vikas Charak (the one who served us those examples ✨)
  • Kamil Aronowski (fixes and improvements, lowkey carrying πŸŽ€)

And that's a wrap, bestie! πŸ¦‹ This lil masterpiece comes to you from the Linux fam, dated Apr 11, 2023, and it's the PESIGN(1) page β€” go forth and sign things, no cap πŸ‘‘πŸ”₯

πŸ“¦ where this page comes from