bss_mem.c 9.1 KB

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