]> git.scottworley.com Git - overonion/blame_incremental - overonion
keyline() and keyfield() operations
[overonion] / overonion
... / ...
CommitLineData
1#!/bin/bash
2
3umask 077
4
5hash_dir=$(mktemp -d)
6
7function die() {
8 echo "$*" >&2
9 exit 1
10}
11
12if (( $# != 2));then
13 die "usage: overonion e|d keyfile"
14fi
15mode=$1
16if [[ "$mode" != e && "$mode" != d ]];then
17 die "Use 'e' for encrypt or 'd' for decrypt"
18fi
19keyfile=$2
20if [[ ! -e "$keyfile" ]];then
21 die "Keyfile not found"
22fi
23if [[ ! -r "$keyfile" ]];then
24 die "Cannot read keyfile"
25fi
26
27num_layers=$(wc -l < "$keyfile")
28if (( num_layers < 20 ));then
29 die "Keyfile doesn't have enough layers to be an onion"
30fi
31
32hash_fields=$(awk '/^openssl-dgst / { print NF }' "$keyfile" | uniq )
33
34if [[ "$mode" == e ]];then
35 first_layer=$num_layers
36 next_layer=-1
37 openssl_decrypt=""
38 if [[ "$hash_fields" != 4 ]];then
39 die "Refusing to encrypt with already-used key"
40 fi
41else
42 first_layer=1
43 next_layer=1
44 openssl_decrypt="-d"
45 if [[ "$hash_fields" != 5 ]];then
46 die "Key does not appear to have been used for encryption (it has no embedded hashes). Refusing to decrypt."
47 fi
48fi
49
50function keyline() {
51 awk -vline="$1" 'NR == line' "$keyfile"
52}
53
54function keyfield() {
55 awk -vline="$1" -vfield="$2" 'NR == line { print $field }' "$keyfile"
56}
57
58function go() {
59 layer=$1
60 if (( layer == 0 || layer > num_layers ));then
61 cat
62 else
63 operation=$(keyfield "$layer" 1)
64 if [[ "$operation" == openssl-enc ]];then
65 openssl enc $openssl_decrypt "-$(keyfield "$layer" 2)" \
66 -nosalt -pass fd:37 37< <(keyfield "$layer" 3)
67 elif [[ "$operation" == reverse ]];then
68 "$(dirname "$0")/reverse"
69 elif [[ "$operation" == openssl-dgst ]];then
70 tee >(echo "$(keyline "$layer") $(
71 {
72 keyfield "$layer" 3 | base64 -d
73 cat
74 keyfield "$layer" 4 | base64 -d
75 } |
76 openssl dgst -binary "-$(keyfield "$layer" 2)" |
77 base64 --wrap=0)" > "$hash_dir/$layer")
78 else
79 die "Unknown operation"
80 fi |
81 go $(( layer + next_layer ))
82 fi
83}
84
85go "$first_layer"
86
87for hash_result in "$hash_dir"/*;do
88 layer=$(basename "$hash_result")
89 if [[ "$mode" == e ]];then
90 # Add the hashes to keyfile
91 key_aside_dir=$(mktemp -d "$keyfile.XXXXXXXXXX")
92 key_aside="$key_aside_dir/key.orig"
93 mv "$keyfile" "$key_aside"
94 sed "${layer}s,.*,$(< "$hash_result")," "$key_aside" > "$keyfile"
95 shred -u "$key_aside"
96 rmdir "$key_aside_dir"
97 else
98 # Verify the hashes
99 if [[ "$(awk '{ print $5 == $6 ? "hash ok" : "mismatch" }' "$hash_result")" != "hash ok" ]];then
100 die "Hash check $layer failed"
101 fi
102 fi
103done
104
105rm -r "$hash_dir"