mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

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-2014, ARM Limited, All Rights Reserved
00005  *
00006  *  This file is part of mbed TLS (https://tls.mbed.org)
00007  *
00008  *  This program is free software; you can redistribute it and/or modify
00009  *  it under the terms of the GNU General Public License as published by
00010  *  the Free Software Foundation; either version 2 of the License, or
00011  *  (at your option) any later version.
00012  *
00013  *  This program is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *  GNU General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU General Public License along
00019  *  with this program; if not, write to the Free Software Foundation, Inc.,
00020  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00021  */
00022 /*
00023  *  The ITU-T X.509 standard defines a certificate format for PKI.
00024  *
00025  *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
00026  *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
00027  *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
00028  *
00029  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
00030  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
00031  */
00032 
00033 #if !defined(POLARSSL_CONFIG_FILE)
00034 #include "polarssl/config.h"
00035 #else
00036 #include POLARSSL_CONFIG_FILE
00037 #endif
00038 
00039 #if defined(POLARSSL_X509_CRL_PARSE_C)
00040 
00041 #include "polarssl/x509_crl.h"
00042 #include "polarssl/oid.h"
00043 
00044 #include <string.h>
00045 
00046 #if defined(POLARSSL_PEM_PARSE_C)
00047 #include "polarssl/pem.h"
00048 #endif
00049 
00050 #if defined(POLARSSL_PLATFORM_C)
00051 #include "polarssl/platform.h"
00052 #else
00053 #include <stdlib.h>
00054 #include <stdio.h>
00055 #define polarssl_free       free
00056 #define polarssl_malloc     malloc
00057 #define polarssl_snprintf   snprintf
00058 #endif
00059 
00060 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
00061 #include <windows.h>
00062 #else
00063 #include <time.h>
00064 #endif
00065 
00066 #if defined(POLARSSL_FS_IO) || defined(EFIX64) || defined(EFI32)
00067 #include <stdio.h>
00068 #endif
00069 
00070 /* Implementation that should never be optimized out by the compiler */
00071 static void polarssl_zeroize( void *v, size_t n ) {
00072     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
00073 }
00074 
00075 /*
00076  *  Version  ::=  INTEGER  {  v1(0), v2(1)  }
00077  */
00078 static int x509_crl_get_version( unsigned char **p,
00079                              const unsigned char *end,
00080                              int *ver )
00081 {
00082     int ret;
00083 
00084     if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
00085     {
00086         if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00087         {
00088             *ver = 0;
00089             return( 0 );
00090         }
00091 
00092         return( POLARSSL_ERR_X509_INVALID_VERSION + ret );
00093     }
00094 
00095     return( 0 );
00096 }
00097 
00098 /*
00099  * X.509 CRL v2 extensions (no extensions parsed yet.)
00100  */
00101 static int x509_get_crl_ext( unsigned char **p,
00102                              const unsigned char *end,
00103                              x509_buf *ext )
00104 {
00105     int ret;
00106     size_t len = 0;
00107 
00108     /* Get explicit tag */
00109     if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
00110     {
00111         if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00112             return( 0 );
00113 
00114         return( ret );
00115     }
00116 
00117     while( *p < end )
00118     {
00119         if( ( ret = asn1_get_tag( p, end, &len,
00120                 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00121             return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00122 
00123         *p += len;
00124     }
00125 
00126     if( *p != end )
00127         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00128                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00129 
00130     return( 0 );
00131 }
00132 
00133 /*
00134  * X.509 CRL v2 entry extensions (no extensions parsed yet.)
00135  */
00136 static int x509_get_crl_entry_ext( unsigned char **p,
00137                              const unsigned char *end,
00138                              x509_buf *ext )
00139 {
00140     int ret;
00141     size_t len = 0;
00142 
00143     /* OPTIONAL */
00144     if( end <= *p )
00145         return( 0 );
00146 
00147     ext->tag = **p;
00148     ext->p = *p;
00149 
00150     /*
00151      * Get CRL-entry extension sequence header
00152      * crlEntryExtensions      Extensions OPTIONAL  -- if present, MUST be v2
00153      */
00154     if( ( ret = asn1_get_tag( p, end, &ext->len,
00155             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00156     {
00157         if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00158         {
00159             ext->p = NULL;
00160             return( 0 );
00161         }
00162         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00163     }
00164 
00165     end = *p + ext->len;
00166 
00167     if( end != *p + ext->len )
00168         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00169                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00170 
00171     while( *p < end )
00172     {
00173         if( ( ret = asn1_get_tag( p, end, &len,
00174                 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00175             return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00176 
00177         *p += len;
00178     }
00179 
00180     if( *p != end )
00181         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00182                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00183 
00184     return( 0 );
00185 }
00186 
00187 /*
00188  * X.509 CRL Entries
00189  */
00190 static int x509_get_entries( unsigned char **p,
00191                              const unsigned char *end,
00192                              x509_crl_entry *entry )
00193 {
00194     int ret;
00195     size_t entry_len;
00196     x509_crl_entry *cur_entry = entry;
00197 
00198     if( *p == end )
00199         return( 0 );
00200 
00201     if( ( ret = asn1_get_tag( p, end, &entry_len,
00202             ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
00203     {
00204         if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00205             return( 0 );
00206 
00207         return( ret );
00208     }
00209 
00210     end = *p + entry_len;
00211 
00212     while( *p < end )
00213     {
00214         size_t len2;
00215         const unsigned char *end2;
00216 
00217         if( ( ret = asn1_get_tag( p, end, &len2,
00218                 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
00219         {
00220             return( ret );
00221         }
00222 
00223         cur_entry->raw.tag = **p;
00224         cur_entry->raw.p = *p;
00225         cur_entry->raw.len = len2;
00226         end2 = *p + len2;
00227 
00228         if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
00229             return( ret );
00230 
00231         if( ( ret = x509_get_time( p, end2,
00232                                    &cur_entry->revocation_date ) ) != 0 )
00233             return( ret );
00234 
00235         if( ( ret = x509_get_crl_entry_ext( p, end2,
00236                                             &cur_entry->entry_ext ) ) != 0 )
00237             return( ret );
00238 
00239         if( *p < end )
00240         {
00241             cur_entry->next = polarssl_malloc( sizeof( x509_crl_entry ) );
00242 
00243             if( cur_entry->next == NULL )
00244                 return( POLARSSL_ERR_X509_MALLOC_FAILED );
00245 
00246             memset( cur_entry->next, 0, sizeof( x509_crl_entry ) );
00247             cur_entry = cur_entry->next;
00248         }
00249     }
00250 
00251     return( 0 );
00252 }
00253 
00254 /*
00255  * Parse one  CRLs in DER format and append it to the chained list
00256  */
00257 int x509_crl_parse_der( x509_crl *chain,
00258                         const unsigned char *buf, size_t buflen )
00259 {
00260     int ret;
00261     size_t len;
00262     unsigned char *p, *end;
00263     x509_buf sig_params1, sig_params2;
00264     x509_crl *crl = chain;
00265 
00266     /*
00267      * Check for valid input
00268      */
00269     if( crl == NULL || buf == NULL )
00270         return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
00271 
00272     memset( &sig_params1, 0, sizeof( x509_buf ) );
00273     memset( &sig_params2, 0, sizeof( x509_buf ) );
00274 
00275     /*
00276      * Add new CRL on the end of the chain if needed.
00277      */
00278     while( crl->version != 0 && crl->next != NULL )
00279         crl = crl->next;
00280 
00281     if( crl->version != 0 && crl->next == NULL )
00282     {
00283         crl->next = polarssl_malloc( sizeof( x509_crl ) );
00284 
00285         if( crl->next == NULL )
00286         {
00287             x509_crl_free( crl );
00288             return( POLARSSL_ERR_X509_MALLOC_FAILED );
00289         }
00290 
00291         x509_crl_init( crl->next );
00292         crl = crl->next;
00293     }
00294 
00295     /*
00296      * Copy raw DER-encoded CRL
00297      */
00298     if( ( p = polarssl_malloc( buflen ) ) == NULL )
00299         return( POLARSSL_ERR_X509_MALLOC_FAILED );
00300 
00301     memcpy( p, buf, buflen );
00302 
00303     crl->raw.p = p;
00304     crl->raw.len = buflen;
00305 
00306     end = p + buflen;
00307 
00308     /*
00309      * CertificateList  ::=  SEQUENCE  {
00310      *      tbsCertList          TBSCertList,
00311      *      signatureAlgorithm   AlgorithmIdentifier,
00312      *      signatureValue       BIT STRING  }
00313      */
00314     if( ( ret = asn1_get_tag( &p, end, &len,
00315             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00316     {
00317         x509_crl_free( crl );
00318         return( POLARSSL_ERR_X509_INVALID_FORMAT );
00319     }
00320 
00321     if( len != (size_t) ( end - p ) )
00322     {
00323         x509_crl_free( crl );
00324         return( POLARSSL_ERR_X509_INVALID_FORMAT +
00325                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00326     }
00327 
00328     /*
00329      * TBSCertList  ::=  SEQUENCE  {
00330      */
00331     crl->tbs.p = p;
00332 
00333     if( ( ret = asn1_get_tag( &p, end, &len,
00334             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00335     {
00336         x509_crl_free( crl );
00337         return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
00338     }
00339 
00340     end = p + len;
00341     crl->tbs.len = end - crl->tbs.p;
00342 
00343     /*
00344      * Version  ::=  INTEGER  OPTIONAL {  v1(0), v2(1)  }
00345      *               -- if present, MUST be v2
00346      *
00347      * signature            AlgorithmIdentifier
00348      */
00349     if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
00350         ( ret = x509_get_alg( &p, end, &crl->sig_oid1, &sig_params1 ) ) != 0 )
00351     {
00352         x509_crl_free( crl );
00353         return( ret );
00354     }
00355 
00356     crl->version++;
00357 
00358     if( crl->version > 2 )
00359     {
00360         x509_crl_free( crl );
00361         return( POLARSSL_ERR_X509_UNKNOWN_VERSION );
00362     }
00363 
00364     if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &sig_params1,
00365                                   &crl->sig_md, &crl->sig_pk,
00366                                   &crl->sig_opts ) ) != 0 )
00367     {
00368         x509_crl_free( crl );
00369         return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG );
00370     }
00371 
00372     /*
00373      * issuer               Name
00374      */
00375     crl->issuer_raw.p = p;
00376 
00377     if( ( ret = asn1_get_tag( &p, end, &len,
00378             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00379     {
00380         x509_crl_free( crl );
00381         return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
00382     }
00383 
00384     if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
00385     {
00386         x509_crl_free( crl );
00387         return( ret );
00388     }
00389 
00390     crl->issuer_raw.len = p - crl->issuer_raw.p;
00391 
00392     /*
00393      * thisUpdate          Time
00394      * nextUpdate          Time OPTIONAL
00395      */
00396     if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
00397     {
00398         x509_crl_free( crl );
00399         return( ret );
00400     }
00401 
00402     if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
00403     {
00404         if( ret != ( POLARSSL_ERR_X509_INVALID_DATE +
00405                         POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
00406             ret != ( POLARSSL_ERR_X509_INVALID_DATE +
00407                         POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
00408         {
00409             x509_crl_free( crl );
00410             return( ret );
00411         }
00412     }
00413 
00414     /*
00415      * revokedCertificates    SEQUENCE OF SEQUENCE   {
00416      *      userCertificate        CertificateSerialNumber,
00417      *      revocationDate         Time,
00418      *      crlEntryExtensions     Extensions OPTIONAL
00419      *                                   -- if present, MUST be v2
00420      *                        } OPTIONAL
00421      */
00422     if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
00423     {
00424         x509_crl_free( crl );
00425         return( ret );
00426     }
00427 
00428     /*
00429      * crlExtensions          EXPLICIT Extensions OPTIONAL
00430      *                              -- if present, MUST be v2
00431      */
00432     if( crl->version == 2 )
00433     {
00434         ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
00435 
00436         if( ret != 0 )
00437         {
00438             x509_crl_free( crl );
00439             return( ret );
00440         }
00441     }
00442 
00443     if( p != end )
00444     {
00445         x509_crl_free( crl );
00446         return( POLARSSL_ERR_X509_INVALID_FORMAT +
00447                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00448     }
00449 
00450     end = crl->raw.p + crl->raw.len;
00451 
00452     /*
00453      *  signatureAlgorithm   AlgorithmIdentifier,
00454      *  signatureValue       BIT STRING
00455      */
00456     if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2, &sig_params2 ) ) != 0 )
00457     {
00458         x509_crl_free( crl );
00459         return( ret );
00460     }
00461 
00462     if( crl->sig_oid1.len != crl->sig_oid2.len ||
00463         memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 ||
00464         sig_params1.len != sig_params2.len ||
00465         ( sig_params1.len != 0 &&
00466           memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
00467     {
00468         x509_crl_free( crl );
00469         return( POLARSSL_ERR_X509_SIG_MISMATCH );
00470     }
00471 
00472     if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
00473     {
00474         x509_crl_free( crl );
00475         return( ret );
00476     }
00477 
00478     if( p != end )
00479     {
00480         x509_crl_free( crl );
00481         return( POLARSSL_ERR_X509_INVALID_FORMAT +
00482                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00483     }
00484 
00485     return( 0 );
00486 }
00487 
00488 /*
00489  * Parse one or more CRLs and add them to the chained list
00490  */
00491 int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
00492 {
00493 #if defined(POLARSSL_PEM_PARSE_C)
00494     int ret;
00495     size_t use_len;
00496     pem_context pem;
00497     int is_pem = 0;
00498 
00499     if( chain == NULL || buf == NULL )
00500         return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
00501 
00502     do
00503     {
00504         pem_init( &pem );
00505         ret = pem_read_buffer( &pem,
00506                                "-----BEGIN X509 CRL-----",
00507                                "-----END X509 CRL-----",
00508                                buf, NULL, 0, &use_len );
00509 
00510         if( ret == 0 )
00511         {
00512             /*
00513              * Was PEM encoded
00514              */
00515             is_pem = 1;
00516 
00517             buflen -= use_len;
00518             buf += use_len;
00519 
00520             if( ( ret = x509_crl_parse_der( chain,
00521                                             pem.buf , pem.buflen  ) ) != 0 )
00522             {
00523                 return( ret );
00524             }
00525 
00526             pem_free( &pem );
00527         }
00528         else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
00529         {
00530             pem_free( &pem );
00531             return( ret );
00532         }
00533     }
00534     while( is_pem && buflen > 0 );
00535 
00536     if( is_pem )
00537         return( 0 );
00538     else
00539 #endif /* POLARSSL_PEM_PARSE_C */
00540         return( x509_crl_parse_der( chain, buf, buflen ) );
00541 }
00542 
00543 #if defined(POLARSSL_FS_IO)
00544 /*
00545  * Load one or more CRLs and add them to the chained list
00546  */
00547 int x509_crl_parse_file( x509_crl *chain, const char *path )
00548 {
00549     int ret;
00550     size_t n;
00551     unsigned char *buf;
00552 
00553     if( ( ret = pk_load_file( path, &buf, &n ) ) != 0 )
00554         return( ret );
00555 
00556     ret = x509_crl_parse( chain, buf, n );
00557 
00558     polarssl_zeroize( buf, n + 1 );
00559     polarssl_free( buf );
00560 
00561     return( ret );
00562 }
00563 #endif /* POLARSSL_FS_IO */
00564 
00565 #if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
00566     !defined(EFI32)
00567 #include <stdarg.h>
00568 
00569 #if !defined vsnprintf
00570 #define vsnprintf _vsnprintf
00571 #endif // vsnprintf
00572 
00573 /*
00574  * Windows _snprintf and _vsnprintf are not compatible to linux versions.
00575  * Result value is not size of buffer needed, but -1 if no fit is possible.
00576  *
00577  * This fuction tries to 'fix' this by at least suggesting enlarging the
00578  * size by 20.
00579  */
00580 static int compat_snprintf( char *str, size_t size, const char *format, ... )
00581 {
00582     va_list ap;
00583     int res = -1;
00584 
00585     va_start( ap, format );
00586 
00587     res = vsnprintf( str, size, format, ap );
00588 
00589     va_end( ap );
00590 
00591     // No quick fix possible
00592     if( res < 0 )
00593         return( (int) size + 20 );
00594 
00595     return( res );
00596 }
00597 
00598 #define snprintf compat_snprintf
00599 #endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */
00600 
00601 #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL    -2
00602 
00603 #define SAFE_SNPRINTF()                             \
00604 {                                                   \
00605     if( ret == -1 )                                 \
00606         return( -1 );                               \
00607                                                     \
00608     if( (unsigned int) ret > n ) {                  \
00609         p[n - 1] = '\0';                            \
00610         return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \
00611     }                                               \
00612                                                     \
00613     n -= (unsigned int) ret;                        \
00614     p += (unsigned int) ret;                        \
00615 }
00616 
00617 /*
00618  * Return an informational string about the certificate.
00619  */
00620 #define BEFORE_COLON    14
00621 #define BC              "14"
00622 /*
00623  * Return an informational string about the CRL.
00624  */
00625 int x509_crl_info( char *buf, size_t size, const char *prefix,
00626                    const x509_crl *crl )
00627 {
00628     int ret;
00629     size_t n;
00630     char *p;
00631     const x509_crl_entry *entry;
00632 
00633     p = buf;
00634     n = size;
00635 
00636     ret = polarssl_snprintf( p, n, "%sCRL version   : %d",
00637                                prefix, crl->version );
00638     SAFE_SNPRINTF();
00639 
00640     ret = polarssl_snprintf( p, n, "\n%sissuer name   : ", prefix );
00641     SAFE_SNPRINTF();
00642     ret = x509_dn_gets( p, n, &crl->issuer );
00643     SAFE_SNPRINTF();
00644 
00645     ret = polarssl_snprintf( p, n, "\n%sthis update   : " \
00646                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
00647                    crl->this_update.year, crl->this_update.mon,
00648                    crl->this_update.day,  crl->this_update.hour,
00649                    crl->this_update.min,  crl->this_update.sec );
00650     SAFE_SNPRINTF();
00651 
00652     ret = polarssl_snprintf( p, n, "\n%snext update   : " \
00653                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
00654                    crl->next_update.year, crl->next_update.mon,
00655                    crl->next_update.day,  crl->next_update.hour,
00656                    crl->next_update.min,  crl->next_update.sec );
00657     SAFE_SNPRINTF();
00658 
00659     entry = &crl->entry;
00660 
00661     ret = polarssl_snprintf( p, n, "\n%sRevoked certificates:",
00662                                prefix );
00663     SAFE_SNPRINTF();
00664 
00665     while( entry != NULL && entry->raw.len != 0 )
00666     {
00667         ret = polarssl_snprintf( p, n, "\n%sserial number: ",
00668                                prefix );
00669         SAFE_SNPRINTF();
00670 
00671         ret = x509_serial_gets( p, n, &entry->serial );
00672         SAFE_SNPRINTF();
00673 
00674         ret = polarssl_snprintf( p, n, " revocation date: " \
00675                    "%04d-%02d-%02d %02d:%02d:%02d",
00676                    entry->revocation_date.year, entry->revocation_date.mon,
00677                    entry->revocation_date.day,  entry->revocation_date.hour,
00678                    entry->revocation_date.min,  entry->revocation_date.sec );
00679         SAFE_SNPRINTF();
00680 
00681         entry = entry->next;
00682     }
00683 
00684     ret = polarssl_snprintf( p, n, "\n%ssigned using  : ", prefix );
00685     SAFE_SNPRINTF();
00686 
00687     ret = x509_sig_alg_gets( p, n, &crl->sig_oid1, crl->sig_pk, crl->sig_md,
00688                              crl->sig_opts );
00689     SAFE_SNPRINTF();
00690 
00691     ret = polarssl_snprintf( p, n, "\n" );
00692     SAFE_SNPRINTF();
00693 
00694     return( (int) ( size - n ) );
00695 }
00696 
00697 /*
00698  * Initialize a CRL chain
00699  */
00700 void x509_crl_init( x509_crl *crl )
00701 {
00702     memset( crl, 0, sizeof(x509_crl) );
00703 }
00704 
00705 /*
00706  * Unallocate all CRL data
00707  */
00708 void x509_crl_free( x509_crl *crl )
00709 {
00710     x509_crl *crl_cur = crl;
00711     x509_crl *crl_prv;
00712     x509_name *name_cur;
00713     x509_name *name_prv;
00714     x509_crl_entry *entry_cur;
00715     x509_crl_entry *entry_prv;
00716 
00717     if( crl == NULL )
00718         return;
00719 
00720     do
00721     {
00722 #if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
00723         polarssl_free( crl_cur->sig_opts );
00724 #endif
00725 
00726         name_cur = crl_cur->issuer.next;
00727         while( name_cur != NULL )
00728         {
00729             name_prv = name_cur;
00730             name_cur = name_cur->next;
00731             polarssl_zeroize( name_prv, sizeof( x509_name ) );
00732             polarssl_free( name_prv );
00733         }
00734 
00735         entry_cur = crl_cur->entry.next;
00736         while( entry_cur != NULL )
00737         {
00738             entry_prv = entry_cur;
00739             entry_cur = entry_cur->next;
00740             polarssl_zeroize( entry_prv, sizeof( x509_crl_entry ) );
00741             polarssl_free( entry_prv );
00742         }
00743 
00744         if( crl_cur->raw.p != NULL )
00745         {
00746             polarssl_zeroize( crl_cur->raw.p, crl_cur->raw.len );
00747             polarssl_free( crl_cur->raw.p );
00748         }
00749 
00750         crl_cur = crl_cur->next;
00751     }
00752     while( crl_cur != NULL );
00753 
00754     crl_cur = crl;
00755     do
00756     {
00757         crl_prv = crl_cur;
00758         crl_cur = crl_cur->next;
00759 
00760         polarssl_zeroize( crl_prv, sizeof( x509_crl ) );
00761         if( crl_prv != crl )
00762             polarssl_free( crl_prv );
00763     }
00764     while( crl_cur != NULL );
00765 }
00766 
00767 #endif /* POLARSSL_X509_CRL_PARSE_C */
00768