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.
Fork of mbedtls by
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 // TODO negative values and values larger than 128 00236 // DER format assumes 2s complement for numbers, so the leftmost bit 00237 // should be 0 for positive numbers and 1 for negative numbers. 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 17:25:41 by
