blob: 5c7cd52e1b8869b04c76269fa29ee85e8ef8bea1 [file] [log] [blame]
/* 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;
}