From 6a367516df1cd7a6eb819c9bc94f4e4cb1d4f0eb Mon Sep 17 00:00:00 2001 From: jsing <> Date: Sat, 19 Jan 2019 02:53:54 +0000 Subject: Provide a TLS record handling implementation. This is a self-contained struct and set of functions that knows how to decode and read a TLS record from data supplied via a read callback, and send itself via a write callback. This will soon be used to build the TLSv1.3 record layer handling code. ok beck@ tb@ --- src/lib/libssl/Makefile | 4 +- src/lib/libssl/tls13_record.c | 160 ++++++++++++++++++++++++++++++++++++++++++ src/lib/libssl/tls13_record.h | 58 +++++++++++++++ 3 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 src/lib/libssl/tls13_record.c create mode 100644 src/lib/libssl/tls13_record.h (limited to 'src') diff --git a/src/lib/libssl/Makefile b/src/lib/libssl/Makefile index 9fc010d534..a5a1f2927f 100644 --- a/src/lib/libssl/Makefile +++ b/src/lib/libssl/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.46 2019/01/18 03:41:30 beck Exp $ +# $OpenBSD: Makefile,v 1.47 2019/01/19 02:53:54 jsing Exp $ .include .ifndef NOMAN @@ -35,7 +35,7 @@ SRCS= \ bio_ssl.c ssl_err.c ssl_methods.c \ ssl_packet.c ssl_tlsext.c ssl_versions.c pqueue.c ssl_init.c \ tls13_buffer.c tls13_handshake.c tls13_key_schedule.c \ - ssl_sigalgs.c + tls13_record.c ssl_sigalgs.c SRCS+= s3_cbc.c SRCS+= bs_ber.c bs_cbb.c bs_cbs.c diff --git a/src/lib/libssl/tls13_record.c b/src/lib/libssl/tls13_record.c new file mode 100644 index 0000000000..857d3bee49 --- /dev/null +++ b/src/lib/libssl/tls13_record.c @@ -0,0 +1,160 @@ +/* $OpenBSD: tls13_record.c,v 1.1 2019/01/19 02:53:54 jsing Exp $ */ +/* + * Copyright (c) 2018, 2019 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "ssl_locl.h" + +#include + +#include "tls13_internal.h" +#include "tls13_record.h" + +struct tls13_record { + uint8_t content_type; + size_t rec_len; + uint8_t *data; + size_t data_len; + CBS cbs; + + struct tls13_buffer *buf; +}; + +struct tls13_record * +tls13_record_new(void) +{ + struct tls13_record *rec = NULL; + + if ((rec = calloc(1, sizeof(struct tls13_record))) == NULL) + goto err; + if ((rec->buf = tls13_buffer_new(TLS13_RECORD_MAX_LEN)) == NULL) + goto err; + + return rec; + + err: + tls13_record_free(rec); + + return NULL; +} + +void +tls13_record_free(struct tls13_record *rec) +{ + if (rec == NULL) + return; + + tls13_buffer_free(rec->buf); + + freezero(rec->data, rec->data_len); + freezero(rec, sizeof(struct tls13_record)); +} + +uint8_t +tls13_record_content_type(struct tls13_record *rec) +{ + return rec->content_type; +} + +int +tls13_record_content(struct tls13_record *rec, CBS *cbs) +{ + CBS content; + + tls13_record_data(rec, &content); + + if (!CBS_skip(&content, TLS13_RECORD_HEADER_LEN)) + return 0; + + CBS_dup(&content, cbs); + + return 1; +} + +void +tls13_record_data(struct tls13_record *rec, CBS *cbs) +{ + CBS_init(cbs, rec->data, rec->data_len); +} + +void +tls13_record_set_data(struct tls13_record *rec, uint8_t *data, size_t data_len) +{ + freezero(rec->data, rec->data_len); + rec->data = data; + rec->data_len = data_len; + CBS_init(&rec->cbs, rec->data, rec->data_len); +} + +ssize_t +tls13_record_recv(struct tls13_record *rec, tls13_read_cb wire_read, + void *wire_arg) +{ + uint16_t rec_len, rec_version; + uint8_t content_type; + CBS cbs; + int ret; + + if (rec->data != NULL) + return TLS13_IO_FAILURE; + + if (rec->content_type == 0) { + if ((ret = tls13_buffer_extend(rec->buf, + TLS13_RECORD_HEADER_LEN, wire_read, wire_arg)) <= 0) + return ret; + + tls13_buffer_cbs(rec->buf, &cbs); + + if (!CBS_get_u8(&cbs, &content_type)) + return TLS13_IO_FAILURE; + if (!CBS_get_u16(&cbs, &rec_version)) + return TLS13_IO_FAILURE; + if (!CBS_get_u16(&cbs, &rec_len)) + return TLS13_IO_FAILURE; + + rec->content_type = content_type; + rec->rec_len = rec_len; + } + + if ((ret = tls13_buffer_extend(rec->buf, + TLS13_RECORD_HEADER_LEN + rec->rec_len, wire_read, wire_arg)) <= 0) + return ret; + + if (!tls13_buffer_finish(rec->buf, &rec->data, &rec->data_len)) + return TLS13_IO_FAILURE; + + return rec->data_len; +} + +ssize_t +tls13_record_send(struct tls13_record *rec, tls13_write_cb wire_write, + void *wire_arg) +{ + ssize_t ret; + + if (rec->data == NULL) + return TLS13_IO_FAILURE; + + while (CBS_len(&rec->cbs) > 0) { + if ((ret = wire_write(CBS_data(&rec->cbs), + CBS_len(&rec->cbs), wire_arg)) <= 0) + return ret; + + if (!CBS_skip(&rec->cbs, ret)) + return TLS13_IO_FAILURE; + } + + return rec->data_len; +} diff --git a/src/lib/libssl/tls13_record.h b/src/lib/libssl/tls13_record.h new file mode 100644 index 0000000000..ca7a63f99c --- /dev/null +++ b/src/lib/libssl/tls13_record.h @@ -0,0 +1,58 @@ +/* $OpenBSD: tls13_record.h,v 1.1 2019/01/19 02:53:54 jsing Exp $ */ +/* + * Copyright (c) 2019 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_TLS13_RECORD_H +#define HEADER_TLS13_RECORD_H + +#include "bytestring.h" +#include "tls13_internal.h" + +__BEGIN_HIDDEN_DECLS + +/* + * TLSv1.3 - RFC 8446 section 5. + * + * The maximum plaintext is 2^14, however for inner plaintext an additional + * byte is allowed for the content type. A maximum AEAD overhead of 255-bytes + * is permitted, along with a 5-byte header, giving a maximum size of + * 5 + 2^14 + 1 + 255 = 16,645-bytes. + */ +#define TLS13_RECORD_HEADER_LEN 5 +#define TLS13_RECORD_MAX_AEAD_OVERHEAD 255 +#define TLS13_RECORD_MAX_PLAINTEXT_LEN 16384 +#define TLS13_RECORD_MAX_INNER_PLAINTEXT_LEN \ + (TLS13_RECORD_MAX_PLAINTEXT_LEN + 1) +#define TLS13_RECORD_MAX_CIPHERTEXT \ + (TLS13_RECORD_MAX_INNER_PLAINTEXT_LEN + TLS13_RECORD_MAX_AEAD_OVERHEAD) +#define TLS13_RECORD_MAX_LEN \ + (TLS13_RECORD_HEADER_LEN + TLS13_RECORD_MAX_CIPHERTEXT) + +struct tls13_record *tls13_record_new(void); +void tls13_record_free(struct tls13_record *_rec); +uint8_t tls13_record_content_type(struct tls13_record *_rec); +int tls13_record_content(struct tls13_record *_rec, CBS *_cbs); +void tls13_record_data(struct tls13_record *_rec, CBS *_cbs); +void tls13_record_set_data(struct tls13_record *_rec, uint8_t *_data, + size_t _data_len); +ssize_t tls13_record_recv(struct tls13_record *_rec, tls13_read_cb _wire_read, + void *_wire_arg); +ssize_t tls13_record_send(struct tls13_record *_rec, tls13_write_cb _wire_write, + void *_wire_arg); + +__END_HIDDEN_DECLS + +#endif -- cgit v1.2.3-55-g6feb