source: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/src/bio.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 43.3 KB
Line 
1/* bio.c
2 *
3 * Copyright (C) 2006-2020 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22#include <wolfssl/wolfcrypt/settings.h>
23
24#if !defined(WOLFSSL_BIO_INCLUDED)
25 #ifndef WOLFSSL_IGNORE_FILE_WARN
26 #warning bio.c does not need to be compiled separately from ssl.c
27 #endif
28#else
29
30
31/* Helper function to decode a base64 input
32 *
33 * returns size of resulting buffer on success
34 */
35static int wolfSSL_BIO_BASE64_read(WOLFSSL_BIO* bio, void* buf, int len)
36{
37 word32 frmtSz = len;
38
39 WOLFSSL_ENTER("wolfSSL_BIO_BASE64_read");
40
41 if (Base64_Decode((const byte*)buf, (word32)len, (byte*)buf, &frmtSz) !=0) {
42 WOLFSSL_MSG("Err doing base64 decode");
43 return SSL_FATAL_ERROR;
44 }
45
46 (void)bio;
47 return (int)frmtSz;
48}
49
50
51/* Helper function to read from WOLFSSL_BIO_BIO type
52 *
53 * returns amount in bytes read on success
54 */
55static int wolfSSL_BIO_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
56{
57 int sz;
58 char* pt;
59
60 sz = wolfSSL_BIO_nread(bio, &pt, len);
61
62 if (sz > 0) {
63 XMEMCPY(buf, pt, sz);
64 }
65
66 return sz;
67}
68
69
70/* Handles reading from a memory type BIO and advancing the state.
71 *
72 * bio WOLFSSL_BIO to read from
73 * buf buffer to put data from bio in
74 * len amount of data to be read
75 *
76 * returns size read on success
77 */
78static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len)
79{
80 int sz;
81 WOLFSSL_ENTER("wolfSSL_BIO_MEMORY_read");
82
83 sz = wolfSSL_BIO_pending(bio);
84 if (sz > 0) {
85 const unsigned char* pt = NULL;
86 int memSz;
87
88 if (sz > len) {
89 sz = len;
90 }
91 memSz = wolfSSL_BIO_get_mem_data(bio, (void*)&pt);
92 if (memSz >= sz && pt != NULL) {
93 byte* tmp;
94
95 XMEMCPY(buf, (void*)pt, sz);
96 if (memSz - sz > 0) {
97 tmp = (byte*)XMALLOC(memSz-sz, bio->heap, DYNAMIC_TYPE_OPENSSL);
98 if (tmp == NULL) {
99 WOLFSSL_MSG("Memory error");
100 return WOLFSSL_BIO_ERROR;
101 }
102 XMEMCPY(tmp, (void*)(pt + sz), memSz - sz);
103
104 /* reset internal bio->mem */
105 XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
106 bio->ptr = tmp;
107 bio->num = memSz-sz;
108 if (bio->mem_buf != NULL) {
109 bio->mem_buf->data = (char*)bio->ptr;
110 bio->mem_buf->length = bio->num;
111 }
112 }
113 bio->wrSz -= sz;
114 }
115 else {
116 WOLFSSL_MSG("Issue with getting bio mem pointer");
117 return 0;
118 }
119 }
120 else {
121 return WOLFSSL_BIO_ERROR;
122 }
123
124 return sz;
125}
126
127#ifndef WOLFCRYPT_ONLY
128/* Helper function to read from WOLFSSL_BIO_SSL type
129 *
130 * returns the number of bytes read on success
131 */
132static int wolfSSL_BIO_SSL_read(WOLFSSL_BIO* bio, void* buf,
133 int len, WOLFSSL_BIO* front)
134{
135 int ret;
136
137 WOLFSSL_ENTER("wolfSSL_BIO_SSL_read");
138
139 /* already got eof, again is error */
140 if ((front == NULL) || front->eof)
141 return WOLFSSL_FATAL_ERROR;
142
143 bio->flags &= ~(WOLFSSL_BIO_FLAG_RETRY); /* default no retry */
144 ret = wolfSSL_read((WOLFSSL*)bio->ptr, buf, len);
145 if (ret == 0)
146 front->eof = 1;
147 else if (ret < 0) {
148 int err = wolfSSL_get_error((WOLFSSL*)bio->ptr, 0);
149 if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) ) {
150 front->eof = 1;
151 }
152 else {
153 bio->flags |= WOLFSSL_BIO_FLAG_RETRY; /* should retry */
154 }
155 }
156
157 return ret;
158}
159
160static int wolfSSL_BIO_MD_read(WOLFSSL_BIO* bio, void* buf, int sz)
161{
162 int ret = sz;
163
164 if (wolfSSL_EVP_MD_CTX_type((WOLFSSL_EVP_MD_CTX*)bio->ptr) == NID_hmac) {
165 if (wolfSSL_EVP_DigestSignUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, buf,
166 sz) != WOLFSSL_SUCCESS)
167 {
168 ret = WOLFSSL_FATAL_ERROR;
169 }
170 }
171 else {
172 if (wolfSSL_EVP_DigestUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, buf, ret)
173 != WOLFSSL_SUCCESS) {
174 ret = WOLFSSL_FATAL_ERROR;
175 }
176 }
177 return ret;
178}
179#endif /* WOLFCRYPT_ONLY */
180
181
182/* Used to read data from a WOLFSSL_BIO structure
183 *
184 * bio structure to read data from
185 * buf buffer to hold the result
186 * len length of buf buffer
187 *
188 * returns the number of bytes read on success
189 */
190int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
191{
192 int ret = 0;
193 WOLFSSL_BIO* front = bio;
194 int sz = 0;
195
196 WOLFSSL_ENTER("wolfSSL_BIO_read");
197
198 /* info cb, abort if user returns <= 0*/
199 if (front != NULL && front->infoCb != NULL) {
200 ret = (int)front->infoCb(front, WOLFSSL_BIO_CB_READ, (const char*)buf,
201 len, 0, 1);
202 if (ret <= 0) {
203 return ret;
204 }
205 }
206
207 /* start at end of list and work backwards */
208 while ((bio != NULL) && (bio->next != NULL)) {
209 bio = bio->next;
210 }
211
212 while (bio != NULL && ret >= 0) {
213 /* check for custom read */
214 if (bio->method && bio->method->readCb) {
215 ret = bio->method->readCb(bio, (char*)buf, len);
216 }
217
218 /* formatting data */
219 if (bio->type == WOLFSSL_BIO_BASE64 && ret > 0 && sz > 0) {
220 ret = wolfSSL_BIO_BASE64_read(bio, buf, sz);
221 }
222
223 /* write BIOs */
224 if (bio && bio->type == WOLFSSL_BIO_BIO) {
225 ret = wolfSSL_BIO_BIO_read(bio, buf, len);
226 }
227
228 if (bio && bio->type == WOLFSSL_BIO_MEMORY) {
229 ret = wolfSSL_BIO_MEMORY_read(bio, buf, len);
230 }
231
232 #ifndef NO_FILESYSTEM
233 if (bio && bio->type == WOLFSSL_BIO_FILE) {
234 ret = (int)XFREAD(buf, 1, len, (XFILE)bio->ptr);
235 }
236 #endif
237
238 #ifndef WOLFCRYPT_ONLY
239 if (bio && bio->type == WOLFSSL_BIO_SSL) {
240 ret = wolfSSL_BIO_SSL_read(bio, buf, len, front);
241 }
242
243 /* data passing through BIO MD wrapper */
244 if (bio && bio->type == WOLFSSL_BIO_MD && ret > 0) {
245 ret = wolfSSL_BIO_MD_read(bio, buf, ret);
246 }
247 #endif
248
249 /* case where front of list is done */
250 if (bio == front) {
251 break; /* at front of list so be done */
252 }
253
254 if (ret > 0) {
255 sz = ret; /* adjust size for formatting */
256 }
257
258 /* previous WOLFSSL_BIO in list working towards head of list */
259 bio = bio->prev;
260 }
261
262 /* info cb, user can override return value */
263 if (front != NULL && front->infoCb != NULL) {
264 ret = (int)front->infoCb(front,
265 WOLFSSL_BIO_CB_READ | WOLFSSL_BIO_CB_RETURN,
266 (const char*)buf, len, 0, ret);
267 }
268
269 return ret;
270}
271
272
273/* Converts data into base64 output
274 *
275 * returns the resulting buffer size on success.
276 */
277static int wolfSSL_BIO_BASE64_write(WOLFSSL_BIO* bio, const void* data,
278 word32 inLen, byte* out, word32* outLen)
279{
280 byte* tmp = NULL;
281 int ret = 0;
282
283 WOLFSSL_ENTER("wolfSSL_BIO_BASE64_write");
284
285 if (bio == NULL || data == NULL || out == NULL || outLen == NULL) {
286 return BAD_FUNC_ARG;
287 }
288
289#if defined(WOLFSSL_BASE64_ENCODE)
290 tmp = (byte*)XMALLOC(*outLen, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
291 if (tmp == NULL) {
292 return WOLFSSL_FATAL_ERROR;
293 }
294
295 if ((bio->flags & WOLFSSL_BIO_FLAG_BASE64_NO_NL) ==
296 WOLFSSL_BIO_FLAG_BASE64_NO_NL) {
297 if (Base64_Encode_NoNl((const byte*)data, inLen,
298 tmp, outLen) < 0) {
299 ret = WOLFSSL_FATAL_ERROR;
300 }
301 }
302 else {
303 if (Base64_Encode((const byte*)data, inLen,
304 tmp, outLen) < 0) {
305 ret = WOLFSSL_FATAL_ERROR;
306 }
307 }
308
309 if (ret != WOLFSSL_FATAL_ERROR) {
310 ret = (int) inLen;
311 XMEMCPY(out, tmp, *outLen);
312
313 }
314 XFREE(tmp, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
315#else
316 (void)bio;
317 (void)data;
318 (void)inLen;
319 (void)out;
320 (void)outLen;
321 (void)tmp;
322 WOLFSSL_MSG("BASE64 encoding not compiled in");
323#endif
324 return ret;
325}
326
327
328#ifndef WOLFCRYPT_ONLY
329/* Helper function for writing to a WOLFSSL_BIO_SSL type
330 *
331 * returns the amount written in bytes on success
332 */
333static int wolfSSL_BIO_SSL_write(WOLFSSL_BIO* bio, const void* data,
334 int len, WOLFSSL_BIO* front)
335{
336 int ret;
337
338 WOLFSSL_ENTER("wolfSSL_BIO_SSL_write");
339
340 if (bio->ptr == NULL) {
341 return BAD_FUNC_ARG;
342 }
343
344 bio->flags &= ~(WOLFSSL_BIO_FLAG_RETRY); /* default no retry */
345 ret = wolfSSL_write((WOLFSSL*)bio->ptr, data, len);
346 if (ret == 0)
347 front->eof = 1;
348 else if (ret < 0) {
349 int err = wolfSSL_get_error((WOLFSSL*)bio->ptr, 0);
350 if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) ) {
351 front->eof = 1;
352 }
353 else {
354 bio->flags |= WOLFSSL_BIO_FLAG_RETRY; /* should retry */
355 }
356 }
357 return ret;
358}
359#endif /* WOLFCRYPT_ONLY */
360
361
362/* Writes to a WOLFSSL_BIO_BIO type.
363 *
364 * returns the amount written on success
365 */
366static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data,
367 int len)
368{
369 int sz;
370 char* buf;
371
372 WOLFSSL_ENTER("wolfSSL_BIO_BIO_write");
373
374 /* adding in sanity checks for static analysis tools */
375 if (bio == NULL || data == NULL) {
376 return BAD_FUNC_ARG;
377 }
378
379 sz = wolfSSL_BIO_nwrite(bio, &buf, len);
380
381 /* test space for write */
382 if (sz <= 0) {
383 WOLFSSL_MSG("No room left to write");
384 return sz;
385 }
386
387 XMEMCPY(buf, data, sz);
388
389 return sz;
390}
391
392
393/* for complete compatibility a bio memory write allocs its own memory
394 * until the application runs out ....
395 *
396 * bio structure to hold incoming data
397 * data buffer holding the data to be written
398 * len length of data buffer
399 *
400 * returns the amount of data written on success and WOLFSSL_FAILURE or
401 * WOLFSSL_BIO_ERROR for failure cases.
402 */
403static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data,
404 int len)
405{
406 int sz;
407 const unsigned char* buf;
408
409 WOLFSSL_ENTER("wolfSSL_BIO_MEMORY_write");
410
411 if (bio == NULL || data == NULL) {
412 return BAD_FUNC_ARG;
413 }
414
415 sz = wolfSSL_BIO_pending(bio);
416 if (sz < 0) {
417 WOLFSSL_MSG("Error getting memory data");
418 return sz;
419 }
420
421 if (bio->ptr == NULL) {
422 bio->ptr = (byte*)XMALLOC(len, bio->heap, DYNAMIC_TYPE_OPENSSL);
423 if (bio->ptr == NULL) {
424 WOLFSSL_MSG("Error on malloc");
425 return WOLFSSL_FAILURE;
426 }
427 bio->num = len;
428 if (bio->mem_buf != NULL) {
429 bio->mem_buf->data = (char*)bio->ptr;
430 bio->mem_buf->length = bio->num;
431 }
432 }
433
434 /* check if will fit in current buffer size */
435 if (wolfSSL_BIO_get_mem_data(bio, (void*)&buf) < 0) {
436 return WOLFSSL_BIO_ERROR;
437 }
438 if (bio->num < sz + len) {
439 bio->ptr = (byte*)XREALLOC(bio->ptr, sz + len, bio->heap,
440 DYNAMIC_TYPE_OPENSSL);
441 if (bio->ptr == NULL) {
442 WOLFSSL_MSG("Error on realloc");
443 return WOLFSSL_FAILURE;
444 }
445 bio->num = sz + len;
446 if (bio->mem_buf != NULL) {
447 bio->mem_buf->data = (char*)bio->ptr;
448 bio->mem_buf->length = bio->num;
449 }
450 }
451
452 XMEMCPY((byte*)bio->ptr + sz, data, len);
453 bio->wrSz += len;
454
455 return len;
456}
457
458
459#ifndef WOLFCRYPT_ONLY
460/* Helper function for writing to a WOLFSSL_BIO_MD type
461 *
462 * returns the amount written in bytes on success (0)
463 */
464static int wolfSSL_BIO_MD_write(WOLFSSL_BIO* bio, const void* data, int len)
465{
466 int ret = 0;
467
468 if (bio == NULL || data == NULL) {
469 return BAD_FUNC_ARG;
470 }
471
472 if (wolfSSL_EVP_MD_CTX_type((WOLFSSL_EVP_MD_CTX*)bio->ptr) == NID_hmac) {
473 if (wolfSSL_EVP_DigestSignUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, data,
474 len) != WOLFSSL_SUCCESS) {
475 ret = WOLFSSL_BIO_ERROR;
476 }
477 }
478 else {
479 if (wolfSSL_EVP_DigestUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, data, len)
480 != WOLFSSL_SUCCESS) {
481 ret = WOLFSSL_BIO_ERROR;
482 }
483 }
484 return ret;
485}
486#endif /* WOLFCRYPT_ONLY */
487
488
489/* Writes data to a WOLFSSL_BIO structure
490 *
491 * bio structure to write to
492 * data holds the data to be written
493 * len length of data buffer
494 *
495 * returns the amount written in bytes on success
496 */
497int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
498{
499 int ret = 0;
500 int retB64 = 0;
501 WOLFSSL_BIO* front = bio;
502 void* frmt = NULL;
503 word32 frmtSz = 0;
504
505 WOLFSSL_ENTER("wolfSSL_BIO_write");
506
507 /* info cb, abort if user returns <= 0*/
508 if (front != NULL && front->infoCb != NULL) {
509 ret = (int)front->infoCb(front, WOLFSSL_BIO_CB_WRITE,
510 (const char*)data, len, 0, 1);
511 if (ret <= 0) {
512 return ret;
513 }
514 }
515
516 while (bio != NULL && ret >= 0) {
517 /* check for custom write */
518 if (bio->method && bio->method->writeCb) {
519 ret = bio->method->writeCb(bio, (const char*)data, len);
520 }
521
522 /* check for formatting */
523 if (bio->type == WOLFSSL_BIO_BASE64) {
524#if defined(WOLFSSL_BASE64_ENCODE)
525 word32 sz = 0;
526
527 if (bio->flags & WOLFSSL_BIO_FLAG_BASE64_NO_NL) {
528 if (Base64_Encode_NoNl((const byte*)data, len, NULL,
529 &sz) != LENGTH_ONLY_E) {
530 WOLFSSL_MSG("Error with base 64 get length");
531 ret = SSL_FATAL_ERROR;
532 }
533 }
534 else {
535 if (Base64_Encode((const byte*)data, len, NULL, &sz) !=
536 LENGTH_ONLY_E) {
537 WOLFSSL_MSG("Error with base 64 get length");
538 ret = SSL_FATAL_ERROR;
539 }
540 }
541
542 if (frmt == NULL && sz > 0 && ret != SSL_FATAL_ERROR) {
543 frmt = (void*)XMALLOC(sz, front->heap,
544 DYNAMIC_TYPE_TMP_BUFFER);
545 if (frmt == NULL) {
546 WOLFSSL_MSG("Memory error");
547 ret = SSL_FATAL_ERROR;
548 }
549 frmtSz = sz;
550 }
551 else if (sz > frmtSz) {
552 frmt = (void*)XREALLOC(frmt, sz, front->heap,
553 DYNAMIC_TYPE_TMP_BUFFER);
554 if (frmt == NULL) {
555 WOLFSSL_MSG("Memory error");
556 ret = SSL_FATAL_ERROR;
557 }
558 /* since frmt already existed then data should point to knew
559 formatted buffer */
560 data = frmt;
561 len = frmtSz;
562 frmtSz = sz;
563 }
564#endif /* defined(WOLFSSL_BASE64_ENCODE) */
565
566 if (ret >= 0) {
567 /* change so that data is formatted buffer */
568 retB64 = wolfSSL_BIO_BASE64_write(bio, data, (word32)len,
569 (byte*)frmt, &frmtSz);
570 data = frmt;
571 len = frmtSz;
572 }
573 }
574
575 /* write bios */
576 if (bio && bio->type == WOLFSSL_BIO_BIO) {
577 ret = wolfSSL_BIO_BIO_write(bio, data, len);
578 }
579
580 if (bio && bio->type == WOLFSSL_BIO_MEMORY) {
581 ret = wolfSSL_BIO_MEMORY_write(bio, data, len);
582 }
583
584 #ifndef NO_FILESYSTEM
585 if (bio && bio->type == WOLFSSL_BIO_FILE) {
586 ret = (int)XFWRITE(data, 1, len, (XFILE)bio->ptr);
587 }
588 #endif
589
590 #ifndef WOLFCRYPT_ONLY
591 if (bio && bio->type == WOLFSSL_BIO_SSL) {
592 /* already got eof, again is error */
593 if (front->eof) {
594 ret = SSL_FATAL_ERROR;
595 }
596 else {
597 ret = wolfSSL_BIO_SSL_write(bio, data, len, front);
598 }
599 }
600
601 if (bio && bio->type == WOLFSSL_BIO_MD) {
602 if (bio->next != NULL) { /* data passing through MD BIO */
603 ret = wolfSSL_BIO_MD_write(bio, data, len);
604 }
605 }
606 #endif /* WOLFCRYPT_ONLY */
607
608 /* advance to the next bio in list */
609 bio = bio->next;
610 }
611
612 if (frmt != NULL) {
613 XFREE(frmt, front->heap, DYNAMIC_TYPE_TMP_BUFFER);
614 }
615
616 /* info cb, user can override return value */
617 if (front != NULL && front->infoCb != NULL) {
618 ret = (int)front->infoCb(front,
619 WOLFSSL_BIO_CB_WRITE | WOLFSSL_BIO_CB_RETURN,
620 (const char*)data, 0, 0, ret);
621 }
622
623 if (retB64 != 0)
624 return retB64;
625 else
626 return ret;
627}
628
629
630/* Wrapper for other BIO type functions, expected to grow as OpenSSL compatibility
631 * layer grows.
632 *
633 * return info. specific to the cmd that is passed in.
634 */
635#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
636long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bio, int cmd, long larg, void *parg)
637{
638 long ret;
639
640 (void)larg; /* not currently used */
641
642 WOLFSSL_ENTER("wolfSSL_BIO_ctrl");
643
644 if (bio && bio->method && bio->method->ctrlCb) {
645 return bio->method->ctrlCb(bio, cmd, larg, parg);
646 }
647
648 switch(cmd) {
649 case BIO_CTRL_PENDING:
650 case BIO_CTRL_WPENDING:
651 ret = (long)wolfSSL_BIO_ctrl_pending(bio);
652 break;
653 case BIO_CTRL_INFO:
654 ret = (long)wolfSSL_BIO_get_mem_data(bio, parg);
655 break;
656 case BIO_CTRL_FLUSH:
657 ret = (long)wolfSSL_BIO_flush(bio);
658 break;
659 case BIO_CTRL_RESET:
660 ret = (long)wolfSSL_BIO_reset(bio);
661 break;
662 default:
663 WOLFSSL_MSG("CMD not yet implemented");
664 ret = WOLFSSL_FAILURE;
665 break;
666 }
667 return ret;
668}
669#endif
670
671
672/* helper function for wolfSSL_BIO_gets
673 * size till a newline is hit
674 * returns the number of bytes including the new line character
675 */
676static int wolfSSL_getLineLength(char* in, int inSz)
677{
678 int i;
679
680 for (i = 0; i < inSz; i++) {
681 if (in[i] == '\n') {
682 return i + 1; /* includes new line character */
683 }
684 }
685
686 return inSz; /* rest of buffer is all one line */
687}
688
689
690/* Gets the next line from bio. Goes until a new line character or end of
691 * buffer is reached.
692 *
693 * bio the structure to read a new line from
694 * buf buffer to hold the result
695 * sz the size of "buf" buffer
696 *
697 * returns the size of the result placed in buf on success and a 0 or negative
698 * value in an error case.
699 */
700int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz)
701{
702 int ret = WOLFSSL_BIO_UNSET;
703
704 WOLFSSL_ENTER("wolfSSL_BIO_gets");
705
706 if (bio == NULL || buf == NULL) {
707 return WOLFSSL_FAILURE;
708 }
709
710 /* not enough space for character plus terminator */
711 if (sz <= 1) {
712 return 0;
713 }
714
715 /* info cb, abort if user returns <= 0*/
716 if (bio->infoCb != NULL) {
717 ret = (int)bio->infoCb(bio, WOLFSSL_BIO_CB_GETS, buf, sz, 0, 1);
718 if (ret <= 0) {
719 return ret;
720 }
721 }
722
723 /* check if is custom method */
724 if (bio->method && bio->method->getsCb) {
725 return bio->method->getsCb(bio, buf, sz);
726 }
727
728 switch (bio->type) {
729#ifndef NO_FILESYSTEM
730 case WOLFSSL_BIO_FILE:
731 if (((XFILE)bio->ptr) == XBADFILE) {
732 return WOLFSSL_BIO_ERROR;
733 }
734
735 #if defined(MICRIUM) || defined(LSR_FS) || defined(EBSNET)
736 WOLFSSL_MSG("XFGETS not ported for this system yet");
737 ret = XFGETS(buf, sz, (XFILE)bio->ptr);
738 #else
739 if (XFGETS(buf, sz, (XFILE)bio->ptr) != NULL) {
740 ret = (int)XSTRLEN(buf);
741 }
742 else {
743 ret = WOLFSSL_BIO_ERROR;
744 }
745 #endif
746 break;
747#endif /* NO_FILESYSTEM */
748 case WOLFSSL_BIO_MEMORY:
749 {
750 const byte* c;
751 int cSz;
752 cSz = wolfSSL_BIO_pending(bio);
753 if (cSz == 0) {
754 ret = 0; /* Nothing to read */
755 buf[0] = '\0';
756 break;
757 }
758
759 if (wolfSSL_BIO_get_mem_data(bio, (void*)&c) <= 0) {
760 ret = WOLFSSL_BIO_ERROR;
761 break;
762 }
763
764 cSz = wolfSSL_getLineLength((char*)c, cSz);
765 /* check case where line was bigger then buffer and buffer
766 * needs end terminator */
767 if (cSz >= sz) {
768 cSz = sz - 1;
769 buf[cSz] = '\0';
770 }
771 else {
772 /* not minus 1 here because placing terminator after
773 msg and have checked that sz is large enough */
774 buf[cSz] = '\0';
775 }
776
777 ret = wolfSSL_BIO_MEMORY_read(bio, (void*)buf, cSz);
778 /* ret is read after the switch statement */
779 break;
780 }
781 case WOLFSSL_BIO_BIO:
782 {
783 char* c;
784 int cSz;
785 cSz = wolfSSL_BIO_nread0(bio, &c);
786 if (cSz == 0) {
787 ret = 0; /* Nothing to read */
788 buf[0] = '\0';
789 break;
790 }
791
792 cSz = wolfSSL_getLineLength(c, cSz);
793 /* check case where line was bigger then buffer and buffer
794 * needs end terminator */
795 if (cSz >= sz) {
796 cSz = sz - 1;
797 buf[cSz] = '\0';
798 }
799 else {
800 /* not minus 1 here because placing terminator after
801 msg and have checked that sz is large enough */
802 buf[cSz] = '\0';
803 }
804
805 ret = wolfSSL_BIO_nread(bio, &c, cSz);
806 if (ret > 0 && ret < sz) {
807 XMEMCPY(buf, c, ret);
808 }
809 break;
810 }
811
812#ifndef WOLFCRYPT_ONLY
813 /* call final on hash */
814 case WOLFSSL_BIO_MD:
815 if (wolfSSL_EVP_MD_CTX_size((WOLFSSL_EVP_MD_CTX*)bio->ptr) > sz) {
816 WOLFSSL_MSG("Output buffer was too small for digest");
817 ret = WOLFSSL_FAILURE;
818 }
819 else {
820 unsigned int szOut = 0;
821 ret = wolfSSL_EVP_DigestFinal((WOLFSSL_EVP_MD_CTX*)bio->ptr,
822 (unsigned char*)buf, &szOut);
823 if (ret == WOLFSSL_SUCCESS) {
824 ret = szOut;
825 }
826 }
827 break;
828#endif /* WOLFCRYPT_ONLY */
829
830 default:
831 WOLFSSL_MSG("BIO type not supported yet with wolfSSL_BIO_gets");
832 }
833
834 /* info cb, user can override return value */
835 if (bio->infoCb != NULL) {
836 ret = (int)bio->infoCb(bio, WOLFSSL_BIO_CB_GETS | WOLFSSL_BIO_CB_RETURN,
837 buf, sz, 0, ret);
838 }
839
840 return ret;
841}
842
843
844/* Writes a null terminated string to bio.
845 *
846 * bio the structure to write to
847 * buf buffer to holding input string
848 *
849 * returns the size of the result placed in bio on success and a 0 or negative
850 * value in an error case. -2 is returned if the implementation is not
851 * supported for the BIO type.
852 */
853int wolfSSL_BIO_puts(WOLFSSL_BIO* bio, const char* buf)
854{
855 int sz;
856
857 if (bio == NULL || buf == NULL) {
858 return WOLFSSL_FATAL_ERROR;
859 }
860
861 /* check if is custom method */
862 if (bio->method && bio->method->putsCb) {
863 return bio->method->putsCb(bio, buf);
864 }
865
866 sz = (int)XSTRLEN(buf);
867 if (sz <= 0) {
868 return WOLFSSL_FATAL_ERROR;
869 }
870
871 return wolfSSL_BIO_write(bio, buf, sz);
872}
873
874
875/* searches through bio list for a BIO of type "type"
876 * returns NULL on failure to find a given type */
877WOLFSSL_BIO* wolfSSL_BIO_find_type(WOLFSSL_BIO* bio, int type)
878{
879 WOLFSSL_BIO* local = NULL;
880 WOLFSSL_BIO* current;
881
882 WOLFSSL_ENTER("wolfSSL_BIO_find_type");
883
884 if (bio == NULL) {
885 return local;
886 }
887
888 current = bio;
889 while (current != NULL) {
890 if (current->type == type) {
891 WOLFSSL_MSG("Found matching WOLFSSL_BIO type");
892 local = current;
893 break;
894 }
895 current = current->next;
896 }
897
898 return local;
899}
900
901
902/* returns a pointer to the next WOLFSSL_BIO in the chain on success.
903 * If a failure case then NULL is returned */
904WOLFSSL_BIO* wolfSSL_BIO_next(WOLFSSL_BIO* bio)
905{
906 WOLFSSL_ENTER("wolfSSL_BIO_next");
907
908 if (bio == NULL) {
909 WOLFSSL_MSG("Bad argument passed in");
910 return NULL;
911 }
912
913 return bio->next;
914}
915
916/* BIO_wpending returns the number of bytes pending to be written. */
917size_t wolfSSL_BIO_wpending(const WOLFSSL_BIO *bio)
918{
919 WOLFSSL_ENTER("BIO_wpending");
920
921 if (bio == NULL)
922 return 0;
923
924 if (bio->type == WOLFSSL_BIO_MEMORY) {
925 return bio->wrSz;
926 }
927
928 /* type BIO_BIO then check paired buffer */
929 if (bio->type == WOLFSSL_BIO_BIO && bio->pair != NULL) {
930 WOLFSSL_BIO* pair = bio->pair;
931 return pair->wrIdx;
932 }
933
934 return 0;
935}
936
937/* Return the number of pending bytes in read and write buffers */
938size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio)
939{
940 WOLFSSL_ENTER("wolfSSL_BIO_ctrl_pending");
941 if (bio == NULL) {
942 return 0;
943 }
944
945 if (bio->type == WOLFSSL_BIO_MD) {
946 /* MD is a wrapper only get next bio */
947 while (bio->next != NULL) {
948 bio = bio->next;
949 if (bio->type != WOLFSSL_BIO_MD) {
950 break;
951 }
952 }
953 }
954
955#ifndef WOLFCRYPT_ONLY
956 if (bio->type == WOLFSSL_BIO_SSL && bio->ptr != NULL) {
957 return (long)wolfSSL_pending((WOLFSSL*)bio->ptr);
958 }
959#endif
960
961 if (bio->type == WOLFSSL_BIO_MEMORY) {
962 return bio->wrSz;
963 }
964
965 /* type BIO_BIO then check paired buffer */
966 if (bio->type == WOLFSSL_BIO_BIO && bio->pair != NULL) {
967 WOLFSSL_BIO* pair = bio->pair;
968 if (pair->wrIdx > 0 && pair->wrIdx <= pair->rdIdx) {
969 /* in wrap around state where beginning of buffer is being
970 * overwritten */
971 return pair->wrSz - pair->rdIdx + pair->wrIdx;
972 }
973 else {
974 /* simple case where has not wrapped around */
975 return pair->wrIdx - pair->rdIdx;
976 }
977 }
978 return 0;
979}
980
981
982long wolfSSL_BIO_get_mem_ptr(WOLFSSL_BIO *bio, WOLFSSL_BUF_MEM **ptr)
983{
984 WOLFSSL_BIO* front = bio;
985 long ret = WOLFSSL_FAILURE;
986
987 WOLFSSL_ENTER("wolfSSL_BIO_get_mem_ptr");
988
989 if (bio == NULL || ptr == NULL) {
990 return WOLFSSL_FAILURE;
991 }
992
993 /* start at end and work backwards to find a memory BIO in the BIO chain */
994 while ((bio != NULL) && (bio->next != NULL)) {
995 bio = bio->next;
996 }
997
998 while (bio != NULL) {
999
1000 if (bio->type == WOLFSSL_BIO_MEMORY) {
1001 *ptr = bio->mem_buf;
1002 ret = WOLFSSL_SUCCESS;
1003 }
1004
1005 if (bio == front) {
1006 break;
1007 }
1008 bio = bio->prev;
1009 }
1010
1011 return ret;
1012}
1013
1014WOLFSSL_API long wolfSSL_BIO_int_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, int iarg)
1015{
1016 (void) bp;
1017 (void) cmd;
1018 (void) larg;
1019 (void) iarg;
1020 WOLFSSL_STUB("BIO_int_ctrl");
1021 return 0;
1022}
1023
1024
1025int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *bio, long size)
1026{
1027 WOLFSSL_ENTER("wolfSSL_BIO_set_write_buf_size");
1028
1029 if (bio == NULL || bio->type != WOLFSSL_BIO_BIO || size < 0) {
1030 return WOLFSSL_FAILURE;
1031 }
1032
1033 /* if already in pair then do not change size */
1034 if (bio->pair != NULL) {
1035 WOLFSSL_MSG("WOLFSSL_BIO is paired, free from pair before changing");
1036 return WOLFSSL_FAILURE;
1037 }
1038
1039 bio->wrSz = (int)size;
1040 if (bio->wrSz < 0) {
1041 WOLFSSL_MSG("Unexpected negative size value");
1042 return WOLFSSL_FAILURE;
1043 }
1044
1045 if (bio->ptr != NULL) {
1046 XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
1047 }
1048
1049 bio->ptr = (byte*)XMALLOC(bio->wrSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
1050 if (bio->ptr == NULL) {
1051 WOLFSSL_MSG("Memory allocation error");
1052 return WOLFSSL_FAILURE;
1053 }
1054 bio->num = bio->wrSz;
1055 bio->wrIdx = 0;
1056 bio->rdIdx = 0;
1057 if (bio->mem_buf != NULL) {
1058 bio->mem_buf->data = (char*)bio->ptr;
1059 bio->mem_buf->length = bio->num;
1060 }
1061
1062 return WOLFSSL_SUCCESS;
1063}
1064
1065
1066/* Joins two BIO_BIO types. The write of b1 goes to the read of b2 and vice
1067 * versa. Creating something similar to a two way pipe.
1068 * Reading and writing between the two BIOs is not thread safe, they are
1069 * expected to be used by the same thread. */
1070int wolfSSL_BIO_make_bio_pair(WOLFSSL_BIO *b1, WOLFSSL_BIO *b2)
1071{
1072 WOLFSSL_ENTER("wolfSSL_BIO_make_bio_pair");
1073
1074 if (b1 == NULL || b2 == NULL) {
1075 WOLFSSL_LEAVE("wolfSSL_BIO_make_bio_pair", BAD_FUNC_ARG);
1076 return WOLFSSL_FAILURE;
1077 }
1078
1079 /* both are expected to be of type BIO and not already paired */
1080 if (b1->type != WOLFSSL_BIO_BIO || b2->type != WOLFSSL_BIO_BIO ||
1081 b1->pair != NULL || b2->pair != NULL) {
1082 WOLFSSL_MSG("Expected type BIO and not already paired");
1083 return WOLFSSL_FAILURE;
1084 }
1085
1086 /* set default write size if not already set */
1087 if (b1->ptr == NULL && wolfSSL_BIO_set_write_buf_size(b1,
1088 WOLFSSL_BIO_SIZE) != WOLFSSL_SUCCESS) {
1089 return WOLFSSL_FAILURE;
1090 }
1091
1092 if (b2->ptr == NULL && wolfSSL_BIO_set_write_buf_size(b2,
1093 WOLFSSL_BIO_SIZE) != WOLFSSL_SUCCESS) {
1094 return WOLFSSL_FAILURE;
1095 }
1096
1097 b1->pair = b2;
1098 b2->pair = b1;
1099
1100 return WOLFSSL_SUCCESS;
1101}
1102
1103
1104int wolfSSL_BIO_ctrl_reset_read_request(WOLFSSL_BIO *b)
1105{
1106 WOLFSSL_ENTER("wolfSSL_BIO_ctrl_reset_read_request");
1107
1108 if (b == NULL || b->type == WOLFSSL_BIO_MEMORY) {
1109 return SSL_FAILURE;
1110 }
1111
1112 b->readRq = 0;
1113
1114 return WOLFSSL_SUCCESS;
1115}
1116
1117
1118/* Does not advance read index pointer */
1119int wolfSSL_BIO_nread0(WOLFSSL_BIO *bio, char **buf)
1120{
1121 WOLFSSL_ENTER("wolfSSL_BIO_nread0");
1122
1123 if (bio == NULL || buf == NULL) {
1124 WOLFSSL_MSG("NULL argument passed in");
1125 return 0;
1126 }
1127
1128 /* if paired read from pair */
1129 if (bio->pair != NULL) {
1130 WOLFSSL_BIO* pair = bio->pair;
1131
1132 /* case where have wrapped around write buffer */
1133 *buf = (char*)pair->ptr + pair->rdIdx;
1134 if (pair->wrIdx > 0 && pair->rdIdx >= pair->wrIdx) {
1135 return pair->wrSz - pair->rdIdx;
1136 }
1137 else {
1138 return pair->wrIdx - pair->rdIdx;
1139 }
1140 }
1141
1142 return 0;
1143}
1144
1145
1146/* similar to wolfSSL_BIO_nread0 but advances the read index */
1147int wolfSSL_BIO_nread(WOLFSSL_BIO *bio, char **buf, int num)
1148{
1149 int sz = WOLFSSL_BIO_UNSET;
1150
1151 WOLFSSL_ENTER("wolfSSL_BIO_nread");
1152
1153 if (bio == NULL || buf == NULL) {
1154 WOLFSSL_MSG("NULL argument passed in");
1155 return WOLFSSL_FAILURE;
1156 }
1157
1158 if (bio->type == WOLFSSL_BIO_MEMORY) {
1159 return SSL_FAILURE;
1160 }
1161
1162 if (bio->pair != NULL) {
1163 /* special case if asking to read 0 bytes */
1164 if (num == 0) {
1165 *buf = (char*)bio->pair->ptr + bio->pair->rdIdx;
1166 return 0;
1167 }
1168
1169 /* get amount able to read and set buffer pointer */
1170 sz = wolfSSL_BIO_nread0(bio, buf);
1171 if (sz == 0) {
1172 return WOLFSSL_BIO_ERROR;
1173 }
1174
1175 if (num < sz) {
1176 sz = num;
1177 }
1178 bio->pair->rdIdx += sz;
1179
1180 /* check if have read to the end of the buffer and need to reset */
1181 if (bio->pair->rdIdx == bio->pair->wrSz) {
1182 bio->pair->rdIdx = 0;
1183 if (bio->pair->wrIdx == bio->pair->wrSz) {
1184 bio->pair->wrIdx = 0;
1185 }
1186 }
1187
1188 /* check if read up to write index, if so then reset index */
1189 if (bio->pair->rdIdx == bio->pair->wrIdx) {
1190 bio->pair->rdIdx = 0;
1191 bio->pair->wrIdx = 0;
1192 }
1193 }
1194
1195 return sz;
1196}
1197
1198
1199int wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num)
1200{
1201 int sz = WOLFSSL_BIO_UNSET;
1202
1203 WOLFSSL_ENTER("wolfSSL_BIO_nwrite");
1204
1205 if (bio == NULL || buf == NULL) {
1206 WOLFSSL_MSG("NULL argument passed in");
1207 return 0;
1208 }
1209
1210 if (bio->type != WOLFSSL_BIO_BIO) {
1211 return SSL_FAILURE;
1212 }
1213
1214 if (bio->pair != NULL) {
1215 if (num == 0) {
1216 *buf = (char*)bio->ptr + bio->wrIdx;
1217 return 0;
1218 }
1219
1220 if (bio->wrIdx < bio->rdIdx) {
1221 /* if wrapped around only write up to read index. In this case
1222 * rdIdx is always greater then wrIdx so sz will not be negative. */
1223 sz = bio->rdIdx - bio->wrIdx;
1224 }
1225 else if (bio->rdIdx > 0 && bio->wrIdx == bio->rdIdx) {
1226 return WOLFSSL_BIO_ERROR; /* no more room to write */
1227 }
1228 else {
1229 /* write index is past read index so write to end of buffer */
1230 sz = bio->wrSz - bio->wrIdx;
1231
1232 if (sz <= 0) {
1233 /* either an error has occurred with write index or it is at the
1234 * end of the write buffer. */
1235 if (bio->rdIdx == 0) {
1236 /* no more room, nothing has been read */
1237 return WOLFSSL_BIO_ERROR;
1238 }
1239
1240 bio->wrIdx = 0;
1241
1242 /* check case where read index is not at 0 */
1243 if (bio->rdIdx > 0) {
1244 sz = bio->rdIdx; /* can write up to the read index */
1245 }
1246 else {
1247 sz = bio->wrSz; /* no restriction other then buffer size */
1248 }
1249 }
1250 }
1251
1252 if (num < sz) {
1253 sz = num;
1254 }
1255 *buf = (char*)bio->ptr + bio->wrIdx;
1256 bio->wrIdx += sz;
1257
1258 /* if at the end of the buffer and space for wrap around then set
1259 * write index back to 0 */
1260 if (bio->wrIdx == bio->wrSz && bio->rdIdx > 0) {
1261 bio->wrIdx = 0;
1262 }
1263 }
1264
1265 return sz;
1266}
1267
1268
1269/* Reset BIO to initial state */
1270int wolfSSL_BIO_reset(WOLFSSL_BIO *bio)
1271{
1272 WOLFSSL_ENTER("wolfSSL_BIO_reset");
1273
1274 if (bio == NULL) {
1275 WOLFSSL_MSG("NULL argument passed in");
1276 /* -1 is consistent failure even for FILE type */
1277 return WOLFSSL_BIO_ERROR;
1278 }
1279
1280 switch (bio->type) {
1281 #ifndef NO_FILESYSTEM
1282 case WOLFSSL_BIO_FILE:
1283 XREWIND((XFILE)bio->ptr);
1284 return 0;
1285 #endif
1286
1287 case WOLFSSL_BIO_BIO:
1288 bio->rdIdx = 0;
1289 bio->wrIdx = 0;
1290 return 0;
1291
1292 case WOLFSSL_BIO_MEMORY:
1293 bio->rdIdx = 0;
1294 bio->wrIdx = 0;
1295 bio->wrSz = 0;
1296 XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
1297 bio->ptr = NULL;
1298 bio->num = 0;
1299 if (bio->mem_buf != NULL) {
1300 bio->mem_buf->data = (char*)bio->ptr;
1301 bio->mem_buf->length = bio->num;
1302 }
1303 return 0;
1304
1305#ifndef WOLFCRYPT_ONLY
1306 case WOLFSSL_BIO_MD:
1307 if (bio->ptr != NULL) {
1308 const WOLFSSL_EVP_MD* md =
1309 wolfSSL_EVP_MD_CTX_md((WOLFSSL_EVP_MD_CTX*)bio->ptr);
1310 wolfSSL_EVP_MD_CTX_init((WOLFSSL_EVP_MD_CTX*)bio->ptr);
1311 wolfSSL_EVP_DigestInit((WOLFSSL_EVP_MD_CTX*)bio->ptr, md);
1312 }
1313 return 0;
1314#endif /* WOLFCRYPT_ONLY */
1315
1316 default:
1317 WOLFSSL_MSG("Unknown BIO type needs added to reset function");
1318 }
1319
1320 return WOLFSSL_BIO_ERROR;
1321}
1322
1323#ifndef NO_FILESYSTEM
1324long wolfSSL_BIO_set_fp(WOLFSSL_BIO *bio, XFILE fp, int c)
1325{
1326 WOLFSSL_ENTER("wolfSSL_BIO_set_fp");
1327
1328 if (bio == NULL || fp == XBADFILE) {
1329 WOLFSSL_LEAVE("wolfSSL_BIO_set_fp", BAD_FUNC_ARG);
1330 return WOLFSSL_FAILURE;
1331 }
1332
1333 if (bio->type != WOLFSSL_BIO_FILE) {
1334 return WOLFSSL_FAILURE;
1335 }
1336
1337 bio->shutdown = (byte)c;
1338 bio->ptr = (XFILE)fp;
1339
1340 return WOLFSSL_SUCCESS;
1341}
1342
1343
1344long wolfSSL_BIO_get_fp(WOLFSSL_BIO *bio, XFILE* fp)
1345{
1346 WOLFSSL_ENTER("wolfSSL_BIO_get_fp");
1347
1348 if (bio == NULL || fp == XBADFILE) {
1349 return WOLFSSL_FAILURE;
1350 }
1351
1352 if (bio->type != WOLFSSL_BIO_FILE) {
1353 return SSL_FAILURE;
1354 }
1355
1356 *fp = (XFILE)bio->ptr;
1357
1358 return WOLFSSL_SUCCESS;
1359}
1360
1361/* overwrites file */
1362int wolfSSL_BIO_write_filename(WOLFSSL_BIO *bio, char *name)
1363{
1364 WOLFSSL_ENTER("wolfSSL_BIO_write_filename");
1365
1366 if (bio == NULL || name == NULL) {
1367 return WOLFSSL_FAILURE;
1368 }
1369
1370 if (bio->type == WOLFSSL_BIO_FILE) {
1371 if (((XFILE)bio->ptr) != XBADFILE && bio->shutdown == BIO_CLOSE) {
1372 XFCLOSE((XFILE)bio->ptr);
1373 }
1374
1375 bio->ptr = XFOPEN(name, "w");
1376 if (((XFILE)bio->ptr) == XBADFILE) {
1377 return WOLFSSL_FAILURE;
1378 }
1379 bio->shutdown = BIO_CLOSE;
1380
1381 return WOLFSSL_SUCCESS;
1382 }
1383
1384 return WOLFSSL_FAILURE;
1385}
1386
1387
1388int wolfSSL_BIO_seek(WOLFSSL_BIO *bio, int ofs)
1389{
1390 WOLFSSL_ENTER("wolfSSL_BIO_seek");
1391
1392 if (bio == NULL) {
1393 return -1;
1394 }
1395
1396 /* offset ofs from beginning of file */
1397 if (bio->type == WOLFSSL_BIO_FILE &&
1398 XFSEEK((XFILE)bio->ptr, ofs, SEEK_SET) < 0) {
1399 return -1;
1400 }
1401
1402 return 0;
1403}
1404#endif /* NO_FILESYSTEM */
1405
1406
1407long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v)
1408{
1409 WOLFSSL_ENTER("wolfSSL_BIO_set_mem_eof_return");
1410
1411 if (bio != NULL) {
1412 bio->eof = v;
1413 }
1414
1415 return 0;
1416}
1417
1418int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio)
1419{
1420 int len;
1421#ifndef NO_FILESYSTEM
1422 long memSz = 0, curr = 0;
1423 XFILE file;
1424#endif
1425
1426 WOLFSSL_ENTER("wolfSSL_BIO_get_len");
1427
1428 if ((len = wolfSSL_BIO_pending(bio)) > 0) {
1429 }
1430#ifndef NO_FILESYSTEM
1431 else if (bio->type == WOLFSSL_BIO_FILE) {
1432 if (wolfSSL_BIO_get_fp(bio, &file) != WOLFSSL_SUCCESS)
1433 len = BAD_FUNC_ARG;
1434 if (len == 0) {
1435 curr = XFTELL(file);
1436 if (curr < 0) {
1437 len = WOLFSSL_BAD_FILE;
1438 }
1439 if (XFSEEK(file, 0, XSEEK_END) != 0)
1440 len = WOLFSSL_BAD_FILE;
1441 }
1442 if (len == 0) {
1443 memSz = XFTELL(file);
1444 if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz < 0)
1445 len = WOLFSSL_BAD_FILE;
1446 }
1447 if (len == 0) {
1448 memSz -= curr;
1449 len = (int)memSz;
1450 if (XFSEEK(file, curr, SEEK_SET) != 0)
1451 len = WOLFSSL_BAD_FILE;
1452 }
1453 }
1454#endif
1455 return len;
1456}
1457
1458
1459void wolfSSL_BIO_set_callback(WOLFSSL_BIO *bio, wolf_bio_info_cb callback_func)
1460{
1461 WOLFSSL_ENTER("wolfSSL_BIO_set_callback");
1462
1463 if (bio != NULL) {
1464 bio->infoCb = callback_func;
1465 }
1466}
1467
1468
1469wolf_bio_info_cb wolfSSL_BIO_get_callback(WOLFSSL_BIO *bio)
1470{
1471 WOLFSSL_ENTER("wolfSSL_BIO_get_callback");
1472
1473 if (bio != NULL) {
1474 return bio->infoCb;
1475 }
1476
1477 return NULL;
1478}
1479
1480
1481void wolfSSL_BIO_set_callback_arg(WOLFSSL_BIO *bio, char *arg)
1482{
1483 WOLFSSL_ENTER("wolfSSL_BIO_set_callback_arg");
1484
1485 if (bio != NULL) {
1486 bio->infoArg = arg;
1487 }
1488}
1489
1490
1491char* wolfSSL_BIO_get_callback_arg(const WOLFSSL_BIO *bio)
1492{
1493 WOLFSSL_ENTER("wolfSSL_BIO_get_callback_arg");
1494
1495 if (bio != NULL) {
1496 return bio->infoArg;
1497 }
1498
1499 return NULL;
1500}
1501
1502
1503/* store a user pointer in the WOLFSSL_BIO structure */
1504void wolfSSL_BIO_set_data(WOLFSSL_BIO* bio, void *ptr)
1505{
1506 WOLFSSL_ENTER("wolfSSL_BIO_set_data");
1507
1508 if (bio != NULL) {
1509 bio->usrCtx = ptr;
1510 }
1511}
1512
1513
1514void* wolfSSL_BIO_get_data(WOLFSSL_BIO* bio)
1515{
1516 WOLFSSL_ENTER("wolfSSL_BIO_get_data");
1517
1518 if (bio != NULL)
1519 return bio->usrCtx;
1520
1521 WOLFSSL_MSG("WOLFSSL_BIO was null");
1522 return NULL;
1523}
1524
1525/* If flag is 0 then blocking is set, if 1 then non blocking.
1526 * Always returns 1
1527 */
1528long wolfSSL_BIO_set_nbio(WOLFSSL_BIO* bio, long on)
1529{
1530 #ifndef WOLFSSL_DTLS
1531 (void)on;
1532 #endif
1533 WOLFSSL_ENTER("wolfSSL_BIO_set_nbio");
1534
1535 switch (bio->type) {
1536 case WOLFSSL_BIO_SOCKET:
1537 #ifdef XFCNTL
1538 {
1539 int flag = XFCNTL(bio->num, F_GETFL, 0);
1540 if (on)
1541 XFCNTL(bio->num, F_SETFL, flag | O_NONBLOCK);
1542 else
1543 XFCNTL(bio->num, F_SETFL, flag & ~O_NONBLOCK);
1544 }
1545 #endif
1546 break;
1547 case WOLFSSL_BIO_SSL:
1548 #ifdef WOLFSSL_DTLS
1549 wolfSSL_dtls_set_using_nonblock((WOLFSSL*)bio->ptr, (int)on);
1550 #endif
1551 break;
1552
1553 default:
1554 WOLFSSL_MSG("Unsupported bio type for non blocking");
1555 break;
1556 }
1557
1558 return 1;
1559}
1560
1561
1562
1563/* creates a new custom WOLFSSL_BIO_METHOD */
1564WOLFSSL_BIO_METHOD *wolfSSL_BIO_meth_new(int type, const char *name)
1565{
1566 WOLFSSL_BIO_METHOD* meth;
1567
1568 WOLFSSL_ENTER("wolfSSL_BIO_meth_new");
1569
1570 meth = (WOLFSSL_BIO_METHOD*)XMALLOC(sizeof(WOLFSSL_BIO_METHOD), NULL,
1571 DYNAMIC_TYPE_OPENSSL);
1572 if (meth == NULL) {
1573 WOLFSSL_MSG("Error allocating memory for WOLFSSL_BIO_METHOD");
1574 return NULL;
1575 }
1576 XMEMSET(meth, 0, sizeof(WOLFSSL_BIO_METHOD));
1577 meth->type = (byte)type;
1578 XSTRNCPY(meth->name, name, MAX_BIO_METHOD_NAME - 1);
1579
1580 return meth;
1581}
1582
1583
1584void wolfSSL_BIO_meth_free(WOLFSSL_BIO_METHOD *biom)
1585{
1586 WOLFSSL_ENTER("wolfSSL_BIO_meth_free");
1587 if (biom) {
1588 XFREE(biom, NULL, DYNAMIC_TYPE_OPENSSL);
1589 }
1590}
1591
1592
1593int wolfSSL_BIO_meth_set_write(WOLFSSL_BIO_METHOD *biom,
1594 wolfSSL_BIO_meth_write_cb biom_write)
1595{
1596 WOLFSSL_ENTER("wolfSSL_BIO_meth_set_write");
1597 if (biom) {
1598 biom->writeCb = biom_write;
1599 return WOLFSSL_SUCCESS;
1600 }
1601 return WOLFSSL_FAILURE;
1602}
1603
1604
1605int wolfSSL_BIO_meth_set_read(WOLFSSL_BIO_METHOD *biom,
1606 wolfSSL_BIO_meth_read_cb biom_read)
1607{
1608 WOLFSSL_ENTER("wolfSSL_BIO_meth_set_read");
1609 if (biom) {
1610 biom->readCb = biom_read;
1611 return WOLFSSL_SUCCESS;
1612 }
1613 return WOLFSSL_FAILURE;
1614}
1615
1616
1617int wolfSSL_BIO_meth_set_puts(WOLFSSL_BIO_METHOD *biom,
1618 wolfSSL_BIO_meth_puts_cb biom_puts)
1619{
1620 WOLFSSL_ENTER("wolfSSL_BIO_meth_set_puts");
1621 if (biom) {
1622 biom->putsCb = biom_puts;
1623 return WOLFSSL_SUCCESS;
1624 }
1625 return WOLFSSL_FAILURE;
1626}
1627
1628
1629int wolfSSL_BIO_meth_set_gets(WOLFSSL_BIO_METHOD *biom,
1630 wolfSSL_BIO_meth_gets_cb biom_gets)
1631{
1632 WOLFSSL_ENTER("wolfSSL_BIO_meth_set_gets");
1633 if (biom) {
1634 biom->getsCb = biom_gets;
1635 return WOLFSSL_SUCCESS;
1636 }
1637 return WOLFSSL_FAILURE;
1638}
1639
1640
1641int wolfSSL_BIO_meth_set_ctrl(WOLFSSL_BIO_METHOD *biom,
1642 wolfSSL_BIO_meth_ctrl_get_cb biom_ctrl)
1643{
1644 WOLFSSL_ENTER("wolfSSL_BIO_meth_set_ctrl");
1645 if (biom) {
1646 biom->ctrlCb = biom_ctrl;
1647 return WOLFSSL_SUCCESS;
1648 }
1649 return WOLFSSL_FAILURE;
1650}
1651
1652
1653int wolfSSL_BIO_meth_set_create(WOLFSSL_BIO_METHOD *biom,
1654 wolfSSL_BIO_meth_create_cb biom_create)
1655{
1656 WOLFSSL_ENTER("wolfSSL_BIO_meth_set_create");
1657 if (biom) {
1658 biom->createCb = biom_create;
1659 return WOLFSSL_SUCCESS;
1660 }
1661 return WOLFSSL_FAILURE;
1662}
1663
1664
1665int wolfSSL_BIO_meth_set_destroy(WOLFSSL_BIO_METHOD *biom,
1666 wolfSSL_BIO_meth_destroy_cb biom_destroy)
1667{
1668 WOLFSSL_STUB("wolfSSL_BIO_meth_set_destroy");
1669 if (biom) {
1670 biom->freeCb = biom_destroy;
1671 return WOLFSSL_SUCCESS;
1672 }
1673 return WOLFSSL_FAILURE;
1674}
1675
1676
1677/* this compatibility function can be used for multiple BIO types */
1678int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, void* p)
1679{
1680 WOLFSSL_ENTER("wolfSSL_BIO_get_mem_data");
1681
1682 if (bio == NULL)
1683 return WOLFSSL_FATAL_ERROR;
1684
1685 if (p) {
1686 *(byte**)p = (byte*)bio->ptr;
1687 }
1688
1689 return bio->num;
1690}
1691
1692int wolfSSL_BIO_pending(WOLFSSL_BIO* bio)
1693{
1694 return (int)wolfSSL_BIO_ctrl_pending(bio);
1695}
1696
1697
1698int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
1699{
1700 /* for wolfSSL no flushing needed */
1701 WOLFSSL_ENTER("BIO_flush");
1702 (void)bio;
1703 return 1;
1704}
1705#endif /* WOLFSSL_BIO_INCLUDED */
Note: See TracBrowser for help on using the repository browser.