xref: /dflybsd-src/crypto/libressl/ssl/tls13_record.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: tls13_record.c,v 1.10 2022/07/22 19:33:53 jsing Exp $ */
2cca6fc52SDaniel Fojt /*
3cca6fc52SDaniel Fojt  * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
4cca6fc52SDaniel Fojt  *
5cca6fc52SDaniel Fojt  * Permission to use, copy, modify, and distribute this software for any
6cca6fc52SDaniel Fojt  * purpose with or without fee is hereby granted, provided that the above
7cca6fc52SDaniel Fojt  * copyright notice and this permission notice appear in all copies.
8cca6fc52SDaniel Fojt  *
9cca6fc52SDaniel Fojt  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10cca6fc52SDaniel Fojt  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11cca6fc52SDaniel Fojt  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12cca6fc52SDaniel Fojt  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13cca6fc52SDaniel Fojt  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14cca6fc52SDaniel Fojt  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15cca6fc52SDaniel Fojt  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16cca6fc52SDaniel Fojt  */
17cca6fc52SDaniel Fojt 
18cca6fc52SDaniel Fojt #include "tls13_internal.h"
19cca6fc52SDaniel Fojt #include "tls13_record.h"
20cca6fc52SDaniel Fojt 
21cca6fc52SDaniel Fojt struct tls13_record {
22cca6fc52SDaniel Fojt 	uint16_t version;
23cca6fc52SDaniel Fojt 	uint8_t content_type;
24cca6fc52SDaniel Fojt 	size_t rec_len;
25cca6fc52SDaniel Fojt 	uint8_t *data;
26cca6fc52SDaniel Fojt 	size_t data_len;
27cca6fc52SDaniel Fojt 	CBS cbs;
28cca6fc52SDaniel Fojt 
29*de0e0e4dSAntonio Huete Jimenez 	struct tls_buffer *buf;
30cca6fc52SDaniel Fojt };
31cca6fc52SDaniel Fojt 
32cca6fc52SDaniel Fojt struct tls13_record *
tls13_record_new(void)33cca6fc52SDaniel Fojt tls13_record_new(void)
34cca6fc52SDaniel Fojt {
35cca6fc52SDaniel Fojt 	struct tls13_record *rec = NULL;
36cca6fc52SDaniel Fojt 
37cca6fc52SDaniel Fojt 	if ((rec = calloc(1, sizeof(struct tls13_record))) == NULL)
38cca6fc52SDaniel Fojt 		goto err;
39*de0e0e4dSAntonio Huete Jimenez 	if ((rec->buf = tls_buffer_new(TLS13_RECORD_MAX_LEN)) == NULL)
40cca6fc52SDaniel Fojt 		goto err;
41cca6fc52SDaniel Fojt 
42cca6fc52SDaniel Fojt 	return rec;
43cca6fc52SDaniel Fojt 
44cca6fc52SDaniel Fojt  err:
45cca6fc52SDaniel Fojt 	tls13_record_free(rec);
46cca6fc52SDaniel Fojt 
47cca6fc52SDaniel Fojt 	return NULL;
48cca6fc52SDaniel Fojt }
49cca6fc52SDaniel Fojt 
50cca6fc52SDaniel Fojt void
tls13_record_free(struct tls13_record * rec)51cca6fc52SDaniel Fojt tls13_record_free(struct tls13_record *rec)
52cca6fc52SDaniel Fojt {
53cca6fc52SDaniel Fojt 	if (rec == NULL)
54cca6fc52SDaniel Fojt 		return;
55cca6fc52SDaniel Fojt 
56*de0e0e4dSAntonio Huete Jimenez 	tls_buffer_free(rec->buf);
57cca6fc52SDaniel Fojt 
58cca6fc52SDaniel Fojt 	freezero(rec->data, rec->data_len);
59cca6fc52SDaniel Fojt 	freezero(rec, sizeof(struct tls13_record));
60cca6fc52SDaniel Fojt }
61cca6fc52SDaniel Fojt 
62cca6fc52SDaniel Fojt uint16_t
tls13_record_version(struct tls13_record * rec)63cca6fc52SDaniel Fojt tls13_record_version(struct tls13_record *rec)
64cca6fc52SDaniel Fojt {
65cca6fc52SDaniel Fojt 	return rec->version;
66cca6fc52SDaniel Fojt }
67cca6fc52SDaniel Fojt 
68cca6fc52SDaniel Fojt uint8_t
tls13_record_content_type(struct tls13_record * rec)69cca6fc52SDaniel Fojt tls13_record_content_type(struct tls13_record *rec)
70cca6fc52SDaniel Fojt {
71cca6fc52SDaniel Fojt 	return rec->content_type;
72cca6fc52SDaniel Fojt }
73cca6fc52SDaniel Fojt 
74cca6fc52SDaniel Fojt int
tls13_record_header(struct tls13_record * rec,CBS * cbs)75cca6fc52SDaniel Fojt tls13_record_header(struct tls13_record *rec, CBS *cbs)
76cca6fc52SDaniel Fojt {
77cca6fc52SDaniel Fojt 	if (rec->data_len < TLS13_RECORD_HEADER_LEN)
78cca6fc52SDaniel Fojt 		return 0;
79cca6fc52SDaniel Fojt 
80cca6fc52SDaniel Fojt 	CBS_init(cbs, rec->data, TLS13_RECORD_HEADER_LEN);
81cca6fc52SDaniel Fojt 
82cca6fc52SDaniel Fojt 	return 1;
83cca6fc52SDaniel Fojt }
84cca6fc52SDaniel Fojt 
85cca6fc52SDaniel Fojt int
tls13_record_content(struct tls13_record * rec,CBS * cbs)86cca6fc52SDaniel Fojt tls13_record_content(struct tls13_record *rec, CBS *cbs)
87cca6fc52SDaniel Fojt {
88cca6fc52SDaniel Fojt 	CBS content;
89cca6fc52SDaniel Fojt 
90cca6fc52SDaniel Fojt 	tls13_record_data(rec, &content);
91cca6fc52SDaniel Fojt 
92cca6fc52SDaniel Fojt 	if (!CBS_skip(&content, TLS13_RECORD_HEADER_LEN))
93cca6fc52SDaniel Fojt 		return 0;
94cca6fc52SDaniel Fojt 
95cca6fc52SDaniel Fojt 	CBS_dup(&content, cbs);
96cca6fc52SDaniel Fojt 
97cca6fc52SDaniel Fojt 	return 1;
98cca6fc52SDaniel Fojt }
99cca6fc52SDaniel Fojt 
100cca6fc52SDaniel Fojt void
tls13_record_data(struct tls13_record * rec,CBS * cbs)101cca6fc52SDaniel Fojt tls13_record_data(struct tls13_record *rec, CBS *cbs)
102cca6fc52SDaniel Fojt {
103cca6fc52SDaniel Fojt 	CBS_init(cbs, rec->data, rec->data_len);
104cca6fc52SDaniel Fojt }
105cca6fc52SDaniel Fojt 
106cca6fc52SDaniel Fojt int
tls13_record_set_data(struct tls13_record * rec,uint8_t * data,size_t data_len)107cca6fc52SDaniel Fojt tls13_record_set_data(struct tls13_record *rec, uint8_t *data, size_t data_len)
108cca6fc52SDaniel Fojt {
109cca6fc52SDaniel Fojt 	if (data_len > TLS13_RECORD_MAX_LEN)
110cca6fc52SDaniel Fojt 		return 0;
111cca6fc52SDaniel Fojt 
112cca6fc52SDaniel Fojt 	freezero(rec->data, rec->data_len);
113cca6fc52SDaniel Fojt 	rec->data = data;
114cca6fc52SDaniel Fojt 	rec->data_len = data_len;
115cca6fc52SDaniel Fojt 	CBS_init(&rec->cbs, rec->data, rec->data_len);
116cca6fc52SDaniel Fojt 
117cca6fc52SDaniel Fojt 	return 1;
118cca6fc52SDaniel Fojt }
119cca6fc52SDaniel Fojt 
120cca6fc52SDaniel Fojt ssize_t
tls13_record_recv(struct tls13_record * rec,tls_read_cb wire_read,void * wire_arg)121*de0e0e4dSAntonio Huete Jimenez tls13_record_recv(struct tls13_record *rec, tls_read_cb wire_read,
122cca6fc52SDaniel Fojt     void *wire_arg)
123cca6fc52SDaniel Fojt {
124cca6fc52SDaniel Fojt 	uint16_t rec_len, rec_version;
125cca6fc52SDaniel Fojt 	uint8_t content_type;
126cca6fc52SDaniel Fojt 	ssize_t ret;
127cca6fc52SDaniel Fojt 	CBS cbs;
128cca6fc52SDaniel Fojt 
129cca6fc52SDaniel Fojt 	if (rec->data != NULL)
130cca6fc52SDaniel Fojt 		return TLS13_IO_FAILURE;
131cca6fc52SDaniel Fojt 
132cca6fc52SDaniel Fojt 	if (rec->content_type == 0) {
133*de0e0e4dSAntonio Huete Jimenez 		if ((ret = tls_buffer_extend(rec->buf,
134cca6fc52SDaniel Fojt 		    TLS13_RECORD_HEADER_LEN, wire_read, wire_arg)) <= 0)
135cca6fc52SDaniel Fojt 			return ret;
136cca6fc52SDaniel Fojt 
137*de0e0e4dSAntonio Huete Jimenez 		if (!tls_buffer_data(rec->buf, &cbs))
138*de0e0e4dSAntonio Huete Jimenez 			return TLS13_IO_FAILURE;
139cca6fc52SDaniel Fojt 
140cca6fc52SDaniel Fojt 		if (!CBS_get_u8(&cbs, &content_type))
141cca6fc52SDaniel Fojt 			return TLS13_IO_FAILURE;
142cca6fc52SDaniel Fojt 		if (!CBS_get_u16(&cbs, &rec_version))
143cca6fc52SDaniel Fojt 			return TLS13_IO_FAILURE;
144cca6fc52SDaniel Fojt 		if (!CBS_get_u16(&cbs, &rec_len))
145cca6fc52SDaniel Fojt 			return TLS13_IO_FAILURE;
146cca6fc52SDaniel Fojt 
1478edacedfSDaniel Fojt 		if ((rec_version >> 8) != SSL3_VERSION_MAJOR)
1488edacedfSDaniel Fojt 			return TLS13_IO_RECORD_VERSION;
149cca6fc52SDaniel Fojt 		if (rec_len > TLS13_RECORD_MAX_CIPHERTEXT_LEN)
1508edacedfSDaniel Fojt 			return TLS13_IO_RECORD_OVERFLOW;
151cca6fc52SDaniel Fojt 
152cca6fc52SDaniel Fojt 		rec->content_type = content_type;
153cca6fc52SDaniel Fojt 		rec->version = rec_version;
154cca6fc52SDaniel Fojt 		rec->rec_len = rec_len;
155cca6fc52SDaniel Fojt 	}
156cca6fc52SDaniel Fojt 
157*de0e0e4dSAntonio Huete Jimenez 	if ((ret = tls_buffer_extend(rec->buf,
158cca6fc52SDaniel Fojt 	    TLS13_RECORD_HEADER_LEN + rec->rec_len, wire_read, wire_arg)) <= 0)
159cca6fc52SDaniel Fojt 		return ret;
160cca6fc52SDaniel Fojt 
161*de0e0e4dSAntonio Huete Jimenez 	if (!tls_buffer_finish(rec->buf, &rec->data, &rec->data_len))
162cca6fc52SDaniel Fojt 		return TLS13_IO_FAILURE;
163cca6fc52SDaniel Fojt 
164cca6fc52SDaniel Fojt 	return rec->data_len;
165cca6fc52SDaniel Fojt }
166cca6fc52SDaniel Fojt 
167cca6fc52SDaniel Fojt ssize_t
tls13_record_send(struct tls13_record * rec,tls_write_cb wire_write,void * wire_arg)168*de0e0e4dSAntonio Huete Jimenez tls13_record_send(struct tls13_record *rec, tls_write_cb wire_write,
169cca6fc52SDaniel Fojt     void *wire_arg)
170cca6fc52SDaniel Fojt {
171cca6fc52SDaniel Fojt 	ssize_t ret;
172cca6fc52SDaniel Fojt 
173cca6fc52SDaniel Fojt 	if (rec->data == NULL)
174cca6fc52SDaniel Fojt 		return TLS13_IO_FAILURE;
175cca6fc52SDaniel Fojt 
176cca6fc52SDaniel Fojt 	while (CBS_len(&rec->cbs) > 0) {
177cca6fc52SDaniel Fojt 		if ((ret = wire_write(CBS_data(&rec->cbs),
178cca6fc52SDaniel Fojt 		    CBS_len(&rec->cbs), wire_arg)) <= 0)
179cca6fc52SDaniel Fojt 			return ret;
180cca6fc52SDaniel Fojt 
181cca6fc52SDaniel Fojt 		if (!CBS_skip(&rec->cbs, ret))
182cca6fc52SDaniel Fojt 			return TLS13_IO_FAILURE;
183cca6fc52SDaniel Fojt 	}
184cca6fc52SDaniel Fojt 
185cca6fc52SDaniel Fojt 	return rec->data_len;
186cca6fc52SDaniel Fojt }
187