diff options
Diffstat (limited to 'src/lib/libcrypto/bio/bss_bio.c')
-rw-r--r-- | src/lib/libcrypto/bio/bss_bio.c | 546 |
1 files changed, 261 insertions, 285 deletions
diff --git a/src/lib/libcrypto/bio/bss_bio.c b/src/lib/libcrypto/bio/bss_bio.c index 52ef0ebcb3..a74fcfdabc 100644 --- a/src/lib/libcrypto/bio/bss_bio.c +++ b/src/lib/libcrypto/bio/bss_bio.c | |||
@@ -103,8 +103,7 @@ static int bio_puts(BIO *bio, const char *str); | |||
103 | static int bio_make_pair(BIO *bio1, BIO *bio2); | 103 | static int bio_make_pair(BIO *bio1, BIO *bio2); |
104 | static void bio_destroy_pair(BIO *bio); | 104 | static void bio_destroy_pair(BIO *bio); |
105 | 105 | ||
106 | static BIO_METHOD methods_biop = | 106 | static BIO_METHOD methods_biop = { |
107 | { | ||
108 | BIO_TYPE_BIO, | 107 | BIO_TYPE_BIO, |
109 | "BIO pair", | 108 | "BIO pair", |
110 | bio_write, | 109 | bio_write, |
@@ -117,50 +116,51 @@ static BIO_METHOD methods_biop = | |||
117 | NULL /* no bio_callback_ctrl */ | 116 | NULL /* no bio_callback_ctrl */ |
118 | }; | 117 | }; |
119 | 118 | ||
120 | BIO_METHOD *BIO_s_bio(void) | 119 | BIO_METHOD |
121 | { | 120 | *BIO_s_bio(void) |
121 | { | ||
122 | return &methods_biop; | 122 | return &methods_biop; |
123 | } | 123 | } |
124 | |||
125 | struct bio_bio_st { | ||
126 | BIO *peer; /* NULL if buf == NULL. | ||
127 | * If peer != NULL, then peer->ptr is also a bio_bio_st, | ||
128 | * and its "peer" member points back to us. | ||
129 | * peer != NULL iff init != 0 in the BIO. */ | ||
124 | 130 | ||
125 | struct bio_bio_st | ||
126 | { | ||
127 | BIO *peer; /* NULL if buf == NULL. | ||
128 | * If peer != NULL, then peer->ptr is also a bio_bio_st, | ||
129 | * and its "peer" member points back to us. | ||
130 | * peer != NULL iff init != 0 in the BIO. */ | ||
131 | |||
132 | /* This is for what we write (i.e. reading uses peer's struct): */ | 131 | /* This is for what we write (i.e. reading uses peer's struct): */ |
133 | int closed; /* valid iff peer != NULL */ | 132 | int closed; /* valid iff peer != NULL */ |
134 | size_t len; /* valid iff buf != NULL; 0 if peer == NULL */ | 133 | size_t len; /* valid iff buf != NULL; 0 if peer == NULL */ |
135 | size_t offset; /* valid iff buf != NULL; 0 if len == 0 */ | 134 | size_t offset; /* valid iff buf != NULL; 0 if len == 0 */ |
136 | size_t size; | 135 | size_t size; |
137 | char *buf; /* "size" elements (if != NULL) */ | 136 | char *buf; /* "size" elements (if != NULL) */ |
138 | 137 | ||
139 | size_t request; /* valid iff peer != NULL; 0 if len != 0, | 138 | size_t request; /* valid iff peer != NULL; 0 if len != 0, |
140 | * otherwise set by peer to number of bytes | 139 | * otherwise set by peer to number of bytes |
141 | * it (unsuccessfully) tried to read, | 140 | * it (unsuccessfully) tried to read, |
142 | * never more than buffer space (size-len) warrants. */ | 141 | * never more than buffer space (size-len) warrants. */ |
143 | }; | 142 | }; |
144 | 143 | ||
145 | static int bio_new(BIO *bio) | 144 | static int |
146 | { | 145 | bio_new(BIO *bio) |
146 | { | ||
147 | struct bio_bio_st *b; | 147 | struct bio_bio_st *b; |
148 | 148 | ||
149 | b = OPENSSL_malloc(sizeof *b); | 149 | b = OPENSSL_malloc(sizeof *b); |
150 | if (b == NULL) | 150 | if (b == NULL) |
151 | return 0; | 151 | return 0; |
152 | 152 | ||
153 | b->peer = NULL; | 153 | b->peer = NULL; |
154 | b->size = 17*1024; /* enough for one TLS record (just a default) */ | 154 | b->size = 17 * 1024; /* enough for one TLS record (just a default) */ |
155 | b->buf = NULL; | 155 | b->buf = NULL; |
156 | 156 | ||
157 | bio->ptr = b; | 157 | bio->ptr = b; |
158 | return 1; | 158 | return 1; |
159 | } | 159 | } |
160 | 160 | ||
161 | 161 | static int | |
162 | static int bio_free(BIO *bio) | 162 | bio_free(BIO *bio) |
163 | { | 163 | { |
164 | struct bio_bio_st *b; | 164 | struct bio_bio_st *b; |
165 | 165 | ||
166 | if (bio == NULL) | 166 | if (bio == NULL) |
@@ -171,21 +171,21 @@ static int bio_free(BIO *bio) | |||
171 | 171 | ||
172 | if (b->peer) | 172 | if (b->peer) |
173 | bio_destroy_pair(bio); | 173 | bio_destroy_pair(bio); |
174 | 174 | ||
175 | if (b->buf != NULL) | 175 | if (b->buf != NULL) { |
176 | { | ||
177 | OPENSSL_free(b->buf); | 176 | OPENSSL_free(b->buf); |
178 | } | 177 | } |
179 | 178 | ||
180 | OPENSSL_free(b); | 179 | OPENSSL_free(b); |
181 | 180 | ||
182 | return 1; | 181 | return 1; |
183 | } | 182 | } |
184 | 183 | ||
185 | 184 | ||
186 | 185 | ||
187 | static int bio_read(BIO *bio, char *buf, int size_) | 186 | static int |
188 | { | 187 | bio_read(BIO *bio, char *buf, int size_) |
188 | { | ||
189 | size_t size = size_; | 189 | size_t size = size_; |
190 | size_t rest; | 190 | size_t rest; |
191 | struct bio_bio_st *b, *peer_b; | 191 | struct bio_bio_st *b, *peer_b; |
@@ -207,12 +207,10 @@ static int bio_read(BIO *bio, char *buf, int size_) | |||
207 | if (buf == NULL || size == 0) | 207 | if (buf == NULL || size == 0) |
208 | return 0; | 208 | return 0; |
209 | 209 | ||
210 | if (peer_b->len == 0) | 210 | if (peer_b->len == 0) { |
211 | { | ||
212 | if (peer_b->closed) | 211 | if (peer_b->closed) |
213 | return 0; /* writer has closed, and no data is left */ | 212 | return 0; /* writer has closed, and no data is left */ |
214 | else | 213 | else { |
215 | { | ||
216 | BIO_set_retry_read(bio); /* buffer is empty */ | 214 | BIO_set_retry_read(bio); /* buffer is empty */ |
217 | if (size <= peer_b->size) | 215 | if (size <= peer_b->size) |
218 | peer_b->request = size; | 216 | peer_b->request = size; |
@@ -221,22 +219,22 @@ static int bio_read(BIO *bio, char *buf, int size_) | |||
221 | * deliver in one write */ | 219 | * deliver in one write */ |
222 | peer_b->request = peer_b->size; | 220 | peer_b->request = peer_b->size; |
223 | return -1; | 221 | return -1; |
224 | } | ||
225 | } | 222 | } |
223 | } | ||
226 | 224 | ||
227 | /* we can read */ | 225 | /* we can read */ |
228 | if (peer_b->len < size) | 226 | if (peer_b->len < size) |
229 | size = peer_b->len; | 227 | size = peer_b->len; |
230 | 228 | ||
231 | /* now read "size" bytes */ | 229 | /* now read "size" bytes */ |
232 | 230 | ||
233 | rest = size; | 231 | rest = size; |
234 | 232 | ||
235 | assert(rest > 0); | 233 | assert(rest > 0); |
236 | do /* one or two iterations */ | 234 | do /* one or two iterations */ |
237 | { | 235 | { |
238 | size_t chunk; | 236 | size_t chunk; |
239 | 237 | ||
240 | assert(rest <= peer_b->len); | 238 | assert(rest <= peer_b->len); |
241 | if (peer_b->offset + rest <= peer_b->size) | 239 | if (peer_b->offset + rest <= peer_b->size) |
242 | chunk = rest; | 240 | chunk = rest; |
@@ -244,30 +242,26 @@ static int bio_read(BIO *bio, char *buf, int size_) | |||
244 | /* wrap around ring buffer */ | 242 | /* wrap around ring buffer */ |
245 | chunk = peer_b->size - peer_b->offset; | 243 | chunk = peer_b->size - peer_b->offset; |
246 | assert(peer_b->offset + chunk <= peer_b->size); | 244 | assert(peer_b->offset + chunk <= peer_b->size); |
247 | 245 | ||
248 | memcpy(buf, peer_b->buf + peer_b->offset, chunk); | 246 | memcpy(buf, peer_b->buf + peer_b->offset, chunk); |
249 | 247 | ||
250 | peer_b->len -= chunk; | 248 | peer_b->len -= chunk; |
251 | if (peer_b->len) | 249 | if (peer_b->len) { |
252 | { | ||
253 | peer_b->offset += chunk; | 250 | peer_b->offset += chunk; |
254 | assert(peer_b->offset <= peer_b->size); | 251 | assert(peer_b->offset <= peer_b->size); |
255 | if (peer_b->offset == peer_b->size) | 252 | if (peer_b->offset == peer_b->size) |
256 | peer_b->offset = 0; | 253 | peer_b->offset = 0; |
257 | buf += chunk; | 254 | buf += chunk; |
258 | } | 255 | } else { |
259 | else | ||
260 | { | ||
261 | /* buffer now empty, no need to advance "buf" */ | 256 | /* buffer now empty, no need to advance "buf" */ |
262 | assert(chunk == rest); | 257 | assert(chunk == rest); |
263 | peer_b->offset = 0; | 258 | peer_b->offset = 0; |
264 | } | ||
265 | rest -= chunk; | ||
266 | } | 259 | } |
267 | while (rest); | 260 | rest -= chunk; |
268 | 261 | } while (rest); | |
262 | |||
269 | return size; | 263 | return size; |
270 | } | 264 | } |
271 | 265 | ||
272 | /* non-copying interface: provide pointer to available data in buffer | 266 | /* non-copying interface: provide pointer to available data in buffer |
273 | * bio_nread0: return number of available bytes | 267 | * bio_nread0: return number of available bytes |
@@ -277,32 +271,32 @@ static int bio_read(BIO *bio, char *buf, int size_) | |||
277 | */ | 271 | */ |
278 | /* WARNING: The non-copying interface is largely untested as of yet | 272 | /* WARNING: The non-copying interface is largely untested as of yet |
279 | * and may contain bugs. */ | 273 | * and may contain bugs. */ |
280 | static ossl_ssize_t bio_nread0(BIO *bio, char **buf) | 274 | static ossl_ssize_t |
281 | { | 275 | bio_nread0(BIO *bio, char **buf) |
276 | { | ||
282 | struct bio_bio_st *b, *peer_b; | 277 | struct bio_bio_st *b, *peer_b; |
283 | ossl_ssize_t num; | 278 | ossl_ssize_t num; |
284 | 279 | ||
285 | BIO_clear_retry_flags(bio); | 280 | BIO_clear_retry_flags(bio); |
286 | 281 | ||
287 | if (!bio->init) | 282 | if (!bio->init) |
288 | return 0; | 283 | return 0; |
289 | 284 | ||
290 | b = bio->ptr; | 285 | b = bio->ptr; |
291 | assert(b != NULL); | 286 | assert(b != NULL); |
292 | assert(b->peer != NULL); | 287 | assert(b->peer != NULL); |
293 | peer_b = b->peer->ptr; | 288 | peer_b = b->peer->ptr; |
294 | assert(peer_b != NULL); | 289 | assert(peer_b != NULL); |
295 | assert(peer_b->buf != NULL); | 290 | assert(peer_b->buf != NULL); |
296 | 291 | ||
297 | peer_b->request = 0; | 292 | peer_b->request = 0; |
298 | 293 | ||
299 | if (peer_b->len == 0) | 294 | if (peer_b->len == 0) { |
300 | { | ||
301 | char dummy; | 295 | char dummy; |
302 | 296 | ||
303 | /* avoid code duplication -- nothing available for reading */ | 297 | /* avoid code duplication -- nothing available for reading */ |
304 | return bio_read(bio, &dummy, 1); /* returns 0 or -1 */ | 298 | return bio_read(bio, &dummy, 1); /* returns 0 or -1 */ |
305 | } | 299 | } |
306 | 300 | ||
307 | num = peer_b->len; | 301 | num = peer_b->len; |
308 | if (peer_b->size < peer_b->offset + num) | 302 | if (peer_b->size < peer_b->offset + num) |
@@ -313,10 +307,11 @@ static ossl_ssize_t bio_nread0(BIO *bio, char **buf) | |||
313 | if (buf != NULL) | 307 | if (buf != NULL) |
314 | *buf = peer_b->buf + peer_b->offset; | 308 | *buf = peer_b->buf + peer_b->offset; |
315 | return num; | 309 | return num; |
316 | } | 310 | } |
317 | 311 | ||
318 | static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_) | 312 | static ossl_ssize_t |
319 | { | 313 | bio_nread(BIO *bio, char **buf, size_t num_) |
314 | { | ||
320 | struct bio_bio_st *b, *peer_b; | 315 | struct bio_bio_st *b, *peer_b; |
321 | ossl_ssize_t num, available; | 316 | ossl_ssize_t num, available; |
322 | 317 | ||
@@ -335,22 +330,21 @@ static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_) | |||
335 | peer_b = b->peer->ptr; | 330 | peer_b = b->peer->ptr; |
336 | 331 | ||
337 | peer_b->len -= num; | 332 | peer_b->len -= num; |
338 | if (peer_b->len) | 333 | if (peer_b->len) { |
339 | { | ||
340 | peer_b->offset += num; | 334 | peer_b->offset += num; |
341 | assert(peer_b->offset <= peer_b->size); | 335 | assert(peer_b->offset <= peer_b->size); |
342 | if (peer_b->offset == peer_b->size) | 336 | if (peer_b->offset == peer_b->size) |
343 | peer_b->offset = 0; | 337 | peer_b->offset = 0; |
344 | } | 338 | } else |
345 | else | ||
346 | peer_b->offset = 0; | 339 | peer_b->offset = 0; |
347 | 340 | ||
348 | return num; | 341 | return num; |
349 | } | 342 | } |
350 | 343 | ||
351 | 344 | ||
352 | static int bio_write(BIO *bio, const char *buf, int num_) | 345 | static int |
353 | { | 346 | bio_write(BIO *bio, const char *buf, int num_) |
347 | { | ||
354 | size_t num = num_; | 348 | size_t num = num_; |
355 | size_t rest; | 349 | size_t rest; |
356 | struct bio_bio_st *b; | 350 | struct bio_bio_st *b; |
@@ -360,38 +354,37 @@ static int bio_write(BIO *bio, const char *buf, int num_) | |||
360 | if (!bio->init || buf == NULL || num == 0) | 354 | if (!bio->init || buf == NULL || num == 0) |
361 | return 0; | 355 | return 0; |
362 | 356 | ||
363 | b = bio->ptr; | 357 | b = bio->ptr; |
358 | |||
364 | assert(b != NULL); | 359 | assert(b != NULL); |
365 | assert(b->peer != NULL); | 360 | assert(b->peer != NULL); |
366 | assert(b->buf != NULL); | 361 | assert(b->buf != NULL); |
367 | 362 | ||
368 | b->request = 0; | 363 | b->request = 0; |
369 | if (b->closed) | 364 | if (b->closed) { |
370 | { | ||
371 | /* we already closed */ | 365 | /* we already closed */ |
372 | BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE); | 366 | BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE); |
373 | return -1; | 367 | return -1; |
374 | } | 368 | } |
375 | 369 | ||
376 | assert(b->len <= b->size); | 370 | assert(b->len <= b->size); |
377 | 371 | ||
378 | if (b->len == b->size) | 372 | if (b->len == b->size) { |
379 | { | ||
380 | BIO_set_retry_write(bio); /* buffer is full */ | 373 | BIO_set_retry_write(bio); /* buffer is full */ |
381 | return -1; | 374 | return -1; |
382 | } | 375 | } |
383 | 376 | ||
384 | /* we can write */ | 377 | /* we can write */ |
385 | if (num > b->size - b->len) | 378 | if (num > b->size - b->len) |
386 | num = b->size - b->len; | 379 | num = b->size - b->len; |
387 | 380 | ||
388 | /* now write "num" bytes */ | 381 | /* now write "num" bytes */ |
389 | 382 | ||
390 | rest = num; | 383 | rest = num; |
391 | 384 | ||
392 | assert(rest > 0); | 385 | assert(rest > 0); |
393 | do /* one or two iterations */ | 386 | do /* one or two iterations */ |
394 | { | 387 | { |
395 | size_t write_offset; | 388 | size_t write_offset; |
396 | size_t chunk; | 389 | size_t chunk; |
397 | 390 | ||
@@ -407,20 +400,19 @@ static int bio_write(BIO *bio, const char *buf, int num_) | |||
407 | else | 400 | else |
408 | /* wrap around ring buffer */ | 401 | /* wrap around ring buffer */ |
409 | chunk = b->size - write_offset; | 402 | chunk = b->size - write_offset; |
410 | 403 | ||
411 | memcpy(b->buf + write_offset, buf, chunk); | 404 | memcpy(b->buf + write_offset, buf, chunk); |
412 | 405 | ||
413 | b->len += chunk; | 406 | b->len += chunk; |
414 | 407 | ||
415 | assert(b->len <= b->size); | 408 | assert(b->len <= b->size); |
416 | 409 | ||
417 | rest -= chunk; | 410 | rest -= chunk; |
418 | buf += chunk; | 411 | buf += chunk; |
419 | } | 412 | } while (rest); |
420 | while (rest); | ||
421 | 413 | ||
422 | return num; | 414 | return num; |
423 | } | 415 | } |
424 | 416 | ||
425 | /* non-copying interface: provide pointer to region to write to | 417 | /* non-copying interface: provide pointer to region to write to |
426 | * bio_nwrite0: check how much space is available | 418 | * bio_nwrite0: check how much space is available |
@@ -428,8 +420,9 @@ static int bio_write(BIO *bio, const char *buf, int num_) | |||
428 | * (example usage: bio_nwrite0(), write to buffer, bio_nwrite() | 420 | * (example usage: bio_nwrite0(), write to buffer, bio_nwrite() |
429 | * or just bio_nwrite(), write to buffer) | 421 | * or just bio_nwrite(), write to buffer) |
430 | */ | 422 | */ |
431 | static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf) | 423 | static ossl_ssize_t |
432 | { | 424 | bio_nwrite0(BIO *bio, char **buf) |
425 | { | ||
433 | struct bio_bio_st *b; | 426 | struct bio_bio_st *b; |
434 | size_t num; | 427 | size_t num; |
435 | size_t write_offset; | 428 | size_t write_offset; |
@@ -439,25 +432,24 @@ static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf) | |||
439 | if (!bio->init) | 432 | if (!bio->init) |
440 | return 0; | 433 | return 0; |
441 | 434 | ||
442 | b = bio->ptr; | 435 | b = bio->ptr; |
436 | |||
443 | assert(b != NULL); | 437 | assert(b != NULL); |
444 | assert(b->peer != NULL); | 438 | assert(b->peer != NULL); |
445 | assert(b->buf != NULL); | 439 | assert(b->buf != NULL); |
446 | 440 | ||
447 | b->request = 0; | 441 | b->request = 0; |
448 | if (b->closed) | 442 | if (b->closed) { |
449 | { | ||
450 | BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE); | 443 | BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE); |
451 | return -1; | 444 | return -1; |
452 | } | 445 | } |
453 | 446 | ||
454 | assert(b->len <= b->size); | 447 | assert(b->len <= b->size); |
455 | 448 | ||
456 | if (b->len == b->size) | 449 | if (b->len == b->size) { |
457 | { | ||
458 | BIO_set_retry_write(bio); | 450 | BIO_set_retry_write(bio); |
459 | return -1; | 451 | return -1; |
460 | } | 452 | } |
461 | 453 | ||
462 | num = b->size - b->len; | 454 | num = b->size - b->len; |
463 | write_offset = b->offset + b->len; | 455 | write_offset = b->offset + b->len; |
@@ -474,10 +466,11 @@ static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf) | |||
474 | assert(write_offset + num <= b->size); | 466 | assert(write_offset + num <= b->size); |
475 | 467 | ||
476 | return num; | 468 | return num; |
477 | } | 469 | } |
478 | 470 | ||
479 | static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_) | 471 | static ossl_ssize_t |
480 | { | 472 | bio_nwrite(BIO *bio, char **buf, size_t num_) |
473 | { | ||
481 | struct bio_bio_st *b; | 474 | struct bio_bio_st *b; |
482 | ossl_ssize_t num, space; | 475 | ossl_ssize_t num, space; |
483 | 476 | ||
@@ -497,46 +490,39 @@ static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_) | |||
497 | assert(b->len <= b->size); | 490 | assert(b->len <= b->size); |
498 | 491 | ||
499 | return num; | 492 | return num; |
500 | } | 493 | } |
501 | 494 | ||
502 | 495 | ||
503 | static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | 496 | static long |
504 | { | 497 | bio_ctrl(BIO *bio, int cmd, long num, void *ptr) |
498 | { | ||
505 | long ret; | 499 | long ret; |
506 | struct bio_bio_st *b = bio->ptr; | 500 | struct bio_bio_st *b = bio->ptr; |
507 | 501 | ||
508 | assert(b != NULL); | 502 | assert(b != NULL); |
509 | 503 | ||
510 | switch (cmd) | 504 | switch (cmd) { |
511 | { | 505 | /* specific CTRL codes */ |
512 | /* specific CTRL codes */ | ||
513 | 506 | ||
514 | case BIO_C_SET_WRITE_BUF_SIZE: | 507 | case BIO_C_SET_WRITE_BUF_SIZE: |
515 | if (b->peer) | 508 | if (b->peer) { |
516 | { | ||
517 | BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE); | 509 | BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE); |
518 | ret = 0; | 510 | ret = 0; |
519 | } | 511 | } else if (num == 0) { |
520 | else if (num == 0) | ||
521 | { | ||
522 | BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT); | 512 | BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT); |
523 | ret = 0; | 513 | ret = 0; |
524 | } | 514 | } else { |
525 | else | ||
526 | { | ||
527 | size_t new_size = num; | 515 | size_t new_size = num; |
528 | 516 | ||
529 | if (b->size != new_size) | 517 | if (b->size != new_size) { |
530 | { | 518 | if (b->buf) { |
531 | if (b->buf) | ||
532 | { | ||
533 | OPENSSL_free(b->buf); | 519 | OPENSSL_free(b->buf); |
534 | b->buf = NULL; | 520 | b->buf = NULL; |
535 | } | ||
536 | b->size = new_size; | ||
537 | } | 521 | } |
538 | ret = 1; | 522 | b->size = new_size; |
539 | } | 523 | } |
524 | ret = 1; | ||
525 | } | ||
540 | break; | 526 | break; |
541 | 527 | ||
542 | case BIO_C_GET_WRITE_BUF_SIZE: | 528 | case BIO_C_GET_WRITE_BUF_SIZE: |
@@ -545,15 +531,15 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | |||
545 | 531 | ||
546 | case BIO_C_MAKE_BIO_PAIR: | 532 | case BIO_C_MAKE_BIO_PAIR: |
547 | { | 533 | { |
548 | BIO *other_bio = ptr; | 534 | BIO *other_bio = ptr; |
549 | 535 | ||
550 | if (bio_make_pair(bio, other_bio)) | 536 | if (bio_make_pair(bio, other_bio)) |
551 | ret = 1; | 537 | ret = 1; |
552 | else | 538 | else |
553 | ret = 0; | 539 | ret = 0; |
554 | } | 540 | } |
555 | break; | 541 | break; |
556 | 542 | ||
557 | case BIO_C_DESTROY_BIO_PAIR: | 543 | case BIO_C_DESTROY_BIO_PAIR: |
558 | /* Affects both BIOs in the pair -- call just once! | 544 | /* Affects both BIOs in the pair -- call just once! |
559 | * Or let BIO_free(bio1); BIO_free(bio2); do the job. */ | 545 | * Or let BIO_free(bio1); BIO_free(bio2); do the job. */ |
@@ -596,12 +582,12 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | |||
596 | /* prepare for non-copying read */ | 582 | /* prepare for non-copying read */ |
597 | ret = (long) bio_nread0(bio, ptr); | 583 | ret = (long) bio_nread0(bio, ptr); |
598 | break; | 584 | break; |
599 | 585 | ||
600 | case BIO_C_NREAD: | 586 | case BIO_C_NREAD: |
601 | /* non-copying read */ | 587 | /* non-copying read */ |
602 | ret = (long) bio_nread(bio, ptr, (size_t) num); | 588 | ret = (long) bio_nread(bio, ptr, (size_t) num); |
603 | break; | 589 | break; |
604 | 590 | ||
605 | case BIO_C_NWRITE0: | 591 | case BIO_C_NWRITE0: |
606 | /* prepare for non-copying write */ | 592 | /* prepare for non-copying write */ |
607 | ret = (long) bio_nwrite0(bio, ptr); | 593 | ret = (long) bio_nwrite0(bio, ptr); |
@@ -611,18 +597,18 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | |||
611 | /* non-copying write */ | 597 | /* non-copying write */ |
612 | ret = (long) bio_nwrite(bio, ptr, (size_t) num); | 598 | ret = (long) bio_nwrite(bio, ptr, (size_t) num); |
613 | break; | 599 | break; |
614 | |||
615 | 600 | ||
616 | /* standard CTRL codes follow */ | 601 | |
602 | /* standard CTRL codes follow */ | ||
617 | 603 | ||
618 | case BIO_CTRL_RESET: | 604 | case BIO_CTRL_RESET: |
619 | if (b->buf != NULL) | 605 | if (b->buf != NULL) { |
620 | { | ||
621 | b->len = 0; | 606 | b->len = 0; |
622 | b->offset = 0; | 607 | b->offset = 0; |
623 | } | 608 | } |
624 | ret = 0; | 609 | ret = 0; |
625 | break; | 610 | break; |
611 | |||
626 | 612 | ||
627 | case BIO_CTRL_GET_CLOSE: | 613 | case BIO_CTRL_GET_CLOSE: |
628 | ret = bio->shutdown; | 614 | ret = bio->shutdown; |
@@ -634,13 +620,11 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | |||
634 | break; | 620 | break; |
635 | 621 | ||
636 | case BIO_CTRL_PENDING: | 622 | case BIO_CTRL_PENDING: |
637 | if (b->peer != NULL) | 623 | if (b->peer != NULL) { |
638 | { | ||
639 | struct bio_bio_st *peer_b = b->peer->ptr; | 624 | struct bio_bio_st *peer_b = b->peer->ptr; |
640 | 625 | ||
641 | ret = (long) peer_b->len; | 626 | ret = (long) peer_b->len; |
642 | } | 627 | } else |
643 | else | ||
644 | ret = 0; | 628 | ret = 0; |
645 | break; | 629 | break; |
646 | 630 | ||
@@ -654,16 +638,16 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | |||
654 | case BIO_CTRL_DUP: | 638 | case BIO_CTRL_DUP: |
655 | /* See BIO_dup_chain for circumstances we have to expect. */ | 639 | /* See BIO_dup_chain for circumstances we have to expect. */ |
656 | { | 640 | { |
657 | BIO *other_bio = ptr; | 641 | BIO *other_bio = ptr; |
658 | struct bio_bio_st *other_b; | 642 | struct bio_bio_st *other_b; |
659 | 643 | ||
660 | assert(other_bio != NULL); | 644 | assert(other_bio != NULL); |
661 | other_b = other_bio->ptr; | 645 | other_b = other_bio->ptr; |
662 | assert(other_b != NULL); | 646 | assert(other_b != NULL); |
663 | 647 | ||
664 | assert(other_b->buf == NULL); /* other_bio is always fresh */ | 648 | assert(other_b->buf == NULL); /* other_bio is always fresh */ |
665 | 649 | ||
666 | other_b->size = b->size; | 650 | other_b->size = b->size; |
667 | } | 651 | } |
668 | 652 | ||
669 | ret = 1; | 653 | ret = 1; |
@@ -675,34 +659,34 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | |||
675 | 659 | ||
676 | case BIO_CTRL_EOF: | 660 | case BIO_CTRL_EOF: |
677 | { | 661 | { |
678 | BIO *other_bio = ptr; | 662 | BIO *other_bio = ptr; |
679 | 663 | ||
680 | if (other_bio) | 664 | if (other_bio) { |
681 | { | 665 | struct bio_bio_st *other_b = other_bio->ptr; |
682 | struct bio_bio_st *other_b = other_bio->ptr; | 666 | |
683 | 667 | assert(other_b != NULL); | |
684 | assert(other_b != NULL); | 668 | ret = other_b->len == 0 && other_b->closed; |
685 | ret = other_b->len == 0 && other_b->closed; | 669 | } else |
686 | } | 670 | ret = 1; |
687 | else | ||
688 | ret = 1; | ||
689 | } | 671 | } |
690 | break; | 672 | break; |
691 | 673 | ||
692 | default: | 674 | default: |
693 | ret = 0; | 675 | ret = 0; |
694 | } | ||
695 | return ret; | ||
696 | } | 676 | } |
677 | return ret; | ||
678 | } | ||
697 | 679 | ||
698 | static int bio_puts(BIO *bio, const char *str) | 680 | static int |
699 | { | 681 | bio_puts(BIO *bio, const char *str) |
682 | { | ||
700 | return bio_write(bio, str, strlen(str)); | 683 | return bio_write(bio, str, strlen(str)); |
701 | } | 684 | } |
702 | 685 | ||
703 | 686 | ||
704 | static int bio_make_pair(BIO *bio1, BIO *bio2) | 687 | static int |
705 | { | 688 | bio_make_pair(BIO *bio1, BIO *bio2) |
689 | { | ||
706 | struct bio_bio_st *b1, *b2; | 690 | struct bio_bio_st *b1, *b2; |
707 | 691 | ||
708 | assert(bio1 != NULL); | 692 | assert(bio1 != NULL); |
@@ -710,37 +694,32 @@ static int bio_make_pair(BIO *bio1, BIO *bio2) | |||
710 | 694 | ||
711 | b1 = bio1->ptr; | 695 | b1 = bio1->ptr; |
712 | b2 = bio2->ptr; | 696 | b2 = bio2->ptr; |
713 | 697 | ||
714 | if (b1->peer != NULL || b2->peer != NULL) | 698 | if (b1->peer != NULL || b2->peer != NULL) { |
715 | { | ||
716 | BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE); | 699 | BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE); |
717 | return 0; | 700 | return 0; |
718 | } | 701 | } |
719 | 702 | ||
720 | if (b1->buf == NULL) | 703 | if (b1->buf == NULL) { |
721 | { | ||
722 | b1->buf = OPENSSL_malloc(b1->size); | 704 | b1->buf = OPENSSL_malloc(b1->size); |
723 | if (b1->buf == NULL) | 705 | if (b1->buf == NULL) { |
724 | { | ||
725 | BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); | 706 | BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); |
726 | return 0; | 707 | return 0; |
727 | } | 708 | } |
728 | b1->len = 0; | 709 | b1->len = 0; |
729 | b1->offset = 0; | 710 | b1->offset = 0; |
730 | } | 711 | } |
731 | 712 | ||
732 | if (b2->buf == NULL) | 713 | if (b2->buf == NULL) { |
733 | { | ||
734 | b2->buf = OPENSSL_malloc(b2->size); | 714 | b2->buf = OPENSSL_malloc(b2->size); |
735 | if (b2->buf == NULL) | 715 | if (b2->buf == NULL) { |
736 | { | ||
737 | BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); | 716 | BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); |
738 | return 0; | 717 | return 0; |
739 | } | 718 | } |
740 | b2->len = 0; | 719 | b2->len = 0; |
741 | b2->offset = 0; | 720 | b2->offset = 0; |
742 | } | 721 | } |
743 | 722 | ||
744 | b1->peer = bio2; | 723 | b1->peer = bio2; |
745 | b1->closed = 0; | 724 | b1->closed = 0; |
746 | b1->request = 0; | 725 | b1->request = 0; |
@@ -752,18 +731,17 @@ static int bio_make_pair(BIO *bio1, BIO *bio2) | |||
752 | bio2->init = 1; | 731 | bio2->init = 1; |
753 | 732 | ||
754 | return 1; | 733 | return 1; |
755 | } | 734 | } |
756 | 735 | ||
757 | static void bio_destroy_pair(BIO *bio) | 736 | static void |
758 | { | 737 | bio_destroy_pair(BIO *bio) |
738 | { | ||
759 | struct bio_bio_st *b = bio->ptr; | 739 | struct bio_bio_st *b = bio->ptr; |
760 | 740 | ||
761 | if (b != NULL) | 741 | if (b != NULL) { |
762 | { | ||
763 | BIO *peer_bio = b->peer; | 742 | BIO *peer_bio = b->peer; |
764 | 743 | ||
765 | if (peer_bio != NULL) | 744 | if (peer_bio != NULL) { |
766 | { | ||
767 | struct bio_bio_st *peer_b = peer_bio->ptr; | 745 | struct bio_bio_st *peer_b = peer_bio->ptr; |
768 | 746 | ||
769 | assert(peer_b != NULL); | 747 | assert(peer_b != NULL); |
@@ -774,151 +752,149 @@ static void bio_destroy_pair(BIO *bio) | |||
774 | assert(peer_b->buf != NULL); | 752 | assert(peer_b->buf != NULL); |
775 | peer_b->len = 0; | 753 | peer_b->len = 0; |
776 | peer_b->offset = 0; | 754 | peer_b->offset = 0; |
777 | 755 | ||
778 | b->peer = NULL; | 756 | b->peer = NULL; |
779 | bio->init = 0; | 757 | bio->init = 0; |
780 | assert(b->buf != NULL); | 758 | assert(b->buf != NULL); |
781 | b->len = 0; | 759 | b->len = 0; |
782 | b->offset = 0; | 760 | b->offset = 0; |
783 | } | ||
784 | } | 761 | } |
785 | } | 762 | } |
786 | 763 | } | |
764 | |||
787 | 765 | ||
788 | /* Exported convenience functions */ | 766 | /* Exported convenience functions */ |
789 | int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, | 767 | int |
790 | BIO **bio2_p, size_t writebuf2) | 768 | BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, BIO **bio2_p, size_t writebuf2) |
791 | { | 769 | { |
792 | BIO *bio1 = NULL, *bio2 = NULL; | 770 | BIO *bio1 = NULL, *bio2 = NULL; |
793 | long r; | 771 | long r; |
794 | int ret = 0; | 772 | int ret = 0; |
795 | 773 | ||
796 | bio1 = BIO_new(BIO_s_bio()); | 774 | bio1 = BIO_new(BIO_s_bio()); |
797 | if (bio1 == NULL) | 775 | if (bio1 == NULL) |
798 | goto err; | 776 | goto err; |
799 | bio2 = BIO_new(BIO_s_bio()); | 777 | bio2 = BIO_new(BIO_s_bio()); |
800 | if (bio2 == NULL) | 778 | if (bio2 == NULL) |
801 | goto err; | 779 | goto err; |
802 | 780 | ||
803 | if (writebuf1) | 781 | if (writebuf1) { |
804 | { | 782 | r = BIO_set_write_buf_size(bio1, writebuf1); |
805 | r = BIO_set_write_buf_size(bio1, writebuf1); | 783 | if (!r) |
806 | if (!r) | 784 | goto err; |
807 | goto err; | 785 | } |
808 | } | 786 | if (writebuf2) { |
809 | if (writebuf2) | 787 | r = BIO_set_write_buf_size(bio2, writebuf2); |
810 | { | 788 | if (!r) |
811 | r = BIO_set_write_buf_size(bio2, writebuf2); | 789 | goto err; |
812 | if (!r) | ||
813 | goto err; | ||
814 | } | ||
815 | |||
816 | r = BIO_make_bio_pair(bio1, bio2); | ||
817 | if (!r) | ||
818 | goto err; | ||
819 | ret = 1; | ||
820 | |||
821 | err: | ||
822 | if (ret == 0) | ||
823 | { | ||
824 | if (bio1) | ||
825 | { | ||
826 | BIO_free(bio1); | ||
827 | bio1 = NULL; | ||
828 | } | ||
829 | if (bio2) | ||
830 | { | ||
831 | BIO_free(bio2); | ||
832 | bio2 = NULL; | ||
833 | } | ||
834 | } | ||
835 | |||
836 | *bio1_p = bio1; | ||
837 | *bio2_p = bio2; | ||
838 | return ret; | ||
839 | } | ||
840 | |||
841 | size_t BIO_ctrl_get_write_guarantee(BIO *bio) | ||
842 | { | ||
843 | return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL); | ||
844 | } | 790 | } |
845 | 791 | ||
846 | size_t BIO_ctrl_get_read_request(BIO *bio) | 792 | r = BIO_make_bio_pair(bio1, bio2); |
847 | { | 793 | if (!r) |
848 | return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); | 794 | goto err; |
795 | ret = 1; | ||
796 | |||
797 | err: | ||
798 | if (ret == 0) { | ||
799 | if (bio1) { | ||
800 | BIO_free(bio1); | ||
801 | bio1 = NULL; | ||
802 | } | ||
803 | if (bio2) { | ||
804 | BIO_free(bio2); | ||
805 | bio2 = NULL; | ||
806 | } | ||
849 | } | 807 | } |
850 | 808 | ||
851 | int BIO_ctrl_reset_read_request(BIO *bio) | 809 | *bio1_p = bio1; |
852 | { | 810 | *bio2_p = bio2; |
811 | return ret; | ||
812 | } | ||
813 | |||
814 | size_t | ||
815 | BIO_ctrl_get_write_guarantee(BIO *bio) | ||
816 | { | ||
817 | return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL); | ||
818 | } | ||
819 | |||
820 | size_t | ||
821 | BIO_ctrl_get_read_request(BIO *bio) | ||
822 | { | ||
823 | return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); | ||
824 | } | ||
825 | |||
826 | int | ||
827 | BIO_ctrl_reset_read_request(BIO *bio) | ||
828 | { | ||
853 | return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0); | 829 | return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0); |
854 | } | 830 | } |
855 | 831 | ||
856 | 832 | ||
857 | /* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now | 833 | /* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now |
858 | * (conceivably some other BIOs could allow non-copying reads and writes too.) | 834 | * (conceivably some other BIOs could allow non-copying reads and writes too.) |
859 | */ | 835 | */ |
860 | int BIO_nread0(BIO *bio, char **buf) | 836 | int |
861 | { | 837 | BIO_nread0(BIO *bio, char **buf) |
838 | { | ||
862 | long ret; | 839 | long ret; |
863 | 840 | ||
864 | if (!bio->init) | 841 | if (!bio->init) { |
865 | { | ||
866 | BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED); | 842 | BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED); |
867 | return -2; | 843 | return -2; |
868 | } | 844 | } |
869 | 845 | ||
870 | ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf); | 846 | ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf); |
871 | if (ret > INT_MAX) | 847 | if (ret > INT_MAX) |
872 | return INT_MAX; | 848 | return INT_MAX; |
873 | else | 849 | else |
874 | return (int) ret; | 850 | return (int) ret; |
875 | } | 851 | } |
876 | 852 | ||
877 | int BIO_nread(BIO *bio, char **buf, int num) | 853 | int |
878 | { | 854 | BIO_nread(BIO *bio, char **buf, int num) |
855 | { | ||
879 | int ret; | 856 | int ret; |
880 | 857 | ||
881 | if (!bio->init) | 858 | if (!bio->init) { |
882 | { | ||
883 | BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED); | 859 | BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED); |
884 | return -2; | 860 | return -2; |
885 | } | 861 | } |
886 | 862 | ||
887 | ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf); | 863 | ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf); |
888 | if (ret > 0) | 864 | if (ret > 0) |
889 | bio->num_read += ret; | 865 | bio->num_read += ret; |
890 | return ret; | 866 | return ret; |
891 | } | 867 | } |
892 | 868 | ||
893 | int BIO_nwrite0(BIO *bio, char **buf) | 869 | int |
894 | { | 870 | BIO_nwrite0(BIO *bio, char **buf) |
871 | { | ||
895 | long ret; | 872 | long ret; |
896 | 873 | ||
897 | if (!bio->init) | 874 | if (!bio->init) { |
898 | { | ||
899 | BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED); | 875 | BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED); |
900 | return -2; | 876 | return -2; |
901 | } | 877 | } |
902 | 878 | ||
903 | ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf); | 879 | ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf); |
904 | if (ret > INT_MAX) | 880 | if (ret > INT_MAX) |
905 | return INT_MAX; | 881 | return INT_MAX; |
906 | else | 882 | else |
907 | return (int) ret; | 883 | return (int) ret; |
908 | } | 884 | } |
909 | 885 | ||
910 | int BIO_nwrite(BIO *bio, char **buf, int num) | 886 | int |
911 | { | 887 | BIO_nwrite(BIO *bio, char **buf, int num) |
888 | { | ||
912 | int ret; | 889 | int ret; |
913 | 890 | ||
914 | if (!bio->init) | 891 | if (!bio->init) { |
915 | { | ||
916 | BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED); | 892 | BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED); |
917 | return -2; | 893 | return -2; |
918 | } | 894 | } |
919 | 895 | ||
920 | ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf); | 896 | ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf); |
921 | if (ret > 0) | 897 | if (ret > 0) |
922 | bio->num_write += ret; | 898 | bio->num_write += ret; |
923 | return ret; | 899 | return ret; |
924 | } | 900 | } |