x509_crl.c 19 KB

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