test_keygen.sh 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. #!/bin/sh
  2. # Note: some of this code is lifted from zero_length_keys.sh, and could be
  3. # unified.
  4. umask 077
  5. set -e
  6. if [ $# -eq 0 ] || [ ! -f ${1} ] || [ ! -x ${1} ]; then
  7. if [ "$TESTING_TOR_BINARY" = ""] ; then
  8. echo "Usage: ${0} PATH_TO_TOR [case-number]"
  9. exit 1
  10. fi
  11. fi
  12. if [ $# -ge 1 ]; then
  13. TOR_BINARY="${1}"
  14. shift
  15. else
  16. TOR_BINARY="${TESTING_TOR_BINARY}"
  17. fi
  18. if [ $# -ge 1 ]; then
  19. dflt=0
  20. else
  21. dflt=1
  22. fi
  23. CASE2A=$dflt
  24. CASE2B=$dflt
  25. CASE3A=$dflt
  26. CASE3B=$dflt
  27. CASE3C=$dflt
  28. CASE4=$dflt
  29. CASE5=$dflt
  30. CASE6=$dflt
  31. CASE7=$dflt
  32. CASE8=$dflt
  33. CASE9=$dflt
  34. CASE10=$dflt
  35. if [ $# -ge 1 ]; then
  36. eval "CASE${1}"=1
  37. fi
  38. die() { echo "$1" >&2 ; exit 5; }
  39. check_dir() { [ -d "$1" ] || die "$1 did not exist"; }
  40. check_file() { [ -e "$1" ] || die "$1 did not exist"; }
  41. check_no_file() { [ -e "$1" ] && die "$1 was not supposed to exist" || true; }
  42. check_files_eq() { cmp "$1" "$2" || die "$1 and $2 did not match"; }
  43. check_keys_eq() { check_files_eq "${SRC}/keys/${1}" "${ME}/keys/${1}"; }
  44. DATA_DIR=`mktemp -d -t tor_keygen_tests.XXXXXX`
  45. if [ -z "$DATA_DIR" ]; then
  46. echo "Failure: mktemp invocation returned empty string" >&2
  47. exit 3
  48. fi
  49. if [ ! -d "$DATA_DIR" ]; then
  50. echo "Failure: mktemp invocation result doesn't point to directory" >&2
  51. exit 3
  52. fi
  53. trap "rm -rf '$DATA_DIR'" 0
  54. touch "${DATA_DIR}/empty_torrc"
  55. QUIETLY="--hush"
  56. TOR="${TOR_BINARY} ${QUIETLY} --DisableNetwork 1 --ShutdownWaitLength 0 --ORPort 12345 --ExitRelay 0 -f ${DATA_DIR}/empty_torrc"
  57. # Step 1: Start Tor with --list-fingerprint. Make sure everything is there.
  58. mkdir "${DATA_DIR}/orig"
  59. ${TOR} --DataDirectory "${DATA_DIR}/orig" --list-fingerprint > /dev/null
  60. check_dir "${DATA_DIR}/orig/keys"
  61. check_file "${DATA_DIR}/orig/keys/ed25519_master_id_public_key"
  62. check_file "${DATA_DIR}/orig/keys/ed25519_master_id_secret_key"
  63. check_file "${DATA_DIR}/orig/keys/ed25519_signing_cert"
  64. check_file "${DATA_DIR}/orig/keys/ed25519_signing_secret_key"
  65. # Step 2: Start Tor with --keygen. Make sure everything is there.
  66. mkdir "${DATA_DIR}/keygen"
  67. ${TOR} --DataDirectory "${DATA_DIR}/keygen" --keygen --no-passphrase 2>"${DATA_DIR}/keygen/stderr"
  68. grep "Not encrypting the secret key" "${DATA_DIR}/keygen/stderr" >/dev/null || die "Tor didn't declare that there would be no encryption"
  69. check_dir "${DATA_DIR}/keygen/keys"
  70. check_file "${DATA_DIR}/keygen/keys/ed25519_master_id_public_key"
  71. check_file "${DATA_DIR}/keygen/keys/ed25519_master_id_secret_key"
  72. check_file "${DATA_DIR}/keygen/keys/ed25519_signing_cert"
  73. check_file "${DATA_DIR}/keygen/keys/ed25519_signing_secret_key"
  74. # Step 3: Start Tor with --keygen and a passphrase.
  75. # Make sure everything is there.
  76. mkdir "${DATA_DIR}/encrypted"
  77. echo "passphrase" | ${TOR} --DataDirectory "${DATA_DIR}/encrypted" --keygen --passphrase-fd 0
  78. check_dir "${DATA_DIR}/encrypted/keys"
  79. check_file "${DATA_DIR}/encrypted/keys/ed25519_master_id_public_key"
  80. check_file "${DATA_DIR}/encrypted/keys/ed25519_master_id_secret_key_encrypted"
  81. check_file "${DATA_DIR}/encrypted/keys/ed25519_signing_cert"
  82. check_file "${DATA_DIR}/encrypted/keys/ed25519_signing_secret_key"
  83. echo "=== Starting tests."
  84. #
  85. # The "case X" numbers below come from s7r's email on
  86. # https://lists.torproject.org/pipermail/tor-dev/2015-August/009204.html
  87. # Case 2a: Missing secret key, public key exists, start tor.
  88. if [ "$CASE2A" = 1 ]; then
  89. ME="${DATA_DIR}/case2a"
  90. SRC="${DATA_DIR}/orig"
  91. mkdir -p "${ME}/keys"
  92. cp "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/"
  93. ${TOR} --DataDirectory "${ME}" --list-fingerprint && die "Somehow succeeded when missing secret key, certs" || true
  94. check_files_eq "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/ed25519_master_id_public_key"
  95. echo "==== Case 2A ok"
  96. fi
  97. # Case 2b: Encrypted secret key, public key exists, start tor.
  98. if [ "$CASE2B" = 1 ]; then
  99. ME="${DATA_DIR}/case2b"
  100. SRC="${DATA_DIR}/encrypted"
  101. mkdir -p "${ME}/keys"
  102. cp "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/"
  103. cp "${SRC}/keys/ed25519_master_id_secret_key_encrypted" "${ME}/keys/"
  104. ${TOR} --DataDirectory "${ME}" --list-fingerprint && dir "Somehow succeeded with encrypted secret key, missing certs"
  105. check_files_eq "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/ed25519_master_id_public_key"
  106. check_files_eq "${SRC}/keys/ed25519_master_id_secret_key_encrypted" "${ME}/keys/ed25519_master_id_secret_key_encrypted"
  107. echo "==== Case 2B ok"
  108. fi
  109. # Case 3a: Start Tor with only master key.
  110. if [ "$CASE3A" = 1 ]; then
  111. ME="${DATA_DIR}/case3a"
  112. SRC="${DATA_DIR}/orig"
  113. mkdir -p "${ME}/keys"
  114. cp "${SRC}/keys/ed25519_master_id_"* "${ME}/keys/"
  115. ${TOR} --DataDirectory "${ME}" --list-fingerprint || die "Tor failed when starting with only master key"
  116. check_files_eq "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/ed25519_master_id_public_key"
  117. check_files_eq "${SRC}/keys/ed25519_master_id_secret_key" "${ME}/keys/ed25519_master_id_secret_key"
  118. check_file "${ME}/keys/ed25519_signing_cert"
  119. check_file "${ME}/keys/ed25519_signing_secret_key"
  120. echo "==== Case 3A ok"
  121. fi
  122. # Case 3b: Call keygen with only unencrypted master key.
  123. if [ "$CASE3B" = 1 ]; then
  124. ME="${DATA_DIR}/case3b"
  125. SRC="${DATA_DIR}/orig"
  126. mkdir -p "${ME}/keys"
  127. cp "${SRC}/keys/ed25519_master_id_"* "${ME}/keys/"
  128. ${TOR} --DataDirectory "${ME}" --keygen || die "Keygen failed with only master key"
  129. check_files_eq "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/ed25519_master_id_public_key"
  130. check_files_eq "${SRC}/keys/ed25519_master_id_secret_key" "${ME}/keys/ed25519_master_id_secret_key"
  131. check_file "${ME}/keys/ed25519_signing_cert"
  132. check_file "${ME}/keys/ed25519_signing_secret_key"
  133. echo "==== Case 3B ok"
  134. fi
  135. # Case 3c: Call keygen with only encrypted master key.
  136. if [ "$CASE3C" = 1 ]; then
  137. ME="${DATA_DIR}/case3c"
  138. SRC="${DATA_DIR}/encrypted"
  139. mkdir -p "${ME}/keys"
  140. cp "${SRC}/keys/ed25519_master_id_"* "${ME}/keys/"
  141. echo "passphrase" | ${TOR} --DataDirectory "${ME}" --keygen --passphrase-fd 0 || die "Keygen failed with only encrypted master key"
  142. check_files_eq "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/ed25519_master_id_public_key"
  143. check_files_eq "${SRC}/keys/ed25519_master_id_secret_key_encrypted" "${ME}/keys/ed25519_master_id_secret_key_encrypted"
  144. check_file "${ME}/keys/ed25519_signing_cert"
  145. check_file "${ME}/keys/ed25519_signing_secret_key"
  146. echo "==== Case 3C ok"
  147. fi
  148. # Case 4: Make a new data directory with only an unencrypted secret key.
  149. # Then start tor. The rest should become correct.
  150. if [ "$CASE4" = 1 ]; then
  151. ME="${DATA_DIR}/case4"
  152. SRC="${DATA_DIR}/orig"
  153. mkdir -p "${ME}/keys"
  154. cp "${SRC}/keys/ed25519_master_id_secret_key" "${ME}/keys/"
  155. ${TOR} --DataDirectory "${ME}" --list-fingerprint || die "Tor wouldn't start with only unencrypted secret key"
  156. check_file "${ME}/keys/ed25519_master_id_public_key"
  157. check_file "${ME}/keys/ed25519_signing_cert"
  158. check_file "${ME}/keys/ed25519_signing_secret_key"
  159. ${TOR} --DataDirectory "${ME}" --list-fingerprint || die "Tor wouldn't start again after starting once with only unencrypted secret key."
  160. echo "==== Case 4 ok"
  161. fi
  162. # Case 5: Make a new data directory with only an encrypted secret key.
  163. if [ "$CASE5" = 1 ]; then
  164. ME="${DATA_DIR}/case5"
  165. SRC="${DATA_DIR}/encrypted"
  166. mkdir -p "${ME}/keys"
  167. cp "${SRC}/keys/ed25519_master_id_secret_key_encrypted" "${ME}/keys/"
  168. ${TOR} --DataDirectory "${ME}" --list-fingerprint && die "Tor started with only encrypted secret key!"
  169. check_no_file "${ME}/keys/ed25519_master_id_public_key"
  170. check_no_file "${ME}/keys/ed25519_master_id_public_key"
  171. echo "==== Case 5 ok"
  172. fi
  173. # Case 6: Make a new data directory with encrypted secret key and public key
  174. if [ "$CASE6" = 1 ]; then
  175. ME="${DATA_DIR}/case6"
  176. SRC="${DATA_DIR}/encrypted"
  177. mkdir -p "${ME}/keys"
  178. cp "${SRC}/keys/ed25519_master_id_secret_key_encrypted" "${ME}/keys/"
  179. cp "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/"
  180. ${TOR} --DataDirectory "${ME}" --list-fingerprint && die "Tor started with encrypted secret key and no certs" || true
  181. check_no_file "${ME}/keys/ed25519_signing_cert"
  182. check_no_file "${ME}/keys/ed25519_signing_secret_key"
  183. echo "==== Case 6 ok"
  184. fi
  185. # Case 7: Make a new data directory with unencrypted secret key and
  186. # certificates; missing master public.
  187. if [ "$CASE7" = 1 ]; then
  188. ME="${DATA_DIR}/case7"
  189. SRC="${DATA_DIR}/keygen"
  190. mkdir -p "${ME}/keys"
  191. cp "${SRC}/keys/ed25519_master_id_secret_key" "${ME}/keys/"
  192. cp "${SRC}/keys/ed25519_signing_cert" "${ME}/keys/"
  193. cp "${SRC}/keys/ed25519_signing_secret_key" "${ME}/keys/"
  194. ${TOR} --DataDirectory "${ME}" --list-fingerprint || die "Failed when starting with missing public key"
  195. check_keys_eq ed25519_master_id_secret_key
  196. check_keys_eq ed25519_master_id_public_key
  197. check_keys_eq ed25519_signing_secret_key
  198. check_keys_eq ed25519_signing_cert
  199. echo "==== Case 7 ok"
  200. fi
  201. # Case 8: offline master secret key.
  202. if [ "$CASE8" = 1 ]; then
  203. ME="${DATA_DIR}/case8"
  204. SRC="${DATA_DIR}/keygen"
  205. mkdir -p "${ME}/keys"
  206. cp "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/"
  207. cp "${SRC}/keys/ed25519_signing_cert" "${ME}/keys/"
  208. cp "${SRC}/keys/ed25519_signing_secret_key" "${ME}/keys/"
  209. ${TOR} --DataDirectory "${ME}" --list-fingerprint || die "Failed when starting with offline secret key"
  210. check_no_file "${ME}/keys/ed25519_master_id_secret_key"
  211. check_keys_eq ed25519_master_id_public_key
  212. check_keys_eq ed25519_signing_secret_key
  213. check_keys_eq ed25519_signing_cert
  214. echo "==== Case 8 ok"
  215. fi
  216. # Case 9: signing cert and secret key provided; could infer master key.
  217. if [ "$CASE9" = 1 ]; then
  218. ME="${DATA_DIR}/case9"
  219. SRC="${DATA_DIR}/keygen"
  220. mkdir -p "${ME}/keys"
  221. cp "${SRC}/keys/ed25519_signing_cert" "${ME}/keys/"
  222. cp "${SRC}/keys/ed25519_signing_secret_key" "${ME}/keys/"
  223. ${TOR} --DataDirectory "${ME}" --list-fingerprint || die "Failed when starting with only signing material"
  224. check_no_file "${ME}/keys/ed25519_master_id_secret_key"
  225. check_no_file "${ME}/keys/ed25519_master_id_public_key"
  226. check_keys_eq ed25519_signing_secret_key
  227. check_keys_eq ed25519_signing_cert
  228. echo "==== Case 9 ok"
  229. fi
  230. # Case 10: master key mismatch.
  231. if [ "$CASE10" = 1 ]; then
  232. ME="${DATA_DIR}/case10"
  233. SRC="${DATA_DIR}/keygen"
  234. OTHER="${DATA_DIR}/orig"
  235. mkdir -p "${ME}/keys"
  236. cp "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/"
  237. cp "${OTHER}/keys/ed25519_master_id_secret_key" "${ME}/keys/"
  238. ${TOR} --DataDirectory "${ME}" --list-fingerprint && die "Successfully started with mismatched keys!?" || true
  239. echo "==== Case 10 ok"
  240. fi
  241. # Check cert-only.