Skip to content

Commit

Permalink
Refactor code and fix a couple of missing DTLSv1.3 checks.
Browse files Browse the repository at this point in the history
  • Loading branch information
fwh-dc committed May 21, 2024
1 parent bf5269e commit 09eeb1d
Show file tree
Hide file tree
Showing 14 changed files with 207 additions and 128 deletions.
31 changes: 22 additions & 9 deletions apps/s_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ static int psk_use_session_cb(SSL *s, const EVP_MD *md,
{
SSL_SESSION *usesess = NULL;
const SSL_CIPHER *cipher = NULL;
const int version1_3 = SSL_is_dtls(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;

if (psksess != NULL) {
SSL_SESSION_up_ref(psksess);
Expand All @@ -231,7 +232,7 @@ static int psk_use_session_cb(SSL *s, const EVP_MD *md,
if (usesess == NULL
|| !SSL_SESSION_set1_master_key(usesess, key, key_len)
|| !SSL_SESSION_set_cipher(usesess, cipher)
|| !SSL_SESSION_set_protocol_version(usesess, TLS1_3_VERSION)) {
|| !SSL_SESSION_set_protocol_version(usesess, version1_3)) {
OPENSSL_free(key);
goto err;
}
Expand Down Expand Up @@ -813,6 +814,7 @@ static void freeandcopy(char **dest, const char *source)

static int new_session_cb(SSL *s, SSL_SESSION *sess)
{
const int version1_3 = SSL_is_dtls(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;

if (sess_out != NULL) {
BIO *stmp = BIO_new_file(sess_out, "w");
Expand All @@ -826,10 +828,10 @@ static int new_session_cb(SSL *s, SSL_SESSION *sess)
}

/*
* Session data gets dumped on connection for TLSv1.2 and below, and on
* arrival of the NewSessionTicket for TLSv1.3.
* Session data gets dumped on connection for (D)TLSv1.2 and below, and on
* arrival of the NewSessionTicket for (D)TLSv1.3.
*/
if (SSL_version(s) == TLS1_3_VERSION || SSL_version(s) == DTLS1_3_VERSION) {
if (SSL_version(s) == version1_3) {
BIO_printf(bio_c_out,
"---\nPost-Handshake New Session Ticket arrived:\n");
SSL_SESSION_print(bio_c_out, sess);
Expand Down Expand Up @@ -931,6 +933,9 @@ int s_client_main(int argc, char **argv)
#ifndef OPENSSL_NO_CT
char *ctlog_file = NULL;
int ct_validation = 0;
#endif
#ifndef OPENSSL_NO_NEXTPROTONEG
int version1_3;
#endif
int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0;
int async = 0;
Expand Down Expand Up @@ -1589,6 +1594,10 @@ int s_client_main(int argc, char **argv)
}
}

#ifndef OPENSSL_NO_NEXTPROTONEG
version1_3 = isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION;
#endif

/* Optional argument is connect string if -connect not used. */
if (opt_num_rest() == 1) {
/* Don't allow -connect and a separate argument. */
Expand Down Expand Up @@ -1629,7 +1638,7 @@ int s_client_main(int argc, char **argv)
}

#ifndef OPENSSL_NO_NEXTPROTONEG
if (min_version == TLS1_3_VERSION && next_proto_neg_in != NULL) {
if (min_version == version1_3 && next_proto_neg_in != NULL) {
BIO_printf(bio_err, "Cannot supply -nextprotoneg with TLSv1.3\n");
goto opthelp;
}
Expand Down Expand Up @@ -3377,7 +3386,8 @@ static void print_stuff(BIO *bio, SSL *s, int full)
STACK_OF(X509) *sk;
const SSL_CIPHER *c;
EVP_PKEY *public_key;
int i, istls13 = (SSL_version(s) == TLS1_3_VERSION);
const int version1_3 = SSL_is_dtls(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
int i;
long verify_result;
#ifndef OPENSSL_NO_COMP
const COMP_METHOD *comp, *expansion;
Expand Down Expand Up @@ -3570,7 +3580,7 @@ static void print_stuff(BIO *bio, SSL *s, int full)
}
#endif

if (istls13) {
if (SSL_version(s) == version1_3) {
switch (SSL_get_early_data_status(s)) {
case SSL_EARLY_DATA_NOT_SENT:
BIO_printf(bio, "Early data was not sent\n");
Expand Down Expand Up @@ -3831,6 +3841,8 @@ static int user_data_add(struct user_data_st *user_data, size_t i)

static int user_data_execute(struct user_data_st *user_data, int cmd, char *arg)
{
const int version1_3 = SSL_is_dtls(user_data->con) ? DTLS1_3_VERSION : TLS1_3_VERSION;

switch (cmd) {
case USER_COMMAND_HELP:
/* This only ever occurs in advanced mode, so just emit advanced help */
Expand All @@ -3843,7 +3855,7 @@ static int user_data_execute(struct user_data_st *user_data, int cmd, char *arg)
BIO_printf(bio_err, " {reconnect}: Reconnect to the peer\n");
if (SSL_is_quic(user_data->con)) {
BIO_printf(bio_err, " {fin}: Send FIN on the stream. No further writing is possible\n");
} else if(SSL_version(user_data->con) == TLS1_3_VERSION) {
} else if(SSL_version(user_data->con) == version1_3) {
BIO_printf(bio_err, " {keyup:req|noreq}: Send a Key Update message\n");
BIO_printf(bio_err, " Arguments:\n");
BIO_printf(bio_err, " req = peer update requested (default)\n");
Expand Down Expand Up @@ -3907,6 +3919,7 @@ static int user_data_process(struct user_data_st *user_data, size_t *len,
{
char *buf_start = user_data->buf + user_data->bufoff;
size_t outlen = user_data->buflen;
const int version1_3 = SSL_is_dtls(user_data->con) ? DTLS1_3_VERSION : TLS1_3_VERSION;

if (user_data->buflen == 0) {
*len = 0;
Expand Down Expand Up @@ -3992,7 +4005,7 @@ static int user_data_process(struct user_data_st *user_data, size_t *len,
} else if(SSL_is_quic(user_data->con)) {
if (OPENSSL_strcasecmp(cmd_start, "fin") == 0)
cmd = USER_COMMAND_FIN;
} if (SSL_version(user_data->con) == TLS1_3_VERSION) {
} if (SSL_version(user_data->con) == version1_3) {
if (OPENSSL_strcasecmp(cmd_start, "keyup") == 0) {
cmd = USER_COMMAND_KEY_UPDATE;
if (arg_start == NULL)
Expand Down
19 changes: 13 additions & 6 deletions apps/s_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,17 +131,17 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity,
{
long key_len = 0;
unsigned char *key;
const int version1_3 = SSL_is_dtls(ssl) ? DTLS1_3_VERSION : TLS1_3_VERSION;

if (s_debug)
BIO_printf(bio_s_out, "psk_server_cb\n");

if ((SSL_is_dtls(ssl) && DTLS_VERSION_GE(SSL_version(ssl), DTLS1_3_VERSION))
|| (!SSL_is_dtls(ssl) && SSL_version(ssl) >= TLS1_3_VERSION)) {
if (PROTOCOL_VERSION_CMP(SSL_is_dtls(ssl), SSL_version(ssl), version1_3) >= 0) {
/*
* This callback is designed for use in (D)TLSv1.2 (or below). It is
* possible to use a single callback for all protocol versions - but it
* is preferred to use a dedicated callback for TLSv1.3. For TLSv1.3 we
* have psk_find_session_cb.
* is preferred to use a dedicated callback for (D)TLSv1.3. For
* (D)TLSv1.3 we have psk_find_session_cb.
*/
return 0;
}
Expand Down Expand Up @@ -1070,6 +1070,9 @@ int s_server_main(int argc, char *argv[])
#endif
#ifndef OPENSSL_NO_SRTP
char *srtp_profiles = NULL;
#endif
#if !(defined(OPENSSL_NO_NEXTPROTONEG) && defined(OPENSSL_NO_PSK))
int version1_3;
#endif
int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0;
int s_server_verify = SSL_VERIFY_NONE;
Expand Down Expand Up @@ -1721,6 +1724,10 @@ int s_server_main(int argc, char *argv[])
}
}

#if !(defined(OPENSSL_NO_NEXTPROTONEG) && defined(OPENSSL_NO_PSK))
version1_3 = (socket_type == SOCK_DGRAM) ? DTLS1_3_VERSION : TLS1_3_VERSION;
#endif

/* No extra arguments. */
if (!opt_check_rest_arg(NULL))
goto opthelp;
Expand All @@ -1729,7 +1736,7 @@ int s_server_main(int argc, char *argv[])
goto end;

#ifndef OPENSSL_NO_NEXTPROTONEG
if (min_version == TLS1_3_VERSION && next_proto_neg_in != NULL) {
if (min_version == version1_3 && next_proto_neg_in != NULL) {
BIO_printf(bio_err, "Cannot supply -nextprotoneg with TLSv1.3\n");
goto opthelp;
}
Expand Down Expand Up @@ -2219,7 +2226,7 @@ int s_server_main(int argc, char *argv[])
}

if (psk_identity_hint != NULL) {
if (min_version == TLS1_3_VERSION) {
if (min_version == version1_3) {
BIO_printf(bio_s_out, "PSK warning: there is NO identity hint in TLSv1.3\n");
} else {
if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) {
Expand Down
5 changes: 3 additions & 2 deletions ssl/record/methods/tls_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,16 @@ int tls_setup_write_buffer(OSSL_RECORD_LAYER *rl, size_t numwpipes,
size_t currpipe;
size_t defltlen = 0;
size_t contenttypelen = 0;
const int version1_3 = rl->isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION;

if (firstlen == 0 || (numwpipes > 1 && nextlen == 0)) {
if (rl->isdtls)
headerlen = DTLS1_RT_HEADER_LENGTH + 1;
else
headerlen = SSL3_RT_HEADER_LENGTH;

/* TLSv1.3 adds an extra content type byte after payload data */
if (rl->version == TLS1_3_VERSION)
/* (D)TLSv1.3 adds an extra content type byte after payload data */
if (rl->version == version1_3)
contenttypelen = 1;

#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
Expand Down
19 changes: 9 additions & 10 deletions ssl/ssl_cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -1141,8 +1141,10 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx,
int op, int bits, int nid, void *other,
void *ex)
{
int level, minbits, pfs_mask;
int level, minbits, pfs_mask, minversion;
const SSL_CONNECTION *sc;
const int version1_3 = SSL_is_dtls(s) ? DTLS1_3_VERSION : TLS1_3_VERSION;
const int version1_2 = SSL_is_dtls(s) ? DTLS1_2_VERSION : TLS1_2_VERSION;

minbits = ssl_get_security_level_bits(s, ctx, &level);

Expand Down Expand Up @@ -1173,25 +1175,22 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx,
/* SHA1 HMAC is 160 bits of security */
if (minbits > 160 && c->algorithm_mac & SSL_SHA1)
return 0;

/* Level 3: forward secure ciphersuites only */
pfs_mask = SSL_kDHE | SSL_kECDHE | SSL_kDHEPSK | SSL_kECDHEPSK;
if (level >= 3 && c->min_tls != TLS1_3_VERSION &&
minversion = SSL_is_dtls(s) ? c->min_dtls : c->min_tls;

if (level >= 3 && minversion != version1_3 &&
!(c->algorithm_mkey & pfs_mask))
return 0;
break;
}
case SSL_SECOP_VERSION:
if ((sc = SSL_CONNECTION_FROM_CONST_SSL(s)) == NULL)
return 0;
if (!SSL_CONNECTION_IS_DTLS(sc)) {
/* SSLv3, TLS v1.0 and TLS v1.1 only allowed at level 0 */
if (nid <= TLS1_1_VERSION && level > 0)
/* SSLv3, TLS v1.0 and TLS v1.1 and DTLS v1.0 only allowed at level 0 */
if (ssl_version_cmp(sc, nid, version1_2) < 0 && level > 0)
return 0;
} else {
/* DTLS v1.0 only allowed at level 0 */
if (DTLS_VERSION_LT(nid, DTLS1_2_VERSION) && level > 0)
return 0;
}
break;

case SSL_SECOP_COMPRESSION:
Expand Down
17 changes: 11 additions & 6 deletions ssl/ssl_ciph.c
Original file line number Diff line number Diff line change
Expand Up @@ -1389,15 +1389,20 @@ static int update_cipher_list(SSL_CTX *ctx,
return 0;

/*
* Delete any existing TLSv1.3 ciphersuites. These are always first in the
* Delete any existing (D)TLSv1.3 ciphersuites. These are always first in the
* list.
*/
while (sk_SSL_CIPHER_num(tmp_cipher_list) > 0
&& sk_SSL_CIPHER_value(tmp_cipher_list, 0)->min_tls
== TLS1_3_VERSION)
(void)sk_SSL_CIPHER_delete(tmp_cipher_list, 0);
if (SSL_CTX_IS_DTLS(ctx)) {
while (sk_SSL_CIPHER_num(tmp_cipher_list) > 0
&& sk_SSL_CIPHER_value(tmp_cipher_list, 0)->min_dtls == DTLS1_3_VERSION)
(void)sk_SSL_CIPHER_delete(tmp_cipher_list, 0);
} else {
while (sk_SSL_CIPHER_num(tmp_cipher_list) > 0
&& sk_SSL_CIPHER_value(tmp_cipher_list, 0)->min_tls == TLS1_3_VERSION)
(void)sk_SSL_CIPHER_delete(tmp_cipher_list, 0);
}

/* Insert the new TLSv1.3 ciphersuites */
/* Insert the new (D)TLSv1.3 ciphersuites */
for (i = sk_SSL_CIPHER_num(tls13_ciphersuites) - 1; i >= 0; i--) {
const SSL_CIPHER *sslc = sk_SSL_CIPHER_value(tls13_ciphersuites, i);

Expand Down
24 changes: 20 additions & 4 deletions ssl/ssl_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,10 @@ static int ssl_check_allowed_versions(int min_version, int max_version)
min_version = DTLS1_VERSION;
if (max_version == 0)
max_version = DTLS1_3_VERSION;
#ifdef OPENSSL_NO_DTLS1_3
if (max_version == DTLS1_3_VERSION)
max_version = DTLS1_2_VERSION;
#endif
#ifdef OPENSSL_NO_DTLS1_2
if (max_version == DTLS1_2_VERSION)
max_version = DTLS1_VERSION;
Expand All @@ -486,6 +490,10 @@ static int ssl_check_allowed_versions(int min_version, int max_version)
#ifdef OPENSSL_NO_DTLS1_2
|| (DTLS_VERSION_GE(min_version, DTLS1_2_VERSION)
&& DTLS_VERSION_GE(DTLS1_2_VERSION, max_version))
#endif
#ifdef OPENSSL_NO_DTLS1_3
|| (DTLS_VERSION_GE(min_version, DTLS1_3_VERSION)
&& DTLS_VERSION_GE(DTLS1_3_VERSION, max_version))
#endif
)
return 0;
Expand Down Expand Up @@ -935,6 +943,9 @@ int SSL_is_dtls(const SSL *s)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);

if (s == NULL)
return 0;

#ifndef OPENSSL_NO_QUIC
if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
return 0;
Expand Down Expand Up @@ -3308,16 +3319,21 @@ STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx)
* Distinguish between ciphers controlled by set_ciphersuite() and
* set_cipher_list() when counting.
*/
static int cipher_list_tls12_num(STACK_OF(SSL_CIPHER) *sk)
static int cipher_list_tls12_num(STACK_OF(SSL_CIPHER) *sk, int isdtls)
{
int i, num = 0;
const SSL_CIPHER *c;
const int version1_3 = isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION;

if (sk == NULL)
return 0;
for (i = 0; i < sk_SSL_CIPHER_num(sk); ++i) {
int minversion;

c = sk_SSL_CIPHER_value(sk, i);
if (c->min_tls >= TLS1_3_VERSION)
minversion = isdtls ? c->min_dtls : c->min_tls;

if (PROTOCOL_VERSION_CMP(isdtls, minversion, version1_3) >= 0)
continue;
num++;
}
Expand All @@ -3341,7 +3357,7 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str)
*/
if (sk == NULL)
return 0;
else if (cipher_list_tls12_num(sk) == 0) {
else if (cipher_list_tls12_num(sk, SSL_CTX_IS_DTLS(ctx)) == 0) {
ERR_raise(ERR_LIB_SSL, SSL_R_NO_CIPHER_MATCH);
return 0;
}
Expand All @@ -3363,7 +3379,7 @@ int SSL_set_cipher_list(SSL *s, const char *str)
/* see comment in SSL_CTX_set_cipher_list */
if (sk == NULL)
return 0;
else if (cipher_list_tls12_num(sk) == 0) {
else if (cipher_list_tls12_num(sk, SSL_CONNECTION_IS_DTLS(sc)) == 0) {
ERR_raise(ERR_LIB_SSL, SSL_R_NO_CIPHER_MATCH);
return 0;
}
Expand Down
Loading

0 comments on commit 09eeb1d

Please sign in to comment.