openssl/ssl/record/ssl3_buffer.c
Matt Caswell e2d5742b14 Transfer the functionality from ssl3_read_n to the new record layer
This transfers the low level function ssl3_read_n to the new record layer.
We temporarily make the read_n function a top level record layer function.
Eventually, in later commits in this refactor, we will remove it as a top
level function and it will just be called from read_record.

Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18132)
2022-08-18 16:38:12 +01:00

187 lines
4.9 KiB
C

/*
* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include "../ssl_local.h"
#include "record_local.h"
void SSL3_BUFFER_set_data(SSL3_BUFFER *b, const unsigned char *d, size_t n)
{
if (d != NULL)
memcpy(b->buf, d, n);
b->left = n;
b->offset = 0;
}
/*
* Clear the contents of an SSL3_BUFFER but retain any memory allocated. Also
* retains the default_len setting
*/
void SSL3_BUFFER_clear(SSL3_BUFFER *b)
{
b->offset = 0;
b->left = 0;
}
void SSL3_BUFFER_release(SSL3_BUFFER *b)
{
OPENSSL_free(b->buf);
b->buf = NULL;
}
int ssl3_setup_read_buffer(SSL_CONNECTION *s)
{
unsigned char *p;
size_t len, align = 0, headerlen;
SSL3_BUFFER *b;
b = s->rrlmethod->get0_rbuf(s->rrl);
if (SSL_CONNECTION_IS_DTLS(s))
headerlen = DTLS1_RT_HEADER_LENGTH;
else
headerlen = SSL3_RT_HEADER_LENGTH;
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
#endif
if (b->buf == NULL) {
len = SSL3_RT_MAX_PLAIN_LENGTH
+ SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
#ifndef OPENSSL_NO_COMP
if (ssl_allow_compression(s))
len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
#endif
if (b->default_len > len)
len = b->default_len;
if ((p = OPENSSL_malloc(len)) == NULL) {
/*
* We've got a malloc failure, and we're still initialising buffers.
* We assume we're so doomed that we won't even be able to send an
* alert.
*/
SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_MALLOC_FAILURE);
return 0;
}
b->buf = p;
b->len = len;
}
return 1;
}
int ssl3_setup_write_buffer(SSL_CONNECTION *s, size_t numwpipes,
size_t len)
{
unsigned char *p;
size_t align = 0, headerlen;
SSL3_BUFFER *wb;
size_t currpipe;
s->rlayer.numwpipes = numwpipes;
if (len == 0) {
if (SSL_CONNECTION_IS_DTLS(s))
headerlen = DTLS1_RT_HEADER_LENGTH + 1;
else
headerlen = SSL3_RT_HEADER_LENGTH;
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
align = SSL3_ALIGN_PAYLOAD - 1;
#endif
len = ssl_get_max_send_fragment(s)
+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
#ifndef OPENSSL_NO_COMP
if (ssl_allow_compression(s))
len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
#endif
if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
len += headerlen + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
}
wb = RECORD_LAYER_get_wbuf(&s->rlayer);
for (currpipe = 0; currpipe < numwpipes; currpipe++) {
SSL3_BUFFER *thiswb = &wb[currpipe];
if (thiswb->len != len) {
OPENSSL_free(thiswb->buf);
thiswb->buf = NULL; /* force reallocation */
}
if (thiswb->buf == NULL) {
if (s->wbio == NULL || !BIO_get_ktls_send(s->wbio)) {
p = OPENSSL_malloc(len);
if (p == NULL) {
s->rlayer.numwpipes = currpipe;
/*
* We've got a malloc failure, and we're still initialising
* buffers. We assume we're so doomed that we won't even be able
* to send an alert.
*/
SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
p = NULL;
}
memset(thiswb, 0, sizeof(SSL3_BUFFER));
thiswb->buf = p;
thiswb->len = len;
}
}
return 1;
}
int ssl3_setup_buffers(SSL_CONNECTION *s)
{
if (!ssl3_setup_read_buffer(s)) {
/* SSLfatal() already called */
return 0;
}
if (!ssl3_setup_write_buffer(s, 1, 0)) {
/* SSLfatal() already called */
return 0;
}
return 1;
}
int ssl3_release_write_buffer(SSL_CONNECTION *s)
{
SSL3_BUFFER *wb;
size_t pipes;
pipes = s->rlayer.numwpipes;
while (pipes > 0) {
wb = &RECORD_LAYER_get_wbuf(&s->rlayer)[pipes - 1];
if (SSL3_BUFFER_is_app_buffer(wb))
SSL3_BUFFER_set_app_buffer(wb, 0);
else
OPENSSL_free(wb->buf);
wb->buf = NULL;
pipes--;
}
s->rlayer.numwpipes = 0;
return 1;
}
int ssl3_release_read_buffer(SSL_CONNECTION *s)
{
SSL3_BUFFER *b;
b = s->rrlmethod->get0_rbuf(s->rrl);
if (s->options & SSL_OP_CLEANSE_PLAINTEXT)
OPENSSL_cleanse(b->buf, b->len);
OPENSSL_free(b->buf);
b->buf = NULL;
return 1;
}