mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 04:31:50 +00:00
77f68bac94
Remove KEY_FLAG_TRUSTED and KEY_ALLOC_TRUSTED as they're no longer meaningful. Also we can drop the trusted flag from the preparse structure. Given this, we no longer need to pass the key flags through to restrict_link(). Further, we can now get rid of keyring_restrict_trusted_only() also. Signed-off-by: David Howells <dhowells@redhat.com>
160 lines
3.7 KiB
C
160 lines
3.7 KiB
C
/*
|
|
* Copyright (C) 2011 Intel Corporation
|
|
*
|
|
* Author:
|
|
* Dmitry Kasatkin <dmitry.kasatkin@intel.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, version 2 of the License.
|
|
*
|
|
*/
|
|
|
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
|
|
#include <linux/err.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/cred.h>
|
|
#include <linux/key-type.h>
|
|
#include <linux/digsig.h>
|
|
#include <crypto/public_key.h>
|
|
#include <keys/system_keyring.h>
|
|
|
|
#include "integrity.h"
|
|
|
|
static struct key *keyring[INTEGRITY_KEYRING_MAX];
|
|
|
|
static const char *keyring_name[INTEGRITY_KEYRING_MAX] = {
|
|
#ifndef CONFIG_INTEGRITY_TRUSTED_KEYRING
|
|
"_evm",
|
|
"_ima",
|
|
#else
|
|
".evm",
|
|
".ima",
|
|
#endif
|
|
"_module",
|
|
};
|
|
|
|
#ifdef CONFIG_INTEGRITY_TRUSTED_KEYRING
|
|
static bool init_keyring __initdata = true;
|
|
#else
|
|
static bool init_keyring __initdata;
|
|
#endif
|
|
|
|
#ifdef CONFIG_SYSTEM_TRUSTED_KEYRING
|
|
/*
|
|
* Restrict the addition of keys into the IMA keyring.
|
|
*
|
|
* Any key that needs to go in .ima keyring must be signed by CA in
|
|
* either .system or .ima_mok keyrings.
|
|
*/
|
|
static int restrict_link_by_ima_mok(struct key *keyring,
|
|
const struct key_type *type,
|
|
const union key_payload *payload)
|
|
{
|
|
int ret;
|
|
|
|
ret = restrict_link_by_builtin_trusted(keyring, type, payload);
|
|
if (ret != -ENOKEY)
|
|
return ret;
|
|
|
|
return restrict_link_by_signature(get_ima_mok_keyring(),
|
|
type, payload);
|
|
}
|
|
#else
|
|
/*
|
|
* If there's no system trusted keyring, then keys cannot be loaded into
|
|
* .ima_mok and added keys cannot be marked trusted.
|
|
*/
|
|
#define restrict_link_by_ima_mok restrict_link_reject
|
|
#endif
|
|
|
|
int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
|
|
const char *digest, int digestlen)
|
|
{
|
|
if (id >= INTEGRITY_KEYRING_MAX)
|
|
return -EINVAL;
|
|
|
|
if (!keyring[id]) {
|
|
keyring[id] =
|
|
request_key(&key_type_keyring, keyring_name[id], NULL);
|
|
if (IS_ERR(keyring[id])) {
|
|
int err = PTR_ERR(keyring[id]);
|
|
pr_err("no %s keyring: %d\n", keyring_name[id], err);
|
|
keyring[id] = NULL;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
switch (sig[1]) {
|
|
case 1:
|
|
/* v1 API expect signature without xattr type */
|
|
return digsig_verify(keyring[id], sig + 1, siglen - 1,
|
|
digest, digestlen);
|
|
case 2:
|
|
return asymmetric_verify(keyring[id], sig, siglen,
|
|
digest, digestlen);
|
|
}
|
|
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
int __init integrity_init_keyring(const unsigned int id)
|
|
{
|
|
const struct cred *cred = current_cred();
|
|
int err = 0;
|
|
|
|
if (!init_keyring)
|
|
return 0;
|
|
|
|
keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
|
|
KGIDT_INIT(0), cred,
|
|
((KEY_POS_ALL & ~KEY_POS_SETATTR) |
|
|
KEY_USR_VIEW | KEY_USR_READ |
|
|
KEY_USR_WRITE | KEY_USR_SEARCH),
|
|
KEY_ALLOC_NOT_IN_QUOTA,
|
|
restrict_link_by_ima_mok, NULL);
|
|
if (IS_ERR(keyring[id])) {
|
|
err = PTR_ERR(keyring[id]);
|
|
pr_info("Can't allocate %s keyring (%d)\n",
|
|
keyring_name[id], err);
|
|
keyring[id] = NULL;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
int __init integrity_load_x509(const unsigned int id, const char *path)
|
|
{
|
|
key_ref_t key;
|
|
char *data;
|
|
int rc;
|
|
|
|
if (!keyring[id])
|
|
return -EINVAL;
|
|
|
|
rc = integrity_read_file(path, &data);
|
|
if (rc < 0)
|
|
return rc;
|
|
|
|
key = key_create_or_update(make_key_ref(keyring[id], 1),
|
|
"asymmetric",
|
|
NULL,
|
|
data,
|
|
rc,
|
|
((KEY_POS_ALL & ~KEY_POS_SETATTR) |
|
|
KEY_USR_VIEW | KEY_USR_READ),
|
|
KEY_ALLOC_NOT_IN_QUOTA);
|
|
if (IS_ERR(key)) {
|
|
rc = PTR_ERR(key);
|
|
pr_err("Problem loading X.509 certificate (%d): %s\n",
|
|
rc, path);
|
|
} else {
|
|
pr_notice("Loaded X.509 cert '%s': %s\n",
|
|
key_ref_to_ptr(key)->description, path);
|
|
key_ref_put(key);
|
|
}
|
|
kfree(data);
|
|
return 0;
|
|
}
|