summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2022-02-18 17:30:13 +0000
committerjsing <>2022-02-18 17:30:13 +0000
commit8a99d590553fa0c8387169b9ba29360c3a52dab8 (patch)
treeb2a0af2ad0615017288f9b467da71f7c2e8ab3c9 /src
parenta72b3400b5022f9456bfb2f05ccf5d617c73fc62 (diff)
downloadopenbsd-8a99d590553fa0c8387169b9ba29360c3a52dab8.tar.gz
openbsd-8a99d590553fa0c8387169b9ba29360c3a52dab8.tar.bz2
openbsd-8a99d590553fa0c8387169b9ba29360c3a52dab8.zip
Clean up and simplify memory BIO code.
This is a first pass that uses sensible and consistent names for variables. Call the BIO 'bio' (instead of 'a', 'b', 'bp', or 'h'), drop a bunch of unnecessary casts, simplify some logic and add additional error checking. With input from and ok tb@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/bio/bss_mem.c263
1 files changed, 139 insertions, 124 deletions
diff --git a/src/lib/libcrypto/bio/bss_mem.c b/src/lib/libcrypto/bio/bss_mem.c
index 3632ffed0b..594351b92b 100644
--- a/src/lib/libcrypto/bio/bss_mem.c
+++ b/src/lib/libcrypto/bio/bss_mem.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bss_mem.c,v 1.18 2022/01/07 09:02:17 tb Exp $ */ 1/* $OpenBSD: bss_mem.c,v 1.19 2022/02/18 17:30:13 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -57,6 +57,7 @@
57 */ 57 */
58 58
59#include <errno.h> 59#include <errno.h>
60#include <limits.h>
60#include <stdio.h> 61#include <stdio.h>
61#include <string.h> 62#include <string.h>
62 63
@@ -66,13 +67,13 @@
66 67
67#include "bio_local.h" 68#include "bio_local.h"
68 69
69static int mem_write(BIO *h, const char *buf, int num); 70static int mem_new(BIO *bio);
70static int mem_read(BIO *h, char *buf, int size); 71static int mem_free(BIO *bio);
71static int mem_puts(BIO *h, const char *str); 72static int mem_write(BIO *bio, const char *in, int in_len);
72static int mem_gets(BIO *h, char *str, int size); 73static int mem_read(BIO *bio, char *out, int out_len);
73static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2); 74static int mem_puts(BIO *bio, const char *in);
74static int mem_new(BIO *h); 75static int mem_gets(BIO *bio, char *out, int out_len);
75static int mem_free(BIO *data); 76static long mem_ctrl(BIO *bio, int cmd, long arg1, void *arg2);
76 77
77static const BIO_METHOD mem_method = { 78static const BIO_METHOD mem_method = {
78 .type = BIO_TYPE_MEM, 79 .type = BIO_TYPE_MEM,
@@ -86,137 +87,157 @@ static const BIO_METHOD mem_method = {
86 .destroy = mem_free 87 .destroy = mem_free
87}; 88};
88 89
89/* bio->num is used to hold the value to return on 'empty', if it is 90/*
90 * 0, should_retry is not set */ 91 * bio->num is used to hold the value to return on 'empty', if it is
92 * 0, should_retry is not set.
93 */
91 94
92const BIO_METHOD * 95const BIO_METHOD *
93BIO_s_mem(void) 96BIO_s_mem(void)
94{ 97{
95 return (&mem_method); 98 return &mem_method;
96} 99}
97 100
98BIO * 101BIO *
99BIO_new_mem_buf(const void *buf, int len) 102BIO_new_mem_buf(const void *buf, int buf_len)
100{ 103{
101 BIO *ret; 104 BIO *bio;
102 BUF_MEM *b; 105 BUF_MEM *b;
103 size_t sz;
104 106
105 if (!buf) { 107 if (buf == NULL) {
106 BIOerror(BIO_R_NULL_PARAMETER); 108 BIOerror(BIO_R_NULL_PARAMETER);
107 return NULL; 109 return NULL;
108 } 110 }
109 sz = (len < 0) ? strlen(buf) : (size_t)len; 111 if (buf_len == -1)
110 if (!(ret = BIO_new(BIO_s_mem()))) 112 buf_len = strlen(buf);
113 if (buf_len < 0) {
114 BIOerror(BIO_R_INVALID_ARGUMENT);
115 return NULL;
116 }
117
118 if ((bio = BIO_new(BIO_s_mem())) == NULL)
111 return NULL; 119 return NULL;
112 b = (BUF_MEM *)ret->ptr; 120
121 b = bio->ptr;
113 b->data = (void *)buf; /* Trust in the BIO_FLAGS_MEM_RDONLY flag. */ 122 b->data = (void *)buf; /* Trust in the BIO_FLAGS_MEM_RDONLY flag. */
114 b->length = sz; 123 b->length = buf_len;
115 b->max = sz; 124 b->max = buf_len;
116 ret->flags |= BIO_FLAGS_MEM_RDONLY; 125 bio->flags |= BIO_FLAGS_MEM_RDONLY;
117 /* Since this is static data retrying wont help */ 126 /* Since this is static data retrying will not help. */
118 ret->num = 0; 127 bio->num = 0;
119 return ret; 128
129 return bio;
120} 130}
121 131
122static int 132static int
123mem_new(BIO *bi) 133mem_new(BIO *bio)
124{ 134{
125 BUF_MEM *b; 135 BUF_MEM *b;
126 136
127 if ((b = BUF_MEM_new()) == NULL) 137 if ((b = BUF_MEM_new()) == NULL)
128 return (0); 138 return 0;
129 bi->shutdown = 1; 139
130 bi->init = 1; 140 bio->shutdown = 1;
131 bi->num = -1; 141 bio->init = 1;
132 bi->ptr = (char *)b; 142 bio->num = -1;
133 return (1); 143 bio->ptr = b;
144
145 return 1;
134} 146}
135 147
136static int 148static int
137mem_free(BIO *a) 149mem_free(BIO *bio)
138{ 150{
139 if (a == NULL) 151 BUF_MEM *b;
140 return (0); 152
141 if (a->shutdown) { 153 if (bio == NULL)
142 if ((a->init) && (a->ptr != NULL)) { 154 return 0;
143 BUF_MEM *b; 155 if (!bio->shutdown || !bio->init || bio->ptr == NULL)
144 b = (BUF_MEM *)a->ptr; 156 return 1;
145 if (a->flags & BIO_FLAGS_MEM_RDONLY) 157
146 b->data = NULL; 158 b = bio->ptr;
147 BUF_MEM_free(b); 159 if (bio->flags & BIO_FLAGS_MEM_RDONLY)
148 a->ptr = NULL; 160 b->data = NULL;
149 } 161 BUF_MEM_free(b);
150 } 162 bio->ptr = NULL;
151 return (1); 163
164 return 1;
152} 165}
153 166
154static int 167static int
155mem_read(BIO *b, char *out, int outl) 168mem_read(BIO *bio, char *out, int out_len)
156{ 169{
157 int ret = -1; 170 BUF_MEM *bm = bio->ptr;
158 BUF_MEM *bm; 171
159 172 BIO_clear_retry_flags(bio);
160 bm = (BUF_MEM *)b->ptr; 173
161 BIO_clear_retry_flags(b); 174 if (out == NULL || out_len <= 0)
162 ret = (outl >=0 && (size_t)outl > bm->length) ? (int)bm->length : outl; 175 return 0;
163 if ((out != NULL) && (ret > 0)) { 176
164 memcpy(out, bm->data, ret); 177 if ((size_t)out_len > bm->length)
165 bm->length -= ret; 178 out_len = bm->length;
166 if (b->flags & BIO_FLAGS_MEM_RDONLY) 179
167 bm->data += ret; 180 if (out_len == 0) {
168 else { 181 if (bio->num != 0)
169 memmove(&(bm->data[0]), &(bm->data[ret]), bm->length); 182 BIO_set_retry_read(bio);
170 } 183 return bio->num;
171 } else if (bm->length == 0) {
172 ret = b->num;
173 if (ret != 0)
174 BIO_set_retry_read(b);
175 } 184 }
176 return (ret); 185
186 memcpy(out, bm->data, out_len);
187 bm->length -= out_len;
188 if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
189 bm->data += out_len;
190 } else {
191 memmove(&(bm->data[0]), &(bm->data[out_len]),
192 bm->length);
193 }
194 return out_len;
177} 195}
178 196
179static int 197static int
180mem_write(BIO *b, const char *in, int inl) 198mem_write(BIO *bio, const char *in, int in_len)
181{ 199{
182 int ret = -1; 200 BUF_MEM *bm = bio->ptr;
183 int blen; 201 size_t buf_len;
184 BUF_MEM *bm;
185 202
186 bm = (BUF_MEM *)b->ptr; 203 BIO_clear_retry_flags(bio);
187 if (in == NULL) { 204
188 BIOerror(BIO_R_NULL_PARAMETER); 205 if (in == NULL || in_len <= 0)
189 goto end; 206 return 0;
190 }
191 207
192 if (b->flags & BIO_FLAGS_MEM_RDONLY) { 208 if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
193 BIOerror(BIO_R_WRITE_TO_READ_ONLY_BIO); 209 BIOerror(BIO_R_WRITE_TO_READ_ONLY_BIO);
194 goto end; 210 return -1;
195 } 211 }
196 212
197 BIO_clear_retry_flags(b); 213 /*
198 blen = bm->length; 214 * Check for overflow and ensure we do not exceed an int, otherwise we
199 if (BUF_MEM_grow_clean(bm, blen + inl) != (blen + inl)) 215 * cannot tell if BUF_MEM_grow_clean() succeeded.
200 goto end; 216 */
201 memcpy(&(bm->data[blen]), in, inl); 217 buf_len = bm->length + in_len;
202 ret = inl; 218 if (buf_len < bm->length || buf_len > INT_MAX)
203end: 219 return -1;
204 return (ret); 220
221 if (BUF_MEM_grow_clean(bm, buf_len) != buf_len)
222 return -1;
223
224 memcpy(&bm->data[buf_len - in_len], in, in_len);
225
226 return in_len;
205} 227}
206 228
207static long 229static long
208mem_ctrl(BIO *b, int cmd, long num, void *ptr) 230mem_ctrl(BIO *bio, int cmd, long num, void *ptr)
209{ 231{
232 BUF_MEM *bm = bio->ptr;
210 long ret = 1; 233 long ret = 1;
211 char **pptr; 234 char **pptr;
212 235
213 BUF_MEM *bm = (BUF_MEM *)b->ptr;
214
215 switch (cmd) { 236 switch (cmd) {
216 case BIO_CTRL_RESET: 237 case BIO_CTRL_RESET:
217 if (bm->data != NULL) { 238 if (bm->data != NULL) {
218 /* For read only case reset to the start again */ 239 /* For read only case reset to the start again */
219 if (b->flags & BIO_FLAGS_MEM_RDONLY) { 240 if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
220 bm->data -= bm->max - bm->length; 241 bm->data -= bm->max - bm->length;
221 bm->length = bm->max; 242 bm->length = bm->max;
222 } else { 243 } else {
@@ -229,19 +250,19 @@ mem_ctrl(BIO *b, int cmd, long num, void *ptr)
229 ret = (long)(bm->length == 0); 250 ret = (long)(bm->length == 0);
230 break; 251 break;
231 case BIO_C_SET_BUF_MEM_EOF_RETURN: 252 case BIO_C_SET_BUF_MEM_EOF_RETURN:
232 b->num = (int)num; 253 bio->num = (int)num;
233 break; 254 break;
234 case BIO_CTRL_INFO: 255 case BIO_CTRL_INFO:
235 ret = (long)bm->length;
236 if (ptr != NULL) { 256 if (ptr != NULL) {
237 pptr = (char **)ptr; 257 pptr = (char **)ptr;
238 *pptr = (char *)&(bm->data[0]); 258 *pptr = (char *)bm->data;
239 } 259 }
260 ret = (long)bm->length;
240 break; 261 break;
241 case BIO_C_SET_BUF_MEM: 262 case BIO_C_SET_BUF_MEM:
242 mem_free(b); 263 mem_free(bio);
243 b->shutdown = (int)num; 264 bio->shutdown = (int)num;
244 b->ptr = ptr; 265 bio->ptr = ptr;
245 break; 266 break;
246 case BIO_C_GET_BUF_MEM_PTR: 267 case BIO_C_GET_BUF_MEM_PTR:
247 if (ptr != NULL) { 268 if (ptr != NULL) {
@@ -250,12 +271,11 @@ mem_ctrl(BIO *b, int cmd, long num, void *ptr)
250 } 271 }
251 break; 272 break;
252 case BIO_CTRL_GET_CLOSE: 273 case BIO_CTRL_GET_CLOSE:
253 ret = (long)b->shutdown; 274 ret = (long)bio->shutdown;
254 break; 275 break;
255 case BIO_CTRL_SET_CLOSE: 276 case BIO_CTRL_SET_CLOSE:
256 b->shutdown = (int)num; 277 bio->shutdown = (int)num;
257 break; 278 break;
258
259 case BIO_CTRL_WPENDING: 279 case BIO_CTRL_WPENDING:
260 ret = 0L; 280 ret = 0L;
261 break; 281 break;
@@ -272,27 +292,29 @@ mem_ctrl(BIO *b, int cmd, long num, void *ptr)
272 ret = 0; 292 ret = 0;
273 break; 293 break;
274 } 294 }
275 return (ret); 295 return ret;
276} 296}
277 297
278static int 298static int
279mem_gets(BIO *bp, char *buf, int size) 299mem_gets(BIO *bio, char *out, int out_len)
280{ 300{
281 int i, j; 301 BUF_MEM *bm = bio->ptr;
282 int ret = -1; 302 int i, out_max;
283 char *p; 303 char *p;
284 BUF_MEM *bm = (BUF_MEM *)bp->ptr; 304 int ret = -1;
285 305
286 BIO_clear_retry_flags(bp); 306 BIO_clear_retry_flags(bio);
287 j = bm->length; 307
288 if ((size - 1) < j) 308 out_max = bm->length;
289 j = size - 1; 309 if (out_len - 1 < out_max)
290 if (j <= 0) { 310 out_max = out_len - 1;
291 *buf = '\0'; 311 if (out_max <= 0) {
312 *out = '\0';
292 return 0; 313 return 0;
293 } 314 }
315
294 p = bm->data; 316 p = bm->data;
295 for (i = 0; i < j; i++) { 317 for (i = 0; i < out_max; i++) {
296 if (p[i] == '\n') { 318 if (p[i] == '\n') {
297 i++; 319 i++;
298 break; 320 break;
@@ -300,24 +322,17 @@ mem_gets(BIO *bp, char *buf, int size)
300 } 322 }
301 323
302 /* 324 /*
303 * i is now the max num of bytes to copy, either j or up to 325 * i is now the max num of bytes to copy, either out_max or up to and
304 * and including the first newline 326 * including the first newline
305 */ 327 */
328 if ((ret = mem_read(bio, out, i)) > 0)
329 out[ret] = '\0';
306 330
307 i = mem_read(bp, buf, i); 331 return ret;
308 if (i > 0)
309 buf[i] = '\0';
310 ret = i;
311 return (ret);
312} 332}
313 333
314static int 334static int
315mem_puts(BIO *bp, const char *str) 335mem_puts(BIO *bio, const char *in)
316{ 336{
317 int n, ret; 337 return mem_write(bio, in, strlen(in));
318
319 n = strlen(str);
320 ret = mem_write(bp, str, n);
321 /* memory semantics is that it will always work */
322 return (ret);
323} 338}