1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* Verify the signature on a PKCS#7 message. 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/export.h> 11 #include <linux/slab.h> 12 #include <linux/err.h> 13 #include <linux/asn1.h> 14 #include <crypto/hash.h> 15 #include <crypto/hash_info.h> 16 #include <crypto/public_key.h> 17 #include "pkcs7_parser.h" 18 19 /* 20 * Digest the relevant parts of the PKCS#7 data 21 */ 22 static int pkcs7_digest(struct pkcs7_message *pkcs7, 23 struct pkcs7_signed_info *sinfo) 24 { 25 struct public_key_signature *sig = sinfo->sig; 26 struct crypto_shash *tfm; 27 struct shash_desc *desc; 28 size_t desc_size; 29 int ret; 30 31 kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo); 32 33 /* The digest was calculated already. */ 34 if (sig->digest) 35 return 0; 36 37 if (!sinfo->sig->hash_algo) 38 return -ENOPKG; 39 40 /* Allocate the hashing algorithm we're going to need and find out how 41 * big the hash operational data will be. 42 */ 43 tfm = crypto_alloc_shash(sinfo->sig->hash_algo, 0, 0); 44 if (IS_ERR(tfm)) 45 return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); 46 47 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 48 sig->digest_size = crypto_shash_digestsize(tfm); 49 50 ret = -ENOMEM; 51 sig->digest = kmalloc(sig->digest_size, GFP_KERNEL); 52 if (!sig->digest) 53 goto error_no_desc; 54 55 desc = kzalloc(desc_size, GFP_KERNEL); 56 if (!desc) 57 goto error_no_desc; 58 59 desc->tfm = tfm; 60 61 /* Digest the message [RFC2315 9.3] */ 62 ret = crypto_shash_digest(desc, pkcs7->data, pkcs7->data_len, 63 sig->digest); 64 if (ret < 0) 65 goto error; 66 pr_devel("MsgDigest = [%*ph]\n", 8, sig->digest); 67 68 /* However, if there are authenticated attributes, there must be a 69 * message digest attribute amongst them which corresponds to the 70 * digest we just calculated. 71 */ 72 if (sinfo->authattrs) { 73 u8 tag; 74 75 if (!sinfo->msgdigest) { 76 pr_warn("Sig %u: No messageDigest\n", sinfo->index); 77 ret = -EKEYREJECTED; 78 goto error; 79 } 80 81 if (sinfo->msgdigest_len != sig->digest_size) { 82 pr_debug("Sig %u: Invalid digest size (%u)\n", 83 sinfo->index, sinfo->msgdigest_len); 84 ret = -EBADMSG; 85 goto error; 86 } 87 88 if (memcmp(sig->digest, sinfo->msgdigest, 89 sinfo->msgdigest_len) != 0) { 90 pr_debug("Sig %u: Message digest doesn't match\n", 91 sinfo->index); 92 ret = -EKEYREJECTED; 93 goto error; 94 } 95 96 /* We then calculate anew, using the authenticated attributes 97 * as the contents of the digest instead. Note that we need to 98 * convert the attributes from a CONT.0 into a SET before we 99 * hash it. 100 */ 101 memset(sig->digest, 0, sig->digest_size); 102 103 ret = crypto_shash_init(desc); 104 if (ret < 0) 105 goto error; 106 tag = ASN1_CONS_BIT | ASN1_SET; 107 ret = crypto_shash_update(desc, &tag, 1); 108 if (ret < 0) 109 goto error; 110 ret = crypto_shash_finup(desc, sinfo->authattrs, 111 sinfo->authattrs_len, sig->digest); 112 if (ret < 0) 113 goto error; 114 pr_devel("AADigest = [%*ph]\n", 8, sig->digest); 115 } 116 117 error: 118 kfree(desc); 119 error_no_desc: 120 crypto_free_shash(tfm); 121 kleave(" = %d", ret); 122 return ret; 123 } 124 125 int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf, u32 *len, 126 enum hash_algo *hash_algo) 127 { 128 struct pkcs7_signed_info *sinfo = pkcs7->signed_infos; 129 int i, ret; 130 131 /* 132 * This function doesn't support messages with more than one signature. 133 */ 134 if (sinfo == NULL || sinfo->next != NULL) 135 return -EBADMSG; 136 137 ret = pkcs7_digest(pkcs7, sinfo); 138 if (ret) 139 return ret; 140 141 *buf = sinfo->sig->digest; 142 *len = sinfo->sig->digest_size; 143 144 i = match_string(hash_algo_name, HASH_ALGO__LAST, 145 sinfo->sig->hash_algo); 146 if (i >= 0) 147 *hash_algo = i; 148 149 return 0; 150 } 151 152 /* 153 * Find the key (X.509 certificate) to use to verify a PKCS#7 message. PKCS#7 154 * uses the issuer's name and the issuing certificate serial number for 155 * matching purposes. These must match the certificate issuer's name (not 156 * subject's name) and the certificate serial number [RFC 2315 6.7]. 157 */ 158 static int pkcs7_find_key(struct pkcs7_message *pkcs7, 159 struct pkcs7_signed_info *sinfo) 160 { 161 struct x509_certificate *x509; 162 unsigned certix = 1; 163 164 kenter("%u", sinfo->index); 165 166 for (x509 = pkcs7->certs; x509; x509 = x509->next, certix++) { 167 /* I'm _assuming_ that the generator of the PKCS#7 message will 168 * encode the fields from the X.509 cert in the same way in the 169 * PKCS#7 message - but I can't be 100% sure of that. It's 170 * possible this will need element-by-element comparison. 171 */ 172 if (!asymmetric_key_id_same(x509->id, sinfo->sig->auth_ids[0])) 173 continue; 174 pr_devel("Sig %u: Found cert serial match X.509[%u]\n", 175 sinfo->index, certix); 176 177 if (strcmp(x509->pub->pkey_algo, sinfo->sig->pkey_algo) != 0) { 178 pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n", 179 sinfo->index); 180 continue; 181 } 182 183 sinfo->signer = x509; 184 return 0; 185 } 186 187 /* The relevant X.509 cert isn't found here, but it might be found in 188 * the trust keyring. 189 */ 190 pr_debug("Sig %u: Issuing X.509 cert not found (#%*phN)\n", 191 sinfo->index, 192 sinfo->sig->auth_ids[0]->len, sinfo->sig->auth_ids[0]->data); 193 return 0; 194 } 195 196 /* 197 * Verify the internal certificate chain as best we can. 198 */ 199 static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7, 200 struct pkcs7_signed_info *sinfo) 201 { 202 struct public_key_signature *sig; 203 struct x509_certificate *x509 = sinfo->signer, *p; 204 struct asymmetric_key_id *auth; 205 int ret; 206 207 kenter(""); 208 209 for (p = pkcs7->certs; p; p = p->next) 210 p->seen = false; 211 212 for (;;) { 213 pr_debug("verify %s: %*phN\n", 214 x509->subject, 215 x509->raw_serial_size, x509->raw_serial); 216 x509->seen = true; 217 218 if (x509->blacklisted) { 219 /* If this cert is blacklisted, then mark everything 220 * that depends on this as blacklisted too. 221 */ 222 sinfo->blacklisted = true; 223 for (p = sinfo->signer; p != x509; p = p->signer) 224 p->blacklisted = true; 225 pr_debug("- blacklisted\n"); 226 return 0; 227 } 228 229 if (x509->unsupported_key) 230 goto unsupported_crypto_in_x509; 231 232 pr_debug("- issuer %s\n", x509->issuer); 233 sig = x509->sig; 234 if (sig->auth_ids[0]) 235 pr_debug("- authkeyid.id %*phN\n", 236 sig->auth_ids[0]->len, sig->auth_ids[0]->data); 237 if (sig->auth_ids[1]) 238 pr_debug("- authkeyid.skid %*phN\n", 239 sig->auth_ids[1]->len, sig->auth_ids[1]->data); 240 241 if (x509->self_signed) { 242 /* If there's no authority certificate specified, then 243 * the certificate must be self-signed and is the root 244 * of the chain. Likewise if the cert is its own 245 * authority. 246 */ 247 if (x509->unsupported_sig) 248 goto unsupported_crypto_in_x509; 249 x509->signer = x509; 250 pr_debug("- self-signed\n"); 251 return 0; 252 } 253 254 /* Look through the X.509 certificates in the PKCS#7 message's 255 * list to see if the next one is there. 256 */ 257 auth = sig->auth_ids[0]; 258 if (auth) { 259 pr_debug("- want %*phN\n", auth->len, auth->data); 260 for (p = pkcs7->certs; p; p = p->next) { 261 pr_debug("- cmp [%u] %*phN\n", 262 p->index, p->id->len, p->id->data); 263 if (asymmetric_key_id_same(p->id, auth)) 264 goto found_issuer_check_skid; 265 } 266 } else if (sig->auth_ids[1]) { 267 auth = sig->auth_ids[1]; 268 pr_debug("- want %*phN\n", auth->len, auth->data); 269 for (p = pkcs7->certs; p; p = p->next) { 270 if (!p->skid) 271 continue; 272 pr_debug("- cmp [%u] %*phN\n", 273 p->index, p->skid->len, p->skid->data); 274 if (asymmetric_key_id_same(p->skid, auth)) 275 goto found_issuer; 276 } 277 } 278 279 /* We didn't find the root of this chain */ 280 pr_debug("- top\n"); 281 return 0; 282 283 found_issuer_check_skid: 284 /* We matched issuer + serialNumber, but if there's an 285 * authKeyId.keyId, that must match the CA subjKeyId also. 286 */ 287 if (sig->auth_ids[1] && 288 !asymmetric_key_id_same(p->skid, sig->auth_ids[1])) { 289 pr_warn("Sig %u: X.509 chain contains auth-skid nonmatch (%u->%u)\n", 290 sinfo->index, x509->index, p->index); 291 return -EKEYREJECTED; 292 } 293 found_issuer: 294 pr_debug("- subject %s\n", p->subject); 295 if (p->seen) { 296 pr_warn("Sig %u: X.509 chain contains loop\n", 297 sinfo->index); 298 return 0; 299 } 300 ret = public_key_verify_signature(p->pub, x509->sig); 301 if (ret < 0) 302 return ret; 303 x509->signer = p; 304 if (x509 == p) { 305 pr_debug("- self-signed\n"); 306 return 0; 307 } 308 x509 = p; 309 might_sleep(); 310 } 311 312 unsupported_crypto_in_x509: 313 /* Just prune the certificate chain at this point if we lack some 314 * crypto module to go further. Note, however, we don't want to set 315 * sinfo->unsupported_crypto as the signed info block may still be 316 * validatable against an X.509 cert lower in the chain that we have a 317 * trusted copy of. 318 */ 319 return 0; 320 } 321 322 /* 323 * Verify one signed information block from a PKCS#7 message. 324 */ 325 static int pkcs7_verify_one(struct pkcs7_message *pkcs7, 326 struct pkcs7_signed_info *sinfo) 327 { 328 int ret; 329 330 kenter(",%u", sinfo->index); 331 332 /* First of all, digest the data in the PKCS#7 message and the 333 * signed information block 334 */ 335 ret = pkcs7_digest(pkcs7, sinfo); 336 if (ret < 0) 337 return ret; 338 339 /* Find the key for the signature if there is one */ 340 ret = pkcs7_find_key(pkcs7, sinfo); 341 if (ret < 0) 342 return ret; 343 344 if (!sinfo->signer) 345 return 0; 346 347 pr_devel("Using X.509[%u] for sig %u\n", 348 sinfo->signer->index, sinfo->index); 349 350 /* Check that the PKCS#7 signing time is valid according to the X.509 351 * certificate. We can't, however, check against the system clock 352 * since that may not have been set yet and may be wrong. 353 */ 354 if (test_bit(sinfo_has_signing_time, &sinfo->aa_set)) { 355 if (sinfo->signing_time < sinfo->signer->valid_from || 356 sinfo->signing_time > sinfo->signer->valid_to) { 357 pr_warn("Message signed outside of X.509 validity window\n"); 358 return -EKEYREJECTED; 359 } 360 } 361 362 /* Verify the PKCS#7 binary against the key */ 363 ret = public_key_verify_signature(sinfo->signer->pub, sinfo->sig); 364 if (ret < 0) 365 return ret; 366 367 pr_devel("Verified signature %u\n", sinfo->index); 368 369 /* Verify the internal certificate chain */ 370 return pkcs7_verify_sig_chain(pkcs7, sinfo); 371 } 372 373 /** 374 * pkcs7_verify - Verify a PKCS#7 message 375 * @pkcs7: The PKCS#7 message to be verified 376 * @usage: The use to which the key is being put 377 * 378 * Verify a PKCS#7 message is internally consistent - that is, the data digest 379 * matches the digest in the AuthAttrs and any signature in the message or one 380 * of the X.509 certificates it carries that matches another X.509 cert in the 381 * message can be verified. 382 * 383 * This does not look to match the contents of the PKCS#7 message against any 384 * external public keys. 385 * 386 * Returns, in order of descending priority: 387 * 388 * (*) -EKEYREJECTED if a key was selected that had a usage restriction at 389 * odds with the specified usage, or: 390 * 391 * (*) -EKEYREJECTED if a signature failed to match for which we found an 392 * appropriate X.509 certificate, or: 393 * 394 * (*) -EBADMSG if some part of the message was invalid, or: 395 * 396 * (*) 0 if a signature chain passed verification, or: 397 * 398 * (*) -EKEYREJECTED if a blacklisted key was encountered, or: 399 * 400 * (*) -ENOPKG if none of the signature chains are verifiable because suitable 401 * crypto modules couldn't be found. 402 */ 403 int pkcs7_verify(struct pkcs7_message *pkcs7, 404 enum key_being_used_for usage) 405 { 406 struct pkcs7_signed_info *sinfo; 407 int actual_ret = -ENOPKG; 408 int ret; 409 410 kenter(""); 411 412 switch (usage) { 413 case VERIFYING_MODULE_SIGNATURE: 414 if (pkcs7->data_type != OID_data) { 415 pr_warn("Invalid module sig (not pkcs7-data)\n"); 416 return -EKEYREJECTED; 417 } 418 if (pkcs7->have_authattrs) { 419 pr_warn("Invalid module sig (has authattrs)\n"); 420 return -EKEYREJECTED; 421 } 422 break; 423 case VERIFYING_FIRMWARE_SIGNATURE: 424 if (pkcs7->data_type != OID_data) { 425 pr_warn("Invalid firmware sig (not pkcs7-data)\n"); 426 return -EKEYREJECTED; 427 } 428 if (!pkcs7->have_authattrs) { 429 pr_warn("Invalid firmware sig (missing authattrs)\n"); 430 return -EKEYREJECTED; 431 } 432 break; 433 case VERIFYING_KEXEC_PE_SIGNATURE: 434 if (pkcs7->data_type != OID_msIndirectData) { 435 pr_warn("Invalid kexec sig (not Authenticode)\n"); 436 return -EKEYREJECTED; 437 } 438 /* Authattr presence checked in parser */ 439 break; 440 case VERIFYING_UNSPECIFIED_SIGNATURE: 441 if (pkcs7->data_type != OID_data) { 442 pr_warn("Invalid unspecified sig (not pkcs7-data)\n"); 443 return -EKEYREJECTED; 444 } 445 break; 446 default: 447 return -EINVAL; 448 } 449 450 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) { 451 ret = pkcs7_verify_one(pkcs7, sinfo); 452 if (sinfo->blacklisted) { 453 if (actual_ret == -ENOPKG) 454 actual_ret = -EKEYREJECTED; 455 continue; 456 } 457 if (ret < 0) { 458 if (ret == -ENOPKG) { 459 sinfo->unsupported_crypto = true; 460 continue; 461 } 462 kleave(" = %d", ret); 463 return ret; 464 } 465 actual_ret = 0; 466 } 467 468 kleave(" = %d", actual_ret); 469 return actual_ret; 470 } 471 EXPORT_SYMBOL_GPL(pkcs7_verify); 472 473 /** 474 * pkcs7_supply_detached_data - Supply the data needed to verify a PKCS#7 message 475 * @pkcs7: The PKCS#7 message 476 * @data: The data to be verified 477 * @datalen: The amount of data 478 * 479 * Supply the detached data needed to verify a PKCS#7 message. Note that no 480 * attempt to retain/pin the data is made. That is left to the caller. The 481 * data will not be modified by pkcs7_verify() and will not be freed when the 482 * PKCS#7 message is freed. 483 * 484 * Returns -EINVAL if data is already supplied in the message, 0 otherwise. 485 */ 486 int pkcs7_supply_detached_data(struct pkcs7_message *pkcs7, 487 const void *data, size_t datalen) 488 { 489 if (pkcs7->data) { 490 pr_debug("Data already supplied\n"); 491 return -EINVAL; 492 } 493 pkcs7->data = data; 494 pkcs7->data_len = datalen; 495 return 0; 496 } 497