diff options
Diffstat (limited to 'src/home/homework-fido2.c')
-rw-r--r-- | src/home/homework-fido2.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/home/homework-fido2.c b/src/home/homework-fido2.c new file mode 100644 index 0000000..5c7cd52 --- /dev/null +++ b/src/home/homework-fido2.c @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include <fido.h> + +#include "hexdecoct.h" +#include "homework-fido2.h" +#include "libfido2-util.h" +#include "memory-util.h" +#include "strv.h" + +int fido2_use_token( + UserRecord *h, + UserRecord *secret, + const Fido2HmacSalt *salt, + char **ret) { + + _cleanup_(erase_and_freep) void *hmac = NULL; + size_t hmac_size; + Fido2EnrollFlags flags = 0; + ssize_t ss; + int r; + + assert(h); + assert(secret); + assert(salt); + assert(ret); + + /* If we know the up/uv/clientPin settings used during enrollment, let's pass this on for + * authentication, or generate errors immediately if interactivity of the specified kind is not + * allowed. */ + + if (salt->up > 0) { + if (h->fido2_user_presence_permitted <= 0) + return -EMEDIUMTYPE; + + flags |= FIDO2ENROLL_UP; + } else if (salt->up < 0) /* unset? */ + flags |= FIDO2ENROLL_UP_IF_NEEDED; /* compat with pre-248 */ + + if (salt->uv > 0) { + if (h->fido2_user_verification_permitted <= 0) + return -ENOCSI; + + flags |= FIDO2ENROLL_UV; + } else if (salt->uv < 0) + flags |= FIDO2ENROLL_UV_OMIT; /* compat with pre-248 */ + + if (salt->client_pin > 0) { + + if (strv_isempty(secret->token_pin)) + return -ENOANO; + + flags |= FIDO2ENROLL_PIN; + } else if (salt->client_pin < 0) + flags |= FIDO2ENROLL_PIN_IF_NEEDED; /* compat with pre-248 */ + + r = fido2_use_hmac_hash( + NULL, + "io.systemd.home", + salt->salt, salt->salt_size, + salt->credential.id, salt->credential.size, + secret->token_pin, + flags, + &hmac, + &hmac_size); + if (r < 0) + return r; + + ss = base64mem(hmac, hmac_size, ret); + if (ss < 0) + return log_error_errno(ss, "Failed to base64 encode HMAC secret: %m"); + + return 0; +} |