tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

test_keygen.sh (15650B)


      1 #!/bin/sh
      2 
      3 # Note: some of this code is lifted from zero_length_keys.sh, and could be
      4 # unified.
      5 
      6 umask 077
      7 set -e
      8 
      9 # emulate realpath(), in case coreutils or equivalent is not installed.
     10 abspath() {
     11    f="$*"
     12    if [ -d "$f" ]; then
     13        dir="$f"
     14        base=""
     15    else
     16        dir="$(dirname "$f")"
     17        base="/$(basename "$f")"
     18    fi
     19    dir="$(cd "$dir" && pwd)"
     20    echo "$dir$base"
     21 }
     22 
     23 if [ $# -eq 0 ] || [ ! -f "${1}" ] || [ ! -x "${1}" ]; then
     24  if [ "$TESTING_TOR_BINARY" = "" ] ; then
     25    echo "Usage: ${0} PATH_TO_TOR [case-number]"
     26    exit 1
     27  fi
     28 fi
     29 
     30 UNAME_OS=$(uname -s | cut -d_ -f1)
     31 if test "$UNAME_OS" = 'CYGWIN' || \
     32   test "$UNAME_OS" = 'MSYS' || \
     33   test "$UNAME_OS" = 'MINGW'; then
     34  echo "This test is unreliable on Windows. See trac #26076. Skipping." >&2
     35  exit 77
     36 fi
     37 
     38 # find the tor binary
     39 if [ $# -ge 1 ]; then
     40  TOR_BINARY="${1}"
     41  shift
     42 else
     43  TOR_BINARY="${TESTING_TOR_BINARY:-./src/app/tor}"
     44 fi
     45 
     46 TOR_BINARY="$(abspath "$TOR_BINARY")"
     47 
     48 echo "TOR BINARY IS ${TOR_BINARY}"
     49 
     50 if "$TOR_BINARY" --list-modules | grep -q "relay: no"; then
     51  echo "This test requires the relay module. Skipping." >&2
     52  exit 77
     53 fi
     54 
     55  if [ $# -ge 1 ]; then
     56      dflt=0
     57  else
     58      dflt=1
     59  fi
     60 
     61  CASE2A=$dflt
     62  CASE2B=$dflt
     63  CASE3A=$dflt
     64  CASE3B=$dflt
     65  CASE3C=$dflt
     66  CASE4=$dflt
     67  CASE5=$dflt
     68  CASE6=$dflt
     69  CASE7=$dflt
     70  CASE8=$dflt
     71  CASE9=$dflt
     72  CASE10=$dflt
     73  CASE11A=$dflt
     74  CASE11B=$dflt
     75  CASE11C=$dflt
     76  CASE11D=$dflt
     77  CASE11E=$dflt
     78  CASE11F=$dflt
     79 
     80  if [ $# -ge 1 ]; then
     81     eval "CASE${1}"=1
     82  fi
     83 
     84 
     85 dump() { xxd -p "$1" | tr -d '\n '; }
     86 die() { echo "$1" >&2 ; exit 5; }
     87 check_dir() { [ -d "$1" ] || die "$1 did not exist"; }
     88 check_file() { [ -e "$1" ] || die "$1 did not exist"; }
     89 check_no_file() { if [ -e "$1" ]; then die "$1 was not supposed to exist"; fi }
     90 check_files_eq() { cmp "$1" "$2" || die "$1 and $2 did not match: $(dump "$1") vs $(dump "$2")"; }
     91 check_keys_eq() { check_files_eq "${SRC}/keys/${1}" "${ME}/keys/${1}"; }
     92 
     93 DATA_DIR=$(mktemp -d -t tor_keygen_tests.XXXXXX)
     94 if [ -z "$DATA_DIR" ]; then
     95  echo "Failure: mktemp invocation returned empty string" >&2
     96  exit 3
     97 fi
     98 if [ ! -d "$DATA_DIR" ]; then
     99  echo "Failure: mktemp invocation result doesn't point to directory" >&2
    100  exit 3
    101 fi
    102 trap 'rm -rf "$DATA_DIR"' 0
    103 
    104 # Use an absolute path for this or Tor will complain
    105 DATA_DIR=$(cd "${DATA_DIR}" && pwd)
    106 
    107 touch "${DATA_DIR}/empty_torrc"
    108 touch "${DATA_DIR}/empty_defaults_torrc"
    109 
    110 QUIETLY="--hush"
    111 SILENTLY="--quiet"
    112 TOR="${TOR_BINARY} ${QUIETLY} --DisableNetwork 1 --ShutdownWaitLength 0 --ORPort 12345 --ExitRelay 0 -f ${DATA_DIR}/empty_torrc --defaults-torrc ${DATA_DIR}/empty_defaults_torrc"
    113 
    114 ##### SETUP
    115 #
    116 # Here we create three sets of keys: one using "tor", one using "tor
    117 # --keygen", and one using "tor --keygen" and encryption.  We'll be
    118 # copying them into different keys directories in order to simulate
    119 # different kinds of configuration problems/issues.
    120 
    121 # Step 1: Start Tor with --list-fingerprint --quiet.  Make sure everything is there.
    122 mkdir "${DATA_DIR}/orig"
    123 ${TOR} --DataDirectory "${DATA_DIR}/orig" ${SILENTLY} --list-fingerprint > /dev/null
    124 
    125 check_dir "${DATA_DIR}/orig/keys"
    126 check_file "${DATA_DIR}/orig/keys/ed25519_master_id_public_key"
    127 check_file "${DATA_DIR}/orig/keys/ed25519_master_id_secret_key"
    128 check_file "${DATA_DIR}/orig/keys/ed25519_signing_cert"
    129 check_file "${DATA_DIR}/orig/keys/ed25519_signing_secret_key"
    130 
    131 # Step 2: Start Tor with --keygen.  Make sure everything is there.
    132 mkdir "${DATA_DIR}/keygen"
    133 ${TOR} --DataDirectory "${DATA_DIR}/keygen" --keygen --no-passphrase 2>"${DATA_DIR}/keygen/stderr"
    134 grep "Not encrypting the secret key" "${DATA_DIR}/keygen/stderr" >/dev/null || die "Tor didn't declare that there would be no encryption"
    135 
    136 check_dir "${DATA_DIR}/keygen/keys"
    137 check_file "${DATA_DIR}/keygen/keys/ed25519_master_id_public_key"
    138 check_file "${DATA_DIR}/keygen/keys/ed25519_master_id_secret_key"
    139 check_file "${DATA_DIR}/keygen/keys/ed25519_signing_cert"
    140 check_file "${DATA_DIR}/keygen/keys/ed25519_signing_secret_key"
    141 
    142 # Step 3: Start Tor with --keygen and a passphrase.
    143 #         Make sure everything is there.
    144 mkdir "${DATA_DIR}/encrypted"
    145 echo "passphrase" | ${TOR} --DataDirectory "${DATA_DIR}/encrypted" --keygen --passphrase-fd 0
    146 
    147 check_dir "${DATA_DIR}/encrypted/keys"
    148 check_file "${DATA_DIR}/encrypted/keys/ed25519_master_id_public_key"
    149 check_file "${DATA_DIR}/encrypted/keys/ed25519_master_id_secret_key_encrypted"
    150 check_file "${DATA_DIR}/encrypted/keys/ed25519_signing_cert"
    151 check_file "${DATA_DIR}/encrypted/keys/ed25519_signing_secret_key"
    152 
    153 
    154 echo "=== Starting keygen tests."
    155 
    156 #
    157 # The "case X" numbers below come from s7r's email on
    158 #   https://lists.torproject.org/pipermail/tor-dev/2015-August/009204.html
    159 
    160 
    161 # Case 2a: Missing secret key, public key exists, start tor.
    162 
    163 if [ "$CASE2A" = 1 ]; then
    164 
    165 ME="${DATA_DIR}/case2a"
    166 SRC="${DATA_DIR}/orig"
    167 mkdir -p "${ME}/keys"
    168 cp "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/"
    169 if ${TOR} --DataDirectory "${ME}" --list-fingerprint > "${ME}/stdout"; then
    170  die "Somehow succeeded when missing secret key, certs: $(cat "${ME}/stdout")"
    171 fi
    172 check_files_eq "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/ed25519_master_id_public_key"
    173 
    174 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"
    175 
    176 echo "==== Case 2A ok"
    177 fi
    178 
    179 # Case 2b: Encrypted secret key, public key exists, start tor.
    180 
    181 if [ "$CASE2B" = 1 ]; then
    182 
    183 ME="${DATA_DIR}/case2b"
    184 SRC="${DATA_DIR}/encrypted"
    185 
    186 mkdir -p "${ME}/keys"
    187 cp "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/"
    188 cp "${SRC}/keys/ed25519_master_id_secret_key_encrypted" "${ME}/keys/"
    189 ${TOR} --DataDirectory "${ME}" --list-fingerprint > "${ME}/stdout" && dir "Somehow succeeded with encrypted secret key, missing certs"
    190 
    191 check_files_eq "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/ed25519_master_id_public_key"
    192 check_files_eq "${SRC}/keys/ed25519_master_id_secret_key_encrypted" "${ME}/keys/ed25519_master_id_secret_key_encrypted"
    193 
    194 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."
    195 
    196 echo "==== Case 2B ok"
    197 
    198 fi
    199 
    200 # Case 3a: Start Tor with only master key.
    201 
    202 if [ "$CASE3A" = 1 ]; then
    203 
    204 ME="${DATA_DIR}/case3a"
    205 SRC="${DATA_DIR}/orig"
    206 
    207 mkdir -p "${ME}/keys"
    208 cp "${SRC}/keys/ed25519_master_id_"* "${ME}/keys/"
    209 ${TOR} --DataDirectory "${ME}" ${SILENTLY} --list-fingerprint >/dev/null || die "Tor failed when starting with only master key"
    210 check_files_eq "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/ed25519_master_id_public_key"
    211 check_files_eq "${SRC}/keys/ed25519_master_id_secret_key" "${ME}/keys/ed25519_master_id_secret_key"
    212 check_file "${ME}/keys/ed25519_signing_cert"
    213 check_file "${ME}/keys/ed25519_signing_secret_key"
    214 
    215 echo "==== Case 3A ok"
    216 
    217 fi
    218 
    219 # Case 3b: Call keygen with only unencrypted master key.
    220 
    221 if [ "$CASE3B" = 1 ]; then
    222 
    223 ME="${DATA_DIR}/case3b"
    224 SRC="${DATA_DIR}/orig"
    225 
    226 mkdir -p "${ME}/keys"
    227 cp "${SRC}/keys/ed25519_master_id_"* "${ME}/keys/"
    228 ${TOR} --DataDirectory "${ME}" --keygen || die "Keygen failed with only master key"
    229 check_files_eq "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/ed25519_master_id_public_key"
    230 check_files_eq "${SRC}/keys/ed25519_master_id_secret_key" "${ME}/keys/ed25519_master_id_secret_key"
    231 check_file "${ME}/keys/ed25519_signing_cert"
    232 check_file "${ME}/keys/ed25519_signing_secret_key"
    233 
    234 echo "==== Case 3B ok"
    235 
    236 fi
    237 
    238 # Case 3c: Call keygen with only encrypted master key.
    239 
    240 if [ "$CASE3C" = 1 ]; then
    241 
    242 ME="${DATA_DIR}/case3c"
    243 SRC="${DATA_DIR}/encrypted"
    244 
    245 mkdir -p "${ME}/keys"
    246 cp "${SRC}/keys/ed25519_master_id_"* "${ME}/keys/"
    247 echo "passphrase" | ${TOR} --DataDirectory "${ME}" --keygen --passphrase-fd 0 || die "Keygen failed with only encrypted master key"
    248 check_files_eq "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/ed25519_master_id_public_key"
    249 check_files_eq "${SRC}/keys/ed25519_master_id_secret_key_encrypted" "${ME}/keys/ed25519_master_id_secret_key_encrypted"
    250 check_file "${ME}/keys/ed25519_signing_cert"
    251 check_file "${ME}/keys/ed25519_signing_secret_key"
    252 
    253 echo "==== Case 3C ok"
    254 
    255 fi
    256 
    257 # Case 4: Make a new data directory with only an unencrypted secret key.
    258 #         Then start tor.  The rest should become correct.
    259 
    260 if [ "$CASE4" = 1 ]; then
    261 
    262 ME="${DATA_DIR}/case4"
    263 SRC="${DATA_DIR}/orig"
    264 
    265 mkdir -p "${ME}/keys"
    266 cp "${SRC}/keys/ed25519_master_id_secret_key" "${ME}/keys/"
    267 ${TOR} --DataDirectory "${ME}" ${SILENTLY} --list-fingerprint > "${ME}/fp1" || die "Tor wouldn't start with only unencrypted secret key"
    268 check_file "${ME}/keys/ed25519_master_id_public_key"
    269 check_file "${ME}/keys/ed25519_signing_cert"
    270 check_file "${ME}/keys/ed25519_signing_secret_key"
    271 ${TOR} --DataDirectory "${ME}" ${SILENTLY} --list-fingerprint > "${ME}/fp2" || die "Tor wouldn't start again after starting once with only unencrypted secret key."
    272 
    273 check_files_eq "${ME}/fp1" "${ME}/fp2"
    274 
    275 echo "==== Case 4 ok"
    276 
    277 fi
    278 
    279 # Case 5: Make a new data directory with only an encrypted secret key.
    280 
    281 if [ "$CASE5" = 1 ]; then
    282 
    283 ME="${DATA_DIR}/case5"
    284 SRC="${DATA_DIR}/encrypted"
    285 
    286 mkdir -p "${ME}/keys"
    287 cp "${SRC}/keys/ed25519_master_id_secret_key_encrypted" "${ME}/keys/"
    288 ${TOR} --DataDirectory "${ME}" --list-fingerprint >"${ME}/stdout" && die "Tor started with only encrypted secret key!"
    289 check_no_file "${ME}/keys/ed25519_master_id_public_key"
    290 check_no_file "${ME}/keys/ed25519_master_id_public_key"
    291 
    292 grep "but not public key file" "${ME}/stdout" >/dev/null || die "Tor didn't declare it couldn't find a public key."
    293 
    294 echo "==== Case 5 ok"
    295 
    296 fi
    297 
    298 # Case 6: Make a new data directory with encrypted secret key and public key
    299 
    300 if [ "$CASE6" = 1 ]; then
    301 
    302 ME="${DATA_DIR}/case6"
    303 SRC="${DATA_DIR}/encrypted"
    304 
    305 mkdir -p "${ME}/keys"
    306 cp "${SRC}/keys/ed25519_master_id_secret_key_encrypted" "${ME}/keys/"
    307 cp "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/"
    308 if ${TOR} --DataDirectory "${ME}" --list-fingerprint > "${ME}/stdout"; then
    309  die "Tor started with encrypted secret key and no certs"
    310 fi
    311 check_no_file "${ME}/keys/ed25519_signing_cert"
    312 check_no_file "${ME}/keys/ed25519_signing_secret_key"
    313 
    314 grep "but it was encrypted" "${ME}/stdout" >/dev/null || die "Tor didn't declare that the secret key was encrypted."
    315 
    316 echo "==== Case 6 ok"
    317 
    318 fi
    319 
    320 # Case 7: Make a new data directory with unencrypted secret key and
    321 # certificates; missing master public.
    322 
    323 if [ "$CASE7" = 1 ]; then
    324 
    325 ME="${DATA_DIR}/case7"
    326 SRC="${DATA_DIR}/keygen"
    327 
    328 mkdir -p "${ME}/keys"
    329 cp "${SRC}/keys/ed25519_master_id_secret_key" "${ME}/keys/"
    330 cp "${SRC}/keys/ed25519_signing_cert" "${ME}/keys/"
    331 cp "${SRC}/keys/ed25519_signing_secret_key" "${ME}/keys/"
    332 
    333 ${TOR} --DataDirectory "${ME}" ${SILENTLY} --list-fingerprint >/dev/null || die "Failed when starting with missing public key"
    334 check_keys_eq ed25519_master_id_secret_key
    335 check_keys_eq ed25519_master_id_public_key
    336 check_keys_eq ed25519_signing_secret_key
    337 check_keys_eq ed25519_signing_cert
    338 
    339 echo "==== Case 7 ok"
    340 
    341 fi
    342 
    343 # Case 8: offline master secret key.
    344 
    345 if [ "$CASE8" = 1 ]; then
    346 
    347 ME="${DATA_DIR}/case8"
    348 SRC="${DATA_DIR}/keygen"
    349 
    350 mkdir -p "${ME}/keys"
    351 cp "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/"
    352 cp "${SRC}/keys/ed25519_signing_cert" "${ME}/keys/"
    353 cp "${SRC}/keys/ed25519_signing_secret_key" "${ME}/keys/"
    354 
    355 ${TOR} --DataDirectory "${ME}" ${SILENTLY} --list-fingerprint >/dev/null || die "Failed when starting with offline secret key"
    356 check_no_file "${ME}/keys/ed25519_master_id_secret_key"
    357 check_keys_eq ed25519_master_id_public_key
    358 check_keys_eq ed25519_signing_secret_key
    359 check_keys_eq ed25519_signing_cert
    360 
    361 echo "==== Case 8 ok"
    362 
    363 fi
    364 
    365 # Case 9: signing cert and secret key provided; could infer master key.
    366 
    367 if [ "$CASE9" = 1 ]; then
    368 
    369 ME="${DATA_DIR}/case9"
    370 SRC="${DATA_DIR}/keygen"
    371 
    372 mkdir -p "${ME}/keys"
    373 cp "${SRC}/keys/ed25519_signing_cert" "${ME}/keys/"
    374 cp "${SRC}/keys/ed25519_signing_secret_key" "${ME}/keys/"
    375 
    376 ${TOR} --DataDirectory "${ME}" ${SILENTLY} --list-fingerprint >/dev/null || die "Failed when starting with only signing material"
    377 check_no_file "${ME}/keys/ed25519_master_id_secret_key"
    378 check_file "${ME}/keys/ed25519_master_id_public_key"
    379 check_keys_eq ed25519_signing_secret_key
    380 check_keys_eq ed25519_signing_cert
    381 
    382 echo "==== Case 9 ok"
    383 
    384 fi
    385 
    386 
    387 # Case 10: master key mismatch.
    388 
    389 if [ "$CASE10" = 1 ]; then
    390 
    391 ME="${DATA_DIR}/case10"
    392 SRC="${DATA_DIR}/keygen"
    393 OTHER="${DATA_DIR}/orig"
    394 
    395 mkdir -p "${ME}/keys"
    396 cp "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/"
    397 cp "${OTHER}/keys/ed25519_master_id_secret_key" "${ME}/keys/"
    398 
    399 if ${TOR} --DataDirectory "${ME}" --list-fingerprint >"${ME}/stdout"; then
    400  die "Successfully started with mismatched keys!?"
    401 fi
    402 
    403 grep "public_key does not match.*secret_key" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a key mismatch"
    404 
    405 echo "==== Case 10 ok"
    406 
    407 fi
    408 
    409 # Case 11a: -passphrase-fd without --keygen
    410 
    411 if [ "$CASE11A" = 1 ]; then
    412 
    413 ME="${DATA_DIR}/case11a"
    414 
    415 mkdir -p "${ME}/keys"
    416 
    417 if ${TOR} --DataDirectory "${ME}" --passphrase-fd 1 > "${ME}/stdout"; then
    418  die "Successfully started with passphrase-fd but no keygen?"
    419 fi
    420 
    421 grep "passphrase-fd specified without --keygen" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
    422 
    423 echo "==== Case 11A ok"
    424 
    425 fi
    426 
    427 # Case 11b: --no-passphrase without --keygen
    428 
    429 if [ "$CASE11B" = 1 ]; then
    430 
    431 ME="${DATA_DIR}/case11b"
    432 
    433 mkdir -p "${ME}/keys"
    434 
    435 if ${TOR} --DataDirectory "${ME}" --no-passphrase > "${ME}/stdout"; then
    436  die "Successfully started with no-passphrase but no keygen?"
    437 fi
    438 
    439 grep "no-passphrase specified without --keygen" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
    440 
    441 echo "==== Case 11B ok"
    442 
    443 fi
    444 
    445 # Case 11c: --newpass without --keygen
    446 
    447 if [ "$CASE11C" = 1 ]; then
    448 
    449 ME="${DATA_DIR}/case11C"
    450 
    451 mkdir -p "${ME}/keys"
    452 
    453 if ${TOR} --DataDirectory "${ME}" --newpass > "${ME}/stdout"; then
    454  die "Successfully started with newpass but no keygen?"
    455 fi
    456 
    457 grep "newpass specified without --keygen" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
    458 
    459 echo "==== Case 11C ok"
    460 
    461 fi
    462 
    463 ######## --master-key does not work yet, but this will test the error case
    464 ########  when it does.
    465 #
    466 # Case 11d: --master-key without --keygen
    467 #
    468 if [ "$CASE11D" = 1 ]; then
    469 #
    470 # ME="${DATA_DIR}/case11d"
    471 #
    472 # mkdir -p "${ME}/keys"
    473 #
    474 # ${TOR} --DataDirectory "${ME}" --master-key "${ME}/foobar" > "${ME}/stdout" && die "Successfully started with master-key but no keygen?" || true
    475 #
    476 # cat "${ME}/stdout"
    477 #
    478 # grep "master-key without --keygen" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
    479 
    480    echo "==== Case 11D skipped"
    481 
    482 fi
    483 
    484 
    485 # Case 11E: Silly passphrase-fd
    486 
    487 if [ "$CASE11E" = 1 ]; then
    488 
    489 ME="${DATA_DIR}/case11E"
    490 
    491 mkdir -p "${ME}/keys"
    492 
    493 if ${TOR} --DataDirectory "${ME}" --keygen --passphrase-fd ewigeblumenkraft > "${ME}/stdout"; then
    494  die "Successfully started with bogus passphrase-fd?"
    495 fi
    496 
    497 grep "Invalid --passphrase-fd value" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
    498 
    499 echo "==== Case 11E ok"
    500 
    501 fi
    502 
    503 
    504 # Case 11F: --no-passphrase with --passphrase-fd
    505 
    506 if [ "$CASE11F" = 1 ]; then
    507 
    508 ME="${DATA_DIR}/case11F"
    509 
    510 mkdir -p "${ME}/keys"
    511 
    512 if ${TOR} --DataDirectory "${ME}" --keygen --passphrase-fd 1 --no-passphrase > "${ME}/stdout"; then
    513  die "Successfully started with bogus passphrase-fd combination?"
    514 fi
    515 
    516 grep "no-passphrase specified with --passphrase-fd" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
    517 
    518 echo "==== Case 11F ok"
    519 
    520 fi
    521 
    522 
    523 # Check cert-only.