diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2019-01-17 06:32:13 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2019-01-17 06:32:13 +0000 |
commit | e5d85c96374742d51c237da91004786fb9695f60 (patch) | |
tree | b387aea167571e6efa095e1ac2ac6772b5fce16c /lib | |
parent | a3147c252e90dae5d26e9b5fe2f8d81f28e22bd2 (diff) |
Provide an extensible buffer implementation that uses a read callback.
The read callback returns a TLS13_IO_* value on EOF, failure, want pollin
or want pollout, or a positive value indicating the number of bytes read.
This will be used by upcoming TLSv1.3 handshake message and record
processing code, both of which need the ability to read a fixed size
header, before extending the buffer to the number of bytes specified in the
header.
ok beck@ tb@
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libssl/Makefile | 5 | ||||
-rw-r--r-- | lib/libssl/tls13_buffer.c | 125 | ||||
-rw-r--r-- | lib/libssl/tls13_internal.h | 21 |
3 files changed, 148 insertions, 3 deletions
diff --git a/lib/libssl/Makefile b/lib/libssl/Makefile index 8923c05bd42..a1300bc9794 100644 --- a/lib/libssl/Makefile +++ b/lib/libssl/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.44 2019/01/17 00:56:57 beck Exp $ +# $OpenBSD: Makefile,v 1.45 2019/01/17 06:32:12 jsing Exp $ .include <bsd.own.mk> .ifndef NOMAN @@ -34,7 +34,8 @@ SRCS= \ ssl_asn1.c ssl_txt.c ssl_algs.c \ bio_ssl.c ssl_err.c ssl_methods.c \ ssl_packet.c ssl_tlsext.c ssl_versions.c pqueue.c ssl_init.c \ - tls13_handshake.c tls13_key_schedule.c tls13_tlsext.c ssl_sigalgs.c + tls13_buffer.c tls13_handshake.c tls13_key_schedule.c tls13_tlsext.c \ + ssl_sigalgs.c SRCS+= s3_cbc.c SRCS+= bs_ber.c bs_cbb.c bs_cbs.c diff --git a/lib/libssl/tls13_buffer.c b/lib/libssl/tls13_buffer.c new file mode 100644 index 00000000000..1b490c8b46d --- /dev/null +++ b/lib/libssl/tls13_buffer.c @@ -0,0 +1,125 @@ +/* $OpenBSD: tls13_buffer.c,v 1.1 2019/01/17 06:32:12 jsing Exp $ */ +/* + * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> + * + * 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 "bytestring.h" +#include "tls13_internal.h" + +struct tls13_buffer { + size_t capacity; + uint8_t *data; + size_t len; + size_t offset; +}; + +static int tls13_buffer_resize(struct tls13_buffer *buf, size_t capacity); + +struct tls13_buffer * +tls13_buffer_new(size_t init_size) +{ + struct tls13_buffer *buf = NULL; + + if ((buf = calloc(1, sizeof(struct tls13_buffer))) == NULL) + goto err; + + if (!tls13_buffer_resize(buf, init_size)) + goto err; + + return buf; + + err: + tls13_buffer_free(buf); + + return NULL; +} + +void +tls13_buffer_free(struct tls13_buffer *buf) +{ + if (buf == NULL) + return; + + freezero(buf->data, buf->capacity); + freezero(buf, sizeof(struct tls13_buffer)); +} + +static int +tls13_buffer_resize(struct tls13_buffer *buf, size_t capacity) +{ + uint8_t *data; + + if (buf->capacity == capacity) + return 1; + + if ((data = recallocarray(buf->data, buf->capacity, capacity, 1)) == NULL) + return 0; + + buf->data = data; + buf->capacity = capacity; + + return 1; +} + +ssize_t +tls13_buffer_extend(struct tls13_buffer *buf, size_t len, + tls13_read_cb read_cb, void *cb_arg) +{ + ssize_t ret; + + if (len == buf->len) + return buf->len; + + if (len < buf->len) + return TLS13_IO_FAILURE; + + if (!tls13_buffer_resize(buf, len)) + return TLS13_IO_FAILURE; + + for (;;) { + if ((ret = read_cb(&buf->data[buf->len], + buf->capacity - buf->len, cb_arg)) <= 0) + return ret; + + buf->len += ret; + + if (buf->len == buf->capacity) + return buf->len; + } +} + +void +tls13_buffer_cbs(struct tls13_buffer *buf, CBS *cbs) +{ + CBS_init(cbs, buf->data, buf->len); +} + +int +tls13_buffer_finish(struct tls13_buffer *buf, uint8_t **out, size_t *out_len) +{ + if (out == NULL || out_len == NULL) + return 0; + + *out = buf->data; + *out_len = buf->len; + + buf->capacity = 0; + buf->data = NULL; + buf->len = 0; + + return 1; +} diff --git a/lib/libssl/tls13_internal.h b/lib/libssl/tls13_internal.h index 83f99881406..872aced77cc 100644 --- a/lib/libssl/tls13_internal.h +++ b/lib/libssl/tls13_internal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tls13_internal.h,v 1.5 2018/11/09 23:56:20 jsing Exp $ */ +/* $OpenBSD: tls13_internal.h,v 1.6 2019/01/17 06:32:12 jsing Exp $ */ /* * Copyright (c) 2018 Bob Beck <beck@openbsd.org> * Copyright (c) 2018 Theo Buehler <tb@openbsd.org> @@ -21,8 +21,27 @@ #include <openssl/evp.h> +#include "bytestring.h" + __BEGIN_HIDDEN_DECLS +#define TLS13_IO_EOF 0 +#define TLS13_IO_FAILURE -1 +#define TLS13_IO_WANT_POLLIN -2 +#define TLS13_IO_WANT_POLLOUT -3 + +typedef ssize_t (*tls13_read_cb)(void *_buf, size_t _buflen, void *_cb_arg); +typedef ssize_t (*tls13_write_cb)(const void *_buf, size_t _buflen, void *_cb_arg); + +struct tls13_buffer; + +struct tls13_buffer *tls13_buffer_new(size_t init_size); +void tls13_buffer_free(struct tls13_buffer *buf); +ssize_t tls13_buffer_extend(struct tls13_buffer *buf, size_t len, + tls13_read_cb read_cb, void *cb_arg); +void tls13_buffer_cbs(struct tls13_buffer *buf, CBS *cbs); +int tls13_buffer_finish(struct tls13_buffer *buf, uint8_t **out, size_t *out_len); + struct tls13_secret { uint8_t *data; size_t len; |