mbed TLS Build

Dependents:   Encypting_Funcional

Committer:
markrad
Date:
Thu Jan 05 00:18:44 2017 +0000
Revision:
0:cdf462088d13
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
markrad 0:cdf462088d13 1 /*
markrad 0:cdf462088d13 2 * ASN.1 buffer writing functionality
markrad 0:cdf462088d13 3 *
markrad 0:cdf462088d13 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
markrad 0:cdf462088d13 5 * SPDX-License-Identifier: Apache-2.0
markrad 0:cdf462088d13 6 *
markrad 0:cdf462088d13 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
markrad 0:cdf462088d13 8 * not use this file except in compliance with the License.
markrad 0:cdf462088d13 9 * You may obtain a copy of the License at
markrad 0:cdf462088d13 10 *
markrad 0:cdf462088d13 11 * http://www.apache.org/licenses/LICENSE-2.0
markrad 0:cdf462088d13 12 *
markrad 0:cdf462088d13 13 * Unless required by applicable law or agreed to in writing, software
markrad 0:cdf462088d13 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
markrad 0:cdf462088d13 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
markrad 0:cdf462088d13 16 * See the License for the specific language governing permissions and
markrad 0:cdf462088d13 17 * limitations under the License.
markrad 0:cdf462088d13 18 *
markrad 0:cdf462088d13 19 * This file is part of mbed TLS (https://tls.mbed.org)
markrad 0:cdf462088d13 20 */
markrad 0:cdf462088d13 21
markrad 0:cdf462088d13 22 #if !defined(MBEDTLS_CONFIG_FILE)
markrad 0:cdf462088d13 23 #include "mbedtls/config.h"
markrad 0:cdf462088d13 24 #else
markrad 0:cdf462088d13 25 #include MBEDTLS_CONFIG_FILE
markrad 0:cdf462088d13 26 #endif
markrad 0:cdf462088d13 27
markrad 0:cdf462088d13 28 #if defined(MBEDTLS_ASN1_WRITE_C)
markrad 0:cdf462088d13 29
markrad 0:cdf462088d13 30 #include "mbedtls/asn1write.h"
markrad 0:cdf462088d13 31
markrad 0:cdf462088d13 32 #include <string.h>
markrad 0:cdf462088d13 33
markrad 0:cdf462088d13 34 #if defined(MBEDTLS_PLATFORM_C)
markrad 0:cdf462088d13 35 #include "mbedtls/platform.h"
markrad 0:cdf462088d13 36 #else
markrad 0:cdf462088d13 37 #include <stdlib.h>
markrad 0:cdf462088d13 38 #define mbedtls_calloc calloc
markrad 0:cdf462088d13 39 #define mbedtls_free free
markrad 0:cdf462088d13 40 #endif
markrad 0:cdf462088d13 41
markrad 0:cdf462088d13 42 int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len )
markrad 0:cdf462088d13 43 {
markrad 0:cdf462088d13 44 if( len < 0x80 )
markrad 0:cdf462088d13 45 {
markrad 0:cdf462088d13 46 if( *p - start < 1 )
markrad 0:cdf462088d13 47 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
markrad 0:cdf462088d13 48
markrad 0:cdf462088d13 49 *--(*p) = (unsigned char) len;
markrad 0:cdf462088d13 50 return( 1 );
markrad 0:cdf462088d13 51 }
markrad 0:cdf462088d13 52
markrad 0:cdf462088d13 53 if( len <= 0xFF )
markrad 0:cdf462088d13 54 {
markrad 0:cdf462088d13 55 if( *p - start < 2 )
markrad 0:cdf462088d13 56 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
markrad 0:cdf462088d13 57
markrad 0:cdf462088d13 58 *--(*p) = (unsigned char) len;
markrad 0:cdf462088d13 59 *--(*p) = 0x81;
markrad 0:cdf462088d13 60 return( 2 );
markrad 0:cdf462088d13 61 }
markrad 0:cdf462088d13 62
markrad 0:cdf462088d13 63 if( len <= 0xFFFF )
markrad 0:cdf462088d13 64 {
markrad 0:cdf462088d13 65 if( *p - start < 3 )
markrad 0:cdf462088d13 66 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
markrad 0:cdf462088d13 67
markrad 0:cdf462088d13 68 *--(*p) = ( len ) & 0xFF;
markrad 0:cdf462088d13 69 *--(*p) = ( len >> 8 ) & 0xFF;
markrad 0:cdf462088d13 70 *--(*p) = 0x82;
markrad 0:cdf462088d13 71 return( 3 );
markrad 0:cdf462088d13 72 }
markrad 0:cdf462088d13 73
markrad 0:cdf462088d13 74 if( len <= 0xFFFFFF )
markrad 0:cdf462088d13 75 {
markrad 0:cdf462088d13 76 if( *p - start < 4 )
markrad 0:cdf462088d13 77 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
markrad 0:cdf462088d13 78
markrad 0:cdf462088d13 79 *--(*p) = ( len ) & 0xFF;
markrad 0:cdf462088d13 80 *--(*p) = ( len >> 8 ) & 0xFF;
markrad 0:cdf462088d13 81 *--(*p) = ( len >> 16 ) & 0xFF;
markrad 0:cdf462088d13 82 *--(*p) = 0x83;
markrad 0:cdf462088d13 83 return( 4 );
markrad 0:cdf462088d13 84 }
markrad 0:cdf462088d13 85
markrad 0:cdf462088d13 86 if( len <= 0xFFFFFFFF )
markrad 0:cdf462088d13 87 {
markrad 0:cdf462088d13 88 if( *p - start < 5 )
markrad 0:cdf462088d13 89 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
markrad 0:cdf462088d13 90
markrad 0:cdf462088d13 91 *--(*p) = ( len ) & 0xFF;
markrad 0:cdf462088d13 92 *--(*p) = ( len >> 8 ) & 0xFF;
markrad 0:cdf462088d13 93 *--(*p) = ( len >> 16 ) & 0xFF;
markrad 0:cdf462088d13 94 *--(*p) = ( len >> 24 ) & 0xFF;
markrad 0:cdf462088d13 95 *--(*p) = 0x84;
markrad 0:cdf462088d13 96 return( 5 );
markrad 0:cdf462088d13 97 }
markrad 0:cdf462088d13 98
markrad 0:cdf462088d13 99 return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
markrad 0:cdf462088d13 100 }
markrad 0:cdf462088d13 101
markrad 0:cdf462088d13 102 int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
markrad 0:cdf462088d13 103 {
markrad 0:cdf462088d13 104 if( *p - start < 1 )
markrad 0:cdf462088d13 105 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
markrad 0:cdf462088d13 106
markrad 0:cdf462088d13 107 *--(*p) = tag;
markrad 0:cdf462088d13 108
markrad 0:cdf462088d13 109 return( 1 );
markrad 0:cdf462088d13 110 }
markrad 0:cdf462088d13 111
markrad 0:cdf462088d13 112 int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
markrad 0:cdf462088d13 113 const unsigned char *buf, size_t size )
markrad 0:cdf462088d13 114 {
markrad 0:cdf462088d13 115 size_t len = 0;
markrad 0:cdf462088d13 116
markrad 0:cdf462088d13 117 if( *p < start || (size_t)( *p - start ) < size )
markrad 0:cdf462088d13 118 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
markrad 0:cdf462088d13 119
markrad 0:cdf462088d13 120 len = size;
markrad 0:cdf462088d13 121 (*p) -= len;
markrad 0:cdf462088d13 122 memcpy( *p, buf, len );
markrad 0:cdf462088d13 123
markrad 0:cdf462088d13 124 return( (int) len );
markrad 0:cdf462088d13 125 }
markrad 0:cdf462088d13 126
markrad 0:cdf462088d13 127 #if defined(MBEDTLS_BIGNUM_C)
markrad 0:cdf462088d13 128 int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X )
markrad 0:cdf462088d13 129 {
markrad 0:cdf462088d13 130 int ret;
markrad 0:cdf462088d13 131 size_t len = 0;
markrad 0:cdf462088d13 132
markrad 0:cdf462088d13 133 // Write the MPI
markrad 0:cdf462088d13 134 //
markrad 0:cdf462088d13 135 len = mbedtls_mpi_size( X );
markrad 0:cdf462088d13 136
markrad 0:cdf462088d13 137 if( *p < start || (size_t)( *p - start ) < len )
markrad 0:cdf462088d13 138 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
markrad 0:cdf462088d13 139
markrad 0:cdf462088d13 140 (*p) -= len;
markrad 0:cdf462088d13 141 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, *p, len ) );
markrad 0:cdf462088d13 142
markrad 0:cdf462088d13 143 // DER format assumes 2s complement for numbers, so the leftmost bit
markrad 0:cdf462088d13 144 // should be 0 for positive numbers and 1 for negative numbers.
markrad 0:cdf462088d13 145 //
markrad 0:cdf462088d13 146 if( X->s ==1 && **p & 0x80 )
markrad 0:cdf462088d13 147 {
markrad 0:cdf462088d13 148 if( *p - start < 1 )
markrad 0:cdf462088d13 149 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
markrad 0:cdf462088d13 150
markrad 0:cdf462088d13 151 *--(*p) = 0x00;
markrad 0:cdf462088d13 152 len += 1;
markrad 0:cdf462088d13 153 }
markrad 0:cdf462088d13 154
markrad 0:cdf462088d13 155 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
markrad 0:cdf462088d13 156 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) );
markrad 0:cdf462088d13 157
markrad 0:cdf462088d13 158 ret = (int) len;
markrad 0:cdf462088d13 159
markrad 0:cdf462088d13 160 cleanup:
markrad 0:cdf462088d13 161 return( ret );
markrad 0:cdf462088d13 162 }
markrad 0:cdf462088d13 163 #endif /* MBEDTLS_BIGNUM_C */
markrad 0:cdf462088d13 164
markrad 0:cdf462088d13 165 int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start )
markrad 0:cdf462088d13 166 {
markrad 0:cdf462088d13 167 int ret;
markrad 0:cdf462088d13 168 size_t len = 0;
markrad 0:cdf462088d13 169
markrad 0:cdf462088d13 170 // Write NULL
markrad 0:cdf462088d13 171 //
markrad 0:cdf462088d13 172 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, 0) );
markrad 0:cdf462088d13 173 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_NULL ) );
markrad 0:cdf462088d13 174
markrad 0:cdf462088d13 175 return( (int) len );
markrad 0:cdf462088d13 176 }
markrad 0:cdf462088d13 177
markrad 0:cdf462088d13 178 int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start,
markrad 0:cdf462088d13 179 const char *oid, size_t oid_len )
markrad 0:cdf462088d13 180 {
markrad 0:cdf462088d13 181 int ret;
markrad 0:cdf462088d13 182 size_t len = 0;
markrad 0:cdf462088d13 183
markrad 0:cdf462088d13 184 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
markrad 0:cdf462088d13 185 (const unsigned char *) oid, oid_len ) );
markrad 0:cdf462088d13 186 MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_len( p, start, len ) );
markrad 0:cdf462088d13 187 MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) );
markrad 0:cdf462088d13 188
markrad 0:cdf462088d13 189 return( (int) len );
markrad 0:cdf462088d13 190 }
markrad 0:cdf462088d13 191
markrad 0:cdf462088d13 192 int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
markrad 0:cdf462088d13 193 const char *oid, size_t oid_len,
markrad 0:cdf462088d13 194 size_t par_len )
markrad 0:cdf462088d13 195 {
markrad 0:cdf462088d13 196 int ret;
markrad 0:cdf462088d13 197 size_t len = 0;
markrad 0:cdf462088d13 198
markrad 0:cdf462088d13 199 if( par_len == 0 )
markrad 0:cdf462088d13 200 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_null( p, start ) );
markrad 0:cdf462088d13 201 else
markrad 0:cdf462088d13 202 len += par_len;
markrad 0:cdf462088d13 203
markrad 0:cdf462088d13 204 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) );
markrad 0:cdf462088d13 205
markrad 0:cdf462088d13 206 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
markrad 0:cdf462088d13 207 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
markrad 0:cdf462088d13 208 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
markrad 0:cdf462088d13 209
markrad 0:cdf462088d13 210 return( (int) len );
markrad 0:cdf462088d13 211 }
markrad 0:cdf462088d13 212
markrad 0:cdf462088d13 213 int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean )
markrad 0:cdf462088d13 214 {
markrad 0:cdf462088d13 215 int ret;
markrad 0:cdf462088d13 216 size_t len = 0;
markrad 0:cdf462088d13 217
markrad 0:cdf462088d13 218 if( *p - start < 1 )
markrad 0:cdf462088d13 219 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
markrad 0:cdf462088d13 220
markrad 0:cdf462088d13 221 *--(*p) = (boolean) ? 255 : 0;
markrad 0:cdf462088d13 222 len++;
markrad 0:cdf462088d13 223
markrad 0:cdf462088d13 224 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
markrad 0:cdf462088d13 225 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BOOLEAN ) );
markrad 0:cdf462088d13 226
markrad 0:cdf462088d13 227 return( (int) len );
markrad 0:cdf462088d13 228 }
markrad 0:cdf462088d13 229
markrad 0:cdf462088d13 230 int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val )
markrad 0:cdf462088d13 231 {
markrad 0:cdf462088d13 232 int ret;
markrad 0:cdf462088d13 233 size_t len = 0;
markrad 0:cdf462088d13 234
markrad 0:cdf462088d13 235 // TODO negative values and values larger than 128
markrad 0:cdf462088d13 236 // DER format assumes 2s complement for numbers, so the leftmost bit
markrad 0:cdf462088d13 237 // should be 0 for positive numbers and 1 for negative numbers.
markrad 0:cdf462088d13 238 //
markrad 0:cdf462088d13 239 if( *p - start < 1 )
markrad 0:cdf462088d13 240 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
markrad 0:cdf462088d13 241
markrad 0:cdf462088d13 242 len += 1;
markrad 0:cdf462088d13 243 *--(*p) = val;
markrad 0:cdf462088d13 244
markrad 0:cdf462088d13 245 if( val > 0 && **p & 0x80 )
markrad 0:cdf462088d13 246 {
markrad 0:cdf462088d13 247 if( *p - start < 1 )
markrad 0:cdf462088d13 248 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
markrad 0:cdf462088d13 249
markrad 0:cdf462088d13 250 *--(*p) = 0x00;
markrad 0:cdf462088d13 251 len += 1;
markrad 0:cdf462088d13 252 }
markrad 0:cdf462088d13 253
markrad 0:cdf462088d13 254 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
markrad 0:cdf462088d13 255 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) );
markrad 0:cdf462088d13 256
markrad 0:cdf462088d13 257 return( (int) len );
markrad 0:cdf462088d13 258 }
markrad 0:cdf462088d13 259
markrad 0:cdf462088d13 260 int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start,
markrad 0:cdf462088d13 261 const char *text, size_t text_len )
markrad 0:cdf462088d13 262 {
markrad 0:cdf462088d13 263 int ret;
markrad 0:cdf462088d13 264 size_t len = 0;
markrad 0:cdf462088d13 265
markrad 0:cdf462088d13 266 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
markrad 0:cdf462088d13 267 (const unsigned char *) text, text_len ) );
markrad 0:cdf462088d13 268
markrad 0:cdf462088d13 269 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
markrad 0:cdf462088d13 270 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_PRINTABLE_STRING ) );
markrad 0:cdf462088d13 271
markrad 0:cdf462088d13 272 return( (int) len );
markrad 0:cdf462088d13 273 }
markrad 0:cdf462088d13 274
markrad 0:cdf462088d13 275 int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
markrad 0:cdf462088d13 276 const char *text, size_t text_len )
markrad 0:cdf462088d13 277 {
markrad 0:cdf462088d13 278 int ret;
markrad 0:cdf462088d13 279 size_t len = 0;
markrad 0:cdf462088d13 280
markrad 0:cdf462088d13 281 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
markrad 0:cdf462088d13 282 (const unsigned char *) text, text_len ) );
markrad 0:cdf462088d13 283
markrad 0:cdf462088d13 284 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
markrad 0:cdf462088d13 285 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_IA5_STRING ) );
markrad 0:cdf462088d13 286
markrad 0:cdf462088d13 287 return( (int) len );
markrad 0:cdf462088d13 288 }
markrad 0:cdf462088d13 289
markrad 0:cdf462088d13 290 int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
markrad 0:cdf462088d13 291 const unsigned char *buf, size_t bits )
markrad 0:cdf462088d13 292 {
markrad 0:cdf462088d13 293 int ret;
markrad 0:cdf462088d13 294 size_t len = 0, size;
markrad 0:cdf462088d13 295
markrad 0:cdf462088d13 296 size = ( bits / 8 ) + ( ( bits % 8 ) ? 1 : 0 );
markrad 0:cdf462088d13 297
markrad 0:cdf462088d13 298 // Calculate byte length
markrad 0:cdf462088d13 299 //
markrad 0:cdf462088d13 300 if( *p < start || (size_t)( *p - start ) < size + 1 )
markrad 0:cdf462088d13 301 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
markrad 0:cdf462088d13 302
markrad 0:cdf462088d13 303 len = size + 1;
markrad 0:cdf462088d13 304 (*p) -= size;
markrad 0:cdf462088d13 305 memcpy( *p, buf, size );
markrad 0:cdf462088d13 306
markrad 0:cdf462088d13 307 // Write unused bits
markrad 0:cdf462088d13 308 //
markrad 0:cdf462088d13 309 *--(*p) = (unsigned char) (size * 8 - bits);
markrad 0:cdf462088d13 310
markrad 0:cdf462088d13 311 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
markrad 0:cdf462088d13 312 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) );
markrad 0:cdf462088d13 313
markrad 0:cdf462088d13 314 return( (int) len );
markrad 0:cdf462088d13 315 }
markrad 0:cdf462088d13 316
markrad 0:cdf462088d13 317 int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
markrad 0:cdf462088d13 318 const unsigned char *buf, size_t size )
markrad 0:cdf462088d13 319 {
markrad 0:cdf462088d13 320 int ret;
markrad 0:cdf462088d13 321 size_t len = 0;
markrad 0:cdf462088d13 322
markrad 0:cdf462088d13 323 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, buf, size ) );
markrad 0:cdf462088d13 324
markrad 0:cdf462088d13 325 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
markrad 0:cdf462088d13 326 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) );
markrad 0:cdf462088d13 327
markrad 0:cdf462088d13 328 return( (int) len );
markrad 0:cdf462088d13 329 }
markrad 0:cdf462088d13 330
markrad 0:cdf462088d13 331 mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **head,
markrad 0:cdf462088d13 332 const char *oid, size_t oid_len,
markrad 0:cdf462088d13 333 const unsigned char *val,
markrad 0:cdf462088d13 334 size_t val_len )
markrad 0:cdf462088d13 335 {
markrad 0:cdf462088d13 336 mbedtls_asn1_named_data *cur;
markrad 0:cdf462088d13 337
markrad 0:cdf462088d13 338 if( ( cur = mbedtls_asn1_find_named_data( *head, oid, oid_len ) ) == NULL )
markrad 0:cdf462088d13 339 {
markrad 0:cdf462088d13 340 // Add new entry if not present yet based on OID
markrad 0:cdf462088d13 341 //
markrad 0:cdf462088d13 342 cur = (mbedtls_asn1_named_data*)mbedtls_calloc( 1,
markrad 0:cdf462088d13 343 sizeof(mbedtls_asn1_named_data) );
markrad 0:cdf462088d13 344 if( cur == NULL )
markrad 0:cdf462088d13 345 return( NULL );
markrad 0:cdf462088d13 346
markrad 0:cdf462088d13 347 cur->oid.len = oid_len;
markrad 0:cdf462088d13 348 cur->oid.p = mbedtls_calloc( 1, oid_len );
markrad 0:cdf462088d13 349 if( cur->oid.p == NULL )
markrad 0:cdf462088d13 350 {
markrad 0:cdf462088d13 351 mbedtls_free( cur );
markrad 0:cdf462088d13 352 return( NULL );
markrad 0:cdf462088d13 353 }
markrad 0:cdf462088d13 354
markrad 0:cdf462088d13 355 memcpy( cur->oid.p, oid, oid_len );
markrad 0:cdf462088d13 356
markrad 0:cdf462088d13 357 cur->val.len = val_len;
markrad 0:cdf462088d13 358 cur->val.p = mbedtls_calloc( 1, val_len );
markrad 0:cdf462088d13 359 if( cur->val.p == NULL )
markrad 0:cdf462088d13 360 {
markrad 0:cdf462088d13 361 mbedtls_free( cur->oid.p );
markrad 0:cdf462088d13 362 mbedtls_free( cur );
markrad 0:cdf462088d13 363 return( NULL );
markrad 0:cdf462088d13 364 }
markrad 0:cdf462088d13 365
markrad 0:cdf462088d13 366 cur->next = *head;
markrad 0:cdf462088d13 367 *head = cur;
markrad 0:cdf462088d13 368 }
markrad 0:cdf462088d13 369 else if( cur->val.len < val_len )
markrad 0:cdf462088d13 370 {
markrad 0:cdf462088d13 371 /*
markrad 0:cdf462088d13 372 * Enlarge existing value buffer if needed
markrad 0:cdf462088d13 373 * Preserve old data until the allocation succeeded, to leave list in
markrad 0:cdf462088d13 374 * a consistent state in case allocation fails.
markrad 0:cdf462088d13 375 */
markrad 0:cdf462088d13 376 void *p = mbedtls_calloc( 1, val_len );
markrad 0:cdf462088d13 377 if( p == NULL )
markrad 0:cdf462088d13 378 return( NULL );
markrad 0:cdf462088d13 379
markrad 0:cdf462088d13 380 mbedtls_free( cur->val.p );
markrad 0:cdf462088d13 381 cur->val.p = p;
markrad 0:cdf462088d13 382 cur->val.len = val_len;
markrad 0:cdf462088d13 383 }
markrad 0:cdf462088d13 384
markrad 0:cdf462088d13 385 if( val != NULL )
markrad 0:cdf462088d13 386 memcpy( cur->val.p, val, val_len );
markrad 0:cdf462088d13 387
markrad 0:cdf462088d13 388 return( cur );
markrad 0:cdf462088d13 389 }
markrad 0:cdf462088d13 390 #endif /* MBEDTLS_ASN1_WRITE_C */