initial commit

This commit is contained in:
Radon 2025-09-23 19:03:16 -05:00
commit 25dddb2c8b
11 changed files with 862 additions and 0 deletions

24
.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Build artifacts
build/
dist/
*.rpm
*.src.rpm
*.tar.gz
ksigner.spec
src/ksigner
docs/ksigner.8
# Temporary files
*~
*.swp
*.tmp
# RPM build artifacts
noarch/
x86_64/
SOURCES/
SPECS/
BUILD/
BUILDROOT/
RPMS/
SRPMS/

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 KSigner Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

59
Makefile Normal file
View File

@ -0,0 +1,59 @@
NAME = ksigner
VERSION = $(shell cat VERSION)
RELEASE = $(shell cat RELEASE)
SOURCEDIR = .
BUILDDIR = build
SOURCES = src/ksigner src/ksigner.conf src/ksigner-update-hook docs/ksigner.8 README.md LICENSE
CLEANFILES = $(BUILDDIR) $(NAME).spec src/$(NAME) docs/$(NAME).8 noarch *.tar.gz *.rpm *.src.rpm
.PHONY: all clean dist rpm srpm install
all: dist
clean:
rm -rf $(CLEANFILES)
$(BUILDDIR):
mkdir -p $(BUILDDIR)
%.spec: %.spec.in VERSION RELEASE
sed -e 's/@VERSION@/$(VERSION)/g' \
-e 's/@RELEASE@/$(RELEASE)/g' \
$< > $@
src/%: src/%.in VERSION RELEASE
sed -e 's/@VERSION@/$(VERSION)/g' \
$< > $@
docs/%: docs/%.in VERSION RELEASE
sed -e 's/@VERSION@/$(VERSION)/g' \
$< > $@
dist: $(BUILDDIR) $(NAME).spec src/$(NAME) docs/$(NAME).8
mkdir -p $(BUILDDIR)/$(NAME)-$(VERSION)
cp -r $(SOURCES) $(NAME).spec $(BUILDDIR)/$(NAME)-$(VERSION)/
cd $(BUILDDIR) && tar -czf $(NAME)-$(VERSION).tar.gz $(NAME)-$(VERSION)/
cp $(BUILDDIR)/$(NAME)-$(VERSION).tar.gz $(SOURCEDIR)
srpm: dist
rpmbuild --define "_topdir $(PWD)/$(BUILDDIR)" \
--define "_sourcedir $(PWD)" \
--define "_srcrpmdir $(PWD)" \
-bs $(NAME).spec
rpm: dist
rpmbuild --define "_topdir $(PWD)/$(BUILDDIR)" \
--define "_sourcedir $(PWD)" \
--define "_rpmdir $(PWD)" \
--define "_buildrootdir $(PWD)/$(BUILDDIR)" \
-ba $(NAME).spec
install:
install -d $(DESTDIR)/usr/bin
install -d $(DESTDIR)/etc/ksigner
install -d $(DESTDIR)/etc/kernel/postinst.d
install -d $(DESTDIR)/usr/share/man/man8
install -m 755 src/ksigner $(DESTDIR)/usr/bin/
install -m 644 src/ksigner.conf $(DESTDIR)/etc/ksigner/
install -m 755 src/ksigner-update-hook $(DESTDIR)/etc/kernel/postinst.d/zz-ksigner
install -m 644 docs/ksigner.8 $(DESTDIR)/usr/share/man/man8/

171
README.md Normal file
View File

@ -0,0 +1,171 @@
```bash
# Enable/disable automatic signing on kernel updates# Kernel Signer
A secure boot kernel signing utility for Red Hat based systems (RHEL, CentOS, Fedora, Rocky Linux, AlmaLinux, etc.).
## Overview
This package provides a comprehensive solution for signing Linux kernels with custom keys for Secure Boot environments. It includes:
- Automatic key generation and MOK enrollment
- Support for signing individual or all kernels
- Configurable through `/etc/ksigner/ksigner.conf`
- Comprehensive logging and status reporting
## Installation
### Building the RPM
1. Install build dependencies:
```bash
# RHEL/CentOS/Rocky/Alma
sudo dnf install rpm-build rpmdevtools
# Create build environment
rpmdev-setuptree
```
2. Build the package:
```bash
# Create source tarball
make dist
# Build RPM
make rpm
# Or build source RPM
make srpm
```
3. Install the package:
```bash
sudo rpm -ivh ksigner*.rpm
```
### Dependencies
The following packages will be automatically installed as dependencies:
- `openssl` - Key generation and certificate operations
- `mokutil` - Machine Owner Key management
- `sbsigntools` - Kernel signing utilities
- `hmaccalc` - HMAC generation for signed kernels
- `sudo` - Privilege escalation
- `bash` (>= 4.0) - Shell scripting features
## Quick Start
1. **Install the package** (as shown above)
2. **Set up signing keys**:
```bash
sudo ksigner setup
```
3. **Reboot and enroll MOK keys**:
- Reboot your system
- In the MOK management interface: Enroll MOK → Continue → Yes → Enter password → OK
4. **Sign kernels**:
```bash
# Sign latest kernel
sudo ksigner sign
# Sign all kernels
sudo ksigner sign-all
# Check status
sudo ksigner status
```
## Configuration
Edit `/etc/ksigner/ksigner.conf` to customize behavior:
```bash
# Enable/disable automatic signing on kernel updates
SIGN_ON_UPDATE=true
# Type of automatic signing (sign, sign-lts, sign-all, sign-all-lts)
AUTO_SIGN_TYPE="sign-lts"
# Define which kernel versions are considered LTS
LTS_VERSIONS=(
"6.12"
"6.6"
"6.1"
"5.15"
"5.10"
)
```
## Commands
- `ksigner setup` - Create and install signing keys
- `ksigner sign [kernel_file]` - Sign a kernel (latest if no file specified)
- `ksigner sign-lts [kernel_file]` - Sign an LTS kernel
- `ksigner sign-all` - Sign all available kernels
- `ksigner sign-all-lts` - Sign all LTS kernels
- `ksigner status` - Show signing key status
- `ksigner version` - Show version information
## Automatic Kernel Signing
When `SIGN_ON_UPDATE=true` in the configuration, kernels are automatically signed when installed via package manager. The hook script `/etc/kernel/postinst.d/zz-ksigner` handles this process.
Logs are written to `/var/log/ksigner.log`.
## File Locations
- **Configuration**: `/etc/ksigner/ksigner.conf`
- **Public Key**: `/etc/pki/sbsign/certs/MOK.pem`
- **Private Key**: `/etc/pki/sbsign/private/MOK.priv`
- **DER Key**: `/etc/pki/sbsign/certs/MOK.der`
- **Log File**: `/var/log/ksigner.log`
- **Update Hook**: `/etc/kernel/postinst.d/zz-ksigner`
## Security Notes
- Private keys are stored with restrictive permissions (600)
- MOK enrollment requires manual confirmation to prevent unauthorized access
- All operations require root privileges
- HMAC files are generated for integrity verification
## Troubleshooting
### Check Status
```bash
sudo ksigner status
```
### View Logs
```bash
sudo tail -f /var/log/ksigner.log
```
### Verify MOK Enrollment
```bash
sudo mokutil --list-enrolled
```
### Re-enroll Keys
If keys become corrupted or lost:
```bash
sudo ksigner setup
# Then reboot and re-enroll MOK
```
## License
This software is released under the MIT License. See LICENSE file for details.
## Contributing
Contributions are welcome! Please submit pull requests or issues through the project repository.
## Support
For support, please:
1. Check the man page: `man ksigner`
2. Review logs in `/var/log/ksigner.log`
3. Use the status command: `sudo ksigner status`
4. File issues in the project repository

1
RELEASE Normal file
View File

@ -0,0 +1 @@
1

1
VERSION Normal file
View File

@ -0,0 +1 @@
1.0.0

147
docs/ksigner.8.in Normal file
View File

@ -0,0 +1,147 @@
.TH KSIGNER 8 "September 2025" "ksigner @VERSION@" "System Administration"
.SH NAME
ksigner \- Secure Boot kernel signing utility
.SH SYNOPSIS
.B ksigner
.RI { setup | sign | sign-all | version | status }
.RI [ vmlinuz_kernel_filepath ]
.SH DESCRIPTION
.B ksigner
is a utility for signing Linux kernels with custom keys for Secure Boot environments.
It supports signing individual kernels or all available kernels.
.SH COMMANDS
.TP
.B setup
Create and install signing keys. This must be run before any signing operations.
The command generates RSA-4096 keys, converts them to appropriate formats,
installs them in the system directories, and imports them to the Machine Owner Key (MOK) database.
After running this command, you must reboot and enroll the keys through the MOK management interface.
.TP
.B sign
Sign a single kernel file. If no kernel filepath is provided, signs the latest available kernel.
.TP
.B sign-all
Sign all available kernels in /boot that match the pattern vmlinuz-*.
Excludes rescue kernels.
.TP
.B version
Display version information.
.TP
.B status
Show the current status of signing keys and MOK enrollment.
.SH FILES
.TP
.I /etc/ksigner/ksigner.conf
Main configuration file. Contains key paths, automatic signing settings, and LTS version definitions.
.TP
.I /etc/pki/sbsign/certs/MOK.pem
Public signing key in PEM format.
.TP
.I /etc/pki/sbsign/private/MOK.priv
Private signing key.
.TP
.I /etc/pki/sbsign/certs/MOK.der
Public signing key in DER format for MOK import.
.TP
.I /etc/kernel/postinst.d/zz-ksigner
Kernel update hook script for automatic signing.
.TP
.I /var/log/ksigner.log
Log file for automatic signing operations.
.SH CONFIGURATION
The behavior of ksigner can be customized through the configuration file
.IR /etc/ksigner/ksigner.conf .
Key configuration options include:
.TP
.B KEY_LIFETIME_DAYS
Number of days the signing keys should remain valid (default: 36500, approximately 100 years).
.TP
.B SIGN_ON_UPDATE
Enable or disable automatic signing when kernels are updated (default: true).
.TP
.B AUTO_SIGN_TYPE
Type of automatic signing to perform on kernel updates.
Valid options are: sign, sign-all (default: sign).
.SH AUTOMATIC KERNEL SIGNING
When SIGN_ON_UPDATE is enabled in the configuration, new kernels are automatically signed
when they are installed through the package manager. The kernel update hook script
.I /etc/kernel/postinst.d/zz-ksigner
is executed during kernel package installation and performs the configured signing operation.
.SH EXAMPLES
.TP
Set up signing keys for the first time:
.B ksigner setup
.TP
Sign the latest kernel:
.B ksigner sign
.TP
Sign a specific kernel:
.B ksigner sign /boot/vmlinuz-6.1.0-13-amd64
.TP
Sign all kernels:
.B ksigner sign-all
.TP
Check the status of signing keys:
.B ksigner status
.SH REQUIREMENTS
The following packages must be installed for ksigner to function:
.IP \(bu 4
openssl - for key generation and certificate operations
.IP \(bu 4
mokutil - for Machine Owner Key management
.IP \(bu 4
sbsigntools - for signing kernels (provides sbsign command)
.IP \(bu 4
hmaccalc - for generating kernel HMAC files
.IP \(bu 4
sudo - for privilege escalation
.IP \(bu 4
bash (version 4.0 or later) - for shell scripting features
.SH SECURITY CONSIDERATIONS
.IP \(bu 4
Private keys are stored with restrictive permissions (600) in /etc/pki/sbsign/private/
.IP \(bu 4
The setup process requires manual MOK enrollment to prevent unauthorized key installation
.IP \(bu 4
All operations require root privileges
.IP \(bu 4
HMAC files are generated for signed kernels to maintain integrity
.SH EXIT STATUS
.B ksigner
exits with status 0 on success, and non-zero on error.
.SH BUGS
Report bugs to your distribution's bug tracking system or the project repository.
.SH SEE ALSO
.BR mokutil (8),
.BR sbsign (1),
.BR openssl (1),
.BR systemctl (1)

70
ksigner.spec.in Normal file
View File

@ -0,0 +1,70 @@
Name: ksigner
Version: @VERSION@
Release: @RELEASE@%{?dist}
Summary: Secure Boot kernel signing utility
License: MIT
URL: https://git.radon.win/radon/ksigner
Source0: %{name}-%{version}.tar.gz
BuildArch: noarch
Requires: openssl
Requires: mokutil
Requires: sbsigntools
Requires: hmaccalc
Requires: sudo
Requires: bash >= 4.0
%description
A utility for signing Linux kernels with custom keys for Secure Boot.
Supports signing individual kernels or all kernels.
%prep
%setup -q
%build
# Nothing to build - shell script
%install
# Create directories
install -d %{buildroot}%{_bindir}
install -d %{buildroot}%{_sysconfdir}/ksigner
install -d %{buildroot}%{_unitdir}
install -d %{buildroot}%{_sysconfdir}/kernel/postinst.d
install -d %{buildroot}%{_mandir}/man8
# Install main script
install -m 755 ksigner %{buildroot}%{_bindir}/ksigner
# Install configuration file
install -m 644 ksigner.conf %{buildroot}%{_sysconfdir}/ksigner/ksigner.conf
# Install kernel update hook
install -m 755 ksigner-update-hook %{buildroot}%{_sysconfdir}/kernel/postinst.d/zz-ksigner
# Install man page
install -m 644 ksigner.8 %{buildroot}%{_mandir}/man8/ksigner.8
%post
echo "==========================================="
echo "Kernel Signer has been installed."
echo "To set up kernel signing:"
echo " 1. Run: sudo ksigner setup"
echo " 2. Reboot your system"
echo " 3. In MOK Manager: Enroll MOK Continue Yes Enter password"
echo "==========================================="
%files
%license LICENSE
%doc README.md
%{_bindir}/ksigner
%config(noreplace) %{_sysconfdir}/ksigner/ksigner.conf
%{_sysconfdir}/kernel/postinst.d/zz-ksigner
%{_mandir}/man8/ksigner.8*
%changelog
* Tue Sep 23 2025 RadioactivePb <radioactivepb@gmail.com> - @VERSION@-@RELEASE@
- Initial RPM release
- Added automatic kernel signing on updates
- Added configuration file support

67
src/ksigner-update-hook Normal file
View File

@ -0,0 +1,67 @@
#!/usr/bin/env bash
# Kernel update hook for automatic signing
# This script is called when new kernels are installed
CONFIG_FILE="/etc/ksigner/ksigner.conf"
KERNEL_SIGNER="/usr/bin/ksigner"
LOG_FILE="/var/log/ksigner.log"
# Source configuration
if [[ -f "$CONFIG_FILE" ]]; then
source "$CONFIG_FILE"
fi
# Default values
SIGN_ON_UPDATE=${SIGN_ON_UPDATE:-true}
AUTO_SIGN_TYPE=${AUTO_SIGN_TYPE:-sign}
LOG_FILE=${LOG_FILE:-/var/log/ksigner.log}
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - ksigner-update-hook: $1" >>"$LOG_FILE"
}
# Exit if automatic signing is disabled
if [[ "$SIGN_ON_UPDATE" != "true" ]]; then
log_message "Automatic signing disabled, skipping"
exit 0
fi
# Check if ksigner exists and keys are set up
if [[ ! -x "$KERNEL_SIGNER" ]]; then
log_message "ksigner not found at $KERNEL_SIGNER"
exit 1
fi
if [[ ! -f "/etc/pki/sbsign/certs/MOK.pem" ]]; then
log_message "Signing keys not found, run 'ksigner setup' first"
exit 1
fi
# Get the kernel version from the environment or find the latest
if [[ -n "$KERNEL_VERSION" ]]; then
KERNEL_FILE="/boot/vmlinuz-$KERNEL_VERSION"
if [[ -f "$KERNEL_FILE" ]]; then
log_message "Signing newly installed kernel: $KERNEL_VERSION"
if "$KERNEL_SIGNER" sign "$KERNEL_FILE" >>"$LOG_FILE" 2>&1; then
log_message "Successfully signed kernel $KERNEL_VERSION"
else
log_message "Failed to sign kernel $KERNEL_VERSION"
exit 1
fi
else
log_message "Kernel file not found: $KERNEL_FILE"
exit 1
fi
else
# Fallback to configured auto-sign type
log_message "Running automatic signing: $AUTO_SIGN_TYPE"
if "$KERNEL_SIGNER" "$AUTO_SIGN_TYPE" >>"$LOG_FILE" 2>&1; then
log_message "Successfully completed $AUTO_SIGN_TYPE"
else
log_message "Failed to complete $AUTO_SIGN_TYPE"
exit 1
fi
fi
exit 0

25
src/ksigner.conf Normal file
View File

@ -0,0 +1,25 @@
# Configuration file for ksigner
# This file is sourced by the ksigner script
# Key lifetime in days (default: 100 years)
KEY_LIFETIME_DAYS=$((365 * 100))
# Directory paths for keys
KEY_PUB_DIR="/etc/pki/sbsign/certs/"
KEY_PRIV_DIR="/etc/pki/sbsign/private/"
# Key filenames
KEY_PUB="MOK.pem"
KEY_PRIV="MOK.priv"
KEY_DER="MOK.der"
# Automatic signing on kernel updates
# Set to true to enable automatic signing when kernels are updated
SIGN_ON_UPDATE=true
# Type of automatic signing to perform
# Options: sign, sign-all
AUTO_SIGN_TYPE="sign"
# Log file for automatic signing operations
LOG_FILE="/var/log/ksigner.log"

276
src/ksigner.in Normal file
View File

@ -0,0 +1,276 @@
#!/usr/bin/env bash
# ksigner - Secure Boot kernel signing utility
# Version: @VERSION@
# Source configuration
CONFIG_FILE="/etc/ksigner/ksigner.conf"
if [[ -f "$CONFIG_FILE" ]]; then
source "$CONFIG_FILE"
fi
# Default configuration values (can be overridden in config file)
KEY_LIFETIME_DAYS=${KEY_LIFETIME_DAYS:-$((365 * 100))}
KEY_PUB_DIR=${KEY_PUB_DIR:-/etc/pki/sbsign/certs/}
KEY_PUB=${KEY_PUB:-MOK.pem}
KEY_PRIV_DIR=${KEY_PRIV_DIR:-/etc/pki/sbsign/private/}
KEY_PRIV=${KEY_PRIV:-MOK.priv}
KEY_DER=${KEY_DER:-MOK.der}
SIGN_ON_UPDATE=${SIGN_ON_UPDATE:-true}
AUTO_SIGN_TYPE=${AUTO_SIGN_TYPE:-sign}
REQUIRED_BINARIES=(
"openssl"
"mokutil"
"sbsign"
"sha512hmac"
)
panic() {
echo "ERROR: $1" >&2
exit 1
}
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >&2
}
usage() {
echo "Usage: $0 {setup|sign|sign-all|version|status} [vmlinuz_kernel_filepath]"
echo " setup - Create and install signing keys"
echo " sign - Sign a kernel file (optional: vmlinuz_kernel_filepath)"
echo " sign-all - Sign all available kernels"
echo " version - Show version information"
echo " status - Show signing key status"
exit 1
}
version() {
echo "ksigner version @VERSION@"
echo "Copyright (C) 2025"
echo "This is free software; see the source for copying conditions."
}
status() {
echo "Kernel Signer Status:"
echo "====================="
echo "Public key file: $KEY_PUB_DIR$KEY_PUB"
if [[ -f "$KEY_PUB_DIR$KEY_PUB" ]]; then
echo " Status: Found"
echo " Details:"
openssl x509 -in "$KEY_PUB_DIR$KEY_PUB" -noout -subject -dates 2>/dev/null || echo " Error reading certificate"
else
echo " Status: Not found"
fi
echo "Private key file: $KEY_PRIV_DIR$KEY_PRIV"
[[ -f "$KEY_PRIV_DIR$KEY_PRIV" ]] && echo " Status: Found" || echo " Status: Not found"
echo "DER key file: $KEY_PUB_DIR$KEY_DER"
[[ -f "$KEY_PUB_DIR$KEY_DER" ]] && echo " Status: Found" || echo " Status: Not found"
echo "MOK keys enrolled:"
mokutil --list-enrolled 2>/dev/null | grep -A 3 -B 1 "Kernel Signing" || echo " No custom MOK keys found"
echo "Configuration file: $CONFIG_FILE"
[[ -f "$CONFIG_FILE" ]] && echo " Status: Found" || echo " Status: Using defaults"
}
req_check() {
local missing_binaries=()
for binary in "${REQUIRED_BINARIES[@]}"; do
if ! command -v "$binary" >/dev/null 2>&1; then
missing_binaries+=("$binary")
fi
done
if [[ ${#missing_binaries[@]} -gt 0 ]]; then
echo "Missing required binaries: ${missing_binaries[*]}" >&2
echo "Please install the following packages:" >&2
for binary in "${missing_binaries[@]}"; do
case "$binary" in
"openssl") echo " - openssl" >&2 ;;
"mokutil") echo " - mokutil" >&2 ;;
"sbsign") echo " - sbsigntools" >&2 ;;
"sha512hmac") echo " - hmaccalc" >&2 ;;
esac
done
exit 1
fi
log "All required binaries are present"
}
version_greater() {
local ver1="$1"
local ver2="$2"
[ "$ver1" = "$(printf '%s\n%s' "$ver1" "$ver2" | sort -V | tail -n1)" ]
}
find_all_kernels() {
local all_files=()
for file in /boot/vmlinuz-*; do
[ -f "$file" ] || continue
if [[ "$file" == *"rescue"* ]]; then
continue
fi
all_files+=("$file")
done
echo "${all_files[@]}"
}
find_latest_kernel() {
local latest_file=""
local latest_version=""
for file in /boot/vmlinuz-*; do
[ -f "$file" ] || continue
if [[ "$file" == *"rescue"* ]]; then
continue
fi
local kver="${file#*vmlinuz-}"
kver="${kver%%-*}"
if [ -z "$latest_version" ] || version_greater "$kver" "$latest_version"; then
latest_version="$kver"
latest_file="$file"
fi
done
echo "$latest_file"
}
setup_signing_keys() {
# Step 1: Create the signing keys
log "[Step 1] Creating signing keys..."
openssl req -new -x509 -newkey rsa:4096 \
-keyout $KEY_PRIV \
-outform DER -out $KEY_DER \
-nodes -days $KEY_LIFETIME_DAYS -subj "/CN=Kernel Signing/" ||
panic "[Step 1] Failed to create signing keys"
# Step 2: Convert the keys to PEM format
log "[Step 2] Converting keys to PEM format..."
openssl x509 -inform der -in $KEY_DER -out $KEY_PUB ||
panic "[Step 2] Failed to convert keys to PEM format"
# Step 3: Create the directory for the keys
log "[Step 3] Creating the directory for the keys..."
mkdir -p $KEY_PUB_DIR $KEY_PRIV_DIR ||
panic "[Step 3] Failed to create the directory for the keys"
# Step 4: Copy the keys to the directory
log "[Step 4] Copying the keys to the directory..."
mv -f $KEY_DER $KEY_PUB $KEY_PUB_DIR ||
panic "[Step 4a] Failed to copy the keys to the directory"
mv -f $KEY_PRIV $KEY_PRIV_DIR ||
panic "[Step 4b] Failed to copy the keys to the directory"
# Step 5: Set the permissions for the keys
log "[Step 5] Setting the permissions for the keys..."
chmod -R 600 $KEY_PRIV_DIR ||
panic "[Step 5] Failed to set the permissions for the keys"
# Step 6: Import the keys to the MOK
log "[Step 6] Importing the keys to the MOK..."
mokutil --import $KEY_PUB_DIR$KEY_DER ||
panic "[Step 6] Failed to import the keys to the MOK"
echo
log "Signing keys have been created and installed"
echo
echo "Please reboot your computer and enroll the keys with MOK"
echo
echo "Enroll MOK -> Continue -> Yes -> Enter password -> OK"
echo
}
sign_kernel() {
local kern_version="$1"
local kern_file="$2"
# Step 1: Sign the kernel
log "[Step 1] Signing '$kern_version'..."
/usr/bin/sbsign \
--key "$KEY_PRIV_DIR$KEY_PRIV" \
--cert "$KEY_PUB_DIR$KEY_PUB" \
"$kern_file" \
--output "$kern_file.signed" ||
panic "[Step 1] Failed to sign '$kern_version'"
# Step 2: Verify the kernel was signed
log "[Step 2] Verifying '$kern_file' was signed"
[ -f "$kern_file.signed" ] ||
panic "'$kern_file.signed' was not found"
# Step 3: Move the signed kernel
log "[Step 3] Moving '$kern_file.signed' to '$kern_file'"
mv -f "$kern_file.signed" "$kern_file" ||
panic "Failed to move '$kern_file.signed'"
# Step 4: Make the kernel executable
log "[Step 4] Setting permissions for '$kern_file'"
chmod +x "$kern_file" ||
panic "Failed to make '$kern_file' executable"
# Step 5: Create the HMAC
log "[Step 5] Creating HMAC for '$kern_file'"
sha512hmac "$kern_file" >"${kern_file/vmlinuz/.vmlinuz}.hmac" ||
panic "Failed to create HMAC for '$kern_file'"
echo
log "Signed '$kern_version' successfully"
echo
}
file_checks() {
local kfile="$1"
[ -e "$kfile" ] ||
panic "Kernel file '$kfile' was not found"
[ -e "$KEY_PUB_DIR$KEY_PUB" ] ||
panic "'$KEY_PUB_DIR$KEY_PUB' was not found, please run 'setup' first"
[ -e "$KEY_PRIV_DIR$KEY_PRIV" ] ||
panic "'$KEY_PRIV_DIR$KEY_PRIV' was not found, please run 'setup' first"
}
main() {
case "$1" in
"setup")
req_check
setup_signing_keys
;;
"sign")
req_check
shift
[ -n "$1" ] &&
kfile="$1" ||
kfile="$(find_latest_kernel)"
kver="${kfile#*vmlinuz-}"
kver="${kver%%-*}"
file_checks "$kfile"
sign_kernel "$kver" "$kfile"
;;
"sign-all")
req_check
all_kernels_str=$(find_all_kernels)
read -ra all_kernels <<<"$all_kernels_str"
for kfile in "${all_kernels[@]}"; do
[ -n "$kfile" ] || continue
kver="${kfile#*vmlinuz-}"
kver="${kver%%-*}"
file_checks "$kfile"
sign_kernel "$kver" "$kfile"
done
;;
"version")
version
;;
"status")
status
;;
*)
usage
;;
esac
}
# Ensure running as root
[[ $EUID -eq 0 ]] || exec sudo "$0" "$@"
main "$@"