Skip to content

Commit

Permalink
integrity: Load certs to the platform keyring
Browse files Browse the repository at this point in the history
The patch refactors integrity_load_x509(), making it a wrapper for a new
function named integrity_add_key(). This patch also defines a new
function named integrity_load_cert() for loading the platform keys.

Signed-off-by: Nayna Jain <[email protected]>
Reviewed-by: Mimi Zohar <[email protected]>
Acked-by: Serge Hallyn <[email protected]>
Reviewed-by: James Morris <[email protected]>
Reviewed-by: Thiago Jung Bauermann <[email protected]>
Signed-off-by: Mimi Zohar <[email protected]>
  • Loading branch information
naynajain authored and mimizohar committed Dec 13, 2018
1 parent 9dc92c4 commit 60740ac
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 24 deletions.
67 changes: 43 additions & 24 deletions security/integrity/digsig.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ static int __integrity_init_keyring(const unsigned int id, key_perm_t perm,

keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
KGIDT_INIT(0), cred, perm,
KEY_ALLOC_NOT_IN_QUOTA,
restriction, NULL);
KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL);
if (IS_ERR(keyring[id])) {
err = PTR_ERR(keyring[id]);
pr_info("Can't allocate %s keyring (%d)\n",
Expand Down Expand Up @@ -121,40 +120,60 @@ int __init integrity_init_keyring(const unsigned int id)
return __integrity_init_keyring(id, perm, restriction);
}

int __init integrity_load_x509(const unsigned int id, const char *path)
int __init integrity_add_key(const unsigned int id, const void *data,
off_t size, key_perm_t perm)
{
key_ref_t key;
void *data;
loff_t size;
int rc;
int rc = 0;

if (!keyring[id])
return -EINVAL;

key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric",
NULL, data, size, perm,
KEY_ALLOC_NOT_IN_QUOTA);
if (IS_ERR(key)) {
rc = PTR_ERR(key);
pr_err("Problem loading X.509 certificate %d\n", rc);
} else {
pr_notice("Loaded X.509 cert '%s'\n",
key_ref_to_ptr(key)->description);
key_ref_put(key);
}

return rc;

}

int __init integrity_load_x509(const unsigned int id, const char *path)
{
void *data;
loff_t size;
int rc;
key_perm_t perm;

rc = kernel_read_file_from_path(path, &data, &size, 0,
READING_X509_CERTIFICATE);
if (rc < 0) {
pr_err("Unable to open file: %s (%d)", path, rc);
return rc;
}

key = key_create_or_update(make_key_ref(keyring[id], 1),
"asymmetric",
NULL,
data,
size,
((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);
}
perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ;

pr_info("Loading X.509 certificate: %s\n", path);
rc = integrity_add_key(id, (const void *)data, size, perm);

vfree(data);
return 0;
return rc;
}

int __init integrity_load_cert(const unsigned int id, const char *source,
const void *data, size_t len, key_perm_t perm)
{
if (!data)
return -EINVAL;

pr_info("Loading X.509 certificate: %s\n", source);
return integrity_add_key(id, data, len, perm);
}
20 changes: 20 additions & 0 deletions security/integrity/integrity.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,

int __init integrity_init_keyring(const unsigned int id);
int __init integrity_load_x509(const unsigned int id, const char *path);
int __init integrity_load_cert(const unsigned int id, const char *source,
const void *data, size_t len, key_perm_t perm);
#else

static inline int integrity_digsig_verify(const unsigned int id,
Expand All @@ -167,6 +169,14 @@ static inline int integrity_init_keyring(const unsigned int id)
{
return 0;
}

static inline int __init integrity_load_cert(const unsigned int id,
const char *source,
const void *data, size_t len,
key_perm_t perm)
{
return 0;
}
#endif /* CONFIG_INTEGRITY_SIGNATURE */

#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
Expand Down Expand Up @@ -223,3 +233,13 @@ integrity_audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type)
}

#endif

#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
void __init add_to_platform_keyring(const char *source, const void *data,
size_t len);
#else
static inline void __init add_to_platform_keyring(const char *source,
const void *data, size_t len)
{
}
#endif
23 changes: 23 additions & 0 deletions security/integrity/platform_certs/platform_keyring.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,29 @@
#include <linux/slab.h>
#include "../integrity.h"

/**
* add_to_platform_keyring - Add to platform keyring without validation.
* @source: Source of key
* @data: The blob holding the key
* @len: The length of the data blob
*
* Add a key to the platform keyring without checking its trust chain. This
* is available only during kernel initialisation.
*/
void __init add_to_platform_keyring(const char *source, const void *data,
size_t len)
{
key_perm_t perm;
int rc;

perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW;

rc = integrity_load_cert(INTEGRITY_KEYRING_PLATFORM, source, data, len,
perm);
if (rc)
pr_info("Error adding keys to platform keyring %s\n", source);
}

/*
* Create the trusted keyrings.
*/
Expand Down

0 comments on commit 60740ac

Please sign in to comment.