* 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;
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);
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;
#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"
{
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;
+}
*/
typedef struct ssl_connection_st SSL_CONNECTION;
+typedef struct ssl3_buffer_st SSL3_BUFFER;
+
+#include "recordmethod.h"
/*****************************************************************************
* *
* *
*****************************************************************************/
-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) */
size_t left;
/* 'buf' is from application for KTLS */
int app_buffer;
-} SSL3_BUFFER;
+};
#define SEQ_NUM_SIZE 8
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);
* 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
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
/* 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) */
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;
}
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;
}
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;
}
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;
}
: ((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)
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;
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:
{
}
+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,