Compare commits

...

4 Commits

Author SHA1 Message Date
Antonio Álvarez Feijoo 450d1607c5
Merge fc2ed0424e into 6fd3496cfd 2024-11-25 08:40:52 +01:00
Antonio Alvarez Feijoo fc2ed0424e
libfido2-util: show also verity features when listing FIDO2 devices
This way, users don't have to check those features using an external program, or
wait for later failure when trying to enroll using an unsupported feature.
2024-11-22 10:36:09 +01:00
Antonio Alvarez Feijoo 4112839d8e
libfido2-util: reorder dl symbols alphabetically 2024-11-22 09:10:03 +01:00
Antonio Alvarez Feijoo 41f348cf1d
man/systemd-cryptenroll: sort --fido2-credential-algorithm after --fido2-device 2024-11-22 09:09:37 +01:00
3 changed files with 54 additions and 27 deletions

View File

@ -387,21 +387,6 @@
<para>The following options are understood that may be used to enroll PKCS#11 tokens:</para> <para>The following options are understood that may be used to enroll PKCS#11 tokens:</para>
<variablelist> <variablelist>
<varlistentry>
<term><option>--fido2-credential-algorithm=<replaceable>STRING</replaceable></option></term>
<listitem><para>Specify COSE algorithm used in credential generation. The default value is
<literal>es256</literal>. Supported values are <literal>es256</literal>, <literal>rs256</literal>
and <literal>eddsa</literal>.</para>
<para><literal>es256</literal> denotes ECDSA over NIST P-256 with SHA-256. <literal>rs256</literal>
denotes 2048-bit RSA with PKCS#1.5 padding and SHA-256. <literal>eddsa</literal> denotes
EDDSA over Curve25519 with SHA-512.</para>
<para>Note that your authenticator may choose not to support some algorithms.</para>
<xi:include href="version-info.xml" xpointer="v251"/></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>--fido2-device=<replaceable>PATH</replaceable></option></term> <term><option>--fido2-device=<replaceable>PATH</replaceable></option></term>
@ -428,6 +413,21 @@
<xi:include href="version-info.xml" xpointer="v248"/></listitem> <xi:include href="version-info.xml" xpointer="v248"/></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--fido2-credential-algorithm=<replaceable>STRING</replaceable></option></term>
<listitem><para>Specify COSE algorithm used in credential generation. The default value is
<literal>es256</literal>. Supported values are <literal>es256</literal>, <literal>rs256</literal>
and <literal>eddsa</literal>.</para>
<para><literal>es256</literal> denotes ECDSA over NIST P-256 with SHA-256. <literal>rs256</literal>
denotes 2048-bit RSA with PKCS#1.5 padding and SHA-256. <literal>eddsa</literal> denotes
EDDSA over Curve25519 with SHA-512.</para>
<para>Note that your authenticator may choose not to support some algorithms.</para>
<xi:include href="version-info.xml" xpointer="v251"/></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>--fido2-salt-file=<replaceable>PATH</replaceable></option></term> <term><option>--fido2-salt-file=<replaceable>PATH</replaceable></option></term>

View File

@ -4,6 +4,7 @@
#if HAVE_LIBFIDO2 #if HAVE_LIBFIDO2
#include "alloc-util.h" #include "alloc-util.h"
#include "ansi-color.h"
#include "ask-password-api.h" #include "ask-password-api.h"
#include "dlfcn-util.h" #include "dlfcn-util.h"
#include "format-table.h" #include "format-table.h"
@ -45,21 +46,21 @@ DLSYM_PROTOTYPE(fido_cred_set_rp) = NULL;
DLSYM_PROTOTYPE(fido_cred_set_type) = NULL; DLSYM_PROTOTYPE(fido_cred_set_type) = NULL;
DLSYM_PROTOTYPE(fido_cred_set_user) = NULL; DLSYM_PROTOTYPE(fido_cred_set_user) = NULL;
DLSYM_PROTOTYPE(fido_cred_set_uv) = NULL; DLSYM_PROTOTYPE(fido_cred_set_uv) = NULL;
DLSYM_PROTOTYPE(fido_dev_close) = NULL;
DLSYM_PROTOTYPE(fido_dev_free) = NULL; DLSYM_PROTOTYPE(fido_dev_free) = NULL;
DLSYM_PROTOTYPE(fido_dev_get_assert) = NULL; DLSYM_PROTOTYPE(fido_dev_get_assert) = NULL;
DLSYM_PROTOTYPE(fido_dev_get_cbor_info) = NULL; DLSYM_PROTOTYPE(fido_dev_get_cbor_info) = NULL;
DLSYM_PROTOTYPE(fido_dev_info_free) = NULL; DLSYM_PROTOTYPE(fido_dev_info_free) = NULL;
DLSYM_PROTOTYPE(fido_dev_info_manifest) = NULL; DLSYM_PROTOTYPE(fido_dev_info_manifest) = NULL;
DLSYM_PROTOTYPE(fido_dev_info_manufacturer_string) = NULL; DLSYM_PROTOTYPE(fido_dev_info_manufacturer_string) = NULL;
DLSYM_PROTOTYPE(fido_dev_info_product_string) = NULL;
DLSYM_PROTOTYPE(fido_dev_info_new) = NULL; DLSYM_PROTOTYPE(fido_dev_info_new) = NULL;
DLSYM_PROTOTYPE(fido_dev_info_path) = NULL; DLSYM_PROTOTYPE(fido_dev_info_path) = NULL;
DLSYM_PROTOTYPE(fido_dev_info_product_string) = NULL;
DLSYM_PROTOTYPE(fido_dev_info_ptr) = NULL; DLSYM_PROTOTYPE(fido_dev_info_ptr) = NULL;
DLSYM_PROTOTYPE(fido_dev_is_fido2) = NULL; DLSYM_PROTOTYPE(fido_dev_is_fido2) = NULL;
DLSYM_PROTOTYPE(fido_dev_make_cred) = NULL; DLSYM_PROTOTYPE(fido_dev_make_cred) = NULL;
DLSYM_PROTOTYPE(fido_dev_new) = NULL; DLSYM_PROTOTYPE(fido_dev_new) = NULL;
DLSYM_PROTOTYPE(fido_dev_open) = NULL; DLSYM_PROTOTYPE(fido_dev_open) = NULL;
DLSYM_PROTOTYPE(fido_dev_close) = NULL;
DLSYM_PROTOTYPE(fido_init) = NULL; DLSYM_PROTOTYPE(fido_init) = NULL;
DLSYM_PROTOTYPE(fido_set_log_handler) = NULL; DLSYM_PROTOTYPE(fido_set_log_handler) = NULL;
DLSYM_PROTOTYPE(fido_strerr) = NULL; DLSYM_PROTOTYPE(fido_strerr) = NULL;
@ -108,6 +109,7 @@ int dlopen_libfido2(void) {
DLSYM_ARG(fido_cred_set_type), DLSYM_ARG(fido_cred_set_type),
DLSYM_ARG(fido_cred_set_user), DLSYM_ARG(fido_cred_set_user),
DLSYM_ARG(fido_cred_set_uv), DLSYM_ARG(fido_cred_set_uv),
DLSYM_ARG(fido_dev_close),
DLSYM_ARG(fido_dev_free), DLSYM_ARG(fido_dev_free),
DLSYM_ARG(fido_dev_get_assert), DLSYM_ARG(fido_dev_get_assert),
DLSYM_ARG(fido_dev_get_cbor_info), DLSYM_ARG(fido_dev_get_cbor_info),
@ -122,7 +124,6 @@ int dlopen_libfido2(void) {
DLSYM_ARG(fido_dev_make_cred), DLSYM_ARG(fido_dev_make_cred),
DLSYM_ARG(fido_dev_new), DLSYM_ARG(fido_dev_new),
DLSYM_ARG(fido_dev_open), DLSYM_ARG(fido_dev_open),
DLSYM_ARG(fido_dev_close),
DLSYM_ARG(fido_init), DLSYM_ARG(fido_init),
DLSYM_ARG(fido_set_log_handler), DLSYM_ARG(fido_set_log_handler),
DLSYM_ARG(fido_strerr)); DLSYM_ARG(fido_strerr));
@ -903,7 +904,7 @@ int fido2_generate_hmac_hash(
"Token action timeout. (User didn't interact with token quickly enough.)"); "Token action timeout. (User didn't interact with token quickly enough.)");
if (r == FIDO_ERR_UNSUPPORTED_ALGORITHM) if (r == FIDO_ERR_UNSUPPORTED_ALGORITHM)
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"Token doesn't support credential algorithm %s.", fido2_algorithm_to_string(cred_alg)); "Token doesn't support credential algorithm %s.", fido2_algorithm_to_string(cred_alg));
if (r != FIDO_OK) if (r != FIDO_OK)
return log_error_errno(SYNTHETIC_ERRNO(EIO), return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Failed to generate FIDO2 credential: %s", sym_fido_strerr(r)); "Failed to generate FIDO2 credential: %s", sym_fido_strerr(r));
@ -1074,7 +1075,13 @@ int fido2_generate_hmac_hash(
#endif #endif
#if HAVE_LIBFIDO2 #if HAVE_LIBFIDO2
static int check_device_is_fido2_with_hmac_secret(const char *path) { static int check_device_is_fido2_with_hmac_secret(
const char *path,
bool *ret_has_rk,
bool *ret_has_client_pin,
bool *ret_has_up,
bool *ret_has_uv) {
_cleanup_(fido_dev_free_wrapper) fido_dev_t *d = NULL; _cleanup_(fido_dev_free_wrapper) fido_dev_t *d = NULL;
int r; int r;
@ -1087,7 +1094,7 @@ static int check_device_is_fido2_with_hmac_secret(const char *path) {
return log_error_errno(SYNTHETIC_ERRNO(EIO), return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Failed to open FIDO2 device %s: %s", path, sym_fido_strerr(r)); "Failed to open FIDO2 device %s: %s", path, sym_fido_strerr(r));
r = verify_features(d, path, LOG_DEBUG, NULL, NULL, NULL, NULL); r = verify_features(d, path, LOG_DEBUG, ret_has_rk, ret_has_client_pin, ret_has_up, ret_has_uv);
if (r == -ENODEV) /* Not a FIDO2 device, or not implementing 'hmac-secret' */ if (r == -ENODEV) /* Not a FIDO2 device, or not implementing 'hmac-secret' */
return false; return false;
if (r < 0) if (r < 0)
@ -1124,7 +1131,7 @@ int fido2_list_devices(void) {
goto finish; goto finish;
} }
t = table_new("path", "manufacturer", "product"); t = table_new("path", "manufacturer", "product", "rk", "clientpin", "up", "uv");
if (!t) { if (!t) {
r = log_oom(); r = log_oom();
goto finish; goto finish;
@ -1132,6 +1139,7 @@ int fido2_list_devices(void) {
for (size_t i = 0; i < found; i++) { for (size_t i = 0; i < found; i++) {
const fido_dev_info_t *entry; const fido_dev_info_t *entry;
bool has_rk, has_client_pin, has_up, has_uv;
entry = sym_fido_dev_info_ptr(di, i); entry = sym_fido_dev_info_ptr(di, i);
if (!entry) { if (!entry) {
@ -1140,7 +1148,7 @@ int fido2_list_devices(void) {
goto finish; goto finish;
} }
r = check_device_is_fido2_with_hmac_secret(sym_fido_dev_info_path(entry)); r = check_device_is_fido2_with_hmac_secret(sym_fido_dev_info_path(entry), &has_rk, &has_client_pin, &has_up, &has_uv);
if (r < 0) if (r < 0)
goto finish; goto finish;
if (!r) if (!r)
@ -1150,7 +1158,11 @@ int fido2_list_devices(void) {
t, t,
TABLE_PATH, sym_fido_dev_info_path(entry), TABLE_PATH, sym_fido_dev_info_path(entry),
TABLE_STRING, sym_fido_dev_info_manufacturer_string(entry), TABLE_STRING, sym_fido_dev_info_manufacturer_string(entry),
TABLE_STRING, sym_fido_dev_info_product_string(entry)); TABLE_STRING, sym_fido_dev_info_product_string(entry),
TABLE_BOOLEAN_CHECKMARK, has_rk,
TABLE_BOOLEAN_CHECKMARK, has_client_pin,
TABLE_BOOLEAN_CHECKMARK, has_up,
TABLE_BOOLEAN_CHECKMARK, has_uv);
if (r < 0) { if (r < 0) {
table_log_add_error(r); table_log_add_error(r);
goto finish; goto finish;
@ -1163,6 +1175,16 @@ int fido2_list_devices(void) {
goto finish; goto finish;
} }
if (table_get_rows(t) > 1)
printf("\n"
"%1$sLegend: RK %2$s Resident key%3$s\n"
"%1$s CLIENTPIN %2$s PIN request%3$s\n"
"%1$s UP %2$s User presence%3$s\n"
"%1$s UV %2$s User verification%3$s\n",
ansi_grey(),
special_glyph(SPECIAL_GLYPH_ARROW_RIGHT),
ansi_normal());
r = 0; r = 0;
finish: finish:
@ -1213,7 +1235,12 @@ int fido2_find_device_auto(char **ret) {
goto finish; goto finish;
} }
r = check_device_is_fido2_with_hmac_secret(sym_fido_dev_info_path(entry)); r = check_device_is_fido2_with_hmac_secret(
sym_fido_dev_info_path(entry),
/* ret_has_rk= */ NULL,
/* ret_has_client_pin= */ NULL,
/* ret_has_up= */ NULL,
/* ret_has_uv= */ NULL);
if (r < 0) if (r < 0)
goto finish; goto finish;
if (!r) { if (!r) {

View File

@ -52,21 +52,21 @@ extern DLSYM_PROTOTYPE(fido_cred_set_rp);
extern DLSYM_PROTOTYPE(fido_cred_set_type); extern DLSYM_PROTOTYPE(fido_cred_set_type);
extern DLSYM_PROTOTYPE(fido_cred_set_user); extern DLSYM_PROTOTYPE(fido_cred_set_user);
extern DLSYM_PROTOTYPE(fido_cred_set_uv); extern DLSYM_PROTOTYPE(fido_cred_set_uv);
extern DLSYM_PROTOTYPE(fido_dev_close);
extern DLSYM_PROTOTYPE(fido_dev_free); extern DLSYM_PROTOTYPE(fido_dev_free);
extern DLSYM_PROTOTYPE(fido_dev_get_assert); extern DLSYM_PROTOTYPE(fido_dev_get_assert);
extern DLSYM_PROTOTYPE(fido_dev_get_cbor_info); extern DLSYM_PROTOTYPE(fido_dev_get_cbor_info);
extern DLSYM_PROTOTYPE(fido_dev_info_free); extern DLSYM_PROTOTYPE(fido_dev_info_free);
extern DLSYM_PROTOTYPE(fido_dev_info_manifest); extern DLSYM_PROTOTYPE(fido_dev_info_manifest);
extern DLSYM_PROTOTYPE(fido_dev_info_manufacturer_string); extern DLSYM_PROTOTYPE(fido_dev_info_manufacturer_string);
extern DLSYM_PROTOTYPE(fido_dev_info_product_string);
extern DLSYM_PROTOTYPE(fido_dev_info_new); extern DLSYM_PROTOTYPE(fido_dev_info_new);
extern DLSYM_PROTOTYPE(fido_dev_info_path); extern DLSYM_PROTOTYPE(fido_dev_info_path);
extern DLSYM_PROTOTYPE(fido_dev_info_product_string);
extern DLSYM_PROTOTYPE(fido_dev_info_ptr); extern DLSYM_PROTOTYPE(fido_dev_info_ptr);
extern DLSYM_PROTOTYPE(fido_dev_is_fido2); extern DLSYM_PROTOTYPE(fido_dev_is_fido2);
extern DLSYM_PROTOTYPE(fido_dev_make_cred); extern DLSYM_PROTOTYPE(fido_dev_make_cred);
extern DLSYM_PROTOTYPE(fido_dev_new); extern DLSYM_PROTOTYPE(fido_dev_new);
extern DLSYM_PROTOTYPE(fido_dev_open); extern DLSYM_PROTOTYPE(fido_dev_open);
extern DLSYM_PROTOTYPE(fido_dev_close);
extern DLSYM_PROTOTYPE(fido_init); extern DLSYM_PROTOTYPE(fido_init);
extern DLSYM_PROTOTYPE(fido_set_log_handler); extern DLSYM_PROTOTYPE(fido_set_log_handler);
extern DLSYM_PROTOTYPE(fido_strerr); extern DLSYM_PROTOTYPE(fido_strerr);