You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

458 regels
13 KiB

  1. /* Copyright (c) 2014, Google Inc.
  2. *
  3. * Permission to use, copy, modify, and/or distribute this software for any
  4. * purpose with or without fee is hereby granted, provided that the above
  5. * copyright notice and this permission notice appear in all copies.
  6. *
  7. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  10. * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  12. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  13. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <openssl/crypto.h>
  17. #include <openssl/bytestring.h>
  18. #include "internal.h"
  19. static int test_skip(void) {
  20. static const uint8_t kData[] = {1, 2, 3};
  21. CBS data;
  22. CBS_init(&data, kData, sizeof(kData));
  23. return CBS_len(&data) == 3 &&
  24. CBS_skip(&data, 1) &&
  25. CBS_len(&data) == 2 &&
  26. CBS_skip(&data, 2) &&
  27. CBS_len(&data) == 0 &&
  28. !CBS_skip(&data, 1);
  29. }
  30. static int test_get_u(void) {
  31. static const uint8_t kData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  32. uint8_t u8;
  33. uint16_t u16;
  34. uint32_t u32;
  35. CBS data;
  36. CBS_init(&data, kData, sizeof(kData));
  37. return CBS_get_u8(&data, &u8) &&
  38. u8 == 1 &&
  39. CBS_get_u16(&data, &u16) &&
  40. u16 == 0x203 &&
  41. CBS_get_u24(&data, &u32) &&
  42. u32 == 0x40506 &&
  43. CBS_get_u32(&data, &u32) &&
  44. u32 == 0x708090a &&
  45. !CBS_get_u8(&data, &u8);
  46. }
  47. static int test_get_prefixed(void) {
  48. static const uint8_t kData[] = {1, 2, 0, 2, 3, 4, 0, 0, 3, 3, 2, 1};
  49. uint8_t u8;
  50. uint16_t u16;
  51. uint32_t u32;
  52. CBS data, prefixed;
  53. CBS_init(&data, kData, sizeof(kData));
  54. return CBS_get_u8_length_prefixed(&data, &prefixed) &&
  55. CBS_len(&prefixed) == 1 &&
  56. CBS_get_u8(&prefixed, &u8) &&
  57. u8 == 2 &&
  58. CBS_get_u16_length_prefixed(&data, &prefixed) &&
  59. CBS_len(&prefixed) == 2 &&
  60. CBS_get_u16(&prefixed, &u16) &&
  61. u16 == 0x304 &&
  62. CBS_get_u24_length_prefixed(&data, &prefixed) &&
  63. CBS_len(&prefixed) == 3 &&
  64. CBS_get_u24(&prefixed, &u32) &&
  65. u32 == 0x30201;
  66. }
  67. static int test_get_prefixed_bad(void) {
  68. static const uint8_t kData1[] = {2, 1};
  69. static const uint8_t kData2[] = {0, 2, 1};
  70. static const uint8_t kData3[] = {0, 0, 2, 1};
  71. CBS data, prefixed;
  72. CBS_init(&data, kData1, sizeof(kData1));
  73. if (CBS_get_u8_length_prefixed(&data, &prefixed)) {
  74. return 0;
  75. }
  76. CBS_init(&data, kData2, sizeof(kData2));
  77. if (CBS_get_u16_length_prefixed(&data, &prefixed)) {
  78. return 0;
  79. }
  80. CBS_init(&data, kData3, sizeof(kData3));
  81. if (CBS_get_u24_length_prefixed(&data, &prefixed)) {
  82. return 0;
  83. }
  84. return 1;
  85. }
  86. static int test_get_asn1(void) {
  87. static const uint8_t kData1[] = {0x30, 2, 1, 2};
  88. static const uint8_t kData2[] = {0x30, 3, 1, 2};
  89. static const uint8_t kData3[] = {0x30, 0x80};
  90. static const uint8_t kData4[] = {0x30, 0x81, 1, 1};
  91. static const uint8_t kData5[] = {0x30, 0x82, 0, 1, 1};
  92. CBS data, contents;
  93. CBS_init(&data, kData1, sizeof(kData1));
  94. if (!CBS_get_asn1(&data, &contents, 0x30) ||
  95. CBS_len(&contents) != 2 ||
  96. memcmp(CBS_data(&contents), "\x01\x02", 2) != 0) {
  97. return 0;
  98. }
  99. CBS_init(&data, kData2, sizeof(kData2));
  100. /* data is truncated */
  101. if (CBS_get_asn1(&data, &contents, 0x30)) {
  102. return 0;
  103. }
  104. CBS_init(&data, kData3, sizeof(kData3));
  105. /* zero byte length of length */
  106. if (CBS_get_asn1(&data, &contents, 0x30)) {
  107. return 0;
  108. }
  109. CBS_init(&data, kData4, sizeof(kData4));
  110. /* long form mistakenly used. */
  111. if (CBS_get_asn1(&data, &contents, 0x30)) {
  112. return 0;
  113. }
  114. CBS_init(&data, kData5, sizeof(kData5));
  115. /* length takes too many bytes. */
  116. if (CBS_get_asn1(&data, &contents, 0x30)) {
  117. return 0;
  118. }
  119. CBS_init(&data, kData1, sizeof(kData1));
  120. /* wrong tag. */
  121. if (CBS_get_asn1(&data, &contents, 0x31)) {
  122. return 0;
  123. }
  124. return 1;
  125. }
  126. static int test_cbb_basic(void) {
  127. static const uint8_t kExpected[] = {1, 2, 3, 4, 5, 6, 7, 8};
  128. uint8_t *buf;
  129. size_t buf_len;
  130. int ok;
  131. CBB cbb;
  132. if (!CBB_init(&cbb, 100)) {
  133. return 0;
  134. }
  135. CBB_cleanup(&cbb);
  136. if (!CBB_init(&cbb, 0) ||
  137. !CBB_add_u8(&cbb, 1) ||
  138. !CBB_add_u16(&cbb, 0x203) ||
  139. !CBB_add_u24(&cbb, 0x40506) ||
  140. !CBB_add_bytes(&cbb, (const uint8_t*) "\x07\x08", 2) ||
  141. !CBB_finish(&cbb, &buf, &buf_len)) {
  142. return 0;
  143. }
  144. ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
  145. free(buf);
  146. return ok;
  147. }
  148. static int test_cbb_fixed(void) {
  149. CBB cbb;
  150. uint8_t buf[1];
  151. uint8_t *out_buf;
  152. size_t out_size;
  153. if (!CBB_init_fixed(&cbb, NULL, 0) ||
  154. CBB_add_u8(&cbb, 1) ||
  155. !CBB_finish(&cbb, &out_buf, &out_size) ||
  156. out_buf != NULL ||
  157. out_size != 0) {
  158. return 0;
  159. }
  160. if (!CBB_init_fixed(&cbb, buf, 1) ||
  161. !CBB_add_u8(&cbb, 1) ||
  162. CBB_add_u8(&cbb, 2) ||
  163. !CBB_finish(&cbb, &out_buf, &out_size) ||
  164. out_buf != buf ||
  165. out_size != 1 ||
  166. buf[0] != 1) {
  167. return 0;
  168. }
  169. return 1;
  170. }
  171. static int test_cbb_finish_child(void) {
  172. CBB cbb, child;
  173. uint8_t *out_buf;
  174. size_t out_size;
  175. if (!CBB_init(&cbb, 16) ||
  176. !CBB_add_u8_length_prefixed(&cbb, &child) ||
  177. CBB_finish(&child, &out_buf, &out_size) ||
  178. !CBB_finish(&cbb, &out_buf, &out_size) ||
  179. out_size != 1 ||
  180. out_buf[0] != 0) {
  181. return 0;
  182. }
  183. free(out_buf);
  184. return 1;
  185. }
  186. static int test_cbb_prefixed(void) {
  187. static const uint8_t kExpected[] = {0, 1, 1, 0, 2, 2, 3, 0, 0, 3,
  188. 4, 5, 6, 5, 4, 1, 0, 1, 2};
  189. uint8_t *buf;
  190. size_t buf_len;
  191. CBB cbb, contents, inner_contents, inner_inner_contents;
  192. int ok;
  193. if (!CBB_init(&cbb, 0) ||
  194. !CBB_add_u8_length_prefixed(&cbb, &contents) ||
  195. !CBB_add_u8_length_prefixed(&cbb, &contents) ||
  196. !CBB_add_u8(&contents, 1) ||
  197. !CBB_add_u16_length_prefixed(&cbb, &contents) ||
  198. !CBB_add_u16(&contents, 0x203) ||
  199. !CBB_add_u24_length_prefixed(&cbb, &contents) ||
  200. !CBB_add_u24(&contents, 0x40506) ||
  201. !CBB_add_u8_length_prefixed(&cbb, &contents) ||
  202. !CBB_add_u8_length_prefixed(&contents, &inner_contents) ||
  203. !CBB_add_u8(&inner_contents, 1) ||
  204. !CBB_add_u16_length_prefixed(&inner_contents, &inner_inner_contents) ||
  205. !CBB_add_u8(&inner_inner_contents, 2) ||
  206. !CBB_finish(&cbb, &buf, &buf_len)) {
  207. return 0;
  208. }
  209. ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
  210. free(buf);
  211. return ok;
  212. }
  213. static int test_cbb_misuse(void) {
  214. CBB cbb, child, contents;
  215. uint8_t *buf;
  216. size_t buf_len;
  217. if (!CBB_init(&cbb, 0) ||
  218. !CBB_add_u8_length_prefixed(&cbb, &child) ||
  219. !CBB_add_u8(&child, 1) ||
  220. !CBB_add_u8(&cbb, 2)) {
  221. return 0;
  222. }
  223. /* Since we wrote to |cbb|, |child| is now invalid and attempts to write to
  224. * it should fail. */
  225. if (CBB_add_u8(&child, 1) ||
  226. CBB_add_u16(&child, 1) ||
  227. CBB_add_u24(&child, 1) ||
  228. CBB_add_u8_length_prefixed(&child, &contents) ||
  229. CBB_add_u16_length_prefixed(&child, &contents) ||
  230. CBB_add_asn1(&child, &contents, 1) ||
  231. CBB_add_bytes(&child, (const uint8_t*) "a", 1)) {
  232. fprintf(stderr, "CBB operation on invalid CBB did not fail.\n");
  233. return 0;
  234. }
  235. if (!CBB_finish(&cbb, &buf, &buf_len) ||
  236. buf_len != 3 ||
  237. memcmp(buf, "\x01\x01\x02", 3) != 0) {
  238. return 0;
  239. }
  240. free(buf);
  241. return 1;
  242. }
  243. static int test_cbb_asn1(void) {
  244. static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3};
  245. uint8_t *buf, *test_data;
  246. size_t buf_len;
  247. CBB cbb, contents, inner_contents;
  248. if (!CBB_init(&cbb, 0) ||
  249. !CBB_add_asn1(&cbb, &contents, 0x30) ||
  250. !CBB_add_bytes(&contents, (const uint8_t*) "\x01\x02\x03", 3) ||
  251. !CBB_finish(&cbb, &buf, &buf_len)) {
  252. return 0;
  253. }
  254. if (buf_len != sizeof(kExpected) || memcmp(buf, kExpected, buf_len) != 0) {
  255. return 0;
  256. }
  257. free(buf);
  258. test_data = malloc(100000);
  259. memset(test_data, 0x42, 100000);
  260. if (!CBB_init(&cbb, 0) ||
  261. !CBB_add_asn1(&cbb, &contents, 0x30) ||
  262. !CBB_add_bytes(&contents, test_data, 130) ||
  263. !CBB_finish(&cbb, &buf, &buf_len)) {
  264. return 0;
  265. }
  266. if (buf_len != 3 + 130 ||
  267. memcmp(buf, "\x30\x81\x82", 3) != 0 ||
  268. memcmp(buf + 3, test_data, 130) != 0) {
  269. return 0;
  270. }
  271. free(buf);
  272. if (!CBB_init(&cbb, 0) ||
  273. !CBB_add_asn1(&cbb, &contents, 0x30) ||
  274. !CBB_add_bytes(&contents, test_data, 1000) ||
  275. !CBB_finish(&cbb, &buf, &buf_len)) {
  276. return 0;
  277. }
  278. if (buf_len != 4 + 1000 ||
  279. memcmp(buf, "\x30\x82\x03\xe8", 4) != 0 ||
  280. memcmp(buf + 4, test_data, 1000)) {
  281. return 0;
  282. }
  283. free(buf);
  284. if (!CBB_init(&cbb, 0) ||
  285. !CBB_add_asn1(&cbb, &contents, 0x30) ||
  286. !CBB_add_asn1(&contents, &inner_contents, 0x30) ||
  287. !CBB_add_bytes(&inner_contents, test_data, 100000) ||
  288. !CBB_finish(&cbb, &buf, &buf_len)) {
  289. return 0;
  290. }
  291. if (buf_len != 5 + 5 + 100000 ||
  292. memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) != 0 ||
  293. memcmp(buf + 10, test_data, 100000)) {
  294. return 0;
  295. }
  296. free(buf);
  297. free(test_data);
  298. return 1;
  299. }
  300. static int do_ber_convert(const char *name,
  301. const uint8_t *der_expected, size_t der_len,
  302. const uint8_t *ber, size_t ber_len) {
  303. CBS in;
  304. uint8_t *out;
  305. size_t out_len;
  306. CBS_init(&in, ber, ber_len);
  307. if (!CBS_asn1_ber_to_der(&in, &out, &out_len)) {
  308. fprintf(stderr, "%s: CBS_asn1_ber_to_der failed.\n", name);
  309. return 0;
  310. }
  311. if (out == NULL) {
  312. if (ber_len != der_len ||
  313. memcmp(der_expected, ber, ber_len) != 0) {
  314. fprintf(stderr, "%s: incorrect unconverted result.\n", name);
  315. return 0;
  316. }
  317. return 1;
  318. }
  319. if (out_len != der_len ||
  320. memcmp(out, der_expected, der_len) != 0) {
  321. fprintf(stderr, "%s: incorrect converted result.\n", name);
  322. return 0;
  323. }
  324. free(out);
  325. return 1;
  326. }
  327. static int test_ber_convert(void) {
  328. static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00};
  329. /* kIndefBER contains a SEQUENCE with an indefinite length. */
  330. static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00, 0x00};
  331. static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02};
  332. /* kOctetStringBER contains an indefinite length OCTETSTRING with two parts.
  333. * These parts need to be concatenated in DER form. */
  334. static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0, 1,
  335. 0x04, 0x02, 2, 3, 0x00, 0x00};
  336. static const uint8_t kOctetStringDER[] = {0x04, 0x04, 0, 1, 2, 3};
  337. /* kNSSBER is part of a PKCS#12 message generated by NSS that uses indefinite
  338. * length elements extensively. */
  339. static const uint8_t kNSSBER[] = {
  340. 0x30, 0x80, 0x02, 0x01, 0x03, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48,
  341. 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, 0x04, 0x04,
  342. 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39,
  343. 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
  344. 0x00, 0x04, 0x14, 0x84, 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90,
  345. 0xc1, 0xb6, 0xe8, 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04,
  346. 0x10, 0x38, 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b,
  347. 0xf0, 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0, 0x00, 0x00,
  348. };
  349. static const uint8_t kNSSDER[] = {
  350. 0x30, 0x53, 0x02, 0x01, 0x03, 0x30, 0x13, 0x06, 0x09, 0x2a, 0x86,
  351. 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x06, 0x04, 0x04,
  352. 0x01, 0x02, 0x03, 0x04, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06,
  353. 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84,
  354. 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8,
  355. 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38,
  356. 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0,
  357. 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0,
  358. };
  359. return do_ber_convert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER),
  360. kSimpleBER, sizeof(kSimpleBER)) &&
  361. do_ber_convert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER,
  362. sizeof(kIndefBER)) &&
  363. do_ber_convert("kOctetStringBER", kOctetStringDER,
  364. sizeof(kOctetStringDER), kOctetStringBER,
  365. sizeof(kOctetStringBER)) &&
  366. do_ber_convert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER,
  367. sizeof(kNSSBER));
  368. }
  369. int main(void) {
  370. CRYPTO_library_init();
  371. if (!test_skip() ||
  372. !test_get_u() ||
  373. !test_get_prefixed() ||
  374. !test_get_prefixed_bad() ||
  375. !test_get_asn1() ||
  376. !test_cbb_basic() ||
  377. !test_cbb_fixed() ||
  378. !test_cbb_finish_child() ||
  379. !test_cbb_misuse() ||
  380. !test_cbb_prefixed() ||
  381. !test_cbb_asn1() ||
  382. !test_ber_convert()) {
  383. return 1;
  384. }
  385. printf("PASS\n");
  386. return 0;
  387. }