Preliminary main mbed library for nexpaq development

Committer:
nexpaq
Date:
Fri Nov 04 20:54:50 2016 +0000
Revision:
1:d96dbedaebdb
Parent:
0:6c56fb4bc5f0
Removed extra directories for other platforms

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nexpaq 0:6c56fb4bc5f0 1 /*
nexpaq 0:6c56fb4bc5f0 2 * X.509 base functions for creating certificates / CSRs
nexpaq 0:6c56fb4bc5f0 3 *
nexpaq 0:6c56fb4bc5f0 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
nexpaq 0:6c56fb4bc5f0 5 * SPDX-License-Identifier: Apache-2.0
nexpaq 0:6c56fb4bc5f0 6 *
nexpaq 0:6c56fb4bc5f0 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
nexpaq 0:6c56fb4bc5f0 8 * not use this file except in compliance with the License.
nexpaq 0:6c56fb4bc5f0 9 * You may obtain a copy of the License at
nexpaq 0:6c56fb4bc5f0 10 *
nexpaq 0:6c56fb4bc5f0 11 * http://www.apache.org/licenses/LICENSE-2.0
nexpaq 0:6c56fb4bc5f0 12 *
nexpaq 0:6c56fb4bc5f0 13 * Unless required by applicable law or agreed to in writing, software
nexpaq 0:6c56fb4bc5f0 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
nexpaq 0:6c56fb4bc5f0 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
nexpaq 0:6c56fb4bc5f0 16 * See the License for the specific language governing permissions and
nexpaq 0:6c56fb4bc5f0 17 * limitations under the License.
nexpaq 0:6c56fb4bc5f0 18 *
nexpaq 0:6c56fb4bc5f0 19 * This file is part of mbed TLS (https://tls.mbed.org)
nexpaq 0:6c56fb4bc5f0 20 */
nexpaq 0:6c56fb4bc5f0 21
nexpaq 0:6c56fb4bc5f0 22 #if !defined(MBEDTLS_CONFIG_FILE)
nexpaq 0:6c56fb4bc5f0 23 #include "mbedtls/config.h"
nexpaq 0:6c56fb4bc5f0 24 #else
nexpaq 0:6c56fb4bc5f0 25 #include MBEDTLS_CONFIG_FILE
nexpaq 0:6c56fb4bc5f0 26 #endif
nexpaq 0:6c56fb4bc5f0 27
nexpaq 0:6c56fb4bc5f0 28 #if defined(MBEDTLS_X509_CREATE_C)
nexpaq 0:6c56fb4bc5f0 29
nexpaq 0:6c56fb4bc5f0 30 #include "mbedtls/x509.h"
nexpaq 0:6c56fb4bc5f0 31 #include "mbedtls/asn1write.h"
nexpaq 0:6c56fb4bc5f0 32 #include "mbedtls/oid.h"
nexpaq 0:6c56fb4bc5f0 33
nexpaq 0:6c56fb4bc5f0 34 #include <string.h>
nexpaq 0:6c56fb4bc5f0 35
nexpaq 0:6c56fb4bc5f0 36 typedef struct {
nexpaq 0:6c56fb4bc5f0 37 const char *name;
nexpaq 0:6c56fb4bc5f0 38 size_t name_len;
nexpaq 0:6c56fb4bc5f0 39 const char*oid;
nexpaq 0:6c56fb4bc5f0 40 } x509_attr_descriptor_t;
nexpaq 0:6c56fb4bc5f0 41
nexpaq 0:6c56fb4bc5f0 42 #define ADD_STRLEN( s ) s, sizeof( s ) - 1
nexpaq 0:6c56fb4bc5f0 43
nexpaq 0:6c56fb4bc5f0 44 static const x509_attr_descriptor_t x509_attrs[] =
nexpaq 0:6c56fb4bc5f0 45 {
nexpaq 0:6c56fb4bc5f0 46 { ADD_STRLEN( "CN" ), MBEDTLS_OID_AT_CN },
nexpaq 0:6c56fb4bc5f0 47 { ADD_STRLEN( "commonName" ), MBEDTLS_OID_AT_CN },
nexpaq 0:6c56fb4bc5f0 48 { ADD_STRLEN( "C" ), MBEDTLS_OID_AT_COUNTRY },
nexpaq 0:6c56fb4bc5f0 49 { ADD_STRLEN( "countryName" ), MBEDTLS_OID_AT_COUNTRY },
nexpaq 0:6c56fb4bc5f0 50 { ADD_STRLEN( "O" ), MBEDTLS_OID_AT_ORGANIZATION },
nexpaq 0:6c56fb4bc5f0 51 { ADD_STRLEN( "organizationName" ), MBEDTLS_OID_AT_ORGANIZATION },
nexpaq 0:6c56fb4bc5f0 52 { ADD_STRLEN( "L" ), MBEDTLS_OID_AT_LOCALITY },
nexpaq 0:6c56fb4bc5f0 53 { ADD_STRLEN( "locality" ), MBEDTLS_OID_AT_LOCALITY },
nexpaq 0:6c56fb4bc5f0 54 { ADD_STRLEN( "R" ), MBEDTLS_OID_PKCS9_EMAIL },
nexpaq 0:6c56fb4bc5f0 55 { ADD_STRLEN( "OU" ), MBEDTLS_OID_AT_ORG_UNIT },
nexpaq 0:6c56fb4bc5f0 56 { ADD_STRLEN( "organizationalUnitName" ), MBEDTLS_OID_AT_ORG_UNIT },
nexpaq 0:6c56fb4bc5f0 57 { ADD_STRLEN( "ST" ), MBEDTLS_OID_AT_STATE },
nexpaq 0:6c56fb4bc5f0 58 { ADD_STRLEN( "stateOrProvinceName" ), MBEDTLS_OID_AT_STATE },
nexpaq 0:6c56fb4bc5f0 59 { ADD_STRLEN( "emailAddress" ), MBEDTLS_OID_PKCS9_EMAIL },
nexpaq 0:6c56fb4bc5f0 60 { ADD_STRLEN( "serialNumber" ), MBEDTLS_OID_AT_SERIAL_NUMBER },
nexpaq 0:6c56fb4bc5f0 61 { ADD_STRLEN( "postalAddress" ), MBEDTLS_OID_AT_POSTAL_ADDRESS },
nexpaq 0:6c56fb4bc5f0 62 { ADD_STRLEN( "postalCode" ), MBEDTLS_OID_AT_POSTAL_CODE },
nexpaq 0:6c56fb4bc5f0 63 { ADD_STRLEN( "dnQualifier" ), MBEDTLS_OID_AT_DN_QUALIFIER },
nexpaq 0:6c56fb4bc5f0 64 { ADD_STRLEN( "title" ), MBEDTLS_OID_AT_TITLE },
nexpaq 0:6c56fb4bc5f0 65 { ADD_STRLEN( "surName" ), MBEDTLS_OID_AT_SUR_NAME },
nexpaq 0:6c56fb4bc5f0 66 { ADD_STRLEN( "SN" ), MBEDTLS_OID_AT_SUR_NAME },
nexpaq 0:6c56fb4bc5f0 67 { ADD_STRLEN( "givenName" ), MBEDTLS_OID_AT_GIVEN_NAME },
nexpaq 0:6c56fb4bc5f0 68 { ADD_STRLEN( "GN" ), MBEDTLS_OID_AT_GIVEN_NAME },
nexpaq 0:6c56fb4bc5f0 69 { ADD_STRLEN( "initials" ), MBEDTLS_OID_AT_INITIALS },
nexpaq 0:6c56fb4bc5f0 70 { ADD_STRLEN( "pseudonym" ), MBEDTLS_OID_AT_PSEUDONYM },
nexpaq 0:6c56fb4bc5f0 71 { ADD_STRLEN( "generationQualifier" ), MBEDTLS_OID_AT_GENERATION_QUALIFIER },
nexpaq 0:6c56fb4bc5f0 72 { ADD_STRLEN( "domainComponent" ), MBEDTLS_OID_DOMAIN_COMPONENT },
nexpaq 0:6c56fb4bc5f0 73 { ADD_STRLEN( "DC" ), MBEDTLS_OID_DOMAIN_COMPONENT },
nexpaq 0:6c56fb4bc5f0 74 { NULL, 0, NULL }
nexpaq 0:6c56fb4bc5f0 75 };
nexpaq 0:6c56fb4bc5f0 76
nexpaq 0:6c56fb4bc5f0 77 static const char *x509_at_oid_from_name( const char *name, size_t name_len )
nexpaq 0:6c56fb4bc5f0 78 {
nexpaq 0:6c56fb4bc5f0 79 const x509_attr_descriptor_t *cur;
nexpaq 0:6c56fb4bc5f0 80
nexpaq 0:6c56fb4bc5f0 81 for( cur = x509_attrs; cur->name != NULL; cur++ )
nexpaq 0:6c56fb4bc5f0 82 if( cur->name_len == name_len &&
nexpaq 0:6c56fb4bc5f0 83 strncmp( cur->name, name, name_len ) == 0 )
nexpaq 0:6c56fb4bc5f0 84 break;
nexpaq 0:6c56fb4bc5f0 85
nexpaq 0:6c56fb4bc5f0 86 return( cur->oid );
nexpaq 0:6c56fb4bc5f0 87 }
nexpaq 0:6c56fb4bc5f0 88
nexpaq 0:6c56fb4bc5f0 89 int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name )
nexpaq 0:6c56fb4bc5f0 90 {
nexpaq 0:6c56fb4bc5f0 91 int ret = 0;
nexpaq 0:6c56fb4bc5f0 92 const char *s = name, *c = s;
nexpaq 0:6c56fb4bc5f0 93 const char *end = s + strlen( s );
nexpaq 0:6c56fb4bc5f0 94 const char *oid = NULL;
nexpaq 0:6c56fb4bc5f0 95 int in_tag = 1;
nexpaq 0:6c56fb4bc5f0 96 char data[MBEDTLS_X509_MAX_DN_NAME_SIZE];
nexpaq 0:6c56fb4bc5f0 97 char *d = data;
nexpaq 0:6c56fb4bc5f0 98
nexpaq 0:6c56fb4bc5f0 99 /* Clear existing chain if present */
nexpaq 0:6c56fb4bc5f0 100 mbedtls_asn1_free_named_data_list( head );
nexpaq 0:6c56fb4bc5f0 101
nexpaq 0:6c56fb4bc5f0 102 while( c <= end )
nexpaq 0:6c56fb4bc5f0 103 {
nexpaq 0:6c56fb4bc5f0 104 if( in_tag && *c == '=' )
nexpaq 0:6c56fb4bc5f0 105 {
nexpaq 0:6c56fb4bc5f0 106 if( ( oid = x509_at_oid_from_name( s, c - s ) ) == NULL )
nexpaq 0:6c56fb4bc5f0 107 {
nexpaq 0:6c56fb4bc5f0 108 ret = MBEDTLS_ERR_X509_UNKNOWN_OID;
nexpaq 0:6c56fb4bc5f0 109 goto exit;
nexpaq 0:6c56fb4bc5f0 110 }
nexpaq 0:6c56fb4bc5f0 111
nexpaq 0:6c56fb4bc5f0 112 s = c + 1;
nexpaq 0:6c56fb4bc5f0 113 in_tag = 0;
nexpaq 0:6c56fb4bc5f0 114 d = data;
nexpaq 0:6c56fb4bc5f0 115 }
nexpaq 0:6c56fb4bc5f0 116
nexpaq 0:6c56fb4bc5f0 117 if( !in_tag && *c == '\\' && c != end )
nexpaq 0:6c56fb4bc5f0 118 {
nexpaq 0:6c56fb4bc5f0 119 c++;
nexpaq 0:6c56fb4bc5f0 120
nexpaq 0:6c56fb4bc5f0 121 /* Check for valid escaped characters */
nexpaq 0:6c56fb4bc5f0 122 if( c == end || *c != ',' )
nexpaq 0:6c56fb4bc5f0 123 {
nexpaq 0:6c56fb4bc5f0 124 ret = MBEDTLS_ERR_X509_INVALID_NAME;
nexpaq 0:6c56fb4bc5f0 125 goto exit;
nexpaq 0:6c56fb4bc5f0 126 }
nexpaq 0:6c56fb4bc5f0 127 }
nexpaq 0:6c56fb4bc5f0 128 else if( !in_tag && ( *c == ',' || c == end ) )
nexpaq 0:6c56fb4bc5f0 129 {
nexpaq 0:6c56fb4bc5f0 130 if( mbedtls_asn1_store_named_data( head, oid, strlen( oid ),
nexpaq 0:6c56fb4bc5f0 131 (unsigned char *) data,
nexpaq 0:6c56fb4bc5f0 132 d - data ) == NULL )
nexpaq 0:6c56fb4bc5f0 133 {
nexpaq 0:6c56fb4bc5f0 134 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
nexpaq 0:6c56fb4bc5f0 135 }
nexpaq 0:6c56fb4bc5f0 136
nexpaq 0:6c56fb4bc5f0 137 while( c < end && *(c + 1) == ' ' )
nexpaq 0:6c56fb4bc5f0 138 c++;
nexpaq 0:6c56fb4bc5f0 139
nexpaq 0:6c56fb4bc5f0 140 s = c + 1;
nexpaq 0:6c56fb4bc5f0 141 in_tag = 1;
nexpaq 0:6c56fb4bc5f0 142 }
nexpaq 0:6c56fb4bc5f0 143
nexpaq 0:6c56fb4bc5f0 144 if( !in_tag && s != c + 1 )
nexpaq 0:6c56fb4bc5f0 145 {
nexpaq 0:6c56fb4bc5f0 146 *(d++) = *c;
nexpaq 0:6c56fb4bc5f0 147
nexpaq 0:6c56fb4bc5f0 148 if( d - data == MBEDTLS_X509_MAX_DN_NAME_SIZE )
nexpaq 0:6c56fb4bc5f0 149 {
nexpaq 0:6c56fb4bc5f0 150 ret = MBEDTLS_ERR_X509_INVALID_NAME;
nexpaq 0:6c56fb4bc5f0 151 goto exit;
nexpaq 0:6c56fb4bc5f0 152 }
nexpaq 0:6c56fb4bc5f0 153 }
nexpaq 0:6c56fb4bc5f0 154
nexpaq 0:6c56fb4bc5f0 155 c++;
nexpaq 0:6c56fb4bc5f0 156 }
nexpaq 0:6c56fb4bc5f0 157
nexpaq 0:6c56fb4bc5f0 158 exit:
nexpaq 0:6c56fb4bc5f0 159
nexpaq 0:6c56fb4bc5f0 160 return( ret );
nexpaq 0:6c56fb4bc5f0 161 }
nexpaq 0:6c56fb4bc5f0 162
nexpaq 0:6c56fb4bc5f0 163 /* The first byte of the value in the mbedtls_asn1_named_data structure is reserved
nexpaq 0:6c56fb4bc5f0 164 * to store the critical boolean for us
nexpaq 0:6c56fb4bc5f0 165 */
nexpaq 0:6c56fb4bc5f0 166 int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
nexpaq 0:6c56fb4bc5f0 167 int critical, const unsigned char *val, size_t val_len )
nexpaq 0:6c56fb4bc5f0 168 {
nexpaq 0:6c56fb4bc5f0 169 mbedtls_asn1_named_data *cur;
nexpaq 0:6c56fb4bc5f0 170
nexpaq 0:6c56fb4bc5f0 171 if( ( cur = mbedtls_asn1_store_named_data( head, oid, oid_len,
nexpaq 0:6c56fb4bc5f0 172 NULL, val_len + 1 ) ) == NULL )
nexpaq 0:6c56fb4bc5f0 173 {
nexpaq 0:6c56fb4bc5f0 174 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
nexpaq 0:6c56fb4bc5f0 175 }
nexpaq 0:6c56fb4bc5f0 176
nexpaq 0:6c56fb4bc5f0 177 cur->val.p[0] = critical;
nexpaq 0:6c56fb4bc5f0 178 memcpy( cur->val.p + 1, val, val_len );
nexpaq 0:6c56fb4bc5f0 179
nexpaq 0:6c56fb4bc5f0 180 return( 0 );
nexpaq 0:6c56fb4bc5f0 181 }
nexpaq 0:6c56fb4bc5f0 182
nexpaq 0:6c56fb4bc5f0 183 /*
nexpaq 0:6c56fb4bc5f0 184 * RelativeDistinguishedName ::=
nexpaq 0:6c56fb4bc5f0 185 * SET OF AttributeTypeAndValue
nexpaq 0:6c56fb4bc5f0 186 *
nexpaq 0:6c56fb4bc5f0 187 * AttributeTypeAndValue ::= SEQUENCE {
nexpaq 0:6c56fb4bc5f0 188 * type AttributeType,
nexpaq 0:6c56fb4bc5f0 189 * value AttributeValue }
nexpaq 0:6c56fb4bc5f0 190 *
nexpaq 0:6c56fb4bc5f0 191 * AttributeType ::= OBJECT IDENTIFIER
nexpaq 0:6c56fb4bc5f0 192 *
nexpaq 0:6c56fb4bc5f0 193 * AttributeValue ::= ANY DEFINED BY AttributeType
nexpaq 0:6c56fb4bc5f0 194 */
nexpaq 0:6c56fb4bc5f0 195 static int x509_write_name( unsigned char **p, unsigned char *start,
nexpaq 0:6c56fb4bc5f0 196 const char *oid, size_t oid_len,
nexpaq 0:6c56fb4bc5f0 197 const unsigned char *name, size_t name_len )
nexpaq 0:6c56fb4bc5f0 198 {
nexpaq 0:6c56fb4bc5f0 199 int ret;
nexpaq 0:6c56fb4bc5f0 200 size_t len = 0;
nexpaq 0:6c56fb4bc5f0 201
nexpaq 0:6c56fb4bc5f0 202 // Write PrintableString for all except MBEDTLS_OID_PKCS9_EMAIL
nexpaq 0:6c56fb4bc5f0 203 //
nexpaq 0:6c56fb4bc5f0 204 if( MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_EMAIL ) == oid_len &&
nexpaq 0:6c56fb4bc5f0 205 memcmp( oid, MBEDTLS_OID_PKCS9_EMAIL, oid_len ) == 0 )
nexpaq 0:6c56fb4bc5f0 206 {
nexpaq 0:6c56fb4bc5f0 207 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_ia5_string( p, start,
nexpaq 0:6c56fb4bc5f0 208 (const char *) name,
nexpaq 0:6c56fb4bc5f0 209 name_len ) );
nexpaq 0:6c56fb4bc5f0 210 }
nexpaq 0:6c56fb4bc5f0 211 else
nexpaq 0:6c56fb4bc5f0 212 {
nexpaq 0:6c56fb4bc5f0 213 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_printable_string( p, start,
nexpaq 0:6c56fb4bc5f0 214 (const char *) name,
nexpaq 0:6c56fb4bc5f0 215 name_len ) );
nexpaq 0:6c56fb4bc5f0 216 }
nexpaq 0:6c56fb4bc5f0 217
nexpaq 0:6c56fb4bc5f0 218 // Write OID
nexpaq 0:6c56fb4bc5f0 219 //
nexpaq 0:6c56fb4bc5f0 220 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) );
nexpaq 0:6c56fb4bc5f0 221
nexpaq 0:6c56fb4bc5f0 222 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
nexpaq 0:6c56fb4bc5f0 223 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
nexpaq 0:6c56fb4bc5f0 224 MBEDTLS_ASN1_SEQUENCE ) );
nexpaq 0:6c56fb4bc5f0 225
nexpaq 0:6c56fb4bc5f0 226 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
nexpaq 0:6c56fb4bc5f0 227 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
nexpaq 0:6c56fb4bc5f0 228 MBEDTLS_ASN1_SET ) );
nexpaq 0:6c56fb4bc5f0 229
nexpaq 0:6c56fb4bc5f0 230 return( (int) len );
nexpaq 0:6c56fb4bc5f0 231 }
nexpaq 0:6c56fb4bc5f0 232
nexpaq 0:6c56fb4bc5f0 233 int mbedtls_x509_write_names( unsigned char **p, unsigned char *start,
nexpaq 0:6c56fb4bc5f0 234 mbedtls_asn1_named_data *first )
nexpaq 0:6c56fb4bc5f0 235 {
nexpaq 0:6c56fb4bc5f0 236 int ret;
nexpaq 0:6c56fb4bc5f0 237 size_t len = 0;
nexpaq 0:6c56fb4bc5f0 238 mbedtls_asn1_named_data *cur = first;
nexpaq 0:6c56fb4bc5f0 239
nexpaq 0:6c56fb4bc5f0 240 while( cur != NULL )
nexpaq 0:6c56fb4bc5f0 241 {
nexpaq 0:6c56fb4bc5f0 242 MBEDTLS_ASN1_CHK_ADD( len, x509_write_name( p, start, (char *) cur->oid.p,
nexpaq 0:6c56fb4bc5f0 243 cur->oid.len,
nexpaq 0:6c56fb4bc5f0 244 cur->val.p, cur->val.len ) );
nexpaq 0:6c56fb4bc5f0 245 cur = cur->next;
nexpaq 0:6c56fb4bc5f0 246 }
nexpaq 0:6c56fb4bc5f0 247
nexpaq 0:6c56fb4bc5f0 248 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
nexpaq 0:6c56fb4bc5f0 249 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
nexpaq 0:6c56fb4bc5f0 250 MBEDTLS_ASN1_SEQUENCE ) );
nexpaq 0:6c56fb4bc5f0 251
nexpaq 0:6c56fb4bc5f0 252 return( (int) len );
nexpaq 0:6c56fb4bc5f0 253 }
nexpaq 0:6c56fb4bc5f0 254
nexpaq 0:6c56fb4bc5f0 255 int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
nexpaq 0:6c56fb4bc5f0 256 const char *oid, size_t oid_len,
nexpaq 0:6c56fb4bc5f0 257 unsigned char *sig, size_t size )
nexpaq 0:6c56fb4bc5f0 258 {
nexpaq 0:6c56fb4bc5f0 259 int ret;
nexpaq 0:6c56fb4bc5f0 260 size_t len = 0;
nexpaq 0:6c56fb4bc5f0 261
nexpaq 0:6c56fb4bc5f0 262 if( *p < start || (size_t)( *p - start ) < size )
nexpaq 0:6c56fb4bc5f0 263 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
nexpaq 0:6c56fb4bc5f0 264
nexpaq 0:6c56fb4bc5f0 265 len = size;
nexpaq 0:6c56fb4bc5f0 266 (*p) -= len;
nexpaq 0:6c56fb4bc5f0 267 memcpy( *p, sig, len );
nexpaq 0:6c56fb4bc5f0 268
nexpaq 0:6c56fb4bc5f0 269 if( *p - start < 1 )
nexpaq 0:6c56fb4bc5f0 270 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
nexpaq 0:6c56fb4bc5f0 271
nexpaq 0:6c56fb4bc5f0 272 *--(*p) = 0;
nexpaq 0:6c56fb4bc5f0 273 len += 1;
nexpaq 0:6c56fb4bc5f0 274
nexpaq 0:6c56fb4bc5f0 275 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
nexpaq 0:6c56fb4bc5f0 276 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) );
nexpaq 0:6c56fb4bc5f0 277
nexpaq 0:6c56fb4bc5f0 278 // Write OID
nexpaq 0:6c56fb4bc5f0 279 //
nexpaq 0:6c56fb4bc5f0 280 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( p, start, oid,
nexpaq 0:6c56fb4bc5f0 281 oid_len, 0 ) );
nexpaq 0:6c56fb4bc5f0 282
nexpaq 0:6c56fb4bc5f0 283 return( (int) len );
nexpaq 0:6c56fb4bc5f0 284 }
nexpaq 0:6c56fb4bc5f0 285
nexpaq 0:6c56fb4bc5f0 286 static int x509_write_extension( unsigned char **p, unsigned char *start,
nexpaq 0:6c56fb4bc5f0 287 mbedtls_asn1_named_data *ext )
nexpaq 0:6c56fb4bc5f0 288 {
nexpaq 0:6c56fb4bc5f0 289 int ret;
nexpaq 0:6c56fb4bc5f0 290 size_t len = 0;
nexpaq 0:6c56fb4bc5f0 291
nexpaq 0:6c56fb4bc5f0 292 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->val.p + 1,
nexpaq 0:6c56fb4bc5f0 293 ext->val.len - 1 ) );
nexpaq 0:6c56fb4bc5f0 294 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->val.len - 1 ) );
nexpaq 0:6c56fb4bc5f0 295 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) );
nexpaq 0:6c56fb4bc5f0 296
nexpaq 0:6c56fb4bc5f0 297 if( ext->val.p[0] != 0 )
nexpaq 0:6c56fb4bc5f0 298 {
nexpaq 0:6c56fb4bc5f0 299 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( p, start, 1 ) );
nexpaq 0:6c56fb4bc5f0 300 }
nexpaq 0:6c56fb4bc5f0 301
nexpaq 0:6c56fb4bc5f0 302 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->oid.p,
nexpaq 0:6c56fb4bc5f0 303 ext->oid.len ) );
nexpaq 0:6c56fb4bc5f0 304 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->oid.len ) );
nexpaq 0:6c56fb4bc5f0 305 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) );
nexpaq 0:6c56fb4bc5f0 306
nexpaq 0:6c56fb4bc5f0 307 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
nexpaq 0:6c56fb4bc5f0 308 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
nexpaq 0:6c56fb4bc5f0 309 MBEDTLS_ASN1_SEQUENCE ) );
nexpaq 0:6c56fb4bc5f0 310
nexpaq 0:6c56fb4bc5f0 311 return( (int) len );
nexpaq 0:6c56fb4bc5f0 312 }
nexpaq 0:6c56fb4bc5f0 313
nexpaq 0:6c56fb4bc5f0 314 /*
nexpaq 0:6c56fb4bc5f0 315 * Extension ::= SEQUENCE {
nexpaq 0:6c56fb4bc5f0 316 * extnID OBJECT IDENTIFIER,
nexpaq 0:6c56fb4bc5f0 317 * critical BOOLEAN DEFAULT FALSE,
nexpaq 0:6c56fb4bc5f0 318 * extnValue OCTET STRING
nexpaq 0:6c56fb4bc5f0 319 * -- contains the DER encoding of an ASN.1 value
nexpaq 0:6c56fb4bc5f0 320 * -- corresponding to the extension type identified
nexpaq 0:6c56fb4bc5f0 321 * -- by extnID
nexpaq 0:6c56fb4bc5f0 322 * }
nexpaq 0:6c56fb4bc5f0 323 */
nexpaq 0:6c56fb4bc5f0 324 int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
nexpaq 0:6c56fb4bc5f0 325 mbedtls_asn1_named_data *first )
nexpaq 0:6c56fb4bc5f0 326 {
nexpaq 0:6c56fb4bc5f0 327 int ret;
nexpaq 0:6c56fb4bc5f0 328 size_t len = 0;
nexpaq 0:6c56fb4bc5f0 329 mbedtls_asn1_named_data *cur_ext = first;
nexpaq 0:6c56fb4bc5f0 330
nexpaq 0:6c56fb4bc5f0 331 while( cur_ext != NULL )
nexpaq 0:6c56fb4bc5f0 332 {
nexpaq 0:6c56fb4bc5f0 333 MBEDTLS_ASN1_CHK_ADD( len, x509_write_extension( p, start, cur_ext ) );
nexpaq 0:6c56fb4bc5f0 334 cur_ext = cur_ext->next;
nexpaq 0:6c56fb4bc5f0 335 }
nexpaq 0:6c56fb4bc5f0 336
nexpaq 0:6c56fb4bc5f0 337 return( (int) len );
nexpaq 0:6c56fb4bc5f0 338 }
nexpaq 0:6c56fb4bc5f0 339
nexpaq 0:6c56fb4bc5f0 340 #endif /* MBEDTLS_X509_CREATE_C */