1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <fido.h>
4
5 #include "hexdecoct.h"
6 #include "homework-fido2.h"
7 #include "libfido2-util.h"
8 #include "memory-util.h"
9 #include "strv.h"
10
fido2_use_token(UserRecord * h,UserRecord * secret,const Fido2HmacSalt * salt,char ** ret)11 int fido2_use_token(
12 UserRecord *h,
13 UserRecord *secret,
14 const Fido2HmacSalt *salt,
15 char **ret) {
16
17 _cleanup_(erase_and_freep) void *hmac = NULL;
18 size_t hmac_size;
19 Fido2EnrollFlags flags = 0;
20 int r;
21
22 assert(h);
23 assert(secret);
24 assert(salt);
25 assert(ret);
26
27 /* If we know the up/uv/clientPin settings used during enrollment, let's pass this on for
28 * authentication, or generate errors immediately if interactivity of the specified kind is not
29 * allowed. */
30
31 if (salt->up > 0) {
32 if (h->fido2_user_presence_permitted <= 0)
33 return -EMEDIUMTYPE;
34
35 flags |= FIDO2ENROLL_UP;
36 } else if (salt->up < 0) /* unset? */
37 flags |= FIDO2ENROLL_UP_IF_NEEDED; /* compat with pre-248 */
38
39 if (salt->uv > 0) {
40 if (h->fido2_user_verification_permitted <= 0)
41 return -ENOCSI;
42
43 flags |= FIDO2ENROLL_UV;
44 } else if (salt->uv < 0)
45 flags |= FIDO2ENROLL_UV_OMIT; /* compat with pre-248 */
46
47 if (salt->client_pin > 0) {
48
49 if (strv_isempty(secret->token_pin))
50 return -ENOANO;
51
52 flags |= FIDO2ENROLL_PIN;
53 } else if (salt->client_pin < 0)
54 flags |= FIDO2ENROLL_PIN_IF_NEEDED; /* compat with pre-248 */
55
56 r = fido2_use_hmac_hash(
57 NULL,
58 "io.systemd.home",
59 salt->salt, salt->salt_size,
60 salt->credential.id, salt->credential.size,
61 secret->token_pin,
62 flags,
63 &hmac,
64 &hmac_size);
65 if (r < 0)
66 return r;
67
68 r = base64mem(hmac, hmac_size, ret);
69 if (r < 0)
70 return log_error_errno(r, "Failed to base64 encode HMAC secret: %m");
71
72 return 0;
73 }
74