wpackettest.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. /*
  2. * Copyright 2016-2020 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 <string.h>
  10. #include <openssl/buffer.h>
  11. #include <openssl/rand.h>
  12. #include "internal/packet.h"
  13. #include "testutil.h"
  14. static const unsigned char simple1[] = { 0xff };
  15. static const unsigned char simple2[] = { 0x01, 0xff };
  16. static const unsigned char simple3[] = { 0x00, 0x00, 0x00, 0x01, 0xff };
  17. static const unsigned char nestedsub[] = { 0x03, 0xff, 0x01, 0xff };
  18. static const unsigned char seqsub[] = { 0x01, 0xff, 0x01, 0xff };
  19. static const unsigned char empty[] = { 0x00 };
  20. static const unsigned char alloc[] = { 0x02, 0xfe, 0xff };
  21. static const unsigned char submem[] = { 0x03, 0x02, 0xfe, 0xff };
  22. static const unsigned char fixed[] = { 0xff, 0xff, 0xff };
  23. static const unsigned char simpleder[] = {
  24. 0xfc, 0x04, 0x00, 0x01, 0x02, 0x03, 0xff, 0xfe, 0xfd
  25. };
  26. static BUF_MEM *buf;
  27. static int cleanup(WPACKET *pkt)
  28. {
  29. WPACKET_cleanup(pkt);
  30. return 0;
  31. }
  32. static int test_WPACKET_init(void)
  33. {
  34. WPACKET pkt;
  35. int i;
  36. size_t written;
  37. unsigned char sbuf[3];
  38. if (!TEST_true(WPACKET_init(&pkt, buf))
  39. || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff))
  40. /* Closing a top level WPACKET should fail */
  41. || !TEST_false(WPACKET_close(&pkt))
  42. /* Finishing a top level WPACKET should succeed */
  43. || !TEST_true(WPACKET_finish(&pkt))
  44. /*
  45. * Can't call close or finish on a WPACKET that's already
  46. * finished.
  47. */
  48. || !TEST_false(WPACKET_close(&pkt))
  49. || !TEST_false(WPACKET_finish(&pkt))
  50. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  51. || !TEST_mem_eq(buf->data, written, simple1, sizeof(simple1)))
  52. return cleanup(&pkt);
  53. /* Now try with a one byte length prefix */
  54. if (!TEST_true(WPACKET_init_len(&pkt, buf, 1))
  55. || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff))
  56. || !TEST_true(WPACKET_finish(&pkt))
  57. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  58. || !TEST_mem_eq(buf->data, written, simple2, sizeof(simple2)))
  59. return cleanup(&pkt);
  60. /* And a longer length prefix */
  61. if (!TEST_true(WPACKET_init_len(&pkt, buf, 4))
  62. || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff))
  63. || !TEST_true(WPACKET_finish(&pkt))
  64. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  65. || !TEST_mem_eq(buf->data, written, simple3, sizeof(simple3)))
  66. return cleanup(&pkt);
  67. if (!TEST_true(WPACKET_init_len(&pkt, buf, 1)))
  68. return cleanup(&pkt);
  69. for (i = 1; i < 257; i++) {
  70. /*
  71. * Putting more bytes in than fit for the size of the length prefix
  72. * should fail
  73. */
  74. if (!TEST_int_eq(WPACKET_put_bytes_u8(&pkt, 0xff), i < 256))
  75. return cleanup(&pkt);
  76. }
  77. if (!TEST_true(WPACKET_finish(&pkt)))
  78. return cleanup(&pkt);
  79. /* Test initialising from a fixed size buffer */
  80. if (!TEST_true(WPACKET_init_static_len(&pkt, sbuf, sizeof(sbuf), 0))
  81. /* Adding 3 bytes should succeed */
  82. || !TEST_true(WPACKET_put_bytes_u24(&pkt, 0xffffff))
  83. /* Adding 1 more byte should fail */
  84. || !TEST_false(WPACKET_put_bytes_u8(&pkt, 0xff))
  85. /* Finishing the top level WPACKET should succeed */
  86. || !TEST_true(WPACKET_finish(&pkt))
  87. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  88. || !TEST_mem_eq(sbuf, written, fixed, sizeof(sbuf))
  89. /* Initialise with 1 len byte */
  90. || !TEST_true(WPACKET_init_static_len(&pkt, sbuf, sizeof(sbuf), 1))
  91. /* Adding 2 bytes should succeed */
  92. || !TEST_true(WPACKET_put_bytes_u16(&pkt, 0xfeff))
  93. /* Adding 1 more byte should fail */
  94. || !TEST_false(WPACKET_put_bytes_u8(&pkt, 0xff))
  95. || !TEST_true(WPACKET_finish(&pkt))
  96. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  97. || !TEST_mem_eq(sbuf, written, alloc, sizeof(alloc)))
  98. return cleanup(&pkt);
  99. return 1;
  100. }
  101. static int test_WPACKET_set_max_size(void)
  102. {
  103. WPACKET pkt;
  104. size_t written;
  105. if (!TEST_true(WPACKET_init(&pkt, buf))
  106. /*
  107. * No previous lenbytes set so we should be ok to set the max
  108. * possible max size
  109. */
  110. || !TEST_true(WPACKET_set_max_size(&pkt, SIZE_MAX))
  111. /* We should be able to set it smaller too */
  112. || !TEST_true(WPACKET_set_max_size(&pkt, SIZE_MAX -1))
  113. /* And setting it bigger again should be ok */
  114. || !TEST_true(WPACKET_set_max_size(&pkt, SIZE_MAX))
  115. || !TEST_true(WPACKET_finish(&pkt)))
  116. return cleanup(&pkt);
  117. if (!TEST_true(WPACKET_init_len(&pkt, buf, 1))
  118. /*
  119. * Should fail because we already consumed 1 byte with the
  120. * length
  121. */
  122. || !TEST_false(WPACKET_set_max_size(&pkt, 0))
  123. /*
  124. * Max size can't be bigger than biggest that will fit in
  125. * lenbytes
  126. */
  127. || !TEST_false(WPACKET_set_max_size(&pkt, 0x0101))
  128. /* It can be the same as the maximum possible size */
  129. || !TEST_true(WPACKET_set_max_size(&pkt, 0x0100))
  130. /* Or it can be less */
  131. || !TEST_true(WPACKET_set_max_size(&pkt, 0x01))
  132. /* Should fail because packet is already filled */
  133. || !TEST_false(WPACKET_put_bytes_u8(&pkt, 0xff))
  134. /* You can't put in more bytes than max size */
  135. || !TEST_true(WPACKET_set_max_size(&pkt, 0x02))
  136. || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff))
  137. || !TEST_false(WPACKET_put_bytes_u8(&pkt, 0xff))
  138. || !TEST_true(WPACKET_finish(&pkt))
  139. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  140. || !TEST_mem_eq(buf->data, written, simple2, sizeof(simple2)))
  141. return cleanup(&pkt);
  142. return 1;
  143. }
  144. static int test_WPACKET_start_sub_packet(void)
  145. {
  146. WPACKET pkt;
  147. size_t written;
  148. size_t len;
  149. if (!TEST_true(WPACKET_init(&pkt, buf))
  150. || !TEST_true(WPACKET_start_sub_packet(&pkt))
  151. || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff))
  152. /* Can't finish because we have a sub packet */
  153. || !TEST_false(WPACKET_finish(&pkt))
  154. || !TEST_true(WPACKET_close(&pkt))
  155. /* Sub packet is closed so can't close again */
  156. || !TEST_false(WPACKET_close(&pkt))
  157. /* Now a top level so finish should succeed */
  158. || !TEST_true(WPACKET_finish(&pkt))
  159. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  160. || !TEST_mem_eq(buf->data, written, simple1, sizeof(simple1)))
  161. return cleanup(&pkt);
  162. /* Single sub-packet with length prefix */
  163. if (!TEST_true(WPACKET_init(&pkt, buf))
  164. || !TEST_true(WPACKET_start_sub_packet_u8(&pkt))
  165. || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff))
  166. || !TEST_true(WPACKET_close(&pkt))
  167. || !TEST_true(WPACKET_finish(&pkt))
  168. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  169. || !TEST_mem_eq(buf->data, written, simple2, sizeof(simple2)))
  170. return cleanup(&pkt);
  171. /* Nested sub-packets with length prefixes */
  172. if (!TEST_true(WPACKET_init(&pkt, buf))
  173. || !TEST_true(WPACKET_start_sub_packet_u8(&pkt))
  174. || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff))
  175. || !TEST_true(WPACKET_start_sub_packet_u8(&pkt))
  176. || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff))
  177. || !TEST_true(WPACKET_get_length(&pkt, &len))
  178. || !TEST_size_t_eq(len, 1)
  179. || !TEST_true(WPACKET_close(&pkt))
  180. || !TEST_true(WPACKET_get_length(&pkt, &len))
  181. || !TEST_size_t_eq(len, 3)
  182. || !TEST_true(WPACKET_close(&pkt))
  183. || !TEST_true(WPACKET_finish(&pkt))
  184. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  185. || !TEST_mem_eq(buf->data, written, nestedsub, sizeof(nestedsub)))
  186. return cleanup(&pkt);
  187. /* Sequential sub-packets with length prefixes */
  188. if (!TEST_true(WPACKET_init(&pkt, buf))
  189. || !TEST_true(WPACKET_start_sub_packet_u8(&pkt))
  190. || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff))
  191. || !TEST_true(WPACKET_close(&pkt))
  192. || !TEST_true(WPACKET_start_sub_packet_u8(&pkt))
  193. || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff))
  194. || !TEST_true(WPACKET_close(&pkt))
  195. || !TEST_true(WPACKET_finish(&pkt))
  196. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  197. || !TEST_mem_eq(buf->data, written, seqsub, sizeof(seqsub)))
  198. return cleanup(&pkt);
  199. /* Nested sub-packets with lengths filled before finish */
  200. if (!TEST_true(WPACKET_init(&pkt, buf))
  201. || !TEST_true(WPACKET_start_sub_packet_u8(&pkt))
  202. || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff))
  203. || !TEST_true(WPACKET_start_sub_packet_u8(&pkt))
  204. || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff))
  205. || !TEST_true(WPACKET_get_length(&pkt, &len))
  206. || !TEST_size_t_eq(len, 1)
  207. || !TEST_true(WPACKET_close(&pkt))
  208. || !TEST_true(WPACKET_get_length(&pkt, &len))
  209. || !TEST_size_t_eq(len, 3)
  210. || !TEST_true(WPACKET_close(&pkt))
  211. || !TEST_true(WPACKET_fill_lengths(&pkt))
  212. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  213. || !TEST_mem_eq(buf->data, written, nestedsub, sizeof(nestedsub))
  214. || !TEST_true(WPACKET_finish(&pkt)))
  215. return cleanup(&pkt);
  216. return 1;
  217. }
  218. static int test_WPACKET_set_flags(void)
  219. {
  220. WPACKET pkt;
  221. size_t written;
  222. /* Set packet to be non-zero length */
  223. if (!TEST_true(WPACKET_init(&pkt, buf))
  224. || !TEST_true(WPACKET_set_flags(&pkt, WPACKET_FLAGS_NON_ZERO_LENGTH))
  225. /* Should fail because of zero length */
  226. || !TEST_false(WPACKET_finish(&pkt))
  227. || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff))
  228. || !TEST_true(WPACKET_finish(&pkt))
  229. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  230. || !TEST_mem_eq(buf->data, written, simple1, sizeof(simple1)))
  231. return cleanup(&pkt);
  232. /* Repeat above test in a sub-packet */
  233. if (!TEST_true(WPACKET_init(&pkt, buf))
  234. || !TEST_true(WPACKET_start_sub_packet(&pkt))
  235. || !TEST_true(WPACKET_set_flags(&pkt, WPACKET_FLAGS_NON_ZERO_LENGTH))
  236. /* Should fail because of zero length */
  237. || !TEST_false(WPACKET_close(&pkt))
  238. || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff))
  239. || !TEST_true(WPACKET_close(&pkt))
  240. || !TEST_true(WPACKET_finish(&pkt))
  241. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  242. || !TEST_mem_eq(buf->data, written, simple1, sizeof(simple1)))
  243. return cleanup(&pkt);
  244. /* Set packet to abandon non-zero length */
  245. if (!TEST_true(WPACKET_init_len(&pkt, buf, 1))
  246. || !TEST_true(WPACKET_set_flags(&pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH))
  247. || !TEST_true(WPACKET_finish(&pkt))
  248. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  249. || !TEST_size_t_eq(written, 0))
  250. return cleanup(&pkt);
  251. /* Repeat above test but only abandon a sub-packet */
  252. if (!TEST_true(WPACKET_init_len(&pkt, buf, 1))
  253. || !TEST_true(WPACKET_start_sub_packet_u8(&pkt))
  254. || !TEST_true(WPACKET_set_flags(&pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH))
  255. || !TEST_true(WPACKET_close(&pkt))
  256. || !TEST_true(WPACKET_finish(&pkt))
  257. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  258. || !TEST_mem_eq(buf->data, written, empty, sizeof(empty)))
  259. return cleanup(&pkt);
  260. /* And repeat with a non empty sub-packet */
  261. if (!TEST_true(WPACKET_init(&pkt, buf))
  262. || !TEST_true(WPACKET_start_sub_packet_u8(&pkt))
  263. || !TEST_true(WPACKET_set_flags(&pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH))
  264. || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xff))
  265. || !TEST_true(WPACKET_close(&pkt))
  266. || !TEST_true(WPACKET_finish(&pkt))
  267. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  268. || !TEST_mem_eq(buf->data, written, simple2, sizeof(simple2)))
  269. return cleanup(&pkt);
  270. return 1;
  271. }
  272. static int test_WPACKET_allocate_bytes(void)
  273. {
  274. WPACKET pkt;
  275. size_t written;
  276. unsigned char *bytes;
  277. if (!TEST_true(WPACKET_init_len(&pkt, buf, 1))
  278. || !TEST_true(WPACKET_allocate_bytes(&pkt, 2, &bytes)))
  279. return cleanup(&pkt);
  280. bytes[0] = 0xfe;
  281. bytes[1] = 0xff;
  282. if (!TEST_true(WPACKET_finish(&pkt))
  283. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  284. || !TEST_mem_eq(buf->data, written, alloc, sizeof(alloc)))
  285. return cleanup(&pkt);
  286. /* Repeat with WPACKET_sub_allocate_bytes */
  287. if (!TEST_true(WPACKET_init_len(&pkt, buf, 1))
  288. || !TEST_true(WPACKET_sub_allocate_bytes_u8(&pkt, 2, &bytes)))
  289. return cleanup(&pkt);
  290. bytes[0] = 0xfe;
  291. bytes[1] = 0xff;
  292. if (!TEST_true(WPACKET_finish(&pkt))
  293. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  294. || !TEST_mem_eq(buf->data, written, submem, sizeof(submem)))
  295. return cleanup(&pkt);
  296. return 1;
  297. }
  298. static int test_WPACKET_memcpy(void)
  299. {
  300. WPACKET pkt;
  301. size_t written;
  302. const unsigned char bytes[] = { 0xfe, 0xff };
  303. if (!TEST_true(WPACKET_init_len(&pkt, buf, 1))
  304. || !TEST_true(WPACKET_memcpy(&pkt, bytes, sizeof(bytes)))
  305. || !TEST_true(WPACKET_finish(&pkt))
  306. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  307. || !TEST_mem_eq(buf->data, written, alloc, sizeof(alloc)))
  308. return cleanup(&pkt);
  309. /* Repeat with WPACKET_sub_memcpy() */
  310. if (!TEST_true(WPACKET_init_len(&pkt, buf, 1))
  311. || !TEST_true(WPACKET_sub_memcpy_u8(&pkt, bytes, sizeof(bytes)))
  312. || !TEST_true(WPACKET_finish(&pkt))
  313. || !TEST_true(WPACKET_get_total_written(&pkt, &written))
  314. || !TEST_mem_eq(buf->data, written, submem, sizeof(submem)))
  315. return cleanup(&pkt);
  316. return 1;
  317. }
  318. static int test_WPACKET_init_der(void)
  319. {
  320. WPACKET pkt;
  321. unsigned char sbuf[1024];
  322. unsigned char testdata[] = { 0x00, 0x01, 0x02, 0x03 };
  323. unsigned char testdata2[259] = { 0x82, 0x01, 0x00 };
  324. size_t written[2];
  325. size_t size1, size2;
  326. int flags = WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH;
  327. int i;
  328. /* Test initialising for writing DER */
  329. if (!TEST_true(WPACKET_init_der(&pkt, sbuf, sizeof(sbuf)))
  330. || !TEST_true(WPACKET_put_bytes_u24(&pkt, 0xfffefd))
  331. /* Test writing data in a length prefixed sub-packet */
  332. || !TEST_true(WPACKET_start_sub_packet(&pkt))
  333. || !TEST_true(WPACKET_memcpy(&pkt, testdata, sizeof(testdata)))
  334. || !TEST_true(WPACKET_close(&pkt))
  335. || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xfc))
  336. /* this sub-packet is empty, and should render zero bytes */
  337. || (!TEST_true(WPACKET_start_sub_packet(&pkt))
  338. || !TEST_true(WPACKET_set_flags(&pkt, flags))
  339. || !TEST_true(WPACKET_get_total_written(&pkt, &size1))
  340. || !TEST_true(WPACKET_close(&pkt))
  341. || !TEST_true(WPACKET_get_total_written(&pkt, &size2))
  342. || !TEST_size_t_eq(size1, size2))
  343. || !TEST_true(WPACKET_finish(&pkt))
  344. || !TEST_true(WPACKET_get_total_written(&pkt, &written[0]))
  345. || !TEST_mem_eq(WPACKET_get_curr(&pkt), written[0], simpleder,
  346. sizeof(simpleder)))
  347. return cleanup(&pkt);
  348. /* Generate random packet data for test */
  349. if (!TEST_true(RAND_bytes(&testdata2[3], sizeof(testdata2) - 3)))
  350. return 0;
  351. /*
  352. * Test with a sub-packet that has 2 length bytes. We do 2 passes - first
  353. * with a NULL buffer, just to calculate lengths, and a second pass with a
  354. * real buffer to actually generate a packet
  355. */
  356. for (i = 0; i < 2; i++) {
  357. if (i == 0) {
  358. if (!TEST_true(WPACKET_init_null_der(&pkt)))
  359. return 0;
  360. } else {
  361. if (!TEST_true(WPACKET_init_der(&pkt, sbuf, sizeof(sbuf))))
  362. return 0;
  363. }
  364. if (!TEST_true(WPACKET_start_sub_packet(&pkt))
  365. || !TEST_true(WPACKET_memcpy(&pkt, &testdata2[3],
  366. sizeof(testdata2) - 3))
  367. || !TEST_true(WPACKET_close(&pkt))
  368. || !TEST_true(WPACKET_finish(&pkt))
  369. || !TEST_true(WPACKET_get_total_written(&pkt, &written[i])))
  370. return cleanup(&pkt);
  371. }
  372. /*
  373. * Check that the size calculated in the first pass equals the size of the
  374. * packet actually generated in the second pass. Also check the generated
  375. * packet looks as we expect it to.
  376. */
  377. if (!TEST_size_t_eq(written[0], written[1])
  378. || !TEST_mem_eq(WPACKET_get_curr(&pkt), written[1], testdata2,
  379. sizeof(testdata2)))
  380. return 0;
  381. return 1;
  382. }
  383. int setup_tests(void)
  384. {
  385. if (!TEST_ptr(buf = BUF_MEM_new()))
  386. return 0;
  387. ADD_TEST(test_WPACKET_init);
  388. ADD_TEST(test_WPACKET_set_max_size);
  389. ADD_TEST(test_WPACKET_start_sub_packet);
  390. ADD_TEST(test_WPACKET_set_flags);
  391. ADD_TEST(test_WPACKET_allocate_bytes);
  392. ADD_TEST(test_WPACKET_memcpy);
  393. ADD_TEST(test_WPACKET_init_der);
  394. return 1;
  395. }
  396. void cleanup_tests(void)
  397. {
  398. BUF_MEM_free(buf);
  399. }