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( len <= 0xFFFFFFFF ) 00087 { 00088 if( *p - start < 5 ) 00089 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00090 00091 *--(*p) = ( len ) & 0xFF; 00092 *--(*p) = ( len >> 8 ) & 0xFF; 00093 *--(*p) = ( len >> 16 ) & 0xFF; 00094 *--(*p) = ( len >> 24 ) & 0xFF; 00095 *--(*p) = 0x84; 00096 return( 5 ); 00097 } 00098 00099 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00100 } 00101 00102 int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ) 00103 { 00104 if( *p - start < 1 ) 00105 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00106 00107 *--(*p) = tag; 00108 00109 return( 1 ); 00110 } 00111 00112 int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start, 00113 const unsigned char *buf, size_t size ) 00114 { 00115 size_t len = 0; 00116 00117 if( *p < start || (size_t)( *p - start ) < size ) 00118 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00119 00120 len = size; 00121 (*p) -= len; 00122 memcpy( *p, buf, len ); 00123 00124 return( (int) len ); 00125 } 00126 00127 #if defined(MBEDTLS_BIGNUM_C) 00128 int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X ) 00129 { 00130 int ret; 00131 size_t len = 0; 00132 00133 // Write the MPI 00134 // 00135 len = mbedtls_mpi_size( X ); 00136 00137 if( *p < start || (size_t)( *p - start ) < len ) 00138 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00139 00140 (*p) -= len; 00141 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, *p, len ) ); 00142 00143 // DER format assumes 2s complement for numbers, so the leftmost bit 00144 // should be 0 for positive numbers and 1 for negative numbers. 00145 // 00146 if( X->s ==1 && **p & 0x80 ) 00147 { 00148 if( *p - start < 1 ) 00149 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00150 00151 *--(*p) = 0x00; 00152 len += 1; 00153 } 00154 00155 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00156 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) ); 00157 00158 ret = (int) len; 00159 00160 cleanup: 00161 return( ret ); 00162 } 00163 #endif /* MBEDTLS_BIGNUM_C */ 00164 00165 int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start ) 00166 { 00167 int ret; 00168 size_t len = 0; 00169 00170 // Write NULL 00171 // 00172 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, 0) ); 00173 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_NULL ) ); 00174 00175 return( (int) len ); 00176 } 00177 00178 int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start, 00179 const char *oid, size_t oid_len ) 00180 { 00181 int ret; 00182 size_t len = 0; 00183 00184 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, 00185 (const unsigned char *) oid, oid_len ) ); 00186 MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_len( p, start, len ) ); 00187 MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) ); 00188 00189 return( (int) len ); 00190 } 00191 00192 int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, 00193 const char *oid, size_t oid_len, 00194 size_t par_len ) 00195 { 00196 int ret; 00197 size_t len = 0; 00198 00199 if( par_len == 0 ) 00200 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_null( p, start ) ); 00201 else 00202 len += par_len; 00203 00204 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); 00205 00206 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00207 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, 00208 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); 00209 00210 return( (int) len ); 00211 } 00212 00213 int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean ) 00214 { 00215 int ret; 00216 size_t len = 0; 00217 00218 if( *p - start < 1 ) 00219 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00220 00221 *--(*p) = (boolean) ? 255 : 0; 00222 len++; 00223 00224 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00225 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BOOLEAN ) ); 00226 00227 return( (int) len ); 00228 } 00229 00230 int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val ) 00231 { 00232 int ret; 00233 size_t len = 0; 00234 00235 if( *p - start < 1 ) 00236 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00237 00238 len += 1; 00239 *--(*p) = val; 00240 00241 if( val > 0 && **p & 0x80 ) 00242 { 00243 if( *p - start < 1 ) 00244 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00245 00246 *--(*p) = 0x00; 00247 len += 1; 00248 } 00249 00250 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00251 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) ); 00252 00253 return( (int) len ); 00254 } 00255 00256 int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start, 00257 const char *text, size_t text_len ) 00258 { 00259 int ret; 00260 size_t len = 0; 00261 00262 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, 00263 (const unsigned char *) text, text_len ) ); 00264 00265 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00266 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_PRINTABLE_STRING ) ); 00267 00268 return( (int) len ); 00269 } 00270 00271 int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start, 00272 const char *text, size_t text_len ) 00273 { 00274 int ret; 00275 size_t len = 0; 00276 00277 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, 00278 (const unsigned char *) text, text_len ) ); 00279 00280 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00281 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_IA5_STRING ) ); 00282 00283 return( (int) len ); 00284 } 00285 00286 int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start, 00287 const unsigned char *buf, size_t bits ) 00288 { 00289 int ret; 00290 size_t len = 0, size; 00291 00292 size = ( bits / 8 ) + ( ( bits % 8 ) ? 1 : 0 ); 00293 00294 // Calculate byte length 00295 // 00296 if( *p < start || (size_t)( *p - start ) < size + 1 ) 00297 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00298 00299 len = size + 1; 00300 (*p) -= size; 00301 memcpy( *p, buf, size ); 00302 00303 // Write unused bits 00304 // 00305 *--(*p) = (unsigned char) (size * 8 - bits); 00306 00307 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00308 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) ); 00309 00310 return( (int) len ); 00311 } 00312 00313 int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start, 00314 const unsigned char *buf, size_t size ) 00315 { 00316 int ret; 00317 size_t len = 0; 00318 00319 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, buf, size ) ); 00320 00321 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00322 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) ); 00323 00324 return( (int) len ); 00325 } 00326 00327 mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **head, 00328 const char *oid, size_t oid_len, 00329 const unsigned char *val, 00330 size_t val_len ) 00331 { 00332 mbedtls_asn1_named_data *cur; 00333 00334 if( ( cur = mbedtls_asn1_find_named_data( *head, oid, oid_len ) ) == NULL ) 00335 { 00336 // Add new entry if not present yet based on OID 00337 // 00338 cur = (mbedtls_asn1_named_data*)mbedtls_calloc( 1, 00339 sizeof(mbedtls_asn1_named_data) ); 00340 if( cur == NULL ) 00341 return( NULL ); 00342 00343 cur->oid.len = oid_len; 00344 cur->oid.p = mbedtls_calloc( 1, oid_len ); 00345 if( cur->oid.p == NULL ) 00346 { 00347 mbedtls_free( cur ); 00348 return( NULL ); 00349 } 00350 00351 memcpy( cur->oid.p, oid, oid_len ); 00352 00353 cur->val.len = val_len; 00354 cur->val.p = mbedtls_calloc( 1, val_len ); 00355 if( cur->val.p == NULL ) 00356 { 00357 mbedtls_free( cur->oid.p ); 00358 mbedtls_free( cur ); 00359 return( NULL ); 00360 } 00361 00362 cur->next = *head; 00363 *head = cur; 00364 } 00365 else if( cur->val.len < val_len ) 00366 { 00367 /* 00368 * Enlarge existing value buffer if needed 00369 * Preserve old data until the allocation succeeded, to leave list in 00370 * a consistent state in case allocation fails. 00371 */ 00372 void *p = mbedtls_calloc( 1, val_len ); 00373 if( p == NULL ) 00374 return( NULL ); 00375 00376 mbedtls_free( cur->val.p ); 00377 cur->val.p = p; 00378 cur->val.len = val_len; 00379 } 00380 00381 if( val != NULL ) 00382 memcpy( cur->val.p, val, val_len ); 00383 00384 return( cur ); 00385 } 00386 #endif /* MBEDTLS_ASN1_WRITE_C */
Generated on Tue Jul 12 2022 12:43:33 by
1.7.2