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>
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)
29 #include POLARSSL_CONFIG_FILE
32 #if defined(POLARSSL_X509_CREATE_C)
35 #include "asn1write.h"
38 #if defined(_MSC_VER) && !defined strncasecmp && !defined(EFIX64) && \
40 #define strncasecmp _strnicmp
43 int x509_string_to_names( asn1_named_data
**head
, const char *name
)
46 const char *s
= name
, *c
= s
;
47 const char *end
= s
+ strlen( s
);
48 const char *oid
= NULL
;
51 /* Clear existing chain if present */
52 asn1_free_named_data_list( head
);
56 if( in_tag
&& *c
== '=' )
58 if( c
- s
== 2 && strncasecmp( s
, "CN", 2 ) == 0 )
60 else if( c
- s
== 10 && strncasecmp( s
, "commonName", 10 ) == 0 )
62 else if( c
- s
== 1 && strncasecmp( s
, "C", 1 ) == 0 )
64 else if( c
- s
== 11 && strncasecmp( s
, "countryName", 11 ) == 0 )
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 )
84 else if( c
- s
== 19 &&
85 strncasecmp( s
, "stateOrProvinceName", 19 ) == 0 )
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 )
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
;
121 ret
= POLARSSL_ERR_X509_UNKNOWN_OID
;
129 if( !in_tag
&& ( *c
== ',' || c
== end
) )
131 if( asn1_store_named_data( head
, oid
, strlen( oid
),
135 return( POLARSSL_ERR_X509_MALLOC_FAILED
);
138 while( c
< end
&& *(c
+ 1) == ' ' )
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
);
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
)
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
,
202 ASN1_CHK_ADD( len
, asn1_write_printable_string( p
, start
,
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
|
215 ASN1_CHK_ADD( len
, asn1_write_len( p
, start
, len
) );
216 ASN1_CHK_ADD( len
, asn1_write_tag( p
, start
, ASN1_CONSTRUCTED
|
222 int x509_write_names( unsigned char **p
, unsigned char *start
,
223 asn1_named_data
*first
)
227 asn1_named_data
*cur
= first
;
231 ASN1_CHK_ADD( len
, x509_write_name( p
, start
, (char *) cur
->oid
.p
,
233 cur
->val
.p
, cur
->val
.len
) );
237 ASN1_CHK_ADD( len
, asn1_write_len( p
, start
, len
) );
238 ASN1_CHK_ADD( len
, asn1_write_tag( p
, start
, ASN1_CONSTRUCTED
|
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
)
251 if( *p
- start
< (int) size
+ 1 )
252 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL
);
256 memcpy( *p
, sig
, len
);
261 ASN1_CHK_ADD( len
, asn1_write_len( p
, start
, len
) );
262 ASN1_CHK_ADD( len
, asn1_write_tag( p
, start
, ASN1_BIT_STRING
) );
266 ASN1_CHK_ADD( len
, asn1_write_algorithm_identifier( p
, start
, oid
,
272 static int x509_write_extension( unsigned char **p
, unsigned char *start
,
273 asn1_named_data
*ext
)
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
,
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
|
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
310 int x509_write_extensions( unsigned char **p
, unsigned char *start
,
311 asn1_named_data
*first
)
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
;
326 #endif /* POLARSSL_X509_CREATE_C */