summaryrefslogtreecommitdiffstats
path: root/lib/libssl/ssl_pkt.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libssl/ssl_pkt.c')
-rw-r--r--lib/libssl/ssl_pkt.c90
1 files changed, 49 insertions, 41 deletions
diff --git a/lib/libssl/ssl_pkt.c b/lib/libssl/ssl_pkt.c
index 39ce46381df..da059915f20 100644
--- a/lib/libssl/ssl_pkt.c
+++ b/lib/libssl/ssl_pkt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_pkt.c,v 1.28 2020/08/02 07:33:15 jsing Exp $ */
+/* $OpenBSD: ssl_pkt.c,v 1.29 2020/08/09 16:02:58 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -617,15 +617,15 @@ ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
}
static int
-ssl3_create_record(SSL *s, unsigned char *p, uint16_t version, uint8_t type,
+ssl3_create_record(SSL *s, CBB *cbb, uint16_t version, uint8_t type,
const unsigned char *buf, unsigned int len)
{
SSL3_RECORD_INTERNAL *wr = &(S3I(s)->wrec);
SSL_SESSION *sess = s->session;
- int eivlen = 0, mac_size = 0;
- CBB cbb;
-
- memset(&cbb, 0, sizeof(cbb));
+ int block_size = 0, eivlen = 0, mac_size = 0;
+ size_t pad_len, record_len;
+ CBB fragment;
+ uint8_t *p;
if (sess != NULL && s->internal->enc_write_ctx != NULL &&
EVP_MD_CTX_md(s->internal->write_hash) != NULL) {
@@ -633,17 +633,6 @@ ssl3_create_record(SSL *s, unsigned char *p, uint16_t version, uint8_t type,
goto err;
}
- if (!CBB_init_fixed(&cbb, p, SSL3_RT_HEADER_LENGTH))
- goto err;
-
- /* Write the header. */
- if (!CBB_add_u8(&cbb, type))
- goto err;
- if (!CBB_add_u16(&cbb, version))
- goto err;
-
- p += SSL3_RT_HEADER_LENGTH;
-
/* Explicit IV length. */
if (s->internal->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) {
int mode = EVP_CIPHER_CTX_mode(s->internal->enc_write_ctx);
@@ -657,6 +646,31 @@ ssl3_create_record(SSL *s, unsigned char *p, uint16_t version, uint8_t type,
eivlen = s->internal->aead_write_ctx->variable_nonce_len;
}
+ /* Determine length of record fragment. */
+ record_len = eivlen + len + mac_size;
+ if (s->internal->enc_write_ctx != NULL) {
+ block_size = EVP_CIPHER_CTX_block_size(s->internal->enc_write_ctx);
+ if (block_size <= 0 || block_size > EVP_MAX_BLOCK_LENGTH)
+ goto err;
+ if (block_size > 1) {
+ pad_len = block_size - (record_len % block_size);
+ record_len += pad_len;
+ }
+ } else if (s->internal->aead_write_ctx != NULL) {
+ record_len += s->internal->aead_write_ctx->tag_len;
+ }
+
+ /* Write the header. */
+ if (!CBB_add_u8(cbb, type))
+ goto err;
+ if (!CBB_add_u16(cbb, version))
+ goto err;
+ if (!CBB_add_u16_length_prefixed(cbb, &fragment))
+ goto err;
+ if (!CBB_add_space(&fragment, &p, record_len))
+ goto err;
+
+ /* Set up the record. */
wr->type = type;
wr->data = p + eivlen;
wr->length = (int)len;
@@ -677,10 +691,10 @@ ssl3_create_record(SSL *s, unsigned char *p, uint16_t version, uint8_t type,
if (tls1_enc(s, 1) != 1)
goto err;
- /* record length after mac and block padding */
- if (!CBB_add_u16(&cbb, wr->length))
+ if (wr->length != record_len)
goto err;
- if (!CBB_finish(&cbb, NULL, NULL))
+
+ if (!CBB_flush(cbb))
goto err;
/*
@@ -693,24 +707,22 @@ ssl3_create_record(SSL *s, unsigned char *p, uint16_t version, uint8_t type,
return 1;
err:
- CBB_cleanup(&cbb);
-
return 0;
}
static int
do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
{
- SSL3_RECORD_INTERNAL *wr = &(S3I(s)->wrec);
SSL3_BUFFER_INTERNAL *wb = &(S3I(s)->wbuf);
SSL_SESSION *sess = s->session;
- unsigned char *p;
int need_empty_fragment = 0;
- int prefix_len = 0;
+ size_t align, out_len;
uint16_t version;
- size_t align;
+ CBB cbb;
int ret;
+ memset(&cbb, 0, sizeof(cbb));
+
if (wb->buf == NULL)
if (!ssl3_setup_write_buffer(s))
return -1;
@@ -768,30 +780,24 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
if (need_empty_fragment)
align += SSL3_RT_HEADER_LENGTH;
align = (-align) & (SSL3_ALIGN_PAYLOAD - 1);
-
- p = wb->buf + align;
wb->offset = align;
- if (need_empty_fragment) {
- if (!ssl3_create_record(s, p, version, type, buf, 0))
- goto err;
+ if (!CBB_init_fixed(&cbb, wb->buf + align, wb->len - align))
+ goto err;
- prefix_len = wr->length;
- if (prefix_len > (SSL3_RT_HEADER_LENGTH +
- SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) {
- /* insufficient space */
- SSLerror(s, ERR_R_INTERNAL_ERROR);
+ if (need_empty_fragment) {
+ if (!ssl3_create_record(s, &cbb, version, type, buf, 0))
goto err;
- }
- p = wb->buf + wb->offset + prefix_len;
-
S3I(s)->empty_fragment_done = 1;
}
- if (!ssl3_create_record(s, p, version, type, buf, len))
+ if (!ssl3_create_record(s, &cbb, version, type, buf, len))
goto err;
- wb->left = prefix_len + wr->length;
+ if (!CBB_finish(&cbb, NULL, &out_len))
+ goto err;
+
+ wb->left = out_len;
/*
* Memorize arguments so that ssl3_write_pending can detect
@@ -806,6 +812,8 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
return ssl3_write_pending(s, type, buf, len);
err:
+ CBB_cleanup(&cbb);
+
return -1;
}