aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ssl/record/methods/tlsrecord.c27
-rw-r--r--ssl/record/rec_layer_s3.c61
-rw-r--r--ssl/record/record.h16
-rw-r--r--ssl/record/recordmethod.h36
-rw-r--r--ssl/s3_enc.c19
-rw-r--r--ssl/ssl_lib.c28
-rw-r--r--ssl/t1_enc.c21
-rw-r--r--ssl/tls13_enc.c40
-rw-r--r--test/tls13secretstest.c12
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,