sshsig.sh revision 1.12
1#	$OpenBSD: sshsig.sh,v 1.12 2022/01/05 04:10:39 djm Exp $
2#	Placed in the Public Domain.
3
4tid="sshsig"
5
6DATA2=$OBJ/${DATANAME}.2
7cat ${DATA} ${DATA} > ${DATA2}
8
9rm -f $OBJ/sshsig-*.sig $OBJ/wrong-key* $OBJ/sigca-key*
10
11sig_namespace="test-$$"
12sig_principal="user-$$@example.com"
13
14# Make a "wrong key"
15${SSHKEYGEN} -q -t ed25519 -f $OBJ/wrong-key \
16	-C "wrong trousers, Grommit" -N '' \
17	|| fatal "couldn't generate key"
18WRONG=$OBJ/wrong-key.pub
19
20# Make a CA key.
21${SSHKEYGEN} -q -t ed25519 -f $OBJ/sigca-key -C "CA" -N '' \
22	|| fatal "couldn't generate key"
23CA_PRIV=$OBJ/sigca-key
24CA_PUB=$OBJ/sigca-key.pub
25
26trace "start agent"
27eval `${SSHAGENT} ${EXTRA_AGENT_ARGS} -s` > /dev/null
28r=$?
29if [ $r -ne 0 ]; then
30	fatal "could not start ssh-agent: exit code $r"
31fi
32
33SIGNKEYS="$SSH_KEYTYPES"
34verbose "$tid: make certificates"
35for t in $SSH_KEYTYPES ; do
36	${SSHKEYGEN} -q -s $CA_PRIV -z $$ \
37	    -I "regress signature key for $USER" \
38		-V "19840101:19860101" \
39	    -n $sig_principal $OBJ/${t} || \
40		fatal "couldn't sign ${t}"
41	SIGNKEYS="$SIGNKEYS ${t}-cert.pub"
42done
43
44for t in $SIGNKEYS; do
45	verbose "$tid: check signature for $t"
46	keybase=`basename $t .pub`
47	privkey=${OBJ}/`basename $t -cert.pub`
48	sigfile=${OBJ}/sshsig-${keybase}.sig
49	sigfile_agent=${OBJ}/sshsig-agent-${keybase}.sig
50	pubkey=${OBJ}/${keybase}.pub
51	cert=${OBJ}/${keybase}-cert.pub
52	sigfile_cert=${OBJ}/sshsig-${keybase}-cert.sig
53
54	${SSHKEYGEN} -vvv -Y sign -f ${OBJ}/$t -n $sig_namespace \
55		< $DATA > $sigfile 2>/dev/null || fail "sign using $t failed"
56
57	(printf "$sig_principal " ; cat $pubkey) > $OBJ/allowed_signers
58	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
59		-I $sig_principal -f $OBJ/allowed_signers \
60		< $DATA >/dev/null 2>&1 || \
61		fail "failed signature for $t key"
62
63	(printf "$sig_principal namespaces=\"$sig_namespace,whatever\" ";
64	 cat $pubkey) > $OBJ/allowed_signers
65	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
66		-I $sig_principal -f $OBJ/allowed_signers \
67		< $DATA >/dev/null 2>&1 || \
68		fail "failed signature for $t key w/ limited namespace"
69
70	(printf "$sig_principal namespaces=\"$sig_namespace,whatever\" ";
71	 cat $pubkey) > $OBJ/allowed_signers
72	${SSHKEYGEN} -q -Y verify -s $sigfile -n $sig_namespace \
73		-I $sig_principal -f $OBJ/allowed_signers \
74		-O print-pubkey \
75		< $DATA | cut -d' ' -f1-2 > ${OBJ}/${keybase}-fromsig.pub || \
76		fail "failed signature for $t key w/ print-pubkey"
77	cut -d' ' -f1-2 ${OBJ}/${keybase}.pub > ${OBJ}/${keybase}-strip.pub
78	diff -r ${OBJ}/${keybase}-strip.pub ${OBJ}/${keybase}-fromsig.pub || \
79		fail "print-pubkey differs from signature key"
80
81	# Invalid option
82	(printf "$sig_principal octopus " ; cat $pubkey) > $OBJ/allowed_signers
83	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
84		-I $sig_principal -f $OBJ/allowed_signers \
85		< $DATA >/dev/null 2>&1 && \
86		fail "accepted signature for $t key with bad signers option"
87
88	# Wrong key trusted.
89	(printf "$sig_principal " ; cat $WRONG) > $OBJ/allowed_signers
90	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
91		-I $sig_principal -f $OBJ/allowed_signers \
92		< $DATA >/dev/null 2>&1 && \
93		fail "accepted signature for $t key with wrong key trusted"
94
95	# incorrect data
96	(printf "$sig_principal " ; cat $pubkey) > $OBJ/allowed_signers
97	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
98		-I $sig_principal -f $OBJ/allowed_signers \
99		< $DATA2 >/dev/null 2>&1 && \
100		fail "passed signature for wrong data with $t key"
101
102	# wrong principal in signers
103	(printf "josef.k@example.com " ; cat $pubkey) > $OBJ/allowed_signers
104	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
105		-I $sig_principal -f $OBJ/allowed_signers \
106		< $DATA >/dev/null 2>&1 && \
107		fail "accepted signature for $t key with wrong principal"
108
109	# wrong namespace
110	(printf "$sig_principal " ; cat $pubkey) > $OBJ/allowed_signers
111	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n COWS_COWS_COWS \
112		-I $sig_principal -f $OBJ/allowed_signers \
113		< $DATA >/dev/null 2>&1 && \
114		fail "accepted signature for $t key with wrong namespace"
115
116	# namespace excluded by option
117	(printf "$sig_principal namespaces=\"whatever\" " ;
118	 cat $pubkey) > $OBJ/allowed_signers
119	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
120		-I $sig_principal -f $OBJ/allowed_signers \
121		< $DATA >/dev/null 2>&1 && \
122		fail "accepted signature for $t key with excluded namespace"
123
124	( printf "$sig_principal " ;
125	  printf "valid-after=\"19800101\",valid-before=\"19900101\" " ;
126	  cat $pubkey) > $OBJ/allowed_signers
127
128	# key lifespan valid
129	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
130		-I $sig_principal -f $OBJ/allowed_signers \
131		-Overify-time=19850101 \
132		< $DATA >/dev/null 2>&1 || \
133		fail "failed signature for $t key with valid expiry interval"
134	# key not yet valid
135	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
136		-I $sig_principal -f $OBJ/allowed_signers \
137		-Overify-time=19790101 \
138		< $DATA >/dev/null 2>&1 && \
139		fail "failed signature for $t not-yet-valid key"
140	# key expired
141	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
142		-I $sig_principal -f $OBJ/allowed_signers \
143		-Overify-time=19910101 \
144		< $DATA >/dev/null 2>&1 && \
145		fail "failed signature for $t with expired key"
146	# NB. assumes we're not running this test in the 1980s
147	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
148		-I $sig_principal -f $OBJ/allowed_signers \
149		< $DATA >/dev/null 2>&1 && \
150		fail "failed signature for $t with expired key"
151
152	# key lifespan valid
153	${SSHKEYGEN} -vvv -Y find-principals -s $sigfile \
154		-Overify-time="19850101" \
155		-f $OBJ/allowed_signers >/dev/null 2>&1 || \
156		fail "failed find-principals for $t key with valid expiry interval"
157	# key not yet valid
158	${SSHKEYGEN} -vvv -Y find-principals -s $sigfile \
159		-Overify-time="19790101" \
160		-f $OBJ/allowed_signers >/dev/null 2>&1 && \
161		fail "failed find-principals for $t not-yet-valid key"
162	# key expired
163	${SSHKEYGEN} -vvv -Y find-principals -s $sigfile \
164		-Overify-time="19990101" \
165		-f $OBJ/allowed_signers >/dev/null 2>&1 && \
166		fail "failed find-principals for $t with expired key"
167	# NB. assumes we're not running this test in the 1980s
168	${SSHKEYGEN} -vvv -Y find-principals -s $sigfile \
169		-f $OBJ/allowed_signers >/dev/null 2>&1 && \
170		fail "failed find-principals for $t with expired key"
171
172	# public key in revoked keys file
173	cat $pubkey > $OBJ/revoked_keys
174	(printf "$sig_principal namespaces=\"whatever\" " ;
175	 cat $pubkey) > $OBJ/allowed_signers
176	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
177		-I $sig_principal -f $OBJ/allowed_signers \
178		-r $OBJ/revoked_keys \
179		< $DATA >/dev/null 2>&1 && \
180		fail "accepted signature for $t key, but key is in revoked_keys"
181
182	# public key not revoked, but others are present in revoked_keysfile
183	cat $WRONG > $OBJ/revoked_keys
184	(printf "$sig_principal " ; cat $pubkey) > $OBJ/allowed_signers
185	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
186		-I $sig_principal -f $OBJ/allowed_signers \
187		-r $OBJ/revoked_keys \
188		< $DATA >/dev/null 2>&1 || \
189		fail "couldn't verify signature for $t key, but key not in revoked_keys"
190
191	# check-novalidate with valid data
192	${SSHKEYGEN} -vvv -Y check-novalidate -s $sigfile -n $sig_namespace \
193		< $DATA >/dev/null 2>&1 || \
194		fail "failed to check valid signature for $t key"
195
196	# check-novalidate with invalid data
197	${SSHKEYGEN} -vvv -Y check-novalidate -s $sigfile -n $sig_namespace \
198		< $DATA2 >/dev/null 2>&1 && \
199		fail "succeeded checking signature for $t key with invalid data"
200
201	# find-principals with valid public key
202	(printf "$sig_principal " ; cat $pubkey) > $OBJ/allowed_signers
203	${SSHKEYGEN} -vvv -Y find-principals -s $sigfile -f $OBJ/allowed_signers >/dev/null 2>&1 || \
204		fail "failed to find valid principals in allowed_signers"
205
206	# find-principals with wrong key not in allowed_signers
207	(printf "$sig_principal " ; cat $WRONG) > $OBJ/allowed_signers
208	${SSHKEYGEN} -vvv -Y find-principals -s $sigfile -f $OBJ/allowed_signers >/dev/null 2>&1 && \
209		fail "succeeded finding principal with invalid signers file"
210
211	# find-principals with a configured namespace but none on command-line
212	(printf "$sig_principal " ;
213	 printf "namespaces=\"test1,test2\" ";
214	 cat $pubkey) > $OBJ/allowed_signers
215	${SSHKEYGEN} -vvv -Y find-principals -s $sigfile \
216	    -f $OBJ/allowed_signers >/dev/null 2>&1 || \
217		fail "failed finding principal when namespaces are configured"
218
219	# Check signing keys using ssh-agent.
220	${SSHADD} -D >/dev/null 2>&1 # Remove all previously-loaded keys.
221	${SSHADD} ${privkey} > /dev/null 2>&1 || fail "ssh-add failed"
222
223	# Move private key to ensure agent key is used
224	mv ${privkey} ${privkey}.tmp
225
226	${SSHKEYGEN} -vvv -Y sign -f $pubkey -n $sig_namespace \
227		< $DATA > $sigfile_agent 2>/dev/null || \
228		fail "ssh-agent based sign using $pubkey failed"
229	${SSHKEYGEN} -vvv -Y check-novalidate -s $sigfile_agent \
230		-n $sig_namespace < $DATA >/dev/null 2>&1 || \
231		fail "failed to check valid signature for $t key"
232
233	# Move private key back
234	mv ${privkey}.tmp ${privkey}
235
236	# Duplicate principals & keys in allowed_signers but with different validities
237	( printf "$sig_principal " ;
238	  printf "valid-after=\"19800101\",valid-before=\"19900101\" " ;
239	  cat $pubkey;
240	  printf "${sig_principal} " ;
241	  printf "valid-after=\"19850101\",valid-before=\"20000101\" " ;
242	  cat $pubkey) > $OBJ/allowed_signers
243
244	# find-principals outside of any validity lifespan
245	${SSHKEYGEN} -vvv -Y find-principals -s $sigfile \
246		-Overify-time="20100101" \
247		-f $OBJ/allowed_signers >/dev/null 2>&1 && \
248		fail "succeeded find-principals for $t verify-time outside of validity"
249	# find-principals matching only the first lifespan
250	${SSHKEYGEN} -vvv -Y find-principals -s $sigfile \
251		-Overify-time="19830101" \
252		-f $OBJ/allowed_signers >/dev/null 2>&1 || \
253		fail "failed find-principals for $t verify-time within first span"
254	# find-principals matching both lifespans
255	${SSHKEYGEN} -vvv -Y find-principals -s $sigfile \
256		-Overify-time="19880101" \
257		-f $OBJ/allowed_signers >/dev/null 2>&1 || \
258		fail "failed find-principals for $t verify-time within both spans"
259	# find-principals matching only the second lifespan
260	${SSHKEYGEN} -vvv -Y find-principals -s $sigfile \
261		-Overify-time="19950101" \
262		-f $OBJ/allowed_signers >/dev/null 2>&1 || \
263		fail "failed find-principals for $t verify-time within second span"
264
265	# verify outside of any validity lifespan
266	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
267		-Overify-time="20100101" -I $sig_principal \
268		-r $OBJ/revoked_keys -f $OBJ/allowed_signers \
269		< $DATA >/dev/null 2>&1 && \
270		fail "succeeded verify for $t verify-time outside of validity"
271	# verify matching only the first lifespan
272	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
273		-Overify-time="19830101" -I $sig_principal \
274		-r $OBJ/revoked_keys -f $OBJ/allowed_signers \
275		< $DATA >/dev/null 2>&1 || \
276		fail "failed verify for $t verify-time within first span"
277	# verify matching both lifespans
278	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
279		-Overify-time="19880101" -I $sig_principal \
280		-r $OBJ/revoked_keys -f $OBJ/allowed_signers \
281		< $DATA >/dev/null 2>&1 || \
282		fail "failed verify for $t verify-time within both spans"
283	# verify matching only the second lifespan
284	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
285		-Overify-time="19950101" -I $sig_principal \
286		-r $OBJ/revoked_keys -f $OBJ/allowed_signers \
287		< $DATA >/dev/null 2>&1 || \
288		fail "failed verify for $t verify-time within second span"
289
290	# Remaining tests are for certificates only.
291	case "$keybase" in
292		*-cert) ;;
293		*) continue ;;
294	esac
295
296	# Check key lifespan on find-principals when using the CA
297	( printf "$sig_principal " ;
298	  printf "cert-authority,valid-after=\"19800101\",valid-before=\"19900101\" ";
299	  cat $CA_PUB) > $OBJ/allowed_signers
300	# key lifespan valid
301	${SSHKEYGEN} -vvv -Y find-principals -s $sigfile \
302		-Overify-time="19850101" \
303		-f $OBJ/allowed_signers >/dev/null 2>&1 || \
304		fail "failed find-principals for $t key with valid expiry interval"
305	# key not yet valid
306	${SSHKEYGEN} -vvv -Y find-principals -s $sigfile \
307		-Overify-time="19790101" \
308		-f $OBJ/allowed_signers >/dev/null 2>&1 && \
309		fail "failed find-principals for $t not-yet-valid key"
310	# key expired
311	${SSHKEYGEN} -vvv -Y find-principals -s $sigfile \
312		-Overify-time="19990101" \
313		-f $OBJ/allowed_signers >/dev/null 2>&1 && \
314		fail "failed find-principals for $t with expired key"
315	# NB. assumes we're not running this test in the 1980s
316	${SSHKEYGEN} -vvv -Y find-principals -s $sigfile \
317		-f $OBJ/allowed_signers >/dev/null 2>&1 && \
318		fail "failed find-principals for $t with expired key"
319
320	# correct CA key
321	(printf "$sig_principal cert-authority " ;
322	 cat $CA_PUB) > $OBJ/allowed_signers
323	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
324		-I $sig_principal -f $OBJ/allowed_signers \
325		-Overify-time=19850101 \
326		< $DATA >/dev/null 2>&1 || \
327		fail "failed signature for $t cert"
328
329	# find-principals
330	${SSHKEYGEN} -vvv -Y find-principals -s $sigfile \
331		-Overify-time=19850101 \
332		-f $OBJ/allowed_signers >/dev/null 2>&1 || \
333		fail "failed find-principals for $t with ca key"
334
335	# signing key listed as cert-authority
336	(printf "$sig_principal cert-authority " ;
337	 cat $pubkey) > $OBJ/allowed_signers
338	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
339		-I $sig_principal -f $OBJ/allowed_signers \
340		< $DATA >/dev/null 2>&1 && \
341		fail "accepted signature with $t key listed as CA"
342
343	# CA key not flagged cert-authority
344	(printf "$sig_principal " ; cat $CA_PUB) > $OBJ/allowed_signers
345	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
346		-I $sig_principal -f $OBJ/allowed_signers \
347		< $DATA >/dev/null 2>&1 && \
348		fail "accepted signature for $t cert with CA not marked"
349
350	# mismatch between cert principal and file
351	(printf "josef.k@example.com cert-authority " ;
352	 cat $CA_PUB) > $OBJ/allowed_signers
353	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
354		-I $sig_principal -f $OBJ/allowed_signers \
355		< $DATA >/dev/null 2>&1 && \
356		fail "accepted signature for $t cert with wrong principal"
357
358	# Cert valid but CA revoked
359	cat $CA_PUB > $OBJ/revoked_keys
360	(printf "$sig_principal " ; cat $pubkey) > $OBJ/allowed_signers
361	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
362		-I $sig_principal -f $OBJ/allowed_signers \
363		-r $OBJ/revoked_keys \
364		< $DATA >/dev/null 2>&1 && \
365		fail "accepted signature for $t key, but CA key in revoked_keys"
366
367	# Set lifespan of CA key and verify signed user certs behave accordingly
368	( printf "$sig_principal " ;
369	  printf "cert-authority,valid-after=\"19800101\",valid-before=\"19900101\" " ;
370	  cat $CA_PUB) > $OBJ/allowed_signers
371
372	# CA key lifespan valid
373	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
374		-I $sig_principal -f $OBJ/allowed_signers \
375		-Overify-time=19850101 \
376		< $DATA >/dev/null 2>&1 >/dev/null 2>&1 || \
377		fail "failed signature for $t key with valid CA expiry interval"
378	# CA lifespan is valid but user key not yet valid
379	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
380		-I $sig_principal -f $OBJ/allowed_signers \
381		-Overify-time=19810101 \
382		< $DATA >/dev/null 2>&1 && \
383		fail "accepted signature for $t key with valid CA expiry interval but not yet valid cert"
384	# CA lifespan is valid but user key expired
385	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
386		-I $sig_principal -f $OBJ/allowed_signers \
387		-Overify-time=19890101 \
388		< $DATA >/dev/null 2>&1 && \
389		fail "accepted signature for $t key with valid CA expiry interval but expired cert"
390	# CA key not yet valid
391	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
392		-I $sig_principal -f $OBJ/allowed_signers \
393		-Overify-time=19790101 \
394		< $DATA >/dev/null 2>&1 && \
395		fail "accepted signature for $t not-yet-valid CA key"
396	# CA key expired
397	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
398		-I $sig_principal -f $OBJ/allowed_signers \
399		-Overify-time=19910101 \
400		< $DATA >/dev/null 2>&1 && \
401		fail "accepted signature for $t with expired CA key"
402	# NB. assumes we're not running this test in the 1980s
403	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
404		-I $sig_principal -f $OBJ/allowed_signers \
405		< $DATA >/dev/null 2>&1 && \
406		fail "accepted signature for $t with expired CA key"
407
408	# Set lifespan of CA outside of the cert validity
409	( printf "$sig_principal " ;
410	  printf "cert-authority,valid-after=\"19800101\",valid-before=\"19820101\" " ;
411	  cat $CA_PUB) > $OBJ/allowed_signers
412	# valid cert validity but expired CA
413	${SSHKEYGEN} -vvv -Y verify -s $sigfile -n $sig_namespace \
414		-I $sig_principal -f $OBJ/allowed_signers \
415		-Overify-time=19840101 \
416		< $DATA >/dev/null 2>&1 && \
417		fail "accepted signature for $t key with expired CA but valid cert"
418
419done
420
421# Test key independant match-principals
422(
423	printf "principal1 " ; cat $pubkey;
424	printf "princi* " ; cat $pubkey;
425	printf "unique " ; cat $pubkey;
426) > $OBJ/allowed_signers
427
428verbose "$tid: match principals"
429${SSHKEYGEN} -Y match-principals -f $OBJ/allowed_signers -I "unique" | \
430    fgrep "unique" >/dev/null || \
431	fail "faild to match static principal"
432
433${SSHKEYGEN} -Y match-principals -f $OBJ/allowed_signers -I "princip" | \
434    fgrep "princi*" >/dev/null || \
435	fail "faild to match wildcard principal"
436
437${SSHKEYGEN} -Y match-principals -f $OBJ/allowed_signers -I "principal1" | \
438    fgrep -e "principal1" -e "princi*" >/dev/null || \
439	fail "faild to match static and wildcard principal"
440verbose "$tid: nomatch principals"
441for x in princ prince unknown ; do
442	${SSHKEYGEN} -Y match-principals -f $OBJ/allowed_signers \
443	    -I $x >/dev/null 2>&1 && \
444		fail "succeeded to match unknown principal \"$x\""
445done
446
447trace "kill agent"
448${SSHAGENT} -k > /dev/null
449
450