summaryrefslogtreecommitdiffstats
path: root/tests/openpgp/tofu.test
blob: 0d34af4095e8df2aaa2bcf4a5da1d3210fd2f713 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#!/bin/sh

. $srcdir/defs.inc || exit 3

# set -x

# Redefine GPG with a fixed time.
GPG="$GPG --faked-system-time=1466684990"

KEYS="2183839A BC15C85A EE37CF96"

# Make sure $srcdir is set.
if test "x$srcdir" = x
then
    echo srcdir environment variable not set!
    exit 1
fi

# Make sure $GNUPGHOME is set.
if test "x$GNUPGHOME" = x
then
    echo "GNUPGHOME not set."
    exit 1
fi

# Import the test keys.
$GPG --import $srcdir/tofu-keys.asc

# Make sure the keys are imported.
for k in $KEYS
do
    if ! $GPG --list-keys $k >/dev/null 2>&1
    then
	echo Missing key $k
	exit 1
    fi
done

format=auto

debug()
{
    echo "$@" >&2
}

debug_exec()
{
    debug "Running GNUPGHOME=$GNUPGHOME $@"
    ${@:+"$@"}
}

# $1 is the keyid of the policy to lookup.  Any remaining arguments
# are simply passed to GPG.
#
# This function only supports keys with a single user id.
getpolicy()
{
    keyid=$1
    if test x$keyid = x
    then
	echo No keyid supplied!
	exit 1
    fi
    shift

    policy=$(debug_exec $GPG --tofu-db-format=$format --trust-model=tofu \
		  --with-colons $@ --list-keys "$keyid" \
		    | awk -F: '/^uid:/ { print $18 }')
    if test $(echo "$policy" | wc -l) -ne 1
    then
	echo "Got: $policy" >&2
	echo "error"
    else
	case $policy in
	    auto|good|unknown|bad|ask) echo $policy ;;
	    *) echo "error" ;;
	esac
    fi
}

# $1 is the key id
# $2 is the expected policy
# The rest are additional options to pass to gpg.
checkpolicy()
{
    debug
    debug "checkpolicy($@)"

    keyid=$1
    shift
    expected_policy=$1
    shift
    policy=$(getpolicy "$keyid" ${@:+"$@"})
    if test "x$policy" != "x$expected_policy"
    then
	echo "$keyid: Expected policy to be \`$expected_policy', but got \`$policy'."
	exit 1
    fi
}

# $1 is the keyid of the trust level to lookup.  Any remaining
# arguments are simply passed to GPG.
#
# This function only supports keys with a single user id.
gettrust()
{
    keyid=$1
    if test x$keyid = x
    then
	echo No keyid supplied!
	exit 1
    fi
    shift

    trust=$(debug_exec $GPG --tofu-db-format=$format --trust-model=tofu \
		 --with-colons $@ --list-keys "$keyid" \
		    | awk -F: '/^pub:/ { print $2 }')
    if test $(echo "$trust" | wc -l) -ne 1
    then
	echo "error"
    else
	case $trust in
	    [oidreqnmfuws-]) echo $trust ;;
	    *) echo "Bad trust value: $trust" >&2; echo "error" ;;
	esac
    fi
}

# $1 is the key id
# $2 is the expected trust level
# The rest are additional options to pass to gpg.
checktrust()
{
    debug
    debug "checktrust($@)"

    keyid=$1
    shift
    expected_trust=$1
    shift
    trust=$(gettrust "$keyid" ${@:+"$@"})
    if test "x$trust" != "x$expected_trust"
    then
	echo "$keyid: Expected trust to be \`$expected_trust', but got \`$trust'."
	exit 1
    fi
}

# Set key $1's policy to $2.  Any remaining arguments are passed as
# options to gpg.
setpolicy()
{
    debug
    debug "setpolicy($@)"

    keyid=$1
    shift
    policy=$1
    shift

    debug_exec $GPG --tofu-db-format=$format \
	 --trust-model=tofu ${@:+"$@"} --tofu-policy $policy $keyid
}

for format in split flat
do
    debug
    debug "Testing with db format $format"

    # Carefully remove the TOFU db.
    test -e $GNUPGHOME/tofu.db && rm $GNUPGHOME/tofu.db
    test -e $GNUPGHOME/tofu.d/email && rm -r $GNUPGHOME/tofu.d/email
    test -e $GNUPGHOME/tofu.d/key && rm -r $GNUPGHOME/tofu.d/key
    # This will fail if the directory is not empty.
    test -e $GNUPGHOME/tofu.d && rmdir $GNUPGHOME/tofu.d

    # Verify a message.  There should be no conflict and the trust policy
    # should be set to auto.
    debug_exec $GPG --tofu-db-format=$format --trust-model=tofu \
	 --verify $srcdir/tofu-2183839A-1.txt

    checkpolicy 2183839A auto

    trust=$(gettrust 2183839A)
    debug "default trust = $trust"
    if test "x$trust" != xm
    then
	echo "Wrong default trust.  Got: \`$trust', expected \`m'"
	exit 1
    fi

    # Trust should be derived lazily.  Thus, if the policy is set to auto
    # and we change --tofu-default-policy, then the trust should change as
    # well.  Try it.
    checktrust 2183839A f --tofu-default-policy=good
    checktrust 2183839A - --tofu-default-policy=unknown
    checktrust 2183839A n --tofu-default-policy=bad

    # Change the policy to something other than auto and make sure the
    # policy and the trust are correct.
    for policy in good unknown bad
    do
	if test $policy = good
	then
	    expected_trust='f'
	elif test $policy = unknown
	then
	    expected_trust='-'
	else
	    expected_trust='n'
	fi

	debug
	debug "Setting TOFU policy to $policy"
	setpolicy 2183839A $policy

	# Since we have a fixed policy, the trust level shouldn't
	# change if we change the default policy.
	for default_policy in auto good unknown bad ask
	do
	    checkpolicy 2183839A $policy --tofu-default-policy=$default_policy
	    checktrust 2183839A $expected_trust \
		       --tofu-default-policy=$default_policy
	done
    done

    # BC15C85A conflicts with 2183839A.  On conflict, this will set
    # BC15C85A to ask.  If 2183839A is auto (it's not, it's bad), then
    # it will be set to ask.
    debug_exec $GPG --tofu-db-format=$format --trust-model=tofu \
	 --verify $srcdir/tofu-BC15C85A-1.txt
    checkpolicy BC15C85A ask
    checkpolicy 2183839A bad

    # EE37CF96 conflicts with 2183839A and BC15C85A.  We change
    # BC15C85A's policy to auto and leave 2183839A's policy at bad.
    # This conflict should cause BC15C85A's policy to be changed to
    # ask (since it is auto), but not affect 2183839A's policy.
    setpolicy BC15C85A auto
    checkpolicy BC15C85A auto
    debug_exec $GPG --tofu-db-format=$format --trust-model=tofu \
	 --verify $srcdir/tofu-EE37CF96-1.txt
    checkpolicy BC15C85A ask
    checkpolicy 2183839A bad
    checkpolicy EE37CF96 ask
done

exit 0