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-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 if( *p - start < 1 ) 00240 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00241 00242 len += 1; 00243 *--(*p) = val; 00244 00245 if( val > 0 && **p & 0x80 ) 00246 { 00247 if( *p - start < 1 ) 00248 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00249 00250 *--(*p) = 0x00; 00251 len += 1; 00252 } 00253 00254 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00255 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) ); 00256 00257 return( (int) len ); 00258 } 00259 00260 int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start, 00261 const char *text, size_t text_len ) 00262 { 00263 int ret; 00264 size_t len = 0; 00265 00266 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, 00267 (const unsigned char *) text, text_len ) ); 00268 00269 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00270 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_PRINTABLE_STRING ) ); 00271 00272 return( (int) len ); 00273 } 00274 00275 int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start, 00276 const char *text, size_t text_len ) 00277 { 00278 int ret; 00279 size_t len = 0; 00280 00281 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, 00282 (const unsigned char *) text, text_len ) ); 00283 00284 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00285 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_IA5_STRING ) ); 00286 00287 return( (int) len ); 00288 } 00289 00290 int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start, 00291 const unsigned char *buf, size_t bits ) 00292 { 00293 int ret; 00294 size_t len = 0, size; 00295 00296 size = ( bits / 8 ) + ( ( bits % 8 ) ? 1 : 0 ); 00297 00298 // Calculate byte length 00299 // 00300 if( *p < start || (size_t)( *p - start ) < size + 1 ) 00301 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00302 00303 len = size + 1; 00304 (*p) -= size; 00305 memcpy( *p, buf, size ); 00306 00307 // Write unused bits 00308 // 00309 *--(*p) = (unsigned char) (size * 8 - bits); 00310 00311 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00312 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) ); 00313 00314 return( (int) len ); 00315 } 00316 00317 int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start, 00318 const unsigned char *buf, size_t size ) 00319 { 00320 int ret; 00321 size_t len = 0; 00322 00323 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, buf, size ) ); 00324 00325 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00326 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) ); 00327 00328 return( (int) len ); 00329 } 00330 00331 mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **head, 00332 const char *oid, size_t oid_len, 00333 const unsigned char *val, 00334 size_t val_len ) 00335 { 00336 mbedtls_asn1_named_data *cur; 00337 00338 if( ( cur = mbedtls_asn1_find_named_data( *head, oid, oid_len ) ) == NULL ) 00339 { 00340 // Add new entry if not present yet based on OID 00341 // 00342 cur = (mbedtls_asn1_named_data*)mbedtls_calloc( 1, 00343 sizeof(mbedtls_asn1_named_data) ); 00344 if( cur == NULL ) 00345 return( NULL ); 00346 00347 cur->oid.len = oid_len; 00348 cur->oid.p = mbedtls_calloc( 1, oid_len ); 00349 if( cur->oid.p == NULL ) 00350 { 00351 mbedtls_free( cur ); 00352 return( NULL ); 00353 } 00354 00355 memcpy( cur->oid.p, oid, oid_len ); 00356 00357 cur->val.len = val_len; 00358 cur->val.p = mbedtls_calloc( 1, val_len ); 00359 if( cur->val.p == NULL ) 00360 { 00361 mbedtls_free( cur->oid.p ); 00362 mbedtls_free( cur ); 00363 return( NULL ); 00364 } 00365 00366 cur->next = *head; 00367 *head = cur; 00368 } 00369 else if( cur->val.len < val_len ) 00370 { 00371 /* 00372 * Enlarge existing value buffer if needed 00373 * Preserve old data until the allocation succeeded, to leave list in 00374 * a consistent state in case allocation fails. 00375 */ 00376 void *p = mbedtls_calloc( 1, val_len ); 00377 if( p == NULL ) 00378 return( NULL ); 00379 00380 mbedtls_free( cur->val.p ); 00381 cur->val.p = p; 00382 cur->val.len = val_len; 00383 } 00384 00385 if( val != NULL ) 00386 memcpy( cur->val.p, val, val_len ); 00387 00388 return( cur ); 00389 } 00390 #endif /* MBEDTLS_ASN1_WRITE_C */
Generated on Tue Jul 12 2022 13:53:01 by
