Messages in this thread Patch in this message | | | From | Dmitry Kasatkin <> | Subject | [PATCH 07/20] integrity: provide x509 certificate loading from the kernel | Date | Wed, 23 Apr 2014 16:30:25 +0300 |
| |
Provide API to load x509 certificates from the kernel into the integrity kernel keyrings.
Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com> --- security/integrity/Kconfig | 4 +++ security/integrity/digsig.c | 72 ++++++++++++++++++++++++++++++++++++++++++ security/integrity/integrity.h | 10 ++++++ 3 files changed, 86 insertions(+)
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig index 89f226a..8f34b28 100644 --- a/security/integrity/Kconfig +++ b/security/integrity/Kconfig @@ -51,6 +51,10 @@ config INTEGRITY_TRUSTED_KEYRING def_bool n depends on IMA_TRUSTED_KEYRING || EVM_TRUSTED_KEYRING +config INTEGRITY_LOAD_X509 + def_bool n + depends on IMA_LOAD_X509 || EVM_LOAD_X509 + source security/integrity/ima/Kconfig source security/integrity/evm/Kconfig diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 45adc07..cba38e3 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -18,6 +18,8 @@ #include <linux/cred.h> #include <linux/key-type.h> #include <linux/digsig.h> +#include <linux/slab.h> +#include <linux/file.h> #include "integrity.h" @@ -59,6 +61,76 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, return -EOPNOTSUPP; } +#ifdef CONFIG_INTEGRITY_LOAD_X509 +int integrity_read_file(const char *path, char **data) +{ + struct file *file; + loff_t size; + char *buf; + int rc = -EINVAL; + + file = filp_open(path, O_RDONLY, 0); + if (IS_ERR(file)) + return PTR_ERR(file); + + size = i_size_read(file_inode(file)); + if (size <= 0) + goto out; + + buf = kmalloc(size, GFP_KERNEL); + if (!buf) { + rc = -ENOMEM; + goto out; + } + + rc = kernel_read(file, 0, buf, size); + if (rc < 0) + kfree(buf); + else if (rc != size) + rc = -EIO; + else + *data = buf; +out: + fput(file); + return rc; +} + +int integrity_load_x509(const unsigned int id, 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 | + KEY_ALLOC_TRUSTED); + 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; +} +#endif + #ifdef CONFIG_INTEGRITY_TRUSTED_KEYRING int integrity_init_keyring(const unsigned int id) { diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index dd26ad0..96960fb 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -146,6 +146,16 @@ static inline int asymmetric_verify(struct key *keyring, const char *sig, } #endif +#ifdef CONFIG_INTEGRITY_LOAD_X509 +int integrity_read_file(const char *path, char **data); +int integrity_load_x509(const unsigned int id, char *path); +#else +static inline int integrity_load_x509(const unsigned int id, char *path) +{ + return 0; +} +#endif + #ifdef CONFIG_INTEGRITY_TRUSTED_KEYRING int integrity_init_keyring(const unsigned int id); #else -- 1.8.3.2
| |