您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

327 行
8.6 KiB

  1. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  2. * All rights reserved.
  3. *
  4. * This package is an SSL implementation written
  5. * by Eric Young (eay@cryptsoft.com).
  6. * The implementation was written so as to conform with Netscapes SSL.
  7. *
  8. * This library is free for commercial and non-commercial use as long as
  9. * the following conditions are aheared to. The following conditions
  10. * apply to all code found in this distribution, be it the RC4, RSA,
  11. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  12. * included with this distribution is covered by the same copyright terms
  13. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  14. *
  15. * Copyright remains Eric Young's, and as such any Copyright notices in
  16. * the code are not to be removed.
  17. * If this package is used in a product, Eric Young should be given attribution
  18. * as the author of the parts of the library used.
  19. * This can be in the form of a textual message at program startup or
  20. * in documentation (online or textual) provided with the package.
  21. *
  22. * Redistribution and use in source and binary forms, with or without
  23. * modification, are permitted provided that the following conditions
  24. * are met:
  25. * 1. Redistributions of source code must retain the copyright
  26. * notice, this list of conditions and the following disclaimer.
  27. * 2. Redistributions in binary form must reproduce the above copyright
  28. * notice, this list of conditions and the following disclaimer in the
  29. * documentation and/or other materials provided with the distribution.
  30. * 3. All advertising materials mentioning features or use of this software
  31. * must display the following acknowledgement:
  32. * "This product includes cryptographic software written by
  33. * Eric Young (eay@cryptsoft.com)"
  34. * The word 'cryptographic' can be left out if the rouines from the library
  35. * being used are not cryptographic related :-).
  36. * 4. If you include any Windows specific code (or a derivative thereof) from
  37. * the apps directory (application code) you must include an acknowledgement:
  38. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  39. *
  40. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  41. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  42. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  43. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  44. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  45. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  46. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  48. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  49. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  50. * SUCH DAMAGE.
  51. *
  52. * The licence and distribution terms for any publically available version or
  53. * derivative of this code cannot be changed. i.e. this code cannot simply be
  54. * copied and put under another distribution licence
  55. * [including the GNU Public Licence.] */
  56. #include <openssl/bio.h>
  57. #include <limits.h>
  58. #include <openssl/buf.h>
  59. #include <openssl/err.h>
  60. #include <openssl/mem.h>
  61. BIO *BIO_new_mem_buf(void *buf, int len) {
  62. BIO *ret;
  63. BUF_MEM *b;
  64. const size_t size = len < 0 ? strlen((char *)buf) : (size_t)len;
  65. if (!buf && len != 0) {
  66. OPENSSL_PUT_ERROR(BIO, BIO_new_mem_buf, BIO_R_NULL_PARAMETER);
  67. return NULL;
  68. }
  69. ret = BIO_new(BIO_s_mem());
  70. if (ret == NULL) {
  71. return NULL;
  72. }
  73. b = (BUF_MEM *)ret->ptr;
  74. b->data = buf;
  75. b->length = size;
  76. b->max = size;
  77. ret->flags |= BIO_FLAGS_MEM_RDONLY;
  78. /* |num| is used to store the value that this BIO will return when it runs
  79. * out of data. If it's negative then the retry flags will also be set. Since
  80. * this is static data, retrying wont help */
  81. ret->num = 0;
  82. return ret;
  83. }
  84. static int mem_new(BIO *bio) {
  85. BUF_MEM *b;
  86. b = BUF_MEM_new();
  87. if (b == NULL) {
  88. return 0;
  89. }
  90. /* |shutdown| is used to store the close flag: whether the BIO has ownership
  91. * of the BUF_MEM. */
  92. bio->shutdown = 1;
  93. bio->init = 1;
  94. bio->num = -1;
  95. bio->ptr = (char *)b;
  96. return 1;
  97. }
  98. static int mem_free(BIO *bio) {
  99. BUF_MEM *b;
  100. if (bio == NULL) {
  101. return 0;
  102. }
  103. if (!bio->shutdown || !bio->init || bio->ptr == NULL) {
  104. return 1;
  105. }
  106. b = (BUF_MEM *)bio->ptr;
  107. if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
  108. b->data = NULL;
  109. }
  110. BUF_MEM_free(b);
  111. bio->ptr = NULL;
  112. return 1;
  113. }
  114. static int mem_read(BIO *bio, char *out, int outl) {
  115. int ret;
  116. BUF_MEM *b = (BUF_MEM*) bio->ptr;
  117. BIO_clear_retry_flags(bio);
  118. ret = outl;
  119. if (b->length < INT_MAX && ret > (int)b->length) {
  120. ret = b->length;
  121. }
  122. if (ret > 0) {
  123. memcpy(out, b->data, ret);
  124. b->length -= ret;
  125. if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
  126. b->data += ret;
  127. } else {
  128. memmove(b->data, &b->data[ret], b->length);
  129. }
  130. } else if (b->length == 0) {
  131. ret = bio->num;
  132. if (ret != 0) {
  133. BIO_set_retry_read(bio);
  134. }
  135. }
  136. return ret;
  137. }
  138. static int mem_write(BIO *bio, const char *in, int inl) {
  139. int ret = -1;
  140. int blen;
  141. BUF_MEM *b;
  142. b = (BUF_MEM *)bio->ptr;
  143. if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
  144. OPENSSL_PUT_ERROR(BIO, mem_write, BIO_R_WRITE_TO_READ_ONLY_BIO);
  145. goto err;
  146. }
  147. BIO_clear_retry_flags(bio);
  148. blen = b->length;
  149. if (INT_MAX - blen < inl) {
  150. goto err;
  151. }
  152. if (BUF_MEM_grow_clean(b, blen + inl) != (blen + inl)) {
  153. goto err;
  154. }
  155. memcpy(&b->data[blen], in, inl);
  156. ret = inl;
  157. err:
  158. return ret;
  159. }
  160. static int mem_puts(BIO *bp, const char *str) {
  161. return mem_write(bp, str, strlen(str));
  162. }
  163. static int mem_gets(BIO *bio, char *buf, int size) {
  164. int i, j;
  165. char *p;
  166. BUF_MEM *b = (BUF_MEM *)bio->ptr;
  167. BIO_clear_retry_flags(bio);
  168. j = b->length;
  169. if (size - 1 < j) {
  170. j = size - 1;
  171. }
  172. if (j <= 0) {
  173. if (size > 0) {
  174. *buf = 0;
  175. }
  176. return 0;
  177. }
  178. p = b->data;
  179. for (i = 0; i < j; i++) {
  180. if (p[i] == '\n') {
  181. i++;
  182. break;
  183. }
  184. }
  185. /* i is now the max num of bytes to copy, either j or up to and including the
  186. * first newline */
  187. i = mem_read(bio, buf, i);
  188. if (i > 0) {
  189. buf[i] = '\0';
  190. }
  191. return i;
  192. }
  193. static long mem_ctrl(BIO *bio, int cmd, long num, void *ptr) {
  194. long ret = 1;
  195. char **pptr;
  196. BUF_MEM *b = (BUF_MEM *)bio->ptr;
  197. switch (cmd) {
  198. case BIO_CTRL_RESET:
  199. if (b->data != NULL) {
  200. /* For read only case reset to the start again */
  201. if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
  202. b->data -= b->max - b->length;
  203. b->length = b->max;
  204. } else {
  205. memset(b->data, 0, b->max);
  206. b->length = 0;
  207. }
  208. }
  209. break;
  210. case BIO_CTRL_EOF:
  211. ret = (long)(b->length == 0);
  212. break;
  213. case BIO_C_SET_BUF_MEM_EOF_RETURN:
  214. bio->num = (int)num;
  215. break;
  216. case BIO_CTRL_INFO:
  217. ret = (long)b->length;
  218. if (ptr != NULL) {
  219. pptr = (char **)ptr;
  220. *pptr = (char *)&b->data[0];
  221. }
  222. break;
  223. case BIO_C_SET_BUF_MEM:
  224. mem_free(bio);
  225. bio->shutdown = (int)num;
  226. bio->ptr = ptr;
  227. break;
  228. case BIO_C_GET_BUF_MEM_PTR:
  229. if (ptr != NULL) {
  230. pptr = (char **)ptr;
  231. *pptr = (char *)b;
  232. }
  233. break;
  234. case BIO_CTRL_GET_CLOSE:
  235. ret = (long)bio->shutdown;
  236. break;
  237. case BIO_CTRL_SET_CLOSE:
  238. bio->shutdown = (int)num;
  239. break;
  240. case BIO_CTRL_WPENDING:
  241. ret = 0L;
  242. break;
  243. case BIO_CTRL_PENDING:
  244. ret = (long)b->length;
  245. break;
  246. case BIO_CTRL_FLUSH:
  247. ret = 1;
  248. break;
  249. default:
  250. ret = 0;
  251. break;
  252. }
  253. return ret;
  254. }
  255. static const BIO_METHOD mem_method = {
  256. BIO_TYPE_MEM, "memory buffer", mem_write, mem_read, mem_puts,
  257. mem_gets, mem_ctrl, mem_new, mem_free, NULL, };
  258. const BIO_METHOD *BIO_s_mem(void) { return &mem_method; }
  259. int BIO_mem_contents(const BIO *bio, const uint8_t **out_contents,
  260. size_t *out_len) {
  261. const BUF_MEM *b;
  262. if (bio->method != &mem_method) {
  263. return 0;
  264. }
  265. b = (BUF_MEM *)bio->ptr;
  266. *out_contents = (uint8_t *)b->data;
  267. *out_len = b->length;
  268. return 1;
  269. }
  270. long BIO_get_mem_data(BIO *bio, char **contents) {
  271. return BIO_ctrl(bio, BIO_CTRL_INFO, 0, (char *) contents);
  272. }
  273. int BIO_get_mem_ptr(BIO *bio, BUF_MEM **out) {
  274. return BIO_ctrl(bio, BIO_C_GET_BUF_MEM_PTR, 0, (char *) out);
  275. }
  276. int BIO_set_mem_buf(BIO *bio, BUF_MEM *b, int take_ownership) {
  277. return BIO_ctrl(bio, BIO_C_SET_BUF_MEM, take_ownership, (char *) b);
  278. }
  279. int BIO_set_mem_eof_return(BIO *bio, int eof_value) {
  280. return BIO_ctrl(bio, BIO_C_SET_BUF_MEM_EOF_RETURN, eof_value, NULL);
  281. }