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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
asn1write.c
00001 /* 00002 * ASN.1 buffer writing functionality 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 00022 #if !defined(MBEDTLS_CONFIG_FILE) 00023 #include "mbedtls/config.h" 00024 #else 00025 #include MBEDTLS_CONFIG_FILE 00026 #endif 00027 00028 #if defined(MBEDTLS_ASN1_WRITE_C) 00029 00030 #include "mbedtls/asn1write.h" 00031 00032 #include <string.h> 00033 00034 #if defined(MBEDTLS_PLATFORM_C) 00035 #include "mbedtls/platform.h" 00036 #else 00037 #include <stdlib.h> 00038 #define mbedtls_calloc calloc 00039 #define mbedtls_free free 00040 #endif 00041 00042 int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len ) 00043 { 00044 if( len < 0x80 ) 00045 { 00046 if( *p - start < 1 ) 00047 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00048 00049 *--(*p) = (unsigned char) len; 00050 return( 1 ); 00051 } 00052 00053 if( len <= 0xFF ) 00054 { 00055 if( *p - start < 2 ) 00056 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00057 00058 *--(*p) = (unsigned char) len; 00059 *--(*p) = 0x81; 00060 return( 2 ); 00061 } 00062 00063 if( len <= 0xFFFF ) 00064 { 00065 if( *p - start < 3 ) 00066 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00067 00068 *--(*p) = ( len ) & 0xFF; 00069 *--(*p) = ( len >> 8 ) & 0xFF; 00070 *--(*p) = 0x82; 00071 return( 3 ); 00072 } 00073 00074 if( len <= 0xFFFFFF ) 00075 { 00076 if( *p - start < 4 ) 00077 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00078 00079 *--(*p) = ( len ) & 0xFF; 00080 *--(*p) = ( len >> 8 ) & 0xFF; 00081 *--(*p) = ( len >> 16 ) & 0xFF; 00082 *--(*p) = 0x83; 00083 return( 4 ); 00084 } 00085 00086 #if SIZE_MAX > 0xFFFFFFFF 00087 if( len <= 0xFFFFFFFF ) 00088 #endif 00089 { 00090 if( *p - start < 5 ) 00091 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00092 00093 *--(*p) = ( len ) & 0xFF; 00094 *--(*p) = ( len >> 8 ) & 0xFF; 00095 *--(*p) = ( len >> 16 ) & 0xFF; 00096 *--(*p) = ( len >> 24 ) & 0xFF; 00097 *--(*p) = 0x84; 00098 return( 5 ); 00099 } 00100 00101 #if SIZE_MAX > 0xFFFFFFFF 00102 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00103 #endif 00104 } 00105 00106 int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ) 00107 { 00108 if( *p - start < 1 ) 00109 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00110 00111 *--(*p) = tag; 00112 00113 return( 1 ); 00114 } 00115 00116 int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start, 00117 const unsigned char *buf, size_t size ) 00118 { 00119 size_t len = 0; 00120 00121 if( *p < start || (size_t)( *p - start ) < size ) 00122 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00123 00124 len = size; 00125 (*p) -= len; 00126 memcpy( *p, buf, len ); 00127 00128 return( (int) len ); 00129 } 00130 00131 #if defined(MBEDTLS_BIGNUM_C) 00132 int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X ) 00133 { 00134 int ret; 00135 size_t len = 0; 00136 00137 // Write the MPI 00138 // 00139 len = mbedtls_mpi_size( X ); 00140 00141 if( *p < start || (size_t)( *p - start ) < len ) 00142 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00143 00144 (*p) -= len; 00145 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, *p, len ) ); 00146 00147 // DER format assumes 2s complement for numbers, so the leftmost bit 00148 // should be 0 for positive numbers and 1 for negative numbers. 00149 // 00150 if( X->s ==1 && **p & 0x80 ) 00151 { 00152 if( *p - start < 1 ) 00153 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00154 00155 *--(*p) = 0x00; 00156 len += 1; 00157 } 00158 00159 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00160 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) ); 00161 00162 ret = (int) len; 00163 00164 cleanup: 00165 return( ret ); 00166 } 00167 #endif /* MBEDTLS_BIGNUM_C */ 00168 00169 int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start ) 00170 { 00171 int ret; 00172 size_t len = 0; 00173 00174 // Write NULL 00175 // 00176 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, 0) ); 00177 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_NULL ) ); 00178 00179 return( (int) len ); 00180 } 00181 00182 int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start, 00183 const char *oid, size_t oid_len ) 00184 { 00185 int ret; 00186 size_t len = 0; 00187 00188 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, 00189 (const unsigned char *) oid, oid_len ) ); 00190 MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_len( p, start, len ) ); 00191 MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) ); 00192 00193 return( (int) len ); 00194 } 00195 00196 int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, 00197 const char *oid, size_t oid_len, 00198 size_t par_len ) 00199 { 00200 int ret; 00201 size_t len = 0; 00202 00203 if( par_len == 0 ) 00204 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_null( p, start ) ); 00205 else 00206 len += par_len; 00207 00208 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); 00209 00210 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00211 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, 00212 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); 00213 00214 return( (int) len ); 00215 } 00216 00217 int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean ) 00218 { 00219 int ret; 00220 size_t len = 0; 00221 00222 if( *p - start < 1 ) 00223 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00224 00225 *--(*p) = (boolean) ? 255 : 0; 00226 len++; 00227 00228 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00229 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BOOLEAN ) ); 00230 00231 return( (int) len ); 00232 } 00233 00234 int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val ) 00235 { 00236 int ret; 00237 size_t len = 0; 00238 00239 do 00240 { 00241 if( *p - start < 1 ) 00242 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00243 len += 1; 00244 *--(*p) = val & 0xff; 00245 val >>= 8; 00246 } 00247 while( val > 0 ); 00248 00249 if( **p & 0x80 ) 00250 { 00251 if( *p - start < 1 ) 00252 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00253 *--(*p) = 0x00; 00254 len += 1; 00255 } 00256 00257 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00258 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) ); 00259 00260 return( (int) len ); 00261 } 00262 00263 int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start, int tag, 00264 const char *text, size_t text_len ) 00265 { 00266 int ret; 00267 size_t len = 0; 00268 00269 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, 00270 (const unsigned char *) text, text_len ) ); 00271 00272 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00273 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, tag ) ); 00274 00275 return( (int) len ); 00276 } 00277 00278 int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start, 00279 const char *text, size_t text_len ) 00280 { 00281 return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_UTF8_STRING, text, text_len) ); 00282 } 00283 00284 int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start, 00285 const char *text, size_t text_len ) 00286 { 00287 return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_PRINTABLE_STRING, text, text_len) ); 00288 } 00289 00290 int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start, 00291 const char *text, size_t text_len ) 00292 { 00293 return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_IA5_STRING, text, text_len) ); 00294 } 00295 00296 int mbedtls_asn1_write_named_bitstring( unsigned char **p, 00297 unsigned char *start, 00298 const unsigned char *buf, 00299 size_t bits ) 00300 { 00301 size_t unused_bits, byte_len; 00302 const unsigned char *cur_byte; 00303 unsigned char cur_byte_shifted; 00304 unsigned char bit; 00305 00306 byte_len = ( bits + 7 ) / 8; 00307 unused_bits = ( byte_len * 8 ) - bits; 00308 00309 /* 00310 * Named bitstrings require that trailing 0s are excluded in the encoding 00311 * of the bitstring. Trailing 0s are considered part of the 'unused' bits 00312 * when encoding this value in the first content octet 00313 */ 00314 if( bits != 0 ) 00315 { 00316 cur_byte = buf + byte_len - 1; 00317 cur_byte_shifted = *cur_byte >> unused_bits; 00318 00319 for( ; ; ) 00320 { 00321 bit = cur_byte_shifted & 0x1; 00322 cur_byte_shifted >>= 1; 00323 00324 if( bit != 0 ) 00325 break; 00326 00327 bits--; 00328 if( bits == 0 ) 00329 break; 00330 00331 if( bits % 8 == 0 ) 00332 cur_byte_shifted = *--cur_byte; 00333 } 00334 } 00335 00336 return( mbedtls_asn1_write_bitstring( p, start, buf, bits ) ); 00337 } 00338 00339 int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start, 00340 const unsigned char *buf, size_t bits ) 00341 { 00342 int ret; 00343 size_t len = 0; 00344 size_t unused_bits, byte_len; 00345 00346 byte_len = ( bits + 7 ) / 8; 00347 unused_bits = ( byte_len * 8 ) - bits; 00348 00349 if( *p < start || (size_t)( *p - start ) < byte_len + 1 ) 00350 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00351 00352 len = byte_len + 1; 00353 00354 /* Write the bitstring. Ensure the unused bits are zeroed */ 00355 if( byte_len > 0 ) 00356 { 00357 byte_len--; 00358 *--( *p ) = buf[byte_len] & ~( ( 0x1 << unused_bits ) - 1 ); 00359 ( *p ) -= byte_len; 00360 memcpy( *p, buf, byte_len ); 00361 } 00362 00363 /* Write unused bits */ 00364 *--( *p ) = (unsigned char)unused_bits; 00365 00366 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00367 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) ); 00368 00369 return( (int) len ); 00370 } 00371 00372 int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start, 00373 const unsigned char *buf, size_t size ) 00374 { 00375 int ret; 00376 size_t len = 0; 00377 00378 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, buf, size ) ); 00379 00380 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00381 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) ); 00382 00383 return( (int) len ); 00384 } 00385 00386 00387 /* This is a copy of the ASN.1 parsing function mbedtls_asn1_find_named_data(), 00388 * which is replicated to avoid a dependency ASN1_WRITE_C on ASN1_PARSE_C. */ 00389 static mbedtls_asn1_named_data *asn1_find_named_data( 00390 mbedtls_asn1_named_data *list, 00391 const char *oid, size_t len ) 00392 { 00393 while( list != NULL ) 00394 { 00395 if( list->oid.len == len && 00396 memcmp( list->oid.p, oid, len ) == 0 ) 00397 { 00398 break; 00399 } 00400 00401 list = list->next; 00402 } 00403 00404 return( list ); 00405 } 00406 00407 mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( 00408 mbedtls_asn1_named_data **head, 00409 const char *oid, size_t oid_len, 00410 const unsigned char *val, 00411 size_t val_len ) 00412 { 00413 mbedtls_asn1_named_data *cur; 00414 00415 if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL ) 00416 { 00417 // Add new entry if not present yet based on OID 00418 // 00419 cur = (mbedtls_asn1_named_data*)mbedtls_calloc( 1, 00420 sizeof(mbedtls_asn1_named_data) ); 00421 if( cur == NULL ) 00422 return( NULL ); 00423 00424 cur->oid.len = oid_len; 00425 cur->oid.p = mbedtls_calloc( 1, oid_len ); 00426 if( cur->oid.p == NULL ) 00427 { 00428 mbedtls_free( cur ); 00429 return( NULL ); 00430 } 00431 00432 memcpy( cur->oid.p, oid, oid_len ); 00433 00434 cur->val.len = val_len; 00435 if( val_len != 0 ) 00436 { 00437 cur->val.p = mbedtls_calloc( 1, val_len ); 00438 if( cur->val.p == NULL ) 00439 { 00440 mbedtls_free( cur->oid.p ); 00441 mbedtls_free( cur ); 00442 return( NULL ); 00443 } 00444 } 00445 00446 cur->next = *head; 00447 *head = cur; 00448 } 00449 else if( val_len == 0 ) 00450 { 00451 mbedtls_free( cur->val.p ); 00452 cur->val.p = NULL; 00453 } 00454 else if( cur->val.len != val_len ) 00455 { 00456 /* 00457 * Enlarge existing value buffer if needed 00458 * Preserve old data until the allocation succeeded, to leave list in 00459 * a consistent state in case allocation fails. 00460 */ 00461 void *p = mbedtls_calloc( 1, val_len ); 00462 if( p == NULL ) 00463 return( NULL ); 00464 00465 mbedtls_free( cur->val.p ); 00466 cur->val.p = p; 00467 cur->val.len = val_len; 00468 } 00469 00470 if( val != NULL ) 00471 memcpy( cur->val.p, val, val_len ); 00472 00473 return( cur ); 00474 } 00475 #endif /* MBEDTLS_ASN1_WRITE_C */
Generated on Tue Jul 12 2022 13:54:01 by
