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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
|
#!/bin/bash
# Copyright (C) 2016 Red Hat, Inc.
#
# This file is part of GnuTLS.
#
# GnuTLS is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# GnuTLS is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GnuTLS; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
srcdir="${srcdir:-.}"
CERTTOOL="${CERTTOOL:-../../src/certtool${EXEEXT}}"
OCSPTOOL="${OCSPTOOL:-../../src/ocsptool${EXEEXT}}"
GNUTLS_SERV="${GNUTLS_SERV:-../../src/gnutls-serv${EXEEXT}}"
GNUTLS_CLI="${GNUTLS_CLI:-../../src/gnutls-cli${EXEEXT}}"
DIFF="${DIFF:-diff}"
TEMPLATE_FILE="ms-out.$$.tmpl.tmp"
SERVER_CERT_FILE="ms-cert.$$.pem.tmp"
OCSP_RESPONSE_FILE="ms-resp.$$.tmp"
OCSP_REQ_FILE="ms-req.$$.tmp"
export TZ="UTC"
if ! test -x "${CERTTOOL}"; then
exit 77
fi
if ! test -x "${OCSPTOOL}"; then
exit 77
fi
if ! test -x "${GNUTLS_SERV}"; then
exit 77
fi
if ! test -x "${GNUTLS_CLI}"; then
exit 77
fi
if ! test -z "${VALGRIND}"; then
VALGRIND="${LIBTOOL:-libtool} --mode=execute ${VALGRIND} --error-exitcode=15"
fi
. "${srcdir}/../scripts/common.sh"
eval "${GETPORT}"
# Port for gnutls-serv
TLS_SERVER_PORT=$PORT
# Port to use for OCSP server, must match the OCSP URI set in the
# server_*.pem certificates
eval "${GETPORT}"
OCSP_PORT=$PORT
# Maximum timeout for server startup (OCSP and TLS)
SERVER_START_TIMEOUT=10
# Check for OpenSSL
OPENSSL=`which openssl`
if ! test -x "${OPENSSL}"; then
echo "You need openssl to run this test."
exit 77
fi
# Check for datefudge
TSTAMP=`datefudge "2006-09-23" date -u +%s || true`
if test "$TSTAMP" != "1158969600"; then
echo $TSTAMP
echo "You need datefudge to run this test."
exit 77
fi
CERTDATE="2016-04-28"
TESTDATE="2016-04-29"
EXP_OCSP_DATE="2016-03-27"
OCSP_PID=""
TLS_SERVER_PID=""
stop_servers ()
{
test -z "${OCSP_PID}" || kill "${OCSP_PID}"
test -z "${TLS_SERVER_PID}" || kill "${TLS_SERVER_PID}"
rm -f "$TEMPLATE_FILE"
rm -f "$SERVER_CERT_FILE"
rm -f "$OCSP_RESPONSE_FILE"
rm -f "$OCSP_REQ_FILE"
}
trap stop_servers 1 15 2 EXIT
echo "=== Generating good server certificate ==="
rm -f "$TEMPLATE_FILE"
cp "${srcdir}/certs/server_good.template" "$TEMPLATE_FILE"
echo "ocsp_uri=http://localhost:${OCSP_PORT}/ocsp/" >>"$TEMPLATE_FILE"
echo "tls_feature = 5" >>"$TEMPLATE_FILE"
# Generate certificates with the random port
datefudge -s "${CERTDATE}" ${CERTTOOL} \
--generate-certificate --load-ca-privkey "${srcdir}/certs/ca.key" \
--load-ca-certificate "${srcdir}/certs/ca.pem" \
--load-privkey "${srcdir}/certs/server_good.key" \
--template "${TEMPLATE_FILE}" --outfile "${SERVER_CERT_FILE}" 2>/dev/null
echo "=== Bringing OCSP server up ==="
INDEXFILE="ocsp_index.txt"
ATTRFILE="${INDEXFILE}.attr"
cp "${srcdir}/certs/ocsp_index.txt" ${INDEXFILE}
cp "${srcdir}/certs/ocsp_index.txt.attr" ${ATTRFILE}
# Start OpenSSL OCSP server
#
# WARNING: As of version 1.0.2g, OpenSSL OCSP cannot bind the TCP port
# if started repeatedly in a short time, probably a lack of
# SO_REUSEADDR usage.
PORT=${OCSP_PORT}
launch_bare_server $$ \
datefudge "${TESTDATE}" \
"${OPENSSL}" ocsp -index "${INDEXFILE}" -text \
-port "${OCSP_PORT}" \
-rsigner "${srcdir}/certs/ocsp-server.pem" \
-rkey "${srcdir}/certs/ocsp-server.key" \
-CA "${srcdir}/certs/ca.pem"
OCSP_PID="${!}"
wait_server "${OCSP_PID}"
echo "=== Verifying OCSP server is up ==="
# Port probing (as done in wait_port) makes the OpenSSL OCSP server
# crash due to the "invalid request", so try proper requests
t=0
while test "${t}" -lt "${SERVER_START_TIMEOUT}"; do
# Run a test request to make sure the server works
datefudge "${TESTDATE}" \
${VALGRIND} "${OCSPTOOL}" --ask \
--load-cert "${SERVER_CERT_FILE}" \
--load-issuer "${srcdir}/certs/ca.pem" \
--outfile "${OCSP_RESPONSE_FILE}"
rc=$?
if test "${rc}" = "0"; then
break
else
t=`expr ${t} + 1`
sleep 1
fi
done
# Fail if the final OCSP request failed
if test "${rc}" != "0"; then
echo "OCSP server check failed."
exit ${rc}
fi
#echo "placed staple in ${OCSP_RESPONSE_FILE}"
echo "=== Test 1: Server with valid certificate - no staple ==="
PORT=${TLS_SERVER_PORT}
launch_bare_server $$ \
datefudge "${TESTDATE}" \
"${GNUTLS_SERV}" --echo --disable-client-cert \
--x509keyfile="${srcdir}/certs/server_good.key" \
--x509certfile="${SERVER_CERT_FILE}" \
--port="${TLS_SERVER_PORT}"
TLS_SERVER_PID="${!}"
wait_server $TLS_SERVER_PID
wait_for_port "${TLS_SERVER_PORT}"
echo "test 123456" | \
datefudge -s "${TESTDATE}" \
"${GNUTLS_CLI}" --ocsp --x509cafile="${srcdir}/certs/ca.pem" \
--port="${TLS_SERVER_PORT}" localhost
rc=$?
if test "${rc}" != "1"; then
echo "Connecting to server with valid certificate and no staple succeeded"
exit ${rc}
fi
kill "${TLS_SERVER_PID}"
wait "${TLS_SERVER_PID}"
unset TLS_SERVER_PID
echo "=== Test 2: Server with valid certificate - valid staple ==="
eval "${GETPORT}"
# Port for gnutls-serv
TLS_SERVER_PORT=$PORT
PORT=${TLS_SERVER_PORT}
launch_bare_server $$ \
datefudge "${TESTDATE}" \
"${GNUTLS_SERV}" --echo --disable-client-cert \
--x509keyfile="${srcdir}/certs/server_good.key" \
--x509certfile="${SERVER_CERT_FILE}" \
--port="${TLS_SERVER_PORT}" \
--ocsp-response="${OCSP_RESPONSE_FILE}"
TLS_SERVER_PID="${!}"
wait_server $TLS_SERVER_PID
wait_for_port "${TLS_SERVER_PORT}"
echo "test 123456" | \
datefudge -s "${TESTDATE}" \
"${GNUTLS_CLI}" --ocsp --x509cafile="${srcdir}/certs/ca.pem" \
--port="${TLS_SERVER_PORT}" localhost
rc=$?
if test "${rc}" != "0"; then
echo "Connecting to server with valid certificate and valid staple failed"
exit ${rc}
fi
kill "${TLS_SERVER_PID}"
wait "${TLS_SERVER_PID}"
unset TLS_SERVER_PID
echo "=== Test 3: Server with valid certificate - invalid staple ==="
head -c 64 /dev/urandom >"${OCSP_RESPONSE_FILE}"
eval "${GETPORT}"
# Port for gnutls-serv
TLS_SERVER_PORT=$PORT
PORT=${TLS_SERVER_PORT}
launch_bare_server $$ \
datefudge "${TESTDATE}" \
"${GNUTLS_SERV}" --echo --disable-client-cert \
--x509keyfile="${srcdir}/certs/server_good.key" \
--x509certfile="${SERVER_CERT_FILE}" \
--port="${TLS_SERVER_PORT}" \
--ocsp-response="${OCSP_RESPONSE_FILE}"
TLS_SERVER_PID="${!}"
wait_server $TLS_SERVER_PID
wait_for_port "${TLS_SERVER_PORT}"
echo "test 123456" | \
datefudge -s "${TESTDATE}" \
"${GNUTLS_CLI}" --ocsp --x509cafile="${srcdir}/certs/ca.pem" \
--port="${TLS_SERVER_PORT}" localhost
rc=$?
if test "${rc}" != "1"; then
echo "Connecting to server with valid certificate and invalid staple succeeded"
exit ${rc}
fi
kill "${TLS_SERVER_PID}"
wait "${TLS_SERVER_PID}"
unset TLS_SERVER_PID
echo "=== Test 4: Server with valid certificate - unrelated cert staple ==="
rm -f "${OCSP_RESPONSE_FILE}"
cp "${srcdir}/certs/ocsp-staple-unrelated.der" "${OCSP_RESPONSE_FILE}"
eval "${GETPORT}"
# Port for gnutls-serv
TLS_SERVER_PORT=$PORT
PORT=${TLS_SERVER_PORT}
launch_bare_server $$ \
datefudge "${TESTDATE}" \
"${GNUTLS_SERV}" --echo --disable-client-cert \
--x509keyfile="${srcdir}/certs/server_good.key" \
--x509certfile="${SERVER_CERT_FILE}" \
--port="${TLS_SERVER_PORT}" \
--ocsp-response="${OCSP_RESPONSE_FILE}"
TLS_SERVER_PID="${!}"
wait_server $TLS_SERVER_PID
wait_for_port "${TLS_SERVER_PORT}"
echo "test 123456" | \
datefudge -s "${TESTDATE}" \
"${GNUTLS_CLI}" --ocsp --x509cafile="${srcdir}/certs/ca.pem" \
--port="${TLS_SERVER_PORT}" localhost
rc=$?
if test "${rc}" != "1"; then
echo "Connecting to server with valid certificate and invalid staple succeeded"
exit ${rc}
fi
kill "${TLS_SERVER_PID}"
wait "${TLS_SERVER_PID}"
unset TLS_SERVER_PID
echo "=== Test 5: Server with valid certificate - expired staple ==="
rm -f "${OCSP_RESPONSE_FILE}"
# Generate an OCSP response which expires in 2 days and use it after
# a month.
${VALGRIND} ${OCSPTOOL} --generate-request --load-issuer "${srcdir}/certs/ocsp-server.pem" --load-cert "${SERVER_CERT_FILE}" --outfile "${OCSP_REQ_FILE}"
datefudge -s ${EXP_OCSP_DATE} \
${OPENSSL} ocsp -index "${INDEXFILE}" -rsigner "${srcdir}/certs/ocsp-server.pem" -rkey "${srcdir}/certs/ocsp-server.key" -CA "${srcdir}/certs/ca.pem" -reqin "${OCSP_REQ_FILE}" -respout "${OCSP_RESPONSE_FILE}" -ndays 2
eval "${GETPORT}"
# Port for gnutls-serv
TLS_SERVER_PORT=$PORT
PORT=${TLS_SERVER_PORT}
launch_bare_server $$ \
datefudge "${TESTDATE}" \
"${GNUTLS_SERV}" --echo --disable-client-cert \
--x509keyfile="${srcdir}/certs/server_good.key" \
--x509certfile="${SERVER_CERT_FILE}" \
--port="${TLS_SERVER_PORT}" \
--ocsp-response="${OCSP_RESPONSE_FILE}"
TLS_SERVER_PID="${!}"
wait_server $TLS_SERVER_PID
wait_for_port "${TLS_SERVER_PORT}"
echo "test 123456" | \
datefudge -s "${TESTDATE}" \
"${GNUTLS_CLI}" --ocsp --x509cafile="${srcdir}/certs/ca.pem" \
--port="${TLS_SERVER_PORT}" localhost
rc=$?
if test "${rc}" != "1"; then
echo "Connecting to server with valid certificate and expired staple succeeded"
exit ${rc}
fi
kill "${TLS_SERVER_PID}"
wait "${TLS_SERVER_PID}"
unset TLS_SERVER_PID
echo "=== Test 6: Server with valid certificate - old staple ==="
# This case is funny. OCSP doesn't mandate an expiration date for a response so
# we are left to decide what to do with responses that don't contain the NextUpdate
# field. Here we test whether a month-old response with no clear expiration is rejected.
rm -f "${OCSP_RESPONSE_FILE}"
${VALGRIND} ${OCSPTOOL} --generate-request --load-issuer "${srcdir}/certs/ocsp-server.pem" --load-cert "${SERVER_CERT_FILE}" --outfile "${OCSP_REQ_FILE}"
datefudge -s ${EXP_OCSP_DATE} \
${OPENSSL} ocsp -index ${INDEXFILE} -rsigner "${srcdir}/certs/ocsp-server.pem" -rkey "${srcdir}/certs/ocsp-server.key" -CA "${srcdir}/certs/ca.pem" -reqin "${OCSP_REQ_FILE}" -respout "${OCSP_RESPONSE_FILE}"
eval "${GETPORT}"
# Port for gnutls-serv
TLS_SERVER_PORT=$PORT
PORT=${TLS_SERVER_PORT}
launch_bare_server $$ \
datefudge "${TESTDATE}" \
"${GNUTLS_SERV}" --echo --disable-client-cert \
--x509keyfile="${srcdir}/certs/server_good.key" \
--x509certfile="${SERVER_CERT_FILE}" \
--port="${TLS_SERVER_PORT}" \
--ocsp-response="${OCSP_RESPONSE_FILE}"
TLS_SERVER_PID="${!}"
wait_server $TLS_SERVER_PID
wait_for_port "${TLS_SERVER_PORT}"
echo "test 123456" | \
datefudge -s "${TESTDATE}" \
"${GNUTLS_CLI}" --ocsp --x509cafile="${srcdir}/certs/ca.pem" \
--port="${TLS_SERVER_PORT}" localhost
rc=$?
if test "${rc}" != "1"; then
echo "Connecting to server with valid certificate and old staple succeeded"
exit ${rc}
fi
kill "${TLS_SERVER_PID}"
wait "${TLS_SERVER_PID}"
unset TLS_SERVER_PID
kill ${OCSP_PID}
wait ${OCSP_PID}
unset OCSP_PID
rm -f "${OCSP_RESPONSE_FILE}"
rm -f "${OCSP_REQ_FILE}"
rm -f "${SERVER_CERT_FILE}"
rm -f "${TEMPLATE_FILE}"
rm -f "${INDEXFILE}" "${ATTRFILE}"
exit 0
|