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