]>
Commit | Line | Data |
---|---|---|
7cdc7ea4 | 1 | #!/usr/bin/env bash |
b291eb83 | 2 | #set -x |
7cdc7ea4 SB |
3 | |
4 | # For the license, see the LICENSE file in the root directory. | |
5 | ||
6 | if [ "$(id -u)" -ne 0 ]; then | |
7 | echo "Need to be root to run this test." | |
8 | exit 77 | |
9 | fi | |
10 | ||
11 | # tpmtool is not packaged everywhere ... | |
12 | if [ -z "$(type -P tpmtool)" ]; then | |
13 | echo "Could not find tpmtool in PATH" | |
14 | exit 77 | |
15 | fi | |
16 | ||
17 | ROOT=${abs_top_builddir:-$(dirname "$0")/..} | |
18 | TESTDIR=${abs_top_testdir:=$(dirname "$0")} | |
19 | SRCDIR=${abs_top_srcdir:-$(dirname "$0")/..} | |
20 | ||
cc410ca9 SB |
21 | PATH=$ROOT/src/swtpm:$PATH |
22 | ||
23 | source ${abs_top_builddir:-$(dirname "$0")/..}/tests/test_config | |
24 | ||
7cdc7ea4 SB |
25 | SWTPM_SETUP=${ROOT}/src/swtpm_setup/swtpm_setup |
26 | SWTPM_CREATE_TPMCA=${SRCDIR}/samples/swtpm-create-tpmca | |
9591808d | 27 | SWTPM_LOCALCA=${ROOT}/samples/swtpm-localca |
7cdc7ea4 SB |
28 | SWTPM=${ROOT}/src/swtpm/swtpm |
29 | SWTPM_IOCTL=${ROOT}/src/swtpm_ioctl/swtpm_ioctl | |
30 | ||
31 | SWTPM_INTERFACE=socket+socket | |
32 | SWTPM_SERVER_NAME=localhost | |
33 | SWTPM_SERVER_PORT=65434 | |
34 | SWTPM_CTRL_PORT=65435 | |
35 | ||
36 | TCSD_LISTEN_PORT=65436 | |
37 | ||
38 | SRK_PASSWORD=srk | |
39 | OWNER_PASSWORD=owner | |
40 | ||
41 | workdir=$(mktemp -d) | |
42 | ||
43 | TCSD_CONF=${workdir}/tcsd.conf | |
44 | TCSD_SYSTEM_PS_FILE=${workdir}/system_ps_file | |
45 | TCSD_PIDFILE=${workdir}/tcsd.pid | |
b291eb83 SB |
46 | SWTPM_LOCALCA_DIR="${workdir}/my localca" |
47 | SWTPM_LOCALCA_CONF="${workdir}/my localca/swtpm-localca.conf" | |
7cdc7ea4 | 48 | |
cc410ca9 SB |
49 | # Captured TCSD file when using a SRK_PASSWORD=srk |
50 | TCSD_FILE="AQEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAABLwEAAAAAAwAAAAAAAAAAAAAA | |
51 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | |
52 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | |
53 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | |
54 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | |
55 | AAAAAAAAAAAAAAAAAAAAAAAAAQEAAAARAAAAAAEAAAABAAMAAQAAAAwAAAgAAAAAAgAAAAAAAAAA | |
56 | AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | |
57 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | |
58 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | |
59 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | |
60 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" | |
61 | ||
7cdc7ea4 SB |
62 | function cleanup() |
63 | { | |
64 | if [ -n "${TCSD_PID}" ]; then | |
65 | kill_quiet -15 ${TCSD_PID} | |
66 | fi | |
67 | if [ -n "${SWTPM_PID}" ]; then | |
68 | kill_quiet -9 ${SWTPM_PID} | |
69 | fi | |
70 | if [ -n "${BASH_PID}" ]; then | |
71 | kill_quiet -9 ${BASH_PID} | |
72 | fi | |
b291eb83 | 73 | rm -rf "${workdir}" |
7cdc7ea4 SB |
74 | } |
75 | ||
76 | trap "cleanup" SIGTERM EXIT | |
77 | source ${TESTDIR}/common | |
78 | ||
4bd99ad9 | 79 | PATH=${ROOT}/src/swtpm_bios:${ROOT}/src/swtpm_cert:${PATH} |
a0e7fbc0 SB |
80 | |
81 | # run the test with the given owner and SRK passwords | |
4bd99ad9 SB |
82 | # @param1: owner password; empty means to use well known password |
83 | # @param2: SRK password; empty means to use well known password | |
84 | # @param3: vTPM is a TPM 2.0 | |
a0e7fbc0 SB |
85 | function run_test() { |
86 | local owner_password="$1" | |
87 | local srk_password="$2" | |
b291eb83 | 88 | local vtpm_is_tpm2="$3" |
4bd99ad9 SB |
89 | |
90 | local params certinfo regex regexs fil i skip | |
91 | ||
b291eb83 | 92 | rm -rf "${workdir}"/* |
a0e7fbc0 | 93 | |
b291eb83 | 94 | cat <<_EOF_ > "${workdir}/swtpm_setup.conf" |
7cdc7ea4 SB |
95 | create_certs_tool=${SWTPM_LOCALCA} |
96 | create_certs_tool_config=${workdir}/swtpm-localca.conf | |
a18cf085 | 97 | create_certs_tool_options=/dev/null |
7cdc7ea4 SB |
98 | _EOF_ |
99 | ||
4bd99ad9 SB |
100 | params="" |
101 | if [ -n "${owner_password}" ]; then | |
102 | params="${params} --ownerpass ${owner_password}" | |
103 | else | |
104 | params="${params} --owner-well-known" | |
105 | fi | |
cc410ca9 | 106 | params="${params} --srkpass ${srk_password}" |
4bd99ad9 | 107 | |
a0e7fbc0 SB |
108 | # First setup the TPM and take ownership of it and set SRK password |
109 | $SWTPM_SETUP \ | |
110 | --runas root \ | |
b291eb83 SB |
111 | --tpm-state "${workdir}" \ |
112 | --logfile "${workdir}/logfile" \ | |
113 | --config "${workdir}/swtpm_setup.conf" \ | |
930c7ba1 | 114 | --tpm "${SWTPM_EXE} socket ${SWTPM_TEST_SECCOMP_OPT}" \ |
a0e7fbc0 | 115 | --take-ownership \ |
cc410ca9 | 116 | ${params} >/dev/null |
a0e7fbc0 SB |
117 | |
118 | if [ $? -ne 0 ]; then | |
119 | echo "Error: Could not run $SWTPM_SETUP." | |
120 | echo "Setup Logfile:" | |
121 | cat ${workdir}/logfile | |
122 | exit 1 | |
123 | fi | |
7cdc7ea4 | 124 | |
a0e7fbc0 | 125 | echo "Successfully took ownership of TPM and set owner and SRK passwords." |
7cdc7ea4 | 126 | |
a0e7fbc0 SB |
127 | run_swtpm ${SWTPM_INTERFACE} \ |
128 | --flags not-need-init \ | |
b291eb83 | 129 | --tpmstate "dir=${workdir}" |
7cdc7ea4 | 130 | |
a0e7fbc0 | 131 | swtpm_open_cmddev ${SWTPM_INTERFACE} 100 |
7cdc7ea4 | 132 | |
a0e7fbc0 | 133 | # Startup the TPM |
b291eb83 | 134 | res="$(swtpm_cmd_tx "${SWTPM_INTERFACE}" '\x00\xC1\x00\x00\x00\x0C\x00\x00\x00\x99\x00\x01')" |
a0e7fbc0 SB |
135 | exp=' 00 c4 00 00 00 0a 00 00 00 00' |
136 | if [ "$res" != "$exp" ]; then | |
137 | echo "Error: Did not get expected result from TPM_Startup(ST_Clear)" | |
138 | echo "expected: $exp" | |
139 | echo "received: $res" | |
140 | exit 1 | |
141 | fi | |
7cdc7ea4 | 142 | |
cc410ca9 SB |
143 | echo "$TCSD_FILE" | base64 -d > "${TCSD_SYSTEM_PS_FILE}" |
144 | ||
a0e7fbc0 | 145 | # Setup the TCSD config file and start TCSD with it |
b291eb83 | 146 | cat <<_EOF_ > "${TCSD_CONF}" |
7cdc7ea4 SB |
147 | port = ${TCSD_LISTEN_PORT} |
148 | system_ps_file = ${TCSD_SYSTEM_PS_FILE} | |
149 | _EOF_ | |
150 | ||
b9452304 SB |
151 | # Due to recent changes in tcsd we have to try with TSS_USER=tss and TSS_USER=root |
152 | # Before the following worked: | |
153 | # - tss:tss 0600 for TSS_USER=tss and TSS_GROUP=tss | |
154 | # - root:tss 0640 for TSS_USER=root and TSS_GROUP=tss | |
155 | # After the changes: | |
156 | # - root:tss 0640 for TSS_USER=tss and TSS_GROUP=tss | |
157 | while :; do | |
158 | chown ${TSS_USER}:${TSS_GROUP} "${TCSD_CONF}" | |
159 | if [ "${TSS_USER}" == "${TSS_GROUP}" ]; then | |
160 | chmod 0600 "${TCSD_CONF}" | |
161 | else | |
162 | chmod 0640 "${TCSD_CONF}" | |
163 | fi | |
7cdc7ea4 | 164 | |
b9452304 SB |
165 | bash -c "TCSD_USE_TCP_DEVICE=1 TCSD_TCP_DEVICE_PORT=${SWTPM_SERVER_PORT} tcsd -c "${TCSD_CONF}" -e -f &>/dev/null & echo \$! > "${TCSD_PIDFILE}"; wait" & |
166 | BASH_PID=$! | |
7cdc7ea4 | 167 | |
b9452304 SB |
168 | if wait_for_file "${TCSD_PIDFILE}" 3; then |
169 | echo "Error: Could not get TCSD's PID file" | |
170 | exit 1 | |
171 | fi | |
7cdc7ea4 | 172 | |
eeb87a86 SB |
173 | # wait for PID to be written |
174 | sleep 0.5 | |
b9452304 SB |
175 | TCSD_PID=$(cat "${TCSD_PIDFILE}") |
176 | kill_quiet -0 "${TCSD_PID}" | |
177 | if [ $? -ne 0 ]; then | |
178 | # Try again with root unless we already tried | |
179 | if [ "$TSS_USER" != "root" ]; then | |
180 | TSS_USER="root" | |
181 | continue | |
182 | fi | |
183 | echo "Error: TCSD with pid ${TCSD_PID} must have terminated" | |
184 | exit 1 | |
185 | fi | |
186 | break | |
187 | done | |
7cdc7ea4 | 188 | |
4bd99ad9 | 189 | ${SWTPM_CREATE_TPMCA} \ |
b291eb83 | 190 | --dir "${SWTPM_LOCALCA_DIR}" \ |
cc410ca9 | 191 | --srk-password "${srk_password}" \ |
a0e7fbc0 | 192 | --register \ |
cc410ca9 | 193 | --group "${TSS_GROUP}" \ |
b291eb83 SB |
194 | --tss-tcsd-port "${TCSD_LISTEN_PORT}" \ |
195 | --outfile "${SWTPM_LOCALCA_CONF}" &>/dev/null | |
7cdc7ea4 | 196 | |
a0e7fbc0 SB |
197 | if [ $? -ne 0 ]; then |
198 | echo "Error: Could not create TPM CA" | |
199 | exit 1 | |
200 | fi | |
7cdc7ea4 | 201 | |
a0e7fbc0 SB |
202 | for fil in \ |
203 | swtpm-localca-rootca-cert.pem \ | |
204 | swtpm-localca-rootca-privkey.pem \ | |
205 | swtpm-localca-tpmca-cert.pem \ | |
206 | swtpm-localca-tpmca-pubkey.pem; do | |
b291eb83 | 207 | if [ ! -r "${SWTPM_LOCALCA_DIR}/${fil}" ]; then |
a0e7fbc0 SB |
208 | echo "Error: TPM CA tool did not create file ${fil}." |
209 | exit 1 | |
210 | fi | |
211 | done | |
212 | ||
4bd99ad9 SB |
213 | params="" |
214 | if [ -n "${srk_password}" ]; then | |
215 | params="^parentkey_password =" | |
216 | fi | |
217 | ||
218 | for regex in \ | |
219 | "^statedir = " \ | |
220 | "^signingkey = " \ | |
221 | "^issuercert = " \ | |
222 | "^certserial = " \ | |
223 | "^TSS_TCSD_HOSTNAME = " \ | |
224 | "^TSS_TCSD_PORT = " \ | |
225 | ${params}; do | |
226 | if [ -n "${regex}" ] && \ | |
b291eb83 | 227 | [ -z "$(grep -E "${regex}" "${SWTPM_LOCALCA_CONF}")" ]; then |
4bd99ad9 | 228 | echo "Error: Could not find regex '${line}' in CA config file." |
b291eb83 | 229 | cat "${SWTPM_LOCALCA_CONF}" |
4bd99ad9 SB |
230 | exit 1 |
231 | fi | |
232 | done | |
233 | ||
234 | params="" | |
235 | if [ ${vtpm_is_tpm2} -ne 0 ]; then | |
236 | params="--tpm2" | |
237 | skip=0 | |
238 | else | |
239 | skip=7 # header in cert | |
240 | fi | |
241 | ||
242 | # make sure we can actually sign with this new certificate | |
243 | ${SWTPM_LOCALCA} \ | |
244 | --type ek \ | |
245 | --ek x=739192d8f1004283957a7b1568d610b41c637ccc114aadcac4908c20456468fa,y=59f63ac06f8011f6fdd1460c6bc8e3e0a2d090d4fc188c7e04870e06795ce8ae \ | |
b291eb83 | 246 | --dir "${workdir}" --vmid test \ |
4bd99ad9 SB |
247 | ${params} \ |
248 | --tpm-spec-family 2.0 --tpm-spec-revision 146 --tpm-spec-level 00 \ | |
249 | --tpm-model swtpm --tpm-version 20170101 --tpm-manufacturer IBM \ | |
b291eb83 | 250 | --configfile "${SWTPM_LOCALCA_CONF}" \ |
a18cf085 | 251 | --optsfile /dev/null |
4bd99ad9 SB |
252 | if [ $? -ne 0 ]; then |
253 | echo "Error: The CA could not sign with the new certificate" | |
254 | exit 1 | |
255 | fi | |
b291eb83 | 256 | if [ ! -f "${workdir}/ek.cert" ]; then |
4bd99ad9 SB |
257 | echo "Error: The CA did not produce a certificate" |
258 | exit 1 | |
259 | fi | |
260 | # cert was for example 541 bytes long | |
b291eb83 | 261 | if [ $(get_filesize "${workdir}/ek.cert") -lt 500 ]; then |
4bd99ad9 | 262 | echo "Error: The certificate's size is dubious" |
b291eb83 | 263 | ls -l "${workdir}/ek.cert" |
4bd99ad9 SB |
264 | exit 1 |
265 | fi | |
266 | ||
267 | # Check the contents of the certificate | |
b291eb83 SB |
268 | certinfo=$(dd "if=${workdir}/ek.cert" bs=1 "skip=$skip" status=none | \ |
269 | "$CERTTOOL" -i --inder) | |
4bd99ad9 SB |
270 | regexs=('^[[:space:]]+2.23.133.8.1$' |
271 | '^[[:space:]]+directoryName:.*(,)?2.23.133.2.3=.*' | |
272 | '^[[:space:]]+directoryName:.*(,)?2.23.133.2.2=.*' | |
273 | '^[[:space:]]+directoryName:.*(,)?2.23.133.2.1=.*' | |
274 | '^[[:space:]]+Certificate Authority \(CA\): FALSE$' | |
275 | '^[[:space:]]+Unknown extension 2.5.29.9 \(not critical\):$' | |
276 | '^[[:space:]]+Hexdump: 3019301706056781050210310e300c0c03322e3002010002020092$') | |
277 | if [ ${vtpm_is_tpm2} -ne 0 ]; then | |
278 | # TPM 2.0; due to ecc: Key agreement | |
279 | regexs+=('^[[:space:]]+Key agreement\.$' | |
280 | '^[[:space:]]+Signature Algorithm: RSA-SHA256$') | |
281 | else | |
282 | regexs+=('^[[:space:]]+Key encipherment\.$' | |
283 | '^[[:space:]]+Signature Algorithm: RSA-SHA1$') | |
284 | fi | |
285 | ||
286 | for ((i=0; i < ${#regexs}; i++)); do \ | |
287 | if [ -n "${regexs[$i]}" ] && \ | |
288 | [ -z "$(echo "${certinfo}" | grep -E "${regexs[$i]}")" ]; then | |
289 | echo "Error: Could not match regex '${regexs[$i]}' with certificate info:" | |
290 | echo "${certinfo}" | |
291 | exit 1 | |
292 | fi | |
293 | done | |
294 | ||
a0e7fbc0 | 295 | # Send SIGTERM to TCSD |
b291eb83 | 296 | kill_quiet -15 "${TCSD_PID}" |
a0e7fbc0 SB |
297 | |
298 | # Shut down TPM | |
b291eb83 | 299 | run_swtpm_ioctl "${SWTPM_INTERFACE}" -s |
a0e7fbc0 SB |
300 | if [ $? -ne 0 ]; then |
301 | echo "Error: Could not shut down the ${SWTPM_INTERFACE} TPM." | |
7cdc7ea4 SB |
302 | exit 1 |
303 | fi | |
7cdc7ea4 | 304 | |
b291eb83 | 305 | if wait_process_gone "${SWTPM_PID}" 4; then |
a0e7fbc0 SB |
306 | echo "Error: ${SWTPM_INTERFACE} TPM should not be running anymore." |
307 | exit 1 | |
308 | fi | |
7cdc7ea4 | 309 | |
b291eb83 | 310 | if wait_process_gone "${SWTPM_PID}" 4; then |
a0e7fbc0 SB |
311 | echo "Error: tcsd should not be running anymore." |
312 | exit 1 | |
313 | fi | |
314 | } # run_test | |
7cdc7ea4 | 315 | |
4bd99ad9 | 316 | run_test "${OWNER_PASSWORD}" "${SRK_PASSWORD}" 1 |
a0e7fbc0 SB |
317 | echo "Test 1: OK" |
318 | ||
4bd99ad9 SB |
319 | run_test "${OWNER_PASSWORD}" "${SRK_PASSWORD}" 0 |
320 | echo "Test 2: OK" | |
321 | ||
322 | run_test "" "${SRK_PASSWORD}" 1 | |
323 | echo "Test 3: OK" | |
324 | ||
325 | run_test "" "${SRK_PASSWORD}" 0 | |
326 | echo "Test 4: OK" | |
327 | ||
7cdc7ea4 | 328 | exit 0 |