/* * Check the new certificate against the ones in the trust keyring. If one of * those is the signing key and validates the new certificate, then mark the * new certificate as being trusted. * * Return 0 if the new certificate was successfully validated, 1 if we couldn't * find a matching parent certificate in the trusted list and an error if there * is a matching certificate but the signature check fails. */ static int x509_validate_trust(struct x509_certificate *cert, struct key *trust_keyring) { struct key *key; int ret = 1; if (!trust_keyring) return -EOPNOTSUPP; if (ca_keyid && !asymmetric_key_id_partial(cert->akid_skid, ca_keyid)) return -EPERM; key = x509_request_asymmetric_key(trust_keyring, cert->akid_skid, false); if (!IS_ERR(key)) { if (!use_builtin_keys || test_bit(KEY_FLAG_BUILTIN, &key->flags)) ret = x509_check_signature(key->payload.data, cert); key_put(key); } return ret; }
/** * restrict_link_by_signature - Restrict additions to a ring of public keys * @trust_keyring: A ring of keys that can be used to vouch for the new cert. * @type: The type of key being added. * @payload: The payload of the new key. * * Check the new certificate against the ones in the trust keyring. If one of * those is the signing key and validates the new certificate, then mark the * new certificate as being trusted. * * Returns 0 if the new certificate was accepted, -ENOKEY if we couldn't find a * matching parent certificate in the trusted list, -EKEYREJECTED if the * signature check fails or the key is blacklisted and some other error if * there is a matching certificate but the signature check cannot be performed. */ int restrict_link_by_signature(struct key *trust_keyring, const struct key_type *type, const union key_payload *payload) { const struct public_key_signature *sig; struct key *key; int ret; pr_devel("==>%s()\n", __func__); if (!trust_keyring) return -ENOKEY; if (type != &key_type_asymmetric) return -EOPNOTSUPP; sig = payload->data[asym_auth]; if (!sig->auth_ids[0] && !sig->auth_ids[1]) return -ENOKEY; if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid)) return -EPERM; /* See if we have a key that signed this one. */ key = find_asymmetric_key(trust_keyring, sig->auth_ids[0], sig->auth_ids[1], false); if (IS_ERR(key)) return -ENOKEY; if (use_builtin_keys && !test_bit(KEY_FLAG_BUILTIN, &key->flags)) ret = -ENOKEY; else ret = verify_signature(key, sig); key_put(key); return ret; }