From 17599e129b63b9dfdcbb1f6d223bbad70c4e7e92 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Nov 2020 16:34:54 +0100 Subject: [PATCH] homed: move fido2 setup code to src/shared/ That way we can reuse it from systemd-cryptenroll --- src/home/homectl-fido2.c | 278 +++++------------------------------ src/shared/libfido2-util.c | 286 +++++++++++++++++++++++++++++++++++++ src/shared/libfido2-util.h | 14 ++ 3 files changed, 332 insertions(+), 246 deletions(-) diff --git a/src/home/homectl-fido2.c b/src/home/homectl-fido2.c index 99a6bd5d9d..d5edec1bc4 100644 --- a/src/home/homectl-fido2.c +++ b/src/home/homectl-fido2.c @@ -110,109 +110,22 @@ static int add_fido2_salt( } #endif -#define FIDO2_SALT_SIZE 32 - int identity_add_fido2_parameters( JsonVariant **v, const char *device) { #if HAVE_LIBFIDO2 - _cleanup_(fido_cbor_info_free_wrapper) fido_cbor_info_t *di = NULL; - _cleanup_(fido_assert_free_wrapper) fido_assert_t *a = NULL; - _cleanup_(fido_cred_free_wrapper) fido_cred_t *c = NULL; - _cleanup_(fido_dev_free_wrapper) fido_dev_t *d = NULL; - _cleanup_(erase_and_freep) char *used_pin = NULL; - _cleanup_(erase_and_freep) void *salt = NULL; JsonVariant *un, *realm, *rn; - bool found_extension = false; - const void *cid, *secret; + _cleanup_(erase_and_freep) void *secret = NULL, *salt = NULL; + _cleanup_(erase_and_freep) char *used_pin = NULL; + size_t cid_size, salt_size, secret_size; + _cleanup_free_ void *cid = NULL; const char *fido_un; - size_t n, cid_size, secret_size; - char **e; int r; - /* Construction is like this: we generate a salt of 32 bytes. We then ask the FIDO2 device to - * HMAC-SHA256 it for us with its internal key. The result is the key used by LUKS and account - * authentication. LUKS and UNIX password auth all do their own salting before hashing, so that FIDO2 - * device never sees the volume key. - * - * S = HMAC-SHA256(I, D) - * - * with: S → LUKS/account authentication key (never stored) - * I → internal key on FIDO2 device (stored in the FIDO2 device) - * D → salt we generate here (stored in the privileged part of the JSON record) - * - */ - assert(v); assert(device); - r = dlopen_libfido2(); - if (r < 0) - return log_error_errno(r, "FIDO2 token support is not installed."); - - salt = malloc(FIDO2_SALT_SIZE); - if (!salt) - return log_oom(); - - r = genuine_random_bytes(salt, FIDO2_SALT_SIZE, RANDOM_BLOCK); - if (r < 0) - return log_error_errno(r, "Failed to generate salt: %m"); - - d = sym_fido_dev_new(); - if (!d) - return log_oom(); - - r = sym_fido_dev_open(d, device); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to open FIDO2 device %s: %s", device, sym_fido_strerr(r)); - - if (!sym_fido_dev_is_fido2(d)) - return log_error_errno(SYNTHETIC_ERRNO(ENODEV), - "Specified device %s is not a FIDO2 device.", device); - - di = sym_fido_cbor_info_new(); - if (!di) - return log_oom(); - - r = sym_fido_dev_get_cbor_info(d, di); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to get CBOR device info for %s: %s", device, sym_fido_strerr(r)); - - e = sym_fido_cbor_info_extensions_ptr(di); - n = sym_fido_cbor_info_extensions_len(di); - - for (size_t i = 0; i < n; i++) - if (streq(e[i], "hmac-secret")) { - found_extension = true; - break; - } - - if (!found_extension) - return log_error_errno(SYNTHETIC_ERRNO(ENODEV), - "Specified device %s is a FIDO2 device, but does not support the required HMAC-SECRET extension.", device); - - c = sym_fido_cred_new(); - if (!c) - return log_oom(); - - r = sym_fido_cred_set_extensions(c, FIDO_EXT_HMAC_SECRET); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to enable HMAC-SECRET extension on FIDO2 credential: %s", sym_fido_strerr(r)); - - r = sym_fido_cred_set_rp(c, "io.systemd.home", "Home Directory"); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to set FIDO2 credential relying party ID/name: %s", sym_fido_strerr(r)); - - r = sym_fido_cred_set_type(c, COSE_ES256); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to set FIDO2 credential type to ES256: %s", sym_fido_strerr(r)); - un = json_variant_by_key(*v, "userName"); if (!un) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), @@ -236,164 +149,37 @@ int identity_add_fido2_parameters( return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "realName field of user record is not a string"); - r = sym_fido_cred_set_user(c, - (const unsigned char*) fido_un, strlen(fido_un), /* We pass the user ID and name as the same */ - fido_un, - rn ? json_variant_string(rn) : NULL, - NULL /* icon URL */); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to set FIDO2 credential user data: %s", sym_fido_strerr(r)); - - r = sym_fido_cred_set_clientdata_hash(c, (const unsigned char[32]) {}, 32); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to set FIDO2 client data hash: %s", sym_fido_strerr(r)); - - r = sym_fido_cred_set_rk(c, FIDO_OPT_FALSE); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to turn off FIDO2 resident key option of credential: %s", sym_fido_strerr(r)); - - r = sym_fido_cred_set_uv(c, FIDO_OPT_FALSE); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to turn off FIDO2 user verification option of credential: %s", sym_fido_strerr(r)); - - log_info("Initializing FIDO2 credential on security token."); - - log_notice("%s%s(Hint: This might require verification of user presence on security token.)", - emoji_enabled() ? special_glyph(SPECIAL_GLYPH_TOUCH) : "", - emoji_enabled() ? " " : ""); - - r = sym_fido_dev_make_cred(d, c, NULL); - if (r == FIDO_ERR_PIN_REQUIRED) { - _cleanup_free_ char *text = NULL; - - if (asprintf(&text, "Please enter security token PIN:") < 0) - return log_oom(); - - for (;;) { - _cleanup_(strv_free_erasep) char **pin = NULL; - char **i; - - r = ask_password_auto(text, "user-home", NULL, "fido2-pin", USEC_INFINITY, 0, &pin); - if (r < 0) - return log_error_errno(r, "Failed to acquire user PIN: %m"); - - r = FIDO_ERR_PIN_INVALID; - STRV_FOREACH(i, pin) { - if (isempty(*i)) { - log_info("PIN may not be empty."); - continue; - } - - r = sym_fido_dev_make_cred(d, c, *i); - if (r == FIDO_OK) { - used_pin = strdup(*i); - if (!used_pin) - return log_oom(); - break; - } - if (r != FIDO_ERR_PIN_INVALID) - break; - } - - if (r != FIDO_ERR_PIN_INVALID) - break; - - log_notice("PIN incorrect, please try again."); - } - } - if (r == FIDO_ERR_PIN_AUTH_BLOCKED) - return log_notice_errno(SYNTHETIC_ERRNO(EPERM), - "Token PIN is currently blocked, please remove and reinsert token."); - if (r == FIDO_ERR_ACTION_TIMEOUT) - return log_error_errno(SYNTHETIC_ERRNO(ENOSTR), - "Token action timeout. (User didn't interact with token quickly enough.)"); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to generate FIDO2 credential: %s", sym_fido_strerr(r)); - - cid = sym_fido_cred_id_ptr(c); - if (!cid) - return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get FIDO2 credential ID."); - - cid_size = sym_fido_cred_id_len(c); - - a = sym_fido_assert_new(); - if (!a) - return log_oom(); - - r = sym_fido_assert_set_extensions(a, FIDO_EXT_HMAC_SECRET); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to enable HMAC-SECRET extension on FIDO2 assertion: %s", sym_fido_strerr(r)); - - r = sym_fido_assert_set_hmac_salt(a, salt, FIDO2_SALT_SIZE); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to set salt on FIDO2 assertion: %s", sym_fido_strerr(r)); - - r = sym_fido_assert_set_rp(a, "io.systemd.home"); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to set FIDO2 assertion ID: %s", sym_fido_strerr(r)); - - r = sym_fido_assert_set_clientdata_hash(a, (const unsigned char[32]) {}, 32); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to set FIDO2 assertion client data hash: %s", sym_fido_strerr(r)); - - r = sym_fido_assert_allow_cred(a, cid, cid_size); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to add FIDO2 assertion credential ID: %s", sym_fido_strerr(r)); - - r = sym_fido_assert_set_up(a, FIDO_OPT_FALSE); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to turn off FIDO2 assertion user presence: %s", sym_fido_strerr(r)); - - log_info("Generating secret key on FIDO2 security token."); - - r = sym_fido_dev_get_assert(d, a, used_pin); - if (r == FIDO_ERR_UP_REQUIRED) { - r = sym_fido_assert_set_up(a, FIDO_OPT_TRUE); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to turn on FIDO2 assertion user presence: %s", sym_fido_strerr(r)); - - log_notice("%s%sIn order to allow secret key generation, please verify presence on security token.", - emoji_enabled() ? special_glyph(SPECIAL_GLYPH_TOUCH) : "", - emoji_enabled() ? " " : ""); - - r = sym_fido_dev_get_assert(d, a, used_pin); - } - if (r == FIDO_ERR_ACTION_TIMEOUT) - return log_error_errno(SYNTHETIC_ERRNO(ENOSTR), - "Token action timeout. (User didn't interact with token quickly enough.)"); - if (r != FIDO_OK) - return log_error_errno(SYNTHETIC_ERRNO(EIO), - "Failed to ask token for assertion: %s", sym_fido_strerr(r)); - - secret = sym_fido_assert_hmac_secret_ptr(a, 0); - if (!secret) - return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve HMAC secret."); - - secret_size = sym_fido_assert_hmac_secret_len(a, 0); - - r = add_fido2_credential_id(v, cid, cid_size); + r = fido2_generate_hmac_hash( + device, + /* rp_id= */ "io.systemd.home", + /* rp_name= */ "Home Directory", + /* user_id= */ fido_un, strlen(fido_un), /* We pass the user ID and name as the same */ + /* user_name= */ fido_un, + /* user_display_name= */ rn ? json_variant_string(rn) : NULL, + /* user_icon_name= */ NULL, + /* askpw_icon_name= */ "user-home", + &cid, &cid_size, + &salt, &salt_size, + &secret, &secret_size, + &used_pin); if (r < 0) return r; - r = add_fido2_salt(v, - cid, - cid_size, - salt, - FIDO2_SALT_SIZE, - secret, - secret_size); + r = add_fido2_credential_id( + v, + cid, + cid_size); + if (r < 0) + return r; + + r = add_fido2_salt( + v, + cid, + cid_size, + salt, + salt_size, + secret, + secret_size); if (r < 0) return r; diff --git a/src/shared/libfido2-util.c b/src/shared/libfido2-util.c index 8358aa2fe3..5438ffc369 100644 --- a/src/shared/libfido2-util.c +++ b/src/shared/libfido2-util.c @@ -4,10 +4,14 @@ #if HAVE_LIBFIDO2 #include "alloc-util.h" +#include "ask-password-api.h" #include "dlfcn-util.h" #include "format-table.h" #include "locale-util.h" #include "log.h" +#include "memory-util.h" +#include "random-util.h" +#include "strv.h" static void *libfido2_dl = NULL; @@ -116,6 +120,288 @@ int dlopen_libfido2(void) { libfido2_dl = TAKE_PTR(dl); return 1; } + +#define FIDO2_SALT_SIZE 32 + +int fido2_generate_hmac_hash( + const char *device, + const char *rp_id, + const char *rp_name, + const void *user_id, size_t user_id_len, + const char *user_name, + const char *user_display_name, + const char *user_icon, + const char *askpw_icon_name, + void **ret_cid, size_t *ret_cid_size, + void **ret_salt, size_t *ret_salt_size, + void **ret_secret, size_t *ret_secret_size, + char **ret_usedpin) { + + _cleanup_(fido_cbor_info_free_wrapper) fido_cbor_info_t *di = NULL; + _cleanup_(erase_and_freep) void *salt = NULL, *secret_copy = NULL; + _cleanup_(fido_assert_free_wrapper) fido_assert_t *a = NULL; + _cleanup_(fido_cred_free_wrapper) fido_cred_t *c = NULL; + _cleanup_(fido_dev_free_wrapper) fido_dev_t *d = NULL; + _cleanup_(erase_and_freep) char *used_pin = NULL; + _cleanup_free_ char *cid_copy = NULL; + size_t n, cid_size, secret_size; + bool found_extension = false; + const void *cid, *secret; + char **e; + int r; + + assert(device); + assert(ret_cid); + assert(ret_cid_size); + assert(ret_salt); + assert(ret_salt_size); + assert(ret_secret); + assert(ret_secret_size); + + /* Construction is like this: we generate a salt of 32 bytes. We then ask the FIDO2 device to + * HMAC-SHA256 it for us with its internal key. The result is the key used by LUKS and account + * authentication. LUKS and UNIX password auth all do their own salting before hashing, so that FIDO2 + * device never sees the volume key. + * + * S = HMAC-SHA256(I, D) + * + * with: S → LUKS/account authentication key (never stored) + * I → internal key on FIDO2 device (stored in the FIDO2 device) + * D → salt we generate here (stored in the privileged part of the JSON record) + * + */ + + assert(device); + + r = dlopen_libfido2(); + if (r < 0) + return log_error_errno(r, "FIDO2 token support is not installed."); + + salt = malloc(FIDO2_SALT_SIZE); + if (!salt) + return log_oom(); + + r = genuine_random_bytes(salt, FIDO2_SALT_SIZE, RANDOM_BLOCK); + if (r < 0) + return log_error_errno(r, "Failed to generate salt: %m"); + + d = sym_fido_dev_new(); + if (!d) + return log_oom(); + + r = sym_fido_dev_open(d, device); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to open FIDO2 device %s: %s", device, sym_fido_strerr(r)); + + if (!sym_fido_dev_is_fido2(d)) + return log_error_errno(SYNTHETIC_ERRNO(ENODEV), + "Specified device %s is not a FIDO2 device.", device); + + di = sym_fido_cbor_info_new(); + if (!di) + return log_oom(); + + r = sym_fido_dev_get_cbor_info(d, di); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to get CBOR device info for %s: %s", device, sym_fido_strerr(r)); + + e = sym_fido_cbor_info_extensions_ptr(di); + n = sym_fido_cbor_info_extensions_len(di); + + for (size_t i = 0; i < n; i++) + if (streq(e[i], "hmac-secret")) { + found_extension = true; + break; + } + + if (!found_extension) + return log_error_errno(SYNTHETIC_ERRNO(ENODEV), + "Specified device %s is a FIDO2 device, but does not support the required HMAC-SECRET extension.", device); + + c = sym_fido_cred_new(); + if (!c) + return log_oom(); + + r = sym_fido_cred_set_extensions(c, FIDO_EXT_HMAC_SECRET); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to enable HMAC-SECRET extension on FIDO2 credential: %s", sym_fido_strerr(r)); + + r = sym_fido_cred_set_rp(c, rp_id, rp_name); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to set FIDO2 credential relying party ID/name: %s", sym_fido_strerr(r)); + + r = sym_fido_cred_set_type(c, COSE_ES256); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to set FIDO2 credential type to ES256: %s", sym_fido_strerr(r)); + + r = sym_fido_cred_set_user( + c, + user_id, user_id_len, + user_name, + user_display_name, + user_icon); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to set FIDO2 credential user data: %s", sym_fido_strerr(r)); + + r = sym_fido_cred_set_clientdata_hash(c, (const unsigned char[32]) {}, 32); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to set FIDO2 client data hash: %s", sym_fido_strerr(r)); + + r = sym_fido_cred_set_rk(c, FIDO_OPT_FALSE); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to turn off FIDO2 resident key option of credential: %s", sym_fido_strerr(r)); + + r = sym_fido_cred_set_uv(c, FIDO_OPT_FALSE); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to turn off FIDO2 user verification option of credential: %s", sym_fido_strerr(r)); + + log_info("Initializing FIDO2 credential on security token."); + + log_notice("%s%s(Hint: This might require verification of user presence on security token.)", + emoji_enabled() ? special_glyph(SPECIAL_GLYPH_TOUCH) : "", + emoji_enabled() ? " " : ""); + + r = sym_fido_dev_make_cred(d, c, NULL); + if (r == FIDO_ERR_PIN_REQUIRED) { + for (;;) { + _cleanup_(strv_free_erasep) char **pin = NULL; + char **i; + + r = ask_password_auto("Please enter security token PIN:", askpw_icon_name, NULL, "fido2-pin", USEC_INFINITY, 0, &pin); + if (r < 0) + return log_error_errno(r, "Failed to acquire user PIN: %m"); + + r = FIDO_ERR_PIN_INVALID; + STRV_FOREACH(i, pin) { + if (isempty(*i)) { + log_info("PIN may not be empty."); + continue; + } + + r = sym_fido_dev_make_cred(d, c, *i); + if (r == FIDO_OK) { + used_pin = strdup(*i); + if (!used_pin) + return log_oom(); + break; + } + if (r != FIDO_ERR_PIN_INVALID) + break; + } + + if (r != FIDO_ERR_PIN_INVALID) + break; + + log_notice("PIN incorrect, please try again."); + } + } + if (r == FIDO_ERR_PIN_AUTH_BLOCKED) + return log_notice_errno(SYNTHETIC_ERRNO(EPERM), + "Token PIN is currently blocked, please remove and reinsert token."); + if (r == FIDO_ERR_ACTION_TIMEOUT) + return log_error_errno(SYNTHETIC_ERRNO(ENOSTR), + "Token action timeout. (User didn't interact with token quickly enough.)"); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to generate FIDO2 credential: %s", sym_fido_strerr(r)); + + cid = sym_fido_cred_id_ptr(c); + if (!cid) + return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get FIDO2 credential ID."); + + cid_size = sym_fido_cred_id_len(c); + + a = sym_fido_assert_new(); + if (!a) + return log_oom(); + + r = sym_fido_assert_set_extensions(a, FIDO_EXT_HMAC_SECRET); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to enable HMAC-SECRET extension on FIDO2 assertion: %s", sym_fido_strerr(r)); + + r = sym_fido_assert_set_hmac_salt(a, salt, FIDO2_SALT_SIZE); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to set salt on FIDO2 assertion: %s", sym_fido_strerr(r)); + + r = sym_fido_assert_set_rp(a, rp_id); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to set FIDO2 assertion ID: %s", sym_fido_strerr(r)); + + r = sym_fido_assert_set_clientdata_hash(a, (const unsigned char[32]) {}, 32); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to set FIDO2 assertion client data hash: %s", sym_fido_strerr(r)); + + r = sym_fido_assert_allow_cred(a, cid, cid_size); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to add FIDO2 assertion credential ID: %s", sym_fido_strerr(r)); + + r = sym_fido_assert_set_up(a, FIDO_OPT_FALSE); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to turn off FIDO2 assertion user presence: %s", sym_fido_strerr(r)); + + log_info("Generating secret key on FIDO2 security token."); + + r = sym_fido_dev_get_assert(d, a, used_pin); + if (r == FIDO_ERR_UP_REQUIRED) { + r = sym_fido_assert_set_up(a, FIDO_OPT_TRUE); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to turn on FIDO2 assertion user presence: %s", sym_fido_strerr(r)); + + log_notice("%s%sIn order to allow secret key generation, please verify presence on security token.", + emoji_enabled() ? special_glyph(SPECIAL_GLYPH_TOUCH) : "", + emoji_enabled() ? " " : ""); + + r = sym_fido_dev_get_assert(d, a, used_pin); + } + if (r == FIDO_ERR_ACTION_TIMEOUT) + return log_error_errno(SYNTHETIC_ERRNO(ENOSTR), + "Token action timeout. (User didn't interact with token quickly enough.)"); + if (r != FIDO_OK) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to ask token for assertion: %s", sym_fido_strerr(r)); + + secret = sym_fido_assert_hmac_secret_ptr(a, 0); + if (!secret) + return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve HMAC secret."); + + secret_size = sym_fido_assert_hmac_secret_len(a, 0); + + secret_copy = memdup(secret, secret_size); + if (!secret_copy) + return log_oom(); + + cid_copy = memdup(cid, cid_size); + if (!cid_copy) + return log_oom(); + + *ret_cid = TAKE_PTR(cid_copy); + *ret_cid_size = cid_size; + *ret_salt = TAKE_PTR(salt); + *ret_salt_size = FIDO2_SALT_SIZE; + *ret_secret = TAKE_PTR(secret_copy); + *ret_secret_size = secret_size; + + if (ret_usedpin) + *ret_usedpin = TAKE_PTR(used_pin); + + return 0; +} #endif int fido2_list_devices(void) { diff --git a/src/shared/libfido2-util.h b/src/shared/libfido2-util.h index 37b2f921ff..869168ee7b 100644 --- a/src/shared/libfido2-util.h +++ b/src/shared/libfido2-util.h @@ -69,6 +69,20 @@ static inline void fido_cred_free_wrapper(fido_cred_t **p) { sym_fido_cred_free(p); } +int fido2_generate_hmac_hash( + const char *device, + const char *rp_id, + const char *rp_name, + const void *user_id, size_t user_id_len, + const char *user_name, + const char *user_display_name, + const char *user_icon, + const char *askpw_icon_name, + void **ret_cid, size_t *ret_cid_size, + void **ret_salt, size_t *ret_salt_size, + void **ret_secret, size_t *ret_secret_size, + char **ret_usedpin); + #endif int fido2_list_devices(void);