1#!/bin/sh
2
3# Test case: Try to establish TLS connections with gnutls-cli and
4# check the validity of the server certificate via OCSP
5#
6# Copyright (C) 2016 Thomas Klute
7#
8# This file is part of GnuTLS.
9#
10# GnuTLS is free software; you can redistribute it and/or modify it
11# under the terms of the GNU General Public License as published by the
12# Free Software Foundation; either version 3 of the License, or (at
13# your option) any later version.
14#
15# GnuTLS is distributed in the hope that it will be useful, but
16# WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18# General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with GnuTLS; if not, write to the Free Software Foundation,
22# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23
24srcdir="${srcdir:-.}"
25CERTTOOL="${CERTTOOL:-../src/certtool${EXEEXT}}"
26OCSPTOOL="${OCSPTOOL:-../src/ocsptool${EXEEXT}}"
27GNUTLS_SERV="${GNUTLS_SERV:-../src/gnutls-serv${EXEEXT}}"
28GNUTLS_CLI="${GNUTLS_CLI:-../src/gnutls-cli${EXEEXT}}"
29DIFF="${DIFF:-diff}"
30TEMPLATE_FILE="out.$$.tmpl.tmp"
31SERVER_CERT_FILE="cert.$$.pem.tmp"
32
33if ! test -x "${CERTTOOL}"; then
34	exit 77
35fi
36
37if ! test -x "${OCSPTOOL}"; then
38	exit 77
39fi
40
41if ! test -x "${GNUTLS_SERV}"; then
42	exit 77
43fi
44
45if ! test -x "${GNUTLS_CLI}"; then
46	exit 77
47fi
48
49if ! test -z "${VALGRIND}"; then
50	VALGRIND="${LIBTOOL:-libtool} --mode=execute ${VALGRIND} --error-exitcode=15"
51fi
52
53export TZ="UTC"
54
55. "${srcdir}/scripts/common.sh"
56
57skip_if_no_datefudge
58
59eval "${GETPORT}"
60# Port for gnutls-serv
61TLS_SERVER_PORT=$PORT
62
63# Port to use for OCSP server, must match the OCSP URI set in the
64# server_*.pem certificates
65eval "${GETPORT}"
66OCSP_PORT=$PORT
67
68# Maximum timeout for server startup (OCSP and TLS)
69SERVER_START_TIMEOUT=10
70
71# Check for OpenSSL
72OPENSSL=`which openssl`
73if ! test -x "${OPENSSL}"; then
74    echo "You need openssl to run this test."
75    exit 77
76fi
77
78CERTDATE="2016-04-28"
79TESTDATE="2016-04-29"
80
81OCSP_PID=""
82TLS_SERVER_PID=""
83stop_servers ()
84{
85    test -z "${OCSP_PID}" || kill "${OCSP_PID}"
86    test -z "${TLS_SERVER_PID}" || kill "${TLS_SERVER_PID}"
87    rm -f "$TEMPLATE_FILE"
88    rm -f "$SERVER_CERT_FILE"
89}
90trap stop_servers 1 15 2 EXIT
91
92echo "=== Generating good server certificate ==="
93
94rm -f "$TEMPLATE_FILE"
95cp "${srcdir}/ocsp-tests/certs/server_good.template" "$TEMPLATE_FILE"
96chmod u+w "$TEMPLATE_FILE"
97echo "ocsp_uri=http://localhost:${OCSP_PORT}/ocsp/" >>"$TEMPLATE_FILE"
98
99# Generate certificates with the random port
100datefudge -s "${CERTDATE}" ${CERTTOOL} \
101	--generate-certificate --load-ca-privkey "${srcdir}/ocsp-tests/certs/ca.key" \
102	--load-ca-certificate "${srcdir}/ocsp-tests/certs/ca.pem" \
103	--load-privkey "${srcdir}/ocsp-tests/certs/server_good.key" \
104	--template "${TEMPLATE_FILE}" --outfile "${SERVER_CERT_FILE}" 2>/dev/null
105
106echo "=== Bringing OCSP server up ==="
107
108# Start OpenSSL OCSP server
109#
110# WARNING: As of version 1.0.2g, OpenSSL OCSP cannot bind the TCP port
111# if started repeatedly in a short time, probably a lack of
112# SO_REUSEADDR usage.
113PORT=${OCSP_PORT}
114launch_bare_server $$ \
115	  datefudge "${TESTDATE}" \
116	  "${OPENSSL}" ocsp -index "${srcdir}/ocsp-tests/certs/ocsp_index.txt" -text \
117	  -port "${OCSP_PORT}" \
118	  -rsigner "${srcdir}/ocsp-tests/certs/ocsp-server.pem" \
119	  -rkey "${srcdir}/ocsp-tests/certs/ocsp-server.key" \
120	  -CA "${srcdir}/ocsp-tests/certs/ca.pem"
121OCSP_PID="${!}"
122wait_server "${OCSP_PID}"
123
124echo "=== Verifying OCSP server is up ==="
125
126# Port probing (as done in wait_port) makes the OpenSSL OCSP server
127# crash due to the "invalid request", so try proper requests
128t=0
129while test "${t}" -lt "${SERVER_START_TIMEOUT}"; do
130    # Run a test request to make sure the server works
131    datefudge "${TESTDATE}" \
132	      ${VALGRIND} "${OCSPTOOL}" --ask \
133	      --load-cert "${SERVER_CERT_FILE}" \
134	      --load-issuer "${srcdir}/ocsp-tests/certs/ca.pem"
135    rc=$?
136    if test "${rc}" = "0"; then
137	break
138    else
139	t=`expr ${t} + 1`
140	sleep 1
141    fi
142done
143# Fail if the final OCSP request failed
144if test "${rc}" != "0"; then
145    echo "OCSP server check failed."
146    exit ${rc}
147fi
148
149echo "=== Test 1: Server with valid certificate ==="
150
151PORT=${TLS_SERVER_PORT}
152launch_bare_server $$ \
153	  datefudge "${TESTDATE}" \
154	  "${GNUTLS_SERV}" --echo --disable-client-cert \
155	  --x509keyfile="${srcdir}/ocsp-tests/certs/server_good.key" \
156	  --x509certfile="${SERVER_CERT_FILE}" \
157	  --port="${TLS_SERVER_PORT}"
158TLS_SERVER_PID="${!}"
159wait_server $TLS_SERVER_PID
160
161wait_for_port "${TLS_SERVER_PORT}"
162
163echo "test 123456" | \
164    datefudge -s "${TESTDATE}" \
165	      "${GNUTLS_CLI}" --ocsp --x509cafile="${srcdir}/ocsp-tests/certs/ca.pem" \
166	      --port="${TLS_SERVER_PORT}" localhost
167rc=$?
168
169if test "${rc}" != "0"; then
170    echo "Connecting to server with valid certificate failed."
171    exit ${rc}
172fi
173
174kill "${TLS_SERVER_PID}"
175wait "${TLS_SERVER_PID}"
176unset TLS_SERVER_PID
177
178echo "=== Generating bad server certificate ==="
179
180rm -f "${SERVER_CERT_FILE}"
181rm -f "${TEMPLATE_FILE}"
182cp "${srcdir}/ocsp-tests/certs/server_bad.template" "$TEMPLATE_FILE"
183echo "ocsp_uri=http://localhost:${OCSP_PORT}/ocsp/" >>"$TEMPLATE_FILE"
184
185# Generate certificates with the random port
186datefudge -s "${CERTDATE}" ${CERTTOOL} \
187	--generate-certificate --load-ca-privkey "${srcdir}/ocsp-tests/certs/ca.key" \
188	--load-ca-certificate "${srcdir}/ocsp-tests/certs/ca.pem" \
189	--load-privkey "${srcdir}/ocsp-tests/certs/server_bad.key" \
190	--template "${TEMPLATE_FILE}" --outfile "${SERVER_CERT_FILE}"
191
192echo "=== Test 2: Server with revoked certificate ==="
193
194eval "${GETPORT}"
195TLS_SERVER_PORT=$PORT
196
197launch_bare_server $$ \
198	  datefudge "${TESTDATE}" \
199	  "${GNUTLS_SERV}" --echo --disable-client-cert \
200	  --x509keyfile="${srcdir}/ocsp-tests/certs/server_bad.key" \
201	  --x509certfile="${SERVER_CERT_FILE}" \
202	  --port="${TLS_SERVER_PORT}"
203TLS_SERVER_PID="${!}"
204wait_server ${TLS_SERVER_PID}
205wait_for_port "${TLS_SERVER_PORT}"
206
207echo "test 123456" | \
208    datefudge -s "${TESTDATE}" \
209	      "${GNUTLS_CLI}" --ocsp --x509cafile="${srcdir}/ocsp-tests/certs/ca.pem" \
210	      --port="${TLS_SERVER_PORT}" localhost
211rc=$?
212
213kill "${TLS_SERVER_PID}"
214wait "${TLS_SERVER_PID}"
215unset TLS_SERVER_PID
216
217# This connection should not work because the certificate has been
218# revoked.
219if test "${rc}" = "0"; then
220    echo "Connecting to server with revoked certificate succeeded."
221    exit 1
222fi
223
224kill ${OCSP_PID}
225wait ${OCSP_PID}
226unset OCSP_PID
227
228rm -f "${SERVER_CERT_FILE}"
229rm -f "${TEMPLATE_FILE}"
230
231exit 0
232