Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
asn1write.c
00001 /* 00002 * ASN.1 buffer writing functionality 00003 * 00004 * Copyright (C) 2006-2014, Brainspark B.V. 00005 * 00006 * This file is part of PolarSSL (http://www.polarssl.org) 00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> 00008 * 00009 * All rights reserved. 00010 * 00011 * This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License along 00022 * with this program; if not, write to the Free Software Foundation, Inc., 00023 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00024 */ 00025 00026 #if !defined(POLARSSL_CONFIG_FILE) 00027 #include "polarssl/config.h" 00028 #else 00029 #include POLARSSL_CONFIG_FILE 00030 #endif 00031 00032 #if defined(POLARSSL_ASN1_WRITE_C) 00033 00034 #include "polarssl/asn1write.h" 00035 00036 #if defined(POLARSSL_PLATFORM_C) 00037 #include "polarssl/platform.h" 00038 #else 00039 #include <stdlib.h> 00040 #define polarssl_malloc malloc 00041 #define polarssl_free free 00042 #endif 00043 00044 int asn1_write_len( unsigned char **p, unsigned char *start, size_t len ) 00045 { 00046 if( len < 0x80 ) 00047 { 00048 if( *p - start < 1 ) 00049 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00050 00051 *--(*p) = (unsigned char) len; 00052 return( 1 ); 00053 } 00054 00055 if( len <= 0xFF ) 00056 { 00057 if( *p - start < 2 ) 00058 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00059 00060 *--(*p) = (unsigned char) len; 00061 *--(*p) = 0x81; 00062 return( 2 ); 00063 } 00064 00065 if( *p - start < 3 ) 00066 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00067 00068 // We assume we never have lengths larger than 65535 bytes 00069 // 00070 *--(*p) = len % 256; 00071 *--(*p) = ( len / 256 ) % 256; 00072 *--(*p) = 0x82; 00073 00074 return( 3 ); 00075 } 00076 00077 int asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ) 00078 { 00079 if( *p - start < 1 ) 00080 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00081 00082 *--(*p) = tag; 00083 00084 return( 1 ); 00085 } 00086 00087 int asn1_write_raw_buffer( unsigned char **p, unsigned char *start, 00088 const unsigned char *buf, size_t size ) 00089 { 00090 size_t len = 0; 00091 00092 if( *p - start < (int) size ) 00093 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00094 00095 len = size; 00096 (*p) -= len; 00097 memcpy( *p, buf, len ); 00098 00099 return( (int) len ); 00100 } 00101 00102 #if defined(POLARSSL_BIGNUM_C) 00103 int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X ) 00104 { 00105 int ret; 00106 size_t len = 0; 00107 00108 // Write the MPI 00109 // 00110 len = mpi_size( X ); 00111 00112 if( *p - start < (int) len ) 00113 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00114 00115 (*p) -= len; 00116 MPI_CHK( mpi_write_binary( X, *p, len ) ); 00117 00118 // DER format assumes 2s complement for numbers, so the leftmost bit 00119 // should be 0 for positive numbers and 1 for negative numbers. 00120 // 00121 if ( X->s ==1 && **p & 0x80 ) 00122 { 00123 if( *p - start < 1 ) 00124 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00125 00126 *--(*p) = 0x00; 00127 len += 1; 00128 } 00129 00130 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); 00131 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) ); 00132 00133 ret = (int) len; 00134 00135 cleanup: 00136 return( ret ); 00137 } 00138 #endif /* POLARSSL_BIGNUM_C */ 00139 00140 int asn1_write_null( unsigned char **p, unsigned char *start ) 00141 { 00142 int ret; 00143 size_t len = 0; 00144 00145 // Write NULL 00146 // 00147 ASN1_CHK_ADD( len, asn1_write_len( p, start, 0) ); 00148 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_NULL ) ); 00149 00150 return( (int) len ); 00151 } 00152 00153 int asn1_write_oid( unsigned char **p, unsigned char *start, 00154 const char *oid, size_t oid_len ) 00155 { 00156 int ret; 00157 size_t len = 0; 00158 00159 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, 00160 (const unsigned char *) oid, oid_len ) ); 00161 ASN1_CHK_ADD( len , asn1_write_len( p, start, len ) ); 00162 ASN1_CHK_ADD( len , asn1_write_tag( p, start, ASN1_OID ) ); 00163 00164 return( (int) len ); 00165 } 00166 00167 int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, 00168 const char *oid, size_t oid_len, 00169 size_t par_len ) 00170 { 00171 int ret; 00172 size_t len = 0; 00173 00174 if( par_len == 0 ) 00175 ASN1_CHK_ADD( len, asn1_write_null( p, start ) ); 00176 else 00177 len += par_len; 00178 00179 ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) ); 00180 00181 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); 00182 ASN1_CHK_ADD( len, asn1_write_tag( p, start, 00183 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); 00184 00185 return( (int) len ); 00186 } 00187 00188 int asn1_write_bool( unsigned char **p, unsigned char *start, int boolean ) 00189 { 00190 int ret; 00191 size_t len = 0; 00192 00193 if( *p - start < 1 ) 00194 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00195 00196 *--(*p) = (boolean) ? 1 : 0; 00197 len++; 00198 00199 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); 00200 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BOOLEAN ) ); 00201 00202 return( (int) len ); 00203 } 00204 00205 int asn1_write_int( unsigned char **p, unsigned char *start, int val ) 00206 { 00207 int ret; 00208 size_t len = 0; 00209 00210 // TODO negative values and values larger than 128 00211 // DER format assumes 2s complement for numbers, so the leftmost bit 00212 // should be 0 for positive numbers and 1 for negative numbers. 00213 // 00214 if( *p - start < 1 ) 00215 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00216 00217 len += 1; 00218 *--(*p) = val; 00219 00220 if ( val > 0 && **p & 0x80 ) 00221 { 00222 if( *p - start < 1 ) 00223 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00224 00225 *--(*p) = 0x00; 00226 len += 1; 00227 } 00228 00229 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); 00230 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) ); 00231 00232 return( (int) len ); 00233 } 00234 00235 int asn1_write_printable_string( unsigned char **p, unsigned char *start, 00236 const char *text, size_t text_len ) 00237 { 00238 int ret; 00239 size_t len = 0; 00240 00241 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, 00242 (const unsigned char *) text, text_len ) ); 00243 00244 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); 00245 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_PRINTABLE_STRING ) ); 00246 00247 return( (int) len ); 00248 } 00249 00250 int asn1_write_ia5_string( unsigned char **p, unsigned char *start, 00251 const char *text, size_t text_len ) 00252 { 00253 int ret; 00254 size_t len = 0; 00255 00256 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, 00257 (const unsigned char *) text, text_len ) ); 00258 00259 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); 00260 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_IA5_STRING ) ); 00261 00262 return( (int) len ); 00263 } 00264 00265 int asn1_write_bitstring( unsigned char **p, unsigned char *start, 00266 const unsigned char *buf, size_t bits ) 00267 { 00268 int ret; 00269 size_t len = 0, size; 00270 00271 size = ( bits / 8 ) + ( ( bits % 8 ) ? 1 : 0 ); 00272 00273 // Calculate byte length 00274 // 00275 if( *p - start < (int) size + 1 ) 00276 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00277 00278 len = size + 1; 00279 (*p) -= size; 00280 memcpy( *p, buf, size ); 00281 00282 // Write unused bits 00283 // 00284 *--(*p) = (unsigned char) (size * 8 - bits); 00285 00286 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); 00287 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) ); 00288 00289 return( (int) len ); 00290 } 00291 00292 int asn1_write_octet_string( unsigned char **p, unsigned char *start, 00293 const unsigned char *buf, size_t size ) 00294 { 00295 int ret; 00296 size_t len = 0; 00297 00298 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, buf, size ) ); 00299 00300 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); 00301 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OCTET_STRING ) ); 00302 00303 return( (int) len ); 00304 } 00305 00306 asn1_named_data *asn1_store_named_data( asn1_named_data **head, 00307 const char *oid, size_t oid_len, 00308 const unsigned char *val, 00309 size_t val_len ) 00310 { 00311 asn1_named_data *cur; 00312 00313 if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL ) 00314 { 00315 // Add new entry if not present yet based on OID 00316 // 00317 if( ( cur = polarssl_malloc( sizeof(asn1_named_data) ) ) == NULL ) 00318 return( NULL ); 00319 00320 memset( cur, 0, sizeof(asn1_named_data) ); 00321 00322 cur->oid.len = oid_len; 00323 cur->oid.p = polarssl_malloc( oid_len ); 00324 if( cur->oid.p == NULL ) 00325 { 00326 polarssl_free( cur ); 00327 return( NULL ); 00328 } 00329 00330 cur->val.len = val_len; 00331 cur->val.p = polarssl_malloc( val_len ); 00332 if( cur->val.p == NULL ) 00333 { 00334 polarssl_free( cur->oid.p ); 00335 polarssl_free( cur ); 00336 return( NULL ); 00337 } 00338 00339 memcpy( cur->oid.p, oid, oid_len ); 00340 00341 cur->next = *head; 00342 *head = cur; 00343 } 00344 else if( cur->val.len < val_len ) 00345 { 00346 // Enlarge existing value buffer if needed 00347 // 00348 polarssl_free( cur->val.p ); 00349 cur->val.p = NULL; 00350 00351 cur->val.len = val_len; 00352 cur->val.p = polarssl_malloc( val_len ); 00353 if( cur->val.p == NULL ) 00354 { 00355 polarssl_free( cur->oid.p ); 00356 polarssl_free( cur ); 00357 return( NULL ); 00358 } 00359 } 00360 00361 if( val != NULL ) 00362 memcpy( cur->val.p, val, val_len ); 00363 00364 return( cur ); 00365 } 00366 #endif /* POLARSSL_ASN1_WRITE_C */ 00367 00368
Generated on Tue Jul 12 2022 19:40:15 by
1.7.2