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