Pinned to some recent date

Committer:
Simon Cooksey
Date:
Thu Nov 17 16:43:53 2016 +0000
Revision:
0:fb7af294d5d9
Initial commit

Who changed what in which revision?

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