x509_crl.c 21 KB

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