bss_mem.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. /*
  2. * Copyright 1995-2018 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. */
  159. static int mem_buf_sync(BIO *b)
  160. {
  161. if (b != NULL && b->init != 0 && b->ptr != NULL) {
  162. BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
  163. if (bbm->readp->data != bbm->buf->data) {
  164. memmove(bbm->buf->data, bbm->readp->data, bbm->readp->length);
  165. bbm->buf->length = bbm->readp->length;
  166. bbm->readp->data = bbm->buf->data;
  167. }
  168. }
  169. return 0;
  170. }
  171. static int mem_read(BIO *b, char *out, int outl)
  172. {
  173. int ret = -1;
  174. BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
  175. BUF_MEM *bm = bbm->readp;
  176. if (b->flags & BIO_FLAGS_MEM_RDONLY)
  177. bm = bbm->buf;
  178. BIO_clear_retry_flags(b);
  179. ret = (outl >= 0 && (size_t)outl > bm->length) ? (int)bm->length : outl;
  180. if ((out != NULL) && (ret > 0)) {
  181. memcpy(out, bm->data, ret);
  182. bm->length -= ret;
  183. bm->max -= ret;
  184. bm->data += ret;
  185. } else if (bm->length == 0) {
  186. ret = b->num;
  187. if (ret != 0)
  188. BIO_set_retry_read(b);
  189. }
  190. return ret;
  191. }
  192. static int mem_write(BIO *b, const char *in, int inl)
  193. {
  194. int ret = -1;
  195. int blen;
  196. BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
  197. if (in == NULL) {
  198. BIOerr(BIO_F_MEM_WRITE, BIO_R_NULL_PARAMETER);
  199. goto end;
  200. }
  201. if (b->flags & BIO_FLAGS_MEM_RDONLY) {
  202. BIOerr(BIO_F_MEM_WRITE, BIO_R_WRITE_TO_READ_ONLY_BIO);
  203. goto end;
  204. }
  205. BIO_clear_retry_flags(b);
  206. if (inl == 0)
  207. return 0;
  208. blen = bbm->readp->length;
  209. mem_buf_sync(b);
  210. if (BUF_MEM_grow_clean(bbm->buf, blen + inl) == 0)
  211. goto end;
  212. memcpy(bbm->buf->data + blen, in, inl);
  213. *bbm->readp = *bbm->buf;
  214. ret = inl;
  215. end:
  216. return ret;
  217. }
  218. static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
  219. {
  220. long ret = 1;
  221. char **pptr;
  222. BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
  223. BUF_MEM *bm;
  224. if (b->flags & BIO_FLAGS_MEM_RDONLY)
  225. bm = bbm->buf;
  226. else
  227. bm = bbm->readp;
  228. switch (cmd) {
  229. case BIO_CTRL_RESET:
  230. bm = bbm->buf;
  231. if (bm->data != NULL) {
  232. if (!(b->flags & BIO_FLAGS_MEM_RDONLY)) {
  233. if (!(b->flags & BIO_FLAGS_NONCLEAR_RST)) {
  234. memset(bm->data, 0, bm->max);
  235. bm->length = 0;
  236. }
  237. *bbm->readp = *bbm->buf;
  238. } else {
  239. /* For read only case just reset to the start again */
  240. *bbm->buf = *bbm->readp;
  241. }
  242. }
  243. break;
  244. case BIO_CTRL_EOF:
  245. ret = (long)(bm->length == 0);
  246. break;
  247. case BIO_C_SET_BUF_MEM_EOF_RETURN:
  248. b->num = (int)num;
  249. break;
  250. case BIO_CTRL_INFO:
  251. ret = (long)bm->length;
  252. if (ptr != NULL) {
  253. pptr = (char **)ptr;
  254. *pptr = (char *)&(bm->data[0]);
  255. }
  256. break;
  257. case BIO_C_SET_BUF_MEM:
  258. mem_buf_free(b);
  259. b->shutdown = (int)num;
  260. bbm->buf = ptr;
  261. *bbm->readp = *bbm->buf;
  262. break;
  263. case BIO_C_GET_BUF_MEM_PTR:
  264. if (ptr != NULL) {
  265. if (!(b->flags & BIO_FLAGS_MEM_RDONLY))
  266. mem_buf_sync(b);
  267. bm = bbm->buf;
  268. pptr = (char **)ptr;
  269. *pptr = (char *)bm;
  270. }
  271. break;
  272. case BIO_CTRL_GET_CLOSE:
  273. ret = (long)b->shutdown;
  274. break;
  275. case BIO_CTRL_SET_CLOSE:
  276. b->shutdown = (int)num;
  277. break;
  278. case BIO_CTRL_WPENDING:
  279. ret = 0L;
  280. break;
  281. case BIO_CTRL_PENDING:
  282. ret = (long)bm->length;
  283. break;
  284. case BIO_CTRL_DUP:
  285. case BIO_CTRL_FLUSH:
  286. ret = 1;
  287. break;
  288. case BIO_CTRL_PUSH:
  289. case BIO_CTRL_POP:
  290. default:
  291. ret = 0;
  292. break;
  293. }
  294. return ret;
  295. }
  296. static int mem_gets(BIO *bp, char *buf, int size)
  297. {
  298. int i, j;
  299. int ret = -1;
  300. char *p;
  301. BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)bp->ptr;
  302. BUF_MEM *bm = bbm->readp;
  303. if (bp->flags & BIO_FLAGS_MEM_RDONLY)
  304. bm = bbm->buf;
  305. BIO_clear_retry_flags(bp);
  306. j = bm->length;
  307. if ((size - 1) < j)
  308. j = size - 1;
  309. if (j <= 0) {
  310. *buf = '\0';
  311. return 0;
  312. }
  313. p = bm->data;
  314. for (i = 0; i < j; i++) {
  315. if (p[i] == '\n') {
  316. i++;
  317. break;
  318. }
  319. }
  320. /*
  321. * i is now the max num of bytes to copy, either j or up to
  322. * and including the first newline
  323. */
  324. i = mem_read(bp, buf, i);
  325. if (i > 0)
  326. buf[i] = '\0';
  327. ret = i;
  328. return ret;
  329. }
  330. static int mem_puts(BIO *bp, const char *str)
  331. {
  332. int n, ret;
  333. n = strlen(str);
  334. ret = mem_write(bp, str, n);
  335. /* memory semantics is that it will always work */
  336. return ret;
  337. }