Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  *  X.509 base functions for creating certificates / CSRs
  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. #if !defined(MBEDTLS_CONFIG_FILE)
  25. #include "mbedtls/config.h"
  26. #else
  27. #include MBEDTLS_CONFIG_FILE
  28. #endif
  29.  
  30. #if defined(MBEDTLS_X509_CREATE_C)
  31.  
  32. #include "mbedtls/x509.h"
  33. #include "mbedtls/asn1write.h"
  34. #include "mbedtls/oid.h"
  35.  
  36. #include <string.h>
  37.  
  38. /* Structure linking OIDs for X.509 DN AttributeTypes to their
  39.  * string representations and default string encodings used by Mbed TLS. */
  40. typedef struct {
  41.    const char *name; /* String representation of AttributeType, e.g.
  42.                       * "CN" or "emailAddress". */
  43.    size_t name_len;  /* Length of 'name', without trailing 0 byte. */
  44.    const char *oid;  /* String representation of OID of AttributeType,
  45.                       * as per RFC 5280, Appendix A.1. */
  46.    int default_tag;  /* The default character encoding used for the
  47.                       * given attribute type, e.g.
  48.                       * MBEDTLS_ASN1_UTF8_STRING for UTF-8. */
  49. } x509_attr_descriptor_t;
  50.  
  51. #define ADD_STRLEN( s )     s, sizeof( s ) - 1
  52.  
  53. /* X.509 DN attributes from RFC 5280, Appendix A.1. */
  54. static const x509_attr_descriptor_t x509_attrs[] =
  55. {
  56.     { ADD_STRLEN( "CN" ),
  57.       MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING },
  58.     { ADD_STRLEN( "commonName" ),
  59.       MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING },
  60.     { ADD_STRLEN( "C" ),
  61.       MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING },
  62.     { ADD_STRLEN( "countryName" ),
  63.       MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING },
  64.     { ADD_STRLEN( "O" ),
  65.       MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING },
  66.     { ADD_STRLEN( "organizationName" ),
  67.       MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING },
  68.     { ADD_STRLEN( "L" ),
  69.       MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING },
  70.     { ADD_STRLEN( "locality" ),
  71.       MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING },
  72.     { ADD_STRLEN( "R" ),
  73.       MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING },
  74.     { ADD_STRLEN( "OU" ),
  75.       MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING },
  76.     { ADD_STRLEN( "organizationalUnitName" ),
  77.       MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING },
  78.     { ADD_STRLEN( "ST" ),
  79.       MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING },
  80.     { ADD_STRLEN( "stateOrProvinceName" ),
  81.       MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING },
  82.     { ADD_STRLEN( "emailAddress" ),
  83.       MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING },
  84.     { ADD_STRLEN( "serialNumber" ),
  85.       MBEDTLS_OID_AT_SERIAL_NUMBER, MBEDTLS_ASN1_PRINTABLE_STRING },
  86.     { ADD_STRLEN( "postalAddress" ),
  87.       MBEDTLS_OID_AT_POSTAL_ADDRESS, MBEDTLS_ASN1_PRINTABLE_STRING },
  88.     { ADD_STRLEN( "postalCode" ),
  89.       MBEDTLS_OID_AT_POSTAL_CODE, MBEDTLS_ASN1_PRINTABLE_STRING },
  90.     { ADD_STRLEN( "dnQualifier" ),
  91.       MBEDTLS_OID_AT_DN_QUALIFIER, MBEDTLS_ASN1_PRINTABLE_STRING },
  92.     { ADD_STRLEN( "title" ),
  93.       MBEDTLS_OID_AT_TITLE, MBEDTLS_ASN1_UTF8_STRING },
  94.     { ADD_STRLEN( "surName" ),
  95.       MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING },
  96.     { ADD_STRLEN( "SN" ),
  97.       MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING },
  98.     { ADD_STRLEN( "givenName" ),
  99.       MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING },
  100.     { ADD_STRLEN( "GN" ),
  101.       MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING },
  102.     { ADD_STRLEN( "initials" ),
  103.       MBEDTLS_OID_AT_INITIALS, MBEDTLS_ASN1_UTF8_STRING },
  104.     { ADD_STRLEN( "pseudonym" ),
  105.       MBEDTLS_OID_AT_PSEUDONYM, MBEDTLS_ASN1_UTF8_STRING },
  106.     { ADD_STRLEN( "generationQualifier" ),
  107.       MBEDTLS_OID_AT_GENERATION_QUALIFIER, MBEDTLS_ASN1_UTF8_STRING },
  108.     { ADD_STRLEN( "domainComponent" ),
  109.       MBEDTLS_OID_DOMAIN_COMPONENT, MBEDTLS_ASN1_IA5_STRING },
  110.     { ADD_STRLEN( "DC" ),
  111.       MBEDTLS_OID_DOMAIN_COMPONENT,   MBEDTLS_ASN1_IA5_STRING },
  112.     { NULL, 0, NULL, MBEDTLS_ASN1_NULL }
  113. };
  114.  
  115. static const x509_attr_descriptor_t *x509_attr_descr_from_name( const char *name, size_t name_len )
  116. {
  117.     const x509_attr_descriptor_t *cur;
  118.  
  119.     for( cur = x509_attrs; cur->name != NULL; cur++ )
  120.         if( cur->name_len == name_len &&
  121.             strncmp( cur->name, name, name_len ) == 0 )
  122.             break;
  123.  
  124.     if ( cur->name == NULL )
  125.         return( NULL );
  126.  
  127.     return( cur );
  128. }
  129.  
  130. int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name )
  131. {
  132.     int ret = 0;
  133.     const char *s = name, *c = s;
  134.     const char *end = s + strlen( s );
  135.     const char *oid = NULL;
  136.     const x509_attr_descriptor_t* attr_descr = NULL;
  137.     int in_tag = 1;
  138.     char data[MBEDTLS_X509_MAX_DN_NAME_SIZE];
  139.     char *d = data;
  140.  
  141.     /* Clear existing chain if present */
  142.     mbedtls_asn1_free_named_data_list( head );
  143.  
  144.     while( c <= end )
  145.     {
  146.         if( in_tag && *c == '=' )
  147.         {
  148.             if( ( attr_descr = x509_attr_descr_from_name( s, c - s ) ) == NULL )
  149.             {
  150.                 ret = MBEDTLS_ERR_X509_UNKNOWN_OID;
  151.                 goto exit;
  152.             }
  153.  
  154.             oid = attr_descr->oid;
  155.             s = c + 1;
  156.             in_tag = 0;
  157.             d = data;
  158.         }
  159.  
  160.         if( !in_tag && *c == '\\' && c != end )
  161.         {
  162.             c++;
  163.  
  164.             /* Check for valid escaped characters */
  165.             if( c == end || *c != ',' )
  166.             {
  167.                 ret = MBEDTLS_ERR_X509_INVALID_NAME;
  168.                 goto exit;
  169.             }
  170.         }
  171.         else if( !in_tag && ( *c == ',' || c == end ) )
  172.         {
  173.             mbedtls_asn1_named_data* cur =
  174.                 mbedtls_asn1_store_named_data( head, oid, strlen( oid ),
  175.                                                (unsigned char *) data,
  176.                                                d - data );
  177.  
  178.             if(cur == NULL )
  179.             {
  180.                 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
  181.             }
  182.  
  183.             // set tagType
  184.             cur->val.tag = attr_descr->default_tag;
  185.  
  186.             while( c < end && *(c + 1) == ' ' )
  187.                 c++;
  188.  
  189.             s = c + 1;
  190.             in_tag = 1;
  191.         }
  192.  
  193.         if( !in_tag && s != c + 1 )
  194.         {
  195.             *(d++) = *c;
  196.  
  197.             if( d - data == MBEDTLS_X509_MAX_DN_NAME_SIZE )
  198.             {
  199.                 ret = MBEDTLS_ERR_X509_INVALID_NAME;
  200.                 goto exit;
  201.             }
  202.         }
  203.  
  204.         c++;
  205.     }
  206.  
  207. exit:
  208.  
  209.     return( ret );
  210. }
  211.  
  212. /* The first byte of the value in the mbedtls_asn1_named_data structure is reserved
  213.  * to store the critical boolean for us
  214.  */
  215. int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
  216.                         int critical, const unsigned char *val, size_t val_len )
  217. {
  218.     mbedtls_asn1_named_data *cur;
  219.  
  220.     if( ( cur = mbedtls_asn1_store_named_data( head, oid, oid_len,
  221.                                        NULL, val_len + 1 ) ) == NULL )
  222.     {
  223.         return( MBEDTLS_ERR_X509_ALLOC_FAILED );
  224.     }
  225.  
  226.     cur->val.p[0] = critical;
  227.     memcpy( cur->val.p + 1, val, val_len );
  228.  
  229.     return( 0 );
  230. }
  231.  
  232. /*
  233.  *  RelativeDistinguishedName ::=
  234.  *    SET OF AttributeTypeAndValue
  235.  *
  236.  *  AttributeTypeAndValue ::= SEQUENCE {
  237.  *    type     AttributeType,
  238.  *    value    AttributeValue }
  239.  *
  240.  *  AttributeType ::= OBJECT IDENTIFIER
  241.  *
  242.  *  AttributeValue ::= ANY DEFINED BY AttributeType
  243.  */
  244. static int x509_write_name( unsigned char **p, unsigned char *start, mbedtls_asn1_named_data* cur_name)
  245. {
  246.     int ret;
  247.     size_t len = 0;
  248.     const char *oid             = (const char*)cur_name->oid.p;
  249.     size_t oid_len              = cur_name->oid.len;
  250.     const unsigned char *name   = cur_name->val.p;
  251.     size_t name_len             = cur_name->val.len;
  252.  
  253.     // Write correct string tag and value
  254.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tagged_string( p, start,
  255.                                                        cur_name->val.tag,
  256.                                                        (const char *) name,
  257.                                                        name_len ) );
  258.     // Write OID
  259.     //
  260.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid,
  261.                                                        oid_len ) );
  262.  
  263.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  264.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
  265.                                                     MBEDTLS_ASN1_CONSTRUCTED |
  266.                                                     MBEDTLS_ASN1_SEQUENCE ) );
  267.  
  268.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  269.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
  270.                                                  MBEDTLS_ASN1_CONSTRUCTED |
  271.                                                  MBEDTLS_ASN1_SET ) );
  272.  
  273.     return( (int) len );
  274. }
  275.  
  276. int mbedtls_x509_write_names( unsigned char **p, unsigned char *start,
  277.                               mbedtls_asn1_named_data *first )
  278. {
  279.     int ret;
  280.     size_t len = 0;
  281.     mbedtls_asn1_named_data *cur = first;
  282.  
  283.     while( cur != NULL )
  284.     {
  285.         MBEDTLS_ASN1_CHK_ADD( len, x509_write_name( p, start, cur ) );
  286.         cur = cur->next;
  287.     }
  288.  
  289.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  290.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
  291.                                                  MBEDTLS_ASN1_SEQUENCE ) );
  292.  
  293.     return( (int) len );
  294. }
  295.  
  296. int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
  297.                     const char *oid, size_t oid_len,
  298.                     unsigned char *sig, size_t size )
  299. {
  300.     int ret;
  301.     size_t len = 0;
  302.  
  303.     if( *p < start || (size_t)( *p - start ) < size )
  304.         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  305.  
  306.     len = size;
  307.     (*p) -= len;
  308.     memcpy( *p, sig, len );
  309.  
  310.     if( *p - start < 1 )
  311.         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  312.  
  313.     *--(*p) = 0;
  314.     len += 1;
  315.  
  316.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  317.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) );
  318.  
  319.     // Write OID
  320.     //
  321.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( p, start, oid,
  322.                                                         oid_len, 0 ) );
  323.  
  324.     return( (int) len );
  325. }
  326.  
  327. static int x509_write_extension( unsigned char **p, unsigned char *start,
  328.                                  mbedtls_asn1_named_data *ext )
  329. {
  330.     int ret;
  331.     size_t len = 0;
  332.  
  333.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->val.p + 1,
  334.                                               ext->val.len - 1 ) );
  335.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->val.len - 1 ) );
  336.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) );
  337.  
  338.     if( ext->val.p[0] != 0 )
  339.     {
  340.         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( p, start, 1 ) );
  341.     }
  342.  
  343.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->oid.p,
  344.                                               ext->oid.len ) );
  345.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->oid.len ) );
  346.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) );
  347.  
  348.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  349.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
  350.                                                  MBEDTLS_ASN1_SEQUENCE ) );
  351.  
  352.     return( (int) len );
  353. }
  354.  
  355. /*
  356.  * Extension  ::=  SEQUENCE  {
  357.  *     extnID      OBJECT IDENTIFIER,
  358.  *     critical    BOOLEAN DEFAULT FALSE,
  359.  *     extnValue   OCTET STRING
  360.  *                 -- contains the DER encoding of an ASN.1 value
  361.  *                 -- corresponding to the extension type identified
  362.  *                 -- by extnID
  363.  *     }
  364.  */
  365. int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
  366.                            mbedtls_asn1_named_data *first )
  367. {
  368.     int ret;
  369.     size_t len = 0;
  370.     mbedtls_asn1_named_data *cur_ext = first;
  371.  
  372.     while( cur_ext != NULL )
  373.     {
  374.         MBEDTLS_ASN1_CHK_ADD( len, x509_write_extension( p, start, cur_ext ) );
  375.         cur_ext = cur_ext->next;
  376.     }
  377.  
  378.     return( (int) len );
  379. }
  380.  
  381. #endif /* MBEDTLS_X509_CREATE_C */
  382.