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