x509_crl.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. /*
  2. * X.509 Certificate Revocation List (CRL) parsing
  3. *
  4. * Copyright The Mbed TLS Contributors
  5. * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
  6. */
  7. /*
  8. * The ITU-T X.509 standard defines a certificate format for PKI.
  9. *
  10. * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
  11. * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
  12. * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
  13. *
  14. * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
  15. * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
  16. */
  17. #include "common.h"
  18. #if defined(MBEDTLS_X509_CRL_PARSE_C)
  19. #include "mbedtls/x509_crl.h"
  20. #include "x509_internal.h"
  21. #include "mbedtls/error.h"
  22. #include "mbedtls/oid.h"
  23. #include "mbedtls/platform_util.h"
  24. #include <string.h>
  25. #if defined(MBEDTLS_PEM_PARSE_C)
  26. #include "mbedtls/pem.h"
  27. #endif
  28. #include "mbedtls/platform.h"
  29. #if defined(MBEDTLS_HAVE_TIME)
  30. #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
  31. #include <windows.h>
  32. #else
  33. #include <time.h>
  34. #endif
  35. #endif
  36. #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
  37. #include <stdio.h>
  38. #endif
  39. /*
  40. * Version ::= INTEGER { v1(0), v2(1) }
  41. */
  42. static int x509_crl_get_version(unsigned char **p,
  43. const unsigned char *end,
  44. int *ver)
  45. {
  46. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  47. if ((ret = mbedtls_asn1_get_int(p, end, ver)) != 0) {
  48. if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
  49. *ver = 0;
  50. return 0;
  51. }
  52. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, ret);
  53. }
  54. return 0;
  55. }
  56. /*
  57. * X.509 CRL v2 extensions
  58. *
  59. * We currently don't parse any extension's content, but we do check that the
  60. * list of extensions is well-formed and abort on critical extensions (that
  61. * are unsupported as we don't support any extension so far)
  62. */
  63. static int x509_get_crl_ext(unsigned char **p,
  64. const unsigned char *end,
  65. mbedtls_x509_buf *ext)
  66. {
  67. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  68. if (*p == end) {
  69. return 0;
  70. }
  71. /*
  72. * crlExtensions [0] EXPLICIT Extensions OPTIONAL
  73. * -- if present, version MUST be v2
  74. */
  75. if ((ret = mbedtls_x509_get_ext(p, end, ext, 0)) != 0) {
  76. return ret;
  77. }
  78. end = ext->p + ext->len;
  79. while (*p < end) {
  80. /*
  81. * Extension ::= SEQUENCE {
  82. * extnID OBJECT IDENTIFIER,
  83. * critical BOOLEAN DEFAULT FALSE,
  84. * extnValue OCTET STRING }
  85. */
  86. int is_critical = 0;
  87. const unsigned char *end_ext_data;
  88. size_t len;
  89. /* Get enclosing sequence tag */
  90. if ((ret = mbedtls_asn1_get_tag(p, end, &len,
  91. MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
  92. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
  93. }
  94. end_ext_data = *p + len;
  95. /* Get OID (currently ignored) */
  96. if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len,
  97. MBEDTLS_ASN1_OID)) != 0) {
  98. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
  99. }
  100. *p += len;
  101. /* Get optional critical */
  102. if ((ret = mbedtls_asn1_get_bool(p, end_ext_data,
  103. &is_critical)) != 0 &&
  104. (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
  105. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
  106. }
  107. /* Data should be octet string type */
  108. if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len,
  109. MBEDTLS_ASN1_OCTET_STRING)) != 0) {
  110. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
  111. }
  112. /* Ignore data so far and just check its length */
  113. *p += len;
  114. if (*p != end_ext_data) {
  115. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
  116. MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
  117. }
  118. /* Abort on (unsupported) critical extensions */
  119. if (is_critical) {
  120. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
  121. MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
  122. }
  123. }
  124. if (*p != end) {
  125. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
  126. MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
  127. }
  128. return 0;
  129. }
  130. /*
  131. * X.509 CRL v2 entry extensions (no extensions parsed yet.)
  132. */
  133. static int x509_get_crl_entry_ext(unsigned char **p,
  134. const unsigned char *end,
  135. mbedtls_x509_buf *ext)
  136. {
  137. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  138. size_t len = 0;
  139. /* OPTIONAL */
  140. if (end <= *p) {
  141. return 0;
  142. }
  143. ext->tag = **p;
  144. ext->p = *p;
  145. /*
  146. * Get CRL-entry extension sequence header
  147. * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
  148. */
  149. if ((ret = mbedtls_asn1_get_tag(p, end, &ext->len,
  150. MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
  151. if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
  152. ext->p = NULL;
  153. return 0;
  154. }
  155. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
  156. }
  157. end = *p + ext->len;
  158. if (end != *p + ext->len) {
  159. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
  160. MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
  161. }
  162. while (*p < end) {
  163. if ((ret = mbedtls_asn1_get_tag(p, end, &len,
  164. MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
  165. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
  166. }
  167. *p += len;
  168. }
  169. if (*p != end) {
  170. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
  171. MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
  172. }
  173. return 0;
  174. }
  175. /*
  176. * X.509 CRL Entries
  177. */
  178. static int x509_get_entries(unsigned char **p,
  179. const unsigned char *end,
  180. mbedtls_x509_crl_entry *entry)
  181. {
  182. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  183. size_t entry_len;
  184. mbedtls_x509_crl_entry *cur_entry = entry;
  185. if (*p == end) {
  186. return 0;
  187. }
  188. if ((ret = mbedtls_asn1_get_tag(p, end, &entry_len,
  189. MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED)) != 0) {
  190. if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
  191. return 0;
  192. }
  193. return ret;
  194. }
  195. end = *p + entry_len;
  196. while (*p < end) {
  197. size_t len2;
  198. const unsigned char *end2;
  199. cur_entry->raw.tag = **p;
  200. if ((ret = mbedtls_asn1_get_tag(p, end, &len2,
  201. MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED)) != 0) {
  202. return ret;
  203. }
  204. cur_entry->raw.p = *p;
  205. cur_entry->raw.len = len2;
  206. end2 = *p + len2;
  207. if ((ret = mbedtls_x509_get_serial(p, end2, &cur_entry->serial)) != 0) {
  208. return ret;
  209. }
  210. if ((ret = mbedtls_x509_get_time(p, end2,
  211. &cur_entry->revocation_date)) != 0) {
  212. return ret;
  213. }
  214. if ((ret = x509_get_crl_entry_ext(p, end2,
  215. &cur_entry->entry_ext)) != 0) {
  216. return ret;
  217. }
  218. if (*p < end) {
  219. cur_entry->next = mbedtls_calloc(1, sizeof(mbedtls_x509_crl_entry));
  220. if (cur_entry->next == NULL) {
  221. return MBEDTLS_ERR_X509_ALLOC_FAILED;
  222. }
  223. cur_entry = cur_entry->next;
  224. }
  225. }
  226. return 0;
  227. }
  228. /*
  229. * Parse one CRLs in DER format and append it to the chained list
  230. */
  231. int mbedtls_x509_crl_parse_der(mbedtls_x509_crl *chain,
  232. const unsigned char *buf, size_t buflen)
  233. {
  234. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  235. size_t len;
  236. unsigned char *p = NULL, *end = NULL;
  237. mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
  238. mbedtls_x509_crl *crl = chain;
  239. /*
  240. * Check for valid input
  241. */
  242. if (crl == NULL || buf == NULL) {
  243. return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
  244. }
  245. memset(&sig_params1, 0, sizeof(mbedtls_x509_buf));
  246. memset(&sig_params2, 0, sizeof(mbedtls_x509_buf));
  247. memset(&sig_oid2, 0, sizeof(mbedtls_x509_buf));
  248. /*
  249. * Add new CRL on the end of the chain if needed.
  250. */
  251. while (crl->version != 0 && crl->next != NULL) {
  252. crl = crl->next;
  253. }
  254. if (crl->version != 0 && crl->next == NULL) {
  255. crl->next = mbedtls_calloc(1, sizeof(mbedtls_x509_crl));
  256. if (crl->next == NULL) {
  257. mbedtls_x509_crl_free(crl);
  258. return MBEDTLS_ERR_X509_ALLOC_FAILED;
  259. }
  260. mbedtls_x509_crl_init(crl->next);
  261. crl = crl->next;
  262. }
  263. /*
  264. * Copy raw DER-encoded CRL
  265. */
  266. if (buflen == 0) {
  267. return MBEDTLS_ERR_X509_INVALID_FORMAT;
  268. }
  269. p = mbedtls_calloc(1, buflen);
  270. if (p == NULL) {
  271. return MBEDTLS_ERR_X509_ALLOC_FAILED;
  272. }
  273. memcpy(p, buf, buflen);
  274. crl->raw.p = p;
  275. crl->raw.len = buflen;
  276. end = p + buflen;
  277. /*
  278. * CertificateList ::= SEQUENCE {
  279. * tbsCertList TBSCertList,
  280. * signatureAlgorithm AlgorithmIdentifier,
  281. * signatureValue BIT STRING }
  282. */
  283. if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
  284. MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
  285. mbedtls_x509_crl_free(crl);
  286. return MBEDTLS_ERR_X509_INVALID_FORMAT;
  287. }
  288. if (len != (size_t) (end - p)) {
  289. mbedtls_x509_crl_free(crl);
  290. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
  291. MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
  292. }
  293. /*
  294. * TBSCertList ::= SEQUENCE {
  295. */
  296. crl->tbs.p = p;
  297. if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
  298. MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
  299. mbedtls_x509_crl_free(crl);
  300. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
  301. }
  302. end = p + len;
  303. crl->tbs.len = (size_t) (end - crl->tbs.p);
  304. /*
  305. * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
  306. * -- if present, MUST be v2
  307. *
  308. * signature AlgorithmIdentifier
  309. */
  310. if ((ret = x509_crl_get_version(&p, end, &crl->version)) != 0 ||
  311. (ret = mbedtls_x509_get_alg(&p, end, &crl->sig_oid, &sig_params1)) != 0) {
  312. mbedtls_x509_crl_free(crl);
  313. return ret;
  314. }
  315. if (crl->version < 0 || crl->version > 1) {
  316. mbedtls_x509_crl_free(crl);
  317. return MBEDTLS_ERR_X509_UNKNOWN_VERSION;
  318. }
  319. crl->version++;
  320. if ((ret = mbedtls_x509_get_sig_alg(&crl->sig_oid, &sig_params1,
  321. &crl->sig_md, &crl->sig_pk,
  322. &crl->sig_opts)) != 0) {
  323. mbedtls_x509_crl_free(crl);
  324. return MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG;
  325. }
  326. /*
  327. * issuer Name
  328. */
  329. crl->issuer_raw.p = p;
  330. if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
  331. MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
  332. mbedtls_x509_crl_free(crl);
  333. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
  334. }
  335. if ((ret = mbedtls_x509_get_name(&p, p + len, &crl->issuer)) != 0) {
  336. mbedtls_x509_crl_free(crl);
  337. return ret;
  338. }
  339. crl->issuer_raw.len = (size_t) (p - crl->issuer_raw.p);
  340. /*
  341. * thisUpdate Time
  342. * nextUpdate Time OPTIONAL
  343. */
  344. if ((ret = mbedtls_x509_get_time(&p, end, &crl->this_update)) != 0) {
  345. mbedtls_x509_crl_free(crl);
  346. return ret;
  347. }
  348. if ((ret = mbedtls_x509_get_time(&p, end, &crl->next_update)) != 0) {
  349. if (ret != (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
  350. MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) &&
  351. ret != (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
  352. MBEDTLS_ERR_ASN1_OUT_OF_DATA))) {
  353. mbedtls_x509_crl_free(crl);
  354. return ret;
  355. }
  356. }
  357. /*
  358. * revokedCertificates SEQUENCE OF SEQUENCE {
  359. * userCertificate CertificateSerialNumber,
  360. * revocationDate Time,
  361. * crlEntryExtensions Extensions OPTIONAL
  362. * -- if present, MUST be v2
  363. * } OPTIONAL
  364. */
  365. if ((ret = x509_get_entries(&p, end, &crl->entry)) != 0) {
  366. mbedtls_x509_crl_free(crl);
  367. return ret;
  368. }
  369. /*
  370. * crlExtensions EXPLICIT Extensions OPTIONAL
  371. * -- if present, MUST be v2
  372. */
  373. if (crl->version == 2) {
  374. ret = x509_get_crl_ext(&p, end, &crl->crl_ext);
  375. if (ret != 0) {
  376. mbedtls_x509_crl_free(crl);
  377. return ret;
  378. }
  379. }
  380. if (p != end) {
  381. mbedtls_x509_crl_free(crl);
  382. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
  383. MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
  384. }
  385. end = crl->raw.p + crl->raw.len;
  386. /*
  387. * signatureAlgorithm AlgorithmIdentifier,
  388. * signatureValue BIT STRING
  389. */
  390. if ((ret = mbedtls_x509_get_alg(&p, end, &sig_oid2, &sig_params2)) != 0) {
  391. mbedtls_x509_crl_free(crl);
  392. return ret;
  393. }
  394. if (crl->sig_oid.len != sig_oid2.len ||
  395. memcmp(crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len) != 0 ||
  396. sig_params1.len != sig_params2.len ||
  397. (sig_params1.len != 0 &&
  398. memcmp(sig_params1.p, sig_params2.p, sig_params1.len) != 0)) {
  399. mbedtls_x509_crl_free(crl);
  400. return MBEDTLS_ERR_X509_SIG_MISMATCH;
  401. }
  402. if ((ret = mbedtls_x509_get_sig(&p, end, &crl->sig)) != 0) {
  403. mbedtls_x509_crl_free(crl);
  404. return ret;
  405. }
  406. if (p != end) {
  407. mbedtls_x509_crl_free(crl);
  408. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
  409. MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
  410. }
  411. return 0;
  412. }
  413. /*
  414. * Parse one or more CRLs and add them to the chained list
  415. */
  416. int mbedtls_x509_crl_parse(mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen)
  417. {
  418. #if defined(MBEDTLS_PEM_PARSE_C)
  419. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  420. size_t use_len = 0;
  421. mbedtls_pem_context pem;
  422. int is_pem = 0;
  423. if (chain == NULL || buf == NULL) {
  424. return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
  425. }
  426. do {
  427. mbedtls_pem_init(&pem);
  428. // Avoid calling mbedtls_pem_read_buffer() on non-null-terminated
  429. // string
  430. if (buflen == 0 || buf[buflen - 1] != '\0') {
  431. ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
  432. } else {
  433. ret = mbedtls_pem_read_buffer(&pem,
  434. "-----BEGIN X509 CRL-----",
  435. "-----END X509 CRL-----",
  436. buf, NULL, 0, &use_len);
  437. }
  438. if (ret == 0) {
  439. /*
  440. * Was PEM encoded
  441. */
  442. is_pem = 1;
  443. buflen -= use_len;
  444. buf += use_len;
  445. if ((ret = mbedtls_x509_crl_parse_der(chain,
  446. pem.buf, pem.buflen)) != 0) {
  447. mbedtls_pem_free(&pem);
  448. return ret;
  449. }
  450. } else if (is_pem) {
  451. mbedtls_pem_free(&pem);
  452. return ret;
  453. }
  454. mbedtls_pem_free(&pem);
  455. }
  456. /* In the PEM case, buflen is 1 at the end, for the terminated NULL byte.
  457. * And a valid CRL cannot be less than 1 byte anyway. */
  458. while (is_pem && buflen > 1);
  459. if (is_pem) {
  460. return 0;
  461. } else
  462. #endif /* MBEDTLS_PEM_PARSE_C */
  463. return mbedtls_x509_crl_parse_der(chain, buf, buflen);
  464. }
  465. #if defined(MBEDTLS_FS_IO)
  466. /*
  467. * Load one or more CRLs and add them to the chained list
  468. */
  469. int mbedtls_x509_crl_parse_file(mbedtls_x509_crl *chain, const char *path)
  470. {
  471. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  472. size_t n;
  473. unsigned char *buf;
  474. if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) {
  475. return ret;
  476. }
  477. ret = mbedtls_x509_crl_parse(chain, buf, n);
  478. mbedtls_zeroize_and_free(buf, n);
  479. return ret;
  480. }
  481. #endif /* MBEDTLS_FS_IO */
  482. #if !defined(MBEDTLS_X509_REMOVE_INFO)
  483. /*
  484. * Return an informational string about the certificate.
  485. */
  486. #define BEFORE_COLON 14
  487. #define BC "14"
  488. /*
  489. * Return an informational string about the CRL.
  490. */
  491. int mbedtls_x509_crl_info(char *buf, size_t size, const char *prefix,
  492. const mbedtls_x509_crl *crl)
  493. {
  494. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  495. size_t n;
  496. char *p;
  497. const mbedtls_x509_crl_entry *entry;
  498. p = buf;
  499. n = size;
  500. ret = mbedtls_snprintf(p, n, "%sCRL version : %d",
  501. prefix, crl->version);
  502. MBEDTLS_X509_SAFE_SNPRINTF;
  503. ret = mbedtls_snprintf(p, n, "\n%sissuer name : ", prefix);
  504. MBEDTLS_X509_SAFE_SNPRINTF;
  505. ret = mbedtls_x509_dn_gets(p, n, &crl->issuer);
  506. MBEDTLS_X509_SAFE_SNPRINTF;
  507. ret = mbedtls_snprintf(p, n, "\n%sthis update : " \
  508. "%04d-%02d-%02d %02d:%02d:%02d", prefix,
  509. crl->this_update.year, crl->this_update.mon,
  510. crl->this_update.day, crl->this_update.hour,
  511. crl->this_update.min, crl->this_update.sec);
  512. MBEDTLS_X509_SAFE_SNPRINTF;
  513. ret = mbedtls_snprintf(p, n, "\n%snext update : " \
  514. "%04d-%02d-%02d %02d:%02d:%02d", prefix,
  515. crl->next_update.year, crl->next_update.mon,
  516. crl->next_update.day, crl->next_update.hour,
  517. crl->next_update.min, crl->next_update.sec);
  518. MBEDTLS_X509_SAFE_SNPRINTF;
  519. entry = &crl->entry;
  520. ret = mbedtls_snprintf(p, n, "\n%sRevoked certificates:",
  521. prefix);
  522. MBEDTLS_X509_SAFE_SNPRINTF;
  523. while (entry != NULL && entry->raw.len != 0) {
  524. ret = mbedtls_snprintf(p, n, "\n%sserial number: ",
  525. prefix);
  526. MBEDTLS_X509_SAFE_SNPRINTF;
  527. ret = mbedtls_x509_serial_gets(p, n, &entry->serial);
  528. MBEDTLS_X509_SAFE_SNPRINTF;
  529. ret = mbedtls_snprintf(p, n, " revocation date: " \
  530. "%04d-%02d-%02d %02d:%02d:%02d",
  531. entry->revocation_date.year, entry->revocation_date.mon,
  532. entry->revocation_date.day, entry->revocation_date.hour,
  533. entry->revocation_date.min, entry->revocation_date.sec);
  534. MBEDTLS_X509_SAFE_SNPRINTF;
  535. entry = entry->next;
  536. }
  537. ret = mbedtls_snprintf(p, n, "\n%ssigned using : ", prefix);
  538. MBEDTLS_X509_SAFE_SNPRINTF;
  539. ret = mbedtls_x509_sig_alg_gets(p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md,
  540. crl->sig_opts);
  541. MBEDTLS_X509_SAFE_SNPRINTF;
  542. ret = mbedtls_snprintf(p, n, "\n");
  543. MBEDTLS_X509_SAFE_SNPRINTF;
  544. return (int) (size - n);
  545. }
  546. #endif /* MBEDTLS_X509_REMOVE_INFO */
  547. /*
  548. * Initialize a CRL chain
  549. */
  550. void mbedtls_x509_crl_init(mbedtls_x509_crl *crl)
  551. {
  552. memset(crl, 0, sizeof(mbedtls_x509_crl));
  553. }
  554. /*
  555. * Unallocate all CRL data
  556. */
  557. void mbedtls_x509_crl_free(mbedtls_x509_crl *crl)
  558. {
  559. mbedtls_x509_crl *crl_cur = crl;
  560. mbedtls_x509_crl *crl_prv;
  561. mbedtls_x509_crl_entry *entry_cur;
  562. mbedtls_x509_crl_entry *entry_prv;
  563. while (crl_cur != NULL) {
  564. #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
  565. mbedtls_free(crl_cur->sig_opts);
  566. #endif
  567. mbedtls_asn1_free_named_data_list_shallow(crl_cur->issuer.next);
  568. entry_cur = crl_cur->entry.next;
  569. while (entry_cur != NULL) {
  570. entry_prv = entry_cur;
  571. entry_cur = entry_cur->next;
  572. mbedtls_zeroize_and_free(entry_prv,
  573. sizeof(mbedtls_x509_crl_entry));
  574. }
  575. if (crl_cur->raw.p != NULL) {
  576. mbedtls_zeroize_and_free(crl_cur->raw.p, crl_cur->raw.len);
  577. }
  578. crl_prv = crl_cur;
  579. crl_cur = crl_cur->next;
  580. mbedtls_platform_zeroize(crl_prv, sizeof(mbedtls_x509_crl));
  581. if (crl_prv != crl) {
  582. mbedtls_free(crl_prv);
  583. }
  584. }
  585. }
  586. #endif /* MBEDTLS_X509_CRL_PARSE_C */