bss_bio.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  1. /*
  2. * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. /*
  10. * Special method for a BIO where the other endpoint is also a BIO of this
  11. * kind, handled by the same thread (i.e. the "peer" is actually ourselves,
  12. * wearing a different hat). Such "BIO pairs" are mainly for using the SSL
  13. * library with I/O interfaces for which no specific BIO method is available.
  14. * See ssl/ssltest.c for some hints on how this can be used.
  15. */
  16. #include "internal/e_os.h"
  17. #include <assert.h>
  18. #include <limits.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include "bio_local.h"
  22. #include <openssl/err.h>
  23. #include <openssl/crypto.h>
  24. static int bio_new(BIO *bio);
  25. static int bio_free(BIO *bio);
  26. static int bio_read(BIO *bio, char *buf, int size);
  27. static int bio_write(BIO *bio, const char *buf, int num);
  28. static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
  29. static int bio_puts(BIO *bio, const char *str);
  30. static int bio_make_pair(BIO *bio1, BIO *bio2);
  31. static void bio_destroy_pair(BIO *bio);
  32. static const BIO_METHOD methods_biop = {
  33. BIO_TYPE_BIO,
  34. "BIO pair",
  35. bwrite_conv,
  36. bio_write,
  37. bread_conv,
  38. bio_read,
  39. bio_puts,
  40. NULL /* no bio_gets */ ,
  41. bio_ctrl,
  42. bio_new,
  43. bio_free,
  44. NULL /* no bio_callback_ctrl */
  45. };
  46. const BIO_METHOD *BIO_s_bio(void)
  47. {
  48. return &methods_biop;
  49. }
  50. struct bio_bio_st {
  51. BIO *peer; /* NULL if buf == NULL. If peer != NULL, then
  52. * peer->ptr is also a bio_bio_st, and its
  53. * "peer" member points back to us. peer !=
  54. * NULL iff init != 0 in the BIO. */
  55. /* This is for what we write (i.e. reading uses peer's struct): */
  56. int closed; /* valid iff peer != NULL */
  57. size_t len; /* valid iff buf != NULL; 0 if peer == NULL */
  58. size_t offset; /* valid iff buf != NULL; 0 if len == 0 */
  59. size_t size;
  60. char *buf; /* "size" elements (if != NULL) */
  61. size_t request; /* valid iff peer != NULL; 0 if len != 0,
  62. * otherwise set by peer to number of bytes
  63. * it (unsuccessfully) tried to read, never
  64. * more than buffer space (size-len)
  65. * warrants. */
  66. };
  67. static int bio_new(BIO *bio)
  68. {
  69. struct bio_bio_st *b = OPENSSL_zalloc(sizeof(*b));
  70. if (b == NULL)
  71. return 0;
  72. /* enough for one TLS record (just a default) */
  73. b->size = 17 * 1024;
  74. bio->ptr = b;
  75. return 1;
  76. }
  77. static int bio_free(BIO *bio)
  78. {
  79. struct bio_bio_st *b;
  80. if (bio == NULL)
  81. return 0;
  82. b = bio->ptr;
  83. assert(b != NULL);
  84. if (b->peer)
  85. bio_destroy_pair(bio);
  86. OPENSSL_free(b->buf);
  87. OPENSSL_free(b);
  88. return 1;
  89. }
  90. static int bio_read(BIO *bio, char *buf, int size_)
  91. {
  92. size_t size = size_;
  93. size_t rest;
  94. struct bio_bio_st *b, *peer_b;
  95. BIO_clear_retry_flags(bio);
  96. if (!bio->init)
  97. return 0;
  98. b = bio->ptr;
  99. assert(b != NULL);
  100. assert(b->peer != NULL);
  101. peer_b = b->peer->ptr;
  102. assert(peer_b != NULL);
  103. assert(peer_b->buf != NULL);
  104. peer_b->request = 0; /* will be set in "retry_read" situation */
  105. if (buf == NULL || size == 0)
  106. return 0;
  107. if (peer_b->len == 0) {
  108. if (peer_b->closed)
  109. return 0; /* writer has closed, and no data is left */
  110. else {
  111. BIO_set_retry_read(bio); /* buffer is empty */
  112. if (size <= peer_b->size)
  113. peer_b->request = size;
  114. else
  115. /*
  116. * don't ask for more than the peer can deliver in one write
  117. */
  118. peer_b->request = peer_b->size;
  119. return -1;
  120. }
  121. }
  122. /* we can read */
  123. if (peer_b->len < size)
  124. size = peer_b->len;
  125. /* now read "size" bytes */
  126. rest = size;
  127. assert(rest > 0);
  128. do { /* one or two iterations */
  129. size_t chunk;
  130. assert(rest <= peer_b->len);
  131. if (peer_b->offset + rest <= peer_b->size)
  132. chunk = rest;
  133. else
  134. /* wrap around ring buffer */
  135. chunk = peer_b->size - peer_b->offset;
  136. assert(peer_b->offset + chunk <= peer_b->size);
  137. memcpy(buf, peer_b->buf + peer_b->offset, chunk);
  138. peer_b->len -= chunk;
  139. if (peer_b->len) {
  140. peer_b->offset += chunk;
  141. assert(peer_b->offset <= peer_b->size);
  142. if (peer_b->offset == peer_b->size)
  143. peer_b->offset = 0;
  144. buf += chunk;
  145. } else {
  146. /* buffer now empty, no need to advance "buf" */
  147. assert(chunk == rest);
  148. peer_b->offset = 0;
  149. }
  150. rest -= chunk;
  151. }
  152. while (rest);
  153. return size;
  154. }
  155. /*-
  156. * non-copying interface: provide pointer to available data in buffer
  157. * bio_nread0: return number of available bytes
  158. * bio_nread: also advance index
  159. * (example usage: bio_nread0(), read from buffer, bio_nread()
  160. * or just bio_nread(), read from buffer)
  161. */
  162. /*
  163. * WARNING: The non-copying interface is largely untested as of yet and may
  164. * contain bugs.
  165. */
  166. static ossl_ssize_t bio_nread0(BIO *bio, char **buf)
  167. {
  168. struct bio_bio_st *b, *peer_b;
  169. ossl_ssize_t num;
  170. BIO_clear_retry_flags(bio);
  171. if (!bio->init)
  172. return 0;
  173. b = bio->ptr;
  174. assert(b != NULL);
  175. assert(b->peer != NULL);
  176. peer_b = b->peer->ptr;
  177. assert(peer_b != NULL);
  178. assert(peer_b->buf != NULL);
  179. peer_b->request = 0;
  180. if (peer_b->len == 0) {
  181. char dummy;
  182. /* avoid code duplication -- nothing available for reading */
  183. return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
  184. }
  185. num = peer_b->len;
  186. if (peer_b->size < peer_b->offset + num)
  187. /* no ring buffer wrap-around for non-copying interface */
  188. num = peer_b->size - peer_b->offset;
  189. assert(num > 0);
  190. if (buf != NULL)
  191. *buf = peer_b->buf + peer_b->offset;
  192. return num;
  193. }
  194. static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_)
  195. {
  196. struct bio_bio_st *b, *peer_b;
  197. ossl_ssize_t num, available;
  198. if (num_ > OSSL_SSIZE_MAX)
  199. num = OSSL_SSIZE_MAX;
  200. else
  201. num = (ossl_ssize_t) num_;
  202. available = bio_nread0(bio, buf);
  203. if (num > available)
  204. num = available;
  205. if (num <= 0)
  206. return num;
  207. b = bio->ptr;
  208. peer_b = b->peer->ptr;
  209. peer_b->len -= num;
  210. if (peer_b->len) {
  211. peer_b->offset += num;
  212. assert(peer_b->offset <= peer_b->size);
  213. if (peer_b->offset == peer_b->size)
  214. peer_b->offset = 0;
  215. } else
  216. peer_b->offset = 0;
  217. return num;
  218. }
  219. static int bio_write(BIO *bio, const char *buf, int num_)
  220. {
  221. size_t num = num_;
  222. size_t rest;
  223. struct bio_bio_st *b;
  224. BIO_clear_retry_flags(bio);
  225. if (!bio->init || buf == NULL || num_ <= 0)
  226. return 0;
  227. b = bio->ptr;
  228. assert(b != NULL);
  229. assert(b->peer != NULL);
  230. assert(b->buf != NULL);
  231. b->request = 0;
  232. if (b->closed) {
  233. /* we already closed */
  234. ERR_raise(ERR_LIB_BIO, BIO_R_BROKEN_PIPE);
  235. return -1;
  236. }
  237. assert(b->len <= b->size);
  238. if (b->len == b->size) {
  239. BIO_set_retry_write(bio); /* buffer is full */
  240. return -1;
  241. }
  242. /* we can write */
  243. if (num > b->size - b->len)
  244. num = b->size - b->len;
  245. /* now write "num" bytes */
  246. rest = num;
  247. assert(rest > 0);
  248. do { /* one or two iterations */
  249. size_t write_offset;
  250. size_t chunk;
  251. assert(b->len + rest <= b->size);
  252. write_offset = b->offset + b->len;
  253. if (write_offset >= b->size)
  254. write_offset -= b->size;
  255. /* b->buf[write_offset] is the first byte we can write to. */
  256. if (write_offset + rest <= b->size)
  257. chunk = rest;
  258. else
  259. /* wrap around ring buffer */
  260. chunk = b->size - write_offset;
  261. memcpy(b->buf + write_offset, buf, chunk);
  262. b->len += chunk;
  263. assert(b->len <= b->size);
  264. rest -= chunk;
  265. buf += chunk;
  266. }
  267. while (rest);
  268. return num;
  269. }
  270. /*-
  271. * non-copying interface: provide pointer to region to write to
  272. * bio_nwrite0: check how much space is available
  273. * bio_nwrite: also increase length
  274. * (example usage: bio_nwrite0(), write to buffer, bio_nwrite()
  275. * or just bio_nwrite(), write to buffer)
  276. */
  277. static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf)
  278. {
  279. struct bio_bio_st *b;
  280. size_t num;
  281. size_t write_offset;
  282. BIO_clear_retry_flags(bio);
  283. if (!bio->init)
  284. return 0;
  285. b = bio->ptr;
  286. assert(b != NULL);
  287. assert(b->peer != NULL);
  288. assert(b->buf != NULL);
  289. b->request = 0;
  290. if (b->closed) {
  291. ERR_raise(ERR_LIB_BIO, BIO_R_BROKEN_PIPE);
  292. return -1;
  293. }
  294. assert(b->len <= b->size);
  295. if (b->len == b->size) {
  296. BIO_set_retry_write(bio);
  297. return -1;
  298. }
  299. num = b->size - b->len;
  300. write_offset = b->offset + b->len;
  301. if (write_offset >= b->size)
  302. write_offset -= b->size;
  303. if (write_offset + num > b->size)
  304. /*
  305. * no ring buffer wrap-around for non-copying interface (to fulfil
  306. * the promise by BIO_ctrl_get_write_guarantee, BIO_nwrite may have
  307. * to be called twice)
  308. */
  309. num = b->size - write_offset;
  310. if (buf != NULL)
  311. *buf = b->buf + write_offset;
  312. assert(write_offset + num <= b->size);
  313. return num;
  314. }
  315. static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)
  316. {
  317. struct bio_bio_st *b;
  318. ossl_ssize_t num, space;
  319. if (num_ > OSSL_SSIZE_MAX)
  320. num = OSSL_SSIZE_MAX;
  321. else
  322. num = (ossl_ssize_t) num_;
  323. space = bio_nwrite0(bio, buf);
  324. if (num > space)
  325. num = space;
  326. if (num <= 0)
  327. return num;
  328. b = bio->ptr;
  329. assert(b != NULL);
  330. b->len += num;
  331. assert(b->len <= b->size);
  332. return num;
  333. }
  334. static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
  335. {
  336. long ret;
  337. struct bio_bio_st *b = bio->ptr;
  338. assert(b != NULL);
  339. switch (cmd) {
  340. /* specific CTRL codes */
  341. case BIO_C_SET_WRITE_BUF_SIZE:
  342. if (b->peer) {
  343. ERR_raise(ERR_LIB_BIO, BIO_R_IN_USE);
  344. ret = 0;
  345. } else if (num == 0) {
  346. ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
  347. ret = 0;
  348. } else {
  349. size_t new_size = num;
  350. if (b->size != new_size) {
  351. OPENSSL_free(b->buf);
  352. b->buf = NULL;
  353. b->size = new_size;
  354. }
  355. ret = 1;
  356. }
  357. break;
  358. case BIO_C_GET_WRITE_BUF_SIZE:
  359. ret = (long)b->size;
  360. break;
  361. case BIO_C_MAKE_BIO_PAIR:
  362. {
  363. BIO *other_bio = ptr;
  364. if (bio_make_pair(bio, other_bio))
  365. ret = 1;
  366. else
  367. ret = 0;
  368. }
  369. break;
  370. case BIO_C_DESTROY_BIO_PAIR:
  371. /*
  372. * Affects both BIOs in the pair -- call just once! Or let
  373. * BIO_free(bio1); BIO_free(bio2); do the job.
  374. */
  375. bio_destroy_pair(bio);
  376. ret = 1;
  377. break;
  378. case BIO_C_GET_WRITE_GUARANTEE:
  379. /*
  380. * How many bytes can the caller feed to the next write without
  381. * having to keep any?
  382. */
  383. if (b->peer == NULL || b->closed)
  384. ret = 0;
  385. else
  386. ret = (long)b->size - b->len;
  387. break;
  388. case BIO_C_GET_READ_REQUEST:
  389. /*
  390. * If the peer unsuccessfully tried to read, how many bytes were
  391. * requested? (As with BIO_CTRL_PENDING, that number can usually be
  392. * treated as boolean.)
  393. */
  394. ret = (long)b->request;
  395. break;
  396. case BIO_C_RESET_READ_REQUEST:
  397. /*
  398. * Reset request. (Can be useful after read attempts at the other
  399. * side that are meant to be non-blocking, e.g. when probing SSL_read
  400. * to see if any data is available.)
  401. */
  402. b->request = 0;
  403. ret = 1;
  404. break;
  405. case BIO_C_SHUTDOWN_WR:
  406. /* similar to shutdown(..., SHUT_WR) */
  407. b->closed = 1;
  408. ret = 1;
  409. break;
  410. case BIO_C_NREAD0:
  411. /* prepare for non-copying read */
  412. ret = (long)bio_nread0(bio, ptr);
  413. break;
  414. case BIO_C_NREAD:
  415. /* non-copying read */
  416. ret = (long)bio_nread(bio, ptr, (size_t)num);
  417. break;
  418. case BIO_C_NWRITE0:
  419. /* prepare for non-copying write */
  420. ret = (long)bio_nwrite0(bio, ptr);
  421. break;
  422. case BIO_C_NWRITE:
  423. /* non-copying write */
  424. ret = (long)bio_nwrite(bio, ptr, (size_t)num);
  425. break;
  426. /* standard CTRL codes follow */
  427. case BIO_CTRL_RESET:
  428. if (b->buf != NULL) {
  429. b->len = 0;
  430. b->offset = 0;
  431. }
  432. ret = 0;
  433. break;
  434. case BIO_CTRL_GET_CLOSE:
  435. ret = bio->shutdown;
  436. break;
  437. case BIO_CTRL_SET_CLOSE:
  438. bio->shutdown = (int)num;
  439. ret = 1;
  440. break;
  441. case BIO_CTRL_PENDING:
  442. if (b->peer != NULL) {
  443. struct bio_bio_st *peer_b = b->peer->ptr;
  444. ret = (long)peer_b->len;
  445. } else
  446. ret = 0;
  447. break;
  448. case BIO_CTRL_WPENDING:
  449. if (b->buf != NULL)
  450. ret = (long)b->len;
  451. else
  452. ret = 0;
  453. break;
  454. case BIO_CTRL_DUP:
  455. /* See BIO_dup_chain for circumstances we have to expect. */
  456. {
  457. BIO *other_bio = ptr;
  458. struct bio_bio_st *other_b;
  459. assert(other_bio != NULL);
  460. other_b = other_bio->ptr;
  461. assert(other_b != NULL);
  462. assert(other_b->buf == NULL); /* other_bio is always fresh */
  463. other_b->size = b->size;
  464. }
  465. ret = 1;
  466. break;
  467. case BIO_CTRL_FLUSH:
  468. ret = 1;
  469. break;
  470. case BIO_CTRL_EOF:
  471. if (b->peer != NULL) {
  472. struct bio_bio_st *peer_b = b->peer->ptr;
  473. if (peer_b->len == 0 && peer_b->closed)
  474. ret = 1;
  475. else
  476. ret = 0;
  477. } else {
  478. ret = 1;
  479. }
  480. break;
  481. default:
  482. ret = 0;
  483. }
  484. return ret;
  485. }
  486. static int bio_puts(BIO *bio, const char *str)
  487. {
  488. return bio_write(bio, str, strlen(str));
  489. }
  490. static int bio_make_pair(BIO *bio1, BIO *bio2)
  491. {
  492. struct bio_bio_st *b1, *b2;
  493. assert(bio1 != NULL);
  494. assert(bio2 != NULL);
  495. b1 = bio1->ptr;
  496. b2 = bio2->ptr;
  497. if (b1->peer != NULL || b2->peer != NULL) {
  498. ERR_raise(ERR_LIB_BIO, BIO_R_IN_USE);
  499. return 0;
  500. }
  501. if (b1->buf == NULL) {
  502. b1->buf = OPENSSL_malloc(b1->size);
  503. if (b1->buf == NULL)
  504. return 0;
  505. b1->len = 0;
  506. b1->offset = 0;
  507. }
  508. if (b2->buf == NULL) {
  509. b2->buf = OPENSSL_malloc(b2->size);
  510. if (b2->buf == NULL)
  511. return 0;
  512. b2->len = 0;
  513. b2->offset = 0;
  514. }
  515. b1->peer = bio2;
  516. b1->closed = 0;
  517. b1->request = 0;
  518. b2->peer = bio1;
  519. b2->closed = 0;
  520. b2->request = 0;
  521. bio1->init = 1;
  522. bio2->init = 1;
  523. return 1;
  524. }
  525. static void bio_destroy_pair(BIO *bio)
  526. {
  527. struct bio_bio_st *b = bio->ptr;
  528. if (b != NULL) {
  529. BIO *peer_bio = b->peer;
  530. if (peer_bio != NULL) {
  531. struct bio_bio_st *peer_b = peer_bio->ptr;
  532. assert(peer_b != NULL);
  533. assert(peer_b->peer == bio);
  534. peer_b->peer = NULL;
  535. peer_bio->init = 0;
  536. assert(peer_b->buf != NULL);
  537. peer_b->len = 0;
  538. peer_b->offset = 0;
  539. b->peer = NULL;
  540. bio->init = 0;
  541. assert(b->buf != NULL);
  542. b->len = 0;
  543. b->offset = 0;
  544. }
  545. }
  546. }
  547. /* Exported convenience functions */
  548. int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
  549. BIO **bio2_p, size_t writebuf2)
  550. {
  551. BIO *bio1 = NULL, *bio2 = NULL;
  552. long r;
  553. int ret = 0;
  554. bio1 = BIO_new(BIO_s_bio());
  555. if (bio1 == NULL)
  556. goto err;
  557. bio2 = BIO_new(BIO_s_bio());
  558. if (bio2 == NULL)
  559. goto err;
  560. if (writebuf1) {
  561. r = BIO_set_write_buf_size(bio1, writebuf1);
  562. if (!r)
  563. goto err;
  564. }
  565. if (writebuf2) {
  566. r = BIO_set_write_buf_size(bio2, writebuf2);
  567. if (!r)
  568. goto err;
  569. }
  570. r = BIO_make_bio_pair(bio1, bio2);
  571. if (!r)
  572. goto err;
  573. ret = 1;
  574. err:
  575. if (ret == 0) {
  576. BIO_free(bio1);
  577. bio1 = NULL;
  578. BIO_free(bio2);
  579. bio2 = NULL;
  580. }
  581. *bio1_p = bio1;
  582. *bio2_p = bio2;
  583. return ret;
  584. }
  585. size_t BIO_ctrl_get_write_guarantee(BIO *bio)
  586. {
  587. return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
  588. }
  589. size_t BIO_ctrl_get_read_request(BIO *bio)
  590. {
  591. return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
  592. }
  593. int BIO_ctrl_reset_read_request(BIO *bio)
  594. {
  595. return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
  596. }
  597. /*
  598. * BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
  599. * (conceivably some other BIOs could allow non-copying reads and writes
  600. * too.)
  601. */
  602. int BIO_nread0(BIO *bio, char **buf)
  603. {
  604. long ret;
  605. if (!bio->init) {
  606. ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
  607. return -2;
  608. }
  609. ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
  610. if (ret > INT_MAX)
  611. return INT_MAX;
  612. else
  613. return (int)ret;
  614. }
  615. int BIO_nread(BIO *bio, char **buf, int num)
  616. {
  617. int ret;
  618. if (!bio->init) {
  619. ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
  620. return -2;
  621. }
  622. ret = (int)BIO_ctrl(bio, BIO_C_NREAD, num, buf);
  623. if (ret > 0)
  624. bio->num_read += ret;
  625. return ret;
  626. }
  627. int BIO_nwrite0(BIO *bio, char **buf)
  628. {
  629. long ret;
  630. if (!bio->init) {
  631. ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
  632. return -2;
  633. }
  634. ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
  635. if (ret > INT_MAX)
  636. return INT_MAX;
  637. else
  638. return (int)ret;
  639. }
  640. int BIO_nwrite(BIO *bio, char **buf, int num)
  641. {
  642. int ret;
  643. if (!bio->init) {
  644. ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
  645. return -2;
  646. }
  647. ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
  648. if (ret > 0)
  649. bio->num_write += ret;
  650. return ret;
  651. }