]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fido2: when listing fido2/hmac-secret devices, actually validate feature set
authorLennart Poettering <lennart@poettering.net>
Thu, 17 Dec 2020 12:55:50 +0000 (13:55 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 17 Dec 2020 19:02:28 +0000 (20:02 +0100)
src/shared/libfido2-util.c

index 879429f63c6c8fbf5b8e58e9faa465a88375744f..22b8aba07e5028a30d372272b339ee61cb0acdbf 100644 (file)
@@ -130,6 +130,7 @@ int dlopen_libfido2(void) {
 static int verify_features(
                 fido_dev_t *d,
                 const char *path,
+                int log_level, /* the log level to use when device is not FIDO2 with hmac-secret */
                 bool *ret_has_rk,
                 bool *ret_has_client_pin,
                 bool *ret_has_up,
@@ -147,7 +148,8 @@ static int verify_features(
         assert(path);
 
         if (!sym_fido_dev_is_fido2(d))
-                return log_error_errno(SYNTHETIC_ERRNO(ENODEV),
+                return log_full_errno(log_level,
+                                      SYNTHETIC_ERRNO(ENODEV),
                                        "Specified device %s is not a FIDO2 device.", path);
 
         di = sym_fido_cbor_info_new();
@@ -183,7 +185,8 @@ static int verify_features(
         }
 
         if (!found_extension)
-                return log_error_errno(SYNTHETIC_ERRNO(ENODEV),
+                return log_full_errno(log_level,
+                                      SYNTHETIC_ERRNO(ENODEV),
                                        "Specified device %s is a FIDO2 device, but does not support the required HMAC-SECRET extension.", path);
 
         log_debug("Has rk ('Resident Key') support: %s\n"
@@ -243,7 +246,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, NULL, &has_client_pin, &has_up, NULL);
+        r = verify_features(d, path, LOG_ERR, NULL, &has_client_pin, &has_up, NULL);
         if (r < 0)
                 return r;
 
@@ -496,7 +499,7 @@ int fido2_generate_hmac_hash(
                 return log_error_errno(SYNTHETIC_ERRNO(EIO),
                                        "Failed to open FIDO2 device %s: %s", device, sym_fido_strerr(r));
 
-        r = verify_features(d, device, &has_rk, &has_client_pin, &has_up, &has_uv);
+        r = verify_features(d, device, LOG_ERR, &has_rk, &has_client_pin, &has_up, &has_uv);
         if (r < 0)
                 return r;
 
@@ -697,6 +700,30 @@ int fido2_generate_hmac_hash(
 }
 #endif
 
+#if HAVE_LIBFIDO2
+static int check_device_is_fido2_with_hmac_secret(const char *path) {
+        _cleanup_(fido_dev_free_wrapper) fido_dev_t *d = NULL;
+        int r;
+
+        d = sym_fido_dev_new();
+        if (!d)
+                return log_oom();
+
+        r = sym_fido_dev_open(d, path);
+        if (r != FIDO_OK)
+                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_DEBUG, NULL, NULL, NULL, NULL);
+        if (r == -ENODEV) /* Not a FIDO2 device, or not implementing 'hmac-secret' */
+                return false;
+        if (r < 0)
+                return r;
+
+        return true;
+}
+#endif
+
 int fido2_list_devices(void) {
 #if HAVE_LIBFIDO2
         _cleanup_(table_unrefp) Table *t = NULL;
@@ -740,6 +767,12 @@ int fido2_list_devices(void) {
                         goto finish;
                 }
 
+                r = check_device_is_fido2_with_hmac_secret(sym_fido_dev_info_path(entry));
+                if (r < 0)
+                        goto finish;
+                if (!r)
+                        continue;
+
                 r = table_add_many(
                                 t,
                                 TABLE_PATH, sym_fido_dev_info_path(entry),
@@ -807,6 +840,14 @@ int fido2_find_device_auto(char **ret) {
                 goto finish;
         }
 
+        r = check_device_is_fido2_with_hmac_secret(sym_fido_dev_info_path(entry));
+        if (r < 0)
+                goto finish;
+        if (!r) {
+                r = log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "FIDO device discovered does not implement FIDO2 with 'hmac-secret' extension.");
+                goto finish;
+        }
+
         path = sym_fido_dev_info_path(entry);
         if (!path) {
                 r = log_error_errno(SYNTHETIC_ERRNO(EIO),