bss_mem.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /*
  2. * Copyright 1995-2023 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. #include <stdio.h>
  10. #include <errno.h>
  11. #include "bio_local.h"
  12. #include "internal/cryptlib.h"
  13. static int mem_write(BIO *h, const char *buf, int num);
  14. static int mem_read(BIO *h, char *buf, int size);
  15. static int mem_puts(BIO *h, const char *str);
  16. static int mem_gets(BIO *h, char *str, int size);
  17. static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2);
  18. static int mem_new(BIO *h);
  19. static int secmem_new(BIO *h);
  20. static int mem_free(BIO *data);
  21. static int mem_buf_free(BIO *data);
  22. static int mem_buf_sync(BIO *h);
  23. static const BIO_METHOD mem_method = {
  24. BIO_TYPE_MEM,
  25. "memory buffer",
  26. bwrite_conv,
  27. mem_write,
  28. bread_conv,
  29. mem_read,
  30. mem_puts,
  31. mem_gets,
  32. mem_ctrl,
  33. mem_new,
  34. mem_free,
  35. NULL, /* mem_callback_ctrl */
  36. };
  37. static const BIO_METHOD secmem_method = {
  38. BIO_TYPE_MEM,
  39. "secure memory buffer",
  40. bwrite_conv,
  41. mem_write,
  42. bread_conv,
  43. mem_read,
  44. mem_puts,
  45. mem_gets,
  46. mem_ctrl,
  47. secmem_new,
  48. mem_free,
  49. NULL, /* mem_callback_ctrl */
  50. };
  51. /*
  52. * BIO memory stores buffer and read pointer
  53. * however the roles are different for read only BIOs.
  54. * In that case the readp just stores the original state
  55. * to be used for reset.
  56. */
  57. typedef struct bio_buf_mem_st {
  58. struct buf_mem_st *buf; /* allocated buffer */
  59. struct buf_mem_st *readp; /* read pointer */
  60. } BIO_BUF_MEM;
  61. /*
  62. * bio->num is used to hold the value to return on 'empty', if it is 0,
  63. * should_retry is not set
  64. */
  65. const BIO_METHOD *BIO_s_mem(void)
  66. {
  67. return &mem_method;
  68. }
  69. const BIO_METHOD *BIO_s_secmem(void)
  70. {
  71. return(&secmem_method);
  72. }
  73. BIO *BIO_new_mem_buf(const void *buf, int len)
  74. {
  75. BIO *ret;
  76. BUF_MEM *b;
  77. BIO_BUF_MEM *bb;
  78. size_t sz;
  79. if (buf == NULL) {
  80. ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
  81. return NULL;
  82. }
  83. sz = (len < 0) ? strlen(buf) : (size_t)len;
  84. if ((ret = BIO_new(BIO_s_mem())) == NULL)
  85. return NULL;
  86. bb = (BIO_BUF_MEM *)ret->ptr;
  87. b = bb->buf;
  88. /* Cast away const and trust in the MEM_RDONLY flag. */
  89. b->data = (void *)buf;
  90. b->length = sz;
  91. b->max = sz;
  92. *bb->readp = *bb->buf;
  93. ret->flags |= BIO_FLAGS_MEM_RDONLY;
  94. /* Since this is static data retrying won't help */
  95. ret->num = 0;
  96. return ret;
  97. }
  98. static int mem_init(BIO *bi, unsigned long flags)
  99. {
  100. BIO_BUF_MEM *bb = OPENSSL_zalloc(sizeof(*bb));
  101. if (bb == NULL)
  102. return 0;
  103. if ((bb->buf = BUF_MEM_new_ex(flags)) == NULL) {
  104. OPENSSL_free(bb);
  105. return 0;
  106. }
  107. if ((bb->readp = OPENSSL_zalloc(sizeof(*bb->readp))) == NULL) {
  108. BUF_MEM_free(bb->buf);
  109. OPENSSL_free(bb);
  110. return 0;
  111. }
  112. *bb->readp = *bb->buf;
  113. bi->shutdown = 1;
  114. bi->init = 1;
  115. bi->num = -1;
  116. bi->ptr = (char *)bb;
  117. return 1;
  118. }
  119. static int mem_new(BIO *bi)
  120. {
  121. return mem_init(bi, 0L);
  122. }
  123. static int secmem_new(BIO *bi)
  124. {
  125. return mem_init(bi, BUF_MEM_FLAG_SECURE);
  126. }
  127. static int mem_free(BIO *a)
  128. {
  129. BIO_BUF_MEM *bb;
  130. if (a == NULL)
  131. return 0;
  132. bb = (BIO_BUF_MEM *)a->ptr;
  133. if (!mem_buf_free(a))
  134. return 0;
  135. OPENSSL_free(bb->readp);
  136. OPENSSL_free(bb);
  137. return 1;
  138. }
  139. static int mem_buf_free(BIO *a)
  140. {
  141. if (a == NULL)
  142. return 0;
  143. if (a->shutdown && a->init && a->ptr != NULL) {
  144. BIO_BUF_MEM *bb = (BIO_BUF_MEM *)a->ptr;
  145. BUF_MEM *b = bb->buf;
  146. if (a->flags & BIO_FLAGS_MEM_RDONLY)
  147. b->data = NULL;
  148. BUF_MEM_free(b);
  149. }
  150. return 1;
  151. }
  152. /*
  153. * Reallocate memory buffer if read pointer differs
  154. * NOT FOR RDONLY
  155. */
  156. static int mem_buf_sync(BIO *b)
  157. {
  158. if (b != NULL && b->init != 0 && b->ptr != NULL) {
  159. BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
  160. if (bbm->readp->data != bbm->buf->data) {
  161. memmove(bbm->buf->data, bbm->readp->data, bbm->readp->length);
  162. bbm->buf->length = bbm->readp->length;
  163. bbm->readp->data = bbm->buf->data;
  164. }
  165. }
  166. return 0;
  167. }
  168. static int mem_read(BIO *b, char *out, int outl)
  169. {
  170. int ret = -1;
  171. BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
  172. BUF_MEM *bm = bbm->readp;
  173. if (b->flags & BIO_FLAGS_MEM_RDONLY)
  174. bm = bbm->buf;
  175. BIO_clear_retry_flags(b);
  176. ret = (outl >= 0 && (size_t)outl > bm->length) ? (int)bm->length : outl;
  177. if ((out != NULL) && (ret > 0)) {
  178. memcpy(out, bm->data, ret);
  179. bm->length -= ret;
  180. bm->max -= ret;
  181. bm->data += ret;
  182. } else if (bm->length == 0) {
  183. ret = b->num;
  184. if (ret != 0)
  185. BIO_set_retry_read(b);
  186. }
  187. return ret;
  188. }
  189. static int mem_write(BIO *b, const char *in, int inl)
  190. {
  191. int ret = -1;
  192. int blen;
  193. BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
  194. if (b->flags & BIO_FLAGS_MEM_RDONLY) {
  195. ERR_raise(ERR_LIB_BIO, BIO_R_WRITE_TO_READ_ONLY_BIO);
  196. goto end;
  197. }
  198. BIO_clear_retry_flags(b);
  199. if (inl == 0)
  200. return 0;
  201. if (in == NULL) {
  202. ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
  203. goto end;
  204. }
  205. blen = bbm->readp->length;
  206. mem_buf_sync(b);
  207. if (BUF_MEM_grow_clean(bbm->buf, blen + inl) == 0)
  208. goto end;
  209. memcpy(bbm->buf->data + blen, in, inl);
  210. *bbm->readp = *bbm->buf;
  211. ret = inl;
  212. end:
  213. return ret;
  214. }
  215. static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
  216. {
  217. long ret = 1;
  218. char **pptr;
  219. BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
  220. BUF_MEM *bm, *bo; /* bio_mem, bio_other */
  221. long off, remain;
  222. if (b->flags & BIO_FLAGS_MEM_RDONLY) {
  223. bm = bbm->buf;
  224. bo = bbm->readp;
  225. } else {
  226. bm = bbm->readp;
  227. bo = bbm->buf;
  228. }
  229. off = (bm->data == bo->data) ? 0 : bm->data - bo->data;
  230. remain = bm->length;
  231. switch (cmd) {
  232. case BIO_CTRL_RESET:
  233. bm = bbm->buf;
  234. if (bm->data != NULL) {
  235. if (!(b->flags & BIO_FLAGS_MEM_RDONLY)) {
  236. if (!(b->flags & BIO_FLAGS_NONCLEAR_RST)) {
  237. memset(bm->data, 0, bm->max);
  238. bm->length = 0;
  239. }
  240. *bbm->readp = *bbm->buf;
  241. } else {
  242. /* For read only case just reset to the start again */
  243. *bbm->buf = *bbm->readp;
  244. }
  245. }
  246. break;
  247. case BIO_C_FILE_SEEK:
  248. if (num < 0 || num > off + remain)
  249. return -1; /* Can't see outside of the current buffer */
  250. bm->data = (num != 0) ? bo->data + num : bo->data;
  251. bm->length = bo->length - num;
  252. bm->max = bo->max - num;
  253. off = num;
  254. /* FALLTHRU */
  255. case BIO_C_FILE_TELL:
  256. ret = off;
  257. break;
  258. case BIO_CTRL_EOF:
  259. ret = (long)(bm->length == 0);
  260. break;
  261. case BIO_C_SET_BUF_MEM_EOF_RETURN:
  262. b->num = (int)num;
  263. break;
  264. case BIO_CTRL_INFO:
  265. ret = (long)bm->length;
  266. if (ptr != NULL) {
  267. pptr = (char **)ptr;
  268. *pptr = (char *)(bm->data);
  269. }
  270. break;
  271. case BIO_C_SET_BUF_MEM:
  272. mem_buf_free(b);
  273. b->shutdown = (int)num;
  274. bbm->buf = ptr;
  275. *bbm->readp = *bbm->buf;
  276. break;
  277. case BIO_C_GET_BUF_MEM_PTR:
  278. if (ptr != NULL) {
  279. if (!(b->flags & BIO_FLAGS_MEM_RDONLY))
  280. mem_buf_sync(b);
  281. bm = bbm->buf;
  282. pptr = (char **)ptr;
  283. *pptr = (char *)bm;
  284. }
  285. break;
  286. case BIO_CTRL_GET_CLOSE:
  287. ret = (long)b->shutdown;
  288. break;
  289. case BIO_CTRL_SET_CLOSE:
  290. b->shutdown = (int)num;
  291. break;
  292. case BIO_CTRL_WPENDING:
  293. ret = 0L;
  294. break;
  295. case BIO_CTRL_PENDING:
  296. ret = (long)bm->length;
  297. break;
  298. case BIO_CTRL_DUP:
  299. case BIO_CTRL_FLUSH:
  300. ret = 1;
  301. break;
  302. case BIO_CTRL_PUSH:
  303. case BIO_CTRL_POP:
  304. default:
  305. ret = 0;
  306. break;
  307. }
  308. return ret;
  309. }
  310. static int mem_gets(BIO *bp, char *buf, int size)
  311. {
  312. int i, j;
  313. int ret = -1;
  314. char *p;
  315. BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)bp->ptr;
  316. BUF_MEM *bm = bbm->readp;
  317. if (bp->flags & BIO_FLAGS_MEM_RDONLY)
  318. bm = bbm->buf;
  319. BIO_clear_retry_flags(bp);
  320. j = bm->length;
  321. if ((size - 1) < j)
  322. j = size - 1;
  323. if (j <= 0) {
  324. *buf = '\0';
  325. return 0;
  326. }
  327. p = bm->data;
  328. for (i = 0; i < j; i++) {
  329. if (p[i] == '\n') {
  330. i++;
  331. break;
  332. }
  333. }
  334. /*
  335. * i is now the max num of bytes to copy, either j or up to
  336. * and including the first newline
  337. */
  338. i = mem_read(bp, buf, i);
  339. if (i > 0)
  340. buf[i] = '\0';
  341. ret = i;
  342. return ret;
  343. }
  344. static int mem_puts(BIO *bp, const char *str)
  345. {
  346. int n, ret;
  347. n = strlen(str);
  348. ret = mem_write(bp, str, n);
  349. /* memory semantics is that it will always work */
  350. return ret;
  351. }