1#!/bin/sh 2 3# compat.sh 4# 5# Copyright The Mbed TLS Contributors 6# SPDX-License-Identifier: Apache-2.0 7# 8# Licensed under the Apache License, Version 2.0 (the "License"); you may 9# not use this file except in compliance with the License. 10# You may obtain a copy of the License at 11# 12# http://www.apache.org/licenses/LICENSE-2.0 13# 14# Unless required by applicable law or agreed to in writing, software 15# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 16# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17# See the License for the specific language governing permissions and 18# limitations under the License. 19# 20# Purpose 21# 22# Test interoperbility with OpenSSL, GnuTLS as well as itself. 23# 24# Check each common ciphersuite, with each version, both ways (client/server), 25# with and without client authentication. 26 27set -u 28 29# Limit the size of each log to 10 GiB, in case of failures with this script 30# where it may output seemingly unlimited length error logs. 31ulimit -f 20971520 32 33# initialise counters 34TESTS=0 35FAILED=0 36SKIPPED=0 37SRVMEM=0 38 39# default commands, can be overridden by the environment 40: ${M_SRV:=../programs/ssl/ssl_server2} 41: ${M_CLI:=../programs/ssl/ssl_client2} 42: ${OPENSSL_CMD:=openssl} # OPENSSL would conflict with the build system 43: ${GNUTLS_CLI:=gnutls-cli} 44: ${GNUTLS_SERV:=gnutls-serv} 45 46# do we have a recent enough GnuTLS? 47if ( which $GNUTLS_CLI && which $GNUTLS_SERV ) >/dev/null 2>&1; then 48 G_VER="$( $GNUTLS_CLI --version | head -n1 )" 49 if echo "$G_VER" | grep '@VERSION@' > /dev/null; then # git version 50 PEER_GNUTLS=" GnuTLS" 51 else 52 eval $( echo $G_VER | sed 's/.* \([0-9]*\)\.\([0-9]\)*\.\([0-9]*\)$/MAJOR="\1" MINOR="\2" PATCH="\3"/' ) 53 if [ $MAJOR -lt 3 -o \ 54 \( $MAJOR -eq 3 -a $MINOR -lt 2 \) -o \ 55 \( $MAJOR -eq 3 -a $MINOR -eq 2 -a $PATCH -lt 15 \) ] 56 then 57 PEER_GNUTLS="" 58 else 59 PEER_GNUTLS=" GnuTLS" 60 if [ $MINOR -lt 4 ]; then 61 GNUTLS_MINOR_LT_FOUR='x' 62 fi 63 fi 64 fi 65else 66 PEER_GNUTLS="" 67fi 68 69# default values for options 70# /!\ keep this synchronised with: 71# - basic-build-test.sh 72# - all.sh (multiple components) 73MODES="tls12 dtls12" 74VERIFIES="NO YES" 75TYPES="ECDSA RSA PSK" 76FILTER="" 77# By default, exclude: 78# - NULL: excluded from our default config + requires OpenSSL legacy 79# - ARIA: requires OpenSSL >= 1.1.1 80# - ChachaPoly: requires OpenSSL >= 1.1.0 81EXCLUDE='NULL\|ARIA\|CHACHA20-POLY1305' 82VERBOSE="" 83MEMCHECK=0 84PEERS="OpenSSL$PEER_GNUTLS mbedTLS" 85 86# hidden option: skip DTLS with OpenSSL 87# (travis CI has a version that doesn't work for us) 88: ${OSSL_NO_DTLS:=0} 89 90print_usage() { 91 echo "Usage: $0" 92 printf " -h|--help\tPrint this help.\n" 93 printf " -f|--filter\tOnly matching ciphersuites are tested (Default: '%s')\n" "$FILTER" 94 printf " -e|--exclude\tMatching ciphersuites are excluded (Default: '%s')\n" "$EXCLUDE" 95 printf " -m|--modes\tWhich modes to perform (Default: '%s')\n" "$MODES" 96 printf " -t|--types\tWhich key exchange type to perform (Default: '%s')\n" "$TYPES" 97 printf " -V|--verify\tWhich verification modes to perform (Default: '%s')\n" "$VERIFIES" 98 printf " -p|--peers\tWhich peers to use (Default: '%s')\n" "$PEERS" 99 printf " \tAlso available: GnuTLS (needs v3.2.15 or higher)\n" 100 printf " -M|--memcheck\tCheck memory leaks and errors.\n" 101 printf " -v|--verbose\tSet verbose output.\n" 102} 103 104get_options() { 105 while [ $# -gt 0 ]; do 106 case "$1" in 107 -f|--filter) 108 shift; FILTER=$1 109 ;; 110 -e|--exclude) 111 shift; EXCLUDE=$1 112 ;; 113 -m|--modes) 114 shift; MODES=$1 115 ;; 116 -t|--types) 117 shift; TYPES=$1 118 ;; 119 -V|--verify) 120 shift; VERIFIES=$1 121 ;; 122 -p|--peers) 123 shift; PEERS=$1 124 ;; 125 -v|--verbose) 126 VERBOSE=1 127 ;; 128 -M|--memcheck) 129 MEMCHECK=1 130 ;; 131 -h|--help) 132 print_usage 133 exit 0 134 ;; 135 *) 136 echo "Unknown argument: '$1'" 137 print_usage 138 exit 1 139 ;; 140 esac 141 shift 142 done 143 144 # sanitize some options (modes checked later) 145 VERIFIES="$( echo $VERIFIES | tr [a-z] [A-Z] )" 146 TYPES="$( echo $TYPES | tr [a-z] [A-Z] )" 147} 148 149log() { 150 if [ "X" != "X$VERBOSE" ]; then 151 echo "" 152 echo "$@" 153 fi 154} 155 156# is_dtls <mode> 157is_dtls() 158{ 159 test "$1" = "dtls12" 160} 161 162# minor_ver <mode> 163minor_ver() 164{ 165 case "$1" in 166 tls12|dtls12) 167 echo 3 168 ;; 169 *) 170 echo "error: invalid mode: $MODE" >&2 171 # exiting is no good here, typically called in a subshell 172 echo -1 173 esac 174} 175 176filter() 177{ 178 LIST="$1" 179 NEW_LIST="" 180 181 EXCLMODE="$EXCLUDE" 182 183 for i in $LIST; 184 do 185 NEW_LIST="$NEW_LIST $( echo "$i" | grep "$FILTER" | grep -v "$EXCLMODE" )" 186 done 187 188 # normalize whitespace 189 echo "$NEW_LIST" | sed -e 's/[[:space:]][[:space:]]*/ /g' -e 's/^ //' -e 's/ $//' 190} 191 192# OpenSSL 1.0.1h with -Verify wants a ClientCertificate message even for 193# PSK ciphersuites with DTLS, which is incorrect, so disable them for now 194check_openssl_server_bug() 195{ 196 if test "X$VERIFY" = "XYES" && is_dtls "$MODE" && \ 197 echo "$1" | grep "^TLS-PSK" >/dev/null; 198 then 199 SKIP_NEXT="YES" 200 fi 201} 202 203filter_ciphersuites() 204{ 205 if [ "X" != "X$FILTER" -o "X" != "X$EXCLUDE" ]; 206 then 207 # Ciphersuite for mbed TLS 208 M_CIPHERS=$( filter "$M_CIPHERS" ) 209 210 # Ciphersuite for OpenSSL 211 O_CIPHERS=$( filter "$O_CIPHERS" ) 212 213 # Ciphersuite for GnuTLS 214 G_CIPHERS=$( filter "$G_CIPHERS" ) 215 fi 216 217 # For GnuTLS client -> mbed TLS server, 218 # we need to force IPv4 by connecting to 127.0.0.1 but then auth fails 219 if [ "X$VERIFY" = "XYES" ] && is_dtls "$MODE"; then 220 G_CIPHERS="" 221 fi 222} 223 224reset_ciphersuites() 225{ 226 M_CIPHERS="" 227 O_CIPHERS="" 228 G_CIPHERS="" 229} 230 231check_translation() 232{ 233 if [ $1 -ne 0 ]; then 234 echo "translate_ciphers.py failed with exit code $1" >&2 235 echo "$2" >&2 236 exit 1 237 fi 238} 239 240# Ciphersuites that can be used with all peers. 241# Since we currently have three possible peers, each ciphersuite should appear 242# three times: in each peer's list (with the name that this peer uses). 243add_common_ciphersuites() 244{ 245 CIPHERS="" 246 case $TYPE in 247 248 "ECDSA") 249 CIPHERS="$CIPHERS \ 250 TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA \ 251 TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256 \ 252 TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \ 253 TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA \ 254 TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384 \ 255 TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384 \ 256 TLS-ECDHE-ECDSA-WITH-NULL-SHA \ 257 " 258 ;; 259 260 "RSA") 261 CIPHERS="$CIPHERS \ 262 TLS-DHE-RSA-WITH-AES-128-CBC-SHA \ 263 TLS-DHE-RSA-WITH-AES-128-CBC-SHA256 \ 264 TLS-DHE-RSA-WITH-AES-128-GCM-SHA256 \ 265 TLS-DHE-RSA-WITH-AES-256-CBC-SHA \ 266 TLS-DHE-RSA-WITH-AES-256-CBC-SHA256 \ 267 TLS-DHE-RSA-WITH-AES-256-GCM-SHA384 \ 268 TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA \ 269 TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA \ 270 TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA \ 271 TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256 \ 272 TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256 \ 273 TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA \ 274 TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384 \ 275 TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384 \ 276 TLS-ECDHE-RSA-WITH-NULL-SHA \ 277 TLS-RSA-WITH-AES-128-CBC-SHA \ 278 TLS-RSA-WITH-AES-128-CBC-SHA256 \ 279 TLS-RSA-WITH-AES-128-GCM-SHA256 \ 280 TLS-RSA-WITH-AES-256-CBC-SHA \ 281 TLS-RSA-WITH-AES-256-CBC-SHA256 \ 282 TLS-RSA-WITH-AES-256-GCM-SHA384 \ 283 TLS-RSA-WITH-CAMELLIA-128-CBC-SHA \ 284 TLS-RSA-WITH-CAMELLIA-256-CBC-SHA \ 285 TLS-RSA-WITH-NULL-MD5 \ 286 TLS-RSA-WITH-NULL-SHA \ 287 TLS-RSA-WITH-NULL-SHA256 \ 288 " 289 ;; 290 291 "PSK") 292 CIPHERS="$CIPHERS \ 293 TLS-PSK-WITH-AES-128-CBC-SHA \ 294 TLS-PSK-WITH-AES-256-CBC-SHA \ 295 " 296 ;; 297 esac 298 299 M_CIPHERS="$M_CIPHERS $CIPHERS" 300 301 T=$(./scripts/translate_ciphers.py g $CIPHERS) 302 check_translation $? "$T" 303 G_CIPHERS="$G_CIPHERS $T" 304 305 T=$(./scripts/translate_ciphers.py o $CIPHERS) 306 check_translation $? "$T" 307 O_CIPHERS="$O_CIPHERS $T" 308} 309 310# Ciphersuites usable only with Mbed TLS and OpenSSL 311# A list of ciphersuites in the Mbed TLS convention is compiled and 312# appended to the list of Mbed TLS ciphersuites $M_CIPHERS. The same list 313# is translated to the OpenSSL naming convention and appended to the list of 314# OpenSSL ciphersuites $O_CIPHERS. 315# 316# NOTE: for some reason RSA-PSK doesn't work with OpenSSL, 317# so RSA-PSK ciphersuites need to go in other sections, see 318# https://github.com/Mbed-TLS/mbedtls/issues/1419 319# 320# ChachaPoly suites are here rather than in "common", as they were added in 321# GnuTLS in 3.5.0 and the CI only has 3.4.x so far. 322add_openssl_ciphersuites() 323{ 324 CIPHERS="" 325 case $TYPE in 326 327 "ECDSA") 328 CIPHERS="$CIPHERS \ 329 TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA \ 330 TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256 \ 331 TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256 \ 332 TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA \ 333 TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384 \ 334 TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384 \ 335 TLS-ECDH-ECDSA-WITH-NULL-SHA \ 336 TLS-ECDHE-ECDSA-WITH-ARIA-128-GCM-SHA256 \ 337 TLS-ECDHE-ECDSA-WITH-ARIA-256-GCM-SHA384 \ 338 TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256 \ 339 " 340 ;; 341 342 "RSA") 343 CIPHERS="$CIPHERS \ 344 TLS-DHE-RSA-WITH-ARIA-128-GCM-SHA256 \ 345 TLS-DHE-RSA-WITH-ARIA-256-GCM-SHA384 \ 346 TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256 \ 347 TLS-ECDHE-RSA-WITH-ARIA-128-GCM-SHA256 \ 348 TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384 \ 349 TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256 \ 350 TLS-RSA-WITH-ARIA-128-GCM-SHA256 \ 351 TLS-RSA-WITH-ARIA-256-GCM-SHA384 \ 352 " 353 ;; 354 355 "PSK") 356 CIPHERS="$CIPHERS \ 357 TLS-DHE-PSK-WITH-ARIA-128-GCM-SHA256 \ 358 TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384 \ 359 TLS-DHE-PSK-WITH-CHACHA20-POLY1305-SHA256 \ 360 TLS-ECDHE-PSK-WITH-CHACHA20-POLY1305-SHA256 \ 361 TLS-PSK-WITH-ARIA-128-GCM-SHA256 \ 362 TLS-PSK-WITH-ARIA-256-GCM-SHA384 \ 363 TLS-PSK-WITH-CHACHA20-POLY1305-SHA256 \ 364 " 365 ;; 366 esac 367 368 M_CIPHERS="$M_CIPHERS $CIPHERS" 369 370 T=$(./scripts/translate_ciphers.py o $CIPHERS) 371 check_translation $? "$T" 372 O_CIPHERS="$O_CIPHERS $T" 373} 374 375# Ciphersuites usable only with Mbed TLS and GnuTLS 376# A list of ciphersuites in the Mbed TLS convention is compiled and 377# appended to the list of Mbed TLS ciphersuites $M_CIPHERS. The same list 378# is translated to the GnuTLS naming convention and appended to the list of 379# GnuTLS ciphersuites $G_CIPHERS. 380add_gnutls_ciphersuites() 381{ 382 CIPHERS="" 383 case $TYPE in 384 385 "ECDSA") 386 CIPHERS="$CIPHERS \ 387 TLS-ECDHE-ECDSA-WITH-AES-128-CCM \ 388 TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8 \ 389 TLS-ECDHE-ECDSA-WITH-AES-256-CCM \ 390 TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8 \ 391 TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256 \ 392 TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256 \ 393 TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384 \ 394 TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384 \ 395 " 396 ;; 397 398 "RSA") 399 CIPHERS="$CIPHERS \ 400 TLS-DHE-RSA-WITH-AES-128-CCM \ 401 TLS-DHE-RSA-WITH-AES-128-CCM-8 \ 402 TLS-DHE-RSA-WITH-AES-256-CCM \ 403 TLS-DHE-RSA-WITH-AES-256-CCM-8 \ 404 TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256 \ 405 TLS-DHE-RSA-WITH-CAMELLIA-128-GCM-SHA256 \ 406 TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256 \ 407 TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384 \ 408 TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256 \ 409 TLS-ECDHE-RSA-WITH-CAMELLIA-128-GCM-SHA256 \ 410 TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384 \ 411 TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384 \ 412 TLS-RSA-WITH-AES-128-CCM \ 413 TLS-RSA-WITH-AES-128-CCM-8 \ 414 TLS-RSA-WITH-AES-256-CCM \ 415 TLS-RSA-WITH-AES-256-CCM-8 \ 416 TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256 \ 417 TLS-RSA-WITH-CAMELLIA-128-GCM-SHA256 \ 418 TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256 \ 419 TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384 \ 420 " 421 ;; 422 423 "PSK") 424 CIPHERS="$CIPHERS \ 425 TLS-DHE-PSK-WITH-AES-128-CBC-SHA \ 426 TLS-DHE-PSK-WITH-AES-128-CBC-SHA256 \ 427 TLS-DHE-PSK-WITH-AES-128-CCM \ 428 TLS-DHE-PSK-WITH-AES-128-CCM-8 \ 429 TLS-DHE-PSK-WITH-AES-128-GCM-SHA256 \ 430 TLS-DHE-PSK-WITH-AES-256-CBC-SHA \ 431 TLS-DHE-PSK-WITH-AES-256-CBC-SHA384 \ 432 TLS-DHE-PSK-WITH-AES-256-CCM \ 433 TLS-DHE-PSK-WITH-AES-256-CCM-8 \ 434 TLS-DHE-PSK-WITH-AES-256-GCM-SHA384 \ 435 TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256 \ 436 TLS-DHE-PSK-WITH-CAMELLIA-128-GCM-SHA256 \ 437 TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384 \ 438 TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384 \ 439 TLS-DHE-PSK-WITH-NULL-SHA256 \ 440 TLS-DHE-PSK-WITH-NULL-SHA384 \ 441 TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA \ 442 TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256 \ 443 TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA \ 444 TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384 \ 445 TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256 \ 446 TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384 \ 447 TLS-ECDHE-PSK-WITH-NULL-SHA256 \ 448 TLS-ECDHE-PSK-WITH-NULL-SHA384 \ 449 TLS-PSK-WITH-AES-128-CBC-SHA256 \ 450 TLS-PSK-WITH-AES-128-CCM \ 451 TLS-PSK-WITH-AES-128-CCM-8 \ 452 TLS-PSK-WITH-AES-128-GCM-SHA256 \ 453 TLS-PSK-WITH-AES-256-CBC-SHA384 \ 454 TLS-PSK-WITH-AES-256-CCM \ 455 TLS-PSK-WITH-AES-256-CCM-8 \ 456 TLS-PSK-WITH-AES-256-GCM-SHA384 \ 457 TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256 \ 458 TLS-PSK-WITH-CAMELLIA-128-GCM-SHA256 \ 459 TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384 \ 460 TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384 \ 461 TLS-PSK-WITH-NULL-SHA256 \ 462 TLS-PSK-WITH-NULL-SHA384 \ 463 TLS-RSA-PSK-WITH-AES-128-CBC-SHA \ 464 TLS-RSA-PSK-WITH-AES-128-CBC-SHA256 \ 465 TLS-RSA-PSK-WITH-AES-128-GCM-SHA256 \ 466 TLS-RSA-PSK-WITH-AES-256-CBC-SHA \ 467 TLS-RSA-PSK-WITH-AES-256-CBC-SHA384 \ 468 TLS-RSA-PSK-WITH-AES-256-GCM-SHA384 \ 469 TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256 \ 470 TLS-RSA-PSK-WITH-CAMELLIA-128-GCM-SHA256 \ 471 TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384 \ 472 TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384 \ 473 TLS-RSA-PSK-WITH-NULL-SHA256 \ 474 TLS-RSA-PSK-WITH-NULL-SHA384 \ 475 " 476 ;; 477 esac 478 479 M_CIPHERS="$M_CIPHERS $CIPHERS" 480 481 T=$(./scripts/translate_ciphers.py g $CIPHERS) 482 check_translation $? "$T" 483 G_CIPHERS="$G_CIPHERS $T" 484} 485 486# Ciphersuites usable only with Mbed TLS (not currently supported by another 487# peer usable in this script). This provide only very rudimentaty testing, as 488# this is not interop testing, but it's better than nothing. 489add_mbedtls_ciphersuites() 490{ 491 case $TYPE in 492 493 "ECDSA") 494 M_CIPHERS="$M_CIPHERS \ 495 TLS-ECDH-ECDSA-WITH-ARIA-128-CBC-SHA256 \ 496 TLS-ECDH-ECDSA-WITH-ARIA-128-GCM-SHA256 \ 497 TLS-ECDH-ECDSA-WITH-ARIA-256-CBC-SHA384 \ 498 TLS-ECDH-ECDSA-WITH-ARIA-256-GCM-SHA384 \ 499 TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256 \ 500 TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256 \ 501 TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384 \ 502 TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384 \ 503 TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256 \ 504 TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384 \ 505 " 506 ;; 507 508 "RSA") 509 M_CIPHERS="$M_CIPHERS \ 510 TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256 \ 511 TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384 \ 512 TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256 \ 513 TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384 \ 514 TLS-RSA-WITH-ARIA-128-CBC-SHA256 \ 515 TLS-RSA-WITH-ARIA-256-CBC-SHA384 \ 516 " 517 ;; 518 519 "PSK") 520 # *PSK-NULL-SHA suites supported by GnuTLS 3.3.5 but not 3.2.15 521 M_CIPHERS="$M_CIPHERS \ 522 TLS-DHE-PSK-WITH-ARIA-128-CBC-SHA256 \ 523 TLS-DHE-PSK-WITH-ARIA-256-CBC-SHA384 \ 524 TLS-DHE-PSK-WITH-NULL-SHA \ 525 TLS-ECDHE-PSK-WITH-ARIA-128-CBC-SHA256 \ 526 TLS-ECDHE-PSK-WITH-ARIA-256-CBC-SHA384 \ 527 TLS-ECDHE-PSK-WITH-NULL-SHA \ 528 TLS-PSK-WITH-ARIA-128-CBC-SHA256 \ 529 TLS-PSK-WITH-ARIA-256-CBC-SHA384 \ 530 TLS-PSK-WITH-NULL-SHA \ 531 TLS-RSA-PSK-WITH-ARIA-128-CBC-SHA256 \ 532 TLS-RSA-PSK-WITH-ARIA-128-GCM-SHA256 \ 533 TLS-RSA-PSK-WITH-ARIA-256-CBC-SHA384 \ 534 TLS-RSA-PSK-WITH-ARIA-256-GCM-SHA384 \ 535 TLS-RSA-PSK-WITH-CHACHA20-POLY1305-SHA256 \ 536 TLS-RSA-PSK-WITH-NULL-SHA \ 537 " 538 ;; 539 esac 540} 541 542setup_arguments() 543{ 544 O_MODE="" 545 G_MODE="" 546 case "$MODE" in 547 "tls12") 548 O_MODE="tls1_2" 549 G_PRIO_MODE="+VERS-TLS1.2" 550 ;; 551 "dtls12") 552 O_MODE="dtls1_2" 553 G_PRIO_MODE="+VERS-DTLS1.2" 554 G_MODE="-u" 555 ;; 556 *) 557 echo "error: invalid mode: $MODE" >&2 558 exit 1; 559 esac 560 561 # GnuTLS < 3.4 will choke if we try to allow CCM-8 562 if [ -z "${GNUTLS_MINOR_LT_FOUR-}" ]; then 563 G_PRIO_CCM="+AES-256-CCM-8:+AES-128-CCM-8:" 564 else 565 G_PRIO_CCM="" 566 fi 567 568 M_SERVER_ARGS="server_port=$PORT server_addr=0.0.0.0 force_version=$MODE" 569 O_SERVER_ARGS="-accept $PORT -cipher NULL,ALL -$O_MODE" 570 G_SERVER_ARGS="-p $PORT --http $G_MODE" 571 G_SERVER_PRIO="NORMAL:${G_PRIO_CCM}+NULL:+MD5:+PSK:+DHE-PSK:+ECDHE-PSK:+SHA256:+SHA384:+RSA-PSK:-VERS-TLS-ALL:$G_PRIO_MODE" 572 573 # The default prime for `openssl s_server` depends on the version: 574 # * OpenSSL <= 1.0.2a: 512-bit 575 # * OpenSSL 1.0.2b to 1.1.1b: 1024-bit 576 # * OpenSSL >= 1.1.1c: 2048-bit 577 # Mbed TLS wants >=1024, so force that for older versions. Don't force 578 # it for newer versions, which reject a 1024-bit prime. Indifferently 579 # force it or not for intermediate versions. 580 case $($OPENSSL_CMD version) in 581 "OpenSSL 1.0"*) 582 O_SERVER_ARGS="$O_SERVER_ARGS -dhparam data_files/dhparams.pem" 583 ;; 584 esac 585 586 # with OpenSSL 1.0.1h, -www, -WWW and -HTTP break DTLS handshakes 587 if is_dtls "$MODE"; then 588 O_SERVER_ARGS="$O_SERVER_ARGS" 589 else 590 O_SERVER_ARGS="$O_SERVER_ARGS -www" 591 fi 592 593 M_CLIENT_ARGS="server_port=$PORT server_addr=127.0.0.1 force_version=$MODE" 594 O_CLIENT_ARGS="-connect localhost:$PORT -$O_MODE" 595 G_CLIENT_ARGS="-p $PORT --debug 3 $G_MODE" 596 G_CLIENT_PRIO="NONE:$G_PRIO_MODE:+COMP-NULL:+CURVE-ALL:+SIGN-ALL" 597 598 # Newer versions of OpenSSL have a syntax to enable all "ciphers", even 599 # low-security ones. This covers not just cipher suites but also protocol 600 # versions. It is necessary, for example, to use (D)TLS 1.0/1.1 on 601 # OpenSSL 1.1.1f from Ubuntu 20.04. The syntax was only introduced in 602 # OpenSSL 1.1.0 (21e0c1d23afff48601eb93135defddae51f7e2e3) and I can't find 603 # a way to discover it from -help, so check the openssl version. 604 case $($OPENSSL_CMD version) in 605 "OpenSSL 0"*|"OpenSSL 1.0"*) :;; 606 *) 607 O_CLIENT_ARGS="$O_CLIENT_ARGS -cipher ALL@SECLEVEL=0" 608 O_SERVER_ARGS="$O_SERVER_ARGS -cipher ALL@SECLEVEL=0" 609 ;; 610 esac 611 612 if [ "X$VERIFY" = "XYES" ]; 613 then 614 M_SERVER_ARGS="$M_SERVER_ARGS ca_file=data_files/test-ca_cat12.crt auth_mode=required" 615 O_SERVER_ARGS="$O_SERVER_ARGS -CAfile data_files/test-ca_cat12.crt -Verify 10" 616 G_SERVER_ARGS="$G_SERVER_ARGS --x509cafile data_files/test-ca_cat12.crt --require-client-cert" 617 618 M_CLIENT_ARGS="$M_CLIENT_ARGS ca_file=data_files/test-ca_cat12.crt auth_mode=required" 619 O_CLIENT_ARGS="$O_CLIENT_ARGS -CAfile data_files/test-ca_cat12.crt -verify 10" 620 G_CLIENT_ARGS="$G_CLIENT_ARGS --x509cafile data_files/test-ca_cat12.crt" 621 else 622 # don't request a client cert at all 623 M_SERVER_ARGS="$M_SERVER_ARGS ca_file=none auth_mode=none" 624 G_SERVER_ARGS="$G_SERVER_ARGS --disable-client-cert" 625 626 M_CLIENT_ARGS="$M_CLIENT_ARGS ca_file=none auth_mode=none" 627 O_CLIENT_ARGS="$O_CLIENT_ARGS" 628 G_CLIENT_ARGS="$G_CLIENT_ARGS --insecure" 629 fi 630 631 case $TYPE in 632 "ECDSA") 633 M_SERVER_ARGS="$M_SERVER_ARGS crt_file=data_files/server5.crt key_file=data_files/server5.key" 634 O_SERVER_ARGS="$O_SERVER_ARGS -cert data_files/server5.crt -key data_files/server5.key" 635 G_SERVER_ARGS="$G_SERVER_ARGS --x509certfile data_files/server5.crt --x509keyfile data_files/server5.key" 636 637 if [ "X$VERIFY" = "XYES" ]; then 638 M_CLIENT_ARGS="$M_CLIENT_ARGS crt_file=data_files/server6.crt key_file=data_files/server6.key" 639 O_CLIENT_ARGS="$O_CLIENT_ARGS -cert data_files/server6.crt -key data_files/server6.key" 640 G_CLIENT_ARGS="$G_CLIENT_ARGS --x509certfile data_files/server6.crt --x509keyfile data_files/server6.key" 641 else 642 M_CLIENT_ARGS="$M_CLIENT_ARGS crt_file=none key_file=none" 643 fi 644 ;; 645 646 "RSA") 647 M_SERVER_ARGS="$M_SERVER_ARGS crt_file=data_files/server2-sha256.crt key_file=data_files/server2.key" 648 O_SERVER_ARGS="$O_SERVER_ARGS -cert data_files/server2-sha256.crt -key data_files/server2.key" 649 G_SERVER_ARGS="$G_SERVER_ARGS --x509certfile data_files/server2-sha256.crt --x509keyfile data_files/server2.key" 650 651 if [ "X$VERIFY" = "XYES" ]; then 652 M_CLIENT_ARGS="$M_CLIENT_ARGS crt_file=data_files/cert_sha256.crt key_file=data_files/server1.key" 653 O_CLIENT_ARGS="$O_CLIENT_ARGS -cert data_files/cert_sha256.crt -key data_files/server1.key" 654 G_CLIENT_ARGS="$G_CLIENT_ARGS --x509certfile data_files/cert_sha256.crt --x509keyfile data_files/server1.key" 655 else 656 M_CLIENT_ARGS="$M_CLIENT_ARGS crt_file=none key_file=none" 657 fi 658 ;; 659 660 "PSK") 661 # give RSA-PSK-capable server a RSA cert 662 # (should be a separate type, but harder to close with openssl) 663 M_SERVER_ARGS="$M_SERVER_ARGS psk=6162636465666768696a6b6c6d6e6f70 ca_file=none crt_file=data_files/server2-sha256.crt key_file=data_files/server2.key" 664 O_SERVER_ARGS="$O_SERVER_ARGS -psk 6162636465666768696a6b6c6d6e6f70 -nocert" 665 G_SERVER_ARGS="$G_SERVER_ARGS --x509certfile data_files/server2-sha256.crt --x509keyfile data_files/server2.key --pskpasswd data_files/passwd.psk" 666 667 M_CLIENT_ARGS="$M_CLIENT_ARGS psk=6162636465666768696a6b6c6d6e6f70 crt_file=none key_file=none" 668 O_CLIENT_ARGS="$O_CLIENT_ARGS -psk 6162636465666768696a6b6c6d6e6f70" 669 G_CLIENT_ARGS="$G_CLIENT_ARGS --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70" 670 ;; 671 esac 672} 673 674# is_mbedtls <cmd_line> 675is_mbedtls() { 676 echo "$1" | grep 'ssl_server2\|ssl_client2' > /dev/null 677} 678 679# has_mem_err <log_file_name> 680has_mem_err() { 681 if ( grep -F 'All heap blocks were freed -- no leaks are possible' "$1" && 682 grep -F 'ERROR SUMMARY: 0 errors from 0 contexts' "$1" ) > /dev/null 683 then 684 return 1 # false: does not have errors 685 else 686 return 0 # true: has errors 687 fi 688} 689 690# Wait for process $2 to be listening on port $1 691if type lsof >/dev/null 2>/dev/null; then 692 wait_server_start() { 693 START_TIME=$(date +%s) 694 if is_dtls "$MODE"; then 695 proto=UDP 696 else 697 proto=TCP 698 fi 699 while ! lsof -a -n -b -i "$proto:$1" -p "$2" >/dev/null 2>/dev/null; do 700 if [ $(( $(date +%s) - $START_TIME )) -gt $DOG_DELAY ]; then 701 echo "SERVERSTART TIMEOUT" 702 echo "SERVERSTART TIMEOUT" >> $SRV_OUT 703 break 704 fi 705 # Linux and *BSD support decimal arguments to sleep. On other 706 # OSes this may be a tight loop. 707 sleep 0.1 2>/dev/null || true 708 done 709 } 710else 711 echo "Warning: lsof not available, wait_server_start = sleep" 712 wait_server_start() { 713 sleep 2 714 } 715fi 716 717 718# start_server <name> 719# also saves name and command 720start_server() { 721 case $1 in 722 [Oo]pen*) 723 SERVER_CMD="$OPENSSL_CMD s_server $O_SERVER_ARGS" 724 ;; 725 [Gg]nu*) 726 SERVER_CMD="$GNUTLS_SERV $G_SERVER_ARGS --priority $G_SERVER_PRIO" 727 ;; 728 mbed*) 729 SERVER_CMD="$M_SRV $M_SERVER_ARGS" 730 if [ "$MEMCHECK" -gt 0 ]; then 731 SERVER_CMD="valgrind --leak-check=full $SERVER_CMD" 732 fi 733 ;; 734 *) 735 echo "error: invalid server name: $1" >&2 736 exit 1 737 ;; 738 esac 739 SERVER_NAME=$1 740 741 log "$SERVER_CMD" 742 echo "$SERVER_CMD" > $SRV_OUT 743 # for servers without -www or equivalent 744 while :; do echo bla; sleep 1; done | $SERVER_CMD >> $SRV_OUT 2>&1 & 745 PROCESS_ID=$! 746 747 wait_server_start "$PORT" "$PROCESS_ID" 748} 749 750# terminate the running server 751stop_server() { 752 kill $PROCESS_ID 2>/dev/null 753 wait $PROCESS_ID 2>/dev/null 754 755 if [ "$MEMCHECK" -gt 0 ]; then 756 if is_mbedtls "$SERVER_CMD" && has_mem_err $SRV_OUT; then 757 echo " ! Server had memory errors" 758 SRVMEM=$(( $SRVMEM + 1 )) 759 return 760 fi 761 fi 762 763 rm -f $SRV_OUT 764} 765 766# kill the running server (used when killed by signal) 767cleanup() { 768 rm -f $SRV_OUT $CLI_OUT 769 kill $PROCESS_ID >/dev/null 2>&1 770 kill $WATCHDOG_PID >/dev/null 2>&1 771 exit 1 772} 773 774# wait for client to terminate and set EXIT 775# must be called right after starting the client 776wait_client_done() { 777 CLI_PID=$! 778 779 ( sleep "$DOG_DELAY"; echo "TIMEOUT" >> $CLI_OUT; kill $CLI_PID ) & 780 WATCHDOG_PID=$! 781 782 wait $CLI_PID 783 EXIT=$? 784 785 kill $WATCHDOG_PID 786 wait $WATCHDOG_PID 787 788 echo "EXIT: $EXIT" >> $CLI_OUT 789} 790 791# run_client <name> <cipher> 792run_client() { 793 # announce what we're going to do 794 TESTS=$(( $TESTS + 1 )) 795 VERIF=$(echo $VERIFY | tr '[:upper:]' '[:lower:]') 796 TITLE="`echo $1 | head -c1`->`echo $SERVER_NAME | head -c1`" 797 TITLE="$TITLE $MODE,$VERIF $2" 798 printf "%s " "$TITLE" 799 LEN=$(( 72 - `echo "$TITLE" | wc -c` )) 800 for i in `seq 1 $LEN`; do printf '.'; done; printf ' ' 801 802 # should we skip? 803 if [ "X$SKIP_NEXT" = "XYES" ]; then 804 SKIP_NEXT="NO" 805 echo "SKIP" 806 SKIPPED=$(( $SKIPPED + 1 )) 807 return 808 fi 809 810 # run the command and interpret result 811 case $1 in 812 [Oo]pen*) 813 CLIENT_CMD="$OPENSSL_CMD s_client $O_CLIENT_ARGS -cipher $2" 814 log "$CLIENT_CMD" 815 echo "$CLIENT_CMD" > $CLI_OUT 816 printf 'GET HTTP/1.0\r\n\r\n' | $CLIENT_CMD >> $CLI_OUT 2>&1 & 817 wait_client_done 818 819 if [ $EXIT -eq 0 ]; then 820 RESULT=0 821 else 822 # If the cipher isn't supported... 823 if grep 'Cipher is (NONE)' $CLI_OUT >/dev/null; then 824 RESULT=1 825 else 826 RESULT=2 827 fi 828 fi 829 ;; 830 831 [Gg]nu*) 832 # need to force IPv4 with UDP, but keep localhost for auth 833 if is_dtls "$MODE"; then 834 G_HOST="127.0.0.1" 835 else 836 G_HOST="localhost" 837 fi 838 CLIENT_CMD="$GNUTLS_CLI $G_CLIENT_ARGS --priority $G_PRIO_MODE:$2 $G_HOST" 839 log "$CLIENT_CMD" 840 echo "$CLIENT_CMD" > $CLI_OUT 841 printf 'GET HTTP/1.0\r\n\r\n' | $CLIENT_CMD >> $CLI_OUT 2>&1 & 842 wait_client_done 843 844 if [ $EXIT -eq 0 ]; then 845 RESULT=0 846 else 847 RESULT=2 848 # interpret early failure, with a handshake_failure alert 849 # before the server hello, as "no ciphersuite in common" 850 if grep -F 'Received alert [40]: Handshake failed' $CLI_OUT; then 851 if grep -i 'SERVER HELLO .* was received' $CLI_OUT; then : 852 else 853 RESULT=1 854 fi 855 fi >/dev/null 856 fi 857 ;; 858 859 mbed*) 860 CLIENT_CMD="$M_CLI $M_CLIENT_ARGS force_ciphersuite=$2" 861 if [ "$MEMCHECK" -gt 0 ]; then 862 CLIENT_CMD="valgrind --leak-check=full $CLIENT_CMD" 863 fi 864 log "$CLIENT_CMD" 865 echo "$CLIENT_CMD" > $CLI_OUT 866 $CLIENT_CMD >> $CLI_OUT 2>&1 & 867 wait_client_done 868 869 case $EXIT in 870 # Success 871 "0") RESULT=0 ;; 872 873 # Ciphersuite not supported 874 "2") RESULT=1 ;; 875 876 # Error 877 *) RESULT=2 ;; 878 esac 879 880 if [ "$MEMCHECK" -gt 0 ]; then 881 if is_mbedtls "$CLIENT_CMD" && has_mem_err $CLI_OUT; then 882 RESULT=2 883 fi 884 fi 885 886 ;; 887 888 *) 889 echo "error: invalid client name: $1" >&2 890 exit 1 891 ;; 892 esac 893 894 echo "EXIT: $EXIT" >> $CLI_OUT 895 896 # report and count result 897 case $RESULT in 898 "0") 899 echo PASS 900 ;; 901 "1") 902 echo SKIP 903 SKIPPED=$(( $SKIPPED + 1 )) 904 ;; 905 "2") 906 echo FAIL 907 cp $SRV_OUT c-srv-${TESTS}.log 908 cp $CLI_OUT c-cli-${TESTS}.log 909 echo " ! outputs saved to c-srv-${TESTS}.log, c-cli-${TESTS}.log" 910 911 if [ "${LOG_FAILURE_ON_STDOUT:-0}" != 0 ]; then 912 echo " ! server output:" 913 cat c-srv-${TESTS}.log 914 echo " ! ===================================================" 915 echo " ! client output:" 916 cat c-cli-${TESTS}.log 917 fi 918 919 FAILED=$(( $FAILED + 1 )) 920 ;; 921 esac 922 923 rm -f $CLI_OUT 924} 925 926# 927# MAIN 928# 929 930if cd $( dirname $0 ); then :; else 931 echo "cd $( dirname $0 ) failed" >&2 932 exit 1 933fi 934 935get_options "$@" 936 937# sanity checks, avoid an avalanche of errors 938if [ ! -x "$M_SRV" ]; then 939 echo "Command '$M_SRV' is not an executable file" >&2 940 exit 1 941fi 942if [ ! -x "$M_CLI" ]; then 943 echo "Command '$M_CLI' is not an executable file" >&2 944 exit 1 945fi 946 947if echo "$PEERS" | grep -i openssl > /dev/null; then 948 if which "$OPENSSL_CMD" >/dev/null 2>&1; then :; else 949 echo "Command '$OPENSSL_CMD' not found" >&2 950 exit 1 951 fi 952fi 953 954if echo "$PEERS" | grep -i gnutls > /dev/null; then 955 for CMD in "$GNUTLS_CLI" "$GNUTLS_SERV"; do 956 if which "$CMD" >/dev/null 2>&1; then :; else 957 echo "Command '$CMD' not found" >&2 958 exit 1 959 fi 960 done 961fi 962 963for PEER in $PEERS; do 964 case "$PEER" in 965 mbed*|[Oo]pen*|[Gg]nu*) 966 ;; 967 *) 968 echo "Unknown peers: $PEER" >&2 969 exit 1 970 esac 971done 972 973# Pick a "unique" port in the range 10000-19999. 974PORT="0000$$" 975PORT="1$(echo $PORT | tail -c 5)" 976 977# Also pick a unique name for intermediate files 978SRV_OUT="srv_out.$$" 979CLI_OUT="cli_out.$$" 980 981# client timeout delay: be more patient with valgrind 982if [ "$MEMCHECK" -gt 0 ]; then 983 DOG_DELAY=30 984else 985 DOG_DELAY=10 986fi 987 988SKIP_NEXT="NO" 989 990trap cleanup INT TERM HUP 991 992for VERIFY in $VERIFIES; do 993 for MODE in $MODES; do 994 for TYPE in $TYPES; do 995 for PEER in $PEERS; do 996 997 setup_arguments 998 999 case "$PEER" in 1000 1001 [Oo]pen*) 1002 1003 if test "$OSSL_NO_DTLS" -gt 0 && is_dtls "$MODE"; then 1004 continue; 1005 fi 1006 1007 # OpenSSL <1.0.2 doesn't support DTLS 1.2. Check if OpenSSL 1008 # supports $O_MODE from the s_server help. (The s_client 1009 # help isn't accurate as of 1.0.2g: it supports DTLS 1.2 1010 # but doesn't list it. But the s_server help seems to be 1011 # accurate.) 1012 if ! $OPENSSL_CMD s_server -help 2>&1 | grep -q "^ *-$O_MODE "; then 1013 continue; 1014 fi 1015 1016 reset_ciphersuites 1017 add_common_ciphersuites 1018 add_openssl_ciphersuites 1019 filter_ciphersuites 1020 1021 if [ "X" != "X$M_CIPHERS" ]; then 1022 start_server "OpenSSL" 1023 for i in $M_CIPHERS; do 1024 check_openssl_server_bug $i 1025 run_client mbedTLS $i 1026 done 1027 stop_server 1028 fi 1029 1030 if [ "X" != "X$O_CIPHERS" ]; then 1031 start_server "mbedTLS" 1032 for i in $O_CIPHERS; do 1033 run_client OpenSSL $i 1034 done 1035 stop_server 1036 fi 1037 1038 ;; 1039 1040 [Gg]nu*) 1041 1042 reset_ciphersuites 1043 add_common_ciphersuites 1044 add_gnutls_ciphersuites 1045 filter_ciphersuites 1046 1047 if [ "X" != "X$M_CIPHERS" ]; then 1048 start_server "GnuTLS" 1049 for i in $M_CIPHERS; do 1050 run_client mbedTLS $i 1051 done 1052 stop_server 1053 fi 1054 1055 if [ "X" != "X$G_CIPHERS" ]; then 1056 start_server "mbedTLS" 1057 for i in $G_CIPHERS; do 1058 run_client GnuTLS $i 1059 done 1060 stop_server 1061 fi 1062 1063 ;; 1064 1065 mbed*) 1066 1067 reset_ciphersuites 1068 add_common_ciphersuites 1069 add_openssl_ciphersuites 1070 add_gnutls_ciphersuites 1071 add_mbedtls_ciphersuites 1072 filter_ciphersuites 1073 1074 if [ "X" != "X$M_CIPHERS" ]; then 1075 start_server "mbedTLS" 1076 for i in $M_CIPHERS; do 1077 run_client mbedTLS $i 1078 done 1079 stop_server 1080 fi 1081 1082 ;; 1083 1084 *) 1085 echo "Unknown peer: $PEER" >&2 1086 exit 1 1087 ;; 1088 1089 esac 1090 1091 done 1092 done 1093 done 1094done 1095 1096echo "------------------------------------------------------------------------" 1097 1098if [ $FAILED -ne 0 -o $SRVMEM -ne 0 ]; 1099then 1100 printf "FAILED" 1101else 1102 printf "PASSED" 1103fi 1104 1105if [ "$MEMCHECK" -gt 0 ]; then 1106 MEMREPORT=", $SRVMEM server memory errors" 1107else 1108 MEMREPORT="" 1109fi 1110 1111PASSED=$(( $TESTS - $FAILED )) 1112echo " ($PASSED / $TESTS tests ($SKIPPED skipped$MEMREPORT))" 1113 1114FAILED=$(( $FAILED + $SRVMEM )) 1115exit $FAILED 1116