blob: cb42018695caee7776650c81a43fef33305dcd55 [file] [log] [blame]
Raymond Mao7deec0f2024-10-03 14:50:30 -07001// 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
13static 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
26static 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
50time64_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
66static char *x509_populate_dn_name_string(const mbedtls_x509_name *name)
67{
68 size_t len = 256;
69 size_t 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
91static 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
222error_sig:
223 public_key_signature_free(s);
224 return ret;
225}
226
227static 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
270error_ctx:
271 x509_free_mbedtls_ctx(ctx);
272 return -ENOMEM;
273}
274
275/*
276 * Free an X.509 certificate
277 */
278void 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
292int 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
327int 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
419error_cert_pop:
420 x509_free_certificate(cert);
421 return ret;
422}
423
424struct 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
441clean_up_ctx:
442 mbedtls_x509_crt_free(&mbedtls_cert);
443 if (!ret)
444 return cert;
445
446 return ERR_PTR(ret);
447}