#!/bin/sh
set -e

# Load debconf functions
. /usr/share/debconf/confmodule

#
# 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"


#
# Functions
#

# 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/" >/dev/null 2>&1
  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 "$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
