STM32F7 Ethernet interface for nucleo STM32F767

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     if( crl->version < 0 || crl->version > 1 )
00356     {
00357         mbedtls_x509_crl_free( crl );
00358         return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
00359     }
00360 
00361     crl->version++;
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
00506         // string
00507         if( buflen == 0 || buf[buflen - 1] != '\0' )
00508             ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
00509         else
00510             ret = mbedtls_pem_read_buffer( &pem,
00511                                            "-----BEGIN X509 CRL-----",
00512                                            "-----END X509 CRL-----",
00513                                             buf, NULL, 0, &use_len );
00514 
00515         if( ret == 0 )
00516         {
00517             /*
00518              * Was PEM encoded
00519              */
00520             is_pem = 1;
00521 
00522             buflen -= use_len;
00523             buf += use_len;
00524 
00525             if( ( ret = mbedtls_x509_crl_parse_der( chain,
00526                                             pem.buf , pem.buflen  ) ) != 0 )
00527             {
00528                 mbedtls_pem_free( &pem );
00529                 return( ret );
00530             }
00531         }
00532         else if( is_pem )
00533         {
00534             mbedtls_pem_free( &pem );
00535             return( ret );
00536         }
00537 
00538         mbedtls_pem_free( &pem );
00539     }
00540     /* In the PEM case, buflen is 1 at the end, for the terminated NULL byte.
00541      * And a valid CRL cannot be less than 1 byte anyway. */
00542     while( is_pem && buflen > 1 );
00543 
00544     if( is_pem )
00545         return( 0 );
00546     else
00547 #endif /* MBEDTLS_PEM_PARSE_C */
00548         return( mbedtls_x509_crl_parse_der( chain, buf, buflen ) );
00549 }
00550 
00551 #if defined(MBEDTLS_FS_IO)
00552 /*
00553  * Load one or more CRLs and add them to the chained list
00554  */
00555 int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path )
00556 {
00557     int ret;
00558     size_t n;
00559     unsigned char *buf;
00560 
00561     if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
00562         return( ret );
00563 
00564     ret = mbedtls_x509_crl_parse( chain, buf, n );
00565 
00566     mbedtls_zeroize( buf, n );
00567     mbedtls_free( buf );
00568 
00569     return( ret );
00570 }
00571 #endif /* MBEDTLS_FS_IO */
00572 
00573 /*
00574  * Return an informational string about the certificate.
00575  */
00576 #define BEFORE_COLON    14
00577 #define BC              "14"
00578 /*
00579  * Return an informational string about the CRL.
00580  */
00581 int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix,
00582                    const mbedtls_x509_crl *crl )
00583 {
00584     int ret;
00585     size_t n;
00586     char *p;
00587     const mbedtls_x509_crl_entry *entry;
00588 
00589     p = buf;
00590     n = size;
00591 
00592     ret = mbedtls_snprintf( p, n, "%sCRL version   : %d",
00593                                prefix, crl->version );
00594     MBEDTLS_X509_SAFE_SNPRINTF;
00595 
00596     ret = mbedtls_snprintf( p, n, "\n%sissuer name   : ", prefix );
00597     MBEDTLS_X509_SAFE_SNPRINTF;
00598     ret = mbedtls_x509_dn_gets( p, n, &crl->issuer );
00599     MBEDTLS_X509_SAFE_SNPRINTF;
00600 
00601     ret = mbedtls_snprintf( p, n, "\n%sthis update   : " \
00602                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
00603                    crl->this_update.year, crl->this_update.mon,
00604                    crl->this_update.day,  crl->this_update.hour,
00605                    crl->this_update.min,  crl->this_update.sec );
00606     MBEDTLS_X509_SAFE_SNPRINTF;
00607 
00608     ret = mbedtls_snprintf( p, n, "\n%snext update   : " \
00609                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
00610                    crl->next_update.year, crl->next_update.mon,
00611                    crl->next_update.day,  crl->next_update.hour,
00612                    crl->next_update.min,  crl->next_update.sec );
00613     MBEDTLS_X509_SAFE_SNPRINTF;
00614 
00615     entry = &crl->entry;
00616 
00617     ret = mbedtls_snprintf( p, n, "\n%sRevoked certificates:",
00618                                prefix );
00619     MBEDTLS_X509_SAFE_SNPRINTF;
00620 
00621     while( entry != NULL && entry->raw.len != 0 )
00622     {
00623         ret = mbedtls_snprintf( p, n, "\n%sserial number: ",
00624                                prefix );
00625         MBEDTLS_X509_SAFE_SNPRINTF;
00626 
00627         ret = mbedtls_x509_serial_gets( p, n, &entry->serial );
00628         MBEDTLS_X509_SAFE_SNPRINTF;
00629 
00630         ret = mbedtls_snprintf( p, n, " revocation date: " \
00631                    "%04d-%02d-%02d %02d:%02d:%02d",
00632                    entry->revocation_date.year, entry->revocation_date.mon,
00633                    entry->revocation_date.day,  entry->revocation_date.hour,
00634                    entry->revocation_date.min,  entry->revocation_date.sec );
00635         MBEDTLS_X509_SAFE_SNPRINTF;
00636 
00637         entry = entry->next;
00638     }
00639 
00640     ret = mbedtls_snprintf( p, n, "\n%ssigned using  : ", prefix );
00641     MBEDTLS_X509_SAFE_SNPRINTF;
00642 
00643     ret = mbedtls_x509_sig_alg_gets( p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md,
00644                              crl->sig_opts );
00645     MBEDTLS_X509_SAFE_SNPRINTF;
00646 
00647     ret = mbedtls_snprintf( p, n, "\n" );
00648     MBEDTLS_X509_SAFE_SNPRINTF;
00649 
00650     return( (int) ( size - n ) );
00651 }
00652 
00653 /*
00654  * Initialize a CRL chain
00655  */
00656 void mbedtls_x509_crl_init( mbedtls_x509_crl *crl )
00657 {
00658     memset( crl, 0, sizeof(mbedtls_x509_crl) );
00659 }
00660 
00661 /*
00662  * Unallocate all CRL data
00663  */
00664 void mbedtls_x509_crl_free( mbedtls_x509_crl *crl )
00665 {
00666     mbedtls_x509_crl *crl_cur = crl;
00667     mbedtls_x509_crl *crl_prv;
00668     mbedtls_x509_name *name_cur;
00669     mbedtls_x509_name *name_prv;
00670     mbedtls_x509_crl_entry *entry_cur;
00671     mbedtls_x509_crl_entry *entry_prv;
00672 
00673     if( crl == NULL )
00674         return;
00675 
00676     do
00677     {
00678 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
00679         mbedtls_free( crl_cur->sig_opts );
00680 #endif
00681 
00682         name_cur = crl_cur->issuer.next;
00683         while( name_cur != NULL )
00684         {
00685             name_prv = name_cur;
00686             name_cur = name_cur->next;
00687             mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
00688             mbedtls_free( name_prv );
00689         }
00690 
00691         entry_cur = crl_cur->entry.next;
00692         while( entry_cur != NULL )
00693         {
00694             entry_prv = entry_cur;
00695             entry_cur = entry_cur->next;
00696             mbedtls_zeroize( entry_prv, sizeof( mbedtls_x509_crl_entry ) );
00697             mbedtls_free( entry_prv );
00698         }
00699 
00700         if( crl_cur->raw.p != NULL )
00701         {
00702             mbedtls_zeroize( crl_cur->raw.p, crl_cur->raw.len );
00703             mbedtls_free( crl_cur->raw.p );
00704         }
00705 
00706         crl_cur = crl_cur->next;
00707     }
00708     while( crl_cur != NULL );
00709 
00710     crl_cur = crl;
00711     do
00712     {
00713         crl_prv = crl_cur;
00714         crl_cur = crl_cur->next;
00715 
00716         mbedtls_zeroize( crl_prv, sizeof( mbedtls_x509_crl ) );
00717         if( crl_prv != crl )
00718             mbedtls_free( crl_prv );
00719     }
00720     while( crl_cur != NULL );
00721 }
00722 
00723 #endif /* MBEDTLS_X509_CRL_PARSE_C */