ssl_misc.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  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. #include <wolfssl/wolfcrypt/types.h>
  26. #include <wolfssl/wolfcrypt/error-crypt.h>
  27. #if !defined(WOLFSSL_SSL_MISC_INCLUDED)
  28. #ifndef WOLFSSL_IGNORE_FILE_WARN
  29. #warning ssl_misc.c does not need to be compiled separately from ssl.c
  30. #endif
  31. #else
  32. #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
  33. #ifndef NO_BIO
  34. #ifdef WOLFSSL_NO_FSEEK
  35. /* Amount of memory to allocate/add. */
  36. #define READ_BIO_FILE_CHUNK 128
  37. /* Read a file in chunks.
  38. *
  39. * Allocates a chunk and reads into it until it is full.
  40. *
  41. * @param [in, out] bio BIO object to read with.
  42. * @param [out] data Read data in a new buffer.
  43. * @return Negative on error.
  44. * @return Number of bytes read on success.
  45. */
  46. static int wolfssl_read_bio_file(WOLFSSL_BIO* bio, char** data)
  47. {
  48. int ret = 0;
  49. char* mem;
  50. char* p;
  51. /* Allocate buffer to hold a chunk of data. */
  52. mem = (char*)XMALLOC(READ_BIO_FILE_CHUNK, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  53. if (mem == NULL) {
  54. WOLFSSL_ERROR_MSG("Memory allocation error");
  55. ret = MEMORY_E;
  56. }
  57. if (ret == 0) {
  58. int sz;
  59. /* ret is the number of bytes read and is zero. */
  60. /* p is where to read in next chunk. */
  61. p = mem;
  62. /* Memory available to read into is one chunk. */
  63. sz = READ_BIO_FILE_CHUNK;
  64. /* Keep reading in chunks until no more or an error. */
  65. while ((sz = wolfSSL_BIO_read(bio, p, sz)) > 0) {
  66. int remaining;
  67. /* Update total read. */
  68. ret += sz;
  69. /* Calculate remaining unused memory. */
  70. remaining = READ_BIO_FILE_CHUNK - (ret % READ_BIO_FILE_CHUNK);
  71. /* Check for space remaining. */
  72. if (remaining != READ_BIO_FILE_CHUNK) {
  73. /* Update where data is read into. */
  74. p += sz;
  75. /* Maximum possible size is the remaining buffer size. */
  76. sz = remaining;
  77. }
  78. else {
  79. /* No space left for more data to be read - add a chunk. */
  80. p = (char*)XREALLOC(mem, ret + READ_BIO_FILE_CHUNK, NULL,
  81. DYNAMIC_TYPE_TMP_BUFFER);
  82. if (p == NULL) {
  83. sz = MEMORY_E;
  84. break;
  85. }
  86. /* Set mem to new pointer. */
  87. mem = p;
  88. /* Set p to where to read in next chunk. */
  89. p += ret;
  90. /* Read in a new chunk. */
  91. sz = READ_BIO_FILE_CHUNK;
  92. }
  93. }
  94. if ((sz < 0) || (ret == 0)) {
  95. /* Dispose of memory on error or no data read. */
  96. XFREE(mem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  97. mem = NULL;
  98. /* Return error. */
  99. ret = sz;
  100. }
  101. }
  102. *data = mem;
  103. return ret;
  104. }
  105. #endif
  106. /* Read exactly the required amount into a newly allocated buffer.
  107. *
  108. * @param [in, out] bio BIO object to read with.
  109. * @param [in sz Amount of data to read.
  110. * @param [out] data Read data in a new buffer.
  111. * @return Negative on error.
  112. * @return Number of bytes read on success.
  113. */
  114. static int wolfssl_read_bio_len(WOLFSSL_BIO* bio, int sz, char** data)
  115. {
  116. int ret = 0;
  117. char* mem;
  118. /* Allocate buffer to hold data. */
  119. mem = (char*)XMALLOC((size_t)sz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  120. if (mem == NULL) {
  121. WOLFSSL_ERROR_MSG("Memory allocation error");
  122. ret = MEMORY_E;
  123. }
  124. else if ((ret = wolfSSL_BIO_read(bio, mem, sz)) != sz) {
  125. /* Pending data not read. */
  126. XFREE(mem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  127. mem = NULL;
  128. ret = MEMORY_E;
  129. }
  130. *data = mem;
  131. return ret;
  132. }
  133. /* Read all the data from a BIO.
  134. *
  135. * @param [in, out] bio BIO object to read with.
  136. * @param [out] data Read data in a buffer.
  137. * @param [out] dataSz Amount of data read in bytes.
  138. * @param [out] memAlloced Indicates whether return buffer was allocated.
  139. * @return Negative on error.
  140. * @return 0 on success.
  141. */
  142. static int wolfssl_read_bio(WOLFSSL_BIO* bio, char** data, int* dataSz,
  143. int* memAlloced)
  144. {
  145. int ret;
  146. int sz;
  147. if (bio->type == WOLFSSL_BIO_MEMORY) {
  148. ret = wolfSSL_BIO_get_mem_data(bio, data);
  149. if (ret > 0) {
  150. bio->rdIdx += ret;
  151. }
  152. *memAlloced = 0;
  153. }
  154. #ifndef WOLFSSL_NO_FSEEK
  155. /* Get pending or, when a file BIO, get length of file. */
  156. else if ((sz = wolfSSL_BIO_get_len(bio)) > 0) {
  157. ret = wolfssl_read_bio_len(bio, sz, data);
  158. if (ret > 0) {
  159. *memAlloced = 1;
  160. }
  161. }
  162. #else
  163. else if ((sz = wolfSSL_BIO_pending(bio)) > 0) {
  164. ret = wolfssl_read_bio_len(bio, sz, data);
  165. if (ret > 0) {
  166. *memAlloced = 1;
  167. }
  168. }
  169. else if (bio->type == WOLFSSL_BIO_FILE) {
  170. ret = wolfssl_read_bio_file(bio, data);
  171. if (ret > 0) {
  172. *memAlloced = 1;
  173. }
  174. }
  175. #endif
  176. else {
  177. WOLFSSL_ERROR_MSG("No data read from bio");
  178. *memAlloced = 0;
  179. ret = NOT_COMPILED_IN;
  180. }
  181. if (ret >= 0) {
  182. *dataSz = ret;
  183. ret = 0;
  184. }
  185. return ret;
  186. }
  187. #endif /* !NO_BIO */
  188. #endif /* OPENSSL_EXTRA && !WOLFCRYPT_ONLY */
  189. #if (defined(OPENSSL_EXTRA) || defined(PERSIST_CERT_CACHE) || \
  190. !defined(NO_CERTS)) && !defined(WOLFCRYPT_ONLY) && !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. #if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS)
  277. #ifdef WOLFSSL_SMALL_STACK
  278. /* Buffer and size with no stack buffer. */
  279. typedef struct {
  280. /* Dynamically allocated buffer. */
  281. byte* buffer;
  282. /* Size of buffer in bytes. */
  283. word32 sz;
  284. } StaticBuffer;
  285. /* Initialize static buffer.
  286. *
  287. * @param [in, out] sb Static buffer.
  288. */
  289. static void static_buffer_init(StaticBuffer* sb)
  290. {
  291. sb->buffer = NULL;
  292. sb->sz = 0;
  293. }
  294. /* Set the size of the buffer.
  295. *
  296. * Can only set size once.
  297. *
  298. * @param [in] sb Static buffer.
  299. * @param [in] len Length required.
  300. * @param [in] heap Dynamic memory allocation hint.
  301. * @param [in] type Type of dynamic memory.
  302. * @return 0 on success.
  303. * @return MEMORY_E when dynamic memory allocation fails.
  304. */
  305. static int static_buffer_set_size(StaticBuffer* sb, word32 len, void* heap,
  306. int type)
  307. {
  308. int ret = 0;
  309. (void)heap;
  310. (void)type;
  311. sb->buffer = (byte*)XMALLOC(len, heap, type);
  312. if (sb->buffer == NULL) {
  313. ret = MEMORY_E;
  314. }
  315. else {
  316. sb->sz = len;
  317. }
  318. return ret;
  319. }
  320. /* Dispose of dynamically allocated buffer.
  321. *
  322. * @param [in] sb Static buffer.
  323. * @param [in] heap Dynamic memory allocation hint.
  324. * @param [in] type Type of dynamic memory.
  325. */
  326. static void static_buffer_free(StaticBuffer* sb, void* heap, int type)
  327. {
  328. (void)heap;
  329. (void)type;
  330. XFREE(sb->buffer, heap, type);
  331. }
  332. #else
  333. /* Buffer and size with stack buffer set and option to dynamically allocate. */
  334. typedef struct {
  335. /* Stack or heap buffer. */
  336. byte* buffer;
  337. /* Size of buffer in bytes. */
  338. word32 sz;
  339. /* Indicates whether the buffer was dynamically allocated. */
  340. int dyn;
  341. } StaticBuffer;
  342. /* Initialize static buffer.
  343. *
  344. * @param [in, out] sb Static buffer.
  345. * @param [in] stackBuffer Buffer allocated on the stack.
  346. * @param [in] len Length of stack buffer.
  347. */
  348. static void static_buffer_init(StaticBuffer* sb, byte* stackBuffer, word32 len)
  349. {
  350. sb->buffer = stackBuffer;
  351. sb->sz = len;
  352. sb->dyn = 0;
  353. }
  354. /* Set the size of the buffer.
  355. *
  356. * Pre: Buffer on the stack set with its size.
  357. * Can only set size once.
  358. *
  359. * @param [in] sb Static buffer.
  360. * @param [in] len Length required.
  361. * @param [in] heap Dynamic memory allocation hint.
  362. * @param [in] type Type of dynamic memory.
  363. * @return 0 on success.
  364. * @return MEMORY_E when dynamic memory allocation fails.
  365. */
  366. static int static_buffer_set_size(StaticBuffer* sb, word32 len, void* heap,
  367. int type)
  368. {
  369. int ret = 0;
  370. (void)heap;
  371. (void)type;
  372. if (len > sb->sz) {
  373. byte* buff = (byte*)XMALLOC(len, heap, type);
  374. if (buff == NULL) {
  375. ret = MEMORY_E;
  376. }
  377. else {
  378. sb->buffer = buff;
  379. sb->sz = len;
  380. sb->dyn = 1;
  381. }
  382. }
  383. return ret;
  384. }
  385. /* Dispose of dynamically allocated buffer.
  386. *
  387. * @param [in] sb Static buffer.
  388. * @param [in] heap Dynamic memory allocation hint.
  389. * @param [in] type Type of dynamic memory.
  390. */
  391. static void static_buffer_free(StaticBuffer* sb, void* heap, int type)
  392. {
  393. (void)heap;
  394. (void)type;
  395. if (sb->dyn) {
  396. XFREE(sb->buffer, heap, type);
  397. }
  398. }
  399. #endif /* WOLFSSL_SMALL_STACK */
  400. #ifndef NO_FILESYSTEM
  401. /* Read all the data from a file into content.
  402. *
  403. * @param [in] fname File pointer to read with.
  404. * @param [in, out] content Read data in an allocated buffer.
  405. * @param [in] heap Dynamic memory allocation hint.
  406. * @param [in] type Type of dynamic memory.
  407. * @param [out] size Amount of data read in bytes.
  408. * @return 0 on success.
  409. * @return WOLFSSL_BAD_FILE when reading fails.
  410. * @return MEMORY_E when memory allocation fails.
  411. */
  412. static int wolfssl_read_file_static(const char* fname, StaticBuffer* content,
  413. void* heap, int type, long* size)
  414. {
  415. int ret = 0;
  416. XFILE file = XBADFILE;
  417. long sz = 0;
  418. /* Check filename is usable. */
  419. if (fname == NULL) {
  420. ret = WOLFSSL_BAD_FILE;
  421. }
  422. /* Open file for reading. */
  423. if ((ret == 0) && ((file = XFOPEN(fname, "rb")) == XBADFILE)) {
  424. ret = WOLFSSL_BAD_FILE;
  425. }
  426. if (ret == 0) {
  427. /* Get length of file. */
  428. ret = wolfssl_file_len(file, &sz);
  429. }
  430. if (ret == 0) {
  431. /* Set the buffer to be big enough to hold all data. */
  432. ret = static_buffer_set_size(content, (word32)sz, heap, type);
  433. }
  434. /* Read data from file. */
  435. if ((ret == 0) && ((size_t)XFREAD(content->buffer, 1, sz, file) !=
  436. (size_t)sz)) {
  437. ret = WOLFSSL_BAD_FILE;
  438. }
  439. /* Close file if opened. */
  440. if (file != XBADFILE) {
  441. XFCLOSE(file);
  442. }
  443. /* Return size read. */
  444. *size = sz;
  445. return ret;
  446. }
  447. #endif /* !NO_FILESYSTEM */
  448. #endif /* !WOLFCRYPT_ONLY && !NO_CERTS */
  449. #endif /* !WOLFSSL_SSL_MISC_INCLUDED */