Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * ASN.1 buffer writing functionality
  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_ASN1_WRITE_C)
  31.  
  32. #include "mbedtls/asn1write.h"
  33.  
  34. #include <string.h>
  35.  
  36. #if defined(MBEDTLS_PLATFORM_C)
  37. #include "mbedtls/platform.h"
  38. #else
  39. #include <stdlib.h>
  40. #define mbedtls_calloc    calloc
  41. #define mbedtls_free       free
  42. #endif
  43.  
  44. int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len )
  45. {
  46.     if( len < 0x80 )
  47.     {
  48.         if( *p - start < 1 )
  49.             return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  50.  
  51.         *--(*p) = (unsigned char) len;
  52.         return( 1 );
  53.     }
  54.  
  55.     if( len <= 0xFF )
  56.     {
  57.         if( *p - start < 2 )
  58.             return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  59.  
  60.         *--(*p) = (unsigned char) len;
  61.         *--(*p) = 0x81;
  62.         return( 2 );
  63.     }
  64.  
  65.     if( len <= 0xFFFF )
  66.     {
  67.         if( *p - start < 3 )
  68.             return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  69.  
  70.         *--(*p) = ( len       ) & 0xFF;
  71.         *--(*p) = ( len >>  8 ) & 0xFF;
  72.         *--(*p) = 0x82;
  73.         return( 3 );
  74.     }
  75.  
  76.     if( len <= 0xFFFFFF )
  77.     {
  78.         if( *p - start < 4 )
  79.             return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  80.  
  81.         *--(*p) = ( len       ) & 0xFF;
  82.         *--(*p) = ( len >>  8 ) & 0xFF;
  83.         *--(*p) = ( len >> 16 ) & 0xFF;
  84.         *--(*p) = 0x83;
  85.         return( 4 );
  86.     }
  87.  
  88. #if SIZE_MAX > 0xFFFFFFFF
  89.     if( len <= 0xFFFFFFFF )
  90. #endif
  91.     {
  92.         if( *p - start < 5 )
  93.             return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  94.  
  95.         *--(*p) = ( len       ) & 0xFF;
  96.         *--(*p) = ( len >>  8 ) & 0xFF;
  97.         *--(*p) = ( len >> 16 ) & 0xFF;
  98.         *--(*p) = ( len >> 24 ) & 0xFF;
  99.         *--(*p) = 0x84;
  100.         return( 5 );
  101.     }
  102.  
  103. #if SIZE_MAX > 0xFFFFFFFF
  104.     return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
  105. #endif
  106. }
  107.  
  108. int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
  109. {
  110.     if( *p - start < 1 )
  111.         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  112.  
  113.     *--(*p) = tag;
  114.  
  115.     return( 1 );
  116. }
  117.  
  118. int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
  119.                            const unsigned char *buf, size_t size )
  120. {
  121.     size_t len = 0;
  122.  
  123.     if( *p < start || (size_t)( *p - start ) < size )
  124.         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  125.  
  126.     len = size;
  127.     (*p) -= len;
  128.     memcpy( *p, buf, len );
  129.  
  130.     return( (int) len );
  131. }
  132.  
  133. #if defined(MBEDTLS_BIGNUM_C)
  134. int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X )
  135. {
  136.     int ret;
  137.     size_t len = 0;
  138.  
  139.     // Write the MPI
  140.     //
  141.     len = mbedtls_mpi_size( X );
  142.  
  143.     if( *p < start || (size_t)( *p - start ) < len )
  144.         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  145.  
  146.     (*p) -= len;
  147.     MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, *p, len ) );
  148.  
  149.     // DER format assumes 2s complement for numbers, so the leftmost bit
  150.     // should be 0 for positive numbers and 1 for negative numbers.
  151.     //
  152.     if( X->s ==1 && **p & 0x80 )
  153.     {
  154.         if( *p - start < 1 )
  155.             return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  156.  
  157.         *--(*p) = 0x00;
  158.         len += 1;
  159.     }
  160.  
  161.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  162.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) );
  163.  
  164.     ret = (int) len;
  165.  
  166. cleanup:
  167.     return( ret );
  168. }
  169. #endif /* MBEDTLS_BIGNUM_C */
  170.  
  171. int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start )
  172. {
  173.     int ret;
  174.     size_t len = 0;
  175.  
  176.     // Write NULL
  177.     //
  178.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, 0) );
  179.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_NULL ) );
  180.  
  181.     return( (int) len );
  182. }
  183.  
  184. int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start,
  185.                     const char *oid, size_t oid_len )
  186. {
  187.     int ret;
  188.     size_t len = 0;
  189.  
  190.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
  191.                                   (const unsigned char *) oid, oid_len ) );
  192.     MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_len( p, start, len ) );
  193.     MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) );
  194.  
  195.     return( (int) len );
  196. }
  197.  
  198. int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
  199.                                      const char *oid, size_t oid_len,
  200.                                      size_t par_len )
  201. {
  202.     int ret;
  203.     size_t len = 0;
  204.  
  205.     if( par_len == 0 )
  206.         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_null( p, start ) );
  207.     else
  208.         len += par_len;
  209.  
  210.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) );
  211.  
  212.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  213.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
  214.                                        MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
  215.  
  216.     return( (int) len );
  217. }
  218.  
  219. int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean )
  220. {
  221.     int ret;
  222.     size_t len = 0;
  223.  
  224.     if( *p - start < 1 )
  225.         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  226.  
  227.     *--(*p) = (boolean) ? 255 : 0;
  228.     len++;
  229.  
  230.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  231.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BOOLEAN ) );
  232.  
  233.     return( (int) len );
  234. }
  235.  
  236. int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val )
  237. {
  238.     int ret;
  239.     size_t len = 0;
  240.  
  241.     if( *p - start < 1 )
  242.         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  243.  
  244.     len += 1;
  245.     *--(*p) = val;
  246.  
  247.     if( val > 0 && **p & 0x80 )
  248.     {
  249.         if( *p - start < 1 )
  250.             return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  251.  
  252.         *--(*p) = 0x00;
  253.         len += 1;
  254.     }
  255.  
  256.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  257.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) );
  258.  
  259.     return( (int) len );
  260. }
  261.  
  262. int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start, int tag,
  263.     const char *text, size_t text_len )
  264. {
  265.     int ret;
  266.     size_t len = 0;
  267.  
  268.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
  269.         (const unsigned char *) text, text_len ) );
  270.  
  271.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  272.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, tag ) );
  273.  
  274.     return( (int) len );
  275. }
  276.  
  277. int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start,
  278.     const char *text, size_t text_len )
  279. {
  280.     return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_UTF8_STRING, text, text_len) );
  281. }
  282.  
  283. int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start,
  284.                                  const char *text, size_t text_len )
  285. {
  286.     return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_PRINTABLE_STRING, text, text_len) );
  287. }
  288.  
  289. int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
  290.                            const char *text, size_t text_len )
  291. {
  292.     return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_IA5_STRING, text, text_len) );
  293. }
  294.  
  295. int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
  296.                           const unsigned char *buf, size_t bits )
  297. {
  298.     int ret;
  299.     size_t len = 0;
  300.     size_t unused_bits, byte_len;
  301.  
  302.     byte_len = ( bits + 7 ) / 8;
  303.     unused_bits = ( byte_len * 8 ) - bits;
  304.  
  305.     if( *p < start || (size_t)( *p - start ) < byte_len + 1 )
  306.         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  307.  
  308.     len = byte_len + 1;
  309.  
  310.     /* Write the bitstring. Ensure the unused bits are zeroed */
  311.     if( byte_len > 0 )
  312.     {
  313.         byte_len--;
  314.         *--( *p ) = buf[byte_len] & ~( ( 0x1 << unused_bits ) - 1 );
  315.         ( *p ) -= byte_len;
  316.         memcpy( *p, buf, byte_len );
  317.     }
  318.  
  319.     /* Write unused bits */
  320.     *--( *p ) = (unsigned char)unused_bits;
  321.  
  322.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  323.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) );
  324.  
  325.     return( (int) len );
  326. }
  327.  
  328. int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
  329.                              const unsigned char *buf, size_t size )
  330. {
  331.     int ret;
  332.     size_t len = 0;
  333.  
  334.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, buf, size ) );
  335.  
  336.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  337.     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) );
  338.  
  339.     return( (int) len );
  340. }
  341.  
  342.  
  343. /* This is a copy of the ASN.1 parsing function mbedtls_asn1_find_named_data(),
  344.  * which is replicated to avoid a dependency ASN1_WRITE_C on ASN1_PARSE_C. */
  345. static mbedtls_asn1_named_data *asn1_find_named_data(
  346.                                                mbedtls_asn1_named_data *list,
  347.                                                const char *oid, size_t len )
  348. {
  349.     while( list != NULL )
  350.     {
  351.         if( list->oid.len == len &&
  352.             memcmp( list->oid.p, oid, len ) == 0 )
  353.         {
  354.             break;
  355.         }
  356.  
  357.         list = list->next;
  358.     }
  359.  
  360.     return( list );
  361. }
  362.  
  363. mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(
  364.                                         mbedtls_asn1_named_data **head,
  365.                                         const char *oid, size_t oid_len,
  366.                                         const unsigned char *val,
  367.                                         size_t val_len )
  368. {
  369.     mbedtls_asn1_named_data *cur;
  370.  
  371.     if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL )
  372.     {
  373.         // Add new entry if not present yet based on OID
  374.         //
  375.         cur = (mbedtls_asn1_named_data*)mbedtls_calloc( 1,
  376.                                             sizeof(mbedtls_asn1_named_data) );
  377.         if( cur == NULL )
  378.             return( NULL );
  379.  
  380.         cur->oid.len = oid_len;
  381.         cur->oid.p = mbedtls_calloc( 1, oid_len );
  382.         if( cur->oid.p == NULL )
  383.         {
  384.             mbedtls_free( cur );
  385.             return( NULL );
  386.         }
  387.  
  388.         memcpy( cur->oid.p, oid, oid_len );
  389.  
  390.         cur->val.len = val_len;
  391.         cur->val.p = mbedtls_calloc( 1, val_len );
  392.         if( cur->val.p == NULL )
  393.         {
  394.             mbedtls_free( cur->oid.p );
  395.             mbedtls_free( cur );
  396.             return( NULL );
  397.         }
  398.  
  399.         cur->next = *head;
  400.         *head = cur;
  401.     }
  402.     else if( cur->val.len < val_len )
  403.     {
  404.         /*
  405.          * Enlarge existing value buffer if needed
  406.          * Preserve old data until the allocation succeeded, to leave list in
  407.          * a consistent state in case allocation fails.
  408.          */
  409.         void *p = mbedtls_calloc( 1, val_len );
  410.         if( p == NULL )
  411.             return( NULL );
  412.  
  413.         mbedtls_free( cur->val.p );
  414.         cur->val.p = p;
  415.         cur->val.len = val_len;
  416.     }
  417.  
  418.     if( val != NULL )
  419.         memcpy( cur->val.p, val, val_len );
  420.  
  421.     return( cur );
  422. }
  423. #endif /* MBEDTLS_ASN1_WRITE_C */
  424.