Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers x509.c Source File

x509.c

00001 /*
00002  *  X.509 certificate and private key decoding
00003  *
00004  *  Copyright (C) 2006-2014, Brainspark B.V.
00005  *
00006  *  This file is part of PolarSSL (http://www.polarssl.org)
00007  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
00008  *
00009  *  All rights reserved.
00010  *
00011  *  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public License along
00022  *  with this program; if not, write to the Free Software Foundation, Inc.,
00023  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00024  */
00025 /*
00026  *  The ITU-T X.509 standard defines a certificate format for PKI.
00027  *
00028  *  http://www.ietf.org/rfc/rfc3279.txt
00029  *  http://www.ietf.org/rfc/rfc3280.txt
00030  *
00031  *  ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
00032  *
00033  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
00034  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
00035  */
00036 
00037 #if !defined(POLARSSL_CONFIG_FILE)
00038 #include "polarssl/config.h"
00039 #else
00040 #include POLARSSL_CONFIG_FILE
00041 #endif
00042 
00043 #if defined(POLARSSL_X509_USE_C)
00044 
00045 #include "polarssl/x509.h"
00046 #include "polarssl/asn1.h"
00047 #include "polarssl/oid.h"
00048 #if defined(POLARSSL_PEM_PARSE_C)
00049 #include "polarssl/pem.h"
00050 #endif
00051 
00052 #if defined(POLARSSL_PLATFORM_C)
00053 #include "polarssl/platform.h"
00054 #else
00055 #define polarssl_printf     printf
00056 #define polarssl_malloc     malloc
00057 #define polarssl_free       free
00058 #endif
00059 
00060 #include <string.h>
00061 #include <stdlib.h>
00062 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
00063 #include <windows.h>
00064 #else
00065 #include <time.h>
00066 #endif
00067 
00068 #if defined(EFIX64) || defined(EFI32)
00069 #include <stdio.h>
00070 #endif
00071 
00072 #if defined(POLARSSL_FS_IO)
00073 #include <stdio.h>
00074 #if !defined(_WIN32)
00075 #include <sys/types.h>
00076 #include <sys/stat.h>
00077 #include <dirent.h>
00078 #endif
00079 #endif
00080 
00081 /*
00082  *  CertificateSerialNumber  ::=  INTEGER
00083  */
00084 int x509_get_serial( unsigned char **p, const unsigned char *end,
00085                      x509_buf *serial )
00086 {
00087     int ret;
00088 
00089     if( ( end - *p ) < 1 )
00090         return( POLARSSL_ERR_X509_INVALID_SERIAL +
00091                 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00092 
00093     if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
00094         **p !=   ASN1_INTEGER )
00095         return( POLARSSL_ERR_X509_INVALID_SERIAL +
00096                 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00097 
00098     serial->tag = *(*p)++;
00099 
00100     if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
00101         return( POLARSSL_ERR_X509_INVALID_SERIAL + ret );
00102 
00103     serial->p = *p;
00104     *p += serial->len;
00105 
00106     return( 0 );
00107 }
00108 
00109 /* Get an algorithm identifier without parameters (eg for signatures)
00110  *
00111  *  AlgorithmIdentifier  ::=  SEQUENCE  {
00112  *       algorithm               OBJECT IDENTIFIER,
00113  *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
00114  */
00115 int x509_get_alg_null( unsigned char **p, const unsigned char *end,
00116                        x509_buf *alg )
00117 {
00118     int ret;
00119 
00120     if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 )
00121         return( POLARSSL_ERR_X509_INVALID_ALG + ret );
00122 
00123     return( 0 );
00124 }
00125 
00126 /*
00127  *  AttributeTypeAndValue ::= SEQUENCE {
00128  *    type     AttributeType,
00129  *    value    AttributeValue }
00130  *
00131  *  AttributeType ::= OBJECT IDENTIFIER
00132  *
00133  *  AttributeValue ::= ANY DEFINED BY AttributeType
00134  */
00135 static int x509_get_attr_type_value( unsigned char **p,
00136                                      const unsigned char *end,
00137                                      x509_name *cur )
00138 {
00139     int ret;
00140     size_t len;
00141     x509_buf *oid;
00142     x509_buf *val;
00143 
00144     if( ( ret = asn1_get_tag( p, end, &len,
00145             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00146         return( POLARSSL_ERR_X509_INVALID_NAME + ret );
00147 
00148     if( ( end - *p ) < 1 )
00149         return( POLARSSL_ERR_X509_INVALID_NAME +
00150                 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00151 
00152     oid = &cur->oid;
00153     oid->tag = **p;
00154 
00155     if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
00156         return( POLARSSL_ERR_X509_INVALID_NAME + ret );
00157 
00158     oid->p = *p;
00159     *p += oid->len;
00160 
00161     if( ( end - *p ) < 1 )
00162         return( POLARSSL_ERR_X509_INVALID_NAME +
00163                 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00164 
00165     if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING      &&
00166         **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
00167         **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
00168         return( POLARSSL_ERR_X509_INVALID_NAME +
00169                 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00170 
00171     val = &cur->val;
00172     val->tag = *(*p)++;
00173 
00174     if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
00175         return( POLARSSL_ERR_X509_INVALID_NAME + ret );
00176 
00177     val->p = *p;
00178     *p += val->len;
00179 
00180     cur->next = NULL;
00181 
00182     return( 0 );
00183 }
00184 
00185 /*
00186  *  RelativeDistinguishedName ::=
00187  *    SET OF AttributeTypeAndValue
00188  *
00189  *  AttributeTypeAndValue ::= SEQUENCE {
00190  *    type     AttributeType,
00191  *    value    AttributeValue }
00192  *
00193  *  AttributeType ::= OBJECT IDENTIFIER
00194  *
00195  *  AttributeValue ::= ANY DEFINED BY AttributeType
00196  */
00197 int x509_get_name( unsigned char **p, const unsigned char *end,
00198                    x509_name *cur )
00199 {
00200     int ret;
00201     size_t len;
00202     const unsigned char *end2;
00203     x509_name *use;
00204 
00205     if( ( ret = asn1_get_tag( p, end, &len,
00206             ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
00207         return( POLARSSL_ERR_X509_INVALID_NAME + ret );
00208 
00209     end2 = end;
00210     end  = *p + len;
00211     use = cur;
00212 
00213     do
00214     {
00215         if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
00216             return( ret );
00217 
00218         if( *p != end )
00219         {
00220             use->next = (x509_name *) polarssl_malloc(
00221                     sizeof( x509_name ) );
00222 
00223             if( use->next == NULL )
00224                 return( POLARSSL_ERR_X509_MALLOC_FAILED );
00225 
00226             memset( use->next, 0, sizeof( x509_name ) );
00227 
00228             use = use->next;
00229         }
00230     }
00231     while( *p != end );
00232 
00233     /*
00234      * recurse until end of SEQUENCE is reached
00235      */
00236     if( *p == end2 )
00237         return( 0 );
00238 
00239     cur->next = (x509_name *) polarssl_malloc(
00240          sizeof( x509_name ) );
00241 
00242     if( cur->next == NULL )
00243         return( POLARSSL_ERR_X509_MALLOC_FAILED );
00244 
00245     memset( cur->next, 0, sizeof( x509_name ) );
00246 
00247     return( x509_get_name( p, end2, cur->next ) );
00248 }
00249 
00250 /*
00251  *  Time ::= CHOICE {
00252  *       utcTime        UTCTime,
00253  *       generalTime    GeneralizedTime }
00254  */
00255 int x509_get_time( unsigned char **p, const unsigned char *end,
00256                    x509_time *time )
00257 {
00258     int ret;
00259     size_t len;
00260     char date[64];
00261     unsigned char tag;
00262 
00263     if( ( end - *p ) < 1 )
00264         return( POLARSSL_ERR_X509_INVALID_DATE +
00265                 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00266 
00267     tag = **p;
00268 
00269     if ( tag == ASN1_UTC_TIME )
00270     {
00271         (*p)++;
00272         ret = asn1_get_len( p, end, &len );
00273 
00274         if( ret != 0 )
00275             return( POLARSSL_ERR_X509_INVALID_DATE + ret );
00276 
00277         memset( date,  0, sizeof( date ) );
00278         memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
00279                 len : sizeof( date ) - 1 );
00280 
00281         if( sscanf( date, "%2d%2d%2d%2d%2d%2dZ",
00282                     &time->year, &time->mon, &time->day,
00283                     &time->hour, &time->min, &time->sec ) < 5 )
00284             return( POLARSSL_ERR_X509_INVALID_DATE );
00285 
00286         time->year +=  100 * ( time->year < 50 );
00287         time->year += 1900;
00288 
00289         *p += len;
00290 
00291         return( 0 );
00292     }
00293     else if ( tag == ASN1_GENERALIZED_TIME )
00294     {
00295         (*p)++;
00296         ret = asn1_get_len( p, end, &len );
00297 
00298         if( ret != 0 )
00299             return( POLARSSL_ERR_X509_INVALID_DATE + ret );
00300 
00301         memset( date,  0, sizeof( date ) );
00302         memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
00303                 len : sizeof( date ) - 1 );
00304 
00305         if( sscanf( date, "%4d%2d%2d%2d%2d%2dZ",
00306                     &time->year, &time->mon, &time->day,
00307                     &time->hour, &time->min, &time->sec ) < 5 )
00308             return( POLARSSL_ERR_X509_INVALID_DATE );
00309 
00310         *p += len;
00311 
00312         return( 0 );
00313     }
00314     else
00315         return( POLARSSL_ERR_X509_INVALID_DATE +
00316                 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00317 }
00318 
00319 int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig )
00320 {
00321     int ret;
00322     size_t len;
00323 
00324     if( ( end - *p ) < 1 )
00325         return( POLARSSL_ERR_X509_INVALID_SIGNATURE +
00326                 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00327 
00328     sig->tag = **p;
00329 
00330     if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
00331         return( POLARSSL_ERR_X509_INVALID_SIGNATURE + ret );
00332 
00333     sig->len = len;
00334     sig->p = *p;
00335 
00336     *p += len;
00337 
00338     return( 0 );
00339 }
00340 
00341 int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
00342                       pk_type_t *pk_alg )
00343 {
00344     int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
00345 
00346     if( ret != 0 )
00347         return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG + ret );
00348 
00349     return( 0 );
00350 }
00351 
00352 /*
00353  * X.509 Extensions (No parsing of extensions, pointer should
00354  * be either manually updated or extensions should be parsed!
00355  */
00356 int x509_get_ext( unsigned char **p, const unsigned char *end,
00357                   x509_buf *ext, int tag )
00358 {
00359     int ret;
00360     size_t len;
00361 
00362     if( *p == end )
00363         return( 0 );
00364 
00365     ext->tag = **p;
00366 
00367     if( ( ret = asn1_get_tag( p, end, &ext->len,
00368             ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
00369         return( ret );
00370 
00371     ext->p = *p;
00372     end = *p + ext->len;
00373 
00374     /*
00375      * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
00376      *
00377      * Extension  ::=  SEQUENCE  {
00378      *      extnID      OBJECT IDENTIFIER,
00379      *      critical    BOOLEAN DEFAULT FALSE,
00380      *      extnValue   OCTET STRING  }
00381      */
00382     if( ( ret = asn1_get_tag( p, end, &len,
00383             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00384         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00385 
00386     if( end != *p + len )
00387         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00388                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00389 
00390     return( 0 );
00391 }
00392 
00393 #if defined(POLARSSL_FS_IO)
00394 /*
00395  * Load all data from a file into a given buffer.
00396  */
00397 int x509_load_file( const char *path, unsigned char **buf, size_t *n )
00398 {
00399     FILE *f;
00400     long size;
00401 
00402     if( ( f = fopen( path, "rb" ) ) == NULL )
00403         return( POLARSSL_ERR_X509_FILE_IO_ERROR );
00404 
00405     fseek( f, 0, SEEK_END );
00406     if( ( size = ftell( f ) ) == -1 )
00407     {
00408         fclose( f );
00409         return( POLARSSL_ERR_X509_FILE_IO_ERROR );
00410     }
00411     fseek( f, 0, SEEK_SET );
00412 
00413     *n = (size_t) size;
00414 
00415     if( *n + 1 == 0 ||
00416         ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
00417     {
00418         fclose( f );
00419         return( POLARSSL_ERR_X509_MALLOC_FAILED );
00420     }
00421 
00422     if( fread( *buf, 1, *n, f ) != *n )
00423     {
00424         fclose( f );
00425         polarssl_free( *buf );
00426         return( POLARSSL_ERR_X509_FILE_IO_ERROR );
00427     }
00428 
00429     fclose( f );
00430 
00431     (*buf)[*n] = '\0';
00432 
00433     return( 0 );
00434 }
00435 #endif /* POLARSSL_FS_IO */
00436 
00437 #if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
00438     !defined(EFI32)
00439 #include <stdarg.h>
00440 
00441 #if !defined vsnprintf
00442 #define vsnprintf _vsnprintf
00443 #endif // vsnprintf
00444 
00445 /*
00446  * Windows _snprintf and _vsnprintf are not compatible to linux versions.
00447  * Result value is not size of buffer needed, but -1 if no fit is possible.
00448  *
00449  * This fuction tries to 'fix' this by at least suggesting enlarging the
00450  * size by 20.
00451  */
00452 static int compat_snprintf(char *str, size_t size, const char *format, ...)
00453 {
00454     va_list ap;
00455     int res = -1;
00456 
00457     va_start( ap, format );
00458 
00459     res = vsnprintf( str, size, format, ap );
00460 
00461     va_end( ap );
00462 
00463     // No quick fix possible
00464     if ( res < 0 )
00465         return( (int) size + 20 );
00466 
00467     return res;
00468 }
00469 
00470 #define snprintf compat_snprintf
00471 #endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */
00472 
00473 #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL    -2
00474 
00475 #define SAFE_SNPRINTF()                         \
00476 {                                               \
00477     if( ret == -1 )                             \
00478         return( -1 );                           \
00479                                                 \
00480     if ( (unsigned int) ret > n ) {             \
00481         p[n - 1] = '\0';                        \
00482         return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
00483     }                                           \
00484                                                 \
00485     n -= (unsigned int) ret;                    \
00486     p += (unsigned int) ret;                    \
00487 }
00488 
00489 /*
00490  * Store the name in printable form into buf; no more
00491  * than size characters will be written
00492  */
00493 int x509_dn_gets( char *buf, size_t size, const x509_name *dn )
00494 {
00495     int ret;
00496     size_t i, n;
00497     unsigned char c;
00498     const x509_name *name;
00499     const char *short_name = NULL;
00500     char s[128], *p;
00501 
00502     memset( s, 0, sizeof( s ) );
00503 
00504     name = dn;
00505     p = buf;
00506     n = size;
00507 
00508     while( name != NULL )
00509     {
00510         if( !name->oid.p )
00511         {
00512             name = name->next;
00513             continue;
00514         }
00515 
00516         if( name != dn )
00517         {
00518             ret = snprintf( p, n, ", " );
00519             SAFE_SNPRINTF();
00520         }
00521 
00522         ret = oid_get_attr_short_name( &name->oid, &short_name );
00523 
00524         if( ret == 0 )
00525             ret = snprintf( p, n, "%s=", short_name );
00526         else
00527             ret = snprintf( p, n, "\?\?=" );
00528         SAFE_SNPRINTF();
00529 
00530         for( i = 0; i < name->val.len; i++ )
00531         {
00532             if( i >= sizeof( s ) - 1 )
00533                 break;
00534 
00535             c = name->val.p[i];
00536             if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
00537                  s[i] = '?';
00538             else s[i] = c;
00539         }
00540         s[i] = '\0';
00541         ret = snprintf( p, n, "%s", s );
00542         SAFE_SNPRINTF();
00543         name = name->next;
00544     }
00545 
00546     return( (int) ( size - n ) );
00547 }
00548 
00549 /*
00550  * Store the serial in printable form into buf; no more
00551  * than size characters will be written
00552  */
00553 int x509_serial_gets( char *buf, size_t size, const x509_buf *serial )
00554 {
00555     int ret;
00556     size_t i, n, nr;
00557     char *p;
00558 
00559     p = buf;
00560     n = size;
00561 
00562     nr = ( serial->len <= 32 )
00563         ? serial->len  : 28;
00564 
00565     for( i = 0; i < nr; i++ )
00566     {
00567         if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
00568             continue;
00569 
00570         ret = snprintf( p, n, "%02X%s",
00571                 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
00572         SAFE_SNPRINTF();
00573     }
00574 
00575     if( nr != serial->len )
00576     {
00577         ret = snprintf( p, n, "...." );
00578         SAFE_SNPRINTF();
00579     }
00580 
00581     return( (int) ( size - n ) );
00582 }
00583 
00584 /*
00585  * Helper for writing "RSA key size", "EC key size", etc
00586  */
00587 int x509_key_size_helper( char *buf, size_t size, const char *name )
00588 {
00589     char *p = buf;
00590     size_t n = size;
00591     int ret;
00592 
00593     if( strlen( name ) + sizeof( " key size" ) > size )
00594         return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;
00595 
00596     ret = snprintf( p, n, "%s key size", name );
00597     SAFE_SNPRINTF();
00598 
00599     return( 0 );
00600 }
00601 
00602 /*
00603  * Return an informational string describing the given OID
00604  */
00605 const char *x509_oid_get_description( x509_buf *oid )
00606 {
00607     const char *desc = NULL;
00608     int ret;
00609 
00610     ret = oid_get_extended_key_usage( oid, &desc );
00611 
00612     if( ret != 0 )
00613         return( NULL );
00614 
00615     return( desc );
00616 }
00617 
00618 /* Return the x.y.z.... style numeric string for the given OID */
00619 int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
00620 {
00621     return oid_get_numeric_string( buf, size, oid );
00622 }
00623 
00624 /*
00625  * Return 0 if the x509_time is still valid, or 1 otherwise.
00626  */
00627 #if defined(POLARSSL_HAVE_TIME)
00628 
00629 static void x509_get_current_time( x509_time *now )
00630 {
00631 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
00632     SYSTEMTIME st;
00633 
00634     GetSystemTime(&st);
00635 
00636     now->year = st.wYear;
00637     now->mon = st.wMonth;
00638     now->day = st.wDay;
00639     now->hour = st.wHour;
00640     now->min = st.wMinute;
00641     now->sec = st.wSecond;
00642 #else
00643     struct tm lt;
00644     time_t tt;
00645 
00646     tt = time( NULL );
00647     gmtime_r( &tt, &lt );
00648 
00649     now->year = lt.tm_year + 1900;
00650     now->mon = lt.tm_mon + 1;
00651     now->day = lt.tm_mday;
00652     now->hour = lt.tm_hour;
00653     now->min = lt.tm_min;
00654     now->sec = lt.tm_sec;
00655 #endif /* _WIN32 && !EFIX64 && !EFI32 */
00656 }
00657 
00658 /*
00659  * Return 0 if before <= after, 1 otherwise
00660  */
00661 static int x509_check_time( const x509_time *before, const x509_time *after )
00662 {
00663     if( before->year  > after->year )
00664         return( 1 );
00665 
00666     if( before->year == after->year &&
00667         before->mon   > after->mon )
00668         return( 1 );
00669 
00670     if( before->year == after->year &&
00671         before->mon  == after->mon  &&
00672         before->day   > after->day )
00673         return( 1 );
00674 
00675     if( before->year == after->year &&
00676         before->mon  == after->mon  &&
00677         before->day  == after->day  &&
00678         before->hour  > after->hour )
00679         return( 1 );
00680 
00681     if( before->year == after->year &&
00682         before->mon  == after->mon  &&
00683         before->day  == after->day  &&
00684         before->hour == after->hour &&
00685         before->min   > after->min  )
00686         return( 1 );
00687 
00688     if( before->year == after->year &&
00689         before->mon  == after->mon  &&
00690         before->day  == after->day  &&
00691         before->hour == after->hour &&
00692         before->min  == after->min  &&
00693         before->sec   > after->sec  )
00694         return( 1 );
00695 
00696     return( 0 );
00697 }
00698 
00699 int x509_time_expired( const x509_time *to )
00700 {
00701     x509_time now;
00702 
00703     x509_get_current_time( &now );
00704 
00705     return( x509_check_time( &now, to ) );
00706 }
00707 
00708 int x509_time_future( const x509_time *from )
00709 {
00710     x509_time now;
00711 
00712     x509_get_current_time( &now );
00713 
00714     return( x509_check_time( from, &now ) );
00715 }
00716 
00717 #else  /* POLARSSL_HAVE_TIME */
00718 
00719 int x509_time_expired( const x509_time *to )
00720 {
00721     ((void) to);
00722     return( 0 );
00723 }
00724 
00725 int x509_time_future( const x509_time *from )
00726 {
00727     ((void) from);
00728     return( 0 );
00729 }
00730 #endif /* POLARSSL_HAVE_TIME */
00731 
00732 #if defined(POLARSSL_SELF_TEST)
00733 
00734 #include "polarssl/x509_crt.h"
00735 #include "polarssl/certs.h"
00736 
00737 /*
00738  * Checkup routine
00739  */
00740 int x509_self_test( int verbose )
00741 {
00742 #if defined(POLARSSL_CERTS_C) && defined(POLARSSL_SHA1_C)
00743     int ret;
00744     int flags;
00745     x509_crt cacert;
00746     x509_crt clicert;
00747 
00748     if( verbose != 0 )
00749         polarssl_printf( "  X.509 certificate load: " );
00750 
00751     x509_crt_init( &clicert );
00752 
00753     ret = x509_crt_parse( &clicert, (const unsigned char *) test_cli_crt,
00754                           strlen( test_cli_crt ) );
00755     if( ret != 0 )
00756     {
00757         if( verbose != 0 )
00758             polarssl_printf( "failed\n" );
00759 
00760         return( ret );
00761     }
00762 
00763     x509_crt_init( &cacert );
00764 
00765     ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_crt,
00766                           strlen( test_ca_crt ) );
00767     if( ret != 0 )
00768     {
00769         if( verbose != 0 )
00770             polarssl_printf( "failed\n" );
00771 
00772         return( ret );
00773     }
00774 
00775     if( verbose != 0 )
00776         polarssl_printf( "passed\n  X.509 signature verify: ");
00777 
00778     ret = x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
00779     if( ret != 0 )
00780     {
00781         if( verbose != 0 )
00782             polarssl_printf( "failed\n" );
00783 
00784         polarssl_printf("ret = %d, &flags = %04x\n", ret, flags);
00785 
00786         return( ret );
00787     }
00788 
00789     if( verbose != 0 )
00790         polarssl_printf( "passed\n\n");
00791 
00792     x509_crt_free( &cacert  );
00793     x509_crt_free( &clicert );
00794 
00795     return( 0 );
00796 #else
00797     ((void) verbose);
00798     return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
00799 #endif /* POLARSSL_CERTS_C && POLARSSL_SHA1_C */
00800 }
00801 
00802 #endif /* POLARSSL_SELF_TEST */
00803 
00804 #endif /* POLARSSL_X509_USE_C */
00805 
00806