Dependents:   blinky_max32630fthr

Committer:
switches
Date:
Fri Nov 11 20:59:50 2016 +0000
Revision:
0:5c4d7b2438d3
Initial commit

Who changed what in which revision?

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