dirvote: Handling adding vote and signature if module is disabled
[tor.git] / src / test / test_keygen.sh
blobb3d4d8e39a81e6a1fb1a9bda67e66cb1214909f7
1 #!/bin/sh
3 # Note: some of this code is lifted from zero_length_keys.sh, and could be
4 # unified.
6 umask 077
7 set -e
9 if [ $# -eq 0 ] || [ ! -f ${1} ] || [ ! -x ${1} ]; then
10 if [ "$TESTING_TOR_BINARY" = "" ] ; then
11 echo "Usage: ${0} PATH_TO_TOR [case-number]"
12 exit 1
16 if [ $# -ge 1 ]; then
17 TOR_BINARY="${1}"
18 shift
19 else
20 TOR_BINARY="${TESTING_TOR_BINARY}"
25 if [ $# -ge 1 ]; then
26 dflt=0
27 else
28 dflt=1
31 CASE2A=$dflt
32 CASE2B=$dflt
33 CASE3A=$dflt
34 CASE3B=$dflt
35 CASE3C=$dflt
36 CASE4=$dflt
37 CASE5=$dflt
38 CASE6=$dflt
39 CASE7=$dflt
40 CASE8=$dflt
41 CASE9=$dflt
42 CASE10=$dflt
43 CASE11A=$dflt
44 CASE11B=$dflt
45 CASE11C=$dflt
46 CASE11D=$dflt
47 CASE11E=$dflt
48 CASE11F=$dflt
50 if [ $# -ge 1 ]; then
51 eval "CASE${1}"=1
55 dump() { xxd -p "$1" | tr -d '\n '; }
56 die() { echo "$1" >&2 ; exit 5; }
57 check_dir() { [ -d "$1" ] || die "$1 did not exist"; }
58 check_file() { [ -e "$1" ] || die "$1 did not exist"; }
59 check_no_file() { [ -e "$1" ] && die "$1 was not supposed to exist" || true; }
60 check_files_eq() { cmp "$1" "$2" || die "$1 and $2 did not match: `dump $1` vs `dump $2`"; }
61 check_keys_eq() { check_files_eq "${SRC}/keys/${1}" "${ME}/keys/${1}"; }
63 DATA_DIR=`mktemp -d -t tor_keygen_tests.XXXXXX`
64 if [ -z "$DATA_DIR" ]; then
65 echo "Failure: mktemp invocation returned empty string" >&2
66 exit 3
68 if [ ! -d "$DATA_DIR" ]; then
69 echo "Failure: mktemp invocation result doesn't point to directory" >&2
70 exit 3
72 trap "rm -rf '$DATA_DIR'" 0
74 # Use an absolute path for this or Tor will complain
75 DATA_DIR=`cd "${DATA_DIR}" && pwd`
77 touch "${DATA_DIR}/empty_torrc"
79 QUIETLY="--hush"
80 SILENTLY="--quiet"
81 TOR="${TOR_BINARY} ${QUIETLY} --DisableNetwork 1 --ShutdownWaitLength 0 --ORPort 12345 --ExitRelay 0 -f ${DATA_DIR}/empty_torrc"
83 ##### SETUP
85 # Here we create three sets of keys: one using "tor", one using "tor
86 # --keygen", and one using "tor --keygen" and encryption. We'll be
87 # copying them into different keys directories in order to simulate
88 # different kinds of configuration problems/issues.
90 # Step 1: Start Tor with --list-fingerprint --quiet. Make sure everything is there.
91 mkdir "${DATA_DIR}/orig"
92 ${TOR} --DataDirectory "${DATA_DIR}/orig" --list-fingerprint ${SILENTLY} > /dev/null
94 check_dir "${DATA_DIR}/orig/keys"
95 check_file "${DATA_DIR}/orig/keys/ed25519_master_id_public_key"
96 check_file "${DATA_DIR}/orig/keys/ed25519_master_id_secret_key"
97 check_file "${DATA_DIR}/orig/keys/ed25519_signing_cert"
98 check_file "${DATA_DIR}/orig/keys/ed25519_signing_secret_key"
100 # Step 2: Start Tor with --keygen. Make sure everything is there.
101 mkdir "${DATA_DIR}/keygen"
102 ${TOR} --DataDirectory "${DATA_DIR}/keygen" --keygen --no-passphrase 2>"${DATA_DIR}/keygen/stderr"
103 grep "Not encrypting the secret key" "${DATA_DIR}/keygen/stderr" >/dev/null || die "Tor didn't declare that there would be no encryption"
105 check_dir "${DATA_DIR}/keygen/keys"
106 check_file "${DATA_DIR}/keygen/keys/ed25519_master_id_public_key"
107 check_file "${DATA_DIR}/keygen/keys/ed25519_master_id_secret_key"
108 check_file "${DATA_DIR}/keygen/keys/ed25519_signing_cert"
109 check_file "${DATA_DIR}/keygen/keys/ed25519_signing_secret_key"
111 # Step 3: Start Tor with --keygen and a passphrase.
112 # Make sure everything is there.
113 mkdir "${DATA_DIR}/encrypted"
114 echo "passphrase" | ${TOR} --DataDirectory "${DATA_DIR}/encrypted" --keygen --passphrase-fd 0
116 check_dir "${DATA_DIR}/encrypted/keys"
117 check_file "${DATA_DIR}/encrypted/keys/ed25519_master_id_public_key"
118 check_file "${DATA_DIR}/encrypted/keys/ed25519_master_id_secret_key_encrypted"
119 check_file "${DATA_DIR}/encrypted/keys/ed25519_signing_cert"
120 check_file "${DATA_DIR}/encrypted/keys/ed25519_signing_secret_key"
123 echo "=== Starting keygen tests."
126 # The "case X" numbers below come from s7r's email on
127 # https://lists.torproject.org/pipermail/tor-dev/2015-August/009204.html
130 # Case 2a: Missing secret key, public key exists, start tor.
132 if [ "$CASE2A" = 1 ]; then
134 ME="${DATA_DIR}/case2a"
135 SRC="${DATA_DIR}/orig"
136 mkdir -p "${ME}/keys"
137 cp "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/"
138 ${TOR} --DataDirectory "${ME}" --list-fingerprint > "${ME}/stdout" && die "Somehow succeeded when missing secret key, certs: `cat ${ME}/stdout`" || true
139 check_files_eq "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/ed25519_master_id_public_key"
141 grep "We needed to load a secret key.*but couldn't find it" "${ME}/stdout" >/dev/null || die "Tor didn't declare that it was missing a secret key"
143 echo "==== Case 2A ok"
146 # Case 2b: Encrypted secret key, public key exists, start tor.
148 if [ "$CASE2B" = 1 ]; then
150 ME="${DATA_DIR}/case2b"
151 SRC="${DATA_DIR}/encrypted"
153 mkdir -p "${ME}/keys"
154 cp "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/"
155 cp "${SRC}/keys/ed25519_master_id_secret_key_encrypted" "${ME}/keys/"
156 ${TOR} --DataDirectory "${ME}" --list-fingerprint > "${ME}/stdout" && dir "Somehow succeeded with encrypted secret key, missing certs"
158 check_files_eq "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/ed25519_master_id_public_key"
159 check_files_eq "${SRC}/keys/ed25519_master_id_secret_key_encrypted" "${ME}/keys/ed25519_master_id_secret_key_encrypted"
161 grep "We needed to load a secret key.*but it was encrypted.*--keygen" "${ME}/stdout" >/dev/null || die "Tor didn't declare that it was missing a secret key and suggest --keygen."
163 echo "==== Case 2B ok"
167 # Case 3a: Start Tor with only master key.
169 if [ "$CASE3A" = 1 ]; then
171 ME="${DATA_DIR}/case3a"
172 SRC="${DATA_DIR}/orig"
174 mkdir -p "${ME}/keys"
175 cp "${SRC}/keys/ed25519_master_id_"* "${ME}/keys/"
176 ${TOR} --DataDirectory "${ME}" --list-fingerprint ${SILENTLY} >/dev/null || die "Tor failed when starting with only master key"
177 check_files_eq "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/ed25519_master_id_public_key"
178 check_files_eq "${SRC}/keys/ed25519_master_id_secret_key" "${ME}/keys/ed25519_master_id_secret_key"
179 check_file "${ME}/keys/ed25519_signing_cert"
180 check_file "${ME}/keys/ed25519_signing_secret_key"
182 echo "==== Case 3A ok"
186 # Case 3b: Call keygen with only unencrypted master key.
188 if [ "$CASE3B" = 1 ]; then
190 ME="${DATA_DIR}/case3b"
191 SRC="${DATA_DIR}/orig"
193 mkdir -p "${ME}/keys"
194 cp "${SRC}/keys/ed25519_master_id_"* "${ME}/keys/"
195 ${TOR} --DataDirectory "${ME}" --keygen || die "Keygen failed with only master key"
196 check_files_eq "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/ed25519_master_id_public_key"
197 check_files_eq "${SRC}/keys/ed25519_master_id_secret_key" "${ME}/keys/ed25519_master_id_secret_key"
198 check_file "${ME}/keys/ed25519_signing_cert"
199 check_file "${ME}/keys/ed25519_signing_secret_key"
201 echo "==== Case 3B ok"
205 # Case 3c: Call keygen with only encrypted master key.
207 if [ "$CASE3C" = 1 ]; then
209 ME="${DATA_DIR}/case3c"
210 SRC="${DATA_DIR}/encrypted"
212 mkdir -p "${ME}/keys"
213 cp "${SRC}/keys/ed25519_master_id_"* "${ME}/keys/"
214 echo "passphrase" | ${TOR} --DataDirectory "${ME}" --keygen --passphrase-fd 0 || die "Keygen failed with only encrypted master key"
215 check_files_eq "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/ed25519_master_id_public_key"
216 check_files_eq "${SRC}/keys/ed25519_master_id_secret_key_encrypted" "${ME}/keys/ed25519_master_id_secret_key_encrypted"
217 check_file "${ME}/keys/ed25519_signing_cert"
218 check_file "${ME}/keys/ed25519_signing_secret_key"
220 echo "==== Case 3C ok"
224 # Case 4: Make a new data directory with only an unencrypted secret key.
225 # Then start tor. The rest should become correct.
227 if [ "$CASE4" = 1 ]; then
229 ME="${DATA_DIR}/case4"
230 SRC="${DATA_DIR}/orig"
232 mkdir -p "${ME}/keys"
233 cp "${SRC}/keys/ed25519_master_id_secret_key" "${ME}/keys/"
234 ${TOR} --DataDirectory "${ME}" --list-fingerprint ${SILENTLY} > "${ME}/fp1" || die "Tor wouldn't start with only unencrypted secret key"
235 check_file "${ME}/keys/ed25519_master_id_public_key"
236 check_file "${ME}/keys/ed25519_signing_cert"
237 check_file "${ME}/keys/ed25519_signing_secret_key"
238 ${TOR} --DataDirectory "${ME}" --list-fingerprint ${SILENTLY} > "${ME}/fp2" || die "Tor wouldn't start again after starting once with only unencrypted secret key."
240 check_files_eq "${ME}/fp1" "${ME}/fp2"
242 echo "==== Case 4 ok"
246 # Case 5: Make a new data directory with only an encrypted secret key.
248 if [ "$CASE5" = 1 ]; then
250 ME="${DATA_DIR}/case5"
251 SRC="${DATA_DIR}/encrypted"
253 mkdir -p "${ME}/keys"
254 cp "${SRC}/keys/ed25519_master_id_secret_key_encrypted" "${ME}/keys/"
255 ${TOR} --DataDirectory "${ME}" --list-fingerprint >"${ME}/stdout" && die "Tor started with only encrypted secret key!"
256 check_no_file "${ME}/keys/ed25519_master_id_public_key"
257 check_no_file "${ME}/keys/ed25519_master_id_public_key"
259 grep "but not public key file" "${ME}/stdout" >/dev/null || die "Tor didn't declare it couldn't find a public key."
261 echo "==== Case 5 ok"
265 # Case 6: Make a new data directory with encrypted secret key and public key
267 if [ "$CASE6" = 1 ]; then
269 ME="${DATA_DIR}/case6"
270 SRC="${DATA_DIR}/encrypted"
272 mkdir -p "${ME}/keys"
273 cp "${SRC}/keys/ed25519_master_id_secret_key_encrypted" "${ME}/keys/"
274 cp "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/"
275 ${TOR} --DataDirectory "${ME}" --list-fingerprint > "${ME}/stdout" && die "Tor started with encrypted secret key and no certs" || true
276 check_no_file "${ME}/keys/ed25519_signing_cert"
277 check_no_file "${ME}/keys/ed25519_signing_secret_key"
279 grep "but it was encrypted" "${ME}/stdout" >/dev/null || die "Tor didn't declare that the secret key was encrypted."
281 echo "==== Case 6 ok"
285 # Case 7: Make a new data directory with unencrypted secret key and
286 # certificates; missing master public.
288 if [ "$CASE7" = 1 ]; then
290 ME="${DATA_DIR}/case7"
291 SRC="${DATA_DIR}/keygen"
293 mkdir -p "${ME}/keys"
294 cp "${SRC}/keys/ed25519_master_id_secret_key" "${ME}/keys/"
295 cp "${SRC}/keys/ed25519_signing_cert" "${ME}/keys/"
296 cp "${SRC}/keys/ed25519_signing_secret_key" "${ME}/keys/"
298 ${TOR} --DataDirectory "${ME}" --list-fingerprint ${SILENTLY} >/dev/null || die "Failed when starting with missing public key"
299 check_keys_eq ed25519_master_id_secret_key
300 check_keys_eq ed25519_master_id_public_key
301 check_keys_eq ed25519_signing_secret_key
302 check_keys_eq ed25519_signing_cert
304 echo "==== Case 7 ok"
308 # Case 8: offline master secret key.
310 if [ "$CASE8" = 1 ]; then
312 ME="${DATA_DIR}/case8"
313 SRC="${DATA_DIR}/keygen"
315 mkdir -p "${ME}/keys"
316 cp "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/"
317 cp "${SRC}/keys/ed25519_signing_cert" "${ME}/keys/"
318 cp "${SRC}/keys/ed25519_signing_secret_key" "${ME}/keys/"
320 ${TOR} --DataDirectory "${ME}" --list-fingerprint ${SILENTLY} >/dev/null || die "Failed when starting with offline secret key"
321 check_no_file "${ME}/keys/ed25519_master_id_secret_key"
322 check_keys_eq ed25519_master_id_public_key
323 check_keys_eq ed25519_signing_secret_key
324 check_keys_eq ed25519_signing_cert
326 echo "==== Case 8 ok"
330 # Case 9: signing cert and secret key provided; could infer master key.
332 if [ "$CASE9" = 1 ]; then
334 ME="${DATA_DIR}/case9"
335 SRC="${DATA_DIR}/keygen"
337 mkdir -p "${ME}/keys"
338 cp "${SRC}/keys/ed25519_signing_cert" "${ME}/keys/"
339 cp "${SRC}/keys/ed25519_signing_secret_key" "${ME}/keys/"
341 ${TOR} --DataDirectory "${ME}" --list-fingerprint ${SILENTLY} >/dev/null || die "Failed when starting with only signing material"
342 check_no_file "${ME}/keys/ed25519_master_id_secret_key"
343 check_file "${ME}/keys/ed25519_master_id_public_key"
344 check_keys_eq ed25519_signing_secret_key
345 check_keys_eq ed25519_signing_cert
347 echo "==== Case 9 ok"
352 # Case 10: master key mismatch.
354 if [ "$CASE10" = 1 ]; then
356 ME="${DATA_DIR}/case10"
357 SRC="${DATA_DIR}/keygen"
358 OTHER="${DATA_DIR}/orig"
360 mkdir -p "${ME}/keys"
361 cp "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/"
362 cp "${OTHER}/keys/ed25519_master_id_secret_key" "${ME}/keys/"
364 ${TOR} --DataDirectory "${ME}" --list-fingerprint >"${ME}/stdout" && die "Successfully started with mismatched keys!?" || true
366 grep "public_key does not match.*secret_key" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a key mismatch"
368 echo "==== Case 10 ok"
372 # Case 11a: -passphrase-fd without --keygen
374 if [ "$CASE11A" = 1 ]; then
376 ME="${DATA_DIR}/case11a"
378 mkdir -p "${ME}/keys"
380 ${TOR} --DataDirectory "${ME}" --passphrase-fd 1 > "${ME}/stdout" && die "Successfully started with passphrase-fd but no keygen?" || true
382 grep "passphrase-fd specified without --keygen" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
384 echo "==== Case 11A ok"
388 # Case 11b: --no-passphrase without --keygen
390 if [ "$CASE11B" = 1 ]; then
392 ME="${DATA_DIR}/case11b"
394 mkdir -p "${ME}/keys"
396 ${TOR} --DataDirectory "${ME}" --no-passphrase > "${ME}/stdout" && die "Successfully started with no-passphrase but no keygen?" || true
398 grep "no-passphrase specified without --keygen" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
400 echo "==== Case 11B ok"
404 # Case 11c: --newpass without --keygen
406 if [ "$CASE11C" = 1 ]; then
408 ME="${DATA_DIR}/case11C"
410 mkdir -p "${ME}/keys"
412 ${TOR} --DataDirectory "${ME}" --newpass > "${ME}/stdout" && die "Successfully started with newpass but no keygen?" || true
414 grep "newpass specified without --keygen" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
416 echo "==== Case 11C ok"
420 ######## --master-key does not work yet, but this will test the error case
421 ######## when it does.
423 # Case 11d: --master-key without --keygen
425 if [ "$CASE11D" = 1 ]; then
427 # ME="${DATA_DIR}/case11d"
429 # mkdir -p "${ME}/keys"
431 # ${TOR} --DataDirectory "${ME}" --master-key "${ME}/foobar" > "${ME}/stdout" && die "Successfully started with master-key but no keygen?" || true
433 # cat "${ME}/stdout"
435 # grep "master-key without --keygen" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
437 echo "==== Case 11D skipped"
442 # Case 11E: Silly passphrase-fd
444 if [ "$CASE11E" = 1 ]; then
446 ME="${DATA_DIR}/case11E"
448 mkdir -p "${ME}/keys"
450 ${TOR} --DataDirectory "${ME}" --keygen --passphrase-fd ewigeblumenkraft > "${ME}/stdout" && die "Successfully started with bogus passphrase-fd?" || true
452 grep "Invalid --passphrase-fd value" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
454 echo "==== Case 11E ok"
459 # Case 11F: --no-passphrase with --passphrase-fd
461 if [ "$CASE11F" = 1 ]; then
463 ME="${DATA_DIR}/case11F"
465 mkdir -p "${ME}/keys"
467 ${TOR} --DataDirectory "${ME}" --keygen --passphrase-fd 1 --no-passphrase > "${ME}/stdout" && die "Successfully started with bogus passphrase-fd combination?" || true
469 grep "no-passphrase specified with --passphrase-fd" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
471 echo "==== Case 11F ok"
476 # Check cert-only.