ssl_misc.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /* ssl_misc.c
  2. *
  3. * Copyright (C) 2006-2023 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <wolfssl/wolfcrypt/settings.h>
  25. #if !defined(WOLFSSL_SSL_MISC_INCLUDED)
  26. #ifndef WOLFSSL_IGNORE_FILE_WARN
  27. #warning ssl_misc.c does not need to be compiled separately from ssl.c
  28. #endif
  29. #else
  30. #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
  31. #ifndef NO_BIO
  32. #ifdef WOLFSSL_NO_FSEEK
  33. /* Amount of memory to allocate/add. */
  34. #define READ_BIO_FILE_CHUNK 128
  35. /* Read a file in chunks.
  36. *
  37. * Allocates a chunk and reads into it until it is full.
  38. *
  39. * @param [in, out] bio BIO object to read with.
  40. * @param [out] data Read data in a new buffer.
  41. * @return Negative on error.
  42. * @return Number of bytes read on success.
  43. */
  44. static int wolfssl_read_bio_file(WOLFSSL_BIO* bio, char** data)
  45. {
  46. int ret = 0;
  47. char* mem;
  48. char* p;
  49. /* Allocate buffer to hold a chunk of data. */
  50. mem = (char*)XMALLOC(READ_BIO_FILE_CHUNK, bio->heap, DYNAMIC_TYPE_OPENSSL);
  51. if (mem == NULL) {
  52. WOLFSSL_ERROR_MSG("Memory allocation error");
  53. ret = MEMORY_E;
  54. }
  55. if (ret == 0) {
  56. int sz;
  57. /* ret is the number of bytes read and is zero. */
  58. /* p is where to read in next chunk. */
  59. p = mem;
  60. /* Memory available to read into is one chunk. */
  61. sz = READ_BIO_FILE_CHUNK;
  62. /* Keep reading in chunks until no more or an error. */
  63. while ((sz = wolfSSL_BIO_read(bio, p, sz)) > 0) {
  64. int remaining;
  65. /* Update total read. */
  66. ret += sz;
  67. /* Calculate remaining unused memory. */
  68. remaining = READ_BIO_FILE_CHUNK - (ret % READ_BIO_FILE_CHUNK);
  69. /* Check for space remaining. */
  70. if (remaining != READ_BIO_FILE_CHUNK) {
  71. /* Update where data is read into. */
  72. p += sz;
  73. /* Maximum possible size is the remaining buffer size. */
  74. sz = remaining;
  75. }
  76. else {
  77. /* No space left for more data to be read - add a chunk. */
  78. p = (char*)XREALLOC(mem, ret + READ_BIO_FILE_CHUNK, bio->heap,
  79. DYNAMIC_TYPE_OPENSSL);
  80. if (p == NULL) {
  81. sz = MEMORY_E;
  82. break;
  83. }
  84. /* Set mem to new pointer. */
  85. mem = p;
  86. /* Set p to where to read in next chunk. */
  87. p += ret;
  88. /* Read in a new chunk. */
  89. sz = READ_BIO_FILE_CHUNK;
  90. }
  91. }
  92. if ((sz < 0) || (ret == 0)) {
  93. /* Dispose of memory on error or no data read. */
  94. XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
  95. mem = NULL;
  96. /* Return error. */
  97. ret = sz;
  98. }
  99. }
  100. *data = mem;
  101. return ret;
  102. }
  103. #endif
  104. /* Read exactly the required amount into a newly allocated buffer.
  105. *
  106. * @param [in, out] bio BIO object to read with.
  107. * @param [in sz Amount of data to read.
  108. * @param [out] data Read data in a new buffer.
  109. * @return Negative on error.
  110. * @return Number of bytes read on success.
  111. */
  112. static int wolfssl_read_bio_len(WOLFSSL_BIO* bio, int sz, char** data)
  113. {
  114. int ret = 0;
  115. char* mem;
  116. /* Allocate buffer to hold data. */
  117. mem = (char*)XMALLOC((size_t)sz, bio->heap, DYNAMIC_TYPE_OPENSSL);
  118. if (mem == NULL) {
  119. WOLFSSL_ERROR_MSG("Memory allocation error");
  120. ret = MEMORY_E;
  121. }
  122. else if ((ret = wolfSSL_BIO_read(bio, mem, sz)) != sz) {
  123. /* Pending data not read. */
  124. XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
  125. mem = NULL;
  126. ret = MEMORY_E;
  127. }
  128. *data = mem;
  129. return ret;
  130. }
  131. /* Read all the data from a BIO.
  132. *
  133. * @param [in, out] bio BIO object to read with.
  134. * @param [out] data Read data in a buffer.
  135. * @param [out] dataSz Amount of data read in bytes.
  136. * @param [out] memAlloced Indicates whether return buffer was allocated.
  137. * @return Negative on error.
  138. * @return 0 on success.
  139. */
  140. static int wolfssl_read_bio(WOLFSSL_BIO* bio, char** data, int* dataSz,
  141. int* memAlloced)
  142. {
  143. int ret;
  144. int sz;
  145. if (bio->type == WOLFSSL_BIO_MEMORY) {
  146. ret = wolfSSL_BIO_get_mem_data(bio, data);
  147. if (ret > 0) {
  148. bio->rdIdx += ret;
  149. }
  150. *memAlloced = 0;
  151. }
  152. #ifndef WOLFSSL_NO_FSEEK
  153. /* Get pending or, when a file BIO, get length of file. */
  154. else if ((sz = wolfSSL_BIO_get_len(bio)) > 0) {
  155. ret = wolfssl_read_bio_len(bio, sz, data);
  156. if (ret > 0) {
  157. *memAlloced = 1;
  158. }
  159. }
  160. #else
  161. else if ((sz = wolfSSL_BIO_pending(bio)) > 0) {
  162. ret = wolfssl_read_bio_len(bio, sz, data);
  163. if (ret > 0) {
  164. *memAlloced = 1;
  165. }
  166. }
  167. else if (bio->type == WOLFSSL_BIO_FILE) {
  168. ret = wolfssl_read_bio_file(bio, data);
  169. if (ret > 0) {
  170. *memAlloced = 1;
  171. }
  172. }
  173. #endif
  174. else {
  175. WOLFSSL_ERROR_MSG("No data read from bio");
  176. *memAlloced = 0;
  177. ret = NOT_COMPILED_IN;
  178. }
  179. if (ret >= 0) {
  180. *dataSz = ret;
  181. ret = 0;
  182. }
  183. return ret;
  184. }
  185. #endif /* !NO_BIO */
  186. #endif /* OPENSSL_EXTRA && !WOLFCRYPT_ONLY */
  187. #if (defined(OPENSSL_EXTRA) || defined(PERSIST_CERT_CACHE) || \
  188. (!defined(NO_CERTS) && (!defined(NO_WOLFSSL_CLIENT) || \
  189. !defined(WOLFSSL_NO_CLIENT_AUTH)))) && !defined(WOLFCRYPT_ONLY) && \
  190. !defined(NO_FILESYSTEM)
  191. /* Read all the data from a file.
  192. *
  193. * @param [in] fp File pointer to read with.
  194. * @param [out] fileSz Amount of data remaining in file in bytes.
  195. * @return WOLFSSL_BAD_FILE on error.
  196. * @return 0 on success.
  197. */
  198. static int wolfssl_file_len(XFILE fp, long* fileSz)
  199. {
  200. int ret = 0;
  201. long sz = 0;
  202. long curr = 0;
  203. if (fp == XBADFILE) {
  204. ret = WOLFSSL_BAD_FILE;
  205. }
  206. if (ret == 0) {
  207. /* Get file offset at end of file. */
  208. curr = (long)XFTELL(fp);
  209. if (curr < 0) {
  210. ret = WOLFSSL_BAD_FILE;
  211. }
  212. }
  213. /* Move to end of file. */
  214. if ((ret == 0) && (XFSEEK(fp, 0, SEEK_END) != 0)) {
  215. ret = WOLFSSL_BAD_FILE;
  216. }
  217. if (ret == 0) {
  218. /* Get file offset at end of file and subtract current offset. */
  219. sz = (long)XFTELL(fp) - curr;
  220. if (sz < 0) {
  221. ret = WOLFSSL_BAD_FILE;
  222. }
  223. }
  224. /* Go back to original offset in file. */
  225. if ((ret == 0) && (XFSEEK(fp, curr, SEEK_SET) != 0)) {
  226. ret = WOLFSSL_BAD_FILE;
  227. }
  228. /* Validate size. */
  229. if ((ret == 0) && ((sz > MAX_WOLFSSL_FILE_SIZE) || (sz <= 0L))) {
  230. ret = WOLFSSL_BAD_FILE;
  231. }
  232. if (ret == 0) {
  233. *fileSz = sz;
  234. }
  235. return ret;
  236. }
  237. #endif
  238. #if (defined(OPENSSL_EXTRA) || defined(PERSIST_CERT_CACHE)) && \
  239. !defined(WOLFCRYPT_ONLY) && !defined(NO_FILESYSTEM)
  240. /* Read all the data from a file.
  241. *
  242. * @param [in] fp File pointer to read with.
  243. * @param [out] data Read data in an allocated buffer.
  244. * @param [out] dataSz Amount of data read in bytes.
  245. * @return WOLFSSL_BAD_FILE when reading fails.
  246. * @return MEMORY_E when memory allocation fails.
  247. * @return 0 on success.
  248. */
  249. static int wolfssl_read_file(XFILE fp, char** data, int* dataSz)
  250. {
  251. int ret = 0;
  252. long sz = 0;
  253. char* mem = NULL;
  254. ret = wolfssl_file_len(fp, &sz);
  255. if (ret == 0) {
  256. /* Allocate memory big enough to hold whole file. */
  257. mem = (char*)XMALLOC((size_t)sz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  258. if (mem == NULL) {
  259. ret = MEMORY_E;
  260. }
  261. }
  262. /* Read whole file into new buffer. */
  263. if ((ret == 0) && ((int)XFREAD(mem, 1, (size_t)sz, fp) != sz)) {
  264. ret = WOLFSSL_BAD_FILE;
  265. }
  266. if (ret == 0) {
  267. *dataSz = (int)sz;
  268. *data = mem;
  269. mem = NULL;
  270. }
  271. XFREE(mem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  272. return ret;
  273. }
  274. #endif /* (OPENSSL_EXTRA || PERSIST_CERT_CACHE) && !WOLFCRYPT_ONLY &&
  275. * !NO_FILESYSTEM */
  276. #endif /* !WOLFSSL_SSL_MISC_INCLUDED */