mbedtls ported to mbed-classic

Fork of mbedtls by Christopher Haster

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers x509_crl.c Source File

x509_crl.c

00001 /*
00002  *  X.509 Certidicate Revocation List (CRL) parsing
00003  *
00004  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
00005  *  SPDX-License-Identifier: Apache-2.0
00006  *
00007  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
00008  *  not use this file except in compliance with the License.
00009  *  You may obtain a copy of the License at
00010  *
00011  *  http://www.apache.org/licenses/LICENSE-2.0
00012  *
00013  *  Unless required by applicable law or agreed to in writing, software
00014  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00015  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016  *  See the License for the specific language governing permissions and
00017  *  limitations under the License.
00018  *
00019  *  This file is part of mbed TLS (https://tls.mbed.org)
00020  */
00021 /*
00022  *  The ITU-T X.509 standard defines a certificate format for PKI.
00023  *
00024  *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
00025  *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
00026  *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
00027  *
00028  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
00029  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
00030  */
00031 
00032 #if !defined(MBEDTLS_CONFIG_FILE)
00033 #include "mbedtls/config.h"
00034 #else
00035 #include MBEDTLS_CONFIG_FILE
00036 #endif
00037 
00038 #if defined(MBEDTLS_X509_CRL_PARSE_C)
00039 
00040 #include "mbedtls/x509_crl.h"
00041 #include "mbedtls/oid.h"
00042 
00043 #include <string.h>
00044 
00045 #if defined(MBEDTLS_PEM_PARSE_C)
00046 #include "mbedtls/pem.h"
00047 #endif
00048 
00049 #if defined(MBEDTLS_PLATFORM_C)
00050 #include "mbedtls/platform.h"
00051 #else
00052 #include <stdlib.h>
00053 #include <stdio.h>
00054 #define mbedtls_free       free
00055 #define mbedtls_calloc    calloc
00056 #define mbedtls_snprintf   snprintf
00057 #endif
00058 
00059 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
00060 #include <windows.h>
00061 #else
00062 #include <time.h>
00063 #endif
00064 
00065 #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
00066 #include <stdio.h>
00067 #endif
00068 
00069 /* Implementation that should never be optimized out by the compiler */
00070 static void mbedtls_zeroize( void *v, size_t n ) {
00071     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
00072 }
00073 
00074 /*
00075  *  Version  ::=  INTEGER  {  v1(0), v2(1)  }
00076  */
00077 static int x509_crl_get_version( unsigned char **p,
00078                              const unsigned char *end,
00079                              int *ver )
00080 {
00081     int ret;
00082 
00083     if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
00084     {
00085         if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
00086         {
00087             *ver = 0;
00088             return( 0 );
00089         }
00090 
00091         return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
00092     }
00093 
00094     return( 0 );
00095 }
00096 
00097 /*
00098  * X.509 CRL v2 extensions (no extensions parsed yet.)
00099  */
00100 static int x509_get_crl_ext( unsigned char **p,
00101                              const unsigned char *end,
00102                              mbedtls_x509_buf *ext )
00103 {
00104     int ret;
00105     size_t len = 0;
00106 
00107     /* Get explicit tag */
00108     if( ( ret = mbedtls_x509_get_ext( p, end, ext, 0) ) != 0 )
00109     {
00110         if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
00111             return( 0 );
00112 
00113         return( ret );
00114     }
00115 
00116     while( *p < end )
00117     {
00118         if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
00119                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00120             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
00121 
00122         *p += len;
00123     }
00124 
00125     if( *p != end )
00126         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
00127                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00128 
00129     return( 0 );
00130 }
00131 
00132 /*
00133  * X.509 CRL v2 entry extensions (no extensions parsed yet.)
00134  */
00135 static int x509_get_crl_entry_ext( unsigned char **p,
00136                              const unsigned char *end,
00137                              mbedtls_x509_buf *ext )
00138 {
00139     int ret;
00140     size_t len = 0;
00141 
00142     /* OPTIONAL */
00143     if( end <= *p )
00144         return( 0 );
00145 
00146     ext->tag = **p;
00147     ext->p = *p;
00148 
00149     /*
00150      * Get CRL-entry extension sequence header
00151      * crlEntryExtensions      Extensions OPTIONAL  -- if present, MUST be v2
00152      */
00153     if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len,
00154             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00155     {
00156         if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
00157         {
00158             ext->p = NULL;
00159             return( 0 );
00160         }
00161         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
00162     }
00163 
00164     end = *p + ext->len;
00165 
00166     if( end != *p + ext->len )
00167         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
00168                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00169 
00170     while( *p < end )
00171     {
00172         if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
00173                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00174             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
00175 
00176         *p += len;
00177     }
00178 
00179     if( *p != end )
00180         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
00181                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00182 
00183     return( 0 );
00184 }
00185 
00186 /*
00187  * X.509 CRL Entries
00188  */
00189 static int x509_get_entries( unsigned char **p,
00190                              const unsigned char *end,
00191                              mbedtls_x509_crl_entry *entry )
00192 {
00193     int ret;
00194     size_t entry_len;
00195     mbedtls_x509_crl_entry *cur_entry = entry;
00196 
00197     if( *p == end )
00198         return( 0 );
00199 
00200     if( ( ret = mbedtls_asn1_get_tag( p, end, &entry_len,
00201             MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 )
00202     {
00203         if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
00204             return( 0 );
00205 
00206         return( ret );
00207     }
00208 
00209     end = *p + entry_len;
00210 
00211     while( *p < end )
00212     {
00213         size_t len2;
00214         const unsigned char *end2;
00215 
00216         if( ( ret = mbedtls_asn1_get_tag( p, end, &len2,
00217                 MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 )
00218         {
00219             return( ret );
00220         }
00221 
00222         cur_entry->raw.tag = **p;
00223         cur_entry->raw.p = *p;
00224         cur_entry->raw.len = len2;
00225         end2 = *p + len2;
00226 
00227         if( ( ret = mbedtls_x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
00228             return( ret );
00229 
00230         if( ( ret = mbedtls_x509_get_time( p, end2,
00231                                    &cur_entry->revocation_date ) ) != 0 )
00232             return( ret );
00233 
00234         if( ( ret = x509_get_crl_entry_ext( p, end2,
00235                                             &cur_entry->entry_ext ) ) != 0 )
00236             return( ret );
00237 
00238         if( *p < end )
00239         {
00240             cur_entry->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crl_entry ) );
00241 
00242             if( cur_entry->next == NULL )
00243                 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
00244 
00245             cur_entry = cur_entry->next;
00246         }
00247     }
00248 
00249     return( 0 );
00250 }
00251 
00252 /*
00253  * Parse one  CRLs in DER format and append it to the chained list
00254  */
00255 int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
00256                         const unsigned char *buf, size_t buflen )
00257 {
00258     int ret;
00259     size_t len;
00260     unsigned char *p, *end;
00261     mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
00262     mbedtls_x509_crl *crl = chain;
00263 
00264     /*
00265      * Check for valid input
00266      */
00267     if( crl == NULL || buf == NULL )
00268         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
00269 
00270     memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) );
00271     memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) );
00272     memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) );
00273 
00274     /*
00275      * Add new CRL on the end of the chain if needed.
00276      */
00277     while( crl->version != 0 && crl->next != NULL )
00278         crl = crl->next;
00279 
00280     if( crl->version != 0 && crl->next == NULL )
00281     {
00282         crl->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crl ) );
00283 
00284         if( crl->next == NULL )
00285         {
00286             mbedtls_x509_crl_free( crl );
00287             return( MBEDTLS_ERR_X509_ALLOC_FAILED );
00288         }
00289 
00290         mbedtls_x509_crl_init( crl->next );
00291         crl = crl->next;
00292     }
00293 
00294     /*
00295      * Copy raw DER-encoded CRL
00296      */
00297     if( ( p = mbedtls_calloc( 1, buflen ) ) == NULL )
00298         return( MBEDTLS_ERR_X509_ALLOC_FAILED );
00299 
00300     memcpy( p, buf, buflen );
00301 
00302     crl->raw.p = p;
00303     crl->raw.len = buflen;
00304 
00305     end = p + buflen;
00306 
00307     /*
00308      * CertificateList  ::=  SEQUENCE  {
00309      *      tbsCertList          TBSCertList,
00310      *      signatureAlgorithm   AlgorithmIdentifier,
00311      *      signatureValue       BIT STRING  }
00312      */
00313     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
00314             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00315     {
00316         mbedtls_x509_crl_free( crl );
00317         return( MBEDTLS_ERR_X509_INVALID_FORMAT );
00318     }
00319 
00320     if( len != (size_t) ( end - p ) )
00321     {
00322         mbedtls_x509_crl_free( crl );
00323         return( MBEDTLS_ERR_X509_INVALID_FORMAT +
00324                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00325     }
00326 
00327     /*
00328      * TBSCertList  ::=  SEQUENCE  {
00329      */
00330     crl->tbs.p = p;
00331 
00332     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
00333             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00334     {
00335         mbedtls_x509_crl_free( crl );
00336         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
00337     }
00338 
00339     end = p + len;
00340     crl->tbs.len = end - crl->tbs.p;
00341 
00342     /*
00343      * Version  ::=  INTEGER  OPTIONAL {  v1(0), v2(1)  }
00344      *               -- if present, MUST be v2
00345      *
00346      * signature            AlgorithmIdentifier
00347      */
00348     if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
00349         ( ret = mbedtls_x509_get_alg( &p, end, &crl->sig_oid, &sig_params1 ) ) != 0 )
00350     {
00351         mbedtls_x509_crl_free( crl );
00352         return( ret );
00353     }
00354 
00355     crl->version++;
00356 
00357     if( crl->version > 2 )
00358     {
00359         mbedtls_x509_crl_free( crl );
00360         return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
00361     }
00362 
00363     if( ( ret = mbedtls_x509_get_sig_alg( &crl->sig_oid, &sig_params1,
00364                                   &crl->sig_md, &crl->sig_pk,
00365                                   &crl->sig_opts ) ) != 0 )
00366     {
00367         mbedtls_x509_crl_free( crl );
00368         return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG );
00369     }
00370 
00371     /*
00372      * issuer               Name
00373      */
00374     crl->issuer_raw.p = p;
00375 
00376     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
00377             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00378     {
00379         mbedtls_x509_crl_free( crl );
00380         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
00381     }
00382 
00383     if( ( ret = mbedtls_x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
00384     {
00385         mbedtls_x509_crl_free( crl );
00386         return( ret );
00387     }
00388 
00389     crl->issuer_raw.len = p - crl->issuer_raw.p;
00390 
00391     /*
00392      * thisUpdate          Time
00393      * nextUpdate          Time OPTIONAL
00394      */
00395     if( ( ret = mbedtls_x509_get_time( &p, end, &crl->this_update ) ) != 0 )
00396     {
00397         mbedtls_x509_crl_free( crl );
00398         return( ret );
00399     }
00400 
00401     if( ( ret = mbedtls_x509_get_time( &p, end, &crl->next_update ) ) != 0 )
00402     {
00403         if( ret != ( MBEDTLS_ERR_X509_INVALID_DATE +
00404                         MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) &&
00405             ret != ( MBEDTLS_ERR_X509_INVALID_DATE +
00406                         MBEDTLS_ERR_ASN1_OUT_OF_DATA ) )
00407         {
00408             mbedtls_x509_crl_free( crl );
00409             return( ret );
00410         }
00411     }
00412 
00413     /*
00414      * revokedCertificates    SEQUENCE OF SEQUENCE   {
00415      *      userCertificate        CertificateSerialNumber,
00416      *      revocationDate         Time,
00417      *      crlEntryExtensions     Extensions OPTIONAL
00418      *                                   -- if present, MUST be v2
00419      *                        } OPTIONAL
00420      */
00421     if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
00422     {
00423         mbedtls_x509_crl_free( crl );
00424         return( ret );
00425     }
00426 
00427     /*
00428      * crlExtensions          EXPLICIT Extensions OPTIONAL
00429      *                              -- if present, MUST be v2
00430      */
00431     if( crl->version == 2 )
00432     {
00433         ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
00434 
00435         if( ret != 0 )
00436         {
00437             mbedtls_x509_crl_free( crl );
00438             return( ret );
00439         }
00440     }
00441 
00442     if( p != end )
00443     {
00444         mbedtls_x509_crl_free( crl );
00445         return( MBEDTLS_ERR_X509_INVALID_FORMAT +
00446                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00447     }
00448 
00449     end = crl->raw.p + crl->raw.len;
00450 
00451     /*
00452      *  signatureAlgorithm   AlgorithmIdentifier,
00453      *  signatureValue       BIT STRING
00454      */
00455     if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 )
00456     {
00457         mbedtls_x509_crl_free( crl );
00458         return( ret );
00459     }
00460 
00461     if( crl->sig_oid.len != sig_oid2.len ||
00462         memcmp( crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len ) != 0 ||
00463         sig_params1.len != sig_params2.len ||
00464         ( sig_params1.len != 0 &&
00465           memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
00466     {
00467         mbedtls_x509_crl_free( crl );
00468         return( MBEDTLS_ERR_X509_SIG_MISMATCH );
00469     }
00470 
00471     if( ( ret = mbedtls_x509_get_sig( &p, end, &crl->sig ) ) != 0 )
00472     {
00473         mbedtls_x509_crl_free( crl );
00474         return( ret );
00475     }
00476 
00477     if( p != end )
00478     {
00479         mbedtls_x509_crl_free( crl );
00480         return( MBEDTLS_ERR_X509_INVALID_FORMAT +
00481                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00482     }
00483 
00484     return( 0 );
00485 }
00486 
00487 /*
00488  * Parse one or more CRLs and add them to the chained list
00489  */
00490 int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen )
00491 {
00492 #if defined(MBEDTLS_PEM_PARSE_C)
00493     int ret;
00494     size_t use_len;
00495     mbedtls_pem_context pem;
00496     int is_pem = 0;
00497 
00498     if( chain == NULL || buf == NULL )
00499         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
00500 
00501     do
00502     {
00503         mbedtls_pem_init( &pem );
00504 
00505     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
00506     if( buflen == 0 || buf[buflen - 1] != '\0' )
00507         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
00508     else
00509         ret = mbedtls_pem_read_buffer( &pem,
00510                                "-----BEGIN X509 CRL-----",
00511                                "-----END X509 CRL-----",
00512                                buf, NULL, 0, &use_len );
00513 
00514         if( ret == 0 )
00515         {
00516             /*
00517              * Was PEM encoded
00518              */
00519             is_pem = 1;
00520 
00521             buflen -= use_len;
00522             buf += use_len;
00523 
00524             if( ( ret = mbedtls_x509_crl_parse_der( chain,
00525                                             pem.buf , pem.buflen  ) ) != 0 )
00526             {
00527                 return( ret );
00528             }
00529 
00530             mbedtls_pem_free( &pem );
00531         }
00532         else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
00533         {
00534             mbedtls_pem_free( &pem );
00535             return( ret );
00536         }
00537     }
00538     /* In the PEM case, buflen is 1 at the end, for the terminated NULL byte.
00539      * And a valid CRL cannot be less than 1 byte anyway. */
00540     while( is_pem && buflen > 1 );
00541 
00542     if( is_pem )
00543         return( 0 );
00544     else
00545 #endif /* MBEDTLS_PEM_PARSE_C */
00546         return( mbedtls_x509_crl_parse_der( chain, buf, buflen ) );
00547 }
00548 
00549 #if defined(MBEDTLS_FS_IO)
00550 /*
00551  * Load one or more CRLs and add them to the chained list
00552  */
00553 int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path )
00554 {
00555     int ret;
00556     size_t n;
00557     unsigned char *buf;
00558 
00559     if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
00560         return( ret );
00561 
00562     ret = mbedtls_x509_crl_parse( chain, buf, n );
00563 
00564     mbedtls_zeroize( buf, n );
00565     mbedtls_free( buf );
00566 
00567     return( ret );
00568 }
00569 #endif /* MBEDTLS_FS_IO */
00570 
00571 /*
00572  * Return an informational string about the certificate.
00573  */
00574 #define BEFORE_COLON    14
00575 #define BC              "14"
00576 /*
00577  * Return an informational string about the CRL.
00578  */
00579 int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix,
00580                    const mbedtls_x509_crl *crl )
00581 {
00582     int ret;
00583     size_t n;
00584     char *p;
00585     const mbedtls_x509_crl_entry *entry;
00586 
00587     p = buf;
00588     n = size;
00589 
00590     ret = mbedtls_snprintf( p, n, "%sCRL version   : %d",
00591                                prefix, crl->version );
00592     MBEDTLS_X509_SAFE_SNPRINTF;
00593 
00594     ret = mbedtls_snprintf( p, n, "\n%sissuer name   : ", prefix );
00595     MBEDTLS_X509_SAFE_SNPRINTF;
00596     ret = mbedtls_x509_dn_gets( p, n, &crl->issuer );
00597     MBEDTLS_X509_SAFE_SNPRINTF;
00598 
00599     ret = mbedtls_snprintf( p, n, "\n%sthis update   : " \
00600                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
00601                    crl->this_update.year, crl->this_update.mon,
00602                    crl->this_update.day,  crl->this_update.hour,
00603                    crl->this_update.min,  crl->this_update.sec );
00604     MBEDTLS_X509_SAFE_SNPRINTF;
00605 
00606     ret = mbedtls_snprintf( p, n, "\n%snext update   : " \
00607                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
00608                    crl->next_update.year, crl->next_update.mon,
00609                    crl->next_update.day,  crl->next_update.hour,
00610                    crl->next_update.min,  crl->next_update.sec );
00611     MBEDTLS_X509_SAFE_SNPRINTF;
00612 
00613     entry = &crl->entry;
00614 
00615     ret = mbedtls_snprintf( p, n, "\n%sRevoked certificates:",
00616                                prefix );
00617     MBEDTLS_X509_SAFE_SNPRINTF;
00618 
00619     while( entry != NULL && entry->raw.len != 0 )
00620     {
00621         ret = mbedtls_snprintf( p, n, "\n%sserial number: ",
00622                                prefix );
00623         MBEDTLS_X509_SAFE_SNPRINTF;
00624 
00625         ret = mbedtls_x509_serial_gets( p, n, &entry->serial );
00626         MBEDTLS_X509_SAFE_SNPRINTF;
00627 
00628         ret = mbedtls_snprintf( p, n, " revocation date: " \
00629                    "%04d-%02d-%02d %02d:%02d:%02d",
00630                    entry->revocation_date.year, entry->revocation_date.mon,
00631                    entry->revocation_date.day,  entry->revocation_date.hour,
00632                    entry->revocation_date.min,  entry->revocation_date.sec );
00633         MBEDTLS_X509_SAFE_SNPRINTF;
00634 
00635         entry = entry->next;
00636     }
00637 
00638     ret = mbedtls_snprintf( p, n, "\n%ssigned using  : ", prefix );
00639     MBEDTLS_X509_SAFE_SNPRINTF;
00640 
00641     ret = mbedtls_x509_sig_alg_gets( p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md,
00642                              crl->sig_opts );
00643     MBEDTLS_X509_SAFE_SNPRINTF;
00644 
00645     ret = mbedtls_snprintf( p, n, "\n" );
00646     MBEDTLS_X509_SAFE_SNPRINTF;
00647 
00648     return( (int) ( size - n ) );
00649 }
00650 
00651 /*
00652  * Initialize a CRL chain
00653  */
00654 void mbedtls_x509_crl_init( mbedtls_x509_crl *crl )
00655 {
00656     memset( crl, 0, sizeof(mbedtls_x509_crl) );
00657 }
00658 
00659 /*
00660  * Unallocate all CRL data
00661  */
00662 void mbedtls_x509_crl_free( mbedtls_x509_crl *crl )
00663 {
00664     mbedtls_x509_crl *crl_cur = crl;
00665     mbedtls_x509_crl *crl_prv;
00666     mbedtls_x509_name *name_cur;
00667     mbedtls_x509_name *name_prv;
00668     mbedtls_x509_crl_entry *entry_cur;
00669     mbedtls_x509_crl_entry *entry_prv;
00670 
00671     if( crl == NULL )
00672         return;
00673 
00674     do
00675     {
00676 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
00677         mbedtls_free( crl_cur->sig_opts );
00678 #endif
00679 
00680         name_cur = crl_cur->issuer.next;
00681         while( name_cur != NULL )
00682         {
00683             name_prv = name_cur;
00684             name_cur = name_cur->next;
00685             mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
00686             mbedtls_free( name_prv );
00687         }
00688 
00689         entry_cur = crl_cur->entry.next;
00690         while( entry_cur != NULL )
00691         {
00692             entry_prv = entry_cur;
00693             entry_cur = entry_cur->next;
00694             mbedtls_zeroize( entry_prv, sizeof( mbedtls_x509_crl_entry ) );
00695             mbedtls_free( entry_prv );
00696         }
00697 
00698         if( crl_cur->raw.p != NULL )
00699         {
00700             mbedtls_zeroize( crl_cur->raw.p, crl_cur->raw.len );
00701             mbedtls_free( crl_cur->raw.p );
00702         }
00703 
00704         crl_cur = crl_cur->next;
00705     }
00706     while( crl_cur != NULL );
00707 
00708     crl_cur = crl;
00709     do
00710     {
00711         crl_prv = crl_cur;
00712         crl_cur = crl_cur->next;
00713 
00714         mbedtls_zeroize( crl_prv, sizeof( mbedtls_x509_crl ) );
00715         if( crl_prv != crl )
00716             mbedtls_free( crl_prv );
00717     }
00718     while( crl_cur != NULL );
00719 }
00720 
00721 #endif /* MBEDTLS_X509_CRL_PARSE_C */