x509_create.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  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: GPL-2.0
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, write to the Free Software Foundation, Inc.,
  19. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. *
  21. * This file is part of mbed TLS (https://tls.mbed.org)
  22. */
  23. #if !defined(MBEDTLS_CONFIG_FILE)
  24. #include "mbedtls/config.h"
  25. #else
  26. #include MBEDTLS_CONFIG_FILE
  27. #endif
  28. #if defined(MBEDTLS_X509_CREATE_C)
  29. #include "mbedtls/x509.h"
  30. #include "mbedtls/asn1write.h"
  31. #include "mbedtls/oid.h"
  32. #include <string.h>
  33. typedef struct {
  34. const char *name;
  35. size_t name_len;
  36. const char*oid;
  37. } x509_attr_descriptor_t;
  38. #define ADD_STRLEN( s ) s, sizeof( s ) - 1
  39. static const x509_attr_descriptor_t x509_attrs[] =
  40. {
  41. { ADD_STRLEN( "CN" ), MBEDTLS_OID_AT_CN },
  42. { ADD_STRLEN( "commonName" ), MBEDTLS_OID_AT_CN },
  43. { ADD_STRLEN( "C" ), MBEDTLS_OID_AT_COUNTRY },
  44. { ADD_STRLEN( "countryName" ), MBEDTLS_OID_AT_COUNTRY },
  45. { ADD_STRLEN( "O" ), MBEDTLS_OID_AT_ORGANIZATION },
  46. { ADD_STRLEN( "organizationName" ), MBEDTLS_OID_AT_ORGANIZATION },
  47. { ADD_STRLEN( "L" ), MBEDTLS_OID_AT_LOCALITY },
  48. { ADD_STRLEN( "locality" ), MBEDTLS_OID_AT_LOCALITY },
  49. { ADD_STRLEN( "R" ), MBEDTLS_OID_PKCS9_EMAIL },
  50. { ADD_STRLEN( "OU" ), MBEDTLS_OID_AT_ORG_UNIT },
  51. { ADD_STRLEN( "organizationalUnitName" ), MBEDTLS_OID_AT_ORG_UNIT },
  52. { ADD_STRLEN( "ST" ), MBEDTLS_OID_AT_STATE },
  53. { ADD_STRLEN( "stateOrProvinceName" ), MBEDTLS_OID_AT_STATE },
  54. { ADD_STRLEN( "emailAddress" ), MBEDTLS_OID_PKCS9_EMAIL },
  55. { ADD_STRLEN( "serialNumber" ), MBEDTLS_OID_AT_SERIAL_NUMBER },
  56. { ADD_STRLEN( "postalAddress" ), MBEDTLS_OID_AT_POSTAL_ADDRESS },
  57. { ADD_STRLEN( "postalCode" ), MBEDTLS_OID_AT_POSTAL_CODE },
  58. { ADD_STRLEN( "dnQualifier" ), MBEDTLS_OID_AT_DN_QUALIFIER },
  59. { ADD_STRLEN( "title" ), MBEDTLS_OID_AT_TITLE },
  60. { ADD_STRLEN( "surName" ), MBEDTLS_OID_AT_SUR_NAME },
  61. { ADD_STRLEN( "SN" ), MBEDTLS_OID_AT_SUR_NAME },
  62. { ADD_STRLEN( "givenName" ), MBEDTLS_OID_AT_GIVEN_NAME },
  63. { ADD_STRLEN( "GN" ), MBEDTLS_OID_AT_GIVEN_NAME },
  64. { ADD_STRLEN( "initials" ), MBEDTLS_OID_AT_INITIALS },
  65. { ADD_STRLEN( "pseudonym" ), MBEDTLS_OID_AT_PSEUDONYM },
  66. { ADD_STRLEN( "generationQualifier" ), MBEDTLS_OID_AT_GENERATION_QUALIFIER },
  67. { ADD_STRLEN( "domainComponent" ), MBEDTLS_OID_DOMAIN_COMPONENT },
  68. { ADD_STRLEN( "DC" ), MBEDTLS_OID_DOMAIN_COMPONENT },
  69. { NULL, 0, NULL }
  70. };
  71. static const char *x509_at_oid_from_name( const char *name, size_t name_len )
  72. {
  73. const x509_attr_descriptor_t *cur;
  74. for( cur = x509_attrs; cur->name != NULL; cur++ )
  75. if( cur->name_len == name_len &&
  76. strncmp( cur->name, name, name_len ) == 0 )
  77. break;
  78. return( cur->oid );
  79. }
  80. int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name )
  81. {
  82. int ret = 0;
  83. const char *s = name, *c = s;
  84. const char *end = s + strlen( s );
  85. const char *oid = NULL;
  86. int in_tag = 1;
  87. char data[MBEDTLS_X509_MAX_DN_NAME_SIZE];
  88. char *d = data;
  89. /* Clear existing chain if present */
  90. mbedtls_asn1_free_named_data_list( head );
  91. while( c <= end )
  92. {
  93. if( in_tag && *c == '=' )
  94. {
  95. if( ( oid = x509_at_oid_from_name( s, c - s ) ) == NULL )
  96. {
  97. ret = MBEDTLS_ERR_X509_UNKNOWN_OID;
  98. goto exit;
  99. }
  100. s = c + 1;
  101. in_tag = 0;
  102. d = data;
  103. }
  104. if( !in_tag && *c == '\\' && c != end )
  105. {
  106. c++;
  107. /* Check for valid escaped characters */
  108. if( c == end || *c != ',' )
  109. {
  110. ret = MBEDTLS_ERR_X509_INVALID_NAME;
  111. goto exit;
  112. }
  113. }
  114. else if( !in_tag && ( *c == ',' || c == end ) )
  115. {
  116. if( mbedtls_asn1_store_named_data( head, oid, strlen( oid ),
  117. (unsigned char *) data,
  118. d - data ) == NULL )
  119. {
  120. return( MBEDTLS_ERR_X509_ALLOC_FAILED );
  121. }
  122. while( c < end && *(c + 1) == ' ' )
  123. c++;
  124. s = c + 1;
  125. in_tag = 1;
  126. }
  127. if( !in_tag && s != c + 1 )
  128. {
  129. *(d++) = *c;
  130. if( d - data == MBEDTLS_X509_MAX_DN_NAME_SIZE )
  131. {
  132. ret = MBEDTLS_ERR_X509_INVALID_NAME;
  133. goto exit;
  134. }
  135. }
  136. c++;
  137. }
  138. exit:
  139. return( ret );
  140. }
  141. /* The first byte of the value in the mbedtls_asn1_named_data structure is reserved
  142. * to store the critical boolean for us
  143. */
  144. int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
  145. int critical, const unsigned char *val, size_t val_len )
  146. {
  147. mbedtls_asn1_named_data *cur;
  148. if( ( cur = mbedtls_asn1_store_named_data( head, oid, oid_len,
  149. NULL, val_len + 1 ) ) == NULL )
  150. {
  151. return( MBEDTLS_ERR_X509_ALLOC_FAILED );
  152. }
  153. cur->val.p[0] = critical;
  154. memcpy( cur->val.p + 1, val, val_len );
  155. return( 0 );
  156. }
  157. /*
  158. * RelativeDistinguishedName ::=
  159. * SET OF AttributeTypeAndValue
  160. *
  161. * AttributeTypeAndValue ::= SEQUENCE {
  162. * type AttributeType,
  163. * value AttributeValue }
  164. *
  165. * AttributeType ::= OBJECT IDENTIFIER
  166. *
  167. * AttributeValue ::= ANY DEFINED BY AttributeType
  168. */
  169. static int x509_write_name( unsigned char **p, unsigned char *start,
  170. const char *oid, size_t oid_len,
  171. const unsigned char *name, size_t name_len )
  172. {
  173. int ret;
  174. size_t len = 0;
  175. // Write PrintableString for all except MBEDTLS_OID_PKCS9_EMAIL
  176. //
  177. if( MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_EMAIL ) == oid_len &&
  178. memcmp( oid, MBEDTLS_OID_PKCS9_EMAIL, oid_len ) == 0 )
  179. {
  180. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_ia5_string( p, start,
  181. (const char *) name,
  182. name_len ) );
  183. }
  184. else
  185. {
  186. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_printable_string( p, start,
  187. (const char *) name,
  188. name_len ) );
  189. }
  190. // Write OID
  191. //
  192. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) );
  193. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  194. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
  195. MBEDTLS_ASN1_SEQUENCE ) );
  196. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  197. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
  198. MBEDTLS_ASN1_SET ) );
  199. return( (int) len );
  200. }
  201. int mbedtls_x509_write_names( unsigned char **p, unsigned char *start,
  202. mbedtls_asn1_named_data *first )
  203. {
  204. int ret;
  205. size_t len = 0;
  206. mbedtls_asn1_named_data *cur = first;
  207. while( cur != NULL )
  208. {
  209. MBEDTLS_ASN1_CHK_ADD( len, x509_write_name( p, start, (char *) cur->oid.p,
  210. cur->oid.len,
  211. cur->val.p, cur->val.len ) );
  212. cur = cur->next;
  213. }
  214. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  215. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
  216. MBEDTLS_ASN1_SEQUENCE ) );
  217. return( (int) len );
  218. }
  219. int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
  220. const char *oid, size_t oid_len,
  221. unsigned char *sig, size_t size )
  222. {
  223. int ret;
  224. size_t len = 0;
  225. if( *p < start || (size_t)( *p - start ) < size )
  226. return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  227. len = size;
  228. (*p) -= len;
  229. memcpy( *p, sig, len );
  230. if( *p - start < 1 )
  231. return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
  232. *--(*p) = 0;
  233. len += 1;
  234. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  235. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) );
  236. // Write OID
  237. //
  238. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( p, start, oid,
  239. oid_len, 0 ) );
  240. return( (int) len );
  241. }
  242. static int x509_write_extension( unsigned char **p, unsigned char *start,
  243. mbedtls_asn1_named_data *ext )
  244. {
  245. int ret;
  246. size_t len = 0;
  247. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->val.p + 1,
  248. ext->val.len - 1 ) );
  249. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->val.len - 1 ) );
  250. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) );
  251. if( ext->val.p[0] != 0 )
  252. {
  253. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( p, start, 1 ) );
  254. }
  255. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->oid.p,
  256. ext->oid.len ) );
  257. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->oid.len ) );
  258. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) );
  259. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  260. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
  261. MBEDTLS_ASN1_SEQUENCE ) );
  262. return( (int) len );
  263. }
  264. /*
  265. * Extension ::= SEQUENCE {
  266. * extnID OBJECT IDENTIFIER,
  267. * critical BOOLEAN DEFAULT FALSE,
  268. * extnValue OCTET STRING
  269. * -- contains the DER encoding of an ASN.1 value
  270. * -- corresponding to the extension type identified
  271. * -- by extnID
  272. * }
  273. */
  274. int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
  275. mbedtls_asn1_named_data *first )
  276. {
  277. int ret;
  278. size_t len = 0;
  279. mbedtls_asn1_named_data *cur_ext = first;
  280. while( cur_ext != NULL )
  281. {
  282. MBEDTLS_ASN1_CHK_ADD( len, x509_write_extension( p, start, cur_ext ) );
  283. cur_ext = cur_ext->next;
  284. }
  285. return( (int) len );
  286. }
  287. #endif /* MBEDTLS_X509_CREATE_C */