diff --git a/man/systemd-cryptenroll.xml b/man/systemd-cryptenroll.xml index 83f8b2d8a1..f3c23adfd0 100644 --- a/man/systemd-cryptenroll.xml +++ b/man/systemd-cryptenroll.xml @@ -384,24 +384,9 @@ FIDO2 Enrollment - The following options are understood that may be used to enroll PKCS#11 tokens: + The following options are understood that may be used to enroll FIDO2 tokens: - - - Specify COSE algorithm used in credential generation. The default value is - es256. Supported values are es256, rs256 - and eddsa. - - es256 denotes ECDSA over NIST P-256 with SHA-256. rs256 - denotes 2048-bit RSA with PKCS#1.5 padding and SHA-256. eddsa denotes - EDDSA over Curve25519 with SHA-512. - - Note that your authenticator may choose not to support some algorithms. - - - - @@ -428,6 +413,21 @@ + + + Specify COSE algorithm used in credential generation. The default value is + es256. Supported values are es256, rs256 + and eddsa. + + es256 denotes ECDSA over NIST P-256 with SHA-256. rs256 + denotes 2048-bit RSA with PKCS#1.5 padding and SHA-256. eddsa denotes + EDDSA over Curve25519 with SHA-512. + + Note that your authenticator may choose not to support some algorithms. + + + + diff --git a/src/shared/libfido2-util.c b/src/shared/libfido2-util.c index ec5235860c..b518dec7fa 100644 --- a/src/shared/libfido2-util.c +++ b/src/shared/libfido2-util.c @@ -4,6 +4,7 @@ #if HAVE_LIBFIDO2 #include "alloc-util.h" +#include "ansi-color.h" #include "ask-password-api.h" #include "dlfcn-util.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_user) = NULL; DLSYM_PROTOTYPE(fido_cred_set_uv) = NULL; +DLSYM_PROTOTYPE(fido_dev_close) = NULL; DLSYM_PROTOTYPE(fido_dev_free) = NULL; DLSYM_PROTOTYPE(fido_dev_get_assert) = NULL; DLSYM_PROTOTYPE(fido_dev_get_cbor_info) = NULL; DLSYM_PROTOTYPE(fido_dev_info_free) = NULL; DLSYM_PROTOTYPE(fido_dev_info_manifest) = 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_path) = NULL; +DLSYM_PROTOTYPE(fido_dev_info_product_string) = NULL; DLSYM_PROTOTYPE(fido_dev_info_ptr) = NULL; DLSYM_PROTOTYPE(fido_dev_is_fido2) = NULL; DLSYM_PROTOTYPE(fido_dev_make_cred) = NULL; DLSYM_PROTOTYPE(fido_dev_new) = NULL; DLSYM_PROTOTYPE(fido_dev_open) = NULL; -DLSYM_PROTOTYPE(fido_dev_close) = NULL; DLSYM_PROTOTYPE(fido_init) = NULL; DLSYM_PROTOTYPE(fido_set_log_handler) = 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_user), DLSYM_ARG(fido_cred_set_uv), + DLSYM_ARG(fido_dev_close), DLSYM_ARG(fido_dev_free), DLSYM_ARG(fido_dev_get_assert), 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_new), DLSYM_ARG(fido_dev_open), - DLSYM_ARG(fido_dev_close), DLSYM_ARG(fido_init), DLSYM_ARG(fido_set_log_handler), DLSYM_ARG(fido_strerr)); @@ -903,7 +904,7 @@ int fido2_generate_hmac_hash( "Token action timeout. (User didn't interact with token quickly enough.)"); if (r == FIDO_ERR_UNSUPPORTED_ALGORITHM) 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) return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to generate FIDO2 credential: %s", sym_fido_strerr(r)); @@ -1074,7 +1075,13 @@ int fido2_generate_hmac_hash( #endif #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; int r; @@ -1087,9 +1094,11 @@ static int check_device_is_fido2_with_hmac_secret(const char *path) { 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' */ + 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' */ + *ret_has_rk = *ret_has_client_pin = *ret_has_up = *ret_has_uv = false; return false; + } if (r < 0) return r; @@ -1100,6 +1109,7 @@ static int check_device_is_fido2_with_hmac_secret(const char *path) { int fido2_list_devices(void) { #if HAVE_LIBFIDO2 _cleanup_(table_unrefp) Table *t = NULL; + size_t allocated = 64, found = 0; fido_dev_info_t *di = NULL; int r; @@ -1124,7 +1134,7 @@ int fido2_list_devices(void) { goto finish; } - t = table_new("path", "manufacturer", "product", "compatible"); + t = table_new("path", "manufacturer", "product", "compatible", "rk", "clientpin", "up", "uv"); if (!t) { r = log_oom(); goto finish; @@ -1132,6 +1142,7 @@ int fido2_list_devices(void) { for (size_t i = 0; i < found; i++) { const fido_dev_info_t *entry; + bool has_rk, has_client_pin, has_up, has_uv; entry = sym_fido_dev_info_ptr(di, i); if (!entry) { @@ -1140,7 +1151,7 @@ int fido2_list_devices(void) { 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) goto finish; bool compatible = r > 0; @@ -1150,7 +1161,11 @@ int fido2_list_devices(void) { TABLE_PATH, sym_fido_dev_info_path(entry), TABLE_STRING, sym_fido_dev_info_manufacturer_string(entry), TABLE_STRING, sym_fido_dev_info_product_string(entry), - TABLE_BOOLEAN_CHECKMARK, compatible); + TABLE_BOOLEAN_CHECKMARK, compatible, + TABLE_BOOLEAN_CHECKMARK, has_rk, + TABLE_BOOLEAN_CHECKMARK, has_client_pin, + TABLE_BOOLEAN_CHECKMARK, has_up, + TABLE_BOOLEAN_CHECKMARK, has_uv); if (r < 0) { table_log_add_error(r); goto finish; @@ -1163,6 +1178,16 @@ int fido2_list_devices(void) { 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; finish: @@ -1213,7 +1238,12 @@ int fido2_find_device_auto(char **ret) { 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) goto finish; if (!r) { diff --git a/src/shared/libfido2-util.h b/src/shared/libfido2-util.h index c7ed6bac34..4a0d8f8cbe 100644 --- a/src/shared/libfido2-util.h +++ b/src/shared/libfido2-util.h @@ -52,21 +52,21 @@ extern DLSYM_PROTOTYPE(fido_cred_set_rp); extern DLSYM_PROTOTYPE(fido_cred_set_type); extern DLSYM_PROTOTYPE(fido_cred_set_user); extern DLSYM_PROTOTYPE(fido_cred_set_uv); +extern DLSYM_PROTOTYPE(fido_dev_close); extern DLSYM_PROTOTYPE(fido_dev_free); extern DLSYM_PROTOTYPE(fido_dev_get_assert); extern DLSYM_PROTOTYPE(fido_dev_get_cbor_info); extern DLSYM_PROTOTYPE(fido_dev_info_free); extern DLSYM_PROTOTYPE(fido_dev_info_manifest); 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_path); +extern DLSYM_PROTOTYPE(fido_dev_info_product_string); extern DLSYM_PROTOTYPE(fido_dev_info_ptr); extern DLSYM_PROTOTYPE(fido_dev_is_fido2); extern DLSYM_PROTOTYPE(fido_dev_make_cred); extern DLSYM_PROTOTYPE(fido_dev_new); extern DLSYM_PROTOTYPE(fido_dev_open); -extern DLSYM_PROTOTYPE(fido_dev_close); extern DLSYM_PROTOTYPE(fido_init); extern DLSYM_PROTOTYPE(fido_set_log_handler); extern DLSYM_PROTOTYPE(fido_strerr);