Fix end-point shared secret for DTLS/SCTP

When computing the end-point shared secret, don't take the
terminating NULL character into account.
Please note that this fix breaks interoperability with older
versions of OpenSSL, which are not fixed.

Fixes #7956

Reviewed-by: Kurt Roeckx <kurt@roeckx.be>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7957)
This commit is contained in:
Michael Tuexen 2018-12-26 12:44:53 +01:00 committed by Matt Caswell
parent a28e4890ee
commit 09d62b336d
15 changed files with 330 additions and 7 deletions

View file

@ -9,6 +9,13 @@
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
*) Fix a bug in the computation of the endpoint-pair shared secret used
by DTLS over SCTP. This breaks interoperability with older versions
of OpenSSL like OpenSSL 1.1.0 and OpenSSL 1.0.2. There is a runtime
switch SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG (off by default) enabling
interoperability with such broken implementations. However, enabling
this switch breaks interoperability with correct implementations.
*) Move strictness check from EVP_PKEY_asn1_new() to EVP_PKEY_asn1_add0().
[Richard Levitte]

View file

@ -598,6 +598,7 @@ typedef enum OPTION_choice {
#endif
OPT_DANE_TLSA_RRDATA, OPT_DANE_EE_NO_NAME,
OPT_ENABLE_PHA,
OPT_SCTP_LABEL_BUG,
OPT_R_ENUM
} OPTION_CHOICE;
@ -754,6 +755,7 @@ const OPTIONS s_client_options[] = {
#endif
#ifndef OPENSSL_NO_SCTP
{"sctp", OPT_SCTP, '-', "Use SCTP"},
{"sctp_label_bug", OPT_SCTP_LABEL_BUG, '-', "Enable SCTP label length bug"},
#endif
#ifndef OPENSSL_NO_SSL_TRACE
{"trace", OPT_TRACE, '-', "Show trace output of protocol messages"},
@ -982,6 +984,9 @@ int s_client_main(int argc, char **argv)
#endif
char *psksessf = NULL;
int enable_pha = 0;
#ifndef OPENSSL_NO_SCTP
int sctp_label_bug = 0;
#endif
FD_ZERO(&readfds);
FD_ZERO(&writefds);
@ -1333,6 +1338,11 @@ int s_client_main(int argc, char **argv)
case OPT_SCTP:
#ifndef OPENSSL_NO_SCTP
protocol = IPPROTO_SCTP;
#endif
break;
case OPT_SCTP_LABEL_BUG:
#ifndef OPENSSL_NO_SCTP
sctp_label_bug = 1;
#endif
break;
case OPT_TIMEOUT:
@ -1729,6 +1739,11 @@ int s_client_main(int argc, char **argv)
}
}
#ifndef OPENSSL_NO_SCTP
if (protocol == IPPROTO_SCTP && sctp_label_bug == 1)
SSL_CTX_set_mode(ctx, SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG);
#endif
if (min_version != 0
&& SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
goto end;

View file

@ -751,7 +751,7 @@ typedef enum OPTION_choice {
OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA,
OPT_S_NUM_TICKETS, OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY,
OPT_S_NUM_TICKETS, OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY, OPT_SCTP_LABEL_BUG,
OPT_R_ENUM,
OPT_S_ENUM,
OPT_V_ENUM,
@ -938,6 +938,7 @@ const OPTIONS s_server_options[] = {
#endif
#ifndef OPENSSL_NO_SCTP
{"sctp", OPT_SCTP, '-', "Use SCTP"},
{"sctp_label_bug", OPT_SCTP_LABEL_BUG, '-', "Enable SCTP label length bug"},
#endif
#ifndef OPENSSL_NO_DH
{"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"},
@ -1047,6 +1048,9 @@ int s_server_main(int argc, char *argv[])
const char *keylog_file = NULL;
int max_early_data = -1, recv_max_early_data = -1;
char *psksessf = NULL;
#ifndef OPENSSL_NO_SCTP
int sctp_label_bug = 0;
#endif
/* Init of few remaining global variables */
local_argc = argc;
@ -1488,6 +1492,11 @@ int s_server_main(int argc, char *argv[])
case OPT_SCTP:
#ifndef OPENSSL_NO_SCTP
protocol = IPPROTO_SCTP;
#endif
break;
case OPT_SCTP_LABEL_BUG:
#ifndef OPENSSL_NO_SCTP
sctp_label_bug = 1;
#endif
break;
case OPT_TIMEOUT:
@ -1792,6 +1801,12 @@ int s_server_main(int argc, char *argv[])
goto end;
}
}
#ifndef OPENSSL_NO_SCTP
if (protocol == IPPROTO_SCTP && sctp_label_bug == 1)
SSL_CTX_set_mode(ctx, SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG);
#endif
if (min_version != 0
&& SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
goto end;

View file

@ -102,6 +102,7 @@ B<openssl> B<s_client>
[B<-dtls1>]
[B<-dtls1_2>]
[B<-sctp>]
[B<-sctp_label_bug>]
[B<-fallback_scsv>]
[B<-async>]
[B<-max_send_frag>]
@ -506,6 +507,14 @@ Use SCTP for the transport protocol instead of UDP in DTLS. Must be used in
conjunction with B<-dtls>, B<-dtls1> or B<-dtls1_2>. This option is only
available where OpenSSL has support for SCTP enabled.
=item B<-sctp_label_bug>
Use the incorrect behaviour of older OpenSSL implementations when computing
endpoint-pair shared secrets for DTLS/SCTP. This allows communication with
older broken implementations but breaks interoperability with correct
implementations. Must be used in conjunction with B<-sctp>. This option is only
available where OpenSSL has support for SCTP enabled.
=item B<-fallback_scsv>
Send TLS_FALLBACK_SCSV in the ClientHello.

View file

@ -173,6 +173,7 @@ B<openssl> B<s_server>
[B<-dtls1>]
[B<-dtls1_2>]
[B<-sctp>]
[B<-sctp_label_bug>]
[B<-no_dhe>]
[B<-nextprotoneg val>]
[B<-use_srtp val>]
@ -685,6 +686,14 @@ Use SCTP for the transport protocol instead of UDP in DTLS. Must be used in
conjunction with B<-dtls>, B<-dtls1> or B<-dtls1_2>. This option is only
available where OpenSSL has support for SCTP enabled.
=item B<-sctp_label_bug>
Use the incorrect behaviour of older OpenSSL implementations when computing
endpoint-pair shared secrets for DTLS/SCTP. This allows communication with
older broken implementations but breaks interoperability with correct
implementations. Must be used in conjunction with B<-sctp>. This option is only
available where OpenSSL has support for SCTP enabled.
=item B<-no_dhe>
If this option is set then no DH parameters will be loaded effectively

View file

@ -121,6 +121,15 @@ Kernel TLS might not support all the features of OpenSSL. For instance,
renegotiation, and setting the maximum fragment size is not possible as of
Linux 4.20.
=item SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG
Older versions of OpenSSL had a bug in the computation of the label length
used for computing the endpoint-pair shared secret. The bug was that the
terminating zero was included in the length of the label. Setting this option
enables this behaviour to allow interoperability with such broken
implementations. Please note that setting this option breaks interoperability
with correct implementations. This option only applies to DTLS over SCTP.
=back
All modes are off by default except for SSL_MODE_AUTO_RETRY which is on by

View file

@ -500,6 +500,18 @@ typedef int (*SSL_async_callback_fn)(SSL *s, void *arg);
* Use the kernel TLS transmission data-path.
*/
# define SSL_MODE_NO_KTLS_TX 0x00000200U
/*
* When using DTLS/SCTP, include the terminating zero in the label
* used for computing the endpoint-pair shared secret. Required for
* interoperability with implementations having this bug like these
* older version of OpenSSL:
* - OpenSSL 1.0.0 series
* - OpenSSL 1.0.1 series
* - OpenSSL 1.0.2 series
* - OpenSSL 1.1.0 series
* - OpenSSL 1.1.1 and 1.1.1a
*/
# define SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG 0x00000400U
/* Cert related flags */
/*

View file

@ -1707,6 +1707,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt)
if (SSL_IS_DTLS(s) && s->hit) {
unsigned char sctpauthkey[64];
char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
size_t labellen;
/*
* Add new shared key for SCTP-Auth, will be ignored if
@ -1715,10 +1716,15 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt)
memcpy(labelbuffer, DTLS1_SCTP_AUTH_LABEL,
sizeof(DTLS1_SCTP_AUTH_LABEL));
/* Don't include the terminating zero. */
labellen = sizeof(labelbuffer) - 1;
if (s->mode & SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG)
labellen += 1;
if (SSL_export_keying_material(s, sctpauthkey,
sizeof(sctpauthkey),
labelbuffer,
sizeof(labelbuffer), NULL, 0, 0) <= 0) {
labellen, NULL, 0, 0) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SERVER_HELLO,
ERR_R_INTERNAL_ERROR);
goto err;
@ -3397,6 +3403,7 @@ int tls_client_key_exchange_post_work(SSL *s)
if (SSL_IS_DTLS(s)) {
unsigned char sctpauthkey[64];
char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
size_t labellen;
/*
* Add new shared key for SCTP-Auth, will be ignored if no SCTP
@ -3405,9 +3412,14 @@ int tls_client_key_exchange_post_work(SSL *s)
memcpy(labelbuffer, DTLS1_SCTP_AUTH_LABEL,
sizeof(DTLS1_SCTP_AUTH_LABEL));
/* Don't include the terminating zero. */
labellen = sizeof(labelbuffer) - 1;
if (s->mode & SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG)
labellen += 1;
if (SSL_export_keying_material(s, sctpauthkey,
sizeof(sctpauthkey), labelbuffer,
sizeof(labelbuffer), NULL, 0, 0) <= 0) {
labellen, NULL, 0, 0) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK,
ERR_R_INTERNAL_ERROR);

View file

@ -830,6 +830,7 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst)
if (SSL_IS_DTLS(s) && s->hit) {
unsigned char sctpauthkey[64];
char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
size_t labellen;
/*
* Add new shared key for SCTP-Auth, will be ignored if no
@ -838,9 +839,14 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst)
memcpy(labelbuffer, DTLS1_SCTP_AUTH_LABEL,
sizeof(DTLS1_SCTP_AUTH_LABEL));
/* Don't include the terminating zero. */
labellen = sizeof(labelbuffer) - 1;
if (s->mode & SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG)
labellen += 1;
if (SSL_export_keying_material(s, sctpauthkey,
sizeof(sctpauthkey), labelbuffer,
sizeof(labelbuffer), NULL, 0,
labellen, NULL, 0,
0) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_OSSL_STATEM_SERVER_POST_WORK,
@ -3500,6 +3506,7 @@ WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst)
if (SSL_IS_DTLS(s)) {
unsigned char sctpauthkey[64];
char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
size_t labellen;
/*
* Add new shared key for SCTP-Auth, will be ignored if no SCTP
* used.
@ -3507,9 +3514,14 @@ WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst)
memcpy(labelbuffer, DTLS1_SCTP_AUTH_LABEL,
sizeof(DTLS1_SCTP_AUTH_LABEL));
/* Don't include the terminating zero. */
labellen = sizeof(labelbuffer) - 1;
if (s->mode & SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG)
labellen += 1;
if (SSL_export_keying_material(s, sctpauthkey,
sizeof(sctpauthkey), labelbuffer,
sizeof(labelbuffer), NULL, 0,
labellen, NULL, 0,
0) <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_POST_PROCESS_CLIENT_KEY_EXCHANGE,

View file

@ -22,6 +22,10 @@
#include "handshake_helper.h"
#include "testutil.h"
#if !defined(OPENSSL_NO_SCTP) && !defined(OPENSSL_NO_SOCK)
#include <netinet/sctp.h>
#endif
HANDSHAKE_RESULT *HANDSHAKE_RESULT_new(void)
{
HANDSHAKE_RESULT *ret;
@ -1282,13 +1286,33 @@ static int peer_pkey_type(SSL *s)
#if !defined(OPENSSL_NO_SCTP) && !defined(OPENSSL_NO_SOCK)
static int set_sock_as_sctp(int sock)
{
struct sctp_assocparams assocparams;
struct sctp_rtoinfo rto_info;
BIO *tmpbio;
/*
* To allow tests to fail fast (within a second or so), reduce the
* retransmission timeouts and the number of retransmissions.
*/
memset(&rto_info, 0, sizeof(struct sctp_rtoinfo));
rto_info.srto_initial = 100;
rto_info.srto_max = 200;
rto_info.srto_min = 50;
(void)setsockopt(sock, IPPROTO_SCTP, SCTP_RTOINFO,
(const void *)&rto_info, sizeof(struct sctp_rtoinfo));
memset(&assocparams, 0, sizeof(struct sctp_assocparams));
assocparams.sasoc_asocmaxrxt = 2;
(void)setsockopt(sock, IPPROTO_SCTP, SCTP_ASSOCINFO,
(const void *)&assocparams,
sizeof(struct sctp_assocparams));
/*
* For SCTP we have to set various options on the socket prior to
* connecting. This is done automatically by BIO_new_dgram_sctp().
* We don't actually need the created BIO though so we free it again
* immediately.
*/
BIO *tmpbio = BIO_new_dgram_sctp(sock, BIO_NOCLOSE);
tmpbio = BIO_new_dgram_sctp(sock, BIO_NOCLOSE);
if (tmpbio == NULL)
return 0;
@ -1438,6 +1462,13 @@ static HANDSHAKE_RESULT *do_handshake_internal(
return NULL;
}
#if !defined(OPENSSL_NO_SCTP) && !defined(OPENSSL_NO_SOCK)
if (test_ctx->enable_client_sctp_label_bug)
SSL_CTX_set_mode(client_ctx, SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG);
if (test_ctx->enable_server_sctp_label_bug)
SSL_CTX_set_mode(server_ctx, SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG);
#endif
/* Setup SSL and buffers; additional configuration happens below. */
if (!create_peer(&server, server_ctx)) {
TEST_note("creating server context");

View file

@ -28,7 +28,7 @@ map { s/\^// } @conf_files if $^O eq "VMS";
# We hard-code the number of tests to double-check that the globbing above
# finds all files as expected.
plan tests => 28; # = scalar @conf_srcs
plan tests => 29; # = scalar @conf_srcs
# Some test results depend on the configuration of enabled protocols. We only
# verify generated sources in the default configuration.
@ -102,6 +102,7 @@ my %skip = (
"24-padding.conf" => disabled("tls1_3"),
"25-cipher.conf" => disabled("ec") || disabled("tls1_2"),
"26-tls13_client_auth.conf" => disabled("tls1_3"),
"29-dtls-sctp-label-bug.conf" => disabled("sctp") || disabled("sock"),
);
foreach my $conf (@conf_files) {

View file

@ -0,0 +1,116 @@
# Generated with generate_ssl_tests.pl
num_tests = 4
test-0 = 0-SCTPLabelBug-good1
test-1 = 1-SCTPLabelBug-good2
test-2 = 2-SCTPLabelBug-bad1
test-3 = 3-SCTPLabelBug-bad2
# ===========================================================
[0-SCTPLabelBug-good1]
ssl_conf = 0-SCTPLabelBug-good1-ssl
[0-SCTPLabelBug-good1-ssl]
server = 0-SCTPLabelBug-good1-server
client = 0-SCTPLabelBug-good1-client
[0-SCTPLabelBug-good1-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[0-SCTPLabelBug-good1-client]
CipherString = DEFAULT
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-0]
EnableClientSCTPLabelBug = No
EnableServerSCTPLabelBug = No
ExpectedResult = Success
Method = DTLS
UseSCTP = Yes
# ===========================================================
[1-SCTPLabelBug-good2]
ssl_conf = 1-SCTPLabelBug-good2-ssl
[1-SCTPLabelBug-good2-ssl]
server = 1-SCTPLabelBug-good2-server
client = 1-SCTPLabelBug-good2-client
[1-SCTPLabelBug-good2-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[1-SCTPLabelBug-good2-client]
CipherString = DEFAULT
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-1]
EnableClientSCTPLabelBug = Yes
EnableServerSCTPLabelBug = Yes
ExpectedResult = Success
Method = DTLS
UseSCTP = Yes
# ===========================================================
[2-SCTPLabelBug-bad1]
ssl_conf = 2-SCTPLabelBug-bad1-ssl
[2-SCTPLabelBug-bad1-ssl]
server = 2-SCTPLabelBug-bad1-server
client = 2-SCTPLabelBug-bad1-client
[2-SCTPLabelBug-bad1-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[2-SCTPLabelBug-bad1-client]
CipherString = DEFAULT
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-2]
EnableClientSCTPLabelBug = Yes
EnableServerSCTPLabelBug = No
ExpectedResult = ClientFail
Method = DTLS
UseSCTP = Yes
# ===========================================================
[3-SCTPLabelBug-bad2]
ssl_conf = 3-SCTPLabelBug-bad2-ssl
[3-SCTPLabelBug-bad2-ssl]
server = 3-SCTPLabelBug-bad2-server
client = 3-SCTPLabelBug-bad2-client
[3-SCTPLabelBug-bad2-server]
Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
CipherString = DEFAULT
PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
[3-SCTPLabelBug-bad2-client]
CipherString = DEFAULT
VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
VerifyMode = Peer
[test-3]
EnableClientSCTPLabelBug = No
EnableServerSCTPLabelBug = Yes
ExpectedResult = ClientFail
Method = DTLS
UseSCTP = Yes

View file

@ -0,0 +1,67 @@
# -*- mode: perl; -*-
# Copyright 2019-2019 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html
## Test SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG handling
use strict;
use warnings;
package ssltests;
use OpenSSL::Test::Utils;
our @tests = (
{
name => "SCTPLabelBug-good1",
server => {},
client => {},
test => {
"Method" => "DTLS",
"UseSCTP" => "Yes",
"EnableClientSCTPLabelBug" => "No",
"EnableServerSCTPLabelBug" => "No",
"ExpectedResult" => "Success"
}
},
{
name => "SCTPLabelBug-good2",
server => {},
client => {},
test => {
"Method" => "DTLS",
"UseSCTP" => "Yes",
"EnableClientSCTPLabelBug" => "Yes",
"EnableServerSCTPLabelBug" => "Yes",
"ExpectedResult" => "Success"
}
},
{
name => "SCTPLabelBug-bad1",
server => {},
client => {},
test => {
"Method" => "DTLS",
"UseSCTP" => "Yes",
"EnableClientSCTPLabelBug" => "Yes",
"EnableServerSCTPLabelBug" => "No",
"ExpectedResult" => "ClientFail"
}
},
{
name => "SCTPLabelBug-bad2",
server => {},
client => {},
test => {
"Method" => "DTLS",
"UseSCTP" => "Yes",
"EnableClientSCTPLabelBug" => "No",
"EnableServerSCTPLabelBug" => "Yes",
"ExpectedResult" => "ClientFail"
}
},
);

View file

@ -446,6 +446,8 @@ const char *ssl_ct_validation_name(ssl_ct_validation_t mode)
IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CTX, test, resumption_expected)
IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_SERVER_CONF, server, broken_session_ticket)
IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CTX, test, use_sctp)
IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CTX, test, enable_client_sctp_label_bug)
IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CTX, test, enable_server_sctp_label_bug)
/* CertStatus */
@ -669,6 +671,8 @@ static const ssl_test_ctx_option ssl_test_ctx_options[] = {
{ "ExpectedClientSignType", &parse_expected_client_sign_type },
{ "ExpectedClientCANames", &parse_expected_client_ca_names },
{ "UseSCTP", &parse_test_use_sctp },
{ "EnableClientSCTPLabelBug", &parse_test_enable_client_sctp_label_bug },
{ "EnableServerSCTPLabelBug", &parse_test_enable_server_sctp_label_bug },
{ "ExpectedCipher", &parse_test_expected_cipher },
{ "ExpectedSessionTicketAppData", &parse_test_expected_session_ticket_app_data },
};

View file

@ -214,6 +214,10 @@ typedef struct {
STACK_OF(X509_NAME) *expected_client_ca_names;
/* Whether to use SCTP for the transport */
int use_sctp;
/* Enable SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG on client side */
int enable_client_sctp_label_bug;
/* Enable SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG on server side */
int enable_server_sctp_label_bug;
/* Whether to expect a session id from the server */
ssl_session_id_t session_id_expected;
char *expected_cipher;