1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Instantiate a public key crypto key from an X.509 Certificate
4 * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
8 #define pr_fmt(fmt) "X.509: "fmt
12 #include <dm/devres.h>
13 #include <linux/compat.h>
14 #include <linux/err.h>
15 #include <linux/errno.h>
17 #include <linux/module.h>
19 #include <linux/kernel.h>
21 #include <crypto/x509_parser.h>
22 #include <u-boot/hash-checksum.h>
24 #include <linux/slab.h>
25 #include <keys/asymmetric-subtype.h>
26 #include <keys/asymmetric-parser.h>
27 #include <keys/system_keyring.h>
28 #include <crypto/hash.h>
29 #include "asymmetric_keys.h"
30 #include "x509_parser.h"
34 * Set up the signature parameters in an X.509 certificate. This involves
35 * digesting the signed data and extracting the signature.
37 int x509_get_sig_params(struct x509_certificate
*cert
)
39 struct public_key_signature
*sig
= cert
->sig
;
41 struct image_region region
;
43 struct crypto_shash
*tfm
;
44 struct shash_desc
*desc
;
49 pr_devel("==>%s()\n", __func__
);
51 if (!cert
->pub
->pkey_algo
)
52 cert
->unsupported_key
= true;
55 cert
->unsupported_sig
= true;
57 /* We check the hash if we can - even if we can't then verify it */
58 if (!sig
->hash_algo
) {
59 cert
->unsupported_sig
= true;
63 sig
->s
= kmemdup(cert
->raw_sig
, cert
->raw_sig_size
, GFP_KERNEL
);
67 sig
->s_size
= cert
->raw_sig_size
;
72 if (!strcmp(sig
->hash_algo
, "sha256"))
73 sig
->digest_size
= SHA256_SUM_LEN
;
74 else if (!strcmp(sig
->hash_algo
, "sha384"))
75 sig
->digest_size
= SHA384_SUM_LEN
;
76 else if (!strcmp(sig
->hash_algo
, "sha512"))
77 sig
->digest_size
= SHA512_SUM_LEN
;
78 else if (!strcmp(sig
->hash_algo
, "sha1"))
79 sig
->digest_size
= SHA1_SUM_LEN
;
83 sig
->digest
= calloc(1, sig
->digest_size
);
87 region
.data
= cert
->tbs
;
88 region
.size
= cert
->tbs_size
;
89 hash_calculate(sig
->hash_algo
, ®ion
, 1, sig
->digest
);
91 /* TODO: is_hash_blacklisted()? */
95 /* Allocate the hashing algorithm we're going to need and find out how
96 * big the hash operational data will be.
98 tfm
= crypto_alloc_shash(sig
->hash_algo
, 0, 0);
100 if (PTR_ERR(tfm
) == -ENOENT
) {
101 cert
->unsupported_sig
= true;
107 desc_size
= crypto_shash_descsize(tfm
) + sizeof(*desc
);
108 sig
->digest_size
= crypto_shash_digestsize(tfm
);
111 sig
->digest
= kmalloc(sig
->digest_size
, GFP_KERNEL
);
115 desc
= kzalloc(desc_size
, GFP_KERNEL
);
121 ret
= crypto_shash_digest(desc
, cert
->tbs
, cert
->tbs_size
, sig
->digest
);
125 ret
= is_hash_blacklisted(sig
->digest
, sig
->digest_size
, "tbs");
126 if (ret
== -EKEYREJECTED
) {
127 pr_err("Cert %*phN is blacklisted\n",
128 sig
->digest_size
, sig
->digest
);
129 cert
->blacklisted
= true;
136 crypto_free_shash(tfm
);
137 #endif /* __UBOOT__ */
138 pr_devel("<==%s() = %d\n", __func__
, ret
);
143 * Check for self-signedness in an X.509 cert and if found, check the signature
144 * immediately if we can.
146 int x509_check_for_self_signed(struct x509_certificate
*cert
)
150 pr_devel("==>%s()\n", __func__
);
152 if (cert
->raw_subject_size
!= cert
->raw_issuer_size
||
153 memcmp(cert
->raw_subject
, cert
->raw_issuer
,
154 cert
->raw_issuer_size
) != 0)
155 goto not_self_signed
;
157 if (cert
->sig
->auth_ids
[0] || cert
->sig
->auth_ids
[1]) {
158 /* If the AKID is present it may have one or two parts. If
159 * both are supplied, both must match.
161 bool a
= asymmetric_key_id_same(cert
->skid
, cert
->sig
->auth_ids
[1]);
162 bool b
= asymmetric_key_id_same(cert
->id
, cert
->sig
->auth_ids
[0]);
165 goto not_self_signed
;
168 if (((a
&& !b
) || (b
&& !a
)) &&
169 cert
->sig
->auth_ids
[0] && cert
->sig
->auth_ids
[1])
174 if (strcmp(cert
->pub
->pkey_algo
, cert
->sig
->pkey_algo
) != 0)
177 ret
= public_key_verify_signature(cert
->pub
, cert
->sig
);
179 if (ret
== -ENOPKG
) {
180 cert
->unsupported_sig
= true;
186 pr_devel("Cert Self-signature verified");
187 cert
->self_signed
= true;
190 pr_devel("<==%s() = %d\n", __func__
, ret
);
194 pr_devel("<==%s() = 0 [not]\n", __func__
);
200 * Attempt to parse a data blob for a key as an X509 certificate.
202 static int x509_key_preparse(struct key_preparsed_payload
*prep
)
204 struct asymmetric_key_ids
*kids
;
205 struct x509_certificate
*cert
;
208 char *desc
= NULL
, *p
;
211 cert
= x509_cert_parse(prep
->data
, prep
->datalen
);
213 return PTR_ERR(cert
);
215 pr_devel("Cert Issuer: %s\n", cert
->issuer
);
216 pr_devel("Cert Subject: %s\n", cert
->subject
);
218 if (cert
->unsupported_key
) {
220 goto error_free_cert
;
223 pr_devel("Cert Key Algo: %s\n", cert
->pub
->pkey_algo
);
224 pr_devel("Cert Valid period: %lld-%lld\n", cert
->valid_from
, cert
->valid_to
);
226 cert
->pub
->id_type
= "X509";
228 if (cert
->unsupported_sig
) {
229 public_key_signature_free(cert
->sig
);
232 pr_devel("Cert Signature: %s + %s\n",
233 cert
->sig
->pkey_algo
, cert
->sig
->hash_algo
);
236 /* Don't permit addition of blacklisted keys */
238 if (cert
->blacklisted
)
239 goto error_free_cert
;
241 /* Propose a description */
242 sulen
= strlen(cert
->subject
);
243 if (cert
->raw_skid
) {
244 srlen
= cert
->raw_skid_size
;
247 srlen
= cert
->raw_serial_size
;
248 q
= cert
->raw_serial
;
252 desc
= kmalloc(sulen
+ 2 + srlen
* 2 + 1, GFP_KERNEL
);
254 goto error_free_cert
;
255 p
= memcpy(desc
, cert
->subject
, sulen
);
259 p
= bin2hex(p
, q
, srlen
);
262 kids
= kmalloc(sizeof(struct asymmetric_key_ids
), GFP_KERNEL
);
264 goto error_free_desc
;
265 kids
->id
[0] = cert
->id
;
266 kids
->id
[1] = cert
->skid
;
268 /* We're pinning the module by being linked against it */
269 __module_get(public_key_subtype
.owner
);
270 prep
->payload
.data
[asym_subtype
] = &public_key_subtype
;
271 prep
->payload
.data
[asym_key_ids
] = kids
;
272 prep
->payload
.data
[asym_crypto
] = cert
->pub
;
273 prep
->payload
.data
[asym_auth
] = cert
->sig
;
274 prep
->description
= desc
;
275 prep
->quotalen
= 100;
277 /* We've finished with the certificate */
288 x509_free_certificate(cert
);
292 static struct asymmetric_key_parser x509_key_parser
= {
293 .owner
= THIS_MODULE
,
295 .parse
= x509_key_preparse
,
301 static int __init
x509_key_init(void)
303 return register_asymmetric_key_parser(&x509_key_parser
);
306 static void __exit
x509_key_exit(void)
308 unregister_asymmetric_key_parser(&x509_key_parser
);
311 module_init(x509_key_init
);
312 module_exit(x509_key_exit
);
313 #endif /* !__UBOOT__ */
315 MODULE_DESCRIPTION("X.509 certificate parser");
316 MODULE_AUTHOR("Red Hat, Inc.");
317 MODULE_LICENSE("GPL");