ssl_bio.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. // Copyright 2020 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. #include "ssl_lib.h"
  14. #include "openssl/bio.h"
  15. #include "ssl_dbg.h"
  16. #include "openssl/err.h"
  17. #define DEFAULT_BIO_SIZE 1024
  18. BIO *BIO_new_mem_buf(void *buf, int len)
  19. {
  20. BIO_METHOD m = { .type = BIO_TYPE_MEM, .size = 0 };
  21. BIO *b = BIO_new(&m);
  22. if (b) {
  23. b->dlen = len;
  24. b->data = buf;
  25. }
  26. return b;
  27. }
  28. /**
  29. * @brief create a BIO object
  30. */
  31. BIO *BIO_new(BIO_METHOD * method)
  32. {
  33. BIO *b = (BIO *)ssl_mem_zalloc(sizeof(BIO));
  34. if (!b) {
  35. OPENSSL_PUT_LIB_ERROR(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
  36. goto err;
  37. }
  38. if (method) {
  39. b->size = method->size;
  40. b->type = method->type;
  41. } else {
  42. b->type = BIO_TYPE_NONE;
  43. }
  44. if ((b->type & BIO_TYPE_BIO) && b->size) {
  45. b->data = ssl_mem_zalloc(b->size);
  46. if (!b->data) {
  47. OPENSSL_PUT_LIB_ERROR(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
  48. goto err;
  49. }
  50. }
  51. return b;
  52. err:
  53. if (b && (b->type&BIO_TYPE_BIO)) {
  54. ssl_mem_free(b->data);
  55. }
  56. ssl_mem_free(b);
  57. return NULL;
  58. }
  59. /**
  60. * @brief free a BIO object
  61. */
  62. void BIO_free(BIO *b)
  63. {
  64. if (b && (b->type&BIO_TYPE_BIO)) {
  65. ssl_mem_free(b->data);
  66. }
  67. ssl_mem_free(b);
  68. }
  69. int BIO_new_bio_pair(BIO **out1, size_t writebuf1, BIO **out2, size_t writebuf2)
  70. {
  71. BIO *bio1 = NULL;
  72. BIO *bio2 = NULL;
  73. if (!writebuf1) {
  74. writebuf1 = DEFAULT_BIO_SIZE;
  75. }
  76. if (!writebuf2) {
  77. writebuf2 = DEFAULT_BIO_SIZE;
  78. }
  79. BIO_METHOD m1 = {
  80. .size = writebuf1,
  81. .type = BIO_TYPE_BIO,
  82. };
  83. BIO_METHOD m2 = {
  84. .size = writebuf1,
  85. .type = BIO_TYPE_BIO,
  86. };
  87. bio1 = BIO_new(&m1);
  88. if (!bio1) {
  89. goto err;
  90. }
  91. bio2 = BIO_new(&m2);
  92. if (!bio2) {
  93. goto err;
  94. }
  95. *out1 = bio1;
  96. *out2 = bio2;
  97. bio1->peer = bio2;
  98. bio1->size = writebuf1;
  99. bio2->peer = bio1;
  100. bio2->size = writebuf2;
  101. return 1;
  102. err:
  103. if (bio1)
  104. {
  105. BIO_free(bio1);
  106. *out1 = NULL;
  107. }
  108. if (bio2)
  109. {
  110. BIO_free(bio2);
  111. *out2 = NULL;
  112. }
  113. return 0;
  114. }
  115. /**
  116. * @brief get the memory BIO method function
  117. */
  118. void *BIO_s_mem(void)
  119. {
  120. return NULL;
  121. }
  122. int BIO_method_type(const BIO *b)
  123. {
  124. SSL_ASSERT1(b);
  125. return b->type;
  126. }
  127. /**
  128. * @brief load data into BIO.
  129. *
  130. */
  131. int BIO_write(BIO *b, const void * data, int dlen)
  132. {
  133. SSL_ASSERT1(b);
  134. int remaining = b->size - b->offset;
  135. if (remaining <= 0) {
  136. b->flags |= BIO_FLAGS_WRITE;
  137. return -1;
  138. }
  139. int len_to_write = dlen > remaining?remaining:dlen;
  140. memcpy(b->data + b->offset, data, len_to_write);
  141. b->offset += len_to_write;
  142. b->dlen = b->offset;
  143. if (len_to_write == dlen) {
  144. b->flags &= ~BIO_FLAGS_WRITE;
  145. }
  146. return len_to_write;
  147. }
  148. /**
  149. * @brief Read from BIO.
  150. *
  151. */
  152. int BIO_read(BIO *bio, void *data, int len)
  153. {
  154. SSL_ASSERT1(bio);
  155. BIO *peer = bio->peer;
  156. int remaining = peer->dlen - peer->roffset;
  157. if (remaining <= 0) {
  158. bio->flags |= BIO_FLAGS_READ;
  159. return -1;
  160. }
  161. int len_to_read = remaining > len ? len : remaining;
  162. memcpy(data, peer->data + peer->roffset, len_to_read);
  163. peer->roffset += len_to_read;
  164. if (len_to_read == len) {
  165. bio->flags &= ~BIO_FLAGS_READ;
  166. }
  167. if (peer->offset) {
  168. // shift data back to the beginning of the buffer
  169. memmove(peer->data, peer->data+peer->roffset, peer->offset - peer->roffset);
  170. peer->offset -= peer->roffset;
  171. peer->roffset = 0;
  172. peer->dlen = peer->offset;
  173. }
  174. return len_to_read;
  175. }
  176. size_t BIO_wpending(const BIO *bio)
  177. {
  178. return bio->dlen - bio->roffset;
  179. }
  180. size_t BIO_ctrl_pending(const BIO *bio)
  181. {
  182. return bio->peer->dlen - bio->peer->roffset;
  183. }
  184. size_t BIO_ctrl_get_write_guarantee(BIO *b)
  185. {
  186. return (long)b->size - b->dlen;
  187. }
  188. int BIO_test_flags(const BIO *b, int flags)
  189. {
  190. return (b->flags & flags);
  191. }