x509_crl.c 19 KB

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