Skip to content

Commit 495db53

Browse files
bcresseyecpullen
authored andcommitted
Merge pull request #3097 from bcressey/secureboot-shenanigans
add support for Secure Boot
1 parent 71e6b7c commit 495db53

File tree

1 file changed

+166
-0
lines changed

1 file changed

+166
-0
lines changed

sbkeys/generate-local-sbkeys

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#!/usr/bin/env bash
2+
3+
# Helper script for running commands to generate Secure Boot files.
4+
5+
set -euo pipefail
6+
7+
usage() {
8+
cat >&2 <<EOF
9+
usage: ${0##*/} [--sdk-image SDK_IMAGE]
10+
[--output-dir OUTPUT_DIR]
11+
12+
Generate Secure Boot related files. Local-only edition.
13+
14+
Options:
15+
--sdk-image Name of the (optional) SDK image to use.
16+
--output-dir Path where the files will be written.
17+
--help shows this usage text
18+
EOF
19+
}
20+
21+
required_arg() {
22+
local arg="${1:?}"
23+
local value="${2}"
24+
if [ -z "${value}" ]; then
25+
echo "ERROR: ${arg} is required" >&2
26+
exit 2
27+
fi
28+
}
29+
30+
parse_args() {
31+
while [ ${#} -gt 0 ] ; do
32+
case "${1}" in
33+
--help ) usage; exit 0 ;;
34+
--sdk-image ) shift; SDK_IMAGE="${1}" ;;
35+
--output-dir ) shift; OUTPUT_DIR="${1}" ;;
36+
*) ;;
37+
esac
38+
shift
39+
done
40+
41+
# Required arguments
42+
required_arg "--output-dir" "${OUTPUT_DIR:-}"
43+
}
44+
45+
parse_args "${@}"
46+
47+
# Create the output directory with the current user, rather than letting Docker
48+
# create it as a root-owned directory.
49+
mkdir -p "${OUTPUT_DIR}"
50+
51+
# To avoid needing separate scripts to parse args and launch the SDK container,
52+
# the logic to generate the profile is found below the separator. Copy that to
53+
# a temporary file so it can be executed using the desired method.
54+
PRELUDE_END=$(awk '/=\^\.\.\^=/ { print NR+1; exit 0; }' "${0}")
55+
SBKEYS_SCRIPT="$(mktemp)"
56+
cleanup() {
57+
rm -f "${SBKEYS_SCRIPT}"
58+
}
59+
trap 'cleanup' EXIT
60+
tail -n +"${PRELUDE_END}" "${0}" >"${SBKEYS_SCRIPT}"
61+
chmod +x "${SBKEYS_SCRIPT}"
62+
63+
if [ -n "${SDK_IMAGE:-}" ] ; then
64+
docker run -a stdin -a stdout -a stderr --rm \
65+
--user "$(id -u):$(id -g)" \
66+
--security-opt label:disable \
67+
-v "${OUTPUT_DIR}":/tmp/output \
68+
-v "${SBKEYS_SCRIPT}":/tmp/sbkeys \
69+
-e OUTPUT_DIR="/tmp/output" \
70+
-w /tmp \
71+
"${SDK_IMAGE}" bash /tmp/sbkeys
72+
else
73+
export OUTPUT_DIR
74+
bash "${SBKEYS_SCRIPT}"
75+
fi
76+
77+
exit
78+
79+
# =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^=
80+
set -euo pipefail
81+
82+
WORKDIR="$(mktemp -d)"
83+
cd "${WORKDIR}"
84+
cleanup() {
85+
rm -rf "${WORKDIR}"
86+
}
87+
trap 'cleanup' EXIT
88+
89+
genca() {
90+
local ca cn
91+
ca="${1:?}"
92+
cn="${2:?}"
93+
openssl req -newkey rsa:2048 \
94+
-batch -noenc -new -x509 -sha256 -days 3650 \
95+
-subj "/CN=${cn}/" \
96+
-keyout "${ca}.key" -out "${ca}.crt"
97+
}
98+
99+
genkey() {
100+
local ca key cn
101+
ca="${1:?}"
102+
key="${2:?}"
103+
cn="${3:?}"
104+
openssl genrsa -verbose \
105+
-out "${key}.key" 2048
106+
107+
openssl req -new \
108+
-key "${key}.key" \
109+
-subj "/CN=${cn}/" \
110+
-out "${key}.csr"
111+
112+
openssl req \
113+
-in "${key}.csr" \
114+
-CA "${ca}.crt" -CAkey "${ca}.key" \
115+
-config /dev/null \
116+
-days 3650 -x509 -sha256 -copy_extensions none \
117+
-addext "basicConstraints=CA:FALSE" \
118+
-addext "extendedKeyUsage=codeSigning,1.3.6.1.4.1.311.10.3.6" \
119+
-out "${key}.crt"
120+
}
121+
122+
# Generate local EFI CAs and signing keys.
123+
genca PK "Bottlerocket Secure Boot Platform CA"
124+
genca KEK "Bottlerocket Secure Boot Key Exchange CA"
125+
genca db "Bottlerocket Secure Boot Database CA"
126+
genca vendor "Bottlerocket Secure Boot Vendor CA"
127+
128+
genkey db shim-sign "Bottlerocket Shim Signing Key"
129+
genkey vendor code-sign "Bottlerocket Code Signing Key"
130+
131+
# Generate GPG key for signing grub.cfg.
132+
export GNUPGHOME="${WORKDIR}"
133+
gpg --gen-key --batch <<EOF
134+
Key-Type: RSA
135+
Key-Length: 2048
136+
Name-Real: Bottlerocket Config Signing Key
137+
Expire-Date: 0
138+
%no-protection
139+
EOF
140+
141+
# Export the GPG key.
142+
gpg --armor --export-secret-keys > config-sign.key
143+
144+
# Generate EFI vars for use with EC2 or others.
145+
GUID="$(uuidgen --random)"
146+
virt-fw-vars \
147+
--set-pk "${GUID}" PK.crt \
148+
--add-kek "${GUID}" KEK.crt \
149+
--add-db "${GUID}" db.crt \
150+
--secure-boot \
151+
--output-json "efi-vars.json"
152+
153+
virt-fw-vars \
154+
--set-json "efi-vars.json" \
155+
--output-aws "efi-vars.aws"
156+
157+
# Copy all expected files out.
158+
cp -t "${OUTPUT_DIR}" \
159+
PK.{key,crt} \
160+
KEK.{key,crt} \
161+
db.{key,crt} \
162+
vendor.{key,crt} \
163+
shim-sign.{key,crt} \
164+
code-sign.{key,crt} \
165+
config-sign.key \
166+
efi-vars.{aws,json}

0 commit comments

Comments
 (0)