xref: /openbsd-src/lib/libssl/tls13_record.c (revision 24c399e99a02e098cfb950694eed3ffbe8491e3e)
1*24c399e9Sjsing /* $OpenBSD: tls13_record.c,v 1.10 2022/07/22 19:33:53 jsing Exp $ */
266f36ca5Sjsing /*
366f36ca5Sjsing  * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
466f36ca5Sjsing  *
566f36ca5Sjsing  * Permission to use, copy, modify, and distribute this software for any
666f36ca5Sjsing  * purpose with or without fee is hereby granted, provided that the above
766f36ca5Sjsing  * copyright notice and this permission notice appear in all copies.
866f36ca5Sjsing  *
966f36ca5Sjsing  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1066f36ca5Sjsing  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1166f36ca5Sjsing  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1266f36ca5Sjsing  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1366f36ca5Sjsing  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1466f36ca5Sjsing  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1566f36ca5Sjsing  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1666f36ca5Sjsing  */
1766f36ca5Sjsing 
1866f36ca5Sjsing #include "tls13_internal.h"
1966f36ca5Sjsing #include "tls13_record.h"
2066f36ca5Sjsing 
2166f36ca5Sjsing struct tls13_record {
22c11ed2b5Sjsing 	uint16_t version;
2366f36ca5Sjsing 	uint8_t content_type;
2466f36ca5Sjsing 	size_t rec_len;
2566f36ca5Sjsing 	uint8_t *data;
2666f36ca5Sjsing 	size_t data_len;
2766f36ca5Sjsing 	CBS cbs;
2866f36ca5Sjsing 
29f6184395Sjsing 	struct tls_buffer *buf;
3066f36ca5Sjsing };
3166f36ca5Sjsing 
3266f36ca5Sjsing struct tls13_record *
tls13_record_new(void)3366f36ca5Sjsing tls13_record_new(void)
3466f36ca5Sjsing {
3566f36ca5Sjsing 	struct tls13_record *rec = NULL;
3666f36ca5Sjsing 
3766f36ca5Sjsing 	if ((rec = calloc(1, sizeof(struct tls13_record))) == NULL)
3866f36ca5Sjsing 		goto err;
39f6184395Sjsing 	if ((rec->buf = tls_buffer_new(TLS13_RECORD_MAX_LEN)) == NULL)
4066f36ca5Sjsing 		goto err;
4166f36ca5Sjsing 
4266f36ca5Sjsing 	return rec;
4366f36ca5Sjsing 
4466f36ca5Sjsing  err:
4566f36ca5Sjsing 	tls13_record_free(rec);
4666f36ca5Sjsing 
4766f36ca5Sjsing 	return NULL;
4866f36ca5Sjsing }
4966f36ca5Sjsing 
5066f36ca5Sjsing void
tls13_record_free(struct tls13_record * rec)5166f36ca5Sjsing tls13_record_free(struct tls13_record *rec)
5266f36ca5Sjsing {
5366f36ca5Sjsing 	if (rec == NULL)
5466f36ca5Sjsing 		return;
5566f36ca5Sjsing 
56f6184395Sjsing 	tls_buffer_free(rec->buf);
5766f36ca5Sjsing 
5866f36ca5Sjsing 	freezero(rec->data, rec->data_len);
5966f36ca5Sjsing 	freezero(rec, sizeof(struct tls13_record));
6066f36ca5Sjsing }
6166f36ca5Sjsing 
62c11ed2b5Sjsing uint16_t
tls13_record_version(struct tls13_record * rec)63c11ed2b5Sjsing tls13_record_version(struct tls13_record *rec)
64c11ed2b5Sjsing {
65c11ed2b5Sjsing 	return rec->version;
66c11ed2b5Sjsing }
67c11ed2b5Sjsing 
68c11ed2b5Sjsing uint8_t
tls13_record_content_type(struct tls13_record * rec)69c11ed2b5Sjsing tls13_record_content_type(struct tls13_record *rec)
70c11ed2b5Sjsing {
71c11ed2b5Sjsing 	return rec->content_type;
72c11ed2b5Sjsing }
73c11ed2b5Sjsing 
74f2b92807Sjsing int
tls13_record_header(struct tls13_record * rec,CBS * cbs)75f2b92807Sjsing tls13_record_header(struct tls13_record *rec, CBS *cbs)
76f2b92807Sjsing {
77f2b92807Sjsing 	if (rec->data_len < TLS13_RECORD_HEADER_LEN)
78f2b92807Sjsing 		return 0;
79f2b92807Sjsing 
80f2b92807Sjsing 	CBS_init(cbs, rec->data, TLS13_RECORD_HEADER_LEN);
81f2b92807Sjsing 
82f2b92807Sjsing 	return 1;
83f2b92807Sjsing }
84f2b92807Sjsing 
8566f36ca5Sjsing int
tls13_record_content(struct tls13_record * rec,CBS * cbs)8666f36ca5Sjsing tls13_record_content(struct tls13_record *rec, CBS *cbs)
8766f36ca5Sjsing {
8866f36ca5Sjsing 	CBS content;
8966f36ca5Sjsing 
9066f36ca5Sjsing 	tls13_record_data(rec, &content);
9166f36ca5Sjsing 
9266f36ca5Sjsing 	if (!CBS_skip(&content, TLS13_RECORD_HEADER_LEN))
9366f36ca5Sjsing 		return 0;
9466f36ca5Sjsing 
9566f36ca5Sjsing 	CBS_dup(&content, cbs);
9666f36ca5Sjsing 
9766f36ca5Sjsing 	return 1;
9866f36ca5Sjsing }
9966f36ca5Sjsing 
10066f36ca5Sjsing void
tls13_record_data(struct tls13_record * rec,CBS * cbs)10166f36ca5Sjsing tls13_record_data(struct tls13_record *rec, CBS *cbs)
10266f36ca5Sjsing {
10366f36ca5Sjsing 	CBS_init(cbs, rec->data, rec->data_len);
10466f36ca5Sjsing }
10566f36ca5Sjsing 
106f2b92807Sjsing int
tls13_record_set_data(struct tls13_record * rec,uint8_t * data,size_t data_len)10766f36ca5Sjsing tls13_record_set_data(struct tls13_record *rec, uint8_t *data, size_t data_len)
10866f36ca5Sjsing {
109f2b92807Sjsing 	if (data_len > TLS13_RECORD_MAX_LEN)
110f2b92807Sjsing 		return 0;
111f2b92807Sjsing 
11266f36ca5Sjsing 	freezero(rec->data, rec->data_len);
11366f36ca5Sjsing 	rec->data = data;
11466f36ca5Sjsing 	rec->data_len = data_len;
11566f36ca5Sjsing 	CBS_init(&rec->cbs, rec->data, rec->data_len);
116f2b92807Sjsing 
117f2b92807Sjsing 	return 1;
11866f36ca5Sjsing }
11966f36ca5Sjsing 
12066f36ca5Sjsing ssize_t
tls13_record_recv(struct tls13_record * rec,tls_read_cb wire_read,void * wire_arg)121f6184395Sjsing tls13_record_recv(struct tls13_record *rec, tls_read_cb wire_read,
12266f36ca5Sjsing     void *wire_arg)
12366f36ca5Sjsing {
12466f36ca5Sjsing 	uint16_t rec_len, rec_version;
12566f36ca5Sjsing 	uint8_t content_type;
126c11ed2b5Sjsing 	ssize_t ret;
12766f36ca5Sjsing 	CBS cbs;
12866f36ca5Sjsing 
12966f36ca5Sjsing 	if (rec->data != NULL)
13066f36ca5Sjsing 		return TLS13_IO_FAILURE;
13166f36ca5Sjsing 
13266f36ca5Sjsing 	if (rec->content_type == 0) {
133f6184395Sjsing 		if ((ret = tls_buffer_extend(rec->buf,
13466f36ca5Sjsing 		    TLS13_RECORD_HEADER_LEN, wire_read, wire_arg)) <= 0)
13566f36ca5Sjsing 			return ret;
13666f36ca5Sjsing 
137*24c399e9Sjsing 		if (!tls_buffer_data(rec->buf, &cbs))
138*24c399e9Sjsing 			return TLS13_IO_FAILURE;
13966f36ca5Sjsing 
14066f36ca5Sjsing 		if (!CBS_get_u8(&cbs, &content_type))
14166f36ca5Sjsing 			return TLS13_IO_FAILURE;
14266f36ca5Sjsing 		if (!CBS_get_u16(&cbs, &rec_version))
14366f36ca5Sjsing 			return TLS13_IO_FAILURE;
14466f36ca5Sjsing 		if (!CBS_get_u16(&cbs, &rec_len))
14566f36ca5Sjsing 			return TLS13_IO_FAILURE;
14666f36ca5Sjsing 
147204f36c2Sjsing 		if ((rec_version >> 8) != SSL3_VERSION_MAJOR)
148204f36c2Sjsing 			return TLS13_IO_RECORD_VERSION;
149f2b92807Sjsing 		if (rec_len > TLS13_RECORD_MAX_CIPHERTEXT_LEN)
1506423e56fSjsing 			return TLS13_IO_RECORD_OVERFLOW;
151f2b92807Sjsing 
15266f36ca5Sjsing 		rec->content_type = content_type;
153c11ed2b5Sjsing 		rec->version = rec_version;
15466f36ca5Sjsing 		rec->rec_len = rec_len;
15566f36ca5Sjsing 	}
15666f36ca5Sjsing 
157f6184395Sjsing 	if ((ret = tls_buffer_extend(rec->buf,
15866f36ca5Sjsing 	    TLS13_RECORD_HEADER_LEN + rec->rec_len, wire_read, wire_arg)) <= 0)
15966f36ca5Sjsing 		return ret;
16066f36ca5Sjsing 
161f6184395Sjsing 	if (!tls_buffer_finish(rec->buf, &rec->data, &rec->data_len))
16266f36ca5Sjsing 		return TLS13_IO_FAILURE;
16366f36ca5Sjsing 
16466f36ca5Sjsing 	return rec->data_len;
16566f36ca5Sjsing }
16666f36ca5Sjsing 
16766f36ca5Sjsing ssize_t
tls13_record_send(struct tls13_record * rec,tls_write_cb wire_write,void * wire_arg)168f6184395Sjsing tls13_record_send(struct tls13_record *rec, tls_write_cb wire_write,
16966f36ca5Sjsing     void *wire_arg)
17066f36ca5Sjsing {
17166f36ca5Sjsing 	ssize_t ret;
17266f36ca5Sjsing 
17366f36ca5Sjsing 	if (rec->data == NULL)
17466f36ca5Sjsing 		return TLS13_IO_FAILURE;
17566f36ca5Sjsing 
17666f36ca5Sjsing 	while (CBS_len(&rec->cbs) > 0) {
17766f36ca5Sjsing 		if ((ret = wire_write(CBS_data(&rec->cbs),
17866f36ca5Sjsing 		    CBS_len(&rec->cbs), wire_arg)) <= 0)
17966f36ca5Sjsing 			return ret;
18066f36ca5Sjsing 
18166f36ca5Sjsing 		if (!CBS_skip(&rec->cbs, ret))
18266f36ca5Sjsing 			return TLS13_IO_FAILURE;
18366f36ca5Sjsing 	}
18466f36ca5Sjsing 
18566f36ca5Sjsing 	return rec->data_len;
18666f36ca5Sjsing }
187