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