x509.c 27.9 KB
Newer Older
1
/*
2
 *  X.509 common functions for parsing and verification
3
 *
4
 *  Copyright (C) 2006-2014, Brainspark B.V.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
 *
 *  This file is part of PolarSSL (http://www.polarssl.org)
 *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
 *
 *  All rights reserved.
 *
 *  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.
 *
28 29 30
 *  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)
31 32 33 34 35
 *
 *  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
 */

36
#if !defined(POLARSSL_CONFIG_FILE)
37
#include "polarssl/config.h"
38 39 40
#else
#include POLARSSL_CONFIG_FILE
#endif
41 42 43 44 45 46 47 48 49 50

#if defined(POLARSSL_X509_USE_C)

#include "polarssl/x509.h"
#include "polarssl/asn1.h"
#include "polarssl/oid.h"
#if defined(POLARSSL_PEM_PARSE_C)
#include "polarssl/pem.h"
#endif

51 52
#if defined(POLARSSL_PLATFORM_C)
#include "polarssl/platform.h"
53
#else
54
#define polarssl_printf     printf
55 56 57 58 59 60
#define polarssl_malloc     malloc
#define polarssl_free       free
#endif

#include <string.h>
#include <stdlib.h>
61
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
62 63 64 65 66
#include <windows.h>
#else
#include <time.h>
#endif

67 68 69 70
#if defined(EFIX64) || defined(EFI32)
#include <stdio.h>
#endif

71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
#if defined(POLARSSL_FS_IO)
#include <stdio.h>
#if !defined(_WIN32)
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#endif
#endif

/*
 *  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 383
                POLARSSL_ERR_ASN1_OUT_OF_DATA );

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

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

    if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
391
        return( POLARSSL_ERR_X509_INVALID_NAME + ret );
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411

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

    cur->next = NULL;

    return( 0 );
}

/*
 *  RelativeDistinguishedName ::=
 *    SET OF AttributeTypeAndValue
 *
 *  AttributeTypeAndValue ::= SEQUENCE {
 *    type     AttributeType,
 *    value    AttributeValue }
 *
 *  AttributeType ::= OBJECT IDENTIFIER
 *
 *  AttributeValue ::= ANY DEFINED BY AttributeType
412 413 414 415
 *
 *  We restrict RelativeDistinguishedName to be a set of 1 element. This is
 *  the most common case, and our x509_name structure currently can't handle
 *  more than that.
416 417 418 419 420
 */
int x509_get_name( unsigned char **p, const unsigned char *end,
                   x509_name *cur )
{
    int ret;
421 422
    size_t set_len;
    const unsigned char *end_set;
423

424 425 426 427 428 429 430 431 432
    /* don't use recursion, we'd risk stack overflow if not optimized */
    while( 1 )
    {
        /*
         * parse first SET, restricted to 1 element
         */
        if( ( ret = asn1_get_tag( p, end, &set_len,
                ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
            return( POLARSSL_ERR_X509_INVALID_NAME + ret );
433

434
        end_set  = *p + set_len;
435

436 437
        if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
            return( ret );
438

439 440
        if( *p != end_set )
            return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
441

442 443 444 445 446
        /*
         * continue until end of SEQUENCE is reached
         */
        if( *p == end )
            return( 0 );
447

448
        cur->next = (x509_name *) polarssl_malloc( sizeof( x509_name ) );
449

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

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

455 456
        cur = cur->next;
    }
457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
}

/*
 *  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;
    char date[64];
    unsigned char tag;

    if( ( end - *p ) < 1 )
473
        return( POLARSSL_ERR_X509_INVALID_DATE +
474 475 476 477
                POLARSSL_ERR_ASN1_OUT_OF_DATA );

    tag = **p;

478
    if( tag == ASN1_UTC_TIME )
479 480 481
    {
        (*p)++;
        ret = asn1_get_len( p, end, &len );
482

483
        if( ret != 0 )
484
            return( POLARSSL_ERR_X509_INVALID_DATE + ret );
485 486 487 488 489

        memset( date,  0, sizeof( date ) );
        memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
                len : sizeof( date ) - 1 );

490
        if( sscanf( date, "%2d%2d%2d%2d%2d%2dZ",
491 492
                    &time->year, &time->mon, &time->day,
                    &time->hour, &time->min, &time->sec ) < 5 )
493
            return( POLARSSL_ERR_X509_INVALID_DATE );
494 495 496 497 498 499 500 501

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

        *p += len;

        return( 0 );
    }
502
    else if( tag == ASN1_GENERALIZED_TIME )
503 504 505
    {
        (*p)++;
        ret = asn1_get_len( p, end, &len );
506

507
        if( ret != 0 )
508
            return( POLARSSL_ERR_X509_INVALID_DATE + ret );
509 510 511 512 513

        memset( date,  0, sizeof( date ) );
        memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
                len : sizeof( date ) - 1 );

514
        if( sscanf( date, "%4d%2d%2d%2d%2d%2dZ",
515 516
                    &time->year, &time->mon, &time->day,
                    &time->hour, &time->min, &time->sec ) < 5 )
517
            return( POLARSSL_ERR_X509_INVALID_DATE );
518 519 520 521 522 523

        *p += len;

        return( 0 );
    }
    else
524 525
        return( POLARSSL_ERR_X509_INVALID_DATE +
                POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
526 527 528 529 530 531 532 533
}

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

    if( ( end - *p ) < 1 )
534
        return( POLARSSL_ERR_X509_INVALID_SIGNATURE +
535 536 537 538 539
                POLARSSL_ERR_ASN1_OUT_OF_DATA );

    sig->tag = **p;

    if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
540
        return( POLARSSL_ERR_X509_INVALID_SIGNATURE + ret );
541 542 543 544 545 546 547 548 549

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

    *p += len;

    return( 0 );
}

550 551 552 553
/*
 * Get signature algorithm from alg OID and optional parameters
 */
int x509_get_sig_alg( const x509_buf *sig_oid, const x509_buf *sig_params,
554 555
                      md_type_t *md_alg, pk_type_t *pk_alg,
                      void **sig_opts )
556
{
557
    int ret;
558

559 560 561
    if( *sig_opts != NULL )
        return( POLARSSL_ERR_X509_BAD_INPUT_DATA );

562
    if( ( ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 )
563
        return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG + ret );
564

565
#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
566 567
    if( *pk_alg == POLARSSL_PK_RSASSA_PSS )
    {
568 569 570 571 572
        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 );
573 574

        ret = x509_get_rsassa_pss_params( sig_params,
575 576 577
                                          md_alg,
                                          &pss_opts->mgf1_hash_id,
                                          &pss_opts->expected_salt_len );
578
        if( ret != 0 )
579 580
        {
            polarssl_free( pss_opts );
581
            return( ret );
582
        }
583

584
        *sig_opts = (void *) pss_opts;
585 586
    }
    else
587
#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
588 589 590 591 592 593 594
    {
        /* 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 );
    }

595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629
    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 )
630
        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
631 632

    if( end != *p + len )
633
        return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
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 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );

    return( 0 );
}

#if defined(POLARSSL_FS_IO)
/*
 * Load all data from a file into a given buffer.
 */
int x509_load_file( const char *path, unsigned char **buf, size_t *n )
{
    FILE *f;
    long size;

    if( ( f = fopen( path, "rb" ) ) == NULL )
        return( POLARSSL_ERR_X509_FILE_IO_ERROR );

    fseek( f, 0, SEEK_END );
    if( ( size = ftell( f ) ) == -1 )
    {
        fclose( f );
        return( POLARSSL_ERR_X509_FILE_IO_ERROR );
    }
    fseek( f, 0, SEEK_SET );

    *n = (size_t) size;

    if( *n + 1 == 0 ||
        ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
    {
        fclose( f );
        return( POLARSSL_ERR_X509_MALLOC_FAILED );
    }

    if( fread( *buf, 1, *n, f ) != *n )
    {
        fclose( f );
        polarssl_free( *buf );
        return( POLARSSL_ERR_X509_FILE_IO_ERROR );
    }

    fclose( f );

    (*buf)[*n] = '\0';

    return( 0 );
}
#endif /* POLARSSL_FS_IO */

683 684
#if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
    !defined(EFI32)
685 686 687 688 689 690 691 692 693 694 695 696 697
#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.
 */
698
static int compat_snprintf( char *str, size_t size, const char *format, ... )
699 700 701 702 703 704 705 706 707 708 709
{
    va_list ap;
    int res = -1;

    va_start( ap, format );

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

    va_end( ap );

    // No quick fix possible
710
    if( res < 0 )
711 712
        return( (int) size + 20 );

713
    return( res );
714 715 716
}

#define snprintf compat_snprintf
717
#endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */
718 719 720

#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL    -2

721 722 723 724 725
#define SAFE_SNPRINTF()                             \
{                                                   \
    if( ret == -1 )                                 \
        return( -1 );                               \
                                                    \
726
    if( (unsigned int) ret > n ) {                  \
727 728 729 730 731 732
        p[n - 1] = '\0';                            \
        return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \
    }                                               \
                                                    \
    n -= (unsigned int) ret;                        \
    p += (unsigned int) ret;                        \
733 734 735 736 737 738
}

/*
 * Store the name in printable form into buf; no more
 * than size characters will be written
 */
739
int x509_dn_gets( char *buf, size_t size, const x509_name *dn )
740 741 742 743 744 745
{
    int ret;
    size_t i, n;
    unsigned char c;
    const x509_name *name;
    const char *short_name = NULL;
746
    char s[X509_MAX_DN_NAME_SIZE], *p;
747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798

    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 )
        {
            ret = snprintf( p, n, ", " );
            SAFE_SNPRINTF();
        }

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

        if( ret == 0 )
            ret = snprintf( p, n, "%s=", short_name );
        else
            ret = snprintf( p, n, "\?\?=" );
        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';
        ret = snprintf( p, n, "%s", s );
        SAFE_SNPRINTF();
        name = name->next;
    }

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

/*
 * Store the serial in printable form into buf; no more
 * than size characters will be written
 */
799
int x509_serial_gets( char *buf, size_t size, const x509_buf *serial )
800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829
{
    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;

        ret = snprintf( p, n, "%02X%s",
                serial->p[i], ( i < nr - 1 ) ? ":" : "" );
        SAFE_SNPRINTF();
    }

    if( nr != serial->len )
    {
        ret = snprintf( p, n, "...." );
        SAFE_SNPRINTF();
    }

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

830
/*
831
 * Helper for writing signature algorithms
832 833
 */
int x509_sig_alg_gets( char *buf, size_t size, const x509_buf *sig_oid,
834 835
                       pk_type_t pk_alg, md_type_t md_alg,
                       const void *sig_opts )
836 837 838 839 840 841 842 843 844 845 846 847 848
{
    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 )
        ret = snprintf( p, n, "???"  );
    else
        ret = snprintf( p, n, "%s", desc );
    SAFE_SNPRINTF();

849
#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
850 851
    if( pk_alg == POLARSSL_PK_RSASSA_PSS )
    {
852
        const pk_rsassa_pss_options *pss_opts;
853 854
        const md_info_t *md_info, *mgf_md_info;

855
        pss_opts = (const pk_rsassa_pss_options *) sig_opts;
856 857

        md_info = md_info_from_type( md_alg );
858
        mgf_md_info = md_info_from_type( pss_opts->mgf1_hash_id );
859

860
        ret = snprintf( p, n, " (%s, MGF1-%s, 0x%02X)",
861 862
                              md_info ? md_info->name : "???",
                              mgf_md_info ? mgf_md_info->name : "???",
863
                              pss_opts->expected_salt_len );
864 865 866 867
        SAFE_SNPRINTF();
    }
#else
    ((void) pk_alg);
868 869
    ((void) md_alg);
    ((void) sig_opts);
870
#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */
871

872
    return( (int)( size - n ) );
873 874
}

875 876 877 878 879 880 881 882 883 884
/*
 * 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 )
885
        return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL );
886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919

    ret = snprintf( p, n, "%s key size", name );
    SAFE_SNPRINTF();

    return( 0 );
}

/*
 * Return an informational string describing the given OID
 */
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 );
}

/* Return the x.y.z.... style numeric string for the given OID */
int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
{
    return oid_get_numeric_string( buf, size, oid );
}

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

920 921
static void x509_get_current_time( x509_time *now )
{
922
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
923 924
    SYSTEMTIME st;

925
    GetSystemTime( &st );
926

927 928 929 930 931 932
    now->year = st.wYear;
    now->mon = st.wMonth;
    now->day = st.wDay;
    now->hour = st.wHour;
    now->min = st.wMinute;
    now->sec = st.wSecond;
933
#else
934
    struct tm lt;
935 936 937
    time_t tt;

    tt = time( NULL );
938
    gmtime_r( &tt, &lt );
939 940 941 942 943 944 945

    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;
946
#endif /* _WIN32 && !EFIX64 && !EFI32 */
947
}
948

949 950 951 952 953 954
/*
 * 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 )
955 956
        return( 1 );

957 958
    if( before->year == after->year &&
        before->mon   > after->mon )
959 960
        return( 1 );

961 962 963
    if( before->year == after->year &&
        before->mon  == after->mon  &&
        before->day   > after->day )
964 965
        return( 1 );

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

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  )
977 978
        return( 1 );

979 980 981 982 983 984
    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  )
985 986 987 988
        return( 1 );

    return( 0 );
}
989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007

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 ) );
}

1008
#else  /* POLARSSL_HAVE_TIME */
1009

1010
int x509_time_expired( const x509_time *to )
1011 1012 1013 1014
{
    ((void) to);
    return( 0 );
}
1015 1016 1017 1018 1019 1020

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

1023 1024 1025 1026 1027 1028 1029 1030 1031 1032
#if defined(POLARSSL_SELF_TEST)

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

/*
 * Checkup routine
 */
int x509_self_test( int verbose )
{
1033
#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_SHA1_C)
1034 1035
    int ret;
    int flags;
1036 1037
    x509_crt cacert;
    x509_crt clicert;
1038 1039

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

1042
    x509_crt_init( &clicert );
1043

1044 1045
    ret = x509_crt_parse( &clicert, (const unsigned char *) test_cli_crt,
                          strlen( test_cli_crt ) );
1046 1047 1048
    if( ret != 0 )
    {
        if( verbose != 0 )
1049
            polarssl_printf( "failed\n" );
1050 1051 1052 1053

        return( ret );
    }

1054
    x509_crt_init( &cacert );
1055

1056 1057
    ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_crt,
                          strlen( test_ca_crt ) );
1058 1059 1060
    if( ret != 0 )
    {
        if( verbose != 0 )
1061
            polarssl_printf( "failed\n" );
1062 1063 1064 1065 1066

        return( ret );
    }

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

1069
    ret = x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
1070 1071 1072
    if( ret != 0 )
    {
        if( verbose != 0 )
1073
            polarssl_printf( "failed\n" );
1074

1075
        polarssl_printf( "ret = %d, &flags = %04x\n", ret, flags );
1076 1077 1078 1079 1080

        return( ret );
    }

    if( verbose != 0 )
1081
        polarssl_printf( "passed\n\n");
1082 1083 1084 1085 1086 1087 1088 1089

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

    return( 0 );
#else
    ((void) verbose);
    return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
1090
#endif /* POLARSSL_CERTS_C && POLARSSL_SHA1_C */
1091 1092
}

1093
#endif /* POLARSSL_SELF_TEST */
1094

1095
#endif /* POLARSSL_X509_USE_C */