00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "polarssl/config.h"
00027
00028 #if defined(POLARSSL_X509_CREATE_C)
00029
00030 #include "polarssl/x509.h"
00031 #include "polarssl/asn1write.h"
00032 #include "polarssl/oid.h"
00033
00034 #if defined(_MSC_VER) && !defined strncasecmp && !defined(EFIX64) && \
00035 !defined(EFI32)
00036 #define strncasecmp _strnicmp
00037 #endif
00038
00039 int x509_string_to_names( asn1_named_data **head, const char *name )
00040 {
00041 int ret = 0;
00042 const char *s = name, *c = s;
00043 const char *end = s + strlen( s );
00044 const char *oid = NULL;
00045 int in_tag = 1;
00046 asn1_named_data *cur;
00047
00048
00049 asn1_free_named_data_list( head );
00050
00051 while( c <= end )
00052 {
00053 if( in_tag && *c == '=' )
00054 {
00055 if( c - s == 2 && strncasecmp( s, "CN", 2 ) == 0 )
00056 oid = OID_AT_CN;
00057 else if( c - s == 1 && strncasecmp( s, "C", 1 ) == 0 )
00058 oid = OID_AT_COUNTRY;
00059 else if( c - s == 1 && strncasecmp( s, "O", 1 ) == 0 )
00060 oid = OID_AT_ORGANIZATION;
00061 else if( c - s == 1 && strncasecmp( s, "L", 1 ) == 0 )
00062 oid = OID_AT_LOCALITY;
00063 else if( c - s == 1 && strncasecmp( s, "R", 1 ) == 0 )
00064 oid = OID_PKCS9_EMAIL;
00065 else if( c - s == 2 && strncasecmp( s, "OU", 2 ) == 0 )
00066 oid = OID_AT_ORG_UNIT;
00067 else if( c - s == 2 && strncasecmp( s, "ST", 2 ) == 0 )
00068 oid = OID_AT_STATE;
00069 else if( c - s == 12 && strncasecmp( s, "serialNumber", 12 ) == 0 )
00070 oid = OID_AT_SERIAL_NUMBER;
00071 else if( c - s == 13 && strncasecmp( s, "postalAddress", 13 ) == 0 )
00072 oid = OID_AT_POSTAL_ADDRESS;
00073 else if( c - s == 10 && strncasecmp( s, "postalCode", 10 ) == 0 )
00074 oid = OID_AT_POSTAL_CODE;
00075 else
00076 {
00077 ret = POLARSSL_ERR_X509_UNKNOWN_OID;
00078 goto exit;
00079 }
00080
00081 s = c + 1;
00082 in_tag = 0;
00083 }
00084
00085 if( !in_tag && ( *c == ',' || c == end ) )
00086 {
00087 if( ( cur = asn1_store_named_data( head, oid, strlen( oid ),
00088 (unsigned char *) s,
00089 c - s ) ) == NULL )
00090 {
00091 return( POLARSSL_ERR_X509_MALLOC_FAILED );
00092 }
00093
00094 while( c < end && *(c + 1) == ' ' )
00095 c++;
00096
00097 s = c + 1;
00098 in_tag = 1;
00099 }
00100 c++;
00101 }
00102
00103 exit:
00104
00105 return( ret );
00106 }
00107
00108
00109
00110
00111 int x509_set_extension( asn1_named_data **head, const char *oid, size_t oid_len,
00112 int critical, const unsigned char *val, size_t val_len )
00113 {
00114 asn1_named_data *cur;
00115
00116 if( ( cur = asn1_store_named_data( head, oid, oid_len,
00117 NULL, val_len + 1 ) ) == NULL )
00118 {
00119 return( POLARSSL_ERR_X509_MALLOC_FAILED );
00120 }
00121
00122 cur->val.p[0] = critical;
00123 memcpy( cur->val.p + 1, val, val_len );
00124
00125 return( 0 );
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 static int x509_write_name( unsigned char **p, unsigned char *start,
00141 const char *oid, size_t oid_len,
00142 const unsigned char *name, size_t name_len )
00143 {
00144 int ret;
00145 size_t len = 0;
00146
00147
00148
00149 if( OID_SIZE( OID_PKCS9_EMAIL ) == oid_len &&
00150 memcmp( oid, OID_PKCS9_EMAIL, oid_len ) == 0 )
00151 {
00152 ASN1_CHK_ADD( len, asn1_write_ia5_string( p, start,
00153 (const char *) name,
00154 name_len ) );
00155 }
00156 else
00157 {
00158 ASN1_CHK_ADD( len, asn1_write_printable_string( p, start,
00159 (const char *) name,
00160 name_len ) );
00161 }
00162
00163
00164
00165 ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) );
00166
00167 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
00168 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00169
00170 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
00171 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SET ) );
00172
00173 return( (int) len );
00174 }
00175
00176 int x509_write_names( unsigned char **p, unsigned char *start,
00177 asn1_named_data *first )
00178 {
00179 int ret;
00180 size_t len = 0;
00181 asn1_named_data *cur = first;
00182
00183 while( cur != NULL )
00184 {
00185 ASN1_CHK_ADD( len, x509_write_name( p, start, (char *) cur->oid.p,
00186 cur->oid.len,
00187 cur->val.p, cur->val.len ) );
00188 cur = cur->next;
00189 }
00190
00191 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
00192 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00193
00194 return( (int) len );
00195 }
00196
00197 int x509_write_sig( unsigned char **p, unsigned char *start,
00198 const char *oid, size_t oid_len,
00199 unsigned char *sig, size_t size )
00200 {
00201 int ret;
00202 size_t len = 0;
00203
00204 if( *p - start < (int) size + 1 )
00205 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
00206
00207 len = size;
00208 (*p) -= len;
00209 memcpy( *p, sig, len );
00210
00211 *--(*p) = 0;
00212 len += 1;
00213
00214 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
00215 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) );
00216
00217
00218
00219 ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( p, start, oid,
00220 oid_len, 0 ) );
00221
00222 return( (int) len );
00223 }
00224
00225 static int x509_write_extension( unsigned char **p, unsigned char *start,
00226 asn1_named_data *ext )
00227 {
00228 int ret;
00229 size_t len = 0;
00230
00231 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, ext->val.p + 1,
00232 ext->val.len - 1 ) );
00233 ASN1_CHK_ADD( len, asn1_write_len( p, start, ext->val.len - 1 ) );
00234 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OCTET_STRING ) );
00235
00236 if( ext->val.p[0] != 0 )
00237 {
00238 ASN1_CHK_ADD( len, asn1_write_bool( p, start, 1 ) );
00239 }
00240
00241 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, ext->oid.p,
00242 ext->oid.len ) );
00243 ASN1_CHK_ADD( len, asn1_write_len( p, start, ext->oid.len ) );
00244 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OID ) );
00245
00246 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
00247 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00248
00249 return( (int) len );
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 int x509_write_extensions( unsigned char **p, unsigned char *start,
00263 asn1_named_data *first )
00264 {
00265 int ret;
00266 size_t len = 0;
00267 asn1_named_data *cur_ext = first;
00268
00269 while( cur_ext != NULL )
00270 {
00271 ASN1_CHK_ADD( len, x509_write_extension( p, start, cur_ext ) );
00272 cur_ext = cur_ext->next;
00273 }
00274
00275 return( (int) len );
00276 }
00277
00278 #endif