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