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( *p - start < 3 ) 00064 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00065 00066 // We assume we never have lengths larger than 65535 bytes 00067 // 00068 *--(*p) = len % 256; 00069 *--(*p) = ( len / 256 ) % 256; 00070 *--(*p) = 0x82; 00071 00072 return( 3 ); 00073 } 00074 00075 int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ) 00076 { 00077 if( *p - start < 1 ) 00078 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00079 00080 *--(*p) = tag; 00081 00082 return( 1 ); 00083 } 00084 00085 int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start, 00086 const unsigned char *buf, size_t size ) 00087 { 00088 size_t len = 0; 00089 00090 if( *p < start || (size_t)( *p - start ) < size ) 00091 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00092 00093 len = size; 00094 (*p) -= len; 00095 memcpy( *p, buf, len ); 00096 00097 return( (int) len ); 00098 } 00099 00100 #if defined(MBEDTLS_BIGNUM_C) 00101 int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X ) 00102 { 00103 int ret; 00104 size_t len = 0; 00105 00106 // Write the MPI 00107 // 00108 len = mbedtls_mpi_size( X ); 00109 00110 if( *p < start || (size_t)( *p - start ) < len ) 00111 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00112 00113 (*p) -= len; 00114 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, *p, len ) ); 00115 00116 // DER format assumes 2s complement for numbers, so the leftmost bit 00117 // should be 0 for positive numbers and 1 for negative numbers. 00118 // 00119 if( X->s ==1 && **p & 0x80 ) 00120 { 00121 if( *p - start < 1 ) 00122 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00123 00124 *--(*p) = 0x00; 00125 len += 1; 00126 } 00127 00128 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00129 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) ); 00130 00131 ret = (int) len; 00132 00133 cleanup: 00134 return( ret ); 00135 } 00136 #endif /* MBEDTLS_BIGNUM_C */ 00137 00138 int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start ) 00139 { 00140 int ret; 00141 size_t len = 0; 00142 00143 // Write NULL 00144 // 00145 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, 0) ); 00146 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_NULL ) ); 00147 00148 return( (int) len ); 00149 } 00150 00151 int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start, 00152 const char *oid, size_t oid_len ) 00153 { 00154 int ret; 00155 size_t len = 0; 00156 00157 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, 00158 (const unsigned char *) oid, oid_len ) ); 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_OID ) ); 00161 00162 return( (int) len ); 00163 } 00164 00165 int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, 00166 const char *oid, size_t oid_len, 00167 size_t par_len ) 00168 { 00169 int ret; 00170 size_t len = 0; 00171 00172 if( par_len == 0 ) 00173 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_null( p, start ) ); 00174 else 00175 len += par_len; 00176 00177 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); 00178 00179 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00180 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, 00181 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); 00182 00183 return( (int) len ); 00184 } 00185 00186 int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean ) 00187 { 00188 int ret; 00189 size_t len = 0; 00190 00191 if( *p - start < 1 ) 00192 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00193 00194 *--(*p) = (boolean) ? 255 : 0; 00195 len++; 00196 00197 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00198 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BOOLEAN ) ); 00199 00200 return( (int) len ); 00201 } 00202 00203 int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val ) 00204 { 00205 int ret; 00206 size_t len = 0; 00207 00208 // TODO negative values and values larger than 128 00209 // DER format assumes 2s complement for numbers, so the leftmost bit 00210 // should be 0 for positive numbers and 1 for negative numbers. 00211 // 00212 if( *p - start < 1 ) 00213 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00214 00215 len += 1; 00216 *--(*p) = val; 00217 00218 if( val > 0 && **p & 0x80 ) 00219 { 00220 if( *p - start < 1 ) 00221 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00222 00223 *--(*p) = 0x00; 00224 len += 1; 00225 } 00226 00227 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00228 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) ); 00229 00230 return( (int) len ); 00231 } 00232 00233 int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start, 00234 const char *text, size_t text_len ) 00235 { 00236 int ret; 00237 size_t len = 0; 00238 00239 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, 00240 (const unsigned char *) text, text_len ) ); 00241 00242 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00243 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_PRINTABLE_STRING ) ); 00244 00245 return( (int) len ); 00246 } 00247 00248 int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start, 00249 const char *text, size_t text_len ) 00250 { 00251 int ret; 00252 size_t len = 0; 00253 00254 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, 00255 (const unsigned char *) text, text_len ) ); 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_IA5_STRING ) ); 00259 00260 return( (int) len ); 00261 } 00262 00263 int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start, 00264 const unsigned char *buf, size_t bits ) 00265 { 00266 int ret; 00267 size_t len = 0, size; 00268 00269 size = ( bits / 8 ) + ( ( bits % 8 ) ? 1 : 0 ); 00270 00271 // Calculate byte length 00272 // 00273 if( *p < start || (size_t)( *p - start ) < size + 1 ) 00274 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00275 00276 len = size + 1; 00277 (*p) -= size; 00278 memcpy( *p, buf, size ); 00279 00280 // Write unused bits 00281 // 00282 *--(*p) = (unsigned char) (size * 8 - bits); 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_BIT_STRING ) ); 00286 00287 return( (int) len ); 00288 } 00289 00290 int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start, 00291 const unsigned char *buf, size_t size ) 00292 { 00293 int ret; 00294 size_t len = 0; 00295 00296 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, buf, size ) ); 00297 00298 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00299 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) ); 00300 00301 return( (int) len ); 00302 } 00303 00304 mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **head, 00305 const char *oid, size_t oid_len, 00306 const unsigned char *val, 00307 size_t val_len ) 00308 { 00309 mbedtls_asn1_named_data *cur; 00310 00311 if( ( cur = mbedtls_asn1_find_named_data( *head, oid, oid_len ) ) == NULL ) 00312 { 00313 // Add new entry if not present yet based on OID 00314 // 00315 if( ( cur = mbedtls_calloc( 1, sizeof(mbedtls_asn1_named_data) ) ) == NULL ) 00316 return( NULL ); 00317 00318 cur->oid.len = oid_len; 00319 cur->oid.p = mbedtls_calloc( 1, oid_len ); 00320 if( cur->oid.p == NULL ) 00321 { 00322 mbedtls_free( cur ); 00323 return( NULL ); 00324 } 00325 00326 memcpy( cur->oid.p, oid, oid_len ); 00327 00328 cur->val.len = val_len; 00329 cur->val.p = mbedtls_calloc( 1, val_len ); 00330 if( cur->val.p == NULL ) 00331 { 00332 mbedtls_free( cur->oid.p ); 00333 mbedtls_free( cur ); 00334 return( NULL ); 00335 } 00336 00337 cur->next = *head; 00338 *head = cur; 00339 } 00340 else if( cur->val.len < val_len ) 00341 { 00342 // Enlarge existing value buffer if needed 00343 // 00344 mbedtls_free( cur->val.p ); 00345 cur->val.p = NULL; 00346 00347 cur->val.len = val_len; 00348 cur->val.p = mbedtls_calloc( 1, val_len ); 00349 if( cur->val.p == NULL ) 00350 { 00351 mbedtls_free( cur->oid.p ); 00352 mbedtls_free( cur ); 00353 return( NULL ); 00354 } 00355 } 00356 00357 if( val != NULL ) 00358 memcpy( cur->val.p, val, val_len ); 00359 00360 return( cur ); 00361 } 00362 #endif /* MBEDTLS_ASN1_WRITE_C */
Generated on Tue Jul 12 2022 12:52:41 by
