bss_mem.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /*
  2. * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (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_lcl.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, int free_all);
  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. /* BIO memory stores buffer and read pointer */
  56. typedef struct bio_buf_mem_st {
  57. struct buf_mem_st *buf; /* allocated buffer */
  58. struct buf_mem_st *readp; /* read pointer */
  59. } BIO_BUF_MEM;
  60. /*
  61. * bio->num is used to hold the value to return on 'empty', if it is 0,
  62. * should_retry is not set
  63. */
  64. const BIO_METHOD *BIO_s_mem(void)
  65. {
  66. return &mem_method;
  67. }
  68. const BIO_METHOD *BIO_s_secmem(void)
  69. {
  70. return(&secmem_method);
  71. }
  72. BIO *BIO_new_mem_buf(const void *buf, int len)
  73. {
  74. BIO *ret;
  75. BUF_MEM *b;
  76. BIO_BUF_MEM *bb;
  77. size_t sz;
  78. if (buf == NULL) {
  79. BIOerr(BIO_F_BIO_NEW_MEM_BUF, BIO_R_NULL_PARAMETER);
  80. return NULL;
  81. }
  82. sz = (len < 0) ? strlen(buf) : (size_t)len;
  83. if ((ret = BIO_new(BIO_s_mem())) == NULL)
  84. return NULL;
  85. bb = (BIO_BUF_MEM *)ret->ptr;
  86. b = bb->buf;
  87. /* Cast away const and trust in the MEM_RDONLY flag. */
  88. b->data = (void *)buf;
  89. b->length = sz;
  90. b->max = sz;
  91. *bb->readp = *bb->buf;
  92. ret->flags |= BIO_FLAGS_MEM_RDONLY;
  93. /* Since this is static data retrying won't help */
  94. ret->num = 0;
  95. return ret;
  96. }
  97. static int mem_init(BIO *bi, unsigned long flags)
  98. {
  99. BIO_BUF_MEM *bb = OPENSSL_zalloc(sizeof(*bb));
  100. if (bb == NULL)
  101. return 0;
  102. if ((bb->buf = BUF_MEM_new_ex(flags)) == NULL) {
  103. OPENSSL_free(bb);
  104. return 0;
  105. }
  106. if ((bb->readp = OPENSSL_zalloc(sizeof(*bb->readp))) == NULL) {
  107. BUF_MEM_free(bb->buf);
  108. OPENSSL_free(bb);
  109. return 0;
  110. }
  111. *bb->readp = *bb->buf;
  112. bi->shutdown = 1;
  113. bi->init = 1;
  114. bi->num = -1;
  115. bi->ptr = (char *)bb;
  116. return 1;
  117. }
  118. static int mem_new(BIO *bi)
  119. {
  120. return mem_init(bi, 0L);
  121. }
  122. static int secmem_new(BIO *bi)
  123. {
  124. return mem_init(bi, BUF_MEM_FLAG_SECURE);
  125. }
  126. static int mem_free(BIO *a)
  127. {
  128. return mem_buf_free(a, 1);
  129. }
  130. static int mem_buf_free(BIO *a, int free_all)
  131. {
  132. if (a == NULL)
  133. return 0;
  134. if (a->shutdown && a->init && a->ptr != NULL) {
  135. BIO_BUF_MEM *bb = (BIO_BUF_MEM *)a->ptr;
  136. BUF_MEM *b = bb->buf;
  137. if (a->flags & BIO_FLAGS_MEM_RDONLY)
  138. b->data = NULL;
  139. BUF_MEM_free(b);
  140. if (free_all) {
  141. OPENSSL_free(bb->readp);
  142. OPENSSL_free(bb);
  143. }
  144. a->ptr = NULL;
  145. }
  146. return 1;
  147. }
  148. /*
  149. * Reallocate memory buffer if read pointer differs
  150. */
  151. static int mem_buf_sync(BIO *b)
  152. {
  153. if (b != NULL && b->init != 0 && b->ptr != NULL) {
  154. BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
  155. if (bbm->readp->data != bbm->buf->data) {
  156. memmove(bbm->buf->data, bbm->readp->data, bbm->readp->length);
  157. bbm->buf->length = bbm->readp->length;
  158. bbm->readp->data = bbm->buf->data;
  159. }
  160. }
  161. return 0;
  162. }
  163. static int mem_read(BIO *b, char *out, int outl)
  164. {
  165. int ret = -1;
  166. BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
  167. BUF_MEM *bm = bbm->readp;
  168. BIO_clear_retry_flags(b);
  169. ret = (outl >= 0 && (size_t)outl > bm->length) ? (int)bm->length : outl;
  170. if ((out != NULL) && (ret > 0)) {
  171. memcpy(out, bm->data, ret);
  172. bm->length -= ret;
  173. bm->data += ret;
  174. } else if (bm->length == 0) {
  175. ret = b->num;
  176. if (ret != 0)
  177. BIO_set_retry_read(b);
  178. }
  179. return ret;
  180. }
  181. static int mem_write(BIO *b, const char *in, int inl)
  182. {
  183. int ret = -1;
  184. int blen;
  185. BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
  186. if (in == NULL) {
  187. BIOerr(BIO_F_MEM_WRITE, BIO_R_NULL_PARAMETER);
  188. goto end;
  189. }
  190. if (b->flags & BIO_FLAGS_MEM_RDONLY) {
  191. BIOerr(BIO_F_MEM_WRITE, BIO_R_WRITE_TO_READ_ONLY_BIO);
  192. goto end;
  193. }
  194. BIO_clear_retry_flags(b);
  195. if (inl == 0)
  196. return 0;
  197. blen = bbm->readp->length;
  198. mem_buf_sync(b);
  199. if (BUF_MEM_grow_clean(bbm->buf, blen + inl) == 0)
  200. goto end;
  201. memcpy(bbm->buf->data + blen, in, inl);
  202. *bbm->readp = *bbm->buf;
  203. ret = inl;
  204. end:
  205. return ret;
  206. }
  207. static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
  208. {
  209. long ret = 1;
  210. char **pptr;
  211. BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
  212. BUF_MEM *bm;
  213. switch (cmd) {
  214. case BIO_CTRL_RESET:
  215. bm = bbm->buf;
  216. if (bm->data != NULL) {
  217. /* For read only case reset to the start again */
  218. if ((b->flags & BIO_FLAGS_MEM_RDONLY) || (b->flags & BIO_FLAGS_NONCLEAR_RST)) {
  219. bm->length = bm->max;
  220. } else {
  221. memset(bm->data, 0, bm->max);
  222. bm->length = 0;
  223. }
  224. *bbm->readp = *bbm->buf;
  225. }
  226. break;
  227. case BIO_CTRL_EOF:
  228. bm = bbm->readp;
  229. ret = (long)(bm->length == 0);
  230. break;
  231. case BIO_C_SET_BUF_MEM_EOF_RETURN:
  232. b->num = (int)num;
  233. break;
  234. case BIO_CTRL_INFO:
  235. bm = bbm->readp;
  236. ret = (long)bm->length;
  237. if (ptr != NULL) {
  238. pptr = (char **)ptr;
  239. *pptr = (char *)&(bm->data[0]);
  240. }
  241. break;
  242. case BIO_C_SET_BUF_MEM:
  243. mem_buf_free(b, 0);
  244. b->shutdown = (int)num;
  245. bbm->buf = ptr;
  246. *bbm->readp = *bbm->buf;
  247. b->ptr = bbm;
  248. break;
  249. case BIO_C_GET_BUF_MEM_PTR:
  250. if (ptr != NULL) {
  251. mem_buf_sync(b);
  252. bm = bbm->readp;
  253. pptr = (char **)ptr;
  254. *pptr = (char *)bm;
  255. }
  256. break;
  257. case BIO_CTRL_GET_CLOSE:
  258. ret = (long)b->shutdown;
  259. break;
  260. case BIO_CTRL_SET_CLOSE:
  261. b->shutdown = (int)num;
  262. break;
  263. case BIO_CTRL_WPENDING:
  264. ret = 0L;
  265. break;
  266. case BIO_CTRL_PENDING:
  267. bm = bbm->readp;
  268. ret = (long)bm->length;
  269. break;
  270. case BIO_CTRL_DUP:
  271. case BIO_CTRL_FLUSH:
  272. ret = 1;
  273. break;
  274. case BIO_CTRL_PUSH:
  275. case BIO_CTRL_POP:
  276. default:
  277. ret = 0;
  278. break;
  279. }
  280. return ret;
  281. }
  282. static int mem_gets(BIO *bp, char *buf, int size)
  283. {
  284. int i, j;
  285. int ret = -1;
  286. char *p;
  287. BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)bp->ptr;
  288. BUF_MEM *bm = bbm->readp;
  289. BIO_clear_retry_flags(bp);
  290. j = bm->length;
  291. if ((size - 1) < j)
  292. j = size - 1;
  293. if (j <= 0) {
  294. *buf = '\0';
  295. return 0;
  296. }
  297. p = bm->data;
  298. for (i = 0; i < j; i++) {
  299. if (p[i] == '\n') {
  300. i++;
  301. break;
  302. }
  303. }
  304. /*
  305. * i is now the max num of bytes to copy, either j or up to
  306. * and including the first newline
  307. */
  308. i = mem_read(bp, buf, i);
  309. if (i > 0)
  310. buf[i] = '\0';
  311. ret = i;
  312. return ret;
  313. }
  314. static int mem_puts(BIO *bp, const char *str)
  315. {
  316. int n, ret;
  317. n = strlen(str);
  318. ret = mem_write(bp, str, n);
  319. /* memory semantics is that it will always work */
  320. return ret;
  321. }