asn1parse.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. /*
  2. * Generic ASN.1 parsing
  3. *
  4. * Copyright The Mbed TLS Contributors
  5. * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
  6. */
  7. #include "common.h"
  8. #if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \
  9. defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
  10. #include "mbedtls/asn1.h"
  11. #include "mbedtls/platform_util.h"
  12. #include "mbedtls/error.h"
  13. #include <string.h>
  14. #if defined(MBEDTLS_BIGNUM_C)
  15. #include "mbedtls/bignum.h"
  16. #endif
  17. #include "mbedtls/platform.h"
  18. /*
  19. * ASN.1 DER decoding routines
  20. */
  21. int mbedtls_asn1_get_len(unsigned char **p,
  22. const unsigned char *end,
  23. size_t *len)
  24. {
  25. if ((end - *p) < 1) {
  26. return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
  27. }
  28. if ((**p & 0x80) == 0) {
  29. *len = *(*p)++;
  30. } else {
  31. int n = (**p) & 0x7F;
  32. if (n == 0 || n > 4) {
  33. return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
  34. }
  35. if ((end - *p) <= n) {
  36. return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
  37. }
  38. *len = 0;
  39. (*p)++;
  40. while (n--) {
  41. *len = (*len << 8) | **p;
  42. (*p)++;
  43. }
  44. }
  45. if (*len > (size_t) (end - *p)) {
  46. return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
  47. }
  48. return 0;
  49. }
  50. int mbedtls_asn1_get_tag(unsigned char **p,
  51. const unsigned char *end,
  52. size_t *len, int tag)
  53. {
  54. if ((end - *p) < 1) {
  55. return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
  56. }
  57. if (**p != tag) {
  58. return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
  59. }
  60. (*p)++;
  61. return mbedtls_asn1_get_len(p, end, len);
  62. }
  63. #endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
  64. #if defined(MBEDTLS_ASN1_PARSE_C)
  65. int mbedtls_asn1_get_bool(unsigned char **p,
  66. const unsigned char *end,
  67. int *val)
  68. {
  69. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  70. size_t len;
  71. if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) {
  72. return ret;
  73. }
  74. if (len != 1) {
  75. return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
  76. }
  77. *val = (**p != 0) ? 1 : 0;
  78. (*p)++;
  79. return 0;
  80. }
  81. static int asn1_get_tagged_int(unsigned char **p,
  82. const unsigned char *end,
  83. int tag, int *val)
  84. {
  85. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  86. size_t len;
  87. if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) {
  88. return ret;
  89. }
  90. /*
  91. * len==0 is malformed (0 must be represented as 020100 for INTEGER,
  92. * or 0A0100 for ENUMERATED tags
  93. */
  94. if (len == 0) {
  95. return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
  96. }
  97. /* This is a cryptography library. Reject negative integers. */
  98. if ((**p & 0x80) != 0) {
  99. return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
  100. }
  101. /* Skip leading zeros. */
  102. while (len > 0 && **p == 0) {
  103. ++(*p);
  104. --len;
  105. }
  106. /* Reject integers that don't fit in an int. This code assumes that
  107. * the int type has no padding bit. */
  108. if (len > sizeof(int)) {
  109. return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
  110. }
  111. if (len == sizeof(int) && (**p & 0x80) != 0) {
  112. return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
  113. }
  114. *val = 0;
  115. while (len-- > 0) {
  116. *val = (*val << 8) | **p;
  117. (*p)++;
  118. }
  119. return 0;
  120. }
  121. int mbedtls_asn1_get_int(unsigned char **p,
  122. const unsigned char *end,
  123. int *val)
  124. {
  125. return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val);
  126. }
  127. int mbedtls_asn1_get_enum(unsigned char **p,
  128. const unsigned char *end,
  129. int *val)
  130. {
  131. return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val);
  132. }
  133. #if defined(MBEDTLS_BIGNUM_C)
  134. int mbedtls_asn1_get_mpi(unsigned char **p,
  135. const unsigned char *end,
  136. mbedtls_mpi *X)
  137. {
  138. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  139. size_t len;
  140. if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
  141. return ret;
  142. }
  143. ret = mbedtls_mpi_read_binary(X, *p, len);
  144. *p += len;
  145. return ret;
  146. }
  147. #endif /* MBEDTLS_BIGNUM_C */
  148. int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end,
  149. mbedtls_asn1_bitstring *bs)
  150. {
  151. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  152. /* Certificate type is a single byte bitstring */
  153. if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
  154. return ret;
  155. }
  156. /* Check length, subtract one for actual bit string length */
  157. if (bs->len < 1) {
  158. return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
  159. }
  160. bs->len -= 1;
  161. /* Get number of unused bits, ensure unused bits <= 7 */
  162. bs->unused_bits = **p;
  163. if (bs->unused_bits > 7) {
  164. return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
  165. }
  166. (*p)++;
  167. /* Get actual bitstring */
  168. bs->p = *p;
  169. *p += bs->len;
  170. if (*p != end) {
  171. return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
  172. }
  173. return 0;
  174. }
  175. /*
  176. * Traverse an ASN.1 "SEQUENCE OF <tag>"
  177. * and call a callback for each entry found.
  178. */
  179. int mbedtls_asn1_traverse_sequence_of(
  180. unsigned char **p,
  181. const unsigned char *end,
  182. unsigned char tag_must_mask, unsigned char tag_must_val,
  183. unsigned char tag_may_mask, unsigned char tag_may_val,
  184. int (*cb)(void *ctx, int tag,
  185. unsigned char *start, size_t len),
  186. void *ctx)
  187. {
  188. int ret;
  189. size_t len;
  190. /* Get main sequence tag */
  191. if ((ret = mbedtls_asn1_get_tag(p, end, &len,
  192. MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
  193. return ret;
  194. }
  195. if (*p + len != end) {
  196. return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
  197. }
  198. while (*p < end) {
  199. unsigned char const tag = *(*p)++;
  200. if ((tag & tag_must_mask) != tag_must_val) {
  201. return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
  202. }
  203. if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) {
  204. return ret;
  205. }
  206. if ((tag & tag_may_mask) == tag_may_val) {
  207. if (cb != NULL) {
  208. ret = cb(ctx, tag, *p, len);
  209. if (ret != 0) {
  210. return ret;
  211. }
  212. }
  213. }
  214. *p += len;
  215. }
  216. return 0;
  217. }
  218. /*
  219. * Get a bit string without unused bits
  220. */
  221. int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end,
  222. size_t *len)
  223. {
  224. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  225. if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
  226. return ret;
  227. }
  228. if (*len == 0) {
  229. return MBEDTLS_ERR_ASN1_INVALID_DATA;
  230. }
  231. --(*len);
  232. if (**p != 0) {
  233. return MBEDTLS_ERR_ASN1_INVALID_DATA;
  234. }
  235. ++(*p);
  236. return 0;
  237. }
  238. void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq)
  239. {
  240. while (seq != NULL) {
  241. mbedtls_asn1_sequence *next = seq->next;
  242. mbedtls_free(seq);
  243. seq = next;
  244. }
  245. }
  246. typedef struct {
  247. int tag;
  248. mbedtls_asn1_sequence *cur;
  249. } asn1_get_sequence_of_cb_ctx_t;
  250. static int asn1_get_sequence_of_cb(void *ctx,
  251. int tag,
  252. unsigned char *start,
  253. size_t len)
  254. {
  255. asn1_get_sequence_of_cb_ctx_t *cb_ctx =
  256. (asn1_get_sequence_of_cb_ctx_t *) ctx;
  257. mbedtls_asn1_sequence *cur =
  258. cb_ctx->cur;
  259. if (cur->buf.p != NULL) {
  260. cur->next =
  261. mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
  262. if (cur->next == NULL) {
  263. return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
  264. }
  265. cur = cur->next;
  266. }
  267. cur->buf.p = start;
  268. cur->buf.len = len;
  269. cur->buf.tag = tag;
  270. cb_ctx->cur = cur;
  271. return 0;
  272. }
  273. /*
  274. * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
  275. */
  276. int mbedtls_asn1_get_sequence_of(unsigned char **p,
  277. const unsigned char *end,
  278. mbedtls_asn1_sequence *cur,
  279. int tag)
  280. {
  281. asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
  282. memset(cur, 0, sizeof(mbedtls_asn1_sequence));
  283. return mbedtls_asn1_traverse_sequence_of(
  284. p, end, 0xFF, tag, 0, 0,
  285. asn1_get_sequence_of_cb, &cb_ctx);
  286. }
  287. int mbedtls_asn1_get_alg(unsigned char **p,
  288. const unsigned char *end,
  289. mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params)
  290. {
  291. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  292. size_t len;
  293. if ((ret = mbedtls_asn1_get_tag(p, end, &len,
  294. MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
  295. return ret;
  296. }
  297. if ((end - *p) < 1) {
  298. return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
  299. }
  300. alg->tag = **p;
  301. end = *p + len;
  302. if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) {
  303. return ret;
  304. }
  305. alg->p = *p;
  306. *p += alg->len;
  307. if (*p == end) {
  308. mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf));
  309. return 0;
  310. }
  311. params->tag = **p;
  312. (*p)++;
  313. if ((ret = mbedtls_asn1_get_len(p, end, &params->len)) != 0) {
  314. return ret;
  315. }
  316. params->p = *p;
  317. *p += params->len;
  318. if (*p != end) {
  319. return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
  320. }
  321. return 0;
  322. }
  323. int mbedtls_asn1_get_alg_null(unsigned char **p,
  324. const unsigned char *end,
  325. mbedtls_asn1_buf *alg)
  326. {
  327. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  328. mbedtls_asn1_buf params;
  329. memset(&params, 0, sizeof(mbedtls_asn1_buf));
  330. if ((ret = mbedtls_asn1_get_alg(p, end, alg, &params)) != 0) {
  331. return ret;
  332. }
  333. if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) {
  334. return MBEDTLS_ERR_ASN1_INVALID_DATA;
  335. }
  336. return 0;
  337. }
  338. #if !defined(MBEDTLS_DEPRECATED_REMOVED)
  339. void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur)
  340. {
  341. if (cur == NULL) {
  342. return;
  343. }
  344. mbedtls_free(cur->oid.p);
  345. mbedtls_free(cur->val.p);
  346. mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data));
  347. }
  348. #endif /* MBEDTLS_DEPRECATED_REMOVED */
  349. void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head)
  350. {
  351. mbedtls_asn1_named_data *cur;
  352. while ((cur = *head) != NULL) {
  353. *head = cur->next;
  354. mbedtls_free(cur->oid.p);
  355. mbedtls_free(cur->val.p);
  356. mbedtls_free(cur);
  357. }
  358. }
  359. void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name)
  360. {
  361. for (mbedtls_asn1_named_data *next; name != NULL; name = next) {
  362. next = name->next;
  363. mbedtls_free(name);
  364. }
  365. }
  366. const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list,
  367. const char *oid, size_t len)
  368. {
  369. while (list != NULL) {
  370. if (list->oid.len == len &&
  371. memcmp(list->oid.p, oid, len) == 0) {
  372. break;
  373. }
  374. list = list->next;
  375. }
  376. return list;
  377. }
  378. #endif /* MBEDTLS_ASN1_PARSE_C */