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