x509_crl.c 22 KB

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