1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * X509 cert parser using MbedTLS X509 library
4  *
5  * Copyright (c) 2024 Linaro Limited
6  * Author: Raymond Mao <raymond.mao@linaro.org>
7  */
8 
9 #include <linux/err.h>
10 #include <crypto/public_key.h>
11 #include <crypto/x509_parser.h>
12 
x509_free_mbedtls_ctx(struct x509_cert_mbedtls_ctx * ctx)13 static void x509_free_mbedtls_ctx(struct x509_cert_mbedtls_ctx *ctx)
14 {
15 	if (!ctx)
16 		return;
17 
18 	kfree(ctx->tbs);
19 	kfree(ctx->raw_serial);
20 	kfree(ctx->raw_issuer);
21 	kfree(ctx->raw_subject);
22 	kfree(ctx->raw_skid);
23 	kfree(ctx);
24 }
25 
x509_set_cert_flags(struct x509_certificate * cert)26 static int x509_set_cert_flags(struct x509_certificate *cert)
27 {
28 	struct public_key_signature *sig = cert->sig;
29 
30 	if (!sig || !cert->pub) {
31 		pr_err("Signature or public key is not initialized\n");
32 		return -ENOPKG;
33 	}
34 
35 	if (!cert->pub->pkey_algo)
36 		cert->unsupported_key = true;
37 
38 	if (!sig->pkey_algo)
39 		cert->unsupported_sig = true;
40 
41 	if (!sig->hash_algo)
42 		cert->unsupported_sig = true;
43 
44 	/* TODO: is_hash_blacklisted()? */
45 
46 	/* Detect self-signed certificates and set self_signed flag */
47 	return x509_check_for_self_signed(cert);
48 }
49 
x509_get_timestamp(const mbedtls_x509_time * x509_time)50 time64_t x509_get_timestamp(const mbedtls_x509_time *x509_time)
51 {
52 	unsigned int year, mon, day, hour, min, sec;
53 
54 	/* Adjust for year since 1900 */
55 	year = x509_time->year - 1900;
56 	/* Adjust for 0-based month */
57 	mon = x509_time->mon - 1;
58 	day = x509_time->day;
59 	hour = x509_time->hour;
60 	min = x509_time->min;
61 	sec = x509_time->sec;
62 
63 	return (time64_t)mktime64(year, mon, day, hour, min, sec);
64 }
65 
x509_populate_dn_name_string(const mbedtls_x509_name * name)66 static char *x509_populate_dn_name_string(const mbedtls_x509_name *name)
67 {
68 	size_t len = 256;
69 	int wb;
70 	char *name_str;
71 
72 	do {
73 		name_str = kzalloc(len, GFP_KERNEL);
74 		if (!name_str)
75 			return NULL;
76 
77 		wb = mbedtls_x509_dn_gets(name_str, len, name);
78 		if (wb < 0) {
79 			pr_err("Get DN string failed, ret:-0x%04x\n",
80 			       (unsigned int)-wb);
81 			kfree(name_str);
82 			len = len * 2; /* Try with a bigger buffer */
83 		}
84 	} while (wb < 0);
85 
86 	name_str[wb] = '\0'; /* add the terminator */
87 
88 	return name_str;
89 }
90 
x509_populate_signature_params(const mbedtls_x509_crt * cert,struct public_key_signature ** sig)91 static int x509_populate_signature_params(const mbedtls_x509_crt *cert,
92 					  struct public_key_signature **sig)
93 {
94 	struct public_key_signature *s;
95 	struct image_region region;
96 	size_t akid_len;
97 	unsigned char *akid_data;
98 	int ret;
99 
100 	/* Check if signed data exist */
101 	if (!cert->tbs.p || !cert->tbs.len)
102 		return -EINVAL;
103 
104 	region.data = cert->tbs.p;
105 	region.size = cert->tbs.len;
106 
107 	s = kzalloc(sizeof(*s), GFP_KERNEL);
108 	if (!s)
109 		return -ENOMEM;
110 
111 	/*
112 	 * Get the public key algorithm.
113 	 * Note:
114 	 * ECRDSA (Elliptic Curve Russian Digital Signature Algorithm) is not
115 	 * supported by MbedTLS.
116 	 */
117 	switch (cert->sig_pk) {
118 	case MBEDTLS_PK_RSA:
119 		s->pkey_algo = "rsa";
120 		break;
121 	default:
122 		ret = -EINVAL;
123 		goto error_sig;
124 	}
125 
126 	/* Get the hash algorithm */
127 	switch (cert->sig_md) {
128 	case MBEDTLS_MD_SHA1:
129 		s->hash_algo = "sha1";
130 		s->digest_size = SHA1_SUM_LEN;
131 		break;
132 	case MBEDTLS_MD_SHA256:
133 		s->hash_algo = "sha256";
134 		s->digest_size = SHA256_SUM_LEN;
135 		break;
136 	case MBEDTLS_MD_SHA384:
137 		s->hash_algo = "sha384";
138 		s->digest_size = SHA384_SUM_LEN;
139 		break;
140 	case MBEDTLS_MD_SHA512:
141 		s->hash_algo = "sha512";
142 		s->digest_size = SHA512_SUM_LEN;
143 		break;
144 	/* Unsupported algo */
145 	case MBEDTLS_MD_MD5:
146 	case MBEDTLS_MD_SHA224:
147 	default:
148 		ret = -EINVAL;
149 		goto error_sig;
150 	}
151 
152 	/*
153 	 * Optional attributes:
154 	 * auth_ids holds AuthorityKeyIdentifier (information of issuer),
155 	 * aka akid, which is used to match with a cert's id or skid to
156 	 * indicate that is the issuer when we lookup a cert chain.
157 	 *
158 	 * auth_ids[0]:
159 	 *	[PKCS#7 or CMS ver 1] - generated from "Issuer + Serial number"
160 	 *	[CMS ver 3] - generated from skid (subjectKeyId)
161 	 * auth_ids[1]: generated from skid (subjectKeyId)
162 	 *
163 	 * Assume that we are using PKCS#7 (msg->version=1),
164 	 * not CMS ver 3 (msg->version=3).
165 	 */
166 	akid_len = cert->authority_key_id.authorityCertSerialNumber.len;
167 	akid_data = cert->authority_key_id.authorityCertSerialNumber.p;
168 
169 	/* Check if serial number exists */
170 	if (akid_len && akid_data) {
171 		s->auth_ids[0] = asymmetric_key_generate_id(akid_data,
172 							    akid_len,
173 							    cert->issuer_raw.p,
174 							    cert->issuer_raw.len);
175 		if (!s->auth_ids[0]) {
176 			ret = -ENOMEM;
177 			goto error_sig;
178 		}
179 	}
180 
181 	akid_len = cert->authority_key_id.keyIdentifier.len;
182 	akid_data = cert->authority_key_id.keyIdentifier.p;
183 
184 	/* Check if subjectKeyId exists */
185 	if (akid_len && akid_data) {
186 		s->auth_ids[1] = asymmetric_key_generate_id(akid_data,
187 							    akid_len,
188 							    "", 0);
189 		if (!s->auth_ids[1]) {
190 			ret = -ENOMEM;
191 			goto error_sig;
192 		}
193 	}
194 
195 	/*
196 	 * Encoding can be pkcs1 or raw, but only pkcs1 is supported.
197 	 * Set the encoding explicitly to pkcs1.
198 	 */
199 	s->encoding = "pkcs1";
200 
201 	/* Copy the signature data */
202 	s->s = kmemdup(cert->sig.p, cert->sig.len, GFP_KERNEL);
203 	if (!s->s) {
204 		ret = -ENOMEM;
205 		goto error_sig;
206 	}
207 	s->s_size = cert->sig.len;
208 
209 	/* Calculate the digest of signed data (tbs) */
210 	s->digest = kzalloc(s->digest_size, GFP_KERNEL);
211 	if (!s->digest) {
212 		ret = -ENOMEM;
213 		goto error_sig;
214 	}
215 
216 	ret = hash_calculate(s->hash_algo, &region, 1, s->digest);
217 	if (!ret)
218 		*sig = s;
219 
220 	return ret;
221 
222 error_sig:
223 	public_key_signature_free(s);
224 	return ret;
225 }
226 
x509_save_mbedtls_ctx(const mbedtls_x509_crt * cert,struct x509_cert_mbedtls_ctx ** pctx)227 static int x509_save_mbedtls_ctx(const mbedtls_x509_crt *cert,
228 				 struct x509_cert_mbedtls_ctx **pctx)
229 {
230 	struct x509_cert_mbedtls_ctx *ctx;
231 
232 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
233 	if (!ctx)
234 		return -ENOMEM;
235 
236 	/* Signed data (tbs - The part that is To Be Signed)*/
237 	ctx->tbs = kmemdup(cert->tbs.p, cert->tbs.len,
238 			   GFP_KERNEL);
239 	if (!ctx->tbs)
240 		goto error_ctx;
241 
242 	/* Raw serial number */
243 	ctx->raw_serial = kmemdup(cert->serial.p,
244 				  cert->serial.len, GFP_KERNEL);
245 	if (!ctx->raw_serial)
246 		goto error_ctx;
247 
248 	/* Raw issuer */
249 	ctx->raw_issuer = kmemdup(cert->issuer_raw.p,
250 				  cert->issuer_raw.len, GFP_KERNEL);
251 	if (!ctx->raw_issuer)
252 		goto error_ctx;
253 
254 	/* Raw subject */
255 	ctx->raw_subject = kmemdup(cert->subject_raw.p,
256 				   cert->subject_raw.len, GFP_KERNEL);
257 	if (!ctx->raw_subject)
258 		goto error_ctx;
259 
260 	/* Raw subjectKeyId */
261 	ctx->raw_skid = kmemdup(cert->subject_key_id.p,
262 				cert->subject_key_id.len, GFP_KERNEL);
263 	if (!ctx->raw_skid)
264 		goto error_ctx;
265 
266 	*pctx = ctx;
267 
268 	return 0;
269 
270 error_ctx:
271 	x509_free_mbedtls_ctx(ctx);
272 	return -ENOMEM;
273 }
274 
275 /*
276  * Free an X.509 certificate
277  */
x509_free_certificate(struct x509_certificate * cert)278 void x509_free_certificate(struct x509_certificate *cert)
279 {
280 	if (cert) {
281 		public_key_free(cert->pub);
282 		public_key_signature_free(cert->sig);
283 		kfree(cert->issuer);
284 		kfree(cert->subject);
285 		kfree(cert->id);
286 		kfree(cert->skid);
287 		x509_free_mbedtls_ctx(cert->mbedtls_ctx);
288 		kfree(cert);
289 	}
290 }
291 
x509_populate_pubkey(mbedtls_x509_crt * cert,struct public_key ** pub_key)292 int x509_populate_pubkey(mbedtls_x509_crt *cert, struct public_key **pub_key)
293 {
294 	struct public_key *pk;
295 
296 	pk = kzalloc(sizeof(*pk), GFP_KERNEL);
297 	if (!pk)
298 		return -ENOMEM;
299 
300 	pk->key = kzalloc(cert->pk_raw.len, GFP_KERNEL);
301 	if (!pk->key) {
302 		kfree(pk);
303 		return -ENOMEM;
304 	}
305 	memcpy(pk->key, cert->pk_raw.p, cert->pk_raw.len);
306 	pk->keylen = cert->pk_raw.len;
307 
308 	/*
309 	 * For ECC keys, params field might include information about the curve used,
310 	 * the generator point, or other algorithm-specific parameters.
311 	 * For RSA keys, it's common for the params field to be NULL.
312 	 * FIXME: Assume that we just support RSA keys with id_type X509.
313 	 */
314 	pk->params = NULL;
315 	pk->paramlen = 0;
316 
317 	pk->key_is_private = false;
318 	pk->id_type = "X509";
319 	pk->pkey_algo = "rsa";
320 	pk->algo = OID_rsaEncryption;
321 
322 	*pub_key = pk;
323 
324 	return 0;
325 }
326 
x509_populate_cert(mbedtls_x509_crt * mbedtls_cert,struct x509_certificate ** pcert)327 int x509_populate_cert(mbedtls_x509_crt *mbedtls_cert,
328 		       struct x509_certificate **pcert)
329 {
330 	struct x509_certificate *cert;
331 	struct asymmetric_key_id *kid;
332 	struct asymmetric_key_id *skid;
333 	int ret;
334 
335 	cert = kzalloc(sizeof(*cert), GFP_KERNEL);
336 	if (!cert)
337 		return -ENOMEM;
338 
339 	/* Public key details */
340 	ret = x509_populate_pubkey(mbedtls_cert, &cert->pub);
341 	if (ret)
342 		goto error_cert_pop;
343 
344 	/* Signature parameters */
345 	ret = x509_populate_signature_params(mbedtls_cert, &cert->sig);
346 	if (ret)
347 		goto error_cert_pop;
348 
349 	ret = -ENOMEM;
350 
351 	/* Name of certificate issuer */
352 	cert->issuer = x509_populate_dn_name_string(&mbedtls_cert->issuer);
353 	if (!cert->issuer)
354 		goto error_cert_pop;
355 
356 	/* Name of certificate subject */
357 	cert->subject = x509_populate_dn_name_string(&mbedtls_cert->subject);
358 	if (!cert->subject)
359 		goto error_cert_pop;
360 
361 	/* Certificate validity */
362 	cert->valid_from = x509_get_timestamp(&mbedtls_cert->valid_from);
363 	cert->valid_to = x509_get_timestamp(&mbedtls_cert->valid_to);
364 
365 	/* Save mbedtls context we need */
366 	ret = x509_save_mbedtls_ctx(mbedtls_cert, &cert->mbedtls_ctx);
367 	if (ret)
368 		goto error_cert_pop;
369 
370 	/* Signed data (tbs - The part that is To Be Signed)*/
371 	cert->tbs = cert->mbedtls_ctx->tbs;
372 	cert->tbs_size = mbedtls_cert->tbs.len;
373 
374 	/* Raw serial number */
375 	cert->raw_serial = cert->mbedtls_ctx->raw_serial;
376 	cert->raw_serial_size = mbedtls_cert->serial.len;
377 
378 	/* Raw issuer */
379 	cert->raw_issuer = cert->mbedtls_ctx->raw_issuer;
380 	cert->raw_issuer_size = mbedtls_cert->issuer_raw.len;
381 
382 	/* Raw subject */
383 	cert->raw_subject = cert->mbedtls_ctx->raw_subject;
384 	cert->raw_subject_size = mbedtls_cert->subject_raw.len;
385 
386 	/* Raw subjectKeyId */
387 	cert->raw_skid = cert->mbedtls_ctx->raw_skid;
388 	cert->raw_skid_size = mbedtls_cert->subject_key_id.len;
389 
390 	/* Generate cert issuer + serial number key ID */
391 	kid = asymmetric_key_generate_id(cert->raw_serial,
392 					 cert->raw_serial_size,
393 					 cert->raw_issuer,
394 					 cert->raw_issuer_size);
395 	if (IS_ERR(kid)) {
396 		ret = PTR_ERR(kid);
397 		goto error_cert_pop;
398 	}
399 	cert->id = kid;
400 
401 	/* Generate subject + subjectKeyId */
402 	skid = asymmetric_key_generate_id(cert->raw_skid, cert->raw_skid_size, "", 0);
403 	if (IS_ERR(skid)) {
404 		ret = PTR_ERR(skid);
405 		goto error_cert_pop;
406 	}
407 	cert->skid = skid;
408 
409 	/*
410 	 * Set the certificate flags:
411 	 * self_signed, unsupported_key, unsupported_sig, blacklisted
412 	 */
413 	ret = x509_set_cert_flags(cert);
414 	if (!ret) {
415 		*pcert = cert;
416 		return 0;
417 	}
418 
419 error_cert_pop:
420 	x509_free_certificate(cert);
421 	return ret;
422 }
423 
x509_cert_parse(const void * data,size_t datalen)424 struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
425 {
426 	mbedtls_x509_crt mbedtls_cert;
427 	struct x509_certificate *cert = NULL;
428 	long ret;
429 
430 	/* Parse DER encoded certificate */
431 	mbedtls_x509_crt_init(&mbedtls_cert);
432 	ret = mbedtls_x509_crt_parse_der(&mbedtls_cert, data, datalen);
433 	if (ret)
434 		goto clean_up_ctx;
435 
436 	/* Populate x509_certificate from mbedtls_x509_crt */
437 	ret = x509_populate_cert(&mbedtls_cert, &cert);
438 	if (ret)
439 		goto clean_up_ctx;
440 
441 clean_up_ctx:
442 	mbedtls_x509_crt_free(&mbedtls_cert);
443 	if (!ret)
444 		return cert;
445 
446 	return ERR_PTR(ret);
447 }
448