summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bio/bss_bio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/bio/bss_bio.c')
-rw-r--r--src/lib/libcrypto/bio/bss_bio.c546
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);
103static int bio_make_pair(BIO *bio1, BIO *bio2); 103static int bio_make_pair(BIO *bio1, BIO *bio2);
104static void bio_destroy_pair(BIO *bio); 104static void bio_destroy_pair(BIO *bio);
105 105
106static BIO_METHOD methods_biop = 106static 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
120BIO_METHOD *BIO_s_bio(void) 119BIO_METHOD
121 { 120*BIO_s_bio(void)
121{
122 return &methods_biop; 122 return &methods_biop;
123 } 123}
124
125struct 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
125struct 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
145static int bio_new(BIO *bio) 144static int
146 { 145bio_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 161static int
162static int bio_free(BIO *bio) 162bio_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
187static int bio_read(BIO *bio, char *buf, int size_) 186static int
188 { 187bio_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. */
280static ossl_ssize_t bio_nread0(BIO *bio, char **buf) 274static ossl_ssize_t
281 { 275bio_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
318static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_) 312static ossl_ssize_t
319 { 313bio_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
352static int bio_write(BIO *bio, const char *buf, int num_) 345static int
353 { 346bio_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 */
431static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf) 423static ossl_ssize_t
432 { 424bio_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
479static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_) 471static ossl_ssize_t
480 { 472bio_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
503static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) 496static long
504 { 497bio_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
698static int bio_puts(BIO *bio, const char *str) 680static int
699 { 681bio_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
704static int bio_make_pair(BIO *bio1, BIO *bio2) 687static int
705 { 688bio_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
757static void bio_destroy_pair(BIO *bio) 736static void
758 { 737bio_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 */
789int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, 767int
790 BIO **bio2_p, size_t writebuf2) 768BIO_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
841size_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
846size_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
851int BIO_ctrl_reset_read_request(BIO *bio) 809 *bio1_p = bio1;
852 { 810 *bio2_p = bio2;
811 return ret;
812}
813
814size_t
815BIO_ctrl_get_write_guarantee(BIO *bio)
816{
817 return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
818}
819
820size_t
821BIO_ctrl_get_read_request(BIO *bio)
822{
823 return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
824}
825
826int
827BIO_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 */
860int BIO_nread0(BIO *bio, char **buf) 836int
861 { 837BIO_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
877int BIO_nread(BIO *bio, char **buf, int num) 853int
878 { 854BIO_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
893int BIO_nwrite0(BIO *bio, char **buf) 869int
894 { 870BIO_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
910int BIO_nwrite(BIO *bio, char **buf, int num) 886int
911 { 887BIO_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}