summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2022-07-22 19:33:53 +0000
committerjsing <>2022-07-22 19:33:53 +0000
commit6612d759045c7571f6be2ff1366a704ba82eb216 (patch)
tree621585d83424bc407b8aa48aef0a859751335e14
parenteb96f22ae583afb63244c20ef4b563fcdd868d57 (diff)
downloadopenbsd-6612d759045c7571f6be2ff1366a704ba82eb216.tar.gz
openbsd-6612d759045c7571f6be2ff1366a704ba82eb216.tar.bz2
openbsd-6612d759045c7571f6be2ff1366a704ba82eb216.zip
Add read and write support to tls_buffer.
tls_buffer was original created for a specific use case, namely reading in length prefixed messages. This adds read and write support, along with a capacity limit, allowing it to be used in additional use cases. ok beck@ tb@
-rw-r--r--src/lib/libssl/tls13_handshake_msg.c5
-rw-r--r--src/lib/libssl/tls13_record.c5
-rw-r--r--src/lib/libssl/tls_buffer.c133
-rw-r--r--src/lib/libssl/tls_internal.h9
4 files changed, 139 insertions, 13 deletions
diff --git a/src/lib/libssl/tls13_handshake_msg.c b/src/lib/libssl/tls13_handshake_msg.c
index 946ccaccd6..134cfb2173 100644
--- a/src/lib/libssl/tls13_handshake_msg.c
+++ b/src/lib/libssl/tls13_handshake_msg.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls13_handshake_msg.c,v 1.5 2022/07/20 06:32:24 jsing Exp $ */ 1/* $OpenBSD: tls13_handshake_msg.c,v 1.6 2022/07/22 19:33:53 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -136,7 +136,8 @@ tls13_handshake_msg_recv(struct tls13_handshake_msg *msg,
136 tls13_handshake_msg_read_cb, rl)) <= 0) 136 tls13_handshake_msg_read_cb, rl)) <= 0)
137 return ret; 137 return ret;
138 138
139 tls_buffer_cbs(msg->buf, &cbs); 139 if (!tls_buffer_data(msg->buf, &cbs))
140 return TLS13_IO_FAILURE;
140 141
141 if (!CBS_get_u8(&cbs, &msg_type)) 142 if (!CBS_get_u8(&cbs, &msg_type))
142 return TLS13_IO_FAILURE; 143 return TLS13_IO_FAILURE;
diff --git a/src/lib/libssl/tls13_record.c b/src/lib/libssl/tls13_record.c
index 2c744668e5..dbc835c546 100644
--- a/src/lib/libssl/tls13_record.c
+++ b/src/lib/libssl/tls13_record.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls13_record.c,v 1.9 2021/10/23 13:12:14 jsing Exp $ */ 1/* $OpenBSD: tls13_record.c,v 1.10 2022/07/22 19:33:53 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -134,7 +134,8 @@ tls13_record_recv(struct tls13_record *rec, tls_read_cb wire_read,
134 TLS13_RECORD_HEADER_LEN, wire_read, wire_arg)) <= 0) 134 TLS13_RECORD_HEADER_LEN, wire_read, wire_arg)) <= 0)
135 return ret; 135 return ret;
136 136
137 tls_buffer_cbs(rec->buf, &cbs); 137 if (!tls_buffer_data(rec->buf, &cbs))
138 return TLS13_IO_FAILURE;
138 139
139 if (!CBS_get_u8(&cbs, &content_type)) 140 if (!CBS_get_u8(&cbs, &content_type))
140 return TLS13_IO_FAILURE; 141 return TLS13_IO_FAILURE;
diff --git a/src/lib/libssl/tls_buffer.c b/src/lib/libssl/tls_buffer.c
index 9bb6b62e51..f70cfbc1a0 100644
--- a/src/lib/libssl/tls_buffer.c
+++ b/src/lib/libssl/tls_buffer.c
@@ -1,6 +1,6 @@
1/* $OpenBSD: tls_buffer.c,v 1.2 2022/07/20 06:32:24 jsing Exp $ */ 1/* $OpenBSD: tls_buffer.c,v 1.3 2022/07/22 19:33:53 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2018, 2019, 2022 Joel Sing <jsing@openbsd.org>
4 * 4 *
5 * Permission to use, copy, modify, and distribute this software for any 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 6 * purpose with or without fee is hereby granted, provided that the above
@@ -21,8 +21,11 @@
21#include "bytestring.h" 21#include "bytestring.h"
22#include "tls_internal.h" 22#include "tls_internal.h"
23 23
24#define TLS_BUFFER_CAPACITY_LIMIT (1024 * 1024)
25
24struct tls_buffer { 26struct tls_buffer {
25 size_t capacity; 27 size_t capacity;
28 size_t capacity_limit;
26 uint8_t *data; 29 uint8_t *data;
27 size_t len; 30 size_t len;
28 size_t offset; 31 size_t offset;
@@ -38,6 +41,8 @@ tls_buffer_new(size_t init_size)
38 if ((buf = calloc(1, sizeof(struct tls_buffer))) == NULL) 41 if ((buf = calloc(1, sizeof(struct tls_buffer))) == NULL)
39 goto err; 42 goto err;
40 43
44 buf->capacity_limit = TLS_BUFFER_CAPACITY_LIMIT;
45
41 if (!tls_buffer_resize(buf, init_size)) 46 if (!tls_buffer_resize(buf, init_size))
42 goto err; 47 goto err;
43 48
@@ -50,32 +55,76 @@ tls_buffer_new(size_t init_size)
50} 55}
51 56
52void 57void
58tls_buffer_clear(struct tls_buffer *buf)
59{
60 freezero(buf->data, buf->capacity);
61
62 buf->data = NULL;
63 buf->capacity = 0;
64 buf->len = 0;
65 buf->offset = 0;
66}
67
68void
53tls_buffer_free(struct tls_buffer *buf) 69tls_buffer_free(struct tls_buffer *buf)
54{ 70{
55 if (buf == NULL) 71 if (buf == NULL)
56 return; 72 return;
57 73
58 freezero(buf->data, buf->capacity); 74 tls_buffer_clear(buf);
75
59 freezero(buf, sizeof(struct tls_buffer)); 76 freezero(buf, sizeof(struct tls_buffer));
60} 77}
61 78
62static int 79static int
80tls_buffer_grow(struct tls_buffer *buf, size_t capacity)
81{
82 if (buf->capacity >= capacity)
83 return 1;
84
85 return tls_buffer_resize(buf, capacity);
86}
87
88static int
63tls_buffer_resize(struct tls_buffer *buf, size_t capacity) 89tls_buffer_resize(struct tls_buffer *buf, size_t capacity)
64{ 90{
65 uint8_t *data; 91 uint8_t *data;
66 92
93 /*
94 * XXX - Consider maintaining a minimum size and growing more
95 * intelligently (rather than exactly).
96 */
67 if (buf->capacity == capacity) 97 if (buf->capacity == capacity)
68 return 1; 98 return 1;
69 99
100 if (capacity > buf->capacity_limit)
101 return 0;
102
70 if ((data = recallocarray(buf->data, buf->capacity, capacity, 1)) == NULL) 103 if ((data = recallocarray(buf->data, buf->capacity, capacity, 1)) == NULL)
71 return 0; 104 return 0;
72 105
73 buf->data = data; 106 buf->data = data;
74 buf->capacity = capacity; 107 buf->capacity = capacity;
75 108
109 /* Ensure that len and offset are valid if capacity decreased. */
110 if (buf->len > buf->capacity)
111 buf->len = buf->capacity;
112 if (buf->offset > buf->len)
113 buf->offset = buf->len;
114
76 return 1; 115 return 1;
77} 116}
78 117
118void
119tls_buffer_set_capacity_limit(struct tls_buffer *buf, size_t limit)
120{
121 /*
122 * XXX - do we want to force a resize if this limit is less than current
123 * capacity... and what do we do with existing data? Force a clear?
124 */
125 buf->capacity_limit = limit;
126}
127
79ssize_t 128ssize_t
80tls_buffer_extend(struct tls_buffer *buf, size_t len, 129tls_buffer_extend(struct tls_buffer *buf, size_t len,
81 tls_read_cb read_cb, void *cb_arg) 130 tls_read_cb read_cb, void *cb_arg)
@@ -106,10 +155,79 @@ tls_buffer_extend(struct tls_buffer *buf, size_t len,
106 } 155 }
107} 156}
108 157
109void 158ssize_t
110tls_buffer_cbs(struct tls_buffer *buf, CBS *cbs) 159tls_buffer_read(struct tls_buffer *buf, uint8_t *rbuf, size_t n)
160{
161 if (buf->offset > buf->len)
162 return TLS_IO_FAILURE;
163
164 if (buf->offset == buf->len)
165 return TLS_IO_WANT_POLLIN;
166
167 if (n > buf->len - buf->offset)
168 n = buf->len - buf->offset;
169
170 memcpy(rbuf, &buf->data[buf->offset], n);
171
172 buf->offset += n;
173
174 return n;
175}
176
177ssize_t
178tls_buffer_write(struct tls_buffer *buf, const uint8_t *wbuf, size_t n)
179{
180 if (buf->offset > buf->len)
181 return TLS_IO_FAILURE;
182
183 /*
184 * To avoid continually growing the buffer, pull data up to the
185 * start of the buffer. If all data has been read then we can simply
186 * reset, otherwise wait until we're going to save at least 4KB of
187 * memory to reduce overhead.
188 */
189 if (buf->offset == buf->len) {
190 buf->len = 0;
191 buf->offset = 0;
192 }
193 if (buf->offset >= 4096) {
194 memmove(buf->data, &buf->data[buf->offset],
195 buf->len - buf->offset);
196 buf->len -= buf->offset;
197 buf->offset = 0;
198 }
199
200 if (buf->len > SIZE_MAX - n)
201 return TLS_IO_FAILURE;
202 if (!tls_buffer_grow(buf, buf->len + n))
203 return TLS_IO_FAILURE;
204
205 memcpy(&buf->data[buf->len], wbuf, n);
206
207 buf->len += n;
208
209 return n;
210}
211
212int
213tls_buffer_append(struct tls_buffer *buf, const uint8_t *wbuf, size_t n)
214{
215 return tls_buffer_write(buf, wbuf, n) == n;
216}
217
218int
219tls_buffer_data(struct tls_buffer *buf, CBS *out_cbs)
111{ 220{
112 CBS_init(cbs, buf->data, buf->len); 221 CBS cbs;
222
223 CBS_init(&cbs, buf->data, buf->len);
224
225 if (!CBS_skip(&cbs, buf->offset))
226 return 0;
227
228 CBS_dup(&cbs, out_cbs);
229
230 return 1;
113} 231}
114 232
115int 233int
@@ -121,9 +239,10 @@ tls_buffer_finish(struct tls_buffer *buf, uint8_t **out, size_t *out_len)
121 *out = buf->data; 239 *out = buf->data;
122 *out_len = buf->len; 240 *out_len = buf->len;
123 241
124 buf->capacity = 0;
125 buf->data = NULL; 242 buf->data = NULL;
243 buf->capacity = 0;
126 buf->len = 0; 244 buf->len = 0;
245 buf->offset = 0;
127 246
128 return 1; 247 return 1;
129} 248}
diff --git a/src/lib/libssl/tls_internal.h b/src/lib/libssl/tls_internal.h
index ac2d14da48..88dae9e67e 100644
--- a/src/lib/libssl/tls_internal.h
+++ b/src/lib/libssl/tls_internal.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls_internal.h,v 1.7 2022/07/20 06:32:24 jsing Exp $ */ 1/* $OpenBSD: tls_internal.h,v 1.8 2022/07/22 19:33:53 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2018, 2019, 2021 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2018, 2019, 2021 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -47,10 +47,15 @@ typedef ssize_t (*tls_flush_cb)(void *_cb_arg);
47struct tls_buffer; 47struct tls_buffer;
48 48
49struct tls_buffer *tls_buffer_new(size_t init_size); 49struct tls_buffer *tls_buffer_new(size_t init_size);
50void tls_buffer_clear(struct tls_buffer *buf);
50void tls_buffer_free(struct tls_buffer *buf); 51void tls_buffer_free(struct tls_buffer *buf);
52void tls_buffer_set_capacity_limit(struct tls_buffer *buf, size_t limit);
51ssize_t tls_buffer_extend(struct tls_buffer *buf, size_t len, 53ssize_t tls_buffer_extend(struct tls_buffer *buf, size_t len,
52 tls_read_cb read_cb, void *cb_arg); 54 tls_read_cb read_cb, void *cb_arg);
53void tls_buffer_cbs(struct tls_buffer *buf, CBS *cbs); 55ssize_t tls_buffer_read(struct tls_buffer *buf, uint8_t *rbuf, size_t n);
56ssize_t tls_buffer_write(struct tls_buffer *buf, const uint8_t *wbuf, size_t n);
57int tls_buffer_append(struct tls_buffer *buf, const uint8_t *wbuf, size_t n);
58int tls_buffer_data(struct tls_buffer *buf, CBS *cbs);
54int tls_buffer_finish(struct tls_buffer *buf, uint8_t **out, size_t *out_len); 59int tls_buffer_finish(struct tls_buffer *buf, uint8_t **out, size_t *out_len);
55 60
56/* 61/*