1*ee4250f6Sjsing /* $OpenBSD: tls_content.c,v 1.2 2022/11/11 17:15:27 jsing Exp $ */
28ccc3944Sjsing /*
38ccc3944Sjsing * Copyright (c) 2020 Joel Sing <jsing@openbsd.org>
48ccc3944Sjsing *
58ccc3944Sjsing * Permission to use, copy, modify, and distribute this software for any
68ccc3944Sjsing * purpose with or without fee is hereby granted, provided that the above
78ccc3944Sjsing * copyright notice and this permission notice appear in all copies.
88ccc3944Sjsing *
98ccc3944Sjsing * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
108ccc3944Sjsing * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
118ccc3944Sjsing * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
128ccc3944Sjsing * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
138ccc3944Sjsing * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
148ccc3944Sjsing * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
158ccc3944Sjsing * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
168ccc3944Sjsing */
178ccc3944Sjsing
188ccc3944Sjsing #include <stdlib.h>
198ccc3944Sjsing #include <string.h>
208ccc3944Sjsing
218ccc3944Sjsing #include "tls_content.h"
228ccc3944Sjsing
238ccc3944Sjsing /* Content from a TLS record. */
248ccc3944Sjsing struct tls_content {
258ccc3944Sjsing uint8_t type;
268ccc3944Sjsing uint16_t epoch;
278ccc3944Sjsing
288ccc3944Sjsing const uint8_t *data;
29*ee4250f6Sjsing size_t data_len;
308ccc3944Sjsing CBS cbs;
318ccc3944Sjsing };
328ccc3944Sjsing
338ccc3944Sjsing struct tls_content *
tls_content_new(void)348ccc3944Sjsing tls_content_new(void)
358ccc3944Sjsing {
368ccc3944Sjsing return calloc(1, sizeof(struct tls_content));
378ccc3944Sjsing }
388ccc3944Sjsing
398ccc3944Sjsing void
tls_content_clear(struct tls_content * content)408ccc3944Sjsing tls_content_clear(struct tls_content *content)
418ccc3944Sjsing {
42*ee4250f6Sjsing freezero((void *)content->data, content->data_len);
438ccc3944Sjsing memset(content, 0, sizeof(*content));
448ccc3944Sjsing }
458ccc3944Sjsing
468ccc3944Sjsing void
tls_content_free(struct tls_content * content)478ccc3944Sjsing tls_content_free(struct tls_content *content)
488ccc3944Sjsing {
498ccc3944Sjsing if (content == NULL)
508ccc3944Sjsing return;
518ccc3944Sjsing
528ccc3944Sjsing tls_content_clear(content);
538ccc3944Sjsing
548ccc3944Sjsing freezero(content, sizeof(struct tls_content));
558ccc3944Sjsing }
568ccc3944Sjsing
578ccc3944Sjsing CBS *
tls_content_cbs(struct tls_content * content)588ccc3944Sjsing tls_content_cbs(struct tls_content *content)
598ccc3944Sjsing {
608ccc3944Sjsing return &content->cbs;
618ccc3944Sjsing }
628ccc3944Sjsing
638ccc3944Sjsing int
tls_content_equal(struct tls_content * content,const uint8_t * buf,size_t n)648ccc3944Sjsing tls_content_equal(struct tls_content *content, const uint8_t *buf, size_t n)
658ccc3944Sjsing {
668ccc3944Sjsing return CBS_mem_equal(&content->cbs, buf, n);
678ccc3944Sjsing }
688ccc3944Sjsing
698ccc3944Sjsing size_t
tls_content_remaining(struct tls_content * content)708ccc3944Sjsing tls_content_remaining(struct tls_content *content)
718ccc3944Sjsing {
728ccc3944Sjsing return CBS_len(&content->cbs);
738ccc3944Sjsing }
748ccc3944Sjsing
758ccc3944Sjsing uint8_t
tls_content_type(struct tls_content * content)768ccc3944Sjsing tls_content_type(struct tls_content *content)
778ccc3944Sjsing {
788ccc3944Sjsing return content->type;
798ccc3944Sjsing }
808ccc3944Sjsing
818ccc3944Sjsing int
tls_content_dup_data(struct tls_content * content,uint8_t type,const uint8_t * data,size_t data_len)828ccc3944Sjsing tls_content_dup_data(struct tls_content *content, uint8_t type,
838ccc3944Sjsing const uint8_t *data, size_t data_len)
848ccc3944Sjsing {
858ccc3944Sjsing uint8_t *dup;
868ccc3944Sjsing
878ccc3944Sjsing if ((dup = calloc(1, data_len)) == NULL)
888ccc3944Sjsing return 0;
898ccc3944Sjsing memcpy(dup, data, data_len);
908ccc3944Sjsing
918ccc3944Sjsing tls_content_set_data(content, type, dup, data_len);
928ccc3944Sjsing
938ccc3944Sjsing return 1;
948ccc3944Sjsing }
958ccc3944Sjsing
968ccc3944Sjsing uint16_t
tls_content_epoch(struct tls_content * content)978ccc3944Sjsing tls_content_epoch(struct tls_content *content)
988ccc3944Sjsing {
998ccc3944Sjsing return content->epoch;
1008ccc3944Sjsing }
1018ccc3944Sjsing
1028ccc3944Sjsing void
tls_content_set_epoch(struct tls_content * content,uint16_t epoch)1038ccc3944Sjsing tls_content_set_epoch(struct tls_content *content, uint16_t epoch)
1048ccc3944Sjsing {
1058ccc3944Sjsing content->epoch = epoch;
1068ccc3944Sjsing }
1078ccc3944Sjsing
1088ccc3944Sjsing void
tls_content_set_data(struct tls_content * content,uint8_t type,const uint8_t * data,size_t data_len)1098ccc3944Sjsing tls_content_set_data(struct tls_content *content, uint8_t type,
1108ccc3944Sjsing const uint8_t *data, size_t data_len)
1118ccc3944Sjsing {
1128ccc3944Sjsing tls_content_clear(content);
1138ccc3944Sjsing
1148ccc3944Sjsing content->type = type;
1158ccc3944Sjsing content->data = data;
116*ee4250f6Sjsing content->data_len = data_len;
1178ccc3944Sjsing
118*ee4250f6Sjsing CBS_init(&content->cbs, content->data, content->data_len);
119*ee4250f6Sjsing }
120*ee4250f6Sjsing
121*ee4250f6Sjsing int
tls_content_set_bounds(struct tls_content * content,size_t offset,size_t len)122*ee4250f6Sjsing tls_content_set_bounds(struct tls_content *content, size_t offset, size_t len)
123*ee4250f6Sjsing {
124*ee4250f6Sjsing size_t content_len;
125*ee4250f6Sjsing
126*ee4250f6Sjsing content_len = offset + len;
127*ee4250f6Sjsing if (content_len < len)
128*ee4250f6Sjsing return 0;
129*ee4250f6Sjsing if (content_len > content->data_len)
130*ee4250f6Sjsing return 0;
131*ee4250f6Sjsing
132*ee4250f6Sjsing CBS_init(&content->cbs, content->data, content_len);
133*ee4250f6Sjsing return CBS_skip(&content->cbs, offset);
1348ccc3944Sjsing }
1358ccc3944Sjsing
1368ccc3944Sjsing static ssize_t
tls_content_read_internal(struct tls_content * content,uint8_t * buf,size_t n,int peek)1378ccc3944Sjsing tls_content_read_internal(struct tls_content *content, uint8_t *buf, size_t n,
1388ccc3944Sjsing int peek)
1398ccc3944Sjsing {
1408ccc3944Sjsing if (n > CBS_len(&content->cbs))
1418ccc3944Sjsing n = CBS_len(&content->cbs);
1428ccc3944Sjsing
1438ccc3944Sjsing /* XXX - CBS_memcpy? CBS_copy_bytes? */
1448ccc3944Sjsing memcpy(buf, CBS_data(&content->cbs), n);
1458ccc3944Sjsing
1468ccc3944Sjsing if (!peek) {
1478ccc3944Sjsing if (!CBS_skip(&content->cbs, n))
1488ccc3944Sjsing return -1;
1498ccc3944Sjsing }
1508ccc3944Sjsing
1518ccc3944Sjsing return n;
1528ccc3944Sjsing }
1538ccc3944Sjsing
1548ccc3944Sjsing ssize_t
tls_content_peek(struct tls_content * content,uint8_t * buf,size_t n)1558ccc3944Sjsing tls_content_peek(struct tls_content *content, uint8_t *buf, size_t n)
1568ccc3944Sjsing {
1578ccc3944Sjsing return tls_content_read_internal(content, buf, n, 1);
1588ccc3944Sjsing }
1598ccc3944Sjsing
1608ccc3944Sjsing ssize_t
tls_content_read(struct tls_content * content,uint8_t * buf,size_t n)1618ccc3944Sjsing tls_content_read(struct tls_content *content, uint8_t *buf, size_t n)
1628ccc3944Sjsing {
1638ccc3944Sjsing return tls_content_read_internal(content, buf, n, 0);
1648ccc3944Sjsing }
165