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