x509.c 28.3 KB
Newer Older
1
/*
2
 *  X.509 common functions for parsing and verification
3
 *
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
4
 *  Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
5
 *
6
 *  This file is part of mbed TLS (https://tls.mbed.org)
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
/*
 *  The ITU-T X.509 standard defines a certificate format for PKI.
 *
25 26 27
 *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
 *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
 *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
28 29 30 31 32
 *
 *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
 *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
 */

33
#if !defined(POLARSSL_CONFIG_FILE)
34
#include "polarssl/config.h"
35 36 37
#else
#include POLARSSL_CONFIG_FILE
#endif
38 39 40 41 42 43

#if defined(POLARSSL_X509_USE_C)

#include "polarssl/x509.h"
#include "polarssl/asn1.h"
#include "polarssl/oid.h"
44

45
#include <stdio.h>
46 47
#include <string.h>

48 49 50 51
#if defined(POLARSSL_PEM_PARSE_C)
#include "polarssl/pem.h"
#endif

52 53
#if defined(POLARSSL_PLATFORM_C)
#include "polarssl/platform.h"
54
#else
55 56
#include <stdio.h>
#include <stdlib.h>
57
#define polarssl_free       free
58 59 60
#define polarssl_malloc     malloc
#define polarssl_printf     printf
#define polarssl_snprintf   snprintf
61 62
#endif

63
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
64 65 66 67 68 69
#include <windows.h>
#else
#include <time.h>
#endif

#if defined(POLARSSL_FS_IO)
70
#include <stdio.h>
71 72 73 74 75 76 77
#if !defined(_WIN32)
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#endif
#endif

78 79
#define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); }

80 81 82 83 84 85 86 87 88
/*
 *  CertificateSerialNumber  ::=  INTEGER
 */
int x509_get_serial( unsigned char **p, const unsigned char *end,
                     x509_buf *serial )
{
    int ret;

    if( ( end - *p ) < 1 )
89
        return( POLARSSL_ERR_X509_INVALID_SERIAL +
90 91 92 93
                POLARSSL_ERR_ASN1_OUT_OF_DATA );

    if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
        **p !=   ASN1_INTEGER )
94
        return( POLARSSL_ERR_X509_INVALID_SERIAL +
95 96 97 98 99
                POLARSSL_ERR_ASN1_UNEXPECTED_TAG );

    serial->tag = *(*p)++;

    if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
100
        return( POLARSSL_ERR_X509_INVALID_SERIAL + ret );
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119

    serial->p = *p;
    *p += serial->len;

    return( 0 );
}

/* Get an algorithm identifier without parameters (eg for signatures)
 *
 *  AlgorithmIdentifier  ::=  SEQUENCE  {
 *       algorithm               OBJECT IDENTIFIER,
 *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
 */
int x509_get_alg_null( unsigned char **p, const unsigned char *end,
                       x509_buf *alg )
{
    int ret;

    if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 )
120
        return( POLARSSL_ERR_X509_INVALID_ALG + ret );
121 122 123 124

    return( 0 );
}

125 126 127 128 129 130 131 132 133 134 135 136 137 138
/*
 * Parse an algorithm identifier with (optional) paramaters
 */
int x509_get_alg( unsigned char **p, const unsigned char *end,
                  x509_buf *alg, x509_buf *params )
{
    int ret;

    if( ( ret = asn1_get_alg( p, end, alg, params ) ) != 0 )
        return( POLARSSL_ERR_X509_INVALID_ALG + ret );

    return( 0 );
}

139
#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
/*
 * HashAlgorithm ::= AlgorithmIdentifier
 *
 * AlgorithmIdentifier  ::=  SEQUENCE  {
 *      algorithm               OBJECT IDENTIFIER,
 *      parameters              ANY DEFINED BY algorithm OPTIONAL  }
 *
 * For HashAlgorithm, parameters MUST be NULL or absent.
 */
static int x509_get_hash_alg( const x509_buf *alg, md_type_t *md_alg )
{
    int ret;
    unsigned char *p;
    const unsigned char *end;
    x509_buf md_oid;
    size_t len;

    /* Make sure we got a SEQUENCE and setup bounds */
    if( alg->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
        return( POLARSSL_ERR_X509_INVALID_ALG +
                POLARSSL_ERR_ASN1_UNEXPECTED_TAG );

    p = (unsigned char *) alg->p;
    end = p + alg->len;

    if( p >= end )
        return( POLARSSL_ERR_X509_INVALID_ALG +
                POLARSSL_ERR_ASN1_OUT_OF_DATA );

    /* Parse md_oid */
    md_oid.tag = *p;

    if( ( ret = asn1_get_tag( &p, end, &md_oid.len, ASN1_OID ) ) != 0 )
        return( POLARSSL_ERR_X509_INVALID_ALG + ret );

    md_oid.p = p;
    p += md_oid.len;

    /* Get md_alg from md_oid */
    if( ( ret = oid_get_md_alg( &md_oid, md_alg ) ) != 0 )
        return( POLARSSL_ERR_X509_INVALID_ALG + ret );

    /* Make sure params is absent of NULL */
    if( p == end )
        return( 0 );

186
    if( ( ret = asn1_get_tag( &p, end, &len, ASN1_NULL ) ) != 0 || len != 0 )
187 188 189 190 191 192 193 194 195
        return( POLARSSL_ERR_X509_INVALID_ALG + ret );

    if( p != end )
        return( POLARSSL_ERR_X509_INVALID_ALG +
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );

    return( 0 );
}

196 197 198 199 200 201 202
/*
 *    RSASSA-PSS-params  ::=  SEQUENCE  {
 *       hashAlgorithm     [0] HashAlgorithm DEFAULT sha1Identifier,
 *       maskGenAlgorithm  [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
 *       saltLength        [2] INTEGER DEFAULT 20,
 *       trailerField      [3] INTEGER DEFAULT 1  }
 *    -- Note that the tags in this Sequence are explicit.
203 204 205 206
 *
 * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value
 * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
 * option. Enfore this at parsing time.
207 208
 */
int x509_get_rsassa_pss_params( const x509_buf *params,
209
                                md_type_t *md_alg, md_type_t *mgf_md,
210
                                int *salt_len )
211 212 213
{
    int ret;
    unsigned char *p;
214
    const unsigned char *end, *end2;
215
    size_t len;
216
    x509_buf alg_id, alg_params;
217 218 219

    /* First set everything to defaults */
    *md_alg = POLARSSL_MD_SHA1;
220
    *mgf_md = POLARSSL_MD_SHA1;
221 222 223 224 225 226 227 228 229 230 231 232 233
    *salt_len = 20;

    /* Make sure params is a SEQUENCE and setup bounds */
    if( params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
        return( POLARSSL_ERR_X509_INVALID_ALG +
                POLARSSL_ERR_ASN1_UNEXPECTED_TAG );

    p = (unsigned char *) params->p;
    end = p + params->len;

    if( p == end )
        return( 0 );

234 235 236
    /*
     * HashAlgorithm
     */
237 238 239
    if( ( ret = asn1_get_tag( &p, end, &len,
                    ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 )
    {
240 241
        end2 = p + len;

242
        /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
243
        if( ( ret = x509_get_alg_null( &p, end2, &alg_id ) ) != 0 )
244 245 246 247
            return( ret );

        if( ( ret = oid_get_md_alg( &alg_id, md_alg ) ) != 0 )
            return( POLARSSL_ERR_X509_INVALID_ALG + ret );
248 249 250 251

        if( p != end2 )
            return( POLARSSL_ERR_X509_INVALID_ALG +
                    POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
252 253 254 255
    }
    else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
        return( POLARSSL_ERR_X509_INVALID_ALG + ret );

256 257 258 259 260 261
    if( p == end )
        return( 0 );

    /*
     * MaskGenAlgorithm
     */
262 263 264
    if( ( ret = asn1_get_tag( &p, end, &len,
                    ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 )
    {
265 266
        end2 = p + len;

267
        /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
268
        if( ( ret = x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 )
269 270 271 272 273 274 275 276 277 278
            return( ret );

        /* Only MFG1 is recognised for now */
        if( ! OID_CMP( OID_MGF1, &alg_id ) )
            return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE +
                    POLARSSL_ERR_OID_NOT_FOUND );

        /* Parse HashAlgorithm */
        if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 )
            return( ret );
279 280 281 282

        if( p != end2 )
            return( POLARSSL_ERR_X509_INVALID_ALG +
                    POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
283 284 285 286 287 288 289
    }
    else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
        return( POLARSSL_ERR_X509_INVALID_ALG + ret );

    if( p == end )
        return( 0 );

290 291 292
    /*
     * salt_len
     */
293 294 295
    if( ( ret = asn1_get_tag( &p, end, &len,
                    ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 2 ) ) == 0 )
    {
296 297 298
        end2 = p + len;

        if( ( ret = asn1_get_int( &p, end2, salt_len ) ) != 0 )
299
            return( POLARSSL_ERR_X509_INVALID_ALG + ret );
300 301 302 303

        if( p != end2 )
            return( POLARSSL_ERR_X509_INVALID_ALG +
                    POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
304 305 306 307 308 309 310
    }
    else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
        return( POLARSSL_ERR_X509_INVALID_ALG + ret );

    if( p == end )
        return( 0 );

311
    /*
312
     * trailer_field (if present, must be 1)
313
     */
314 315 316
    if( ( ret = asn1_get_tag( &p, end, &len,
                    ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) == 0 )
    {
317 318
        int trailer_field;

319 320
        end2 = p + len;

321
        if( ( ret = asn1_get_int( &p, end2, &trailer_field ) ) != 0 )
322
            return( POLARSSL_ERR_X509_INVALID_ALG + ret );
323 324 325 326

        if( p != end2 )
            return( POLARSSL_ERR_X509_INVALID_ALG +
                    POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
327 328 329

        if( trailer_field != 1 )
            return( POLARSSL_ERR_X509_INVALID_ALG );
330 331 332 333 334 335 336 337 338 339
    }
    else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
        return( POLARSSL_ERR_X509_INVALID_ALG + ret );

    if( p != end )
        return( POLARSSL_ERR_X509_INVALID_ALG +
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );

    return( 0 );
}
340
#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
341

342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
/*
 *  AttributeTypeAndValue ::= SEQUENCE {
 *    type     AttributeType,
 *    value    AttributeValue }
 *
 *  AttributeType ::= OBJECT IDENTIFIER
 *
 *  AttributeValue ::= ANY DEFINED BY AttributeType
 */
static int x509_get_attr_type_value( unsigned char **p,
                                     const unsigned char *end,
                                     x509_name *cur )
{
    int ret;
    size_t len;
    x509_buf *oid;
    x509_buf *val;

    if( ( ret = asn1_get_tag( p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
362
        return( POLARSSL_ERR_X509_INVALID_NAME + ret );
363 364

    if( ( end - *p ) < 1 )
365
        return( POLARSSL_ERR_X509_INVALID_NAME +
366 367 368 369 370 371
                POLARSSL_ERR_ASN1_OUT_OF_DATA );

    oid = &cur->oid;
    oid->tag = **p;

    if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
372
        return( POLARSSL_ERR_X509_INVALID_NAME + ret );
373 374 375 376 377

    oid->p = *p;
    *p += oid->len;

    if( ( end - *p ) < 1 )
378
        return( POLARSSL_ERR_X509_INVALID_NAME +
379 380 381 382
                POLARSSL_ERR_ASN1_OUT_OF_DATA );

    if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING      &&
        **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
383 384
        **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING &&
        **p != ASN1_BIT_STRING )
385
        return( POLARSSL_ERR_X509_INVALID_NAME +
386 387 388 389 390 391
                POLARSSL_ERR_ASN1_UNEXPECTED_TAG );

    val = &cur->val;
    val->tag = *(*p)++;

    if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
392
        return( POLARSSL_ERR_X509_INVALID_NAME + ret );
393 394 395 396 397 398 399 400 401 402

    val->p = *p;
    *p += val->len;

    cur->next = NULL;

    return( 0 );
}

/*
403 404 405 406 407
 *  Name ::= CHOICE { -- only one possibility for now --
 *       rdnSequence  RDNSequence }
 *
 *  RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
 *
408 409 410 411 412 413 414 415 416 417
 *  RelativeDistinguishedName ::=
 *    SET OF AttributeTypeAndValue
 *
 *  AttributeTypeAndValue ::= SEQUENCE {
 *    type     AttributeType,
 *    value    AttributeValue }
 *
 *  AttributeType ::= OBJECT IDENTIFIER
 *
 *  AttributeValue ::= ANY DEFINED BY AttributeType
418
 *
419 420 421 422 423
 * The data structure is optimized for the common case where each RDN has only
 * one element, which is represented as a list of AttributeTypeAndValue.
 * For the general case we still use a flat list, but we mark elements of the
 * same set so that they are "merged" together in the functions that consume
 * this list, eg x509_dn_gets().
424 425 426 427 428
 */
int x509_get_name( unsigned char **p, const unsigned char *end,
                   x509_name *cur )
{
    int ret;
429 430
    size_t set_len;
    const unsigned char *end_set;
431

432 433 434 435
    /* don't use recursion, we'd risk stack overflow if not optimized */
    while( 1 )
    {
        /*
436
         * parse SET
437 438 439 440
         */
        if( ( ret = asn1_get_tag( p, end, &set_len,
                ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
            return( POLARSSL_ERR_X509_INVALID_NAME + ret );
441

442
        end_set  = *p + set_len;
443

444 445 446 447 448 449 450
        while( 1 )
        {
            if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
                return( ret );

            if( *p == end_set )
                break;
451

452 453 454
            /* Mark this item as being only one in a set */
            cur->next_merged = 1;

455
            cur->next = polarssl_malloc( sizeof( x509_name ) );
456 457 458 459 460 461 462 463

            if( cur->next == NULL )
                return( POLARSSL_ERR_X509_MALLOC_FAILED );

            memset( cur->next, 0, sizeof( x509_name ) );

            cur = cur->next;
        }
464

465 466 467 468 469
        /*
         * continue until end of SEQUENCE is reached
         */
        if( *p == end )
            return( 0 );
470

471
        cur->next = polarssl_malloc( sizeof( x509_name ) );
472

473 474
        if( cur->next == NULL )
            return( POLARSSL_ERR_X509_MALLOC_FAILED );
475

476
        memset( cur->next, 0, sizeof( x509_name ) );
477

478 479
        cur = cur->next;
    }
480 481
}

482 483 484 485 486 487 488 489 490 491
static int x509_parse_int(unsigned char **p, unsigned n, int *res){
    *res = 0;
    for( ; n > 0; --n ){
        if( ( **p < '0') || ( **p > '9' ) ) return POLARSSL_ERR_X509_INVALID_DATE;
        *res *= 10;
        *res += (*(*p)++ - '0');
    }
    return 0;
}

492 493 494 495 496 497 498 499 500 501 502 503 504
/*
 *  Time ::= CHOICE {
 *       utcTime        UTCTime,
 *       generalTime    GeneralizedTime }
 */
int x509_get_time( unsigned char **p, const unsigned char *end,
                   x509_time *time )
{
    int ret;
    size_t len;
    unsigned char tag;

    if( ( end - *p ) < 1 )
505
        return( POLARSSL_ERR_X509_INVALID_DATE +
506 507 508 509
                POLARSSL_ERR_ASN1_OUT_OF_DATA );

    tag = **p;

510
    if( tag == ASN1_UTC_TIME )
511 512 513
    {
        (*p)++;
        ret = asn1_get_len( p, end, &len );
514

515
        if( ret != 0 )
516
            return( POLARSSL_ERR_X509_INVALID_DATE + ret );
517

518 519 520 521 522 523 524 525
        CHECK( x509_parse_int( p, 2, &time->year ) );
        CHECK( x509_parse_int( p, 2, &time->mon ) );
        CHECK( x509_parse_int( p, 2, &time->day ) );
        CHECK( x509_parse_int( p, 2, &time->hour ) );
        CHECK( x509_parse_int( p, 2, &time->min ) );
        if( len > 10 )
            CHECK( x509_parse_int( p, 2, &time->sec ) );
        if( len > 12 && *(*p)++ != 'Z' )
526
            return( POLARSSL_ERR_X509_INVALID_DATE );
527 528 529 530 531 532

        time->year +=  100 * ( time->year < 50 );
        time->year += 1900;

        return( 0 );
    }
533
    else if( tag == ASN1_GENERALIZED_TIME )
534 535 536
    {
        (*p)++;
        ret = asn1_get_len( p, end, &len );
537

538
        if( ret != 0 )
539
            return( POLARSSL_ERR_X509_INVALID_DATE + ret );
540

541 542 543 544 545 546 547 548
        CHECK( x509_parse_int( p, 4, &time->year ) );
        CHECK( x509_parse_int( p, 2, &time->mon ) );
        CHECK( x509_parse_int( p, 2, &time->day ) );
        CHECK( x509_parse_int( p, 2, &time->hour ) );
        CHECK( x509_parse_int( p, 2, &time->min ) );
        if( len > 12 )
            CHECK( x509_parse_int( p, 2, &time->sec ) );
        if( len > 14 && *(*p)++ != 'Z' )
549
            return( POLARSSL_ERR_X509_INVALID_DATE );
550 551 552 553

        return( 0 );
    }
    else
554 555
        return( POLARSSL_ERR_X509_INVALID_DATE +
                POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
556 557 558 559 560 561 562 563
}

int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig )
{
    int ret;
    size_t len;

    if( ( end - *p ) < 1 )
564
        return( POLARSSL_ERR_X509_INVALID_SIGNATURE +
565 566 567 568 569
                POLARSSL_ERR_ASN1_OUT_OF_DATA );

    sig->tag = **p;

    if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
570
        return( POLARSSL_ERR_X509_INVALID_SIGNATURE + ret );
571 572 573 574 575 576 577 578 579

    sig->len = len;
    sig->p = *p;

    *p += len;

    return( 0 );
}

580 581 582 583
/*
 * Get signature algorithm from alg OID and optional parameters
 */
int x509_get_sig_alg( const x509_buf *sig_oid, const x509_buf *sig_params,
584 585
                      md_type_t *md_alg, pk_type_t *pk_alg,
                      void **sig_opts )
586
{
587
    int ret;
588

589 590 591
    if( *sig_opts != NULL )
        return( POLARSSL_ERR_X509_BAD_INPUT_DATA );

592
    if( ( ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 )
593
        return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG + ret );
594

595
#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
596 597
    if( *pk_alg == POLARSSL_PK_RSASSA_PSS )
    {
598 599 600 601 602
        pk_rsassa_pss_options *pss_opts;

        pss_opts = polarssl_malloc( sizeof( pk_rsassa_pss_options ) );
        if( pss_opts == NULL )
            return( POLARSSL_ERR_X509_MALLOC_FAILED );
603 604

        ret = x509_get_rsassa_pss_params( sig_params,
605 606 607
                                          md_alg,
                                          &pss_opts->mgf1_hash_id,
                                          &pss_opts->expected_salt_len );
608
        if( ret != 0 )
609 610
        {
            polarssl_free( pss_opts );
611
            return( ret );
612
        }
613

614
        *sig_opts = (void *) pss_opts;
615 616
    }
    else
617
#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
618 619 620 621 622 623 624
    {
        /* Make sure parameters are absent or NULL */
        if( ( sig_params->tag != ASN1_NULL && sig_params->tag != 0 ) ||
              sig_params->len != 0 )
        return( POLARSSL_ERR_X509_INVALID_ALG );
    }

625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659
    return( 0 );
}

/*
 * X.509 Extensions (No parsing of extensions, pointer should
 * be either manually updated or extensions should be parsed!
 */
int x509_get_ext( unsigned char **p, const unsigned char *end,
                  x509_buf *ext, int tag )
{
    int ret;
    size_t len;

    if( *p == end )
        return( 0 );

    ext->tag = **p;

    if( ( ret = asn1_get_tag( p, end, &ext->len,
            ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
        return( ret );

    ext->p = *p;
    end = *p + ext->len;

    /*
     * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
     *
     * Extension  ::=  SEQUENCE  {
     *      extnID      OBJECT IDENTIFIER,
     *      critical    BOOLEAN DEFAULT FALSE,
     *      extnValue   OCTET STRING  }
     */
    if( ( ret = asn1_get_tag( p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
660
        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
661 662

    if( end != *p + len )
663
        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
664 665 666 667 668
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );

    return( 0 );
}

669 670
#if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
    !defined(EFI32)
671 672 673 674 675 676 677 678 679 680 681 682 683
#include <stdarg.h>

#if !defined vsnprintf
#define vsnprintf _vsnprintf
#endif // vsnprintf

/*
 * Windows _snprintf and _vsnprintf are not compatible to linux versions.
 * Result value is not size of buffer needed, but -1 if no fit is possible.
 *
 * This fuction tries to 'fix' this by at least suggesting enlarging the
 * size by 20.
 */
684
static int compat_snprintf( char *str, size_t size, const char *format, ... )
685 686 687 688 689 690 691 692 693 694 695
{
    va_list ap;
    int res = -1;

    va_start( ap, format );

    res = vsnprintf( str, size, format, ap );

    va_end( ap );

    // No quick fix possible
696
    if( res < 0 )
697 698
        return( (int) size + 20 );

699
    return( res );
700 701 702
}

#define snprintf compat_snprintf
703
#endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */
704 705 706

#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL    -2

707 708 709 710 711
#define SAFE_SNPRINTF()                             \
{                                                   \
    if( ret == -1 )                                 \
        return( -1 );                               \
                                                    \
712
    if( (unsigned int) ret > n ) {                  \
713 714 715 716 717 718
        p[n - 1] = '\0';                            \
        return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \
    }                                               \
                                                    \
    n -= (unsigned int) ret;                        \
    p += (unsigned int) ret;                        \
719 720 721 722 723 724
}

/*
 * Store the name in printable form into buf; no more
 * than size characters will be written
 */
725
int x509_dn_gets( char *buf, size_t size, const x509_name *dn )
726 727 728
{
    int ret;
    size_t i, n;
729
    unsigned char c, merge = 0;
730 731
    const x509_name *name;
    const char *short_name = NULL;
732
    char s[X509_MAX_DN_NAME_SIZE], *p;
733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749

    memset( s, 0, sizeof( s ) );

    name = dn;
    p = buf;
    n = size;

    while( name != NULL )
    {
        if( !name->oid.p )
        {
            name = name->next;
            continue;
        }

        if( name != dn )
        {
750
            ret = polarssl_snprintf( p, n, merge ? " + " : ", " );
751 752 753 754 755 756
            SAFE_SNPRINTF();
        }

        ret = oid_get_attr_short_name( &name->oid, &short_name );

        if( ret == 0 )
757
            ret = polarssl_snprintf( p, n, "%s=", short_name );
758
        else
759
            ret = polarssl_snprintf( p, n, "\?\?=" );
760 761 762 763 764 765 766 767 768 769 770 771 772
        SAFE_SNPRINTF();

        for( i = 0; i < name->val.len; i++ )
        {
            if( i >= sizeof( s ) - 1 )
                break;

            c = name->val.p[i];
            if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
                 s[i] = '?';
            else s[i] = c;
        }
        s[i] = '\0';
773
        ret = polarssl_snprintf( p, n, "%s", s );
774
        SAFE_SNPRINTF();
775 776

        merge = name->next_merged;
777 778 779 780 781 782 783 784 785 786
        name = name->next;
    }

    return( (int) ( size - n ) );
}

/*
 * Store the serial in printable form into buf; no more
 * than size characters will be written
 */
787
int x509_serial_gets( char *buf, size_t size, const x509_buf *serial )
788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803
{
    int ret;
    size_t i, n, nr;
    char *p;

    p = buf;
    n = size;

    nr = ( serial->len <= 32 )
        ? serial->len  : 28;

    for( i = 0; i < nr; i++ )
    {
        if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
            continue;

804
        ret = polarssl_snprintf( p, n, "%02X%s",
805 806 807 808 809 810
                serial->p[i], ( i < nr - 1 ) ? ":" : "" );
        SAFE_SNPRINTF();
    }

    if( nr != serial->len )
    {
811
        ret = polarssl_snprintf( p, n, "...." );
812 813 814 815 816 817
        SAFE_SNPRINTF();
    }

    return( (int) ( size - n ) );
}

818
/*
819
 * Helper for writing signature algorithms
820 821
 */
int x509_sig_alg_gets( char *buf, size_t size, const x509_buf *sig_oid,
822 823
                       pk_type_t pk_alg, md_type_t md_alg,
                       const void *sig_opts )
824 825 826 827 828 829 830 831
{
    int ret;
    char *p = buf;
    size_t n = size;
    const char *desc = NULL;

    ret = oid_get_sig_alg_desc( sig_oid, &desc );
    if( ret != 0 )
832
        ret = polarssl_snprintf( p, n, "???"  );
833
    else
834
        ret = polarssl_snprintf( p, n, "%s", desc );
835 836
    SAFE_SNPRINTF();

837
#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
838 839
    if( pk_alg == POLARSSL_PK_RSASSA_PSS )
    {
840
        const pk_rsassa_pss_options *pss_opts;
841 842
        const md_info_t *md_info, *mgf_md_info;

843
        pss_opts = (const pk_rsassa_pss_options *) sig_opts;
844 845

        md_info = md_info_from_type( md_alg );
846
        mgf_md_info = md_info_from_type( pss_opts->mgf1_hash_id );
847

848
        ret = polarssl_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)",
849 850
                              md_info ? md_info->name : "???",
                              mgf_md_info ? mgf_md_info->name : "???",
851
                              pss_opts->expected_salt_len );
852 853 854 855
        SAFE_SNPRINTF();
    }
#else
    ((void) pk_alg);
856 857
    ((void) md_alg);
    ((void) sig_opts);
858
#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
859

860
    return( (int)( size - n ) );
861 862
}

863 864 865 866 867 868 869 870 871 872
/*
 * Helper for writing "RSA key size", "EC key size", etc
 */
int x509_key_size_helper( char *buf, size_t size, const char *name )
{
    char *p = buf;
    size_t n = size;
    int ret;

    if( strlen( name ) + sizeof( " key size" ) > size )
873
        return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL );
874

875
    ret = polarssl_snprintf( p, n, "%s key size", name );
876 877 878 879 880 881 882 883
    SAFE_SNPRINTF();

    return( 0 );
}

/*
 * Return an informational string describing the given OID
 */
884
#if ! defined(POLARSSL_DEPRECATED_REMOVED)
885 886 887 888 889 890 891 892 893 894 895 896
const char *x509_oid_get_description( x509_buf *oid )
{
    const char *desc = NULL;
    int ret;

    ret = oid_get_extended_key_usage( oid, &desc );

    if( ret != 0 )
        return( NULL );

    return( desc );
}
897
#endif
898 899

/* Return the x.y.z.... style numeric string for the given OID */
900
#if ! defined(POLARSSL_DEPRECATED_REMOVED)
901 902 903 904
int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
{
    return oid_get_numeric_string( buf, size, oid );
}
905
#endif
906 907 908 909 910 911

/*
 * Return 0 if the x509_time is still valid, or 1 otherwise.
 */
#if defined(POLARSSL_HAVE_TIME)

912 913
static void x509_get_current_time( x509_time *now )
{
914
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
915 916
    SYSTEMTIME st;

917
    GetSystemTime( &st );
918

919 920 921 922 923 924
    now->year = st.wYear;
    now->mon = st.wMonth;
    now->day = st.wDay;
    now->hour = st.wHour;
    now->min = st.wMinute;
    now->sec = st.wSecond;
925
#else
926
    struct tm lt;
927 928 929
    time_t tt;

    tt = time( NULL );
930
    gmtime_r( &tt, &lt );
931 932 933 934 935 936 937

    now->year = lt.tm_year + 1900;
    now->mon = lt.tm_mon + 1;
    now->day = lt.tm_mday;
    now->hour = lt.tm_hour;
    now->min = lt.tm_min;
    now->sec = lt.tm_sec;
938
#endif /* _WIN32 && !EFIX64 && !EFI32 */
939
}
940

941 942 943 944 945 946
/*
 * Return 0 if before <= after, 1 otherwise
 */
static int x509_check_time( const x509_time *before, const x509_time *after )
{
    if( before->year  > after->year )
947 948
        return( 1 );

949 950
    if( before->year == after->year &&
        before->mon   > after->mon )
951 952
        return( 1 );

953 954 955
    if( before->year == after->year &&
        before->mon  == after->mon  &&
        before->day   > after->day )
956 957
        return( 1 );

958 959 960 961
    if( before->year == after->year &&
        before->mon  == after->mon  &&
        before->day  == after->day  &&
        before->hour  > after->hour )
962 963
        return( 1 );

964 965 966 967 968
    if( before->year == after->year &&
        before->mon  == after->mon  &&
        before->day  == after->day  &&
        before->hour == after->hour &&
        before->min   > after->min  )
969 970
        return( 1 );

971 972 973 974 975 976
    if( before->year == after->year &&
        before->mon  == after->mon  &&
        before->day  == after->day  &&
        before->hour == after->hour &&
        before->min  == after->min  &&
        before->sec   > after->sec  )
977 978 979 980
        return( 1 );

    return( 0 );
}
981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999

int x509_time_expired( const x509_time *to )
{
    x509_time now;

    x509_get_current_time( &now );

    return( x509_check_time( &now, to ) );
}

int x509_time_future( const x509_time *from )
{
    x509_time now;

    x509_get_current_time( &now );

    return( x509_check_time( from, &now ) );
}

1000
#else  /* POLARSSL_HAVE_TIME */
1001

1002
int x509_time_expired( const x509_time *to )
1003 1004 1005 1006
{
    ((void) to);
    return( 0 );
}
1007 1008 1009 1010 1011 1012

int x509_time_future( const x509_time *from )
{
    ((void) from);
    return( 0 );
}
1013 1014
#endif /* POLARSSL_HAVE_TIME */

1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
#if defined(POLARSSL_SELF_TEST)

#include "polarssl/x509_crt.h"
#include "polarssl/certs.h"

/*
 * Checkup routine
 */
int x509_self_test( int verbose )
{
1025
#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_SHA1_C)
1026 1027
    int ret;
    int flags;
1028 1029
    x509_crt cacert;
    x509_crt clicert;
1030 1031

    if( verbose != 0 )
1032
        polarssl_printf( "  X.509 certificate load: " );
1033

1034
    x509_crt_init( &clicert );
1035

1036 1037
    ret = x509_crt_parse( &clicert, (const unsigned char *) test_cli_crt,
                          strlen( test_cli_crt ) );
1038 1039 1040
    if( ret != 0 )
    {
        if( verbose != 0 )
1041
            polarssl_printf( "failed\n" );
1042 1043 1044 1045

        return( ret );
    }

1046
    x509_crt_init( &cacert );
1047

1048 1049
    ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_crt,
                          strlen( test_ca_crt ) );
1050 1051 1052
    if( ret != 0 )
    {
        if( verbose != 0 )
1053
            polarssl_printf( "failed\n" );
1054 1055 1056 1057 1058

        return( ret );
    }

    if( verbose != 0 )
1059
        polarssl_printf( "passed\n  X.509 signature verify: ");
1060

1061
    ret = x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
1062 1063 1064
    if( ret != 0 )
    {
        if( verbose != 0 )
1065
            polarssl_printf( "failed\n" );
1066

1067
        polarssl_printf( "ret = %d, &flags = %04x\n", ret, flags );
1068 1069 1070 1071 1072

        return( ret );
    }

    if( verbose != 0 )
1073
        polarssl_printf( "passed\n\n");
1074 1075 1076 1077 1078 1079 1080 1081

    x509_crt_free( &cacert  );
    x509_crt_free( &clicert );

    return( 0 );
#else
    ((void) verbose);
    return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );