On Fri, 2015-10-16 at 22:31 +0300, Petko Manolov wrote: > This option creates IMA MOK and blacklist keyrings. IMA MOK is an > intermediate keyring that sits between .system and .ima keyrings, > effectively forming a simple CA hierarchy. To successfully import a key > into .ima_mok it must be signed by a key which CA is in .system keyring. > On turn any key that needs to go in .ima keyring must be signed by CA in > either .system or .ima_mok keyrings. IMA MOK is empty at kernel boot. > > IMA blacklist keyring contains all revoked IMA keys. It is consulted > before any other keyring. If the search is successful the requested > operation is rejected and error is returned to the caller.
Why is the blacklist so closely tied to the .ima_mok keyring? Is this keyring only used for blacklisting keys on the .ima_mok keyring or for blacklisting keys on the .ima keyring as well? > Signed-off-by: Petko Manolov <pet...@mip-labs.com> > --- > crypto/asymmetric_keys/x509_public_key.c | 2 ++ > include/keys/system_keyring.h | 24 ++++++++++++++ > security/integrity/digsig_asymmetric.c | 14 +++++++++ > security/integrity/ima/Kconfig | 17 ++++++++++ > security/integrity/ima/Makefile | 1 + > security/integrity/ima/ima_mok.c | 54 > ++++++++++++++++++++++++++++++++ > 6 files changed, 112 insertions(+) > create mode 100644 security/integrity/ima/ima_mok.c > > diff --git a/crypto/asymmetric_keys/x509_public_key.c > b/crypto/asymmetric_keys/x509_public_key.c > index 1970966..66dcf30 100644 > --- a/crypto/asymmetric_keys/x509_public_key.c > +++ b/crypto/asymmetric_keys/x509_public_key.c > @@ -319,6 +319,8 @@ static int x509_key_preparse(struct key_preparsed_payload > *prep) > goto error_free_cert; > } else if (!prep->trusted) { > ret = x509_validate_trust(cert, get_system_trusted_keyring()); > + if (ret) > + ret = x509_validate_trust(cert, get_ima_mok_keyring()); > if (!ret) > prep->trusted = 1; > } > diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h > index b20cd88..39fd38c 100644 > --- a/include/keys/system_keyring.h > +++ b/include/keys/system_keyring.h > @@ -35,4 +35,28 @@ extern int system_verify_data(const void *data, unsigned > long len, > enum key_being_used_for usage); > #endif > > +#ifdef CONFIG_IMA_MOK_KEYRING > +extern struct key *ima_mok_keyring; > +extern struct key *ima_blacklist_keyring; > + > +static inline struct key *get_ima_mok_keyring(void) > +{ > + return ima_mok_keyring; > +} > +static inline struct key *get_ima_blacklist_keyring(void) > +{ > + return ima_blacklist_keyring; > +} > +#else > +static inline struct key *get_ima_mok_keyring(void) > +{ > + return NULL; > +} > +static inline struct key *get_ima_blacklist_keyring(void) > +{ > + return NULL; > +} > +#endif /* CONFIG_IMA_MOK_KEYRING */ > + > + > #endif /* _KEYS_SYSTEM_KEYRING_H */ > diff --git a/security/integrity/digsig_asymmetric.c > b/security/integrity/digsig_asymmetric.c > index 4fec181..5ade2a7 100644 > --- a/security/integrity/digsig_asymmetric.c > +++ b/security/integrity/digsig_asymmetric.c > @@ -17,6 +17,7 @@ > #include <linux/key-type.h> > #include <crypto/public_key.h> > #include <keys/asymmetric-type.h> > +#include <keys/system_keyring.h> > > #include "integrity.h" > > @@ -32,9 +33,22 @@ static struct key *request_asymmetric_key(struct key > *keyring, uint32_t keyid) > > pr_debug("key search: \"%s\"\n", name); > > + key = get_ima_blacklist_keyring(); > + if (key) { > + key_ref_t kref; > + > + kref = keyring_search(make_key_ref(key, 1), > + &key_type_asymmetric, name); > + if (!IS_ERR(kref)) { > + pr_err("Key '%s' is in ima_blacklist_keyring\n", name); > + return ERR_PTR(-EKEYREJECTED); > + } > + } > + > if (keyring) { > /* search in specific keyring */ > key_ref_t kref; > + > kref = keyring_search(make_key_ref(keyring, 1), > &key_type_asymmetric, name); > if (IS_ERR(kref)) > diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig > index 15264b7..235b3c2 100644 > --- a/security/integrity/ima/Kconfig > +++ b/security/integrity/ima/Kconfig > @@ -145,6 +145,23 @@ config IMA_TRUSTED_KEYRING > This option requires that all keys added to the .ima > keyring be signed by a key on the system trusted keyring. > > +config IMA_MOK_KEYRING > + bool "Create IMA machine owner keys (MOK) and blacklist keyrings" > + depends on IMA_TRUSTED_KEYRING > + default y > + help > + This option creates IMA MOK and blacklist keyrings. IMA MOK is an > + intermediate keyring that sits between .system and .ima keyrings, > + effectively forming a simple CA hierarchy. To successfully import a > + key into .ima_mok it must be signed by a key which CA is in .system > + keyring. On turn any key that needs to go in .ima keyring must be > + signed by CA in either .system or .ima_mok keyrings. IMA MOK is empty > + at kernel boot. > + > + IMA blacklist keyring contains all revoked IMA keys. It is consulted > + before any other keyring. If the search is successful the requested > + operation is rejected and error is returned to the caller. > + > config IMA_LOAD_X509 > bool "Load X509 certificate onto the '.ima' trusted keyring" > depends on IMA_TRUSTED_KEYRING > diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile > index d79263d..a8539f9 100644 > --- a/security/integrity/ima/Makefile > +++ b/security/integrity/ima/Makefile > @@ -8,3 +8,4 @@ obj-$(CONFIG_IMA) += ima.o > ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ > ima_policy.o ima_template.o ima_template_lib.o > ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o > +obj-$(CONFIG_IMA_MOK_KEYRING) += ima_mok.o > diff --git a/security/integrity/ima/ima_mok.c > b/security/integrity/ima/ima_mok.c > new file mode 100644 > index 0000000..18e37f5 > --- /dev/null > +++ b/security/integrity/ima/ima_mok.c > @@ -0,0 +1,54 @@ > +/* > + * Copyright (C) 2015 Juniper Networks, Inc. > + * > + * Author: > + * Petko Manolov <petko.mano...@konsulko.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. > + * > + */ > + > +#include <linux/export.h> > +#include <linux/kernel.h> > +#include <linux/sched.h> > +#include <linux/cred.h> > +#include <linux/err.h> > +#include <linux/module.h> > +#include <keys/asymmetric-type.h> > + > + > +struct key *ima_mok_keyring; > +struct key *ima_blacklist_keyring; > + > +/* > + * Allocate the IMA MOK and blacklist keyrings > + */ > +__init int ima_mok_init(void) > +{ > + pr_notice("Allocating IMA MOK and blacklist keyrings.\n"); > + > + ima_mok_keyring = keyring_alloc(".ima_mok", > + KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), > + (KEY_POS_ALL & ~KEY_POS_SETATTR) | > + KEY_USR_VIEW | KEY_USR_READ | > + KEY_USR_WRITE | KEY_USR_SEARCH, > + KEY_ALLOC_NOT_IN_QUOTA, NULL); > + > + ima_blacklist_keyring = keyring_alloc(".ima_blacklist", > + KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), > + (KEY_POS_ALL & ~KEY_POS_SETATTR) | > + KEY_USR_VIEW | KEY_USR_READ | > + KEY_USR_WRITE | KEY_USR_SEARCH, > + KEY_ALLOC_NOT_IN_QUOTA, NULL); Any reason for not using integrity_init_keyring()? Mimi > + if (IS_ERR(ima_mok_keyring) || IS_ERR(ima_blacklist_keyring)) > + panic("Can't allocate IMA MOK or blacklist keyrings."); > + set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_mok_keyring->flags); > + set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_blacklist_keyring->flags); > + return 0; > +} > + > +module_init(ima_mok_init); -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html