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