-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcreate-databases.sh
More file actions
executable file
·163 lines (143 loc) · 6.43 KB
/
create-databases.sh
File metadata and controls
executable file
·163 lines (143 loc) · 6.43 KB
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/usr/bin/env bash
# Generates the new secure boot databases suitable for importing into firmware.
# Does this by combining certs and signing as necessary.
# This script will write its output to the 'final' folder.
# Exit on error.
set -e
# Expand PATH to contain efitools prebuilts.
export PATH="$PATH:$(readlink -f "$(dirname "$0")")/efitools/extracted/bin"
# Do not run if there is an existing 'final' or 'finalwork' directory.
if test -e final; then
echo "Remove the existing 'final' directory before running this." >&2
exit 1
fi
if test -e finalwork; then
echo "Remove the existing 'finalwork' directory before running this." >&2
exit 1
fi
# Do not run if mykeys do not exist.
if test ! -e mykeys/private/PK.key || test ! -e mykeys/private/KEK.key || test ! -e mykeys/private/db.key || test ! -e mykeys/public/PK.crt || test ! -e mykeys/public/KEK.crt || test ! -e mykeys/public/db.crt; then
echo "Your PK, KEK and db keys/certs must be in the 'mykeys' directory." >&2
echo "Run 'generate-keys.sh' if you need to generate them." >&2
echo "If you already have keys, see README.md for the directory layout." >&2
exit 1
fi
# Require efitools to be installed.
if ! command -v cert-to-efi-sig-list &>/dev/null || ! command -v sign-efi-sig-list &>/dev/null; then
echo "This script requires the utilities from the 'efitools' package." >&2
echo "You can run the following command to setup prebuilt efitools:" >&2
echo >&2
echo " ./efitools/efitools-prebuilt.sh" >&2
echo >&2
echo "Then re-run $(basename "$0"). It will auto-find the prebuilts." >&2
exit 1
fi
# Determine how we can best generate UUIDs.
if uuidgen &>/dev/null; then
# uuidgen utility from util-linux.
_uuidgen="uuidgen"
elif cat /proc/sys/kernel/random/uuid &>/dev/null; then
# Inbuilt kernel generator (requires /proc to be mounted).
_uuidgen="cat /proc/sys/kernel/random/uuid"
elif python3 -m uuid; then
# The uuid module from Python 3.
_uuidgen="python3 -m uuid"
else
# No suitable UUID generator found.
echo "No suitable UUID generation method was found." >&2
echo "Please install uuidgen, OR mount /proc, OR install Python 3." >&2
exit 1
fi
echo "NOTE: UUIDs will be generated using '$_uuidgen'."
# Set up array to list additional certs that should be included.
extrakeks=()
extradbs=()
# Only include additional certs if the directory exists.
if test -d extracerts/kek; then
while read -r line; do
echo "NOTE: Including extra KEK certificate '${line/extracerts\/kek\//}'."
extrakeks+=("$line")
done < <(find extracerts/kek -type f -name \*.crt | sort -u)
fi
if test -d extracerts/db; then
while read -r line; do
echo "NOTE: Including extra db certificate '${line/extracerts\/db\//}'."
extradbs+=("$line")
done < <(find extracerts/db -type f -name \*.crt | sort -u)
fi
# Show a notice if no additional KEK or db certificates are used.
if test -z "${extrakeks[0]}"; then
echo "WARNING: Not including any additional KEK certificates." >&2
fi
if test -z "${extradbs[0]}"; then
# Sorry for the EXTREMELY naggy warning message, but we need it.
echo "WARNING: Not including any additional db certificates." >&2
echo "WARNING:" >&2
echo "WARNING: You may NOT be able to boot Windows nor MS-signed Linux." >&2
echo "WARNING: If this was unintentional, press Control+C IMMEDIATELY." >&2
echo "WARNING: And set up extracerts before proceeding any further." >&2
echo "WARNING:" >&2
echo "WARNING: For the simplest usage, just run the following command:" >&2
echo "WARNING:" >&2
echo "WARNING: cp -rv extracerts.DEFAULT/{db,kek} extracerts/" >&2
echo "WARNING:" >&2
echo "WARNING: Re-run $(basename "$0") (this script) after doing so." >&2
echo "WARNING: This warning message will then no longer appear." >&2
echo "WARNING:" >&2
echo "WARNING: See README.md for full details on how to customize." >&2
echo "WARNING: Otherwise this script will continue in 30 seconds." >&2
sleep 30
fi
# Use owner GUID from file, or randomly generate if missing.
if test -r mykeys/owner.guid; then
ownerguid="$(cat mykeys/owner.guid)"
echo "NOTE: Using previously-generated owner GUID ($ownerguid) for mykeys."
else
ownerguid="$($_uuidgen)"
echo "NOTE: No owner GUID found for mykeys, using random one ($ownerguid)."
echo "NOTE: You can save it with 'echo $ownerguid > mykeys/owner.guid'."
fi
# Create directories we need.
mkdir -p finalwork/{esl/{split/{KEK,db},combined},auth}
# Create combined ESL for PK (as there is only one PK certificate).
cert-to-efi-sig-list -g "$ownerguid" mykeys/public/PK.crt finalwork/esl/combined/PK.esl
# Create split ESLs for each KEK and DB.
cert-to-efi-sig-list -g "$ownerguid" mykeys/public/KEK.crt finalwork/esl/split/KEK/0000_KEK.esl
for c in "${extrakeks[@]}"; do
# Use pre-defined GUID, or randomly generate if missing.
if test -e "$c".guid; then
g="$(cat "$c".guid)"
else
echo "NOTE: $c does not have an existing GUID, will randomly generate one."
g="$($_uuidgen)"
fi
o="$(echo "$c" | sed -e 's|^extracerts/kek/||' -e 's|.crt$||' -e 's|/|_|g')"
cert-to-efi-sig-list -g "$g" "$c" finalwork/esl/split/KEK/"$o".esl
done
cert-to-efi-sig-list -g "$ownerguid" mykeys/public/db.crt finalwork/esl/split/db/0000_db.esl
for c in "${extradbs[@]}"; do
# Use pre-defined GUID, or randomly generate if missing.
if test -e "$c".guid; then
g="$(cat "$c".guid)"
else
echo "NOTE: $c does not have an existing GUID, will randomly generate one."
g="$($_uuidgen)"
fi
o="$(echo "$c" | sed -e 's|^extracerts/db/||' -e 's|.crt$||' -e 's|/|_|g')"
cert-to-efi-sig-list -g "$g" "$c" finalwork/esl/split/db/"$o".esl
done
# Merge ESLs.
cat finalwork/esl/split/KEK/*.esl > finalwork/esl/combined/KEK.esl
cat finalwork/esl/split/db/*.esl > finalwork/esl/combined/db.esl
# PK is signed by itself, KEK is signed by PK, db is signed by KEK.
sign-efi-sig-list -k mykeys/private/PK.key -c mykeys/public/PK.crt PK finalwork/{esl/combined/PK.esl,auth/PK.auth}
sign-efi-sig-list -k mykeys/private/PK.key -c mykeys/public/PK.crt KEK finalwork/{esl/combined/KEK.esl,auth/KEK.auth}
sign-efi-sig-list -k mykeys/private/KEK.key -c mykeys/public/KEK.crt db finalwork/{esl/combined/db.esl,auth/db.auth}
# Move final produced assets into 'final' directory.
mkdir -p final
cp finalwork/auth/* final/
# Clean up finalwork directory.
rm -rf finalwork
echo "The new final secure boot databases were placed in 'final/'."
echo "You can now run 'import-to-firmware.sh' to proceed."
echo "However you must be booted in setup mode - see README.md for info."