xref: /openbsd-src/lib/libssl/tls_content.c (revision ee4250f602ddc943dc6358c3db4ef7172118489a)
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