mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers x509.c Source File

x509.c

00001 /*
00002  *  X.509 common functions for parsing and verification
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_USE_C)
00040 
00041 #include "polarssl/x509.h"
00042 #include "polarssl/asn1.h"
00043 #include "polarssl/oid.h"
00044 
00045 #include <stdio.h>
00046 #include <string.h>
00047 
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 #include <stdio.h>
00056 #include <stdlib.h>
00057 #define polarssl_free       free
00058 #define polarssl_malloc     malloc
00059 #define polarssl_printf     printf
00060 #define polarssl_snprintf   snprintf
00061 #endif
00062 
00063 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
00064 #include <windows.h>
00065 #else
00066 #include <time.h>
00067 #endif
00068 
00069 #if defined(POLARSSL_FS_IO)
00070 #include <stdio.h>
00071 #if !defined(_WIN32)
00072 #include <sys/types.h>
00073 #include <sys/stat.h>
00074 #include <dirent.h>
00075 #endif
00076 #endif
00077 
00078 #define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); }
00079 
00080 /*
00081  *  CertificateSerialNumber  ::=  INTEGER
00082  */
00083 int x509_get_serial( unsigned char **p, const unsigned char *end,
00084                      x509_buf *serial )
00085 {
00086     int ret;
00087 
00088     if( ( end - *p ) < 1 )
00089         return( POLARSSL_ERR_X509_INVALID_SERIAL +
00090                 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00091 
00092     if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
00093         **p !=   ASN1_INTEGER )
00094         return( POLARSSL_ERR_X509_INVALID_SERIAL +
00095                 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00096 
00097     serial->tag = *(*p)++;
00098 
00099     if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
00100         return( POLARSSL_ERR_X509_INVALID_SERIAL + ret );
00101 
00102     serial->p = *p;
00103     *p += serial->len;
00104 
00105     return( 0 );
00106 }
00107 
00108 /* Get an algorithm identifier without parameters (eg for signatures)
00109  *
00110  *  AlgorithmIdentifier  ::=  SEQUENCE  {
00111  *       algorithm               OBJECT IDENTIFIER,
00112  *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
00113  */
00114 int x509_get_alg_null( unsigned char **p, const unsigned char *end,
00115                        x509_buf *alg )
00116 {
00117     int ret;
00118 
00119     if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 )
00120         return( POLARSSL_ERR_X509_INVALID_ALG + ret );
00121 
00122     return( 0 );
00123 }
00124 
00125 /*
00126  * Parse an algorithm identifier with (optional) paramaters
00127  */
00128 int x509_get_alg( unsigned char **p, const unsigned char *end,
00129                   x509_buf *alg, x509_buf *params )
00130 {
00131     int ret;
00132 
00133     if( ( ret = asn1_get_alg( p, end, alg, params ) ) != 0 )
00134         return( POLARSSL_ERR_X509_INVALID_ALG + ret );
00135 
00136     return( 0 );
00137 }
00138 
00139 #if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
00140 /*
00141  * HashAlgorithm ::= AlgorithmIdentifier
00142  *
00143  * AlgorithmIdentifier  ::=  SEQUENCE  {
00144  *      algorithm               OBJECT IDENTIFIER,
00145  *      parameters              ANY DEFINED BY algorithm OPTIONAL  }
00146  *
00147  * For HashAlgorithm, parameters MUST be NULL or absent.
00148  */
00149 static int x509_get_hash_alg( const x509_buf *alg, md_type_t *md_alg )
00150 {
00151     int ret;
00152     unsigned char *p;
00153     const unsigned char *end;
00154     x509_buf md_oid;
00155     size_t len;
00156 
00157     /* Make sure we got a SEQUENCE and setup bounds */
00158     if( alg->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
00159         return( POLARSSL_ERR_X509_INVALID_ALG +
00160                 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00161 
00162     p = (unsigned char *) alg->p;
00163     end = p + alg->len;
00164 
00165     if( p >= end )
00166         return( POLARSSL_ERR_X509_INVALID_ALG +
00167                 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00168 
00169     /* Parse md_oid */
00170     md_oid.tag = *p;
00171 
00172     if( ( ret = asn1_get_tag( &p, end, &md_oid.len, ASN1_OID ) ) != 0 )
00173         return( POLARSSL_ERR_X509_INVALID_ALG + ret );
00174 
00175     md_oid.p = p;
00176     p += md_oid.len;
00177 
00178     /* Get md_alg from md_oid */
00179     if( ( ret = oid_get_md_alg( &md_oid, md_alg ) ) != 0 )
00180         return( POLARSSL_ERR_X509_INVALID_ALG + ret );
00181 
00182     /* Make sure params is absent of NULL */
00183     if( p == end )
00184         return( 0 );
00185 
00186     if( ( ret = asn1_get_tag( &p, end, &len, ASN1_NULL ) ) != 0 || len != 0 )
00187         return( POLARSSL_ERR_X509_INVALID_ALG + ret );
00188 
00189     if( p != end )
00190         return( POLARSSL_ERR_X509_INVALID_ALG +
00191                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00192 
00193     return( 0 );
00194 }
00195 
00196 /*
00197  *    RSASSA-PSS-params  ::=  SEQUENCE  {
00198  *       hashAlgorithm     [0] HashAlgorithm DEFAULT sha1Identifier,
00199  *       maskGenAlgorithm  [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
00200  *       saltLength        [2] INTEGER DEFAULT 20,
00201  *       trailerField      [3] INTEGER DEFAULT 1  }
00202  *    -- Note that the tags in this Sequence are explicit.
00203  *
00204  * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value
00205  * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
00206  * option. Enfore this at parsing time.
00207  */
00208 int x509_get_rsassa_pss_params( const x509_buf *params,
00209                                 md_type_t *md_alg, md_type_t *mgf_md,
00210                                 int *salt_len )
00211 {
00212     int ret;
00213     unsigned char *p;
00214     const unsigned char *end, *end2;
00215     size_t len;
00216     x509_buf alg_id, alg_params;
00217 
00218     /* First set everything to defaults */
00219     *md_alg = POLARSSL_MD_SHA1;
00220     *mgf_md = POLARSSL_MD_SHA1;
00221     *salt_len = 20;
00222 
00223     /* Make sure params is a SEQUENCE and setup bounds */
00224     if( params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
00225         return( POLARSSL_ERR_X509_INVALID_ALG +
00226                 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00227 
00228     p = (unsigned char *) params->p;
00229     end = p + params->len;
00230 
00231     if( p == end )
00232         return( 0 );
00233 
00234     /*
00235      * HashAlgorithm
00236      */
00237     if( ( ret = asn1_get_tag( &p, end, &len,
00238                     ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 )
00239     {
00240         end2 = p + len;
00241 
00242         /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
00243         if( ( ret = x509_get_alg_null( &p, end2, &alg_id ) ) != 0 )
00244             return( ret );
00245 
00246         if( ( ret = oid_get_md_alg( &alg_id, md_alg ) ) != 0 )
00247             return( POLARSSL_ERR_X509_INVALID_ALG + ret );
00248 
00249         if( p != end2 )
00250             return( POLARSSL_ERR_X509_INVALID_ALG +
00251                     POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00252     }
00253     else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00254         return( POLARSSL_ERR_X509_INVALID_ALG + ret );
00255 
00256     if( p == end )
00257         return( 0 );
00258 
00259     /*
00260      * MaskGenAlgorithm
00261      */
00262     if( ( ret = asn1_get_tag( &p, end, &len,
00263                     ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 )
00264     {
00265         end2 = p + len;
00266 
00267         /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
00268         if( ( ret = x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 )
00269             return( ret );
00270 
00271         /* Only MFG1 is recognised for now */
00272         if( ! OID_CMP( OID_MGF1, &alg_id ) )
00273             return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE +
00274                     POLARSSL_ERR_OID_NOT_FOUND );
00275 
00276         /* Parse HashAlgorithm */
00277         if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 )
00278             return( ret );
00279 
00280         if( p != end2 )
00281             return( POLARSSL_ERR_X509_INVALID_ALG +
00282                     POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00283     }
00284     else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00285         return( POLARSSL_ERR_X509_INVALID_ALG + ret );
00286 
00287     if( p == end )
00288         return( 0 );
00289 
00290     /*
00291      * salt_len
00292      */
00293     if( ( ret = asn1_get_tag( &p, end, &len,
00294                     ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 2 ) ) == 0 )
00295     {
00296         end2 = p + len;
00297 
00298         if( ( ret = asn1_get_int( &p, end2, salt_len ) ) != 0 )
00299             return( POLARSSL_ERR_X509_INVALID_ALG + ret );
00300 
00301         if( p != end2 )
00302             return( POLARSSL_ERR_X509_INVALID_ALG +
00303                     POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00304     }
00305     else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00306         return( POLARSSL_ERR_X509_INVALID_ALG + ret );
00307 
00308     if( p == end )
00309         return( 0 );
00310 
00311     /*
00312      * trailer_field (if present, must be 1)
00313      */
00314     if( ( ret = asn1_get_tag( &p, end, &len,
00315                     ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) == 0 )
00316     {
00317         int trailer_field;
00318 
00319         end2 = p + len;
00320 
00321         if( ( ret = asn1_get_int( &p, end2, &trailer_field ) ) != 0 )
00322             return( POLARSSL_ERR_X509_INVALID_ALG + ret );
00323 
00324         if( p != end2 )
00325             return( POLARSSL_ERR_X509_INVALID_ALG +
00326                     POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00327 
00328         if( trailer_field != 1 )
00329             return( POLARSSL_ERR_X509_INVALID_ALG );
00330     }
00331     else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00332         return( POLARSSL_ERR_X509_INVALID_ALG + ret );
00333 
00334     if( p != end )
00335         return( POLARSSL_ERR_X509_INVALID_ALG +
00336                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00337 
00338     return( 0 );
00339 }
00340 #endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
00341 
00342 /*
00343  *  AttributeTypeAndValue ::= SEQUENCE {
00344  *    type     AttributeType,
00345  *    value    AttributeValue }
00346  *
00347  *  AttributeType ::= OBJECT IDENTIFIER
00348  *
00349  *  AttributeValue ::= ANY DEFINED BY AttributeType
00350  */
00351 static int x509_get_attr_type_value( unsigned char **p,
00352                                      const unsigned char *end,
00353                                      x509_name *cur )
00354 {
00355     int ret;
00356     size_t len;
00357     x509_buf *oid;
00358     x509_buf *val;
00359 
00360     if( ( ret = asn1_get_tag( p, end, &len,
00361             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00362         return( POLARSSL_ERR_X509_INVALID_NAME + ret );
00363 
00364     if( ( end - *p ) < 1 )
00365         return( POLARSSL_ERR_X509_INVALID_NAME +
00366                 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00367 
00368     oid = &cur->oid;
00369     oid->tag = **p;
00370 
00371     if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
00372         return( POLARSSL_ERR_X509_INVALID_NAME + ret );
00373 
00374     oid->p = *p;
00375     *p += oid->len;
00376 
00377     if( ( end - *p ) < 1 )
00378         return( POLARSSL_ERR_X509_INVALID_NAME +
00379                 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00380 
00381     if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING      &&
00382         **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
00383         **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING &&
00384         **p != ASN1_BIT_STRING )
00385         return( POLARSSL_ERR_X509_INVALID_NAME +
00386                 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00387 
00388     val = &cur->val;
00389     val->tag = *(*p)++;
00390 
00391     if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
00392         return( POLARSSL_ERR_X509_INVALID_NAME + ret );
00393 
00394     val->p = *p;
00395     *p += val->len;
00396 
00397     cur->next = NULL;
00398 
00399     return( 0 );
00400 }
00401 
00402 /*
00403  *  Name ::= CHOICE { -- only one possibility for now --
00404  *       rdnSequence  RDNSequence }
00405  *
00406  *  RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
00407  *
00408  *  RelativeDistinguishedName ::=
00409  *    SET OF AttributeTypeAndValue
00410  *
00411  *  AttributeTypeAndValue ::= SEQUENCE {
00412  *    type     AttributeType,
00413  *    value    AttributeValue }
00414  *
00415  *  AttributeType ::= OBJECT IDENTIFIER
00416  *
00417  *  AttributeValue ::= ANY DEFINED BY AttributeType
00418  *
00419  * The data structure is optimized for the common case where each RDN has only
00420  * one element, which is represented as a list of AttributeTypeAndValue.
00421  * For the general case we still use a flat list, but we mark elements of the
00422  * same set so that they are "merged" together in the functions that consume
00423  * this list, eg x509_dn_gets().
00424  */
00425 int x509_get_name( unsigned char **p, const unsigned char *end,
00426                    x509_name *cur )
00427 {
00428     int ret;
00429     size_t set_len;
00430     const unsigned char *end_set;
00431 
00432     /* don't use recursion, we'd risk stack overflow if not optimized */
00433     while( 1 )
00434     {
00435         /*
00436          * parse SET
00437          */
00438         if( ( ret = asn1_get_tag( p, end, &set_len,
00439                 ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
00440             return( POLARSSL_ERR_X509_INVALID_NAME + ret );
00441 
00442         end_set  = *p + set_len;
00443 
00444         while( 1 )
00445         {
00446             if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
00447                 return( ret );
00448 
00449             if( *p == end_set )
00450                 break;
00451 
00452             /* Mark this item as being not the only one in a set */
00453             cur->next_merged = 1;
00454 
00455             cur->next = polarssl_malloc( sizeof( x509_name ) );
00456 
00457             if( cur->next == NULL )
00458                 return( POLARSSL_ERR_X509_MALLOC_FAILED );
00459 
00460             memset( cur->next, 0, sizeof( x509_name ) );
00461 
00462             cur = cur->next;
00463         }
00464 
00465         /*
00466          * continue until end of SEQUENCE is reached
00467          */
00468         if( *p == end )
00469             return( 0 );
00470 
00471         cur->next = polarssl_malloc( sizeof( x509_name ) );
00472 
00473         if( cur->next == NULL )
00474             return( POLARSSL_ERR_X509_MALLOC_FAILED );
00475 
00476         memset( cur->next, 0, sizeof( x509_name ) );
00477 
00478         cur = cur->next;
00479     }
00480 }
00481 
00482 static int x509_parse_int(unsigned char **p, unsigned n, int *res){
00483     *res = 0;
00484     for( ; n > 0; --n ){
00485         if( ( **p < '0') || ( **p > '9' ) ) return POLARSSL_ERR_X509_INVALID_DATE;
00486         *res *= 10;
00487         *res += (*(*p)++ - '0');
00488     }
00489     return 0;
00490 }
00491 
00492 /*
00493  *  Time ::= CHOICE {
00494  *       utcTime        UTCTime,
00495  *       generalTime    GeneralizedTime }
00496  */
00497 int x509_get_time( unsigned char **p, const unsigned char *end,
00498                    x509_time *time )
00499 {
00500     int ret;
00501     size_t len;
00502     unsigned char tag;
00503 
00504     if( ( end - *p ) < 1 )
00505         return( POLARSSL_ERR_X509_INVALID_DATE +
00506                 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00507 
00508     tag = **p;
00509 
00510     if( tag == ASN1_UTC_TIME )
00511     {
00512         (*p)++;
00513         ret = asn1_get_len( p, end, &len );
00514 
00515         if( ret != 0 )
00516             return( POLARSSL_ERR_X509_INVALID_DATE + ret );
00517 
00518         CHECK( x509_parse_int( p, 2, &time->year ) );
00519         CHECK( x509_parse_int( p, 2, &time->mon ) );
00520         CHECK( x509_parse_int( p, 2, &time->day ) );
00521         CHECK( x509_parse_int( p, 2, &time->hour ) );
00522         CHECK( x509_parse_int( p, 2, &time->min ) );
00523         if( len > 10 )
00524             CHECK( x509_parse_int( p, 2, &time->sec ) );
00525         if( len > 12 && *(*p)++ != 'Z' )
00526             return( POLARSSL_ERR_X509_INVALID_DATE );
00527 
00528         time->year +=  100 * ( time->year < 50 );
00529         time->year += 1900;
00530 
00531         return( 0 );
00532     }
00533     else if( tag == ASN1_GENERALIZED_TIME )
00534     {
00535         (*p)++;
00536         ret = asn1_get_len( p, end, &len );
00537 
00538         if( ret != 0 )
00539             return( POLARSSL_ERR_X509_INVALID_DATE + ret );
00540 
00541         CHECK( x509_parse_int( p, 4, &time->year ) );
00542         CHECK( x509_parse_int( p, 2, &time->mon ) );
00543         CHECK( x509_parse_int( p, 2, &time->day ) );
00544         CHECK( x509_parse_int( p, 2, &time->hour ) );
00545         CHECK( x509_parse_int( p, 2, &time->min ) );
00546         if( len > 12 )
00547             CHECK( x509_parse_int( p, 2, &time->sec ) );
00548         if( len > 14 && *(*p)++ != 'Z' )
00549             return( POLARSSL_ERR_X509_INVALID_DATE );
00550 
00551         return( 0 );
00552     }
00553     else
00554         return( POLARSSL_ERR_X509_INVALID_DATE +
00555                 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00556 }
00557 
00558 int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig )
00559 {
00560     int ret;
00561     size_t len;
00562 
00563     if( ( end - *p ) < 1 )
00564         return( POLARSSL_ERR_X509_INVALID_SIGNATURE +
00565                 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00566 
00567     sig->tag = **p;
00568 
00569     if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
00570         return( POLARSSL_ERR_X509_INVALID_SIGNATURE + ret );
00571 
00572     sig->len = len;
00573     sig->p = *p;
00574 
00575     *p += len;
00576 
00577     return( 0 );
00578 }
00579 
00580 /*
00581  * Get signature algorithm from alg OID and optional parameters
00582  */
00583 int x509_get_sig_alg( const x509_buf *sig_oid, const x509_buf *sig_params,
00584                       md_type_t *md_alg, pk_type_t *pk_alg,
00585                       void **sig_opts )
00586 {
00587     int ret;
00588 
00589     if( *sig_opts != NULL )
00590         return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
00591 
00592     if( ( ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 )
00593         return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG + ret );
00594 
00595 #if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
00596     if( *pk_alg == POLARSSL_PK_RSASSA_PSS )
00597     {
00598         pk_rsassa_pss_options *pss_opts;
00599 
00600         pss_opts = polarssl_malloc( sizeof( pk_rsassa_pss_options ) );
00601         if( pss_opts == NULL )
00602             return( POLARSSL_ERR_X509_MALLOC_FAILED );
00603 
00604         ret = x509_get_rsassa_pss_params( sig_params,
00605                                           md_alg,
00606                                           &pss_opts->mgf1_hash_id,
00607                                           &pss_opts->expected_salt_len );
00608         if( ret != 0 )
00609         {
00610             polarssl_free( pss_opts );
00611             return( ret );
00612         }
00613 
00614         *sig_opts = (void *) pss_opts;
00615     }
00616     else
00617 #endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
00618     {
00619         /* Make sure parameters are absent or NULL */
00620         if( ( sig_params->tag != ASN1_NULL && sig_params->tag != 0 ) ||
00621               sig_params->len != 0 )
00622         return( POLARSSL_ERR_X509_INVALID_ALG );
00623     }
00624 
00625     return( 0 );
00626 }
00627 
00628 /*
00629  * X.509 Extensions (No parsing of extensions, pointer should
00630  * be either manually updated or extensions should be parsed!
00631  */
00632 int x509_get_ext( unsigned char **p, const unsigned char *end,
00633                   x509_buf *ext, int tag )
00634 {
00635     int ret;
00636     size_t len;
00637 
00638     if( *p == end )
00639         return( 0 );
00640 
00641     ext->tag = **p;
00642 
00643     if( ( ret = asn1_get_tag( p, end, &ext->len,
00644             ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
00645         return( ret );
00646 
00647     ext->p = *p;
00648     end = *p + ext->len;
00649 
00650     /*
00651      * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
00652      *
00653      * Extension  ::=  SEQUENCE  {
00654      *      extnID      OBJECT IDENTIFIER,
00655      *      critical    BOOLEAN DEFAULT FALSE,
00656      *      extnValue   OCTET STRING  }
00657      */
00658     if( ( ret = asn1_get_tag( p, end, &len,
00659             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00660         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00661 
00662     if( end != *p + len )
00663         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00664                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00665 
00666     return( 0 );
00667 }
00668 
00669 #if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
00670     !defined(EFI32)
00671 #include <stdarg.h>
00672 
00673 #if !defined vsnprintf
00674 #define vsnprintf _vsnprintf
00675 #endif // vsnprintf
00676 
00677 /*
00678  * Windows _snprintf and _vsnprintf are not compatible to linux versions.
00679  * Result value is not size of buffer needed, but -1 if no fit is possible.
00680  *
00681  * This fuction tries to 'fix' this by at least suggesting enlarging the
00682  * size by 20.
00683  */
00684 static int compat_snprintf( char *str, size_t size, const char *format, ... )
00685 {
00686     va_list ap;
00687     int res = -1;
00688 
00689     va_start( ap, format );
00690 
00691     res = vsnprintf( str, size, format, ap );
00692 
00693     va_end( ap );
00694 
00695     // No quick fix possible
00696     if( res < 0 )
00697         return( (int) size + 20 );
00698 
00699     return( res );
00700 }
00701 
00702 #define snprintf compat_snprintf
00703 #endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */
00704 
00705 #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL    -2
00706 
00707 #define SAFE_SNPRINTF()                             \
00708 {                                                   \
00709     if( ret == -1 )                                 \
00710         return( -1 );                               \
00711                                                     \
00712     if( (unsigned int) ret > n ) {                  \
00713         p[n - 1] = '\0';                            \
00714         return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \
00715     }                                               \
00716                                                     \
00717     n -= (unsigned int) ret;                        \
00718     p += (unsigned int) ret;                        \
00719 }
00720 
00721 /*
00722  * Store the name in printable form into buf; no more
00723  * than size characters will be written
00724  */
00725 int x509_dn_gets( char *buf, size_t size, const x509_name *dn )
00726 {
00727     int ret;
00728     size_t i, n;
00729     unsigned char c, merge = 0;
00730     const x509_name *name;
00731     const char *short_name = NULL;
00732     char s[X509_MAX_DN_NAME_SIZE], *p;
00733 
00734     memset( s, 0, sizeof( s ) );
00735 
00736     name = dn;
00737     p = buf;
00738     n = size;
00739 
00740     while( name != NULL )
00741     {
00742         if( !name->oid.p )
00743         {
00744             name = name->next;
00745             continue;
00746         }
00747 
00748         if( name != dn )
00749         {
00750             ret = polarssl_snprintf( p, n, merge ? " + " : ", " );
00751             SAFE_SNPRINTF();
00752         }
00753 
00754         ret = oid_get_attr_short_name( &name->oid, &short_name );
00755 
00756         if( ret == 0 )
00757             ret = polarssl_snprintf( p, n, "%s=", short_name );
00758         else
00759             ret = polarssl_snprintf( p, n, "\?\?=" );
00760         SAFE_SNPRINTF();
00761 
00762         for( i = 0; i < name->val.len; i++ )
00763         {
00764             if( i >= sizeof( s ) - 1 )
00765                 break;
00766 
00767             c = name->val.p[i];
00768             if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
00769                  s[i] = '?';
00770             else s[i] = c;
00771         }
00772         s[i] = '\0';
00773         ret = polarssl_snprintf( p, n, "%s", s );
00774         SAFE_SNPRINTF();
00775 
00776         merge = name->next_merged;
00777         name = name->next;
00778     }
00779 
00780     return( (int) ( size - n ) );
00781 }
00782 
00783 /*
00784  * Store the serial in printable form into buf; no more
00785  * than size characters will be written
00786  */
00787 int x509_serial_gets( char *buf, size_t size, const x509_buf *serial )
00788 {
00789     int ret;
00790     size_t i, n, nr;
00791     char *p;
00792 
00793     p = buf;
00794     n = size;
00795 
00796     nr = ( serial->len <= 32 )
00797         ? serial->len  : 28;
00798 
00799     for( i = 0; i < nr; i++ )
00800     {
00801         if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
00802             continue;
00803 
00804         ret = polarssl_snprintf( p, n, "%02X%s",
00805                 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
00806         SAFE_SNPRINTF();
00807     }
00808 
00809     if( nr != serial->len )
00810     {
00811         ret = polarssl_snprintf( p, n, "...." );
00812         SAFE_SNPRINTF();
00813     }
00814 
00815     return( (int) ( size - n ) );
00816 }
00817 
00818 /*
00819  * Helper for writing signature algorithms
00820  */
00821 int x509_sig_alg_gets( char *buf, size_t size, const x509_buf *sig_oid,
00822                        pk_type_t pk_alg, md_type_t md_alg,
00823                        const void *sig_opts )
00824 {
00825     int ret;
00826     char *p = buf;
00827     size_t n = size;
00828     const char *desc = NULL;
00829 
00830     ret = oid_get_sig_alg_desc( sig_oid, &desc );
00831     if( ret != 0 )
00832         ret = polarssl_snprintf( p, n, "???"  );
00833     else
00834         ret = polarssl_snprintf( p, n, "%s", desc );
00835     SAFE_SNPRINTF();
00836 
00837 #if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
00838     if( pk_alg == POLARSSL_PK_RSASSA_PSS )
00839     {
00840         const pk_rsassa_pss_options *pss_opts;
00841         const md_info_t *md_info, *mgf_md_info;
00842 
00843         pss_opts = (const pk_rsassa_pss_options *) sig_opts;
00844 
00845         md_info = md_info_from_type( md_alg );
00846         mgf_md_info = md_info_from_type( pss_opts->mgf1_hash_id );
00847 
00848         ret = polarssl_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)",
00849                               md_info ? md_info->name : "???",
00850                               mgf_md_info ? mgf_md_info->name : "???",
00851                               pss_opts->expected_salt_len );
00852         SAFE_SNPRINTF();
00853     }
00854 #else
00855     ((void) pk_alg);
00856     ((void) md_alg);
00857     ((void) sig_opts);
00858 #endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
00859 
00860     return( (int)( size - n ) );
00861 }
00862 
00863 /*
00864  * Helper for writing "RSA key size", "EC key size", etc
00865  */
00866 int x509_key_size_helper( char *buf, size_t size, const char *name )
00867 {
00868     char *p = buf;
00869     size_t n = size;
00870     int ret;
00871 
00872     if( strlen( name ) + sizeof( " key size" ) > size )
00873         return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL );
00874 
00875     ret = polarssl_snprintf( p, n, "%s key size", name );
00876     SAFE_SNPRINTF();
00877 
00878     return( 0 );
00879 }
00880 
00881 /*
00882  * Return an informational string describing the given OID
00883  */
00884 #if ! defined(POLARSSL_DEPRECATED_REMOVED)
00885 const char *x509_oid_get_description( x509_buf *oid )
00886 {
00887     const char *desc = NULL;
00888     int ret;
00889 
00890     ret = oid_get_extended_key_usage( oid, &desc );
00891 
00892     if( ret != 0 )
00893         return( NULL );
00894 
00895     return( desc );
00896 }
00897 #endif
00898 
00899 /* Return the x.y.z.... style numeric string for the given OID */
00900 #if ! defined(POLARSSL_DEPRECATED_REMOVED)
00901 int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
00902 {
00903     return oid_get_numeric_string( buf, size, oid );
00904 }
00905 #endif
00906 
00907 /*
00908  * Return 0 if the x509_time is still valid, or 1 otherwise.
00909  */
00910 #if defined(POLARSSL_HAVE_TIME)
00911 
00912 static void x509_get_current_time( x509_time *now )
00913 {
00914 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
00915     SYSTEMTIME st;
00916 
00917     GetSystemTime( &st );
00918 
00919     now->year = st.wYear;
00920     now->mon = st.wMonth;
00921     now->day = st.wDay;
00922     now->hour = st.wHour;
00923     now->min = st.wMinute;
00924     now->sec = st.wSecond;
00925 #else
00926     struct tm lt;
00927     time_t tt;
00928 
00929     tt = time( NULL );
00930     gmtime_r( &tt, &lt );
00931 
00932     now->year = lt.tm_year + 1900;
00933     now->mon = lt.tm_mon + 1;
00934     now->day = lt.tm_mday;
00935     now->hour = lt.tm_hour;
00936     now->min = lt.tm_min;
00937     now->sec = lt.tm_sec;
00938 #endif /* _WIN32 && !EFIX64 && !EFI32 */
00939 }
00940 
00941 /*
00942  * Return 0 if before <= after, 1 otherwise
00943  */
00944 static int x509_check_time( const x509_time *before, const x509_time *after )
00945 {
00946     if( before->year  > after->year )
00947         return( 1 );
00948 
00949     if( before->year == after->year &&
00950         before->mon   > after->mon )
00951         return( 1 );
00952 
00953     if( before->year == after->year &&
00954         before->mon  == after->mon  &&
00955         before->day   > after->day )
00956         return( 1 );
00957 
00958     if( before->year == after->year &&
00959         before->mon  == after->mon  &&
00960         before->day  == after->day  &&
00961         before->hour  > after->hour )
00962         return( 1 );
00963 
00964     if( before->year == after->year &&
00965         before->mon  == after->mon  &&
00966         before->day  == after->day  &&
00967         before->hour == after->hour &&
00968         before->min   > after->min  )
00969         return( 1 );
00970 
00971     if( before->year == after->year &&
00972         before->mon  == after->mon  &&
00973         before->day  == after->day  &&
00974         before->hour == after->hour &&
00975         before->min  == after->min  &&
00976         before->sec   > after->sec  )
00977         return( 1 );
00978 
00979     return( 0 );
00980 }
00981 
00982 int x509_time_expired( const x509_time *to )
00983 {
00984     x509_time now;
00985 
00986     x509_get_current_time( &now );
00987 
00988     return( x509_check_time( &now, to ) );
00989 }
00990 
00991 int x509_time_future( const x509_time *from )
00992 {
00993     x509_time now;
00994 
00995     x509_get_current_time( &now );
00996 
00997     return( x509_check_time( from, &now ) );
00998 }
00999 
01000 #else  /* POLARSSL_HAVE_TIME */
01001 
01002 int x509_time_expired( const x509_time *to )
01003 {
01004     ((void) to);
01005     return( 0 );
01006 }
01007 
01008 int x509_time_future( const x509_time *from )
01009 {
01010     ((void) from);
01011     return( 0 );
01012 }
01013 #endif /* POLARSSL_HAVE_TIME */
01014 
01015 #if defined(POLARSSL_SELF_TEST)
01016 
01017 #include "polarssl/x509_crt.h"
01018 #include "polarssl/certs.h"
01019 
01020 /*
01021  * Checkup routine
01022  */
01023 int x509_self_test( int verbose )
01024 {
01025 #if defined(POLARSSL_CERTS_C) && defined(POLARSSL_SHA1_C)
01026     int ret;
01027     int flags;
01028     x509_crt cacert;
01029     x509_crt clicert;
01030 
01031     if( verbose != 0 )
01032         polarssl_printf( "  X.509 certificate load: " );
01033 
01034     x509_crt_init( &clicert );
01035 
01036     ret = x509_crt_parse( &clicert, (const unsigned char *) test_cli_crt,
01037                           strlen( test_cli_crt ) );
01038     if( ret != 0 )
01039     {
01040         if( verbose != 0 )
01041             polarssl_printf( "failed\n" );
01042 
01043         return( ret );
01044     }
01045 
01046     x509_crt_init( &cacert );
01047 
01048     ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_crt,
01049                           strlen( test_ca_crt ) );
01050     if( ret != 0 )
01051     {
01052         if( verbose != 0 )
01053             polarssl_printf( "failed\n" );
01054 
01055         return( ret );
01056     }
01057 
01058     if( verbose != 0 )
01059         polarssl_printf( "passed\n  X.509 signature verify: ");
01060 
01061     ret = x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
01062     if( ret != 0 )
01063     {
01064         if( verbose != 0 )
01065             polarssl_printf( "failed\n" );
01066 
01067         polarssl_printf( "ret = %d, &flags = %04x\n", ret, flags );
01068 
01069         return( ret );
01070     }
01071 
01072     if( verbose != 0 )
01073         polarssl_printf( "passed\n\n");
01074 
01075     x509_crt_free( &cacert  );
01076     x509_crt_free( &clicert );
01077 
01078     return( 0 );
01079 #else
01080     ((void) verbose);
01081     return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
01082 #endif /* POLARSSL_CERTS_C && POLARSSL_SHA1_C */
01083 }
01084 
01085 #endif /* POLARSSL_SELF_TEST */
01086 
01087 #endif /* POLARSSL_X509_USE_C */
01088