• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/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="tls1 tls1_1 tls12 dtls1 dtls12" # ssl3 not in default config
89VERIFIES="NO YES"
90TYPES="ECDSA RSA PSK"
91FILTER=""
92# exclude:
93# - NULL: excluded from our default config + requires OpenSSL legacy
94# - RC4, single-DES: requires legacy OpenSSL/GnuTLS versions
95# - 3DES: not in default config
96# - ARIA: not in default config.h + requires OpenSSL >= 1.1.1
97# - ChachaPoly: requires OpenSSL >= 1.1.0
98EXCLUDE='NULL\|DES\|RC4\|ARCFOUR\|ARIA\|CHACHA20-POLY1305'
99VERBOSE=""
100MEMCHECK=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-case\tList all potential test cases (No Execution)\n"
120    printf "     --outcome-file\tFile where test outcomes are written\n"
121    printf "                   \t(default: \$MBEDTLS_TEST_OUTCOME_FILE, none if empty)\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 $TITLE
129    done
130}
131
132# list_test_case lists all potential test cases in compat.sh without execution
133list_test_case() {
134    for MODE in $MODES; do
135        for TYPE in $TYPES; do
136            for VERIFY in $VERIFIES; do
137                VERIF=$(echo $VERIFY | tr '[:upper:]' '[:lower:]')
138                reset_ciphersuites
139                add_common_ciphersuites
140                add_openssl_ciphersuites
141                add_gnutls_ciphersuites
142                add_mbedtls_ciphersuites
143                print_test_case m O "$O_CIPHERS"
144                print_test_case O m "$O_CIPHERS"
145                print_test_case m G "$G_CIPHERS"
146                print_test_case G m "$G_CIPHERS"
147                print_test_case m m "$M_CIPHERS"
148            done
149        done
150    done
151}
152
153get_options() {
154    while [ $# -gt 0 ]; do
155        case "$1" in
156            -f|--filter)
157                shift; FILTER=$1
158                ;;
159            -e|--exclude)
160                shift; EXCLUDE=$1
161                ;;
162            -m|--modes)
163                shift; MODES=$1
164                ;;
165            -t|--types)
166                shift; TYPES=$1
167                ;;
168            -V|--verify)
169                shift; VERIFIES=$1
170                ;;
171            -p|--peers)
172                shift; PEERS=$1
173                ;;
174            -v|--verbose)
175                VERBOSE=1
176                ;;
177            -M|--memcheck)
178                MEMCHECK=1
179                ;;
180            # Please check scripts/check_test_cases.py correspondingly
181            # if you have to modify option, --list-test-case
182            --list-test-case)
183                list_test_case
184                exit $?
185                ;;
186            --outcome-file)
187                shift; MBEDTLS_TEST_OUTCOME_FILE=$1
188                ;;
189            -h|--help)
190                print_usage
191                exit 0
192                ;;
193            *)
194                echo "Unknown argument: '$1'"
195                print_usage
196                exit 1
197                ;;
198        esac
199        shift
200    done
201
202    # sanitize some options (modes checked later)
203    VERIFIES="$( echo $VERIFIES | tr [a-z] [A-Z] )"
204    TYPES="$( echo $TYPES | tr [a-z] [A-Z] )"
205}
206
207log() {
208  if [ "X" != "X$VERBOSE" ]; then
209    echo ""
210    echo "$@"
211  fi
212}
213
214# is_dtls <mode>
215is_dtls()
216{
217    test "$1" = "dtls1" -o "$1" = "dtls12"
218}
219
220# minor_ver <mode>
221minor_ver()
222{
223    case "$1" in
224        ssl3)
225            echo 0
226            ;;
227        tls1)
228            echo 1
229            ;;
230        tls1_1|dtls1)
231            echo 2
232            ;;
233        tls12|dtls12)
234            echo 3
235            ;;
236        *)
237            echo "error: invalid mode: $MODE" >&2
238            # exiting is no good here, typically called in a subshell
239            echo -1
240    esac
241}
242
243filter()
244{
245  LIST="$1"
246  NEW_LIST=""
247
248  if is_dtls "$MODE"; then
249      EXCLMODE="$EXCLUDE"'\|RC4\|ARCFOUR'
250  else
251      EXCLMODE="$EXCLUDE"
252  fi
253
254  for i in $LIST;
255  do
256    NEW_LIST="$NEW_LIST $( echo "$i" | grep "$FILTER" | grep -v "$EXCLMODE" )"
257  done
258
259  # normalize whitespace
260  echo "$NEW_LIST" | sed -e 's/[[:space:]][[:space:]]*/ /g' -e 's/^ //' -e 's/ $//'
261}
262
263filter_ciphersuites()
264{
265    if [ "X" != "X$FILTER" -o "X" != "X$EXCLUDE" ];
266    then
267        # Ciphersuite for Mbed TLS
268        M_CIPHERS=$( filter "$M_CIPHERS" )
269
270        # Ciphersuite for OpenSSL
271        O_CIPHERS=$( filter "$O_CIPHERS" )
272
273        # Ciphersuite for GnuTLS
274        G_CIPHERS=$( filter "$G_CIPHERS" )
275    fi
276
277    # For GnuTLS client -> Mbed TLS server,
278    # we need to force IPv4 by connecting to 127.0.0.1 but then auth fails
279    if is_dtls "$MODE" && [ "X$VERIFY" = "XYES" ]; then
280        G_CIPHERS=""
281    fi
282}
283
284reset_ciphersuites()
285{
286    M_CIPHERS=""
287    O_CIPHERS=""
288    G_CIPHERS=""
289}
290
291# Ciphersuites that can be used with all peers.
292# Since we currently have three possible peers, each ciphersuite should appear
293# three times: in each peer's list (with the name that this peer uses).
294add_common_ciphersuites()
295{
296    case $TYPE in
297
298        "ECDSA")
299            if [ `minor_ver "$MODE"` -gt 0 ]
300            then
301                M_CIPHERS="$M_CIPHERS                       \
302                    TLS-ECDHE-ECDSA-WITH-NULL-SHA           \
303                    TLS-ECDHE-ECDSA-WITH-RC4-128-SHA        \
304                    TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA   \
305                    TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA    \
306                    TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA    \
307                    "
308                G_CIPHERS="$G_CIPHERS                       \
309                    +ECDHE-ECDSA:+NULL:+SHA1                \
310                    +ECDHE-ECDSA:+ARCFOUR-128:+SHA1         \
311                    +ECDHE-ECDSA:+3DES-CBC:+SHA1            \
312                    +ECDHE-ECDSA:+AES-128-CBC:+SHA1         \
313                    +ECDHE-ECDSA:+AES-256-CBC:+SHA1         \
314                    "
315                O_CIPHERS="$O_CIPHERS               \
316                    ECDHE-ECDSA-NULL-SHA            \
317                    ECDHE-ECDSA-RC4-SHA             \
318                    ECDHE-ECDSA-DES-CBC3-SHA        \
319                    ECDHE-ECDSA-AES128-SHA          \
320                    ECDHE-ECDSA-AES256-SHA          \
321                    "
322            fi
323            if [ `minor_ver "$MODE"` -ge 3 ]
324            then
325                M_CIPHERS="$M_CIPHERS                               \
326                    TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256         \
327                    TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384         \
328                    TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256         \
329                    TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384         \
330                    "
331                G_CIPHERS="$G_CIPHERS                               \
332                    +ECDHE-ECDSA:+AES-128-CBC:+SHA256               \
333                    +ECDHE-ECDSA:+AES-256-CBC:+SHA384               \
334                    +ECDHE-ECDSA:+AES-128-GCM:+AEAD                 \
335                    +ECDHE-ECDSA:+AES-256-GCM:+AEAD                 \
336                    "
337                O_CIPHERS="$O_CIPHERS               \
338                    ECDHE-ECDSA-AES128-SHA256       \
339                    ECDHE-ECDSA-AES256-SHA384       \
340                    ECDHE-ECDSA-AES128-GCM-SHA256   \
341                    ECDHE-ECDSA-AES256-GCM-SHA384   \
342                    "
343            fi
344            ;;
345
346        "RSA")
347            M_CIPHERS="$M_CIPHERS                       \
348                TLS-DHE-RSA-WITH-AES-128-CBC-SHA        \
349                TLS-DHE-RSA-WITH-AES-256-CBC-SHA        \
350                TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA   \
351                TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA   \
352                TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA       \
353                TLS-RSA-WITH-AES-256-CBC-SHA            \
354                TLS-RSA-WITH-CAMELLIA-256-CBC-SHA       \
355                TLS-RSA-WITH-AES-128-CBC-SHA            \
356                TLS-RSA-WITH-CAMELLIA-128-CBC-SHA       \
357                TLS-RSA-WITH-3DES-EDE-CBC-SHA           \
358                TLS-RSA-WITH-RC4-128-SHA                \
359                TLS-RSA-WITH-RC4-128-MD5                \
360                TLS-RSA-WITH-NULL-MD5                   \
361                TLS-RSA-WITH-NULL-SHA                   \
362                "
363            G_CIPHERS="$G_CIPHERS                       \
364                +DHE-RSA:+AES-128-CBC:+SHA1             \
365                +DHE-RSA:+AES-256-CBC:+SHA1             \
366                +DHE-RSA:+CAMELLIA-128-CBC:+SHA1        \
367                +DHE-RSA:+CAMELLIA-256-CBC:+SHA1        \
368                +DHE-RSA:+3DES-CBC:+SHA1                \
369                +RSA:+AES-256-CBC:+SHA1                 \
370                +RSA:+CAMELLIA-256-CBC:+SHA1            \
371                +RSA:+AES-128-CBC:+SHA1                 \
372                +RSA:+CAMELLIA-128-CBC:+SHA1            \
373                +RSA:+3DES-CBC:+SHA1                    \
374                +RSA:+ARCFOUR-128:+SHA1                 \
375                +RSA:+ARCFOUR-128:+MD5                  \
376                +RSA:+NULL:+MD5                         \
377                +RSA:+NULL:+SHA1                        \
378                "
379            O_CIPHERS="$O_CIPHERS               \
380                DHE-RSA-AES128-SHA              \
381                DHE-RSA-AES256-SHA              \
382                DHE-RSA-CAMELLIA128-SHA         \
383                DHE-RSA-CAMELLIA256-SHA         \
384                EDH-RSA-DES-CBC3-SHA            \
385                AES256-SHA                      \
386                CAMELLIA256-SHA                 \
387                AES128-SHA                      \
388                CAMELLIA128-SHA                 \
389                DES-CBC3-SHA                    \
390                RC4-SHA                         \
391                RC4-MD5                         \
392                NULL-MD5                        \
393                NULL-SHA                        \
394                "
395            if [ `minor_ver "$MODE"` -gt 0 ]
396            then
397                M_CIPHERS="$M_CIPHERS                       \
398                    TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA      \
399                    TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA      \
400                    TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA     \
401                    TLS-ECDHE-RSA-WITH-RC4-128-SHA          \
402                    TLS-ECDHE-RSA-WITH-NULL-SHA             \
403                    "
404                G_CIPHERS="$G_CIPHERS                       \
405                    +ECDHE-RSA:+AES-128-CBC:+SHA1           \
406                    +ECDHE-RSA:+AES-256-CBC:+SHA1           \
407                    +ECDHE-RSA:+3DES-CBC:+SHA1              \
408                    +ECDHE-RSA:+ARCFOUR-128:+SHA1           \
409                    +ECDHE-RSA:+NULL:+SHA1                  \
410                    "
411                O_CIPHERS="$O_CIPHERS               \
412                    ECDHE-RSA-AES256-SHA            \
413                    ECDHE-RSA-AES128-SHA            \
414                    ECDHE-RSA-DES-CBC3-SHA          \
415                    ECDHE-RSA-RC4-SHA               \
416                    ECDHE-RSA-NULL-SHA              \
417                    "
418            fi
419            if [ `minor_ver "$MODE"` -ge 3 ]
420            then
421                M_CIPHERS="$M_CIPHERS                       \
422                    TLS-RSA-WITH-AES-128-CBC-SHA256         \
423                    TLS-DHE-RSA-WITH-AES-128-CBC-SHA256     \
424                    TLS-RSA-WITH-AES-256-CBC-SHA256         \
425                    TLS-DHE-RSA-WITH-AES-256-CBC-SHA256     \
426                    TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256   \
427                    TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384   \
428                    TLS-RSA-WITH-AES-128-GCM-SHA256         \
429                    TLS-RSA-WITH-AES-256-GCM-SHA384         \
430                    TLS-DHE-RSA-WITH-AES-128-GCM-SHA256     \
431                    TLS-DHE-RSA-WITH-AES-256-GCM-SHA384     \
432                    TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256   \
433                    TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384   \
434                    "
435                G_CIPHERS="$G_CIPHERS                       \
436                    +RSA:+AES-128-CBC:+SHA256               \
437                    +DHE-RSA:+AES-128-CBC:+SHA256           \
438                    +RSA:+AES-256-CBC:+SHA256               \
439                    +DHE-RSA:+AES-256-CBC:+SHA256           \
440                    +ECDHE-RSA:+AES-128-CBC:+SHA256         \
441                    +ECDHE-RSA:+AES-256-CBC:+SHA384         \
442                    +RSA:+AES-128-GCM:+AEAD                 \
443                    +RSA:+AES-256-GCM:+AEAD                 \
444                    +DHE-RSA:+AES-128-GCM:+AEAD             \
445                    +DHE-RSA:+AES-256-GCM:+AEAD             \
446                    +ECDHE-RSA:+AES-128-GCM:+AEAD           \
447                    +ECDHE-RSA:+AES-256-GCM:+AEAD           \
448                    "
449                O_CIPHERS="$O_CIPHERS           \
450                    NULL-SHA256                 \
451                    AES128-SHA256               \
452                    DHE-RSA-AES128-SHA256       \
453                    AES256-SHA256               \
454                    DHE-RSA-AES256-SHA256       \
455                    ECDHE-RSA-AES128-SHA256     \
456                    ECDHE-RSA-AES256-SHA384     \
457                    AES128-GCM-SHA256           \
458                    DHE-RSA-AES128-GCM-SHA256   \
459                    AES256-GCM-SHA384           \
460                    DHE-RSA-AES256-GCM-SHA384   \
461                    ECDHE-RSA-AES128-GCM-SHA256 \
462                    ECDHE-RSA-AES256-GCM-SHA384 \
463                    "
464            fi
465            ;;
466
467        "PSK")
468            M_CIPHERS="$M_CIPHERS                       \
469                TLS-PSK-WITH-RC4-128-SHA                \
470                TLS-PSK-WITH-3DES-EDE-CBC-SHA           \
471                TLS-PSK-WITH-AES-128-CBC-SHA            \
472                TLS-PSK-WITH-AES-256-CBC-SHA            \
473                "
474            G_CIPHERS="$G_CIPHERS                       \
475                +PSK:+ARCFOUR-128:+SHA1                 \
476                +PSK:+3DES-CBC:+SHA1                    \
477                +PSK:+AES-128-CBC:+SHA1                 \
478                +PSK:+AES-256-CBC:+SHA1                 \
479                "
480            O_CIPHERS="$O_CIPHERS               \
481                PSK-RC4-SHA                     \
482                PSK-3DES-EDE-CBC-SHA            \
483                PSK-AES128-CBC-SHA              \
484                PSK-AES256-CBC-SHA              \
485                "
486            ;;
487    esac
488}
489
490# Ciphersuites usable only with Mbed TLS and OpenSSL
491# Each ciphersuite should appear two times, once with its OpenSSL name, once
492# with its Mbed TLS name.
493#
494# NOTE: for some reason RSA-PSK doesn't work with OpenSSL,
495# so RSA-PSK ciphersuites need to go in other sections, see
496# https://github.com/Mbed-TLS/mbedtls/issues/1419
497#
498# ChachaPoly suites are here rather than in "common", as they were added in
499# GnuTLS in 3.5.0 and the CI only has 3.4.x so far.
500add_openssl_ciphersuites()
501{
502    case $TYPE in
503
504        "ECDSA")
505            if [ `minor_ver "$MODE"` -gt 0 ]
506            then
507                M_CIPHERS="$M_CIPHERS                       \
508                    TLS-ECDH-ECDSA-WITH-NULL-SHA            \
509                    TLS-ECDH-ECDSA-WITH-RC4-128-SHA         \
510                    TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA    \
511                    TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA     \
512                    TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA     \
513                    "
514                O_CIPHERS="$O_CIPHERS               \
515                    ECDH-ECDSA-NULL-SHA             \
516                    ECDH-ECDSA-RC4-SHA              \
517                    ECDH-ECDSA-DES-CBC3-SHA         \
518                    ECDH-ECDSA-AES128-SHA           \
519                    ECDH-ECDSA-AES256-SHA           \
520                    "
521            fi
522            if [ `minor_ver "$MODE"` -ge 3 ]
523            then
524                M_CIPHERS="$M_CIPHERS                               \
525                    TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256          \
526                    TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384          \
527                    TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256          \
528                    TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384          \
529                    TLS-ECDHE-ECDSA-WITH-ARIA-256-GCM-SHA384        \
530                    TLS-ECDHE-ECDSA-WITH-ARIA-128-GCM-SHA256        \
531                    TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256   \
532                    "
533                O_CIPHERS="$O_CIPHERS               \
534                    ECDH-ECDSA-AES128-SHA256        \
535                    ECDH-ECDSA-AES256-SHA384        \
536                    ECDH-ECDSA-AES128-GCM-SHA256    \
537                    ECDH-ECDSA-AES256-GCM-SHA384    \
538                    ECDHE-ECDSA-ARIA256-GCM-SHA384  \
539                    ECDHE-ECDSA-ARIA128-GCM-SHA256  \
540                    ECDHE-ECDSA-CHACHA20-POLY1305   \
541                    "
542            fi
543            ;;
544
545        "RSA")
546            M_CIPHERS="$M_CIPHERS                       \
547                TLS-RSA-WITH-DES-CBC-SHA                \
548                TLS-DHE-RSA-WITH-DES-CBC-SHA            \
549                "
550            O_CIPHERS="$O_CIPHERS               \
551                DES-CBC-SHA                     \
552                EDH-RSA-DES-CBC-SHA             \
553                "
554            if [ `minor_ver "$MODE"` -ge 3 ]
555            then
556                M_CIPHERS="$M_CIPHERS                               \
557                    TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384          \
558                    TLS-DHE-RSA-WITH-ARIA-256-GCM-SHA384            \
559                    TLS-RSA-WITH-ARIA-256-GCM-SHA384                \
560                    TLS-ECDHE-RSA-WITH-ARIA-128-GCM-SHA256          \
561                    TLS-DHE-RSA-WITH-ARIA-128-GCM-SHA256            \
562                    TLS-RSA-WITH-ARIA-128-GCM-SHA256                \
563                    TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256       \
564                    TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256     \
565                    "
566                O_CIPHERS="$O_CIPHERS               \
567                    ECDHE-ARIA256-GCM-SHA384        \
568                    DHE-RSA-ARIA256-GCM-SHA384      \
569                    ARIA256-GCM-SHA384              \
570                    ECDHE-ARIA128-GCM-SHA256        \
571                    DHE-RSA-ARIA128-GCM-SHA256      \
572                    ARIA128-GCM-SHA256              \
573                    DHE-RSA-CHACHA20-POLY1305       \
574                    ECDHE-RSA-CHACHA20-POLY1305     \
575                    "
576            fi
577            ;;
578
579        "PSK")
580            if [ `minor_ver "$MODE"` -ge 3 ]
581            then
582                M_CIPHERS="$M_CIPHERS                               \
583                    TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384            \
584                    TLS-DHE-PSK-WITH-ARIA-128-GCM-SHA256            \
585                    TLS-PSK-WITH-ARIA-256-GCM-SHA384                \
586                    TLS-PSK-WITH-ARIA-128-GCM-SHA256                \
587                    TLS-PSK-WITH-CHACHA20-POLY1305-SHA256           \
588                    TLS-ECDHE-PSK-WITH-CHACHA20-POLY1305-SHA256     \
589                    TLS-DHE-PSK-WITH-CHACHA20-POLY1305-SHA256       \
590                    "
591                O_CIPHERS="$O_CIPHERS               \
592                    DHE-PSK-ARIA256-GCM-SHA384      \
593                    DHE-PSK-ARIA128-GCM-SHA256      \
594                    PSK-ARIA256-GCM-SHA384          \
595                    PSK-ARIA128-GCM-SHA256          \
596                    DHE-PSK-CHACHA20-POLY1305       \
597                    ECDHE-PSK-CHACHA20-POLY1305     \
598                    PSK-CHACHA20-POLY1305           \
599                    "
600            fi
601            ;;
602    esac
603}
604
605# Ciphersuites usable only with Mbed TLS and GnuTLS
606# Each ciphersuite should appear two times, once with its GnuTLS name, once
607# with its Mbed TLS name.
608add_gnutls_ciphersuites()
609{
610    case $TYPE in
611
612        "ECDSA")
613            if [ `minor_ver "$MODE"` -ge 3 ]
614            then
615                M_CIPHERS="$M_CIPHERS                               \
616                    TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256    \
617                    TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384    \
618                    TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256    \
619                    TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384    \
620                    TLS-ECDHE-ECDSA-WITH-AES-128-CCM                \
621                    TLS-ECDHE-ECDSA-WITH-AES-256-CCM                \
622                    TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8              \
623                    TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8              \
624                   "
625                G_CIPHERS="$G_CIPHERS                               \
626                    +ECDHE-ECDSA:+CAMELLIA-128-CBC:+SHA256          \
627                    +ECDHE-ECDSA:+CAMELLIA-256-CBC:+SHA384          \
628                    +ECDHE-ECDSA:+CAMELLIA-128-GCM:+AEAD            \
629                    +ECDHE-ECDSA:+CAMELLIA-256-GCM:+AEAD            \
630                    +ECDHE-ECDSA:+AES-128-CCM:+AEAD                 \
631                    +ECDHE-ECDSA:+AES-256-CCM:+AEAD                 \
632                    +ECDHE-ECDSA:+AES-128-CCM-8:+AEAD               \
633                    +ECDHE-ECDSA:+AES-256-CCM-8:+AEAD               \
634                   "
635            fi
636            ;;
637
638        "RSA")
639            if [ `minor_ver "$MODE"` -gt 0 ]
640            then
641                M_CIPHERS="$M_CIPHERS                           \
642                    TLS-RSA-WITH-NULL-SHA256                    \
643                    "
644                G_CIPHERS="$G_CIPHERS                           \
645                    +RSA:+NULL:+SHA256                          \
646                    "
647            fi
648            if [ `minor_ver "$MODE"` -ge 3 ]
649            then
650                M_CIPHERS="$M_CIPHERS                           \
651                    TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256  \
652                    TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384  \
653                    TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256        \
654                    TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256        \
655                    TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256    \
656                    TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256    \
657                    TLS-ECDHE-RSA-WITH-CAMELLIA-128-GCM-SHA256  \
658                    TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384  \
659                    TLS-DHE-RSA-WITH-CAMELLIA-128-GCM-SHA256    \
660                    TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384    \
661                    TLS-RSA-WITH-CAMELLIA-128-GCM-SHA256        \
662                    TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384        \
663                    TLS-RSA-WITH-AES-128-CCM                    \
664                    TLS-RSA-WITH-AES-256-CCM                    \
665                    TLS-DHE-RSA-WITH-AES-128-CCM                \
666                    TLS-DHE-RSA-WITH-AES-256-CCM                \
667                    TLS-RSA-WITH-AES-128-CCM-8                  \
668                    TLS-RSA-WITH-AES-256-CCM-8                  \
669                    TLS-DHE-RSA-WITH-AES-128-CCM-8              \
670                    TLS-DHE-RSA-WITH-AES-256-CCM-8              \
671                    "
672                G_CIPHERS="$G_CIPHERS                           \
673                    +ECDHE-RSA:+CAMELLIA-128-CBC:+SHA256        \
674                    +ECDHE-RSA:+CAMELLIA-256-CBC:+SHA384        \
675                    +RSA:+CAMELLIA-128-CBC:+SHA256              \
676                    +RSA:+CAMELLIA-256-CBC:+SHA256              \
677                    +DHE-RSA:+CAMELLIA-128-CBC:+SHA256          \
678                    +DHE-RSA:+CAMELLIA-256-CBC:+SHA256          \
679                    +ECDHE-RSA:+CAMELLIA-128-GCM:+AEAD          \
680                    +ECDHE-RSA:+CAMELLIA-256-GCM:+AEAD          \
681                    +DHE-RSA:+CAMELLIA-128-GCM:+AEAD            \
682                    +DHE-RSA:+CAMELLIA-256-GCM:+AEAD            \
683                    +RSA:+CAMELLIA-128-GCM:+AEAD                \
684                    +RSA:+CAMELLIA-256-GCM:+AEAD                \
685                    +RSA:+AES-128-CCM:+AEAD                     \
686                    +RSA:+AES-256-CCM:+AEAD                     \
687                    +RSA:+AES-128-CCM-8:+AEAD                   \
688                    +RSA:+AES-256-CCM-8:+AEAD                   \
689                    +DHE-RSA:+AES-128-CCM:+AEAD                 \
690                    +DHE-RSA:+AES-256-CCM:+AEAD                 \
691                    +DHE-RSA:+AES-128-CCM-8:+AEAD               \
692                    +DHE-RSA:+AES-256-CCM-8:+AEAD               \
693                    "
694            fi
695            ;;
696
697        "PSK")
698            M_CIPHERS="$M_CIPHERS                               \
699                TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA               \
700                TLS-DHE-PSK-WITH-AES-128-CBC-SHA                \
701                TLS-DHE-PSK-WITH-AES-256-CBC-SHA                \
702                TLS-DHE-PSK-WITH-RC4-128-SHA                    \
703                "
704            G_CIPHERS="$G_CIPHERS                               \
705                +DHE-PSK:+3DES-CBC:+SHA1                        \
706                +DHE-PSK:+AES-128-CBC:+SHA1                     \
707                +DHE-PSK:+AES-256-CBC:+SHA1                     \
708                +DHE-PSK:+ARCFOUR-128:+SHA1                     \
709                "
710            if [ `minor_ver "$MODE"` -gt 0 ]
711            then
712                M_CIPHERS="$M_CIPHERS                           \
713                    TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA          \
714                    TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA          \
715                    TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA         \
716                    TLS-ECDHE-PSK-WITH-RC4-128-SHA              \
717                    TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA           \
718                    TLS-RSA-PSK-WITH-AES-256-CBC-SHA            \
719                    TLS-RSA-PSK-WITH-AES-128-CBC-SHA            \
720                    TLS-RSA-PSK-WITH-RC4-128-SHA                \
721                    "
722                G_CIPHERS="$G_CIPHERS                           \
723                    +ECDHE-PSK:+3DES-CBC:+SHA1                  \
724                    +ECDHE-PSK:+AES-128-CBC:+SHA1               \
725                    +ECDHE-PSK:+AES-256-CBC:+SHA1               \
726                    +ECDHE-PSK:+ARCFOUR-128:+SHA1               \
727                    +RSA-PSK:+3DES-CBC:+SHA1                    \
728                    +RSA-PSK:+AES-256-CBC:+SHA1                 \
729                    +RSA-PSK:+AES-128-CBC:+SHA1                 \
730                    +RSA-PSK:+ARCFOUR-128:+SHA1                 \
731                    "
732            fi
733            if [ `minor_ver "$MODE"` -ge 3 ]
734            then
735                M_CIPHERS="$M_CIPHERS                           \
736                    TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384       \
737                    TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384  \
738                    TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256       \
739                    TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256  \
740                    TLS-ECDHE-PSK-WITH-NULL-SHA384              \
741                    TLS-ECDHE-PSK-WITH-NULL-SHA256              \
742                    TLS-PSK-WITH-AES-128-CBC-SHA256             \
743                    TLS-PSK-WITH-AES-256-CBC-SHA384             \
744                    TLS-DHE-PSK-WITH-AES-128-CBC-SHA256         \
745                    TLS-DHE-PSK-WITH-AES-256-CBC-SHA384         \
746                    TLS-PSK-WITH-NULL-SHA256                    \
747                    TLS-PSK-WITH-NULL-SHA384                    \
748                    TLS-DHE-PSK-WITH-NULL-SHA256                \
749                    TLS-DHE-PSK-WITH-NULL-SHA384                \
750                    TLS-RSA-PSK-WITH-AES-256-CBC-SHA384         \
751                    TLS-RSA-PSK-WITH-AES-128-CBC-SHA256         \
752                    TLS-RSA-PSK-WITH-NULL-SHA256                \
753                    TLS-RSA-PSK-WITH-NULL-SHA384                \
754                    TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256    \
755                    TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384    \
756                    TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256        \
757                    TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384        \
758                    TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384    \
759                    TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256    \
760                    TLS-PSK-WITH-AES-128-GCM-SHA256             \
761                    TLS-PSK-WITH-AES-256-GCM-SHA384             \
762                    TLS-DHE-PSK-WITH-AES-128-GCM-SHA256         \
763                    TLS-DHE-PSK-WITH-AES-256-GCM-SHA384         \
764                    TLS-PSK-WITH-AES-128-CCM                    \
765                    TLS-PSK-WITH-AES-256-CCM                    \
766                    TLS-DHE-PSK-WITH-AES-128-CCM                \
767                    TLS-DHE-PSK-WITH-AES-256-CCM                \
768                    TLS-PSK-WITH-AES-128-CCM-8                  \
769                    TLS-PSK-WITH-AES-256-CCM-8                  \
770                    TLS-DHE-PSK-WITH-AES-128-CCM-8              \
771                    TLS-DHE-PSK-WITH-AES-256-CCM-8              \
772                    TLS-RSA-PSK-WITH-CAMELLIA-128-GCM-SHA256    \
773                    TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384    \
774                    TLS-PSK-WITH-CAMELLIA-128-GCM-SHA256        \
775                    TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384        \
776                    TLS-DHE-PSK-WITH-CAMELLIA-128-GCM-SHA256    \
777                    TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384    \
778                    TLS-RSA-PSK-WITH-AES-256-GCM-SHA384         \
779                    TLS-RSA-PSK-WITH-AES-128-GCM-SHA256         \
780                    "
781                G_CIPHERS="$G_CIPHERS                           \
782                    +ECDHE-PSK:+AES-256-CBC:+SHA384             \
783                    +ECDHE-PSK:+CAMELLIA-256-CBC:+SHA384        \
784                    +ECDHE-PSK:+AES-128-CBC:+SHA256             \
785                    +ECDHE-PSK:+CAMELLIA-128-CBC:+SHA256        \
786                    +PSK:+AES-128-CBC:+SHA256                   \
787                    +PSK:+AES-256-CBC:+SHA384                   \
788                    +DHE-PSK:+AES-128-CBC:+SHA256               \
789                    +DHE-PSK:+AES-256-CBC:+SHA384               \
790                    +RSA-PSK:+AES-256-CBC:+SHA384               \
791                    +RSA-PSK:+AES-128-CBC:+SHA256               \
792                    +DHE-PSK:+CAMELLIA-128-CBC:+SHA256          \
793                    +DHE-PSK:+CAMELLIA-256-CBC:+SHA384          \
794                    +PSK:+CAMELLIA-128-CBC:+SHA256              \
795                    +PSK:+CAMELLIA-256-CBC:+SHA384              \
796                    +RSA-PSK:+CAMELLIA-256-CBC:+SHA384          \
797                    +RSA-PSK:+CAMELLIA-128-CBC:+SHA256          \
798                    +PSK:+AES-128-GCM:+AEAD                     \
799                    +PSK:+AES-256-GCM:+AEAD                     \
800                    +DHE-PSK:+AES-128-GCM:+AEAD                 \
801                    +DHE-PSK:+AES-256-GCM:+AEAD                 \
802                    +PSK:+AES-128-CCM:+AEAD                     \
803                    +PSK:+AES-256-CCM:+AEAD                     \
804                    +DHE-PSK:+AES-128-CCM:+AEAD                 \
805                    +DHE-PSK:+AES-256-CCM:+AEAD                 \
806                    +PSK:+AES-128-CCM-8:+AEAD                   \
807                    +PSK:+AES-256-CCM-8:+AEAD                   \
808                    +DHE-PSK:+AES-128-CCM-8:+AEAD               \
809                    +DHE-PSK:+AES-256-CCM-8:+AEAD               \
810                    +RSA-PSK:+CAMELLIA-128-GCM:+AEAD            \
811                    +RSA-PSK:+CAMELLIA-256-GCM:+AEAD            \
812                    +PSK:+CAMELLIA-128-GCM:+AEAD                \
813                    +PSK:+CAMELLIA-256-GCM:+AEAD                \
814                    +DHE-PSK:+CAMELLIA-128-GCM:+AEAD            \
815                    +DHE-PSK:+CAMELLIA-256-GCM:+AEAD            \
816                    +RSA-PSK:+AES-256-GCM:+AEAD                 \
817                    +RSA-PSK:+AES-128-GCM:+AEAD                 \
818                    +ECDHE-PSK:+NULL:+SHA384                    \
819                    +ECDHE-PSK:+NULL:+SHA256                    \
820                    +PSK:+NULL:+SHA256                          \
821                    +PSK:+NULL:+SHA384                          \
822                    +DHE-PSK:+NULL:+SHA256                      \
823                    +DHE-PSK:+NULL:+SHA384                      \
824                    +RSA-PSK:+NULL:+SHA256                      \
825                    +RSA-PSK:+NULL:+SHA384                      \
826                    "
827            fi
828            ;;
829    esac
830}
831
832# Ciphersuites usable only with Mbed TLS (not currently supported by another
833# peer usable in this script). This provide only very rudimentaty testing, as
834# this is not interop testing, but it's better than nothing.
835add_mbedtls_ciphersuites()
836{
837    case $TYPE in
838
839        "ECDSA")
840            if [ `minor_ver "$MODE"` -gt 0 ]
841            then
842                M_CIPHERS="$M_CIPHERS                               \
843                    TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256     \
844                    TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384     \
845                    "
846            fi
847            if [ `minor_ver "$MODE"` -ge 3 ]
848            then
849                M_CIPHERS="$M_CIPHERS                               \
850                    TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256     \
851                    TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384     \
852                    TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384        \
853                    TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256        \
854                    TLS-ECDH-ECDSA-WITH-ARIA-256-GCM-SHA384         \
855                    TLS-ECDH-ECDSA-WITH-ARIA-128-GCM-SHA256         \
856                    TLS-ECDH-ECDSA-WITH-ARIA-256-CBC-SHA384         \
857                    TLS-ECDH-ECDSA-WITH-ARIA-128-CBC-SHA256         \
858                    "
859            fi
860            ;;
861
862        "RSA")
863            if [ `minor_ver "$MODE"` -ge 3 ]
864            then
865                M_CIPHERS="$M_CIPHERS                               \
866                    TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384          \
867                    TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384            \
868                    TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256          \
869                    TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256            \
870                    TLS-RSA-WITH-ARIA-256-CBC-SHA384                \
871                    TLS-RSA-WITH-ARIA-128-CBC-SHA256                \
872                    "
873            fi
874            ;;
875
876        "PSK")
877            # *PSK-NULL-SHA suites supported by GnuTLS 3.3.5 but not 3.2.15
878            M_CIPHERS="$M_CIPHERS                        \
879                TLS-PSK-WITH-NULL-SHA                    \
880                TLS-DHE-PSK-WITH-NULL-SHA                \
881                "
882            if [ `minor_ver "$MODE"` -gt 0 ]
883            then
884                M_CIPHERS="$M_CIPHERS                    \
885                    TLS-ECDHE-PSK-WITH-NULL-SHA          \
886                    TLS-RSA-PSK-WITH-NULL-SHA            \
887                    "
888            fi
889            if [ `minor_ver "$MODE"` -ge 3 ]
890            then
891                M_CIPHERS="$M_CIPHERS                               \
892                    TLS-RSA-PSK-WITH-ARIA-256-CBC-SHA384            \
893                    TLS-RSA-PSK-WITH-ARIA-128-CBC-SHA256            \
894                    TLS-PSK-WITH-ARIA-256-CBC-SHA384                \
895                    TLS-PSK-WITH-ARIA-128-CBC-SHA256                \
896                    TLS-RSA-PSK-WITH-ARIA-256-GCM-SHA384            \
897                    TLS-RSA-PSK-WITH-ARIA-128-GCM-SHA256            \
898                    TLS-ECDHE-PSK-WITH-ARIA-256-CBC-SHA384          \
899                    TLS-ECDHE-PSK-WITH-ARIA-128-CBC-SHA256          \
900                    TLS-DHE-PSK-WITH-ARIA-256-CBC-SHA384            \
901                    TLS-DHE-PSK-WITH-ARIA-128-CBC-SHA256            \
902                    TLS-RSA-PSK-WITH-CHACHA20-POLY1305-SHA256       \
903                    "
904            fi
905            ;;
906    esac
907}
908
909# o_check_ciphersuite CIPHER_SUITE_NAME
910o_check_ciphersuite()
911{
912    if [ "${O_SUPPORT_ECDH}" = "NO" ]; then
913        case "$1" in
914            *ECDH-*) SKIP_NEXT="YES"
915        esac
916    fi
917}
918
919setup_arguments()
920{
921    O_MODE=""
922    G_MODE=""
923    case "$MODE" in
924        "ssl3")
925            O_MODE="ssl3"
926            G_PRIO_MODE="+VERS-SSL3.0"
927            ;;
928        "tls1")
929            O_MODE="tls1"
930            G_PRIO_MODE="+VERS-TLS1.0"
931            ;;
932        "tls1_1")
933            O_MODE="tls1_1"
934            G_PRIO_MODE="+VERS-TLS1.1"
935            ;;
936        "tls12")
937            O_MODE="tls1_2"
938            G_PRIO_MODE="+VERS-TLS1.2"
939            ;;
940        "dtls1")
941            O_MODE="dtls1"
942            G_PRIO_MODE="+VERS-DTLS1.0"
943            G_MODE="-u"
944            ;;
945        "dtls12")
946            O_MODE="dtls1_2"
947            G_PRIO_MODE="+VERS-DTLS1.2"
948            G_MODE="-u"
949            ;;
950        *)
951            echo "error: invalid mode: $MODE" >&2
952            exit 1;
953    esac
954
955    # GnuTLS < 3.4 will choke if we try to allow CCM-8
956    if [ -z "${GNUTLS_MINOR_LT_FOUR-}" ]; then
957        G_PRIO_CCM="+AES-256-CCM-8:+AES-128-CCM-8:"
958    else
959        G_PRIO_CCM=""
960    fi
961
962    M_SERVER_ARGS="server_port=$PORT server_addr=0.0.0.0 force_version=$MODE arc4=1"
963    O_SERVER_ARGS="-accept $PORT -cipher NULL,ALL -$O_MODE"
964    G_SERVER_ARGS="-p $PORT --http $G_MODE"
965    G_SERVER_PRIO="NORMAL:${G_PRIO_CCM}+ARCFOUR-128:+NULL:+MD5:+PSK:+DHE-PSK:+ECDHE-PSK:+SHA256:+SHA384:+RSA-PSK:-VERS-TLS-ALL:$G_PRIO_MODE"
966
967    # The default prime for `openssl s_server` depends on the version:
968    # * OpenSSL <= 1.0.2a: 512-bit
969    # * OpenSSL 1.0.2b to 1.1.1b: 1024-bit
970    # * OpenSSL >= 1.1.1c: 2048-bit
971    # Mbed TLS wants >=1024, so force that for older versions. Don't force
972    # it for newer versions, which reject a 1024-bit prime. Indifferently
973    # force it or not for intermediate versions.
974    case $($OPENSSL version) in
975        "OpenSSL 1.0"*)
976            O_SERVER_ARGS="$O_SERVER_ARGS -dhparam data_files/dhparams.pem"
977            ;;
978    esac
979
980    # with OpenSSL 1.0.1h, -www, -WWW and -HTTP break DTLS handshakes
981    if is_dtls "$MODE"; then
982        O_SERVER_ARGS="$O_SERVER_ARGS"
983    else
984        O_SERVER_ARGS="$O_SERVER_ARGS -www"
985    fi
986
987    M_CLIENT_ARGS="server_port=$PORT server_addr=127.0.0.1 force_version=$MODE"
988    O_CLIENT_ARGS="-connect localhost:$PORT -$O_MODE"
989    G_CLIENT_ARGS="-p $PORT --debug 3 $G_MODE"
990
991    # Newer versions of OpenSSL have a syntax to enable all "ciphers", even
992    # low-security ones. This covers not just cipher suites but also protocol
993    # versions. It is necessary, for example, to use (D)TLS 1.0/1.1 on
994    # OpenSSL 1.1.1f from Ubuntu 20.04. The syntax was only introduced in
995    # OpenSSL 1.1.0 (21e0c1d23afff48601eb93135defddae51f7e2e3) and I can't find
996    # a way to discover it from -help, so check the openssl version.
997    case $($OPENSSL version) in
998        "OpenSSL 0"*|"OpenSSL 1.0"*) :;;
999        *)
1000            O_CLIENT_ARGS="$O_CLIENT_ARGS -cipher ALL@SECLEVEL=0"
1001            O_SERVER_ARGS="$O_SERVER_ARGS -cipher ALL@SECLEVEL=0"
1002            ;;
1003    esac
1004
1005    case $($OPENSSL ciphers ALL) in
1006        *ECDH-ECDSA*|*ECDH-RSA*) O_SUPPORT_ECDH="YES";;
1007        *) O_SUPPORT_ECDH="NO";;
1008    esac
1009
1010    if [ "X$VERIFY" = "XYES" ];
1011    then
1012        M_SERVER_ARGS="$M_SERVER_ARGS ca_file=data_files/test-ca_cat12.crt auth_mode=required"
1013        O_SERVER_ARGS="$O_SERVER_ARGS -CAfile data_files/test-ca_cat12.crt -Verify 10"
1014        G_SERVER_ARGS="$G_SERVER_ARGS --x509cafile data_files/test-ca_cat12.crt --require-client-cert"
1015
1016        M_CLIENT_ARGS="$M_CLIENT_ARGS ca_file=data_files/test-ca_cat12.crt auth_mode=required"
1017        O_CLIENT_ARGS="$O_CLIENT_ARGS -CAfile data_files/test-ca_cat12.crt -verify 10"
1018        G_CLIENT_ARGS="$G_CLIENT_ARGS --x509cafile data_files/test-ca_cat12.crt"
1019    else
1020        # don't request a client cert at all
1021        M_SERVER_ARGS="$M_SERVER_ARGS ca_file=none auth_mode=none"
1022        G_SERVER_ARGS="$G_SERVER_ARGS --disable-client-cert"
1023
1024        M_CLIENT_ARGS="$M_CLIENT_ARGS ca_file=none auth_mode=none"
1025        O_CLIENT_ARGS="$O_CLIENT_ARGS"
1026        G_CLIENT_ARGS="$G_CLIENT_ARGS --insecure"
1027    fi
1028
1029    case $TYPE in
1030        "ECDSA")
1031            M_SERVER_ARGS="$M_SERVER_ARGS crt_file=data_files/server5.crt key_file=data_files/server5.key"
1032            O_SERVER_ARGS="$O_SERVER_ARGS -cert data_files/server5.crt -key data_files/server5.key"
1033            G_SERVER_ARGS="$G_SERVER_ARGS --x509certfile data_files/server5.crt --x509keyfile data_files/server5.key"
1034
1035            if [ "X$VERIFY" = "XYES" ]; then
1036                M_CLIENT_ARGS="$M_CLIENT_ARGS crt_file=data_files/server6.crt key_file=data_files/server6.key"
1037                O_CLIENT_ARGS="$O_CLIENT_ARGS -cert data_files/server6.crt -key data_files/server6.key"
1038                G_CLIENT_ARGS="$G_CLIENT_ARGS --x509certfile data_files/server6.crt --x509keyfile data_files/server6.key"
1039            else
1040                M_CLIENT_ARGS="$M_CLIENT_ARGS crt_file=none key_file=none"
1041            fi
1042            ;;
1043
1044        "RSA")
1045            M_SERVER_ARGS="$M_SERVER_ARGS crt_file=data_files/server2-sha256.crt key_file=data_files/server2.key"
1046            O_SERVER_ARGS="$O_SERVER_ARGS -cert data_files/server2-sha256.crt -key data_files/server2.key"
1047            G_SERVER_ARGS="$G_SERVER_ARGS --x509certfile data_files/server2-sha256.crt --x509keyfile data_files/server2.key"
1048
1049            if [ "X$VERIFY" = "XYES" ]; then
1050                M_CLIENT_ARGS="$M_CLIENT_ARGS crt_file=data_files/cert_sha256.crt key_file=data_files/server1.key"
1051                O_CLIENT_ARGS="$O_CLIENT_ARGS -cert data_files/cert_sha256.crt -key data_files/server1.key"
1052                G_CLIENT_ARGS="$G_CLIENT_ARGS --x509certfile data_files/cert_sha256.crt --x509keyfile data_files/server1.key"
1053            else
1054                M_CLIENT_ARGS="$M_CLIENT_ARGS crt_file=none key_file=none"
1055            fi
1056            ;;
1057
1058        "PSK")
1059            # give RSA-PSK-capable server a RSA cert
1060            # (should be a separate type, but harder to close with openssl)
1061            M_SERVER_ARGS="$M_SERVER_ARGS psk=6162636465666768696a6b6c6d6e6f70 ca_file=none crt_file=data_files/server2-sha256.crt key_file=data_files/server2.key"
1062            O_SERVER_ARGS="$O_SERVER_ARGS -psk 6162636465666768696a6b6c6d6e6f70 -nocert"
1063            G_SERVER_ARGS="$G_SERVER_ARGS --x509certfile data_files/server2-sha256.crt --x509keyfile data_files/server2.key --pskpasswd data_files/passwd.psk"
1064
1065            M_CLIENT_ARGS="$M_CLIENT_ARGS psk=6162636465666768696a6b6c6d6e6f70 crt_file=none key_file=none"
1066            O_CLIENT_ARGS="$O_CLIENT_ARGS -psk 6162636465666768696a6b6c6d6e6f70"
1067            G_CLIENT_ARGS="$G_CLIENT_ARGS --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70"
1068            ;;
1069    esac
1070}
1071
1072# is_mbedtls <cmd_line>
1073is_mbedtls() {
1074    echo "$1" | grep 'ssl_server2\|ssl_client2' > /dev/null
1075}
1076
1077# has_mem_err <log_file_name>
1078has_mem_err() {
1079    if ( grep -F 'All heap blocks were freed -- no leaks are possible' "$1" &&
1080         grep -F 'ERROR SUMMARY: 0 errors from 0 contexts' "$1" ) > /dev/null
1081    then
1082        return 1 # false: does not have errors
1083    else
1084        return 0 # true: has errors
1085    fi
1086}
1087
1088# Wait for process $2 to be listening on port $1
1089if type lsof >/dev/null 2>/dev/null; then
1090    wait_server_start() {
1091        START_TIME=$(date +%s)
1092        if is_dtls "$MODE"; then
1093            proto=UDP
1094        else
1095            proto=TCP
1096        fi
1097        while ! lsof -a -n -b -i "$proto:$1" -p "$2" >/dev/null 2>/dev/null; do
1098              if [ $(( $(date +%s) - $START_TIME )) -gt $DOG_DELAY ]; then
1099                  echo "SERVERSTART TIMEOUT"
1100                  echo "SERVERSTART TIMEOUT" >> $SRV_OUT
1101                  break
1102              fi
1103              # Linux and *BSD support decimal arguments to sleep. On other
1104              # OSes this may be a tight loop.
1105              sleep 0.1 2>/dev/null || true
1106        done
1107    }
1108else
1109    echo "Warning: lsof not available, wait_server_start = sleep"
1110    wait_server_start() {
1111        sleep 2
1112    }
1113fi
1114
1115
1116# start_server <name>
1117# also saves name and command
1118start_server() {
1119    case $1 in
1120        [Oo]pen*)
1121            SERVER_CMD="$OPENSSL s_server $O_SERVER_ARGS"
1122            ;;
1123        [Gg]nu*)
1124            SERVER_CMD="$GNUTLS_SERV $G_SERVER_ARGS --priority $G_SERVER_PRIO"
1125            ;;
1126        mbed*)
1127            SERVER_CMD="$M_SRV $M_SERVER_ARGS"
1128            if [ "$MEMCHECK" -gt 0 ]; then
1129                SERVER_CMD="valgrind --leak-check=full $SERVER_CMD"
1130            fi
1131            ;;
1132        *)
1133            echo "error: invalid server name: $1" >&2
1134            exit 1
1135            ;;
1136    esac
1137    SERVER_NAME=$1
1138
1139    log "$SERVER_CMD"
1140    echo "$SERVER_CMD" > $SRV_OUT
1141    # for servers without -www or equivalent
1142    while :; do echo bla; sleep 1; done | $SERVER_CMD >> $SRV_OUT 2>&1 &
1143    SRV_PID=$!
1144
1145    wait_server_start "$PORT" "$SRV_PID"
1146}
1147
1148# terminate the running server
1149stop_server() {
1150    # For Ubuntu 22.04, `Terminated` message is outputed by wait command.
1151    # To remove it from stdout, redirect stdout/stderr to SRV_OUT
1152    kill $SRV_PID >/dev/null 2>&1
1153    wait $SRV_PID >> $SRV_OUT 2>&1
1154
1155    if [ "$MEMCHECK" -gt 0 ]; then
1156        if is_mbedtls "$SERVER_CMD" && has_mem_err $SRV_OUT; then
1157            echo "  ! Server had memory errors"
1158            SRVMEM=$(( $SRVMEM + 1 ))
1159            return
1160        fi
1161    fi
1162
1163    rm -f $SRV_OUT
1164}
1165
1166# kill the running server (used when killed by signal)
1167cleanup() {
1168    rm -f $SRV_OUT $CLI_OUT
1169    kill $SRV_PID >/dev/null 2>&1
1170    kill $WATCHDOG_PID >/dev/null 2>&1
1171    exit 1
1172}
1173
1174# wait for client to terminate and set EXIT
1175# must be called right after starting the client
1176wait_client_done() {
1177    CLI_PID=$!
1178
1179    ( sleep "$DOG_DELAY"; echo "TIMEOUT" >> $CLI_OUT; kill $CLI_PID ) &
1180    WATCHDOG_PID=$!
1181
1182    # For Ubuntu 22.04, `Terminated` message is outputed by wait command.
1183    # To remove it from stdout, redirect stdout/stderr to CLI_OUT
1184    wait $CLI_PID >> $CLI_OUT 2>&1
1185    EXIT=$?
1186
1187    kill $WATCHDOG_PID >/dev/null 2>&1
1188    wait $WATCHDOG_PID >> $CLI_OUT 2>&1
1189
1190    echo "EXIT: $EXIT" >> $CLI_OUT
1191}
1192
1193# record_outcome <outcome> [<failure-reason>]
1194record_outcome() {
1195    echo "$1"
1196    if [ -n "$MBEDTLS_TEST_OUTCOME_FILE" ]; then
1197        # The test outcome file has the format (in single line):
1198        # platform;configuration;
1199        # test suite name;test case description;
1200        # PASS/FAIL/SKIP;[failure cause]
1201        printf '%s;%s;%s;%s;%s;%s\n'                                    \
1202            "$MBEDTLS_TEST_PLATFORM" "$MBEDTLS_TEST_CONFIGURATION"      \
1203            "compat" "$TITLE"                                           \
1204            "$1" "${2-}"                                                \
1205            >> "$MBEDTLS_TEST_OUTCOME_FILE"
1206    fi
1207}
1208
1209# display additional information if test case fails
1210report_fail() {
1211    FAIL_PROMPT="outputs saved to c-srv-${TESTS}.log, c-cli-${TESTS}.log"
1212    record_outcome "FAIL" "$FAIL_PROMPT"
1213    cp $SRV_OUT c-srv-${TESTS}.log
1214    cp $CLI_OUT c-cli-${TESTS}.log
1215    echo "  ! $FAIL_PROMPT"
1216
1217    if [ "${LOG_FAILURE_ON_STDOUT:-0}" != 0 ]; then
1218        echo "  ! server output:"
1219        cat c-srv-${TESTS}.log
1220        echo "  ! ==================================================="
1221        echo "  ! client output:"
1222        cat c-cli-${TESTS}.log
1223    fi
1224}
1225
1226# uniform_title <CLIENT> <SERVER> <STANDARD_CIPHER_SUITE>
1227# $TITLE is considered as test case description for both --list-test-case and
1228# MBEDTLS_TEST_OUTCOME_FILE. This function aims to control the format of
1229# each test case description.
1230uniform_title() {
1231    TITLE="$1->$2 $MODE,$VERIF $3"
1232}
1233
1234# run_client <name> <cipher>
1235run_client() {
1236    # announce what we're going to do
1237    TESTS=$(( $TESTS + 1 ))
1238    uniform_title "${1%"${1#?}"}" "${SERVER_NAME%"${SERVER_NAME#?}"}" $2
1239    DOTS72="........................................................................"
1240    printf "%s %.*s " "$TITLE" "$((71 - ${#TITLE}))" "$DOTS72"
1241
1242    # should we skip?
1243    if [ "X$SKIP_NEXT" = "XYES" ]; then
1244        SKIP_NEXT="NO"
1245        record_outcome "SKIP"
1246        SKIPPED=$(( $SKIPPED + 1 ))
1247        return
1248    fi
1249
1250    # run the command and interpret result
1251    case $1 in
1252        [Oo]pen*)
1253            CLIENT_CMD="$OPENSSL s_client $O_CLIENT_ARGS -cipher $2"
1254            log "$CLIENT_CMD"
1255            echo "$CLIENT_CMD" > $CLI_OUT
1256            printf 'GET HTTP/1.0\r\n\r\n' | $CLIENT_CMD >> $CLI_OUT 2>&1 &
1257            wait_client_done
1258
1259            if [ $EXIT -eq 0 ]; then
1260                RESULT=0
1261            else
1262                # If it is NULL cipher ...
1263                if grep 'Cipher is (NONE)' $CLI_OUT >/dev/null; then
1264                    RESULT=1
1265                else
1266                    RESULT=2
1267                fi
1268            fi
1269            ;;
1270
1271        [Gg]nu*)
1272            # need to force IPv4 with UDP, but keep localhost for auth
1273            if is_dtls "$MODE"; then
1274                G_HOST="127.0.0.1"
1275            else
1276                G_HOST="localhost"
1277            fi
1278            CLIENT_CMD="$GNUTLS_CLI $G_CLIENT_ARGS --priority $G_PRIO_MODE:$2 $G_HOST"
1279            log "$CLIENT_CMD"
1280            echo "$CLIENT_CMD" > $CLI_OUT
1281            printf 'GET HTTP/1.0\r\n\r\n' | $CLIENT_CMD >> $CLI_OUT 2>&1 &
1282            wait_client_done
1283
1284            if [ $EXIT -eq 0 ]; then
1285                RESULT=0
1286            else
1287                RESULT=2
1288                # interpret early failure, with a handshake_failure alert
1289                # before the server hello, as "no ciphersuite in common"
1290                if grep -F 'Received alert [40]: Handshake failed' $CLI_OUT; then
1291                    if grep -i 'SERVER HELLO .* was received' $CLI_OUT; then :
1292                    else
1293                        RESULT=1
1294                    fi
1295                fi >/dev/null
1296            fi
1297            ;;
1298
1299        mbed*)
1300            CLIENT_CMD="$M_CLI $M_CLIENT_ARGS force_ciphersuite=$2"
1301            if [ "$MEMCHECK" -gt 0 ]; then
1302                CLIENT_CMD="valgrind --leak-check=full $CLIENT_CMD"
1303            fi
1304            log "$CLIENT_CMD"
1305            echo "$CLIENT_CMD" > $CLI_OUT
1306            $CLIENT_CMD >> $CLI_OUT 2>&1 &
1307            wait_client_done
1308
1309            case $EXIT in
1310                # Success
1311                "0")    RESULT=0    ;;
1312
1313                # Ciphersuite not supported
1314                "2")    RESULT=1    ;;
1315
1316                # Error
1317                *)      RESULT=2    ;;
1318            esac
1319
1320            if [ "$MEMCHECK" -gt 0 ]; then
1321                if is_mbedtls "$CLIENT_CMD" && has_mem_err $CLI_OUT; then
1322                    RESULT=2
1323                fi
1324            fi
1325
1326            ;;
1327
1328        *)
1329            echo "error: invalid client name: $1" >&2
1330            exit 1
1331            ;;
1332    esac
1333
1334    echo "EXIT: $EXIT" >> $CLI_OUT
1335
1336    # report and count result
1337    case $RESULT in
1338        "0")
1339            record_outcome "PASS"
1340            ;;
1341        "1")
1342            record_outcome "SKIP"
1343            SKIPPED=$(( $SKIPPED + 1 ))
1344            ;;
1345        "2")
1346            report_fail
1347            FAILED=$(( $FAILED + 1 ))
1348            ;;
1349    esac
1350
1351    rm -f $CLI_OUT
1352}
1353
1354#
1355# MAIN
1356#
1357
1358get_options "$@"
1359
1360# Make the outcome file path relative to the original directory, not
1361# to .../tests
1362case "$MBEDTLS_TEST_OUTCOME_FILE" in
1363    [!/]*)
1364        MBEDTLS_TEST_OUTCOME_FILE="$ORIGINAL_PWD/$MBEDTLS_TEST_OUTCOME_FILE"
1365        ;;
1366esac
1367
1368# sanity checks, avoid an avalanche of errors
1369if [ ! -x "$M_SRV" ]; then
1370    echo "Command '$M_SRV' is not an executable file" >&2
1371    exit 1
1372fi
1373if [ ! -x "$M_CLI" ]; then
1374    echo "Command '$M_CLI' is not an executable file" >&2
1375    exit 1
1376fi
1377
1378if echo "$PEERS" | grep -i openssl > /dev/null; then
1379    if which "$OPENSSL" >/dev/null 2>&1; then :; else
1380        echo "Command '$OPENSSL' not found" >&2
1381        exit 1
1382    fi
1383fi
1384
1385if echo "$PEERS" | grep -i gnutls > /dev/null; then
1386    for CMD in "$GNUTLS_CLI" "$GNUTLS_SERV"; do
1387        if which "$CMD" >/dev/null 2>&1; then :; else
1388            echo "Command '$CMD' not found" >&2
1389            exit 1
1390        fi
1391    done
1392fi
1393
1394for PEER in $PEERS; do
1395    case "$PEER" in
1396        mbed*|[Oo]pen*|[Gg]nu*)
1397            ;;
1398        *)
1399            echo "Unknown peers: $PEER" >&2
1400            exit 1
1401    esac
1402done
1403
1404# Pick a "unique" port in the range 10000-19999.
1405PORT="0000$$"
1406PORT="1$(echo $PORT | tail -c 5)"
1407
1408# Also pick a unique name for intermediate files
1409SRV_OUT="srv_out.$$"
1410CLI_OUT="cli_out.$$"
1411
1412# client timeout delay: be more patient with valgrind
1413if [ "$MEMCHECK" -gt 0 ]; then
1414    DOG_DELAY=30
1415else
1416    DOG_DELAY=10
1417fi
1418
1419SKIP_NEXT="NO"
1420
1421trap cleanup INT TERM HUP
1422
1423for MODE in $MODES; do
1424    for TYPE in $TYPES; do
1425
1426        # PSK cipher suites do not allow client certificate verification.
1427        # This means PSK test cases with VERIFY=YES should be replaced by
1428        # VERIFY=NO or be ignored. SUB_VERIFIES variable is used to constrain
1429        # verification option for PSK test cases.
1430        SUB_VERIFIES=$VERIFIES
1431        if [ "$TYPE" = "PSK" ]; then
1432            SUB_VERIFIES="NO"
1433        fi
1434
1435        for VERIFY in $SUB_VERIFIES; do
1436            VERIF=$(echo $VERIFY | tr '[:upper:]' '[:lower:]')
1437            for PEER in $PEERS; do
1438
1439            setup_arguments
1440
1441            case "$PEER" in
1442
1443                [Oo]pen*)
1444
1445                    if test "$OSSL_NO_DTLS" -gt 0 && is_dtls "$MODE"; then
1446                        continue;
1447                    fi
1448
1449                    # OpenSSL <1.0.2 doesn't support DTLS 1.2. Check if OpenSSL
1450                    # supports $O_MODE from the s_server help. (The s_client
1451                    # help isn't accurate as of 1.0.2g: it supports DTLS 1.2
1452                    # but doesn't list it. But the s_server help seems to be
1453                    # accurate.)
1454                    if ! $OPENSSL s_server -help 2>&1 | grep -q "^ *-$O_MODE "; then
1455                        continue;
1456                    fi
1457
1458                    reset_ciphersuites
1459                    add_common_ciphersuites
1460                    add_openssl_ciphersuites
1461                    filter_ciphersuites
1462
1463                    if [ "X" != "X$M_CIPHERS" ]; then
1464                        start_server "OpenSSL"
1465                        for i in $M_CIPHERS; do
1466                            o_check_ciphersuite "$i"
1467                            run_client mbedTLS $i
1468                        done
1469                        stop_server
1470                    fi
1471
1472                    if [ "X" != "X$O_CIPHERS" ]; then
1473                        start_server "mbedTLS"
1474                        for i in $O_CIPHERS; do
1475                            o_check_ciphersuite "$i"
1476                            run_client OpenSSL $i
1477                        done
1478                        stop_server
1479                    fi
1480
1481                    ;;
1482
1483                [Gg]nu*)
1484
1485                    reset_ciphersuites
1486                    add_common_ciphersuites
1487                    add_gnutls_ciphersuites
1488                    filter_ciphersuites
1489
1490                    if [ "X" != "X$M_CIPHERS" ]; then
1491                        start_server "GnuTLS"
1492                        for i in $M_CIPHERS; do
1493                            run_client mbedTLS $i
1494                        done
1495                        stop_server
1496                    fi
1497
1498                    if [ "X" != "X$G_CIPHERS" ]; then
1499                        start_server "mbedTLS"
1500                        for i in $G_CIPHERS; do
1501                            run_client GnuTLS $i
1502                        done
1503                        stop_server
1504                    fi
1505
1506                    ;;
1507
1508                mbed*)
1509
1510                    reset_ciphersuites
1511                    add_common_ciphersuites
1512                    add_openssl_ciphersuites
1513                    add_gnutls_ciphersuites
1514                    add_mbedtls_ciphersuites
1515                    filter_ciphersuites
1516
1517                    if [ "X" != "X$M_CIPHERS" ]; then
1518                        start_server "mbedTLS"
1519                        for i in $M_CIPHERS; do
1520                            run_client mbedTLS $i
1521                        done
1522                        stop_server
1523                    fi
1524
1525                    ;;
1526
1527                *)
1528                    echo "Unknown peer: $PEER" >&2
1529                    exit 1
1530                    ;;
1531
1532                esac
1533
1534            done
1535        done
1536    done
1537done
1538
1539echo "------------------------------------------------------------------------"
1540
1541if [ $FAILED -ne 0 -o $SRVMEM -ne 0 ]; then
1542    printf "FAILED"
1543else
1544    printf "PASSED"
1545fi
1546
1547if [ "$MEMCHECK" -gt 0 ]; then
1548    MEMREPORT=", $SRVMEM server memory errors"
1549else
1550    MEMREPORT=""
1551fi
1552
1553PASSED=$(( $TESTS - $FAILED ))
1554echo " ($PASSED / $TESTS tests ($SKIPPED skipped$MEMREPORT))"
1555
1556FAILED=$(( $FAILED + $SRVMEM ))
1557if [ $FAILED -gt 255 ]; then
1558    # Clamp at 255 as caller gets exit code & 0xFF
1559    # (so 256 would be 0, or success, etc)
1560    FAILED=255
1561fi
1562exit $FAILED
1563