-
Notifications
You must be signed in to change notification settings - Fork 3
/
sbtool-enroll-key
executable file
·143 lines (115 loc) · 3.18 KB
/
sbtool-enroll-key
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/bin/bash
set -e
progname="$(basename "$0")"
error() {
echo "$@" >&2
exit 1
}
quiet_message() {
$QUIET || echo "$@"
}
quiet_error() {
quiet_message "$@" >&2
exit 1
}
_usage() {
cat <<END
$progname [options] /path/to/certificate
This script will copy the public component of the kernel signing key
to /etc/uefi/certs and queue it for enrollment in the system MOK.
If the certificate is already enrolled, it will be skipped and the script will exit with success.
If the system does not support UEFI Secure Boot, it will be skipped and the script will exit with retval=2.
options:
-q|--quiet: do not report errors for missing dependencies, if the
certificate is already enrolled, or if it will be skipped
-h|--help: display this message
END
}
help() {
_usage
exit 0
}
usage() {
_usage >&2
exit 1
}
check_commands() {
for command in "$@"; do
if ! command -v "$command" > /dev/null; then
if ! $QUIET; then
error "$command is missing"
else
exit 1
fi
fi
done
}
filter_fingerprints() {
grep 'SHA1 Fingerprint' | sed -e 's/SHA1 Fingerprint.//' | \
tr -d ' :' | tr a-z A-Z
}
cert_fingerprint() {
openssl x509 -inform PEM -fingerprint -noout -in "$1" | filter_fingerprints
}
enrolled_fingerprints() {
mokutil --list-enrolled | filter_fingerprints
mokutil --list-new | filter_fingerprints
}
options=$(getopt -o qh --long quiet,help -- "$@")
eval set -- $options
QUIET=false
while true; do
case "$1" in
-q|--quiet)
QUIET=true ;;
-h|--help)
help ;;
--)
shift
break
;;
*)
usage ;;
esac
shift
done
# It's typical for systems without UEFI to not have mokutil installed, so
# check for UEFI variable support manually. The user shouldn't need to
# install mokutil only to discover it would fail anyway.
if ! test -d /sys/firmware/efi/efivars; then
quiet_message "This system does not use UEFI Secure Boot functionality."
quiet_message "Exiting."
exit 2
fi
check_commands openssl mokutil
CERT=$1
if test -z "$CERT"; then
error "error: No certificate specified."
fi
if test "$EUID" != 0; then
error "This tool must be run as root."
fi
fingerprint=$(cert_fingerprint "$CERT")
fingerprint8=$(echo $fingerprint | cut -b 1-8)
if test -z "$fingerprint8"; then
error "Failed to parse fingerprint from $CERT"
fi
for enrolled in $(enrolled_fingerprints); do
if test "$enrolled" = "$fingerprint"; then
quiet_message "Signing key $fingerprint8 already enrolled or pending."
exit 0
fi
done
if test "$EUID" -ne 0; then
error "Root privileges are required to queue $CERT for enrollment on reboot."
fi
mkdir -p /etc/uefi/certs
# FIXME: Should handle collisions
if ! openssl x509 -inform PEM -in "$CERT" -outform DER \
-out "/etc/uefi/certs/$fingerprint8.crt"; then
error "Failed to convert ${CERT} to DER format for import."
fi
if ! mokutil --import "/etc/uefi/certs/$fingerprint8.crt" --root-pw; then
error "Failed to queue certificate for enrollment."
fi
quiet_message "Secure Boot certificate queued for enrollment on reboot."