xref: /aosp_15_r20/external/arm-trusted-firmware/tools/cert_create/src/cert.c (revision 54fd6939e177f8ff529b10183254802c76df6d08)
1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park  * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
3*54fd6939SJiyong Park  *
4*54fd6939SJiyong Park  * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park  */
6*54fd6939SJiyong Park 
7*54fd6939SJiyong Park #include <stdio.h>
8*54fd6939SJiyong Park #include <stdlib.h>
9*54fd6939SJiyong Park #include <string.h>
10*54fd6939SJiyong Park 
11*54fd6939SJiyong Park #include <openssl/conf.h>
12*54fd6939SJiyong Park #include <openssl/err.h>
13*54fd6939SJiyong Park #include <openssl/opensslv.h>
14*54fd6939SJiyong Park #include <openssl/pem.h>
15*54fd6939SJiyong Park #include <openssl/sha.h>
16*54fd6939SJiyong Park #include <openssl/x509v3.h>
17*54fd6939SJiyong Park 
18*54fd6939SJiyong Park #include "cert.h"
19*54fd6939SJiyong Park #include "cmd_opt.h"
20*54fd6939SJiyong Park #include "debug.h"
21*54fd6939SJiyong Park #include "key.h"
22*54fd6939SJiyong Park #include "sha.h"
23*54fd6939SJiyong Park 
24*54fd6939SJiyong Park #define SERIAL_RAND_BITS	64
25*54fd6939SJiyong Park #define RSA_SALT_LEN		32
26*54fd6939SJiyong Park 
27*54fd6939SJiyong Park cert_t *certs;
28*54fd6939SJiyong Park unsigned int num_certs;
29*54fd6939SJiyong Park 
rand_serial(BIGNUM * b,ASN1_INTEGER * ai)30*54fd6939SJiyong Park int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
31*54fd6939SJiyong Park {
32*54fd6939SJiyong Park 	BIGNUM *btmp;
33*54fd6939SJiyong Park 	int ret = 0;
34*54fd6939SJiyong Park 	if (b)
35*54fd6939SJiyong Park 		btmp = b;
36*54fd6939SJiyong Park 	else
37*54fd6939SJiyong Park 		btmp = BN_new();
38*54fd6939SJiyong Park 
39*54fd6939SJiyong Park 	if (!btmp)
40*54fd6939SJiyong Park 		return 0;
41*54fd6939SJiyong Park 
42*54fd6939SJiyong Park 	if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
43*54fd6939SJiyong Park 		goto error;
44*54fd6939SJiyong Park 	if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
45*54fd6939SJiyong Park 		goto error;
46*54fd6939SJiyong Park 
47*54fd6939SJiyong Park 	ret = 1;
48*54fd6939SJiyong Park 
49*54fd6939SJiyong Park error:
50*54fd6939SJiyong Park 
51*54fd6939SJiyong Park 	if (!b)
52*54fd6939SJiyong Park 		BN_free(btmp);
53*54fd6939SJiyong Park 
54*54fd6939SJiyong Park 	return ret;
55*54fd6939SJiyong Park }
get_digest(int alg)56*54fd6939SJiyong Park const EVP_MD *get_digest(int alg)
57*54fd6939SJiyong Park {
58*54fd6939SJiyong Park 	switch (alg) {
59*54fd6939SJiyong Park 	case HASH_ALG_SHA256:
60*54fd6939SJiyong Park 		return EVP_sha256();
61*54fd6939SJiyong Park 	case HASH_ALG_SHA384:
62*54fd6939SJiyong Park 		return EVP_sha384();
63*54fd6939SJiyong Park 	case HASH_ALG_SHA512:
64*54fd6939SJiyong Park 		return EVP_sha512();
65*54fd6939SJiyong Park 	default:
66*54fd6939SJiyong Park 		return NULL;
67*54fd6939SJiyong Park 	}
68*54fd6939SJiyong Park }
69*54fd6939SJiyong Park 
cert_add_ext(X509 * issuer,X509 * subject,int nid,char * value)70*54fd6939SJiyong Park int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value)
71*54fd6939SJiyong Park {
72*54fd6939SJiyong Park 	X509_EXTENSION *ex;
73*54fd6939SJiyong Park 	X509V3_CTX ctx;
74*54fd6939SJiyong Park 
75*54fd6939SJiyong Park 	/* No configuration database */
76*54fd6939SJiyong Park 	X509V3_set_ctx_nodb(&ctx);
77*54fd6939SJiyong Park 
78*54fd6939SJiyong Park 	/* Set issuer and subject certificates in the context */
79*54fd6939SJiyong Park 	X509V3_set_ctx(&ctx, issuer, subject, NULL, NULL, 0);
80*54fd6939SJiyong Park 	ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
81*54fd6939SJiyong Park 	if (!ex) {
82*54fd6939SJiyong Park 		ERR_print_errors_fp(stdout);
83*54fd6939SJiyong Park 		return 0;
84*54fd6939SJiyong Park 	}
85*54fd6939SJiyong Park 
86*54fd6939SJiyong Park 	X509_add_ext(subject, ex, -1);
87*54fd6939SJiyong Park 	X509_EXTENSION_free(ex);
88*54fd6939SJiyong Park 
89*54fd6939SJiyong Park 	return 1;
90*54fd6939SJiyong Park }
91*54fd6939SJiyong Park 
cert_new(int md_alg,cert_t * cert,int days,int ca,STACK_OF (X509_EXTENSION)* sk)92*54fd6939SJiyong Park int cert_new(
93*54fd6939SJiyong Park 	int md_alg,
94*54fd6939SJiyong Park 	cert_t *cert,
95*54fd6939SJiyong Park 	int days,
96*54fd6939SJiyong Park 	int ca,
97*54fd6939SJiyong Park 	STACK_OF(X509_EXTENSION) * sk)
98*54fd6939SJiyong Park {
99*54fd6939SJiyong Park 	EVP_PKEY *pkey = keys[cert->key].key;
100*54fd6939SJiyong Park 	cert_t *issuer_cert = &certs[cert->issuer];
101*54fd6939SJiyong Park 	EVP_PKEY *ikey = keys[issuer_cert->key].key;
102*54fd6939SJiyong Park 	X509 *issuer = issuer_cert->x;
103*54fd6939SJiyong Park 	X509 *x;
104*54fd6939SJiyong Park 	X509_EXTENSION *ex;
105*54fd6939SJiyong Park 	X509_NAME *name;
106*54fd6939SJiyong Park 	ASN1_INTEGER *sno;
107*54fd6939SJiyong Park 	int i, num, rc = 0;
108*54fd6939SJiyong Park 	EVP_MD_CTX *mdCtx;
109*54fd6939SJiyong Park 	EVP_PKEY_CTX *pKeyCtx = NULL;
110*54fd6939SJiyong Park 
111*54fd6939SJiyong Park 	/* Create the certificate structure */
112*54fd6939SJiyong Park 	x = X509_new();
113*54fd6939SJiyong Park 	if (!x) {
114*54fd6939SJiyong Park 		return 0;
115*54fd6939SJiyong Park 	}
116*54fd6939SJiyong Park 
117*54fd6939SJiyong Park 	/* If we do not have a key, use the issuer key (the certificate will
118*54fd6939SJiyong Park 	 * become self signed). This happens in content certificates. */
119*54fd6939SJiyong Park 	if (!pkey) {
120*54fd6939SJiyong Park 		pkey = ikey;
121*54fd6939SJiyong Park 	}
122*54fd6939SJiyong Park 
123*54fd6939SJiyong Park 	/* If we do not have an issuer certificate, use our own (the certificate
124*54fd6939SJiyong Park 	 * will become self signed) */
125*54fd6939SJiyong Park 	if (!issuer) {
126*54fd6939SJiyong Park 		issuer = x;
127*54fd6939SJiyong Park 	}
128*54fd6939SJiyong Park 
129*54fd6939SJiyong Park 	mdCtx = EVP_MD_CTX_create();
130*54fd6939SJiyong Park 	if (mdCtx == NULL) {
131*54fd6939SJiyong Park 		ERR_print_errors_fp(stdout);
132*54fd6939SJiyong Park 		goto END;
133*54fd6939SJiyong Park 	}
134*54fd6939SJiyong Park 
135*54fd6939SJiyong Park 	/* Sign the certificate with the issuer key */
136*54fd6939SJiyong Park 	if (!EVP_DigestSignInit(mdCtx, &pKeyCtx, get_digest(md_alg), NULL, ikey)) {
137*54fd6939SJiyong Park 		ERR_print_errors_fp(stdout);
138*54fd6939SJiyong Park 		goto END;
139*54fd6939SJiyong Park 	}
140*54fd6939SJiyong Park 
141*54fd6939SJiyong Park 	/*
142*54fd6939SJiyong Park 	 * Set additional parameters if issuing public key algorithm is RSA.
143*54fd6939SJiyong Park 	 * This is not required for ECDSA.
144*54fd6939SJiyong Park 	 */
145*54fd6939SJiyong Park 	if (EVP_PKEY_base_id(ikey) == EVP_PKEY_RSA) {
146*54fd6939SJiyong Park 		if (!EVP_PKEY_CTX_set_rsa_padding(pKeyCtx, RSA_PKCS1_PSS_PADDING)) {
147*54fd6939SJiyong Park 			ERR_print_errors_fp(stdout);
148*54fd6939SJiyong Park 			goto END;
149*54fd6939SJiyong Park 		}
150*54fd6939SJiyong Park 
151*54fd6939SJiyong Park 		if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx, RSA_SALT_LEN)) {
152*54fd6939SJiyong Park 			ERR_print_errors_fp(stdout);
153*54fd6939SJiyong Park 			goto END;
154*54fd6939SJiyong Park 		}
155*54fd6939SJiyong Park 
156*54fd6939SJiyong Park 		if (!EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, get_digest(md_alg))) {
157*54fd6939SJiyong Park 			ERR_print_errors_fp(stdout);
158*54fd6939SJiyong Park 			goto END;
159*54fd6939SJiyong Park 		}
160*54fd6939SJiyong Park 	}
161*54fd6939SJiyong Park 
162*54fd6939SJiyong Park 	/* x509.v3 */
163*54fd6939SJiyong Park 	X509_set_version(x, 2);
164*54fd6939SJiyong Park 
165*54fd6939SJiyong Park 	/* Random serial number */
166*54fd6939SJiyong Park 	sno = ASN1_INTEGER_new();
167*54fd6939SJiyong Park 	rand_serial(NULL, sno);
168*54fd6939SJiyong Park 	X509_set_serialNumber(x, sno);
169*54fd6939SJiyong Park 	ASN1_INTEGER_free(sno);
170*54fd6939SJiyong Park 
171*54fd6939SJiyong Park 	X509_gmtime_adj(X509_get_notBefore(x), 0);
172*54fd6939SJiyong Park 	X509_gmtime_adj(X509_get_notAfter(x), (long)60*60*24*days);
173*54fd6939SJiyong Park 	X509_set_pubkey(x, pkey);
174*54fd6939SJiyong Park 
175*54fd6939SJiyong Park 	/* Subject name */
176*54fd6939SJiyong Park 	name = X509_get_subject_name(x);
177*54fd6939SJiyong Park 	X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
178*54fd6939SJiyong Park 			(const unsigned char *)cert->cn, -1, -1, 0);
179*54fd6939SJiyong Park 	X509_set_subject_name(x, name);
180*54fd6939SJiyong Park 
181*54fd6939SJiyong Park 	/* Issuer name */
182*54fd6939SJiyong Park 	name = X509_get_issuer_name(x);
183*54fd6939SJiyong Park 	X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
184*54fd6939SJiyong Park 			(const unsigned char *)issuer_cert->cn, -1, -1, 0);
185*54fd6939SJiyong Park 	X509_set_issuer_name(x, name);
186*54fd6939SJiyong Park 
187*54fd6939SJiyong Park 	/* Add various extensions: standard extensions */
188*54fd6939SJiyong Park 	cert_add_ext(issuer, x, NID_subject_key_identifier, "hash");
189*54fd6939SJiyong Park 	cert_add_ext(issuer, x, NID_authority_key_identifier, "keyid:always");
190*54fd6939SJiyong Park 	if (ca) {
191*54fd6939SJiyong Park 		cert_add_ext(issuer, x, NID_basic_constraints, "CA:TRUE");
192*54fd6939SJiyong Park 		cert_add_ext(issuer, x, NID_key_usage, "keyCertSign");
193*54fd6939SJiyong Park 	} else {
194*54fd6939SJiyong Park 		cert_add_ext(issuer, x, NID_basic_constraints, "CA:FALSE");
195*54fd6939SJiyong Park 	}
196*54fd6939SJiyong Park 
197*54fd6939SJiyong Park 	/* Add custom extensions */
198*54fd6939SJiyong Park 	if (sk != NULL) {
199*54fd6939SJiyong Park 		num = sk_X509_EXTENSION_num(sk);
200*54fd6939SJiyong Park 		for (i = 0; i < num; i++) {
201*54fd6939SJiyong Park 			ex = sk_X509_EXTENSION_value(sk, i);
202*54fd6939SJiyong Park 			X509_add_ext(x, ex, -1);
203*54fd6939SJiyong Park 		}
204*54fd6939SJiyong Park 	}
205*54fd6939SJiyong Park 
206*54fd6939SJiyong Park 	if (!X509_sign_ctx(x, mdCtx)) {
207*54fd6939SJiyong Park 		ERR_print_errors_fp(stdout);
208*54fd6939SJiyong Park 		goto END;
209*54fd6939SJiyong Park 	}
210*54fd6939SJiyong Park 
211*54fd6939SJiyong Park 	/* X509 certificate signed successfully */
212*54fd6939SJiyong Park 	rc = 1;
213*54fd6939SJiyong Park 	cert->x = x;
214*54fd6939SJiyong Park 
215*54fd6939SJiyong Park END:
216*54fd6939SJiyong Park 	EVP_MD_CTX_destroy(mdCtx);
217*54fd6939SJiyong Park 	return rc;
218*54fd6939SJiyong Park }
219*54fd6939SJiyong Park 
cert_init(void)220*54fd6939SJiyong Park int cert_init(void)
221*54fd6939SJiyong Park {
222*54fd6939SJiyong Park 	cmd_opt_t cmd_opt;
223*54fd6939SJiyong Park 	cert_t *cert;
224*54fd6939SJiyong Park 	unsigned int i;
225*54fd6939SJiyong Park 
226*54fd6939SJiyong Park 	certs = malloc((num_def_certs * sizeof(def_certs[0]))
227*54fd6939SJiyong Park #ifdef PDEF_CERTS
228*54fd6939SJiyong Park 		       + (num_pdef_certs * sizeof(pdef_certs[0]))
229*54fd6939SJiyong Park #endif
230*54fd6939SJiyong Park 		       );
231*54fd6939SJiyong Park 	if (certs == NULL) {
232*54fd6939SJiyong Park 		ERROR("%s:%d Failed to allocate memory.\n", __func__, __LINE__);
233*54fd6939SJiyong Park 		return 1;
234*54fd6939SJiyong Park 	}
235*54fd6939SJiyong Park 
236*54fd6939SJiyong Park 	memcpy(&certs[0], &def_certs[0],
237*54fd6939SJiyong Park 	       (num_def_certs * sizeof(def_certs[0])));
238*54fd6939SJiyong Park 
239*54fd6939SJiyong Park #ifdef PDEF_CERTS
240*54fd6939SJiyong Park 	memcpy(&certs[num_def_certs], &pdef_certs[0],
241*54fd6939SJiyong Park 	       (num_pdef_certs * sizeof(pdef_certs[0])));
242*54fd6939SJiyong Park 
243*54fd6939SJiyong Park 	num_certs = num_def_certs + num_pdef_certs;
244*54fd6939SJiyong Park #else
245*54fd6939SJiyong Park 	num_certs = num_def_certs;
246*54fd6939SJiyong Park #endif
247*54fd6939SJiyong Park 
248*54fd6939SJiyong Park 	for (i = 0; i < num_certs; i++) {
249*54fd6939SJiyong Park 		cert = &certs[i];
250*54fd6939SJiyong Park 		cmd_opt.long_opt.name = cert->opt;
251*54fd6939SJiyong Park 		cmd_opt.long_opt.has_arg = required_argument;
252*54fd6939SJiyong Park 		cmd_opt.long_opt.flag = NULL;
253*54fd6939SJiyong Park 		cmd_opt.long_opt.val = CMD_OPT_CERT;
254*54fd6939SJiyong Park 		cmd_opt.help_msg = cert->help_msg;
255*54fd6939SJiyong Park 		cmd_opt_add(&cmd_opt);
256*54fd6939SJiyong Park 	}
257*54fd6939SJiyong Park 
258*54fd6939SJiyong Park 	return 0;
259*54fd6939SJiyong Park }
260*54fd6939SJiyong Park 
cert_get_by_opt(const char * opt)261*54fd6939SJiyong Park cert_t *cert_get_by_opt(const char *opt)
262*54fd6939SJiyong Park {
263*54fd6939SJiyong Park 	cert_t *cert;
264*54fd6939SJiyong Park 	unsigned int i;
265*54fd6939SJiyong Park 
266*54fd6939SJiyong Park 	for (i = 0; i < num_certs; i++) {
267*54fd6939SJiyong Park 		cert = &certs[i];
268*54fd6939SJiyong Park 		if (0 == strcmp(cert->opt, opt)) {
269*54fd6939SJiyong Park 			return cert;
270*54fd6939SJiyong Park 		}
271*54fd6939SJiyong Park 	}
272*54fd6939SJiyong Park 
273*54fd6939SJiyong Park 	return NULL;
274*54fd6939SJiyong Park }
275