x509write_crt.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. /*
  2. * X.509 certificate writing
  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. /*
  47. * References:
  48. * - certificates: RFC 5280, updated by RFC 6818
  49. * - CSRs: PKCS#10 v1.7 aka RFC 2986
  50. * - attributes: PKCS#9 v2.0 aka RFC 2985
  51. */
  52. #if !defined(MBEDTLS_CONFIG_FILE)
  53. #include "mbedtls/config.h"
  54. #else
  55. #include MBEDTLS_CONFIG_FILE
  56. #endif
  57. #if defined(MBEDTLS_X509_CRT_WRITE_C)
  58. #include "mbedtls/x509_crt.h"
  59. #include "mbedtls/oid.h"
  60. #include "mbedtls/asn1write.h"
  61. #include "mbedtls/sha1.h"
  62. #include "mbedtls/platform_util.h"
  63. #include <string.h>
  64. #if defined(MBEDTLS_PEM_WRITE_C)
  65. #include "mbedtls/pem.h"
  66. #endif /* MBEDTLS_PEM_WRITE_C */
  67. /*
  68. * For the currently used signature algorithms the buffer to store any signature
  69. * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)
  70. */
  71. #if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE
  72. #define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN
  73. #else
  74. #define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
  75. #endif
  76. void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx )
  77. {
  78. memset( ctx, 0, sizeof( mbedtls_x509write_cert ) );
  79. mbedtls_mpi_init( &ctx->serial );
  80. ctx->version = MBEDTLS_X509_CRT_VERSION_3;
  81. }
  82. void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx )
  83. {
  84. mbedtls_mpi_free( &ctx->serial );
  85. mbedtls_asn1_free_named_data_list( &ctx->subject );
  86. mbedtls_asn1_free_named_data_list( &ctx->issuer );
  87. mbedtls_asn1_free_named_data_list( &ctx->extensions );
  88. mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_cert ) );
  89. }
  90. void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx,
  91. int version )
  92. {
  93. ctx->version = version;
  94. }
  95. void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx,
  96. mbedtls_md_type_t md_alg )
  97. {
  98. ctx->md_alg = md_alg;
  99. }
  100. void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx,
  101. mbedtls_pk_context *key )
  102. {
  103. ctx->subject_key = key;
  104. }
  105. void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx,
  106. mbedtls_pk_context *key )
  107. {
  108. ctx->issuer_key = key;
  109. }
  110. int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx,
  111. const char *subject_name )
  112. {
  113. return mbedtls_x509_string_to_names( &ctx->subject, subject_name );
  114. }
  115. int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx,
  116. const char *issuer_name )
  117. {
  118. return mbedtls_x509_string_to_names( &ctx->issuer, issuer_name );
  119. }
  120. int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx,
  121. const mbedtls_mpi *serial )
  122. {
  123. int ret;
  124. if( ( ret = mbedtls_mpi_copy( &ctx->serial, serial ) ) != 0 )
  125. return( ret );
  126. return( 0 );
  127. }
  128. int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx,
  129. const char *not_before,
  130. const char *not_after )
  131. {
  132. if( strlen( not_before ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 ||
  133. strlen( not_after ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 )
  134. {
  135. return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
  136. }
  137. strncpy( ctx->not_before, not_before, MBEDTLS_X509_RFC5280_UTC_TIME_LEN );
  138. strncpy( ctx->not_after , not_after , MBEDTLS_X509_RFC5280_UTC_TIME_LEN );
  139. ctx->not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
  140. ctx->not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
  141. return( 0 );
  142. }
  143. int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx,
  144. const char *oid, size_t oid_len,
  145. int critical,
  146. const unsigned char *val, size_t val_len )
  147. {
  148. return( mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len,
  149. critical, val, val_len ) );
  150. }
  151. int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx,
  152. int is_ca, int max_pathlen )
  153. {
  154. int ret;
  155. unsigned char buf[9];
  156. unsigned char *c = buf + sizeof(buf);
  157. size_t len = 0;
  158. memset( buf, 0, sizeof(buf) );
  159. if( is_ca && max_pathlen > 127 )
  160. return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
  161. if( is_ca )
  162. {
  163. if( max_pathlen >= 0 )
  164. {
  165. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf,
  166. max_pathlen ) );
  167. }
  168. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( &c, buf, 1 ) );
  169. }
  170. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
  171. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf,
  172. MBEDTLS_ASN1_CONSTRUCTED |
  173. MBEDTLS_ASN1_SEQUENCE ) );
  174. return(
  175. mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS,
  176. MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ),
  177. 0, buf + sizeof(buf) - len, len ) );
  178. }
  179. #if defined(MBEDTLS_SHA1_C)
  180. int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx )
  181. {
  182. int ret;
  183. unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
  184. unsigned char *c = buf + sizeof(buf);
  185. size_t len = 0;
  186. memset( buf, 0, sizeof(buf) );
  187. MBEDTLS_ASN1_CHK_ADD( len,
  188. mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) );
  189. ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len,
  190. buf + sizeof( buf ) - 20 );
  191. if( ret != 0 )
  192. return( ret );
  193. c = buf + sizeof( buf ) - 20;
  194. len = 20;
  195. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
  196. MBEDTLS_ASN1_CHK_ADD( len,
  197. mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_OCTET_STRING ) );
  198. return mbedtls_x509write_crt_set_extension( ctx,
  199. MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER,
  200. MBEDTLS_OID_SIZE( MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER ),
  201. 0, buf + sizeof(buf) - len, len );
  202. }
  203. int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx )
  204. {
  205. int ret;
  206. unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
  207. unsigned char *c = buf + sizeof( buf );
  208. size_t len = 0;
  209. memset( buf, 0, sizeof(buf) );
  210. MBEDTLS_ASN1_CHK_ADD( len,
  211. mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) );
  212. ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len,
  213. buf + sizeof( buf ) - 20 );
  214. if( ret != 0 )
  215. return( ret );
  216. c = buf + sizeof( buf ) - 20;
  217. len = 20;
  218. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
  219. MBEDTLS_ASN1_CHK_ADD( len,
  220. mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0 ) );
  221. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
  222. MBEDTLS_ASN1_CHK_ADD( len,
  223. mbedtls_asn1_write_tag( &c, buf,
  224. MBEDTLS_ASN1_CONSTRUCTED |
  225. MBEDTLS_ASN1_SEQUENCE ) );
  226. return mbedtls_x509write_crt_set_extension(
  227. ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER,
  228. MBEDTLS_OID_SIZE( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ),
  229. 0, buf + sizeof( buf ) - len, len );
  230. }
  231. #endif /* MBEDTLS_SHA1_C */
  232. static size_t crt_get_unused_bits_for_named_bitstring( unsigned char bitstring,
  233. size_t bit_offset )
  234. {
  235. size_t unused_bits;
  236. /* Count the unused bits removing trailing 0s */
  237. for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ )
  238. if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 )
  239. break;
  240. return( unused_bits );
  241. }
  242. int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx,
  243. unsigned int key_usage )
  244. {
  245. unsigned char buf[4], ku;
  246. unsigned char *c;
  247. int ret;
  248. size_t unused_bits;
  249. const unsigned int allowed_bits = MBEDTLS_X509_KU_DIGITAL_SIGNATURE |
  250. MBEDTLS_X509_KU_NON_REPUDIATION |
  251. MBEDTLS_X509_KU_KEY_ENCIPHERMENT |
  252. MBEDTLS_X509_KU_DATA_ENCIPHERMENT |
  253. MBEDTLS_X509_KU_KEY_AGREEMENT |
  254. MBEDTLS_X509_KU_KEY_CERT_SIGN |
  255. MBEDTLS_X509_KU_CRL_SIGN;
  256. /* Check that nothing other than the allowed flags is set */
  257. if( ( key_usage & ~allowed_bits ) != 0 )
  258. return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
  259. c = buf + 4;
  260. ku = (unsigned char)key_usage;
  261. unused_bits = crt_get_unused_bits_for_named_bitstring( ku, 1 );
  262. ret = mbedtls_asn1_write_bitstring( &c, buf, &ku, 8 - unused_bits );
  263. if( ret < 0 )
  264. return( ret );
  265. else if( ret < 3 || ret > 4 )
  266. return( MBEDTLS_ERR_X509_INVALID_FORMAT );
  267. ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_KEY_USAGE,
  268. MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ),
  269. 1, c, (size_t)ret );
  270. if( ret != 0 )
  271. return( ret );
  272. return( 0 );
  273. }
  274. int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx,
  275. unsigned char ns_cert_type )
  276. {
  277. unsigned char buf[4];
  278. unsigned char *c;
  279. size_t unused_bits;
  280. int ret;
  281. c = buf + 4;
  282. unused_bits = crt_get_unused_bits_for_named_bitstring( ns_cert_type, 0 );
  283. ret = mbedtls_asn1_write_bitstring( &c,
  284. buf,
  285. &ns_cert_type,
  286. 8 - unused_bits );
  287. if( ret < 3 || ret > 4 )
  288. return( ret );
  289. ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE,
  290. MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ),
  291. 0, c, (size_t)ret );
  292. if( ret != 0 )
  293. return( ret );
  294. return( 0 );
  295. }
  296. static int x509_write_time( unsigned char **p, unsigned char *start,
  297. const char *t, size_t size )
  298. {
  299. int ret;
  300. size_t len = 0;
  301. /*
  302. * write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter)
  303. */
  304. if( t[0] == '2' && t[1] == '0' && t[2] < '5' )
  305. {
  306. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
  307. (const unsigned char *) t + 2,
  308. size - 2 ) );
  309. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  310. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
  311. MBEDTLS_ASN1_UTC_TIME ) );
  312. }
  313. else
  314. {
  315. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
  316. (const unsigned char *) t,
  317. size ) );
  318. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
  319. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
  320. MBEDTLS_ASN1_GENERALIZED_TIME ) );
  321. }
  322. return( (int) len );
  323. }
  324. int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx,
  325. unsigned char *buf, size_t size,
  326. int (*f_rng)(void *, unsigned char *, size_t),
  327. void *p_rng )
  328. {
  329. int ret;
  330. const char *sig_oid;
  331. size_t sig_oid_len = 0;
  332. unsigned char *c, *c2;
  333. unsigned char hash[64];
  334. unsigned char sig[SIGNATURE_MAX_SIZE];
  335. size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len;
  336. size_t len = 0;
  337. mbedtls_pk_type_t pk_alg;
  338. /*
  339. * Prepare data to be signed at the end of the target buffer
  340. */
  341. c = buf + size;
  342. /* Signature algorithm needed in TBS, and later for actual signature */
  343. /* There's no direct way of extracting a signature algorithm
  344. * (represented as an element of mbedtls_pk_type_t) from a PK instance. */
  345. if( mbedtls_pk_can_do( ctx->issuer_key, MBEDTLS_PK_RSA ) )
  346. pk_alg = MBEDTLS_PK_RSA;
  347. else if( mbedtls_pk_can_do( ctx->issuer_key, MBEDTLS_PK_ECDSA ) )
  348. pk_alg = MBEDTLS_PK_ECDSA;
  349. else
  350. return( MBEDTLS_ERR_X509_INVALID_ALG );
  351. if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
  352. &sig_oid, &sig_oid_len ) ) != 0 )
  353. {
  354. return( ret );
  355. }
  356. /*
  357. * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
  358. */
  359. /* Only for v3 */
  360. if( ctx->version == MBEDTLS_X509_CRT_VERSION_3 )
  361. {
  362. MBEDTLS_ASN1_CHK_ADD( len,
  363. mbedtls_x509_write_extensions( &c,
  364. buf, ctx->extensions ) );
  365. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
  366. MBEDTLS_ASN1_CHK_ADD( len,
  367. mbedtls_asn1_write_tag( &c, buf,
  368. MBEDTLS_ASN1_CONSTRUCTED |
  369. MBEDTLS_ASN1_SEQUENCE ) );
  370. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
  371. MBEDTLS_ASN1_CHK_ADD( len,
  372. mbedtls_asn1_write_tag( &c, buf,
  373. MBEDTLS_ASN1_CONTEXT_SPECIFIC |
  374. MBEDTLS_ASN1_CONSTRUCTED | 3 ) );
  375. }
  376. /*
  377. * SubjectPublicKeyInfo
  378. */
  379. MBEDTLS_ASN1_CHK_ADD( pub_len,
  380. mbedtls_pk_write_pubkey_der( ctx->subject_key,
  381. buf, c - buf ) );
  382. c -= pub_len;
  383. len += pub_len;
  384. /*
  385. * Subject ::= Name
  386. */
  387. MBEDTLS_ASN1_CHK_ADD( len,
  388. mbedtls_x509_write_names( &c, buf,
  389. ctx->subject ) );
  390. /*
  391. * Validity ::= SEQUENCE {
  392. * notBefore Time,
  393. * notAfter Time }
  394. */
  395. sub_len = 0;
  396. MBEDTLS_ASN1_CHK_ADD( sub_len,
  397. x509_write_time( &c, buf, ctx->not_after,
  398. MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) );
  399. MBEDTLS_ASN1_CHK_ADD( sub_len,
  400. x509_write_time( &c, buf, ctx->not_before,
  401. MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) );
  402. len += sub_len;
  403. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, sub_len ) );
  404. MBEDTLS_ASN1_CHK_ADD( len,
  405. mbedtls_asn1_write_tag( &c, buf,
  406. MBEDTLS_ASN1_CONSTRUCTED |
  407. MBEDTLS_ASN1_SEQUENCE ) );
  408. /*
  409. * Issuer ::= Name
  410. */
  411. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, buf,
  412. ctx->issuer ) );
  413. /*
  414. * Signature ::= AlgorithmIdentifier
  415. */
  416. MBEDTLS_ASN1_CHK_ADD( len,
  417. mbedtls_asn1_write_algorithm_identifier( &c, buf,
  418. sig_oid, strlen( sig_oid ), 0 ) );
  419. /*
  420. * Serial ::= INTEGER
  421. */
  422. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf,
  423. &ctx->serial ) );
  424. /*
  425. * Version ::= INTEGER { v1(0), v2(1), v3(2) }
  426. */
  427. /* Can be omitted for v1 */
  428. if( ctx->version != MBEDTLS_X509_CRT_VERSION_1 )
  429. {
  430. sub_len = 0;
  431. MBEDTLS_ASN1_CHK_ADD( sub_len,
  432. mbedtls_asn1_write_int( &c, buf, ctx->version ) );
  433. len += sub_len;
  434. MBEDTLS_ASN1_CHK_ADD( len,
  435. mbedtls_asn1_write_len( &c, buf, sub_len ) );
  436. MBEDTLS_ASN1_CHK_ADD( len,
  437. mbedtls_asn1_write_tag( &c, buf,
  438. MBEDTLS_ASN1_CONTEXT_SPECIFIC |
  439. MBEDTLS_ASN1_CONSTRUCTED | 0 ) );
  440. }
  441. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
  442. MBEDTLS_ASN1_CHK_ADD( len,
  443. mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
  444. MBEDTLS_ASN1_SEQUENCE ) );
  445. /*
  446. * Make signature
  447. */
  448. /* Compute hash of CRT. */
  449. if( ( ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c,
  450. len, hash ) ) != 0 )
  451. {
  452. return( ret );
  453. }
  454. if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg,
  455. hash, 0, sig, &sig_len,
  456. f_rng, p_rng ) ) != 0 )
  457. {
  458. return( ret );
  459. }
  460. /* Move CRT to the front of the buffer to have space
  461. * for the signature. */
  462. memmove( buf, c, len );
  463. c = buf + len;
  464. /* Add signature at the end of the buffer,
  465. * making sure that it doesn't underflow
  466. * into the CRT buffer. */
  467. c2 = buf + size;
  468. MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, c,
  469. sig_oid, sig_oid_len, sig, sig_len ) );
  470. /*
  471. * Memory layout after this step:
  472. *
  473. * buf c=buf+len c2 buf+size
  474. * [CRT0,...,CRTn, UNUSED, ..., UNUSED, SIG0, ..., SIGm]
  475. */
  476. /* Move raw CRT to just before the signature. */
  477. c = c2 - len;
  478. memmove( c, buf, len );
  479. len += sig_and_oid_len;
  480. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
  481. MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf,
  482. MBEDTLS_ASN1_CONSTRUCTED |
  483. MBEDTLS_ASN1_SEQUENCE ) );
  484. return( (int) len );
  485. }
  486. #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n"
  487. #define PEM_END_CRT "-----END CERTIFICATE-----\n"
  488. #if defined(MBEDTLS_PEM_WRITE_C)
  489. int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *crt,
  490. unsigned char *buf, size_t size,
  491. int (*f_rng)(void *, unsigned char *, size_t),
  492. void *p_rng )
  493. {
  494. int ret;
  495. size_t olen;
  496. if( ( ret = mbedtls_x509write_crt_der( crt, buf, size,
  497. f_rng, p_rng ) ) < 0 )
  498. {
  499. return( ret );
  500. }
  501. if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT,
  502. buf + size - ret, ret,
  503. buf, size, &olen ) ) != 0 )
  504. {
  505. return( ret );
  506. }
  507. return( 0 );
  508. }
  509. #endif /* MBEDTLS_PEM_WRITE_C */
  510. #endif /* MBEDTLS_X509_CRT_WRITE_C */