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