1#!/bin/sh
2
3# context-info.sh
4#
5# Copyright The Mbed TLS Contributors
6# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7#
8# This program is intended for testing the ssl_context_info program
9#
10
11set -eu
12
13if ! cd "$(dirname "$0")"; then
14    exit 125
15fi
16
17# Variables
18
19THIS_SCRIPT_NAME=$(basename "$0")
20PROG_PATH="../programs/ssl/ssl_context_info"
21OUT_FILE="ssl_context_info.log"
22IN_DIR="data_files/base64"
23
24USE_VALGRIND=0
25
26T_COUNT=0
27T_PASSED=0
28T_FAILED=0
29
30
31# Functions
32
33print_usage() {
34    echo "Usage: $0 [options]"
35    printf "  -h|--help\tPrint this help.\n"
36    printf "  -m|--memcheck\tUse valgrind to check the memory.\n"
37}
38
39# Print test name <name>
40print_name() {
41    printf "%s %.*s " "$1" $(( 71 - ${#1} )) \
42    "........................................................................"
43}
44
45# Print header to the test output file <test name> <file path> <test command>
46print_header()
47{
48    date="$(date)"
49    echo "******************************************************************" >  $2
50    echo "* File created by: $THIS_SCRIPT_NAME"                               >> $2
51    echo "* Test name:  $1"                                                   >> $2
52    echo "* Date:       $date"                                                >> $2
53    echo "* Command:    $3"                                                   >> $2
54    echo "******************************************************************" >> $2
55    echo ""                                                                   >> $2
56}
57
58# Print footer at the end of file <file path>
59print_footer()
60{
61    echo ""                                                                   >> $1
62    echo "******************************************************************" >> $1
63    echo "* End command"                                                      >> $1
64    echo "******************************************************************" >> $1
65    echo ""                                                                   >> $1
66}
67
68# Use the arguments of this script
69get_options() {
70    while [ $# -gt 0 ]; do
71        case "$1" in
72            -h|--help)
73                print_usage
74                exit 0
75                ;;
76            -m|--memcheck)
77                USE_VALGRIND=1
78                ;;
79            *)
80                echo "Unknown argument: '$1'"
81                print_usage
82                exit 1
83                ;;
84        esac
85        shift
86    done
87}
88
89# Current test failed
90fail()
91{
92    T_FAILED=$(( $T_FAILED + 1))
93    FAIL_OUT="Fail.$T_FAILED""_$OUT_FILE"
94
95    echo "FAIL"
96    echo "    Error: $1"
97
98    cp -f "$OUT_FILE" "$FAIL_OUT"
99    echo "Error: $1" >> "$FAIL_OUT"
100}
101
102# Current test passed
103pass()
104{
105    T_PASSED=$(( $T_PASSED + 1))
106    echo "PASS"
107}
108
109# Usage: run_test <name> <input file with b64 code> [ -arg <extra arguments for tested program> ] [option [...]]
110# Options:  -m <pattern that MUST be present in the output of tested program>
111#           -n <pattern that must NOT be present in the output of tested program>
112#           -u <pattern that must be UNIQUE in the output of tested program>
113run_test()
114{
115    TEST_NAME="$1"
116    RUN_CMD="$PROG_PATH -f $IN_DIR/$2"
117
118    if [ "-arg" = "$3" ]; then
119        RUN_CMD="$RUN_CMD $4"
120        shift 4
121    else
122        shift 2
123    fi
124
125    # prepend valgrind to our commands if active
126    if [ "$USE_VALGRIND" -gt 0 ]; then
127        RUN_CMD="valgrind --leak-check=full $RUN_CMD"
128    fi
129
130    T_COUNT=$(( $T_COUNT + 1))
131    print_name "$TEST_NAME"
132
133    # run tested program
134    print_header "$TEST_NAME" "$OUT_FILE" "$RUN_CMD"
135    eval "$RUN_CMD" >> "$OUT_FILE" 2>&1
136    print_footer "$OUT_FILE"
137
138    # check valgrind's results
139    if [ "$USE_VALGRIND" -gt 0 ]; then
140        if ! ( grep -F 'All heap blocks were freed -- no leaks are possible' "$OUT_FILE" &&
141             grep -F 'ERROR SUMMARY: 0 errors from 0 contexts' "$OUT_FILE" ) > /dev/null
142        then
143            fail "Memory error detected"
144            return
145        fi
146    fi
147
148    # check other assertions
149    # lines beginning with == are added by valgrind, ignore them, because we already checked them before
150    # lines with 'Serious error when reading debug info', are valgrind issues as well
151    # lines beginning with * are added by this script, ignore too
152    while [ $# -gt 0 ]
153    do
154        case $1 in
155            "-m")
156                if grep -v '^==' "$OUT_FILE" | grep -v 'Serious error when reading debug info' | grep -v "^*" | grep "$2" >/dev/null; then :; else
157                    fail "pattern '$2' MUST be present in the output"
158                    return
159                fi
160                ;;
161
162            "-n")
163                if grep -v '^==' "$OUT_FILE" | grep -v 'Serious error when reading debug info' | grep -v "^*" | grep "$2" >/dev/null; then
164                    fail "pattern '$2' MUST NOT be present in the output"
165                    return
166                fi
167                ;;
168
169            "-u")
170                if [ $(grep -v '^==' "$OUT_FILE"| grep -v 'Serious error when reading debug info' | grep -v "^*" | grep "$2" | wc -l) -ne 1 ]; then
171                    fail "lines following pattern '$2' must be once in the output"
172                    return
173                fi
174                ;;
175
176            *)
177                echo "Unknown test: $1" >&2
178                exit 1
179        esac
180        shift 2
181    done
182
183    rm -f "$OUT_FILE"
184
185    pass
186}
187
188get_options "$@"
189
190# Tests
191
192run_test "Default configuration, server" \
193         "srv_def.txt" \
194         -n "ERROR" \
195         -u "major.* 2$" \
196         -u "minor.* 21$" \
197         -u "path.* 0$" \
198         -u "MBEDTLS_HAVE_TIME$" \
199         -u "MBEDTLS_X509_CRT_PARSE_C$" \
200         -u "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH$" \
201         -u "MBEDTLS_SSL_ENCRYPT_THEN_MAC$" \
202         -u "MBEDTLS_SSL_SESSION_TICKETS$" \
203         -u "MBEDTLS_SSL_SESSION_TICKETS and client$" \
204         -u "MBEDTLS_SSL_DTLS_ANTI_REPLAY$" \
205         -u "MBEDTLS_SSL_ALPN$" \
206         -u "ciphersuite.* TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256$" \
207         -u "cipher flags.* 0x00$" \
208         -u "Message-Digest.* SHA256$" \
209         -u "compression.* disabled$" \
210         -u "DTLS datagram packing.* enabled$" \
211         -n "Certificate" \
212         -n "bytes left to analyze from context"
213
214run_test "Default configuration, client" \
215         "cli_def.txt" \
216         -n "ERROR" \
217         -u "major.* 2$" \
218         -u "minor.* 21$" \
219         -u "path.* 0$" \
220         -u "MBEDTLS_HAVE_TIME$" \
221         -u "MBEDTLS_X509_CRT_PARSE_C$" \
222         -u "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH$" \
223         -u "MBEDTLS_SSL_ENCRYPT_THEN_MAC$" \
224         -u "MBEDTLS_SSL_SESSION_TICKETS$" \
225         -u "MBEDTLS_SSL_SESSION_TICKETS and client$" \
226         -u "MBEDTLS_SSL_DTLS_ANTI_REPLAY$" \
227         -u "MBEDTLS_SSL_ALPN$" \
228         -u "ciphersuite.* TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256$" \
229         -u "cipher flags.* 0x00$" \
230         -u "Message-Digest.* SHA256$" \
231         -u "compression.* disabled$" \
232         -u "DTLS datagram packing.* enabled$" \
233         -u "cert. version .* 3$" \
234         -u "serial number.* 02$" \
235         -u "issuer name.* C=NL, O=PolarSSL, CN=PolarSSL Test CA$" \
236         -u "subject name.* C=NL, O=PolarSSL, CN=localhost$" \
237         -u "issued  on.* 2019-02-10 14:44:06$" \
238         -u "expires on.* 2029-02-10 14:44:06$" \
239         -u "signed using.* RSA with SHA-256$" \
240         -u "RSA key size.* 2048 bits$" \
241         -u "basic constraints.* CA=false$" \
242         -n "bytes left to analyze from context"
243
244run_test "Ciphersuite TLS-RSA-WITH-AES-256-CCM-8, server" \
245         "srv_ciphersuite.txt" \
246         -n "ERROR" \
247         -u "ciphersuite.* TLS-RSA-WITH-AES-256-CCM-8$" \
248
249run_test "Ciphersuite TLS-RSA-WITH-AES-256-CCM-8, client" \
250         "cli_ciphersuite.txt" \
251         -n "ERROR" \
252         -u "ciphersuite.* TLS-RSA-WITH-AES-256-CCM-8$" \
253
254run_test "No packing, server" \
255         "srv_no_packing.txt" \
256         -n "ERROR" \
257         -u "DTLS datagram packing.* disabled"
258
259run_test "No packing, client" \
260         "cli_no_packing.txt" \
261         -n "ERROR" \
262         -u "DTLS datagram packing.* disabled"
263
264run_test "DTLS CID, server" \
265         "srv_cid.txt" \
266         -n "ERROR" \
267         -u "in CID.* DE AD" \
268         -u "out CID.* BE EF"
269
270run_test "DTLS CID, client" \
271         "cli_cid.txt" \
272         -n "ERROR" \
273         -u "in CID.* BE EF" \
274         -u "out CID.* DE AD"
275
276run_test "No MBEDTLS_SSL_MAX_FRAGMENT_LENGTH, server" \
277         "srv_no_mfl.txt" \
278         -n "ERROR" \
279         -n "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH"
280
281run_test "No MBEDTLS_SSL_MAX_FRAGMENT_LENGTH, client" \
282         "cli_no_mfl.txt" \
283         -n "ERROR" \
284         -n "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH"
285
286run_test "No MBEDTLS_SSL_ALPN, server" \
287         "srv_no_alpn.txt" \
288         -n "ERROR" \
289         -n "MBEDTLS_SSL_ALPN"
290
291run_test "No MBEDTLS_SSL_ALPN, client" \
292         "cli_no_alpn.txt" \
293         -n "ERROR" \
294         -n "MBEDTLS_SSL_ALPN"
295
296run_test "No MBEDTLS_SSL_KEEP_PEER_CERTIFICATE, server" \
297         "srv_no_keep_cert.txt" \
298         -arg "--keep-peer-cert=0" \
299         -u "ciphersuite.* TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256$" \
300         -u "cipher flags.* 0x00" \
301         -u "compression.* disabled" \
302         -u "DTLS datagram packing.* enabled" \
303         -n "ERROR"
304
305run_test "No MBEDTLS_SSL_KEEP_PEER_CERTIFICATE, client" \
306         "cli_no_keep_cert.txt" \
307         -arg "--keep-peer-cert=0" \
308         -u "ciphersuite.* TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256$" \
309         -u "cipher flags.* 0x00" \
310         -u "compression.* disabled" \
311         -u "DTLS datagram packing.* enabled" \
312         -n "ERROR"
313
314run_test "No MBEDTLS_SSL_KEEP_PEER_CERTIFICATE, negative, server" \
315         "srv_no_keep_cert.txt" \
316         -m "Deserializing" \
317         -m "ERROR"
318
319run_test "No MBEDTLS_SSL_KEEP_PEER_CERTIFICATE, negative, client" \
320         "cli_no_keep_cert.txt" \
321         -m "Deserializing" \
322         -m "ERROR"
323
324run_test "Minimal configuration, server" \
325         "srv_min_cfg.txt" \
326         -n "ERROR" \
327         -n "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH$" \
328         -n "MBEDTLS_SSL_ENCRYPT_THEN_MAC$" \
329         -n "MBEDTLS_SSL_SESSION_TICKETS$" \
330         -n "MBEDTLS_SSL_SESSION_TICKETS and client$" \
331         -n "MBEDTLS_SSL_DTLS_ANTI_REPLAY$" \
332         -n "MBEDTLS_SSL_ALPN$" \
333
334run_test "Minimal configuration, client" \
335         "cli_min_cfg.txt" \
336         -n "ERROR" \
337         -n "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH$" \
338         -n "MBEDTLS_SSL_ENCRYPT_THEN_MAC$" \
339         -n "MBEDTLS_SSL_SESSION_TICKETS$" \
340         -n "MBEDTLS_SSL_SESSION_TICKETS and client$" \
341         -n "MBEDTLS_SSL_DTLS_ANTI_REPLAY$" \
342         -n "MBEDTLS_SSL_ALPN$" \
343
344run_test "MTU=10000" \
345         "mtu_10000.txt" \
346         -n "ERROR" \
347         -u "MTU.* 10000$"
348
349run_test "MFL=1024" \
350         "mfl_1024.txt" \
351         -n "ERROR" \
352         -u "MFL.* 1024$"
353
354run_test "Older version (v2.19.1)" \
355         "v2.19.1.txt" \
356         -n "ERROR" \
357         -u "major.* 2$" \
358         -u "minor.* 19$" \
359         -u "path.* 1$" \
360         -u "ciphersuite.* TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8$" \
361         -u "Message-Digest.* SHA256$" \
362         -u "compression.* disabled$" \
363         -u "serial number.* 01:70:AF:40:B4:E6$" \
364         -u "issuer name.* CN=ca$" \
365         -u "subject name.* L=160001, OU=acc1, CN=device01$" \
366         -u "issued  on.* 2020-03-06 09:50:18$" \
367         -u "expires on.* 2056-02-26 09:50:18$" \
368         -u "signed using.* ECDSA with SHA256$" \
369         -u "lifetime.* 0 sec.$" \
370         -u "MFL.* none$" \
371         -u "negotiate truncated HMAC.* disabled$" \
372         -u "Encrypt-then-MAC.* enabled$" \
373         -u "DTLS datagram packing.* enabled$" \
374         -u "verify result.* 0x00000000$" \
375         -n "bytes left to analyze from context"
376
377run_test "Wrong base64 format" \
378         "def_bad_b64.txt" \
379         -m "ERROR" \
380         -u "The length of the base64 code found should be a multiple of 4" \
381         -n "bytes left to analyze from context"
382
383run_test "Too much data at the beginning of base64 code" \
384         "def_b64_too_big_1.txt" \
385         -m "ERROR" \
386         -n "The length of the base64 code found should be a multiple of 4" \
387
388run_test "Too much data in the middle of base64 code" \
389         "def_b64_too_big_2.txt" \
390         -m "ERROR" \
391         -n "The length of the base64 code found should be a multiple of 4" \
392
393run_test "Too much data at the end of base64 code" \
394         "def_b64_too_big_3.txt" \
395         -m "ERROR" \
396         -n "The length of the base64 code found should be a multiple of 4" \
397         -u "bytes left to analyze from context"
398
399run_test "Empty file as input" \
400         "empty.txt" \
401         -u "Finished. No valid base64 code found"
402
403run_test "Not empty file without base64 code" \
404         "../../context-info.sh" \
405         -n "Deserializing"
406
407run_test "Binary file instead of text file" \
408         "../../../programs/ssl/ssl_context_info" \
409         -m "ERROR" \
410         -u "Too many bad symbols detected. File check aborted" \
411         -n "Deserializing"
412
413run_test "Decoder continues past 0xff character" \
414         "def_b64_ff.bin" \
415         -n "No valid base64" \
416         -u "ciphersuite.* TLS-"
417
418
419# End of tests
420
421echo
422if [ $T_FAILED -eq 0 ]; then
423    echo "PASSED ( $T_COUNT tests )"
424else
425    echo "FAILED ( $T_FAILED / $T_COUNT tests )"
426fi
427
428exit $T_FAILED
429