blob: 6fd1dce1fc680aaddff35db02ee3faeeefca0767 [file] [log] [blame]
Paul Bakker9397dcb2013-09-06 09:55:26 +02001/*
2 * Certificate generation and signing
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakker9397dcb2013-09-06 09:55:26 +02006 */
7
Bence Szépkútic662b362021-05-27 11:25:03 +02008#include "mbedtls/build_info.h"
Paul Bakker9397dcb2013-09-06 09:55:26 +02009
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000010#include "mbedtls/platform.h"
Andrzej Kurek0af32482023-04-07 03:10:28 -040011/* md.h is included this early since MD_CAN_XXX macros are defined there. */
Andrzej Kurek1b75e5f2023-04-04 09:55:06 -040012#include "mbedtls/md.h"
Rich Evansf90016a2015-01-19 14:26:37 +000013
Simon Butcher203a6932016-10-07 15:00:17 +010014#if !defined(MBEDTLS_X509_CRT_WRITE_C) || \
15 !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_FS_IO) || \
16 !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C) || \
Manuel Pégourié-Gonnard93302422023-03-21 17:23:08 +010017 !defined(MBEDTLS_ERROR_C) || !defined(MBEDTLS_MD_CAN_SHA256) || \
Valerio Settie3511762024-01-22 16:28:23 +010018 !defined(MBEDTLS_PEM_WRITE_C) || !defined(MBEDTLS_MD_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010019int main(void)
Manuel Pégourié-Gonnard8d649c62015-03-31 15:10:03 +020020{
Gilles Peskine449bd832023-01-11 14:50:10 +010021 mbedtls_printf("MBEDTLS_X509_CRT_WRITE_C and/or MBEDTLS_X509_CRT_PARSE_C and/or "
Manuel Pégourié-Gonnard93302422023-03-21 17:23:08 +010022 "MBEDTLS_FS_IO and/or MBEDTLS_MD_CAN_SHA256 and/or "
Gilles Peskine449bd832023-01-11 14:50:10 +010023 "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or "
24 "MBEDTLS_ERROR_C not defined.\n");
25 mbedtls_exit(0);
Manuel Pégourié-Gonnard8d649c62015-03-31 15:10:03 +020026}
27#else
28
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/x509_crt.h"
30#include "mbedtls/x509_csr.h"
Nicholas Wilson8e5bdfb2015-09-09 19:03:34 +010031#include "mbedtls/oid.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/entropy.h"
33#include "mbedtls/ctr_drbg.h"
34#include "mbedtls/error.h"
Valerio Setti791bbe62023-01-11 10:40:18 +010035#include "test/helpers.h"
Manuel Pégourié-Gonnard7831b0c2013-09-20 12:29:56 +020036
Rich Evans18b78c72015-02-11 14:06:19 +000037#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
Valerio Setti791bbe62023-01-11 10:40:18 +010040#include <errno.h>
Rich Evans18b78c72015-02-11 14:06:19 +000041
Nicholas Wilson8e5bdfb2015-09-09 19:03:34 +010042#define SET_OID(x, oid) \
Gilles Peskine449bd832023-01-11 14:50:10 +010043 do { x.len = MBEDTLS_OID_SIZE(oid); x.p = (unsigned char *) oid; } while (0)
Nicholas Wilson8e5bdfb2015-09-09 19:03:34 +010044
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_X509_CSR_PARSE_C)
Rich Evans18b78c72015-02-11 14:06:19 +000046#define USAGE_CSR \
Hanno Becker81535d02017-09-13 15:39:59 +010047 " request_file=%%s default: (empty)\n" \
48 " If request_file is specified, subject_key,\n" \
49 " subject_pwd and subject_name are ignored!\n"
Rich Evans18b78c72015-02-11 14:06:19 +000050#else
51#define USAGE_CSR ""
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052#endif /* MBEDTLS_X509_CSR_PARSE_C */
Rich Evans18b78c72015-02-11 14:06:19 +000053
Dave Rodgman66e05502022-10-27 16:29:38 +010054#define FORMAT_PEM 0
55#define FORMAT_DER 1
56
Paul Bakker1014e952013-09-09 13:59:42 +020057#define DFL_ISSUER_CRT ""
Paul Bakkere2673fb2013-09-09 15:52:07 +020058#define DFL_REQUEST_FILE ""
Paul Bakker9397dcb2013-09-06 09:55:26 +020059#define DFL_SUBJECT_KEY "subject.key"
60#define DFL_ISSUER_KEY "ca.key"
61#define DFL_SUBJECT_PWD ""
62#define DFL_ISSUER_PWD ""
63#define DFL_OUTPUT_FILENAME "cert.crt"
Manuel Pégourié-Gonnard91699212015-01-22 16:26:39 +000064#define DFL_SUBJECT_NAME "CN=Cert,O=mbed TLS,C=UK"
65#define DFL_ISSUER_NAME "CN=CA,O=mbed TLS,C=UK"
Paul Bakker9397dcb2013-09-06 09:55:26 +020066#define DFL_NOT_BEFORE "20010101000000"
67#define DFL_NOT_AFTER "20301231235959"
68#define DFL_SERIAL "1"
Valerio Setti791bbe62023-01-11 10:40:18 +010069#define DFL_SERIAL_HEX "1"
Andrzej Kurekccdd9752023-04-01 10:38:30 -040070#define DFL_EXT_SUBJECTALTNAME ""
Paul Bakkerb2d7f232013-09-09 16:24:18 +020071#define DFL_SELFSIGN 0
Paul Bakker15162a02013-09-06 19:27:21 +020072#define DFL_IS_CA 0
73#define DFL_MAX_PATHLEN -1
Nicholas Wilson99a96b12015-09-10 18:28:01 +010074#define DFL_SIG_ALG MBEDTLS_MD_SHA256
Paul Bakker9397dcb2013-09-06 09:55:26 +020075#define DFL_KEY_USAGE 0
Dave Rodgman1577c542022-09-09 10:22:15 +010076#define DFL_EXT_KEY_USAGE NULL
Paul Bakker9397dcb2013-09-06 09:55:26 +020077#define DFL_NS_CERT_TYPE 0
Hanno Becker6c13d372017-09-13 12:49:22 +010078#define DFL_VERSION 3
79#define DFL_AUTH_IDENT 1
80#define DFL_SUBJ_IDENT 1
81#define DFL_CONSTRAINTS 1
82#define DFL_DIGEST MBEDTLS_MD_SHA256
Dave Rodgman66e05502022-10-27 16:29:38 +010083#define DFL_FORMAT FORMAT_PEM
Paul Bakker9397dcb2013-09-06 09:55:26 +020084
Rich Evans18b78c72015-02-11 14:06:19 +000085#define USAGE \
86 "\n usage: cert_write param=<>...\n" \
87 "\n acceptable parameters:\n" \
88 USAGE_CSR \
Hanno Becker81535d02017-09-13 15:39:59 +010089 " subject_key=%%s default: subject.key\n" \
90 " subject_pwd=%%s default: (empty)\n" \
91 " subject_name=%%s default: CN=Cert,O=mbed TLS,C=UK\n" \
Rich Evans18b78c72015-02-11 14:06:19 +000092 "\n" \
Hanno Becker81535d02017-09-13 15:39:59 +010093 " issuer_crt=%%s default: (empty)\n" \
94 " If issuer_crt is specified, issuer_name is\n" \
95 " ignored!\n" \
96 " issuer_name=%%s default: CN=CA,O=mbed TLS,C=UK\n" \
Rich Evans18b78c72015-02-11 14:06:19 +000097 "\n" \
Hanno Becker81535d02017-09-13 15:39:59 +010098 " selfsign=%%d default: 0 (false)\n" \
99 " If selfsign is enabled, issuer_name and\n" \
100 " issuer_key are required (issuer_crt and\n" \
101 " subject_* are ignored\n" \
102 " issuer_key=%%s default: ca.key\n" \
103 " issuer_pwd=%%s default: (empty)\n" \
104 " output_file=%%s default: cert.crt\n" \
105 " serial=%%s default: 1\n" \
Valerio Setti791bbe62023-01-11 10:40:18 +0100106 " In decimal format; it can be used as\n" \
107 " alternative to serial_hex, but it's\n" \
108 " limited in max length to\n" \
109 " unsigned long long int\n" \
110 " serial_hex=%%s default: 1\n" \
111 " In hex format; it can be used as\n" \
112 " alternative to serial\n" \
Gilles Peskine449bd832023-01-11 14:50:10 +0100113 " not_before=%%s default: 20010101000000\n" \
114 " not_after=%%s default: 20301231235959\n" \
Hanno Becker81535d02017-09-13 15:39:59 +0100115 " is_ca=%%d default: 0 (disabled)\n" \
116 " max_pathlen=%%d default: -1 (none)\n" \
117 " md=%%s default: SHA256\n" \
Gilles Peskine18292fe2020-08-21 20:42:32 +0200118 " Supported values (if enabled):\n" \
TRodziewicz10e8cf52021-05-31 17:58:57 +0200119 " MD5, RIPEMD160, SHA1,\n" \
Gilles Peskine18292fe2020-08-21 20:42:32 +0200120 " SHA224, SHA256, SHA384, SHA512\n" \
Hanno Becker81535d02017-09-13 15:39:59 +0100121 " version=%%d default: 3\n" \
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 " Possible values: 1, 2, 3\n" \
Hanno Becker81535d02017-09-13 15:39:59 +0100123 " subject_identifier=%%s default: 1\n" \
124 " Possible values: 0, 1\n" \
Gilles Peskine449bd832023-01-11 14:50:10 +0100125 " (Considered for v3 only)\n" \
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400126 " san=%%s default: (none)\n" \
Andrzej Kurekf70f4602023-04-24 18:39:53 -0400127 " Semicolon-separated-list of values:\n" \
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400128 " DNS:value\n" \
129 " URI:value\n" \
130 " RFC822:value\n" \
131 " IP:value (Only IPv4 is supported)\n" \
Andrzej Kurek446e53d2023-04-25 02:21:07 -0400132 " DN:list of comma separated key=value pairs\n" \
Hanno Becker81535d02017-09-13 15:39:59 +0100133 " authority_identifier=%%s default: 1\n" \
134 " Possible values: 0, 1\n" \
Gilles Peskine449bd832023-01-11 14:50:10 +0100135 " (Considered for v3 only)\n" \
Hanno Becker81535d02017-09-13 15:39:59 +0100136 " basic_constraints=%%d default: 1\n" \
137 " Possible values: 0, 1\n" \
Gilles Peskine449bd832023-01-11 14:50:10 +0100138 " (Considered for v3 only)\n" \
Hanno Becker81535d02017-09-13 15:39:59 +0100139 " key_usage=%%s default: (empty)\n" \
140 " Comma-separated-list of values:\n" \
141 " digital_signature\n" \
142 " non_repudiation\n" \
143 " key_encipherment\n" \
144 " data_encipherment\n" \
145 " key_agreement\n" \
146 " key_cert_sign\n" \
147 " crl_sign\n" \
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 " (Considered for v3 only)\n" \
Nicholas Wilson8e5bdfb2015-09-09 19:03:34 +0100149 " ext_key_usage=%%s default: (empty)\n" \
150 " Comma-separated-list of values:\n" \
151 " serverAuth\n" \
152 " clientAuth\n" \
153 " codeSigning\n" \
154 " emailProtection\n" \
155 " timeStamping\n" \
156 " OCSPSigning\n" \
Hanno Becker81535d02017-09-13 15:39:59 +0100157 " ns_cert_type=%%s default: (empty)\n" \
158 " Comma-separated-list of values:\n" \
159 " ssl_client\n" \
160 " ssl_server\n" \
161 " email\n" \
162 " object_signing\n" \
163 " ssl_ca\n" \
164 " email_ca\n" \
165 " object_signing_ca\n" \
Dave Rodgman66e05502022-10-27 16:29:38 +0100166 " format=pem|der default: pem\n" \
Rich Evans18b78c72015-02-11 14:06:19 +0000167 "\n"
Manuel Pégourié-Gonnard6c5abfa2015-02-13 14:12:07 +0000168
Valerio Setti791bbe62023-01-11 10:40:18 +0100169typedef enum {
170 SERIAL_FRMT_UNSPEC,
171 SERIAL_FRMT_DEC,
172 SERIAL_FRMT_HEX
173} serial_format_t;
Simon Butcher63cb97e2018-12-06 17:43:31 +0000174
Paul Bakker9397dcb2013-09-06 09:55:26 +0200175/*
176 * global options
177 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100178struct options {
Paul Bakker8fc30b12013-11-25 13:29:43 +0100179 const char *issuer_crt; /* filename of the issuer certificate */
180 const char *request_file; /* filename of the certificate request */
181 const char *subject_key; /* filename of the subject key file */
182 const char *issuer_key; /* filename of the issuer key file */
183 const char *subject_pwd; /* password for the subject key file */
184 const char *issuer_pwd; /* password for the issuer key file */
Hanno Becker25d882b2018-08-23 15:26:06 +0100185 const char *output_file; /* where to store the constructed CRT */
Paul Bakker8fc30b12013-11-25 13:29:43 +0100186 const char *subject_name; /* subject name for certificate */
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400187 mbedtls_x509_san_list *san_list; /* subjectAltName for certificate */
Paul Bakker8fc30b12013-11-25 13:29:43 +0100188 const char *issuer_name; /* issuer name for certificate */
189 const char *not_before; /* validity period not before */
190 const char *not_after; /* validity period not after */
Valerio Setti791bbe62023-01-11 10:40:18 +0100191 const char *serial; /* serial number string (decimal) */
192 const char *serial_hex; /* serial number string (hex) */
Paul Bakkerb2d7f232013-09-09 16:24:18 +0200193 int selfsign; /* selfsign the certificate */
Paul Bakker15162a02013-09-06 19:27:21 +0200194 int is_ca; /* is a CA certificate */
195 int max_pathlen; /* maximum CA path length */
Hanno Beckere1b1d0a2017-09-22 15:35:16 +0100196 int authority_identifier; /* add authority identifier to CRT */
197 int subject_identifier; /* add subject identifier to CRT */
Hanno Becker6c13d372017-09-13 12:49:22 +0100198 int basic_constraints; /* add basic constraints ext to CRT */
199 int version; /* CRT version */
200 mbedtls_md_type_t md; /* Hash used for signing */
Paul Bakker9397dcb2013-09-06 09:55:26 +0200201 unsigned char key_usage; /* key usage flags */
Nicholas Wilson8e5bdfb2015-09-09 19:03:34 +0100202 mbedtls_asn1_sequence *ext_key_usage; /* extended key usages */
Paul Bakker9397dcb2013-09-06 09:55:26 +0200203 unsigned char ns_cert_type; /* NS cert type */
Dave Rodgman66e05502022-10-27 16:29:38 +0100204 int format; /* format */
Paul Bakker9397dcb2013-09-06 09:55:26 +0200205} opt;
206
Michael Schuster6fa32fd2024-06-01 21:15:02 +0200207static int write_certificate(mbedtls_x509write_cert *crt, const char *output_file,
Michael Schuster82984bc2024-06-12 00:05:25 +0200208 int (*f_rng)(void *, unsigned char *, size_t),
209 void *p_rng)
Paul Bakker9397dcb2013-09-06 09:55:26 +0200210{
211 int ret;
212 FILE *f;
213 unsigned char output_buf[4096];
Dave Rodgman66e05502022-10-27 16:29:38 +0100214 unsigned char *output_start;
Paul Bakker9397dcb2013-09-06 09:55:26 +0200215 size_t len = 0;
216
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 memset(output_buf, 0, 4096);
218 if (opt.format == FORMAT_DER) {
219 ret = mbedtls_x509write_crt_der(crt, output_buf, 4096,
220 f_rng, p_rng);
221 if (ret < 0) {
222 return ret;
223 }
Paul Bakker9397dcb2013-09-06 09:55:26 +0200224
Dave Rodgman66e05502022-10-27 16:29:38 +0100225 len = ret;
226 output_start = output_buf + 4096 - len;
227 } else {
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 ret = mbedtls_x509write_crt_pem(crt, output_buf, 4096,
229 f_rng, p_rng);
230 if (ret < 0) {
231 return ret;
232 }
Dave Rodgman66e05502022-10-27 16:29:38 +0100233
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 len = strlen((char *) output_buf);
Dave Rodgman66e05502022-10-27 16:29:38 +0100235 output_start = output_buf;
236 }
Paul Bakker9397dcb2013-09-06 09:55:26 +0200237
Gilles Peskine449bd832023-01-11 14:50:10 +0100238 if ((f = fopen(output_file, "w")) == NULL) {
239 return -1;
Paul Bakker0c226102014-04-17 16:02:36 +0200240 }
Paul Bakker9397dcb2013-09-06 09:55:26 +0200241
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 if (fwrite(output_start, 1, len, f) != len) {
243 fclose(f);
244 return -1;
245 }
Paul Bakker9397dcb2013-09-06 09:55:26 +0200246
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 fclose(f);
248
249 return 0;
Paul Bakker9397dcb2013-09-06 09:55:26 +0200250}
251
Michael Schuster6fa32fd2024-06-01 21:15:02 +0200252static int parse_serial_decimal_format(unsigned char *obuf, size_t obufmax,
Michael Schuster82984bc2024-06-12 00:05:25 +0200253 const char *ibuf, size_t *len)
Valerio Settiacf12fb2023-01-09 17:19:26 +0100254{
Valerio Setti791bbe62023-01-11 10:40:18 +0100255 unsigned long long int dec;
256 unsigned int remaining_bytes = sizeof(dec);
257 unsigned char *p = obuf;
Valerio Settiacf12fb2023-01-09 17:19:26 +0100258 unsigned char val;
Valerio Setti791bbe62023-01-11 10:40:18 +0100259 char *end_ptr = NULL;
Valerio Settiacf12fb2023-01-09 17:19:26 +0100260
Valerio Setti791bbe62023-01-11 10:40:18 +0100261 errno = 0;
262 dec = strtoull(ibuf, &end_ptr, 10);
263
264 if ((errno != 0) || (end_ptr == ibuf)) {
Valerio Settiacf12fb2023-01-09 17:19:26 +0100265 return -1;
266 }
267
Valerio Setti791bbe62023-01-11 10:40:18 +0100268 *len = 0;
Valerio Settiacf12fb2023-01-09 17:19:26 +0100269
Valerio Setti791bbe62023-01-11 10:40:18 +0100270 while (remaining_bytes > 0) {
271 if (obufmax < (*len + 1)) {
Valerio Settiacf12fb2023-01-09 17:19:26 +0100272 return -1;
273 }
274
Valerio Setti791bbe62023-01-11 10:40:18 +0100275 val = (dec >> ((remaining_bytes - 1) * 8)) & 0xFF;
276
277 /* Skip leading zeros */
Valerio Setti48fdbb32023-01-12 15:31:35 +0100278 if ((val != 0) || (*len != 0)) {
Valerio Setti791bbe62023-01-11 10:40:18 +0100279 *p = val;
280 (*len)++;
281 p++;
282 }
283
284 remaining_bytes--;
Valerio Settiacf12fb2023-01-09 17:19:26 +0100285 }
286
287 return 0;
288}
289
Gilles Peskine449bd832023-01-11 14:50:10 +0100290int main(int argc, char *argv[])
Paul Bakker9397dcb2013-09-06 09:55:26 +0200291{
Andres Amaya Garciaf9a54d32018-04-29 21:42:45 +0100292 int ret = 1;
293 int exit_code = MBEDTLS_EXIT_FAILURE;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200294 mbedtls_x509_crt issuer_crt;
295 mbedtls_pk_context loaded_issuer_key, loaded_subject_key;
296 mbedtls_pk_context *issuer_key = &loaded_issuer_key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100297 *subject_key = &loaded_subject_key;
Paul Bakker9397dcb2013-09-06 09:55:26 +0200298 char buf[1024];
Jonathan Leroybbc75d92015-10-10 21:58:07 +0200299 char issuer_name[256];
Paul Bakkerc97f9f62013-11-30 15:13:02 +0100300 int i;
Andrzej Kurek5eebfb82023-04-27 07:50:56 -0400301 char *p, *q, *r;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200302#if defined(MBEDTLS_X509_CSR_PARSE_C)
Jonathan Leroybbc75d92015-10-10 21:58:07 +0200303 char subject_name[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200304 mbedtls_x509_csr csr;
Paul Bakker7fc7fa62013-09-17 14:44:00 +0200305#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200306 mbedtls_x509write_cert crt;
Valerio Setti791bbe62023-01-11 10:40:18 +0100307 serial_format_t serial_frmt = SERIAL_FRMT_UNSPEC;
Valerio Settiacf12fb2023-01-09 17:19:26 +0100308 unsigned char serial[MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN];
309 size_t serial_len;
Nicholas Wilson8e5bdfb2015-09-09 19:03:34 +0100310 mbedtls_asn1_sequence *ext_key_usage;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200311 mbedtls_entropy_context entropy;
312 mbedtls_ctr_drbg_context ctr_drbg;
Manuel Pégourié-Gonnard31e59402013-09-12 05:59:05 +0200313 const char *pers = "crt example app";
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400314 mbedtls_x509_san_list *cur, *prev;
Andrzej Kurek5da1d752023-04-05 08:30:59 -0400315 mbedtls_asn1_named_data *ext_san_dirname = NULL;
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400316 uint8_t ip[4] = { 0 };
Paul Bakker9397dcb2013-09-06 09:55:26 +0200317 /*
318 * Set to sane values
319 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 mbedtls_x509write_crt_init(&crt);
321 mbedtls_pk_init(&loaded_issuer_key);
322 mbedtls_pk_init(&loaded_subject_key);
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 mbedtls_ctr_drbg_init(&ctr_drbg);
324 mbedtls_entropy_init(&entropy);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200325#if defined(MBEDTLS_X509_CSR_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 mbedtls_x509_csr_init(&csr);
Paul Bakker7fc7fa62013-09-17 14:44:00 +0200327#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 mbedtls_x509_crt_init(&issuer_crt);
329 memset(buf, 0, sizeof(buf));
Valerio Setti791bbe62023-01-11 10:40:18 +0100330 memset(serial, 0, sizeof(serial));
Paul Bakker9397dcb2013-09-06 09:55:26 +0200331
Przemek Stekiela0a1c1e2023-04-17 11:10:05 +0200332#if defined(MBEDTLS_USE_PSA_CRYPTO)
333 psa_status_t status = psa_crypto_init();
334 if (status != PSA_SUCCESS) {
335 mbedtls_fprintf(stderr, "Failed to initialize PSA Crypto implementation: %d\n",
336 (int) status);
337 goto exit;
338 }
339#endif /* MBEDTLS_USE_PSA_CRYPTO */
340
Aditya Deshpande644a5c02023-01-30 15:58:50 +0000341 if (argc < 2) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100342usage:
343 mbedtls_printf(USAGE);
Paul Bakker9397dcb2013-09-06 09:55:26 +0200344 goto exit;
345 }
346
Paul Bakker1014e952013-09-09 13:59:42 +0200347 opt.issuer_crt = DFL_ISSUER_CRT;
Paul Bakkere2673fb2013-09-09 15:52:07 +0200348 opt.request_file = DFL_REQUEST_FILE;
Paul Bakker9397dcb2013-09-06 09:55:26 +0200349 opt.subject_key = DFL_SUBJECT_KEY;
350 opt.issuer_key = DFL_ISSUER_KEY;
351 opt.subject_pwd = DFL_SUBJECT_PWD;
352 opt.issuer_pwd = DFL_ISSUER_PWD;
353 opt.output_file = DFL_OUTPUT_FILENAME;
354 opt.subject_name = DFL_SUBJECT_NAME;
355 opt.issuer_name = DFL_ISSUER_NAME;
356 opt.not_before = DFL_NOT_BEFORE;
357 opt.not_after = DFL_NOT_AFTER;
358 opt.serial = DFL_SERIAL;
Valerio Setti791bbe62023-01-11 10:40:18 +0100359 opt.serial_hex = DFL_SERIAL_HEX;
Paul Bakkerb2d7f232013-09-09 16:24:18 +0200360 opt.selfsign = DFL_SELFSIGN;
Paul Bakker15162a02013-09-06 19:27:21 +0200361 opt.is_ca = DFL_IS_CA;
362 opt.max_pathlen = DFL_MAX_PATHLEN;
Paul Bakker9397dcb2013-09-06 09:55:26 +0200363 opt.key_usage = DFL_KEY_USAGE;
Nicholas Wilson8e5bdfb2015-09-09 19:03:34 +0100364 opt.ext_key_usage = DFL_EXT_KEY_USAGE;
Paul Bakker9397dcb2013-09-06 09:55:26 +0200365 opt.ns_cert_type = DFL_NS_CERT_TYPE;
Hanno Becker38eff432017-09-22 15:38:20 +0100366 opt.version = DFL_VERSION - 1;
Hanno Becker6c13d372017-09-13 12:49:22 +0100367 opt.md = DFL_DIGEST;
368 opt.subject_identifier = DFL_SUBJ_IDENT;
369 opt.authority_identifier = DFL_AUTH_IDENT;
370 opt.basic_constraints = DFL_CONSTRAINTS;
Dave Rodgman66e05502022-10-27 16:29:38 +0100371 opt.format = DFL_FORMAT;
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400372 opt.san_list = NULL;
Paul Bakker9397dcb2013-09-06 09:55:26 +0200373
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 for (i = 1; i < argc; i++) {
Paul Bakker9397dcb2013-09-06 09:55:26 +0200375
376 p = argv[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 if ((q = strchr(p, '=')) == NULL) {
Paul Bakker9397dcb2013-09-06 09:55:26 +0200378 goto usage;
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 }
Paul Bakker9397dcb2013-09-06 09:55:26 +0200380 *q++ = '\0';
381
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 if (strcmp(p, "request_file") == 0) {
Paul Bakkere2673fb2013-09-09 15:52:07 +0200383 opt.request_file = q;
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 } else if (strcmp(p, "subject_key") == 0) {
Paul Bakker9397dcb2013-09-06 09:55:26 +0200385 opt.subject_key = q;
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 } else if (strcmp(p, "issuer_key") == 0) {
Paul Bakker9397dcb2013-09-06 09:55:26 +0200387 opt.issuer_key = q;
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 } else if (strcmp(p, "subject_pwd") == 0) {
Paul Bakker9397dcb2013-09-06 09:55:26 +0200389 opt.subject_pwd = q;
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 } else if (strcmp(p, "issuer_pwd") == 0) {
Paul Bakker9397dcb2013-09-06 09:55:26 +0200391 opt.issuer_pwd = q;
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 } else if (strcmp(p, "issuer_crt") == 0) {
Paul Bakker1014e952013-09-09 13:59:42 +0200393 opt.issuer_crt = q;
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 } else if (strcmp(p, "output_file") == 0) {
Paul Bakker9397dcb2013-09-06 09:55:26 +0200395 opt.output_file = q;
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 } else if (strcmp(p, "subject_name") == 0) {
Paul Bakker9397dcb2013-09-06 09:55:26 +0200397 opt.subject_name = q;
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 } else if (strcmp(p, "issuer_name") == 0) {
Paul Bakker9397dcb2013-09-06 09:55:26 +0200399 opt.issuer_name = q;
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 } else if (strcmp(p, "not_before") == 0) {
Paul Bakker9397dcb2013-09-06 09:55:26 +0200401 opt.not_before = q;
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 } else if (strcmp(p, "not_after") == 0) {
Paul Bakker9397dcb2013-09-06 09:55:26 +0200403 opt.not_after = q;
Gilles Peskine449bd832023-01-11 14:50:10 +0100404 } else if (strcmp(p, "serial") == 0) {
Valerio Setti791bbe62023-01-11 10:40:18 +0100405 if (serial_frmt != SERIAL_FRMT_UNSPEC) {
406 mbedtls_printf("Invalid attempt to set the serial more than once\n");
407 goto usage;
408 }
409 serial_frmt = SERIAL_FRMT_DEC;
Paul Bakker9397dcb2013-09-06 09:55:26 +0200410 opt.serial = q;
Valerio Setti791bbe62023-01-11 10:40:18 +0100411 } else if (strcmp(p, "serial_hex") == 0) {
412 if (serial_frmt != SERIAL_FRMT_UNSPEC) {
413 mbedtls_printf("Invalid attempt to set the serial more than once\n");
414 goto usage;
415 }
416 serial_frmt = SERIAL_FRMT_HEX;
417 opt.serial_hex = q;
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 } else if (strcmp(p, "authority_identifier") == 0) {
419 opt.authority_identifier = atoi(q);
420 if (opt.authority_identifier != 0 &&
421 opt.authority_identifier != 1) {
422 mbedtls_printf("Invalid argument for option %s\n", p);
Hanno Becker6c13d372017-09-13 12:49:22 +0100423 goto usage;
424 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 } else if (strcmp(p, "subject_identifier") == 0) {
426 opt.subject_identifier = atoi(q);
427 if (opt.subject_identifier != 0 &&
428 opt.subject_identifier != 1) {
429 mbedtls_printf("Invalid argument for option %s\n", p);
Hanno Becker6c13d372017-09-13 12:49:22 +0100430 goto usage;
431 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 } else if (strcmp(p, "basic_constraints") == 0) {
433 opt.basic_constraints = atoi(q);
434 if (opt.basic_constraints != 0 &&
435 opt.basic_constraints != 1) {
436 mbedtls_printf("Invalid argument for option %s\n", p);
Hanno Becker6c13d372017-09-13 12:49:22 +0100437 goto usage;
438 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100439 } else if (strcmp(p, "md") == 0) {
Gilles Peskine18292fe2020-08-21 20:42:32 +0200440 const mbedtls_md_info_t *md_info =
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 mbedtls_md_info_from_string(q);
442 if (md_info == NULL) {
443 mbedtls_printf("Invalid argument for option %s\n", p);
Hanno Becker6c13d372017-09-13 12:49:22 +0100444 goto usage;
Hanno Becker17c32762017-10-03 14:56:04 +0100445 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100446 opt.md = mbedtls_md_get_type(md_info);
447 } else if (strcmp(p, "version") == 0) {
448 opt.version = atoi(q);
449 if (opt.version < 1 || opt.version > 3) {
450 mbedtls_printf("Invalid argument for option %s\n", p);
Hanno Becker6c13d372017-09-13 12:49:22 +0100451 goto usage;
Hanno Becker17c32762017-10-03 14:56:04 +0100452 }
Hanno Becker38eff432017-09-22 15:38:20 +0100453 opt.version--;
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 } else if (strcmp(p, "selfsign") == 0) {
455 opt.selfsign = atoi(q);
456 if (opt.selfsign < 0 || opt.selfsign > 1) {
457 mbedtls_printf("Invalid argument for option %s\n", p);
Paul Bakkerb2d7f232013-09-09 16:24:18 +0200458 goto usage;
Hanno Becker17c32762017-10-03 14:56:04 +0100459 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 } else if (strcmp(p, "is_ca") == 0) {
461 opt.is_ca = atoi(q);
462 if (opt.is_ca < 0 || opt.is_ca > 1) {
463 mbedtls_printf("Invalid argument for option %s\n", p);
Paul Bakker15162a02013-09-06 19:27:21 +0200464 goto usage;
Hanno Becker17c32762017-10-03 14:56:04 +0100465 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 } else if (strcmp(p, "max_pathlen") == 0) {
467 opt.max_pathlen = atoi(q);
468 if (opt.max_pathlen < -1 || opt.max_pathlen > 127) {
469 mbedtls_printf("Invalid argument for option %s\n", p);
Paul Bakker15162a02013-09-06 19:27:21 +0200470 goto usage;
Hanno Becker17c32762017-10-03 14:56:04 +0100471 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 } else if (strcmp(p, "key_usage") == 0) {
473 while (q != NULL) {
474 if ((r = strchr(q, ',')) != NULL) {
Paul Bakker9397dcb2013-09-06 09:55:26 +0200475 *r++ = '\0';
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 }
Paul Bakker9397dcb2013-09-06 09:55:26 +0200477
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 if (strcmp(q, "digital_signature") == 0) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200479 opt.key_usage |= MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 } else if (strcmp(q, "non_repudiation") == 0) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481 opt.key_usage |= MBEDTLS_X509_KU_NON_REPUDIATION;
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 } else if (strcmp(q, "key_encipherment") == 0) {
Manuel Pégourié-Gonnarde6028c92015-04-20 12:19:02 +0100483 opt.key_usage |= MBEDTLS_X509_KU_KEY_ENCIPHERMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 } else if (strcmp(q, "data_encipherment") == 0) {
Manuel Pégourié-Gonnarde6028c92015-04-20 12:19:02 +0100485 opt.key_usage |= MBEDTLS_X509_KU_DATA_ENCIPHERMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 } else if (strcmp(q, "key_agreement") == 0) {
Manuel Pégourié-Gonnarde6028c92015-04-20 12:19:02 +0100487 opt.key_usage |= MBEDTLS_X509_KU_KEY_AGREEMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100488 } else if (strcmp(q, "key_cert_sign") == 0) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489 opt.key_usage |= MBEDTLS_X509_KU_KEY_CERT_SIGN;
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 } else if (strcmp(q, "crl_sign") == 0) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491 opt.key_usage |= MBEDTLS_X509_KU_CRL_SIGN;
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 } else {
493 mbedtls_printf("Invalid argument for option %s\n", p);
Paul Bakker9397dcb2013-09-06 09:55:26 +0200494 goto usage;
Hanno Becker17c32762017-10-03 14:56:04 +0100495 }
Paul Bakker9397dcb2013-09-06 09:55:26 +0200496
497 q = r;
498 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 } else if (strcmp(p, "ext_key_usage") == 0) {
Dave Rodgman64937852022-08-15 14:12:25 +0100500 mbedtls_asn1_sequence **tail = &opt.ext_key_usage;
501
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 while (q != NULL) {
503 if ((r = strchr(q, ',')) != NULL) {
Nicholas Wilson8e5bdfb2015-09-09 19:03:34 +0100504 *r++ = '\0';
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 }
Nicholas Wilson8e5bdfb2015-09-09 19:03:34 +0100506
Gilles Peskine449bd832023-01-11 14:50:10 +0100507 ext_key_usage = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
Nicholas Wilson8e5bdfb2015-09-09 19:03:34 +0100508 ext_key_usage->buf.tag = MBEDTLS_ASN1_OID;
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 if (strcmp(q, "serverAuth") == 0) {
510 SET_OID(ext_key_usage->buf, MBEDTLS_OID_SERVER_AUTH);
511 } else if (strcmp(q, "clientAuth") == 0) {
512 SET_OID(ext_key_usage->buf, MBEDTLS_OID_CLIENT_AUTH);
513 } else if (strcmp(q, "codeSigning") == 0) {
514 SET_OID(ext_key_usage->buf, MBEDTLS_OID_CODE_SIGNING);
515 } else if (strcmp(q, "emailProtection") == 0) {
516 SET_OID(ext_key_usage->buf, MBEDTLS_OID_EMAIL_PROTECTION);
517 } else if (strcmp(q, "timeStamping") == 0) {
518 SET_OID(ext_key_usage->buf, MBEDTLS_OID_TIME_STAMPING);
519 } else if (strcmp(q, "OCSPSigning") == 0) {
520 SET_OID(ext_key_usage->buf, MBEDTLS_OID_OCSP_SIGNING);
Pengyu Lvb0786072023-05-18 17:18:36 +0800521 } else if (strcmp(q, "any") == 0) {
522 SET_OID(ext_key_usage->buf, MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE);
Gilles Peskine449bd832023-01-11 14:50:10 +0100523 } else {
524 mbedtls_printf("Invalid argument for option %s\n", p);
Nicholas Wilson8e5bdfb2015-09-09 19:03:34 +0100525 goto usage;
Dave Rodgmanc5e0a8a2022-08-15 14:24:22 +0100526 }
Dave Rodgman64937852022-08-15 14:12:25 +0100527
528 *tail = ext_key_usage;
529 tail = &ext_key_usage->next;
Nicholas Wilson8e5bdfb2015-09-09 19:03:34 +0100530
531 q = r;
532 }
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400533 } else if (strcmp(p, "san") == 0) {
Andrzej Kurek5eebfb82023-04-27 07:50:56 -0400534 char *subtype_value;
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400535 prev = NULL;
536
537 while (q != NULL) {
Andrzej Kurek5eebfb82023-04-27 07:50:56 -0400538 char *semicolon;
539 r = q;
540
541 /* Find the first non-escaped ; occurrence and remove escaped ones */
542 do {
543 if ((semicolon = strchr(r, ';')) != NULL) {
544 if (*(semicolon-1) != '\\') {
545 r = semicolon;
546 break;
547 }
548 /* Remove the escape character */
549 size_t size_left = strlen(semicolon);
550 memmove(semicolon-1, semicolon, size_left);
551 *(semicolon + size_left - 1) = '\0';
552 /* r will now point at the character after the semicolon */
553 r = semicolon;
554 }
555
556 } while (semicolon != NULL);
557
558 if (semicolon != NULL) {
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400559 *r++ = '\0';
Andrzej Kurek5eebfb82023-04-27 07:50:56 -0400560 } else {
561 r = NULL;
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400562 }
563
564 cur = mbedtls_calloc(1, sizeof(mbedtls_x509_san_list));
565 if (cur == NULL) {
566 mbedtls_printf("Not enough memory for subjectAltName list\n");
567 goto usage;
568 }
569
570 cur->next = NULL;
571
Andrzej Kurek5eebfb82023-04-27 07:50:56 -0400572 if ((subtype_value = strchr(q, ':')) != NULL) {
573 *subtype_value++ = '\0';
Waleed Elmelegy476c1192023-10-12 14:19:25 +0100574 } else {
Waleed Elmelegy58674652023-10-13 10:03:12 +0100575 mbedtls_printf(
David Horstmann4a493b22023-10-17 14:57:23 +0100576 "Invalid argument for option SAN: Entry must be of the form TYPE:value\n");
Waleed Elmelegy476c1192023-10-12 14:19:25 +0100577 goto usage;
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400578 }
579 if (strcmp(q, "RFC822") == 0) {
580 cur->node.type = MBEDTLS_X509_SAN_RFC822_NAME;
581 } else if (strcmp(q, "URI") == 0) {
582 cur->node.type = MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER;
583 } else if (strcmp(q, "DNS") == 0) {
584 cur->node.type = MBEDTLS_X509_SAN_DNS_NAME;
585 } else if (strcmp(q, "IP") == 0) {
Tom Cosgrove656d4b32023-12-08 21:51:15 +0000586 size_t ip_addr_len = 0;
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400587 cur->node.type = MBEDTLS_X509_SAN_IP_ADDRESS;
Tom Cosgrove656d4b32023-12-08 21:51:15 +0000588 ip_addr_len = mbedtls_x509_crt_parse_cn_inet_pton(subtype_value, ip);
589 if (ip_addr_len == 0) {
Andrzej Kurekcd17ecf2023-06-05 17:02:17 -0400590 mbedtls_printf("mbedtls_x509_crt_parse_cn_inet_pton failed to parse %s\n",
591 subtype_value);
592 goto exit;
593 }
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400594 cur->node.san.unstructured_name.p = (unsigned char *) ip;
595 cur->node.san.unstructured_name.len = sizeof(ip);
596 } else if (strcmp(q, "DN") == 0) {
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400597 cur->node.type = MBEDTLS_X509_SAN_DIRECTORY_NAME;
598 if ((ret = mbedtls_x509_string_to_names(&ext_san_dirname,
Andrzej Kurek5eebfb82023-04-27 07:50:56 -0400599 subtype_value)) != 0) {
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400600 mbedtls_strerror(ret, buf, sizeof(buf));
601 mbedtls_printf(
602 " failed\n ! mbedtls_x509_string_to_names "
603 "returned -0x%04x - %s\n\n",
604 (unsigned int) -ret, buf);
605 goto exit;
606 }
607 cur->node.san.directory_name = *ext_san_dirname;
608 } else {
609 mbedtls_free(cur);
610 goto usage;
611 }
612
Andrzej Kurekf994bc52023-06-02 05:10:17 -0400613 if (cur->node.type == MBEDTLS_X509_SAN_RFC822_NAME ||
614 cur->node.type == MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER ||
615 cur->node.type == MBEDTLS_X509_SAN_DNS_NAME) {
Andrzej Kurekcd17ecf2023-06-05 17:02:17 -0400616 q = subtype_value;
617 cur->node.san.unstructured_name.p = (unsigned char *) q;
618 cur->node.san.unstructured_name.len = strlen(q);
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400619 }
620
621 if (prev == NULL) {
622 opt.san_list = cur;
623 } else {
624 prev->next = cur;
625 }
626
627 prev = cur;
628 q = r;
629 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 } else if (strcmp(p, "ns_cert_type") == 0) {
631 while (q != NULL) {
632 if ((r = strchr(q, ',')) != NULL) {
Paul Bakker9397dcb2013-09-06 09:55:26 +0200633 *r++ = '\0';
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 }
Paul Bakker9397dcb2013-09-06 09:55:26 +0200635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 if (strcmp(q, "ssl_client") == 0) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637 opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 } else if (strcmp(q, "ssl_server") == 0) {
Manuel Pégourié-Gonnarde6028c92015-04-20 12:19:02 +0100639 opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER;
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 } else if (strcmp(q, "email") == 0) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200641 opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_EMAIL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 } else if (strcmp(q, "object_signing") == 0) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643 opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING;
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 } else if (strcmp(q, "ssl_ca") == 0) {
Manuel Pégourié-Gonnarde6028c92015-04-20 12:19:02 +0100645 opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_SSL_CA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 } else if (strcmp(q, "email_ca") == 0) {
Manuel Pégourié-Gonnarde6028c92015-04-20 12:19:02 +0100647 opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 } else if (strcmp(q, "object_signing_ca") == 0) {
Manuel Pégourié-Gonnarde6028c92015-04-20 12:19:02 +0100649 opt.ns_cert_type |= MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 } else {
651 mbedtls_printf("Invalid argument for option %s\n", p);
Paul Bakker9397dcb2013-09-06 09:55:26 +0200652 goto usage;
Hanno Becker17c32762017-10-03 14:56:04 +0100653 }
Paul Bakker9397dcb2013-09-06 09:55:26 +0200654
655 q = r;
656 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 } else if (strcmp(p, "format") == 0) {
658 if (strcmp(q, "der") == 0) {
659 opt.format = FORMAT_DER;
660 } else if (strcmp(q, "pem") == 0) {
661 opt.format = FORMAT_PEM;
662 } else {
663 mbedtls_printf("Invalid argument for option %s\n", p);
Dave Rodgman66e05502022-10-27 16:29:38 +0100664 goto usage;
665 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 } else {
Paul Bakker9397dcb2013-09-06 09:55:26 +0200667 goto usage;
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 }
Paul Bakker9397dcb2013-09-06 09:55:26 +0200669 }
670
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200671 mbedtls_printf("\n");
Paul Bakker1014e952013-09-09 13:59:42 +0200672
Manuel Pégourié-Gonnard31e59402013-09-12 05:59:05 +0200673 /*
674 * 0. Seed the PRNG
675 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100676 mbedtls_printf(" . Seeding the random number generator...");
677 fflush(stdout);
Manuel Pégourié-Gonnard31e59402013-09-12 05:59:05 +0200678
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
680 (const unsigned char *) pers,
681 strlen(pers))) != 0) {
682 mbedtls_strerror(ret, buf, sizeof(buf));
683 mbedtls_printf(" failed\n ! mbedtls_ctr_drbg_seed returned %d - %s\n",
684 ret, buf);
Manuel Pégourié-Gonnard31e59402013-09-12 05:59:05 +0200685 goto exit;
686 }
687
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 mbedtls_printf(" ok\n");
Manuel Pégourié-Gonnard31e59402013-09-12 05:59:05 +0200689
Paul Bakker9397dcb2013-09-06 09:55:26 +0200690 // Parse serial to MPI
691 //
Gilles Peskine449bd832023-01-11 14:50:10 +0100692 mbedtls_printf(" . Reading serial number...");
693 fflush(stdout);
Manuel Pégourié-Gonnard31e59402013-09-12 05:59:05 +0200694
Valerio Setti791bbe62023-01-11 10:40:18 +0100695 if (serial_frmt == SERIAL_FRMT_HEX) {
696 ret = mbedtls_test_unhexify(serial, sizeof(serial),
697 opt.serial_hex, &serial_len);
698 } else { // SERIAL_FRMT_DEC || SERIAL_FRMT_UNSPEC
699 ret = parse_serial_decimal_format(serial, sizeof(serial),
700 opt.serial, &serial_len);
701 }
702
703 if (ret != 0) {
704 mbedtls_printf(" failed\n ! Unable to parse serial\n");
705 goto exit;
706 }
707
Gilles Peskine449bd832023-01-11 14:50:10 +0100708 mbedtls_printf(" ok\n");
Manuel Pégourié-Gonnard31e59402013-09-12 05:59:05 +0200709
Paul Bakker1014e952013-09-09 13:59:42 +0200710 // Parse issuer certificate if present
711 //
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 if (!opt.selfsign && strlen(opt.issuer_crt)) {
Paul Bakker1014e952013-09-09 13:59:42 +0200713 /*
Paul Bakkere2673fb2013-09-09 15:52:07 +0200714 * 1.0.a. Load the certificates
Paul Bakker1014e952013-09-09 13:59:42 +0200715 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 mbedtls_printf(" . Loading the issuer certificate ...");
717 fflush(stdout);
Paul Bakker1014e952013-09-09 13:59:42 +0200718
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 if ((ret = mbedtls_x509_crt_parse_file(&issuer_crt, opt.issuer_crt)) != 0) {
720 mbedtls_strerror(ret, buf, sizeof(buf));
721 mbedtls_printf(" failed\n ! mbedtls_x509_crt_parse_file "
722 "returned -0x%04x - %s\n\n", (unsigned int) -ret, buf);
Paul Bakker1014e952013-09-09 13:59:42 +0200723 goto exit;
724 }
725
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 ret = mbedtls_x509_dn_gets(issuer_name, sizeof(issuer_name),
727 &issuer_crt.subject);
728 if (ret < 0) {
729 mbedtls_strerror(ret, buf, sizeof(buf));
730 mbedtls_printf(" failed\n ! mbedtls_x509_dn_gets "
731 "returned -0x%04x - %s\n\n", (unsigned int) -ret, buf);
Paul Bakker1014e952013-09-09 13:59:42 +0200732 goto exit;
733 }
734
Paul Bakkere2673fb2013-09-09 15:52:07 +0200735 opt.issuer_name = issuer_name;
736
Gilles Peskine449bd832023-01-11 14:50:10 +0100737 mbedtls_printf(" ok\n");
Paul Bakkere2673fb2013-09-09 15:52:07 +0200738 }
739
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200740#if defined(MBEDTLS_X509_CSR_PARSE_C)
Paul Bakkere2673fb2013-09-09 15:52:07 +0200741 // Parse certificate request if present
742 //
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 if (!opt.selfsign && strlen(opt.request_file)) {
Paul Bakkere2673fb2013-09-09 15:52:07 +0200744 /*
745 * 1.0.b. Load the CSR
746 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 mbedtls_printf(" . Loading the certificate request ...");
748 fflush(stdout);
Paul Bakkere2673fb2013-09-09 15:52:07 +0200749
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 if ((ret = mbedtls_x509_csr_parse_file(&csr, opt.request_file)) != 0) {
751 mbedtls_strerror(ret, buf, sizeof(buf));
752 mbedtls_printf(" failed\n ! mbedtls_x509_csr_parse_file "
753 "returned -0x%04x - %s\n\n", (unsigned int) -ret, buf);
Paul Bakkere2673fb2013-09-09 15:52:07 +0200754 goto exit;
755 }
756
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 ret = mbedtls_x509_dn_gets(subject_name, sizeof(subject_name),
758 &csr.subject);
759 if (ret < 0) {
760 mbedtls_strerror(ret, buf, sizeof(buf));
761 mbedtls_printf(" failed\n ! mbedtls_x509_dn_gets "
762 "returned -0x%04x - %s\n\n", (unsigned int) -ret, buf);
Paul Bakkere2673fb2013-09-09 15:52:07 +0200763 goto exit;
764 }
765
766 opt.subject_name = subject_name;
Gilles Peskine842edf42021-08-04 21:56:10 +0200767 subject_key = &csr.pk;
Paul Bakkere2673fb2013-09-09 15:52:07 +0200768
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 mbedtls_printf(" ok\n");
Paul Bakkerb2d7f232013-09-09 16:24:18 +0200770 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200771#endif /* MBEDTLS_X509_CSR_PARSE_C */
Paul Bakkerb2d7f232013-09-09 16:24:18 +0200772
773 /*
774 * 1.1. Load the keys
775 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 if (!opt.selfsign && !strlen(opt.request_file)) {
777 mbedtls_printf(" . Loading the subject key ...");
778 fflush(stdout);
Paul Bakkerb2d7f232013-09-09 16:24:18 +0200779
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 ret = mbedtls_pk_parse_keyfile(&loaded_subject_key, opt.subject_key,
781 opt.subject_pwd, mbedtls_ctr_drbg_random, &ctr_drbg);
782 if (ret != 0) {
783 mbedtls_strerror(ret, buf, sizeof(buf));
784 mbedtls_printf(" failed\n ! mbedtls_pk_parse_keyfile "
785 "returned -0x%04x - %s\n\n", (unsigned int) -ret, buf);
Paul Bakkere2673fb2013-09-09 15:52:07 +0200786 goto exit;
787 }
Paul Bakker1014e952013-09-09 13:59:42 +0200788
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 mbedtls_printf(" ok\n");
Paul Bakker1014e952013-09-09 13:59:42 +0200790 }
791
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 mbedtls_printf(" . Loading the issuer key ...");
793 fflush(stdout);
Paul Bakkerb2d7f232013-09-09 16:24:18 +0200794
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 ret = mbedtls_pk_parse_keyfile(&loaded_issuer_key, opt.issuer_key,
796 opt.issuer_pwd, mbedtls_ctr_drbg_random, &ctr_drbg);
797 if (ret != 0) {
798 mbedtls_strerror(ret, buf, sizeof(buf));
799 mbedtls_printf(" failed\n ! mbedtls_pk_parse_keyfile "
800 "returned -x%02x - %s\n\n", (unsigned int) -ret, buf);
Paul Bakkerb2d7f232013-09-09 16:24:18 +0200801 goto exit;
802 }
803
804 // Check if key and issuer certificate match
805 //
Gilles Peskine449bd832023-01-11 14:50:10 +0100806 if (strlen(opt.issuer_crt)) {
807 if (mbedtls_pk_check_pair(&issuer_crt.pk, issuer_key,
808 mbedtls_ctr_drbg_random, &ctr_drbg) != 0) {
809 mbedtls_printf(" failed\n ! issuer_key does not match "
810 "issuer certificate\n\n");
Paul Bakkerb2d7f232013-09-09 16:24:18 +0200811 goto exit;
812 }
813 }
814
Gilles Peskine449bd832023-01-11 14:50:10 +0100815 mbedtls_printf(" ok\n");
Paul Bakkerb2d7f232013-09-09 16:24:18 +0200816
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 if (opt.selfsign) {
Paul Bakker93c6aa42013-10-28 22:28:09 +0100818 opt.subject_name = opt.issuer_name;
Manuel Pégourié-Gonnardf38e71a2013-09-12 05:21:54 +0200819 subject_key = issuer_key;
Paul Bakkerb2d7f232013-09-09 16:24:18 +0200820 }
821
Gilles Peskine449bd832023-01-11 14:50:10 +0100822 mbedtls_x509write_crt_set_subject_key(&crt, subject_key);
823 mbedtls_x509write_crt_set_issuer_key(&crt, issuer_key);
Paul Bakkerb2d7f232013-09-09 16:24:18 +0200824
Paul Bakker9397dcb2013-09-06 09:55:26 +0200825 /*
826 * 1.0. Check the names for validity
827 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 if ((ret = mbedtls_x509write_crt_set_subject_name(&crt, opt.subject_name)) != 0) {
829 mbedtls_strerror(ret, buf, sizeof(buf));
830 mbedtls_printf(" failed\n ! mbedtls_x509write_crt_set_subject_name "
831 "returned -0x%04x - %s\n\n", (unsigned int) -ret, buf);
Paul Bakker9397dcb2013-09-06 09:55:26 +0200832 goto exit;
833 }
834
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 if ((ret = mbedtls_x509write_crt_set_issuer_name(&crt, opt.issuer_name)) != 0) {
836 mbedtls_strerror(ret, buf, sizeof(buf));
837 mbedtls_printf(" failed\n ! mbedtls_x509write_crt_set_issuer_name "
838 "returned -0x%04x - %s\n\n", (unsigned int) -ret, buf);
Paul Bakker9397dcb2013-09-06 09:55:26 +0200839 goto exit;
840 }
841
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 mbedtls_printf(" . Setting certificate values ...");
843 fflush(stdout);
Paul Bakker9397dcb2013-09-06 09:55:26 +0200844
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 mbedtls_x509write_crt_set_version(&crt, opt.version);
846 mbedtls_x509write_crt_set_md_alg(&crt, opt.md);
Hanno Becker6c13d372017-09-13 12:49:22 +0100847
Valerio Settiaf4815c2023-01-26 17:43:09 +0100848 ret = mbedtls_x509write_crt_set_serial_raw(&crt, serial, serial_len);
Valerio Settida0afcc2023-01-05 16:46:59 +0100849 if (ret != 0) {
850 mbedtls_strerror(ret, buf, sizeof(buf));
Valerio Settiaf4815c2023-01-26 17:43:09 +0100851 mbedtls_printf(" failed\n ! mbedtls_x509write_crt_set_serial_raw "
Valerio Settida0afcc2023-01-05 16:46:59 +0100852 "returned -0x%04x - %s\n\n", (unsigned int) -ret, buf);
853 goto exit;
854 }
Paul Bakker9397dcb2013-09-06 09:55:26 +0200855
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 ret = mbedtls_x509write_crt_set_validity(&crt, opt.not_before, opt.not_after);
857 if (ret != 0) {
858 mbedtls_strerror(ret, buf, sizeof(buf));
859 mbedtls_printf(" failed\n ! mbedtls_x509write_crt_set_validity "
860 "returned -0x%04x - %s\n\n", (unsigned int) -ret, buf);
Paul Bakker9397dcb2013-09-06 09:55:26 +0200861 goto exit;
862 }
863
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 mbedtls_printf(" ok\n");
Paul Bakker9397dcb2013-09-06 09:55:26 +0200865
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 if (opt.version == MBEDTLS_X509_CRT_VERSION_3 &&
867 opt.basic_constraints != 0) {
868 mbedtls_printf(" . Adding the Basic Constraints extension ...");
869 fflush(stdout);
Paul Bakker15162a02013-09-06 19:27:21 +0200870
Gilles Peskine449bd832023-01-11 14:50:10 +0100871 ret = mbedtls_x509write_crt_set_basic_constraints(&crt, opt.is_ca,
872 opt.max_pathlen);
873 if (ret != 0) {
874 mbedtls_strerror(ret, buf, sizeof(buf));
875 mbedtls_printf(" failed\n ! x509write_crt_set_basic_constraints "
876 "returned -0x%04x - %s\n\n", (unsigned int) -ret, buf);
Hanno Becker6c13d372017-09-13 12:49:22 +0100877 goto exit;
878 }
879
Gilles Peskine449bd832023-01-11 14:50:10 +0100880 mbedtls_printf(" ok\n");
Hanno Becker6c13d372017-09-13 12:49:22 +0100881 }
Paul Bakker15162a02013-09-06 19:27:21 +0200882
Manuel Pégourié-Gonnard93302422023-03-21 17:23:08 +0100883#if defined(MBEDTLS_MD_CAN_SHA1)
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 if (opt.version == MBEDTLS_X509_CRT_VERSION_3 &&
885 opt.subject_identifier != 0) {
886 mbedtls_printf(" . Adding the Subject Key Identifier ...");
887 fflush(stdout);
Hanno Becker6c13d372017-09-13 12:49:22 +0100888
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 ret = mbedtls_x509write_crt_set_subject_key_identifier(&crt);
890 if (ret != 0) {
891 mbedtls_strerror(ret, buf, sizeof(buf));
892 mbedtls_printf(" failed\n ! mbedtls_x509write_crt_set_subject"
893 "_key_identifier returned -0x%04x - %s\n\n",
894 (unsigned int) -ret, buf);
Hanno Becker6c13d372017-09-13 12:49:22 +0100895 goto exit;
896 }
897
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 mbedtls_printf(" ok\n");
Paul Bakker15162a02013-09-06 19:27:21 +0200899 }
900
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 if (opt.version == MBEDTLS_X509_CRT_VERSION_3 &&
902 opt.authority_identifier != 0) {
903 mbedtls_printf(" . Adding the Authority Key Identifier ...");
904 fflush(stdout);
Paul Bakker15162a02013-09-06 19:27:21 +0200905
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 ret = mbedtls_x509write_crt_set_authority_key_identifier(&crt);
907 if (ret != 0) {
908 mbedtls_strerror(ret, buf, sizeof(buf));
909 mbedtls_printf(" failed\n ! mbedtls_x509write_crt_set_authority_"
910 "key_identifier returned -0x%04x - %s\n\n",
911 (unsigned int) -ret, buf);
Hanno Becker6c13d372017-09-13 12:49:22 +0100912 goto exit;
913 }
914
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 mbedtls_printf(" ok\n");
Hanno Becker6c13d372017-09-13 12:49:22 +0100916 }
Manuel Pégourié-Gonnard93302422023-03-21 17:23:08 +0100917#endif /* MBEDTLS_MD_CAN_SHA1 */
Paul Bakker15162a02013-09-06 19:27:21 +0200918
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 if (opt.version == MBEDTLS_X509_CRT_VERSION_3 &&
920 opt.key_usage != 0) {
921 mbedtls_printf(" . Adding the Key Usage extension ...");
922 fflush(stdout);
Paul Bakker52be08c2013-09-09 12:37:54 +0200923
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 ret = mbedtls_x509write_crt_set_key_usage(&crt, opt.key_usage);
925 if (ret != 0) {
926 mbedtls_strerror(ret, buf, sizeof(buf));
927 mbedtls_printf(" failed\n ! mbedtls_x509write_crt_set_key_usage "
928 "returned -0x%04x - %s\n\n", (unsigned int) -ret, buf);
Paul Bakker52be08c2013-09-09 12:37:54 +0200929 goto exit;
930 }
931
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 mbedtls_printf(" ok\n");
Paul Bakker52be08c2013-09-09 12:37:54 +0200933 }
934
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400935 if (opt.san_list != NULL) {
936 ret = mbedtls_x509write_crt_set_subject_alternative_name(&crt, opt.san_list);
937
938 if (ret != 0) {
939 mbedtls_printf(
Andrzej Kurek1bc7df22023-04-04 07:09:04 -0400940 " failed\n ! mbedtls_x509write_crt_set_subject_alternative_name returned %d",
Andrzej Kurekccdd9752023-04-01 10:38:30 -0400941 ret);
942 goto exit;
943 }
944 }
945
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 if (opt.ext_key_usage) {
947 mbedtls_printf(" . Adding the Extended Key Usage extension ...");
948 fflush(stdout);
Nicholas Wilson8e5bdfb2015-09-09 19:03:34 +0100949
Gilles Peskine449bd832023-01-11 14:50:10 +0100950 ret = mbedtls_x509write_crt_set_ext_key_usage(&crt, opt.ext_key_usage);
951 if (ret != 0) {
952 mbedtls_strerror(ret, buf, sizeof(buf));
953 mbedtls_printf(
954 " failed\n ! mbedtls_x509write_crt_set_ext_key_usage returned -0x%02x - %s\n\n",
955 (unsigned int) -ret,
956 buf);
Nicholas Wilson8e5bdfb2015-09-09 19:03:34 +0100957 goto exit;
958 }
959
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 mbedtls_printf(" ok\n");
Nicholas Wilson8e5bdfb2015-09-09 19:03:34 +0100961 }
962
Gilles Peskine449bd832023-01-11 14:50:10 +0100963 if (opt.version == MBEDTLS_X509_CRT_VERSION_3 &&
964 opt.ns_cert_type != 0) {
965 mbedtls_printf(" . Adding the NS Cert Type extension ...");
966 fflush(stdout);
Paul Bakker52be08c2013-09-09 12:37:54 +0200967
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 ret = mbedtls_x509write_crt_set_ns_cert_type(&crt, opt.ns_cert_type);
969 if (ret != 0) {
970 mbedtls_strerror(ret, buf, sizeof(buf));
971 mbedtls_printf(" failed\n ! mbedtls_x509write_crt_set_ns_cert_type "
972 "returned -0x%04x - %s\n\n", (unsigned int) -ret, buf);
Paul Bakker52be08c2013-09-09 12:37:54 +0200973 goto exit;
974 }
975
Gilles Peskine449bd832023-01-11 14:50:10 +0100976 mbedtls_printf(" ok\n");
Paul Bakker52be08c2013-09-09 12:37:54 +0200977 }
978
Paul Bakker9397dcb2013-09-06 09:55:26 +0200979 /*
Hanno Becker25d882b2018-08-23 15:26:06 +0100980 * 1.2. Writing the certificate
Paul Bakker9397dcb2013-09-06 09:55:26 +0200981 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 mbedtls_printf(" . Writing the certificate...");
983 fflush(stdout);
Paul Bakker9397dcb2013-09-06 09:55:26 +0200984
Gilles Peskine449bd832023-01-11 14:50:10 +0100985 if ((ret = write_certificate(&crt, opt.output_file,
986 mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) {
987 mbedtls_strerror(ret, buf, sizeof(buf));
988 mbedtls_printf(" failed\n ! write_certificate -0x%04x - %s\n\n",
989 (unsigned int) -ret, buf);
Paul Bakker9397dcb2013-09-06 09:55:26 +0200990 goto exit;
991 }
992
Gilles Peskine449bd832023-01-11 14:50:10 +0100993 mbedtls_printf(" ok\n");
Paul Bakker9397dcb2013-09-06 09:55:26 +0200994
Andres Amaya Garciaf9a54d32018-04-29 21:42:45 +0100995 exit_code = MBEDTLS_EXIT_SUCCESS;
996
Paul Bakker9397dcb2013-09-06 09:55:26 +0200997exit:
Hanno Becker30a95102018-10-05 09:49:33 +0100998#if defined(MBEDTLS_X509_CSR_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 mbedtls_x509_csr_free(&csr);
Hanno Becker30a95102018-10-05 09:49:33 +01001000#endif /* MBEDTLS_X509_CSR_PARSE_C */
Andrzej Kurek5da1d752023-04-05 08:30:59 -04001001 mbedtls_asn1_free_named_data_list(&ext_san_dirname);
Gilles Peskine449bd832023-01-11 14:50:10 +01001002 mbedtls_x509_crt_free(&issuer_crt);
1003 mbedtls_x509write_crt_free(&crt);
1004 mbedtls_pk_free(&loaded_subject_key);
1005 mbedtls_pk_free(&loaded_issuer_key);
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 mbedtls_ctr_drbg_free(&ctr_drbg);
1007 mbedtls_entropy_free(&entropy);
Przemek Stekiel758aef62023-04-19 13:47:43 +02001008#if defined(MBEDTLS_USE_PSA_CRYPTO)
Przemek Stekiela8c560a2023-04-19 10:15:26 +02001009 mbedtls_psa_crypto_free();
Przemek Stekiel758aef62023-04-19 13:47:43 +02001010#endif /* MBEDTLS_USE_PSA_CRYPTO */
Paul Bakker9397dcb2013-09-06 09:55:26 +02001011
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 mbedtls_exit(exit_code);
Paul Bakker9397dcb2013-09-06 09:55:26 +02001013}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001014#endif /* MBEDTLS_X509_CRT_WRITE_C && MBEDTLS_X509_CRT_PARSE_C &&
1015 MBEDTLS_FS_IO && MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C &&
Simon Butcher203a6932016-10-07 15:00:17 +01001016 MBEDTLS_ERROR_C && MBEDTLS_PEM_WRITE_C */