xref: /linux/crypto/asymmetric_keys/pkcs7_parser.c (revision 6f7e6393d1ce636bb7ec77a7fe7b77458fddf701)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* PKCS#7 parser
3  *
4  * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
5  * Written by David Howells (dhowells@redhat.com)
6  */
7 
8 #define pr_fmt(fmt) "PKCS7: "fmt
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/export.h>
12 #include <linux/slab.h>
13 #include <linux/err.h>
14 #include <linux/oid_registry.h>
15 #include <crypto/public_key.h>
16 #include "pkcs7_parser.h"
17 #include "pkcs7.asn1.h"
18 
19 MODULE_DESCRIPTION("PKCS#7 parser");
20 MODULE_AUTHOR("Red Hat, Inc.");
21 MODULE_LICENSE("GPL");
22 
23 struct pkcs7_parse_context {
24 	struct pkcs7_message	*msg;		/* Message being constructed */
25 	struct pkcs7_signed_info *sinfo;	/* SignedInfo being constructed */
26 	struct pkcs7_signed_info **ppsinfo;
27 	struct x509_certificate *certs;		/* Certificate cache */
28 	struct x509_certificate **ppcerts;
29 	unsigned long	data;			/* Start of data */
30 	enum OID	last_oid;		/* Last OID encountered */
31 	unsigned	x509_index;
32 	unsigned	sinfo_index;
33 	const void	*raw_serial;
34 	unsigned	raw_serial_size;
35 	unsigned	raw_issuer_size;
36 	const void	*raw_issuer;
37 	const void	*raw_skid;
38 	unsigned	raw_skid_size;
39 	bool		expect_skid;
40 };
41 
42 /*
43  * Free a signed information block.
44  */
45 static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
46 {
47 	if (sinfo) {
48 		public_key_signature_free(sinfo->sig);
49 		kfree(sinfo);
50 	}
51 }
52 
53 /**
54  * pkcs7_free_message - Free a PKCS#7 message
55  * @pkcs7: The PKCS#7 message to free
56  */
57 void pkcs7_free_message(struct pkcs7_message *pkcs7)
58 {
59 	struct x509_certificate *cert;
60 	struct pkcs7_signed_info *sinfo;
61 
62 	if (pkcs7) {
63 		while (pkcs7->certs) {
64 			cert = pkcs7->certs;
65 			pkcs7->certs = cert->next;
66 			x509_free_certificate(cert);
67 		}
68 		while (pkcs7->crl) {
69 			cert = pkcs7->crl;
70 			pkcs7->crl = cert->next;
71 			x509_free_certificate(cert);
72 		}
73 		while (pkcs7->signed_infos) {
74 			sinfo = pkcs7->signed_infos;
75 			pkcs7->signed_infos = sinfo->next;
76 			pkcs7_free_signed_info(sinfo);
77 		}
78 		kfree(pkcs7);
79 	}
80 }
81 EXPORT_SYMBOL_GPL(pkcs7_free_message);
82 
83 /*
84  * Check authenticatedAttributes are provided or not provided consistently.
85  */
86 static int pkcs7_check_authattrs(struct pkcs7_message *msg)
87 {
88 	struct pkcs7_signed_info *sinfo;
89 	bool want = false;
90 
91 	sinfo = msg->signed_infos;
92 	if (!sinfo)
93 		goto inconsistent;
94 
95 #ifdef CONFIG_PKCS7_WAIVE_AUTHATTRS_REJECTION_FOR_MLDSA
96 	msg->authattrs_rej_waivable = true;
97 #endif
98 
99 	if (sinfo->authattrs) {
100 		want = true;
101 		msg->have_authattrs = true;
102 #ifdef CONFIG_PKCS7_WAIVE_AUTHATTRS_REJECTION_FOR_MLDSA
103 		if (strncmp(sinfo->sig->pkey_algo, "mldsa", 5) != 0)
104 			msg->authattrs_rej_waivable = false;
105 #endif
106 	} else if (sinfo->sig->algo_takes_data) {
107 		sinfo->sig->hash_algo = "none";
108 	}
109 
110 	for (sinfo = sinfo->next; sinfo; sinfo = sinfo->next) {
111 		if (!!sinfo->authattrs != want)
112 			goto inconsistent;
113 
114 		if (!sinfo->authattrs &&
115 		    sinfo->sig->algo_takes_data)
116 			sinfo->sig->hash_algo = "none";
117 	}
118 	return 0;
119 
120 inconsistent:
121 	pr_warn("Inconsistently supplied authAttrs\n");
122 	return -EINVAL;
123 }
124 
125 /**
126  * pkcs7_parse_message - Parse a PKCS#7 message
127  * @data: The raw binary ASN.1 encoded message to be parsed
128  * @datalen: The size of the encoded message
129  */
130 struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen)
131 {
132 	struct pkcs7_parse_context *ctx;
133 	struct pkcs7_message *msg = ERR_PTR(-ENOMEM);
134 	int ret;
135 
136 	ctx = kzalloc(sizeof(struct pkcs7_parse_context), GFP_KERNEL);
137 	if (!ctx)
138 		goto out_no_ctx;
139 	ctx->msg = kzalloc(sizeof(struct pkcs7_message), GFP_KERNEL);
140 	if (!ctx->msg)
141 		goto out_no_msg;
142 	ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
143 	if (!ctx->sinfo)
144 		goto out_no_sinfo;
145 	ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),
146 				  GFP_KERNEL);
147 	if (!ctx->sinfo->sig)
148 		goto out_no_sig;
149 
150 	ctx->data = (unsigned long)data;
151 	ctx->ppcerts = &ctx->certs;
152 	ctx->ppsinfo = &ctx->msg->signed_infos;
153 
154 	/* Attempt to decode the signature */
155 	ret = asn1_ber_decoder(&pkcs7_decoder, ctx, data, datalen);
156 	if (ret < 0) {
157 		msg = ERR_PTR(ret);
158 		goto out;
159 	}
160 
161 	ret = pkcs7_check_authattrs(ctx->msg);
162 	if (ret < 0) {
163 		msg = ERR_PTR(ret);
164 		goto out;
165 	}
166 
167 	msg = ctx->msg;
168 	ctx->msg = NULL;
169 
170 out:
171 	while (ctx->certs) {
172 		struct x509_certificate *cert = ctx->certs;
173 		ctx->certs = cert->next;
174 		x509_free_certificate(cert);
175 	}
176 out_no_sig:
177 	pkcs7_free_signed_info(ctx->sinfo);
178 out_no_sinfo:
179 	pkcs7_free_message(ctx->msg);
180 out_no_msg:
181 	kfree(ctx);
182 out_no_ctx:
183 	return msg;
184 }
185 EXPORT_SYMBOL_GPL(pkcs7_parse_message);
186 
187 /**
188  * pkcs7_get_content_data - Get access to the PKCS#7 content
189  * @pkcs7: The preparsed PKCS#7 message to access
190  * @_data: Place to return a pointer to the data
191  * @_data_len: Place to return the data length
192  * @_headerlen: Size of ASN.1 header not included in _data
193  *
194  * Get access to the data content of the PKCS#7 message.  The size of the
195  * header of the ASN.1 object that contains it is also provided and can be used
196  * to adjust *_data and *_data_len to get the entire object.
197  *
198  * Returns -ENODATA if the data object was missing from the message.
199  */
200 int pkcs7_get_content_data(const struct pkcs7_message *pkcs7,
201 			   const void **_data, size_t *_data_len,
202 			   size_t *_headerlen)
203 {
204 	if (!pkcs7->data)
205 		return -ENODATA;
206 
207 	*_data = pkcs7->data;
208 	*_data_len = pkcs7->data_len;
209 	if (_headerlen)
210 		*_headerlen = pkcs7->data_hdrlen;
211 	return 0;
212 }
213 EXPORT_SYMBOL_GPL(pkcs7_get_content_data);
214 
215 /*
216  * Note an OID when we find one for later processing when we know how
217  * to interpret it.
218  */
219 int pkcs7_note_OID(void *context, size_t hdrlen,
220 		   unsigned char tag,
221 		   const void *value, size_t vlen)
222 {
223 	struct pkcs7_parse_context *ctx = context;
224 
225 	ctx->last_oid = look_up_OID(value, vlen);
226 	if (ctx->last_oid == OID__NR) {
227 		char buffer[50];
228 		sprint_oid(value, vlen, buffer, sizeof(buffer));
229 		printk("PKCS7: Unknown OID: [%lu] %s\n",
230 		       (unsigned long)value - ctx->data, buffer);
231 	}
232 	return 0;
233 }
234 
235 /*
236  * Note the digest algorithm for the signature.
237  */
238 int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen,
239 			       unsigned char tag,
240 			       const void *value, size_t vlen)
241 {
242 	struct pkcs7_parse_context *ctx = context;
243 
244 	switch (ctx->last_oid) {
245 	case OID_sha1:
246 		ctx->sinfo->sig->hash_algo = "sha1";
247 		break;
248 	case OID_sha256:
249 		ctx->sinfo->sig->hash_algo = "sha256";
250 		break;
251 	case OID_sha384:
252 		ctx->sinfo->sig->hash_algo = "sha384";
253 		break;
254 	case OID_sha512:
255 		ctx->sinfo->sig->hash_algo = "sha512";
256 		break;
257 	case OID_sha224:
258 		ctx->sinfo->sig->hash_algo = "sha224";
259 		break;
260 	case OID_sm3:
261 		ctx->sinfo->sig->hash_algo = "sm3";
262 		break;
263 	case OID_gost2012Digest256:
264 		ctx->sinfo->sig->hash_algo = "streebog256";
265 		break;
266 	case OID_gost2012Digest512:
267 		ctx->sinfo->sig->hash_algo = "streebog512";
268 		break;
269 	case OID_sha3_256:
270 		ctx->sinfo->sig->hash_algo = "sha3-256";
271 		break;
272 	case OID_sha3_384:
273 		ctx->sinfo->sig->hash_algo = "sha3-384";
274 		break;
275 	case OID_sha3_512:
276 		ctx->sinfo->sig->hash_algo = "sha3-512";
277 		break;
278 	default:
279 		printk("Unsupported digest algo: %u\n", ctx->last_oid);
280 		return -ENOPKG;
281 	}
282 	return 0;
283 }
284 
285 /*
286  * Note the public key algorithm for the signature.
287  */
288 int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
289 			     unsigned char tag,
290 			     const void *value, size_t vlen)
291 {
292 	struct pkcs7_parse_context *ctx = context;
293 
294 	switch (ctx->last_oid) {
295 	case OID_rsaEncryption:
296 		ctx->sinfo->sig->pkey_algo = "rsa";
297 		ctx->sinfo->sig->encoding = "pkcs1";
298 		break;
299 	case OID_id_ecdsa_with_sha1:
300 	case OID_id_ecdsa_with_sha224:
301 	case OID_id_ecdsa_with_sha256:
302 	case OID_id_ecdsa_with_sha384:
303 	case OID_id_ecdsa_with_sha512:
304 	case OID_id_ecdsa_with_sha3_256:
305 	case OID_id_ecdsa_with_sha3_384:
306 	case OID_id_ecdsa_with_sha3_512:
307 		ctx->sinfo->sig->pkey_algo = "ecdsa";
308 		ctx->sinfo->sig->encoding = "x962";
309 		break;
310 	case OID_gost2012PKey256:
311 	case OID_gost2012PKey512:
312 		ctx->sinfo->sig->pkey_algo = "ecrdsa";
313 		ctx->sinfo->sig->encoding = "raw";
314 		break;
315 	case OID_id_ml_dsa_44:
316 		ctx->sinfo->sig->pkey_algo = "mldsa44";
317 		ctx->sinfo->sig->encoding = "raw";
318 		ctx->sinfo->sig->algo_takes_data = true;
319 		break;
320 	case OID_id_ml_dsa_65:
321 		ctx->sinfo->sig->pkey_algo = "mldsa65";
322 		ctx->sinfo->sig->encoding = "raw";
323 		ctx->sinfo->sig->algo_takes_data = true;
324 		break;
325 	case OID_id_ml_dsa_87:
326 		ctx->sinfo->sig->pkey_algo = "mldsa87";
327 		ctx->sinfo->sig->encoding = "raw";
328 		ctx->sinfo->sig->algo_takes_data = true;
329 		break;
330 	default:
331 		printk("Unsupported pkey algo: %u\n", ctx->last_oid);
332 		return -ENOPKG;
333 	}
334 	return 0;
335 }
336 
337 /*
338  * We only support signed data [RFC2315 sec 9].
339  */
340 int pkcs7_check_content_type(void *context, size_t hdrlen,
341 			     unsigned char tag,
342 			     const void *value, size_t vlen)
343 {
344 	struct pkcs7_parse_context *ctx = context;
345 
346 	if (ctx->last_oid != OID_signed_data) {
347 		pr_warn("Only support pkcs7_signedData type\n");
348 		return -EINVAL;
349 	}
350 
351 	return 0;
352 }
353 
354 /*
355  * Note the SignedData version
356  */
357 int pkcs7_note_signeddata_version(void *context, size_t hdrlen,
358 				  unsigned char tag,
359 				  const void *value, size_t vlen)
360 {
361 	struct pkcs7_parse_context *ctx = context;
362 	unsigned version;
363 
364 	if (vlen != 1)
365 		goto unsupported;
366 
367 	ctx->msg->version = version = *(const u8 *)value;
368 	switch (version) {
369 	case 1:
370 		/* PKCS#7 SignedData [RFC2315 sec 9.1]
371 		 * CMS ver 1 SignedData [RFC5652 sec 5.1]
372 		 */
373 		break;
374 	case 3:
375 		/* CMS ver 3 SignedData [RFC2315 sec 5.1] */
376 		break;
377 	default:
378 		goto unsupported;
379 	}
380 
381 	return 0;
382 
383 unsupported:
384 	pr_warn("Unsupported SignedData version\n");
385 	return -EINVAL;
386 }
387 
388 /*
389  * Note the SignerInfo version
390  */
391 int pkcs7_note_signerinfo_version(void *context, size_t hdrlen,
392 				  unsigned char tag,
393 				  const void *value, size_t vlen)
394 {
395 	struct pkcs7_parse_context *ctx = context;
396 	unsigned version;
397 
398 	if (vlen != 1)
399 		goto unsupported;
400 
401 	version = *(const u8 *)value;
402 	switch (version) {
403 	case 1:
404 		/* PKCS#7 SignerInfo [RFC2315 sec 9.2]
405 		 * CMS ver 1 SignerInfo [RFC5652 sec 5.3]
406 		 */
407 		if (ctx->msg->version != 1)
408 			goto version_mismatch;
409 		ctx->expect_skid = false;
410 		break;
411 	case 3:
412 		/* CMS ver 3 SignerInfo [RFC2315 sec 5.3] */
413 		if (ctx->msg->version == 1)
414 			goto version_mismatch;
415 		ctx->expect_skid = true;
416 		break;
417 	default:
418 		goto unsupported;
419 	}
420 
421 	return 0;
422 
423 unsupported:
424 	pr_warn("Unsupported SignerInfo version\n");
425 	return -EINVAL;
426 version_mismatch:
427 	pr_warn("SignedData-SignerInfo version mismatch\n");
428 	return -EBADMSG;
429 }
430 
431 /*
432  * Extract a certificate and store it in the context.
433  */
434 int pkcs7_extract_cert(void *context, size_t hdrlen,
435 		       unsigned char tag,
436 		       const void *value, size_t vlen)
437 {
438 	struct pkcs7_parse_context *ctx = context;
439 	struct x509_certificate *x509;
440 
441 	if (tag != ((ASN1_UNIV << 6) | ASN1_CONS_BIT | ASN1_SEQ)) {
442 		pr_debug("Cert began with tag %02x at %lu\n",
443 			 tag, (unsigned long)ctx - ctx->data);
444 		return -EBADMSG;
445 	}
446 
447 	/* We have to correct for the header so that the X.509 parser can start
448 	 * from the beginning.  Note that since X.509 stipulates DER, there
449 	 * probably shouldn't be an EOC trailer - but it is in PKCS#7 (which
450 	 * stipulates BER).
451 	 */
452 	value -= hdrlen;
453 	vlen += hdrlen;
454 
455 	if (((u8*)value)[1] == 0x80)
456 		vlen += 2; /* Indefinite length - there should be an EOC */
457 
458 	x509 = x509_cert_parse(value, vlen);
459 	if (IS_ERR(x509))
460 		return PTR_ERR(x509);
461 
462 	x509->index = ++ctx->x509_index;
463 	pr_debug("Got cert %u for %s\n", x509->index, x509->subject);
464 	pr_debug("- fingerprint %*phN\n", x509->id->len, x509->id->data);
465 
466 	*ctx->ppcerts = x509;
467 	ctx->ppcerts = &x509->next;
468 	return 0;
469 }
470 
471 /*
472  * Save the certificate list
473  */
474 int pkcs7_note_certificate_list(void *context, size_t hdrlen,
475 				unsigned char tag,
476 				const void *value, size_t vlen)
477 {
478 	struct pkcs7_parse_context *ctx = context;
479 
480 	pr_devel("Got cert list (%02x)\n", tag);
481 
482 	*ctx->ppcerts = ctx->msg->certs;
483 	ctx->msg->certs = ctx->certs;
484 	ctx->certs = NULL;
485 	ctx->ppcerts = &ctx->certs;
486 	return 0;
487 }
488 
489 /*
490  * Note the content type.
491  */
492 int pkcs7_note_content(void *context, size_t hdrlen,
493 		       unsigned char tag,
494 		       const void *value, size_t vlen)
495 {
496 	struct pkcs7_parse_context *ctx = context;
497 
498 	if (ctx->last_oid != OID_data &&
499 	    ctx->last_oid != OID_msIndirectData) {
500 		pr_warn("Unsupported data type %d\n", ctx->last_oid);
501 		return -EINVAL;
502 	}
503 
504 	ctx->msg->data_type = ctx->last_oid;
505 	return 0;
506 }
507 
508 /*
509  * Extract the data from the message and store that and its content type OID in
510  * the context.
511  */
512 int pkcs7_note_data(void *context, size_t hdrlen,
513 		    unsigned char tag,
514 		    const void *value, size_t vlen)
515 {
516 	struct pkcs7_parse_context *ctx = context;
517 
518 	pr_debug("Got data\n");
519 
520 	ctx->msg->data = value;
521 	ctx->msg->data_len = vlen;
522 	ctx->msg->data_hdrlen = hdrlen;
523 	return 0;
524 }
525 
526 /*
527  * Parse authenticated attributes.
528  */
529 int pkcs7_sig_note_authenticated_attr(void *context, size_t hdrlen,
530 				      unsigned char tag,
531 				      const void *value, size_t vlen)
532 {
533 	struct pkcs7_parse_context *ctx = context;
534 	struct pkcs7_signed_info *sinfo = ctx->sinfo;
535 	enum OID content_type;
536 
537 	pr_devel("AuthAttr: %02x %zu [%*ph]\n", tag, vlen, (unsigned)vlen, value);
538 
539 	switch (ctx->last_oid) {
540 	case OID_contentType:
541 		if (__test_and_set_bit(sinfo_has_content_type, &sinfo->aa_set))
542 			goto repeated;
543 		content_type = look_up_OID(value, vlen);
544 		if (content_type != ctx->msg->data_type) {
545 			pr_warn("Mismatch between global data type (%d) and sinfo %u (%d)\n",
546 				ctx->msg->data_type, sinfo->index,
547 				content_type);
548 			return -EBADMSG;
549 		}
550 		return 0;
551 
552 	case OID_signingTime:
553 		if (__test_and_set_bit(sinfo_has_signing_time, &sinfo->aa_set))
554 			goto repeated;
555 		/* Should we check that the signing time is consistent
556 		 * with the signer's X.509 cert?
557 		 */
558 		return x509_decode_time(&sinfo->signing_time,
559 					hdrlen, tag, value, vlen);
560 
561 	case OID_messageDigest:
562 		if (__test_and_set_bit(sinfo_has_message_digest, &sinfo->aa_set))
563 			goto repeated;
564 		if (tag != ASN1_OTS)
565 			return -EBADMSG;
566 		sinfo->msgdigest = value;
567 		sinfo->msgdigest_len = vlen;
568 		return 0;
569 
570 	case OID_smimeCapabilites:
571 		if (__test_and_set_bit(sinfo_has_smime_caps, &sinfo->aa_set))
572 			goto repeated;
573 		if (ctx->msg->data_type != OID_msIndirectData) {
574 			pr_warn("S/MIME Caps only allowed with Authenticode\n");
575 			return -EKEYREJECTED;
576 		}
577 		return 0;
578 
579 		/* Microsoft SpOpusInfo seems to be contain cont[0] 16-bit BE
580 		 * char URLs and cont[1] 8-bit char URLs.
581 		 *
582 		 * Microsoft StatementType seems to contain a list of OIDs that
583 		 * are also used as extendedKeyUsage types in X.509 certs.
584 		 */
585 	case OID_msSpOpusInfo:
586 		if (__test_and_set_bit(sinfo_has_ms_opus_info, &sinfo->aa_set))
587 			goto repeated;
588 		goto authenticode_check;
589 	case OID_msStatementType:
590 		if (__test_and_set_bit(sinfo_has_ms_statement_type, &sinfo->aa_set))
591 			goto repeated;
592 	authenticode_check:
593 		if (ctx->msg->data_type != OID_msIndirectData) {
594 			pr_warn("Authenticode AuthAttrs only allowed with Authenticode\n");
595 			return -EKEYREJECTED;
596 		}
597 		/* I'm not sure how to validate these */
598 		return 0;
599 	default:
600 		return 0;
601 	}
602 
603 repeated:
604 	/* We permit max one item per AuthenticatedAttribute and no repeats */
605 	pr_warn("Repeated/multivalue AuthAttrs not permitted\n");
606 	return -EKEYREJECTED;
607 }
608 
609 /*
610  * Note the set of auth attributes for digestion purposes [RFC2315 sec 9.3]
611  */
612 int pkcs7_sig_note_set_of_authattrs(void *context, size_t hdrlen,
613 				    unsigned char tag,
614 				    const void *value, size_t vlen)
615 {
616 	struct pkcs7_parse_context *ctx = context;
617 	struct pkcs7_signed_info *sinfo = ctx->sinfo;
618 
619 	if (!test_bit(sinfo_has_content_type, &sinfo->aa_set) ||
620 	    !test_bit(sinfo_has_message_digest, &sinfo->aa_set)) {
621 		pr_warn("Missing required AuthAttr\n");
622 		return -EBADMSG;
623 	}
624 
625 	if (ctx->msg->data_type != OID_msIndirectData &&
626 	    test_bit(sinfo_has_ms_opus_info, &sinfo->aa_set)) {
627 		pr_warn("Unexpected Authenticode AuthAttr\n");
628 		return -EBADMSG;
629 	}
630 
631 	/* We need to switch the 'CONT 0' to a 'SET OF' when we digest */
632 	sinfo->authattrs = value - hdrlen;
633 	sinfo->authattrs_len = vlen + hdrlen;
634 	return 0;
635 }
636 
637 /*
638  * Note the issuing certificate serial number
639  */
640 int pkcs7_sig_note_serial(void *context, size_t hdrlen,
641 			  unsigned char tag,
642 			  const void *value, size_t vlen)
643 {
644 	struct pkcs7_parse_context *ctx = context;
645 	ctx->raw_serial = value;
646 	ctx->raw_serial_size = vlen;
647 	return 0;
648 }
649 
650 /*
651  * Note the issuer's name
652  */
653 int pkcs7_sig_note_issuer(void *context, size_t hdrlen,
654 			  unsigned char tag,
655 			  const void *value, size_t vlen)
656 {
657 	struct pkcs7_parse_context *ctx = context;
658 	ctx->raw_issuer = value;
659 	ctx->raw_issuer_size = vlen;
660 	return 0;
661 }
662 
663 /*
664  * Note the issuing cert's subjectKeyIdentifier
665  */
666 int pkcs7_sig_note_skid(void *context, size_t hdrlen,
667 			unsigned char tag,
668 			const void *value, size_t vlen)
669 {
670 	struct pkcs7_parse_context *ctx = context;
671 
672 	pr_devel("SKID: %02x %zu [%*ph]\n", tag, vlen, (unsigned)vlen, value);
673 
674 	ctx->raw_skid = value;
675 	ctx->raw_skid_size = vlen;
676 	return 0;
677 }
678 
679 /*
680  * Note the signature data
681  */
682 int pkcs7_sig_note_signature(void *context, size_t hdrlen,
683 			     unsigned char tag,
684 			     const void *value, size_t vlen)
685 {
686 	struct pkcs7_parse_context *ctx = context;
687 
688 	ctx->sinfo->sig->s = kmemdup(value, vlen, GFP_KERNEL);
689 	if (!ctx->sinfo->sig->s)
690 		return -ENOMEM;
691 
692 	ctx->sinfo->sig->s_size = vlen;
693 	return 0;
694 }
695 
696 /*
697  * Note a signature information block
698  */
699 int pkcs7_note_signed_info(void *context, size_t hdrlen,
700 			   unsigned char tag,
701 			   const void *value, size_t vlen)
702 {
703 	struct pkcs7_parse_context *ctx = context;
704 	struct pkcs7_signed_info *sinfo = ctx->sinfo;
705 	struct asymmetric_key_id *kid;
706 
707 	if (ctx->msg->data_type == OID_msIndirectData && !sinfo->authattrs) {
708 		pr_warn("Authenticode requires AuthAttrs\n");
709 		return -EBADMSG;
710 	}
711 
712 	/* Generate cert issuer + serial number key ID */
713 	if (!ctx->expect_skid) {
714 		kid = asymmetric_key_generate_id(ctx->raw_serial,
715 						 ctx->raw_serial_size,
716 						 ctx->raw_issuer,
717 						 ctx->raw_issuer_size);
718 	} else {
719 		kid = asymmetric_key_generate_id(ctx->raw_skid,
720 						 ctx->raw_skid_size,
721 						 "", 0);
722 	}
723 	if (IS_ERR(kid))
724 		return PTR_ERR(kid);
725 
726 	pr_devel("SINFO KID: %u [%*phN]\n", kid->len, kid->len, kid->data);
727 
728 	sinfo->sig->auth_ids[0] = kid;
729 	sinfo->index = ++ctx->sinfo_index;
730 	*ctx->ppsinfo = sinfo;
731 	ctx->ppsinfo = &sinfo->next;
732 	ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
733 	if (!ctx->sinfo)
734 		return -ENOMEM;
735 	ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),
736 				  GFP_KERNEL);
737 	if (!ctx->sinfo->sig)
738 		return -ENOMEM;
739 	return 0;
740 }
741