x509_create.c 13 KB

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