Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  *  X.509 common functions for parsing and verification
  3.  *
  4.  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  5.  *  SPDX-License-Identifier: GPL-2.0
  6.  *
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License along
  18.  *  with this program; if not, write to the Free Software Foundation, Inc.,
  19.  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20.  *
  21.  *  This file is part of mbed TLS (https://tls.mbed.org)
  22.  */
  23. /*
  24.  *  The ITU-T X.509 standard defines a certificate format for PKI.
  25.  *
  26.  *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
  27.  *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
  28.  *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
  29.  *
  30.  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
  31.  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
  32.  */
  33.  
  34. #if !defined(MBEDTLS_CONFIG_FILE)
  35. #include "mbedtls/config.h"
  36. #else
  37. #include MBEDTLS_CONFIG_FILE
  38. #endif
  39.  
  40. #if defined(MBEDTLS_X509_USE_C)
  41.  
  42. #include "mbedtls/x509.h"
  43. #include "mbedtls/asn1.h"
  44. #include "mbedtls/oid.h"
  45.  
  46. #include <stdio.h>
  47. #include <string.h>
  48.  
  49. #if defined(MBEDTLS_PEM_PARSE_C)
  50. #include "mbedtls/pem.h"
  51. #endif
  52.  
  53. #if defined(MBEDTLS_PLATFORM_C)
  54. #include "mbedtls/platform.h"
  55. #else
  56. #include <stdio.h>
  57. #include <stdlib.h>
  58. #define mbedtls_free      free
  59. #define mbedtls_calloc    calloc
  60. #define mbedtls_printf    printf
  61. #define mbedtls_snprintf  snprintf
  62. #endif
  63.  
  64. #if defined(MBEDTLS_HAVE_TIME)
  65. #include "mbedtls/platform_time.h"
  66. #endif
  67. #if defined(MBEDTLS_HAVE_TIME_DATE)
  68. #include "mbedtls/platform_util.h"
  69. #include <time.h>
  70. #endif
  71.  
  72. #define CHECK(code) if( ( ret = ( code ) ) != 0 ){ return( ret ); }
  73. #define CHECK_RANGE(min, max, val)                      \
  74.     do                                                  \
  75.     {                                                   \
  76.         if( ( val ) < ( min ) || ( val ) > ( max ) )    \
  77.         {                                               \
  78.             return( ret );                              \
  79.         }                                               \
  80.     } while( 0 )
  81.  
  82. /*
  83.  *  CertificateSerialNumber  ::=  INTEGER
  84.  */
  85. int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
  86.                      mbedtls_x509_buf *serial )
  87. {
  88.     int ret;
  89.  
  90.     if( ( end - *p ) < 1 )
  91.         return( MBEDTLS_ERR_X509_INVALID_SERIAL +
  92.                 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
  93.  
  94.     if( **p != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2 ) &&
  95.         **p !=   MBEDTLS_ASN1_INTEGER )
  96.         return( MBEDTLS_ERR_X509_INVALID_SERIAL +
  97.                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
  98.  
  99.     serial->tag = *(*p)++;
  100.  
  101.     if( ( ret = mbedtls_asn1_get_len( p, end, &serial->len ) ) != 0 )
  102.         return( MBEDTLS_ERR_X509_INVALID_SERIAL + ret );
  103.  
  104.     serial->p = *p;
  105.     *p += serial->len;
  106.  
  107.     return( 0 );
  108. }
  109.  
  110. /* Get an algorithm identifier without parameters (eg for signatures)
  111.  *
  112.  *  AlgorithmIdentifier  ::=  SEQUENCE  {
  113.  *       algorithm               OBJECT IDENTIFIER,
  114.  *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
  115.  */
  116. int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
  117.                        mbedtls_x509_buf *alg )
  118. {
  119.     int ret;
  120.  
  121.     if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 )
  122.         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
  123.  
  124.     return( 0 );
  125. }
  126.  
  127. /*
  128.  * Parse an algorithm identifier with (optional) parameters
  129.  */
  130. int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
  131.                   mbedtls_x509_buf *alg, mbedtls_x509_buf *params )
  132. {
  133.     int ret;
  134.  
  135.     if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 )
  136.         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
  137.  
  138.     return( 0 );
  139. }
  140.  
  141. #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
  142. /*
  143.  * HashAlgorithm ::= AlgorithmIdentifier
  144.  *
  145.  * AlgorithmIdentifier  ::=  SEQUENCE  {
  146.  *      algorithm               OBJECT IDENTIFIER,
  147.  *      parameters              ANY DEFINED BY algorithm OPTIONAL  }
  148.  *
  149.  * For HashAlgorithm, parameters MUST be NULL or absent.
  150.  */
  151. static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg )
  152. {
  153.     int ret;
  154.     unsigned char *p;
  155.     const unsigned char *end;
  156.     mbedtls_x509_buf md_oid;
  157.     size_t len;
  158.  
  159.     /* Make sure we got a SEQUENCE and setup bounds */
  160.     if( alg->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
  161.         return( MBEDTLS_ERR_X509_INVALID_ALG +
  162.                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
  163.  
  164.     p = (unsigned char *) alg->p;
  165.     end = p + alg->len;
  166.  
  167.     if( p >= end )
  168.         return( MBEDTLS_ERR_X509_INVALID_ALG +
  169.                 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
  170.  
  171.     /* Parse md_oid */
  172.     md_oid.tag = *p;
  173.  
  174.     if( ( ret = mbedtls_asn1_get_tag( &p, end, &md_oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
  175.         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
  176.  
  177.     md_oid.p = p;
  178.     p += md_oid.len;
  179.  
  180.     /* Get md_alg from md_oid */
  181.     if( ( ret = mbedtls_oid_get_md_alg( &md_oid, md_alg ) ) != 0 )
  182.         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
  183.  
  184.     /* Make sure params is absent of NULL */
  185.     if( p == end )
  186.         return( 0 );
  187.  
  188.     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_NULL ) ) != 0 || len != 0 )
  189.         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
  190.  
  191.     if( p != end )
  192.         return( MBEDTLS_ERR_X509_INVALID_ALG +
  193.                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
  194.  
  195.     return( 0 );
  196. }
  197.  
  198. /*
  199.  *    RSASSA-PSS-params  ::=  SEQUENCE  {
  200.  *       hashAlgorithm     [0] HashAlgorithm DEFAULT sha1Identifier,
  201.  *       maskGenAlgorithm  [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
  202.  *       saltLength        [2] INTEGER DEFAULT 20,
  203.  *       trailerField      [3] INTEGER DEFAULT 1  }
  204.  *    -- Note that the tags in this Sequence are explicit.
  205.  *
  206.  * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value
  207.  * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
  208.  * option. Enfore this at parsing time.
  209.  */
  210. int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
  211.                                 mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
  212.                                 int *salt_len )
  213. {
  214.     int ret;
  215.     unsigned char *p;
  216.     const unsigned char *end, *end2;
  217.     size_t len;
  218.     mbedtls_x509_buf alg_id, alg_params;
  219.  
  220.     /* First set everything to defaults */
  221.     *md_alg = MBEDTLS_MD_SHA1;
  222.     *mgf_md = MBEDTLS_MD_SHA1;
  223.     *salt_len = 20;
  224.  
  225.     /* Make sure params is a SEQUENCE and setup bounds */
  226.     if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
  227.         return( MBEDTLS_ERR_X509_INVALID_ALG +
  228.                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
  229.  
  230.     p = (unsigned char *) params->p;
  231.     end = p + params->len;
  232.  
  233.     if( p == end )
  234.         return( 0 );
  235.  
  236.     /*
  237.      * HashAlgorithm
  238.      */
  239.     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
  240.                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 )
  241.     {
  242.         end2 = p + len;
  243.  
  244.         /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
  245.         if( ( ret = mbedtls_x509_get_alg_null( &p, end2, &alg_id ) ) != 0 )
  246.             return( ret );
  247.  
  248.         if( ( ret = mbedtls_oid_get_md_alg( &alg_id, md_alg ) ) != 0 )
  249.             return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
  250.  
  251.         if( p != end2 )
  252.             return( MBEDTLS_ERR_X509_INVALID_ALG +
  253.                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
  254.     }
  255.     else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
  256.         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
  257.  
  258.     if( p == end )
  259.         return( 0 );
  260.  
  261.     /*
  262.      * MaskGenAlgorithm
  263.      */
  264.     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
  265.                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 )
  266.     {
  267.         end2 = p + len;
  268.  
  269.         /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
  270.         if( ( ret = mbedtls_x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 )
  271.             return( ret );
  272.  
  273.         /* Only MFG1 is recognised for now */
  274.         if( MBEDTLS_OID_CMP( MBEDTLS_OID_MGF1, &alg_id ) != 0 )
  275.             return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE +
  276.                     MBEDTLS_ERR_OID_NOT_FOUND );
  277.  
  278.         /* Parse HashAlgorithm */
  279.         if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 )
  280.             return( ret );
  281.  
  282.         if( p != end2 )
  283.             return( MBEDTLS_ERR_X509_INVALID_ALG +
  284.                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
  285.     }
  286.     else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
  287.         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
  288.  
  289.     if( p == end )
  290.         return( 0 );
  291.  
  292.     /*
  293.      * salt_len
  294.      */
  295.     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
  296.                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 2 ) ) == 0 )
  297.     {
  298.         end2 = p + len;
  299.  
  300.         if( ( ret = mbedtls_asn1_get_int( &p, end2, salt_len ) ) != 0 )
  301.             return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
  302.  
  303.         if( p != end2 )
  304.             return( MBEDTLS_ERR_X509_INVALID_ALG +
  305.                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
  306.     }
  307.     else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
  308.         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
  309.  
  310.     if( p == end )
  311.         return( 0 );
  312.  
  313.     /*
  314.      * trailer_field (if present, must be 1)
  315.      */
  316.     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
  317.                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 3 ) ) == 0 )
  318.     {
  319.         int trailer_field;
  320.  
  321.         end2 = p + len;
  322.  
  323.         if( ( ret = mbedtls_asn1_get_int( &p, end2, &trailer_field ) ) != 0 )
  324.             return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
  325.  
  326.         if( p != end2 )
  327.             return( MBEDTLS_ERR_X509_INVALID_ALG +
  328.                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
  329.  
  330.         if( trailer_field != 1 )
  331.             return( MBEDTLS_ERR_X509_INVALID_ALG );
  332.     }
  333.     else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
  334.         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
  335.  
  336.     if( p != end )
  337.         return( MBEDTLS_ERR_X509_INVALID_ALG +
  338.                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
  339.  
  340.     return( 0 );
  341. }
  342. #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
  343.  
  344. /*
  345.  *  AttributeTypeAndValue ::= SEQUENCE {
  346.  *    type     AttributeType,
  347.  *    value    AttributeValue }
  348.  *
  349.  *  AttributeType ::= OBJECT IDENTIFIER
  350.  *
  351.  *  AttributeValue ::= ANY DEFINED BY AttributeType
  352.  */
  353. static int x509_get_attr_type_value( unsigned char **p,
  354.                                      const unsigned char *end,
  355.                                      mbedtls_x509_name *cur )
  356. {
  357.     int ret;
  358.     size_t len;
  359.     mbedtls_x509_buf *oid;
  360.     mbedtls_x509_buf *val;
  361.  
  362.     if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
  363.             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
  364.         return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
  365.  
  366.     end = *p + len;
  367.  
  368.     if( ( end - *p ) < 1 )
  369.         return( MBEDTLS_ERR_X509_INVALID_NAME +
  370.                 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
  371.  
  372.     oid = &cur->oid;
  373.     oid->tag = **p;
  374.  
  375.     if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 )
  376.         return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
  377.  
  378.     oid->p = *p;
  379.     *p += oid->len;
  380.  
  381.     if( ( end - *p ) < 1 )
  382.         return( MBEDTLS_ERR_X509_INVALID_NAME +
  383.                 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
  384.  
  385.     if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING      &&
  386.         **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING &&
  387.         **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING &&
  388.         **p != MBEDTLS_ASN1_BIT_STRING )
  389.         return( MBEDTLS_ERR_X509_INVALID_NAME +
  390.                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
  391.  
  392.     val = &cur->val;
  393.     val->tag = *(*p)++;
  394.  
  395.     if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 )
  396.         return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
  397.  
  398.     val->p = *p;
  399.     *p += val->len;
  400.  
  401.     if( *p != end )
  402.     {
  403.         return( MBEDTLS_ERR_X509_INVALID_NAME +
  404.                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
  405.     }
  406.  
  407.     cur->next = NULL;
  408.  
  409.     return( 0 );
  410. }
  411.  
  412. /*
  413.  *  Name ::= CHOICE { -- only one possibility for now --
  414.  *       rdnSequence  RDNSequence }
  415.  *
  416.  *  RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
  417.  *
  418.  *  RelativeDistinguishedName ::=
  419.  *    SET OF AttributeTypeAndValue
  420.  *
  421.  *  AttributeTypeAndValue ::= SEQUENCE {
  422.  *    type     AttributeType,
  423.  *    value    AttributeValue }
  424.  *
  425.  *  AttributeType ::= OBJECT IDENTIFIER
  426.  *
  427.  *  AttributeValue ::= ANY DEFINED BY AttributeType
  428.  *
  429.  * The data structure is optimized for the common case where each RDN has only
  430.  * one element, which is represented as a list of AttributeTypeAndValue.
  431.  * For the general case we still use a flat list, but we mark elements of the
  432.  * same set so that they are "merged" together in the functions that consume
  433.  * this list, eg mbedtls_x509_dn_gets().
  434.  */
  435. int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
  436.                    mbedtls_x509_name *cur )
  437. {
  438.     int ret;
  439.     size_t set_len;
  440.     const unsigned char *end_set;
  441.  
  442.     /* don't use recursion, we'd risk stack overflow if not optimized */
  443.     while( 1 )
  444.     {
  445.         /*
  446.          * parse SET
  447.          */
  448.         if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len,
  449.                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 )
  450.             return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
  451.  
  452.         end_set  = *p + set_len;
  453.  
  454.         while( 1 )
  455.         {
  456.             if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
  457.                 return( ret );
  458.  
  459.             if( *p == end_set )
  460.                 break;
  461.  
  462.             /* Mark this item as being no the only one in a set */
  463.             cur->next_merged = 1;
  464.  
  465.             cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
  466.  
  467.             if( cur->next == NULL )
  468.                 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
  469.  
  470.             cur = cur->next;
  471.         }
  472.  
  473.         /*
  474.          * continue until end of SEQUENCE is reached
  475.          */
  476.         if( *p == end )
  477.             return( 0 );
  478.  
  479.         cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
  480.  
  481.         if( cur->next == NULL )
  482.             return( MBEDTLS_ERR_X509_ALLOC_FAILED );
  483.  
  484.         cur = cur->next;
  485.     }
  486. }
  487.  
  488. static int x509_parse_int( unsigned char **p, size_t n, int *res )
  489. {
  490.     *res = 0;
  491.  
  492.     for( ; n > 0; --n )
  493.     {
  494.         if( ( **p < '0') || ( **p > '9' ) )
  495.             return ( MBEDTLS_ERR_X509_INVALID_DATE );
  496.  
  497.         *res *= 10;
  498.         *res += ( *(*p)++ - '0' );
  499.     }
  500.  
  501.     return( 0 );
  502. }
  503.  
  504. static int x509_date_is_valid(const mbedtls_x509_time *t )
  505. {
  506.     int ret = MBEDTLS_ERR_X509_INVALID_DATE;
  507.     int month_len;
  508.  
  509.     CHECK_RANGE( 0, 9999, t->year );
  510.     CHECK_RANGE( 0, 23,   t->hour );
  511.     CHECK_RANGE( 0, 59,   t->min  );
  512.     CHECK_RANGE( 0, 59,   t->sec  );
  513.  
  514.     switch( t->mon )
  515.     {
  516.         case 1: case 3: case 5: case 7: case 8: case 10: case 12:
  517.             month_len = 31;
  518.             break;
  519.         case 4: case 6: case 9: case 11:
  520.             month_len = 30;
  521.             break;
  522.         case 2:
  523.             if( ( !( t->year % 4 ) && t->year % 100 ) ||
  524.                 !( t->year % 400 ) )
  525.                 month_len = 29;
  526.             else
  527.                 month_len = 28;
  528.             break;
  529.         default:
  530.             return( ret );
  531.     }
  532.     CHECK_RANGE( 1, month_len, t->day );
  533.  
  534.     return( 0 );
  535. }
  536.  
  537. /*
  538.  * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4)
  539.  * field.
  540.  */
  541. static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen,
  542.                             mbedtls_x509_time *tm )
  543. {
  544.     int ret;
  545.  
  546.     /*
  547.      * Minimum length is 10 or 12 depending on yearlen
  548.      */
  549.     if ( len < yearlen + 8 )
  550.         return ( MBEDTLS_ERR_X509_INVALID_DATE );
  551.     len -= yearlen + 8;
  552.  
  553.     /*
  554.      * Parse year, month, day, hour, minute
  555.      */
  556.     CHECK( x509_parse_int( p, yearlen, &tm->year ) );
  557.     if ( 2 == yearlen )
  558.     {
  559.         if ( tm->year < 50 )
  560.             tm->year += 100;
  561.  
  562.         tm->year += 1900;
  563.     }
  564.  
  565.     CHECK( x509_parse_int( p, 2, &tm->mon ) );
  566.     CHECK( x509_parse_int( p, 2, &tm->day ) );
  567.     CHECK( x509_parse_int( p, 2, &tm->hour ) );
  568.     CHECK( x509_parse_int( p, 2, &tm->min ) );
  569.  
  570.     /*
  571.      * Parse seconds if present
  572.      */
  573.     if ( len >= 2 )
  574.     {
  575.         CHECK( x509_parse_int( p, 2, &tm->sec ) );
  576.         len -= 2;
  577.     }
  578.     else
  579.         return ( MBEDTLS_ERR_X509_INVALID_DATE );
  580.  
  581.     /*
  582.      * Parse trailing 'Z' if present
  583.      */
  584.     if ( 1 == len && 'Z' == **p )
  585.     {
  586.         (*p)++;
  587.         len--;
  588.     }
  589.  
  590.     /*
  591.      * We should have parsed all characters at this point
  592.      */
  593.     if ( 0 != len )
  594.         return ( MBEDTLS_ERR_X509_INVALID_DATE );
  595.  
  596.     CHECK( x509_date_is_valid( tm ) );
  597.  
  598.     return ( 0 );
  599. }
  600.  
  601. /*
  602.  *  Time ::= CHOICE {
  603.  *       utcTime        UTCTime,
  604.  *       generalTime    GeneralizedTime }
  605.  */
  606. int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
  607.                            mbedtls_x509_time *tm )
  608. {
  609.     int ret;
  610.     size_t len, year_len;
  611.     unsigned char tag;
  612.  
  613.     if( ( end - *p ) < 1 )
  614.         return( MBEDTLS_ERR_X509_INVALID_DATE +
  615.                 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
  616.  
  617.     tag = **p;
  618.  
  619.     if( tag == MBEDTLS_ASN1_UTC_TIME )
  620.         year_len = 2;
  621.     else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME )
  622.         year_len = 4;
  623.     else
  624.         return( MBEDTLS_ERR_X509_INVALID_DATE +
  625.                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
  626.  
  627.     (*p)++;
  628.     ret = mbedtls_asn1_get_len( p, end, &len );
  629.  
  630.     if( ret != 0 )
  631.         return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
  632.  
  633.     return x509_parse_time( p, len, year_len, tm );
  634. }
  635.  
  636. int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig )
  637. {
  638.     int ret;
  639.     size_t len;
  640.     int tag_type;
  641.  
  642.     if( ( end - *p ) < 1 )
  643.         return( MBEDTLS_ERR_X509_INVALID_SIGNATURE +
  644.                 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
  645.  
  646.     tag_type = **p;
  647.  
  648.     if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 )
  649.         return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret );
  650.  
  651.     sig->tag = tag_type;
  652.     sig->len = len;
  653.     sig->p = *p;
  654.  
  655.     *p += len;
  656.  
  657.     return( 0 );
  658. }
  659.  
  660. /*
  661.  * Get signature algorithm from alg OID and optional parameters
  662.  */
  663. int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
  664.                       mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
  665.                       void **sig_opts )
  666. {
  667.     int ret;
  668.  
  669.     if( *sig_opts != NULL )
  670.         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
  671.  
  672.     if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 )
  673.         return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret );
  674.  
  675. #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
  676.     if( *pk_alg == MBEDTLS_PK_RSASSA_PSS )
  677.     {
  678.         mbedtls_pk_rsassa_pss_options *pss_opts;
  679.  
  680.         pss_opts = mbedtls_calloc( 1, sizeof( mbedtls_pk_rsassa_pss_options ) );
  681.         if( pss_opts == NULL )
  682.             return( MBEDTLS_ERR_X509_ALLOC_FAILED );
  683.  
  684.         ret = mbedtls_x509_get_rsassa_pss_params( sig_params,
  685.                                           md_alg,
  686.                                           &pss_opts->mgf1_hash_id,
  687.                                           &pss_opts->expected_salt_len );
  688.         if( ret != 0 )
  689.         {
  690.             mbedtls_free( pss_opts );
  691.             return( ret );
  692.         }
  693.  
  694.         *sig_opts = (void *) pss_opts;
  695.     }
  696.     else
  697. #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
  698.     {
  699.         /* Make sure parameters are absent or NULL */
  700.         if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) ||
  701.               sig_params->len != 0 )
  702.         return( MBEDTLS_ERR_X509_INVALID_ALG );
  703.     }
  704.  
  705.     return( 0 );
  706. }
  707.  
  708. /*
  709.  * X.509 Extensions (No parsing of extensions, pointer should
  710.  * be either manually updated or extensions should be parsed!)
  711.  */
  712. int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
  713.                           mbedtls_x509_buf *ext, int tag )
  714. {
  715.     int ret;
  716.     size_t len;
  717.  
  718.     /* Extension structure use EXPLICIT tagging. That is, the actual
  719.      * `Extensions` structure is wrapped by a tag-length pair using
  720.      * the respective context-specific tag. */
  721.     ret = mbedtls_asn1_get_tag( p, end, &ext->len,
  722.               MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag );
  723.     if( ret != 0 )
  724.         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
  725.  
  726.     ext->tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag;
  727.     ext->p   = *p;
  728.     end      = *p + ext->len;
  729.  
  730.     /*
  731.      * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
  732.      */
  733.     if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
  734.             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
  735.         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
  736.  
  737.     if( end != *p + len )
  738.         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
  739.                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
  740.  
  741.     return( 0 );
  742. }
  743.  
  744. /*
  745.  * Store the name in printable form into buf; no more
  746.  * than size characters will be written
  747.  */
  748. int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
  749. {
  750.     int ret;
  751.     size_t i, n;
  752.     unsigned char c, merge = 0;
  753.     const mbedtls_x509_name *name;
  754.     const char *short_name = NULL;
  755.     char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p;
  756.  
  757.     memset( s, 0, sizeof( s ) );
  758.  
  759.     name = dn;
  760.     p = buf;
  761.     n = size;
  762.  
  763.     while( name != NULL )
  764.     {
  765.         if( !name->oid.p )
  766.         {
  767.             name = name->next;
  768.             continue;
  769.         }
  770.  
  771.         if( name != dn )
  772.         {
  773.             ret = mbedtls_snprintf( p, n, merge ? " + " : ", " );
  774.             MBEDTLS_X509_SAFE_SNPRINTF;
  775.         }
  776.  
  777.         ret = mbedtls_oid_get_attr_short_name( &name->oid, &short_name );
  778.  
  779.         if( ret == 0 )
  780.             ret = mbedtls_snprintf( p, n, "%s=", short_name );
  781.         else
  782.             ret = mbedtls_snprintf( p, n, "\?\?=" );
  783.         MBEDTLS_X509_SAFE_SNPRINTF;
  784.  
  785.         for( i = 0; i < name->val.len; i++ )
  786.         {
  787.             if( i >= sizeof( s ) - 1 )
  788.                 break;
  789.  
  790.             c = name->val.p[i];
  791.             if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
  792.                  s[i] = '?';
  793.             else s[i] = c;
  794.         }
  795.         s[i] = '\0';
  796.         ret = mbedtls_snprintf( p, n, "%s", s );
  797.         MBEDTLS_X509_SAFE_SNPRINTF;
  798.  
  799.         merge = name->next_merged;
  800.         name = name->next;
  801.     }
  802.  
  803.     return( (int) ( size - n ) );
  804. }
  805.  
  806. /*
  807.  * Store the serial in printable form into buf; no more
  808.  * than size characters will be written
  809.  */
  810. int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial )
  811. {
  812.     int ret;
  813.     size_t i, n, nr;
  814.     char *p;
  815.  
  816.     p = buf;
  817.     n = size;
  818.  
  819.     nr = ( serial->len <= 32 )
  820.         ? serial->len  : 28;
  821.  
  822.     for( i = 0; i < nr; i++ )
  823.     {
  824.         if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
  825.             continue;
  826.  
  827.         ret = mbedtls_snprintf( p, n, "%02X%s",
  828.                 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
  829.         MBEDTLS_X509_SAFE_SNPRINTF;
  830.     }
  831.  
  832.     if( nr != serial->len )
  833.     {
  834.         ret = mbedtls_snprintf( p, n, "...." );
  835.         MBEDTLS_X509_SAFE_SNPRINTF;
  836.     }
  837.  
  838.     return( (int) ( size - n ) );
  839. }
  840.  
  841. /*
  842.  * Helper for writing signature algorithms
  843.  */
  844. int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
  845.                        mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
  846.                        const void *sig_opts )
  847. {
  848.     int ret;
  849.     char *p = buf;
  850.     size_t n = size;
  851.     const char *desc = NULL;
  852.  
  853.     ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc );
  854.     if( ret != 0 )
  855.         ret = mbedtls_snprintf( p, n, "???"  );
  856.     else
  857.         ret = mbedtls_snprintf( p, n, "%s", desc );
  858.     MBEDTLS_X509_SAFE_SNPRINTF;
  859.  
  860. #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
  861.     if( pk_alg == MBEDTLS_PK_RSASSA_PSS )
  862.     {
  863.         const mbedtls_pk_rsassa_pss_options *pss_opts;
  864.         const mbedtls_md_info_t *md_info, *mgf_md_info;
  865.  
  866.         pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts;
  867.  
  868.         md_info = mbedtls_md_info_from_type( md_alg );
  869.         mgf_md_info = mbedtls_md_info_from_type( pss_opts->mgf1_hash_id );
  870.  
  871.         ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)",
  872.                               md_info ? mbedtls_md_get_name( md_info ) : "???",
  873.                               mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???",
  874.                               pss_opts->expected_salt_len );
  875.         MBEDTLS_X509_SAFE_SNPRINTF;
  876.     }
  877. #else
  878.     ((void) pk_alg);
  879.     ((void) md_alg);
  880.     ((void) sig_opts);
  881. #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
  882.  
  883.     return( (int)( size - n ) );
  884. }
  885.  
  886. /*
  887.  * Helper for writing "RSA key size", "EC key size", etc
  888.  */
  889. int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name )
  890. {
  891.     char *p = buf;
  892.     size_t n = buf_size;
  893.     int ret;
  894.  
  895.     ret = mbedtls_snprintf( p, n, "%s key size", name );
  896.     MBEDTLS_X509_SAFE_SNPRINTF;
  897.  
  898.     return( 0 );
  899. }
  900.  
  901. #if defined(MBEDTLS_HAVE_TIME_DATE)
  902. /*
  903.  * Set the time structure to the current time.
  904.  * Return 0 on success, non-zero on failure.
  905.  */
  906. static int x509_get_current_time( mbedtls_x509_time *now )
  907. {
  908.     struct tm *lt, tm_buf;
  909.     mbedtls_time_t tt;
  910.     int ret = 0;
  911.  
  912.     tt = mbedtls_time( NULL );
  913.     lt = mbedtls_platform_gmtime_r( &tt, &tm_buf );
  914.  
  915.     if( lt == NULL )
  916.         ret = -1;
  917.     else
  918.     {
  919.         now->year = lt->tm_year + 1900;
  920.         now->mon  = lt->tm_mon  + 1;
  921.         now->day  = lt->tm_mday;
  922.         now->hour = lt->tm_hour;
  923.         now->min  = lt->tm_min;
  924.         now->sec  = lt->tm_sec;
  925.     }
  926.  
  927.     return( ret );
  928. }
  929.  
  930. /*
  931.  * Return 0 if before <= after, 1 otherwise
  932.  */
  933. static int x509_check_time( const mbedtls_x509_time *before, const mbedtls_x509_time *after )
  934. {
  935.     if( before->year  > after->year )
  936.         return( 1 );
  937.  
  938.     if( before->year == after->year &&
  939.         before->mon   > after->mon )
  940.         return( 1 );
  941.  
  942.     if( before->year == after->year &&
  943.         before->mon  == after->mon  &&
  944.         before->day   > after->day )
  945.         return( 1 );
  946.  
  947.     if( before->year == after->year &&
  948.         before->mon  == after->mon  &&
  949.         before->day  == after->day  &&
  950.         before->hour  > after->hour )
  951.         return( 1 );
  952.  
  953.     if( before->year == after->year &&
  954.         before->mon  == after->mon  &&
  955.         before->day  == after->day  &&
  956.         before->hour == after->hour &&
  957.         before->min   > after->min  )
  958.         return( 1 );
  959.  
  960.     if( before->year == after->year &&
  961.         before->mon  == after->mon  &&
  962.         before->day  == after->day  &&
  963.         before->hour == after->hour &&
  964.         before->min  == after->min  &&
  965.         before->sec   > after->sec  )
  966.         return( 1 );
  967.  
  968.     return( 0 );
  969. }
  970.  
  971. int mbedtls_x509_time_is_past( const mbedtls_x509_time *to )
  972. {
  973.     mbedtls_x509_time now;
  974.  
  975.     if( x509_get_current_time( &now ) != 0 )
  976.         return( 1 );
  977.  
  978.     return( x509_check_time( &now, to ) );
  979. }
  980.  
  981. int mbedtls_x509_time_is_future( const mbedtls_x509_time *from )
  982. {
  983.     mbedtls_x509_time now;
  984.  
  985.     if( x509_get_current_time( &now ) != 0 )
  986.         return( 1 );
  987.  
  988.     return( x509_check_time( from, &now ) );
  989. }
  990.  
  991. #else  /* MBEDTLS_HAVE_TIME_DATE */
  992.  
  993. int mbedtls_x509_time_is_past( const mbedtls_x509_time *to )
  994. {
  995.     ((void) to);
  996.     return( 0 );
  997. }
  998.  
  999. int mbedtls_x509_time_is_future( const mbedtls_x509_time *from )
  1000. {
  1001.     ((void) from);
  1002.     return( 0 );
  1003. }
  1004. #endif /* MBEDTLS_HAVE_TIME_DATE */
  1005.  
  1006. #if defined(MBEDTLS_SELF_TEST)
  1007.  
  1008. #include "mbedtls/x509_crt.h"
  1009. #include "mbedtls/certs.h"
  1010.  
  1011. /*
  1012.  * Checkup routine
  1013.  */
  1014. int mbedtls_x509_self_test( int verbose )
  1015. {
  1016.     int ret = 0;
  1017. #if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C)
  1018.     uint32_t flags;
  1019.     mbedtls_x509_crt cacert;
  1020.     mbedtls_x509_crt clicert;
  1021.  
  1022.     if( verbose != 0 )
  1023.         mbedtls_printf( "  X.509 certificate load: " );
  1024.  
  1025.     mbedtls_x509_crt_init( &cacert );
  1026.     mbedtls_x509_crt_init( &clicert );
  1027.  
  1028.     ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt,
  1029.                            mbedtls_test_cli_crt_len );
  1030.     if( ret != 0 )
  1031.     {
  1032.         if( verbose != 0 )
  1033.             mbedtls_printf( "failed\n" );
  1034.  
  1035.         goto cleanup;
  1036.     }
  1037.  
  1038.     ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt,
  1039.                           mbedtls_test_ca_crt_len );
  1040.     if( ret != 0 )
  1041.     {
  1042.         if( verbose != 0 )
  1043.             mbedtls_printf( "failed\n" );
  1044.  
  1045.         goto cleanup;
  1046.     }
  1047.  
  1048.     if( verbose != 0 )
  1049.         mbedtls_printf( "passed\n  X.509 signature verify: ");
  1050.  
  1051.     ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
  1052.     if( ret != 0 )
  1053.     {
  1054.         if( verbose != 0 )
  1055.             mbedtls_printf( "failed\n" );
  1056.  
  1057.         goto cleanup;
  1058.     }
  1059.  
  1060.     if( verbose != 0 )
  1061.         mbedtls_printf( "passed\n\n");
  1062.  
  1063. cleanup:
  1064.     mbedtls_x509_crt_free( &cacert  );
  1065.     mbedtls_x509_crt_free( &clicert );
  1066. #else
  1067.     ((void) verbose);
  1068. #endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA256_C */
  1069.     return( ret );
  1070. }
  1071.  
  1072. #endif /* MBEDTLS_SELF_TEST */
  1073.  
  1074. #endif /* MBEDTLS_X509_USE_C */
  1075.