#!/bin/bash
-if (( $# != 2));then
- echo "usage: overonion e|d keyfile"
+umask 077
+
+hash_dir=$(mktemp -d)
+
+function die() {
+ echo "$*" >&2
exit 1
+}
+
+if (( $# != 2));then
+ die "usage: overonion e|d keyfile"
fi
mode=$1
if [[ "$mode" != e && "$mode" != d ]];then
- echo "Use 'e' for encrypt or 'd' for decrypt"
- exit 1
+ die "Use 'e' for encrypt or 'd' for decrypt"
fi
keyfile=$2
if [[ ! -e "$keyfile" ]];then
- echo "Keyfile not found"
- exit 1
+ die "Keyfile not found"
fi
if [[ ! -r "$keyfile" ]];then
- echo "Cannot read keyfile"
- exit 1
+ die "Cannot read keyfile"
fi
num_layers=$(wc -l < "$keyfile")
if (( num_layers < 20 ));then
- echo "Keyfile doesn't have enough layers to be an onion"
- exit 1
+ die "Keyfile doesn't have enough layers to be an onion"
fi
if [[ "$mode" == e ]];then
if (( layer == 0 || layer > num_layers ));then
cat
else
- openssl enc $openssl_decrypt "-$(sed -n "${layer}s/ .*//p" "$keyfile")" \
- -pass fd:37 37< <(sed -n "${layer}s/^[^ ]* //p" "$keyfile") |
- go $(( layer + next_layer ))
+ operation=$(sed -n "${layer}{;s/ .*//;p;}" "$keyfile")
+ if [[ "$operation" == openssl-enc ]];then
+ openssl enc $openssl_decrypt "-$(sed -rn "${layer}s/[^ ]+ ([^ ]+) .*/\\1/p" "$keyfile")" \
+ -pass fd:37 37< <(sed -rn "${layer}s/^[^ ]+ [^ ]+ //p" "$keyfile")
+ elif [[ "$operation" == reverse ]];then
+ reverse
+ elif [[ "$operation" == openssl-dgst ]];then
+ tee >(echo "$(sed -n "${layer}p" "$keyfile") $(openssl dgst -binary "-$(sed -rn "${layer}s/^[^ ]+ ([^ ]+).*/\\1/p" "$keyfile")" | base64 --wrap=0)" > "$hash_dir/$layer")
+ else
+ die "Unknown operation"
+ fi |
+ go $(( layer + next_layer ))
fi
}
go "$first_layer"
+
+for hash_result in "$hash_dir"/*;do
+ layer=$(basename "$hash_result")
+ if [[ "$mode" == e ]];then
+ # Add the hashes to keyfile
+ key_aside_dir=$(mktemp -d "$keyfile.XXXXXXXXXX")
+ key_aside="$key_aside_dir/key.orig"
+ mv "$keyfile" "$key_aside"
+ sed "${layer}s,.*,$(< "$hash_result")," "$key_aside" > "$keyfile"
+ shred -u "$key_aside"
+ rmdir "$key_aside_dir"
+ else
+ # Verify the hashes
+ if [[ "$(awk '{ print $3 == $4 ? "hash ok" : "mismatch" }' "$hash_result")" != "hash ok" ]];then
+ die "Hash check $layer failed"
+ fi
+ fi
+done
+
+rm -r "$hash_dir"