From 7d475266b62d0eebe3d3d6da2cab7e2ea2b88892 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Mon, 24 Jun 2019 11:53:54 +0200 Subject: [PATCH] Simplify internal tokens handling. --- lib/luks2/luks2.h | 21 ++--- lib/luks2/luks2_internal.h | 17 ---- lib/luks2/luks2_token.c | 140 ++++++-------------------------- lib/luks2/luks2_token_keyring.c | 44 ++-------- lib/setup.c | 7 +- 5 files changed, 49 insertions(+), 180 deletions(-) diff --git a/lib/luks2/luks2.h b/lib/luks2/luks2.h index eb42b778..cb07a7da 100644 --- a/lib/luks2/luks2.h +++ b/lib/luks2/luks2.h @@ -253,19 +253,6 @@ crypt_token_info LUKS2_token_status(struct crypt_device *cd, int token, const char **type); -int LUKS2_builtin_token_get(struct crypt_device *cd, - struct luks2_hdr *hdr, - int token, - const char *type, - void *params); - -int LUKS2_builtin_token_create(struct crypt_device *cd, - struct luks2_hdr *hdr, - int token, - const char *type, - const void *params, - int commit); - int LUKS2_token_open_and_activate(struct crypt_device *cd, struct luks2_hdr *hdr, int token, @@ -278,6 +265,14 @@ int LUKS2_token_open_and_activate_any(struct crypt_device *cd, const char *name, uint32_t flags); +int LUKS2_token_keyring_get(struct crypt_device *cd, + struct luks2_hdr *hdr, + int token, + struct crypt_token_params_luks2_keyring *keyring_params); + +int LUKS2_token_keyring_json(char *buffer, size_t buffer_size, + const struct crypt_token_params_luks2_keyring *keyring_params); + /* * Generic LUKS2 digest */ diff --git a/lib/luks2/luks2_internal.h b/lib/luks2/luks2_internal.h index 799e3126..6c4f722f 100644 --- a/lib/luks2/luks2_internal.h +++ b/lib/luks2/luks2_internal.h @@ -164,23 +164,6 @@ typedef struct { digest_dump_func dump; } digest_handler; -/** - * LUKS2 token handlers (internal use only) - */ -typedef int (*builtin_token_get_func) (json_object *jobj_token, void *params); -typedef int (*builtin_token_set_func) (json_object **jobj_token, const void *params); - -typedef struct { - /* internal only section used by builtin tokens */ - builtin_token_get_func get; - builtin_token_set_func set; - /* public token handler */ - const crypt_token_handler *h; -} token_handler; - -int token_keyring_set(json_object **, const void *); -int token_keyring_get(json_object *, void *); - int LUKS2_find_area_gap(struct crypt_device *cd, struct luks2_hdr *hdr, size_t keylength, uint64_t *area_offset, uint64_t *area_length); int LUKS2_find_area_max_gap(struct crypt_device *cd, struct luks2_hdr *hdr, diff --git a/lib/luks2/luks2_token.c b/lib/luks2/luks2_token.c index ad6722a3..10e6fc5e 100644 --- a/lib/luks2/luks2_token.c +++ b/lib/luks2/luks2_token.c @@ -26,13 +26,10 @@ /* Builtin tokens */ extern const crypt_token_handler keyring_handler; -static token_handler token_handlers[LUKS2_TOKENS_MAX] = { +static const crypt_token_handler *token_handlers[LUKS2_TOKENS_MAX] = { /* keyring builtin token */ - { - .get = token_keyring_get, - .set = token_keyring_set, - .h = &keyring_handler - }, + &keyring_handler, + NULL }; static int is_builtin_candidate(const char *type) @@ -49,8 +46,8 @@ int crypt_token_register(const crypt_token_handler *handler) return -EINVAL; } - for (i = 0; i < LUKS2_TOKENS_MAX && token_handlers[i].h; i++) { - if (!strcmp(token_handlers[i].h->name, handler->name)) { + for (i = 0; i < LUKS2_TOKENS_MAX && token_handlers[i]; i++) { + if (!strcmp(token_handlers[i]->name, handler->name)) { log_dbg(NULL, "Keyslot handler %s is already registered.", handler->name); return -EINVAL; } @@ -59,32 +56,24 @@ int crypt_token_register(const crypt_token_handler *handler) if (i == LUKS2_TOKENS_MAX) return -EINVAL; - token_handlers[i].h = handler; + token_handlers[i] = handler; return 0; } -static const token_handler -*LUKS2_token_handler_type_internal(struct crypt_device *cd, const char *type) -{ - int i; - - for (i = 0; i < LUKS2_TOKENS_MAX && token_handlers[i].h; i++) - if (!strcmp(token_handlers[i].h->name, type)) - return token_handlers + i; - - return NULL; -} - static const crypt_token_handler *LUKS2_token_handler_type(struct crypt_device *cd, const char *type) { - const token_handler *th = LUKS2_token_handler_type_internal(cd, type); + int i; - return th ? th->h : NULL; + for (i = 0; i < LUKS2_TOKENS_MAX && token_handlers[i]; i++) + if (!strcmp(token_handlers[i]->name, type)) + return token_handlers[i]; + + return NULL; } -static const token_handler -*LUKS2_token_handler_internal(struct crypt_device *cd, int token) +static const crypt_token_handler +*LUKS2_token_handler(struct crypt_device *cd, int token) { struct luks2_hdr *hdr; json_object *jobj1, *jobj2; @@ -101,15 +90,7 @@ static const token_handler if (!json_object_object_get_ex(jobj1, "type", &jobj2)) return NULL; - return LUKS2_token_handler_type_internal(cd, json_object_get_string(jobj2)); -} - -static const crypt_token_handler -*LUKS2_token_handler(struct crypt_device *cd, int token) -{ - const token_handler *th = LUKS2_token_handler_internal(cd, token); - - return th ? th->h : NULL; + return LUKS2_token_handler_type(cd, json_object_get_string(jobj2)); } static int LUKS2_token_find_free(struct luks2_hdr *hdr) @@ -130,7 +111,6 @@ int LUKS2_token_create(struct crypt_device *cd, int commit) { const crypt_token_handler *h; - const token_handler *th; json_object *jobj_tokens, *jobj_type, *jobj; enum json_tokener_error jerr; char num[16]; @@ -166,16 +146,14 @@ int LUKS2_token_create(struct crypt_device *cd, } json_object_object_get_ex(jobj, "type", &jobj_type); - if (is_builtin_candidate(json_object_get_string(jobj_type))) { - th = LUKS2_token_handler_type_internal(cd, json_object_get_string(jobj_type)); - if (!th || !th->set) { - log_dbg(cd, "%s is builtin token candidate with missing handler", json_object_get_string(jobj_type)); - json_object_put(jobj); - return -EINVAL; - } - h = th->h; - } else - h = LUKS2_token_handler_type(cd, json_object_get_string(jobj_type)); + h = LUKS2_token_handler_type(cd, json_object_get_string(jobj_type)); + + if (is_builtin_candidate(json_object_get_string(jobj_type)) && !h) { + log_dbg(cd, "%s is builtin token candidate with missing handler", + json_object_get_string(jobj_type)); + json_object_put(jobj); + return -EINVAL; + } if (h && h->validate && h->validate(cd, json)) { json_object_put(jobj); @@ -203,7 +181,7 @@ crypt_token_info LUKS2_token_status(struct crypt_device *cd, const char **type) { const char *tmp; - const token_handler *th; + const crypt_token_handler *th; json_object *jobj_type, *jobj_token; if (token < 0 || token >= LUKS2_TOKENS_MAX) @@ -215,10 +193,10 @@ crypt_token_info LUKS2_token_status(struct crypt_device *cd, json_object_object_get_ex(jobj_token, "type", &jobj_type); tmp = json_object_get_string(jobj_type); - if ((th = LUKS2_token_handler_type_internal(cd, tmp))) { + if ((th = LUKS2_token_handler_type(cd, tmp))) { if (type) - *type = th->h->name; - return th->set ? CRYPT_TOKEN_INTERNAL : CRYPT_TOKEN_EXTERNAL; + *type = th->name; + return is_builtin_candidate(tmp) ? CRYPT_TOKEN_INTERNAL : CRYPT_TOKEN_EXTERNAL; } if (type) @@ -227,70 +205,6 @@ crypt_token_info LUKS2_token_status(struct crypt_device *cd, return is_builtin_candidate(tmp) ? CRYPT_TOKEN_INTERNAL_UNKNOWN : CRYPT_TOKEN_EXTERNAL_UNKNOWN; } -int LUKS2_builtin_token_get(struct crypt_device *cd, - struct luks2_hdr *hdr, - int token, - const char *type, - void *params) -{ - const token_handler *th = LUKS2_token_handler_type_internal(cd, type); - - // internal error - assert(th && th->get); - - return th->get(LUKS2_get_token_jobj(hdr, token), params) ?: token; -} - -int LUKS2_builtin_token_create(struct crypt_device *cd, - struct luks2_hdr *hdr, - int token, - const char *type, - const void *params, - int commit) -{ - const token_handler *th; - int r; - json_object *jobj_token, *jobj_tokens; - - th = LUKS2_token_handler_type_internal(cd, type); - - // at this point all builtin handlers must exist and have validate fn defined - assert(th && th->set && th->h->validate); - - if (token == CRYPT_ANY_TOKEN) { - if ((token = LUKS2_token_find_free(hdr)) < 0) - log_err(cd, _("No free token slot.")); - } - if (token < 0 || token >= LUKS2_TOKENS_MAX) - return -EINVAL; - - r = th->set(&jobj_token, params); - if (r) { - log_err(cd, _("Failed to create builtin token %s."), type); - return r; - } - - // builtin tokens must produce valid json - r = LUKS2_token_validate(cd, hdr->jobj, jobj_token, "new"); - assert(!r); - r = th->h->validate(cd, json_object_to_json_string_ext(jobj_token, - JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE)); - assert(!r); - - json_object_object_get_ex(hdr->jobj, "tokens", &jobj_tokens); - json_object_object_add_by_uint(jobj_tokens, token, jobj_token); - if (LUKS2_check_json_size(cd, hdr)) { - log_dbg(cd, "Not enough space in header json area for new %s token.", type); - json_object_object_del_by_uint(jobj_tokens, token); - return -ENOSPC; - } - - if (commit) - return LUKS2_hdr_write(cd, hdr) ?: token; - - return token; -} - static int LUKS2_token_open(struct crypt_device *cd, struct luks2_hdr *hdr, int token, diff --git a/lib/luks2/luks2_token_keyring.c b/lib/luks2/luks2_token_keyring.c index 448ad45c..5d9e44de 100644 --- a/lib/luks2/luks2_token_keyring.c +++ b/lib/luks2/luks2_token_keyring.c @@ -111,47 +111,21 @@ static void keyring_dump(struct crypt_device *cd, const char *json) json_object_put(jobj_token); } -int token_keyring_set(json_object **jobj_builtin_token, - const void *params) +int LUKS2_token_keyring_json(char *buffer, size_t buffer_size, + const struct crypt_token_params_luks2_keyring *keyring_params) { - json_object *jobj_token, *jobj; - const struct crypt_token_params_luks2_keyring *keyring_params = (const struct crypt_token_params_luks2_keyring *) params; + snprintf(buffer, buffer_size, "{ \"type\": \"%s\", \"keyslots\":[],\"key_description\":\"%s\"}", + LUKS2_TOKEN_KEYRING, keyring_params->key_description); - jobj_token = json_object_new_object(); - if (!jobj_token) - return -ENOMEM; - - jobj = json_object_new_string(LUKS2_TOKEN_KEYRING); - if (!jobj) { - json_object_put(jobj_token); - return -ENOMEM; - } - json_object_object_add(jobj_token, "type", jobj); - - jobj = json_object_new_array(); - if (!jobj) { - json_object_put(jobj_token); - return -ENOMEM; - } - json_object_object_add(jobj_token, "keyslots", jobj); - - jobj = json_object_new_string(keyring_params->key_description); - if (!jobj) { - json_object_put(jobj_token); - return -ENOMEM; - } - json_object_object_add(jobj_token, "key_description", jobj); - - *jobj_builtin_token = jobj_token; return 0; } -int token_keyring_get(json_object *jobj_token, - void *params) +int LUKS2_token_keyring_get(struct crypt_device *cd, struct luks2_hdr *hdr, int token, + struct crypt_token_params_luks2_keyring *keyring_params) { - json_object *jobj; - struct crypt_token_params_luks2_keyring *keyring_params = (struct crypt_token_params_luks2_keyring *) params; + json_object *jobj_token, *jobj; + jobj_token = LUKS2_get_token_jobj(hdr, token); json_object_object_get_ex(jobj_token, "type", &jobj); assert(!strcmp(json_object_get_string(jobj), LUKS2_TOKEN_KEYRING)); @@ -159,7 +133,7 @@ int token_keyring_get(json_object *jobj_token, keyring_params->key_description = json_object_get_string(jobj); - return 0; + return token; } const crypt_token_handler keyring_handler = { diff --git a/lib/setup.c b/lib/setup.c index ee621690..74d94c39 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -5617,7 +5617,7 @@ int crypt_token_luks2_keyring_get(struct crypt_device *cd, return -EINVAL; } - return LUKS2_builtin_token_get(cd, &cd->u.luks2.hdr, token, LUKS2_TOKEN_KEYRING, params); + return LUKS2_token_keyring_get(cd, &cd->u.luks2.hdr, token, params); } int crypt_token_luks2_keyring_set(struct crypt_device *cd, @@ -5625,6 +5625,7 @@ int crypt_token_luks2_keyring_set(struct crypt_device *cd, const struct crypt_token_params_luks2_keyring *params) { int r; + char json[4096]; if (!params) return -EINVAL; @@ -5634,7 +5635,9 @@ int crypt_token_luks2_keyring_set(struct crypt_device *cd, if ((r = onlyLUKS2(cd))) return r; - return LUKS2_builtin_token_create(cd, &cd->u.luks2.hdr, token, LUKS2_TOKEN_KEYRING, params, 1); + LUKS2_token_keyring_json(json, sizeof(json), params); + + return LUKS2_token_create(cd, &cd->u.luks2.hdr, token, json, 1); } int crypt_token_assign_keyslot(struct crypt_device *cd, int token, int keyslot)