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