Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

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