mbed TLS library
Dependents: HTTPClient-SSL WS_SERVER
x509_create.c
00001 /* 00002 * X.509 base functions for creating certificates / CSRs 00003 * 00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved 00005 * 00006 * This file is part of mbed TLS (https://tls.mbed.org) 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License along 00019 * with this program; if not, write to the Free Software Foundation, Inc., 00020 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00021 */ 00022 00023 #if !defined(POLARSSL_CONFIG_FILE) 00024 #include "polarssl/config.h" 00025 #else 00026 #include POLARSSL_CONFIG_FILE 00027 #endif 00028 00029 #if defined(POLARSSL_X509_CREATE_C) 00030 00031 #include "polarssl/x509.h" 00032 #include "polarssl/asn1write.h" 00033 #include "polarssl/oid.h" 00034 00035 #include <string.h> 00036 00037 #if defined(_MSC_VER) && !defined strncasecmp && !defined(EFIX64) && \ 00038 !defined(EFI32) 00039 #define strncasecmp _strnicmp 00040 #endif 00041 00042 typedef struct { 00043 const char *name; 00044 size_t name_len; 00045 const char*oid; 00046 } x509_attr_descriptor_t; 00047 00048 #define ADD_STRLEN( s ) s, sizeof( s ) - 1 00049 00050 static const x509_attr_descriptor_t x509_attrs[] = 00051 { 00052 { ADD_STRLEN( "CN" ), OID_AT_CN }, 00053 { ADD_STRLEN( "commonName" ), OID_AT_CN }, 00054 { ADD_STRLEN( "C" ), OID_AT_COUNTRY }, 00055 { ADD_STRLEN( "countryName" ), OID_AT_COUNTRY }, 00056 { ADD_STRLEN( "O" ), OID_AT_ORGANIZATION }, 00057 { ADD_STRLEN( "organizationName" ), OID_AT_ORGANIZATION }, 00058 { ADD_STRLEN( "L" ), OID_AT_LOCALITY }, 00059 { ADD_STRLEN( "locality" ), OID_AT_LOCALITY }, 00060 { ADD_STRLEN( "R" ), OID_PKCS9_EMAIL }, 00061 { ADD_STRLEN( "OU" ), OID_AT_ORG_UNIT }, 00062 { ADD_STRLEN( "organizationalUnitName" ), OID_AT_ORG_UNIT }, 00063 { ADD_STRLEN( "ST" ), OID_AT_STATE }, 00064 { ADD_STRLEN( "stateOrProvinceName" ), OID_AT_STATE }, 00065 { ADD_STRLEN( "emailAddress" ), OID_PKCS9_EMAIL }, 00066 { ADD_STRLEN( "serialNumber" ), OID_AT_SERIAL_NUMBER }, 00067 { ADD_STRLEN( "postalAddress" ), OID_AT_POSTAL_ADDRESS }, 00068 { ADD_STRLEN( "postalCode" ), OID_AT_POSTAL_CODE }, 00069 { ADD_STRLEN( "dnQualifier" ), OID_AT_DN_QUALIFIER }, 00070 { ADD_STRLEN( "title" ), OID_AT_TITLE }, 00071 { ADD_STRLEN( "surName" ), OID_AT_SUR_NAME }, 00072 { ADD_STRLEN( "SN" ), OID_AT_SUR_NAME }, 00073 { ADD_STRLEN( "givenName" ), OID_AT_GIVEN_NAME }, 00074 { ADD_STRLEN( "GN" ), OID_AT_GIVEN_NAME }, 00075 { ADD_STRLEN( "initials" ), OID_AT_INITIALS }, 00076 { ADD_STRLEN( "pseudonym" ), OID_AT_PSEUDONYM }, 00077 { ADD_STRLEN( "generationQualifier" ), OID_AT_GENERATION_QUALIFIER }, 00078 { ADD_STRLEN( "domainComponent" ), OID_DOMAIN_COMPONENT }, 00079 { ADD_STRLEN( "DC" ), OID_DOMAIN_COMPONENT }, 00080 { NULL, 0, NULL } 00081 }; 00082 00083 static const char *x509_at_oid_from_name( const char *name, size_t name_len ) 00084 { 00085 const x509_attr_descriptor_t *cur; 00086 00087 for( cur = x509_attrs; cur->name != NULL; cur++ ) 00088 if( cur->name_len == name_len && 00089 strncasecmp( cur->name, name, name_len ) == 0 ) 00090 break; 00091 00092 return( cur->oid ); 00093 } 00094 00095 int x509_string_to_names( asn1_named_data **head, const char *name ) 00096 { 00097 int ret = 0; 00098 const char *s = name, *c = s; 00099 const char *end = s + strlen( s ); 00100 const char *oid = NULL; 00101 int in_tag = 1; 00102 char data[X509_MAX_DN_NAME_SIZE]; 00103 char *d = data; 00104 00105 /* Clear existing chain if present */ 00106 asn1_free_named_data_list( head ); 00107 00108 while( c <= end ) 00109 { 00110 if( in_tag && *c == '=' ) 00111 { 00112 if( ( oid = x509_at_oid_from_name( s, c - s ) ) == NULL ) 00113 { 00114 ret = POLARSSL_ERR_X509_UNKNOWN_OID; 00115 goto exit; 00116 } 00117 00118 s = c + 1; 00119 in_tag = 0; 00120 d = data; 00121 } 00122 00123 if( !in_tag && *c == '\\' && c != end ) 00124 { 00125 c++; 00126 00127 /* Check for valid escaped characters */ 00128 if( c == end || *c != ',' ) 00129 { 00130 ret = POLARSSL_ERR_X509_INVALID_NAME; 00131 goto exit; 00132 } 00133 } 00134 else if( !in_tag && ( *c == ',' || c == end ) ) 00135 { 00136 if( asn1_store_named_data( head, oid, strlen( oid ), 00137 (unsigned char *) data, 00138 d - data ) == NULL ) 00139 { 00140 return( POLARSSL_ERR_X509_MALLOC_FAILED ); 00141 } 00142 00143 while( c < end && *(c + 1) == ' ' ) 00144 c++; 00145 00146 s = c + 1; 00147 in_tag = 1; 00148 } 00149 00150 if( !in_tag && s != c + 1 ) 00151 { 00152 *(d++) = *c; 00153 00154 if( d - data == X509_MAX_DN_NAME_SIZE ) 00155 { 00156 ret = POLARSSL_ERR_X509_INVALID_NAME; 00157 goto exit; 00158 } 00159 } 00160 00161 c++; 00162 } 00163 00164 exit: 00165 00166 return( ret ); 00167 } 00168 00169 /* The first byte of the value in the asn1_named_data structure is reserved 00170 * to store the critical boolean for us 00171 */ 00172 int x509_set_extension( asn1_named_data **head, const char *oid, size_t oid_len, 00173 int critical, const unsigned char *val, size_t val_len ) 00174 { 00175 asn1_named_data *cur; 00176 00177 if( ( cur = asn1_store_named_data( head, oid, oid_len, 00178 NULL, val_len + 1 ) ) == NULL ) 00179 { 00180 return( POLARSSL_ERR_X509_MALLOC_FAILED ); 00181 } 00182 00183 cur->val.p[0] = critical; 00184 memcpy( cur->val.p + 1, val, val_len ); 00185 00186 return( 0 ); 00187 } 00188 00189 /* 00190 * RelativeDistinguishedName ::= 00191 * SET OF AttributeTypeAndValue 00192 * 00193 * AttributeTypeAndValue ::= SEQUENCE { 00194 * type AttributeType, 00195 * value AttributeValue } 00196 * 00197 * AttributeType ::= OBJECT IDENTIFIER 00198 * 00199 * AttributeValue ::= ANY DEFINED BY AttributeType 00200 */ 00201 static int x509_write_name( unsigned char **p, unsigned char *start, 00202 const char *oid, size_t oid_len, 00203 const unsigned char *name, size_t name_len ) 00204 { 00205 int ret; 00206 size_t len = 0; 00207 00208 // Write PrintableString for all except OID_PKCS9_EMAIL 00209 // 00210 if( OID_SIZE( OID_PKCS9_EMAIL ) == oid_len && 00211 memcmp( oid, OID_PKCS9_EMAIL, oid_len ) == 0 ) 00212 { 00213 ASN1_CHK_ADD( len, asn1_write_ia5_string( p, start, 00214 (const char *) name, 00215 name_len ) ); 00216 } 00217 else 00218 { 00219 ASN1_CHK_ADD( len, asn1_write_printable_string( p, start, 00220 (const char *) name, 00221 name_len ) ); 00222 } 00223 00224 // Write OID 00225 // 00226 ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) ); 00227 00228 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); 00229 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | 00230 ASN1_SEQUENCE ) ); 00231 00232 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); 00233 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | 00234 ASN1_SET ) ); 00235 00236 return( (int) len ); 00237 } 00238 00239 int x509_write_names( unsigned char **p, unsigned char *start, 00240 asn1_named_data *first ) 00241 { 00242 int ret; 00243 size_t len = 0; 00244 asn1_named_data *cur = first; 00245 00246 while( cur != NULL ) 00247 { 00248 ASN1_CHK_ADD( len, x509_write_name( p, start, (char *) cur->oid.p, 00249 cur->oid.len, 00250 cur->val.p, cur->val.len ) ); 00251 cur = cur->next; 00252 } 00253 00254 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); 00255 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | 00256 ASN1_SEQUENCE ) ); 00257 00258 return( (int) len ); 00259 } 00260 00261 int x509_write_sig( unsigned char **p, unsigned char *start, 00262 const char *oid, size_t oid_len, 00263 unsigned char *sig, size_t size ) 00264 { 00265 int ret; 00266 size_t len = 0; 00267 00268 if( *p - start < (int) size + 1 ) 00269 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00270 00271 len = size; 00272 (*p) -= len; 00273 memcpy( *p, sig, len ); 00274 00275 *--(*p) = 0; 00276 len += 1; 00277 00278 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); 00279 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) ); 00280 00281 // Write OID 00282 // 00283 ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( p, start, oid, 00284 oid_len, 0 ) ); 00285 00286 return( (int) len ); 00287 } 00288 00289 static int x509_write_extension( unsigned char **p, unsigned char *start, 00290 asn1_named_data *ext ) 00291 { 00292 int ret; 00293 size_t len = 0; 00294 00295 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, ext->val.p + 1, 00296 ext->val.len - 1 ) ); 00297 ASN1_CHK_ADD( len, asn1_write_len( p, start, ext->val.len - 1 ) ); 00298 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OCTET_STRING ) ); 00299 00300 if( ext->val.p[0] != 0 ) 00301 { 00302 ASN1_CHK_ADD( len, asn1_write_bool( p, start, 1 ) ); 00303 } 00304 00305 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, ext->oid.p, 00306 ext->oid.len ) ); 00307 ASN1_CHK_ADD( len, asn1_write_len( p, start, ext->oid.len ) ); 00308 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OID ) ); 00309 00310 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); 00311 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | 00312 ASN1_SEQUENCE ) ); 00313 00314 return( (int) len ); 00315 } 00316 00317 /* 00318 * Extension ::= SEQUENCE { 00319 * extnID OBJECT IDENTIFIER, 00320 * critical BOOLEAN DEFAULT FALSE, 00321 * extnValue OCTET STRING 00322 * -- contains the DER encoding of an ASN.1 value 00323 * -- corresponding to the extension type identified 00324 * -- by extnID 00325 * } 00326 */ 00327 int x509_write_extensions( unsigned char **p, unsigned char *start, 00328 asn1_named_data *first ) 00329 { 00330 int ret; 00331 size_t len = 0; 00332 asn1_named_data *cur_ext = first; 00333 00334 while( cur_ext != NULL ) 00335 { 00336 ASN1_CHK_ADD( len, x509_write_extension( p, start, cur_ext ) ); 00337 cur_ext = cur_ext->next; 00338 } 00339 00340 return( (int) len ); 00341 } 00342 00343 #endif /* POLARSSL_X509_CREATE_C */ 00344
Generated on Tue Jul 12 2022 13:50:39 by 1.7.2