2015-08-06 03:09:21 +02:00
#!/bin/sh
# Note: some of this code is lifted from zero_length_keys.sh, and could be
# unified.
umask 077
set -e
if [ $# -eq 0 ] || [ ! -f ${ 1 } ] || [ ! -x ${ 1 } ] ; then
2015-08-07 21:22:23 +02:00
if [ " $TESTING_TOR_BINARY " = "" ] ; then
2015-08-06 17:27:25 +02:00
echo " Usage: ${ 0 } PATH_TO_TOR [case-number] "
exit 1
fi
fi
2018-07-17 03:24:02 +02:00
UNAME_OS = ` uname -s | cut -d_ -f1`
if test " $UNAME_OS " = 'CYGWIN' || \
test " $UNAME_OS " = 'MSYS' || \
test " $UNAME_OS " = 'MINGW' ; then
echo "This test is unreliable on Windows. See trac #26076. Skipping." >& 2
exit 77
fi
2015-08-06 17:27:25 +02:00
if [ $# -ge 1 ] ; then
2015-08-06 03:09:21 +02:00
TOR_BINARY = " ${ 1 } "
shift
2015-08-06 17:27:25 +02:00
else
TOR_BINARY = " ${ TESTING_TOR_BINARY } "
fi
2015-08-06 03:09:21 +02:00
if [ $# -ge 1 ] ; then
dflt = 0
else
dflt = 1
fi
CASE2A = $dflt
CASE2B = $dflt
CASE3A = $dflt
CASE3B = $dflt
CASE3C = $dflt
CASE4 = $dflt
CASE5 = $dflt
CASE6 = $dflt
CASE7 = $dflt
CASE8 = $dflt
CASE9 = $dflt
CASE10 = $dflt
2017-10-21 01:10:05 +02:00
CASE11A = $dflt
CASE11B = $dflt
CASE11C = $dflt
CASE11D = $dflt
CASE11E = $dflt
CASE11F = $dflt
2015-08-06 03:09:21 +02:00
if [ $# -ge 1 ] ; then
eval " CASE ${ 1 } " = 1
fi
2015-08-06 17:27:25 +02:00
2015-08-06 03:09:21 +02:00
2015-09-03 18:51:58 +02:00
dump( ) { xxd -p " $1 " | tr -d '\n ' ; }
2015-08-06 03:09:21 +02:00
die( ) { echo " $1 " >& 2 ; exit 5; }
check_dir( ) { [ -d " $1 " ] || die " $1 did not exist " ; }
check_file( ) { [ -e " $1 " ] || die " $1 did not exist " ; }
check_no_file( ) { [ -e " $1 " ] && die " $1 was not supposed to exist " || true; }
2015-09-03 18:51:58 +02:00
check_files_eq( ) { cmp " $1 " " $2 " || die " $1 and $2 did not match: `dump $1 ` vs `dump $2 ` " ; }
2015-08-06 03:09:21 +02:00
check_keys_eq( ) { check_files_eq " ${ SRC } /keys/ ${ 1 } " " ${ ME } /keys/ ${ 1 } " ; }
DATA_DIR = ` mktemp -d -t tor_keygen_tests.XXXXXX`
if [ -z " $DATA_DIR " ] ; then
echo "Failure: mktemp invocation returned empty string" >& 2
exit 3
fi
if [ ! -d " $DATA_DIR " ] ; then
echo "Failure: mktemp invocation result doesn't point to directory" >& 2
exit 3
fi
trap " rm -rf ' $DATA_DIR ' " 0
2015-09-03 20:53:50 +02:00
# Use an absolute path for this or Tor will complain
DATA_DIR = ` cd " ${ DATA_DIR } " && pwd `
2015-08-06 03:09:21 +02:00
touch " ${ DATA_DIR } /empty_torrc "
2015-08-06 17:12:44 +02:00
QUIETLY = "--hush"
2015-09-03 21:23:10 +02:00
SILENTLY = "--quiet"
2015-08-06 17:12:44 +02:00
TOR = " ${ TOR_BINARY } ${ QUIETLY } --DisableNetwork 1 --ShutdownWaitLength 0 --ORPort 12345 --ExitRelay 0 -f ${ DATA_DIR } /empty_torrc "
2015-08-06 03:09:21 +02:00
2015-08-06 17:58:50 +02:00
##### SETUP
#
# Here we create three sets of keys: one using "tor", one using "tor
# --keygen", and one using "tor --keygen" and encryption. We'll be
# copying them into different keys directories in order to simulate
# different kinds of configuration problems/issues.
2015-09-03 21:23:10 +02:00
# Step 1: Start Tor with --list-fingerprint --quiet. Make sure everything is there.
2015-08-06 03:09:21 +02:00
mkdir " ${ DATA_DIR } /orig "
2015-09-03 21:23:10 +02:00
${ TOR } --DataDirectory " ${ DATA_DIR } /orig " --list-fingerprint ${ SILENTLY } > /dev/null
2015-08-06 03:09:21 +02:00
check_dir " ${ DATA_DIR } /orig/keys "
check_file " ${ DATA_DIR } /orig/keys/ed25519_master_id_public_key "
check_file " ${ DATA_DIR } /orig/keys/ed25519_master_id_secret_key "
check_file " ${ DATA_DIR } /orig/keys/ed25519_signing_cert "
check_file " ${ DATA_DIR } /orig/keys/ed25519_signing_secret_key "
# Step 2: Start Tor with --keygen. Make sure everything is there.
mkdir " ${ DATA_DIR } /keygen "
2015-08-06 17:12:44 +02:00
${ TOR } --DataDirectory " ${ DATA_DIR } /keygen " --keygen --no-passphrase 2>" ${ DATA_DIR } /keygen/stderr "
grep "Not encrypting the secret key" " ${ DATA_DIR } /keygen/stderr " >/dev/null || die "Tor didn't declare that there would be no encryption"
2015-08-06 03:09:21 +02:00
check_dir " ${ DATA_DIR } /keygen/keys "
check_file " ${ DATA_DIR } /keygen/keys/ed25519_master_id_public_key "
check_file " ${ DATA_DIR } /keygen/keys/ed25519_master_id_secret_key "
check_file " ${ DATA_DIR } /keygen/keys/ed25519_signing_cert "
check_file " ${ DATA_DIR } /keygen/keys/ed25519_signing_secret_key "
# Step 3: Start Tor with --keygen and a passphrase.
# Make sure everything is there.
mkdir " ${ DATA_DIR } /encrypted "
echo "passphrase" | ${ TOR } --DataDirectory " ${ DATA_DIR } /encrypted " --keygen --passphrase-fd 0
check_dir " ${ DATA_DIR } /encrypted/keys "
check_file " ${ DATA_DIR } /encrypted/keys/ed25519_master_id_public_key "
check_file " ${ DATA_DIR } /encrypted/keys/ed25519_master_id_secret_key_encrypted "
check_file " ${ DATA_DIR } /encrypted/keys/ed25519_signing_cert "
check_file " ${ DATA_DIR } /encrypted/keys/ed25519_signing_secret_key "
2015-09-03 16:53:04 +02:00
echo "=== Starting keygen tests."
2015-08-06 03:09:21 +02:00
#
# The "case X" numbers below come from s7r's email on
# https://lists.torproject.org/pipermail/tor-dev/2015-August/009204.html
# Case 2a: Missing secret key, public key exists, start tor.
if [ " $CASE2A " = 1 ] ; then
ME = " ${ DATA_DIR } /case2a "
SRC = " ${ DATA_DIR } /orig "
mkdir -p " ${ ME } /keys "
cp " ${ SRC } /keys/ed25519_master_id_public_key " " ${ ME } /keys/ "
2015-09-03 16:53:04 +02:00
${ TOR } --DataDirectory " ${ ME } " --list-fingerprint > " ${ ME } /stdout " && die " Somehow succeeded when missing secret key, certs: `cat ${ ME } /stdout` " || true
2015-08-06 03:09:21 +02:00
check_files_eq " ${ SRC } /keys/ed25519_master_id_public_key " " ${ ME } /keys/ed25519_master_id_public_key "
2015-08-06 17:57:00 +02:00
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"
2015-08-06 03:09:21 +02:00
echo "==== Case 2A ok"
fi
# Case 2b: Encrypted secret key, public key exists, start tor.
if [ " $CASE2B " = 1 ] ; then
ME = " ${ DATA_DIR } /case2b "
SRC = " ${ DATA_DIR } /encrypted "
mkdir -p " ${ ME } /keys "
cp " ${ SRC } /keys/ed25519_master_id_public_key " " ${ ME } /keys/ "
cp " ${ SRC } /keys/ed25519_master_id_secret_key_encrypted " " ${ ME } /keys/ "
2015-08-06 17:57:00 +02:00
${ TOR } --DataDirectory " ${ ME } " --list-fingerprint > " ${ ME } /stdout " && dir "Somehow succeeded with encrypted secret key, missing certs"
2015-08-06 03:09:21 +02:00
check_files_eq " ${ SRC } /keys/ed25519_master_id_public_key " " ${ ME } /keys/ed25519_master_id_public_key "
check_files_eq " ${ SRC } /keys/ed25519_master_id_secret_key_encrypted " " ${ ME } /keys/ed25519_master_id_secret_key_encrypted "
2015-08-06 17:57:00 +02:00
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."
2015-08-06 03:09:21 +02:00
echo "==== Case 2B ok"
fi
# Case 3a: Start Tor with only master key.
if [ " $CASE3A " = 1 ] ; then
ME = " ${ DATA_DIR } /case3a "
SRC = " ${ DATA_DIR } /orig "
mkdir -p " ${ ME } /keys "
cp " ${ SRC } /keys/ed25519_master_id_ " * " ${ ME } /keys/ "
2015-09-03 21:23:10 +02:00
${ TOR } --DataDirectory " ${ ME } " --list-fingerprint ${ SILENTLY } >/dev/null || die "Tor failed when starting with only master key"
2015-08-06 03:09:21 +02:00
check_files_eq " ${ SRC } /keys/ed25519_master_id_public_key " " ${ ME } /keys/ed25519_master_id_public_key "
check_files_eq " ${ SRC } /keys/ed25519_master_id_secret_key " " ${ ME } /keys/ed25519_master_id_secret_key "
check_file " ${ ME } /keys/ed25519_signing_cert "
check_file " ${ ME } /keys/ed25519_signing_secret_key "
echo "==== Case 3A ok"
fi
# Case 3b: Call keygen with only unencrypted master key.
if [ " $CASE3B " = 1 ] ; then
ME = " ${ DATA_DIR } /case3b "
SRC = " ${ DATA_DIR } /orig "
mkdir -p " ${ ME } /keys "
cp " ${ SRC } /keys/ed25519_master_id_ " * " ${ ME } /keys/ "
${ TOR } --DataDirectory " ${ ME } " --keygen || die "Keygen failed with only master key"
check_files_eq " ${ SRC } /keys/ed25519_master_id_public_key " " ${ ME } /keys/ed25519_master_id_public_key "
check_files_eq " ${ SRC } /keys/ed25519_master_id_secret_key " " ${ ME } /keys/ed25519_master_id_secret_key "
check_file " ${ ME } /keys/ed25519_signing_cert "
check_file " ${ ME } /keys/ed25519_signing_secret_key "
echo "==== Case 3B ok"
fi
# Case 3c: Call keygen with only encrypted master key.
if [ " $CASE3C " = 1 ] ; then
ME = " ${ DATA_DIR } /case3c "
SRC = " ${ DATA_DIR } /encrypted "
mkdir -p " ${ ME } /keys "
cp " ${ SRC } /keys/ed25519_master_id_ " * " ${ ME } /keys/ "
echo "passphrase" | ${ TOR } --DataDirectory " ${ ME } " --keygen --passphrase-fd 0 || die "Keygen failed with only encrypted master key"
check_files_eq " ${ SRC } /keys/ed25519_master_id_public_key " " ${ ME } /keys/ed25519_master_id_public_key "
check_files_eq " ${ SRC } /keys/ed25519_master_id_secret_key_encrypted " " ${ ME } /keys/ed25519_master_id_secret_key_encrypted "
check_file " ${ ME } /keys/ed25519_signing_cert "
check_file " ${ ME } /keys/ed25519_signing_secret_key "
echo "==== Case 3C ok"
fi
# Case 4: Make a new data directory with only an unencrypted secret key.
# Then start tor. The rest should become correct.
if [ " $CASE4 " = 1 ] ; then
ME = " ${ DATA_DIR } /case4 "
SRC = " ${ DATA_DIR } /orig "
mkdir -p " ${ ME } /keys "
cp " ${ SRC } /keys/ed25519_master_id_secret_key " " ${ ME } /keys/ "
2015-09-03 21:23:10 +02:00
${ TOR } --DataDirectory " ${ ME } " --list-fingerprint ${ SILENTLY } > " ${ ME } /fp1 " || die "Tor wouldn't start with only unencrypted secret key"
2015-08-06 03:09:21 +02:00
check_file " ${ ME } /keys/ed25519_master_id_public_key "
2015-08-06 17:12:44 +02:00
check_file " ${ ME } /keys/ed25519_signing_cert "
check_file " ${ ME } /keys/ed25519_signing_secret_key "
2015-09-03 21:23:10 +02:00
${ TOR } --DataDirectory " ${ ME } " --list-fingerprint ${ SILENTLY } > " ${ ME } /fp2 " || die "Tor wouldn't start again after starting once with only unencrypted secret key."
2015-08-06 17:30:04 +02:00
check_files_eq " ${ ME } /fp1 " " ${ ME } /fp2 "
2015-08-06 03:09:21 +02:00
echo "==== Case 4 ok"
fi
# Case 5: Make a new data directory with only an encrypted secret key.
if [ " $CASE5 " = 1 ] ; then
ME = " ${ DATA_DIR } /case5 "
SRC = " ${ DATA_DIR } /encrypted "
mkdir -p " ${ ME } /keys "
cp " ${ SRC } /keys/ed25519_master_id_secret_key_encrypted " " ${ ME } /keys/ "
2015-08-06 17:57:00 +02:00
${ TOR } --DataDirectory " ${ ME } " --list-fingerprint >" ${ ME } /stdout " && die "Tor started with only encrypted secret key!"
2015-08-06 17:12:44 +02:00
check_no_file " ${ ME } /keys/ed25519_master_id_public_key "
check_no_file " ${ ME } /keys/ed25519_master_id_public_key "
2015-08-06 03:09:21 +02:00
2015-08-06 17:57:00 +02:00
grep "but not public key file" " ${ ME } /stdout " >/dev/null || die "Tor didn't declare it couldn't find a public key."
2015-08-06 03:09:21 +02:00
echo "==== Case 5 ok"
fi
# Case 6: Make a new data directory with encrypted secret key and public key
if [ " $CASE6 " = 1 ] ; then
ME = " ${ DATA_DIR } /case6 "
SRC = " ${ DATA_DIR } /encrypted "
mkdir -p " ${ ME } /keys "
cp " ${ SRC } /keys/ed25519_master_id_secret_key_encrypted " " ${ ME } /keys/ "
cp " ${ SRC } /keys/ed25519_master_id_public_key " " ${ ME } /keys/ "
2015-08-06 17:57:00 +02:00
${ TOR } --DataDirectory " ${ ME } " --list-fingerprint > " ${ ME } /stdout " && die "Tor started with encrypted secret key and no certs" || true
2015-08-06 03:09:21 +02:00
check_no_file " ${ ME } /keys/ed25519_signing_cert "
check_no_file " ${ ME } /keys/ed25519_signing_secret_key "
2015-08-06 17:57:00 +02:00
grep "but it was encrypted" " ${ ME } /stdout " >/dev/null || die "Tor didn't declare that the secret key was encrypted."
2015-08-06 03:09:21 +02:00
echo "==== Case 6 ok"
fi
# Case 7: Make a new data directory with unencrypted secret key and
# certificates; missing master public.
if [ " $CASE7 " = 1 ] ; then
ME = " ${ DATA_DIR } /case7 "
SRC = " ${ DATA_DIR } /keygen "
mkdir -p " ${ ME } /keys "
cp " ${ SRC } /keys/ed25519_master_id_secret_key " " ${ ME } /keys/ "
cp " ${ SRC } /keys/ed25519_signing_cert " " ${ ME } /keys/ "
cp " ${ SRC } /keys/ed25519_signing_secret_key " " ${ ME } /keys/ "
2015-09-03 21:23:10 +02:00
${ TOR } --DataDirectory " ${ ME } " --list-fingerprint ${ SILENTLY } >/dev/null || die "Failed when starting with missing public key"
2015-08-06 03:09:21 +02:00
check_keys_eq ed25519_master_id_secret_key
check_keys_eq ed25519_master_id_public_key
check_keys_eq ed25519_signing_secret_key
check_keys_eq ed25519_signing_cert
echo "==== Case 7 ok"
fi
# Case 8: offline master secret key.
if [ " $CASE8 " = 1 ] ; then
ME = " ${ DATA_DIR } /case8 "
SRC = " ${ DATA_DIR } /keygen "
mkdir -p " ${ ME } /keys "
cp " ${ SRC } /keys/ed25519_master_id_public_key " " ${ ME } /keys/ "
cp " ${ SRC } /keys/ed25519_signing_cert " " ${ ME } /keys/ "
cp " ${ SRC } /keys/ed25519_signing_secret_key " " ${ ME } /keys/ "
2015-09-03 21:23:10 +02:00
${ TOR } --DataDirectory " ${ ME } " --list-fingerprint ${ SILENTLY } >/dev/null || die "Failed when starting with offline secret key"
2015-08-06 03:09:21 +02:00
check_no_file " ${ ME } /keys/ed25519_master_id_secret_key "
check_keys_eq ed25519_master_id_public_key
check_keys_eq ed25519_signing_secret_key
check_keys_eq ed25519_signing_cert
echo "==== Case 8 ok"
fi
# Case 9: signing cert and secret key provided; could infer master key.
if [ " $CASE9 " = 1 ] ; then
ME = " ${ DATA_DIR } /case9 "
SRC = " ${ DATA_DIR } /keygen "
mkdir -p " ${ ME } /keys "
cp " ${ SRC } /keys/ed25519_signing_cert " " ${ ME } /keys/ "
cp " ${ SRC } /keys/ed25519_signing_secret_key " " ${ ME } /keys/ "
2015-09-03 21:23:10 +02:00
${ TOR } --DataDirectory " ${ ME } " --list-fingerprint ${ SILENTLY } >/dev/null || die "Failed when starting with only signing material"
2015-08-06 03:09:21 +02:00
check_no_file " ${ ME } /keys/ed25519_master_id_secret_key "
2015-08-07 21:22:23 +02:00
check_file " ${ ME } /keys/ed25519_master_id_public_key "
2015-08-06 03:09:21 +02:00
check_keys_eq ed25519_signing_secret_key
check_keys_eq ed25519_signing_cert
echo "==== Case 9 ok"
fi
2015-08-06 17:12:44 +02:00
# Case 10: master key mismatch.
2015-08-06 03:09:21 +02:00
if [ " $CASE10 " = 1 ] ; then
ME = " ${ DATA_DIR } /case10 "
SRC = " ${ DATA_DIR } /keygen "
OTHER = " ${ DATA_DIR } /orig "
mkdir -p " ${ ME } /keys "
cp " ${ SRC } /keys/ed25519_master_id_public_key " " ${ ME } /keys/ "
cp " ${ OTHER } /keys/ed25519_master_id_secret_key " " ${ ME } /keys/ "
2015-08-06 17:57:00 +02:00
${ TOR } --DataDirectory " ${ ME } " --list-fingerprint >" ${ ME } /stdout " && die "Successfully started with mismatched keys!?" || true
grep "public_key does not match.*secret_key" " ${ ME } /stdout " >/dev/null || die "Tor didn't declare that there was a key mismatch"
2015-08-06 03:09:21 +02:00
echo "==== Case 10 ok"
fi
2017-10-21 01:10:05 +02:00
# Case 11a: -passphrase-fd without --keygen
if [ " $CASE11A " = 1 ] ; then
ME = " ${ DATA_DIR } /case11a "
mkdir -p " ${ ME } /keys "
${ TOR } --DataDirectory " ${ ME } " --passphrase-fd 1 > " ${ ME } /stdout " && die "Successfully started with passphrase-fd but no keygen?" || true
grep "passphrase-fd specified without --keygen" " ${ ME } /stdout " >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
echo "==== Case 11A ok"
fi
# Case 11b: --no-passphrase without --keygen
if [ " $CASE11B " = 1 ] ; then
ME = " ${ DATA_DIR } /case11b "
mkdir -p " ${ ME } /keys "
${ TOR } --DataDirectory " ${ ME } " --no-passphrase > " ${ ME } /stdout " && die "Successfully started with no-passphrase but no keygen?" || true
grep "no-passphrase specified without --keygen" " ${ ME } /stdout " >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
echo "==== Case 11B ok"
fi
# Case 11c: --newpass without --keygen
if [ " $CASE11C " = 1 ] ; then
ME = " ${ DATA_DIR } /case11C "
mkdir -p " ${ ME } /keys "
${ TOR } --DataDirectory " ${ ME } " --newpass > " ${ ME } /stdout " && die "Successfully started with newpass but no keygen?" || true
grep "newpass specified without --keygen" " ${ ME } /stdout " >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
echo "==== Case 11C ok"
fi
######## --master-key does not work yet, but this will test the error case
######## when it does.
#
# Case 11d: --master-key without --keygen
#
if [ " $CASE11D " = 1 ] ; then
#
# ME="${DATA_DIR}/case11d"
#
# mkdir -p "${ME}/keys"
#
# ${TOR} --DataDirectory "${ME}" --master-key "${ME}/foobar" > "${ME}/stdout" && die "Successfully started with master-key but no keygen?" || true
#
# cat "${ME}/stdout"
#
# grep "master-key without --keygen" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
echo "==== Case 11D skipped"
fi
# Case 11E: Silly passphrase-fd
if [ " $CASE11E " = 1 ] ; then
ME = " ${ DATA_DIR } /case11E "
mkdir -p " ${ ME } /keys "
${ TOR } --DataDirectory " ${ ME } " --keygen --passphrase-fd ewigeblumenkraft > " ${ ME } /stdout " && die "Successfully started with bogus passphrase-fd?" || true
grep "Invalid --passphrase-fd value" " ${ ME } /stdout " >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
echo "==== Case 11E ok"
fi
# Case 11F: --no-passphrase with --passphrase-fd
if [ " $CASE11F " = 1 ] ; then
ME = " ${ DATA_DIR } /case11F "
mkdir -p " ${ ME } /keys "
${ TOR } --DataDirectory " ${ ME } " --keygen --passphrase-fd 1 --no-passphrase > " ${ ME } /stdout " && die "Successfully started with bogus passphrase-fd combination?" || true
grep "no-passphrase specified with --passphrase-fd" " ${ ME } /stdout " >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
echo "==== Case 11F ok"
fi
2015-08-06 03:09:21 +02:00
# Check cert-only.