diff --git a/.github/scripts/codespell-ignore.txt b/.github/scripts/codespell-ignore.txt index 3832cec4d7..a239d9ef54 100644 --- a/.github/scripts/codespell-ignore.txt +++ b/.github/scripts/codespell-ignore.txt @@ -13,3 +13,4 @@ inout msdos ba fo +ede diff --git a/docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.md b/docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.md index ce6a778b9e..06080f3809 100644 --- a/docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.md +++ b/docs/libcurl/opts/CURLOPT_PROXY_SSL_CIPHER_LIST.md @@ -19,6 +19,7 @@ TLS-backend: - Secure Transport - wolfSSL - GnuTLS + - mbedTLS --- # NAME @@ -49,12 +50,13 @@ set when you compile OpenSSL. For WolfSSL, valid examples of cipher lists include **ECDHE-RSA-RC4-SHA**, **AES256-SHA:AES256-SHA256**, etc. -For BearSSL, valid examples of cipher lists include -**ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256**, or when using IANA names +For mbedTLS and BearSSL, valid examples of cipher lists include +**ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256**, or when using +IANA names **TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256**, -etc. -With BearSSL you do not add/remove ciphers. If one uses this option then all -known ciphers are disabled and only those passed in are enabled. +etc. With mbedTLS and BearSSL you do not add/remove ciphers. If one uses this +option then all known ciphers are disabled and only those passed in are +enabled. Find more details about cipher lists on this URL: @@ -86,7 +88,7 @@ int main(void) # AVAILABILITY -Added in 7.52.0, in 7.83.0 for BearSSL +Added in 7.52.0, in 7.83.0 for BearSSL, in 8.8.0 for mbedTLS If built TLS enabled. diff --git a/docs/libcurl/opts/CURLOPT_SSL_CIPHER_LIST.md b/docs/libcurl/opts/CURLOPT_SSL_CIPHER_LIST.md index 3bf09d8dbf..a887fe9a16 100644 --- a/docs/libcurl/opts/CURLOPT_SSL_CIPHER_LIST.md +++ b/docs/libcurl/opts/CURLOPT_SSL_CIPHER_LIST.md @@ -19,6 +19,7 @@ TLS-backend: - Secure Transport - wolfSSL - GnuTLS + - mbedTLS --- # NAME @@ -48,12 +49,13 @@ you compile OpenSSL. For WolfSSL, valid examples of cipher lists include **ECDHE-RSA-RC4-SHA**, **AES256-SHA:AES256-SHA256**, etc. -For BearSSL, valid examples of cipher lists include +For mbedTLS and BearSSL, valid examples of cipher lists include **ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256**, or when using IANA names **TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256**, -etc. With BearSSL you do not add/remove ciphers. If one uses this option then -all known ciphers are disabled and only those passed in are enabled. +etc. With mbedTLS and BearSSL you do not add/remove ciphers. If one uses this +option then all known ciphers are disabled and only those passed in are +enabled. For Schannel, you can use this option to set algorithms but not specific cipher suites. Refer to the ciphers lists document for algorithms. @@ -87,7 +89,7 @@ int main(void) # AVAILABILITY -Added in 7.9, in 7.83.0 for BearSSL +Added in 7.9, in 7.83.0 for BearSSL, in 8.8.0 for mbedTLS If built TLS enabled. diff --git a/lib/Makefile.inc b/lib/Makefile.inc index 12afebfb5c..66680f3adb 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -44,6 +44,7 @@ LIB_VAUTH_HFILES = \ LIB_VTLS_CFILES = \ vtls/bearssl.c \ + vtls/cipher_suite.c \ vtls/gtls.c \ vtls/hostcheck.c \ vtls/keylog.c \ @@ -60,6 +61,7 @@ LIB_VTLS_CFILES = \ LIB_VTLS_HFILES = \ vtls/bearssl.h \ + vtls/cipher_suite.h \ vtls/gtls.h \ vtls/hostcheck.h \ vtls/keylog.h \ diff --git a/lib/vtls/cipher_suite.c b/lib/vtls/cipher_suite.c new file mode 100644 index 0000000000..d01f9d90eb --- /dev/null +++ b/lib/vtls/cipher_suite.c @@ -0,0 +1,699 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) Jan Venekamp, + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "curl_setup.h" + +#if defined(USE_MBEDTLS) +#include "cipher_suite.h" +#include "curl_printf.h" +#include "strcase.h" +#include + +/* + * To support the CURLOPT_SSL_CIPHER_LIST option on SSL backends + * that do not support it natively, but do support setting a list of + * IANA ids, we need a list of all supported cipher suite names + * (openssl and IANA) to be able to look up the IANA ids. + * + * To keep the binary size of this list down we compress each entry + * down to 2 + 6 bytes using the C preprocessor. + */ + +/* + * mbedTLS NOTE: mbedTLS has mbedtls_ssl_get_ciphersuite_id() to + * convert a string representation to an IANA id, we do not use that + * because it does not support "standard" openssl cipher suite + * names, nor IANA names. + */ + +/* NOTE: also see tests/unit/unit3205.c */ + +/* Text for cipher suite parts (max 64 entries), + keep indexes below in sync with this! */ +static const char *cs_txt = + "\0" + "TLS" "\0" + "WITH" "\0" + "128" "\0" + "256" "\0" + "3DES" "\0" + "8" "\0" + "AES" "\0" + "AES128" "\0" + "AES256" "\0" + "CBC" "\0" + "CBC3" "\0" + "CCM" "\0" + "CCM8" "\0" + "CHACHA20" "\0" + "DES" "\0" + "DHE" "\0" + "ECDH" "\0" + "ECDHE" "\0" + "ECDSA" "\0" + "EDE" "\0" + "GCM" "\0" + "MD5" "\0" + "NULL" "\0" + "POLY1305" "\0" + "PSK" "\0" + "RSA" "\0" + "SHA" "\0" + "SHA256" "\0" + "SHA384" "\0" + "ARIA" "\0" + "ARIA128" "\0" + "ARIA256" "\0" + "CAMELLIA" "\0" + "CAMELLIA128" "\0" + "CAMELLIA256" "\0" +; +/* Indexes of above cs_txt */ +enum { + CS_TXT_IDX_, + CS_TXT_IDX_TLS, + CS_TXT_IDX_WITH, + CS_TXT_IDX_128, + CS_TXT_IDX_256, + CS_TXT_IDX_3DES, + CS_TXT_IDX_8, + CS_TXT_IDX_AES, + CS_TXT_IDX_AES128, + CS_TXT_IDX_AES256, + CS_TXT_IDX_CBC, + CS_TXT_IDX_CBC3, + CS_TXT_IDX_CCM, + CS_TXT_IDX_CCM8, + CS_TXT_IDX_CHACHA20, + CS_TXT_IDX_DES, + CS_TXT_IDX_DHE, + CS_TXT_IDX_ECDH, + CS_TXT_IDX_ECDHE, + CS_TXT_IDX_ECDSA, + CS_TXT_IDX_EDE, + CS_TXT_IDX_GCM, + CS_TXT_IDX_MD5, + CS_TXT_IDX_NULL, + CS_TXT_IDX_POLY1305, + CS_TXT_IDX_PSK, + CS_TXT_IDX_RSA, + CS_TXT_IDX_SHA, + CS_TXT_IDX_SHA256, + CS_TXT_IDX_SHA384, + CS_TXT_IDX_ARIA, + CS_TXT_IDX_ARIA128, + CS_TXT_IDX_ARIA256, + CS_TXT_IDX_CAMELLIA, + CS_TXT_IDX_CAMELLIA128, + CS_TXT_IDX_CAMELLIA256, + CS_TXT_LEN, +}; + +#define CS_ZIP_IDX(a, b, c, d, e, f, g, h) \ +{ \ + (uint8_t) ((a) << 2 | ((b) & 0x3F) >> 4), \ + (uint8_t) ((b) << 4 | ((c) & 0x3F) >> 2), \ + (uint8_t) ((c) << 6 | ((d) & 0x3F)), \ + (uint8_t) ((e) << 2 | ((f) & 0x3F) >> 4), \ + (uint8_t) ((f) << 4 | ((g) & 0x3F) >> 2), \ + (uint8_t) ((g) << 6 | ((h) & 0x3F)) \ +} +#define CS_ENTRY(id, a, b, c, d, e, f, g, h) \ +{ \ + id, \ + CS_ZIP_IDX( \ + CS_TXT_IDX_ ## a, CS_TXT_IDX_ ## b, \ + CS_TXT_IDX_ ## c, CS_TXT_IDX_ ## d, \ + CS_TXT_IDX_ ## e, CS_TXT_IDX_ ## f, \ + CS_TXT_IDX_ ## g, CS_TXT_IDX_ ## h \ + ) \ +} + +struct cs_entry { + uint16_t id; + uint8_t zip[6]; +}; + +/* !checksrc! disable COMMANOSPACE all */ +static const struct cs_entry cs_list [] = { + CS_ENTRY(0x002F, TLS,RSA,WITH,AES,128,CBC,SHA,), + CS_ENTRY(0x002F, AES128,SHA,,,,,,), + CS_ENTRY(0x0035, TLS,RSA,WITH,AES,256,CBC,SHA,), + CS_ENTRY(0x0035, AES256,SHA,,,,,,), + CS_ENTRY(0x003C, TLS,RSA,WITH,AES,128,CBC,SHA256,), + CS_ENTRY(0x003C, AES128,SHA256,,,,,,), + CS_ENTRY(0x003D, TLS,RSA,WITH,AES,256,CBC,SHA256,), + CS_ENTRY(0x003D, AES256,SHA256,,,,,,), + CS_ENTRY(0x009C, TLS,RSA,WITH,AES,128,GCM,SHA256,), + CS_ENTRY(0x009C, AES128,GCM,SHA256,,,,,), + CS_ENTRY(0x009D, TLS,RSA,WITH,AES,256,GCM,SHA384,), + CS_ENTRY(0x009D, AES256,GCM,SHA384,,,,,), + CS_ENTRY(0xC004, TLS,ECDH,ECDSA,WITH,AES,128,CBC,SHA), + CS_ENTRY(0xC004, ECDH,ECDSA,AES128,SHA,,,,), + CS_ENTRY(0xC005, TLS,ECDH,ECDSA,WITH,AES,256,CBC,SHA), + CS_ENTRY(0xC005, ECDH,ECDSA,AES256,SHA,,,,), + CS_ENTRY(0xC009, TLS,ECDHE,ECDSA,WITH,AES,128,CBC,SHA), + CS_ENTRY(0xC009, ECDHE,ECDSA,AES128,SHA,,,,), + CS_ENTRY(0xC00A, TLS,ECDHE,ECDSA,WITH,AES,256,CBC,SHA), + CS_ENTRY(0xC00A, ECDHE,ECDSA,AES256,SHA,,,,), + CS_ENTRY(0xC00E, TLS,ECDH,RSA,WITH,AES,128,CBC,SHA), + CS_ENTRY(0xC00E, ECDH,RSA,AES128,SHA,,,,), + CS_ENTRY(0xC00F, TLS,ECDH,RSA,WITH,AES,256,CBC,SHA), + CS_ENTRY(0xC00F, ECDH,RSA,AES256,SHA,,,,), + CS_ENTRY(0xC013, TLS,ECDHE,RSA,WITH,AES,128,CBC,SHA), + CS_ENTRY(0xC013, ECDHE,RSA,AES128,SHA,,,,), + CS_ENTRY(0xC014, TLS,ECDHE,RSA,WITH,AES,256,CBC,SHA), + CS_ENTRY(0xC014, ECDHE,RSA,AES256,SHA,,,,), + CS_ENTRY(0xC023, TLS,ECDHE,ECDSA,WITH,AES,128,CBC,SHA256), + CS_ENTRY(0xC023, ECDHE,ECDSA,AES128,SHA256,,,,), + CS_ENTRY(0xC024, TLS,ECDHE,ECDSA,WITH,AES,256,CBC,SHA384), + CS_ENTRY(0xC024, ECDHE,ECDSA,AES256,SHA384,,,,), + CS_ENTRY(0xC025, TLS,ECDH,ECDSA,WITH,AES,128,CBC,SHA256), + CS_ENTRY(0xC025, ECDH,ECDSA,AES128,SHA256,,,,), + CS_ENTRY(0xC026, TLS,ECDH,ECDSA,WITH,AES,256,CBC,SHA384), + CS_ENTRY(0xC026, ECDH,ECDSA,AES256,SHA384,,,,), + CS_ENTRY(0xC027, TLS,ECDHE,RSA,WITH,AES,128,CBC,SHA256), + CS_ENTRY(0xC027, ECDHE,RSA,AES128,SHA256,,,,), + CS_ENTRY(0xC028, TLS,ECDHE,RSA,WITH,AES,256,CBC,SHA384), + CS_ENTRY(0xC028, ECDHE,RSA,AES256,SHA384,,,,), + CS_ENTRY(0xC029, TLS,ECDH,RSA,WITH,AES,128,CBC,SHA256), + CS_ENTRY(0xC029, ECDH,RSA,AES128,SHA256,,,,), + CS_ENTRY(0xC02A, TLS,ECDH,RSA,WITH,AES,256,CBC,SHA384), + CS_ENTRY(0xC02A, ECDH,RSA,AES256,SHA384,,,,), + CS_ENTRY(0xC02B, TLS,ECDHE,ECDSA,WITH,AES,128,GCM,SHA256), + CS_ENTRY(0xC02B, ECDHE,ECDSA,AES128,GCM,SHA256,,,), + CS_ENTRY(0xC02C, TLS,ECDHE,ECDSA,WITH,AES,256,GCM,SHA384), + CS_ENTRY(0xC02C, ECDHE,ECDSA,AES256,GCM,SHA384,,,), + CS_ENTRY(0xC02D, TLS,ECDH,ECDSA,WITH,AES,128,GCM,SHA256), + CS_ENTRY(0xC02D, ECDH,ECDSA,AES128,GCM,SHA256,,,), + CS_ENTRY(0xC02E, TLS,ECDH,ECDSA,WITH,AES,256,GCM,SHA384), + CS_ENTRY(0xC02E, ECDH,ECDSA,AES256,GCM,SHA384,,,), + CS_ENTRY(0xC02F, TLS,ECDHE,RSA,WITH,AES,128,GCM,SHA256), + CS_ENTRY(0xC02F, ECDHE,RSA,AES128,GCM,SHA256,,,), + CS_ENTRY(0xC030, TLS,ECDHE,RSA,WITH,AES,256,GCM,SHA384), + CS_ENTRY(0xC030, ECDHE,RSA,AES256,GCM,SHA384,,,), + CS_ENTRY(0xC031, TLS,ECDH,RSA,WITH,AES,128,GCM,SHA256), + CS_ENTRY(0xC031, ECDH,RSA,AES128,GCM,SHA256,,,), + CS_ENTRY(0xC032, TLS,ECDH,RSA,WITH,AES,256,GCM,SHA384), + CS_ENTRY(0xC032, ECDH,RSA,AES256,GCM,SHA384,,,), + CS_ENTRY(0xCCA8, TLS,ECDHE,RSA,WITH,CHACHA20,POLY1305,SHA256,), + CS_ENTRY(0xCCA8, ECDHE,RSA,CHACHA20,POLY1305,,,,), + CS_ENTRY(0xCCA9, TLS,ECDHE,ECDSA,WITH,CHACHA20,POLY1305,SHA256,), + CS_ENTRY(0xCCA9, ECDHE,ECDSA,CHACHA20,POLY1305,,,,), + + CS_ENTRY(0x0001, TLS,RSA,WITH,NULL,MD5,,,), + CS_ENTRY(0x0001, NULL,MD5,,,,,,), + CS_ENTRY(0x0002, TLS,RSA,WITH,NULL,SHA,,,), + CS_ENTRY(0x0002, NULL,SHA,,,,,,), + CS_ENTRY(0x002C, TLS,PSK,WITH,NULL,SHA,,,), + CS_ENTRY(0x002C, PSK,NULL,SHA,,,,,), + CS_ENTRY(0x002D, TLS,DHE,PSK,WITH,NULL,SHA,,), + CS_ENTRY(0x002D, DHE,PSK,NULL,SHA,,,,), + CS_ENTRY(0x002E, TLS,RSA,PSK,WITH,NULL,SHA,,), + CS_ENTRY(0x002E, RSA,PSK,NULL,SHA,,,,), + CS_ENTRY(0x0033, TLS,DHE,RSA,WITH,AES,128,CBC,SHA), + CS_ENTRY(0x0033, DHE,RSA,AES128,SHA,,,,), + CS_ENTRY(0x0039, TLS,DHE,RSA,WITH,AES,256,CBC,SHA), + CS_ENTRY(0x0039, DHE,RSA,AES256,SHA,,,,), + CS_ENTRY(0x003B, TLS,RSA,WITH,NULL,SHA256,,,), + CS_ENTRY(0x003B, NULL,SHA256,,,,,,), + CS_ENTRY(0x0067, TLS,DHE,RSA,WITH,AES,128,CBC,SHA256), + CS_ENTRY(0x0067, DHE,RSA,AES128,SHA256,,,,), + CS_ENTRY(0x006B, TLS,DHE,RSA,WITH,AES,256,CBC,SHA256), + CS_ENTRY(0x006B, DHE,RSA,AES256,SHA256,,,,), + CS_ENTRY(0x008C, TLS,PSK,WITH,AES,128,CBC,SHA,), + CS_ENTRY(0x008C, PSK,AES128,CBC,SHA,,,,), + CS_ENTRY(0x008D, TLS,PSK,WITH,AES,256,CBC,SHA,), + CS_ENTRY(0x008D, PSK,AES256,CBC,SHA,,,,), + CS_ENTRY(0x0090, TLS,DHE,PSK,WITH,AES,128,CBC,SHA), + CS_ENTRY(0x0090, DHE,PSK,AES128,CBC,SHA,,,), + CS_ENTRY(0x0091, TLS,DHE,PSK,WITH,AES,256,CBC,SHA), + CS_ENTRY(0x0091, DHE,PSK,AES256,CBC,SHA,,,), + CS_ENTRY(0x0094, TLS,RSA,PSK,WITH,AES,128,CBC,SHA), + CS_ENTRY(0x0094, RSA,PSK,AES128,CBC,SHA,,,), + CS_ENTRY(0x0095, TLS,RSA,PSK,WITH,AES,256,CBC,SHA), + CS_ENTRY(0x0095, RSA,PSK,AES256,CBC,SHA,,,), + CS_ENTRY(0x009E, TLS,DHE,RSA,WITH,AES,128,GCM,SHA256), + CS_ENTRY(0x009E, DHE,RSA,AES128,GCM,SHA256,,,), + CS_ENTRY(0x009F, TLS,DHE,RSA,WITH,AES,256,GCM,SHA384), + CS_ENTRY(0x009F, DHE,RSA,AES256,GCM,SHA384,,,), + CS_ENTRY(0x00A8, TLS,PSK,WITH,AES,128,GCM,SHA256,), + CS_ENTRY(0x00A8, PSK,AES128,GCM,SHA256,,,,), + CS_ENTRY(0x00A9, TLS,PSK,WITH,AES,256,GCM,SHA384,), + CS_ENTRY(0x00A9, PSK,AES256,GCM,SHA384,,,,), + CS_ENTRY(0x00AA, TLS,DHE,PSK,WITH,AES,128,GCM,SHA256), + CS_ENTRY(0x00AA, DHE,PSK,AES128,GCM,SHA256,,,), + CS_ENTRY(0x00AB, TLS,DHE,PSK,WITH,AES,256,GCM,SHA384), + CS_ENTRY(0x00AB, DHE,PSK,AES256,GCM,SHA384,,,), + CS_ENTRY(0x00AC, TLS,RSA,PSK,WITH,AES,128,GCM,SHA256), + CS_ENTRY(0x00AC, RSA,PSK,AES128,GCM,SHA256,,,), + CS_ENTRY(0x00AD, TLS,RSA,PSK,WITH,AES,256,GCM,SHA384), + CS_ENTRY(0x00AD, RSA,PSK,AES256,GCM,SHA384,,,), + CS_ENTRY(0x00AE, TLS,PSK,WITH,AES,128,CBC,SHA256,), + CS_ENTRY(0x00AE, PSK,AES128,CBC,SHA256,,,,), + CS_ENTRY(0x00AF, TLS,PSK,WITH,AES,256,CBC,SHA384,), + CS_ENTRY(0x00AF, PSK,AES256,CBC,SHA384,,,,), + CS_ENTRY(0x00B0, TLS,PSK,WITH,NULL,SHA256,,,), + CS_ENTRY(0x00B0, PSK,NULL,SHA256,,,,,), + CS_ENTRY(0x00B1, TLS,PSK,WITH,NULL,SHA384,,,), + CS_ENTRY(0x00B1, PSK,NULL,SHA384,,,,,), + CS_ENTRY(0x00B2, TLS,DHE,PSK,WITH,AES,128,CBC,SHA256), + CS_ENTRY(0x00B2, DHE,PSK,AES128,CBC,SHA256,,,), + CS_ENTRY(0x00B3, TLS,DHE,PSK,WITH,AES,256,CBC,SHA384), + CS_ENTRY(0x00B3, DHE,PSK,AES256,CBC,SHA384,,,), + CS_ENTRY(0x00B4, TLS,DHE,PSK,WITH,NULL,SHA256,,), + CS_ENTRY(0x00B4, DHE,PSK,NULL,SHA256,,,,), + CS_ENTRY(0x00B5, TLS,DHE,PSK,WITH,NULL,SHA384,,), + CS_ENTRY(0x00B5, DHE,PSK,NULL,SHA384,,,,), + CS_ENTRY(0x00B6, TLS,RSA,PSK,WITH,AES,128,CBC,SHA256), + CS_ENTRY(0x00B6, RSA,PSK,AES128,CBC,SHA256,,,), + CS_ENTRY(0x00B7, TLS,RSA,PSK,WITH,AES,256,CBC,SHA384), + CS_ENTRY(0x00B7, RSA,PSK,AES256,CBC,SHA384,,,), + CS_ENTRY(0x00B8, TLS,RSA,PSK,WITH,NULL,SHA256,,), + CS_ENTRY(0x00B8, RSA,PSK,NULL,SHA256,,,,), + CS_ENTRY(0x00B9, TLS,RSA,PSK,WITH,NULL,SHA384,,), + CS_ENTRY(0x00B9, RSA,PSK,NULL,SHA384,,,,), + CS_ENTRY(0x1301, TLS,AES,128,GCM,SHA256,,,), + CS_ENTRY(0x1302, TLS,AES,256,GCM,SHA384,,,), + CS_ENTRY(0x1303, TLS,CHACHA20,POLY1305,SHA256,,,,), + CS_ENTRY(0x1304, TLS,AES,128,CCM,SHA256,,,), + CS_ENTRY(0x1305, TLS,AES,128,CCM,8,SHA256,,), + CS_ENTRY(0xC001, TLS,ECDH,ECDSA,WITH,NULL,SHA,,), + CS_ENTRY(0xC001, ECDH,ECDSA,NULL,SHA,,,,), + CS_ENTRY(0xC006, TLS,ECDHE,ECDSA,WITH,NULL,SHA,,), + CS_ENTRY(0xC006, ECDHE,ECDSA,NULL,SHA,,,,), + CS_ENTRY(0xC00B, TLS,ECDH,RSA,WITH,NULL,SHA,,), + CS_ENTRY(0xC00B, ECDH,RSA,NULL,SHA,,,,), + CS_ENTRY(0xC010, TLS,ECDHE,RSA,WITH,NULL,SHA,,), + CS_ENTRY(0xC010, ECDHE,RSA,NULL,SHA,,,,), + CS_ENTRY(0xC035, TLS,ECDHE,PSK,WITH,AES,128,CBC,SHA), + CS_ENTRY(0xC035, ECDHE,PSK,AES128,CBC,SHA,,,), + CS_ENTRY(0xC036, TLS,ECDHE,PSK,WITH,AES,256,CBC,SHA), + CS_ENTRY(0xC036, ECDHE,PSK,AES256,CBC,SHA,,,), + CS_ENTRY(0xCCAB, TLS,PSK,WITH,CHACHA20,POLY1305,SHA256,,), + CS_ENTRY(0xCCAB, PSK,CHACHA20,POLY1305,,,,,), + + CS_ENTRY(0xC09C, TLS,RSA,WITH,AES,128,CCM,,), + CS_ENTRY(0xC09C, AES128,CCM,,,,,,), + CS_ENTRY(0xC09D, TLS,RSA,WITH,AES,256,CCM,,), + CS_ENTRY(0xC09D, AES256,CCM,,,,,,), + CS_ENTRY(0xC0A0, TLS,RSA,WITH,AES,128,CCM,8,), + CS_ENTRY(0xC0A0, AES128,CCM8,,,,,,), + CS_ENTRY(0xC0A1, TLS,RSA,WITH,AES,256,CCM,8,), + CS_ENTRY(0xC0A1, AES256,CCM8,,,,,,), + CS_ENTRY(0xC0AC, TLS,ECDHE,ECDSA,WITH,AES,128,CCM,), + CS_ENTRY(0xC0AC, ECDHE,ECDSA,AES128,CCM,,,,), + CS_ENTRY(0xC0AD, TLS,ECDHE,ECDSA,WITH,AES,256,CCM,), + CS_ENTRY(0xC0AD, ECDHE,ECDSA,AES256,CCM,,,,), + CS_ENTRY(0xC0AE, TLS,ECDHE,ECDSA,WITH,AES,128,CCM,8), + CS_ENTRY(0xC0AE, ECDHE,ECDSA,AES128,CCM8,,,,), + CS_ENTRY(0xC0AF, TLS,ECDHE,ECDSA,WITH,AES,256,CCM,8), + CS_ENTRY(0xC0AF, ECDHE,ECDSA,AES256,CCM8,,,,), + + /* entries marked ns are "non-standard", they are not in openssl */ + CS_ENTRY(0x0041, TLS,RSA,WITH,CAMELLIA,128,CBC,SHA,), + CS_ENTRY(0x0041, CAMELLIA128,SHA,,,,,,), + CS_ENTRY(0x0045, TLS,DHE,RSA,WITH,CAMELLIA,128,CBC,SHA), + CS_ENTRY(0x0045, DHE,RSA,CAMELLIA128,SHA,,,,), + CS_ENTRY(0x0084, TLS,RSA,WITH,CAMELLIA,256,CBC,SHA,), + CS_ENTRY(0x0084, CAMELLIA256,SHA,,,,,,), + CS_ENTRY(0x0088, TLS,DHE,RSA,WITH,CAMELLIA,256,CBC,SHA), + CS_ENTRY(0x0088, DHE,RSA,CAMELLIA256,SHA,,,,), + CS_ENTRY(0x00BA, TLS,RSA,WITH,CAMELLIA,128,CBC,SHA256,), + CS_ENTRY(0x00BA, CAMELLIA128,SHA256,,,,,,), + CS_ENTRY(0x00BE, TLS,DHE,RSA,WITH,CAMELLIA,128,CBC,SHA256), + CS_ENTRY(0x00BE, DHE,RSA,CAMELLIA128,SHA256,,,,), + CS_ENTRY(0x00C0, TLS,RSA,WITH,CAMELLIA,256,CBC,SHA256,), + CS_ENTRY(0x00C0, CAMELLIA256,SHA256,,,,,,), + CS_ENTRY(0x00C4, TLS,DHE,RSA,WITH,CAMELLIA,256,CBC,SHA256), + CS_ENTRY(0x00C4, DHE,RSA,CAMELLIA256,SHA256,,,,), + CS_ENTRY(0xC037, TLS,ECDHE,PSK,WITH,AES,128,CBC,SHA256), + CS_ENTRY(0xC037, ECDHE,PSK,AES128,CBC,SHA256,,,), + CS_ENTRY(0xC038, TLS,ECDHE,PSK,WITH,AES,256,CBC,SHA384), + CS_ENTRY(0xC038, ECDHE,PSK,AES256,CBC,SHA384,,,), + CS_ENTRY(0xC039, TLS,ECDHE,PSK,WITH,NULL,SHA,,), + CS_ENTRY(0xC039, ECDHE,PSK,NULL,SHA,,,,), + CS_ENTRY(0xC03A, TLS,ECDHE,PSK,WITH,NULL,SHA256,,), + CS_ENTRY(0xC03A, ECDHE,PSK,NULL,SHA256,,,,), + CS_ENTRY(0xC03B, TLS,ECDHE,PSK,WITH,NULL,SHA384,,), + CS_ENTRY(0xC03B, ECDHE,PSK,NULL,SHA384,,,,), + CS_ENTRY(0xC03C, TLS,RSA,WITH,ARIA,128,CBC,SHA256,), + CS_ENTRY(0xC03C, ARIA128,SHA256,,,,,,), /* ns */ + CS_ENTRY(0xC03D, TLS,RSA,WITH,ARIA,256,CBC,SHA384,), + CS_ENTRY(0xC03D, ARIA256,SHA384,,,,,,), /* ns */ + CS_ENTRY(0xC044, TLS,DHE,RSA,WITH,ARIA,128,CBC,SHA256), + CS_ENTRY(0xC044, DHE,RSA,ARIA128,SHA256,,,,), /* ns */ + CS_ENTRY(0xC045, TLS,DHE,RSA,WITH,ARIA,256,CBC,SHA384), + CS_ENTRY(0xC045, DHE,RSA,ARIA256,SHA384,,,,), /* ns */ + CS_ENTRY(0xC048, TLS,ECDHE,ECDSA,WITH,ARIA,128,CBC,SHA256), + CS_ENTRY(0xC048, ECDHE,ECDSA,ARIA128,SHA256,,,,), /* ns */ + CS_ENTRY(0xC049, TLS,ECDHE,ECDSA,WITH,ARIA,256,CBC,SHA384), + CS_ENTRY(0xC049, ECDHE,ECDSA,ARIA256,SHA384,,,,), /* ns */ + CS_ENTRY(0xC04A, TLS,ECDH,ECDSA,WITH,ARIA,128,CBC,SHA256), + CS_ENTRY(0xC04A, ECDH,ECDSA,ARIA128,SHA256,,,,), /* ns */ + CS_ENTRY(0xC04B, TLS,ECDH,ECDSA,WITH,ARIA,256,CBC,SHA384), + CS_ENTRY(0xC04B, ECDH,ECDSA,ARIA256,SHA384,,,,), /* ns */ + CS_ENTRY(0xC04C, TLS,ECDHE,RSA,WITH,ARIA,128,CBC,SHA256), + CS_ENTRY(0xC04C, ECDHE,ARIA128,SHA256,,,,,), /* ns */ + CS_ENTRY(0xC04D, TLS,ECDHE,RSA,WITH,ARIA,256,CBC,SHA384), + CS_ENTRY(0xC04D, ECDHE,ARIA256,SHA384,,,,,), /* ns */ + CS_ENTRY(0xC04E, TLS,ECDH,RSA,WITH,ARIA,128,CBC,SHA256), + CS_ENTRY(0xC04E, ECDH,ARIA128,SHA256,,,,,), /* ns */ + CS_ENTRY(0xC04F, TLS,ECDH,RSA,WITH,ARIA,256,CBC,SHA384), + CS_ENTRY(0xC04F, ECDH,ARIA256,SHA384,,,,,), /* ns */ + CS_ENTRY(0xC050, TLS,RSA,WITH,ARIA,128,GCM,SHA256,), + CS_ENTRY(0xC050, ARIA128,GCM,SHA256,,,,,), + CS_ENTRY(0xC051, TLS,RSA,WITH,ARIA,256,GCM,SHA384,), + CS_ENTRY(0xC051, ARIA256,GCM,SHA384,,,,,), + CS_ENTRY(0xC052, TLS,DHE,RSA,WITH,ARIA,128,GCM,SHA256), + CS_ENTRY(0xC052, DHE,RSA,ARIA128,GCM,SHA256,,,), + CS_ENTRY(0xC053, TLS,DHE,RSA,WITH,ARIA,256,GCM,SHA384), + CS_ENTRY(0xC053, DHE,RSA,ARIA256,GCM,SHA384,,,), + CS_ENTRY(0xC05C, TLS,ECDHE,ECDSA,WITH,ARIA,128,GCM,SHA256), + CS_ENTRY(0xC05C, ECDHE,ECDSA,ARIA128,GCM,SHA256,,,), + CS_ENTRY(0xC05D, TLS,ECDHE,ECDSA,WITH,ARIA,256,GCM,SHA384), + CS_ENTRY(0xC05D, ECDHE,ECDSA,ARIA256,GCM,SHA384,,,), + CS_ENTRY(0xC05E, TLS,ECDH,ECDSA,WITH,ARIA,128,GCM,SHA256), + CS_ENTRY(0xC05E, ECDH,ECDSA,ARIA128,GCM,SHA256,,,), /* ns */ + CS_ENTRY(0xC05F, TLS,ECDH,ECDSA,WITH,ARIA,256,GCM,SHA384), + CS_ENTRY(0xC05F, ECDH,ECDSA,ARIA256,GCM,SHA384,,,), /* ns */ + CS_ENTRY(0xC060, TLS,ECDHE,RSA,WITH,ARIA,128,GCM,SHA256), + CS_ENTRY(0xC060, ECDHE,ARIA128,GCM,SHA256,,,,), + CS_ENTRY(0xC061, TLS,ECDHE,RSA,WITH,ARIA,256,GCM,SHA384), + CS_ENTRY(0xC061, ECDHE,ARIA256,GCM,SHA384,,,,), + CS_ENTRY(0xC062, TLS,ECDH,RSA,WITH,ARIA,128,GCM,SHA256), + CS_ENTRY(0xC062, ECDH,ARIA128,GCM,SHA256,,,,), /* ns */ + CS_ENTRY(0xC063, TLS,ECDH,RSA,WITH,ARIA,256,GCM,SHA384), + CS_ENTRY(0xC063, ECDH,ARIA256,GCM,SHA384,,,,), /* ns */ + CS_ENTRY(0xC064, TLS,PSK,WITH,ARIA,128,CBC,SHA256,), + CS_ENTRY(0xC064, PSK,ARIA128,SHA256,,,,,), /* ns */ + CS_ENTRY(0xC065, TLS,PSK,WITH,ARIA,256,CBC,SHA384,), + CS_ENTRY(0xC065, PSK,ARIA256,SHA384,,,,,), /* ns */ + CS_ENTRY(0xC066, TLS,DHE,PSK,WITH,ARIA,128,CBC,SHA256), + CS_ENTRY(0xC066, DHE,PSK,ARIA128,SHA256,,,,), /* ns */ + CS_ENTRY(0xC067, TLS,DHE,PSK,WITH,ARIA,256,CBC,SHA384), + CS_ENTRY(0xC067, DHE,PSK,ARIA256,SHA384,,,,), /* ns */ + CS_ENTRY(0xC068, TLS,RSA,PSK,WITH,ARIA,128,CBC,SHA256), + CS_ENTRY(0xC068, RSA,PSK,ARIA128,SHA256,,,,), /* ns */ + CS_ENTRY(0xC069, TLS,RSA,PSK,WITH,ARIA,256,CBC,SHA384), + CS_ENTRY(0xC069, RSA,PSK,ARIA256,SHA384,,,,), /* ns */ + CS_ENTRY(0xC06A, TLS,PSK,WITH,ARIA,128,GCM,SHA256,), + CS_ENTRY(0xC06A, PSK,ARIA128,GCM,SHA256,,,,), + CS_ENTRY(0xC06B, TLS,PSK,WITH,ARIA,256,GCM,SHA384,), + CS_ENTRY(0xC06B, PSK,ARIA256,GCM,SHA384,,,,), + CS_ENTRY(0xC06C, TLS,DHE,PSK,WITH,ARIA,128,GCM,SHA256), + CS_ENTRY(0xC06C, DHE,PSK,ARIA128,GCM,SHA256,,,), + CS_ENTRY(0xC06D, TLS,DHE,PSK,WITH,ARIA,256,GCM,SHA384), + CS_ENTRY(0xC06D, DHE,PSK,ARIA256,GCM,SHA384,,,), + CS_ENTRY(0xC06E, TLS,RSA,PSK,WITH,ARIA,128,GCM,SHA256), + CS_ENTRY(0xC06E, RSA,PSK,ARIA128,GCM,SHA256,,,), + CS_ENTRY(0xC06F, TLS,RSA,PSK,WITH,ARIA,256,GCM,SHA384), + CS_ENTRY(0xC06F, RSA,PSK,ARIA256,GCM,SHA384,,,), + CS_ENTRY(0xC070, TLS,ECDHE,PSK,WITH,ARIA,128,CBC,SHA256), + CS_ENTRY(0xC070, ECDHE,PSK,ARIA128,SHA256,,,,), /* ns */ + CS_ENTRY(0xC071, TLS,ECDHE,PSK,WITH,ARIA,256,CBC,SHA384), + CS_ENTRY(0xC071, ECDHE,PSK,ARIA256,SHA384,,,,), /* ns */ + CS_ENTRY(0xC072, TLS,ECDHE,ECDSA,WITH,CAMELLIA,128,CBC,SHA256), + CS_ENTRY(0xC072, ECDHE,ECDSA,CAMELLIA128,SHA256,,,,), + CS_ENTRY(0xC073, TLS,ECDHE,ECDSA,WITH,CAMELLIA,256,CBC,SHA384), + CS_ENTRY(0xC073, ECDHE,ECDSA,CAMELLIA256,SHA384,,,,), + CS_ENTRY(0xC074, TLS,ECDH,ECDSA,WITH,CAMELLIA,128,CBC,SHA256), + CS_ENTRY(0xC074, ECDH,ECDSA,CAMELLIA128,SHA256,,,,), /* ns */ + CS_ENTRY(0xC075, TLS,ECDH,ECDSA,WITH,CAMELLIA,256,CBC,SHA384), + CS_ENTRY(0xC075, ECDH,ECDSA,CAMELLIA256,SHA384,,,,), /* ns */ + CS_ENTRY(0xC076, TLS,ECDHE,RSA,WITH,CAMELLIA,128,CBC,SHA256), + CS_ENTRY(0xC076, ECDHE,RSA,CAMELLIA128,SHA256,,,,), + CS_ENTRY(0xC077, TLS,ECDHE,RSA,WITH,CAMELLIA,256,CBC,SHA384), + CS_ENTRY(0xC077, ECDHE,RSA,CAMELLIA256,SHA384,,,,), + CS_ENTRY(0xC078, TLS,ECDH,RSA,WITH,CAMELLIA,128,CBC,SHA256), + CS_ENTRY(0xC078, ECDH,CAMELLIA128,SHA256,,,,,), /* ns */ + CS_ENTRY(0xC079, TLS,ECDH,RSA,WITH,CAMELLIA,256,CBC,SHA384), + CS_ENTRY(0xC079, ECDH,CAMELLIA256,SHA384,,,,,), /* ns */ + CS_ENTRY(0xC07A, TLS,RSA,WITH,CAMELLIA,128,GCM,SHA256,), + CS_ENTRY(0xC07A, CAMELLIA128,GCM,SHA256,,,,,), /* ns */ + CS_ENTRY(0xC07B, TLS,RSA,WITH,CAMELLIA,256,GCM,SHA384,), + CS_ENTRY(0xC07B, CAMELLIA256,GCM,SHA384,,,,,), /* ns */ + CS_ENTRY(0xC07C, TLS,DHE,RSA,WITH,CAMELLIA,128,GCM,SHA256), + CS_ENTRY(0xC07C, DHE,RSA,CAMELLIA128,GCM,SHA256,,,), /* ns */ + CS_ENTRY(0xC07D, TLS,DHE,RSA,WITH,CAMELLIA,256,GCM,SHA384), + CS_ENTRY(0xC07D, DHE,RSA,CAMELLIA256,GCM,SHA384,,,), /* ns */ + CS_ENTRY(0xC086, TLS,ECDHE,ECDSA,WITH,CAMELLIA,128,GCM,SHA256), + CS_ENTRY(0xC086, ECDHE,ECDSA,CAMELLIA128,GCM,SHA256,,,), /* ns */ + CS_ENTRY(0xC087, TLS,ECDHE,ECDSA,WITH,CAMELLIA,256,GCM,SHA384), + CS_ENTRY(0xC087, ECDHE,ECDSA,CAMELLIA256,GCM,SHA384,,,), /* ns */ + CS_ENTRY(0xC088, TLS,ECDH,ECDSA,WITH,CAMELLIA,128,GCM,SHA256), + CS_ENTRY(0xC088, ECDH,ECDSA,CAMELLIA128,GCM,SHA256,,,), /* ns */ + CS_ENTRY(0xC089, TLS,ECDH,ECDSA,WITH,CAMELLIA,256,GCM,SHA384), + CS_ENTRY(0xC089, ECDH,ECDSA,CAMELLIA256,GCM,SHA384,,,), /* ns */ + CS_ENTRY(0xC08A, TLS,ECDHE,RSA,WITH,CAMELLIA,128,GCM,SHA256), + CS_ENTRY(0xC08A, ECDHE,CAMELLIA128,GCM,SHA256,,,,), /* ns */ + CS_ENTRY(0xC08B, TLS,ECDHE,RSA,WITH,CAMELLIA,256,GCM,SHA384), + CS_ENTRY(0xC08B, ECDHE,CAMELLIA256,GCM,SHA384,,,,), /* ns */ + CS_ENTRY(0xC08C, TLS,ECDH,RSA,WITH,CAMELLIA,128,GCM,SHA256), + CS_ENTRY(0xC08C, ECDH,CAMELLIA128,GCM,SHA256,,,,), /* ns */ + CS_ENTRY(0xC08D, TLS,ECDH,RSA,WITH,CAMELLIA,256,GCM,SHA384), + CS_ENTRY(0xC08D, ECDH,CAMELLIA256,GCM,SHA384,,,,), /* ns */ + CS_ENTRY(0xC08E, TLS,PSK,WITH,CAMELLIA,128,GCM,SHA256,), + CS_ENTRY(0xC08E, PSK,CAMELLIA128,GCM,SHA256,,,,), /* ns */ + CS_ENTRY(0xC08F, TLS,PSK,WITH,CAMELLIA,256,GCM,SHA384,), + CS_ENTRY(0xC08F, PSK,CAMELLIA256,GCM,SHA384,,,,), /* ns */ + CS_ENTRY(0xC090, TLS,DHE,PSK,WITH,CAMELLIA,128,GCM,SHA256), + CS_ENTRY(0xC090, DHE,PSK,CAMELLIA128,GCM,SHA256,,,), /* ns */ + CS_ENTRY(0xC091, TLS,DHE,PSK,WITH,CAMELLIA,256,GCM,SHA384), + CS_ENTRY(0xC091, DHE,PSK,CAMELLIA256,GCM,SHA384,,,), /* ns */ + CS_ENTRY(0xC092, TLS,RSA,PSK,WITH,CAMELLIA,128,GCM,SHA256), + CS_ENTRY(0xC092, RSA,PSK,CAMELLIA128,GCM,SHA256,,,), /* ns */ + CS_ENTRY(0xC093, TLS,RSA,PSK,WITH,CAMELLIA,256,GCM,SHA384), + CS_ENTRY(0xC093, RSA,PSK,CAMELLIA256,GCM,SHA384,,,), /* ns */ + CS_ENTRY(0xC094, TLS,PSK,WITH,CAMELLIA,128,CBC,SHA256,), + CS_ENTRY(0xC094, PSK,CAMELLIA128,SHA256,,,,,), + CS_ENTRY(0xC095, TLS,PSK,WITH,CAMELLIA,256,CBC,SHA384,), + CS_ENTRY(0xC095, PSK,CAMELLIA256,SHA384,,,,,), + CS_ENTRY(0xC096, TLS,DHE,PSK,WITH,CAMELLIA,128,CBC,SHA256), + CS_ENTRY(0xC096, DHE,PSK,CAMELLIA128,SHA256,,,,), + CS_ENTRY(0xC097, TLS,DHE,PSK,WITH,CAMELLIA,256,CBC,SHA384), + CS_ENTRY(0xC097, DHE,PSK,CAMELLIA256,SHA384,,,,), + CS_ENTRY(0xC098, TLS,RSA,PSK,WITH,CAMELLIA,128,CBC,SHA256), + CS_ENTRY(0xC098, RSA,PSK,CAMELLIA128,SHA256,,,,), + CS_ENTRY(0xC099, TLS,RSA,PSK,WITH,CAMELLIA,256,CBC,SHA384), + CS_ENTRY(0xC099, RSA,PSK,CAMELLIA256,SHA384,,,,), + CS_ENTRY(0xC09A, TLS,ECDHE,PSK,WITH,CAMELLIA,128,CBC,SHA256), + CS_ENTRY(0xC09A, ECDHE,PSK,CAMELLIA128,SHA256,,,,), + CS_ENTRY(0xC09B, TLS,ECDHE,PSK,WITH,CAMELLIA,256,CBC,SHA384), + CS_ENTRY(0xC09B, ECDHE,PSK,CAMELLIA256,SHA384,,,,), + CS_ENTRY(0xC09E, TLS,DHE,RSA,WITH,AES,128,CCM,), + CS_ENTRY(0xC09E, DHE,RSA,AES128,CCM,,,,), + CS_ENTRY(0xC09F, TLS,DHE,RSA,WITH,AES,256,CCM,), + CS_ENTRY(0xC09F, DHE,RSA,AES256,CCM,,,,), + CS_ENTRY(0xC0A2, TLS,DHE,RSA,WITH,AES,128,CCM,8), + CS_ENTRY(0xC0A2, DHE,RSA,AES128,CCM8,,,,), + CS_ENTRY(0xC0A3, TLS,DHE,RSA,WITH,AES,256,CCM,8), + CS_ENTRY(0xC0A3, DHE,RSA,AES256,CCM8,,,,), + CS_ENTRY(0xC0A4, TLS,PSK,WITH,AES,128,CCM,,), + CS_ENTRY(0xC0A4, PSK,AES128,CCM,,,,,), + CS_ENTRY(0xC0A5, TLS,PSK,WITH,AES,256,CCM,,), + CS_ENTRY(0xC0A5, PSK,AES256,CCM,,,,,), + CS_ENTRY(0xC0A6, TLS,DHE,PSK,WITH,AES,128,CCM,), + CS_ENTRY(0xC0A6, DHE,PSK,AES128,CCM,,,,), + CS_ENTRY(0xC0A7, TLS,DHE,PSK,WITH,AES,256,CCM,), + CS_ENTRY(0xC0A7, DHE,PSK,AES256,CCM,,,,), + CS_ENTRY(0xC0A8, TLS,PSK,WITH,AES,128,CCM,8,), + CS_ENTRY(0xC0A8, PSK,AES128,CCM8,,,,,), + CS_ENTRY(0xC0A9, TLS,PSK,WITH,AES,256,CCM,8,), + CS_ENTRY(0xC0A9, PSK,AES256,CCM8,,,,,), + CS_ENTRY(0xC0AA, TLS,PSK,DHE,WITH,AES,128,CCM,8), + CS_ENTRY(0xC0AA, DHE,PSK,AES128,CCM8,,,,), + CS_ENTRY(0xC0AB, TLS,PSK,DHE,WITH,AES,256,CCM,8), + CS_ENTRY(0xC0AB, DHE,PSK,AES256,CCM8,,,,), + CS_ENTRY(0xCCAA, TLS,DHE,RSA,WITH,CHACHA20,POLY1305,SHA256,), + CS_ENTRY(0xCCAA, DHE,RSA,CHACHA20,POLY1305,,,,), + CS_ENTRY(0xCCAC, TLS,ECDHE,PSK,WITH,CHACHA20,POLY1305,SHA256,), + CS_ENTRY(0xCCAC, ECDHE,PSK,CHACHA20,POLY1305,,,,), + CS_ENTRY(0xCCAD, TLS,DHE,PSK,WITH,CHACHA20,POLY1305,SHA256,), + CS_ENTRY(0xCCAD, DHE,PSK,CHACHA20,POLY1305,,,,), + CS_ENTRY(0xCCAE, TLS,RSA,PSK,WITH,CHACHA20,POLY1305,SHA256,), + CS_ENTRY(0xCCAE, RSA,PSK,CHACHA20,POLY1305,,,,), +}; +#define CS_LIST_LEN (sizeof(cs_list) / sizeof(cs_list[0])) + +static int cs_str_to_zip(const char *cs_str, size_t cs_len, + uint8_t zip[6]) +{ + uint8_t indexes[8] = {0}; + const char *entry, *cur; + const char *nxt = cs_str; + const char *end = cs_str + cs_len; + char separator = '-'; + int idx, i = 0; + size_t len; + + /* split the cipher string by '-' or '_' */ + if(strncasecompare(cs_str, "TLS", 3)) + separator = '_'; + + do { + if(i == 8) + return -1; + + /* determine the length of the part */ + cur = nxt; + for(; nxt < end && *nxt != '\0' && *nxt != separator; nxt++); + len = nxt - cur; + + /* lookup index for the part (skip empty string at 0) */ + for(idx = 1, entry = cs_txt + 1; idx < CS_TXT_LEN; idx++) { + size_t elen = strlen(entry); + if(elen == len && strncasecompare(entry, cur, len)) + break; + entry += elen + 1; + } + if(idx == CS_TXT_LEN) + return -1; + + indexes[i++] = (uint8_t) idx; + } while(nxt < end && *(nxt++) != '\0'); + + /* zip the 8 indexes into 48 bits */ + zip[0] = (uint8_t) (indexes[0] << 2 | (indexes[1] & 0x3F) >> 4); + zip[1] = (uint8_t) (indexes[1] << 4 | (indexes[2] & 0x3F) >> 2); + zip[2] = (uint8_t) (indexes[2] << 6 | (indexes[3] & 0x3F)); + zip[3] = (uint8_t) (indexes[4] << 2 | (indexes[5] & 0x3F) >> 4); + zip[4] = (uint8_t) (indexes[5] << 4 | (indexes[6] & 0x3F) >> 2); + zip[5] = (uint8_t) (indexes[6] << 6 | (indexes[7] & 0x3F)); + + return 0; +} + +static int cs_zip_to_str(const uint8_t zip[6], + char *buf, size_t buf_size) +{ + uint8_t indexes[8] = {0}; + const char *entry; + char separator = '-'; + int idx, i, r; + size_t len = 0; + + /* unzip the 8 indexes */ + indexes[0] = zip[0] >> 2; + indexes[1] = ((zip[0] << 4) & 0x3F) | zip[1] >> 4; + indexes[2] = ((zip[1] << 2) & 0x3F) | zip[2] >> 6; + indexes[3] = ((zip[2] << 0) & 0x3F); + indexes[4] = zip[3] >> 2; + indexes[5] = ((zip[3] << 4) & 0x3F) | zip[4] >> 4; + indexes[6] = ((zip[4] << 2) & 0x3F) | zip[5] >> 6; + indexes[7] = ((zip[5] << 0) & 0x3F); + + if(indexes[0] == CS_TXT_IDX_TLS) + separator = '_'; + + for(i = 0; i < 8 && indexes[i] != 0 && len < buf_size; i++) { + if(indexes[i] >= CS_TXT_LEN) + return -1; + + /* lookup the part string for the index (skip empty string at 0) */ + for(idx = 1, entry = cs_txt + 1; idx < indexes[i]; idx++) { + size_t elen = strlen(entry); + entry += elen + 1; + } + + /* append the part string to the buffer */ + if(i > 0) + r = msnprintf(&buf[len], buf_size - len, "%c%s", separator, entry); + else + r = msnprintf(&buf[len], buf_size - len, "%s", entry); + + if(r < 0) + return -1; + len += r; + } + + return 0; +} + +uint16_t Curl_cipher_suite_lookup_id(const char *cs_str, size_t cs_len) +{ + size_t i; + uint8_t zip[6]; + + if(cs_len > 0 && cs_str_to_zip(cs_str, cs_len, zip) == 0) { + for(i = 0; i < CS_LIST_LEN; i++) { + if(memcmp(cs_list[i].zip, zip, sizeof(zip)) == 0) + return cs_list[i].id; + } + } + + return 0; +} + +static bool cs_is_separator(char c) +{ + switch(c) { + case ' ': + case '\t': + case ':': + case ',': + case ';': + return true; + default:; + } + return false; +} + +uint16_t Curl_cipher_suite_walk_str(const char **str, const char **end) +{ + /* move string pointer to first non-separator or end of string */ + for(; cs_is_separator(*str[0]); (*str)++); + + /* move end pointer to next separator or end of string */ + for(*end = *str; *end[0] != '\0' && !cs_is_separator(*end[0]); (*end)++); + + return Curl_cipher_suite_lookup_id(*str, *end - *str); +} + +int Curl_cipher_suite_get_str(uint16_t id, char *buf, size_t buf_size, + bool prefer_rfc) +{ + size_t i, j = CS_LIST_LEN; + int r = -1; + + for(i = 0; i < CS_LIST_LEN; i++) { + if(cs_list[i].id != id) + continue; + if((cs_list[i].zip[0] >> 2 != CS_TXT_IDX_TLS) == !prefer_rfc) { + j = i; + break; + } + if(j == CS_LIST_LEN) + j = i; + } + + if(j < CS_LIST_LEN) + r = cs_zip_to_str(cs_list[j].zip, buf, buf_size); + + if(r < 0) + msnprintf(buf, buf_size, "TLS_UNKNOWN_0x%04x", id); + + return r; +} + +#endif /* defined(USE_MBEDTLS) */ diff --git a/lib/vtls/cipher_suite.h b/lib/vtls/cipher_suite.h new file mode 100644 index 0000000000..87fa259cd6 --- /dev/null +++ b/lib/vtls/cipher_suite.h @@ -0,0 +1,46 @@ +#ifndef HEADER_CURL_CIPHER_SUITE_H +#define HEADER_CURL_CIPHER_SUITE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) Jan Venekamp, + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(USE_MBEDTLS) +#include + +/* Lookup IANA id for cipher suite string, returns 0 if not recognized */ +uint16_t Curl_cipher_suite_lookup_id(const char *cs_str, size_t cs_len); + +/* Walk over cipher suite string, update str and end pointers to next + cipher suite in string, returns IANA id of that suite if recognized */ +uint16_t Curl_cipher_suite_walk_str(const char **str, const char **end); + +/* Copy openssl or RFC name for cipher suite in supplied buffer. + Caller is responsible to supply sufficiently large buffer (size + of 64 should suffice), excess bytes are silently truncated. */ +int Curl_cipher_suite_get_str(uint16_t id, char *buf, size_t buf_size, + bool prefer_rfc); + +#endif /* defined(USE_MBEDTLS) */ +#endif /* HEADER_CURL_CIPHER_SUITE_H */ diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index a70a6b6fe0..02c9299449 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -67,6 +67,8 @@ #pragma GCC diagnostic pop #endif +#include "cipher_suite.h" +#include "strcase.h" #include "urldata.h" #include "sendf.h" #include "inet_pton.h" @@ -107,6 +109,7 @@ struct mbed_ssl_backend_data { #ifdef HAS_ALPN const char *protocols[3]; #endif + int *ciphersuites; }; /* apply threading? */ @@ -358,6 +361,99 @@ set_ssl_version_min_max(struct Curl_cfilter *cf, struct Curl_easy *data) return result; } +/* TLS_ECJPAKE_WITH_AES_128_CCM_8 (0xC0FF) is marked experimental + in mbedTLS. The number is not reserved by IANA nor is the + cipher suite present in other SSL implementations. Provide + provisional support for specifying the cipher suite here. */ +#ifdef MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 +static int +mbed_cipher_suite_get_str(uint16_t id, char *buf, size_t buf_size, + bool prefer_rfc) +{ + if(id == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8) + msnprintf(buf, buf_size, "%s", "TLS_ECJPAKE_WITH_AES_128_CCM_8"); + else + return Curl_cipher_suite_get_str(id, buf, buf_size, prefer_rfc); + return 0; +} + +static uint16_t +mbed_cipher_suite_walk_str(const char **str, const char **end) +{ + uint16_t id = Curl_cipher_suite_walk_str(str, end); + size_t len = *end - *str; + + if(!id) { + if(strncasecompare("TLS_ECJPAKE_WITH_AES_128_CCM_8", *str, len)) + id = MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8; + } + return id; +} +#else +#define mbed_cipher_suite_get_str Curl_cipher_suite_get_str +#define mbed_cipher_suite_walk_str Curl_cipher_suite_walk_str +#endif + +static CURLcode +mbed_set_selected_ciphers(struct Curl_easy *data, + struct mbed_ssl_backend_data *backend, + const char *ciphers) +{ + const int *supported; + int *selected; + size_t supported_len, count = 0, i; + const char *ptr, *end; + + supported = mbedtls_ssl_list_ciphersuites(); + for(i = 0; supported[i] != 0; i++); + supported_len = i; + + selected = malloc(sizeof(int) * (supported_len + 1)); + if(!selected) + return CURLE_OUT_OF_MEMORY; + + for(ptr = ciphers; ptr[0] != '\0' && count < supported_len; ptr = end) { + uint16_t id = mbed_cipher_suite_walk_str(&ptr, &end); + + /* Check if cipher is supported */ + if(id) { + for(i = 0; i < supported_len && supported[i] != id; i++); + if(i == supported_len) + id = 0; + } + if(!id) { + if(ptr[0] != '\0') + infof(data, "mbedTLS: unknown cipher in list: \"%.*s\"", + (int) (end - ptr), ptr); + continue; + } + + /* No duplicates allowed (so selected cannot overflow) */ + for(i = 0; i < count && selected[i] != id; i++); + if(i < count) { + infof(data, "mbedTLS: duplicate cipher in list: \"%.*s\"", + (int) (end - ptr), ptr); + continue; + } + + selected[count++] = id; + } + + selected[count] = 0; + + if(count == 0) { + free(selected); + failf(data, "mbedTLS: no supported cipher in list"); + return CURLE_SSL_CIPHER; + } + + /* mbedtls_ssl_conf_ciphersuites(): The ciphersuites array is not copied. + It must remain valid for the lifetime of the SSL configuration */ + backend->ciphersuites = selected; + mbedtls_ssl_conf_ciphersuites(&backend->config, backend->ciphersuites); + return CURLE_OK; +} + static CURLcode mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) { @@ -652,8 +748,18 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) mbedtls_bio_cf_read, NULL /* rev_timeout() */); - mbedtls_ssl_conf_ciphersuites(&backend->config, - mbedtls_ssl_list_ciphersuites()); + if(conn_config->cipher_list) { + ret = mbed_set_selected_ciphers(data, backend, conn_config->cipher_list); + if(ret) { + failf(data, "mbedTLS: failed to set cipher suites"); + return ret; + } + } + else { + mbedtls_ssl_conf_ciphersuites(&backend->config, + mbedtls_ssl_list_ciphersuites()); + } + #if defined(MBEDTLS_SSL_RENEGOTIATION) mbedtls_ssl_conf_renegotiation(&backend->config, @@ -760,6 +866,8 @@ mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) (struct mbed_ssl_backend_data *)connssl->backend; struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); const mbedtls_x509_crt *peercert; + char cipher_str[64]; + uint16_t cipher_id; #ifndef CURL_DISABLE_PROXY const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf)? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]: @@ -788,8 +896,10 @@ mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) return CURLE_SSL_CONNECT_ERROR; } - infof(data, "mbedTLS: Handshake complete, cipher is %s", - mbedtls_ssl_get_ciphersuite(&backend->ssl)); + cipher_id = (uint16_t) + mbedtls_ssl_get_ciphersuite_id_from_ssl(&backend->ssl); + mbed_cipher_suite_get_str(cipher_id, cipher_str, sizeof(cipher_str), true); + infof(data, "mbedTLS: Handshake complete, cipher is %s", cipher_str); ret = mbedtls_ssl_get_verify_result(&backend->ssl); @@ -1027,6 +1137,7 @@ static void mbedtls_close(struct Curl_cfilter *cf, struct Curl_easy *data) #ifdef MBEDTLS_X509_CRL_PARSE_C mbedtls_x509_crl_free(&backend->crl); #endif + Curl_safefree(backend->ciphersuites); mbedtls_ssl_config_free(&backend->config); mbedtls_ssl_free(&backend->ssl); mbedtls_ctr_drbg_free(&backend->ctr_drbg); diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index b891c1154c..1664ee0f71 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -261,4 +261,4 @@ test3024 test3025 test3026 test3027 test3028 test3029 test3030 \ \ test3100 test3101 test3102 test3103 \ test3200 \ -test3201 test3202 test3203 test3204 +test3201 test3202 test3203 test3204 test3205 diff --git a/tests/data/test3205 b/tests/data/test3205 new file mode 100644 index 0000000000..3a26cd6d89 --- /dev/null +++ b/tests/data/test3205 @@ -0,0 +1,22 @@ + + + +unittest +cipher_suite + + + +# +# Client-side + + +none + + +unittest + + +cipher suite name lookup + + + diff --git a/tests/unit/Makefile.inc b/tests/unit/Makefile.inc index 3959f6027b..677850cec3 100644 --- a/tests/unit/Makefile.inc +++ b/tests/unit/Makefile.inc @@ -39,7 +39,8 @@ UNITPROGS = unit1300 unit1302 unit1303 unit1304 unit1305 unit1307 \ unit1650 unit1651 unit1652 unit1653 unit1654 unit1655 \ unit1660 unit1661 \ unit2600 unit2601 unit2602 unit2603 \ - unit3200 + unit3200 \ + unit3205 unit1300_SOURCES = unit1300.c $(UNITFILES) @@ -134,3 +135,5 @@ unit2602_SOURCES = unit2602.c $(UNITFILES) unit2603_SOURCES = unit2603.c $(UNITFILES) unit3200_SOURCES = unit3200.c $(UNITFILES) + +unit3205_SOURCES = unit3205.c $(UNITFILES) diff --git a/tests/unit/unit3205.c b/tests/unit/unit3205.c new file mode 100644 index 0000000000..c88e829648 --- /dev/null +++ b/tests/unit/unit3205.c @@ -0,0 +1,581 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) Jan Venekamp, + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "curlcheck.h" + +#include "vtls/cipher_suite.h" + +static CURLcode unit_setup(void) +{ + return CURLE_OK; +} + +static void unit_stop(void) +{ +} + +#if defined(USE_MBEDTLS) + +struct test_cs_entry { + uint16_t id; + const char *rfc; + const char *openssl; +}; +static const struct test_cs_entry test_cs_list[] = { + { 0x002F, "TLS_RSA_WITH_AES_128_CBC_SHA", + "AES128-SHA" }, + { 0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA", + "AES256-SHA" }, + { 0x003C, "TLS_RSA_WITH_AES_128_CBC_SHA256", + "AES128-SHA256" }, + { 0x003D, "TLS_RSA_WITH_AES_256_CBC_SHA256", + "AES256-SHA256" }, + { 0x009C, "TLS_RSA_WITH_AES_128_GCM_SHA256", + "AES128-GCM-SHA256" }, + { 0x009D, "TLS_RSA_WITH_AES_256_GCM_SHA384", + "AES256-GCM-SHA384" }, + { 0xC004, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", + "ECDH-ECDSA-AES128-SHA" }, + { 0xC005, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", + "ECDH-ECDSA-AES256-SHA" }, + { 0xC009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "ECDHE-ECDSA-AES128-SHA" }, + { 0xC00A, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "ECDHE-ECDSA-AES256-SHA" }, + { 0xC00E, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", + "ECDH-RSA-AES128-SHA" }, + { 0xC00F, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", + "ECDH-RSA-AES256-SHA" }, + { 0xC013, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "ECDHE-RSA-AES128-SHA" }, + { 0xC014, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "ECDHE-RSA-AES256-SHA" }, + { 0xC023, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", + "ECDHE-ECDSA-AES128-SHA256" }, + { 0xC024, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", + "ECDHE-ECDSA-AES256-SHA384" }, + { 0xC025, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", + "ECDH-ECDSA-AES128-SHA256" }, + { 0xC026, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", + "ECDH-ECDSA-AES256-SHA384" }, + { 0xC027, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + "ECDHE-RSA-AES128-SHA256" }, + { 0xC028, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", + "ECDHE-RSA-AES256-SHA384" }, + { 0xC029, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", + "ECDH-RSA-AES128-SHA256" }, + { 0xC02A, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", + "ECDH-RSA-AES256-SHA384" }, + { 0xC02B, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "ECDHE-ECDSA-AES128-GCM-SHA256" }, + { 0xC02C, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "ECDHE-ECDSA-AES256-GCM-SHA384" }, + { 0xC02D, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", + "ECDH-ECDSA-AES128-GCM-SHA256" }, + { 0xC02E, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", + "ECDH-ECDSA-AES256-GCM-SHA384" }, + { 0xC02F, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "ECDHE-RSA-AES128-GCM-SHA256" }, + { 0xC030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "ECDHE-RSA-AES256-GCM-SHA384" }, + { 0xC031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", + "ECDH-RSA-AES128-GCM-SHA256" }, + { 0xC032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", + "ECDH-RSA-AES256-GCM-SHA384" }, + { 0xCCA8, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "ECDHE-RSA-CHACHA20-POLY1305" }, + { 0xCCA9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + "ECDHE-ECDSA-CHACHA20-POLY1305" }, + + { 0x0001, "TLS_RSA_WITH_NULL_MD5", + "NULL-MD5" }, + { 0x0002, "TLS_RSA_WITH_NULL_SHA", + "NULL-SHA" }, + { 0x002C, "TLS_PSK_WITH_NULL_SHA", + "PSK-NULL-SHA" }, + { 0x002D, "TLS_DHE_PSK_WITH_NULL_SHA", + "DHE-PSK-NULL-SHA" }, + { 0x002E, "TLS_RSA_PSK_WITH_NULL_SHA", + "RSA-PSK-NULL-SHA" }, + { 0x0033, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", + "DHE-RSA-AES128-SHA" }, + { 0x0039, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", + "DHE-RSA-AES256-SHA" }, + { 0x003B, "TLS_RSA_WITH_NULL_SHA256", + "NULL-SHA256" }, + { 0x0067, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", + "DHE-RSA-AES128-SHA256" }, + { 0x006B, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", + "DHE-RSA-AES256-SHA256" }, + { 0x008C, "TLS_PSK_WITH_AES_128_CBC_SHA", + "PSK-AES128-CBC-SHA" }, + { 0x008D, "TLS_PSK_WITH_AES_256_CBC_SHA", + "PSK-AES256-CBC-SHA" }, + { 0x0090, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA", + "DHE-PSK-AES128-CBC-SHA" }, + { 0x0091, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA", + "DHE-PSK-AES256-CBC-SHA" }, + { 0x0094, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA", + "RSA-PSK-AES128-CBC-SHA" }, + { 0x0095, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA", + "RSA-PSK-AES256-CBC-SHA" }, + { 0x009E, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", + "DHE-RSA-AES128-GCM-SHA256" }, + { 0x009F, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", + "DHE-RSA-AES256-GCM-SHA384" }, + { 0x00A8, "TLS_PSK_WITH_AES_128_GCM_SHA256", + "PSK-AES128-GCM-SHA256" }, + { 0x00A9, "TLS_PSK_WITH_AES_256_GCM_SHA384", + "PSK-AES256-GCM-SHA384" }, + { 0x00AA, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", + "DHE-PSK-AES128-GCM-SHA256" }, + { 0x00AB, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", + "DHE-PSK-AES256-GCM-SHA384" }, + { 0x00AC, "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", + "RSA-PSK-AES128-GCM-SHA256" }, + { 0x00AD, "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", + "RSA-PSK-AES256-GCM-SHA384" }, + { 0x00AE, "TLS_PSK_WITH_AES_128_CBC_SHA256", + "PSK-AES128-CBC-SHA256" }, + { 0x00AF, "TLS_PSK_WITH_AES_256_CBC_SHA384", + "PSK-AES256-CBC-SHA384" }, + { 0x00B0, "TLS_PSK_WITH_NULL_SHA256", + "PSK-NULL-SHA256" }, + { 0x00B1, "TLS_PSK_WITH_NULL_SHA384", + "PSK-NULL-SHA384" }, + { 0x00B2, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", + "DHE-PSK-AES128-CBC-SHA256" }, + { 0x00B3, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", + "DHE-PSK-AES256-CBC-SHA384" }, + { 0x00B4, "TLS_DHE_PSK_WITH_NULL_SHA256", + "DHE-PSK-NULL-SHA256" }, + { 0x00B5, "TLS_DHE_PSK_WITH_NULL_SHA384", + "DHE-PSK-NULL-SHA384" }, + { 0x00B6, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", + "RSA-PSK-AES128-CBC-SHA256" }, + { 0x00B7, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", + "RSA-PSK-AES256-CBC-SHA384" }, + { 0x00B8, "TLS_RSA_PSK_WITH_NULL_SHA256", + "RSA-PSK-NULL-SHA256" }, + { 0x00B9, "TLS_RSA_PSK_WITH_NULL_SHA384", + "RSA-PSK-NULL-SHA384" }, + { 0x1301, "TLS_AES_128_GCM_SHA256", + NULL }, + { 0x1302, "TLS_AES_256_GCM_SHA384", + NULL }, + { 0x1303, "TLS_CHACHA20_POLY1305_SHA256", + NULL }, + { 0x1304, "TLS_AES_128_CCM_SHA256", + NULL }, + { 0x1305, "TLS_AES_128_CCM_8_SHA256", + NULL }, + { 0xC001, "TLS_ECDH_ECDSA_WITH_NULL_SHA", + "ECDH-ECDSA-NULL-SHA" }, + { 0xC006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA", + "ECDHE-ECDSA-NULL-SHA" }, + { 0xC00B, "TLS_ECDH_RSA_WITH_NULL_SHA", + "ECDH-RSA-NULL-SHA" }, + { 0xC010, "TLS_ECDHE_RSA_WITH_NULL_SHA", + "ECDHE-RSA-NULL-SHA" }, + { 0xC035, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", + "ECDHE-PSK-AES128-CBC-SHA" }, + { 0xC036, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", + "ECDHE-PSK-AES256-CBC-SHA" }, + { 0xCCAB, "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256", + "PSK-CHACHA20-POLY1305" }, + + { 0xC09C, "TLS_RSA_WITH_AES_128_CCM", + "AES128-CCM" }, + { 0xC09D, "TLS_RSA_WITH_AES_256_CCM", + "AES256-CCM" }, + { 0xC0A0, "TLS_RSA_WITH_AES_128_CCM_8", + "AES128-CCM8" }, + { 0xC0A1, "TLS_RSA_WITH_AES_256_CCM_8", + "AES256-CCM8" }, + { 0xC0AC, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM", + "ECDHE-ECDSA-AES128-CCM" }, + { 0xC0AD, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM", + "ECDHE-ECDSA-AES256-CCM" }, + { 0xC0AE, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8", + "ECDHE-ECDSA-AES128-CCM8" }, + { 0xC0AF, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8", + "ECDHE-ECDSA-AES256-CCM8" }, + + /* entries marked ns are non-"standard", they are not in openssl */ + { 0x0041, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", + "CAMELLIA128-SHA" }, + { 0x0045, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", + "DHE-RSA-CAMELLIA128-SHA" }, + { 0x0084, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", + "CAMELLIA256-SHA" }, + { 0x0088, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", + "DHE-RSA-CAMELLIA256-SHA" }, + { 0x00BA, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", + "CAMELLIA128-SHA256" }, + { 0x00BE, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", + "DHE-RSA-CAMELLIA128-SHA256" }, + { 0x00C0, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256", + "CAMELLIA256-SHA256" }, + { 0x00C4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", + "DHE-RSA-CAMELLIA256-SHA256" }, + { 0xC037, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", + "ECDHE-PSK-AES128-CBC-SHA256" }, + { 0xC038, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", + "ECDHE-PSK-AES256-CBC-SHA384" }, + { 0xC039, "TLS_ECDHE_PSK_WITH_NULL_SHA", + "ECDHE-PSK-NULL-SHA" }, + { 0xC03A, "TLS_ECDHE_PSK_WITH_NULL_SHA256", + "ECDHE-PSK-NULL-SHA256" }, + { 0xC03B, "TLS_ECDHE_PSK_WITH_NULL_SHA384", + "ECDHE-PSK-NULL-SHA384" }, + { 0xC03C, "TLS_RSA_WITH_ARIA_128_CBC_SHA256", + "ARIA128-SHA256" /* ns */ }, + { 0xC03D, "TLS_RSA_WITH_ARIA_256_CBC_SHA384", + "ARIA256-SHA384" /* ns */ }, + { 0xC044, "TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256", + "DHE-RSA-ARIA128-SHA256" /* ns */ }, + { 0xC045, "TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384", + "DHE-RSA-ARIA256-SHA384" /* ns */ }, + { 0xC048, "TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256", + "ECDHE-ECDSA-ARIA128-SHA256" /* ns */ }, + { 0xC049, "TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384", + "ECDHE-ECDSA-ARIA256-SHA384" /* ns */ }, + { 0xC04A, "TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256", + "ECDH-ECDSA-ARIA128-SHA256" /* ns */ }, + { 0xC04B, "TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384", + "ECDH-ECDSA-ARIA256-SHA384" /* ns */ }, + { 0xC04C, "TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256", + "ECDHE-ARIA128-SHA256" /* ns */ }, + { 0xC04D, "TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384", + "ECDHE-ARIA256-SHA384" /* ns */ }, + { 0xC04E, "TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256", + "ECDH-ARIA128-SHA256" /* ns */ }, + { 0xC04F, "TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384", + "ECDH-ARIA256-SHA384" /* ns */ }, + { 0xC050, "TLS_RSA_WITH_ARIA_128_GCM_SHA256", + "ARIA128-GCM-SHA256" }, + { 0xC051, "TLS_RSA_WITH_ARIA_256_GCM_SHA384", + "ARIA256-GCM-SHA384" }, + { 0xC052, "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256", + "DHE-RSA-ARIA128-GCM-SHA256" }, + { 0xC053, "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384", + "DHE-RSA-ARIA256-GCM-SHA384" }, + { 0xC05C, "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256", + "ECDHE-ECDSA-ARIA128-GCM-SHA256" }, + { 0xC05D, "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384", + "ECDHE-ECDSA-ARIA256-GCM-SHA384" }, + { 0xC05E, "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256", + "ECDH-ECDSA-ARIA128-GCM-SHA256" /* ns */ }, + { 0xC05F, "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384", + "ECDH-ECDSA-ARIA256-GCM-SHA384" /* ns */ }, + { 0xC060, "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256", + "ECDHE-ARIA128-GCM-SHA256" }, + { 0xC061, "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384", + "ECDHE-ARIA256-GCM-SHA384" }, + { 0xC062, "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256", + "ECDH-ARIA128-GCM-SHA256" /* ns */ }, + { 0xC063, "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384", + "ECDH-ARIA256-GCM-SHA384" /* ns */ }, + { 0xC064, "TLS_PSK_WITH_ARIA_128_CBC_SHA256", + "PSK-ARIA128-SHA256" /* ns */ }, + { 0xC065, "TLS_PSK_WITH_ARIA_256_CBC_SHA384", + "PSK-ARIA256-SHA384" /* ns */ }, + { 0xC066, "TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256", + "DHE-PSK-ARIA128-SHA256" /* ns */ }, + { 0xC067, "TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384", + "DHE-PSK-ARIA256-SHA384" /* ns */ }, + { 0xC068, "TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256", + "RSA-PSK-ARIA128-SHA256" /* ns */ }, + { 0xC069, "TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384", + "RSA-PSK-ARIA256-SHA384" /* ns */ }, + { 0xC06A, "TLS_PSK_WITH_ARIA_128_GCM_SHA256", + "PSK-ARIA128-GCM-SHA256" }, + { 0xC06B, "TLS_PSK_WITH_ARIA_256_GCM_SHA384", + "PSK-ARIA256-GCM-SHA384" }, + { 0xC06C, "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256", + "DHE-PSK-ARIA128-GCM-SHA256" }, + { 0xC06D, "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384", + "DHE-PSK-ARIA256-GCM-SHA384" }, + { 0xC06E, "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256", + "RSA-PSK-ARIA128-GCM-SHA256" }, + { 0xC06F, "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384", + "RSA-PSK-ARIA256-GCM-SHA384" }, + { 0xC070, "TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256", + "ECDHE-PSK-ARIA128-SHA256" /* ns */ }, + { 0xC071, "TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384", + "ECDHE-PSK-ARIA256-SHA384" /* ns */ }, + { 0xC072, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", + "ECDHE-ECDSA-CAMELLIA128-SHA256" }, + { 0xC073, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", + "ECDHE-ECDSA-CAMELLIA256-SHA384" }, + { 0xC074, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", + "ECDH-ECDSA-CAMELLIA128-SHA256" /* ns */ }, + { 0xC075, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", + "ECDH-ECDSA-CAMELLIA256-SHA384" /* ns */ }, + { 0xC076, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", + "ECDHE-RSA-CAMELLIA128-SHA256" }, + { 0xC077, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384", + "ECDHE-RSA-CAMELLIA256-SHA384" }, + { 0xC078, "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256", + "ECDH-CAMELLIA128-SHA256" /* ns */ }, + { 0xC079, "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384", + "ECDH-CAMELLIA256-SHA384" /* ns */ }, + { 0xC07A, "TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256", + "CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC07B, "TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384", + "CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC07C, "TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", + "DHE-RSA-CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC07D, "TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", + "DHE-RSA-CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC086, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", + "ECDHE-ECDSA-CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC087, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", + "ECDHE-ECDSA-CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC088, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", + "ECDH-ECDSA-CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC089, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", + "ECDH-ECDSA-CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC08A, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", + "ECDHE-CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC08B, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", + "ECDHE-CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC08C, "TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256", + "ECDH-CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC08D, "TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384", + "ECDH-CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC08E, "TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256", + "PSK-CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC08F, "TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384", + "PSK-CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC090, "TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256", + "DHE-PSK-CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC091, "TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384", + "DHE-PSK-CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC092, "TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256", + "RSA-PSK-CAMELLIA128-GCM-SHA256" /* ns */ }, + { 0xC093, "TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384", + "RSA-PSK-CAMELLIA256-GCM-SHA384" /* ns */ }, + { 0xC094, "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256", + "PSK-CAMELLIA128-SHA256" }, + { 0xC095, "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384", + "PSK-CAMELLIA256-SHA384" }, + { 0xC096, "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", + "DHE-PSK-CAMELLIA128-SHA256" }, + { 0xC097, "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", + "DHE-PSK-CAMELLIA256-SHA384" }, + { 0xC098, "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256", + "RSA-PSK-CAMELLIA128-SHA256" }, + { 0xC099, "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384", + "RSA-PSK-CAMELLIA256-SHA384" }, + { 0xC09A, "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", + "ECDHE-PSK-CAMELLIA128-SHA256" }, + { 0xC09B, "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", + "ECDHE-PSK-CAMELLIA256-SHA384" }, + { 0xC09E, "TLS_DHE_RSA_WITH_AES_128_CCM", + "DHE-RSA-AES128-CCM" }, + { 0xC09F, "TLS_DHE_RSA_WITH_AES_256_CCM", + "DHE-RSA-AES256-CCM" }, + { 0xC0A2, "TLS_DHE_RSA_WITH_AES_128_CCM_8", + "DHE-RSA-AES128-CCM8" }, + { 0xC0A3, "TLS_DHE_RSA_WITH_AES_256_CCM_8", + "DHE-RSA-AES256-CCM8" }, + { 0xC0A4, "TLS_PSK_WITH_AES_128_CCM", + "PSK-AES128-CCM" }, + { 0xC0A5, "TLS_PSK_WITH_AES_256_CCM", + "PSK-AES256-CCM" }, + { 0xC0A6, "TLS_DHE_PSK_WITH_AES_128_CCM", + "DHE-PSK-AES128-CCM" }, + { 0xC0A7, "TLS_DHE_PSK_WITH_AES_256_CCM", + "DHE-PSK-AES256-CCM" }, + { 0xC0A8, "TLS_PSK_WITH_AES_128_CCM_8", + "PSK-AES128-CCM8" }, + { 0xC0A9, "TLS_PSK_WITH_AES_256_CCM_8", + "PSK-AES256-CCM8" }, + { 0xC0AA, "TLS_PSK_DHE_WITH_AES_128_CCM_8", + "DHE-PSK-AES128-CCM8" }, + { 0xC0AB, "TLS_PSK_DHE_WITH_AES_256_CCM_8", + "DHE-PSK-AES256-CCM8" }, + { 0xCCAA, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "DHE-RSA-CHACHA20-POLY1305" }, + { 0xCCAC, "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", + "ECDHE-PSK-CHACHA20-POLY1305" }, + { 0xCCAD, "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", + "DHE-PSK-CHACHA20-POLY1305" }, + { 0xCCAE, "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256", + "RSA-PSK-CHACHA20-POLY1305" }, +}; +#define TEST_CS_LIST_LEN (sizeof(test_cs_list) / sizeof(test_cs_list[0])) + +static const char *cs_test_string = + "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:" + "TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:" + "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:" + "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:" + "ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:" + "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:" + "ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:" + "ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:" + "ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:" + "DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:" + "AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:" + "DES-CBC3-SHA:" + ":: GIBBERISH ::" +; + +struct test_str_entry { + uint16_t id; + const char *str; +}; +static const struct test_str_entry test_str_list[] = { + { 0x1301, "TLS_AES_128_GCM_SHA256"}, + { 0x1302, "TLS_AES_256_GCM_SHA384"}, + { 0x1303, "TLS_CHACHA20_POLY1305_SHA256"}, + { 0xC02B, "ECDHE-ECDSA-AES128-GCM-SHA256"}, + { 0xC02F, "ECDHE-RSA-AES128-GCM-SHA256"}, + { 0xC02C, "ECDHE-ECDSA-AES256-GCM-SHA384"}, + { 0xC030, "ECDHE-RSA-AES256-GCM-SHA384"}, + { 0xCCA9, "ECDHE-ECDSA-CHACHA20-POLY1305"}, + { 0xCCA8, "ECDHE-RSA-CHACHA20-POLY1305"}, + { 0x009E, "DHE-RSA-AES128-GCM-SHA256"}, + { 0x009F, "DHE-RSA-AES256-GCM-SHA384"}, + { 0xCCAA, "DHE-RSA-CHACHA20-POLY1305"}, + { 0xC023, "ECDHE-ECDSA-AES128-SHA256" }, + { 0xC027, "ECDHE-RSA-AES128-SHA256" }, + { 0xC009, "ECDHE-ECDSA-AES128-SHA" }, + { 0xC013, "ECDHE-RSA-AES128-SHA" }, + { 0xC024, "ECDHE-ECDSA-AES256-SHA384" }, + { 0xC028, "ECDHE-RSA-AES256-SHA384" }, + { 0xC00A, "ECDHE-ECDSA-AES256-SHA" }, + { 0xC014, "ECDHE-RSA-AES256-SHA" }, + { 0x0067, "DHE-RSA-AES128-SHA256" }, + { 0x006B, "DHE-RSA-AES256-SHA256" }, + { 0x009C, "AES128-GCM-SHA256" }, + { 0x009D, "AES256-GCM-SHA384" }, + { 0x003C, "AES128-SHA256" }, + { 0x003D, "AES256-SHA256" }, + { 0x002F, "AES128-SHA" }, + { 0x0035, "AES256-SHA" }, + { 0x0000, "DES-CBC3-SHA" }, + { 0x0000, "GIBBERISH" }, + { 0x0000, "" }, +}; +#define TEST_STR_LIST_LEN (sizeof(test_str_list) / sizeof(test_str_list[0])) + +UNITTEST_START +{ + for(size_t i = 0; i < TEST_CS_LIST_LEN; i++) { + const struct test_cs_entry *test = &test_cs_list[i]; + const char *expect; + char buf[64] = ""; + uint16_t id; + + /* test Curl_cipher_suite_lookup_id() for rfc name */ + if(test->rfc) { + id = Curl_cipher_suite_lookup_id(test->rfc, strlen(test->rfc)); + if(id != test->id) { + fprintf(stderr, "Curl_cipher_suite_lookup_id FAILED for \"%s\", " + "result = 0x%04x, expected = 0x%04x\n", + test->rfc, id, test->id); + unitfail++; + } + } + + /* test Curl_cipher_suite_lookup_id() for openssl name */ + if(test->openssl) { + id = Curl_cipher_suite_lookup_id(test->openssl, strlen(test->openssl)); + if(id != test->id) { + fprintf(stderr, "Curl_cipher_suite_lookup_id FAILED for \"%s\", " + "result = 0x%04x, expected = 0x%04x\n", + test->openssl, id, test->id); + unitfail++; + } + } + + /* test Curl_cipher_suite_get_str() prefer rfc name */ + buf[0] = '\0'; + expect = test->rfc ? test->rfc : test->openssl; + + Curl_cipher_suite_get_str(test->id, buf, sizeof(buf), true); + + if(strcmp(buf, expect) != 0) { + fprintf(stderr, "Curl_cipher_suite_get_str FAILED for 0x%04x, " + "result = \"%s\", expected = \"%s\"\n", + test->id, buf, expect); + unitfail++; + } + + /* test Curl_cipher_suite_get_str() prefer openssl name */ + buf[0] = '\0'; + expect = test->openssl ? test->openssl : test->rfc; + + Curl_cipher_suite_get_str(test->id, buf, sizeof(buf), false); + + if(strcmp(buf, expect) != 0) { + fprintf(stderr, "Curl_cipher_suite_get_str FAILED for 0x%04x, " + "result = \"%s\", expected = \"%s\"\n", + test->id, buf, expect); + unitfail++; + } + } + + /* test Curl_cipher_suite_walk_str() */ + { + const char *ptr, *end = cs_test_string; + int i = 0; + uint16_t id; + size_t len; + + for(ptr = cs_test_string; ptr[0] != '\0'; ptr = end) { + const struct test_str_entry *test = &test_str_list[i]; + abort_if(i == TEST_STR_LIST_LEN, "should have been done"); + + id = Curl_cipher_suite_walk_str(&ptr, &end); + len = end - ptr; + + if(id != test->id) { + fprintf(stderr, "Curl_cipher_suite_walk_str FAILED for \"%s\" " + "unexpected cipher, " + "result = 0x%04x, expected = 0x%04x\n", + test->str, id, test->id); + unitfail++; + } + if(len > 64 || strncmp(ptr, test->str, len) != 0) { + fprintf(stderr, "Curl_cipher_suite_walk_str ABORT for \"%s\" " + "unexpected pointers\n", + test->str); + unitfail++; + goto unit_test_abort; + } + i++; + } + } +} +UNITTEST_STOP + +#else /* defined(USE_MBEDTLS) */ + +UNITTEST_START +UNITTEST_STOP + +#endif /* defined(USE_MBEDTLS) */