bio.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134
  1. /* bio.c
  2. *
  3. * Copyright (C) 2006-2017 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. #if !defined(WOLFSSL_BIO_INCLUDED)
  22. #warning bio.c does not need to be compiled seperatly from ssl.c
  23. #else
  24. /* Helper function to decode a base64 input
  25. *
  26. * returns size of resulting buffer on success
  27. */
  28. static int wolfSSL_BIO_BASE64_read(WOLFSSL_BIO* bio, void* buf, int len)
  29. {
  30. word32 frmtSz = len;
  31. WOLFSSL_ENTER("wolfSSL_BIO_BASE64_read");
  32. if (Base64_Decode((const byte*)buf, (word32)len, (byte*)buf, &frmtSz) !=0) {
  33. WOLFSSL_MSG("Err doing base64 decode");
  34. return SSL_FATAL_ERROR;
  35. }
  36. (void)bio;
  37. return (int)frmtSz;
  38. }
  39. /* Helper function to read from WOLFSSL_BIO_BIO type
  40. *
  41. * returns amount in bytes read on success
  42. */
  43. static int wolfSSL_BIO_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
  44. {
  45. int sz;
  46. char* pt;
  47. sz = wolfSSL_BIO_nread(bio, &pt, len);
  48. if (sz > 0) {
  49. XMEMCPY(buf, pt, sz);
  50. }
  51. return sz;
  52. }
  53. /* Handles reading from a memory type BIO and advancing the state.
  54. *
  55. * bio WOLFSSL_BIO to read from
  56. * buf buffer to put data from bio in
  57. * len amount of data to be read
  58. *
  59. * returns size read on success
  60. */
  61. static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len)
  62. {
  63. int sz;
  64. sz = wolfSSL_BIO_pending(bio);
  65. if (sz > 0) {
  66. const unsigned char* pt = NULL;
  67. int memSz;
  68. if (sz > len) {
  69. sz = len;
  70. }
  71. memSz = wolfSSL_BIO_get_mem_data(bio, (void*)&pt);
  72. if (memSz >= sz && pt != NULL) {
  73. byte* tmp;
  74. XMEMCPY(buf, (void*)pt, sz);
  75. if (memSz - sz > 0) {
  76. tmp = (byte*)XMALLOC(memSz-sz, bio->heap, DYNAMIC_TYPE_OPENSSL);
  77. if (tmp == NULL) {
  78. WOLFSSL_MSG("Memory error");
  79. return WOLFSSL_BIO_ERROR;
  80. }
  81. XMEMCPY(tmp, (void*)(pt + sz), memSz - sz);
  82. /* reset internal bio->mem */
  83. XFREE(bio->mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
  84. bio->mem = tmp;
  85. bio->memLen = memSz-sz;
  86. if (bio->mem_buf != NULL) {
  87. bio->mem_buf->data = (char*)bio->mem;
  88. bio->mem_buf->length = bio->memLen;
  89. }
  90. }
  91. bio->wrSz -= sz;
  92. }
  93. else {
  94. WOLFSSL_MSG("Issue with getting bio mem pointer");
  95. return 0;
  96. }
  97. }
  98. else {
  99. return WOLFSSL_BIO_ERROR;
  100. }
  101. return sz;
  102. }
  103. /* Helper function to read from WOLFSSL_BIO_SSL type
  104. *
  105. * returns the number of bytes read on success
  106. */
  107. static int wolfSSL_BIO_SSL_read(WOLFSSL_BIO* bio, void* buf,
  108. int len, WOLFSSL_BIO* front)
  109. {
  110. int ret;
  111. WOLFSSL_ENTER("wolfSSL_BIO_SSL_write");
  112. /* already got eof, again is error */
  113. if (bio && front->eof)
  114. return WOLFSSL_FATAL_ERROR;
  115. ret = wolfSSL_read(bio->ssl, buf, len);
  116. if (ret == 0)
  117. front->eof = 1;
  118. else if (ret < 0) {
  119. int err = wolfSSL_get_error(bio->ssl, 0);
  120. if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
  121. front->eof = 1;
  122. }
  123. return ret;
  124. }
  125. /* Used to read data from a WOLFSSL_BIO structure
  126. *
  127. * bio structure to read data from
  128. * buf buffer to hold the result
  129. * len length of buf buffer
  130. *
  131. * returns the number of bytes read on success
  132. */
  133. int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
  134. {
  135. int ret = 0;
  136. WOLFSSL_BIO* front = bio;
  137. int sz = 0;
  138. WOLFSSL_ENTER("wolfSSL_BIO_read");
  139. /* start at end of list and work backwards */
  140. while (bio->next != NULL) {
  141. bio = bio->next;
  142. }
  143. while (bio != NULL && ret >= 0) {
  144. /* formating data */
  145. if (bio->type == WOLFSSL_BIO_BASE64 && ret > 0 && sz > 0) {
  146. ret = wolfSSL_BIO_BASE64_read(bio, buf, sz);
  147. }
  148. /* write BIOs */
  149. if (bio && bio->type == WOLFSSL_BIO_BIO) {
  150. ret = wolfSSL_BIO_BIO_read(bio, buf, len);
  151. }
  152. if (bio && bio->type == WOLFSSL_BIO_MEMORY) {
  153. ret = wolfSSL_BIO_MEMORY_read(bio, buf, len);
  154. }
  155. #ifndef NO_FILESYSTEM
  156. if (bio && bio->type == WOLFSSL_BIO_FILE) {
  157. ret = (int)XFREAD(buf, 1, len, bio->file);
  158. }
  159. #endif
  160. if (bio && bio->type == WOLFSSL_BIO_SSL) {
  161. ret = wolfSSL_BIO_SSL_read(bio, buf, len, front);
  162. }
  163. /* case where front of list is done */
  164. if (bio == front) {
  165. break; /* at front of list so be done */
  166. }
  167. if (ret > 0) {
  168. sz = ret; /* adjust size for formating */
  169. }
  170. /* previous WOLFSSL_BIO in list working towards head of list */
  171. bio = bio->prev;
  172. }
  173. return ret;
  174. }
  175. /* Converts data into base64 output
  176. *
  177. * returns the resulting buffer size on success.
  178. */
  179. static int wolfSSL_BIO_BASE64_write(WOLFSSL_BIO* bio, const void* data,
  180. word32 inLen, byte* out, word32* outLen)
  181. {
  182. byte* tmp = NULL;
  183. int ret = 0;
  184. WOLFSSL_ENTER("wolfSSL_BIO_BASE64_write");
  185. if (bio == NULL || data == NULL || out == NULL || outLen == NULL) {
  186. return BAD_FUNC_ARG;
  187. }
  188. #if defined(WOLFSSL_BASE64_ENCODE)
  189. tmp = (byte*)XMALLOC(*outLen, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
  190. if (tmp == NULL) {
  191. return WOLFSSL_FATAL_ERROR;
  192. }
  193. if ((bio->flags & WOLFSSL_BIO_FLAG_BASE64_NO_NL) ==
  194. WOLFSSL_BIO_FLAG_BASE64_NO_NL) {
  195. if (Base64_Encode_NoNl((const byte*)data, inLen,
  196. tmp, outLen) < 0) {
  197. ret = WOLFSSL_FATAL_ERROR;
  198. }
  199. }
  200. else {
  201. if (Base64_Encode((const byte*)data, inLen,
  202. tmp, outLen) < 0) {
  203. ret = WOLFSSL_FATAL_ERROR;
  204. }
  205. }
  206. if (ret != WOLFSSL_FATAL_ERROR) {
  207. ret = (int)*outLen;
  208. XMEMCPY(out, tmp, *outLen);
  209. }
  210. XFREE(tmp, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
  211. #else
  212. (void)bio;
  213. (void)data;
  214. (void)inLen;
  215. (void)out;
  216. (void)outLen;
  217. (void)tmp;
  218. WOLFSSL_MSG("BASE64 encoding not compiled in");
  219. #endif
  220. return ret;
  221. }
  222. /* Helper function for writing to a WOLFSSL_BIO_SSL type
  223. *
  224. * returns the amount written in bytes on success
  225. */
  226. static int wolfSSL_BIO_SSL_write(WOLFSSL_BIO* bio, const void* data,
  227. int len, WOLFSSL_BIO* front)
  228. {
  229. int ret;
  230. WOLFSSL_ENTER("wolfSSL_BIO_SSL_write");
  231. if (bio->ssl == 0) return BAD_FUNC_ARG;
  232. ret = wolfSSL_write(bio->ssl, data, len);
  233. if (ret == 0)
  234. front->eof = 1;
  235. else if (ret < 0) {
  236. int err = wolfSSL_get_error(bio->ssl, 0);
  237. if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
  238. front->eof = 1;
  239. }
  240. return ret;
  241. }
  242. /* Writes to a WOLFSSL_BIO_BIO type.
  243. *
  244. * returns the amount written on success
  245. */
  246. static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data,
  247. int len)
  248. {
  249. int sz;
  250. char* buf;
  251. WOLFSSL_ENTER("wolfSSL_BIO_BIO_write");
  252. /*adding in sanity checks for static analysis tools */
  253. if (bio == NULL || data == NULL) {
  254. return BAD_FUNC_ARG;
  255. }
  256. sz = wolfSSL_BIO_nwrite(bio, &buf, len);
  257. /* test space for write */
  258. if (sz <= 0) {
  259. WOLFSSL_MSG("No room left to write");
  260. return sz;
  261. }
  262. XMEMCPY(buf, data, sz);
  263. return sz;
  264. }
  265. /* for complete compatibility a bio memory write allocs its own memory
  266. * until the application runs out ....
  267. *
  268. * bio structure to hold incoming data
  269. * data buffer holding the data to be written
  270. * len length of data buffer
  271. *
  272. * returns the amount of data written on success and WOLFSSL_FAILURE or
  273. * WOLFSSL_BIO_ERROR for failure cases.
  274. */
  275. static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data,
  276. int len)
  277. {
  278. int sz;
  279. const unsigned char* buf;
  280. WOLFSSL_ENTER("wolfSSL_BIO_MEMORY_write");
  281. if (bio == NULL || data == NULL) {
  282. return BAD_FUNC_ARG;
  283. }
  284. sz = wolfSSL_BIO_pending(bio);
  285. if (sz < 0) {
  286. WOLFSSL_MSG("Error getting memory data");
  287. return sz;
  288. }
  289. if (bio->mem == NULL) {
  290. bio->mem = (byte*)XMALLOC(len, bio->heap, DYNAMIC_TYPE_OPENSSL);
  291. if (bio->mem == NULL) {
  292. WOLFSSL_MSG("Error on malloc");
  293. return WOLFSSL_FAILURE;
  294. }
  295. bio->memLen = len;
  296. if (bio->mem_buf != NULL) {
  297. bio->mem_buf->data = (char*)bio->mem;
  298. bio->mem_buf->length = bio->memLen;
  299. }
  300. }
  301. /* check if will fit in current buffer size */
  302. if (wolfSSL_BIO_get_mem_data(bio, (void*)&buf) < 0) {
  303. return WOLFSSL_BIO_ERROR;
  304. }
  305. if (bio->memLen < sz + len) {
  306. bio->mem = (byte*)XREALLOC(bio->mem, sz + len, bio->heap,
  307. DYNAMIC_TYPE_OPENSSL);
  308. if (bio->mem == NULL) {
  309. WOLFSSL_MSG("Error on realloc");
  310. return WOLFSSL_FAILURE;
  311. }
  312. bio->memLen = sz + len;
  313. if (bio->mem_buf != NULL) {
  314. bio->mem_buf->data = (char*)bio->mem;
  315. bio->mem_buf->length = bio->memLen;
  316. }
  317. }
  318. XMEMCPY(bio->mem + sz, data, len);
  319. bio->wrSz += len;
  320. return len;
  321. }
  322. /* Writes data to a WOLFSSL_BIO structure
  323. *
  324. * bio structure to write to
  325. * data holds the data to be written
  326. * len length of data buffer
  327. *
  328. * returns the amount written in bytes on success
  329. */
  330. int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
  331. {
  332. int ret = 0;
  333. WOLFSSL_BIO* front = bio;
  334. void* frmt = NULL;
  335. word32 frmtSz = 0;
  336. WOLFSSL_ENTER("wolfSSL_BIO_write");
  337. while (bio != NULL && ret >= 0) {
  338. /* check for formating */
  339. if (bio && bio->type == WOLFSSL_BIO_BASE64) {
  340. #if defined(WOLFSSL_BASE64_ENCODE)
  341. word32 sz = 0;
  342. if (bio->flags & WOLFSSL_BIO_FLAG_BASE64_NO_NL) {
  343. if (Base64_Encode_NoNl((const byte*)data, len, NULL,
  344. &sz) != LENGTH_ONLY_E) {
  345. WOLFSSL_MSG("Error with base 64 get length");
  346. ret = SSL_FATAL_ERROR;
  347. }
  348. }
  349. else {
  350. if (Base64_Encode((const byte*)data, len, NULL, &sz) !=
  351. LENGTH_ONLY_E) {
  352. WOLFSSL_MSG("Error with base 64 get length");
  353. ret = SSL_FATAL_ERROR;
  354. }
  355. }
  356. if (frmt == NULL && sz > 0 && ret != SSL_FATAL_ERROR) {
  357. frmt = (void*)XMALLOC(sz, front->heap,
  358. DYNAMIC_TYPE_TMP_BUFFER);
  359. if (frmt == NULL) {
  360. WOLFSSL_MSG("Memory error");
  361. ret = SSL_FATAL_ERROR;
  362. }
  363. frmtSz = sz;
  364. }
  365. else if (sz > frmtSz) {
  366. frmt = (void*)XREALLOC(frmt, sz, front->heap,
  367. DYNAMIC_TYPE_TMP_BUFFER);
  368. if (frmt == NULL) {
  369. WOLFSSL_MSG("Memory error");
  370. ret = SSL_FATAL_ERROR;
  371. }
  372. /* since frmt already existed then data should point to knew
  373. formated buffer */
  374. data = frmt;
  375. len = frmtSz;
  376. frmtSz = sz;
  377. }
  378. #endif /* defined(WOLFSSL_BASE64_ENCODE) */
  379. if (ret >= 0) {
  380. /* change so that data is formated buffer */
  381. ret = wolfSSL_BIO_BASE64_write(bio, data, (word32)len,
  382. (byte*)frmt, &frmtSz);
  383. data = frmt;
  384. len = frmtSz;
  385. }
  386. }
  387. /* write bios */
  388. if (bio && bio->type == WOLFSSL_BIO_BIO) {
  389. ret = wolfSSL_BIO_BIO_write(bio, data, len);
  390. }
  391. if (bio && bio->type == WOLFSSL_BIO_MEMORY) {
  392. ret = wolfSSL_BIO_MEMORY_write(bio, data, len);
  393. }
  394. #ifndef NO_FILESYSTEM
  395. if (bio && bio->type == WOLFSSL_BIO_FILE) {
  396. ret = (int)XFWRITE(data, 1, len, bio->file);
  397. }
  398. #endif
  399. if (bio && bio->type == WOLFSSL_BIO_SSL) {
  400. /* already got eof, again is error */
  401. if (bio && front->eof) {
  402. ret = SSL_FATAL_ERROR;
  403. }
  404. else {
  405. ret = wolfSSL_BIO_SSL_write(bio, data, len, front);
  406. }
  407. }
  408. /* advance to the next bio in list */
  409. bio = bio->next;
  410. }
  411. if (frmt != NULL) {
  412. XFREE(frmt, front->heap, DYNAMIC_TYPE_TMP_BUFFER);
  413. }
  414. return ret;
  415. }
  416. /*** TBD ***/
  417. WOLFSSL_API long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bio, int cmd, long larg, void *parg)
  418. {
  419. (void)bio;
  420. (void)cmd;
  421. (void)larg;
  422. (void)parg;
  423. WOLFSSL_ENTER("BIO_ctrl");
  424. return 1;
  425. }
  426. /* helper function for wolfSSL_BIO_gets
  427. * size till a newline is hit
  428. * returns the number of bytes including the new line character
  429. */
  430. static int wolfSSL_getLineLength(char* in, int inSz)
  431. {
  432. int i;
  433. for (i = 0; i < inSz; i++) {
  434. if (in[i] == '\n') {
  435. return i + 1; /* includes new line character */
  436. }
  437. }
  438. return inSz; /* rest of buffer is all one line */
  439. }
  440. /* Gets the next line from bio. Goes until a new line character or end of
  441. * buffer is reached.
  442. *
  443. * bio the structure to read a new line from
  444. * buf buffer to hold the result
  445. * sz the size of "buf" buffer
  446. *
  447. * returns the size of the result placed in buf on success and a 0 or negative
  448. * value in an error case.
  449. */
  450. int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz)
  451. {
  452. int ret = WOLFSSL_BIO_UNSET;
  453. WOLFSSL_ENTER("wolfSSL_BIO_gets");
  454. if (bio == NULL || buf == NULL) {
  455. return WOLFSSL_FAILURE;
  456. }
  457. /* not enough space for character plus terminator */
  458. if (sz <= 1) {
  459. return 0;
  460. }
  461. switch (bio->type) {
  462. #ifndef NO_FILESYSTEM
  463. case WOLFSSL_BIO_FILE:
  464. if (bio->file == NULL) {
  465. return WOLFSSL_BIO_ERROR;
  466. }
  467. #if defined(MICRIUM) || defined(LSR_FS) || defined(EBSNET)
  468. WOLFSSL_MSG("XFGETS not ported for this system yet");
  469. ret = XFGETS(buf, sz, bio->file);
  470. #else
  471. if (XFGETS(buf, sz, bio->file) != NULL) {
  472. ret = (int)XSTRLEN(buf);
  473. }
  474. else {
  475. ret = WOLFSSL_BIO_ERROR;
  476. }
  477. #endif
  478. break;
  479. #endif /* NO_FILESYSTEM */
  480. case WOLFSSL_BIO_MEMORY:
  481. {
  482. const byte* c;
  483. int cSz;
  484. cSz = wolfSSL_BIO_pending(bio);
  485. if (cSz < 0) {
  486. ret = cSz;
  487. break;
  488. }
  489. if (wolfSSL_BIO_get_mem_data(bio, (void*)&c) <= 0) {
  490. ret = WOLFSSL_BIO_ERROR;
  491. break;
  492. }
  493. cSz = wolfSSL_getLineLength((char*)c, cSz);
  494. /* check case where line was bigger then buffer and buffer
  495. * needs end terminator */
  496. if (cSz >= sz) {
  497. cSz = sz - 1;
  498. buf[cSz] = '\0';
  499. }
  500. else {
  501. /* not minus 1 here because placing terminator after
  502. msg and have checked that sz is large enough */
  503. buf[cSz] = '\0';
  504. }
  505. ret = wolfSSL_BIO_MEMORY_read(bio, (void*)buf, cSz);
  506. /* ret is read after the switch statment */
  507. break;
  508. }
  509. case WOLFSSL_BIO_BIO:
  510. {
  511. char* c;
  512. int cSz;
  513. cSz = wolfSSL_BIO_nread0(bio, &c);
  514. if (cSz < 0) {
  515. ret = cSz;
  516. break;
  517. }
  518. cSz = wolfSSL_getLineLength(c, cSz);
  519. /* check case where line was bigger then buffer and buffer
  520. * needs end terminator */
  521. if (cSz >= sz) {
  522. cSz = sz - 1;
  523. buf[cSz] = '\0';
  524. }
  525. else {
  526. /* not minus 1 here because placing terminator after
  527. msg and have checked that sz is large enough */
  528. buf[cSz] = '\0';
  529. }
  530. ret = wolfSSL_BIO_nread(bio, &c, cSz);
  531. if (ret > 0 && ret < sz) {
  532. XMEMCPY(buf, c, ret);
  533. }
  534. break;
  535. }
  536. default:
  537. WOLFSSL_MSG("BIO type not supported yet with wolfSSL_BIO_gets");
  538. }
  539. return ret;
  540. }
  541. /* searches through bio list for a BIO of type "type"
  542. * returns NULL on failure to find a given type */
  543. WOLFSSL_BIO* wolfSSL_BIO_find_type(WOLFSSL_BIO* bio, int type)
  544. {
  545. WOLFSSL_BIO* local = NULL;
  546. WOLFSSL_BIO* current;
  547. WOLFSSL_ENTER("wolfSSL_BIO_find_type");
  548. if (bio == NULL) {
  549. return local;
  550. }
  551. current = bio;
  552. while (current != NULL) {
  553. if (current->type == type) {
  554. WOLFSSL_MSG("Found matching WOLFSSL_BIO type");
  555. local = current;
  556. break;
  557. }
  558. current = current->next;
  559. }
  560. return local;
  561. }
  562. /* returns a pointer to the next WOLFSSL_BIO in the chain on success.
  563. * If a failure case then NULL is returned */
  564. WOLFSSL_BIO* wolfSSL_BIO_next(WOLFSSL_BIO* bio)
  565. {
  566. WOLFSSL_ENTER("wolfSSL_BIO_next");
  567. if (bio == NULL) {
  568. WOLFSSL_MSG("Bad argument passed in");
  569. return NULL;
  570. }
  571. return bio->next;
  572. }
  573. /* Return the number of pending bytes in read and write buffers */
  574. size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio)
  575. {
  576. WOLFSSL_ENTER("BIO_ctrl_pending");
  577. if (bio == NULL) {
  578. return 0;
  579. }
  580. if (bio->ssl != NULL) {
  581. return (long)wolfSSL_pending(bio->ssl);
  582. }
  583. if (bio->type == WOLFSSL_BIO_MEMORY) {
  584. return bio->wrSz;
  585. }
  586. /* type BIO_BIO then check paired buffer */
  587. if (bio->type == WOLFSSL_BIO_BIO && bio->pair != NULL) {
  588. WOLFSSL_BIO* pair = bio->pair;
  589. if (pair->wrIdx > 0 && pair->wrIdx <= pair->rdIdx) {
  590. /* in wrap around state where begining of buffer is being
  591. * overwritten */
  592. return pair->wrSz - pair->rdIdx + pair->wrIdx;
  593. }
  594. else {
  595. /* simple case where has not wrapped around */
  596. return pair->wrIdx - pair->rdIdx;
  597. }
  598. }
  599. return 0;
  600. }
  601. long wolfSSL_BIO_get_mem_ptr(WOLFSSL_BIO *bio, WOLFSSL_BUF_MEM **ptr)
  602. {
  603. WOLFSSL_ENTER("wolfSSL_BIO_get_mem_ptr");
  604. if (bio == NULL || ptr == NULL) {
  605. return WOLFSSL_FAILURE;
  606. }
  607. if (bio->type == WOLFSSL_BIO_FILE || bio->type == WOLFSSL_BIO_SOCKET) {
  608. WOLFSSL_MSG("NO memory buffer for FILE type");
  609. return SSL_FAILURE;
  610. }
  611. *ptr = bio->mem_buf;
  612. return SSL_SUCCESS;
  613. }
  614. /*** TBD ***/
  615. WOLFSSL_API long wolfSSL_BIO_int_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, int iarg)
  616. {
  617. (void) bp;
  618. (void) cmd;
  619. (void) larg;
  620. (void) iarg;
  621. WOLFSSL_ENTER("BIO_int_ctrl");
  622. return 0;
  623. }
  624. int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *bio, long size)
  625. {
  626. WOLFSSL_ENTER("wolfSSL_BIO_set_write_buf_size");
  627. if (bio == NULL || bio->type != WOLFSSL_BIO_BIO || size < 0) {
  628. return WOLFSSL_FAILURE;
  629. }
  630. /* if already in pair then do not change size */
  631. if (bio->pair != NULL) {
  632. WOLFSSL_MSG("WOLFSSL_BIO is paired, free from pair before changing");
  633. return WOLFSSL_FAILURE;
  634. }
  635. bio->wrSz = (int)size;
  636. if (bio->wrSz < 0) {
  637. WOLFSSL_MSG("Unexpected negative size value");
  638. return WOLFSSL_FAILURE;
  639. }
  640. if (bio->mem != NULL) {
  641. XFREE(bio->mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
  642. }
  643. bio->mem = (byte*)XMALLOC(bio->wrSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
  644. if (bio->mem == NULL) {
  645. WOLFSSL_MSG("Memory allocation error");
  646. return WOLFSSL_FAILURE;
  647. }
  648. bio->memLen = bio->wrSz;
  649. bio->wrIdx = 0;
  650. bio->rdIdx = 0;
  651. if (bio->mem_buf != NULL) {
  652. bio->mem_buf->data = (char*)bio->mem;
  653. bio->mem_buf->length = bio->memLen;
  654. }
  655. return WOLFSSL_SUCCESS;
  656. }
  657. /* Joins two BIO_BIO types. The write of b1 goes to the read of b2 and vise
  658. * versa. Creating something similar to a two way pipe.
  659. * Reading and writing between the two BIOs is not thread safe, they are
  660. * expected to be used by the same thread. */
  661. int wolfSSL_BIO_make_bio_pair(WOLFSSL_BIO *b1, WOLFSSL_BIO *b2)
  662. {
  663. WOLFSSL_ENTER("wolfSSL_BIO_make_bio_pair");
  664. if (b1 == NULL || b2 == NULL) {
  665. WOLFSSL_LEAVE("wolfSSL_BIO_make_bio_pair", BAD_FUNC_ARG);
  666. return WOLFSSL_FAILURE;
  667. }
  668. /* both are expected to be of type BIO and not already paired */
  669. if (b1->type != WOLFSSL_BIO_BIO || b2->type != WOLFSSL_BIO_BIO ||
  670. b1->pair != NULL || b2->pair != NULL) {
  671. WOLFSSL_MSG("Expected type BIO and not already paired");
  672. return WOLFSSL_FAILURE;
  673. }
  674. /* set default write size if not already set */
  675. if (b1->mem == NULL && wolfSSL_BIO_set_write_buf_size(b1,
  676. WOLFSSL_BIO_SIZE) != WOLFSSL_SUCCESS) {
  677. return WOLFSSL_FAILURE;
  678. }
  679. if (b2->mem == NULL && wolfSSL_BIO_set_write_buf_size(b2,
  680. WOLFSSL_BIO_SIZE) != WOLFSSL_SUCCESS) {
  681. return WOLFSSL_FAILURE;
  682. }
  683. b1->pair = b2;
  684. b2->pair = b1;
  685. return WOLFSSL_SUCCESS;
  686. }
  687. int wolfSSL_BIO_ctrl_reset_read_request(WOLFSSL_BIO *b)
  688. {
  689. WOLFSSL_ENTER("wolfSSL_BIO_ctrl_reset_read_request");
  690. if (b == NULL || b->type == WOLFSSL_BIO_MEMORY) {
  691. return SSL_FAILURE;
  692. }
  693. b->readRq = 0;
  694. return WOLFSSL_SUCCESS;
  695. }
  696. /* Does not advance read index pointer */
  697. int wolfSSL_BIO_nread0(WOLFSSL_BIO *bio, char **buf)
  698. {
  699. WOLFSSL_ENTER("wolfSSL_BIO_nread0");
  700. if (bio == NULL || buf == NULL) {
  701. WOLFSSL_MSG("NULL argument passed in");
  702. return 0;
  703. }
  704. /* if paired read from pair */
  705. if (bio->pair != NULL) {
  706. WOLFSSL_BIO* pair = bio->pair;
  707. /* case where have wrapped around write buffer */
  708. *buf = (char*)pair->mem + pair->rdIdx;
  709. if (pair->wrIdx > 0 && pair->rdIdx >= pair->wrIdx) {
  710. return pair->wrSz - pair->rdIdx;
  711. }
  712. else {
  713. return pair->wrIdx - pair->rdIdx;
  714. }
  715. }
  716. return 0;
  717. }
  718. /* similar to wolfSSL_BIO_nread0 but advances the read index */
  719. int wolfSSL_BIO_nread(WOLFSSL_BIO *bio, char **buf, int num)
  720. {
  721. int sz = WOLFSSL_BIO_UNSET;
  722. WOLFSSL_ENTER("wolfSSL_BIO_nread");
  723. if (bio == NULL || buf == NULL) {
  724. WOLFSSL_MSG("NULL argument passed in");
  725. return WOLFSSL_FAILURE;
  726. }
  727. if (bio->type == WOLFSSL_BIO_MEMORY) {
  728. return SSL_FAILURE;
  729. }
  730. if (bio->pair != NULL) {
  731. /* special case if asking to read 0 bytes */
  732. if (num == 0) {
  733. *buf = (char*)bio->pair->mem + bio->pair->rdIdx;
  734. return 0;
  735. }
  736. /* get amount able to read and set buffer pointer */
  737. sz = wolfSSL_BIO_nread0(bio, buf);
  738. if (sz == 0) {
  739. return WOLFSSL_BIO_ERROR;
  740. }
  741. if (num < sz) {
  742. sz = num;
  743. }
  744. bio->pair->rdIdx += sz;
  745. /* check if have read to the end of the buffer and need to reset */
  746. if (bio->pair->rdIdx == bio->pair->wrSz) {
  747. bio->pair->rdIdx = 0;
  748. if (bio->pair->wrIdx == bio->pair->wrSz) {
  749. bio->pair->wrIdx = 0;
  750. }
  751. }
  752. /* check if read up to write index, if so then reset indexs */
  753. if (bio->pair->rdIdx == bio->pair->wrIdx) {
  754. bio->pair->rdIdx = 0;
  755. bio->pair->wrIdx = 0;
  756. }
  757. }
  758. return sz;
  759. }
  760. int wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num)
  761. {
  762. int sz = WOLFSSL_BIO_UNSET;
  763. WOLFSSL_ENTER("wolfSSL_BIO_nwrite");
  764. if (bio == NULL || buf == NULL) {
  765. WOLFSSL_MSG("NULL argument passed in");
  766. return 0;
  767. }
  768. if (bio->type != WOLFSSL_BIO_BIO) {
  769. return SSL_FAILURE;
  770. }
  771. if (bio->pair != NULL) {
  772. if (num == 0) {
  773. *buf = (char*)bio->mem + bio->wrIdx;
  774. return 0;
  775. }
  776. if (bio->wrIdx < bio->rdIdx) {
  777. /* if wrapped around only write up to read index. In this case
  778. * rdIdx is always greater then wrIdx so sz will not be negative. */
  779. sz = bio->rdIdx - bio->wrIdx;
  780. }
  781. else if (bio->rdIdx > 0 && bio->wrIdx == bio->rdIdx) {
  782. return WOLFSSL_BIO_ERROR; /* no more room to write */
  783. }
  784. else {
  785. /* write index is past read index so write to end of buffer */
  786. sz = bio->wrSz - bio->wrIdx;
  787. if (sz <= 0) {
  788. /* either an error has occured with write index or it is at the
  789. * end of the write buffer. */
  790. if (bio->rdIdx == 0) {
  791. /* no more room, nothing has been read */
  792. return WOLFSSL_BIO_ERROR;
  793. }
  794. bio->wrIdx = 0;
  795. /* check case where read index is not at 0 */
  796. if (bio->rdIdx > 0) {
  797. sz = bio->rdIdx; /* can write up to the read index */
  798. }
  799. else {
  800. sz = bio->wrSz; /* no restriction other then buffer size */
  801. }
  802. }
  803. }
  804. if (num < sz) {
  805. sz = num;
  806. }
  807. *buf = (char*)bio->mem + bio->wrIdx;
  808. bio->wrIdx += sz;
  809. /* if at the end of the buffer and space for wrap around then set
  810. * write index back to 0 */
  811. if (bio->wrIdx == bio->wrSz && bio->rdIdx > 0) {
  812. bio->wrIdx = 0;
  813. }
  814. }
  815. return sz;
  816. }
  817. /* Reset BIO to initial state */
  818. int wolfSSL_BIO_reset(WOLFSSL_BIO *bio)
  819. {
  820. WOLFSSL_ENTER("wolfSSL_BIO_reset");
  821. if (bio == NULL) {
  822. WOLFSSL_MSG("NULL argument passed in");
  823. /* -1 is consistent failure even for FILE type */
  824. return WOLFSSL_BIO_ERROR;
  825. }
  826. switch (bio->type) {
  827. #ifndef NO_FILESYSTEM
  828. case WOLFSSL_BIO_FILE:
  829. XREWIND(bio->file);
  830. return 0;
  831. #endif
  832. case WOLFSSL_BIO_BIO:
  833. bio->rdIdx = 0;
  834. bio->wrIdx = 0;
  835. return 0;
  836. case WOLFSSL_BIO_MEMORY:
  837. bio->rdIdx = 0;
  838. bio->wrIdx = 0;
  839. bio->wrSz = 0;
  840. XFREE(bio->mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
  841. bio->mem = NULL;
  842. bio->memLen = 0;
  843. if (bio->mem_buf != NULL) {
  844. bio->mem_buf->data = (char*)bio->mem;
  845. bio->mem_buf->length = bio->memLen;
  846. }
  847. return 0;
  848. default:
  849. WOLFSSL_MSG("Unknown BIO type needs added to reset function");
  850. }
  851. return WOLFSSL_BIO_ERROR;
  852. }
  853. #ifndef NO_FILESYSTEM
  854. long wolfSSL_BIO_set_fp(WOLFSSL_BIO *bio, XFILE fp, int c)
  855. {
  856. WOLFSSL_ENTER("wolfSSL_BIO_set_fp");
  857. if (bio == NULL || fp == NULL) {
  858. WOLFSSL_LEAVE("wolfSSL_BIO_set_fp", BAD_FUNC_ARG);
  859. return WOLFSSL_FAILURE;
  860. }
  861. if (bio->type != WOLFSSL_BIO_FILE) {
  862. return WOLFSSL_FAILURE;
  863. }
  864. bio->close = (byte)c;
  865. bio->file = fp;
  866. return WOLFSSL_SUCCESS;
  867. }
  868. long wolfSSL_BIO_get_fp(WOLFSSL_BIO *bio, XFILE* fp)
  869. {
  870. WOLFSSL_ENTER("wolfSSL_BIO_get_fp");
  871. if (bio == NULL || fp == NULL) {
  872. return WOLFSSL_FAILURE;
  873. }
  874. if (bio->type != WOLFSSL_BIO_FILE) {
  875. return SSL_FAILURE;
  876. }
  877. *fp = bio->file;
  878. return WOLFSSL_SUCCESS;
  879. }
  880. /* overwrites file */
  881. int wolfSSL_BIO_write_filename(WOLFSSL_BIO *bio, char *name)
  882. {
  883. WOLFSSL_ENTER("wolfSSL_BIO_write_filename");
  884. if (bio == NULL || name == NULL) {
  885. return WOLFSSL_FAILURE;
  886. }
  887. if (bio->type == WOLFSSL_BIO_FILE) {
  888. if (bio->file != NULL && bio->close == BIO_CLOSE) {
  889. XFCLOSE(bio->file);
  890. }
  891. bio->file = XFOPEN(name, "w");
  892. if (bio->file == NULL) {
  893. return WOLFSSL_FAILURE;
  894. }
  895. bio->close = BIO_CLOSE;
  896. return WOLFSSL_SUCCESS;
  897. }
  898. return WOLFSSL_FAILURE;
  899. }
  900. int wolfSSL_BIO_seek(WOLFSSL_BIO *bio, int ofs)
  901. {
  902. WOLFSSL_ENTER("wolfSSL_BIO_seek");
  903. if (bio == NULL) {
  904. return -1;
  905. }
  906. /* offset ofs from begining of file */
  907. if (bio->type == WOLFSSL_BIO_FILE &&
  908. XFSEEK(bio->file, ofs, SEEK_SET) < 0) {
  909. return -1;
  910. }
  911. return 0;
  912. }
  913. #endif /* NO_FILESYSTEM */
  914. long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v)
  915. {
  916. WOLFSSL_ENTER("wolfSSL_BIO_set_mem_eof_return");
  917. if (bio != NULL) {
  918. bio->eof = v;
  919. }
  920. return 0;
  921. }
  922. #endif /* WOLFSSL_BIO_INCLUDED */