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