Dear developers,

A patch to add a script to do the key generation for users, and
(maybe?) a debconf question to ask them if they'd like it to be run
would be nice, though!

Here you go :)

This patch adds a debconf question to configure a MOK (defaults to false; also translated to French), and maintainer scripts to generate a MOK, request its enrollment (one-time password: machine's hostname), and generate conffiles for DKMS and systemd-ukify (managed by ucf).

Please let me know if it suits your needs.

Sorry to contribute this so late in Trixie's release cycle, I hope it can get in in time (I know it's not a "small, targeted fix", but it's also a feature that was requested for a long time; if it can't, well, we'll wait for Forky!).

Regards,

--
Raphaël Halimi
From a917660b33ed83199fd12e400e1d1455bdaee687 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rapha=C3=ABl=20Halimi?= <raphael.hal...@gmail.com>
Date: Tue, 20 May 2025 10:00:54 +0200
Subject: [PATCH] Configure MOK

- Ask user through debconf (en, fr)
- Generate MOK if it doesn't exist
- Request MOK enroll if it's not enrolled yet
- Generate configuration files for DKMS and systemd-ukify
---
 debian/config           |  9 +++++
 debian/control          |  4 +-
 debian/dirs             |  3 ++
 debian/po/POTFILES.in   |  1 +
 debian/po/fr.po         | 58 +++++++++++++++++++++++++++
 debian/po/templates.pot | 48 +++++++++++++++++++++++
 debian/postinst         | 86 +++++++++++++++++++++++++++++++++++++++++
 debian/postrm           | 37 ++++++++++++++++++
 debian/templates        | 19 +++++++++
 9 files changed, 263 insertions(+), 2 deletions(-)
 create mode 100755 debian/config
 create mode 100644 debian/dirs
 create mode 100644 debian/po/POTFILES.in
 create mode 100644 debian/po/fr.po
 create mode 100644 debian/po/templates.pot
 create mode 100755 debian/postinst
 create mode 100755 debian/postrm
 create mode 100644 debian/templates

diff --git a/debian/config b/debian/config
new file mode 100755
index 0000000..7aa279f
--- /dev/null
+++ b/debian/config
@@ -0,0 +1,9 @@
+#!/bin/sh
+set -e
+
+# Load debconf functions
+. /usr/share/debconf/confmodule
+
+# Ask question
+db_input high mokutil/configure || true
+db_go
diff --git a/debian/control b/debian/control
index 264d549..3bd8392 100644
--- a/debian/control
+++ b/debian/control
@@ -4,14 +4,14 @@ Priority: optional
 Maintainer: Debian UEFI Maintainers <debian-...@lists.debian.org>
 Uploaders: Steve McIntyre <93...@debian.org>, Simon Quigley <tsimo...@debian.org>
 Standards-Version: 4.6.1
-Build-Depends: debhelper-compat (= 13), libssl-dev, pkgconf, libefivar-dev, libkeyutils-dev
+Build-Depends: debhelper-compat (= 13), libssl-dev, pkgconf, libefivar-dev, libkeyutils-dev, po-debconf
 Vcs-Browser: https://salsa.debian.org/efi-team/mokutil
 Vcs-Git: https://salsa.debian.org/efi-team/mokutil.git
 
 Package: mokutil
 Architecture: any
 Multi-Arch: foreign
-Depends: ${shlibs:Depends}, ${misc:Depends}
+Depends: openssl (>= 3.2.0), ucf, ${shlibs:Depends}, ${misc:Depends}
 Description: tools for manipulating machine owner keys
  This program provides the means to enroll and erase the machine owner
  keys (MOK) stored in the database of shim.
diff --git a/debian/dirs b/debian/dirs
new file mode 100644
index 0000000..59e6946
--- /dev/null
+++ b/debian/dirs
@@ -0,0 +1,3 @@
+/etc/dkms/framework.conf.d
+/etc/kernel
+/var/lib/shim-signed/mok
diff --git a/debian/po/POTFILES.in b/debian/po/POTFILES.in
new file mode 100644
index 0000000..cef83a3
--- /dev/null
+++ b/debian/po/POTFILES.in
@@ -0,0 +1 @@
+[type: gettext/rfc822deb] templates
diff --git a/debian/po/fr.po b/debian/po/fr.po
new file mode 100644
index 0000000..1164693
--- /dev/null
+++ b/debian/po/fr.po
@@ -0,0 +1,58 @@
+# Translation of mokutil debconf templates to French.
+# Copyright (C) 2025 Raphaël Halimi <raphael.hal...@gmail.com>
+# This file is distributed under the same license as the mokutil package.
+# Raphaël Halimi <raphael.hal...@gmail.com>, 2025.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: mokutil 0.7.2-1\n"
+"Report-Msgid-Bugs-To: moku...@packages.debian.org\n"
+"POT-Creation-Date: 2025-05-21 17:32+0200\n"
+"PO-Revision-Date: 2025-05-21 17:46+0200\n"
+"Last-Translator: Raphaël Halimi <raphael.hal...@gmail.com>\n"
+"Language-Team: \n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: boolean
+#. Description
+#: ../templates:1001
+msgid "Configure a MOK automatically?"
+msgstr "Configurer une MOK automatiquement ?"
+
+#. Type: boolean
+#. Description
+#. Translators, please keep the acronym "MOK" and its meaning, but feel free to
+#. translate it afterwards, like "MOK (Machine Owner Key, <translation>)". This
+#. also applies to "Secure Boot".
+#: ../templates:1001
+msgid ""
+"A MOK (Machine Owner Key) allows software like DKMS or systemd-ukify to sign "
+"binary files in order to allow their loading with Secure Boot."
+msgstr ""
+"Une MOK (Machine Owner Key, clé de propriétaire de machine) permet aux "
+"logiciels tels que DKMS ou systemd-ukify de signer des fichiers binaires "
+"afin d'autoriser leur chargement avec Secure Boot (démarrage sécurisé)."
+
+#. Type: boolean
+#. Description
+#. Please don't translate "Enroll MOK", the MOK manager is not localized.
+#: ../templates:1001
+msgid ""
+"This package can automatically generate a MOK (along with some suitable "
+"configuration files) and request its enrollment in the machine's firmware. "
+"In this case, shim's MOK Manager will ask to confirm the enrollment at next "
+"boot; when prompted, simply select \"Enroll MOK\" and follow the on-screen "
+"instructions. The one-time password is the machine's hostname (beware, it's "
+"case-sensitiive, and the keyboard layout will probably be QWERTY)."
+msgstr ""
+"Ce paquet peut automatiquement générer une MOK (ainsi que quelques fichiers "
+"de configuration adéquats) et demander son enrôlement dans le micrologiciel "
+"de la machine. Dans ce cas, le gestionnaire de MOK de shim demandera de "
+"confirmer l'enrôlement au prochain démarrage; lorsque demandé, sélectionner "
+"simplement \"Enroll MOK\" et suivre les instructions à l'écran. Le mot de "
+"passe à usage unique est le nom d'hôte de la machine (attention, il est "
+"sensible à la casse, et l'agencement du clavier sera probablement QWERTY)."
diff --git a/debian/po/templates.pot b/debian/po/templates.pot
new file mode 100644
index 0000000..be2ae62
--- /dev/null
+++ b/debian/po/templates.pot
@@ -0,0 +1,48 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the mokutil package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: mokutil\n"
+"Report-Msgid-Bugs-To: moku...@packages.debian.org\n"
+"POT-Creation-Date: 2025-05-21 17:32+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <l...@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: boolean
+#. Description
+#: ../templates:1001
+msgid "Configure a MOK automatically?"
+msgstr ""
+
+#. Type: boolean
+#. Description
+#. Translators, please keep the acronym "MOK" and its meaning, but feel free to
+#. translate it afterwards, like "MOK (Machine Owner Key, <translation>)". This
+#. also applies to "Secure Boot".
+#: ../templates:1001
+msgid ""
+"A MOK (Machine Owner Key) allows software like DKMS or systemd-ukify to sign "
+"binary files in order to allow their loading with Secure Boot."
+msgstr ""
+
+#. Type: boolean
+#. Description
+#. Please don't translate "Enroll MOK", the MOK manager is not localized.
+#: ../templates:1001
+msgid ""
+"This package can automatically generate a MOK (along with some suitable "
+"configuration files) and request its enrollment in the machine's firmware. "
+"In this case, shim's MOK Manager will ask to confirm the enrollment at next "
+"boot; when prompted, simply select \"Enroll MOK\" and follow the on-screen "
+"instructions. The one-time password is the machine's hostname (beware, it's "
+"case-sensitiive, and the keyboard layout will probably be QWERTY)."
+msgstr ""
diff --git a/debian/postinst b/debian/postinst
new file mode 100755
index 0000000..d0c19c5
--- /dev/null
+++ b/debian/postinst
@@ -0,0 +1,86 @@
+#!/bin/sh
+set -e
+
+# Load debconf functions
+. /usr/share/debconf/confmodule
+
+# Set variables
+MOK_DIR="/var/lib/shim-signed/mok"
+MOK_KEY="$MOK_DIR/MOK.priv"
+MOK_DER="$MOK_DIR/MOK.der"
+MOK_PEM="$MOK_DIR/MOK.pem"
+MOK_CN="MOK for $(hostname -f)"
+MOK_DAYS=36500
+MOK_PASSWORD="$(hostname)"
+CONFFILES="/etc/dkms/framework.conf.d/mok.conf /etc/kernel/uki.conf"
+
+# Create MOK
+mok_create () {
+  printf "Generating MOK...\n" >&2
+  [ -d "$MOK_DIR" ] || mkdir -p "$MOK_DIR"
+  openssl req -noenc -new -x509 -newkey rsa:2048 -keyout "$MOK_KEY" -outform DER -out "$MOK_DER" -days $MOK_DAYS -subj "/CN=$MOK_CN/" -quiet
+  openssl x509 -inform DER -in "$MOK_DER" -out "$MOK_PEM"
+}
+
+# Enroll MOK
+mok_enroll () {
+  printf "Requesting MOK enroll...\n" >&2
+  printf "%s\n%s\n" "$MOK_PASSWORD" "$MOK_PASSWORD" | mokutil --import "$MOK_DER" ; mokutil --timeout -1
+  printf "\n######\nPLEASE ENROLL MOK AT NEXT BOOT (one-time password: '%s')\n######\n\n" "$MOK_PASSWORD" >&2
+}
+
+# Check if MOK is enrolled (or about to be)
+is_mok_enrolled () {
+  ( mokutil --list-enrolled ; mokutil --list-new ) | sed -n 's/^SHA1 Fingerprint: //p' | grep -q -F "$(openssl x509 -in "$MOK_PEM" -fingerprint -noout | cut -d = -f 2 | tr '[:upper:]' '[:lower:]')" || return 1
+}
+
+# Print conffile
+print_conffile () {
+  local CONFFILE
+  CONFFILE="$1"
+  case "$CONFFILE" in
+    /etc/dkms/framework.conf.d/mok.conf) printf "mok_signing_key=%s\nmok_certificate=%s\n" "$MOK_KEY" "$MOK_DER" ;;
+    /etc/kernel/uki.conf) printf "[UKI]\nSecureBootPrivateKey=%s\nSecureBootCertificate=%s\n" "$MOK_KEY" "$MOK_PEM" ;;
+  esac
+}
+
+# Create conffiles
+create_conffiles () {
+  local CONFFILE TEMP DIR
+  for CONFFILE in $CONFFILES ; do
+    TEMP="$(mktemp)"
+    chmod 644 "$TEMP"
+    printf "# Automatically generated by %s\n\n" "$DPKG_MAINTSCRIPT_PACKAGE" > "$TEMP"
+    print_conffile "$CONFFILE" >> "$TEMP"
+    DIR="${CONFFILE%/*}"
+    [ -d "$DIR" ] || mkdir -p "$DIR"
+    ucf --debconf-ok --three-way "$TEMP" "$CONFFILE"
+    ucfr --force $DPKG_MAINTSCRIPT_PACKAGE "$CONFFILE"
+    rm -f "$TEMP"
+  done
+}
+
+# Main
+case "$1" in
+  configure)
+    # Create and/or enroll MOK according to user's choice
+    db_get mokutil/configure
+    if [ "$RET" = "true" ] ; then
+      [ -e "$MOK_KEY" ] || mok_create
+      is_mok_enrolled || mok_enroll
+      create_conffiles
+    fi
+  ;;
+
+  abort-upgrade|abort-remove|abort-deconfigure)
+  ;;
+
+  *)
+    echo "postinst called with unknown argument '$1'" >&2
+    exit 1
+  ;;
+esac
+
+#DEBHELPER#
+
+exit 0
diff --git a/debian/postrm b/debian/postrm
new file mode 100755
index 0000000..2597d7d
--- /dev/null
+++ b/debian/postrm
@@ -0,0 +1,37 @@
+#!/bin/sh
+set -e
+
+# Set variables
+CONFFILES="/etc/dkms/framework.conf.d/mok.conf /etc/kernel/uki.conf"
+
+# Purge conffiles
+purge_conffiles () {
+  local UCF UCFR CONFFILE
+  UCF="$(command -v ucf || true)"
+  UCFR="$(command -v ucfr || true)"
+  for CONFFILE ; do
+    for EXT in '' .ucf-new .ucf-old .ucf-dist ; do rm -f "$CONFFILE$EXT" ; done
+    if [ -x "$UCF" ] ; then $UCF --purge "$CONFFILE" ; fi
+    if [ -x "$UCFR" ] ; then $UCFR --force --purge $DPKG_MAINTSCRIPT_PACKAGE "$CONFFILE" ; fi
+  done
+}
+
+# Main
+case "$1" in
+  purge)
+    # Purge conffiles
+    purge_conffiles $CONFFILES
+  ;;
+
+  remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
+  ;;
+
+  *)
+    echo "postrm called with unknown argument '$1'" >&2
+    exit 1
+  ;;
+esac
+
+#DEBHELPER#
+
+exit 0
diff --git a/debian/templates b/debian/templates
new file mode 100644
index 0000000..0510658
--- /dev/null
+++ b/debian/templates
@@ -0,0 +1,19 @@
+Template: mokutil/configure
+Type: boolean
+Default: false
+#flag:comment:2
+# Translators, please keep the acronym "MOK" and its meaning, but feel free to
+# translate it afterwards, like "MOK (Machine Owner Key, <translation>)". This
+# also applies to "Secure Boot".
+#flag:comment:3
+# Please don't translate "Enroll MOK", the MOK manager is not localized.
+_Description: Configure a MOK automatically?
+ A MOK (Machine Owner Key) allows software like DKMS or systemd-ukify to sign
+ binary files in order to allow their loading with Secure Boot.
+ .
+ This package can automatically generate a MOK (along with some suitable
+ configuration files) and request its enrollment in the machine's firmware.
+ In this case, shim's MOK Manager will ask to confirm the enrollment at next
+ boot; when prompted, simply select "Enroll MOK" and follow the on-screen
+ instructions. The one-time password is the machine's hostname (beware, it's
+ case-sensitiive, and the keyboard layout will probably be QWERTY).
-- 
2.49.0

Reply via email to