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