|
@@ -108,3 +108,74 @@ int restrict_link_by_signature(struct key *dest_keyring,
|
|
|
key_put(key);
|
|
|
return ret;
|
|
|
}
|
|
|
+
|
|
|
+/**
|
|
|
+ * restrict_link_by_key_or_keyring - Restrict additions to a ring of public
|
|
|
+ * keys using the restrict_key information stored in the ring.
|
|
|
+ * @dest_keyring: Keyring being linked to.
|
|
|
+ * @type: The type of key being added.
|
|
|
+ * @payload: The payload of the new key.
|
|
|
+ * @trusted: A key or ring of keys that can be used to vouch for the new cert.
|
|
|
+ *
|
|
|
+ * Check the new certificate only against the key or keys passed in the data
|
|
|
+ * parameter. If one of those is the signing key and validates the new
|
|
|
+ * certificate, then mark the new certificate as being ok to link.
|
|
|
+ *
|
|
|
+ * 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, and some other error if
|
|
|
+ * there is a matching certificate but the signature check cannot be
|
|
|
+ * performed.
|
|
|
+ */
|
|
|
+int restrict_link_by_key_or_keyring(struct key *dest_keyring,
|
|
|
+ const struct key_type *type,
|
|
|
+ const union key_payload *payload,
|
|
|
+ struct key *trusted)
|
|
|
+{
|
|
|
+ const struct public_key_signature *sig;
|
|
|
+ struct key *key;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ pr_devel("==>%s()\n", __func__);
|
|
|
+
|
|
|
+ if (!dest_keyring)
|
|
|
+ return -ENOKEY;
|
|
|
+ else if (dest_keyring->type != &key_type_keyring)
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+
|
|
|
+ if (!trusted)
|
|
|
+ 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 (trusted->type == &key_type_keyring) {
|
|
|
+ /* See if we have a key that signed this one. */
|
|
|
+ key = find_asymmetric_key(trusted, sig->auth_ids[0],
|
|
|
+ sig->auth_ids[1], false);
|
|
|
+ if (IS_ERR(key))
|
|
|
+ return -ENOKEY;
|
|
|
+ } else if (trusted->type == &key_type_asymmetric) {
|
|
|
+ const struct asymmetric_key_ids *kids;
|
|
|
+
|
|
|
+ kids = asymmetric_key_ids(trusted);
|
|
|
+
|
|
|
+ if (!asymmetric_key_id_same(kids->id[1], sig->auth_ids[0]))
|
|
|
+ return -ENOKEY;
|
|
|
+
|
|
|
+ key = __key_get(trusted);
|
|
|
+ } else {
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = key_validate(key);
|
|
|
+ if (ret == 0)
|
|
|
+ ret = verify_signature(key, sig);
|
|
|
+
|
|
|
+ key_put(key);
|
|
|
+ return ret;
|
|
|
+}
|