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