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

Reply via email to