diff options
-rw-r--r-- | ssl/record/methods/tlsrecord.c | 27 | ||||
-rw-r--r-- | ssl/record/rec_layer_s3.c | 61 | ||||
-rw-r--r-- | ssl/record/record.h | 16 | ||||
-rw-r--r-- | ssl/record/recordmethod.h | 36 | ||||
-rw-r--r-- | ssl/s3_enc.c | 19 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 28 | ||||
-rw-r--r-- | ssl/t1_enc.c | 21 | ||||
-rw-r--r-- | ssl/tls13_enc.c | 40 | ||||
-rw-r--r-- | test/tls13secretstest.c | 12 |
9 files changed, 166 insertions, 94 deletions
diff --git a/ssl/record/methods/tlsrecord.c b/ssl/record/methods/tlsrecord.c index 5a50ef25f0..d12b38ce39 100644 --- a/ssl/record/methods/tlsrecord.c +++ b/ssl/record/methods/tlsrecord.c @@ -1486,7 +1486,7 @@ static int tls_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend, * Ktls always reads full records. * Also, we always act like read_ahead is set for DTLS. */ - if (!BIO_get_ktls_recv(s->rbio) && !rl->read_ahead + if (!BIO_get_ktls_recv(rl->bio) && !rl->read_ahead && !rl->isdtls) { /* ignore max parameter */ max = n; @@ -2341,6 +2341,10 @@ static OSSL_RECORD_LAYER *tls_new_record_layer(OSSL_LIB_CTX *libctx, goto err; } + /* + * TODO(RECLAYER): Need to handle the case where the params are updated + * after the record layer has been created. + */ p = OSSL_PARAM_locate_const(options, OSSL_LIBSSL_RECORD_LAYER_PARAM_OPTIONS); if (p != NULL && !OSSL_PARAM_get_uint64(p, &rl->options)) { RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_FAILED_TO_GET_PARAMETER); @@ -2353,11 +2357,22 @@ static OSSL_RECORD_LAYER *tls_new_record_layer(OSSL_LIB_CTX *libctx, goto err; } - - p = OSSL_PARAM_locate_const(options, OSSL_LIBSSL_RECORD_LAYER_PARAM_READ_AHEAD); - if (p != NULL && !OSSL_PARAM_get_int(p, &rl->read_ahead)) { - RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_FAILED_TO_GET_PARAMETER); - goto err; + if (level == OSSL_RECORD_PROTECTION_LEVEL_APPLICATION) { + /* + * We ignore any read_ahead setting prior to the application protection + * level. Otherwise we may read ahead data in a lower protection level + * that is destined for a higher protection level. To simplify the logic + * we don't support that at this stage. + */ + /* + * TODO(RECLAYER): Handle the case of read_ahead at the application + * level and a key update/reneg occurs. + */ + p = OSSL_PARAM_locate_const(options, OSSL_LIBSSL_RECORD_LAYER_PARAM_READ_AHEAD); + if (p != NULL && !OSSL_PARAM_get_int(p, &rl->read_ahead)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_FAILED_TO_GET_PARAMETER); + goto err; + } } rl->libctx = libctx; diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index d4a92e540e..61a4316704 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -14,6 +14,8 @@ #include <openssl/evp.h> #include <openssl/buffer.h> #include <openssl/rand.h> +#include <openssl/core_names.h> +#include <openssl/param_build.h> #include "record_local.h" #include "internal/packet.h" @@ -1747,3 +1749,62 @@ size_t RECORD_LAYER_get_rrec_length(RECORD_LAYER *rl) { return SSL3_RECORD_get_length(&rl->rrec[0]); } + +int ssl_set_new_record_layer(SSL_CONNECTION *s, const OSSL_RECORD_METHOD *meth, + int version, int direction, int level, + unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, size_t taglen, + int mactype, const EVP_MD *md, + const SSL_COMP *comp) +{ + OSSL_PARAM_BLD *tmpl = NULL; + OSSL_PARAM *options = NULL; + int ret = 0; + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + + if (s->rrlmethod != NULL) + s->rrlmethod->free(s->rrl); + + if (meth != NULL) + s->rrlmethod = meth; + + if (!ossl_assert(s->rrlmethod != NULL)) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + if ((tmpl = OSSL_PARAM_BLD_new()) == NULL + || !OSSL_PARAM_BLD_push_uint64(tmpl, + OSSL_LIBSSL_RECORD_LAYER_PARAM_OPTIONS, + s->options) + || !OSSL_PARAM_BLD_push_uint32(tmpl, + OSSL_LIBSSL_RECORD_LAYER_PARAM_MODE, + s->mode) + || !OSSL_PARAM_BLD_push_int(tmpl, + OSSL_LIBSSL_RECORD_LAYER_PARAM_READ_AHEAD, + s->rlayer.read_ahead) + || (options = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + goto err; + } + + s->rrl = s->rrlmethod->new_record_layer(sctx->libctx, sctx->propq, + version, s->server, direction, + level, key, keylen, iv, ivlen, + mackey, mackeylen, ciph, taglen, + mactype, md, comp, s->rbio, + NULL, NULL, NULL, options, s); + if (s->rrl == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = 1; + err: + OSSL_PARAM_free(options); + OSSL_PARAM_BLD_free(tmpl); + + return ret; +} diff --git a/ssl/record/record.h b/ssl/record/record.h index 390ea92b3b..fb836716fa 100644 --- a/ssl/record/record.h +++ b/ssl/record/record.h @@ -8,6 +8,9 @@ */ typedef struct ssl_connection_st SSL_CONNECTION; +typedef struct ssl3_buffer_st SSL3_BUFFER; + +#include "recordmethod.h" /***************************************************************************** * * @@ -16,7 +19,7 @@ typedef struct ssl_connection_st SSL_CONNECTION; * * *****************************************************************************/ -typedef struct ssl3_buffer_st { +struct ssl3_buffer_st { /* at least SSL3_RT_MAX_PACKET_SIZE bytes, see ssl3_setup_buffers() */ unsigned char *buf; /* default buffer size (or 0 if no default set) */ @@ -29,7 +32,7 @@ typedef struct ssl3_buffer_st { size_t left; /* 'buf' is from application for KTLS */ int app_buffer; -} SSL3_BUFFER; +}; #define SEQ_NUM_SIZE 8 @@ -279,3 +282,12 @@ int dtls_buffer_listen_record(SSL_CONNECTION *s, size_t len, unsigned char *seq, int ossl_tls_handle_rlayer_return(SSL_CONNECTION *s, int ret, char *file, int line); + +int ssl_set_new_record_layer(SSL_CONNECTION *s, const OSSL_RECORD_METHOD *meth, + int version, int direction, int level, + unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, size_t taglen, + int mactype, const EVP_MD *md, + const SSL_COMP *comp); diff --git a/ssl/record/recordmethod.h b/ssl/record/recordmethod.h index d2eecb7dd7..a14737836d 100644 --- a/ssl/record/recordmethod.h +++ b/ssl/record/recordmethod.h @@ -7,7 +7,11 @@ * https://www.openssl.org/source/license.html */ -#include <openssl/ssl.h> +#ifndef OSSL_INTERNAL_RECORDMETHOD_H +# define OSSL_INTERNAL_RECORDMETHOD_H +# pragma once + +# include <openssl/ssl.h> /* * We use the term "record" here to refer to a packet of data. Records are @@ -54,26 +58,26 @@ typedef struct ossl_record_method_st OSSL_RECORD_METHOD; typedef struct ossl_record_layer_st OSSL_RECORD_LAYER; -#define OSSL_RECORD_ROLE_CLIENT 0 -#define OSSL_RECORD_ROLE_SERVER 1 +# define OSSL_RECORD_ROLE_CLIENT 0 +# define OSSL_RECORD_ROLE_SERVER 1 -#define OSSL_RECORD_DIRECTION_READ 0 -#define OSSL_RECORD_DIRECTION_WRITE 1 +# define OSSL_RECORD_DIRECTION_READ 0 +# define OSSL_RECORD_DIRECTION_WRITE 1 /* * Protection level. For <= TLSv1.2 only "NONE" and "APPLICATION" are used. */ -#define OSSL_RECORD_PROTECTION_LEVEL_NONE 0 -#define OSSL_RECORD_PROTECTION_LEVEL_EARLY 1 -#define OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE 2 -#define OSSL_RECORD_PROTECTION_LEVEL_APPLICATION 3 +# define OSSL_RECORD_PROTECTION_LEVEL_NONE 0 +# define OSSL_RECORD_PROTECTION_LEVEL_EARLY 1 +# define OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE 2 +# define OSSL_RECORD_PROTECTION_LEVEL_APPLICATION 3 -#define OSSL_RECORD_RETURN_SUCCESS 1 -#define OSSL_RECORD_RETURN_RETRY 0 -#define OSSL_RECORD_RETURN_NON_FATAL_ERR -1 -#define OSSL_RECORD_RETURN_FATAL -2 -#define OSSL_RECORD_RETURN_EOF -3 +# define OSSL_RECORD_RETURN_SUCCESS 1 +# define OSSL_RECORD_RETURN_RETRY 0 +# define OSSL_RECORD_RETURN_NON_FATAL_ERR -1 +# define OSSL_RECORD_RETURN_FATAL -2 +# define OSSL_RECORD_RETURN_EOF -3 /* * Template for creating a record. A record consists of the |type| of data it @@ -290,4 +294,6 @@ struct ossl_record_method_st { /* Standard built-in record methods */ extern const OSSL_RECORD_METHOD ossl_tls_record_method; -extern const OSSL_RECORD_METHOD ossl_dtls_record_method;
\ No newline at end of file +extern const OSSL_RECORD_METHOD ossl_dtls_record_method; + +#endif /* !defined(OSSL_INTERNAL_RECORDMETHOD_H) */ diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index 8e6db3f0c1..bd66f300ef 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -101,7 +101,6 @@ int ssl3_change_cipher_state(SSL_CONNECTION *s, int which) int mdi; size_t n, iv_len, key_len; int reuse_dd = 0; - SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); ciph = s->s3.tmp.new_sym_enc; md = s->s3.tmp.new_hash; @@ -147,18 +146,12 @@ int ssl3_change_cipher_state(SSL_CONNECTION *s, int which) } if (which & SSL3_CC_READ) { - s->rrlmethod->free(s->rrl); - s->rrl = s->rrlmethod->new_record_layer(sctx->libctx, - sctx->propq, - SSL3_VERSION, s->server, - OSSL_RECORD_DIRECTION_READ, - OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, - key, key_len, iv, iv_len, - mac_secret, md_len, ciph, 0, - NID_undef, md, comp, s->rbio, - NULL, NULL, NULL, NULL, s); - if (s->rrl == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + if (!ssl_set_new_record_layer(s, NULL, SSL3_VERSION, + OSSL_RECORD_DIRECTION_READ, + OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, + key, key_len, iv, iv_len, mac_secret, + md_len, ciph, 0, NID_undef, md, comp)) { + /* SSLfatal already called */ goto err; } diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index f1c2db02e2..e076a27560 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -657,28 +657,20 @@ int ossl_ssl_connection_reset(SSL *s) RECORD_LAYER_clear(&sc->rlayer); - if (sc->rrlmethod != NULL) - sc->rrlmethod->free(sc->rrl); - /* - * TODO(RECLAYER): This assignment should probably initialy come from the + * TODO(RECLAYER): The record method should probably initialy come from the * SSL_METHOD, and potentially be updated later. For now though we just * assign it. */ - if (SSL_CONNECTION_IS_DTLS(sc)) - sc->rrlmethod = &ossl_dtls_record_method; - else - sc->rrlmethod = &ossl_tls_record_method; - - sc->rrl = sc->rrlmethod->new_record_layer(s->ctx->libctx, s->ctx->propq, - TLS_ANY_VERSION, sc->server, - OSSL_RECORD_DIRECTION_READ, - OSSL_RECORD_PROTECTION_LEVEL_NONE, - NULL, 0, NULL, 0, NULL, 0, NULL, 0, - NID_undef, NULL, NULL, sc->rbio, - NULL, NULL, NULL, NULL, sc); - if (sc->rrl == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + if (!ssl_set_new_record_layer(sc, + SSL_CONNECTION_IS_DTLS(sc) ? &ossl_dtls_record_method + : &ossl_tls_record_method, + TLS_ANY_VERSION, + OSSL_RECORD_DIRECTION_READ, + OSSL_RECORD_PROTECTION_LEVEL_NONE, + NULL, 0, NULL, 0, NULL, 0, NULL, 0, + NID_undef, NULL, NULL)) { + /* SSLfatal already called */ return 0; } diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 2539b42209..6fee020f32 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -275,21 +275,16 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which) taglen = EVP_CCM_TLS_TAG_LEN; } - s->rrlmethod->free(s->rrl); - s->rrl = s->rrlmethod->new_record_layer(sctx->libctx, - sctx->propq, - s->version, s->server, - OSSL_RECORD_DIRECTION_READ, - OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, - key, cl, iv, (size_t)k, - mac_secret, - mac_secret_size, c, taglen, - mac_type, m, comp, s->rbio, - NULL, NULL, NULL, NULL, s); - if (s->rrl == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + if (!ssl_set_new_record_layer(s, NULL, s->version, + OSSL_RECORD_DIRECTION_READ, + OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, + key, cl, iv, (size_t)k, mac_secret, + mac_secret_size, c, taglen, mac_type, m, + comp)) { + /* SSLfatal already called */ goto err; } + /* TODO(RECLAYER): Temporary - remove me */ goto check_ktls; } diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c index 9001a4455a..8ef0ca6981 100644 --- a/ssl/tls13_enc.c +++ b/ssl/tls13_enc.c @@ -709,22 +709,16 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) : ((which &SSL3_CC_HANDSHAKE) != 0 ? OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE : OSSL_RECORD_PROTECTION_LEVEL_APPLICATION); - s->rrlmethod->free(s->rrl); - s->rrl = s->rrlmethod->new_record_layer(sctx->libctx, - sctx->propq, - s->version, s->server, - OSSL_RECORD_DIRECTION_READ, - level, key, keylen, iv, ivlen, - NULL, 0, cipher, taglen, - NID_undef, NULL, NULL, s->rbio, - NULL, NULL, NULL, NULL, s); - if (s->rrl == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + + if (!ssl_set_new_record_layer(s, NULL, s->version, + OSSL_RECORD_DIRECTION_READ, + level, key, keylen, iv, ivlen, NULL, 0, + cipher, taglen, NID_undef, NULL, NULL)) { + /* SSLfatal already called */ goto err; } } - #ifndef OPENSSL_NO_KTLS # if defined(OPENSSL_KTLS_TLS13) if (!(which & SSL3_CC_APPLICATION) @@ -803,7 +797,6 @@ int tls13_update_key(SSL_CONNECTION *s, int sending) EVP_CIPHER_CTX *ciph_ctx; size_t keylen, ivlen, taglen; int ret = 0; - SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); if (s->server == sending) insecret = s->server_app_traffic_secret; @@ -833,24 +826,17 @@ int tls13_update_key(SSL_CONNECTION *s, int sending) memcpy(insecret, secret, hashlen); if (!sending) { - s->rrlmethod->free(s->rrl); - s->rrl = s->rrlmethod->new_record_layer(sctx->libctx, - sctx->propq, - s->version, s->server, - OSSL_RECORD_DIRECTION_READ, - OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, - key, keylen, iv, ivlen, - NULL, 0, s->s3.tmp.new_sym_enc, - taglen, NID_undef, NULL, NULL, - s->rbio, NULL, NULL, NULL, NULL, - s); - if (s->rrl == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + if (!ssl_set_new_record_layer(s, NULL, s->version, + OSSL_RECORD_DIRECTION_READ, + OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, + key, keylen, iv, ivlen, NULL, 0, + s->s3.tmp.new_sym_enc, taglen, NID_undef, NULL, + NULL)) { + /* SSLfatal already called */ goto err; } } - s->statem.enc_write_state = ENC_WRITE_STATE_VALID; ret = 1; err: diff --git a/test/tls13secretstest.c b/test/tls13secretstest.c index 6a2479210a..f8d14777b3 100644 --- a/test/tls13secretstest.c +++ b/test/tls13secretstest.c @@ -225,6 +225,18 @@ void ssl_evp_md_free(const EVP_MD *md) { } +int ssl_set_new_record_layer(SSL_CONNECTION *s, const OSSL_RECORD_METHOD *meth, + int version, int direction, int level, + unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *ciph, size_t taglen, + int mactype, const EVP_MD *md, + const SSL_COMP *comp) +{ + return 0; +} + /* End of mocked out code */ static int test_secret(SSL_CONNECTION *s, unsigned char *prk, |