Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/usr.sbin/certctl/tests/certctl_test.sh
102637 views
1
#
2
# Copyright (c) 2025 Dag-Erling Smørgrav <[email protected]>
3
#
4
# SPDX-License-Identifier: BSD-2-Clause
5
#
6
7
. $(atf_get_srcdir)/certctl.subr
8
9
# Random sets of eight non-colliding names
10
set1()
11
{
12
cat <<EOF
13
AVOYKJHSLFHWPVQMKBHENUAHJTEGMCCB 0ca83bbe
14
UYSYXKDNNJTYOQPBGIKQDHRJYZHTDPKK 0d9a6512
15
LODHGFXMZYKGOKAYGWTMMYQJYHDATDDM 4e6219f5
16
NBBTQHJLHKBFFFWJTHHSNKOQYMGLHLPW 5dd76abc
17
BJFAQZXZHYQLIDDPCAQFPDMNXICUXBXW ad68573d
18
IOKNTHVEVVIJMNMYAVILMEMQQWLVRESN b577803d
19
BHGMAJJGNJPIVMHMFCUTJLGFROJICEKN c98a6338
20
HCRFQMGDQJALMLUQNXMPGLXFLLJRODJW f50c6379
21
EOF
22
}
23
24
set2()
25
{
26
cat <<EOF
27
GOHKZTSKIPDSYNLMGYXGLROPTATELXIU 30789c88
28
YOOTYHEGHZIYFXOBLNKENPSJUDGOPJJU 7fadbc13
29
ETRINNYBGKIENAVGOKVJYFSSHFZIJZRH 8ed664af
30
DBFGMFFMRNLPQLQPOLXOEUVLCRXLRSWT 8f34355e
31
WFOPBQPLQFHDHZOUQFEIDGSYDUOTSNDQ ac0471df
32
HMNETZMGNIWRGXQCVZXVZGWSGFBRRDQC b32f1472
33
SHFYBXDVAUACBFPPAIGDAQIAGYOYGMQE baca75fa
34
PCBGDNVPYCDGNRQSGRSLXFHYKXLAVLHW ddeeae01
35
EOF
36
}
37
38
set3()
39
{
40
cat <<EOF
41
NJWIRLPWAIICVJBKXXHFHLCPAERZATRL 000aa2e5
42
RJAENDPOCZQEVCPFUWOWDXPCSMYJPVYC 021b95a3
43
PQUQDSWHBNVLBTNBGONYRLGZZVEFXVLO 071e8c50
44
VZEXRKJUPZSFBDWBOLUZXOGLNTEAPCZM 3af7bb9b
45
ZXOWOXQTXNZMAMZIWVFDZDJEWOOAGAOH 48d5c7cc
46
KQSFQYVJMFTMADIHJIWGSQISWKSHRYQO 509f5ba1
47
AIECYSLWZOIEPJWWUTWSQXCNCIHHZHYI 8cb0c503
48
RFHWDJZEPOFLMPGXAHVEJFHCDODAPVEV 9ae4e049
49
EOF
50
}
51
52
# Random set of three colliding names
53
collhash=f2888ce3
54
coll()
55
{
56
cat <<EOF
57
EJFTZEOANQLOYPEHWWXBWEWEFVKHMSNA $collhash
58
LEMRWZAZLKZLPPSFLNLQZVGKKBEOFYWG $collhash
59
ZWUPHYWKKTVEFBJOLLPDAIKGRDFVXZID $collhash
60
EOF
61
}
62
63
sortfile() {
64
for filename; do
65
sort "${filename}" >"${filename}"-
66
mv "${filename}"- "${filename}"
67
done
68
}
69
70
certctl_setup()
71
{
72
export DESTDIR="$PWD"
73
74
# Create input directories
75
mkdir -p ${DESTDIR}${DISTBASE}/usr/share/certs/trusted
76
mkdir -p ${DESTDIR}${DISTBASE}/usr/share/certs/untrusted
77
mkdir -p ${DESTDIR}/usr/local/share/certs
78
79
# Do not create output directories; certctl will take care of it
80
#mkdir -p ${DESTDIR}${DISTBASE}/etc/ssl/certs
81
#mkdir -p ${DESTDIR}${DISTBASE}/etc/ssl/untrusted
82
83
# Generate a random key
84
keyname="testkey"
85
gen_key ${keyname}
86
87
# Generate certificates
88
:>metalog.expect
89
:>trusted.expect
90
:>untrusted.expect
91
metalog() {
92
echo ".${DISTBASE}$@ type=file" >>metalog.expect
93
}
94
trusted() {
95
local crtname=$1
96
local filename=$2
97
printf "%s\t%s\n" "${filename}" "${crtname}" >>trusted.expect
98
metalog "/etc/ssl/certs/${filename}"
99
}
100
untrusted() {
101
local crtname=$1
102
local filename=$2
103
printf "%s\t%s\n" "${filename}" "${crtname}" >>untrusted.expect
104
metalog "/etc/ssl/untrusted/${filename}"
105
}
106
set1 | while read crtname hash ; do
107
gen_crt ${crtname} ${keyname}
108
mv ${crtname}.crt ${DESTDIR}${DISTBASE}/usr/share/certs/trusted
109
trusted "${crtname}" "${hash}.0"
110
done
111
local c=0
112
coll | while read crtname hash ; do
113
gen_crt ${crtname} ${keyname}
114
mv ${crtname}.crt ${DESTDIR}${DISTBASE}/usr/share/certs/trusted
115
trusted "${crtname}" "${hash}.${c}"
116
c=$((c+1))
117
done
118
set2 | while read crtname hash ; do
119
gen_crt ${crtname} ${keyname}
120
openssl x509 -in ${crtname}.crt
121
rm ${crtname}.crt
122
trusted "${crtname}" "${hash}.0"
123
done >usr/local/share/certs/bundle.crt
124
set3 | while read crtname hash ; do
125
gen_crt ${crtname} ${keyname}
126
mv ${crtname}.crt ${DESTDIR}${DISTBASE}/usr/share/certs/untrusted
127
untrusted "${crtname}" "${hash}.0"
128
done
129
metalog "/etc/ssl/cert.pem"
130
unset -f untrusted
131
unset -f trusted
132
unset -f metalog
133
sortfile *.expect
134
}
135
136
check_trusted() {
137
local crtname=$1
138
local subject="$(subject ${crtname})"
139
local c=${2:-1}
140
141
atf_check -e ignore -o match:"found: ${c}\$" \
142
openssl storeutl -noout -subject "${subject}" \
143
${DESTDIR}${DISTBASE}/etc/ssl/certs
144
atf_check -e ignore -o not-match:"found: [1-9]" \
145
openssl storeutl -noout -subject "${subject}" \
146
${DESTDIR}${DISTBASE}/etc/ssl/untrusted
147
}
148
149
check_untrusted() {
150
local crtname=$1
151
local subject="$(subject ${crtname})"
152
local c=${2:-1}
153
154
atf_check -e ignore -o not-match:"found: [1-9]" \
155
openssl storeutl -noout -subject "${subject}" \
156
${DESTDIR}/${DISTBASE}/etc/ssl/certs
157
atf_check -e ignore -o match:"found: ${c}\$" \
158
openssl storeutl -noout -subject "${subject}" \
159
${DESTDIR}/${DISTBASE}/etc/ssl/untrusted
160
}
161
162
check_in_bundle() {
163
local b=${DISTBASE}${DISTBASE+/}
164
local crtfile=$1
165
local line
166
167
line=$(tail +5 "${crtfile}" | head -1)
168
atf_check grep -q "${line}" ${DESTDIR}${DISTBASE}/etc/ssl/cert.pem
169
}
170
171
check_not_in_bundle() {
172
local b=${DISTBASE}${DISTBASE+/}
173
local crtfile=$1
174
local line
175
176
line=$(tail +5 "${crtfile}" | head -1)
177
atf_check -s exit:1 grep -q "${line}" etc/ssl/cert.pem
178
}
179
180
atf_test_case rehash
181
rehash_head()
182
{
183
atf_set "descr" "Test the rehash command"
184
}
185
rehash_body()
186
{
187
certctl_setup
188
atf_check certctl rehash
189
190
# Verify non-colliding trusted certificates
191
(set1; set2) >trusted
192
while read crtname hash ; do
193
check_trusted "${crtname}"
194
done <trusted
195
196
# Verify colliding trusted certificates
197
coll >coll
198
while read crtname hash ; do
199
check_trusted "${crtname}" $(wc -l <coll)
200
done <coll
201
202
# Verify untrusted certificates
203
set3 >untrusted
204
while read crtname hash ; do
205
check_untrusted "${crtname}"
206
done <untrusted
207
208
# Verify bundle
209
for f in etc/ssl/certs/*.? ; do
210
check_in_bundle "${f}"
211
done
212
for f in etc/ssl/untrusted/*.? ; do
213
check_not_in_bundle "${f}"
214
done
215
}
216
217
atf_test_case list
218
list_head()
219
{
220
atf_set "descr" "Test the list and untrusted commands"
221
}
222
list_body()
223
{
224
certctl_setup
225
atf_check certctl rehash
226
227
atf_check -o save:trusted.out certctl list
228
sortfile trusted.out
229
# the ordering of the colliding certificates is partly
230
# determined by fields that change every time we regenerate
231
# them, so ignore them in the diff
232
atf_check diff -u \
233
--ignore-matching-lines $collhash \
234
trusted.expect trusted.out
235
236
atf_check -o save:untrusted.out certctl untrusted
237
sortfile untrusted.out
238
atf_check diff -u \
239
untrusted.expect untrusted.out
240
}
241
242
atf_test_case trust
243
trust_head()
244
{
245
atf_set "descr" "Test the trust command"
246
}
247
trust_body()
248
{
249
certctl_setup
250
atf_check certctl rehash
251
crtname=$(set3 | (read crtname hash ; echo ${crtname}))
252
crtfile=usr/share/certs/untrusted/${crtname}.crt
253
check_untrusted ${crtname}
254
check_not_in_bundle ${crtfile}
255
atf_check -e match:"was previously untrusted" \
256
certctl trust ${crtfile}
257
check_trusted ${crtname}
258
check_in_bundle ${crtfile}
259
}
260
261
atf_test_case untrust
262
untrust_head()
263
{
264
atf_set "descr" "Test the untrust command"
265
}
266
untrust_body()
267
{
268
certctl_setup
269
atf_check certctl rehash
270
crtname=$(set1 | (read crtname hash ; echo ${crtname}))
271
crtfile=usr/share/certs/trusted/${crtname}.crt
272
check_trusted "${crtname}"
273
check_in_bundle ${crtfile}
274
atf_check certctl untrust "${crtfile}"
275
check_untrusted "${crtname}"
276
check_not_in_bundle ${crtfile}
277
}
278
279
atf_test_case metalog
280
metalog_head()
281
{
282
atf_set "descr" "Verify the metalog"
283
}
284
metalog_body()
285
{
286
export DISTBASE=/base
287
certctl_setup
288
289
# certctl gets DESTDIR and DISTBASE from environment
290
rm -f metalog.orig
291
atf_check certctl -U -M metalog.orig rehash
292
sed -E 's/(type=file) .*/\1/' metalog.orig | sort >metalog.short
293
atf_check diff -u metalog.expect metalog.short
294
295
# certctl gets DESTDIR and DISTBASE from command line
296
rm -f metalog.orig
297
atf_check env -uDESTDIR -uDISTBASE \
298
certctl -D ${DESTDIR} -d ${DISTBASE} -U -M metalog.orig rehash
299
sed -E 's/(type=file) .*/\1/' metalog.orig | sort >metalog.short
300
atf_check diff -u metalog.expect metalog.short
301
302
# as above, but intentionally add trailing slashes
303
rm -f metalog.orig
304
atf_check env -uDESTDIR -uDISTBASE \
305
certctl -D ${DESTDIR}// -d ${DISTBASE}/ -U -M metalog.orig rehash
306
sed -E 's/(type=file) .*/\1/' metalog.orig | sort >metalog.short
307
atf_check diff -u metalog.expect metalog.short
308
}
309
310
atf_test_case misc
311
misc_head()
312
{
313
atf_set "descr" "Test miscellaneous edge cases"
314
}
315
misc_body()
316
{
317
# certctl rejects DISTBASE that does not begin with a slash
318
atf_check -s exit:1 -e match:"begin with a slash" \
319
certctl -d base -n rehash
320
atf_check -s exit:1 -e match:"begin with a slash" \
321
env DISTBASE=base certctl -n rehash
322
}
323
324
atf_init_test_cases()
325
{
326
atf_add_test_case rehash
327
atf_add_test_case list
328
atf_add_test_case trust
329
atf_add_test_case untrust
330
atf_add_test_case metalog
331
atf_add_test_case misc
332
}
333
334