1#!/bin/sh
2
3# compat.sh
4#
5# Copyright The Mbed TLS Contributors
6# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7#
8# Purpose
9#
10# Test interoperbility with OpenSSL, GnuTLS as well as itself.
11#
12# Check each common ciphersuite, with each version, both ways (client/server),
13# with and without client authentication.
14
15set -u
16
17# Limit the size of each log to 10 GiB, in case of failures with this script
18# where it may output seemingly unlimited length error logs.
19ulimit -f 20971520
20
21ORIGINAL_PWD=$PWD
22if ! cd "$(dirname "$0")"; then
23    exit 125
24fi
25
26# initialise counters
27TESTS=0
28FAILED=0
29SKIPPED=0
30SRVMEM=0
31
32# default commands, can be overridden by the environment
33: ${M_SRV:=../programs/ssl/ssl_server2}
34: ${M_CLI:=../programs/ssl/ssl_client2}
35: ${OPENSSL:=openssl}
36: ${GNUTLS_CLI:=gnutls-cli}
37: ${GNUTLS_SERV:=gnutls-serv}
38
39# The OPENSSL variable used to be OPENSSL_CMD for historical reasons.
40# To help the migration, error out if the old variable is set,
41# but only if it has a different value than the new one.
42if [ "${OPENSSL_CMD+set}" = set ]; then
43    # the variable is set, we can now check its value
44    if [ "$OPENSSL_CMD" != "$OPENSSL" ]; then
45        echo "Please use OPENSSL instead of OPENSSL_CMD." >&2
46        exit 125
47    fi
48fi
49
50# do we have a recent enough GnuTLS?
51if ( which $GNUTLS_CLI && which $GNUTLS_SERV ) >/dev/null 2>&1; then
52    G_VER="$( $GNUTLS_CLI --version | head -n1 )"
53    if echo "$G_VER" | grep '@VERSION@' > /dev/null; then # git version
54        PEER_GNUTLS=" GnuTLS"
55    else
56        eval $( echo $G_VER | sed 's/.* \([0-9]*\)\.\([0-9]\)*\.\([0-9]*\)$/MAJOR="\1" MINOR="\2" PATCH="\3"/' )
57        if [ $MAJOR -lt 3 -o \
58            \( $MAJOR -eq 3 -a $MINOR -lt 2 \) -o \
59            \( $MAJOR -eq 3 -a $MINOR -eq 2 -a $PATCH -lt 15 \) ]
60        then
61            PEER_GNUTLS=""
62        else
63            PEER_GNUTLS=" GnuTLS"
64            if [ $MINOR -lt 4 ]; then
65                GNUTLS_MINOR_LT_FOUR='x'
66            fi
67        fi
68    fi
69else
70    PEER_GNUTLS=""
71fi
72
73guess_config_name() {
74    if git diff --quiet ../include/mbedtls/mbedtls_config.h 2>/dev/null; then
75        echo "default"
76    else
77        echo "unknown"
78    fi
79}
80: ${MBEDTLS_TEST_OUTCOME_FILE=}
81: ${MBEDTLS_TEST_CONFIGURATION:="$(guess_config_name)"}
82: ${MBEDTLS_TEST_PLATFORM:="$(uname -s | tr -c \\n0-9A-Za-z _)-$(uname -m | tr -c \\n0-9A-Za-z _)"}
83
84# default values for options
85# /!\ keep this synchronised with:
86# - basic-build-test.sh
87# - all.sh (multiple components)
88MODES="tls12 dtls12"
89VERIFIES="NO YES"
90TYPES="ECDSA RSA PSK"
91FILTER=""
92# By default, exclude:
93# - NULL: excluded from our default config + requires OpenSSL legacy
94# - ARIA: requires OpenSSL >= 1.1.1
95# - ChachaPoly: requires OpenSSL >= 1.1.0
96EXCLUDE='NULL\|ARIA\|CHACHA20_POLY1305'
97VERBOSE=""
98MEMCHECK=0
99MIN_TESTS=1
100PRESERVE_LOGS=0
101PEERS="OpenSSL$PEER_GNUTLS mbedTLS"
102
103# hidden option: skip DTLS with OpenSSL
104# (travis CI has a version that doesn't work for us)
105: ${OSSL_NO_DTLS:=0}
106
107print_usage() {
108    echo "Usage: $0"
109    printf "  -h|--help\tPrint this help.\n"
110    printf "  -f|--filter\tOnly matching ciphersuites are tested (Default: '%s')\n" "$FILTER"
111    printf "  -e|--exclude\tMatching ciphersuites are excluded (Default: '%s')\n" "$EXCLUDE"
112    printf "  -m|--modes\tWhich modes to perform (Default: '%s')\n" "$MODES"
113    printf "  -t|--types\tWhich key exchange type to perform (Default: '%s')\n" "$TYPES"
114    printf "  -V|--verify\tWhich verification modes to perform (Default: '%s')\n" "$VERIFIES"
115    printf "  -p|--peers\tWhich peers to use (Default: '%s')\n" "$PEERS"
116    printf "            \tAlso available: GnuTLS (needs v3.2.15 or higher)\n"
117    printf "  -M|--memcheck\tCheck memory leaks and errors.\n"
118    printf "  -v|--verbose\tSet verbose output.\n"
119    printf "     --list-test-cases\tList all potential test cases (No Execution)\n"
120    printf "     --min      \tMinimum number of non-skipped tests (default 1)\n"
121    printf "     --outcome-file\tFile where test outcomes are written\n"
122    printf "                   \t(default: \$MBEDTLS_TEST_OUTCOME_FILE, none if empty)\n"
123    printf "     --preserve-logs\tPreserve logs of successful tests as well\n"
124}
125
126# print_test_case <CLIENT> <SERVER> <STANDARD_CIPHER_SUITE>
127print_test_case() {
128    for i in $3; do
129        uniform_title $1 $2 $i
130        echo "compat;$TITLE"
131    done
132}
133
134# list_test_cases lists all potential test cases in compat.sh without execution
135list_test_cases() {
136    for TYPE in $TYPES; do
137        reset_ciphersuites
138        add_common_ciphersuites
139        add_openssl_ciphersuites
140        add_gnutls_ciphersuites
141        add_mbedtls_ciphersuites
142
143        # PSK cipher suites do not allow client certificate verification.
144        SUB_VERIFIES=$VERIFIES
145        if [ "$TYPE" = "PSK" ]; then
146            SUB_VERIFIES="NO"
147        fi
148
149        for VERIFY in $SUB_VERIFIES; do
150            VERIF=$(echo $VERIFY | tr '[:upper:]' '[:lower:]')
151            for MODE in $MODES; do
152                print_test_case m O "$O_CIPHERS"
153                print_test_case O m "$O_CIPHERS"
154                print_test_case m G "$G_CIPHERS"
155                print_test_case G m "$G_CIPHERS"
156                print_test_case m m "$M_CIPHERS"
157            done
158        done
159    done
160}
161
162get_options() {
163    while [ $# -gt 0 ]; do
164        case "$1" in
165            -f|--filter)
166                shift; FILTER=$1
167                ;;
168            -e|--exclude)
169                shift; EXCLUDE=$1
170                ;;
171            -m|--modes)
172                shift; MODES=$1
173                ;;
174            -t|--types)
175                shift; TYPES=$1
176                ;;
177            -V|--verify)
178                shift; VERIFIES=$1
179                ;;
180            -p|--peers)
181                shift; PEERS=$1
182                ;;
183            -v|--verbose)
184                VERBOSE=1
185                ;;
186            -M|--memcheck)
187                MEMCHECK=1
188                ;;
189            # Please check scripts/check_test_cases.py correspondingly
190            # if you have to modify option, --list-test-cases
191            --list-test-cases)
192                list_test_cases
193                exit $?
194                ;;
195            --min)
196                shift; MIN_TESTS=$1
197                ;;
198            --outcome-file)
199                shift; MBEDTLS_TEST_OUTCOME_FILE=$1
200                ;;
201            --preserve-logs)
202                PRESERVE_LOGS=1
203                ;;
204            -h|--help)
205                print_usage
206                exit 0
207                ;;
208            *)
209                echo "Unknown argument: '$1'"
210                print_usage
211                exit 1
212                ;;
213        esac
214        shift
215    done
216
217    # sanitize some options (modes checked later)
218    VERIFIES="$( echo $VERIFIES | tr [a-z] [A-Z] )"
219    TYPES="$( echo $TYPES | tr [a-z] [A-Z] )"
220}
221
222log() {
223  if [ "X" != "X$VERBOSE" ]; then
224    echo ""
225    echo "$@"
226  fi
227}
228
229# is_dtls <mode>
230is_dtls()
231{
232    test "$1" = "dtls12"
233}
234
235# minor_ver <mode>
236minor_ver()
237{
238    case "$1" in
239        tls12|dtls12)
240            echo 3
241            ;;
242        *)
243            echo "error: invalid mode: $MODE" >&2
244            # exiting is no good here, typically called in a subshell
245            echo -1
246    esac
247}
248
249filter()
250{
251  LIST="$1"
252  NEW_LIST=""
253
254  EXCLMODE="$EXCLUDE"
255
256  for i in $LIST;
257  do
258    NEW_LIST="$NEW_LIST $( echo "$i" | grep "$FILTER" | grep -v "$EXCLMODE" )"
259  done
260
261  # normalize whitespace
262  echo "$NEW_LIST" | sed -e 's/[[:space:]][[:space:]]*/ /g' -e 's/^ //' -e 's/ $//'
263}
264
265filter_ciphersuites()
266{
267    if [ "X" != "X$FILTER" -o "X" != "X$EXCLUDE" ];
268    then
269        # Ciphersuite for Mbed TLS
270        M_CIPHERS=$( filter "$M_CIPHERS" )
271
272        # Ciphersuite for OpenSSL
273        O_CIPHERS=$( filter "$O_CIPHERS" )
274
275        # Ciphersuite for GnuTLS
276        G_CIPHERS=$( filter "$G_CIPHERS" )
277    fi
278}
279
280reset_ciphersuites()
281{
282    M_CIPHERS=""
283    O_CIPHERS=""
284    G_CIPHERS=""
285}
286
287# translate_ciphers {g|m|o} {STANDARD_CIPHER_SUITE_NAME...}
288# Set $ciphers to the cipher suite name translations for the specified
289# program (gnutls, mbedtls or openssl). $ciphers is a space-separated
290# list of entries of the form "STANDARD_NAME=PROGRAM_NAME".
291translate_ciphers()
292{
293    ciphers=$(scripts/translate_ciphers.py "$@")
294    if [ $? -ne 0 ]; then
295        echo "translate_ciphers.py failed with exit code $1" >&2
296        echo "$2" >&2
297        exit 1
298    fi
299}
300
301# Ciphersuites that can be used with all peers.
302# Since we currently have three possible peers, each ciphersuite should appear
303# three times: in each peer's list (with the name that this peer uses).
304add_common_ciphersuites()
305{
306    CIPHERS=""
307    case $TYPE in
308
309        "ECDSA")
310            CIPHERS="$CIPHERS                           \
311                TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA    \
312                TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 \
313                TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 \
314                TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA    \
315                TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 \
316                TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 \
317                TLS_ECDHE_ECDSA_WITH_NULL_SHA           \
318                "
319            ;;
320
321        "RSA")
322            CIPHERS="$CIPHERS                           \
323                TLS_DHE_RSA_WITH_AES_128_CBC_SHA        \
324                TLS_DHE_RSA_WITH_AES_128_CBC_SHA256     \
325                TLS_DHE_RSA_WITH_AES_128_GCM_SHA256     \
326                TLS_DHE_RSA_WITH_AES_256_CBC_SHA        \
327                TLS_DHE_RSA_WITH_AES_256_CBC_SHA256     \
328                TLS_DHE_RSA_WITH_AES_256_GCM_SHA384     \
329                TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA   \
330                TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA   \
331                TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA      \
332                TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256   \
333                TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256   \
334                TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA      \
335                TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384   \
336                TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384   \
337                TLS_ECDHE_RSA_WITH_NULL_SHA             \
338                TLS_RSA_WITH_AES_128_CBC_SHA            \
339                TLS_RSA_WITH_AES_128_CBC_SHA256         \
340                TLS_RSA_WITH_AES_128_GCM_SHA256         \
341                TLS_RSA_WITH_AES_256_CBC_SHA            \
342                TLS_RSA_WITH_AES_256_CBC_SHA256         \
343                TLS_RSA_WITH_AES_256_GCM_SHA384         \
344                TLS_RSA_WITH_CAMELLIA_128_CBC_SHA       \
345                TLS_RSA_WITH_CAMELLIA_256_CBC_SHA       \
346                TLS_RSA_WITH_NULL_MD5                   \
347                TLS_RSA_WITH_NULL_SHA                   \
348                TLS_RSA_WITH_NULL_SHA256                \
349                "
350            ;;
351
352        "PSK")
353            CIPHERS="$CIPHERS                           \
354                TLS_PSK_WITH_AES_128_CBC_SHA            \
355                TLS_PSK_WITH_AES_256_CBC_SHA            \
356                "
357            ;;
358    esac
359
360    O_CIPHERS="$O_CIPHERS $CIPHERS"
361    G_CIPHERS="$G_CIPHERS $CIPHERS"
362    M_CIPHERS="$M_CIPHERS $CIPHERS"
363}
364
365# Ciphersuites usable only with Mbed TLS and OpenSSL
366# A list of ciphersuites in the standard naming convention is appended
367# to the list of Mbed TLS ciphersuites $M_CIPHERS and
368# to the list of OpenSSL ciphersuites $O_CIPHERS respectively.
369# Based on client's naming convention, all ciphersuite names will be
370# translated into another naming format before sent to the client.
371#
372# NOTE: for some reason RSA-PSK doesn't work with OpenSSL,
373# so RSA-PSK ciphersuites need to go in other sections, see
374# https://github.com/Mbed-TLS/mbedtls/issues/1419
375#
376# ChachaPoly suites are here rather than in "common", as they were added in
377# GnuTLS in 3.5.0 and the CI only has 3.4.x so far.
378add_openssl_ciphersuites()
379{
380    CIPHERS=""
381    case $TYPE in
382
383        "ECDSA")
384            CIPHERS="$CIPHERS                                   \
385                TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA             \
386                TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256          \
387                TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256          \
388                TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA             \
389                TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384          \
390                TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384          \
391                TLS_ECDH_ECDSA_WITH_NULL_SHA                    \
392                TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256        \
393                TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384        \
394                TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256   \
395                "
396            ;;
397
398        "RSA")
399            CIPHERS="$CIPHERS                                   \
400                TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256            \
401                TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384            \
402                TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256       \
403                TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256          \
404                TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384          \
405                TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256     \
406                TLS_RSA_WITH_ARIA_128_GCM_SHA256                \
407                TLS_RSA_WITH_ARIA_256_GCM_SHA384                \
408                "
409            ;;
410
411        "PSK")
412            CIPHERS="$CIPHERS                                   \
413                TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256            \
414                TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384            \
415                TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256       \
416                TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256     \
417                TLS_PSK_WITH_ARIA_128_GCM_SHA256                \
418                TLS_PSK_WITH_ARIA_256_GCM_SHA384                \
419                TLS_PSK_WITH_CHACHA20_POLY1305_SHA256           \
420                "
421            ;;
422    esac
423
424    O_CIPHERS="$O_CIPHERS $CIPHERS"
425    M_CIPHERS="$M_CIPHERS $CIPHERS"
426}
427
428# Ciphersuites usable only with Mbed TLS and GnuTLS
429# A list of ciphersuites in the standard naming convention is appended
430# to the list of Mbed TLS ciphersuites $M_CIPHERS and
431# to the list of GnuTLS ciphersuites $G_CIPHERS respectively.
432# Based on client's naming convention, all ciphersuite names will be
433# translated into another naming format before sent to the client.
434add_gnutls_ciphersuites()
435{
436    CIPHERS=""
437    case $TYPE in
438
439        "ECDSA")
440            CIPHERS="$CIPHERS                                       \
441                TLS_ECDHE_ECDSA_WITH_AES_128_CCM                    \
442                TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8                  \
443                TLS_ECDHE_ECDSA_WITH_AES_256_CCM                    \
444                TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8                  \
445                TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256        \
446                TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256        \
447                TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384        \
448                TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384        \
449                "
450            ;;
451
452        "RSA")
453            CIPHERS="$CIPHERS                               \
454                TLS_DHE_RSA_WITH_AES_128_CCM                \
455                TLS_DHE_RSA_WITH_AES_128_CCM_8              \
456                TLS_DHE_RSA_WITH_AES_256_CCM                \
457                TLS_DHE_RSA_WITH_AES_256_CCM_8              \
458                TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256    \
459                TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256    \
460                TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256    \
461                TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384    \
462                TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256  \
463                TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256  \
464                TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384  \
465                TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384  \
466                TLS_RSA_WITH_AES_128_CCM                    \
467                TLS_RSA_WITH_AES_128_CCM_8                  \
468                TLS_RSA_WITH_AES_256_CCM                    \
469                TLS_RSA_WITH_AES_256_CCM_8                  \
470                TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256        \
471                TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256        \
472                TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256        \
473                TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384        \
474                "
475            ;;
476
477        "PSK")
478            CIPHERS="$CIPHERS                               \
479                TLS_DHE_PSK_WITH_AES_128_CBC_SHA            \
480                TLS_DHE_PSK_WITH_AES_128_CBC_SHA256         \
481                TLS_DHE_PSK_WITH_AES_128_CCM                \
482                TLS_DHE_PSK_WITH_AES_128_CCM_8              \
483                TLS_DHE_PSK_WITH_AES_128_GCM_SHA256         \
484                TLS_DHE_PSK_WITH_AES_256_CBC_SHA            \
485                TLS_DHE_PSK_WITH_AES_256_CBC_SHA384         \
486                TLS_DHE_PSK_WITH_AES_256_CCM                \
487                TLS_DHE_PSK_WITH_AES_256_CCM_8              \
488                TLS_DHE_PSK_WITH_AES_256_GCM_SHA384         \
489                TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256    \
490                TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256    \
491                TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384    \
492                TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384    \
493                TLS_DHE_PSK_WITH_NULL_SHA256                \
494                TLS_DHE_PSK_WITH_NULL_SHA384                \
495                TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA          \
496                TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256       \
497                TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA          \
498                TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384       \
499                TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256  \
500                TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384  \
501                TLS_ECDHE_PSK_WITH_NULL_SHA256              \
502                TLS_ECDHE_PSK_WITH_NULL_SHA384              \
503                TLS_PSK_WITH_AES_128_CBC_SHA256             \
504                TLS_PSK_WITH_AES_128_CCM                    \
505                TLS_PSK_WITH_AES_128_CCM_8                  \
506                TLS_PSK_WITH_AES_128_GCM_SHA256             \
507                TLS_PSK_WITH_AES_256_CBC_SHA384             \
508                TLS_PSK_WITH_AES_256_CCM                    \
509                TLS_PSK_WITH_AES_256_CCM_8                  \
510                TLS_PSK_WITH_AES_256_GCM_SHA384             \
511                TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256        \
512                TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256        \
513                TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384        \
514                TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384        \
515                TLS_PSK_WITH_NULL_SHA256                    \
516                TLS_PSK_WITH_NULL_SHA384                    \
517                TLS_RSA_PSK_WITH_AES_128_CBC_SHA            \
518                TLS_RSA_PSK_WITH_AES_128_CBC_SHA256         \
519                TLS_RSA_PSK_WITH_AES_128_GCM_SHA256         \
520                TLS_RSA_PSK_WITH_AES_256_CBC_SHA            \
521                TLS_RSA_PSK_WITH_AES_256_CBC_SHA384         \
522                TLS_RSA_PSK_WITH_AES_256_GCM_SHA384         \
523                TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256    \
524                TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256    \
525                TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384    \
526                TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384    \
527                TLS_RSA_PSK_WITH_NULL_SHA256                \
528                TLS_RSA_PSK_WITH_NULL_SHA384                \
529                "
530            ;;
531    esac
532
533    G_CIPHERS="$G_CIPHERS $CIPHERS"
534    M_CIPHERS="$M_CIPHERS $CIPHERS"
535}
536
537# Ciphersuites usable only with Mbed TLS (not currently supported by another
538# peer usable in this script). This provides only very rudimentaty testing, as
539# this is not interop testing, but it's better than nothing.
540add_mbedtls_ciphersuites()
541{
542    case $TYPE in
543
544        "ECDSA")
545            M_CIPHERS="$M_CIPHERS                               \
546                TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256         \
547                TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256         \
548                TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384         \
549                TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384         \
550                TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256     \
551                TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256     \
552                TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384     \
553                TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384     \
554                TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256        \
555                TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384        \
556                "
557            ;;
558
559        "RSA")
560            M_CIPHERS="$M_CIPHERS                               \
561                TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256            \
562                TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384            \
563                TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256          \
564                TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384          \
565                TLS_RSA_WITH_ARIA_128_CBC_SHA256                \
566                TLS_RSA_WITH_ARIA_256_CBC_SHA384                \
567                "
568            ;;
569
570        "PSK")
571            # *PSK_NULL_SHA suites supported by GnuTLS 3.3.5 but not 3.2.15
572            M_CIPHERS="$M_CIPHERS                               \
573                TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256            \
574                TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384            \
575                TLS_DHE_PSK_WITH_NULL_SHA                       \
576                TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256          \
577                TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384          \
578                TLS_ECDHE_PSK_WITH_NULL_SHA                     \
579                TLS_PSK_WITH_ARIA_128_CBC_SHA256                \
580                TLS_PSK_WITH_ARIA_256_CBC_SHA384                \
581                TLS_PSK_WITH_NULL_SHA                           \
582                TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256            \
583                TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256            \
584                TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384            \
585                TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384            \
586                TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256       \
587                TLS_RSA_PSK_WITH_NULL_SHA                       \
588                "
589            ;;
590    esac
591}
592
593# o_check_ciphersuite STANDARD_CIPHER_SUITE
594o_check_ciphersuite()
595{
596    # skip DTLS when lack of support was declared
597    if test "$OSSL_NO_DTLS" -gt 0 && is_dtls "$MODE"; then
598        SKIP_NEXT_="YES"
599    fi
600
601    # skip DTLS 1.2 is support was not detected
602    if [ "$O_SUPPORT_DTLS12" = "NO" -a "$MODE" = "dtls12" ]; then
603        SKIP_NEXT="YES"
604    fi
605
606    # skip static ECDH when OpenSSL doesn't support it
607    if [ "${O_SUPPORT_STATIC_ECDH}" = "NO" ]; then
608        case "$1" in
609            *ECDH_*) SKIP_NEXT="YES"
610        esac
611    fi
612}
613
614setup_arguments()
615{
616    DATA_FILES_PATH="../framework/data_files"
617
618    O_MODE=""
619    G_MODE=""
620    case "$MODE" in
621        "tls12")
622            O_MODE="tls1_2"
623            G_PRIO_MODE="+VERS-TLS1.2"
624            ;;
625        "dtls12")
626            O_MODE="dtls1_2"
627            G_PRIO_MODE="+VERS-DTLS1.2"
628            G_MODE="-u"
629            ;;
630        *)
631            echo "error: invalid mode: $MODE" >&2
632            exit 1;
633    esac
634
635    # GnuTLS < 3.4 will choke if we try to allow CCM-8
636    if [ -z "${GNUTLS_MINOR_LT_FOUR-}" ]; then
637        G_PRIO_CCM="+AES-256-CCM-8:+AES-128-CCM-8:"
638    else
639        G_PRIO_CCM=""
640    fi
641
642    M_SERVER_ARGS="server_port=$PORT server_addr=0.0.0.0 force_version=$MODE"
643    O_SERVER_ARGS="-accept $PORT -cipher ALL,COMPLEMENTOFALL -$O_MODE"
644    G_SERVER_ARGS="-p $PORT --http $G_MODE"
645    G_SERVER_PRIO="NORMAL:${G_PRIO_CCM}+NULL:+MD5:+PSK:+DHE-PSK:+ECDHE-PSK:+SHA256:+SHA384:+RSA-PSK:-VERS-TLS-ALL:$G_PRIO_MODE"
646
647    # The default prime for `openssl s_server` depends on the version:
648    # * OpenSSL <= 1.0.2a: 512-bit
649    # * OpenSSL 1.0.2b to 1.1.1b: 1024-bit
650    # * OpenSSL >= 1.1.1c: 2048-bit
651    # Mbed TLS wants >=1024, so force that for older versions. Don't force
652    # it for newer versions, which reject a 1024-bit prime. Indifferently
653    # force it or not for intermediate versions.
654    case $($OPENSSL version) in
655        "OpenSSL 1.0"*)
656            O_SERVER_ARGS="$O_SERVER_ARGS -dhparam $DATA_FILES_PATH/dhparams.pem"
657            ;;
658    esac
659
660    # with OpenSSL 1.0.1h, -www, -WWW and -HTTP break DTLS handshakes
661    if is_dtls "$MODE"; then
662        O_SERVER_ARGS="$O_SERVER_ARGS"
663    else
664        O_SERVER_ARGS="$O_SERVER_ARGS -www"
665    fi
666
667    M_CLIENT_ARGS="server_port=$PORT server_addr=127.0.0.1 force_version=$MODE"
668    O_CLIENT_ARGS="-connect localhost:$PORT -$O_MODE"
669    G_CLIENT_ARGS="-p $PORT --debug 3 $G_MODE"
670
671    # Newer versions of OpenSSL have a syntax to enable all "ciphers", even
672    # low-security ones. This covers not just cipher suites but also protocol
673    # versions. It is necessary, for example, to use (D)TLS 1.0/1.1 on
674    # OpenSSL 1.1.1f from Ubuntu 20.04. The syntax was only introduced in
675    # OpenSSL 1.1.0 (21e0c1d23afff48601eb93135defddae51f7e2e3) and I can't find
676    # a way to discover it from -help, so check the openssl version.
677    case $($OPENSSL version) in
678        "OpenSSL 0"*|"OpenSSL 1.0"*) :;;
679        *)
680            O_CLIENT_ARGS="$O_CLIENT_ARGS -cipher ALL@SECLEVEL=0"
681            O_SERVER_ARGS="$O_SERVER_ARGS -cipher ALL@SECLEVEL=0"
682            ;;
683    esac
684
685    case $($OPENSSL ciphers ALL) in
686        *ECDH-ECDSA*|*ECDH-RSA*) O_SUPPORT_STATIC_ECDH="YES";;
687        *) O_SUPPORT_STATIC_ECDH="NO";;
688    esac
689
690    case $($OPENSSL ciphers ALL) in
691        *DES-CBC-*) O_SUPPORT_SINGLE_DES="YES";;
692        *) O_SUPPORT_SINGLE_DES="NO";;
693    esac
694
695    # OpenSSL <1.0.2 doesn't support DTLS 1.2. Check if OpenSSL
696    # supports -dtls1_2 from the s_server help. (The s_client
697    # help isn't accurate as of 1.0.2g: it supports DTLS 1.2
698    # but doesn't list it. But the s_server help seems to be
699    # accurate.)
700    O_SUPPORT_DTLS12="NO"
701    if $OPENSSL s_server -help 2>&1 | grep -q "^ *-dtls1_2 "; then
702        O_SUPPORT_DTLS12="YES"
703    fi
704
705    if [ "X$VERIFY" = "XYES" ];
706    then
707        M_SERVER_ARGS="$M_SERVER_ARGS ca_file=$DATA_FILES_PATH/test-ca_cat12.crt auth_mode=required"
708        O_SERVER_ARGS="$O_SERVER_ARGS -CAfile $DATA_FILES_PATH/test-ca_cat12.crt -Verify 10"
709        G_SERVER_ARGS="$G_SERVER_ARGS --x509cafile $DATA_FILES_PATH/test-ca_cat12.crt --require-client-cert"
710
711        M_CLIENT_ARGS="$M_CLIENT_ARGS ca_file=$DATA_FILES_PATH/test-ca_cat12.crt auth_mode=required"
712        O_CLIENT_ARGS="$O_CLIENT_ARGS -CAfile $DATA_FILES_PATH/test-ca_cat12.crt -verify 10"
713        G_CLIENT_ARGS="$G_CLIENT_ARGS --x509cafile $DATA_FILES_PATH/test-ca_cat12.crt"
714    else
715        # don't request a client cert at all
716        M_SERVER_ARGS="$M_SERVER_ARGS ca_file=none auth_mode=none"
717        G_SERVER_ARGS="$G_SERVER_ARGS --disable-client-cert"
718
719        M_CLIENT_ARGS="$M_CLIENT_ARGS ca_file=none auth_mode=none"
720        O_CLIENT_ARGS="$O_CLIENT_ARGS"
721        G_CLIENT_ARGS="$G_CLIENT_ARGS --insecure"
722    fi
723
724    case $TYPE in
725        "ECDSA")
726            M_SERVER_ARGS="$M_SERVER_ARGS crt_file=$DATA_FILES_PATH/server5.crt key_file=$DATA_FILES_PATH/server5.key"
727            O_SERVER_ARGS="$O_SERVER_ARGS -cert $DATA_FILES_PATH/server5.crt -key $DATA_FILES_PATH/server5.key"
728            G_SERVER_ARGS="$G_SERVER_ARGS --x509certfile $DATA_FILES_PATH/server5.crt --x509keyfile $DATA_FILES_PATH/server5.key"
729
730            if [ "X$VERIFY" = "XYES" ]; then
731                M_CLIENT_ARGS="$M_CLIENT_ARGS crt_file=$DATA_FILES_PATH/server6.crt key_file=$DATA_FILES_PATH/server6.key"
732                O_CLIENT_ARGS="$O_CLIENT_ARGS -cert $DATA_FILES_PATH/server6.crt -key $DATA_FILES_PATH/server6.key"
733                G_CLIENT_ARGS="$G_CLIENT_ARGS --x509certfile $DATA_FILES_PATH/server6.crt --x509keyfile $DATA_FILES_PATH/server6.key"
734            else
735                M_CLIENT_ARGS="$M_CLIENT_ARGS crt_file=none key_file=none"
736            fi
737            ;;
738
739        "RSA")
740            M_SERVER_ARGS="$M_SERVER_ARGS crt_file=$DATA_FILES_PATH/server2-sha256.crt key_file=$DATA_FILES_PATH/server2.key"
741            O_SERVER_ARGS="$O_SERVER_ARGS -cert $DATA_FILES_PATH/server2-sha256.crt -key $DATA_FILES_PATH/server2.key"
742            G_SERVER_ARGS="$G_SERVER_ARGS --x509certfile $DATA_FILES_PATH/server2-sha256.crt --x509keyfile $DATA_FILES_PATH/server2.key"
743
744            if [ "X$VERIFY" = "XYES" ]; then
745                M_CLIENT_ARGS="$M_CLIENT_ARGS crt_file=$DATA_FILES_PATH/cert_sha256.crt key_file=$DATA_FILES_PATH/server1.key"
746                O_CLIENT_ARGS="$O_CLIENT_ARGS -cert $DATA_FILES_PATH/cert_sha256.crt -key $DATA_FILES_PATH/server1.key"
747                G_CLIENT_ARGS="$G_CLIENT_ARGS --x509certfile $DATA_FILES_PATH/cert_sha256.crt --x509keyfile $DATA_FILES_PATH/server1.key"
748            else
749                M_CLIENT_ARGS="$M_CLIENT_ARGS crt_file=none key_file=none"
750            fi
751            ;;
752
753        "PSK")
754            # give RSA-PSK-capable server a RSA cert
755            # (should be a separate type, but harder to close with openssl)
756            M_SERVER_ARGS="$M_SERVER_ARGS psk=6162636465666768696a6b6c6d6e6f70 ca_file=none crt_file=$DATA_FILES_PATH/server2-sha256.crt key_file=$DATA_FILES_PATH/server2.key"
757            O_SERVER_ARGS="$O_SERVER_ARGS -psk 6162636465666768696a6b6c6d6e6f70 -nocert"
758            G_SERVER_ARGS="$G_SERVER_ARGS --x509certfile $DATA_FILES_PATH/server2-sha256.crt --x509keyfile $DATA_FILES_PATH/server2.key --pskpasswd $DATA_FILES_PATH/passwd.psk"
759
760            M_CLIENT_ARGS="$M_CLIENT_ARGS psk=6162636465666768696a6b6c6d6e6f70 crt_file=none key_file=none"
761            O_CLIENT_ARGS="$O_CLIENT_ARGS -psk 6162636465666768696a6b6c6d6e6f70"
762            G_CLIENT_ARGS="$G_CLIENT_ARGS --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70"
763            ;;
764    esac
765}
766
767# is_mbedtls <cmd_line>
768is_mbedtls() {
769    case $1 in
770        *ssl_client2*) true;;
771        *ssl_server2*) true;;
772        *) false;;
773    esac
774}
775
776# has_mem_err <log_file_name>
777has_mem_err() {
778    if ( grep -F 'All heap blocks were freed -- no leaks are possible' "$1" &&
779         grep -F 'ERROR SUMMARY: 0 errors from 0 contexts' "$1" ) > /dev/null
780    then
781        return 1 # false: does not have errors
782    else
783        return 0 # true: has errors
784    fi
785}
786
787# Wait for process $2 to be listening on port $1
788if type lsof >/dev/null 2>/dev/null; then
789    wait_server_start() {
790        START_TIME=$(date +%s)
791        if is_dtls "$MODE"; then
792            proto=UDP
793        else
794            proto=TCP
795        fi
796        while ! lsof -a -n -b -i "$proto:$1" -p "$2" >/dev/null 2>/dev/null; do
797              if [ $(( $(date +%s) - $START_TIME )) -gt $DOG_DELAY ]; then
798                  echo "SERVERSTART TIMEOUT"
799                  echo "SERVERSTART TIMEOUT" >> $SRV_OUT
800                  break
801              fi
802              # Linux and *BSD support decimal arguments to sleep. On other
803              # OSes this may be a tight loop.
804              sleep 0.1 2>/dev/null || true
805        done
806    }
807else
808    echo "Warning: lsof not available, wait_server_start = sleep"
809    wait_server_start() {
810        sleep 2
811    }
812fi
813
814
815# start_server <name>
816# also saves name and command
817start_server() {
818    case $1 in
819        [Oo]pen*)
820            SERVER_CMD="$OPENSSL s_server $O_SERVER_ARGS"
821            ;;
822        [Gg]nu*)
823            SERVER_CMD="$GNUTLS_SERV $G_SERVER_ARGS --priority $G_SERVER_PRIO"
824            ;;
825        mbed*)
826            SERVER_CMD="$M_SRV $M_SERVER_ARGS"
827            if [ "$MEMCHECK" -gt 0 ]; then
828                SERVER_CMD="valgrind --leak-check=full $SERVER_CMD"
829            fi
830            ;;
831        *)
832            echo "error: invalid server name: $1" >&2
833            exit 1
834            ;;
835    esac
836    SERVER_NAME=$1
837
838    log "$SERVER_CMD"
839    echo "$SERVER_CMD" > $SRV_OUT
840    # for servers without -www or equivalent
841    while :; do echo bla; sleep 1; done | $SERVER_CMD >> $SRV_OUT 2>&1 &
842    SRV_PID=$!
843
844    wait_server_start "$PORT" "$SRV_PID"
845}
846
847# terminate the running server
848stop_server() {
849    # For Ubuntu 22.04, `Terminated` message is outputed by wait command.
850    # To remove it from stdout, redirect stdout/stderr to SRV_OUT
851    kill $SRV_PID >/dev/null 2>&1
852    wait $SRV_PID >> $SRV_OUT 2>&1
853
854    if [ "$MEMCHECK" -gt 0 ]; then
855        if is_mbedtls "$SERVER_CMD" && has_mem_err $SRV_OUT; then
856            echo "  ! Server had memory errors"
857            SRVMEM=$(( $SRVMEM + 1 ))
858            return
859        fi
860    fi
861
862    rm -f $SRV_OUT
863}
864
865# kill the running server (used when killed by signal)
866cleanup() {
867    rm -f $SRV_OUT $CLI_OUT
868    kill $SRV_PID >/dev/null 2>&1
869    kill $WATCHDOG_PID >/dev/null 2>&1
870    exit 1
871}
872
873# wait for client to terminate and set EXIT
874# must be called right after starting the client
875wait_client_done() {
876    CLI_PID=$!
877
878    ( sleep "$DOG_DELAY"; echo "TIMEOUT" >> $CLI_OUT; kill $CLI_PID ) &
879    WATCHDOG_PID=$!
880
881    # For Ubuntu 22.04, `Terminated` message is outputed by wait command.
882    # To remove it from stdout, redirect stdout/stderr to CLI_OUT
883    wait $CLI_PID >> $CLI_OUT 2>&1
884    EXIT=$?
885
886    kill $WATCHDOG_PID >/dev/null 2>&1
887    wait $WATCHDOG_PID >> $CLI_OUT 2>&1
888
889    echo "EXIT: $EXIT" >> $CLI_OUT
890}
891
892# uniform_title <CLIENT> <SERVER> <STANDARD_CIPHER_SUITE>
893# $TITLE is considered as test case description for both --list-test-cases and
894# MBEDTLS_TEST_OUTCOME_FILE. This function aims to control the format of
895# each test case description.
896uniform_title() {
897    TITLE="$1->$2 $MODE,$VERIF $3"
898}
899
900# record_outcome <outcome> [<failure-reason>]
901record_outcome() {
902    echo "$1"
903    if [ -n "$MBEDTLS_TEST_OUTCOME_FILE" ]; then
904        # The test outcome file has the format (in single line):
905        # platform;configuration;
906        # test suite name;test case description;
907        # PASS/FAIL/SKIP;[failure cause]
908        printf '%s;%s;%s;%s;%s;%s\n'                                    \
909            "$MBEDTLS_TEST_PLATFORM" "$MBEDTLS_TEST_CONFIGURATION"      \
910            "compat" "$TITLE"                                           \
911            "$1" "${2-}"                                                \
912            >> "$MBEDTLS_TEST_OUTCOME_FILE"
913    fi
914}
915
916save_logs() {
917    cp $SRV_OUT c-srv-${TESTS}.log
918    cp $CLI_OUT c-cli-${TESTS}.log
919}
920
921# display additional information if test case fails
922report_fail() {
923    FAIL_PROMPT="outputs saved to c-srv-${TESTS}.log, c-cli-${TESTS}.log"
924    record_outcome "FAIL" "$FAIL_PROMPT"
925    save_logs
926    echo "  ! $FAIL_PROMPT"
927
928    if [ "${LOG_FAILURE_ON_STDOUT:-0}" != 0 ]; then
929        echo "  ! server output:"
930        cat c-srv-${TESTS}.log
931        echo "  ! ==================================================="
932        echo "  ! client output:"
933        cat c-cli-${TESTS}.log
934    fi
935}
936
937# run_client PROGRAM_NAME STANDARD_CIPHER_SUITE PROGRAM_CIPHER_SUITE
938run_client() {
939    # announce what we're going to do
940    TESTS=$(( $TESTS + 1 ))
941    uniform_title "${1%"${1#?}"}" "${SERVER_NAME%"${SERVER_NAME#?}"}" $2
942    DOTS72="........................................................................"
943    printf "%s %.*s " "$TITLE" "$((71 - ${#TITLE}))" "$DOTS72"
944
945    # should we skip?
946    if [ "X$SKIP_NEXT" = "XYES" ]; then
947        SKIP_NEXT="NO"
948        record_outcome "SKIP"
949        SKIPPED=$(( $SKIPPED + 1 ))
950        return
951    fi
952
953    # run the command and interpret result
954    case $1 in
955        [Oo]pen*)
956            CLIENT_CMD="$OPENSSL s_client $O_CLIENT_ARGS -cipher $3"
957            log "$CLIENT_CMD"
958            echo "$CLIENT_CMD" > $CLI_OUT
959            printf 'GET HTTP/1.0\r\n\r\n' | $CLIENT_CMD >> $CLI_OUT 2>&1 &
960            wait_client_done
961
962            if [ $EXIT -eq 0 ]; then
963                RESULT=0
964            else
965                # If it is NULL cipher ...
966                if grep 'Cipher is (NONE)' $CLI_OUT >/dev/null; then
967                    RESULT=1
968                else
969                    RESULT=2
970                fi
971            fi
972            ;;
973
974        [Gg]nu*)
975            CLIENT_CMD="$GNUTLS_CLI $G_CLIENT_ARGS --priority $G_PRIO_MODE:$3 localhost"
976            log "$CLIENT_CMD"
977            echo "$CLIENT_CMD" > $CLI_OUT
978            printf 'GET HTTP/1.0\r\n\r\n' | $CLIENT_CMD >> $CLI_OUT 2>&1 &
979            wait_client_done
980
981            if [ $EXIT -eq 0 ]; then
982                RESULT=0
983            else
984                RESULT=2
985                # interpret early failure, with a handshake_failure alert
986                # before the server hello, as "no ciphersuite in common"
987                if grep -F 'Received alert [40]: Handshake failed' $CLI_OUT; then
988                    if grep -i 'SERVER HELLO .* was received' $CLI_OUT; then :
989                    else
990                        RESULT=1
991                    fi
992                fi >/dev/null
993            fi
994            ;;
995
996        mbed*)
997            CLIENT_CMD="$M_CLI $M_CLIENT_ARGS force_ciphersuite=$3"
998            if [ "$MEMCHECK" -gt 0 ]; then
999                CLIENT_CMD="valgrind --leak-check=full $CLIENT_CMD"
1000            fi
1001            log "$CLIENT_CMD"
1002            echo "$CLIENT_CMD" > $CLI_OUT
1003            $CLIENT_CMD >> $CLI_OUT 2>&1 &
1004            wait_client_done
1005
1006            case $EXIT in
1007                # Success
1008                "0")    RESULT=0    ;;
1009
1010                # Ciphersuite not supported
1011                "2")    RESULT=1    ;;
1012
1013                # Error
1014                *)      RESULT=2    ;;
1015            esac
1016
1017            if [ "$MEMCHECK" -gt 0 ]; then
1018                if is_mbedtls "$CLIENT_CMD" && has_mem_err $CLI_OUT; then
1019                    RESULT=2
1020                fi
1021            fi
1022
1023            ;;
1024
1025        *)
1026            echo "error: invalid client name: $1" >&2
1027            exit 1
1028            ;;
1029    esac
1030
1031    echo "EXIT: $EXIT" >> $CLI_OUT
1032
1033    # report and count result
1034    case $RESULT in
1035        "0")
1036            record_outcome "PASS"
1037            if [ "$PRESERVE_LOGS" -gt 0 ]; then
1038                save_logs
1039            fi
1040            ;;
1041        "1")
1042            record_outcome "SKIP"
1043            SKIPPED=$(( $SKIPPED + 1 ))
1044            ;;
1045        "2")
1046            report_fail
1047            FAILED=$(( $FAILED + 1 ))
1048            ;;
1049    esac
1050
1051    rm -f $CLI_OUT
1052}
1053
1054#
1055# MAIN
1056#
1057
1058get_options "$@"
1059
1060# Make the outcome file path relative to the original directory, not
1061# to .../tests
1062case "$MBEDTLS_TEST_OUTCOME_FILE" in
1063    [!/]*)
1064        MBEDTLS_TEST_OUTCOME_FILE="$ORIGINAL_PWD/$MBEDTLS_TEST_OUTCOME_FILE"
1065        ;;
1066esac
1067
1068# sanity checks, avoid an avalanche of errors
1069if [ ! -x "$M_SRV" ]; then
1070    echo "Command '$M_SRV' is not an executable file" >&2
1071    exit 1
1072fi
1073if [ ! -x "$M_CLI" ]; then
1074    echo "Command '$M_CLI' is not an executable file" >&2
1075    exit 1
1076fi
1077
1078if echo "$PEERS" | grep -i openssl > /dev/null; then
1079    if which "$OPENSSL" >/dev/null 2>&1; then :; else
1080        echo "Command '$OPENSSL' not found" >&2
1081        exit 1
1082    fi
1083fi
1084
1085if echo "$PEERS" | grep -i gnutls > /dev/null; then
1086    for CMD in "$GNUTLS_CLI" "$GNUTLS_SERV"; do
1087        if which "$CMD" >/dev/null 2>&1; then :; else
1088            echo "Command '$CMD' not found" >&2
1089            exit 1
1090        fi
1091    done
1092fi
1093
1094for PEER in $PEERS; do
1095    case "$PEER" in
1096        mbed*|[Oo]pen*|[Gg]nu*)
1097            ;;
1098        *)
1099            echo "Unknown peers: $PEER" >&2
1100            exit 1
1101    esac
1102done
1103
1104# Pick a "unique" port in the range 10000-19999.
1105PORT="0000$$"
1106PORT="1$(echo $PORT | tail -c 5)"
1107
1108# Also pick a unique name for intermediate files
1109SRV_OUT="srv_out.$$"
1110CLI_OUT="cli_out.$$"
1111
1112# client timeout delay: be more patient with valgrind
1113if [ "$MEMCHECK" -gt 0 ]; then
1114    DOG_DELAY=30
1115else
1116    DOG_DELAY=10
1117fi
1118
1119SKIP_NEXT="NO"
1120
1121trap cleanup INT TERM HUP
1122
1123for MODE in $MODES; do
1124    for TYPE in $TYPES; do
1125
1126        # PSK cipher suites do not allow client certificate verification.
1127        # This means PSK test cases with VERIFY=YES should be replaced by
1128        # VERIFY=NO or be ignored. SUB_VERIFIES variable is used to constrain
1129        # verification option for PSK test cases.
1130        SUB_VERIFIES=$VERIFIES
1131        if [ "$TYPE" = "PSK" ]; then
1132            SUB_VERIFIES="NO"
1133        fi
1134
1135        for VERIFY in $SUB_VERIFIES; do
1136            VERIF=$(echo $VERIFY | tr '[:upper:]' '[:lower:]')
1137            for PEER in $PEERS; do
1138
1139            setup_arguments
1140
1141            case "$PEER" in
1142
1143                [Oo]pen*)
1144
1145                    reset_ciphersuites
1146                    add_common_ciphersuites
1147                    add_openssl_ciphersuites
1148                    filter_ciphersuites
1149
1150                    if [ "X" != "X$M_CIPHERS" ]; then
1151                        start_server "OpenSSL"
1152                        translate_ciphers m $M_CIPHERS
1153                        for i in $ciphers; do
1154                            o_check_ciphersuite "${i%%=*}"
1155                            run_client mbedTLS ${i%%=*} ${i#*=}
1156                        done
1157                        stop_server
1158                    fi
1159
1160                    if [ "X" != "X$O_CIPHERS" ]; then
1161                        start_server "mbedTLS"
1162                        translate_ciphers o $O_CIPHERS
1163                        for i in $ciphers; do
1164                            o_check_ciphersuite "${i%%=*}"
1165                            run_client OpenSSL ${i%%=*} ${i#*=}
1166                        done
1167                        stop_server
1168                    fi
1169
1170                    ;;
1171
1172                [Gg]nu*)
1173
1174                    reset_ciphersuites
1175                    add_common_ciphersuites
1176                    add_gnutls_ciphersuites
1177                    filter_ciphersuites
1178
1179                    if [ "X" != "X$M_CIPHERS" ]; then
1180                        start_server "GnuTLS"
1181                        translate_ciphers m $M_CIPHERS
1182                        for i in $ciphers; do
1183                            run_client mbedTLS ${i%%=*} ${i#*=}
1184                        done
1185                        stop_server
1186                    fi
1187
1188                    if [ "X" != "X$G_CIPHERS" ]; then
1189                        start_server "mbedTLS"
1190                        translate_ciphers g $G_CIPHERS
1191                        for i in $ciphers; do
1192                            run_client GnuTLS ${i%%=*} ${i#*=}
1193                        done
1194                        stop_server
1195                    fi
1196
1197                    ;;
1198
1199                mbed*)
1200
1201                    reset_ciphersuites
1202                    add_common_ciphersuites
1203                    add_openssl_ciphersuites
1204                    add_gnutls_ciphersuites
1205                    add_mbedtls_ciphersuites
1206                    filter_ciphersuites
1207
1208                    if [ "X" != "X$M_CIPHERS" ]; then
1209                        start_server "mbedTLS"
1210                        translate_ciphers m $M_CIPHERS
1211                        for i in $ciphers; do
1212                            run_client mbedTLS ${i%%=*} ${i#*=}
1213                        done
1214                        stop_server
1215                    fi
1216
1217                    ;;
1218
1219                *)
1220                    echo "Unknown peer: $PEER" >&2
1221                    exit 1
1222                    ;;
1223
1224                esac
1225
1226            done
1227        done
1228    done
1229done
1230
1231echo "------------------------------------------------------------------------"
1232
1233if [ $FAILED -ne 0 -o $SRVMEM -ne 0 ]; then
1234    printf "FAILED"
1235else
1236    printf "PASSED"
1237fi
1238
1239if [ "$MEMCHECK" -gt 0 ]; then
1240    MEMREPORT=", $SRVMEM server memory errors"
1241else
1242    MEMREPORT=""
1243fi
1244
1245PASSED=$(( $TESTS - $FAILED ))
1246echo " ($PASSED / $TESTS tests ($SKIPPED skipped$MEMREPORT))"
1247
1248if [ $((TESTS - SKIPPED)) -lt $MIN_TESTS ]; then
1249    cat <<EOF
1250Error: Expected to run at least $MIN_TESTS, but only ran $((TESTS - SKIPPED)).
1251Maybe a bad filter ('$FILTER' excluding '$EXCLUDE') or a bad configuration?
1252EOF
1253    if [ $FAILED -eq 0 ]; then
1254        FAILED=1
1255    fi
1256fi
1257
1258FAILED=$(( $FAILED + $SRVMEM ))
1259if [ $FAILED -gt 255 ]; then
1260    # Clamp at 255 as caller gets exit code & 0xFF
1261    # (so 256 would be 0, or success, etc)
1262    FAILED=255
1263fi
1264exit $FAILED
1265