^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Validate the trust chain of a PKCS#7 message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define pr_fmt(fmt) "PKCS7: "fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/asn1.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/key.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <keys/asymmetric-type.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <crypto/public_key.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "pkcs7_parser.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Check the trust on one PKCS#7 SignedInfo block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct pkcs7_signed_info *sinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct key *trust_keyring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct public_key_signature *sig = sinfo->sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct x509_certificate *x509, *last = NULL, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct key *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) kenter(",%u,", sinfo->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (sinfo->unsupported_crypto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) kleave(" = -ENOPKG [cached]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return -ENOPKG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) for (x509 = sinfo->signer; x509; x509 = x509->signer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (x509->seen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (x509->verified)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) goto verified;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) kleave(" = -ENOKEY [cached]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return -ENOKEY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) x509->seen = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* Look to see if this certificate is present in the trusted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * keys.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) key = find_asymmetric_key(trust_keyring,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) x509->id, x509->skid, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (!IS_ERR(key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* One of the X.509 certificates in the PKCS#7 message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * is apparently the same as one we already trust.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * Verify that the trusted variant can also validate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * the signature on the descendant.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) pr_devel("sinfo %u: Cert %u as key %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) sinfo->index, x509->index, key_serial(key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) goto matched;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (key == ERR_PTR(-ENOMEM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* Self-signed certificates form roots of their own, and if we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * don't know them, then we can't accept them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (x509->signer == x509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) kleave(" = -ENOKEY [unknown self-signed]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return -ENOKEY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) might_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) last = x509;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) sig = last->sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* No match - see if the root certificate has a signer amongst the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * trusted keys.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (last && (last->sig->auth_ids[0] || last->sig->auth_ids[1])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) key = find_asymmetric_key(trust_keyring,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) last->sig->auth_ids[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) last->sig->auth_ids[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (!IS_ERR(key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) x509 = last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) pr_devel("sinfo %u: Root cert %u signer is key %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) sinfo->index, x509->index, key_serial(key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) goto matched;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (PTR_ERR(key) != -ENOKEY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return PTR_ERR(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* As a last resort, see if we have a trusted public key that matches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * the signed info directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) key = find_asymmetric_key(trust_keyring,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) sinfo->sig->auth_ids[0], NULL, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (!IS_ERR(key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) pr_devel("sinfo %u: Direct signer is key %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) sinfo->index, key_serial(key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) x509 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) sig = sinfo->sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) goto matched;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (PTR_ERR(key) != -ENOKEY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return PTR_ERR(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) kleave(" = -ENOKEY [no backref]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return -ENOKEY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) matched:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ret = verify_signature(key, sig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) key_put(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (ret == -ENOMEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) kleave(" = -EKEYREJECTED [verify %d]", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return -EKEYREJECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) verified:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (x509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) x509->verified = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) for (p = sinfo->signer; p != x509; p = p->signer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) p->verified = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) kleave(" = 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * pkcs7_validate_trust - Validate PKCS#7 trust chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * @pkcs7: The PKCS#7 certificate to validate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * @trust_keyring: Signing certificates to use as starting points
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * Validate that the certificate chain inside the PKCS#7 message intersects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * keys we already know and trust.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * Returns, in order of descending priority:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * (*) -EKEYREJECTED if a signature failed to match for which we have a valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * key, or:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * (*) 0 if at least one signature chain intersects with the keys in the trust
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * keyring, or:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * (*) -ENOPKG if a suitable crypto module couldn't be found for a check on a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * chain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * (*) -ENOKEY if we couldn't find a match for any of the signature chains in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * the message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * May also return -ENOMEM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int pkcs7_validate_trust(struct pkcs7_message *pkcs7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct key *trust_keyring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct pkcs7_signed_info *sinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct x509_certificate *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int cached_ret = -ENOKEY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) for (p = pkcs7->certs; p; p = p->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) p->seen = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) ret = pkcs7_validate_trust_one(pkcs7, sinfo, trust_keyring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) case -ENOKEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) case -ENOPKG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (cached_ret == -ENOKEY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) cached_ret = -ENOPKG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) cached_ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return cached_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) EXPORT_SYMBOL_GPL(pkcs7_validate_trust);