diff options
author | Matt Caswell <matt@openssl.org> | 2022-10-21 16:12:31 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2022-10-27 10:52:52 +0100 |
commit | 7eb39ecb299db3eade11946f9385f5dee1d458d3 (patch) | |
tree | d877abd221285d0a959b7766982e5e00ca31d62b /ssl | |
parent | 225f94e818d9f8cb9e272fb9128b4b0ef88a0cbc (diff) | |
download | openssl-new-7eb39ecb299db3eade11946f9385f5dee1d458d3.tar.gz |
Make SSL_alloc_buffers() and SSL_free_buffers() work again
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19472)
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/record/methods/dtls_meth.c | 4 | ||||
-rw-r--r-- | ssl/record/methods/ktls_meth.c | 22 | ||||
-rw-r--r-- | ssl/record/methods/recmethod_local.h | 2 | ||||
-rw-r--r-- | ssl/record/methods/tls_common.c | 64 | ||||
-rw-r--r-- | ssl/record/rec_layer_s3.c | 8 | ||||
-rw-r--r-- | ssl/record/record.h | 1 | ||||
-rw-r--r-- | ssl/record/recordmethod.h | 12 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 14 |
8 files changed, 108 insertions, 19 deletions
diff --git a/ssl/record/methods/dtls_meth.c b/ssl/record/methods/dtls_meth.c index 1f3e1b102c..9988e2406f 100644 --- a/ssl/record/methods/dtls_meth.c +++ b/ssl/record/methods/dtls_meth.c @@ -790,5 +790,7 @@ const OSSL_RECORD_METHOD ossl_dtls_record_method = { tls_get_compression, tls_set_max_frag_len, dtls_get_max_record_overhead, - tls_increment_sequence_ctr + tls_increment_sequence_ctr, + tls_alloc_buffers, + tls_free_buffers }; diff --git a/ssl/record/methods/ktls_meth.c b/ssl/record/methods/ktls_meth.c index 6354c85cd4..63cf6b475f 100644 --- a/ssl/record/methods/ktls_meth.c +++ b/ssl/record/methods/ktls_meth.c @@ -533,6 +533,24 @@ static int ktls_prepare_write_bio(OSSL_RECORD_LAYER *rl, int type) return OSSL_RECORD_RETURN_SUCCESS; } +static int ktls_alloc_buffers(OSSL_RECORD_LAYER *rl) +{ + /* We use the application buffer directly for writing */ + if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) + return 1; + + return tls_alloc_buffers(rl); +} + +static int ktls_free_buffers(OSSL_RECORD_LAYER *rl) +{ + /* We use the application buffer directly for writing */ + if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) + return 1; + + return tls_free_buffers(rl); +} + static struct record_functions_st ossl_ktls_funcs = { ktls_set_crypto_state, ktls_cipher, @@ -580,5 +598,7 @@ const OSSL_RECORD_METHOD ossl_ktls_record_method = { tls_get_compression, tls_set_max_frag_len, NULL, - tls_increment_sequence_ctr + tls_increment_sequence_ctr, + ktls_alloc_buffers, + ktls_free_buffers }; diff --git a/ssl/record/methods/recmethod_local.h b/ssl/record/methods/recmethod_local.h index 21a8297b08..b02ab296bd 100644 --- a/ssl/record/methods/recmethod_local.h +++ b/ssl/record/methods/recmethod_local.h @@ -345,6 +345,8 @@ __owur int ssl3_cbc_digest_record(const EVP_MD *md, size_t mac_secret_length, char is_sslv3); int tls_increment_sequence_ctr(OSSL_RECORD_LAYER *rl); +int tls_alloc_buffers(OSSL_RECORD_LAYER *rl); +int tls_free_buffers(OSSL_RECORD_LAYER *rl); int tls_default_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend, int clearold, size_t *readbytes); diff --git a/ssl/record/methods/tls_common.c b/ssl/record/methods/tls_common.c index 96697828ba..4ef65ae152 100644 --- a/ssl/record/methods/tls_common.c +++ b/ssl/record/methods/tls_common.c @@ -2031,6 +2031,66 @@ int tls_increment_sequence_ctr(OSSL_RECORD_LAYER *rl) return 1; } +int tls_alloc_buffers(OSSL_RECORD_LAYER *rl) +{ + if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) { + /* If we have a pending write then buffers are already allocated */ + if (rl->nextwbuf < rl->numwpipes) + return 1; + /* + * We assume 1 pipe with default sized buffer. If what we need ends up + * being a different size to that then it will be reallocated on demand. + * If we need more than 1 pipe then that will also be allocated on + * demand + */ + if (!tls_setup_write_buffer(rl, 1, 0, 0)) + return 0; + + /* + * Normally when we allocate write buffers we immediately write + * something into it. In this case we're not doing that so mark the + * buffer as empty. + */ + SSL3_BUFFER_set_left(&rl->wbuf[0], 0); + return 1; + } + + /* Read direction */ + + /* If we have pending data to be read then buffers are already allocated */ + if (rl->curr_rec < rl->num_recs || SSL3_BUFFER_get_left(&rl->rbuf) != 0) + return 1; + return tls_setup_read_buffer(rl); +} + +int tls_free_buffers(OSSL_RECORD_LAYER *rl) +{ + if (rl->direction == OSSL_RECORD_DIRECTION_WRITE) { + if (rl->nextwbuf < rl->numwpipes) { + /* + * We may have pending data. If we've just got one empty buffer + * allocated then it has probably just been alloc'd via + * tls_alloc_buffers, and it is fine to free it. Otherwise this + * looks like real pending data and it is an error. + */ + if (rl->nextwbuf != 0 + || rl->numwpipes != 1 + || SSL3_BUFFER_get_left(&rl->wbuf[0]) != 0) + return 0; + } + tls_release_write_buffer(rl); + return 1; + } + + /* Read direction */ + + /* If we have pending data to be read then fail */ + if (rl->curr_rec < rl->num_recs || SSL3_BUFFER_get_left(&rl->rbuf) != 0) + return 0; + + return tls_release_read_buffer(rl); +} + const OSSL_RECORD_METHOD ossl_tls_record_method = { tls_new_record_layer, tls_free, @@ -2057,5 +2117,7 @@ const OSSL_RECORD_METHOD ossl_tls_record_method = { tls_get_compression, tls_set_max_frag_len, NULL, - tls_increment_sequence_ctr + tls_increment_sequence_ctr, + tls_alloc_buffers, + tls_free_buffers }; diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index 0e2c5b3b3f..f90f639b0c 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -48,14 +48,6 @@ void RECORD_LAYER_clear(RECORD_LAYER *rl) DTLS_RECORD_LAYER_clear(rl); } -void RECORD_LAYER_release(RECORD_LAYER *rl) -{ - /* - * TODO(RECLAYER): Need a way to release the write buffers in the record - * layer on demand - */ -} - /* Checks if we have unprocessed read ahead data pending */ int RECORD_LAYER_read_pending(const RECORD_LAYER *rl) { diff --git a/ssl/record/record.h b/ssl/record/record.h index be86a758f5..d835703c13 100644 --- a/ssl/record/record.h +++ b/ssl/record/record.h @@ -202,7 +202,6 @@ typedef struct ssl_mac_buf_st SSL_MAC_BUF; void RECORD_LAYER_init(RECORD_LAYER *rl, SSL_CONNECTION *s); void RECORD_LAYER_clear(RECORD_LAYER *rl); -void RECORD_LAYER_release(RECORD_LAYER *rl); int RECORD_LAYER_read_pending(const RECORD_LAYER *rl); int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl); int RECORD_LAYER_write_pending(const RECORD_LAYER *rl); diff --git a/ssl/record/recordmethod.h b/ssl/record/recordmethod.h index 3bbca66fed..70e6e4d26a 100644 --- a/ssl/record/recordmethod.h +++ b/ssl/record/recordmethod.h @@ -320,6 +320,18 @@ struct ossl_record_method_st { * Increment the record sequence number */ int (*increment_sequence_ctr)(OSSL_RECORD_LAYER *rl); + + /* + * Allocate read or write buffers. Does nothing if already allocated. + * Assumes default buffer length and 1 pipeline. + */ + int (*alloc_buffers)(OSSL_RECORD_LAYER *rl); + + /* + * Free read or write buffers. Fails if there is pending read or write + * data. Buffers are automatically reallocated on next read/write. + */ + int (*free_buffers)(OSSL_RECORD_LAYER *rl); }; diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 3b3eda4001..e71f0b5da5 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -6365,22 +6365,22 @@ int SSL_free_buffers(SSL *ssl) rl = &sc->rlayer; - if (RECORD_LAYER_read_pending(rl) || RECORD_LAYER_write_pending(rl)) - return 0; - - RECORD_LAYER_release(rl); - return 1; + return rl->rrlmethod->free_buffers(rl->rrl) + && rl->wrlmethod->free_buffers(rl->wrl); } int SSL_alloc_buffers(SSL *ssl) { + RECORD_LAYER *rl; SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); if (sc == NULL) return 0; - /* TODO(RECLAYER): Need a way to make this happen in the record layer */ - return 1; + rl = &sc->rlayer; + + return rl->rrlmethod->alloc_buffers(rl->rrl) + && rl->wrlmethod->alloc_buffers(rl->wrl); } void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb) |