1 /* $OpenBSD: tls13_record.c,v 1.6 2020/05/11 18:08:11 jsing Exp $ */
3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
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.
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.
20 #include "tls13_internal.h"
21 #include "tls13_record.h"
31 struct tls13_buffer *buf;
35 tls13_record_new(void)
37 struct tls13_record *rec = NULL;
39 if ((rec = calloc(1, sizeof(struct tls13_record))) == NULL)
41 if ((rec->buf = tls13_buffer_new(TLS13_RECORD_MAX_LEN)) == NULL)
47 tls13_record_free(rec);
53 tls13_record_free(struct tls13_record *rec)
58 tls13_buffer_free(rec->buf);
60 freezero(rec->data, rec->data_len);
61 freezero(rec, sizeof(struct tls13_record));
65 tls13_record_version(struct tls13_record *rec)
71 tls13_record_content_type(struct tls13_record *rec)
73 return rec->content_type;
77 tls13_record_header(struct tls13_record *rec, CBS *cbs)
79 if (rec->data_len < TLS13_RECORD_HEADER_LEN)
82 CBS_init(cbs, rec->data, TLS13_RECORD_HEADER_LEN);
88 tls13_record_content(struct tls13_record *rec, CBS *cbs)
92 tls13_record_data(rec, &content);
94 if (!CBS_skip(&content, TLS13_RECORD_HEADER_LEN))
97 CBS_dup(&content, cbs);
103 tls13_record_data(struct tls13_record *rec, CBS *cbs)
105 CBS_init(cbs, rec->data, rec->data_len);
109 tls13_record_set_data(struct tls13_record *rec, uint8_t *data, size_t data_len)
111 if (data_len > TLS13_RECORD_MAX_LEN)
114 freezero(rec->data, rec->data_len);
116 rec->data_len = data_len;
117 CBS_init(&rec->cbs, rec->data, rec->data_len);
123 tls13_record_recv(struct tls13_record *rec, tls13_read_cb wire_read,
126 uint16_t rec_len, rec_version;
127 uint8_t content_type;
131 if (rec->data != NULL)
132 return TLS13_IO_FAILURE;
134 if (rec->content_type == 0) {
135 if ((ret = tls13_buffer_extend(rec->buf,
136 TLS13_RECORD_HEADER_LEN, wire_read, wire_arg)) <= 0)
139 tls13_buffer_cbs(rec->buf, &cbs);
141 if (!CBS_get_u8(&cbs, &content_type))
142 return TLS13_IO_FAILURE;
143 if (!CBS_get_u16(&cbs, &rec_version))
144 return TLS13_IO_FAILURE;
145 if (!CBS_get_u16(&cbs, &rec_len))
146 return TLS13_IO_FAILURE;
148 if ((rec_version >> 8) != SSL3_VERSION_MAJOR)
149 return TLS13_IO_RECORD_VERSION;
150 if (rec_len > TLS13_RECORD_MAX_CIPHERTEXT_LEN)
151 return TLS13_IO_RECORD_OVERFLOW;
153 rec->content_type = content_type;
154 rec->version = rec_version;
155 rec->rec_len = rec_len;
158 if ((ret = tls13_buffer_extend(rec->buf,
159 TLS13_RECORD_HEADER_LEN + rec->rec_len, wire_read, wire_arg)) <= 0)
162 if (!tls13_buffer_finish(rec->buf, &rec->data, &rec->data_len))
163 return TLS13_IO_FAILURE;
165 return rec->data_len;
169 tls13_record_send(struct tls13_record *rec, tls13_write_cb wire_write,
174 if (rec->data == NULL)
175 return TLS13_IO_FAILURE;
177 while (CBS_len(&rec->cbs) > 0) {
178 if ((ret = wire_write(CBS_data(&rec->cbs),
179 CBS_len(&rec->cbs), wire_arg)) <= 0)
182 if (!CBS_skip(&rec->cbs, ret))
183 return TLS13_IO_FAILURE;
186 return rec->data_len;