mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-12 19:30:04 +01:00
Simplify internal tokens handling.
This commit is contained in:
@@ -253,19 +253,6 @@ crypt_token_info LUKS2_token_status(struct crypt_device *cd,
|
|||||||
int token,
|
int token,
|
||||||
const char **type);
|
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,
|
int LUKS2_token_open_and_activate(struct crypt_device *cd,
|
||||||
struct luks2_hdr *hdr,
|
struct luks2_hdr *hdr,
|
||||||
int token,
|
int token,
|
||||||
@@ -278,6 +265,14 @@ int LUKS2_token_open_and_activate_any(struct crypt_device *cd,
|
|||||||
const char *name,
|
const char *name,
|
||||||
uint32_t flags);
|
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
|
* Generic LUKS2 digest
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -164,23 +164,6 @@ typedef struct {
|
|||||||
digest_dump_func dump;
|
digest_dump_func dump;
|
||||||
} digest_handler;
|
} 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,
|
int LUKS2_find_area_gap(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||||
size_t keylength, uint64_t *area_offset, uint64_t *area_length);
|
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,
|
int LUKS2_find_area_max_gap(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||||
|
|||||||
@@ -26,13 +26,10 @@
|
|||||||
/* Builtin tokens */
|
/* Builtin tokens */
|
||||||
extern const crypt_token_handler keyring_handler;
|
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 */
|
/* keyring builtin token */
|
||||||
{
|
&keyring_handler,
|
||||||
.get = token_keyring_get,
|
NULL
|
||||||
.set = token_keyring_set,
|
|
||||||
.h = &keyring_handler
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int is_builtin_candidate(const char *type)
|
static int is_builtin_candidate(const char *type)
|
||||||
@@ -49,8 +46,8 @@ int crypt_token_register(const crypt_token_handler *handler)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < LUKS2_TOKENS_MAX && token_handlers[i].h; i++) {
|
for (i = 0; i < LUKS2_TOKENS_MAX && token_handlers[i]; i++) {
|
||||||
if (!strcmp(token_handlers[i].h->name, handler->name)) {
|
if (!strcmp(token_handlers[i]->name, handler->name)) {
|
||||||
log_dbg(NULL, "Keyslot handler %s is already registered.", handler->name);
|
log_dbg(NULL, "Keyslot handler %s is already registered.", handler->name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -59,32 +56,24 @@ int crypt_token_register(const crypt_token_handler *handler)
|
|||||||
if (i == LUKS2_TOKENS_MAX)
|
if (i == LUKS2_TOKENS_MAX)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
token_handlers[i].h = handler;
|
token_handlers[i] = handler;
|
||||||
return 0;
|
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
|
static const crypt_token_handler
|
||||||
*LUKS2_token_handler_type(struct crypt_device *cd, const char *type)
|
*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
|
static const crypt_token_handler
|
||||||
*LUKS2_token_handler_internal(struct crypt_device *cd, int token)
|
*LUKS2_token_handler(struct crypt_device *cd, int token)
|
||||||
{
|
{
|
||||||
struct luks2_hdr *hdr;
|
struct luks2_hdr *hdr;
|
||||||
json_object *jobj1, *jobj2;
|
json_object *jobj1, *jobj2;
|
||||||
@@ -101,15 +90,7 @@ static const token_handler
|
|||||||
if (!json_object_object_get_ex(jobj1, "type", &jobj2))
|
if (!json_object_object_get_ex(jobj1, "type", &jobj2))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return LUKS2_token_handler_type_internal(cd, json_object_get_string(jobj2));
|
return LUKS2_token_handler_type(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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int LUKS2_token_find_free(struct luks2_hdr *hdr)
|
static int LUKS2_token_find_free(struct luks2_hdr *hdr)
|
||||||
@@ -130,7 +111,6 @@ int LUKS2_token_create(struct crypt_device *cd,
|
|||||||
int commit)
|
int commit)
|
||||||
{
|
{
|
||||||
const crypt_token_handler *h;
|
const crypt_token_handler *h;
|
||||||
const token_handler *th;
|
|
||||||
json_object *jobj_tokens, *jobj_type, *jobj;
|
json_object *jobj_tokens, *jobj_type, *jobj;
|
||||||
enum json_tokener_error jerr;
|
enum json_tokener_error jerr;
|
||||||
char num[16];
|
char num[16];
|
||||||
@@ -166,16 +146,14 @@ int LUKS2_token_create(struct crypt_device *cd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
json_object_object_get_ex(jobj, "type", &jobj_type);
|
json_object_object_get_ex(jobj, "type", &jobj_type);
|
||||||
if (is_builtin_candidate(json_object_get_string(jobj_type))) {
|
h = LUKS2_token_handler_type(cd, json_object_get_string(jobj_type));
|
||||||
th = LUKS2_token_handler_type_internal(cd, json_object_get_string(jobj_type));
|
|
||||||
if (!th || !th->set) {
|
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));
|
log_dbg(cd, "%s is builtin token candidate with missing handler",
|
||||||
json_object_put(jobj);
|
json_object_get_string(jobj_type));
|
||||||
return -EINVAL;
|
json_object_put(jobj);
|
||||||
}
|
return -EINVAL;
|
||||||
h = th->h;
|
}
|
||||||
} else
|
|
||||||
h = LUKS2_token_handler_type(cd, json_object_get_string(jobj_type));
|
|
||||||
|
|
||||||
if (h && h->validate && h->validate(cd, json)) {
|
if (h && h->validate && h->validate(cd, json)) {
|
||||||
json_object_put(jobj);
|
json_object_put(jobj);
|
||||||
@@ -203,7 +181,7 @@ crypt_token_info LUKS2_token_status(struct crypt_device *cd,
|
|||||||
const char **type)
|
const char **type)
|
||||||
{
|
{
|
||||||
const char *tmp;
|
const char *tmp;
|
||||||
const token_handler *th;
|
const crypt_token_handler *th;
|
||||||
json_object *jobj_type, *jobj_token;
|
json_object *jobj_type, *jobj_token;
|
||||||
|
|
||||||
if (token < 0 || token >= LUKS2_TOKENS_MAX)
|
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);
|
json_object_object_get_ex(jobj_token, "type", &jobj_type);
|
||||||
tmp = json_object_get_string(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)
|
if (type)
|
||||||
*type = th->h->name;
|
*type = th->name;
|
||||||
return th->set ? CRYPT_TOKEN_INTERNAL : CRYPT_TOKEN_EXTERNAL;
|
return is_builtin_candidate(tmp) ? CRYPT_TOKEN_INTERNAL : CRYPT_TOKEN_EXTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type)
|
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;
|
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,
|
static int LUKS2_token_open(struct crypt_device *cd,
|
||||||
struct luks2_hdr *hdr,
|
struct luks2_hdr *hdr,
|
||||||
int token,
|
int token,
|
||||||
|
|||||||
@@ -111,47 +111,21 @@ static void keyring_dump(struct crypt_device *cd, const char *json)
|
|||||||
json_object_put(jobj_token);
|
json_object_put(jobj_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
int token_keyring_set(json_object **jobj_builtin_token,
|
int LUKS2_token_keyring_json(char *buffer, size_t buffer_size,
|
||||||
const void *params)
|
const struct crypt_token_params_luks2_keyring *keyring_params)
|
||||||
{
|
{
|
||||||
json_object *jobj_token, *jobj;
|
snprintf(buffer, buffer_size, "{ \"type\": \"%s\", \"keyslots\":[],\"key_description\":\"%s\"}",
|
||||||
const struct crypt_token_params_luks2_keyring *keyring_params = (const struct crypt_token_params_luks2_keyring *) params;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int token_keyring_get(json_object *jobj_token,
|
int LUKS2_token_keyring_get(struct crypt_device *cd, struct luks2_hdr *hdr, int token,
|
||||||
void *params)
|
struct crypt_token_params_luks2_keyring *keyring_params)
|
||||||
{
|
{
|
||||||
json_object *jobj;
|
json_object *jobj_token, *jobj;
|
||||||
struct crypt_token_params_luks2_keyring *keyring_params = (struct crypt_token_params_luks2_keyring *) params;
|
|
||||||
|
|
||||||
|
jobj_token = LUKS2_get_token_jobj(hdr, token);
|
||||||
json_object_object_get_ex(jobj_token, "type", &jobj);
|
json_object_object_get_ex(jobj_token, "type", &jobj);
|
||||||
assert(!strcmp(json_object_get_string(jobj), LUKS2_TOKEN_KEYRING));
|
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);
|
keyring_params->key_description = json_object_get_string(jobj);
|
||||||
|
|
||||||
return 0;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
const crypt_token_handler keyring_handler = {
|
const crypt_token_handler keyring_handler = {
|
||||||
|
|||||||
@@ -5617,7 +5617,7 @@ int crypt_token_luks2_keyring_get(struct crypt_device *cd,
|
|||||||
return -EINVAL;
|
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,
|
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)
|
const struct crypt_token_params_luks2_keyring *params)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
char json[4096];
|
||||||
|
|
||||||
if (!params)
|
if (!params)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -5634,7 +5635,9 @@ int crypt_token_luks2_keyring_set(struct crypt_device *cd,
|
|||||||
if ((r = onlyLUKS2(cd)))
|
if ((r = onlyLUKS2(cd)))
|
||||||
return r;
|
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)
|
int crypt_token_assign_keyslot(struct crypt_device *cd, int token, int keyslot)
|
||||||
|
|||||||
Reference in New Issue
Block a user