xref: /OK3568_Linux_fs/kernel/crypto/asymmetric_keys/pkcs7_verify.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /* Verify the signature on a PKCS#7 message.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
5*4882a593Smuzhiyun  * Written by David Howells (dhowells@redhat.com)
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #define pr_fmt(fmt) "PKCS7: "fmt
9*4882a593Smuzhiyun #include <linux/kernel.h>
10*4882a593Smuzhiyun #include <linux/export.h>
11*4882a593Smuzhiyun #include <linux/slab.h>
12*4882a593Smuzhiyun #include <linux/err.h>
13*4882a593Smuzhiyun #include <linux/asn1.h>
14*4882a593Smuzhiyun #include <crypto/hash.h>
15*4882a593Smuzhiyun #include <crypto/hash_info.h>
16*4882a593Smuzhiyun #include <crypto/public_key.h>
17*4882a593Smuzhiyun #include "pkcs7_parser.h"
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun /*
20*4882a593Smuzhiyun  * Digest the relevant parts of the PKCS#7 data
21*4882a593Smuzhiyun  */
pkcs7_digest(struct pkcs7_message * pkcs7,struct pkcs7_signed_info * sinfo)22*4882a593Smuzhiyun static int pkcs7_digest(struct pkcs7_message *pkcs7,
23*4882a593Smuzhiyun 			struct pkcs7_signed_info *sinfo)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun 	struct public_key_signature *sig = sinfo->sig;
26*4882a593Smuzhiyun 	struct crypto_shash *tfm;
27*4882a593Smuzhiyun 	struct shash_desc *desc;
28*4882a593Smuzhiyun 	size_t desc_size;
29*4882a593Smuzhiyun 	int ret;
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun 	kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo);
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun 	/* The digest was calculated already. */
34*4882a593Smuzhiyun 	if (sig->digest)
35*4882a593Smuzhiyun 		return 0;
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun 	if (!sinfo->sig->hash_algo)
38*4882a593Smuzhiyun 		return -ENOPKG;
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun 	/* Allocate the hashing algorithm we're going to need and find out how
41*4882a593Smuzhiyun 	 * big the hash operational data will be.
42*4882a593Smuzhiyun 	 */
43*4882a593Smuzhiyun 	tfm = crypto_alloc_shash(sinfo->sig->hash_algo, 0, 0);
44*4882a593Smuzhiyun 	if (IS_ERR(tfm))
45*4882a593Smuzhiyun 		return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm);
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 	desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
48*4882a593Smuzhiyun 	sig->digest_size = crypto_shash_digestsize(tfm);
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	ret = -ENOMEM;
51*4882a593Smuzhiyun 	sig->digest = kmalloc(sig->digest_size, GFP_KERNEL);
52*4882a593Smuzhiyun 	if (!sig->digest)
53*4882a593Smuzhiyun 		goto error_no_desc;
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	desc = kzalloc(desc_size, GFP_KERNEL);
56*4882a593Smuzhiyun 	if (!desc)
57*4882a593Smuzhiyun 		goto error_no_desc;
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 	desc->tfm   = tfm;
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	/* Digest the message [RFC2315 9.3] */
62*4882a593Smuzhiyun 	ret = crypto_shash_digest(desc, pkcs7->data, pkcs7->data_len,
63*4882a593Smuzhiyun 				  sig->digest);
64*4882a593Smuzhiyun 	if (ret < 0)
65*4882a593Smuzhiyun 		goto error;
66*4882a593Smuzhiyun 	pr_devel("MsgDigest = [%*ph]\n", 8, sig->digest);
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 	/* However, if there are authenticated attributes, there must be a
69*4882a593Smuzhiyun 	 * message digest attribute amongst them which corresponds to the
70*4882a593Smuzhiyun 	 * digest we just calculated.
71*4882a593Smuzhiyun 	 */
72*4882a593Smuzhiyun 	if (sinfo->authattrs) {
73*4882a593Smuzhiyun 		u8 tag;
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 		if (!sinfo->msgdigest) {
76*4882a593Smuzhiyun 			pr_warn("Sig %u: No messageDigest\n", sinfo->index);
77*4882a593Smuzhiyun 			ret = -EKEYREJECTED;
78*4882a593Smuzhiyun 			goto error;
79*4882a593Smuzhiyun 		}
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 		if (sinfo->msgdigest_len != sig->digest_size) {
82*4882a593Smuzhiyun 			pr_debug("Sig %u: Invalid digest size (%u)\n",
83*4882a593Smuzhiyun 				 sinfo->index, sinfo->msgdigest_len);
84*4882a593Smuzhiyun 			ret = -EBADMSG;
85*4882a593Smuzhiyun 			goto error;
86*4882a593Smuzhiyun 		}
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 		if (memcmp(sig->digest, sinfo->msgdigest,
89*4882a593Smuzhiyun 			   sinfo->msgdigest_len) != 0) {
90*4882a593Smuzhiyun 			pr_debug("Sig %u: Message digest doesn't match\n",
91*4882a593Smuzhiyun 				 sinfo->index);
92*4882a593Smuzhiyun 			ret = -EKEYREJECTED;
93*4882a593Smuzhiyun 			goto error;
94*4882a593Smuzhiyun 		}
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 		/* We then calculate anew, using the authenticated attributes
97*4882a593Smuzhiyun 		 * as the contents of the digest instead.  Note that we need to
98*4882a593Smuzhiyun 		 * convert the attributes from a CONT.0 into a SET before we
99*4882a593Smuzhiyun 		 * hash it.
100*4882a593Smuzhiyun 		 */
101*4882a593Smuzhiyun 		memset(sig->digest, 0, sig->digest_size);
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 		ret = crypto_shash_init(desc);
104*4882a593Smuzhiyun 		if (ret < 0)
105*4882a593Smuzhiyun 			goto error;
106*4882a593Smuzhiyun 		tag = ASN1_CONS_BIT | ASN1_SET;
107*4882a593Smuzhiyun 		ret = crypto_shash_update(desc, &tag, 1);
108*4882a593Smuzhiyun 		if (ret < 0)
109*4882a593Smuzhiyun 			goto error;
110*4882a593Smuzhiyun 		ret = crypto_shash_finup(desc, sinfo->authattrs,
111*4882a593Smuzhiyun 					 sinfo->authattrs_len, sig->digest);
112*4882a593Smuzhiyun 		if (ret < 0)
113*4882a593Smuzhiyun 			goto error;
114*4882a593Smuzhiyun 		pr_devel("AADigest = [%*ph]\n", 8, sig->digest);
115*4882a593Smuzhiyun 	}
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun error:
118*4882a593Smuzhiyun 	kfree(desc);
119*4882a593Smuzhiyun error_no_desc:
120*4882a593Smuzhiyun 	crypto_free_shash(tfm);
121*4882a593Smuzhiyun 	kleave(" = %d", ret);
122*4882a593Smuzhiyun 	return ret;
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun 
pkcs7_get_digest(struct pkcs7_message * pkcs7,const u8 ** buf,u32 * len,enum hash_algo * hash_algo)125*4882a593Smuzhiyun int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf, u32 *len,
126*4882a593Smuzhiyun 		     enum hash_algo *hash_algo)
127*4882a593Smuzhiyun {
128*4882a593Smuzhiyun 	struct pkcs7_signed_info *sinfo = pkcs7->signed_infos;
129*4882a593Smuzhiyun 	int i, ret;
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	/*
132*4882a593Smuzhiyun 	 * This function doesn't support messages with more than one signature.
133*4882a593Smuzhiyun 	 */
134*4882a593Smuzhiyun 	if (sinfo == NULL || sinfo->next != NULL)
135*4882a593Smuzhiyun 		return -EBADMSG;
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	ret = pkcs7_digest(pkcs7, sinfo);
138*4882a593Smuzhiyun 	if (ret)
139*4882a593Smuzhiyun 		return ret;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	*buf = sinfo->sig->digest;
142*4882a593Smuzhiyun 	*len = sinfo->sig->digest_size;
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	for (i = 0; i < HASH_ALGO__LAST; i++)
145*4882a593Smuzhiyun 		if (!strcmp(hash_algo_name[i], sinfo->sig->hash_algo)) {
146*4882a593Smuzhiyun 			*hash_algo = i;
147*4882a593Smuzhiyun 			break;
148*4882a593Smuzhiyun 		}
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	return 0;
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun /*
154*4882a593Smuzhiyun  * Find the key (X.509 certificate) to use to verify a PKCS#7 message.  PKCS#7
155*4882a593Smuzhiyun  * uses the issuer's name and the issuing certificate serial number for
156*4882a593Smuzhiyun  * matching purposes.  These must match the certificate issuer's name (not
157*4882a593Smuzhiyun  * subject's name) and the certificate serial number [RFC 2315 6.7].
158*4882a593Smuzhiyun  */
pkcs7_find_key(struct pkcs7_message * pkcs7,struct pkcs7_signed_info * sinfo)159*4882a593Smuzhiyun static int pkcs7_find_key(struct pkcs7_message *pkcs7,
160*4882a593Smuzhiyun 			  struct pkcs7_signed_info *sinfo)
161*4882a593Smuzhiyun {
162*4882a593Smuzhiyun 	struct x509_certificate *x509;
163*4882a593Smuzhiyun 	unsigned certix = 1;
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	kenter("%u", sinfo->index);
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	for (x509 = pkcs7->certs; x509; x509 = x509->next, certix++) {
168*4882a593Smuzhiyun 		/* I'm _assuming_ that the generator of the PKCS#7 message will
169*4882a593Smuzhiyun 		 * encode the fields from the X.509 cert in the same way in the
170*4882a593Smuzhiyun 		 * PKCS#7 message - but I can't be 100% sure of that.  It's
171*4882a593Smuzhiyun 		 * possible this will need element-by-element comparison.
172*4882a593Smuzhiyun 		 */
173*4882a593Smuzhiyun 		if (!asymmetric_key_id_same(x509->id, sinfo->sig->auth_ids[0]))
174*4882a593Smuzhiyun 			continue;
175*4882a593Smuzhiyun 		pr_devel("Sig %u: Found cert serial match X.509[%u]\n",
176*4882a593Smuzhiyun 			 sinfo->index, certix);
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 		if (strcmp(x509->pub->pkey_algo, sinfo->sig->pkey_algo) != 0) {
179*4882a593Smuzhiyun 			pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n",
180*4882a593Smuzhiyun 				sinfo->index);
181*4882a593Smuzhiyun 			continue;
182*4882a593Smuzhiyun 		}
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 		sinfo->signer = x509;
185*4882a593Smuzhiyun 		return 0;
186*4882a593Smuzhiyun 	}
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	/* The relevant X.509 cert isn't found here, but it might be found in
189*4882a593Smuzhiyun 	 * the trust keyring.
190*4882a593Smuzhiyun 	 */
191*4882a593Smuzhiyun 	pr_debug("Sig %u: Issuing X.509 cert not found (#%*phN)\n",
192*4882a593Smuzhiyun 		 sinfo->index,
193*4882a593Smuzhiyun 		 sinfo->sig->auth_ids[0]->len, sinfo->sig->auth_ids[0]->data);
194*4882a593Smuzhiyun 	return 0;
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun /*
198*4882a593Smuzhiyun  * Verify the internal certificate chain as best we can.
199*4882a593Smuzhiyun  */
pkcs7_verify_sig_chain(struct pkcs7_message * pkcs7,struct pkcs7_signed_info * sinfo)200*4882a593Smuzhiyun static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
201*4882a593Smuzhiyun 				  struct pkcs7_signed_info *sinfo)
202*4882a593Smuzhiyun {
203*4882a593Smuzhiyun 	struct public_key_signature *sig;
204*4882a593Smuzhiyun 	struct x509_certificate *x509 = sinfo->signer, *p;
205*4882a593Smuzhiyun 	struct asymmetric_key_id *auth;
206*4882a593Smuzhiyun 	int ret;
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	kenter("");
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	for (p = pkcs7->certs; p; p = p->next)
211*4882a593Smuzhiyun 		p->seen = false;
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	for (;;) {
214*4882a593Smuzhiyun 		pr_debug("verify %s: %*phN\n",
215*4882a593Smuzhiyun 			 x509->subject,
216*4882a593Smuzhiyun 			 x509->raw_serial_size, x509->raw_serial);
217*4882a593Smuzhiyun 		x509->seen = true;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 		if (x509->blacklisted) {
220*4882a593Smuzhiyun 			/* If this cert is blacklisted, then mark everything
221*4882a593Smuzhiyun 			 * that depends on this as blacklisted too.
222*4882a593Smuzhiyun 			 */
223*4882a593Smuzhiyun 			sinfo->blacklisted = true;
224*4882a593Smuzhiyun 			for (p = sinfo->signer; p != x509; p = p->signer)
225*4882a593Smuzhiyun 				p->blacklisted = true;
226*4882a593Smuzhiyun 			pr_debug("- blacklisted\n");
227*4882a593Smuzhiyun 			return 0;
228*4882a593Smuzhiyun 		}
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 		if (x509->unsupported_key)
231*4882a593Smuzhiyun 			goto unsupported_crypto_in_x509;
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 		pr_debug("- issuer %s\n", x509->issuer);
234*4882a593Smuzhiyun 		sig = x509->sig;
235*4882a593Smuzhiyun 		if (sig->auth_ids[0])
236*4882a593Smuzhiyun 			pr_debug("- authkeyid.id %*phN\n",
237*4882a593Smuzhiyun 				 sig->auth_ids[0]->len, sig->auth_ids[0]->data);
238*4882a593Smuzhiyun 		if (sig->auth_ids[1])
239*4882a593Smuzhiyun 			pr_debug("- authkeyid.skid %*phN\n",
240*4882a593Smuzhiyun 				 sig->auth_ids[1]->len, sig->auth_ids[1]->data);
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 		if (x509->self_signed) {
243*4882a593Smuzhiyun 			/* If there's no authority certificate specified, then
244*4882a593Smuzhiyun 			 * the certificate must be self-signed and is the root
245*4882a593Smuzhiyun 			 * of the chain.  Likewise if the cert is its own
246*4882a593Smuzhiyun 			 * authority.
247*4882a593Smuzhiyun 			 */
248*4882a593Smuzhiyun 			if (x509->unsupported_sig)
249*4882a593Smuzhiyun 				goto unsupported_crypto_in_x509;
250*4882a593Smuzhiyun 			x509->signer = x509;
251*4882a593Smuzhiyun 			pr_debug("- self-signed\n");
252*4882a593Smuzhiyun 			return 0;
253*4882a593Smuzhiyun 		}
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 		/* Look through the X.509 certificates in the PKCS#7 message's
256*4882a593Smuzhiyun 		 * list to see if the next one is there.
257*4882a593Smuzhiyun 		 */
258*4882a593Smuzhiyun 		auth = sig->auth_ids[0];
259*4882a593Smuzhiyun 		if (auth) {
260*4882a593Smuzhiyun 			pr_debug("- want %*phN\n", auth->len, auth->data);
261*4882a593Smuzhiyun 			for (p = pkcs7->certs; p; p = p->next) {
262*4882a593Smuzhiyun 				pr_debug("- cmp [%u] %*phN\n",
263*4882a593Smuzhiyun 					 p->index, p->id->len, p->id->data);
264*4882a593Smuzhiyun 				if (asymmetric_key_id_same(p->id, auth))
265*4882a593Smuzhiyun 					goto found_issuer_check_skid;
266*4882a593Smuzhiyun 			}
267*4882a593Smuzhiyun 		} else if (sig->auth_ids[1]) {
268*4882a593Smuzhiyun 			auth = sig->auth_ids[1];
269*4882a593Smuzhiyun 			pr_debug("- want %*phN\n", auth->len, auth->data);
270*4882a593Smuzhiyun 			for (p = pkcs7->certs; p; p = p->next) {
271*4882a593Smuzhiyun 				if (!p->skid)
272*4882a593Smuzhiyun 					continue;
273*4882a593Smuzhiyun 				pr_debug("- cmp [%u] %*phN\n",
274*4882a593Smuzhiyun 					 p->index, p->skid->len, p->skid->data);
275*4882a593Smuzhiyun 				if (asymmetric_key_id_same(p->skid, auth))
276*4882a593Smuzhiyun 					goto found_issuer;
277*4882a593Smuzhiyun 			}
278*4882a593Smuzhiyun 		}
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 		/* We didn't find the root of this chain */
281*4882a593Smuzhiyun 		pr_debug("- top\n");
282*4882a593Smuzhiyun 		return 0;
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	found_issuer_check_skid:
285*4882a593Smuzhiyun 		/* We matched issuer + serialNumber, but if there's an
286*4882a593Smuzhiyun 		 * authKeyId.keyId, that must match the CA subjKeyId also.
287*4882a593Smuzhiyun 		 */
288*4882a593Smuzhiyun 		if (sig->auth_ids[1] &&
289*4882a593Smuzhiyun 		    !asymmetric_key_id_same(p->skid, sig->auth_ids[1])) {
290*4882a593Smuzhiyun 			pr_warn("Sig %u: X.509 chain contains auth-skid nonmatch (%u->%u)\n",
291*4882a593Smuzhiyun 				sinfo->index, x509->index, p->index);
292*4882a593Smuzhiyun 			return -EKEYREJECTED;
293*4882a593Smuzhiyun 		}
294*4882a593Smuzhiyun 	found_issuer:
295*4882a593Smuzhiyun 		pr_debug("- subject %s\n", p->subject);
296*4882a593Smuzhiyun 		if (p->seen) {
297*4882a593Smuzhiyun 			pr_warn("Sig %u: X.509 chain contains loop\n",
298*4882a593Smuzhiyun 				sinfo->index);
299*4882a593Smuzhiyun 			return 0;
300*4882a593Smuzhiyun 		}
301*4882a593Smuzhiyun 		ret = public_key_verify_signature(p->pub, x509->sig);
302*4882a593Smuzhiyun 		if (ret < 0)
303*4882a593Smuzhiyun 			return ret;
304*4882a593Smuzhiyun 		x509->signer = p;
305*4882a593Smuzhiyun 		if (x509 == p) {
306*4882a593Smuzhiyun 			pr_debug("- self-signed\n");
307*4882a593Smuzhiyun 			return 0;
308*4882a593Smuzhiyun 		}
309*4882a593Smuzhiyun 		x509 = p;
310*4882a593Smuzhiyun 		might_sleep();
311*4882a593Smuzhiyun 	}
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun unsupported_crypto_in_x509:
314*4882a593Smuzhiyun 	/* Just prune the certificate chain at this point if we lack some
315*4882a593Smuzhiyun 	 * crypto module to go further.  Note, however, we don't want to set
316*4882a593Smuzhiyun 	 * sinfo->unsupported_crypto as the signed info block may still be
317*4882a593Smuzhiyun 	 * validatable against an X.509 cert lower in the chain that we have a
318*4882a593Smuzhiyun 	 * trusted copy of.
319*4882a593Smuzhiyun 	 */
320*4882a593Smuzhiyun 	return 0;
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun /*
324*4882a593Smuzhiyun  * Verify one signed information block from a PKCS#7 message.
325*4882a593Smuzhiyun  */
pkcs7_verify_one(struct pkcs7_message * pkcs7,struct pkcs7_signed_info * sinfo)326*4882a593Smuzhiyun static int pkcs7_verify_one(struct pkcs7_message *pkcs7,
327*4882a593Smuzhiyun 			    struct pkcs7_signed_info *sinfo)
328*4882a593Smuzhiyun {
329*4882a593Smuzhiyun 	int ret;
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 	kenter(",%u", sinfo->index);
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	/* First of all, digest the data in the PKCS#7 message and the
334*4882a593Smuzhiyun 	 * signed information block
335*4882a593Smuzhiyun 	 */
336*4882a593Smuzhiyun 	ret = pkcs7_digest(pkcs7, sinfo);
337*4882a593Smuzhiyun 	if (ret < 0)
338*4882a593Smuzhiyun 		return ret;
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	/* Find the key for the signature if there is one */
341*4882a593Smuzhiyun 	ret = pkcs7_find_key(pkcs7, sinfo);
342*4882a593Smuzhiyun 	if (ret < 0)
343*4882a593Smuzhiyun 		return ret;
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	if (!sinfo->signer)
346*4882a593Smuzhiyun 		return 0;
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 	pr_devel("Using X.509[%u] for sig %u\n",
349*4882a593Smuzhiyun 		 sinfo->signer->index, sinfo->index);
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	/* Check that the PKCS#7 signing time is valid according to the X.509
352*4882a593Smuzhiyun 	 * certificate.  We can't, however, check against the system clock
353*4882a593Smuzhiyun 	 * since that may not have been set yet and may be wrong.
354*4882a593Smuzhiyun 	 */
355*4882a593Smuzhiyun 	if (test_bit(sinfo_has_signing_time, &sinfo->aa_set)) {
356*4882a593Smuzhiyun 		if (sinfo->signing_time < sinfo->signer->valid_from ||
357*4882a593Smuzhiyun 		    sinfo->signing_time > sinfo->signer->valid_to) {
358*4882a593Smuzhiyun 			pr_warn("Message signed outside of X.509 validity window\n");
359*4882a593Smuzhiyun 			return -EKEYREJECTED;
360*4882a593Smuzhiyun 		}
361*4882a593Smuzhiyun 	}
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	/* Verify the PKCS#7 binary against the key */
364*4882a593Smuzhiyun 	ret = public_key_verify_signature(sinfo->signer->pub, sinfo->sig);
365*4882a593Smuzhiyun 	if (ret < 0)
366*4882a593Smuzhiyun 		return ret;
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 	pr_devel("Verified signature %u\n", sinfo->index);
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 	/* Verify the internal certificate chain */
371*4882a593Smuzhiyun 	return pkcs7_verify_sig_chain(pkcs7, sinfo);
372*4882a593Smuzhiyun }
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun /**
375*4882a593Smuzhiyun  * pkcs7_verify - Verify a PKCS#7 message
376*4882a593Smuzhiyun  * @pkcs7: The PKCS#7 message to be verified
377*4882a593Smuzhiyun  * @usage: The use to which the key is being put
378*4882a593Smuzhiyun  *
379*4882a593Smuzhiyun  * Verify a PKCS#7 message is internally consistent - that is, the data digest
380*4882a593Smuzhiyun  * matches the digest in the AuthAttrs and any signature in the message or one
381*4882a593Smuzhiyun  * of the X.509 certificates it carries that matches another X.509 cert in the
382*4882a593Smuzhiyun  * message can be verified.
383*4882a593Smuzhiyun  *
384*4882a593Smuzhiyun  * This does not look to match the contents of the PKCS#7 message against any
385*4882a593Smuzhiyun  * external public keys.
386*4882a593Smuzhiyun  *
387*4882a593Smuzhiyun  * Returns, in order of descending priority:
388*4882a593Smuzhiyun  *
389*4882a593Smuzhiyun  *  (*) -EKEYREJECTED if a key was selected that had a usage restriction at
390*4882a593Smuzhiyun  *      odds with the specified usage, or:
391*4882a593Smuzhiyun  *
392*4882a593Smuzhiyun  *  (*) -EKEYREJECTED if a signature failed to match for which we found an
393*4882a593Smuzhiyun  *	appropriate X.509 certificate, or:
394*4882a593Smuzhiyun  *
395*4882a593Smuzhiyun  *  (*) -EBADMSG if some part of the message was invalid, or:
396*4882a593Smuzhiyun  *
397*4882a593Smuzhiyun  *  (*) 0 if a signature chain passed verification, or:
398*4882a593Smuzhiyun  *
399*4882a593Smuzhiyun  *  (*) -EKEYREJECTED if a blacklisted key was encountered, or:
400*4882a593Smuzhiyun  *
401*4882a593Smuzhiyun  *  (*) -ENOPKG if none of the signature chains are verifiable because suitable
402*4882a593Smuzhiyun  *	crypto modules couldn't be found.
403*4882a593Smuzhiyun  */
pkcs7_verify(struct pkcs7_message * pkcs7,enum key_being_used_for usage)404*4882a593Smuzhiyun int pkcs7_verify(struct pkcs7_message *pkcs7,
405*4882a593Smuzhiyun 		 enum key_being_used_for usage)
406*4882a593Smuzhiyun {
407*4882a593Smuzhiyun 	struct pkcs7_signed_info *sinfo;
408*4882a593Smuzhiyun 	int actual_ret = -ENOPKG;
409*4882a593Smuzhiyun 	int ret;
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun 	kenter("");
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	switch (usage) {
414*4882a593Smuzhiyun 	case VERIFYING_MODULE_SIGNATURE:
415*4882a593Smuzhiyun 		if (pkcs7->data_type != OID_data) {
416*4882a593Smuzhiyun 			pr_warn("Invalid module sig (not pkcs7-data)\n");
417*4882a593Smuzhiyun 			return -EKEYREJECTED;
418*4882a593Smuzhiyun 		}
419*4882a593Smuzhiyun 		if (pkcs7->have_authattrs) {
420*4882a593Smuzhiyun 			pr_warn("Invalid module sig (has authattrs)\n");
421*4882a593Smuzhiyun 			return -EKEYREJECTED;
422*4882a593Smuzhiyun 		}
423*4882a593Smuzhiyun 		break;
424*4882a593Smuzhiyun 	case VERIFYING_FIRMWARE_SIGNATURE:
425*4882a593Smuzhiyun 		if (pkcs7->data_type != OID_data) {
426*4882a593Smuzhiyun 			pr_warn("Invalid firmware sig (not pkcs7-data)\n");
427*4882a593Smuzhiyun 			return -EKEYREJECTED;
428*4882a593Smuzhiyun 		}
429*4882a593Smuzhiyun 		if (!pkcs7->have_authattrs) {
430*4882a593Smuzhiyun 			pr_warn("Invalid firmware sig (missing authattrs)\n");
431*4882a593Smuzhiyun 			return -EKEYREJECTED;
432*4882a593Smuzhiyun 		}
433*4882a593Smuzhiyun 		break;
434*4882a593Smuzhiyun 	case VERIFYING_KEXEC_PE_SIGNATURE:
435*4882a593Smuzhiyun 		if (pkcs7->data_type != OID_msIndirectData) {
436*4882a593Smuzhiyun 			pr_warn("Invalid kexec sig (not Authenticode)\n");
437*4882a593Smuzhiyun 			return -EKEYREJECTED;
438*4882a593Smuzhiyun 		}
439*4882a593Smuzhiyun 		/* Authattr presence checked in parser */
440*4882a593Smuzhiyun 		break;
441*4882a593Smuzhiyun 	case VERIFYING_UNSPECIFIED_SIGNATURE:
442*4882a593Smuzhiyun 		if (pkcs7->data_type != OID_data) {
443*4882a593Smuzhiyun 			pr_warn("Invalid unspecified sig (not pkcs7-data)\n");
444*4882a593Smuzhiyun 			return -EKEYREJECTED;
445*4882a593Smuzhiyun 		}
446*4882a593Smuzhiyun 		break;
447*4882a593Smuzhiyun 	default:
448*4882a593Smuzhiyun 		return -EINVAL;
449*4882a593Smuzhiyun 	}
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
452*4882a593Smuzhiyun 		ret = pkcs7_verify_one(pkcs7, sinfo);
453*4882a593Smuzhiyun 		if (sinfo->blacklisted) {
454*4882a593Smuzhiyun 			if (actual_ret == -ENOPKG)
455*4882a593Smuzhiyun 				actual_ret = -EKEYREJECTED;
456*4882a593Smuzhiyun 			continue;
457*4882a593Smuzhiyun 		}
458*4882a593Smuzhiyun 		if (ret < 0) {
459*4882a593Smuzhiyun 			if (ret == -ENOPKG) {
460*4882a593Smuzhiyun 				sinfo->unsupported_crypto = true;
461*4882a593Smuzhiyun 				continue;
462*4882a593Smuzhiyun 			}
463*4882a593Smuzhiyun 			kleave(" = %d", ret);
464*4882a593Smuzhiyun 			return ret;
465*4882a593Smuzhiyun 		}
466*4882a593Smuzhiyun 		actual_ret = 0;
467*4882a593Smuzhiyun 	}
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun 	kleave(" = %d", actual_ret);
470*4882a593Smuzhiyun 	return actual_ret;
471*4882a593Smuzhiyun }
472*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pkcs7_verify);
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun /**
475*4882a593Smuzhiyun  * pkcs7_supply_detached_data - Supply the data needed to verify a PKCS#7 message
476*4882a593Smuzhiyun  * @pkcs7: The PKCS#7 message
477*4882a593Smuzhiyun  * @data: The data to be verified
478*4882a593Smuzhiyun  * @datalen: The amount of data
479*4882a593Smuzhiyun  *
480*4882a593Smuzhiyun  * Supply the detached data needed to verify a PKCS#7 message.  Note that no
481*4882a593Smuzhiyun  * attempt to retain/pin the data is made.  That is left to the caller.  The
482*4882a593Smuzhiyun  * data will not be modified by pkcs7_verify() and will not be freed when the
483*4882a593Smuzhiyun  * PKCS#7 message is freed.
484*4882a593Smuzhiyun  *
485*4882a593Smuzhiyun  * Returns -EINVAL if data is already supplied in the message, 0 otherwise.
486*4882a593Smuzhiyun  */
pkcs7_supply_detached_data(struct pkcs7_message * pkcs7,const void * data,size_t datalen)487*4882a593Smuzhiyun int pkcs7_supply_detached_data(struct pkcs7_message *pkcs7,
488*4882a593Smuzhiyun 			       const void *data, size_t datalen)
489*4882a593Smuzhiyun {
490*4882a593Smuzhiyun 	if (pkcs7->data) {
491*4882a593Smuzhiyun 		pr_debug("Data already supplied\n");
492*4882a593Smuzhiyun 		return -EINVAL;
493*4882a593Smuzhiyun 	}
494*4882a593Smuzhiyun 	pkcs7->data = data;
495*4882a593Smuzhiyun 	pkcs7->data_len = datalen;
496*4882a593Smuzhiyun 	return 0;
497*4882a593Smuzhiyun }
498