From 69f1bdba2b4eb0383d3cbbafe1a4d90a352f3f19 Mon Sep 17 00:00:00 2001 From: Harald Pfeiffer Date: Thu, 28 Jan 2021 07:26:08 +0100 Subject: initial commit --- .gitignore | 3 +++ README.md | 15 ++++++++++++++ genkey | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ signko | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++ x509.cnf | 20 ++++++++++++++++++ 5 files changed, 163 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100755 genkey create mode 100755 signko create mode 100644 x509.cnf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d6bd2e9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +public_key.der +private_key.priv +*.ko diff --git a/README.md b/README.md new file mode 100644 index 0000000..d714b31 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Content + +This directory is here for three purposes: + +1. Create an x509 key/cert pair with which we can sign the proprietary NVIDIA + drivers (since it's proprietary black box crap plus coming from a tertiary + repository, RPMfusion, it's understandably not signed by Fedora themselves) +2. Import the resulting x509 public certificate into the UEFI MOK store +2. Sign the proprietary NVIDIA drivers + +For now, we will create a self-signed certificate. Future versions may include +the option to generate a CSR and throw this at your PKI. :-) + +Also, **this code is written rather quickly. If in doubt, derive from the +scripts.** diff --git a/genkey b/genkey new file mode 100755 index 0000000..779fe6a --- /dev/null +++ b/genkey @@ -0,0 +1,69 @@ +#!/usr/bin/env bash + +export MOKISKIP=0 +MYCD="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)" + +if [ ! -r public_key.der ] && [ ! -r private_key.priv ]; then + openssl req -x509 -new -nodes -utf8 -sha256 -days 36500 -batch -config x509.cnf -outform DER -out public_key.der -keyout private_key.priv + chmod -v 0600 private_key.priv + chmod -v 0644 public_key.der +elif [ ! -r public_key.der ];then + openssl req -x509 -utf8 -sha256 -days 36500 -batch -config x509.cnf -key private_key.priv -outform DER -out public_key.der + chmod -v 0644 public_key.der +else + printf "Nothing to do in terms of key creation.\\n" +fi + +printf "================\n" +openssl x509 -inform DER -noout -subject -issuer -issuer_hash -dates -serial -fingerprint -ocsp_uri -ext "subjectAltName,subjectKeyIdentifier" -in public_key.der|sed 's/^/ /' +OSLRET="${PIPESTATUS[0]}" +printf "================\n" +[ "$OSLRET" -ne 0 ]&&exit 1 +read -rp "Is this OK? [y/N] " PROEMT +case "$PROEMT" in + # we are kartoffels, so we check for "j" as well (as in "JA!") + "y"|"Y"|"j"|"J") ;; + *) exit 2 ;; +esac + +if [ -r public_key.der ];then + printf "Importing new public key to MOK import store..." + MOKIRET="$(sudo mokutil --import public_key.der 2>&1)" + case "$?" in + 0) + if printf "%b" "$MOKIRET"|grep -P 'SKIP:.*already enrolled' >/dev/null;then + printf " SKIPPED (already enrolled).\\n" + export MOKISKIP=1 + else + printf " OK.\\n" + fi + ;; + *) printf " FAILED!\\n";exit 1;; + esac +else + printf "Public key cannot be read!\\n" >&2 + exit 1 +fi + +(printf "LISTING NEW KEYS\\n================\\n";sudo mokutil --list-new)|less +[ "$MOKISKIP" -eq 0 ]&&[ "${PIPESTATUS[0]}" -ne 0 ]&&exit 1 +read -rp "Was this key OK? [y/N] " PROEMT +case "$PROEMT" in + "y"|"Y"|"j"|"J") ;; + *) + printf "Deleting key from MOK import store..." + sudo mokutil --revoke-import + case "$?" in + 0) printf " OK.\\n";; + *) printf " FAILED!\\n";exit 1;; + esac + exit 127 + ;; +esac +[ "$MOKISKIP" -eq 0 ]&&printf "\\n---- NOTICE ----\\nYou should reboot soon to finish the MOK import in UEFI.\\n\\n" + +read -rp "Continue to sign NVIDIA kernel modules? [y/N] " PROEMT +case "$PROEMT" in + "y"|"Y"|"j"|"J") "$MYCD"/signko ;; + *) exit 0 ;; +esac diff --git a/signko b/signko new file mode 100755 index 0000000..4114fa1 --- /dev/null +++ b/signko @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +export KVER="$(uname -r)" + +function hayulp { + printf "USAGE: %b [ -k KVER ]\\n" "$(basename "$0")" + ( + printf -- "-h:;This help\\n" + printf -- "-k:;Sign drivers supplied for KVER\\n" + printf " ;KVER equals the version name supplied by the folders in /lib/modules\\n" + )|column -ts\; +} + +while getopts :hk: SHOPT;do + case "${SHOPT}" in + h) hayulp;exit 0;; + k) export KVER="${OPTARG}";; + *) printf "Unknown parameter: -%b\\n\\n" "$OPTARG" >&2;hayulp;exit 1;; + esac +done + +SIGNER="$(grep ^CN x509.cnf|awk -F= '{print $NF}'|sed 's/^\ \+//;s/\ \+$//')" +[ "${PIPESTATUS[0]}" -ne 0 ]&&exit 1 + +if [ ! -r private_key.priv ] || [ ! -r public_key.der ];then + printf "No signing key and/or certificate found!\\n" >&2 + exit 1 +fi + +#printf "We will sign following kernel modules: %b.\n" "$(ls -amA /usr/lib/modules/"$(uname -r)"/extra/nvidia/nvidia{,-uvm}.ko)" +printf "We will sign following kernel modules: %b.\n" "$(ls -amA /usr/lib/modules/"$KVER"/extra/nvidia/nvidia*.ko /usr/lib/modules/"$KVER"/extra/nvidia/nvidia*.ko.xz 2>/dev/null)" +read -rp "Is this OK? [y/N] " PROEMT +case "$PROEMT" in + "y"|"Y"|"j"|"J") ;; + *) exit 1 ;; +esac +# shellcheck disable=SC2207 +SGDMODS=( $(ls -aA /usr/lib/modules/"$KVER"/extra/nvidia/nvidia*.ko.xz) ) +for i in "${SGDMODS[@]}";do + MODSIG=0 MODGOODSIG=0 + sudo xz -vd "$i"||exit 4 + MMOD="$(printf "%b" "$i"|sed 's/\.xz$//')" + if sudo modinfo "$MMOD"|grep '^sig_id:'|grep 'PKCS#7$' >/dev/null; then MODSIG=1; fi + if sudo modinfo "$MMOD"|grep '^signer:'|grep "$SIGNER\$" > /dev/null; then MODGOODSIG=1; fi + if [ "$MODSIG" -ne 1 ] || [ "$MODGOODSIG" -ne 1 ];then + printf "Signing %b..." "$i" + sudo /usr/src/kernels/"$KVER"/scripts/sign-file sha256 private_key.priv public_key.der "$MMOD" + case "$?" in + 0) printf " OK.\n";; + *) printf "FAILED!\n";exit 3;; + esac + else + printf "%b is already properly signed.\n" "$(basename "$i")" + fi + sudo xz -v "$MMOD"||exit 5 +done diff --git a/x509.cnf b/x509.cnf new file mode 100644 index 0000000..cc62c72 --- /dev/null +++ b/x509.cnf @@ -0,0 +1,20 @@ +[ req ] +default_bits = 4096 +distinguished_name = req_distinguished_name +prompt = no +string_mask = utf8only +x509_extensions = myexts + +[ req_distinguished_name ] +C = DE +ST = BW +L = Mannheim +O = Diringer & Scheidel GmbH & Co. KG +CN = Harald Pfeiffer +emailAddress = harald.pfeiffer@dus.de + +[ myexts ] +basicConstraints=critical,CA:FALSE +keyUsage=digitalSignature +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid -- cgit v1.2.3