Improvements to error code handling during token based activation.

This commit is contained in:
Ondrej Kozina
2021-04-15 18:15:51 +02:00
parent e9434dc9e3
commit b047b8ae20
3 changed files with 38 additions and 9 deletions

View File

@@ -2276,6 +2276,12 @@ int crypt_token_register(const crypt_token_handler *handler);
* *
* @return unlocked key slot number or negative errno otherwise. * @return unlocked key slot number or negative errno otherwise.
* *
* @note EPERM errno means token provided passphrase successfully, but
* passphrase did not unlock any keyslot associated with the token.
*
* @note ENOENT errno means no token (or subsequently assigned keyslot) was
* eligible to unlock device.
*
* @note EAGAIN errno means that token is PIN protected and you should call * @note EAGAIN errno means that token is PIN protected and you should call
* @link crypt_activate_by_token_pin @endlink with PIN * @link crypt_activate_by_token_pin @endlink with PIN
*/ */
@@ -2290,13 +2296,19 @@ int crypt_activate_by_token(struct crypt_device *cd,
* *
* @param cd crypt device handle * @param cd crypt device handle
* @param name name of device to create, if @e NULL only check token * @param name name of device to create, if @e NULL only check token
* @param type restrict type of token, if @e NULL all types eligible * @param type restrict type of token, if @e NULL all types are allowed
* @param token requested token to check or CRYPT_ANY_TOKEN to check all * @param token requested token to check or CRYPT_ANY_TOKEN to check all
* @param usrptr provided identification in callback * @param usrptr provided identification in callback
* @param flags activation flags * @param flags activation flags
* *
* @return unlocked key slot number or negative errno otherwise. * @return unlocked key slot number or negative errno otherwise.
* *
* @note EPERM errno means token provided passphrase successfully, but
* passphrase did not unlock any keyslot associated with the token.
*
* @note ENOENT errno means no token of given type (or subsequently assigned keyslot)
* was eligible to unlock device.
*
* @note EAGAIN errno means that token is PIN protected and you should call * @note EAGAIN errno means that token is PIN protected and you should call
* @link crypt_activate_by_token_pin @endlink with PIN * @link crypt_activate_by_token_pin @endlink with PIN
*/ */
@@ -2312,7 +2324,7 @@ int crypt_activate_by_token_type(struct crypt_device *cd,
* *
* @param cd crypt device handle * @param cd crypt device handle
* @param name name of device to create, if @e NULL only check token * @param name name of device to create, if @e NULL only check token
* @param type restrict type of token, if @e NULL all types eligible * @param type restrict type of token, if @e NULL all types are allowed
* @param token requested token to check or CRYPT_ANY_TOKEN to check all * @param token requested token to check or CRYPT_ANY_TOKEN to check all
* @param pin passphrase (or PIN) to unlock token (may be binary data) * @param pin passphrase (or PIN) to unlock token (may be binary data)
* @param pin_size size of @e pin * @param pin_size size of @e pin
@@ -2320,6 +2332,13 @@ int crypt_activate_by_token_type(struct crypt_device *cd,
* @param flags activation flags * @param flags activation flags
* *
* @return unlocked key slot number or negative errno otherwise. * @return unlocked key slot number or negative errno otherwise.
*
* @note EPERM errno means pin did not match or token provided passphrase
* successfully, but passphrase did not unlock any keyslot associated
* with the token.
*
* @note ENOENT errno means no token (or subsequently assigned keyslot) was
* eligible to unlock device.
*/ */
int crypt_activate_by_token_pin(struct crypt_device *cd, int crypt_activate_by_token_pin(struct crypt_device *cd,
const char *name, const char *name,

View File

@@ -429,6 +429,16 @@ static int token_for_segment(struct luks2_hdr *hdr, json_object *jobj_token, int
return r; return r;
} }
static int translate_errno(struct crypt_device *cd, int ret_val, const char *type)
{
if ((ret_val > 0 || ret_val == -EINVAL || ret_val == -ENOENT) && !is_builtin_candidate(type)) {
log_dbg(cd, "%s token handler returned %d. Changing to %d.", type, ret_val, -EPERM);
ret_val = -EPERM;
}
return ret_val;
}
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,
@@ -467,15 +477,15 @@ static int LUKS2_token_open(struct crypt_device *cd,
if (h->validate && h->validate(cd, token_json_to_string(jobj_token))) { if (h->validate && h->validate(cd, token_json_to_string(jobj_token))) {
log_dbg(cd, "Token %d (%s) validation failed.", token, h->name); log_dbg(cd, "Token %d (%s) validation failed.", token, h->name);
return -EINVAL; return -ENOENT;
} }
if (pin && !h->open_pin) if (pin && !h->open_pin)
r = -ENOENT; r = -ENOENT;
else if (pin) else if (pin)
r = h->open_pin(cd, token, pin, pin_size, buffer, buffer_len, usrptr); r = translate_errno(cd, h->open_pin(cd, token, pin, pin_size, buffer, buffer_len, usrptr), h->name);
else else
r = h->open(cd, token, buffer, buffer_len, usrptr); r = translate_errno(cd, h->open(cd, token, buffer, buffer_len, usrptr), h->name);
if (r < 0) if (r < 0)
log_dbg(cd, "Token %d (%s) open failed with %d.", token, h->name, r); log_dbg(cd, "Token %d (%s) open failed with %d.", token, h->name, r);
@@ -521,7 +531,7 @@ static int LUKS2_keyslot_open_by_token(struct crypt_device *cd,
return -EINVAL; return -EINVAL;
/* Try to open keyslot referenced in token */ /* Try to open keyslot referenced in token */
r = -EINVAL; r = -ENOENT;
for (i = 0; i < (int) json_object_array_length(jobj_token_keyslots) && r < 0; i++) { for (i = 0; i < (int) json_object_array_length(jobj_token_keyslots) && r < 0; i++) {
jobj = json_object_array_get_idx(jobj_token_keyslots, i); jobj = json_object_array_get_idx(jobj_token_keyslots, i);
num = atoi(json_object_get_string(jobj)); num = atoi(json_object_get_string(jobj));
@@ -584,7 +594,7 @@ int LUKS2_token_open_and_activate(struct crypt_device *cd,
buffer, buffer_size, &vk); buffer, buffer_size, &vk);
LUKS2_token_buffer_free(cd, token, buffer, buffer_size); LUKS2_token_buffer_free(cd, token, buffer, buffer_size);
} }
if (r >= 0) if (r != -ENOENT && r != -EPERM)
break; break;
} }
} else } else

View File

@@ -45,10 +45,10 @@ int keyring_open(struct crypt_device *cd,
r = keyring_get_passphrase(json_object_get_string(jobj_key), buffer, buffer_len); r = keyring_get_passphrase(json_object_get_string(jobj_key), buffer, buffer_len);
if (r == -ENOTSUP) { if (r == -ENOTSUP) {
log_dbg(cd, "Kernel keyring features disabled."); log_dbg(cd, "Kernel keyring features disabled.");
return -EINVAL; return -ENOENT;
} else if (r < 0) { } else if (r < 0) {
log_dbg(cd, "keyring_get_passphrase failed (error %d)", r); log_dbg(cd, "keyring_get_passphrase failed (error %d)", r);
return -EINVAL; return -EPERM;
} }
return 0; return 0;