insert nonsensical useragent for sourceshit, so it won't try to show its idiotic...
[syren.git] / src / libpolarssl / x509_create.c
blobd55fec6b29c587f6490fd79a581368b42cf3c2af
1 /*
2 * X.509 base functions for creating certificates / CSRs
4 * Copyright (C) 2006-2013, Brainspark B.V.
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
9 * All rights reserved.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #if !defined(POLARSSL_CONFIG_FILE)
27 #include "config.h"
28 #else
29 #include POLARSSL_CONFIG_FILE
30 #endif
32 #if defined(POLARSSL_X509_CREATE_C)
34 #include "x509.h"
35 #include "asn1write.h"
36 #include "oid.h"
38 #if defined(_MSC_VER) && !defined strncasecmp && !defined(EFIX64) && \
39 !defined(EFI32)
40 #define strncasecmp _strnicmp
41 #endif
43 int x509_string_to_names( asn1_named_data **head, const char *name )
45 int ret = 0;
46 const char *s = name, *c = s;
47 const char *end = s + strlen( s );
48 const char *oid = NULL;
49 int in_tag = 1;
51 /* Clear existing chain if present */
52 asn1_free_named_data_list( head );
54 while( c <= end )
56 if( in_tag && *c == '=' )
58 if( c - s == 2 && strncasecmp( s, "CN", 2 ) == 0 )
59 oid = OID_AT_CN;
60 else if( c - s == 10 && strncasecmp( s, "commonName", 10 ) == 0 )
61 oid = OID_AT_CN;
62 else if( c - s == 1 && strncasecmp( s, "C", 1 ) == 0 )
63 oid = OID_AT_COUNTRY;
64 else if( c - s == 11 && strncasecmp( s, "countryName", 11 ) == 0 )
65 oid = OID_AT_COUNTRY;
66 else if( c - s == 1 && strncasecmp( s, "O", 1 ) == 0 )
67 oid = OID_AT_ORGANIZATION;
68 else if( c - s == 16 &&
69 strncasecmp( s, "organizationName", 16 ) == 0 )
70 oid = OID_AT_ORGANIZATION;
71 else if( c - s == 1 && strncasecmp( s, "L", 1 ) == 0 )
72 oid = OID_AT_LOCALITY;
73 else if( c - s == 8 && strncasecmp( s, "locality", 8 ) == 0 )
74 oid = OID_AT_LOCALITY;
75 else if( c - s == 1 && strncasecmp( s, "R", 1 ) == 0 )
76 oid = OID_PKCS9_EMAIL;
77 else if( c - s == 2 && strncasecmp( s, "OU", 2 ) == 0 )
78 oid = OID_AT_ORG_UNIT;
79 else if( c - s == 22 &&
80 strncasecmp( s, "organizationalUnitName", 22 ) == 0 )
81 oid = OID_AT_ORG_UNIT;
82 else if( c - s == 2 && strncasecmp( s, "ST", 2 ) == 0 )
83 oid = OID_AT_STATE;
84 else if( c - s == 19 &&
85 strncasecmp( s, "stateOrProvinceName", 19 ) == 0 )
86 oid = OID_AT_STATE;
87 else if( c - s == 12 && strncasecmp( s, "emailAddress", 12 ) == 0 )
88 oid = OID_PKCS9_EMAIL;
89 else if( c - s == 12 && strncasecmp( s, "serialNumber", 12 ) == 0 )
90 oid = OID_AT_SERIAL_NUMBER;
91 else if( c - s == 13 && strncasecmp( s, "postalAddress", 13 ) == 0 )
92 oid = OID_AT_POSTAL_ADDRESS;
93 else if( c - s == 10 && strncasecmp( s, "postalCode", 10 ) == 0 )
94 oid = OID_AT_POSTAL_CODE;
95 else if( c - s == 11 && strncasecmp( s, "dnQualifier", 11 ) == 0 )
96 oid = OID_AT_DN_QUALIFIER;
97 else if( c - s == 5 && strncasecmp( s, "title", 5 ) == 0 )
98 oid = OID_AT_TITLE;
99 else if( c - s == 7 && strncasecmp( s, "surName", 7 ) == 0 )
100 oid = OID_AT_SUR_NAME;
101 else if( c - s == 2 && strncasecmp( s, "SN", 2 ) == 0 )
102 oid = OID_AT_SUR_NAME;
103 else if( c - s == 9 && strncasecmp( s, "givenName", 9 ) == 0 )
104 oid = OID_AT_GIVEN_NAME;
105 else if( c - s == 2 && strncasecmp( s, "GN", 2 ) == 0 )
106 oid = OID_AT_GIVEN_NAME;
107 else if( c - s == 8 && strncasecmp( s, "initials", 8 ) == 0 )
108 oid = OID_AT_INITIALS;
109 else if( c - s == 9 && strncasecmp( s, "pseudonym", 9 ) == 0 )
110 oid = OID_AT_PSEUDONYM;
111 else if( c - s == 19 &&
112 strncasecmp( s, "generationQualifier", 19 ) == 0 )
113 oid = OID_AT_GENERATION_QUALIFIER;
114 else if( c - s == 15 &&
115 strncasecmp( s, "domainComponent", 15 ) == 0 )
116 oid = OID_DOMAIN_COMPONENT;
117 else if( c - s == 2 && strncasecmp( s, "DC", 2 ) == 0 )
118 oid = OID_DOMAIN_COMPONENT;
119 else
121 ret = POLARSSL_ERR_X509_UNKNOWN_OID;
122 goto exit;
125 s = c + 1;
126 in_tag = 0;
129 if( !in_tag && ( *c == ',' || c == end ) )
131 if( asn1_store_named_data( head, oid, strlen( oid ),
132 (unsigned char *) s,
133 c - s ) == NULL )
135 return( POLARSSL_ERR_X509_MALLOC_FAILED );
138 while( c < end && *(c + 1) == ' ' )
139 c++;
141 s = c + 1;
142 in_tag = 1;
144 c++;
147 exit:
149 return( ret );
152 /* The first byte of the value in the asn1_named_data structure is reserved
153 * to store the critical boolean for us
155 int x509_set_extension( asn1_named_data **head, const char *oid, size_t oid_len,
156 int critical, const unsigned char *val, size_t val_len )
158 asn1_named_data *cur;
160 if( ( cur = asn1_store_named_data( head, oid, oid_len,
161 NULL, val_len + 1 ) ) == NULL )
163 return( POLARSSL_ERR_X509_MALLOC_FAILED );
166 cur->val.p[0] = critical;
167 memcpy( cur->val.p + 1, val, val_len );
169 return( 0 );
173 * RelativeDistinguishedName ::=
174 * SET OF AttributeTypeAndValue
176 * AttributeTypeAndValue ::= SEQUENCE {
177 * type AttributeType,
178 * value AttributeValue }
180 * AttributeType ::= OBJECT IDENTIFIER
182 * AttributeValue ::= ANY DEFINED BY AttributeType
184 static int x509_write_name( unsigned char **p, unsigned char *start,
185 const char *oid, size_t oid_len,
186 const unsigned char *name, size_t name_len )
188 int ret;
189 size_t len = 0;
191 // Write PrintableString for all except OID_PKCS9_EMAIL
193 if( OID_SIZE( OID_PKCS9_EMAIL ) == oid_len &&
194 memcmp( oid, OID_PKCS9_EMAIL, oid_len ) == 0 )
196 ASN1_CHK_ADD( len, asn1_write_ia5_string( p, start,
197 (const char *) name,
198 name_len ) );
200 else
202 ASN1_CHK_ADD( len, asn1_write_printable_string( p, start,
203 (const char *) name,
204 name_len ) );
207 // Write OID
209 ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) );
211 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
212 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED |
213 ASN1_SEQUENCE ) );
215 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
216 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED |
217 ASN1_SET ) );
219 return( (int) len );
222 int x509_write_names( unsigned char **p, unsigned char *start,
223 asn1_named_data *first )
225 int ret;
226 size_t len = 0;
227 asn1_named_data *cur = first;
229 while( cur != NULL )
231 ASN1_CHK_ADD( len, x509_write_name( p, start, (char *) cur->oid.p,
232 cur->oid.len,
233 cur->val.p, cur->val.len ) );
234 cur = cur->next;
237 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
238 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED |
239 ASN1_SEQUENCE ) );
241 return( (int) len );
244 int x509_write_sig( unsigned char **p, unsigned char *start,
245 const char *oid, size_t oid_len,
246 unsigned char *sig, size_t size )
248 int ret;
249 size_t len = 0;
251 if( *p - start < (int) size + 1 )
252 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
254 len = size;
255 (*p) -= len;
256 memcpy( *p, sig, len );
258 *--(*p) = 0;
259 len += 1;
261 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
262 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) );
264 // Write OID
266 ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( p, start, oid,
267 oid_len, 0 ) );
269 return( (int) len );
272 static int x509_write_extension( unsigned char **p, unsigned char *start,
273 asn1_named_data *ext )
275 int ret;
276 size_t len = 0;
278 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, ext->val.p + 1,
279 ext->val.len - 1 ) );
280 ASN1_CHK_ADD( len, asn1_write_len( p, start, ext->val.len - 1 ) );
281 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OCTET_STRING ) );
283 if( ext->val.p[0] != 0 )
285 ASN1_CHK_ADD( len, asn1_write_bool( p, start, 1 ) );
288 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, ext->oid.p,
289 ext->oid.len ) );
290 ASN1_CHK_ADD( len, asn1_write_len( p, start, ext->oid.len ) );
291 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OID ) );
293 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
294 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED |
295 ASN1_SEQUENCE ) );
297 return( (int) len );
301 * Extension ::= SEQUENCE {
302 * extnID OBJECT IDENTIFIER,
303 * critical BOOLEAN DEFAULT FALSE,
304 * extnValue OCTET STRING
305 * -- contains the DER encoding of an ASN.1 value
306 * -- corresponding to the extension type identified
307 * -- by extnID
310 int x509_write_extensions( unsigned char **p, unsigned char *start,
311 asn1_named_data *first )
313 int ret;
314 size_t len = 0;
315 asn1_named_data *cur_ext = first;
317 while( cur_ext != NULL )
319 ASN1_CHK_ADD( len, x509_write_extension( p, start, cur_ext ) );
320 cur_ext = cur_ext->next;
323 return( (int) len );
326 #endif /* POLARSSL_X509_CREATE_C */