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
x509_create.c
00001 /* 00002 * X.509 base functions for creating certificates / CSRs 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_X509_CREATE_C) 00029 00030 #include "mbedtls/x509.h" 00031 #include "mbedtls/asn1write.h" 00032 #include "mbedtls/oid.h" 00033 00034 #include <string.h> 00035 00036 typedef struct { 00037 const char *name; 00038 size_t name_len; 00039 const char*oid; 00040 } x509_attr_descriptor_t; 00041 00042 #define ADD_STRLEN( s ) s, sizeof( s ) - 1 00043 00044 static const x509_attr_descriptor_t x509_attrs[] = 00045 { 00046 { ADD_STRLEN( "CN" ), MBEDTLS_OID_AT_CN }, 00047 { ADD_STRLEN( "commonName" ), MBEDTLS_OID_AT_CN }, 00048 { ADD_STRLEN( "C" ), MBEDTLS_OID_AT_COUNTRY }, 00049 { ADD_STRLEN( "countryName" ), MBEDTLS_OID_AT_COUNTRY }, 00050 { ADD_STRLEN( "O" ), MBEDTLS_OID_AT_ORGANIZATION }, 00051 { ADD_STRLEN( "organizationName" ), MBEDTLS_OID_AT_ORGANIZATION }, 00052 { ADD_STRLEN( "L" ), MBEDTLS_OID_AT_LOCALITY }, 00053 { ADD_STRLEN( "locality" ), MBEDTLS_OID_AT_LOCALITY }, 00054 { ADD_STRLEN( "R" ), MBEDTLS_OID_PKCS9_EMAIL }, 00055 { ADD_STRLEN( "OU" ), MBEDTLS_OID_AT_ORG_UNIT }, 00056 { ADD_STRLEN( "organizationalUnitName" ), MBEDTLS_OID_AT_ORG_UNIT }, 00057 { ADD_STRLEN( "ST" ), MBEDTLS_OID_AT_STATE }, 00058 { ADD_STRLEN( "stateOrProvinceName" ), MBEDTLS_OID_AT_STATE }, 00059 { ADD_STRLEN( "emailAddress" ), MBEDTLS_OID_PKCS9_EMAIL }, 00060 { ADD_STRLEN( "serialNumber" ), MBEDTLS_OID_AT_SERIAL_NUMBER }, 00061 { ADD_STRLEN( "postalAddress" ), MBEDTLS_OID_AT_POSTAL_ADDRESS }, 00062 { ADD_STRLEN( "postalCode" ), MBEDTLS_OID_AT_POSTAL_CODE }, 00063 { ADD_STRLEN( "dnQualifier" ), MBEDTLS_OID_AT_DN_QUALIFIER }, 00064 { ADD_STRLEN( "title" ), MBEDTLS_OID_AT_TITLE }, 00065 { ADD_STRLEN( "surName" ), MBEDTLS_OID_AT_SUR_NAME }, 00066 { ADD_STRLEN( "SN" ), MBEDTLS_OID_AT_SUR_NAME }, 00067 { ADD_STRLEN( "givenName" ), MBEDTLS_OID_AT_GIVEN_NAME }, 00068 { ADD_STRLEN( "GN" ), MBEDTLS_OID_AT_GIVEN_NAME }, 00069 { ADD_STRLEN( "initials" ), MBEDTLS_OID_AT_INITIALS }, 00070 { ADD_STRLEN( "pseudonym" ), MBEDTLS_OID_AT_PSEUDONYM }, 00071 { ADD_STRLEN( "generationQualifier" ), MBEDTLS_OID_AT_GENERATION_QUALIFIER }, 00072 { ADD_STRLEN( "domainComponent" ), MBEDTLS_OID_DOMAIN_COMPONENT }, 00073 { ADD_STRLEN( "DC" ), MBEDTLS_OID_DOMAIN_COMPONENT }, 00074 { NULL, 0, NULL } 00075 }; 00076 00077 static const char *x509_at_oid_from_name( const char *name, size_t name_len ) 00078 { 00079 const x509_attr_descriptor_t *cur; 00080 00081 for( cur = x509_attrs; cur->name != NULL; cur++ ) 00082 if( cur->name_len == name_len && 00083 strncmp( cur->name, name, name_len ) == 0 ) 00084 break; 00085 00086 return( cur->oid ); 00087 } 00088 00089 int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name ) 00090 { 00091 int ret = 0; 00092 const char *s = name, *c = s; 00093 const char *end = s + strlen( s ); 00094 const char *oid = NULL; 00095 int in_tag = 1; 00096 char data[MBEDTLS_X509_MAX_DN_NAME_SIZE]; 00097 char *d = data; 00098 00099 /* Clear existing chain if present */ 00100 mbedtls_asn1_free_named_data_list( head ); 00101 00102 while( c <= end ) 00103 { 00104 if( in_tag && *c == '=' ) 00105 { 00106 if( ( oid = x509_at_oid_from_name( s, c - s ) ) == NULL ) 00107 { 00108 ret = MBEDTLS_ERR_X509_UNKNOWN_OID; 00109 goto exit; 00110 } 00111 00112 s = c + 1; 00113 in_tag = 0; 00114 d = data; 00115 } 00116 00117 if( !in_tag && *c == '\\' && c != end ) 00118 { 00119 c++; 00120 00121 /* Check for valid escaped characters */ 00122 if( c == end || *c != ',' ) 00123 { 00124 ret = MBEDTLS_ERR_X509_INVALID_NAME; 00125 goto exit; 00126 } 00127 } 00128 else if( !in_tag && ( *c == ',' || c == end ) ) 00129 { 00130 if( mbedtls_asn1_store_named_data( head, oid, strlen( oid ), 00131 (unsigned char *) data, 00132 d - data ) == NULL ) 00133 { 00134 return( MBEDTLS_ERR_X509_ALLOC_FAILED ); 00135 } 00136 00137 while( c < end && *(c + 1) == ' ' ) 00138 c++; 00139 00140 s = c + 1; 00141 in_tag = 1; 00142 } 00143 00144 if( !in_tag && s != c + 1 ) 00145 { 00146 *(d++) = *c; 00147 00148 if( d - data == MBEDTLS_X509_MAX_DN_NAME_SIZE ) 00149 { 00150 ret = MBEDTLS_ERR_X509_INVALID_NAME; 00151 goto exit; 00152 } 00153 } 00154 00155 c++; 00156 } 00157 00158 exit: 00159 00160 return( ret ); 00161 } 00162 00163 /* The first byte of the value in the mbedtls_asn1_named_data structure is reserved 00164 * to store the critical boolean for us 00165 */ 00166 int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, 00167 int critical, const unsigned char *val, size_t val_len ) 00168 { 00169 mbedtls_asn1_named_data *cur; 00170 00171 if( ( cur = mbedtls_asn1_store_named_data( head, oid, oid_len, 00172 NULL, val_len + 1 ) ) == NULL ) 00173 { 00174 return( MBEDTLS_ERR_X509_ALLOC_FAILED ); 00175 } 00176 00177 cur->val.p[0] = critical; 00178 memcpy( cur->val.p + 1, val, val_len ); 00179 00180 return( 0 ); 00181 } 00182 00183 /* 00184 * RelativeDistinguishedName ::= 00185 * SET OF AttributeTypeAndValue 00186 * 00187 * AttributeTypeAndValue ::= SEQUENCE { 00188 * type AttributeType, 00189 * value AttributeValue } 00190 * 00191 * AttributeType ::= OBJECT IDENTIFIER 00192 * 00193 * AttributeValue ::= ANY DEFINED BY AttributeType 00194 */ 00195 static int x509_write_name( unsigned char **p, unsigned char *start, 00196 const char *oid, size_t oid_len, 00197 const unsigned char *name, size_t name_len ) 00198 { 00199 int ret; 00200 size_t len = 0; 00201 00202 // Write PrintableString for all except MBEDTLS_OID_PKCS9_EMAIL 00203 // 00204 if( MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_EMAIL ) == oid_len && 00205 memcmp( oid, MBEDTLS_OID_PKCS9_EMAIL, oid_len ) == 0 ) 00206 { 00207 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_ia5_string( p, start, 00208 (const char *) name, 00209 name_len ) ); 00210 } 00211 else 00212 { 00213 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_printable_string( p, start, 00214 (const char *) name, 00215 name_len ) ); 00216 } 00217 00218 // Write OID 00219 // 00220 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); 00221 00222 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00223 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | 00224 MBEDTLS_ASN1_SEQUENCE ) ); 00225 00226 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00227 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | 00228 MBEDTLS_ASN1_SET ) ); 00229 00230 return( (int) len ); 00231 } 00232 00233 int mbedtls_x509_write_names( unsigned char **p, unsigned char *start, 00234 mbedtls_asn1_named_data *first ) 00235 { 00236 int ret; 00237 size_t len = 0; 00238 mbedtls_asn1_named_data *cur = first; 00239 00240 while( cur != NULL ) 00241 { 00242 MBEDTLS_ASN1_CHK_ADD( len, x509_write_name( p, start, (char *) cur->oid.p, 00243 cur->oid.len, 00244 cur->val.p, cur->val.len ) ); 00245 cur = cur->next; 00246 } 00247 00248 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00249 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | 00250 MBEDTLS_ASN1_SEQUENCE ) ); 00251 00252 return( (int) len ); 00253 } 00254 00255 int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start, 00256 const char *oid, size_t oid_len, 00257 unsigned char *sig, size_t size ) 00258 { 00259 int ret; 00260 size_t len = 0; 00261 00262 if( *p < start || (size_t)( *p - start ) < size ) 00263 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00264 00265 len = size; 00266 (*p) -= len; 00267 memcpy( *p, sig, len ); 00268 00269 if( *p - start < 1 ) 00270 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00271 00272 *--(*p) = 0; 00273 len += 1; 00274 00275 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00276 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) ); 00277 00278 // Write OID 00279 // 00280 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( p, start, oid, 00281 oid_len, 0 ) ); 00282 00283 return( (int) len ); 00284 } 00285 00286 static int x509_write_extension( unsigned char **p, unsigned char *start, 00287 mbedtls_asn1_named_data *ext ) 00288 { 00289 int ret; 00290 size_t len = 0; 00291 00292 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->val.p + 1, 00293 ext->val.len - 1 ) ); 00294 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->val.len - 1 ) ); 00295 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) ); 00296 00297 if( ext->val.p[0] != 0 ) 00298 { 00299 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( p, start, 1 ) ); 00300 } 00301 00302 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->oid.p, 00303 ext->oid.len ) ); 00304 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->oid.len ) ); 00305 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) ); 00306 00307 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00308 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | 00309 MBEDTLS_ASN1_SEQUENCE ) ); 00310 00311 return( (int) len ); 00312 } 00313 00314 /* 00315 * Extension ::= SEQUENCE { 00316 * extnID OBJECT IDENTIFIER, 00317 * critical BOOLEAN DEFAULT FALSE, 00318 * extnValue OCTET STRING 00319 * -- contains the DER encoding of an ASN.1 value 00320 * -- corresponding to the extension type identified 00321 * -- by extnID 00322 * } 00323 */ 00324 int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start, 00325 mbedtls_asn1_named_data *first ) 00326 { 00327 int ret; 00328 size_t len = 0; 00329 mbedtls_asn1_named_data *cur_ext = first; 00330 00331 while( cur_ext != NULL ) 00332 { 00333 MBEDTLS_ASN1_CHK_ADD( len, x509_write_extension( p, start, cur_ext ) ); 00334 cur_ext = cur_ext->next; 00335 } 00336 00337 return( (int) len ); 00338 } 00339 00340 #endif /* MBEDTLS_X509_CREATE_C */
Generated on Tue Jul 12 2022 17:25:43 by
