source: azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/src/bio.c@ 464

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

WolfSSLとAzure IoT SDKを更新

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