x509_create.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /*
  2. * X.509 base functions for creating certificates / CSRs
  3. *
  4. * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  8. * not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. * This file is part of mbed TLS (https://tls.mbed.org)
  20. */
  21. #if !defined(MBEDTLS_CONFIG_FILE)
  22. #include "mbedtls/config.h"
  23. #else
  24. #include MBEDTLS_CONFIG_FILE
  25. #endif
  26. #if defined(MBEDTLS_X509_CREATE_C)
  27. #include "mbedtls/x509.h"
  28. #include "mbedtls/asn1write.h"
  29. #include "mbedtls/oid.h"
  30. #include <string.h>
  31. /* Structure linking OIDs for X.509 DN AttributeTypes to their
  32. * string representations and default string encodings used by Mbed TLS. */
  33. typedef struct {
  34. const char *name; /* String representation of AttributeType, e.g.
  35. * "CN" or "emailAddress". */
  36. size_t name_len; /* Length of 'name', without trailing 0 byte. */
  37. const char *oid; /* String representation of OID of AttributeType,
  38. * as per RFC 5280, Appendix A.1. */
  39. int default_tag; /* The default character encoding used for the
  40. * given attribute type, e.g.
  41. * MBEDTLS_ASN1_UTF8_STRING for UTF-8. */
  42. } x509_attr_descriptor_t;
  43. #define ADD_STRLEN( s ) s, sizeof( s ) - 1
  44. /* X.509 DN attributes from RFC 5280, Appendix A.1. */
  45. static const x509_attr_descriptor_t x509_attrs[] =
  46. {
  47. { ADD_STRLEN( "CN" ),
  48. MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING },
  49. { ADD_STRLEN( "commonName" ),
  50. MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING },
  51. { ADD_STRLEN( "C" ),
  52. MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING },
  53. { ADD_STRLEN( "countryName" ),
  54. MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING },
  55. { ADD_STRLEN( "O" ),
  56. MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING },
  57. { ADD_STRLEN( "organizationName" ),
  58. MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING },
  59. { ADD_STRLEN( "L" ),
  60. MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING },
  61. { ADD_STRLEN( "locality" ),
  62. MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING },
  63. { ADD_STRLEN( "R" ),
  64. MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING },
  65. { ADD_STRLEN( "OU" ),
  66. MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING },
  67. { ADD_STRLEN( "organizationalUnitName" ),
  68. MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING },
  69. { ADD_STRLEN( "ST" ),
  70. MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING },
  71. { ADD_STRLEN( "stateOrProvinceName" ),
  72. MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING },
  73. { ADD_STRLEN( "emailAddress" ),
  74. MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING },
  75. { ADD_STRLEN( "serialNumber" ),
  76. MBEDTLS_OID_AT_SERIAL_NUMBER, MBEDTLS_ASN1_PRINTABLE_STRING },
  77. { ADD_STRLEN( "postalAddress" ),
  78. MBEDTLS_OID_AT_POSTAL_ADDRESS, MBEDTLS_ASN1_PRINTABLE_STRING },
  79. { ADD_STRLEN( "postalCode" ),
  80. MBEDTLS_OID_AT_POSTAL_CODE, MBEDTLS_ASN1_PRINTABLE_STRING },
  81. { ADD_STRLEN( "dnQualifier" ),
  82. MBEDTLS_OID_AT_DN_QUALIFIER, MBEDTLS_ASN1_PRINTABLE_STRING },
  83. { ADD_STRLEN( "title" ),
  84. MBEDTLS_OID_AT_TITLE, MBEDTLS_ASN1_UTF8_STRING },
  85. { ADD_STRLEN( "surName" ),
  86. MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING },
  87. { ADD_STRLEN( "SN" ),
  88. MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING },
  89. { ADD_STRLEN( "givenName" ),
  90. MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING },
  91. { ADD_STRLEN( "GN" ),
  92. MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING },
  93. { ADD_STRLEN( "initials" ),
  94. MBEDTLS_OID_AT_INITIALS, MBEDTLS_ASN1_UTF8_STRING },
  95. { ADD_STRLEN( "pseudonym" ),
  96. MBEDTLS_OID_AT_PSEUDONYM, MBEDTLS_ASN1_UTF8_STRING },
  97. { ADD_STRLEN( "generationQualifier" ),
  98. MBEDTLS_OID_AT_GENERATION_QUALIFIER, MBEDTLS_ASN1_UTF8_STRING },
  99. { ADD_STRLEN( "domainComponent" ),
  100. MBEDTLS_OID_DOMAIN_COMPONENT, MBEDTLS_ASN1_IA5_STRING },
  101. { ADD_STRLEN( "DC" ),
  102. MBEDTLS_OID_DOMAIN_COMPONENT, MBEDTLS_ASN1_IA5_STRING },
  103. { NULL, 0, NULL, MBEDTLS_ASN1_NULL }
  104. };
  105. static const x509_attr_descriptor_t *x509_attr_descr_from_name( const char *name, size_t name_len )
  106. {
  107. const x509_attr_descriptor_t *cur;
  108. for( cur = x509_attrs; cur->name != NULL; cur++ )
  109. if( cur->name_len == name_len &&
  110. strncmp( cur->name, name, name_len ) == 0 )
  111. break;
  112. if ( cur->name == NULL )
  113. return( NULL );
  114. return( cur );
  115. }
  116. int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name )
  117. {
  118. int ret = 0;
  119. const char *s = name, *c = s;
  120. const char *end = s + strlen( s );
  121. const char *oid = NULL;
  122. const x509_attr_descriptor_t* attr_descr = NULL;
  123. int in_tag = 1;
  124. char data[MBEDTLS_X509_MAX_DN_NAME_SIZE];
  125. char *d = data;
  126. /* Clear existing chain if present */
  127. mbedtls_asn1_free_named_data_list( head );
  128. while( c <= end )
  129. {
  130. if( in_tag && *c == '=' )
  131. {
  132. if( ( attr_descr = x509_attr_descr_from_name( s, c - s ) ) == NULL )
  133. {
  134. ret = MBEDTLS_ERR_X509_UNKNOWN_OID;
  135. goto exit;
  136. }
  137. oid = attr_descr->oid;
  138. s = c + 1;
  139. in_tag = 0;
  140. d = data;
  141. }
  142. if( !in_tag && *c == '\\' && c != end )
  143. {
  144. c++;
  145. /* Check for valid escaped characters */
  146. if( c == end || *c != ',' )
  147. {
  148. ret = MBEDTLS_ERR_X509_INVALID_NAME;
  149. goto exit;
  150. }
  151. }
  152. else if( !in_tag && ( *c == ',' || c == end ) )
  153. {
  154. mbedtls_asn1_named_data* cur =
  155. mbedtls_asn1_store_named_data( head, oid, strlen( oid ),
  156. (unsigned char *) data,
  157. d - data );
  158. if(cur == NULL )
  159. {
  160. return( MBEDTLS_ERR_X509_ALLOC_FAILED );
  161. }
  162. // set tagType
  163. cur->val.tag = attr_descr->default_tag;
  164. while( c < end && *(c + 1) == ' ' )
  165. c++;
  166. s = c + 1;
  167. in_tag = 1;
  168. }
  169. if( !in_tag && s != c + 1 )
  170. {
  171. *(d++) = *c;
  172. if( d - data == MBEDTLS_X509_MAX_DN_NAME_SIZE )
  173. {
  174. ret = MBEDTLS_ERR_X509_INVALID_NAME;
  175. goto exit;
  176. }
  177. }
  178. c++;
  179. }
  180. exit:
  181. return( ret );
  182. }
  183. /* The first byte of the value in the mbedtls_asn1_named_data structure is reserved
  184. * to store the critical boolean for us
  185. */
  186. int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
  187. int critical, const unsigned char *val, size_t val_len )
  188. {
  189. mbedtls_asn1_named_data *cur;
  190. if( ( cur = mbedtls_asn1_store_named_data( head, oid, oid_len,
  191. NULL, val_len + 1 ) ) == NULL )
  192. {
  193. return( MBEDTLS_ERR_X509_ALLOC_FAILED );
  194. }
  195. cur->val.p[0] = critical;
  196. memcpy( cur->val.p + 1, val, val_len );
  197. return( 0 );
  198. }
  199. /*
  200. * RelativeDistinguishedName ::=
  201. * SET OF AttributeTypeAndValue
  202. *
  203. * AttributeTypeAndValue ::= SEQUENCE {
  204. * type AttributeType,
  205. * value AttributeValue }
  206. *
  207. * AttributeType ::= OBJECT IDENTIFIER
  208. *
  209. * AttributeValue ::= ANY DEFINED BY AttributeType
  210. */
  211. static int x509_write_name( unsigned char **p, unsigned char *start, mbedtls_asn1_named_data* cur_name)
  212. {
  213. int ret;
  214. size_t len = 0;
  215. const char *oid = (const char*)cur_name->oid.p;
  216. size_t oid_len = cur_name->oid.len;
  217. const unsigned char *name = cur_name->val.p;
  218. size_t name_len = cur_name->val.len;
  219. // Write correct string tag and value
  220. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tagged_string( p, start,
  221. cur_name->val.tag,
  222. (const char *) name,
  223. name_len ) );
  224. // Write OID
  225. //
  226. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid,
  227. oid_len ) );
  228. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  229. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
  230. MBEDTLS_ASN1_CONSTRUCTED |
  231. MBEDTLS_ASN1_SEQUENCE ) );
  232. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  233. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
  234. MBEDTLS_ASN1_CONSTRUCTED |
  235. MBEDTLS_ASN1_SET ) );
  236. return( (int) len );
  237. }
  238. int mbedtls_x509_write_names( unsigned char **p, unsigned char *start,
  239. mbedtls_asn1_named_data *first )
  240. {
  241. int ret;
  242. size_t len = 0;
  243. mbedtls_asn1_named_data *cur = first;
  244. while( cur != NULL )
  245. {
  246. MBEDTLS_ASN1_CHK_ADD( len, x509_write_name( p, start, cur ) );
  247. cur = cur->next;
  248. }
  249. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  250. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
  251. MBEDTLS_ASN1_SEQUENCE ) );
  252. return( (int) len );
  253. }
  254. int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
  255. const char *oid, size_t oid_len,
  256. unsigned char *sig, size_t size )
  257. {
  258. int ret;
  259. size_t len = 0;
  260. if( *p < start || (size_t)( *p - start ) < size )
  261. return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  262. len = size;
  263. (*p) -= len;
  264. memcpy( *p, sig, len );
  265. if( *p - start < 1 )
  266. return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  267. *--(*p) = 0;
  268. len += 1;
  269. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  270. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) );
  271. // Write OID
  272. //
  273. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( p, start, oid,
  274. oid_len, 0 ) );
  275. return( (int) len );
  276. }
  277. static int x509_write_extension( unsigned char **p, unsigned char *start,
  278. mbedtls_asn1_named_data *ext )
  279. {
  280. int ret;
  281. size_t len = 0;
  282. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->val.p + 1,
  283. ext->val.len - 1 ) );
  284. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->val.len - 1 ) );
  285. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) );
  286. if( ext->val.p[0] != 0 )
  287. {
  288. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( p, start, 1 ) );
  289. }
  290. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->oid.p,
  291. ext->oid.len ) );
  292. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->oid.len ) );
  293. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) );
  294. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  295. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
  296. MBEDTLS_ASN1_SEQUENCE ) );
  297. return( (int) len );
  298. }
  299. /*
  300. * Extension ::= SEQUENCE {
  301. * extnID OBJECT IDENTIFIER,
  302. * critical BOOLEAN DEFAULT FALSE,
  303. * extnValue OCTET STRING
  304. * -- contains the DER encoding of an ASN.1 value
  305. * -- corresponding to the extension type identified
  306. * -- by extnID
  307. * }
  308. */
  309. int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
  310. mbedtls_asn1_named_data *first )
  311. {
  312. int ret;
  313. size_t len = 0;
  314. mbedtls_asn1_named_data *cur_ext = first;
  315. while( cur_ext != NULL )
  316. {
  317. MBEDTLS_ASN1_CHK_ADD( len, x509_write_extension( p, start, cur_ext ) );
  318. cur_ext = cur_ext->next;
  319. }
  320. return( (int) len );
  321. }
  322. #endif /* MBEDTLS_X509_CREATE_C */