summaryrefslogtreecommitdiff
path: root/src/shared/libfido2-util.c
diff options
context:
space:
mode:
authorLuca Boccassi <luca.boccassi@microsoft.com>2021-04-13 13:12:46 +0100
committerLuca Boccassi <bluca@debian.org>2021-05-07 21:36:27 +0100
commit896cc0da986f85980c4377d3f7073ce1f1cae778 (patch)
treee678cb598fddf587c83ec6f4e7d9c02339825c69 /src/shared/libfido2-util.c
parent06f087192d27d6bbb237f8966c2fa2d6b790f7f2 (diff)
downloadsystemd-896cc0da986f85980c4377d3f7073ce1f1cae778.tar.gz
FIDO2: ask and record whether user verification was used to lock the volume
Some tokens support authorization via fingerprint or other biometric ID. Add support for "user verification" to cryptenroll and cryptsetup. Disable by default, as it is still quite uncommon.
Diffstat (limited to 'src/shared/libfido2-util.c')
-rw-r--r--src/shared/libfido2-util.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/src/shared/libfido2-util.c b/src/shared/libfido2-util.c
index 50e1efb2dc..ec69793f7c 100644
--- a/src/shared/libfido2-util.c
+++ b/src/shared/libfido2-util.c
@@ -25,6 +25,7 @@ int (*sym_fido_assert_set_extensions)(fido_assert_t *, int) = NULL;
int (*sym_fido_assert_set_hmac_salt)(fido_assert_t *, const unsigned char *, size_t) = NULL;
int (*sym_fido_assert_set_rp)(fido_assert_t *, const char *) = NULL;
int (*sym_fido_assert_set_up)(fido_assert_t *, fido_opt_t) = NULL;
+int (*sym_fido_assert_set_uv)(fido_assert_t *, fido_opt_t) = NULL;
size_t (*sym_fido_cbor_info_extensions_len)(const fido_cbor_info_t *) = NULL;
char **(*sym_fido_cbor_info_extensions_ptr)(const fido_cbor_info_t *) = NULL;
void (*sym_fido_cbor_info_free)(fido_cbor_info_t **) = NULL;
@@ -84,6 +85,7 @@ int dlopen_libfido2(void) {
DLSYM_ARG(fido_assert_set_hmac_salt),
DLSYM_ARG(fido_assert_set_rp),
DLSYM_ARG(fido_assert_set_up),
+ DLSYM_ARG(fido_assert_set_uv),
DLSYM_ARG(fido_cbor_info_extensions_len),
DLSYM_ARG(fido_cbor_info_extensions_ptr),
DLSYM_ARG(fido_cbor_info_free),
@@ -225,7 +227,7 @@ static int fido2_use_hmac_hash_specific_token(
_cleanup_(fido_assert_free_wrapper) fido_assert_t *a = NULL;
_cleanup_(fido_dev_free_wrapper) fido_dev_t *d = NULL;
_cleanup_(erase_and_freep) void *hmac_copy = NULL;
- bool has_up, has_client_pin;
+ bool has_up, has_client_pin, has_uv;
size_t hmac_size;
const void *hmac;
int r;
@@ -246,7 +248,7 @@ static int fido2_use_hmac_hash_specific_token(
return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Failed to open FIDO2 device %s: %s", path, sym_fido_strerr(r));
- r = verify_features(d, path, LOG_ERR, NULL, &has_client_pin, &has_up, NULL);
+ r = verify_features(d, path, LOG_ERR, NULL, &has_client_pin, &has_up, &has_uv);
if (r < 0)
return r;
@@ -260,6 +262,11 @@ static int fido2_use_hmac_hash_specific_token(
"User presence test required to unlock, but FIDO2 device %s does not support it.",
path);
+ if (!has_uv && FLAGS_SET(required, FIDO2ENROLL_UV))
+ return log_error_errno(SYNTHETIC_ERRNO(EHWPOISON),
+ "User verification required to unlock, but FIDO2 device %s does not support it.",
+ path);
+
a = sym_fido_assert_new();
if (!a)
return log_oom();
@@ -303,6 +310,18 @@ static int fido2_use_hmac_hash_specific_token(
log_info("User presence required to unlock.");
}
+ if (has_uv) {
+ r = sym_fido_assert_set_uv(a, FLAGS_SET(required, FIDO2ENROLL_UV) ? FIDO_OPT_TRUE : FIDO_OPT_FALSE);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to %s FIDO2 user verification: %s",
+ enable_disable(FLAGS_SET(required, FIDO2ENROLL_UV)),
+ sym_fido_strerr(r));
+
+ if (FLAGS_SET(required, FIDO2ENROLL_UV))
+ log_info("User verification required to unlock.");
+ }
+
if (FLAGS_SET(required, FIDO2ENROLL_PIN)) {
char **i;
@@ -515,6 +534,11 @@ int fido2_generate_hmac_hash(
"Locking with user presence test requested, but FIDO2 device %s does not support it.",
device);
+ if (!has_uv && FLAGS_SET(lock_with, FIDO2ENROLL_UV))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "Locking with user verification requested, but FIDO2 device %s does not support it.",
+ device);
+
c = sym_fido_cred_new();
if (!c)
return log_oom();
@@ -667,6 +691,20 @@ int fido2_generate_hmac_hash(
emoji_enabled() ? " " : "");
}
+ if (has_uv) {
+ r = sym_fido_assert_set_uv(a, FLAGS_SET(lock_with, FIDO2ENROLL_UV) ? FIDO_OPT_TRUE : FIDO_OPT_FALSE);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to %s FIDO user verification: %s",
+ enable_disable(FLAGS_SET(lock_with, FIDO2ENROLL_UV)),
+ sym_fido_strerr(r));
+
+ if (FLAGS_SET(lock_with, FIDO2ENROLL_UV))
+ log_notice("%s%sIn order to allow secret key generation, please verify user on security token.",
+ emoji_enabled() ? special_glyph(SPECIAL_GLYPH_TOUCH) : "",
+ emoji_enabled() ? " " : "");
+ }
+
r = sym_fido_dev_get_assert(d, a, FLAGS_SET(lock_with, FIDO2ENROLL_PIN) ? used_pin : NULL);
if (r == FIDO_ERR_UP_REQUIRED && !FLAGS_SET(lock_with, FIDO2ENROLL_UP))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),