diff options
author | Ed Maste <emaste@FreeBSD.org> | 2023-05-05 23:11:52 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2023-05-05 23:11:52 +0000 |
commit | f540a43052c12c76d3453ead881248d5467a1ab0 (patch) | |
tree | 3095d517d1742f500df2b5421b62ae1bde7bc04d | |
parent | 648a208ef3a171585f3446464646832f0e0ed3dc (diff) | |
parent | 7248ec417c7d81cfb19038eee0db15723a85550e (diff) | |
download | src-f540a43052c1.tar.gz src-f540a43052c1.zip |
libfido2: update to 1.9.0
Some highlights from NEWS:
** Added OpenSSL 3.0 compatibility.
** Removed OpenSSL 1.0 compatibility.
** Support for FIDO 2.1 "minPinLength" extension.
** Support for COSE_EDDSA, COSE_ES256, and COSE_RS1 attestation.
** Support for TPM 2.0 attestation.
** Support for device timeouts; see fido_dev_set_timeout().
** New API calls:
- es256_pk_from_EVP_PKEY;
- fido_cred_attstmt_len;
- fido_cred_attstmt_ptr;
- fido_cred_pin_minlen;
- fido_cred_set_attstmt;
- fido_cred_set_pin_minlen;
- fido_dev_set_pin_minlen_rpid;
- fido_dev_set_timeout;
- rs256_pk_from_EVP_PKEY.
** Reliability and portability fixes.
** Better handling of HID devices without identification strings; gh#381.
Relnotes: Yes
Sponsored by: The FreeBSD Foundation
99 files changed, 5599 insertions, 2302 deletions
diff --git a/contrib/libfido2/CMakeLists.txt b/contrib/libfido2/CMakeLists.txt index 101b7b33e2fc..d775a98c5b48 100644 --- a/contrib/libfido2/CMakeLists.txt +++ b/contrib/libfido2/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2018 Yubico AB. All rights reserved. +# Copyright (c) 2018-2021 Yubico AB. All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. @@ -28,7 +28,7 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_COLOR_MAKEFILE OFF) set(CMAKE_VERBOSE_MAKEFILE ON) set(FIDO_MAJOR "1") -set(FIDO_MINOR "8") +set(FIDO_MINOR "9") set(FIDO_PATCH "0") set(FIDO_VERSION ${FIDO_MAJOR}.${FIDO_MINOR}.${FIDO_PATCH}) @@ -68,10 +68,11 @@ if(NOT MSVC) set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_DARWIN_C_SOURCE") set(FIDO_CFLAGS "${FIDO_CFLAGS} -D__STDC_WANT_LIB_EXT1__=1") elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(NFC_LINUX OFF) + set(NFC_LINUX ON) set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_GNU_SOURCE") set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_DEFAULT_SOURCE") - elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR + CMAKE_SYSTEM_NAME STREQUAL "MidnightBSD") set(FIDO_CFLAGS "${FIDO_CFLAGS} -D__BSD_VISIBLE=1") endif() set(FIDO_CFLAGS "${FIDO_CFLAGS} -std=c99") @@ -79,7 +80,7 @@ if(NOT MSVC) endif() check_c_compiler_flag("-Wshorten-64-to-32" HAVE_SHORTEN_64_TO_32) -check_c_compiler_flag("-fstack-protector-all" HAVE_STACK_PROTECTOR_ALL) +check_c_compiler_flag("-Werror -fstack-protector-all" HAVE_STACK_PROTECTOR_ALL) check_include_files(cbor.h HAVE_CBOR_H) check_include_files(endian.h HAVE_ENDIAN_H) @@ -88,7 +89,6 @@ check_include_files(openssl/opensslv.h HAVE_OPENSSLV_H) check_include_files(signal.h HAVE_SIGNAL_H) check_include_files(sys/random.h HAVE_SYS_RANDOM_H) check_include_files(unistd.h HAVE_UNISTD_H) -check_include_files("windows.h;webauthn.h" HAVE_WEBAUTHN_H) check_symbol_exists(arc4random_buf stdlib.h HAVE_ARC4RANDOM_BUF) check_symbol_exists(clock_gettime time.h HAVE_CLOCK_GETTIME) @@ -101,17 +101,13 @@ check_symbol_exists(getrandom sys/random.h HAVE_GETRANDOM) check_symbol_exists(memset_s string.h HAVE_MEMSET_S) check_symbol_exists(readpassphrase readpassphrase.h HAVE_READPASSPHRASE) check_symbol_exists(recallocarray stdlib.h HAVE_RECALLOCARRAY) -check_symbol_exists(sigaction signal.h HAVE_SIGACTION) check_symbol_exists(strlcat string.h HAVE_STRLCAT) check_symbol_exists(strlcpy string.h HAVE_STRLCPY) +check_symbol_exists(strsep string.h HAVE_STRSEP) check_symbol_exists(sysconf unistd.h HAVE_SYSCONF) check_symbol_exists(timespecsub sys/time.h HAVE_TIMESPECSUB) check_symbol_exists(timingsafe_bcmp string.h HAVE_TIMINGSAFE_BCMP) -set(CMAKE_EXTRA_INCLUDE_FILES signal.h) -check_type_size("sig_atomic_t" HAVE_SIG_ATOMIC_T) -set(CMAKE_EXTRA_INCLUDE_FILES) - set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) try_compile(HAVE_POSIX_IOCTL "${CMAKE_CURRENT_BINARY_DIR}/posix_ioctl_check.o" @@ -134,16 +130,15 @@ list(APPEND CHECK_VARIABLES HAVE_POSIX_IOCTL HAVE_READPASSPHRASE HAVE_RECALLOCARRAY - HAVE_SIGACTION HAVE_SIGNAL_H HAVE_STRLCAT HAVE_STRLCPY + HAVE_STRSEP HAVE_SYSCONF HAVE_SYS_RANDOM_H HAVE_TIMESPECSUB HAVE_TIMINGSAFE_BCMP HAVE_UNISTD_H - HAVE_WEBAUTHN_H ) foreach(v ${CHECK_VARIABLES}) @@ -156,26 +151,26 @@ if(HAVE_EXPLICIT_BZERO AND NOT LIBFUZZER) add_definitions(-DHAVE_EXPLICIT_BZERO) endif() -if(HAVE_SIGACTION AND (NOT HAVE_SIG_ATOMIC_T STREQUAL "")) - add_definitions(-DSIGNAL_EXAMPLE) -endif() - if(UNIX) add_definitions(-DHAVE_DEV_URANDOM) endif() if(MSVC) if((NOT CBOR_INCLUDE_DIRS) OR (NOT CBOR_LIBRARY_DIRS) OR - (NOT CRYPTO_INCLUDE_DIRS) OR (NOT CRYPTO_LIBRARY_DIRS) OR - (NOT ZLIB_INCLUDE_DIRS) OR (NOT ZLIB_LIBRARY_DIRS)) - message(FATAL_ERROR "please provide definitions for " - "{CBOR,CRYPTO,ZLIB}_{INCLUDE,LIBRARY}_DIRS when building " - "under msvc") + (NOT CBOR_BIN_DIRS) OR (NOT CRYPTO_INCLUDE_DIRS) OR + (NOT CRYPTO_LIBRARY_DIRS) OR (NOT CRYPTO_BIN_DIRS) OR + (NOT ZLIB_INCLUDE_DIRS) OR (NOT ZLIB_LIBRARY_DIRS) OR + (NOT ZLIB_BIN_DIRS)) + message(FATAL_ERROR "please define " + "{CBOR,CRYPTO,ZLIB}_{INCLUDE,LIBRARY,BIN}_DIRS when " + "building under msvc") endif() set(CBOR_LIBRARIES cbor) set(ZLIB_LIBRARIES zlib) set(CRYPTO_LIBRARIES crypto-46) set(MSVC_DISABLED_WARNINGS_LIST + "C4152" # nonstandard extension used: function/data pointer + # conversion in expression; "C4200" # nonstandard extension used: zero-sized array in # struct/union; "C4204" # nonstandard extension used: non-constant aggregate @@ -191,12 +186,10 @@ if(MSVC) ${MSVC_DISABLED_WARNINGS_LIST}) string(REGEX REPLACE "[/-]W[1234][ ]?" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -MP -W4 -WX ${MSVC_DISABLED_WARNINGS_STR}") - set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Z7 /guard:cf /sdl /RTCcsu") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Od /Z7 /guard:cf /sdl /RTCcsu") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Zi /guard:cf /sdl") - if (HAVE_WEBAUTHN_H) - add_definitions(-DUSE_WINHELLO) - set(USE_WINHELLO ON) - endif() + add_definitions(-DUSE_WINHELLO) + set(USE_WINHELLO ON) else() include(FindPkgConfig) pkg_search_module(CBOR libcbor) @@ -275,9 +268,14 @@ else() set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -D_FORTIFY_SOURCE=2") + if(CRYPTO_VERSION VERSION_GREATER_EQUAL 3.0) + add_definitions(-DOPENSSL_API_COMPAT=0x10100000L) + endif() + if(FUZZ) add_definitions(-DFIDO_FUZZ) endif() + if(LIBFUZZER) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=fuzzer-no-link") endif() @@ -404,10 +402,9 @@ if(BUILD_MANPAGES) endif() if(NOT WIN32) - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - if(NOT LIBFUZZER AND NOT FUZZ) - subdirs(regress) - endif() + if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT FUZZ) + enable_testing() + subdirs(regress) endif() if(FUZZ) subdirs(fuzz) diff --git a/contrib/libfido2/NEWS b/contrib/libfido2/NEWS index a89766b72e89..04cda4e0e83a 100644 --- a/contrib/libfido2/NEWS +++ b/contrib/libfido2/NEWS @@ -1,3 +1,25 @@ +* Version 1.9.0 (2021-10-27) + ** Enabled NFC support on Linux. + ** Added OpenSSL 3.0 compatibility. + ** Removed OpenSSL 1.0 compatibility. + ** Support for FIDO 2.1 "minPinLength" extension. + ** Support for COSE_EDDSA, COSE_ES256, and COSE_RS1 attestation. + ** Support for TPM 2.0 attestation. + ** Support for device timeouts; see fido_dev_set_timeout(). + ** New API calls: + - es256_pk_from_EVP_PKEY; + - fido_cred_attstmt_len; + - fido_cred_attstmt_ptr; + - fido_cred_pin_minlen; + - fido_cred_set_attstmt; + - fido_cred_set_pin_minlen; + - fido_dev_set_pin_minlen_rpid; + - fido_dev_set_timeout; + - rs256_pk_from_EVP_PKEY. + ** Reliability and portability fixes. + ** Better handling of HID devices without identification strings; gh#381. + ** Fixed detection of Windows's native webauthn API; gh#382. + * Version 1.8.0 (2021-07-22) ** Dropped 'Requires.private' entry from pkg-config file. ** Better support for FIDO 2.1 authenticators. diff --git a/contrib/libfido2/README.adoc b/contrib/libfido2/README.adoc index f5ffa7e4e602..a0e188bf8774 100644 --- a/contrib/libfido2/README.adoc +++ b/contrib/libfido2/README.adoc @@ -23,6 +23,8 @@ file for the full license text. *libfido2* is known to work on Linux, macOS, Windows, OpenBSD, and FreeBSD. +NFC support is available on Linux and Windows. + === Documentation Documentation is available in troff and HTML formats. An @@ -40,7 +42,7 @@ is also available. ==== Releases -The current release of *libfido2* is 1.8.0. Please consult Yubico's +The current release of *libfido2* is 1.9.0. Please consult Yubico's https://developers.yubico.com/libfido2/Releases[release page] for source and binary releases. @@ -66,7 +68,7 @@ Follow the instructions for Ubuntu 18.04 (Bionic) below. Or from source, on UNIX-like systems: - $ (rm -rf build && mkdir build && cd build && cmake ..) + $ cmake -B build $ make -C build $ sudo make -C build install @@ -75,7 +77,8 @@ https://www.freedesktop.org/wiki/Software/pkg-config/[pkg-config] may need to be installed, or the PKG_CONFIG_PATH environment variable set. *libfido2* depends on https://github.com/pjk/libcbor[libcbor], -https://www.openssl.org[OpenSSL], and https://zlib.net[zlib]. On Linux, libudev +https://www.openssl.org[OpenSSL] 1.1 or newer, and https://zlib.net[zlib]. +On Linux, libudev (part of https://www.freedesktop.org/wiki/Software/systemd[systemd]) is also required. diff --git a/contrib/libfido2/examples/assert.c b/contrib/libfido2/examples/assert.c index dc3fda3ac447..8b0dbd9f6eb2 100644 --- a/contrib/libfido2/examples/assert.c +++ b/contrib/libfido2/examples/assert.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -20,7 +20,7 @@ #include "../openbsd-compat/openbsd-compat.h" #include "extern.h" -static const unsigned char cdh[32] = { +static const unsigned char cd[32] = { 0xec, 0x8d, 0x8f, 0x78, 0x42, 0x4a, 0x2b, 0xb7, 0x82, 0x34, 0xaa, 0xca, 0x07, 0xa1, 0xf6, 0x56, 0x42, 0x1c, 0xb6, 0xf6, 0xb3, 0x00, 0x86, 0x52, @@ -106,10 +106,9 @@ verify_assert(int type, const unsigned char *authdata_ptr, size_t authdata_len, errx(1, "fido_assert_new"); /* client data hash */ - r = fido_assert_set_clientdata_hash(assert, cdh, sizeof(cdh)); + r = fido_assert_set_clientdata(assert, cd, sizeof(cd)); if (r != FIDO_OK) - errx(1, "fido_assert_set_clientdata_hash: %s (0x%x)", - fido_strerr(r), r); + errx(1, "fido_assert_set_clientdata: %s (0x%x)", fido_strerr(r), r); /* relying party */ r = fido_assert_set_rp(assert, "localhost"); @@ -166,7 +165,7 @@ main(int argc, char **argv) const char *blobkey_out = NULL; const char *hmac_out = NULL; unsigned char *body = NULL; - long long seconds = 0; + long long ms = 0; size_t len; int type = COSE_ES256; int ext = 0; @@ -182,16 +181,12 @@ main(int argc, char **argv) pin = optarg; break; case 'T': -#ifndef SIGNAL_EXAMPLE - (void)seconds; - errx(1, "-T not supported"); -#else - if (base10(optarg, &seconds) < 0) + if (base10(optarg, &ms) < 0) errx(1, "base10: %s", optarg); - if (seconds <= 0 || seconds > 30) + if (ms <= 0 || ms > 30) errx(1, "-T: %s must be in (0,30]", optarg); + ms *= 1000; /* seconds to milliseconds */ break; -#endif case 'a': if (read_blob(optarg, &body, &len) < 0) errx(1, "read_blob: %s", optarg); @@ -262,10 +257,9 @@ main(int argc, char **argv) fido_dev_force_u2f(dev); /* client data hash */ - r = fido_assert_set_clientdata_hash(assert, cdh, sizeof(cdh)); + r = fido_assert_set_clientdata(assert, cd, sizeof(cd)); if (r != FIDO_OK) - errx(1, "fido_assert_set_clientdata_hash: %s (0x%x)", - fido_strerr(r), r); + errx(1, "fido_assert_set_clientdata: %s (0x%x)", fido_strerr(r), r); /* relying party */ r = fido_assert_set_rp(assert, "localhost"); @@ -286,20 +280,12 @@ main(int argc, char **argv) if (uv && (r = fido_assert_set_uv(assert, FIDO_OPT_TRUE)) != FIDO_OK) errx(1, "fido_assert_set_uv: %s (0x%x)", fido_strerr(r), r); -#ifdef SIGNAL_EXAMPLE - prepare_signal_handler(SIGINT); - if (seconds) { - prepare_signal_handler(SIGALRM); - alarm((unsigned)seconds); - } -#endif + /* timeout */ + if (ms != 0 && (r = fido_dev_set_timeout(dev, (int)ms)) != FIDO_OK) + errx(1, "fido_dev_set_timeout: %s (0x%x)", fido_strerr(r), r); - r = fido_dev_get_assert(dev, assert, pin); - if (r != FIDO_OK) { -#ifdef SIGNAL_EXAMPLE - if (got_signal) - fido_dev_cancel(dev); -#endif + if ((r = fido_dev_get_assert(dev, assert, pin)) != FIDO_OK) { + fido_dev_cancel(dev); errx(1, "fido_dev_get_assert: %s (0x%x)", fido_strerr(r), r); } diff --git a/contrib/libfido2/examples/cred.c b/contrib/libfido2/examples/cred.c index 74145c761380..4a9d8bf4b25a 100644 --- a/contrib/libfido2/examples/cred.c +++ b/contrib/libfido2/examples/cred.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -17,7 +17,7 @@ #include "../openbsd-compat/openbsd-compat.h" #include "extern.h" -static const unsigned char cdh[32] = { +static const unsigned char cd[32] = { 0xf9, 0x64, 0x57, 0xe7, 0x2d, 0x97, 0xf6, 0xbb, 0xdd, 0xd7, 0xfb, 0x06, 0x37, 0x62, 0xea, 0x26, 0x20, 0x44, 0x8e, 0x69, 0x7c, 0x03, 0xf2, 0x31, @@ -42,9 +42,8 @@ usage(void) static void verify_cred(int type, const char *fmt, const unsigned char *authdata_ptr, - size_t authdata_len, const unsigned char *x509_ptr, size_t x509_len, - const unsigned char *sig_ptr, size_t sig_len, bool rk, bool uv, int ext, - const char *key_out, const char *id_out) + size_t authdata_len, const unsigned char *attstmt_ptr, size_t attstmt_len, + bool rk, bool uv, int ext, const char *key_out, const char *id_out) { fido_cred_t *cred; int r; @@ -57,11 +56,10 @@ verify_cred(int type, const char *fmt, const unsigned char *authdata_ptr, if (r != FIDO_OK) errx(1, "fido_cred_set_type: %s (0x%x)", fido_strerr(r), r); - /* client data hash */ - r = fido_cred_set_clientdata_hash(cred, cdh, sizeof(cdh)); + /* client data */ + r = fido_cred_set_clientdata(cred, cd, sizeof(cd)); if (r != FIDO_OK) - errx(1, "fido_cred_set_clientdata_hash: %s (0x%x)", - fido_strerr(r), r); + errx(1, "fido_cred_set_clientdata: %s (0x%x)", fido_strerr(r), r); /* relying party */ r = fido_cred_set_rp(cred, "localhost", "sweet home localhost"); @@ -96,15 +94,10 @@ verify_cred(int type, const char *fmt, const unsigned char *authdata_ptr, goto out; } - /* x509 */ - r = fido_cred_set_x509(cred, x509_ptr, x509_len); + /* attestation statement */ + r = fido_cred_set_attstmt(cred, attstmt_ptr, attstmt_len); if (r != FIDO_OK) - errx(1, "fido_cred_set_x509: %s (0x%x)", fido_strerr(r), r); - - /* sig */ - r = fido_cred_set_sig(cred, sig_ptr, sig_len); - if (r != FIDO_OK) - errx(1, "fido_cred_set_sig: %s (0x%x)", fido_strerr(r), r); + errx(1, "fido_cred_set_attstmt: %s (0x%x)", fido_strerr(r), r); r = fido_cred_verify(cred); if (r != FIDO_OK) @@ -138,27 +131,6 @@ out: fido_cred_free(&cred); } -static fido_dev_t * -open_from_manifest(const fido_dev_info_t *dev_infos, size_t len, - const char *path) -{ - size_t i; - fido_dev_t *dev; - - for (i = 0; i < len; i++) { - const fido_dev_info_t *curr = fido_dev_info_ptr(dev_infos, i); - if (path == NULL || - strcmp(path, fido_dev_info_path(curr)) == 0) { - dev = fido_dev_new_with_info(curr); - if (fido_dev_open_with_info(dev) == FIDO_OK) - return (dev); - fido_dev_free(&dev); - } - } - - return (NULL); -} - int main(int argc, char **argv) { @@ -171,16 +143,13 @@ main(int argc, char **argv) const char *blobkey_out = NULL; const char *key_out = NULL; const char *id_out = NULL; - const char *path = NULL; unsigned char *body = NULL; - long long seconds = 0; + long long ms = 0; size_t len; int type = COSE_ES256; int ext = 0; int ch; int r; - fido_dev_info_t *dev_infos = NULL; - size_t dev_infos_len = 0; if ((cred = fido_cred_new()) == NULL) errx(1, "fido_cred_new"); @@ -191,16 +160,12 @@ main(int argc, char **argv) pin = optarg; break; case 'T': -#ifndef SIGNAL_EXAMPLE - (void)seconds; - errx(1, "-T not supported"); -#else - if (base10(optarg, &seconds) < 0) + if (base10(optarg, &ms) < 0) errx(1, "base10: %s", optarg); - if (seconds <= 0 || seconds > 30) + if (ms <= 0 || ms > 30) errx(1, "-T: %s must be in (0,30]", optarg); + ms *= 1000; /* seconds to milliseconds */ break; -#endif case 'b': ext |= FIDO_EXT_LARGEBLOB_KEY; blobkey_out = optarg; @@ -248,21 +213,20 @@ main(int argc, char **argv) } } - fido_init(0); - argc -= optind; argv += optind; - if (argc > 1) + if (argc != 1) usage(); - dev_infos = fido_dev_info_new(16); - fido_dev_info_manifest(dev_infos, 16, &dev_infos_len); - if (argc == 1) - path = argv[0]; - if ((dev = open_from_manifest(dev_infos, dev_infos_len, path)) == NULL) - errx(1, "open_from_manifest"); + fido_init(0); + + if ((dev = fido_dev_new()) == NULL) + errx(1, "fido_dev_new"); + r = fido_dev_open(dev, argv[0]); + if (r != FIDO_OK) + errx(1, "fido_dev_open: %s (0x%x)", fido_strerr(r), r); if (u2f) fido_dev_force_u2f(dev); @@ -271,11 +235,10 @@ main(int argc, char **argv) if (r != FIDO_OK) errx(1, "fido_cred_set_type: %s (0x%x)", fido_strerr(r), r); - /* client data hash */ - r = fido_cred_set_clientdata_hash(cred, cdh, sizeof(cdh)); + /* client data */ + r = fido_cred_set_clientdata(cred, cd, sizeof(cd)); if (r != FIDO_OK) - errx(1, "fido_cred_set_clientdata_hash: %s (0x%x)", - fido_strerr(r), r); + errx(1, "fido_cred_set_clientdata: %s (0x%x)", fido_strerr(r), r); /* relying party */ r = fido_cred_set_rp(cred, "localhost", "sweet home localhost"); @@ -301,20 +264,12 @@ main(int argc, char **argv) if (uv && (r = fido_cred_set_uv(cred, FIDO_OPT_TRUE)) != FIDO_OK) errx(1, "fido_cred_set_uv: %s (0x%x)", fido_strerr(r), r); -#ifdef SIGNAL_EXAMPLE - prepare_signal_handler(SIGINT); - if (seconds) { - prepare_signal_handler(SIGALRM); - alarm((unsigned)seconds); - } -#endif + /* timeout */ + if (ms != 0 && (r = fido_dev_set_timeout(dev, (int)ms)) != FIDO_OK) + errx(1, "fido_dev_set_timeout: %s (0x%x)", fido_strerr(r), r); - r = fido_dev_make_cred(dev, cred, pin); - if (r != FIDO_OK) { -#ifdef SIGNAL_EXAMPLE - if (got_signal) - fido_dev_cancel(dev); -#endif + if ((r = fido_dev_make_cred(dev, cred, pin)) != FIDO_OK) { + fido_dev_cancel(dev); errx(1, "fido_makecred: %s (0x%x)", fido_strerr(r), r); } @@ -329,9 +284,8 @@ main(int argc, char **argv) uv = true; verify_cred(type, fido_cred_fmt(cred), fido_cred_authdata_ptr(cred), - fido_cred_authdata_len(cred), fido_cred_x5c_ptr(cred), - fido_cred_x5c_len(cred), fido_cred_sig_ptr(cred), - fido_cred_sig_len(cred), rk, uv, ext, key_out, id_out); + fido_cred_authdata_len(cred), fido_cred_attstmt_ptr(cred), + fido_cred_attstmt_len(cred), rk, uv, ext, key_out, id_out); if (blobkey_out != NULL) { /* extract the "largeBlob" key */ diff --git a/contrib/libfido2/examples/extern.h b/contrib/libfido2/examples/extern.h index 0ea68c4fb585..5633b23d2003 100644 --- a/contrib/libfido2/examples/extern.h +++ b/contrib/libfido2/examples/extern.h @@ -11,10 +11,6 @@ #include <openssl/evp.h> #include <openssl/rsa.h> -#ifdef HAVE_SIGNAL_H -#include <signal.h> -#endif - /* util.c */ EC_KEY *read_ec_pubkey(const char *); RSA *read_rsa_pubkey(const char *); @@ -25,9 +21,5 @@ int write_blob(const char *, const unsigned char *, size_t); int write_ec_pubkey(const char *, const void *, size_t); int write_rsa_pubkey(const char *, const void *, size_t); int write_eddsa_pubkey(const char *, const void *, size_t); -#ifdef SIGNAL_EXAMPLE -void prepare_signal_handler(int); -extern volatile sig_atomic_t got_signal; -#endif #endif /* _EXTERN_H_ */ diff --git a/contrib/libfido2/examples/reset.c b/contrib/libfido2/examples/reset.c index eb341c26c0cd..b429d05f0fe4 100644 --- a/contrib/libfido2/examples/reset.c +++ b/contrib/libfido2/examples/reset.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -34,16 +34,9 @@ main(int argc, char **argv) if ((r = fido_dev_open(dev, argv[1])) != FIDO_OK) errx(1, "fido_dev_open: %s (0x%x)", fido_strerr(r), r); -#ifdef SIGNAL_EXAMPLE - prepare_signal_handler(SIGINT); -#endif - if ((r = fido_dev_reset(dev)) != FIDO_OK) { -#ifdef SIGNAL_EXAMPLE - if (got_signal) - fido_dev_cancel(dev); -#endif - errx(1, "fido_reset: %s (0x%x)", fido_strerr(r), r); + fido_dev_cancel(dev); + errx(1, "fido_dev_reset: %s (0x%x)", fido_strerr(r), r); } if ((r = fido_dev_close(dev)) != FIDO_OK) diff --git a/contrib/libfido2/examples/util.c b/contrib/libfido2/examples/util.c index caa68aa880ee..8b360af21c7a 100644 --- a/contrib/libfido2/examples/util.c +++ b/contrib/libfido2/examples/util.c @@ -21,9 +21,6 @@ #include <limits.h> #include <stdlib.h> #include <string.h> -#ifdef HAVE_SIGNAL_H -#include <signal.h> -#endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif @@ -33,31 +30,6 @@ #include "../openbsd-compat/openbsd-compat.h" #include "extern.h" -#ifdef SIGNAL_EXAMPLE -volatile sig_atomic_t got_signal = 0; - -static void -signal_handler(int signo) -{ - (void)signo; - got_signal = 1; -} - -void -prepare_signal_handler(int signo) -{ - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - - sigemptyset(&sa.sa_mask); - sa.sa_handler = signal_handler; - - if (sigaction(signo, &sa, NULL) < 0) - err(1, "sigaction"); -} -#endif - int base10(const char *str, long long *ll) { diff --git a/contrib/libfido2/fuzz/Dockerfile b/contrib/libfido2/fuzz/Dockerfile index 895da69e4c4c..f175991d0462 100644 --- a/contrib/libfido2/fuzz/Dockerfile +++ b/contrib/libfido2/fuzz/Dockerfile @@ -1,12 +1,12 @@ -# Copyright (c) 2019 Yubico AB. All rights reserved. +# Copyright (c) 2019-2021 Yubico AB. All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. FROM ubuntu:focal ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update -RUN apt-get install -y clang-11 cmake git libssl-dev libudev-dev make pkg-config +RUN apt-get install -y clang-12 cmake git libssl-dev libudev-dev make pkg-config RUN apt-get install -y zlib1g-dev RUN git clone --branch v0.8.0 https://github.com/PJK/libcbor RUN git clone https://github.com/yubico/libfido2 -RUN CC=clang-11 CXX=clang++-11 /libfido2/fuzz/build-coverage /libcbor /libfido2 +RUN CC=clang-12 CXX=clang++-12 /libfido2/fuzz/build-coverage /libcbor /libfido2 diff --git a/contrib/libfido2/fuzz/Makefile b/contrib/libfido2/fuzz/Makefile index 4b067c23aac2..1a974a2bf557 100644 --- a/contrib/libfido2/fuzz/Makefile +++ b/contrib/libfido2/fuzz/Makefile @@ -1,11 +1,11 @@ -# Copyright (c) 2019 Yubico AB. All rights reserved. +# Copyright (c) 2019-2021 Yubico AB. All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. -IMAGE := libfido2-coverage:1.8.0 +IMAGE := libfido2-coverage:1.9.1 RUNNER := libfido2-runner -PROFDATA := llvm-profdata-11 -COV := llvm-cov-11 +PROFDATA := llvm-profdata-12 +COV := llvm-cov-12 TARGETS := fuzz_assert fuzz_bio fuzz_cred fuzz_credman fuzz_hid \ fuzz_largeblob fuzz_netlink fuzz_mgmt CORPORA := $(foreach f,${TARGETS},${f}/corpus) @@ -50,16 +50,18 @@ profdata: run report.tgz: profdata docker exec ${RUNNER} /bin/sh -c 'rm -rf /report && mkdir /report && \ ${COV} show -format=html -tab-size=8 -instr-profile=/$< \ - -output-dir=/report /libfido2/build/src/libfido2.so' + --show-branch-summary=false -output-dir=/report \ + /libfido2/build/src/libfido2.so' docker exec -i ${RUNNER} tar Czcf / - report > $@ summary.txt: profdata docker exec ${RUNNER} ${COV} report -use-color=false \ - /libfido2/build/src/libfido2.so -instr-profile=/$< > $@ + --show-branch-summary=false /libfido2/build/src/libfido2.so \ + -instr-profile=/$< > $@ functions.txt: profdata docker exec ${RUNNER} /bin/sh -c '${COV} report -use-color=false \ - -show-functions -instr-profile=/$< \ + -show-functions --show-branch-summary=false -instr-profile=/$< \ /libfido2/build/src/libfido2.so /libfido2/src/*.[ch]' > $@ clean: run diff --git a/contrib/libfido2/fuzz/clock.c b/contrib/libfido2/fuzz/clock.c new file mode 100644 index 000000000000..23803c2ee3e5 --- /dev/null +++ b/contrib/libfido2/fuzz/clock.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2021 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + +#include <stdint.h> +#include <time.h> + +#include "mutator_aux.h" + +/* + * A pseudo-random monotonic clock with a probabilistic discontinuity to + * the end of time (as measured by struct timespec). + */ + +extern int prng_up; +extern int __wrap_clock_gettime(clockid_t, struct timespec *); +extern int __real_clock_gettime(clockid_t, struct timespec *); +extern int __wrap_usleep(unsigned int); +static TLS struct timespec fuzz_clock; + +static void +tick(unsigned int usec) +{ + long long drift; + + /* + * Simulate a jump to the end of time with 0.125% probability. + * This condition should be gracefully handled by callers of + * clock_gettime(). + */ + if (uniform_random(800) < 1) { + fuzz_clock.tv_sec = LLONG_MAX; + fuzz_clock.tv_nsec = LONG_MAX; + return; + } + + drift = usec * 1000LL + (long long)uniform_random(10000000); /* 10ms */ + if (LLONG_MAX - drift < (long long)fuzz_clock.tv_nsec) { + fuzz_clock_reset(); /* Not much we can do here. */ + } else if (drift + (long long)fuzz_clock.tv_nsec < 1000000000) { + fuzz_clock.tv_nsec += (long)(drift); + } else { + fuzz_clock.tv_sec += (long)(drift / 1000000000); + fuzz_clock.tv_nsec += (long)(drift % 1000000000); + } +} + +int +__wrap_clock_gettime(clockid_t clk_id, struct timespec *tp) +{ + if (!prng_up || clk_id != CLOCK_MONOTONIC) + return __real_clock_gettime(clk_id, tp); + if (uniform_random(400) < 1) + return -1; + + tick(0); + *tp = fuzz_clock; + + return 0; +} + +int +__wrap_usleep(unsigned int usec) +{ + if (uniform_random(400) < 1) + return -1; + + tick(usec); + + return 0; +} + +void +fuzz_clock_reset(void) +{ + memset(&fuzz_clock, 0, sizeof(fuzz_clock)); +} diff --git a/contrib/libfido2/fuzz/dummy.h b/contrib/libfido2/fuzz/dummy.h index 981cceec37b5..95744eba634b 100644 --- a/contrib/libfido2/fuzz/dummy.h +++ b/contrib/libfido2/fuzz/dummy.h @@ -93,4 +93,87 @@ const uint8_t dummy_eddsa[] = { 0xe2, 0x39, 0xdf, 0x2f, 0x87, 0x19, 0xb3, 0x02, }; +const uint8_t dummy_netlink_wiredata[] = { + 0xd8, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9d, 0x2e, 0x00, 0x00, + 0x01, 0x02, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x6e, 0x66, 0x63, 0x00, 0x06, 0x00, 0x01, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x80, 0x01, 0x06, 0x00, + 0x14, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x05, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x06, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x07, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x09, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0a, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0c, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0e, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x10, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x11, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x13, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x07, 0x00, + 0x18, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x9d, 0x2e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x9d, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9d, 0x2e, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, + 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x05, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x06, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x07, 0x00, 0x27, 0x00, 0x00, 0x00, + 0x93, 0xb9, 0x25, 0x00 +}; + #endif /* !_DUMMY_H */ diff --git a/contrib/libfido2/fuzz/export.gnu b/contrib/libfido2/fuzz/export.gnu index bd70d1c7eaac..0c712b30a429 100644 --- a/contrib/libfido2/fuzz/export.gnu +++ b/contrib/libfido2/fuzz/export.gnu @@ -7,6 +7,7 @@ eddsa_pk_to_EVP_PKEY; es256_pk_free; es256_pk_from_EC_KEY; + es256_pk_from_EVP_PKEY; es256_pk_from_ptr; es256_pk_new; es256_pk_to_EVP_PKEY; @@ -30,6 +31,7 @@ fido_assert_rp_id; fido_assert_set_authdata; fido_assert_set_authdata_raw; + fido_assert_set_clientdata; fido_assert_set_clientdata_hash; fido_assert_set_count; fido_assert_set_extensions; @@ -98,6 +100,8 @@ fido_cbor_info_transports_ptr; fido_cbor_info_versions_len; fido_cbor_info_versions_ptr; + fido_cred_attstmt_len; + fido_cred_attstmt_ptr; fido_cred_authdata_len; fido_cred_authdata_ptr; fido_cred_authdata_raw_len; @@ -137,19 +141,23 @@ fido_credman_rp_new; fido_credman_set_dev_rk; fido_cred_new; + fido_cred_pin_minlen; fido_cred_prot; fido_cred_pubkey_len; fido_cred_pubkey_ptr; fido_cred_rp_id; fido_cred_rp_name; + fido_cred_set_attstmt; fido_cred_set_authdata; fido_cred_set_authdata_raw; fido_cred_set_blob; + fido_cred_set_clientdata; fido_cred_set_clientdata_hash; fido_cred_set_extensions; fido_cred_set_fmt; fido_cred_set_id; fido_cred_set_options; + fido_cred_set_pin_minlen; fido_cred_set_prot; fido_cred_set_rk; fido_cred_set_rp; @@ -205,6 +213,8 @@ fido_dev_set_io_functions; fido_dev_set_pin; fido_dev_set_pin_minlen; + fido_dev_set_pin_minlen_rpid; + fido_dev_set_timeout; fido_dev_set_transport_functions; fido_dev_supports_cred_prot; fido_dev_supports_credman; @@ -230,10 +240,12 @@ fido_strerr; rs256_pk_free; rs256_pk_from_ptr; + rs256_pk_from_EVP_PKEY; rs256_pk_from_RSA; rs256_pk_new; rs256_pk_to_EVP_PKEY; prng_init; + fuzz_clock_reset; set_netlink_io_functions; set_udev_parameters; uniform_random; diff --git a/contrib/libfido2/fuzz/functions.txt b/contrib/libfido2/fuzz/functions.txt index 28fe4f6af17b..886893b1d11d 100644 --- a/contrib/libfido2/fuzz/functions.txt +++ b/contrib/libfido2/fuzz/functions.txt @@ -1,285 +1,286 @@ File '/libfido2/src/aes256.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------- +-------------------------------------------------------------------------------------------------------- aes256_cbc_enc 3 0 100.00% 4 0 100.00% aes256_cbc_dec 3 0 100.00% 4 0 100.00% aes256_gcm_enc 1 0 100.00% 3 0 100.00% aes256_gcm_dec 1 0 100.00% 3 0 100.00% -aes256.c:aes256_cbc_fips 26 2 92.31% 45 7 84.44% -aes256.c:aes256_cbc 29 1 96.55% 40 3 92.50% -aes256.c:aes256_cbc_proto1 1 0 100.00% 7 0 100.00% -aes256.c:aes256_gcm 51 1 98.04% 69 4 94.20% ------------------------------------------------------------------------------- -TOTAL 115 4 96.52% 175 14 92.00% +aes256.c:aes256_cbc_fips 26 2 92.31% 42 7 83.33% +aes256.c:aes256_cbc 29 1 96.55% 36 3 91.67% +aes256.c:aes256_cbc_proto1 1 0 100.00% 5 0 100.00% +aes256.c:aes256_gcm 51 1 98.04% 60 4 93.33% +-------------------------------------------------------------------------------------------------------- +TOTAL 115 4 96.52% 157 14 91.08% File '/libfido2/src/assert.c': Name Regions Miss Cover Lines Miss Cover ---------------------------------------------------------------------------------------- -fido_dev_get_assert 40 0 100.00% 41 0 100.00% -fido_check_flags 13 0 100.00% 18 0 100.00% -fido_get_signed_hash 32 0 100.00% 46 0 100.00% -fido_verify_sig_es256 17 2 88.24% 31 7 77.42% -fido_verify_sig_rs256 17 2 88.24% 31 7 77.42% -fido_verify_sig_eddsa 23 2 91.30% 43 7 83.72% -fido_assert_verify 48 4 91.67% 79 5 93.67% -fido_assert_set_clientdata 12 12 0.00% 12 12 0.00% -fido_assert_set_clientdata_hash 8 0 100.00% 7 0 100.00% -fido_assert_set_hmac_salt 10 0 100.00% 7 0 100.00% -fido_assert_set_hmac_secret 12 12 0.00% 8 8 0.00% -fido_assert_set_rp 12 0 100.00% 14 0 100.00% -fido_assert_allow_cred 13 2 84.62% 29 3 89.66% -fido_assert_set_extensions 14 0 100.00% 11 0 100.00% -fido_assert_set_options 6 6 0.00% 6 6 0.00% -fido_assert_set_up 2 0 100.00% 5 0 100.00% -fido_assert_set_uv 2 0 100.00% 5 0 100.00% +----------------------------------------------------------------------------------------------------------------- +fido_dev_get_assert 40 0 100.00% 35 0 100.00% +fido_check_flags 13 0 100.00% 15 0 100.00% +fido_get_signed_hash 36 0 100.00% 46 0 100.00% +fido_assert_verify 48 4 91.67% 67 5 92.54% +fido_assert_set_clientdata 12 12 0.00% 11 11 0.00% +fido_assert_set_clientdata_hash 8 0 100.00% 6 0 100.00% +fido_assert_set_hmac_salt 10 0 100.00% 6 0 100.00% +fido_assert_set_hmac_secret 12 12 0.00% 7 7 0.00% +fido_assert_set_rp 12 0 100.00% 11 0 100.00% +fido_assert_allow_cred 13 2 84.62% 22 3 86.36% +fido_assert_set_extensions 14 0 100.00% 10 0 100.00% +fido_assert_set_options 6 6 0.00% 5 5 0.00% +fido_assert_set_up 2 0 100.00% 4 0 100.00% +fido_assert_set_uv 2 0 100.00% 4 0 100.00% fido_assert_clientdata_hash_ptr 1 0 100.00% 3 0 100.00% fido_assert_clientdata_hash_len 1 0 100.00% 3 0 100.00% fido_assert_new 1 0 100.00% 3 0 100.00% fido_assert_reset_tx 1 0 100.00% 12 0 100.00% fido_assert_reset_rx 4 0 100.00% 19 0 100.00% -fido_assert_free 6 0 100.00% 10 0 100.00% +fido_assert_free 6 0 100.00% 9 0 100.00% fido_assert_count 1 0 100.00% 3 0 100.00% fido_assert_rp_id 1 0 100.00% 3 0 100.00% -fido_assert_flags 4 0 100.00% 6 0 100.00% -fido_assert_sigcount 4 0 100.00% 6 0 100.00% -fido_assert_authdata_ptr 4 0 100.00% 6 0 100.00% -fido_assert_authdata_len 4 0 100.00% 6 0 100.00% -fido_assert_sig_ptr 4 0 100.00% 6 0 100.00% -fido_assert_sig_len 4 0 100.00% 6 0 100.00% -fido_assert_id_ptr 4 0 100.00% 6 0 100.00% -fido_assert_id_len 4 0 100.00% 6 0 100.00% -fido_assert_user_id_ptr 4 0 100.00% 6 0 100.00% -fido_assert_user_id_len 4 0 100.00% 6 0 100.00% -fido_assert_user_icon 4 0 100.00% 6 0 100.00% -fido_assert_user_name 4 0 100.00% 6 0 100.00% -fido_assert_user_display_name 4 0 100.00% 6 0 100.00% -fido_assert_hmac_secret_ptr 4 0 100.00% 6 0 100.00% -fido_assert_hmac_secret_len 4 0 100.00% 6 0 100.00% -fido_assert_largeblob_key_ptr 4 0 100.00% 6 0 100.00% -fido_assert_largeblob_key_len 4 0 100.00% 6 0 100.00% -fido_assert_blob_ptr 4 0 100.00% 6 0 100.00% -fido_assert_blob_len 4 0 100.00% 6 0 100.00% -fido_assert_set_authdata 24 0 100.00% 35 0 100.00% -fido_assert_set_authdata_raw 24 0 100.00% 34 0 100.00% -fido_assert_set_sig 14 0 100.00% 8 0 100.00% -fido_assert_set_count 10 0 100.00% 21 0 100.00% -assert.c:fido_dev_get_assert_wait 21 0 100.00% 16 0 100.00% -assert.c:fido_dev_get_assert_tx 56 2 96.43% 77 5 93.51% -assert.c:fido_dev_get_assert_rx 19 0 100.00% 38 0 100.00% -assert.c:adjust_assert_count 24 0 100.00% 33 0 100.00% -assert.c:parse_assert_reply 12 0 100.00% 26 0 100.00% -assert.c:fido_get_next_assert_tx 8 0 100.00% 10 0 100.00% -assert.c:fido_get_next_assert_rx 15 2 86.67% 26 4 84.62% -assert.c:decrypt_hmac_secrets 9 0 100.00% 16 0 100.00% -assert.c:check_extensions 5 0 100.00% 11 0 100.00% +fido_assert_flags 4 0 100.00% 5 0 100.00% +fido_assert_sigcount 4 0 100.00% 5 0 100.00% +fido_assert_authdata_ptr 4 0 100.00% 5 0 100.00% +fido_assert_authdata_len 4 0 100.00% 5 0 100.00% +fido_assert_sig_ptr 4 0 100.00% 5 0 100.00% +fido_assert_sig_len 4 0 100.00% 5 0 100.00% +fido_assert_id_ptr 4 0 100.00% 5 0 100.00% +fido_assert_id_len 4 0 100.00% 5 0 100.00% +fido_assert_user_id_ptr 4 0 100.00% 5 0 100.00% +fido_assert_user_id_len 4 0 100.00% 5 0 100.00% +fido_assert_user_icon 4 0 100.00% 5 0 100.00% +fido_assert_user_name 4 0 100.00% 5 0 100.00% +fido_assert_user_display_name 4 0 100.00% 5 0 100.00% +fido_assert_hmac_secret_ptr 4 0 100.00% 5 0 100.00% +fido_assert_hmac_secret_len 4 0 100.00% 5 0 100.00% +fido_assert_largeblob_key_ptr 4 0 100.00% 5 0 100.00% +fido_assert_largeblob_key_len 4 0 100.00% 5 0 100.00% +fido_assert_blob_ptr 4 0 100.00% 5 0 100.00% +fido_assert_blob_len 4 0 100.00% 5 0 100.00% +fido_assert_set_authdata 24 0 100.00% 28 0 100.00% +fido_assert_set_authdata_raw 24 0 100.00% 27 0 100.00% +fido_assert_set_sig 14 0 100.00% 7 0 100.00% +fido_assert_set_count 10 0 100.00% 17 0 100.00% +assert.c:fido_dev_get_assert_wait 21 0 100.00% 14 0 100.00% +assert.c:fido_dev_get_assert_tx 56 2 96.43% 62 5 91.94% +assert.c:fido_dev_get_assert_rx 19 0 100.00% 27 0 100.00% +assert.c:adjust_assert_count 24 0 100.00% 26 0 100.00% +assert.c:parse_assert_reply 12 0 100.00% 24 0 100.00% +assert.c:fido_get_next_assert_tx 8 0 100.00% 8 0 100.00% +assert.c:fido_get_next_assert_rx 15 2 86.67% 21 4 80.95% +assert.c:decrypt_hmac_secrets 9 0 100.00% 15 0 100.00% +assert.c:check_extensions 5 0 100.00% 9 0 100.00% assert.c:fido_assert_reset_extattr 1 0 100.00% 5 0 100.00% assert.c:fido_assert_clean_authdata 1 0 100.00% 5 0 100.00% ---------------------------------------------------------------------------------------- -TOTAL 616 46 92.53% 924 64 93.07% +----------------------------------------------------------------------------------------------------------------- +TOTAL 563 40 92.90% 694 40 94.24% File '/libfido2/src/authkey.c': Name Regions Miss Cover Lines Miss Cover ---------------------------------------------------------------------------------------- +----------------------------------------------------------------------------------------------------------------- fido_dev_authkey 1 0 100.00% 3 0 100.00% -authkey.c:fido_dev_authkey_wait 10 0 100.00% 9 0 100.00% -authkey.c:fido_dev_authkey_tx 19 0 100.00% 33 0 100.00% -authkey.c:fido_dev_authkey_rx 6 0 100.00% 18 0 100.00% -authkey.c:parse_authkey 8 0 100.00% 12 0 100.00% ---------------------------------------------------------------------------------------- -TOTAL 44 0 100.00% 75 0 100.00% +authkey.c:fido_dev_authkey_wait 10 0 100.00% 7 0 100.00% +authkey.c:fido_dev_authkey_tx 19 0 100.00% 25 0 100.00% +authkey.c:fido_dev_authkey_rx 6 0 100.00% 14 0 100.00% +authkey.c:parse_authkey 8 0 100.00% 10 0 100.00% +----------------------------------------------------------------------------------------------------------------- +TOTAL 44 0 100.00% 59 0 100.00% File '/libfido2/src/bio.c': Name Regions Miss Cover Lines Miss Cover ---------------------------------------------------------------------------------------- +----------------------------------------------------------------------------------------------------------------- fido_bio_dev_get_template_array 5 2 60.00% 6 0 100.00% fido_bio_dev_set_template_name 7 0 100.00% 6 0 100.00% -fido_bio_dev_enroll_begin 25 2 92.00% 37 0 100.00% +fido_bio_dev_enroll_begin 25 2 92.00% 31 0 100.00% fido_bio_dev_enroll_continue 5 2 60.00% 6 0 100.00% -fido_bio_dev_enroll_cancel 1 1 0.00% 3 3 0.00% -fido_bio_dev_enroll_remove 1 0 100.00% 3 0 100.00% -fido_bio_dev_get_info 1 0 100.00% 3 0 100.00% +fido_bio_dev_enroll_cancel 1 1 0.00% 4 4 0.00% +fido_bio_dev_enroll_remove 1 0 100.00% 4 0 100.00% +fido_bio_dev_get_info 1 0 100.00% 4 0 100.00% fido_bio_template_name 1 0 100.00% 3 0 100.00% fido_bio_template_id_ptr 1 0 100.00% 3 0 100.00% fido_bio_template_id_len 1 0 100.00% 3 0 100.00% fido_bio_template_array_count 1 0 100.00% 3 0 100.00% fido_bio_template_array_new 1 0 100.00% 3 0 100.00% fido_bio_template_new 1 0 100.00% 3 0 100.00% -fido_bio_template_array_free 6 0 100.00% 10 0 100.00% -fido_bio_template_free 6 0 100.00% 10 0 100.00% -fido_bio_template_set_name 8 0 100.00% 9 0 100.00% -fido_bio_template_set_id 8 0 100.00% 8 0 100.00% -fido_bio_template 4 0 100.00% 6 0 100.00% +fido_bio_template_array_free 6 0 100.00% 8 0 100.00% +fido_bio_template_free 6 0 100.00% 8 0 100.00% +fido_bio_template_set_name 8 0 100.00% 7 0 100.00% +fido_bio_template_set_id 8 0 100.00% 6 0 100.00% +fido_bio_template 4 0 100.00% 5 0 100.00% fido_bio_enroll_new 1 0 100.00% 3 0 100.00% fido_bio_info_new 1 0 100.00% 3 0 100.00% fido_bio_info_type 1 0 100.00% 3 0 100.00% fido_bio_info_max_samples 1 0 100.00% 3 0 100.00% -fido_bio_enroll_free 6 0 100.00% 11 0 100.00% -fido_bio_info_free 6 0 100.00% 9 0 100.00% +fido_bio_enroll_free 6 0 100.00% 8 0 100.00% +fido_bio_info_free 6 0 100.00% 7 0 100.00% fido_bio_enroll_remaining_samples 1 0 100.00% 3 0 100.00% fido_bio_enroll_last_status 1 0 100.00% 3 0 100.00% -bio.c:bio_get_template_array_wait 11 0 100.00% 9 0 100.00% -bio.c:bio_tx 43 0 100.00% 66 0 100.00% -bio.c:bio_prepare_hmac 18 0 100.00% 36 0 100.00% -bio.c:bio_rx_template_array 11 0 100.00% 21 0 100.00% -bio.c:bio_parse_template_array 26 1 96.15% 34 4 88.24% -bio.c:decode_template_array 12 1 91.67% 23 3 86.96% -bio.c:decode_template 9 0 100.00% 18 0 100.00% -bio.c:bio_set_template_name_wait 19 0 100.00% 24 0 100.00% -bio.c:bio_enroll_begin_wait 17 0 100.00% 24 0 100.00% -bio.c:bio_rx_enroll_begin 15 0 100.00% 29 0 100.00% -bio.c:bio_parse_enroll_status 20 0 100.00% 31 0 100.00% -bio.c:bio_parse_template_id 8 0 100.00% 12 0 100.00% -bio.c:bio_enroll_continue_wait 19 0 100.00% 25 0 100.00% -bio.c:bio_rx_enroll_continue 11 0 100.00% 22 0 100.00% -bio.c:bio_enroll_cancel_wait 11 11 0.00% 12 12 0.00% -bio.c:bio_enroll_remove_wait 17 0 100.00% 24 0 100.00% -bio.c:bio_get_info_wait 11 0 100.00% 11 0 100.00% -bio.c:bio_rx_info 11 0 100.00% 21 0 100.00% +bio.c:bio_get_template_array_wait 11 0 100.00% 7 0 100.00% +bio.c:bio_tx 43 0 100.00% 55 0 100.00% +bio.c:bio_prepare_hmac 18 0 100.00% 29 0 100.00% +bio.c:bio_rx_template_array 11 0 100.00% 17 0 100.00% +bio.c:bio_parse_template_array 26 1 96.15% 27 4 85.19% +bio.c:decode_template_array 12 1 91.67% 18 3 83.33% +bio.c:decode_template 9 0 100.00% 15 0 100.00% +bio.c:bio_set_template_name_wait 19 0 100.00% 20 0 100.00% +bio.c:bio_enroll_begin_wait 17 0 100.00% 19 0 100.00% +bio.c:bio_rx_enroll_begin 15 0 100.00% 24 0 100.00% +bio.c:bio_parse_enroll_status 20 0 100.00% 28 0 100.00% +bio.c:bio_parse_template_id 8 0 100.00% 10 0 100.00% +bio.c:bio_enroll_continue_wait 19 0 100.00% 20 0 100.00% +bio.c:bio_rx_enroll_continue 11 0 100.00% 18 0 100.00% +bio.c:bio_enroll_cancel_wait 11 11 0.00% 10 10 0.00% +bio.c:bio_enroll_remove_wait 17 0 100.00% 19 0 100.00% +bio.c:bio_get_info_wait 11 0 100.00% 10 0 100.00% +bio.c:bio_rx_info 11 0 100.00% 17 0 100.00% bio.c:bio_reset_info 1 0 100.00% 4 0 100.00% -bio.c:bio_parse_info 20 0 100.00% 31 0 100.00% -bio.c:bio_reset_template_array 4 0 100.00% 8 0 100.00% +bio.c:bio_parse_info 20 0 100.00% 28 0 100.00% +bio.c:bio_reset_template_array 4 0 100.00% 7 0 100.00% bio.c:bio_reset_template 1 0 100.00% 5 0 100.00% -bio.c:bio_reset_enroll 3 0 100.00% 7 0 100.00% ---------------------------------------------------------------------------------------- -TOTAL 419 20 95.23% 660 22 96.67% +bio.c:bio_reset_enroll 3 0 100.00% 6 0 100.00% +----------------------------------------------------------------------------------------------------------------- +TOTAL 419 20 95.23% 559 21 96.24% File '/libfido2/src/blob.c': Name Regions Miss Cover Lines Miss Cover ---------------------------------------------------------------------------------------- +----------------------------------------------------------------------------------------------------------------- fido_blob_new 1 0 100.00% 3 0 100.00% fido_blob_reset 1 0 100.00% 4 0 100.00% -fido_blob_set 9 0 100.00% 19 0 100.00% -fido_blob_append 12 2 83.33% 22 6 72.73% -fido_blob_free 6 0 100.00% 10 0 100.00% -fido_free_blob_array 7 0 100.00% 14 0 100.00% -fido_blob_encode 6 0 100.00% 6 0 100.00% +fido_blob_set 9 0 100.00% 15 0 100.00% +fido_blob_append 12 1 91.67% 20 3 85.00% +fido_blob_free 6 0 100.00% 8 0 100.00% +fido_free_blob_array 7 0 100.00% 12 0 100.00% +fido_blob_encode 6 0 100.00% 5 0 100.00% fido_blob_decode 1 0 100.00% 3 0 100.00% fido_blob_is_empty 3 0 100.00% 3 0 100.00% -fido_blob_serialise 7 1 85.71% 12 1 91.67% ---------------------------------------------------------------------------------------- -TOTAL 53 3 94.34% 96 7 92.71% +fido_blob_serialise 7 1 85.71% 10 1 90.00% +----------------------------------------------------------------------------------------------------------------- +TOTAL 53 2 96.23% 83 4 95.18% File '/libfido2/src/buf.c': Name Regions Miss Cover Lines Miss Cover ---------------------------------------------------------------------------------------- -fido_buf_read 4 0 100.00% 10 0 100.00% -fido_buf_write 4 1 75.00% 10 1 90.00% ---------------------------------------------------------------------------------------- -TOTAL 8 1 87.50% 20 1 95.00% +----------------------------------------------------------------------------------------------------------------- +fido_buf_read 4 0 100.00% 8 0 100.00% +fido_buf_write 4 1 75.00% 8 1 87.50% +----------------------------------------------------------------------------------------------------------------- +TOTAL 8 1 87.50% 16 1 93.75% File '/libfido2/src/cbor.c': Name Regions Miss Cover Lines Miss Cover ----------------------------------------------------------------------------------------- -cbor_map_iter 20 1 95.00% 30 4 86.67% -cbor_array_iter 12 0 100.00% 20 0 100.00% -cbor_parse_reply 27 0 100.00% 43 0 100.00% +------------------------------------------------------------------------------------------------------------------ +cbor_map_iter 20 1 95.00% 26 4 84.62% +cbor_array_iter 12 0 100.00% 16 0 100.00% +cbor_parse_reply 27 0 100.00% 36 0 100.00% cbor_vector_free 6 0 100.00% 5 0 100.00% -cbor_bytestring_copy 14 0 100.00% 22 0 100.00% -cbor_string_copy 14 0 100.00% 23 0 100.00% -cbor_add_bytestring 14 0 100.00% 26 0 100.00% -cbor_add_string 14 0 100.00% 26 0 100.00% -cbor_add_bool 14 0 100.00% 26 0 100.00% -cbor_flatten_vector 14 1 92.86% 21 1 95.24% -cbor_build_frame 15 0 100.00% 32 0 100.00% -cbor_encode_rp_entity 13 0 100.00% 14 0 100.00% -cbor_encode_user_entity 21 0 100.00% 18 0 100.00% -cbor_encode_pubkey_param 36 0 100.00% 48 0 100.00% -cbor_encode_pubkey 10 0 100.00% 13 0 100.00% -cbor_encode_pubkey_list 18 0 100.00% 23 0 100.00% -cbor_encode_cred_ext 46 0 100.00% 46 0 100.00% -cbor_encode_cred_opt 13 0 100.00% 13 0 100.00% -cbor_encode_assert_opt 13 0 100.00% 13 0 100.00% -cbor_encode_pin_auth 20 1 95.00% 30 3 90.00% -cbor_encode_pin_opt 4 0 100.00% 10 0 100.00% -cbor_encode_change_pin_auth 33 1 96.97% 49 3 93.88% -cbor_encode_assert_ext 33 0 100.00% 35 0 100.00% -cbor_decode_fmt 11 0 100.00% 19 0 100.00% -cbor_decode_pubkey 21 1 95.24% 32 2 93.75% -cbor_decode_cred_authdata 31 1 96.77% 45 3 93.33% -cbor_decode_assert_authdata 21 0 100.00% 42 0 100.00% -cbor_decode_attstmt 8 0 100.00% 10 0 100.00% -cbor_decode_uint64 4 0 100.00% 10 0 100.00% -cbor_decode_cred_id 8 0 100.00% 10 0 100.00% -cbor_decode_user 8 0 100.00% 10 0 100.00% -cbor_decode_rp_entity 8 0 100.00% 10 0 100.00% -cbor_build_uint 10 4 60.00% 10 5 50.00% -cbor_array_append 17 0 100.00% 23 0 100.00% -cbor_array_drop 18 2 88.89% 19 3 84.21% -cbor.c:ctap_check_cbor 28 0 100.00% 32 0 100.00% -cbor.c:check_key_type 8 0 100.00% 9 0 100.00% -cbor.c:cbor_add_arg 13 0 100.00% 28 0 100.00% -cbor.c:cbor_add_uint8 14 0 100.00% 26 0 100.00% -cbor.c:cbor_encode_largeblob_key_ext 6 0 100.00% 7 0 100.00% -cbor.c:cbor_encode_hmac_secret_param 53 2 96.23% 75 4 94.67% -cbor.c:get_cose_alg 36 0 100.00% 48 0 100.00% -cbor.c:find_cose_alg 35 0 100.00% 40 0 100.00% -cbor.c:decode_attcred 25 0 100.00% 56 0 100.00% -cbor.c:decode_cred_extensions 14 0 100.00% 31 0 100.00% -cbor.c:decode_cred_extension 40 3 92.50% 45 9 80.00% -cbor.c:decode_assert_extensions 14 0 100.00% 29 0 100.00% -cbor.c:decode_assert_extension 19 0 100.00% 31 0 100.00% -cbor.c:decode_attstmt_entry 38 0 100.00% 44 0 100.00% -cbor.c:decode_x5c 4 0 100.00% 8 0 100.00% -cbor.c:decode_cred_id_entry 10 0 100.00% 23 0 100.00% -cbor.c:decode_user_entry 25 0 100.00% 39 0 100.00% -cbor.c:decode_rp_entity_entry 15 0 100.00% 29 0 100.00% ----------------------------------------------------------------------------------------- -TOTAL 986 17 98.28% 1426 37 97.41% +cbor_bytestring_copy 14 0 100.00% 18 0 100.00% +cbor_string_copy 14 1 92.86% 18 3 83.33% +cbor_add_bytestring 14 0 100.00% 21 0 100.00% +cbor_add_string 14 0 100.00% 21 0 100.00% +cbor_add_bool 14 0 100.00% 21 0 100.00% +cbor_flatten_vector 14 1 92.86% 16 1 93.75% +cbor_build_frame 15 0 100.00% 25 0 100.00% +cbor_encode_rp_entity 13 0 100.00% 11 0 100.00% +cbor_encode_user_entity 21 0 100.00% 15 0 100.00% +cbor_encode_pubkey_param 36 0 100.00% 39 0 100.00% +cbor_encode_pubkey 10 0 100.00% 11 0 100.00% +cbor_encode_pubkey_list 18 0 100.00% 19 0 100.00% +cbor_encode_str_array 18 0 100.00% 19 0 100.00% +cbor_encode_cred_ext 55 0 100.00% 50 0 100.00% +cbor_encode_cred_opt 13 0 100.00% 11 0 100.00% +cbor_encode_assert_opt 13 0 100.00% 11 0 100.00% +cbor_encode_pin_auth 20 1 95.00% 22 3 86.36% +cbor_encode_pin_opt 4 0 100.00% 8 0 100.00% +cbor_encode_change_pin_auth 31 1 96.77% 36 3 91.67% +cbor_encode_assert_ext 33 0 100.00% 32 0 100.00% +cbor_decode_fmt 13 0 100.00% 15 0 100.00% +cbor_decode_pubkey 21 1 95.24% 30 2 93.33% +cbor_decode_cred_authdata 31 1 96.77% 35 3 91.43% +cbor_decode_assert_authdata 21 0 100.00% 32 0 100.00% +cbor_decode_attstmt 13 0 100.00% 16 0 100.00% +cbor_decode_uint64 4 0 100.00% 8 0 100.00% +cbor_decode_cred_id 8 0 100.00% 9 0 100.00% +cbor_decode_user 8 0 100.00% 9 0 100.00% +cbor_decode_rp_entity 8 0 100.00% 9 0 100.00% +cbor_build_uint 10 4 60.00% 9 4 55.56% +cbor_array_append 17 0 100.00% 21 0 100.00% +cbor_array_drop 18 2 88.89% 17 3 82.35% +cbor.c:ctap_check_cbor 28 0 100.00% 26 0 100.00% +cbor.c:check_key_type 8 0 100.00% 7 0 100.00% +cbor.c:cbor_add_arg 13 0 100.00% 21 0 100.00% +cbor.c:cbor_add_uint8 14 0 100.00% 21 0 100.00% +cbor.c:cbor_encode_largeblob_key_ext 6 0 100.00% 6 0 100.00% +cbor.c:cbor_encode_hmac_secret_param 59 4 93.22% 66 8 87.88% +cbor.c:get_cose_alg 36 1 97.22% 38 3 92.11% +cbor.c:find_cose_alg 35 0 100.00% 33 0 100.00% +cbor.c:decode_attcred 25 0 100.00% 44 0 100.00% +cbor.c:decode_cred_extensions 14 0 100.00% 24 0 100.00% +cbor.c:decode_cred_extension 49 10 79.59% 49 17 65.31% +cbor.c:decode_assert_extensions 14 0 100.00% 23 0 100.00% +cbor.c:decode_assert_extension 19 0 100.00% 27 0 100.00% +cbor.c:decode_attstmt_entry 52 0 100.00% 50 0 100.00% +cbor.c:decode_x5c 4 0 100.00% 6 0 100.00% +cbor.c:decode_cred_id_entry 10 0 100.00% 19 0 100.00% +cbor.c:decode_user_entry 25 0 100.00% 35 0 100.00% +cbor.c:decode_rp_entity_entry 15 0 100.00% 25 0 100.00% +------------------------------------------------------------------------------------------------------------------ +TOTAL 1047 28 97.33% 1237 54 95.63% File '/libfido2/src/compress.c': Name Regions Miss Cover Lines Miss Cover ----------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------------------ fido_compress 1 0 100.00% 3 0 100.00% fido_uncompress 1 0 100.00% 3 0 100.00% -compress.c:do_compress 32 4 87.50% 24 3 87.50% ----------------------------------------------------------------------------------------- -TOTAL 34 4 88.24% 30 3 90.00% +compress.c:do_compress 32 4 87.50% 22 3 86.36% +------------------------------------------------------------------------------------------------------------------ +TOTAL 34 4 88.24% 28 3 89.29% File '/libfido2/src/config.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ -fido_dev_enable_entattest 1 0 100.00% 3 0 100.00% -fido_dev_toggle_always_uv 1 0 100.00% 3 0 100.00% -fido_dev_set_pin_minlen 1 0 100.00% 3 0 100.00% -fido_dev_force_pin_change 1 0 100.00% 3 0 100.00% -config.c:config_enable_entattest_wait 6 0 100.00% 8 0 100.00% -config.c:config_tx 37 0 100.00% 57 0 100.00% -config.c:config_prepare_hmac 8 1 87.50% 22 3 86.36% -config.c:config_toggle_always_uv_wait 6 0 100.00% 8 0 100.00% -config.c:config_pin_minlen 5 0 100.00% 8 0 100.00% -config.c:config_pin_minlen_tx 28 0 100.00% 31 0 100.00% ------------------------------------------------------------------------------------------ -TOTAL 94 1 98.94% 146 3 97.95% +------------------------------------------------------------------------------------------------------------------- +fido_dev_enable_entattest 1 0 100.00% 4 0 100.00% +fido_dev_toggle_always_uv 1 0 100.00% 4 0 100.00% +fido_dev_set_pin_minlen 1 0 100.00% 4 0 100.00% +fido_dev_force_pin_change 1 0 100.00% 4 0 100.00% +fido_dev_set_pin_minlen_rpid 6 0 100.00% 15 0 100.00% +config.c:config_enable_entattest_wait 6 0 100.00% 7 0 100.00% +config.c:config_tx 37 0 100.00% 48 0 100.00% +config.c:config_prepare_hmac 8 0 100.00% 19 0 100.00% +config.c:config_toggle_always_uv_wait 6 0 100.00% 7 0 100.00% +config.c:config_pin_minlen 5 0 100.00% 7 0 100.00% +config.c:config_pin_minlen_tx 36 0 100.00% 32 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 108 0 100.00% 151 0 100.00% File '/libfido2/src/cred.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------- fido_dev_make_cred 12 0 100.00% 10 0 100.00% -fido_check_rp_id 4 0 100.00% 14 0 100.00% -fido_cred_verify 50 4 92.00% 75 8 89.33% -fido_cred_verify_self 58 6 89.66% 94 10 89.36% +fido_check_rp_id 4 0 100.00% 11 0 100.00% +fido_cred_verify 56 2 96.43% 72 5 93.06% +fido_cred_verify_self 58 4 93.10% 83 5 93.98% fido_cred_new 1 0 100.00% 3 0 100.00% -fido_cred_reset_tx 1 0 100.00% 22 0 100.00% -fido_cred_reset_rx 1 0 100.00% 8 0 100.00% -fido_cred_free 6 0 100.00% 10 0 100.00% -fido_cred_set_authdata 23 0 100.00% 37 0 100.00% -fido_cred_set_authdata_raw 25 0 100.00% 38 0 100.00% -fido_cred_set_id 6 0 100.00% 6 0 100.00% -fido_cred_set_x509 6 0 100.00% 6 0 100.00% -fido_cred_set_sig 6 0 100.00% 6 0 100.00% -fido_cred_exclude 14 2 85.71% 25 3 88.00% -fido_cred_set_clientdata 12 12 0.00% 12 12 0.00% -fido_cred_set_clientdata_hash 8 0 100.00% 7 0 100.00% -fido_cred_set_rp 18 0 100.00% 26 0 100.00% -fido_cred_set_user 32 0 100.00% 46 0 100.00% -fido_cred_set_extensions 15 0 100.00% 11 0 100.00% -fido_cred_set_options 6 6 0.00% 6 6 0.00% -fido_cred_set_rk 2 0 100.00% 5 0 100.00% -fido_cred_set_uv 2 0 100.00% 5 0 100.00% -fido_cred_set_prot 21 0 100.00% 16 0 100.00% -fido_cred_set_blob 13 2 84.62% 10 1 90.00% -fido_cred_set_fmt 18 4 77.78% 16 1 93.75% -fido_cred_set_type 17 0 100.00% 9 0 100.00% +fido_cred_reset_tx 1 0 100.00% 19 0 100.00% +fido_cred_reset_rx 1 0 100.00% 7 0 100.00% +fido_cred_free 6 0 100.00% 9 0 100.00% +fido_cred_set_authdata 23 0 100.00% 28 0 100.00% +fido_cred_set_authdata_raw 25 0 100.00% 29 0 100.00% +fido_cred_set_id 6 0 100.00% 5 0 100.00% +fido_cred_set_x509 6 0 100.00% 5 0 100.00% +fido_cred_set_sig 6 0 100.00% 5 0 100.00% +fido_cred_set_attstmt 20 0 100.00% 23 0 100.00% +fido_cred_exclude 14 2 85.71% 19 3 84.21% +fido_cred_set_clientdata 12 12 0.00% 11 11 0.00% +fido_cred_set_clientdata_hash 8 0 100.00% 6 0 100.00% +fido_cred_set_rp 18 0 100.00% 22 0 100.00% +fido_cred_set_user 32 0 100.00% 41 0 100.00% +fido_cred_set_extensions 16 0 100.00% 10 0 100.00% +fido_cred_set_options 6 6 0.00% 5 5 0.00% +fido_cred_set_rk 2 0 100.00% 4 0 100.00% +fido_cred_set_uv 2 0 100.00% 4 0 100.00% +fido_cred_set_prot 21 0 100.00% 14 0 100.00% +fido_cred_set_pin_minlen 7 0 100.00% 8 0 100.00% +fido_cred_set_blob 13 2 84.62% 8 1 87.50% +fido_cred_set_fmt 20 4 80.00% 12 1 91.67% +fido_cred_set_type 17 0 100.00% 7 0 100.00% fido_cred_type 1 0 100.00% 3 0 100.00% fido_cred_flags 1 0 100.00% 3 0 100.00% fido_cred_sigcount 1 0 100.00% 3 0 100.00% @@ -293,13 +294,16 @@ fido_cred_authdata_ptr 1 0 100.00% 3 fido_cred_authdata_len 1 0 100.00% 3 0 100.00% fido_cred_authdata_raw_ptr 1 0 100.00% 3 0 100.00% fido_cred_authdata_raw_len 1 0 100.00% 3 0 100.00% -fido_cred_pubkey_ptr 9 0 100.00% 20 0 100.00% -fido_cred_pubkey_len 9 0 100.00% 20 0 100.00% +fido_cred_attstmt_ptr 1 0 100.00% 3 0 100.00% +fido_cred_attstmt_len 1 0 100.00% 3 0 100.00% +fido_cred_pubkey_ptr 9 0 100.00% 18 0 100.00% +fido_cred_pubkey_len 9 0 100.00% 18 0 100.00% fido_cred_id_ptr 1 0 100.00% 3 0 100.00% fido_cred_id_len 1 0 100.00% 3 0 100.00% fido_cred_aaguid_ptr 1 0 100.00% 3 0 100.00% fido_cred_aaguid_len 1 0 100.00% 3 0 100.00% fido_cred_prot 1 0 100.00% 3 0 100.00% +fido_cred_pin_minlen 1 0 100.00% 3 0 100.00% fido_cred_fmt 1 0 100.00% 3 0 100.00% fido_cred_rp_id 1 0 100.00% 3 0 100.00% fido_cred_rp_name 1 0 100.00% 3 0 100.00% @@ -309,82 +313,83 @@ fido_cred_user_id_ptr 1 0 100.00% 3 fido_cred_user_id_len 1 0 100.00% 3 0 100.00% fido_cred_largeblob_key_ptr 1 0 100.00% 3 0 100.00% fido_cred_largeblob_key_len 1 0 100.00% 3 0 100.00% -cred.c:fido_dev_make_cred_wait 10 0 100.00% 9 0 100.00% -cred.c:fido_dev_make_cred_tx 64 0 100.00% 85 0 100.00% -cred.c:fido_dev_make_cred_rx 19 0 100.00% 27 0 100.00% -cred.c:parse_makecred_reply 14 0 100.00% 29 0 100.00% -cred.c:check_extensions 2 0 100.00% 9 0 100.00% -cred.c:get_signed_hash_u2f 22 0 100.00% 20 0 100.00% -cred.c:verify_sig 27 2 92.59% 40 7 82.50% -cred.c:fido_cred_clean_authdata 1 0 100.00% 9 0 100.00% ------------------------------------------------------------------------------------------ -TOTAL 581 38 93.46% 872 48 94.50% +cred.c:fido_dev_make_cred_wait 10 0 100.00% 7 0 100.00% +cred.c:fido_dev_make_cred_tx 64 0 100.00% 70 0 100.00% +cred.c:fido_dev_make_cred_rx 29 0 100.00% 32 0 100.00% +cred.c:parse_makecred_reply 14 0 100.00% 27 0 100.00% +cred.c:check_extensions 2 0 100.00% 6 0 100.00% +cred.c:get_signed_hash_u2f 27 0 100.00% 26 0 100.00% +cred.c:verify_attstmt 23 2 91.30% 40 5 87.50% +cred.c:fido_cred_clean_authdata 1 0 100.00% 8 0 100.00% +cred.c:fido_cred_clean_attstmt 1 0 100.00% 8 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 632 34 94.62% 830 36 95.66% File '/libfido2/src/credman.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ -fido_credman_get_dev_metadata 1 0 100.00% 3 0 100.00% -fido_credman_get_dev_rk 1 0 100.00% 3 0 100.00% -fido_credman_del_dev_rk 1 0 100.00% 3 0 100.00% -fido_credman_get_dev_rp 1 0 100.00% 3 0 100.00% -fido_credman_set_dev_rk 1 0 100.00% 3 0 100.00% +------------------------------------------------------------------------------------------------------------------- +fido_credman_get_dev_metadata 1 0 100.00% 4 0 100.00% +fido_credman_get_dev_rk 1 0 100.00% 4 0 100.00% +fido_credman_del_dev_rk 1 0 100.00% 4 0 100.00% +fido_credman_get_dev_rp 1 0 100.00% 4 0 100.00% +fido_credman_set_dev_rk 1 0 100.00% 4 0 100.00% fido_credman_rk_new 1 0 100.00% 3 0 100.00% -fido_credman_rk_free 6 1 83.33% 10 0 100.00% +fido_credman_rk_free 6 1 83.33% 8 0 100.00% fido_credman_rk_count 1 0 100.00% 3 0 100.00% -fido_credman_rk 4 0 100.00% 6 0 100.00% +fido_credman_rk 4 0 100.00% 5 0 100.00% fido_credman_metadata_new 1 0 100.00% 3 0 100.00% -fido_credman_metadata_free 6 1 83.33% 9 0 100.00% +fido_credman_metadata_free 6 1 83.33% 7 0 100.00% fido_credman_rk_existing 1 0 100.00% 3 0 100.00% fido_credman_rk_remaining 1 0 100.00% 3 0 100.00% fido_credman_rp_new 1 0 100.00% 3 0 100.00% -fido_credman_rp_free 6 1 83.33% 10 0 100.00% +fido_credman_rp_free 6 1 83.33% 8 0 100.00% fido_credman_rp_count 1 0 100.00% 3 0 100.00% -fido_credman_rp_id 4 0 100.00% 6 0 100.00% -fido_credman_rp_name 4 0 100.00% 6 0 100.00% -fido_credman_rp_id_hash_len 4 0 100.00% 6 0 100.00% -fido_credman_rp_id_hash_ptr 4 0 100.00% 6 0 100.00% -credman.c:credman_get_metadata_wait 11 0 100.00% 10 0 100.00% -credman.c:credman_tx 36 0 100.00% 60 0 100.00% -credman.c:credman_prepare_hmac 31 1 96.77% 56 2 96.43% -credman.c:credman_rx_metadata 11 0 100.00% 21 0 100.00% -credman.c:credman_parse_metadata 9 0 100.00% 19 0 100.00% -credman.c:credman_get_rk_wait 27 0 100.00% 28 0 100.00% -credman.c:credman_rx_rk 19 0 100.00% 36 0 100.00% -credman.c:credman_parse_rk_count 16 0 100.00% 25 0 100.00% -credman.c:credman_grow_array 17 2 88.24% 28 5 82.14% -credman.c:credman_parse_rk 23 0 100.00% 33 0 100.00% -credman.c:credman_rx_next_rk 15 2 86.67% 26 4 84.62% -credman.c:credman_del_rk_wait 16 0 100.00% 20 0 100.00% -credman.c:credman_get_rp_wait 23 0 100.00% 18 0 100.00% -credman.c:credman_rx_rp 19 0 100.00% 36 0 100.00% -credman.c:credman_parse_rp_count 16 0 100.00% 25 0 100.00% -credman.c:credman_parse_rp 9 0 100.00% 19 0 100.00% -credman.c:credman_rx_next_rp 15 2 86.67% 26 4 84.62% -credman.c:credman_set_dev_rk_wait 11 0 100.00% 10 0 100.00% -credman.c:credman_reset_rk 4 0 100.00% 10 0 100.00% -credman.c:credman_reset_rp 4 0 100.00% 13 0 100.00% ------------------------------------------------------------------------------------------ -TOTAL 382 10 97.38% 614 15 97.56% +fido_credman_rp_id 4 0 100.00% 5 0 100.00% +fido_credman_rp_name 4 0 100.00% 5 0 100.00% +fido_credman_rp_id_hash_len 4 0 100.00% 5 0 100.00% +fido_credman_rp_id_hash_ptr 4 0 100.00% 5 0 100.00% +credman.c:credman_get_metadata_wait 11 0 100.00% 8 0 100.00% +credman.c:credman_tx 36 0 100.00% 50 0 100.00% +credman.c:credman_prepare_hmac 31 1 96.77% 50 2 96.00% +credman.c:credman_rx_metadata 11 0 100.00% 17 0 100.00% +credman.c:credman_parse_metadata 9 0 100.00% 17 0 100.00% +credman.c:credman_get_rk_wait 27 0 100.00% 23 0 100.00% +credman.c:credman_rx_rk 19 0 100.00% 27 0 100.00% +credman.c:credman_parse_rk_count 16 0 100.00% 20 0 100.00% +credman.c:credman_grow_array 17 2 88.24% 21 5 76.19% +credman.c:credman_parse_rk 23 0 100.00% 31 0 100.00% +credman.c:credman_rx_next_rk 15 2 86.67% 21 4 80.95% +credman.c:credman_del_rk_wait 16 0 100.00% 15 0 100.00% +credman.c:credman_get_rp_wait 23 0 100.00% 15 0 100.00% +credman.c:credman_rx_rp 19 0 100.00% 27 0 100.00% +credman.c:credman_parse_rp_count 16 0 100.00% 20 0 100.00% +credman.c:credman_parse_rp 9 0 100.00% 17 0 100.00% +credman.c:credman_rx_next_rp 15 2 86.67% 21 4 80.95% +credman.c:credman_set_dev_rk_wait 11 0 100.00% 8 0 100.00% +credman.c:credman_reset_rk 4 0 100.00% 9 0 100.00% +credman.c:credman_reset_rp 4 0 100.00% 12 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 382 10 97.38% 518 15 97.10% File '/libfido2/src/dev.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ -fido_dev_register_manifest_func 10 2 80.00% 18 3 83.33% -fido_dev_unregister_manifest_func 7 7 0.00% 13 13 0.00% -fido_dev_info_manifest 22 4 81.82% 28 0 100.00% +------------------------------------------------------------------------------------------------------------------- +fido_dev_register_manifest_func 10 2 80.00% 14 3 78.57% +fido_dev_unregister_manifest_func 7 7 0.00% 11 11 0.00% +fido_dev_info_manifest 22 4 81.82% 24 0 100.00% fido_dev_open_with_info 5 5 0.00% 6 6 0.00% -fido_dev_open 11 5 54.55% 26 12 53.85% -fido_dev_close 9 2 77.78% 10 0 100.00% -fido_dev_set_sigmask 12 12 0.00% 10 10 0.00% +fido_dev_open 5 1 80.00% 19 12 36.84% +fido_dev_close 9 2 77.78% 8 0 100.00% +fido_dev_set_sigmask 18 18 0.00% 11 11 0.00% fido_dev_cancel 11 0 100.00% 8 0 100.00% -fido_dev_get_touch_begin 50 0 100.00% 68 0 100.00% -fido_dev_get_touch_status 17 0 100.00% 25 0 100.00% -fido_dev_set_io_functions 18 4 77.78% 17 6 64.71% -fido_dev_set_transport_functions 6 2 66.67% 11 3 72.73% -fido_init 8 1 87.50% 6 0 100.00% -fido_dev_new 5 0 100.00% 16 0 100.00% -fido_dev_new_with_info 10 10 0.00% 20 20 0.00% -fido_dev_free 6 0 100.00% 11 0 100.00% +fido_dev_get_touch_begin 50 0 100.00% 59 0 100.00% +fido_dev_get_touch_status 17 0 100.00% 20 0 100.00% +fido_dev_set_io_functions 18 4 77.78% 14 6 57.14% +fido_dev_set_transport_functions 6 2 66.67% 9 3 66.67% +fido_init 8 1 87.50% 5 0 100.00% +fido_dev_new 5 0 100.00% 14 0 100.00% +fido_dev_new_with_info 10 10 0.00% 16 16 0.00% +fido_dev_free 6 0 100.00% 8 0 100.00% fido_dev_protocol 1 0 100.00% 3 0 100.00% fido_dev_major 1 0 100.00% 3 0 100.00% fido_dev_minor 1 0 100.00% 3 0 100.00% @@ -401,135 +406,141 @@ fido_dev_has_uv 2 0 100.00% 3 fido_dev_supports_permissions 2 0 100.00% 3 0 100.00% fido_dev_force_u2f 2 0 100.00% 4 0 100.00% fido_dev_force_fido2 2 2 0.00% 3 3 0.00% -fido_dev_get_pin_protocol 11 0 100.00% 8 0 100.00% +fido_dev_get_pin_protocol 11 0 100.00% 7 0 100.00% fido_dev_maxmsgsize 1 0 100.00% 3 0 100.00% -dev.c:find_manifest_func_node 5 0 100.00% 9 0 100.00% -dev.c:fido_dev_open_wait 10 0 100.00% 9 0 100.00% -dev.c:fido_dev_open_tx 56 15 73.21% 67 26 61.19% +fido_dev_set_timeout 6 2 66.67% 6 1 83.33% +dev.c:find_manifest_func_node 5 0 100.00% 8 0 100.00% +dev.c:fido_dev_open_wait 10 0 100.00% 7 0 100.00% +dev.c:fido_dev_open_tx 56 15 73.21% 56 26 53.57% dev.c:set_random_report_len 11 0 100.00% 6 0 100.00% -dev.c:fido_dev_open_rx 36 1 97.22% 62 1 98.39% +dev.c:fido_dev_open_rx 36 1 97.22% 53 1 98.11% dev.c:fido_dev_set_flags 1 0 100.00% 5 0 100.00% -dev.c:fido_dev_set_extension_flags 7 0 100.00% 8 0 100.00% -dev.c:fido_dev_set_option_flags 29 0 100.00% 19 0 100.00% -dev.c:fido_dev_set_protocol_flags 11 0 100.00% 18 0 100.00% ------------------------------------------------------------------------------------------ -TOTAL 414 74 82.13% 556 106 80.94% +dev.c:fido_dev_set_extension_flags 7 0 100.00% 7 0 100.00% +dev.c:fido_dev_set_option_flags 29 0 100.00% 18 0 100.00% +dev.c:fido_dev_set_protocol_flags 11 0 100.00% 17 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 420 78 81.43% 488 102 79.10% File '/libfido2/src/ecdh.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ -fido_do_ecdh 29 0 100.00% 40 0 100.00% -ecdh.c:do_ecdh 37 0 100.00% 48 0 100.00% -ecdh.c:kdf 19 1 94.74% 32 2 93.75% -ecdh.c:hkdf_sha256 32 1 96.88% 41 3 92.68% ------------------------------------------------------------------------------------------ -TOTAL 117 2 98.29% 161 5 96.89% +------------------------------------------------------------------------------------------------------------------- +fido_do_ecdh 29 0 100.00% 36 0 100.00% +ecdh.c:do_ecdh 37 0 100.00% 44 0 100.00% +ecdh.c:kdf 19 1 94.74% 28 2 92.86% +ecdh.c:hkdf_sha256 32 1 96.88% 38 3 92.11% +------------------------------------------------------------------------------------------------------------------- +TOTAL 117 2 98.29% 146 5 96.58% File '/libfido2/src/eddsa.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ -eddsa_pk_decode 8 0 100.00% 10 0 100.00% +------------------------------------------------------------------------------------------------------------------- +eddsa_pk_decode 8 0 100.00% 9 0 100.00% eddsa_pk_new 1 0 100.00% 3 0 100.00% -eddsa_pk_free 6 0 100.00% 9 0 100.00% -eddsa_pk_from_ptr 6 0 100.00% 8 0 100.00% -eddsa_pk_to_EVP_PKEY 3 0 100.00% 9 0 100.00% -eddsa_pk_from_EVP_PKEY 14 0 100.00% 12 0 100.00% -eddsa.c:decode_pubkey_point 8 0 100.00% 14 0 100.00% -eddsa.c:decode_coord 8 0 100.00% 12 0 100.00% ------------------------------------------------------------------------------------------ -TOTAL 54 0 100.00% 77 0 100.00% +eddsa_pk_free 6 0 100.00% 7 0 100.00% +eddsa_pk_from_ptr 6 0 100.00% 6 0 100.00% +eddsa_pk_to_EVP_PKEY 3 0 100.00% 7 0 100.00% +eddsa_pk_from_EVP_PKEY 14 0 100.00% 10 0 100.00% +eddsa_verify_sig 19 2 89.47% 30 6 80.00% +eddsa_pk_verify_sig 7 1 85.71% 13 2 84.62% +eddsa.c:decode_pubkey_point 8 0 100.00% 11 0 100.00% +eddsa.c:decode_coord 8 0 100.00% 10 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 80 3 96.25% 106 8 92.45% File '/libfido2/src/err.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------- fido_strerr 122 10 91.80% 126 10 92.06% ------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------- TOTAL 122 10 91.80% 126 10 92.06% File '/libfido2/src/es256.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ -es256_pk_decode 8 0 100.00% 10 0 100.00% -es256_pk_encode 56 0 100.00% 70 0 100.00% +------------------------------------------------------------------------------------------------------------------- +es256_pk_decode 8 0 100.00% 9 0 100.00% +es256_pk_encode 56 0 100.00% 48 0 100.00% es256_sk_new 1 0 100.00% 3 0 100.00% -es256_sk_free 6 0 100.00% 9 0 100.00% +es256_sk_free 6 0 100.00% 7 0 100.00% es256_pk_new 1 0 100.00% 3 0 100.00% -es256_pk_free 6 0 100.00% 9 0 100.00% -es256_pk_from_ptr 11 0 100.00% 13 0 100.00% -es256_pk_set_x 1 0 100.00% 5 0 100.00% -es256_pk_set_y 1 0 100.00% 5 0 100.00% -es256_sk_create 39 0 100.00% 46 0 100.00% -es256_pk_to_EVP_PKEY 42 0 100.00% 66 0 100.00% -es256_pk_from_EC_KEY 38 0 100.00% 43 0 100.00% -es256_sk_to_EVP_PKEY 28 0 100.00% 50 0 100.00% -es256_derive_pk 25 0 100.00% 34 0 100.00% -es256.c:decode_pubkey_point 9 0 100.00% 16 0 100.00% -es256.c:decode_coord 8 0 100.00% 12 0 100.00% ------------------------------------------------------------------------------------------ -TOTAL 280 0 100.00% 394 0 100.00% +es256_pk_free 6 0 100.00% 7 0 100.00% +es256_pk_from_ptr 11 0 100.00% 10 0 100.00% +es256_pk_set_x 1 0 100.00% 4 0 100.00% +es256_pk_set_y 1 0 100.00% 4 0 100.00% +es256_sk_create 39 0 100.00% 41 0 100.00% +es256_pk_to_EVP_PKEY 42 0 100.00% 54 0 100.00% +es256_pk_from_EC_KEY 38 0 100.00% 36 0 100.00% +es256_pk_from_EVP_PKEY 7 2 71.43% 7 0 100.00% +es256_sk_to_EVP_PKEY 28 0 100.00% 40 0 100.00% +es256_derive_pk 25 0 100.00% 30 0 100.00% +es256_verify_sig 12 2 83.33% 19 5 73.68% +es256_pk_verify_sig 7 1 85.71% 13 2 84.62% +es256.c:decode_pubkey_point 9 0 100.00% 13 0 100.00% +es256.c:decode_coord 8 0 100.00% 10 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 306 5 98.37% 358 7 98.04% File '/libfido2/src/extern.h': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------- File '/libfido2/src/fido.h': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------- File '/libfido2/src/hid.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ -fido_hid_get_usage 13 0 100.00% 28 0 100.00% -fido_hid_get_report_len 19 0 100.00% 33 0 100.00% +------------------------------------------------------------------------------------------------------------------- +fido_hid_get_usage 13 0 100.00% 22 0 100.00% +fido_hid_get_report_len 19 0 100.00% 27 0 100.00% fido_dev_info_new 1 0 100.00% 3 0 100.00% -fido_dev_info_free 9 0 100.00% 18 0 100.00% +fido_dev_info_free 9 0 100.00% 14 0 100.00% fido_dev_info_ptr 1 0 100.00% 3 0 100.00% fido_dev_info_path 1 0 100.00% 3 0 100.00% fido_dev_info_vendor 1 0 100.00% 3 0 100.00% fido_dev_info_product 1 0 100.00% 3 0 100.00% fido_dev_info_manufacturer_string 1 0 100.00% 3 0 100.00% fido_dev_info_product_string 1 0 100.00% 3 0 100.00% -hid.c:get_key_len 6 0 100.00% 14 0 100.00% -hid.c:get_key_val 6 0 100.00% 20 0 100.00% ------------------------------------------------------------------------------------------ -TOTAL 60 0 100.00% 134 0 100.00% +hid.c:get_key_len 6 0 100.00% 12 0 100.00% +hid.c:get_key_val 6 0 100.00% 18 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 60 0 100.00% 114 0 100.00% File '/libfido2/src/hid_linux.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ -fido_hid_manifest 35 4 88.57% 50 1 98.00% -fido_hid_open 27 27 0.00% 44 44 0.00% -fido_hid_close 3 3 0.00% 8 8 0.00% -fido_hid_set_sigmask 2 2 0.00% 8 8 0.00% -fido_hid_read 15 15 0.00% 26 26 0.00% -fido_hid_write 12 12 0.00% 21 21 0.00% -fido_hid_report_in_len 1 1 0.00% 5 5 0.00% -fido_hid_report_out_len 1 1 0.00% 5 5 0.00% -hid_linux.c:copy_info 34 0 100.00% 53 0 100.00% -hid_linux.c:is_fido 10 2 80.00% 19 2 89.47% -hid_linux.c:get_parent_attr 6 0 100.00% 11 0 100.00% -hid_linux.c:parse_uevent 12 0 100.00% 28 0 100.00% +------------------------------------------------------------------------------------------------------------------- +fido_hid_manifest 35 4 88.57% 41 1 97.56% +fido_hid_open 27 27 0.00% 40 40 0.00% +fido_hid_close 3 3 0.00% 6 6 0.00% +fido_hid_set_sigmask 2 2 0.00% 6 6 0.00% +fido_hid_read 15 15 0.00% 21 21 0.00% +fido_hid_write 12 12 0.00% 17 17 0.00% +fido_hid_report_in_len 1 1 0.00% 4 4 0.00% +fido_hid_report_out_len 1 1 0.00% 4 4 0.00% +hid_linux.c:copy_info 34 0 100.00% 44 0 100.00% +hid_linux.c:is_fido 10 2 80.00% 14 2 85.71% +hid_linux.c:get_parent_attr 6 0 100.00% 9 0 100.00% +hid_linux.c:parse_uevent 12 0 100.00% 24 0 100.00% hid_linux.c:get_usb_attr 1 0 100.00% 3 0 100.00% -hid_linux.c:get_report_descriptor 14 1 92.86% 22 3 86.36% ------------------------------------------------------------------------------------------ -TOTAL 173 68 60.69% 303 123 59.41% +hid_linux.c:get_report_descriptor 14 1 92.86% 17 3 82.35% +------------------------------------------------------------------------------------------------------------------- +TOTAL 173 68 60.69% 250 104 58.40% File '/libfido2/src/hid_unix.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ -fido_hid_unix_open 18 11 38.89% 26 14 46.15% -fido_hid_unix_wait 12 9 25.00% 26 14 46.15% ------------------------------------------------------------------------------------------ -TOTAL 30 20 33.33% 52 28 46.15% +------------------------------------------------------------------------------------------------------------------- +fido_hid_unix_open 18 11 38.89% 22 14 36.36% +fido_hid_unix_wait 10 9 10.00% 21 10 52.38% +------------------------------------------------------------------------------------------------------------------- +TOTAL 28 20 28.57% 43 24 44.19% File '/libfido2/src/info.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ -fido_dev_get_cbor_info_wait 10 0 100.00% 9 0 100.00% -fido_dev_get_cbor_info 1 0 100.00% 3 0 100.00% +------------------------------------------------------------------------------------------------------------------- +fido_dev_get_cbor_info_wait 10 0 100.00% 7 0 100.00% +fido_dev_get_cbor_info 1 0 100.00% 4 0 100.00% fido_cbor_info_new 1 0 100.00% 3 0 100.00% fido_cbor_info_reset 1 0 100.00% 8 0 100.00% -fido_cbor_info_free 6 0 100.00% 9 0 100.00% +fido_cbor_info_free 6 0 100.00% 8 0 100.00% fido_cbor_info_versions_ptr 1 0 100.00% 3 0 100.00% fido_cbor_info_versions_len 1 0 100.00% 3 0 100.00% fido_cbor_info_extensions_ptr 1 0 100.00% 3 0 100.00% @@ -549,259 +560,307 @@ fido_cbor_info_fwversion 1 0 100.00% 3 fido_cbor_info_protocols_ptr 1 0 100.00% 3 0 100.00% fido_cbor_info_protocols_len 1 0 100.00% 3 0 100.00% fido_cbor_info_algorithm_count 1 0 100.00% 3 0 100.00% -fido_cbor_info_algorithm_type 4 0 100.00% 6 0 100.00% -fido_cbor_info_algorithm_cose 4 0 100.00% 6 0 100.00% -info.c:fido_dev_get_cbor_info_tx 8 0 100.00% 12 0 100.00% -info.c:fido_dev_get_cbor_info_rx 6 0 100.00% 18 0 100.00% -info.c:parse_reply_element 19 0 100.00% 39 0 100.00% -info.c:decode_string_array 12 0 100.00% 21 0 100.00% -info.c:decode_string 4 0 100.00% 14 0 100.00% -info.c:decode_aaguid 8 0 100.00% 12 0 100.00% -info.c:decode_options 11 0 100.00% 18 0 100.00% -info.c:decode_option 11 0 100.00% 22 0 100.00% -info.c:decode_protocols 12 0 100.00% 21 0 100.00% -info.c:decode_protocol 6 0 100.00% 16 0 100.00% -info.c:decode_algorithms 12 0 100.00% 21 0 100.00% -info.c:decode_algorithm 9 0 100.00% 23 0 100.00% -info.c:decode_algorithm_entry 20 0 100.00% 31 0 100.00% -info.c:free_algo 1 0 100.00% 5 0 100.00% -info.c:free_str_array 4 0 100.00% 8 0 100.00% -info.c:free_opt_array 4 0 100.00% 9 0 100.00% -info.c:free_byte_array 1 0 100.00% 6 0 100.00% -info.c:free_algo_array 4 0 100.00% 8 0 100.00% ------------------------------------------------------------------------------------------ -TOTAL 198 0 100.00% 405 0 100.00% +fido_cbor_info_algorithm_type 4 0 100.00% 5 0 100.00% +fido_cbor_info_algorithm_cose 4 0 100.00% 5 0 100.00% +info.c:fido_dev_get_cbor_info_tx 8 0 100.00% 9 0 100.00% +info.c:fido_dev_get_cbor_info_rx 6 0 100.00% 14 0 100.00% +info.c:parse_reply_element 19 0 100.00% 37 0 100.00% +info.c:decode_string_array 12 0 100.00% 17 0 100.00% +info.c:decode_string 4 0 100.00% 10 0 100.00% +info.c:decode_aaguid 8 0 100.00% 10 0 100.00% +info.c:decode_options 11 0 100.00% 15 0 100.00% +info.c:decode_option 11 0 100.00% 17 0 100.00% +info.c:decode_protocols 12 0 100.00% 17 0 100.00% +info.c:decode_protocol 6 0 100.00% 12 0 100.00% +info.c:decode_algorithms 12 0 100.00% 17 0 100.00% +info.c:decode_algorithm 9 0 100.00% 17 0 100.00% +info.c:decode_algorithm_entry 20 0 100.00% 27 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 184 0 100.00% 316 0 100.00% File '/libfido2/src/io.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ -fido_tx 13 0 100.00% 13 0 100.00% -fido_rx 13 1 92.31% 17 3 82.35% -fido_rx_cbor_status 8 0 100.00% 12 0 100.00% -io.c:tx_empty 9 0 100.00% 17 0 100.00% -io.c:tx 13 0 100.00% 21 0 100.00% -io.c:tx_preamble 16 1 93.75% 24 1 95.83% -io.c:tx_frame 15 1 93.33% 22 1 95.45% -io.c:rx 40 2 95.00% 65 1 98.46% -io.c:rx_preamble 23 2 91.30% 26 5 80.77% -io.c:rx_frame 8 0 100.00% 11 0 100.00% ------------------------------------------------------------------------------------------ -TOTAL 158 7 95.57% 228 11 95.18% +------------------------------------------------------------------------------------------------------------------- +fido_tx 13 0 100.00% 11 0 100.00% +fido_rx 13 1 92.31% 14 3 78.57% +fido_rx_cbor_status 8 0 100.00% 10 0 100.00% +io.c:transport_tx 7 0 100.00% 10 0 100.00% +io.c:tx_empty 9 0 100.00% 14 0 100.00% +io.c:tx_pkt 7 0 100.00% 10 0 100.00% +io.c:tx 13 0 100.00% 19 0 100.00% +io.c:tx_preamble 16 1 93.75% 20 1 95.00% +io.c:tx_frame 15 1 93.33% 18 1 94.44% +io.c:transport_rx 7 0 100.00% 10 0 100.00% +io.c:rx 40 2 95.00% 52 1 98.08% +io.c:rx_preamble 23 2 91.30% 22 5 77.27% +io.c:rx_frame 11 0 100.00% 11 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 182 7 96.15% 221 11 95.02% File '/libfido2/src/iso7816.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ -iso7816_new 4 0 100.00% 18 0 100.00% -iso7816_free 6 0 100.00% 8 0 100.00% -iso7816_add 6 1 83.33% 9 0 100.00% +------------------------------------------------------------------------------------------------------------------- +iso7816_new 4 0 100.00% 16 0 100.00% +iso7816_free 6 0 100.00% 7 0 100.00% +iso7816_add 6 1 83.33% 8 0 100.00% iso7816_ptr 1 0 100.00% 3 0 100.00% iso7816_len 1 0 100.00% 4 0 100.00% ------------------------------------------------------------------------------------------ -TOTAL 18 1 94.44% 42 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 18 1 94.44% 38 0 100.00% File '/libfido2/src/largeblob.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ -fido_dev_largeblob_get 26 2 92.31% 41 4 90.24% -fido_dev_largeblob_set 27 0 100.00% 39 0 100.00% -fido_dev_largeblob_remove 12 0 100.00% 21 0 100.00% -fido_dev_largeblob_get_array 15 2 86.67% 30 4 86.67% -fido_dev_largeblob_set_array 14 0 100.00% 21 0 100.00% -largeblob.c:largeblob_get_array 32 0 100.00% 39 0 100.00% -largeblob.c:get_chunklen 9 1 88.89% 11 0 100.00% -largeblob.c:largeblob_get_tx 19 0 100.00% 28 0 100.00% -largeblob.c:largeblob_get_rx 15 0 100.00% 23 0 100.00% -largeblob.c:parse_largeblob_reply 8 0 100.00% 10 0 100.00% -largeblob.c:largeblob_array_check 7 0 100.00% 18 0 100.00% -largeblob.c:largeblob_array_digest 10 0 100.00% 11 0 100.00% -largeblob.c:largeblob_array_load 14 2 85.71% 21 7 66.67% -largeblob.c:largeblob_array_lookup 25 0 100.00% 36 0 100.00% -largeblob.c:largeblob_decode 16 2 87.50% 17 6 64.71% -largeblob.c:largeblob_do_decode 27 3 88.89% 32 5 84.38% -largeblob.c:largeblob_decrypt 15 0 100.00% 28 0 100.00% -largeblob.c:largeblob_aad 1 0 100.00% 12 0 100.00% +------------------------------------------------------------------------------------------------------------------- +fido_dev_largeblob_get 26 2 92.31% 38 4 89.47% +fido_dev_largeblob_set 27 2 92.59% 36 4 88.89% +fido_dev_largeblob_remove 12 0 100.00% 18 0 100.00% +fido_dev_largeblob_get_array 15 2 86.67% 27 4 85.19% +fido_dev_largeblob_set_array 14 0 100.00% 19 0 100.00% +largeblob.c:largeblob_get_array 32 0 100.00% 36 0 100.00% +largeblob.c:get_chunklen 9 1 88.89% 9 0 100.00% +largeblob.c:largeblob_get_tx 19 0 100.00% 24 0 100.00% +largeblob.c:largeblob_get_rx 15 0 100.00% 21 0 100.00% +largeblob.c:parse_largeblob_reply 8 0 100.00% 9 0 100.00% +largeblob.c:largeblob_array_check 7 0 100.00% 16 0 100.00% +largeblob.c:largeblob_array_digest 10 0 100.00% 9 0 100.00% +largeblob.c:largeblob_array_load 14 2 85.71% 19 7 63.16% +largeblob.c:largeblob_array_lookup 25 0 100.00% 33 0 100.00% +largeblob.c:largeblob_decode 16 2 87.50% 16 6 62.50% +largeblob.c:largeblob_do_decode 27 3 88.89% 30 5 83.33% +largeblob.c:largeblob_decrypt 15 0 100.00% 24 0 100.00% +largeblob.c:largeblob_aad 1 0 100.00% 10 0 100.00% largeblob.c:largeblob_reset 1 0 100.00% 5 0 100.00% -largeblob.c:largeblob_encode 16 0 100.00% 23 0 100.00% +largeblob.c:largeblob_encode 16 0 100.00% 21 0 100.00% largeblob.c:largeblob_new 1 0 100.00% 3 0 100.00% -largeblob.c:largeblob_seal 20 0 100.00% 35 0 100.00% -largeblob.c:largeblob_get_nonce 8 1 87.50% 19 3 84.21% -largeblob.c:largeblob_free 6 0 100.00% 9 0 100.00% -largeblob.c:largeblob_add 27 2 92.59% 40 3 92.50% -largeblob.c:largeblob_drop 21 0 100.00% 30 0 100.00% -largeblob.c:largeblob_set_array 54 2 96.30% 64 4 93.75% -largeblob.c:largeblob_get_uv_token 19 0 100.00% 27 0 100.00% -largeblob.c:largeblob_set_tx 35 0 100.00% 40 0 100.00% -largeblob.c:prepare_hmac 13 2 84.62% 26 7 73.08% ------------------------------------------------------------------------------------------ -TOTAL 513 19 96.30% 759 43 94.33% +largeblob.c:largeblob_seal 20 0 100.00% 32 0 100.00% +largeblob.c:largeblob_get_nonce 8 1 87.50% 16 3 81.25% +largeblob.c:largeblob_free 6 0 100.00% 8 0 100.00% +largeblob.c:largeblob_add 27 2 92.59% 35 3 91.43% +largeblob.c:largeblob_drop 21 0 100.00% 27 0 100.00% +largeblob.c:largeblob_set_array 54 2 96.30% 61 4 93.44% +largeblob.c:largeblob_get_uv_token 19 0 100.00% 23 0 100.00% +largeblob.c:largeblob_set_tx 35 0 100.00% 36 0 100.00% +largeblob.c:prepare_hmac 13 2 84.62% 23 7 69.57% +------------------------------------------------------------------------------------------------------------------- +TOTAL 513 21 95.91% 684 47 93.13% File '/libfido2/src/log.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------- fido_log_init 1 0 100.00% 4 0 100.00% -fido_log_debug 6 1 83.33% 10 0 100.00% -fido_log_xxd 16 1 93.75% 27 0 100.00% -fido_log_error 8 2 75.00% 13 1 92.31% +fido_log_debug 6 1 83.33% 8 0 100.00% +fido_log_xxd 16 1 93.75% 24 0 100.00% +fido_log_error 8 2 75.00% 11 1 90.91% fido_set_log_handler 3 0 100.00% 4 0 100.00% log.c:log_on_stderr 1 1 0.00% 3 3 0.00% -log.c:do_log 4 0 100.00% 12 0 100.00% ------------------------------------------------------------------------------------------ -TOTAL 39 5 87.18% 73 4 94.52% +log.c:do_log 4 0 100.00% 9 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 39 5 87.18% 63 4 93.65% File '/libfido2/src/netlink.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ -fido_nl_power_nfc 18 1 94.44% 26 3 88.46% -fido_nl_get_nfc_target 16 1 93.75% 33 3 90.91% -fido_nl_free 10 2 80.00% 11 1 90.91% -fido_nl_new 16 2 87.50% 29 6 79.31% +------------------------------------------------------------------------------------------------------------------- +fido_nl_power_nfc 18 1 94.44% 24 3 87.50% +fido_nl_get_nfc_target 17 1 94.12% 31 3 90.32% +fido_nl_free 10 2 80.00% 9 1 88.89% +fido_nl_new 16 1 93.75% 26 3 88.46% set_netlink_io_functions 1 0 100.00% 4 0 100.00% -netlink.c:nlmsg_new 8 0 100.00% 18 0 100.00% -netlink.c:nlmsg_set_genl 1 0 100.00% 9 0 100.00% -netlink.c:nlmsg_write 6 1 83.33% 9 1 88.89% +netlink.c:nlmsg_new 8 0 100.00% 15 0 100.00% +netlink.c:nlmsg_set_genl 1 0 100.00% 7 0 100.00% +netlink.c:nlmsg_write 6 1 83.33% 7 1 85.71% netlink.c:nlmsg_set_u32 1 0 100.00% 3 0 100.00% -netlink.c:nlmsg_setattr 14 1 92.86% 21 0 100.00% -netlink.c:nlmsg_tx 10 1 90.00% 15 3 80.00% +netlink.c:nlmsg_setattr 14 1 92.86% 17 0 100.00% +netlink.c:nlmsg_tx 10 1 90.00% 13 3 76.92% netlink.c:nlmsg_ptr 1 0 100.00% 3 0 100.00% netlink.c:nlmsg_len 1 0 100.00% 3 0 100.00% -netlink.c:nlmsg_rx 11 3 72.73% 19 9 52.63% -netlink.c:nl_parse_reply 20 0 100.00% 30 0 100.00% -netlink.c:nlmsg_from_buf 15 0 100.00% 22 0 100.00% +netlink.c:nlmsg_rx 11 3 72.73% 17 9 47.06% +netlink.c:nl_parse_reply 20 0 100.00% 28 0 100.00% +netlink.c:nlmsg_from_buf 15 0 100.00% 17 0 100.00% netlink.c:nlmsg_type 1 0 100.00% 3 0 100.00% -netlink.c:nlmsg_get_status 8 0 100.00% 10 0 100.00% -netlink.c:nlmsg_read 6 0 100.00% 9 0 100.00% -netlink.c:nlmsg_get_genl 6 0 100.00% 10 0 100.00% -netlink.c:nlmsg_iter 6 0 100.00% 15 0 100.00% +netlink.c:nlmsg_get_status 8 0 100.00% 8 0 100.00% +netlink.c:nlmsg_read 6 0 100.00% 7 0 100.00% +netlink.c:nlmsg_get_genl 6 0 100.00% 7 0 100.00% +netlink.c:nlmsg_iter 6 0 100.00% 13 0 100.00% netlink.c:nlmsg_getattr 1 0 100.00% 3 0 100.00% -netlink.c:nla_from_buf 17 0 100.00% 26 0 100.00% -netlink.c:nl_nfc_poll 18 1 94.44% 27 3 88.89% -netlink.c:parse_nfc_event 10 0 100.00% 19 0 100.00% +netlink.c:nla_from_buf 17 0 100.00% 21 0 100.00% +netlink.c:nl_nfc_poll 18 1 94.44% 25 3 88.00% +netlink.c:parse_nfc_event 10 0 100.00% 17 0 100.00% netlink.c:nla_type 1 0 100.00% 3 0 100.00% netlink.c:nla_get_u32 1 0 100.00% 3 0 100.00% -netlink.c:nla_read 6 0 100.00% 9 0 100.00% -netlink.c:nl_dump_nfc_target 19 1 94.74% 33 3 90.91% -netlink.c:parse_target 9 0 100.00% 15 0 100.00% -netlink.c:nl_get_nfc_family 23 1 95.65% 35 3 91.43% +netlink.c:nla_read 6 0 100.00% 7 0 100.00% +netlink.c:nl_dump_nfc_target 19 1 94.74% 31 3 90.32% +netlink.c:parse_target 9 0 100.00% 13 0 100.00% +netlink.c:nl_get_nfc_family 23 1 95.65% 33 3 90.91% netlink.c:nlmsg_set_u16 1 0 100.00% 3 0 100.00% netlink.c:nlmsg_set_str 1 0 100.00% 3 0 100.00% -netlink.c:parse_family 10 0 100.00% 20 0 100.00% +netlink.c:parse_family 10 0 100.00% 17 0 100.00% netlink.c:nla_get_u16 1 0 100.00% 3 0 100.00% -netlink.c:nla_iter 6 0 100.00% 15 0 100.00% +netlink.c:nla_iter 6 0 100.00% 13 0 100.00% netlink.c:nla_getattr 1 0 100.00% 3 0 100.00% netlink.c:parse_mcastgrps 1 0 100.00% 3 0 100.00% -netlink.c:parse_mcastgrp 15 0 100.00% 27 0 100.00% -netlink.c:nla_get_str 10 0 100.00% 13 0 100.00% ------------------------------------------------------------------------------------------ -TOTAL 327 15 95.41% 565 35 93.81% +netlink.c:parse_mcastgrp 15 0 100.00% 24 0 100.00% +netlink.c:nla_get_str 10 0 100.00% 11 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 328 14 95.73% 498 32 93.57% File '/libfido2/src/nfc_linux.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------ -fido_nfc_tx 28 0 100.00% 48 0 100.00% +------------------------------------------------------------------------------------------------------------------- +fido_nfc_tx 28 0 100.00% 43 0 100.00% fido_nfc_rx 8 1 87.50% 13 3 76.92% -fido_nfc_manifest 35 2 94.29% 54 0 100.00% -fido_nfc_open 14 14 0.00% 21 21 0.00% -fido_nfc_close 1 1 0.00% 5 5 0.00% -fido_nfc_set_sigmask 2 2 0.00% 8 8 0.00% -fido_nfc_read 14 14 0.00% 34 34 0.00% -fido_nfc_write 12 12 0.00% 21 21 0.00% -nfc_linux.c:nfc_do_tx 20 2 90.00% 30 6 80.00% -nfc_linux.c:tx_short_apdu 14 0 100.00% 37 0 100.00% -nfc_linux.c:rx_init 25 6 76.00% 34 5 85.29% -nfc_linux.c:rx_cbor 4 0 100.00% 8 0 100.00% -nfc_linux.c:rx_msg 18 2 88.89% 28 6 78.57% -nfc_linux.c:rx_apdu 8 1 87.50% 22 3 86.36% -nfc_linux.c:tx_get_response 4 0 100.00% 14 0 100.00% -nfc_linux.c:copy_info 30 6 80.00% 42 0 100.00% +fido_nfc_manifest 35 5 85.71% 45 13 71.11% +fido_nfc_open 20 3 85.00% 23 5 78.26% +fido_nfc_close 1 1 0.00% 4 4 0.00% +fido_nfc_set_sigmask 2 2 0.00% 6 6 0.00% +fido_nfc_read 14 14 0.00% 30 30 0.00% +fido_nfc_write 12 12 0.00% 18 18 0.00% +nfc_linux.c:nfc_do_tx 20 2 90.00% 25 6 76.00% +nfc_linux.c:tx_short_apdu 14 0 100.00% 32 0 100.00% +nfc_linux.c:rx_init 25 6 76.00% 27 5 81.48% +nfc_linux.c:rx_cbor 4 0 100.00% 6 0 100.00% +nfc_linux.c:rx_msg 18 2 88.89% 23 6 73.91% +nfc_linux.c:rx_apdu 14 1 92.86% 22 3 86.36% +nfc_linux.c:tx_get_response 4 0 100.00% 11 0 100.00% +nfc_linux.c:copy_info 41 9 78.05% 44 3 93.18% nfc_linux.c:get_usb_attr 1 0 100.00% 3 0 100.00% -nfc_linux.c:get_parent_attr 6 0 100.00% 11 0 100.00% -nfc_linux.c:to_int 21 21 0.00% 16 16 0.00% -nfc_linux.c:sysnum_from_syspath 12 12 0.00% 20 20 0.00% -nfc_linux.c:nfc_new 6 6 0.00% 14 14 0.00% -nfc_linux.c:nfc_target_connect 9 9 0.00% 24 24 0.00% -nfc_linux.c:nfc_free 12 12 0.00% 13 13 0.00% ------------------------------------------------------------------------------------------ -TOTAL 304 123 59.54% 520 199 61.73% +nfc_linux.c:get_parent_attr 6 0 100.00% 9 0 100.00% +nfc_linux.c:to_int 21 6 71.43% 14 1 92.86% +nfc_linux.c:sysnum_from_syspath 12 0 100.00% 17 0 100.00% +nfc_linux.c:nfc_new 6 0 100.00% 11 0 100.00% +nfc_linux.c:nfc_target_connect 9 9 0.00% 21 21 0.00% +nfc_linux.c:nfc_free 12 0 100.00% 11 0 100.00% +------------------------------------------------------------------------------------------------------------------- +TOTAL 327 73 77.68% 458 124 72.93% File '/libfido2/src/pin.c': Name Regions Miss Cover Lines Miss Cover -------------------------------------------------------------------------------------------- -fido_sha256 7 0 100.00% 13 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +fido_sha256 7 0 100.00% 10 0 100.00% fido_dev_get_uv_token 1 0 100.00% 3 0 100.00% -fido_dev_set_pin 1 0 100.00% 3 0 100.00% -fido_dev_get_retry_count 1 0 100.00% 3 0 100.00% -fido_dev_get_uv_retry_count 1 0 100.00% 3 0 100.00% -cbor_add_uv_params 17 0 100.00% 28 0 100.00% -pin.c:uv_token_wait 14 2 85.71% 14 0 100.00% -pin.c:ctap21_uv_token_tx 49 0 100.00% 59 0 100.00% -pin.c:pin_sha256_enc 19 0 100.00% 30 0 100.00% +fido_dev_set_pin 1 0 100.00% 4 0 100.00% +fido_dev_get_retry_count 1 0 100.00% 4 0 100.00% +fido_dev_get_uv_retry_count 1 0 100.00% 4 0 100.00% +cbor_add_uv_params 17 0 100.00% 23 0 100.00% +pin.c:uv_token_wait 14 2 85.71% 12 0 100.00% +pin.c:ctap21_uv_token_tx 49 0 100.00% 53 0 100.00% +pin.c:pin_sha256_enc 19 0 100.00% 24 0 100.00% pin.c:encode_uv_permission 20 1 95.00% 19 3 84.21% -pin.c:ctap20_uv_token_tx 37 0 100.00% 53 0 100.00% -pin.c:uv_token_rx 20 0 100.00% 36 0 100.00% -pin.c:parse_uv_token 8 0 100.00% 12 0 100.00% -pin.c:fido_dev_set_pin_wait 21 0 100.00% 27 0 100.00% -pin.c:fido_dev_change_pin_tx 45 0 100.00% 68 0 100.00% -pin.c:pin_pad64_enc 15 0 100.00% 26 0 100.00% -pin.c:pad64 18 0 100.00% 24 0 100.00% -pin.c:fido_dev_set_pin_tx 33 0 100.00% 48 0 100.00% -pin.c:fido_dev_get_pin_retry_count_wait 10 0 100.00% 9 0 100.00% -pin.c:fido_dev_get_retry_count_tx 19 0 100.00% 28 0 100.00% -pin.c:fido_dev_get_pin_retry_count_rx 11 0 100.00% 21 0 100.00% +pin.c:ctap20_uv_token_tx 37 0 100.00% 45 0 100.00% +pin.c:uv_token_rx 20 0 100.00% 30 0 100.00% +pin.c:parse_uv_token 8 0 100.00% 10 0 100.00% +pin.c:fido_dev_set_pin_wait 21 0 100.00% 24 0 100.00% +pin.c:fido_dev_change_pin_tx 45 0 100.00% 56 0 100.00% +pin.c:pin_pad64_enc 15 0 100.00% 21 0 100.00% +pin.c:pad64 18 0 100.00% 19 0 100.00% +pin.c:fido_dev_set_pin_tx 33 0 100.00% 41 0 100.00% +pin.c:fido_dev_get_pin_retry_count_wait 10 0 100.00% 7 0 100.00% +pin.c:fido_dev_get_retry_count_tx 19 0 100.00% 23 0 100.00% +pin.c:fido_dev_get_pin_retry_count_rx 11 0 100.00% 17 0 100.00% pin.c:parse_pin_retry_count 1 0 100.00% 3 0 100.00% -pin.c:parse_retry_count 13 0 100.00% 20 0 100.00% -pin.c:fido_dev_get_uv_retry_count_wait 10 0 100.00% 9 0 100.00% -pin.c:fido_dev_get_uv_retry_count_rx 11 0 100.00% 21 0 100.00% +pin.c:parse_retry_count 13 0 100.00% 16 0 100.00% +pin.c:fido_dev_get_uv_retry_count_wait 10 0 100.00% 7 0 100.00% +pin.c:fido_dev_get_uv_retry_count_rx 11 0 100.00% 17 0 100.00% pin.c:parse_uv_retry_count 1 0 100.00% 3 0 100.00% -------------------------------------------------------------------------------------------- -TOTAL 403 3 99.26% 583 3 99.49% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 403 3 99.26% 495 3 99.39% File '/libfido2/src/random.c': Name Regions Miss Cover Lines Miss Cover -------------------------------------------------------------------------------------------- -fido_get_random 6 1 83.33% 8 1 87.50% -------------------------------------------------------------------------------------------- -TOTAL 6 1 83.33% 8 1 87.50% +--------------------------------------------------------------------------------------------------------------------- +fido_get_random 6 1 83.33% 6 1 83.33% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 6 1 83.33% 6 1 83.33% File '/libfido2/src/reset.c': Name Regions Miss Cover Lines Miss Cover -------------------------------------------------------------------------------------------- -fido_dev_reset 1 0 100.00% 3 0 100.00% -reset.c:fido_dev_reset_wait 15 0 100.00% 14 0 100.00% -reset.c:fido_dev_reset_tx 8 0 100.00% 10 0 100.00% -------------------------------------------------------------------------------------------- -TOTAL 24 0 100.00% 27 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +fido_dev_reset 1 0 100.00% 4 0 100.00% +reset.c:fido_dev_reset_wait 15 0 100.00% 11 0 100.00% +reset.c:fido_dev_reset_tx 8 0 100.00% 8 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 24 0 100.00% 23 0 100.00% + +File '/libfido2/src/rs1.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +rs1_verify_sig 20 1 95.00% 30 3 90.00% +rs1.c:rs1_get_EVP_MD 4 0 100.00% 6 0 100.00% +rs1.c:rs1_free_EVP_MD 1 0 100.00% 3 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 25 1 96.00% 39 3 92.31% File '/libfido2/src/rs256.c': Name Regions Miss Cover Lines Miss Cover -------------------------------------------------------------------------------------------- -rs256_pk_decode 8 0 100.00% 10 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +rs256_pk_decode 8 0 100.00% 9 0 100.00% rs256_pk_new 1 0 100.00% 3 0 100.00% -rs256_pk_free 6 0 100.00% 9 0 100.00% -rs256_pk_from_ptr 6 0 100.00% 8 0 100.00% -rs256_pk_to_EVP_PKEY 32 0 100.00% 48 0 100.00% -rs256_pk_from_RSA 32 4 87.50% 32 6 81.25% -rs256.c:decode_rsa_pubkey 9 0 100.00% 16 0 100.00% -rs256.c:decode_bignum 8 0 100.00% 12 0 100.00% -------------------------------------------------------------------------------------------- -TOTAL 102 4 96.08% 138 6 95.65% +rs256_pk_free 6 0 100.00% 7 0 100.00% +rs256_pk_from_ptr 6 0 100.00% 6 0 100.00% +rs256_pk_to_EVP_PKEY 32 0 100.00% 39 0 100.00% +rs256_pk_from_RSA 32 4 87.50% 26 6 76.92% +rs256_pk_from_EVP_PKEY 7 2 71.43% 7 0 100.00% +rs256_verify_sig 20 1 95.00% 30 2 93.33% +rs256_pk_verify_sig 7 1 85.71% 13 2 84.62% +rs256.c:decode_rsa_pubkey 9 0 100.00% 13 0 100.00% +rs256.c:decode_bignum 8 0 100.00% 10 0 100.00% +rs256.c:rs256_get_EVP_MD 4 0 100.00% 6 0 100.00% +rs256.c:rs256_free_EVP_MD 1 0 100.00% 3 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 141 8 94.33% 172 10 94.19% + +File '/libfido2/src/time.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_time_now 4 0 100.00% 7 0 100.00% +fido_time_delta 23 1 95.65% 23 0 100.00% +time.c:timespec_to_ms 16 2 87.50% 13 1 92.31% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 43 3 93.02% 43 1 97.67% + +File '/libfido2/src/tpm.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_get_signed_hash_tpm 20 0 100.00% 25 0 100.00% +tpm.c:check_rsa2048_pubarea 16 0 100.00% 28 0 100.00% +tpm.c:bswap_rsa2048_pubarea 1 0 100.00% 10 0 100.00% +tpm.c:check_sha1_certinfo 14 0 100.00% 38 0 100.00% +tpm.c:get_signed_sha1 17 0 100.00% 19 0 100.00% +tpm.c:get_signed_name 7 0 100.00% 10 0 100.00% +tpm.c:bswap_sha1_certinfo 1 0 100.00% 8 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 76 0 100.00% 138 0 100.00% + +File '/libfido2/src/types.c': +Name Regions Miss Cover Lines Miss Cover +--------------------------------------------------------------------------------------------------------------------- +fido_str_array_free 4 0 100.00% 7 0 100.00% +fido_opt_array_free 4 0 100.00% 8 0 100.00% +fido_byte_array_free 1 0 100.00% 5 0 100.00% +fido_algo_free 1 0 100.00% 5 0 100.00% +fido_algo_array_free 4 0 100.00% 7 0 100.00% +fido_str_array_pack 11 0 100.00% 14 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 25 0 100.00% 46 0 100.00% File '/libfido2/src/u2f.c': Name Regions Miss Cover Lines Miss Cover -------------------------------------------------------------------------------------------- -u2f_register 70 1 98.57% 88 0 100.00% -u2f_authenticate 32 0 100.00% 44 0 100.00% -u2f_get_touch_begin 30 0 100.00% 46 0 100.00% -u2f_get_touch_status 18 0 100.00% 29 0 100.00% -u2f.c:key_lookup 44 0 100.00% 69 0 100.00% -u2f.c:send_dummy_register 31 1 96.77% 49 0 100.00% -u2f.c:parse_register_reply 49 0 100.00% 71 0 100.00% -u2f.c:x5c_get 21 1 95.24% 34 3 91.18% -u2f.c:sig_get 6 0 100.00% 11 0 100.00% -u2f.c:encode_cred_authdata 33 2 93.94% 76 6 92.11% -u2f.c:cbor_blob_from_ec_point 22 0 100.00% 39 0 100.00% -u2f.c:u2f_authenticate_single 32 0 100.00% 52 0 100.00% -u2f.c:do_auth 50 1 98.00% 71 0 100.00% -u2f.c:parse_auth_reply 23 0 100.00% 29 0 100.00% -u2f.c:authdata_fake 12 0 100.00% 34 0 100.00% -------------------------------------------------------------------------------------------- -TOTAL 473 6 98.73% 742 9 98.79% +--------------------------------------------------------------------------------------------------------------------- +u2f_register 69 0 100.00% 75 0 100.00% +u2f_authenticate 32 0 100.00% 36 0 100.00% +u2f_get_touch_begin 30 0 100.00% 39 0 100.00% +u2f_get_touch_status 18 0 100.00% 26 0 100.00% +u2f.c:key_lookup 44 0 100.00% 59 0 100.00% +u2f.c:send_dummy_register 30 0 100.00% 39 0 100.00% +u2f.c:delay_ms 13 1 92.31% 15 3 80.00% +u2f.c:parse_register_reply 49 0 100.00% 62 0 100.00% +u2f.c:x5c_get 21 1 95.24% 26 3 88.46% +u2f.c:sig_get 6 0 100.00% 10 0 100.00% +u2f.c:encode_cred_attstmt 45 0 100.00% 52 0 100.00% +u2f.c:encode_cred_authdata 33 2 93.94% 61 6 90.16% +u2f.c:cbor_blob_from_ec_point 22 0 100.00% 31 0 100.00% +u2f.c:u2f_authenticate_single 32 0 100.00% 43 0 100.00% +u2f.c:do_auth 49 0 100.00% 61 0 100.00% +u2f.c:parse_auth_reply 23 0 100.00% 23 0 100.00% +u2f.c:authdata_fake 12 0 100.00% 27 0 100.00% +--------------------------------------------------------------------------------------------------------------------- +TOTAL 528 4 99.24% 685 12 98.25% diff --git a/contrib/libfido2/fuzz/fuzz_assert.c b/contrib/libfido2/fuzz/fuzz_assert.c index 1ecbde38bd0a..4331148b5e06 100644 --- a/contrib/libfido2/fuzz/fuzz_assert.c +++ b/contrib/libfido2/fuzz/fuzz_assert.c @@ -255,6 +255,7 @@ verify_assert(int type, const unsigned char *cdh_ptr, size_t cdh_len, int ext, void *pk) { fido_assert_t *assert = NULL; + int r; if ((assert = fido_assert_new()) == NULL) return; @@ -285,33 +286,52 @@ verify_assert(int type, const unsigned char *cdh_ptr, size_t cdh_len, } fido_assert_set_sig(assert, 0, sig_ptr, sig_len); - assert(fido_assert_verify(assert, 0, type, pk) != FIDO_OK); + r = fido_assert_verify(assert, 0, type, pk); + consume(&r, sizeof(r)); fido_assert_free(&assert); } /* - * Do a dummy conversion to exercise rs256_pk_from_RSA(). + * Do a dummy conversion to exercise es256_pk_from_EVP_PKEY(). + */ +static void +es256_convert(const es256_pk_t *k) +{ + EVP_PKEY *pkey = NULL; + es256_pk_t *pk = NULL; + int r; + + if ((pkey = es256_pk_to_EVP_PKEY(k)) == NULL || + (pk = es256_pk_new()) == NULL) + goto out; + + r = es256_pk_from_EVP_PKEY(pk, pkey); + consume(&r, sizeof(r)); +out: + es256_pk_free(&pk); + EVP_PKEY_free(pkey); +} + +/* + * Do a dummy conversion to exercise rs256_pk_from_EVP_PKEY(). */ static void rs256_convert(const rs256_pk_t *k) { EVP_PKEY *pkey = NULL; rs256_pk_t *pk = NULL; - RSA *rsa = NULL; - volatile int r; + int r; if ((pkey = rs256_pk_to_EVP_PKEY(k)) == NULL || - (pk = rs256_pk_new()) == NULL || - (rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) + (pk = rs256_pk_new()) == NULL) goto out; - r = rs256_pk_from_RSA(pk, rsa); + r = rs256_pk_from_EVP_PKEY(pk, pkey); + consume(&r, sizeof(r)); out: - if (pk) - rs256_pk_free(&pk); - if (pkey) - EVP_PKEY_free(pkey); + rs256_pk_free(&pk); + EVP_PKEY_free(pkey); } /* @@ -322,13 +342,14 @@ eddsa_convert(const eddsa_pk_t *k) { EVP_PKEY *pkey = NULL; eddsa_pk_t *pk = NULL; - volatile int r; + int r; if ((pkey = eddsa_pk_to_EVP_PKEY(k)) == NULL || (pk = eddsa_pk_new()) == NULL) goto out; r = eddsa_pk_from_EVP_PKEY(pk, pkey); + consume(&r, sizeof(r)); out: if (pk) eddsa_pk_free(&pk); @@ -349,6 +370,7 @@ test(const struct param *p) void *pk; prng_init((unsigned int)p->seed); + fuzz_clock_reset(); fido_init(FIDO_DEBUG); fido_set_log_handler(consume_str); @@ -362,6 +384,8 @@ test(const struct param *p) es256_pk_from_ptr(es256_pk, p->es256.body, p->es256.len); pk = es256_pk; + es256_convert(pk); + break; case 1: cose_alg = COSE_RS256; diff --git a/contrib/libfido2/fuzz/fuzz_bio.c b/contrib/libfido2/fuzz/fuzz_bio.c index ed3deec93693..49a50932a543 100644 --- a/contrib/libfido2/fuzz/fuzz_bio.c +++ b/contrib/libfido2/fuzz/fuzz_bio.c @@ -408,6 +408,7 @@ void test(const struct param *p) { prng_init((unsigned int)p->seed); + fuzz_clock_reset(); fido_init(FIDO_DEBUG); fido_set_log_handler(consume_str); diff --git a/contrib/libfido2/fuzz/fuzz_cred.c b/contrib/libfido2/fuzz/fuzz_cred.c index 004852d3451a..d7b630224054 100644 --- a/contrib/libfido2/fuzz/fuzz_cred.c +++ b/contrib/libfido2/fuzz/fuzz_cred.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Yubico AB. All rights reserved. + * Copyright (c) 2019-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -231,12 +231,15 @@ make_cred(fido_cred_t *cred, uint8_t opt, int type, const struct blob *cdh, fido_cred_set_rp(cred, rp_id, rp_name); fido_cred_set_user(cred, user_id->body, user_id->len, user_name, user_nick, user_icon); + if (ext & FIDO_EXT_HMAC_SECRET) fido_cred_set_extensions(cred, FIDO_EXT_HMAC_SECRET); if (ext & FIDO_EXT_CRED_BLOB) fido_cred_set_blob(cred, user_id->body, user_id->len); if (ext & FIDO_EXT_LARGEBLOB_KEY) fido_cred_set_extensions(cred, FIDO_EXT_LARGEBLOB_KEY); + if (ext & FIDO_EXT_MINPINLEN) + fido_cred_set_pin_minlen(cred, strlen(pin)); if (rk & 1) fido_cred_set_rk(cred, FIDO_OPT_TRUE); @@ -268,11 +271,13 @@ verify_cred(int type, const unsigned char *cdh_ptr, size_t cdh_len, size_t authdata_len, const unsigned char *authdata_raw_ptr, size_t authdata_raw_len, int ext, uint8_t rk, uint8_t uv, const unsigned char *x5c_ptr, size_t x5c_len, const unsigned char *sig_ptr, - size_t sig_len, const char *fmt, int prot) + size_t sig_len, const unsigned char *attstmt_ptr, size_t attstmt_len, + const char *fmt, int prot, size_t minpinlen) { fido_cred_t *cred; uint8_t flags; uint32_t sigcount; + int r; if ((cred = fido_cred_new()) == NULL) return; @@ -282,13 +287,19 @@ verify_cred(int type, const unsigned char *cdh_ptr, size_t cdh_len, fido_cred_set_rp(cred, rp_id, rp_name); consume(authdata_ptr, authdata_len); consume(authdata_raw_ptr, authdata_raw_len); + consume(x5c_ptr, x5c_len); + consume(sig_ptr, sig_len); + consume(attstmt_ptr, attstmt_len); if (fido_cred_set_authdata(cred, authdata_ptr, authdata_len) != FIDO_OK) fido_cred_set_authdata_raw(cred, authdata_raw_ptr, authdata_raw_len); fido_cred_set_extensions(cred, ext); - fido_cred_set_x509(cred, x5c_ptr, x5c_len); - fido_cred_set_sig(cred, sig_ptr, sig_len); + if (fido_cred_set_attstmt(cred, attstmt_ptr, attstmt_len) != FIDO_OK) { + fido_cred_set_x509(cred, x5c_ptr, x5c_len); + fido_cred_set_sig(cred, sig_ptr, sig_len); + } fido_cred_set_prot(cred, prot); + fido_cred_set_pin_minlen(cred, minpinlen); if (rk & 1) fido_cred_set_rk(cred, FIDO_OPT_TRUE); @@ -299,12 +310,19 @@ verify_cred(int type, const unsigned char *cdh_ptr, size_t cdh_len, /* repeat memory operations to trigger reallocation paths */ if (fido_cred_set_authdata(cred, authdata_ptr, authdata_len) != FIDO_OK) - fido_cred_set_authdata_raw(cred, authdata_ptr, authdata_len); + fido_cred_set_authdata_raw(cred, authdata_raw_ptr, + authdata_raw_len); + if (fido_cred_set_attstmt(cred, attstmt_ptr, attstmt_len) != FIDO_OK) { + fido_cred_set_x509(cred, x5c_ptr, x5c_len); + fido_cred_set_sig(cred, sig_ptr, sig_len); + } fido_cred_set_x509(cred, x5c_ptr, x5c_len); fido_cred_set_sig(cred, sig_ptr, sig_len); - assert(fido_cred_verify(cred) != FIDO_OK); - assert(fido_cred_verify_self(cred) != FIDO_OK); + r = fido_cred_verify(cred); + consume(&r, sizeof(r)); + r = fido_cred_verify_self(cred); + consume(&r, sizeof(r)); consume(fido_cred_pubkey_ptr(cred), fido_cred_pubkey_len(cred)); consume(fido_cred_id_ptr(cred), fido_cred_id_len(cred)); @@ -321,6 +339,8 @@ verify_cred(int type, const unsigned char *cdh_ptr, size_t cdh_len, consume(&sigcount, sizeof(sigcount)); type = fido_cred_type(cred); consume(&type, sizeof(type)); + minpinlen = fido_cred_pin_minlen(cred); + consume(&minpinlen, sizeof(minpinlen)); fido_cred_free(&cred); } @@ -360,7 +380,9 @@ test_cred(const struct param *p) fido_cred_authdata_raw_len(cred), p->ext, p->rk, p->uv, fido_cred_x5c_ptr(cred), fido_cred_x5c_len(cred), fido_cred_sig_ptr(cred), fido_cred_sig_len(cred), - fido_cred_fmt(cred), fido_cred_prot(cred)); + fido_cred_attstmt_ptr(cred), fido_cred_attstmt_len(cred), + fido_cred_fmt(cred), fido_cred_prot(cred), + fido_cred_pin_minlen(cred)); fido_cred_free(&cred); } @@ -408,6 +430,7 @@ void test(const struct param *p) { prng_init((unsigned int)p->seed); + fuzz_clock_reset(); fido_init(FIDO_DEBUG); fido_set_log_handler(consume_str); diff --git a/contrib/libfido2/fuzz/fuzz_credman.c b/contrib/libfido2/fuzz/fuzz_credman.c index 89a37379d87f..fb34f22f8147 100644 --- a/contrib/libfido2/fuzz/fuzz_credman.c +++ b/contrib/libfido2/fuzz/fuzz_credman.c @@ -374,6 +374,7 @@ void test(const struct param *p) { prng_init((unsigned int)p->seed); + fuzz_clock_reset(); fido_init(FIDO_DEBUG); fido_set_log_handler(consume_str); diff --git a/contrib/libfido2/fuzz/fuzz_hid.c b/contrib/libfido2/fuzz/fuzz_hid.c index 6aca7ef5da5b..556e62ac4cd3 100644 --- a/contrib/libfido2/fuzz/fuzz_hid.c +++ b/contrib/libfido2/fuzz/fuzz_hid.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Yubico AB. All rights reserved. + * Copyright (c) 2020-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -12,6 +12,7 @@ #include "../openbsd-compat/openbsd-compat.h" #include "mutator_aux.h" +#include "dummy.h" extern int fido_hid_get_usage(const uint8_t *, size_t, uint32_t *); extern int fido_hid_get_report_len(const uint8_t *, size_t, size_t *, size_t *); @@ -21,6 +22,7 @@ struct param { int seed; char uevent[MAXSTR]; struct blob report_descriptor; + struct blob netlink_wiredata; }; /* @@ -58,13 +60,14 @@ unpack(const uint8_t *ptr, size_t len) cbor.read != len || cbor_isa_array(item) == false || cbor_array_is_definite(item) == false || - cbor_array_size(item) != 3 || + cbor_array_size(item) != 4 || (v = cbor_array_handle(item)) == NULL) goto fail; if (unpack_int(v[0], &p->seed) < 0 || unpack_string(v[1], p->uevent) < 0 || - unpack_blob(v[2], &p->report_descriptor) < 0) + unpack_blob(v[2], &p->report_descriptor) < 0 || + unpack_blob(v[3], &p->netlink_wiredata) < 0) goto fail; ok = 0; @@ -83,19 +86,20 @@ fail: size_t pack(uint8_t *ptr, size_t len, const struct param *p) { - cbor_item_t *argv[3], *array = NULL; + cbor_item_t *argv[4], *array = NULL; size_t cbor_alloc_len, cbor_len = 0; unsigned char *cbor = NULL; memset(argv, 0, sizeof(argv)); - if ((array = cbor_new_definite_array(3)) == NULL || + if ((array = cbor_new_definite_array(4)) == NULL || (argv[0] = pack_int(p->seed)) == NULL || (argv[1] = pack_string(p->uevent)) == NULL || - (argv[2] = pack_blob(&p->report_descriptor)) == NULL) + (argv[2] = pack_blob(&p->report_descriptor)) == NULL || + (argv[3] = pack_blob(&p->netlink_wiredata)) == NULL) goto fail; - for (size_t i = 0; i < 3; i++) + for (size_t i = 0; i < 4; i++) if (cbor_array_push(array, argv[i]) == false) goto fail; @@ -107,7 +111,7 @@ pack(uint8_t *ptr, size_t len, const struct param *p) memcpy(ptr, cbor, cbor_len); fail: - for (size_t i = 0; i < 3; i++) + for (size_t i = 0; i < 4; i++) if (argv[i]) cbor_decref(&argv[i]); @@ -132,6 +136,9 @@ pack_dummy(uint8_t *ptr, size_t len) strlcpy(dummy.uevent, dummy_uevent, sizeof(dummy.uevent)); memcpy(&dummy.report_descriptor.body, &dummy_report_descriptor, dummy.report_descriptor.len); + dummy.netlink_wiredata.len = sizeof(dummy_netlink_wiredata); + memcpy(&dummy.netlink_wiredata.body, &dummy_netlink_wiredata, + dummy.netlink_wiredata.len); assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); if (blob_len > len) @@ -171,7 +178,10 @@ manifest(const struct param *p) fido_dev_info_t *devlist; int16_t vendor_id, product_id; + set_netlink_io_functions(fd_read, fd_write); + set_wire_data(p->netlink_wiredata.body, p->netlink_wiredata.len); set_udev_parameters(p->uevent, &p->report_descriptor); + ndevs = uniform_random(64); if ((devlist = fido_dev_info_new(ndevs)) == NULL || fido_dev_info_manifest(devlist, ndevs, &nfound) != FIDO_OK) @@ -194,6 +204,7 @@ void test(const struct param *p) { prng_init((unsigned int)p->seed); + fuzz_clock_reset(); fido_init(FIDO_DEBUG); fido_set_log_handler(consume_str); @@ -212,4 +223,7 @@ mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN mutate_blob(&p->report_descriptor); mutate_string(p->uevent); } + + if (flags & MUTATE_WIREDATA) + mutate_blob(&p->netlink_wiredata); } diff --git a/contrib/libfido2/fuzz/fuzz_largeblob.c b/contrib/libfido2/fuzz/fuzz_largeblob.c index 6886261bf529..3289ed46e2a7 100644 --- a/contrib/libfido2/fuzz/fuzz_largeblob.c +++ b/contrib/libfido2/fuzz/fuzz_largeblob.c @@ -242,6 +242,7 @@ void test(const struct param *p) { prng_init((unsigned int)p->seed); + fuzz_clock_reset(); fido_init(FIDO_DEBUG); fido_set_log_handler(consume_str); diff --git a/contrib/libfido2/fuzz/fuzz_mgmt.c b/contrib/libfido2/fuzz/fuzz_mgmt.c index 28afbc6aae5f..7c28979fb624 100644 --- a/contrib/libfido2/fuzz/fuzz_mgmt.c +++ b/contrib/libfido2/fuzz/fuzz_mgmt.c @@ -16,6 +16,8 @@ #include "../openbsd-compat/openbsd-compat.h" +#define MAXRPID 64 + struct param { char pin1[MAXSTR]; char pin2[MAXSTR]; @@ -440,10 +442,35 @@ dev_set_pin_minlen(const struct param *p) fido_dev_free(&dev); } +static void +dev_set_pin_minlen_rpid(const struct param *p) +{ + fido_dev_t *dev; + const char *rpid[MAXRPID]; + const char *pin; + size_t n; + int r; + + set_wire_data(p->config_wire_data.body, p->config_wire_data.len); + if ((dev = open_dev(0)) == NULL) + return; + n = uniform_random(MAXRPID); + for (size_t i = 0; i < n; i++) + rpid[i] = dummy_rp_id; + pin = p->pin1; + if (strlen(pin) == 0) + pin = NULL; + r = fido_dev_set_pin_minlen_rpid(dev, rpid, n, pin); + consume_str(fido_strerr(r)); + fido_dev_close(dev); + fido_dev_free(&dev); +} + void test(const struct param *p) { prng_init((unsigned int)p->seed); + fuzz_clock_reset(); fido_init(FIDO_DEBUG); fido_set_log_handler(consume_str); @@ -457,6 +484,7 @@ test(const struct param *p) dev_toggle_always_uv(p); dev_force_pin_change(p); dev_set_pin_minlen(p); + dev_set_pin_minlen_rpid(p); } void diff --git a/contrib/libfido2/fuzz/fuzz_netlink.c b/contrib/libfido2/fuzz/fuzz_netlink.c index 9b7f930cde38..2447215a2471 100644 --- a/contrib/libfido2/fuzz/fuzz_netlink.c +++ b/contrib/libfido2/fuzz/fuzz_netlink.c @@ -12,6 +12,7 @@ #include "../openbsd-compat/openbsd-compat.h" #include "mutator_aux.h" +#include "dummy.h" struct param { int seed; @@ -19,94 +20,6 @@ struct param { struct blob wiredata; }; -/* - * Sample netlink messages. These are unlikely to get the harness very far in - * terms of coverage, but serve to give libFuzzer a sense of the underlying - * structure. - */ -static const uint8_t sample_netlink_wiredata[] = { - 0xd8, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x9d, 0x2e, 0x00, 0x00, - 0x01, 0x02, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x6e, 0x66, 0x63, 0x00, 0x06, 0x00, 0x01, 0x00, - 0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00, - 0x1f, 0x00, 0x00, 0x00, 0x80, 0x01, 0x06, 0x00, - 0x14, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, - 0x08, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x04, 0x00, - 0x08, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x05, 0x00, 0x08, 0x00, 0x01, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x06, 0x00, - 0x08, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x07, 0x00, 0x08, 0x00, 0x01, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x08, 0x00, - 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x09, 0x00, 0x08, 0x00, 0x01, 0x00, - 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0a, 0x00, - 0x08, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x01, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0c, 0x00, - 0x08, 0x00, 0x01, 0x00, 0x15, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x01, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0e, 0x00, - 0x08, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x01, 0x00, - 0x1a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x10, 0x00, - 0x08, 0x00, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x11, 0x00, 0x08, 0x00, 0x01, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, - 0x08, 0x00, 0x01, 0x00, 0x1d, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x13, 0x00, 0x08, 0x00, 0x01, 0x00, - 0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x07, 0x00, - 0x18, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x9d, 0x2e, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, - 0x1e, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x9d, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x05, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x1e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9d, 0x2e, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, - 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x05, 0x00, 0x44, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x06, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x07, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x93, 0xb9, 0x25, 0x00 -}; - struct param * unpack(const uint8_t *ptr, size_t len) { @@ -190,8 +103,8 @@ pack_dummy(uint8_t *ptr, size_t len) memset(&dummy, 0, sizeof(dummy)); - dummy.wiredata.len = sizeof(sample_netlink_wiredata); - memcpy(&dummy.wiredata.body, &sample_netlink_wiredata, + dummy.wiredata.len = sizeof(dummy_netlink_wiredata); + memcpy(&dummy.wiredata.body, &dummy_netlink_wiredata, dummy.wiredata.len); assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); @@ -213,6 +126,7 @@ test(const struct param *p) uint32_t target; prng_init((unsigned int)p->seed); + fuzz_clock_reset(); fido_init(FIDO_DEBUG); fido_set_log_handler(consume_str); diff --git a/contrib/libfido2/fuzz/mutator_aux.c b/contrib/libfido2/fuzz/mutator_aux.c index 0dc3ae1bf054..92a67be78106 100644 --- a/contrib/libfido2/fuzz/mutator_aux.c +++ b/contrib/libfido2/fuzz/mutator_aux.c @@ -37,6 +37,8 @@ consume(const void *body, size_t len) while (len--) x ^= *ptr++; + + (void)x; } void @@ -308,7 +310,8 @@ open_dev(int nfc) goto fail; } - if (fido_dev_open(dev, "nodev") != FIDO_OK) + if (fido_dev_set_timeout(dev, 300) != FIDO_OK || + fido_dev_open(dev, "nodev") != FIDO_OK) goto fail; return dev; diff --git a/contrib/libfido2/fuzz/mutator_aux.h b/contrib/libfido2/fuzz/mutator_aux.h index 6b1a98215b07..a9bebe232bae 100644 --- a/contrib/libfido2/fuzz/mutator_aux.h +++ b/contrib/libfido2/fuzz/mutator_aux.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Yubico AB. All rights reserved. + * Copyright (c) 2019-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -49,7 +49,7 @@ #define MUTATE_ALL (MUTATE_SEED | MUTATE_PARAM | MUTATE_WIREDATA) #define MAXSTR 1024 -#define MAXBLOB 3072 +#define MAXBLOB 3600 struct blob { uint8_t body[MAXBLOB]; @@ -88,6 +88,7 @@ ssize_t fd_write(int, const void *, size_t); fido_dev_t *open_dev(int); void set_wire_data(const uint8_t *, size_t); +void fuzz_clock_reset(void); void prng_init(unsigned long); unsigned long prng_uint32(void); diff --git a/contrib/libfido2/fuzz/report.tgz b/contrib/libfido2/fuzz/report.tgz Binary files differindex c8d4d3f38028..cf74f315cb80 100644 --- a/contrib/libfido2/fuzz/report.tgz +++ b/contrib/libfido2/fuzz/report.tgz diff --git a/contrib/libfido2/fuzz/summary.txt b/contrib/libfido2/fuzz/summary.txt index 8516bf3723aa..298c8377379f 100644 --- a/contrib/libfido2/fuzz/summary.txt +++ b/contrib/libfido2/fuzz/summary.txt @@ -1,51 +1,57 @@ Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -fuzz/prng.c 31 0 100.00% 2 0 100.00% 49 0 100.00% -fuzz/udev.c 103 5 95.15% 17 1 94.12% 141 7 95.04% -fuzz/uniform_random.c 7 1 85.71% 1 0 100.00% 23 1 95.65% +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +fuzz/clock.c 24 1 95.83% 4 0 100.00% 35 0 100.00% +fuzz/prng.c 31 0 100.00% 2 0 100.00% 35 0 100.00% +fuzz/udev.c 103 1 99.03% 17 0 100.00% 126 3 97.62% +fuzz/uniform_random.c 7 1 85.71% 1 0 100.00% 12 1 91.67% fuzz/wrap.c 6 0 100.00% 1 0 100.00% 7 0 100.00% -openbsd-compat/explicit_bzero.c 4 0 100.00% 1 0 100.00% 13 0 100.00% +openbsd-compat/explicit_bzero.c 4 0 100.00% 1 0 100.00% 7 0 100.00% openbsd-compat/freezero.c 4 0 100.00% 1 0 100.00% 6 0 100.00% -openbsd-compat/recallocarray.c 41 7 82.93% 1 0 100.00% 49 7 85.71% -openbsd-compat/strlcat.c 12 1 91.67% 1 0 100.00% 25 1 96.00% -openbsd-compat/timingsafe_bcmp.c 4 0 100.00% 1 0 100.00% 8 0 100.00% -src/aes256.c 115 4 96.52% 8 0 100.00% 175 14 92.00% -src/assert.c 616 46 92.53% 59 3 94.92% 924 64 93.07% -src/authkey.c 44 0 100.00% 5 0 100.00% 75 0 100.00% -src/bio.c 419 20 95.23% 49 2 95.92% 660 22 96.67% -src/blob.c 53 3 94.34% 10 0 100.00% 96 7 92.71% -src/buf.c 8 1 87.50% 2 0 100.00% 20 1 95.00% -src/cbor.c 986 17 98.28% 53 0 100.00% 1426 37 97.41% -src/compress.c 34 4 88.24% 3 0 100.00% 30 3 90.00% -src/config.c 94 1 98.94% 10 0 100.00% 146 3 97.95% -src/cred.c 581 38 93.46% 63 2 96.83% 872 48 94.50% -src/credman.c 382 10 97.38% 40 0 100.00% 614 15 97.56% -src/dev.c 414 74 82.13% 43 6 86.05% 556 106 80.94% -src/ecdh.c 117 2 98.29% 4 0 100.00% 161 5 96.89% -src/eddsa.c 54 0 100.00% 8 0 100.00% 77 0 100.00% +openbsd-compat/recallocarray.c 41 7 82.93% 1 0 100.00% 36 7 80.56% +openbsd-compat/strlcat.c 12 1 91.67% 1 0 100.00% 21 1 95.24% +openbsd-compat/timingsafe_bcmp.c 4 0 100.00% 1 0 100.00% 7 0 100.00% +src/aes256.c 115 4 96.52% 8 0 100.00% 157 14 91.08% +src/assert.c 563 40 92.90% 56 3 94.64% 694 40 94.24% +src/authkey.c 44 0 100.00% 5 0 100.00% 59 0 100.00% +src/bio.c 419 20 95.23% 49 2 95.92% 559 21 96.24% +src/blob.c 53 2 96.23% 10 0 100.00% 83 4 95.18% +src/buf.c 8 1 87.50% 2 0 100.00% 16 1 93.75% +src/cbor.c 1047 28 97.33% 54 0 100.00% 1237 54 95.63% +src/compress.c 34 4 88.24% 3 0 100.00% 28 3 89.29% +src/config.c 108 0 100.00% 11 0 100.00% 151 0 100.00% +src/cred.c 632 34 94.62% 69 2 97.10% 830 36 95.66% +src/credman.c 382 10 97.38% 40 0 100.00% 518 15 97.10% +src/dev.c 420 78 81.43% 44 6 86.36% 488 102 79.10% +src/ecdh.c 117 2 98.29% 4 0 100.00% 146 5 96.58% +src/eddsa.c 80 3 96.25% 10 0 100.00% 106 8 92.45% src/err.c 122 10 91.80% 1 0 100.00% 126 10 92.06% -src/es256.c 280 0 100.00% 16 0 100.00% 394 0 100.00% -src/hid.c 60 0 100.00% 12 0 100.00% 134 0 100.00% -src/hid_linux.c 173 68 60.69% 14 7 50.00% 303 123 59.41% -src/hid_unix.c 30 20 33.33% 2 0 100.00% 52 28 46.15% -src/info.c 198 0 100.00% 44 0 100.00% 405 0 100.00% -src/io.c 158 7 95.57% 10 0 100.00% 228 11 95.18% -src/iso7816.c 18 1 94.44% 5 0 100.00% 42 0 100.00% -src/largeblob.c 513 19 96.30% 30 0 100.00% 759 43 94.33% -src/log.c 39 5 87.18% 7 1 85.71% 73 4 94.52% -src/netlink.c 327 15 95.41% 40 0 100.00% 565 35 93.81% -src/nfc_linux.c 304 123 59.54% 23 10 56.52% 520 199 61.73% -src/pin.c 403 3 99.26% 26 0 100.00% 583 3 99.49% -src/random.c 6 1 83.33% 1 0 100.00% 8 1 87.50% -src/reset.c 24 0 100.00% 3 0 100.00% 27 0 100.00% -src/rs256.c 102 4 96.08% 8 0 100.00% 138 6 95.65% -src/u2f.c 473 6 98.73% 15 0 100.00% 742 9 98.79% +src/es256.c 306 5 98.37% 19 0 100.00% 358 7 98.04% +src/hid.c 60 0 100.00% 12 0 100.00% 114 0 100.00% +src/hid_linux.c 173 68 60.69% 14 7 50.00% 250 104 58.40% +src/hid_unix.c 28 20 28.57% 2 0 100.00% 43 24 44.19% +src/info.c 184 0 100.00% 39 0 100.00% 316 0 100.00% +src/io.c 182 7 96.15% 13 0 100.00% 221 11 95.02% +src/iso7816.c 18 1 94.44% 5 0 100.00% 38 0 100.00% +src/largeblob.c 513 21 95.91% 30 0 100.00% 684 47 93.13% +src/log.c 39 5 87.18% 7 1 85.71% 63 4 93.65% +src/netlink.c 328 14 95.73% 40 0 100.00% 498 32 93.57% +src/nfc_linux.c 327 73 77.68% 23 5 78.26% 458 124 72.93% +src/pin.c 403 3 99.26% 26 0 100.00% 495 3 99.39% +src/random.c 6 1 83.33% 1 0 100.00% 6 1 83.33% +src/reset.c 24 0 100.00% 3 0 100.00% 23 0 100.00% +src/rs1.c 25 1 96.00% 3 0 100.00% 39 3 92.31% +src/rs256.c 141 8 94.33% 13 0 100.00% 172 10 94.19% +src/time.c 43 3 93.02% 3 0 100.00% 43 1 97.67% +src/tpm.c 76 0 100.00% 7 0 100.00% 138 0 100.00% +src/types.c 25 0 100.00% 6 0 100.00% 46 0 100.00% +src/u2f.c 528 4 99.24% 17 0 100.00% 685 12 98.25% Files which contain no functions: openbsd-compat/openbsd-compat.h 0 0 - 0 0 - 0 0 - +openbsd-compat/time.h 0 0 - 0 0 - 0 0 - src/extern.h 0 0 - 0 0 - 0 0 - src/fido.h 0 0 - 0 0 - 0 0 - src/fido/err.h 0 0 - 0 0 - 0 0 - src/fido/param.h 0 0 - 0 0 - 0 0 - --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -TOTAL 7359 516 92.99% 640 32 95.00% 11252 813 92.77% +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +TOTAL 7809 481 93.84% 679 26 96.17% 10180 708 93.05% diff --git a/contrib/libfido2/fuzz/wrap.c b/contrib/libfido2/fuzz/wrap.c index 5b91a64dbf4b..8d7be6bb6247 100644 --- a/contrib/libfido2/fuzz/wrap.c +++ b/contrib/libfido2/fuzz/wrap.c @@ -4,6 +4,9 @@ * license that can be found in the LICENSE file. */ +#include <sys/types.h> +#include <sys/socket.h> + #include <openssl/bn.h> #include <openssl/evp.h> #include <openssl/sha.h> @@ -50,6 +53,14 @@ WRAP(void *, 1 ) +WRAP(void *, + realloc, + (void *ptr, size_t size), + NULL, + (ptr, size), + 1 +) + WRAP(char *, strdup, (const char *s), @@ -84,32 +95,6 @@ WRAP(EVP_CIPHER_CTX *, ) WRAP(int, - EVP_EncryptInit_ex, - (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, - const unsigned char *key, const unsigned char *iv), - 0, - (ctx, type, impl, key, iv), - 1 -) - -WRAP(int, - EVP_CIPHER_CTX_set_padding, - (EVP_CIPHER_CTX *x, int padding), - 0, - (x, padding), - 1 -) - -WRAP(int, - EVP_EncryptUpdate, - (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, - const unsigned char *in, int inl), - 0, - (ctx, out, outl, in, inl), - 1 -) - -WRAP(int, EVP_CipherInit, (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv, int enc), @@ -118,48 +103,6 @@ WRAP(int, 1 ) -WRAP(int, - EVP_DecryptInit_ex, - (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, - const unsigned char *key, const unsigned char *iv), - 0, - (ctx, type, impl, key, iv), - 1 -) - -WRAP(int, - EVP_DecryptUpdate, - (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, - const unsigned char *in, int inl), - 0, - (ctx, out, outl, in, inl), - 1 -) - -WRAP(int, - SHA256_Init, - (SHA256_CTX *c), - 0, - (c), - 1 -) - -WRAP(int, - SHA256_Update, - (SHA256_CTX *c, const void *data, size_t len), - 0, - (c, data, len), - 1 -) - -WRAP(int, - SHA256_Final, - (unsigned char *md, SHA256_CTX *c), - 0, - (md, c), - 1 -) - WRAP(RSA *, EVP_PKEY_get0_RSA, (EVP_PKEY *pkey), @@ -201,6 +144,30 @@ WRAP(int, 1 ) +WRAP(int, + EVP_DigestInit_ex, + (EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl), + 0, + (ctx, type, impl), + 1 +) + +WRAP(int, + EVP_DigestUpdate, + (EVP_MD_CTX *ctx, const void *data, size_t count), + 0, + (ctx, data, count), + 1 +) + +WRAP(int, + EVP_DigestFinal_ex, + (EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize), + 0, + (ctx, md, isize), + 1 +) + WRAP(BIGNUM *, BN_bin2bn, (const unsigned char *s, int len, BIGNUM *ret), @@ -241,6 +208,14 @@ WRAP(BIGNUM *, 1 ) +WRAP(RSA *, + RSA_new, + (void), + NULL, + (), + 1 +) + WRAP(int, RSA_set0_key, (RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d), @@ -249,6 +224,14 @@ WRAP(int, 1 ) +WRAP(int, + RSA_pkey_ctx_ctrl, + (EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2), + -1, + (ctx, optype, cmd, p1, p2), + 1 +) + WRAP(EC_KEY *, EC_KEY_new_by_curve_name, (int nid), @@ -385,6 +368,30 @@ WRAP(int, 1 ) +WRAP(int, + EVP_PKEY_verify_init, + (EVP_PKEY_CTX *ctx), + 0, + (ctx), + 1 +) + +WRAP(int, + EVP_PKEY_CTX_ctrl, + (EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2), + -1, + (ctx, keytype, optype, cmd, p1, p2), + 1 +) + +WRAP(const EVP_MD *, + EVP_sha1, + (void), + NULL, + (), + 1 +) + WRAP(const EVP_MD *, EVP_sha256, (void), @@ -393,6 +400,22 @@ WRAP(const EVP_MD *, 1 ) +WRAP(const EVP_CIPHER *, + EVP_aes_256_cbc, + (void), + NULL, + (), + 1 +) + +WRAP(const EVP_CIPHER *, + EVP_aes_256_gcm, + (void), + NULL, + (), + 1 +) + WRAP(unsigned char *, HMAC, (const EVP_MD *evp_md, const void *key, int key_len, @@ -437,6 +460,14 @@ WRAP(int, ) WRAP(unsigned char *, + SHA1, + (const unsigned char *d, size_t n, unsigned char *md), + NULL, + (d, n, md), + 1 +) + +WRAP(unsigned char *, SHA256, (const unsigned char *d, size_t n, unsigned char *md), NULL, @@ -501,6 +532,14 @@ WRAP(cbor_item_t *, ) WRAP(cbor_item_t *, + cbor_build_uint16, + (uint16_t value), + NULL, + (value), + 1 +) + +WRAP(cbor_item_t *, cbor_build_uint32, (uint32_t value), NULL, @@ -508,6 +547,14 @@ WRAP(cbor_item_t *, 1 ) +WRAP(cbor_item_t *, + cbor_build_uint64, + (uint64_t value), + NULL, + (value), + 1 +) + WRAP(struct cbor_pair *, cbor_map_handle, (const cbor_item_t *item), @@ -556,6 +603,14 @@ WRAP(cbor_item_t *, 1 ) +WRAP(cbor_item_t *, + cbor_new_definite_bytestring, + (void), + NULL, + (), + 1 +) + WRAP(size_t, cbor_serialize_alloc, (const cbor_item_t *item, cbor_mutable_data *buffer, @@ -567,16 +622,16 @@ WRAP(size_t, WRAP(int, fido_tx, - (fido_dev_t *d, uint8_t cmd, const void *buf, size_t count), + (fido_dev_t *d, uint8_t cmd, const void *buf, size_t count, int *ms), -1, - (d, cmd, buf, count), + (d, cmd, buf, count, ms), 1 ) WRAP(int, - usleep, - (unsigned int usec), + bind, + (int sockfd, const struct sockaddr *addr, socklen_t addrlen), -1, - (usec), + (sockfd, addr, addrlen), 1 ) diff --git a/contrib/libfido2/fuzz/wrapped.sym b/contrib/libfido2/fuzz/wrapped.sym index de4f24ae0355..0e9d34627f86 100644 --- a/contrib/libfido2/fuzz/wrapped.sym +++ b/contrib/libfido2/fuzz/wrapped.sym @@ -1,3 +1,4 @@ +bind BN_bin2bn BN_bn2bin BN_CTX_get @@ -11,31 +12,36 @@ cbor_build_bytestring cbor_build_negint16 cbor_build_negint8 cbor_build_string +cbor_build_uint16 cbor_build_uint32 +cbor_build_uint64 cbor_build_uint8 cbor_load cbor_map_add cbor_map_handle cbor_new_definite_array +cbor_new_definite_bytestring cbor_new_definite_map cbor_serialize_alloc +clock_gettime EC_KEY_get0_group EC_KEY_get0_private_key EC_KEY_new_by_curve_name EC_POINT_get_affine_coordinates_GFp EC_POINT_new +EVP_aes_256_cbc +EVP_aes_256_gcm EVP_Cipher EVP_CIPHER_CTX_ctrl EVP_CIPHER_CTX_new -EVP_CIPHER_CTX_set_padding EVP_CipherInit -EVP_DecryptInit_ex -EVP_DecryptUpdate +EVP_DigestFinal_ex +EVP_DigestInit_ex +EVP_DigestUpdate EVP_DigestVerifyInit -EVP_EncryptInit_ex -EVP_EncryptUpdate EVP_MD_CTX_new EVP_PKEY_assign +EVP_PKEY_CTX_ctrl EVP_PKEY_CTX_new EVP_PKEY_CTX_new_id EVP_PKEY_derive @@ -50,6 +56,8 @@ EVP_PKEY_new EVP_PKEY_new_raw_public_key EVP_PKEY_paramgen EVP_PKEY_paramgen_init +EVP_PKEY_verify_init +EVP_sha1 EVP_sha256 fido_tx HMAC @@ -59,11 +67,12 @@ HMAC_Init_ex HMAC_Update ioctl malloc +realloc +RSA_new +RSA_pkey_ctx_ctrl RSA_set0_key +SHA1 SHA256 -SHA256_Final -SHA256_Init -SHA256_Update strdup udev_device_get_devnode udev_device_get_parent_with_subsystem_devtype diff --git a/contrib/libfido2/man/CMakeLists.txt b/contrib/libfido2/man/CMakeLists.txt index ad9f339e6f9b..3e50c50d37a0 100644 --- a/contrib/libfido2/man/CMakeLists.txt +++ b/contrib/libfido2/man/CMakeLists.txt @@ -48,6 +48,7 @@ list(APPEND MAN_ALIAS eddsa_pk_new eddsa_pk_to_EVP_PKEY es256_pk_new es256_pk_free es256_pk_new es256_pk_from_EC_KEY + es256_pk_new es256_pk_from_EVP_PKEY es256_pk_new es256_pk_from_ptr es256_pk_new es256_pk_to_EVP_PKEY fido_assert_new fido_assert_authdata_len @@ -129,6 +130,10 @@ list(APPEND MAN_ALIAS fido_cbor_info_new fido_cbor_info_versions_len fido_cbor_info_new fido_cbor_info_versions_ptr fido_cbor_info_new fido_dev_get_cbor_info + fido_cred_new fido_cred_aaguid_len + fido_cred_new fido_cred_aaguid_ptr + fido_cred_new fido_cred_attstmt_len + fido_cred_new fido_cred_attstmt_ptr fido_cred_new fido_cred_authdata_len fido_cred_new fido_cred_authdata_ptr fido_cred_new fido_cred_authdata_raw_len @@ -137,26 +142,25 @@ list(APPEND MAN_ALIAS fido_cred_new fido_cred_clientdata_hash_ptr fido_cred_new fido_cred_display_name fido_cred_new fido_cred_flags - fido_cred_new fido_cred_sigcount fido_cred_new fido_cred_fmt fido_cred_new fido_cred_free fido_cred_new fido_cred_id_len fido_cred_new fido_cred_id_ptr - fido_cred_new fido_cred_aaguid_len - fido_cred_new fido_cred_aaguid_ptr fido_cred_new fido_cred_largeblob_key_len fido_cred_new fido_cred_largeblob_key_ptr + fido_cred_new fido_cred_pin_minlen fido_cred_new fido_cred_prot fido_cred_new fido_cred_pubkey_len fido_cred_new fido_cred_pubkey_ptr fido_cred_new fido_cred_rp_id fido_cred_new fido_cred_rp_name + fido_cred_new fido_cred_sigcount fido_cred_new fido_cred_sig_len fido_cred_new fido_cred_sig_ptr fido_cred_new fido_cred_type - fido_cred_new fido_cred_user_name fido_cred_new fido_cred_user_id_len fido_cred_new fido_cred_user_id_ptr + fido_cred_new fido_cred_user_name fido_cred_new fido_cred_x5c_len fido_cred_new fido_cred_x5c_ptr fido_credman_metadata_new fido_credman_del_dev_rk @@ -178,6 +182,7 @@ list(APPEND MAN_ALIAS fido_credman_metadata_new fido_credman_rp_name fido_credman_metadata_new fido_credman_rp_new fido_credman_metadata_new fido_credman_set_dev_rk + fido_cred_set_authdata fido_cred_set_attstmt fido_cred_set_authdata fido_cred_set_authdata_raw fido_cred_set_authdata fido_cred_set_blob fido_cred_set_authdata fido_cred_set_clientdata @@ -185,6 +190,7 @@ list(APPEND MAN_ALIAS fido_cred_set_authdata fido_cred_set_extensions fido_cred_set_authdata fido_cred_set_fmt fido_cred_set_authdata fido_cred_set_id + fido_cred_set_authdata fido_cred_set_pin_minlen fido_cred_set_authdata fido_cred_set_prot fido_cred_set_authdata fido_cred_set_rk fido_cred_set_authdata fido_cred_set_rp @@ -196,6 +202,7 @@ list(APPEND MAN_ALIAS fido_dev_enable_entattest fido_dev_toggle_always_uv fido_dev_enable_entattest fido_dev_force_pin_change fido_dev_enable_entattest fido_dev_set_pin_minlen + fido_dev_enable_entattest fido_dev_set_pin_minlen_rpid fido_dev_get_touch_begin fido_dev_get_touch_status fido_dev_info_manifest fido_dev_info_free fido_dev_info_manifest fido_dev_info_manufacturer_string @@ -227,12 +234,14 @@ list(APPEND MAN_ALIAS fido_dev_set_pin fido_dev_get_uv_retry_count fido_dev_set_pin fido_dev_reset fido_dev_set_io_functions fido_dev_set_sigmask + fido_dev_set_io_functions fido_dev_set_timeout fido_dev_largeblob_get fido_dev_largeblob_set fido_dev_largeblob_get fido_dev_largeblob_remove fido_dev_largeblob_get fido_dev_largeblob_get_array fido_dev_largeblob_get fido_dev_largeblob_set_array rs256_pk_new rs256_pk_free rs256_pk_new rs256_pk_from_ptr + rs256_pk_new rs256_pk_from_EVP_PKEY rs256_pk_new rs256_pk_from_RSA rs256_pk_new rs256_pk_to_EVP_PKEY ) diff --git a/contrib/libfido2/man/es256_pk_new.3 b/contrib/libfido2/man/es256_pk_new.3 index 54439cd300cf..6c1bac0f57f9 100644 --- a/contrib/libfido2/man/es256_pk_new.3 +++ b/contrib/libfido2/man/es256_pk_new.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2018 Yubico AB. All rights reserved. +.\" Copyright (c) 2018-2021 Yubico AB. All rights reserved. .\" Use of this source code is governed by a BSD-style .\" license that can be found in the LICENSE file. .\" @@ -9,6 +9,7 @@ .Nm es256_pk_new , .Nm es256_pk_free , .Nm es256_pk_from_EC_KEY , +.Nm es256_pk_from_EVP_KEY , .Nm es256_pk_from_ptr , .Nm es256_pk_to_EVP_PKEY .Nd FIDO 2 COSE ES256 API @@ -22,6 +23,8 @@ .Ft int .Fn es256_pk_from_EC_KEY "es256_pk_t *pk" "const EC_KEY *ec" .Ft int +.Fn es256_pk_from_EVP_PKEY "es256_pk_t *pk" "const EVP_PKEY *pkey" +.Ft int .Fn es256_pk_from_ptr "es256_pk_t *pk" "const void *ptr" "size_t len" .Ft EVP_PKEY * .Fn es256_pk_to_EVP_PKEY "const es256_pk_t *pk" @@ -79,6 +82,16 @@ No references to are kept. .Pp The +.Fn es256_pk_from_EVP_KEY +function fills +.Fa pk +with the contents of +.Fa pkey . +No references to +.Fa pkey +are kept. +.Pp +The .Fn es256_pk_from_ptr function fills .Fa pk @@ -110,7 +123,8 @@ If an error occurs, returns NULL. .Sh RETURN VALUES The -.Fn es256_pk_from_EC_KEY +.Fn es256_pk_from_EC_KEY , +.Fn es256_pk_from_EVP_KEY , and .Fn es256_pk_from_ptr functions return diff --git a/contrib/libfido2/man/fido2-token.1 b/contrib/libfido2/man/fido2-token.1 index 43f1c0ea48b7..fd82c23cffb7 100644 --- a/contrib/libfido2/man/fido2-token.1 +++ b/contrib/libfido2/man/fido2-token.1 @@ -82,6 +82,7 @@ .Op Fl d .Fl i Ar template_id .Fl n Ar template_name +.Ar device .Nm .Fl S .Op Fl d @@ -112,6 +113,11 @@ .Fl p Ar display_name .Ar device .Nm +.Fl S +.Fl m +.Ar rp_id +.Ar device +.Nm .Fl V .Sh DESCRIPTION .Nm @@ -340,6 +346,12 @@ Sets the minimum PIN length of to .Ar pin_length . The user will be prompted for the PIN. +.It Fl S Fl m Ar rp_id Ar device +Sets the list of relying party IDs that are allowed to retrieve +the minimum PIN length of +.Ar device . +Multiple IDs may be specified, separated by commas. +The user will be prompted for the PIN. .It Fl S Fl u Ar device Enables the FIDO 2.1 .Dq user verification always diff --git a/contrib/libfido2/man/fido_cred_new.3 b/contrib/libfido2/man/fido_cred_new.3 index 8cecf5f29850..d779cb2c659d 100644 --- a/contrib/libfido2/man/fido_cred_new.3 +++ b/contrib/libfido2/man/fido_cred_new.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2018 Yubico AB. All rights reserved. +.\" Copyright (c) 2018-2021 Yubico AB. All rights reserved. .\" Use of this source code is governed by a BSD-style .\" license that can be found in the LICENSE file. .\" @@ -8,6 +8,7 @@ .Sh NAME .Nm fido_cred_new , .Nm fido_cred_free , +.Nm fido_cred_pin_minlen , .Nm fido_cred_prot , .Nm fido_cred_fmt , .Nm fido_cred_rp_id , @@ -24,6 +25,7 @@ .Nm fido_cred_sig_ptr , .Nm fido_cred_user_id_ptr , .Nm fido_cred_x5c_ptr , +.Nm fido_cred_attstmt_ptr , .Nm fido_cred_authdata_len , .Nm fido_cred_authdata_raw_len , .Nm fido_cred_clientdata_hash_len , @@ -34,6 +36,7 @@ .Nm fido_cred_sig_len , .Nm fido_cred_user_id_len , .Nm fido_cred_x5c_len , +.Nm fido_cred_attstmt_len , .Nm fido_cred_type , .Nm fido_cred_flags , .Nm fido_cred_sigcount @@ -44,8 +47,10 @@ .Fn fido_cred_new "void" .Ft void .Fn fido_cred_free "fido_cred_t **cred_p" +.Ft size_t +.Fn fido_cred_pin_minlen "const fido_cred_t *cred" .Ft int -.Fn fido_cred_prot "fido_cred_t *cred" +.Fn fido_cred_prot "const fido_cred_t *cred" .Ft const char * .Fn fido_cred_fmt "const fido_cred_t *cred" .Ft const char * @@ -76,6 +81,8 @@ .Fn fido_cred_user_id_ptr "const fido_cred_t *cred" .Ft const unsigned char * .Fn fido_cred_x5c_ptr "const fido_cred_t *cred" +.Ft const unsigned char * +.Fn fido_cred_attstmt_ptr "const fido_cred_t *cred" .Ft size_t .Fn fido_cred_authdata_len "const fido_cred_t *cred" .Ft size_t @@ -96,6 +103,8 @@ .Fn fido_cred_user_id_len "const fido_cred_t *cred" .Ft size_t .Fn fido_cred_x5c_len "const fido_cred_t *cred" +.Ft size_t +.Fn fido_cred_attstmt_len "const fido_cred_t *cred" .Ft int .Fn fido_cred_type "const fido_cred_t *cred" .Ft uint8_t @@ -146,13 +155,35 @@ may be NULL, in which case .Fn fido_cred_free is a NOP. .Pp -The +If the FIDO 2.1 +.Dv FIDO_EXT_MINPINLEN +extension is enabled on +.Fa cred , +then the +.Fn fido_cred_pin_minlen +function returns the minimum PIN length of +.Fa cred . +Otherwise, +.Fn fido_cred_pin_minlen +returns zero. +See +.Xr fido_cred_set_pin_minlen 3 +on how to enable this extension. +.Pp +If the FIDO 2.1 +.Dv FIDO_EXT_CRED_PROTECT +extension is enabled on +.Fa cred , +then the .Fn fido_cred_prot function returns the protection of .Fa cred . +Otherwise, +.Fn fido_cred_prot +returns zero. See .Xr fido_cred_set_prot 3 -for the values understood by +for the protection policies understood by .Em libfido2 . .Pp The @@ -186,12 +217,14 @@ The .Fn fido_cred_pubkey_ptr , .Fn fido_cred_sig_ptr , .Fn fido_cred_user_id_ptr , +.Fn fido_cred_x5c_ptr , and -.Fn fido_cred_x5c_ptr +.Fn fido_cred_attstmt_ptr functions return pointers to the CBOR-encoded and raw authenticator data, client data hash, ID, authenticator attestation GUID, .Dq largeBlobKey , -public key, signature, user ID, and x509 certificate parts of +public key, signature, user ID, x509 certificate, and attestation +statement parts of .Fa cred , or NULL if the respective entry is not set. .Pp @@ -205,8 +238,9 @@ The corresponding length can be obtained by .Fn fido_cred_pubkey_len , .Fn fido_cred_sig_len , .Fn fido_cred_user_id_len , +.Fn fido_cred_x5c_len , and -.Fn fido_cred_x5c_len . +.Fn fido_cred_attstmt_len . .Pp The authenticator data, x509 certificate, and signature parts of a credential are typically passed to a FIDO 2 server for verification. @@ -251,6 +285,8 @@ qualifier is invoked. .Sh SEE ALSO .Xr fido_cred_exclude 3 , .Xr fido_cred_set_authdata 3 , +.Xr fido_cred_set_pin_minlen 3 , +.Xr fido_cred_set_prot 3 , .Xr fido_cred_verify 3 , .Xr fido_credman_metadata_new 3 , .Xr fido_dev_largeblob_get 3 , diff --git a/contrib/libfido2/man/fido_cred_set_authdata.3 b/contrib/libfido2/man/fido_cred_set_authdata.3 index 91e1edbaf810..7bae51f43674 100644 --- a/contrib/libfido2/man/fido_cred_set_authdata.3 +++ b/contrib/libfido2/man/fido_cred_set_authdata.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2018 Yubico AB. All rights reserved. +.\" Copyright (c) 2018-2021 Yubico AB. All rights reserved. .\" Use of this source code is governed by a BSD-style .\" license that can be found in the LICENSE file. .\" @@ -8,6 +8,7 @@ .Sh NAME .Nm fido_cred_set_authdata , .Nm fido_cred_set_authdata_raw , +.Nm fido_cred_set_attstmt , .Nm fido_cred_set_x509 , .Nm fido_cred_set_sig , .Nm fido_cred_set_id , @@ -17,6 +18,7 @@ .Nm fido_cred_set_user , .Nm fido_cred_set_extensions , .Nm fido_cred_set_blob , +.Nm fido_cred_set_pin_minlen , .Nm fido_cred_set_prot , .Nm fido_cred_set_rk , .Nm fido_cred_set_uv , @@ -37,6 +39,8 @@ typedef enum { .Ft int .Fn fido_cred_set_authdata_raw "fido_cred_t *cred" "const unsigned char *ptr" "size_t len" .Ft int +.Fn fido_cred_set_attstmt "fido_cred_t *cred" "const unsigned char *ptr" "size_t len" +.Ft int .Fn fido_cred_set_x509 "fido_cred_t *cred" "const unsigned char *ptr" "size_t len" .Ft int .Fn fido_cred_set_sig "fido_cred_t *cred" "const unsigned char *ptr" "size_t len" @@ -55,6 +59,8 @@ typedef enum { .Ft int .Fn fido_cred_set_blob "fido_cred_t *cred" "const unsigned char *ptr" "size_t len" .Ft int +.Fn fido_cred_set_pin_minlen "fido_cred_t *cred" "size_t len" +.Ft int .Fn fido_cred_set_prot "fido_cred_t *cred" "int prot" .Ft int .Fn fido_cred_set_rk "fido_cred_t *cred" "fido_opt_t rk" @@ -80,13 +86,15 @@ of its constituent parts, please refer to the Web Authentication .Pp The .Fn fido_cred_set_authdata , +.Fn fido_cred_set_attstmt , .Fn fido_cred_set_x509 , .Fn fido_cred_set_sig , .Fn fido_cred_set_id , and .Fn fido_cred_set_clientdata_hash -functions set the authenticator data, attestation certificate, -signature, id, and client data hash parts of +functions set the authenticator data, attestation statement, +attestation certificate, attestation signature, id, and client +data hash parts of .Fa cred to .Fa ptr , @@ -98,13 +106,13 @@ bytes. A copy of .Fa ptr is made, and no references to the passed pointer are kept. +.Pp The authenticator data passed to .Fn fido_cred_set_authdata must be a CBOR-encoded byte string, as obtained from .Fn fido_cred_authdata_ptr . Alternatively, a raw binary blob may be passed to .Fn fido_cred_set_authdata_raw . -.Pp An application calling .Fn fido_cred_set_authdata does not need to call @@ -112,6 +120,20 @@ does not need to call The latter is meant to be used in contexts where the credential's authenticator data is not available. .Pp +The attestation statement passed to +.Fn fido_cred_set_attstmt +must be a CBOR-encoded map, as obtained from +.Fn fido_cred_attstmt_ptr . +An application calling +.Fn fido_cred_set_attstmt +does not need to call +.Fn fido_cred_set_x509 +or +.Fn fido_cred_set_sig . +The latter two are meant to be used in contexts where the +credential's complete attestation statement is not available or +required. +.Pp The .Fn fido_cred_set_clientdata function allows an application to set the client data hash of @@ -183,6 +205,7 @@ At the moment, only the .Dv FIDO_EXT_CRED_BLOB , .Dv FIDO_EXT_CRED_PROTECT , .Dv FIDO_EXT_HMAC_SECRET , +.Dv FIDO_EXT_MINPINLEN , and .Dv FIDO_EXT_LARGEBLOB_KEY extensions are supported. @@ -205,8 +228,32 @@ which must be bytes long. .Pp The +.Fn fido_cred_set_pin_minlen +function enables the FIDO 2.1 +.Dv FIDO_EXT_MINPINLEN +extension on +.Fa cred +and sets the expected minimum PIN length of +.Fa cred +to +.Fa len , +where +.Fa len +is greater than zero. +If +.Fa len +is zero, the +.Dv FIDO_EXT_MINPINLEN +extension is disabled on +.Fa cred . +.Pp +The .Fn fido_cred_set_prot -function sets the protection of +function enables the FIDO 2.1 +.Dv FIDO_EXT_CRED_PROTECT +extension on +.Fa cred +and sets the protection of .Fa cred to the scalar .Fa prot . diff --git a/contrib/libfido2/man/fido_cred_verify.3 b/contrib/libfido2/man/fido_cred_verify.3 index 6b720f2132ea..ec95e134572e 100644 --- a/contrib/libfido2/man/fido_cred_verify.3 +++ b/contrib/libfido2/man/fido_cred_verify.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2018 Yubico AB. All rights reserved. +.\" Copyright (c) 2018-2021 Yubico AB. All rights reserved. .\" Use of this source code is governed by a BSD-style .\" license that can be found in the LICENSE file. .\" @@ -29,8 +29,8 @@ A brief description follows: The .Fn fido_cred_verify function verifies whether the client data hash, relying party ID, -credential ID, type, and resident/discoverable key and user verification -attributes of +credential ID, type, protection policy, minimum PIN length, and +resident/discoverable key and user verification attributes of .Fa cred have been attested by the holder of the private counterpart of the public key contained in the credential's x509 certificate. @@ -40,14 +40,14 @@ Please note that the x509 certificate itself is not verified. The attestation statement formats supported by .Fn fido_cred_verify are -.Em packed +.Em packed , +.Em fido-u2f , and -.Em fido-u2f . +.Em tpm . The attestation type implemented by .Fn fido_cred_verify is .Em Basic Attestation . -The attestation key pair is assumed to be of the type ES256. Other attestation formats and types are not supported. .Sh RETURN VALUES The error codes returned by diff --git a/contrib/libfido2/man/fido_dev_enable_entattest.3 b/contrib/libfido2/man/fido_dev_enable_entattest.3 index 7cb766d41d0c..17962d3d35d5 100644 --- a/contrib/libfido2/man/fido_dev_enable_entattest.3 +++ b/contrib/libfido2/man/fido_dev_enable_entattest.3 @@ -9,7 +9,8 @@ .Nm fido_dev_enable_entattest , .Nm fido_dev_toggle_always_uv , .Nm fido_dev_force_pin_change , -.Nm fido_dev_set_pin_minlen +.Nm fido_dev_set_pin_minlen , +.Nm fido_dev_set_pin_minlen_rpid .Nd FIDO 2.1 configuration authenticator API .Sh SYNOPSIS .In fido.h @@ -22,6 +23,8 @@ .Fn fido_dev_force_pin_change "fido_dev_t *dev" "const char *pin" .Ft int .Fn fido_dev_set_pin_minlen "fido_dev_t *dev" "size_t len" "const char *pin" +.Ft int +.Fn fido_dev_set_pin_minlen_rpid "fido_dev_t *dev" "const char * const *rpid" "size_t n" "const char *pin" .Sh DESCRIPTION The functions described in this page allow configuration of a FIDO 2.1 authenticator. @@ -77,6 +80,24 @@ to .Fa len . Minimum PIN lengths may only be increased. .Pp +The +.Fn fido_dev_set_pin_minlen_rpid +function sets the list of relying party identifiers +.Pq RP IDs +that are allowed to obtain the minimum PIN length of +.Fa dev +through the FIDO 2.1 +.Dv FIDO_EXT_MINPINLEN +extension. +The list of RP identifiers is denoted by +.Fa rpid , +a vector of +.Fa n +NUL-terminated UTF-8 strings. +A copy of +.Fa rpid +is made, and no reference to it or its contents is kept. +.Pp Configuration settings are reflected in the payload returned by the authenticator in response to a .Xr fido_dev_get_cbor_info 3 @@ -86,13 +107,15 @@ The error codes returned by .Fn fido_dev_enable_entattest , .Fn fido_dev_toggle_always_uv , .Fn fido_dev_force_pin_change , +.Fn fido_dev_set_pin_minlen , and -.Fn fido_dev_set_pin_minlen +.Fn fido_dev_set_pin_minlen_rpid are defined in .In fido/err.h . On success, .Dv FIDO_OK is returned. .Sh SEE ALSO +.Xr fido_cred_pin_minlen 3 , .Xr fido_dev_get_cbor_info 3 , .Xr fido_dev_reset 3 diff --git a/contrib/libfido2/man/fido_dev_info_manifest.3 b/contrib/libfido2/man/fido_dev_info_manifest.3 index 22519e29b9fa..76e399cec319 100644 --- a/contrib/libfido2/man/fido_dev_info_manifest.3 +++ b/contrib/libfido2/man/fido_dev_info_manifest.3 @@ -112,11 +112,21 @@ The .Fn fido_dev_info_manufacturer_string function returns the manufacturer string of .Fa di . +If +.Fa di +does not have an associated manufacturer string, +.Fn fido_dev_info_manufacturer_string +returns an empty string. .Pp The .Fn fido_dev_info_product_string function returns the product string of .Fa di . +If +.Fa di +does not have an associated product string, +.Fn fido_dev_info_product_string +returns an empty string. .Pp An example of how to use the functions described in this document can be found in the diff --git a/contrib/libfido2/man/fido_dev_set_io_functions.3 b/contrib/libfido2/man/fido_dev_set_io_functions.3 index 231ae2411be8..52081f126e78 100644 --- a/contrib/libfido2/man/fido_dev_set_io_functions.3 +++ b/contrib/libfido2/man/fido_dev_set_io_functions.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2018 Yubico AB. All rights reserved. +.\" Copyright (c) 2018-2021 Yubico AB. All rights reserved. .\" Use of this source code is governed by a BSD-style .\" license that can be found in the LICENSE file. .\" @@ -7,7 +7,8 @@ .Os .Sh NAME .Nm fido_dev_set_io_functions , -.Nm fido_dev_set_sigmask +.Nm fido_dev_set_sigmask , +.Nm fido_dev_set_timeout .Nd FIDO 2 device I/O interface .Sh SYNOPSIS .In fido.h @@ -34,6 +35,8 @@ typedef sigset_t fido_sigset_t; .Fn fido_dev_set_io_functions "fido_dev_t *dev" "const fido_dev_io_t *io" .Ft int .Fn fido_dev_set_sigmask "fido_dev_t *dev" "const fido_sigset_t *sigmask" +.Ft int +.Fn fido_dev_set_timeout "fido_dev_t *dev" "int ms" .Sh DESCRIPTION The .Fn fido_dev_set_io_functions @@ -122,11 +125,35 @@ No references to .Fa sigmask are held by .Fn fido_dev_set_sigmask . +.Pp +The +.Fn fido_dev_set_timeout +function informs +.Em libfido2 +not to block for more than +.Fa ms +milliseconds while communicating with +.Fa dev . +If a timeout occurs, the corresponding +.Em fido_dev_* +function will fail with +.Dv FIDO_ERR_RX . +If +.Fa ms +is -1, +then +.Em libfido2 +may block indefinitely. +This is the default behaviour. +When using the Windows Hello backend, +.Fa ms +is used as a guidance and may be overwritten by the platform. .Sh RETURN VALUES On success, -.Fn fido_dev_set_io_functions +.Fn fido_dev_set_io_functions , +.Fn fido_dev_set_sigmask , and -.Fn fido_dev_set_sigmask +.Fn fido_dev_set_timeout return .Dv FIDO_OK . On error, a different error code defined in diff --git a/contrib/libfido2/man/rs256_pk_new.3 b/contrib/libfido2/man/rs256_pk_new.3 index 4ad0ebe936f3..ad33ee66ba7b 100644 --- a/contrib/libfido2/man/rs256_pk_new.3 +++ b/contrib/libfido2/man/rs256_pk_new.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2018 Yubico AB. All rights reserved. +.\" Copyright (c) 2018-2021 Yubico AB. All rights reserved. .\" Use of this source code is governed by a BSD-style .\" license that can be found in the LICENSE file. .\" @@ -8,6 +8,7 @@ .Sh NAME .Nm rs256_pk_new , .Nm rs256_pk_free , +.Nm rs256_pk_from_EVP_PKEY , .Nm rs256_pk_from_RSA , .Nm rs256_pk_from_ptr , .Nm rs256_pk_to_EVP_PKEY @@ -20,6 +21,8 @@ .Ft void .Fn rs256_pk_free "rs256_pk_t **pkp" .Ft int +.Fn rs256_pk_from_EVP_PKEY "rs256_pk_t *pk" "const EVP_PKEY *pkey" +.Ft int .Fn rs256_pk_from_RSA "rs256_pk_t *pk" "const RSA *rsa" .Ft int .Fn rs256_pk_from_ptr "rs256_pk_t *pk" "const void *ptr" "size_t len" @@ -69,6 +72,16 @@ may be NULL, in which case is a NOP. .Pp The +.Fn rs256_pk_from_EVP_PKEY +function fills +.Fa pk +with the contents of +.Fa pkey . +No references to +.Fa pkey +are kept. +.Pp +The .Fn rs256_pk_from_RSA function fills .Fa pk @@ -106,7 +119,8 @@ If an error occurs, returns NULL. .Sh RETURN VALUES The -.Fn rs256_pk_from_RSA +.Fn rs256_pk_from_EVP_PKEY , +.Fn rs256_pk_from_RSA , and .Fn rs256_pk_from_ptr functions return diff --git a/contrib/libfido2/openbsd-compat/hkdf.c b/contrib/libfido2/openbsd-compat/hkdf.c deleted file mode 100644 index 745b420f3747..000000000000 --- a/contrib/libfido2/openbsd-compat/hkdf.c +++ /dev/null @@ -1,124 +0,0 @@ -/* $OpenBSD: hkdf.c,v 1.4 2019/11/21 20:02:20 tim Exp $ */ -/* Copyright (c) 2014, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "openbsd-compat.h" -#include "fido.h" - -#if OPENSSL_VERSION_NUMBER < 0x10100000L - -#include <assert.h> -#include <string.h> - -#include <openssl/err.h> -#include <openssl/hmac.h> - -#define CRYPTOerror(r) CRYPTOerr(ERR_LIB_CRYPTO, (r)) - -/* https://tools.ietf.org/html/rfc5869#section-2 */ -int -HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest, - const uint8_t *secret, size_t secret_len, const uint8_t *salt, - size_t salt_len, const uint8_t *info, size_t info_len) -{ - uint8_t prk[EVP_MAX_MD_SIZE]; - size_t prk_len; - - if (!HKDF_extract(prk, &prk_len, digest, secret, secret_len, salt, - salt_len)) - return 0; - if (!HKDF_expand(out_key, out_len, digest, prk, prk_len, info, - info_len)) - return 0; - - return 1; -} - -/* https://tools.ietf.org/html/rfc5869#section-2.2 */ -int -HKDF_extract(uint8_t *out_key, size_t *out_len, - const EVP_MD *digest, const uint8_t *secret, size_t secret_len, - const uint8_t *salt, size_t salt_len) -{ - unsigned int len; - - /* - * If salt is not given, HashLength zeros are used. However, HMAC does - * that internally already so we can ignore it. - */ - if (salt_len > INT_MAX || HMAC(digest, salt, (int)salt_len, secret, - secret_len, out_key, &len) == NULL) { - CRYPTOerror(ERR_R_CRYPTO_LIB); - return 0; - } - *out_len = len; - return 1; -} - -/* https://tools.ietf.org/html/rfc5869#section-2.3 */ -int -HKDF_expand(uint8_t *out_key, size_t out_len, - const EVP_MD *digest, const uint8_t *prk, size_t prk_len, - const uint8_t *info, size_t info_len) -{ - const size_t digest_len = EVP_MD_size(digest); - uint8_t previous[EVP_MAX_MD_SIZE]; - size_t n, done = 0; - unsigned int i; - int ret = 0; - HMAC_CTX hmac; - - /* Expand key material to desired length. */ - n = (out_len + digest_len - 1) / digest_len; - if (out_len + digest_len < out_len || n > 255 || prk_len > INT_MAX) { - CRYPTOerror(EVP_R_TOO_LARGE); - return 0; - } - - HMAC_CTX_init(&hmac); - if (!HMAC_Init_ex(&hmac, prk, (int)prk_len, digest, NULL)) - goto out; - - for (i = 0; i < n; i++) { - uint8_t ctr = i + 1; - size_t todo; - - if (i != 0 && (!HMAC_Init_ex(&hmac, NULL, 0, NULL, NULL) || - !HMAC_Update(&hmac, previous, digest_len))) - goto out; - - if (!HMAC_Update(&hmac, info, info_len) || - !HMAC_Update(&hmac, &ctr, 1) || - !HMAC_Final(&hmac, previous, NULL)) - goto out; - - todo = digest_len; - if (done + todo > out_len) - todo = out_len - done; - - memcpy(out_key + done, previous, todo); - done += todo; - } - - ret = 1; - - out: - HMAC_CTX_cleanup(&hmac); - explicit_bzero(previous, sizeof(previous)); - if (ret != 1) - CRYPTOerror(ERR_R_CRYPTO_LIB); - return ret; -} -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ diff --git a/contrib/libfido2/openbsd-compat/hkdf.h b/contrib/libfido2/openbsd-compat/hkdf.h deleted file mode 100644 index 34450f9dd7f0..000000000000 --- a/contrib/libfido2/openbsd-compat/hkdf.h +++ /dev/null @@ -1,65 +0,0 @@ -/* $OpenBSD: hkdf.h,v 1.2 2018/04/03 13:33:53 tb Exp $ */ -/* Copyright (c) 2014, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -#ifndef OPENSSL_HEADER_HKDF_H -#define OPENSSL_HEADER_HKDF_H - -#include <openssl/evp.h> - -#if defined(__cplusplus) -extern "C" { -#endif - -/* - * HKDF computes HKDF (as specified by RFC 5869) of initial keying - * material |secret| with |salt| and |info| using |digest|, and - * outputs |out_len| bytes to |out_key|. It returns one on success and - * zero on error. - * - * HKDF is an Extract-and-Expand algorithm. It does not do any key - * stretching, and as such, is not suited to be used alone to generate - * a key from a password. - */ - -int HKDF(uint8_t *out_key, size_t out_len, const struct env_md_st *digest, - const uint8_t *secret, size_t secret_len, const uint8_t *salt, - size_t salt_len, const uint8_t *info, size_t info_len); - -/* - * HKDF_extract computes a HKDF PRK (as specified by RFC 5869) from - * initial keying material |secret| and salt |salt| using |digest|, - * and outputs |out_len| bytes to |out_key|. The maximum output size - * is |EVP_MAX_MD_SIZE|. It returns one on success and zero on error. - */ -int HKDF_extract(uint8_t *out_key, size_t *out_len, - const struct env_md_st *digest, const uint8_t *secret, - size_t secret_len, const uint8_t *salt, size_t salt_len); - -/* - * HKDF_expand computes a HKDF OKM (as specified by RFC 5869) of - * length |out_len| from the PRK |prk| and info |info| using |digest|, - * and outputs the result to |out_key|. It returns one on success and - * zero on error. - */ -int HKDF_expand(uint8_t *out_key, size_t out_len, - const EVP_MD *digest, const uint8_t *prk, size_t prk_len, - const uint8_t *info, size_t info_len); - - -#if defined(__cplusplus) -} /* extern C */ -#endif - -#endif /* OPENSSL_HEADER_HKDF_H */ diff --git a/contrib/libfido2/openbsd-compat/openbsd-compat.h b/contrib/libfido2/openbsd-compat/openbsd-compat.h index 1be3aa295051..dc9acec4c0a8 100644 --- a/contrib/libfido2/openbsd-compat/openbsd-compat.h +++ b/contrib/libfido2/openbsd-compat/openbsd-compat.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -20,6 +20,7 @@ #define be16toh(x) OSSwapBigToHostInt16((x)) #define htobe16(x) OSSwapHostToBigInt16((x)) #define be32toh(x) OSSwapBigToHostInt32((x)) +#define htobe32(x) OSSwapHostToBigInt32((x)) #define htole32(x) OSSwapHostToLittleInt32((x)) #define htole64(x) OSSwapHostToLittleInt64((x)) #endif /* __APPLE__ && !HAVE_ENDIAN_H */ @@ -33,11 +34,12 @@ #define be16toh(x) ntohs((x)) #define htobe16(x) htons((x)) #define be32toh(x) ntohl((x)) +#define htobe32(x) htonl((x)) uint32_t htole32(uint32_t); uint64_t htole64(uint64_t); #endif /* _WIN32 && !HAVE_ENDIAN_H */ -#if defined(__FreeBSD__) && !defined(HAVE_ENDIAN_H) +#if (defined(__FreeBSD__) || defined(__MidnightBSD__)) && !defined(HAVE_ENDIAN_H) #include <sys/endian.h> #endif @@ -52,6 +54,10 @@ size_t strlcat(char *, const char *, size_t); size_t strlcpy(char *, const char *, size_t); #endif +#if !defined(HAVE_STRSEP) +char *strsep(char **, const char *); +#endif + #if !defined(HAVE_RECALLOCARRAY) void *recallocarray(void *, size_t, size_t, size_t); #endif @@ -80,13 +86,6 @@ int timingsafe_bcmp(const void *, const void *, size_t); #include <openssl/opensslv.h> -#if OPENSSL_VERSION_NUMBER < 0x10100000L -#include <stdint.h> -#include "hkdf.h" -#define EVP_PKEY_get0_EC_KEY(x) ((x)->pkey.ec) -#define EVP_PKEY_get0_RSA(x) ((x)->pkey.rsa) -#endif - #if !defined(HAVE_ERR_H) #include "err.h" #else diff --git a/contrib/libfido2/openbsd-compat/strsep.c b/contrib/libfido2/openbsd-compat/strsep.c new file mode 100644 index 000000000000..578668c8ac7b --- /dev/null +++ b/contrib/libfido2/openbsd-compat/strsep.c @@ -0,0 +1,79 @@ +/* $OpenBSD: strsep.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/strsep.c */ + +#include "openbsd-compat.h" + +#if !defined(HAVE_STRSEP) + +#include <string.h> +#include <stdio.h> + +/* + * Get next token from string *stringp, where tokens are possibly-empty + * strings separated by characters from delim. + * + * Writes NULs into the string at *stringp to end tokens. + * delim need not remain constant from call to call. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, strsep returns NULL. + */ +char * +strsep(char **stringp, const char *delim) +{ + char *s; + const char *spanp; + int c, sc; + char *tok; + + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +#endif /* !defined(HAVE_STRSEP) */ diff --git a/contrib/libfido2/regress/CMakeLists.txt b/contrib/libfido2/regress/CMakeLists.txt index 0314c38f7161..c550b3141822 100644 --- a/contrib/libfido2/regress/CMakeLists.txt +++ b/contrib/libfido2/regress/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2018 Yubico AB. All rights reserved. +# Copyright (c) 2018-2021 Yubico AB. All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. @@ -7,10 +7,14 @@ add_custom_target(regress ALL) macro(add_regress_test NAME SOURCES) add_executable(${NAME} ${SOURCES}) target_link_libraries(${NAME} fido2_shared) - add_custom_command(TARGET regress POST_BUILD COMMAND ${NAME} - DEPENDS ${NAME}) + add_test(${NAME} ${NAME}) + add_dependencies(regress ${NAME}) endmacro() +add_custom_command(TARGET regress POST_BUILD + COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + add_regress_test(regress_cred cred.c) add_regress_test(regress_assert assert.c) add_regress_test(regress_dev dev.c) diff --git a/contrib/libfido2/regress/assert.c b/contrib/libfido2/regress/assert.c index dfaf50662c76..23d666a61173 100644 --- a/contrib/libfido2/regress/assert.c +++ b/contrib/libfido2/regress/assert.c @@ -1,9 +1,11 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ +#define _FIDO_INTERNAL + #include <assert.h> #include <fido.h> #include <fido/es256.h> @@ -24,6 +26,42 @@ static const unsigned char es256_pk[64] = { 0x64, 0x1a, 0x1d, 0xf8, 0xbe, 0x14, 0x90, 0x8a, }; +static const unsigned char rs256_pk[259] = { + 0x9e, 0x54, 0x78, 0xb2, 0x51, 0xbe, 0x19, 0x7c, + 0xcb, 0x1a, 0x9a, 0xc3, 0x49, 0x2a, 0x2f, 0xfd, + 0x99, 0x64, 0x76, 0xc6, 0xdb, 0xca, 0x38, 0x3f, + 0xb0, 0x6a, 0xc9, 0xc0, 0x07, 0x9f, 0x5c, 0x4d, + 0xfc, 0xd1, 0x01, 0x7f, 0x69, 0x65, 0xab, 0x9c, + 0x2a, 0xc2, 0x95, 0xd9, 0x44, 0xf3, 0xea, 0x94, + 0x6b, 0x25, 0x66, 0x54, 0x81, 0xee, 0x24, 0x1d, + 0xe1, 0x7d, 0x7f, 0xbe, 0xea, 0x76, 0x90, 0x5c, + 0xbf, 0x59, 0x22, 0xd3, 0xa0, 0x68, 0x1a, 0x65, + 0x8b, 0x2f, 0xb6, 0xa8, 0x30, 0x2d, 0x26, 0x81, + 0xfa, 0x9e, 0x59, 0xec, 0x2f, 0xee, 0x59, 0x39, + 0xe2, 0x79, 0x19, 0x54, 0x54, 0xdf, 0x24, 0x83, + 0xee, 0x61, 0x5a, 0x66, 0x24, 0x2b, 0x7b, 0xfb, + 0x82, 0x66, 0xe4, 0x85, 0x18, 0x20, 0x76, 0xe5, + 0x4a, 0xb6, 0xcb, 0xec, 0x43, 0xbe, 0xfd, 0xb0, + 0x8f, 0xfd, 0x2f, 0x69, 0xda, 0x06, 0x9c, 0x09, + 0x68, 0x7a, 0x94, 0x6c, 0xb7, 0x51, 0x6d, 0x4c, + 0xf7, 0x13, 0xe8, 0xd5, 0x22, 0x6b, 0x1e, 0xba, + 0xb9, 0x85, 0xe8, 0x5f, 0xa1, 0x66, 0xe3, 0x20, + 0x75, 0x30, 0x11, 0xb5, 0xa3, 0xc3, 0xb0, 0x72, + 0x08, 0xff, 0xa3, 0xbb, 0xf1, 0x32, 0x0b, 0x06, + 0xc4, 0x12, 0xa3, 0x49, 0x30, 0x19, 0xb9, 0xfe, + 0x69, 0x0c, 0xd6, 0xe1, 0x58, 0x36, 0xe6, 0x41, + 0x22, 0x41, 0xbf, 0x96, 0x50, 0x35, 0x56, 0x0d, + 0x92, 0x8c, 0x34, 0xea, 0x28, 0x91, 0x88, 0x9e, + 0x8a, 0xaa, 0x36, 0xd0, 0x0f, 0xbe, 0x16, 0xde, + 0x9d, 0x5f, 0x7b, 0xda, 0x52, 0xf7, 0xf1, 0xb6, + 0x28, 0x10, 0x05, 0x8f, 0xb9, 0x19, 0x7a, 0xcf, + 0x18, 0x9b, 0x40, 0xcd, 0xff, 0x78, 0xea, 0x61, + 0x24, 0x3b, 0x80, 0x68, 0x04, 0x9b, 0x40, 0x07, + 0x98, 0xd4, 0x94, 0xd1, 0x18, 0x44, 0xa5, 0xed, + 0xee, 0x18, 0xc2, 0x25, 0x52, 0x66, 0x42, 0xdf, + 0x01, 0x00, 0x01, +}; + static const unsigned char cdh[32] = { 0xec, 0x8d, 0x8f, 0x78, 0x42, 0x4a, 0x2b, 0xb7, 0x82, 0x34, 0xaa, 0xca, 0x07, 0xa1, 0xf6, 0x56, @@ -397,7 +435,7 @@ junk_cdh(void) junk = malloc(sizeof(cdh)); assert(junk != NULL); memcpy(junk, cdh, sizeof(cdh)); - junk[0] = ~junk[0]; + junk[0] = (unsigned char)~junk[0]; a = alloc_assert(); pk = alloc_es256_pk(); @@ -448,7 +486,7 @@ junk_authdata(void) junk = malloc(sizeof(authdata)); assert(junk != NULL); memcpy(junk, authdata, sizeof(authdata)); - junk[0] = ~junk[0]; + junk[0] = (unsigned char)~junk[0]; a = alloc_assert(); assert(fido_assert_set_count(a, 1) == FIDO_OK); @@ -468,7 +506,7 @@ junk_sig(void) junk = malloc(sizeof(sig)); assert(junk != NULL); memcpy(junk, sig, sizeof(sig)); - junk[0] = ~junk[0]; + junk[0] = (unsigned char)~junk[0]; a = alloc_assert(); pk = alloc_es256_pk(); @@ -531,6 +569,46 @@ bad_cbor_serialize(void) free_assert(a); } +/* rs256 <-> EVP_PKEY transformations */ +static void +rs256_PKEY(void) +{ + rs256_pk_t *pk1, *pk2; + EVP_PKEY *pkey; + + pk1 = alloc_rs256_pk(); + pk2 = alloc_rs256_pk(); + + assert(rs256_pk_from_ptr(pk1, rs256_pk, sizeof(rs256_pk)) == FIDO_OK); + assert((pkey = rs256_pk_to_EVP_PKEY(pk1)) != NULL); + assert(rs256_pk_from_EVP_PKEY(pk2, pkey) == FIDO_OK); + assert(memcmp(pk1, pk2, sizeof(*pk1)) == 0); + + free_rs256_pk(pk1); + free_rs256_pk(pk2); + EVP_PKEY_free(pkey); +} + +/* es256 <-> EVP_PKEY transformations */ +static void +es256_PKEY(void) +{ + es256_pk_t *pk1, *pk2; + EVP_PKEY *pkey; + + pk1 = alloc_es256_pk(); + pk2 = alloc_es256_pk(); + + assert(es256_pk_from_ptr(pk1, es256_pk, sizeof(es256_pk)) == FIDO_OK); + assert((pkey = es256_pk_to_EVP_PKEY(pk1)) != NULL); + assert(es256_pk_from_EVP_PKEY(pk2, pkey) == FIDO_OK); + assert(memcmp(pk1, pk2, sizeof(*pk1)) == 0); + + free_es256_pk(pk1); + free_es256_pk(pk2); + EVP_PKEY_free(pkey); +} + int main(void) { @@ -548,6 +626,8 @@ main(void) junk_sig(); wrong_options(); bad_cbor_serialize(); + rs256_PKEY(); + es256_PKEY(); exit(0); } diff --git a/contrib/libfido2/regress/cred.c b/contrib/libfido2/regress/cred.c index 01df1ef9320d..b0df1481636a 100644 --- a/contrib/libfido2/regress/cred.c +++ b/contrib/libfido2/regress/cred.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -102,6 +102,55 @@ static const unsigned char authdata_unsorted_keys[198] = { 0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2, }; +const unsigned char authdata_tpm[362] = { + 0x59, 0x01, 0x67, 0x49, 0x96, 0x0d, 0xe5, 0x88, + 0x0e, 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64, + 0x76, 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2, + 0x86, 0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, 0x83, + 0x1d, 0x97, 0x63, 0x45, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x98, 0x70, 0x58, 0xca, 0xdc, 0x4b, 0x81, + 0xb6, 0xe1, 0x30, 0xde, 0x50, 0xdc, 0xbe, 0x96, + 0x00, 0x20, 0x89, 0x99, 0x6d, 0x5a, 0x00, 0x29, + 0xe5, 0x3e, 0x6a, 0x1c, 0x72, 0x6d, 0x71, 0x4a, + 0x4f, 0x03, 0x9b, 0x68, 0x17, 0xdb, 0x29, 0x1a, + 0x6b, 0x02, 0x6c, 0x26, 0xf9, 0xbd, 0xc3, 0x0e, + 0x38, 0x1a, 0xa4, 0x01, 0x03, 0x03, 0x39, 0x01, + 0x00, 0x20, 0x59, 0x01, 0x00, 0xc5, 0xb6, 0x9c, + 0x06, 0x1d, 0xcf, 0xb9, 0xf2, 0x5e, 0x99, 0x7d, + 0x6d, 0x73, 0xd8, 0x36, 0xc1, 0x4a, 0x90, 0x05, + 0x4d, 0x82, 0x57, 0xc1, 0xb6, 0x6a, 0xd1, 0x43, + 0x03, 0x85, 0xf8, 0x52, 0x4f, 0xd2, 0x27, 0x91, + 0x0b, 0xb5, 0x93, 0xa0, 0x68, 0xf8, 0x80, 0x1b, + 0xaa, 0x65, 0x97, 0x45, 0x11, 0x86, 0x34, 0xd6, + 0x67, 0xf8, 0xd5, 0x12, 0x79, 0x84, 0xee, 0x70, + 0x99, 0x00, 0x63, 0xa8, 0xb4, 0x43, 0x0b, 0x4c, + 0x57, 0x4a, 0xd6, 0x9b, 0x75, 0x63, 0x8a, 0x46, + 0x57, 0xdb, 0x14, 0xc8, 0x71, 0xd1, 0xb3, 0x07, + 0x68, 0x58, 0xbc, 0x55, 0x84, 0x80, 0x2a, 0xd2, + 0x36, 0x9f, 0xc1, 0x64, 0xa0, 0x11, 0x4b, 0xc9, + 0x32, 0x31, 0x3a, 0xd6, 0x87, 0x26, 0x1a, 0x3a, + 0x78, 0x3d, 0x89, 0xdb, 0x00, 0x28, 0x3b, 0xae, + 0x2b, 0x1b, 0x56, 0xe2, 0x8c, 0x4c, 0x63, 0xac, + 0x6e, 0x6c, 0xf7, 0xb5, 0x7d, 0x4d, 0x0b, 0x9f, + 0x06, 0xa0, 0x10, 0x35, 0x38, 0x20, 0x4d, 0xcc, + 0x07, 0xd7, 0x00, 0x4e, 0x86, 0xba, 0xfe, 0x8b, + 0xe4, 0x3f, 0x4a, 0xd6, 0xca, 0xbf, 0x67, 0x40, + 0x1a, 0xa4, 0xda, 0x82, 0x52, 0x15, 0xb8, 0x14, + 0x3a, 0x7c, 0xa9, 0x02, 0xc1, 0x01, 0x69, 0xc6, + 0x51, 0xd4, 0xbc, 0x1f, 0x95, 0xb2, 0xee, 0x1f, + 0xdd, 0xb5, 0x73, 0x16, 0x5e, 0x29, 0x3f, 0x47, + 0xac, 0x65, 0xfb, 0x63, 0x5c, 0xb9, 0xc8, 0x13, + 0x2d, 0xec, 0x85, 0xde, 0x71, 0x0d, 0x84, 0x93, + 0x74, 0x76, 0x91, 0xdd, 0x1d, 0x6d, 0x3d, 0xc7, + 0x36, 0x19, 0x19, 0x86, 0xde, 0x7c, 0xca, 0xd6, + 0xc6, 0x65, 0x7e, 0x4b, 0x24, 0x9c, 0xce, 0x92, + 0x6b, 0x1c, 0xe0, 0xa0, 0xa9, 0x6c, 0xc3, 0xed, + 0x4f, 0x2a, 0x54, 0x07, 0x00, 0x32, 0x5e, 0x1b, + 0x94, 0x37, 0xcd, 0xe2, 0x32, 0xa8, 0xd5, 0x2c, + 0xfb, 0x03, 0x9d, 0x79, 0xdf, 0x21, 0x43, 0x01, + 0x00, 0x01 +}; + static const unsigned char x509[742] = { 0x30, 0x82, 0x02, 0xe2, 0x30, 0x81, 0xcb, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, @@ -221,6 +270,42 @@ const unsigned char pubkey[64] = { 0xfe, 0x5d, 0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2, }; +const unsigned char pubkey_tpm[259] = { + 0xc5, 0xb6, 0x9c, 0x06, 0x1d, 0xcf, 0xb9, 0xf2, + 0x5e, 0x99, 0x7d, 0x6d, 0x73, 0xd8, 0x36, 0xc1, + 0x4a, 0x90, 0x05, 0x4d, 0x82, 0x57, 0xc1, 0xb6, + 0x6a, 0xd1, 0x43, 0x03, 0x85, 0xf8, 0x52, 0x4f, + 0xd2, 0x27, 0x91, 0x0b, 0xb5, 0x93, 0xa0, 0x68, + 0xf8, 0x80, 0x1b, 0xaa, 0x65, 0x97, 0x45, 0x11, + 0x86, 0x34, 0xd6, 0x67, 0xf8, 0xd5, 0x12, 0x79, + 0x84, 0xee, 0x70, 0x99, 0x00, 0x63, 0xa8, 0xb4, + 0x43, 0x0b, 0x4c, 0x57, 0x4a, 0xd6, 0x9b, 0x75, + 0x63, 0x8a, 0x46, 0x57, 0xdb, 0x14, 0xc8, 0x71, + 0xd1, 0xb3, 0x07, 0x68, 0x58, 0xbc, 0x55, 0x84, + 0x80, 0x2a, 0xd2, 0x36, 0x9f, 0xc1, 0x64, 0xa0, + 0x11, 0x4b, 0xc9, 0x32, 0x31, 0x3a, 0xd6, 0x87, + 0x26, 0x1a, 0x3a, 0x78, 0x3d, 0x89, 0xdb, 0x00, + 0x28, 0x3b, 0xae, 0x2b, 0x1b, 0x56, 0xe2, 0x8c, + 0x4c, 0x63, 0xac, 0x6e, 0x6c, 0xf7, 0xb5, 0x7d, + 0x4d, 0x0b, 0x9f, 0x06, 0xa0, 0x10, 0x35, 0x38, + 0x20, 0x4d, 0xcc, 0x07, 0xd7, 0x00, 0x4e, 0x86, + 0xba, 0xfe, 0x8b, 0xe4, 0x3f, 0x4a, 0xd6, 0xca, + 0xbf, 0x67, 0x40, 0x1a, 0xa4, 0xda, 0x82, 0x52, + 0x15, 0xb8, 0x14, 0x3a, 0x7c, 0xa9, 0x02, 0xc1, + 0x01, 0x69, 0xc6, 0x51, 0xd4, 0xbc, 0x1f, 0x95, + 0xb2, 0xee, 0x1f, 0xdd, 0xb5, 0x73, 0x16, 0x5e, + 0x29, 0x3f, 0x47, 0xac, 0x65, 0xfb, 0x63, 0x5c, + 0xb9, 0xc8, 0x13, 0x2d, 0xec, 0x85, 0xde, 0x71, + 0x0d, 0x84, 0x93, 0x74, 0x76, 0x91, 0xdd, 0x1d, + 0x6d, 0x3d, 0xc7, 0x36, 0x19, 0x19, 0x86, 0xde, + 0x7c, 0xca, 0xd6, 0xc6, 0x65, 0x7e, 0x4b, 0x24, + 0x9c, 0xce, 0x92, 0x6b, 0x1c, 0xe0, 0xa0, 0xa9, + 0x6c, 0xc3, 0xed, 0x4f, 0x2a, 0x54, 0x07, 0x00, + 0x32, 0x5e, 0x1b, 0x94, 0x37, 0xcd, 0xe2, 0x32, + 0xa8, 0xd5, 0x2c, 0xfb, 0x03, 0x9d, 0x79, 0xdf, + 0x01, 0x00, 0x01, +}; + const unsigned char id[64] = { 0x53, 0xfb, 0xdf, 0xaa, 0xce, 0x63, 0xde, 0xc5, 0xfe, 0x47, 0xe6, 0x52, 0xeb, 0xf3, 0x5d, 0x53, @@ -232,16 +317,539 @@ const unsigned char id[64] = { 0x34, 0xe3, 0x83, 0xe7, 0xd1, 0xbd, 0x9f, 0x25, }; +const unsigned char id_tpm[32] = { + 0x89, 0x99, 0x6d, 0x5a, 0x00, 0x29, 0xe5, 0x3e, + 0x6a, 0x1c, 0x72, 0x6d, 0x71, 0x4a, 0x4f, 0x03, + 0x9b, 0x68, 0x17, 0xdb, 0x29, 0x1a, 0x6b, 0x02, + 0x6c, 0x26, 0xf9, 0xbd, 0xc3, 0x0e, 0x38, 0x1a +}; + +const unsigned char attstmt_tpm[4034] = { + 0xa6, 0x63, 0x61, 0x6c, 0x67, 0x39, 0xff, 0xfe, + 0x63, 0x73, 0x69, 0x67, 0x59, 0x01, 0x00, 0x1c, + 0x09, 0x0d, 0x35, 0x97, 0x22, 0xfc, 0xfe, 0xc0, + 0x58, 0x49, 0x9e, 0xd4, 0x7e, 0x6a, 0x7d, 0xdb, + 0x6d, 0x20, 0x95, 0x5c, 0x0b, 0xd0, 0xd5, 0x72, + 0x4f, 0x15, 0x22, 0x38, 0x97, 0xb2, 0x4b, 0xd0, + 0xef, 0x31, 0x7c, 0xf2, 0x42, 0x19, 0x41, 0xa1, + 0xe2, 0xc5, 0xca, 0xc6, 0x74, 0x95, 0xcf, 0xf9, + 0x41, 0x75, 0x0b, 0x56, 0x39, 0x82, 0x78, 0xf6, + 0x59, 0xf1, 0x09, 0x96, 0x9e, 0x38, 0x7f, 0x14, + 0x9b, 0xf5, 0x36, 0xbb, 0x92, 0x32, 0xc4, 0x64, + 0xe8, 0xff, 0xb4, 0xc7, 0xcf, 0xcd, 0x17, 0x48, + 0x0f, 0x83, 0xd9, 0x44, 0x03, 0x35, 0x26, 0xad, + 0x01, 0xb7, 0x57, 0x06, 0xb3, 0x9c, 0xa0, 0x6e, + 0x2f, 0x58, 0xcb, 0x5c, 0xaa, 0x7c, 0xea, 0x7e, + 0x3f, 0xbc, 0x76, 0xc9, 0x0e, 0x52, 0x39, 0x81, + 0xa9, 0x9e, 0x37, 0x14, 0x1f, 0x50, 0x6a, 0x4f, + 0xd7, 0xfc, 0xd4, 0xfa, 0xf2, 0x18, 0x60, 0xd5, + 0xc3, 0x57, 0x7d, 0x6d, 0x05, 0x28, 0x25, 0xc3, + 0xde, 0x86, 0x85, 0x06, 0x71, 0xfb, 0x84, 0xa2, + 0x07, 0xb6, 0x77, 0xc9, 0x68, 0x41, 0x53, 0x32, + 0x4c, 0xa8, 0x4b, 0xf7, 0x08, 0x84, 0x62, 0x6c, + 0x8a, 0xb6, 0xcf, 0xc1, 0xde, 0x6b, 0x61, 0xc8, + 0xdd, 0xc0, 0x13, 0x70, 0x22, 0x28, 0xe1, 0x0f, + 0x46, 0x02, 0xc6, 0xb1, 0xfa, 0x30, 0xcb, 0xec, + 0xd1, 0x82, 0xfa, 0x51, 0xcb, 0x71, 0x5e, 0x1f, + 0x1b, 0x5f, 0xe0, 0xb0, 0x02, 0x8a, 0x7c, 0x78, + 0xd1, 0xb7, 0x4d, 0x56, 0xb0, 0x92, 0x3e, 0xda, + 0xc7, 0xb1, 0x74, 0xcf, 0x6a, 0x40, 0xeb, 0x98, + 0x1c, 0x2e, 0xf2, 0x86, 0x76, 0xf8, 0x2e, 0x6a, + 0x9f, 0x77, 0x51, 0x64, 0xce, 0xdc, 0x12, 0x85, + 0x84, 0x6b, 0x01, 0xc8, 0xeb, 0xbc, 0x57, 0x6c, + 0x32, 0x26, 0xcb, 0xb2, 0x84, 0x02, 0x2a, 0x33, + 0x15, 0xd9, 0xe3, 0x15, 0xfc, 0x3a, 0x24, 0x63, + 0x76, 0x65, 0x72, 0x63, 0x32, 0x2e, 0x30, 0x63, + 0x78, 0x35, 0x63, 0x82, 0x59, 0x05, 0xc4, 0x30, + 0x82, 0x05, 0xc0, 0x30, 0x82, 0x03, 0xa8, 0xa0, + 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x78, 0xd9, + 0xa8, 0xb2, 0x64, 0xf9, 0x4d, 0x28, 0x82, 0xc0, + 0xd3, 0x1b, 0x40, 0x3c, 0xc8, 0xd9, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x41, 0x31, + 0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x36, 0x45, 0x55, 0x53, 0x2d, 0x53, 0x54, + 0x4d, 0x2d, 0x4b, 0x45, 0x59, 0x49, 0x44, 0x2d, + 0x31, 0x41, 0x44, 0x42, 0x39, 0x39, 0x34, 0x41, + 0x42, 0x35, 0x38, 0x42, 0x45, 0x35, 0x37, 0x41, + 0x30, 0x43, 0x43, 0x39, 0x42, 0x39, 0x30, 0x30, + 0x45, 0x37, 0x38, 0x35, 0x31, 0x45, 0x31, 0x41, + 0x34, 0x33, 0x43, 0x30, 0x38, 0x36, 0x36, 0x30, + 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x37, + 0x31, 0x35, 0x31, 0x31, 0x31, 0x32, 0x31, 0x33, + 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x33, 0x32, + 0x31, 0x32, 0x30, 0x32, 0x39, 0x31, 0x35, 0x5a, + 0x30, 0x00, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, + 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, + 0x01, 0x01, 0x00, 0xca, 0xbe, 0x77, 0x9f, 0x45, + 0x97, 0x17, 0x8d, 0x01, 0xe1, 0x18, 0xcc, 0xf0, + 0xb5, 0xed, 0x9a, 0xb7, 0x36, 0xac, 0x05, 0x26, + 0xbe, 0x35, 0xd9, 0x5c, 0x00, 0x5c, 0x5d, 0x8b, + 0x6f, 0x2a, 0xb8, 0xf6, 0x02, 0x4f, 0x33, 0xfe, + 0x84, 0x45, 0x4c, 0x4f, 0x7a, 0xdb, 0xa9, 0x6a, + 0x62, 0x0f, 0x19, 0x35, 0x5d, 0xd2, 0x34, 0x1a, + 0x9d, 0x73, 0x55, 0xe5, 0x3e, 0x04, 0xa2, 0xd6, + 0xbe, 0xe7, 0x5a, 0xb9, 0x16, 0x6c, 0x55, 0x18, + 0xa8, 0x4b, 0xb2, 0x37, 0xb9, 0xa3, 0x87, 0xfc, + 0x76, 0xa8, 0x55, 0xc9, 0xe7, 0x30, 0xe5, 0x0e, + 0x3c, 0x7b, 0x74, 0xd2, 0x1e, 0xa8, 0x05, 0xd5, + 0xe2, 0xe3, 0xcb, 0xaf, 0x63, 0x33, 0x12, 0xaa, + 0xfd, 0x31, 0x32, 0x71, 0x4f, 0x41, 0x96, 0x05, + 0xb5, 0x69, 0x73, 0x45, 0xbe, 0x6f, 0x90, 0xd9, + 0x10, 0x36, 0xaf, 0x7a, 0x1c, 0xf1, 0x6d, 0x14, + 0xb0, 0x1e, 0xbb, 0xae, 0x1c, 0x35, 0xec, 0x1c, + 0xb5, 0x0e, 0xf6, 0x33, 0x98, 0x13, 0x4e, 0x44, + 0x7b, 0x5c, 0x97, 0x47, 0xed, 0x4f, 0xfe, 0xbd, + 0x08, 0xd2, 0xa9, 0xc6, 0xbe, 0x8c, 0x04, 0x9e, + 0xdc, 0x3d, 0xbe, 0x98, 0xe9, 0x2a, 0xb1, 0xf4, + 0xfa, 0x45, 0xf9, 0xc8, 0x9a, 0x55, 0x85, 0x26, + 0xfc, 0x5f, 0xad, 0x00, 0x8b, 0xc8, 0x41, 0xf2, + 0x86, 0x4e, 0xba, 0x55, 0x1c, 0xb2, 0x89, 0xe8, + 0x85, 0x6e, 0x1e, 0x02, 0x9f, 0x55, 0x70, 0xbe, + 0xfd, 0xe7, 0x9f, 0xba, 0x59, 0xa0, 0x2e, 0x9a, + 0x74, 0x11, 0xe7, 0xad, 0xa9, 0xc7, 0x7b, 0x58, + 0xc4, 0x16, 0xd3, 0x35, 0xcb, 0x61, 0x00, 0xec, + 0x36, 0x4a, 0xa3, 0x51, 0xa3, 0xdd, 0x61, 0xb6, + 0xd6, 0x29, 0xcb, 0x76, 0xe1, 0xab, 0x51, 0x3a, + 0xe8, 0xbf, 0xdb, 0x09, 0x4a, 0x39, 0x96, 0xd9, + 0xac, 0x8f, 0x6c, 0x62, 0xe0, 0x03, 0x23, 0x24, + 0xbe, 0xd4, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, + 0xa3, 0x82, 0x01, 0xf3, 0x30, 0x82, 0x01, 0xef, + 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, + 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, + 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, + 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x6d, + 0x06, 0x03, 0x55, 0x1d, 0x20, 0x01, 0x01, 0xff, + 0x04, 0x63, 0x30, 0x61, 0x30, 0x5f, 0x06, 0x09, + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, + 0x1f, 0x30, 0x52, 0x30, 0x50, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, + 0x44, 0x1e, 0x42, 0x00, 0x54, 0x00, 0x43, 0x00, + 0x50, 0x00, 0x41, 0x00, 0x20, 0x00, 0x20, 0x00, + 0x54, 0x00, 0x72, 0x00, 0x75, 0x00, 0x73, 0x00, + 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, + 0x20, 0x00, 0x50, 0x00, 0x6c, 0x00, 0x61, 0x00, + 0x74, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, + 0x6d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x49, 0x00, + 0x64, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, + 0x69, 0x00, 0x74, 0x00, 0x79, 0x30, 0x10, 0x06, + 0x03, 0x55, 0x1d, 0x25, 0x04, 0x09, 0x30, 0x07, + 0x06, 0x05, 0x67, 0x81, 0x05, 0x08, 0x03, 0x30, + 0x59, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x01, 0x01, + 0xff, 0x04, 0x4f, 0x30, 0x4d, 0xa4, 0x4b, 0x30, + 0x49, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67, + 0x81, 0x05, 0x02, 0x01, 0x0c, 0x0b, 0x69, 0x64, + 0x3a, 0x35, 0x33, 0x35, 0x34, 0x34, 0x44, 0x32, + 0x30, 0x31, 0x17, 0x30, 0x15, 0x06, 0x05, 0x67, + 0x81, 0x05, 0x02, 0x02, 0x0c, 0x0c, 0x53, 0x54, + 0x33, 0x33, 0x48, 0x54, 0x50, 0x48, 0x41, 0x48, + 0x42, 0x34, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, + 0x67, 0x81, 0x05, 0x02, 0x03, 0x0c, 0x0b, 0x69, + 0x64, 0x3a, 0x30, 0x30, 0x34, 0x39, 0x30, 0x30, + 0x30, 0x34, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb8, + 0x5f, 0xd5, 0x67, 0xca, 0x92, 0xc4, 0x0e, 0xcf, + 0x0c, 0xd8, 0x1f, 0x6d, 0x3f, 0x03, 0x55, 0x6f, + 0x38, 0xa6, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd4, 0x04, + 0x64, 0xfc, 0x6e, 0x50, 0x0a, 0x56, 0x48, 0x0f, + 0x05, 0xa9, 0x00, 0xb7, 0x1d, 0x5e, 0x57, 0x08, + 0xd5, 0xdc, 0x30, 0x81, 0xb2, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, + 0x81, 0xa5, 0x30, 0x81, 0xa2, 0x30, 0x81, 0x9f, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x30, 0x02, 0x86, 0x81, 0x92, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x7a, 0x63, 0x73, + 0x70, 0x72, 0x6f, 0x64, 0x65, 0x75, 0x73, 0x61, + 0x69, 0x6b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x2e, 0x62, 0x6c, 0x6f, 0x62, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, + 0x6f, 0x77, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x2f, + 0x65, 0x75, 0x73, 0x2d, 0x73, 0x74, 0x6d, 0x2d, + 0x6b, 0x65, 0x79, 0x69, 0x64, 0x2d, 0x31, 0x61, + 0x64, 0x62, 0x39, 0x39, 0x34, 0x61, 0x62, 0x35, + 0x38, 0x62, 0x65, 0x35, 0x37, 0x61, 0x30, 0x63, + 0x63, 0x39, 0x62, 0x39, 0x30, 0x30, 0x65, 0x37, + 0x38, 0x35, 0x31, 0x65, 0x31, 0x61, 0x34, 0x33, + 0x63, 0x30, 0x38, 0x36, 0x36, 0x30, 0x2f, 0x61, + 0x62, 0x64, 0x36, 0x31, 0x35, 0x66, 0x32, 0x2d, + 0x31, 0x35, 0x38, 0x61, 0x2d, 0x34, 0x35, 0x38, + 0x65, 0x2d, 0x61, 0x31, 0x35, 0x35, 0x2d, 0x37, + 0x63, 0x34, 0x63, 0x38, 0x63, 0x62, 0x31, 0x33, + 0x63, 0x36, 0x35, 0x2e, 0x63, 0x65, 0x72, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, + 0x02, 0x01, 0x00, 0xa2, 0x10, 0xc5, 0xbf, 0x41, + 0xa6, 0xba, 0x8c, 0x72, 0xca, 0x0f, 0x3e, 0x5e, + 0x7f, 0xe2, 0xcb, 0x60, 0xb8, 0x3f, 0xfb, 0xde, + 0x03, 0xe2, 0xfe, 0x20, 0x29, 0xdf, 0x11, 0xf5, + 0xb0, 0x50, 0x6d, 0x32, 0xe8, 0x1b, 0x05, 0xad, + 0x6b, 0x60, 0xb5, 0xed, 0xf3, 0xa4, 0x4a, 0xea, + 0x09, 0xe5, 0x65, 0x7e, 0xe0, 0xd5, 0x3a, 0x6a, + 0xdb, 0x64, 0xb7, 0x07, 0x8f, 0xa1, 0x63, 0xb3, + 0x89, 0x8a, 0xac, 0x49, 0x97, 0xa0, 0x9a, 0xa3, + 0xd3, 0x3a, 0xc2, 0x13, 0xb2, 0xbb, 0xab, 0x0d, + 0xf2, 0x35, 0xc5, 0x03, 0xde, 0x1c, 0xad, 0x6a, + 0x03, 0x0a, 0x4c, 0xe1, 0x37, 0x8f, 0xbc, 0x13, + 0xc0, 0x9a, 0x17, 0xd4, 0x2e, 0x36, 0x17, 0x51, + 0x12, 0xb0, 0x79, 0xbf, 0x9b, 0xb3, 0xb0, 0x74, + 0x25, 0x81, 0x7e, 0x21, 0x31, 0xb7, 0xc2, 0x5e, + 0xfb, 0x36, 0xab, 0xf3, 0x7a, 0x5f, 0xa4, 0x5e, + 0x8f, 0x0c, 0xbd, 0xcf, 0xf5, 0x50, 0xe7, 0x0c, + 0x51, 0x55, 0x48, 0xe6, 0x15, 0xb6, 0xd4, 0xaf, + 0x95, 0x72, 0x56, 0x94, 0xf7, 0x0e, 0xd6, 0x90, + 0xe3, 0xd3, 0x5d, 0xbd, 0x93, 0xa1, 0xbd, 0x6c, + 0xe4, 0xf2, 0x39, 0x4d, 0x54, 0x74, 0xcf, 0xf5, + 0xeb, 0x70, 0xdb, 0x4f, 0x52, 0xcd, 0x39, 0x8f, + 0x11, 0x54, 0x28, 0x06, 0x29, 0x8f, 0x23, 0xde, + 0x9e, 0x2f, 0x7b, 0xb6, 0x5f, 0xa3, 0x89, 0x04, + 0x99, 0x0a, 0xf1, 0x2d, 0xf9, 0x66, 0xd3, 0x13, + 0x45, 0xbd, 0x6c, 0x22, 0x57, 0xf5, 0xb1, 0xb9, + 0xdf, 0x5b, 0x7b, 0x1a, 0x3a, 0xdd, 0x6b, 0xc7, + 0x35, 0x88, 0xed, 0xc4, 0x09, 0x70, 0x4e, 0x5f, + 0xb5, 0x3e, 0xd1, 0x0b, 0xd0, 0xca, 0xef, 0x0b, + 0xe9, 0x8b, 0x6f, 0xc3, 0x16, 0xc3, 0x3d, 0x79, + 0x06, 0xef, 0x81, 0xf0, 0x60, 0x0b, 0x32, 0xe3, + 0x86, 0x6b, 0x92, 0x38, 0x90, 0x62, 0xed, 0x84, + 0x3a, 0xb7, 0x45, 0x43, 0x2e, 0xd0, 0x3a, 0x71, + 0x9e, 0x80, 0xcc, 0x9c, 0xac, 0x27, 0x10, 0x91, + 0xb7, 0xb2, 0xbd, 0x41, 0x40, 0xa7, 0xb7, 0xcf, + 0xe7, 0x38, 0xca, 0x68, 0xdd, 0x62, 0x09, 0xff, + 0x68, 0xce, 0xba, 0xe2, 0x07, 0x49, 0x09, 0xe7, + 0x1f, 0xdf, 0xe6, 0x26, 0xe5, 0x0f, 0xa9, 0xbf, + 0x2a, 0x5b, 0x67, 0x92, 0xa1, 0x10, 0x53, 0xb2, + 0x7a, 0x07, 0x29, 0x9d, 0xfd, 0x6d, 0xb6, 0x3b, + 0x45, 0xc1, 0x94, 0xcb, 0x1c, 0xc3, 0xce, 0xf6, + 0x8a, 0x1a, 0x81, 0x66, 0xb0, 0xa5, 0x14, 0xc7, + 0x9e, 0x1f, 0x6e, 0xb6, 0xff, 0x8b, 0x90, 0x87, + 0x3a, 0x3f, 0xa8, 0xc2, 0x2d, 0x8f, 0x6f, 0xdb, + 0xb4, 0xc4, 0x14, 0x3c, 0x1d, 0x12, 0x1d, 0x6d, + 0xcf, 0xa6, 0x04, 0x6a, 0xa8, 0x13, 0x5e, 0xf2, + 0x5e, 0x77, 0x80, 0x6b, 0x85, 0x83, 0xfe, 0xbb, + 0xeb, 0x70, 0xcb, 0x5f, 0xe4, 0x95, 0xaa, 0x0f, + 0x61, 0x36, 0x7c, 0xbb, 0x22, 0x1e, 0xba, 0x98, + 0x43, 0x52, 0x33, 0xae, 0xed, 0x5d, 0x10, 0x2c, + 0xb3, 0xa9, 0x31, 0x8e, 0x60, 0x54, 0xaf, 0x40, + 0x6d, 0x2e, 0x18, 0xc2, 0x6a, 0xf4, 0x7b, 0x9a, + 0x73, 0x0f, 0x58, 0x69, 0x23, 0xbb, 0xc4, 0x84, + 0x53, 0x30, 0xe2, 0xd6, 0x1e, 0x10, 0xc1, 0xec, + 0x82, 0x13, 0xab, 0x53, 0x86, 0xa2, 0xb9, 0xda, + 0xbb, 0x3a, 0xa2, 0xbe, 0xb0, 0x10, 0x99, 0x0e, + 0xe5, 0x9c, 0xc9, 0xf1, 0xce, 0x76, 0x46, 0xea, + 0x86, 0xaa, 0x36, 0x83, 0x99, 0x09, 0x9b, 0x30, + 0xd3, 0x26, 0xc7, 0xdf, 0x66, 0xc7, 0xf0, 0xdd, + 0x08, 0x09, 0x15, 0x15, 0x21, 0x49, 0x46, 0xd8, + 0x8a, 0x66, 0xca, 0x62, 0x9c, 0x79, 0x1d, 0x81, + 0xea, 0x5d, 0x82, 0xb0, 0xa6, 0x6b, 0x5c, 0xf5, + 0xb8, 0x8c, 0xf6, 0x16, 0x01, 0x2c, 0xf8, 0x27, + 0xf8, 0xcf, 0x88, 0xfe, 0xf3, 0xa4, 0xfc, 0x17, + 0x97, 0xe7, 0x07, 0x59, 0x06, 0xef, 0x30, 0x82, + 0x06, 0xeb, 0x30, 0x82, 0x04, 0xd3, 0xa0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x13, 0x33, 0x00, 0x00, + 0x02, 0x39, 0xf9, 0xbb, 0x6a, 0x1d, 0x49, 0x64, + 0x47, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, + 0x81, 0x8c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, + 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, + 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, + 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, + 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x36, + 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x2d, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, + 0x66, 0x74, 0x20, 0x54, 0x50, 0x4d, 0x20, 0x52, + 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x32, 0x30, 0x31, 0x34, 0x30, 0x1e, + 0x17, 0x0d, 0x31, 0x39, 0x30, 0x33, 0x32, 0x31, + 0x32, 0x30, 0x32, 0x39, 0x31, 0x35, 0x5a, 0x17, + 0x0d, 0x32, 0x35, 0x30, 0x33, 0x32, 0x31, 0x32, + 0x30, 0x32, 0x39, 0x31, 0x35, 0x5a, 0x30, 0x41, + 0x31, 0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x36, 0x45, 0x55, 0x53, 0x2d, 0x53, + 0x54, 0x4d, 0x2d, 0x4b, 0x45, 0x59, 0x49, 0x44, + 0x2d, 0x31, 0x41, 0x44, 0x42, 0x39, 0x39, 0x34, + 0x41, 0x42, 0x35, 0x38, 0x42, 0x45, 0x35, 0x37, + 0x41, 0x30, 0x43, 0x43, 0x39, 0x42, 0x39, 0x30, + 0x30, 0x45, 0x37, 0x38, 0x35, 0x31, 0x45, 0x31, + 0x41, 0x34, 0x33, 0x43, 0x30, 0x38, 0x36, 0x36, + 0x30, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, + 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, + 0x01, 0x00, 0xdb, 0xe2, 0x23, 0xf9, 0x86, 0x8f, + 0xa9, 0x71, 0x9f, 0x8b, 0xf9, 0x7c, 0xe9, 0x45, + 0x2d, 0x59, 0x56, 0x5e, 0x96, 0xf4, 0xdd, 0x9a, + 0x12, 0xcd, 0x90, 0x1a, 0x0c, 0xb5, 0x03, 0xbf, + 0x09, 0xbe, 0xbf, 0xf7, 0x55, 0x52, 0xe8, 0x39, + 0x4c, 0xbe, 0x2a, 0x28, 0x88, 0x78, 0x39, 0xa7, + 0xcb, 0xf9, 0x4c, 0x55, 0xd2, 0x31, 0x96, 0x3b, + 0x48, 0xa2, 0xf3, 0xf6, 0xd3, 0x1a, 0x81, 0x7f, + 0x90, 0x62, 0xab, 0xec, 0x5a, 0xc7, 0xa0, 0x7f, + 0x81, 0x32, 0x27, 0x9b, 0x29, 0x75, 0x7d, 0x1e, + 0x96, 0xc5, 0xfa, 0x0e, 0x7c, 0xe0, 0x60, 0x96, + 0x7a, 0xca, 0x94, 0xba, 0xe6, 0xb2, 0x69, 0xdd, + 0xc4, 0x7d, 0xbb, 0xd3, 0xc4, 0xb4, 0x6e, 0x00, + 0x86, 0x1f, 0x9d, 0x25, 0xe8, 0xae, 0xc7, 0x10, + 0x84, 0xdc, 0xc0, 0x34, 0x24, 0x6e, 0xf7, 0xfc, + 0xdd, 0x3d, 0x32, 0x7a, 0x43, 0x96, 0xd6, 0xc8, + 0x7b, 0xf4, 0x9b, 0x3d, 0xa7, 0x1e, 0xba, 0x4d, + 0xd0, 0x3b, 0x3d, 0x84, 0x9a, 0xd1, 0x25, 0x22, + 0x5d, 0x00, 0x44, 0xb0, 0x59, 0xb7, 0x40, 0xc5, + 0xa3, 0x53, 0x53, 0xaf, 0x8f, 0x9e, 0xfd, 0x8f, + 0x1e, 0x02, 0xd3, 0x4f, 0xf7, 0x09, 0xce, 0xc5, + 0xc6, 0x71, 0x5c, 0xe9, 0xe8, 0x7a, 0xb5, 0x6b, + 0xa4, 0xbf, 0x0b, 0xd9, 0xb6, 0xfa, 0x24, 0xb0, + 0xcd, 0x52, 0x22, 0x1d, 0x7e, 0xe8, 0x15, 0x2f, + 0x1e, 0x5e, 0xa2, 0xec, 0xd3, 0xa8, 0x02, 0x77, + 0xb9, 0x55, 0x9a, 0xcf, 0xcc, 0xd7, 0x08, 0x20, + 0xa5, 0xda, 0x39, 0x9a, 0x30, 0x76, 0x90, 0x37, + 0xa7, 0x60, 0xdf, 0x18, 0x12, 0x65, 0x17, 0xaa, + 0xdd, 0x48, 0xd5, 0x12, 0x1d, 0x4c, 0x83, 0x5d, + 0x81, 0x07, 0x1d, 0x18, 0x81, 0x40, 0x55, 0x60, + 0x8f, 0xa3, 0x6b, 0x34, 0x1e, 0xd5, 0xe6, 0xcf, + 0x52, 0x73, 0x77, 0x4a, 0x50, 0x4f, 0x1b, 0x0f, + 0x39, 0xc3, 0x0d, 0x16, 0xf9, 0xbb, 0x4c, 0x77, + 0xf6, 0x4e, 0xac, 0x9c, 0xfe, 0xe8, 0xbb, 0x52, + 0xa5, 0x0a, 0x0e, 0x9b, 0xf0, 0x0d, 0xef, 0xfb, + 0x6f, 0x89, 0x34, 0x7d, 0x47, 0xec, 0x14, 0x6a, + 0xf4, 0x0a, 0xe1, 0x60, 0x44, 0x73, 0x7b, 0xa0, + 0xab, 0x5b, 0x8c, 0x43, 0xa6, 0x05, 0x42, 0x61, + 0x46, 0xaa, 0x1c, 0xf5, 0xec, 0x2c, 0x86, 0x85, + 0x21, 0x99, 0xdf, 0x45, 0x8e, 0xf4, 0xd1, 0x1e, + 0xfb, 0xcd, 0x9b, 0x94, 0x32, 0xe0, 0xa0, 0xcc, + 0x4f, 0xad, 0xae, 0x44, 0x8b, 0x86, 0x27, 0x91, + 0xfe, 0x60, 0x9f, 0xf2, 0x63, 0x30, 0x6c, 0x5d, + 0x8d, 0xbc, 0xab, 0xd4, 0xf5, 0xa2, 0xb2, 0x74, + 0xe8, 0xd4, 0x95, 0xf2, 0xd6, 0x03, 0x8b, 0xc9, + 0xa3, 0x52, 0xe7, 0x63, 0x05, 0x64, 0x50, 0xe5, + 0x0a, 0x6a, 0xa0, 0x6c, 0x50, 0xcd, 0x37, 0x98, + 0xa8, 0x87, 0x02, 0x38, 0x5b, 0x6c, 0x02, 0x69, + 0x3d, 0x1f, 0x95, 0x74, 0x4d, 0x46, 0x76, 0x2a, + 0x9d, 0x62, 0xd4, 0xc7, 0x1b, 0xf9, 0x31, 0xa6, + 0x51, 0xee, 0x7b, 0xc8, 0xe4, 0x6e, 0x3a, 0xcf, + 0x4f, 0x4f, 0x49, 0x8a, 0xf5, 0x4f, 0x25, 0x93, + 0x23, 0x02, 0xef, 0x79, 0xa6, 0x27, 0xbe, 0x5a, + 0xe7, 0x74, 0xb7, 0xd7, 0xa8, 0xc1, 0xae, 0x55, + 0x88, 0xa4, 0xc7, 0x4d, 0xb7, 0x62, 0xf0, 0xf9, + 0x5b, 0xbf, 0x47, 0x5b, 0xfe, 0xcc, 0x0b, 0x89, + 0x19, 0x65, 0x4b, 0x6f, 0xdf, 0x4f, 0x7d, 0x4d, + 0x96, 0x42, 0x0d, 0x2a, 0xa1, 0xbd, 0x3e, 0x70, + 0x92, 0xba, 0xc8, 0x59, 0xd5, 0x1d, 0x3a, 0x98, + 0x53, 0x75, 0xa6, 0x32, 0xc8, 0x72, 0x03, 0x46, + 0x5f, 0x5c, 0x13, 0xa4, 0xdb, 0xc7, 0x55, 0x35, + 0x22, 0x0d, 0xc6, 0x17, 0x85, 0xbd, 0x46, 0x4b, + 0xfa, 0x1e, 0x49, 0xc2, 0xfe, 0x1e, 0xf9, 0x62, + 0x89, 0x56, 0x84, 0xdf, 0xa0, 0xfb, 0xfd, 0x93, + 0xa4, 0x25, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x82, 0x01, 0x8e, 0x30, 0x82, 0x01, 0x8a, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, + 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x84, 0x30, + 0x1b, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x14, + 0x30, 0x12, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, + 0x01, 0x82, 0x37, 0x15, 0x24, 0x06, 0x05, 0x67, + 0x81, 0x05, 0x08, 0x03, 0x30, 0x16, 0x06, 0x03, + 0x55, 0x1d, 0x20, 0x04, 0x0f, 0x30, 0x0d, 0x30, + 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, + 0x82, 0x37, 0x15, 0x1f, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, + 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, + 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, + 0x16, 0x04, 0x14, 0xb8, 0x5f, 0xd5, 0x67, 0xca, + 0x92, 0xc4, 0x0e, 0xcf, 0x0c, 0xd8, 0x1f, 0x6d, + 0x3f, 0x03, 0x55, 0x6f, 0x38, 0xa6, 0x51, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, + 0x30, 0x16, 0x80, 0x14, 0x7a, 0x8c, 0x0a, 0xce, + 0x2f, 0x48, 0x62, 0x17, 0xe2, 0x94, 0xd1, 0xae, + 0x55, 0xc1, 0x52, 0xec, 0x71, 0x74, 0xa4, 0x56, + 0x30, 0x70, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, + 0x69, 0x30, 0x67, 0x30, 0x65, 0xa0, 0x63, 0xa0, + 0x61, 0x86, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, + 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x6f, + 0x70, 0x73, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x4d, + 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, + 0x25, 0x32, 0x30, 0x54, 0x50, 0x4d, 0x25, 0x32, + 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x25, + 0x32, 0x30, 0x32, 0x30, 0x31, 0x34, 0x2e, 0x63, + 0x72, 0x6c, 0x30, 0x7d, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x71, + 0x30, 0x6f, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x61, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, + 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x70, 0x6b, 0x69, 0x6f, 0x70, 0x73, 0x2f, + 0x63, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x4d, 0x69, + 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x25, + 0x32, 0x30, 0x54, 0x50, 0x4d, 0x25, 0x32, 0x30, + 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x25, 0x32, + 0x30, 0x32, 0x30, 0x31, 0x34, 0x2e, 0x63, 0x72, + 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, + 0x03, 0x82, 0x02, 0x01, 0x00, 0x41, 0xaa, 0xfe, + 0x28, 0x6c, 0xf7, 0x6b, 0x53, 0xde, 0x77, 0xc0, + 0x80, 0x50, 0x94, 0xd9, 0xdb, 0x46, 0x8e, 0x6a, + 0x93, 0xa9, 0x10, 0x37, 0x27, 0x1f, 0xf5, 0x70, + 0xf1, 0xa8, 0xcf, 0xa1, 0x45, 0x86, 0x2a, 0xdd, + 0x8f, 0xb8, 0xb5, 0xc1, 0xe6, 0xcf, 0x8a, 0xfa, + 0x32, 0xa1, 0x4b, 0xb7, 0xa4, 0xbf, 0x0a, 0x48, + 0xcb, 0x42, 0x63, 0x71, 0xc1, 0x96, 0xb9, 0x3a, + 0x37, 0x84, 0x0e, 0x24, 0x39, 0xeb, 0x58, 0xce, + 0x3d, 0xb7, 0xa9, 0x44, 0x92, 0x59, 0xb9, 0xff, + 0xdb, 0x18, 0xbe, 0x6a, 0x5e, 0xe7, 0xce, 0xef, + 0xb8, 0x40, 0x53, 0xaf, 0xc1, 0x9b, 0xfb, 0x42, + 0x99, 0x7e, 0x9d, 0x05, 0x2b, 0x71, 0x0a, 0x7a, + 0x7a, 0x44, 0xd1, 0x31, 0xca, 0xf0, 0x5f, 0x74, + 0x85, 0xa9, 0xe2, 0xbc, 0xc8, 0x0c, 0xad, 0x57, + 0xd1, 0xe9, 0x48, 0x90, 0x88, 0x57, 0x86, 0xd7, + 0xc5, 0xc9, 0xe6, 0xb2, 0x5e, 0x5f, 0x13, 0xdc, + 0x10, 0x7f, 0xdf, 0x63, 0x8a, 0xd5, 0x9e, 0x90, + 0xc2, 0x75, 0x53, 0x1e, 0x68, 0x17, 0x2b, 0x03, + 0x29, 0x15, 0x03, 0xc5, 0x8c, 0x66, 0x3e, 0xae, + 0xbd, 0x4a, 0x32, 0x7e, 0x59, 0x89, 0x0b, 0x84, + 0xc2, 0xd9, 0x90, 0xfa, 0x02, 0x22, 0x90, 0x8d, + 0x9c, 0xb6, 0x0c, 0x4d, 0xe1, 0x28, 0x76, 0xd7, + 0x82, 0xc3, 0x36, 0xc2, 0xa3, 0x2a, 0x52, 0xe5, + 0xfe, 0x3c, 0x8f, 0xe3, 0x4b, 0xda, 0x6a, 0xdb, + 0xc0, 0x7a, 0x3c, 0x57, 0xfa, 0x85, 0x8f, 0xfb, + 0x62, 0xc3, 0xa1, 0x38, 0xce, 0x84, 0xf2, 0xba, + 0x12, 0xf4, 0x30, 0x2a, 0x4a, 0x94, 0xa9, 0x35, + 0x2c, 0x7d, 0x11, 0xc7, 0x68, 0x1f, 0x47, 0xaa, + 0x57, 0x43, 0x06, 0x70, 0x79, 0x8c, 0xb6, 0x3b, + 0x5d, 0x57, 0xf3, 0xf3, 0xc0, 0x2c, 0xc5, 0xde, + 0x41, 0x99, 0xf6, 0xdd, 0x55, 0x8a, 0xe4, 0x13, + 0xca, 0xc9, 0xec, 0x69, 0x93, 0x13, 0x48, 0xf0, + 0x5f, 0xda, 0x2e, 0xfd, 0xfb, 0xa9, 0x1b, 0x92, + 0xde, 0x49, 0x71, 0x37, 0x8c, 0x3f, 0xc2, 0x08, + 0x0a, 0x83, 0x25, 0xf1, 0x6e, 0x0a, 0xe3, 0x55, + 0x85, 0x96, 0x9a, 0x2d, 0xa2, 0xc0, 0xa1, 0xee, + 0xfe, 0x23, 0x3b, 0x69, 0x22, 0x03, 0xfd, 0xcc, + 0x8a, 0xdd, 0xb4, 0x53, 0x8d, 0x84, 0xa6, 0xac, + 0xe0, 0x1e, 0x07, 0xe5, 0xd7, 0xf9, 0xcb, 0xb9, + 0xe3, 0x9a, 0xb7, 0x84, 0x70, 0xa1, 0x93, 0xd6, + 0x02, 0x1e, 0xfe, 0xdb, 0x28, 0x7c, 0xf7, 0xd4, + 0x62, 0x6f, 0x80, 0x75, 0xc8, 0xd8, 0x35, 0x26, + 0x0c, 0xcb, 0x84, 0xed, 0xbb, 0x95, 0xdf, 0x7f, + 0xd5, 0xbb, 0x00, 0x96, 0x97, 0x32, 0xe7, 0xba, + 0xe8, 0x29, 0xb5, 0x1a, 0x51, 0x81, 0xbb, 0x04, + 0xd1, 0x21, 0x76, 0x34, 0x6d, 0x1e, 0x93, 0x96, + 0x1f, 0x96, 0x53, 0x5f, 0x5c, 0x9e, 0xf3, 0x9d, + 0x82, 0x1c, 0x39, 0x36, 0x59, 0xae, 0xc9, 0x3c, + 0x53, 0x4a, 0x67, 0x65, 0x6e, 0xbf, 0xa6, 0xac, + 0x3e, 0xda, 0xb2, 0xa7, 0x63, 0x07, 0x17, 0xe1, + 0x5b, 0xda, 0x6a, 0x31, 0x9f, 0xfb, 0xb4, 0xea, + 0xa1, 0x97, 0x08, 0x6e, 0xb2, 0x68, 0xf3, 0x72, + 0x76, 0x99, 0xe8, 0x00, 0x46, 0x88, 0x26, 0xe1, + 0x3c, 0x07, 0x2b, 0x78, 0x49, 0xda, 0x79, 0x3a, + 0xbd, 0x6f, 0xca, 0x5c, 0xa0, 0xa8, 0xed, 0x34, + 0xcc, 0xdb, 0x13, 0xe2, 0x51, 0x9b, 0x3d, 0x03, + 0xac, 0xc7, 0xf6, 0x32, 0xe1, 0x11, 0x5d, 0xe1, + 0xc5, 0xfd, 0x9e, 0x7a, 0xcd, 0x06, 0xb9, 0xe6, + 0xfc, 0xe0, 0x03, 0x31, 0xf4, 0x4a, 0xa9, 0x3b, + 0x79, 0x01, 0xb0, 0x64, 0x68, 0x9f, 0x6e, 0x76, + 0xa1, 0xcc, 0xec, 0x17, 0x41, 0x9d, 0xd4, 0x5b, + 0x4e, 0x9d, 0xe5, 0x46, 0xd4, 0x6b, 0x60, 0x2a, + 0x23, 0xb5, 0x7a, 0x89, 0x7c, 0x27, 0x96, 0x65, + 0x97, 0x56, 0xec, 0x98, 0xe3, 0x67, 0x70, 0x75, + 0x62, 0x41, 0x72, 0x65, 0x61, 0x59, 0x01, 0x36, + 0x00, 0x01, 0x00, 0x0b, 0x00, 0x06, 0x04, 0x72, + 0x00, 0x20, 0x9d, 0xff, 0xcb, 0xf3, 0x6c, 0x38, + 0x3a, 0xe6, 0x99, 0xfb, 0x98, 0x68, 0xdc, 0x6d, + 0xcb, 0x89, 0xd7, 0x15, 0x38, 0x84, 0xbe, 0x28, + 0x03, 0x92, 0x2c, 0x12, 0x41, 0x58, 0xbf, 0xad, + 0x22, 0xae, 0x00, 0x10, 0x00, 0x10, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc5, 0xb6, + 0x9c, 0x06, 0x1d, 0xcf, 0xb9, 0xf2, 0x5e, 0x99, + 0x7d, 0x6d, 0x73, 0xd8, 0x36, 0xc1, 0x4a, 0x90, + 0x05, 0x4d, 0x82, 0x57, 0xc1, 0xb6, 0x6a, 0xd1, + 0x43, 0x03, 0x85, 0xf8, 0x52, 0x4f, 0xd2, 0x27, + 0x91, 0x0b, 0xb5, 0x93, 0xa0, 0x68, 0xf8, 0x80, + 0x1b, 0xaa, 0x65, 0x97, 0x45, 0x11, 0x86, 0x34, + 0xd6, 0x67, 0xf8, 0xd5, 0x12, 0x79, 0x84, 0xee, + 0x70, 0x99, 0x00, 0x63, 0xa8, 0xb4, 0x43, 0x0b, + 0x4c, 0x57, 0x4a, 0xd6, 0x9b, 0x75, 0x63, 0x8a, + 0x46, 0x57, 0xdb, 0x14, 0xc8, 0x71, 0xd1, 0xb3, + 0x07, 0x68, 0x58, 0xbc, 0x55, 0x84, 0x80, 0x2a, + 0xd2, 0x36, 0x9f, 0xc1, 0x64, 0xa0, 0x11, 0x4b, + 0xc9, 0x32, 0x31, 0x3a, 0xd6, 0x87, 0x26, 0x1a, + 0x3a, 0x78, 0x3d, 0x89, 0xdb, 0x00, 0x28, 0x3b, + 0xae, 0x2b, 0x1b, 0x56, 0xe2, 0x8c, 0x4c, 0x63, + 0xac, 0x6e, 0x6c, 0xf7, 0xb5, 0x7d, 0x4d, 0x0b, + 0x9f, 0x06, 0xa0, 0x10, 0x35, 0x38, 0x20, 0x4d, + 0xcc, 0x07, 0xd7, 0x00, 0x4e, 0x86, 0xba, 0xfe, + 0x8b, 0xe4, 0x3f, 0x4a, 0xd6, 0xca, 0xbf, 0x67, + 0x40, 0x1a, 0xa4, 0xda, 0x82, 0x52, 0x15, 0xb8, + 0x14, 0x3a, 0x7c, 0xa9, 0x02, 0xc1, 0x01, 0x69, + 0xc6, 0x51, 0xd4, 0xbc, 0x1f, 0x95, 0xb2, 0xee, + 0x1f, 0xdd, 0xb5, 0x73, 0x16, 0x5e, 0x29, 0x3f, + 0x47, 0xac, 0x65, 0xfb, 0x63, 0x5c, 0xb9, 0xc8, + 0x13, 0x2d, 0xec, 0x85, 0xde, 0x71, 0x0d, 0x84, + 0x93, 0x74, 0x76, 0x91, 0xdd, 0x1d, 0x6d, 0x3d, + 0xc7, 0x36, 0x19, 0x19, 0x86, 0xde, 0x7c, 0xca, + 0xd6, 0xc6, 0x65, 0x7e, 0x4b, 0x24, 0x9c, 0xce, + 0x92, 0x6b, 0x1c, 0xe0, 0xa0, 0xa9, 0x6c, 0xc3, + 0xed, 0x4f, 0x2a, 0x54, 0x07, 0x00, 0x32, 0x5e, + 0x1b, 0x94, 0x37, 0xcd, 0xe2, 0x32, 0xa8, 0xd5, + 0x2c, 0xfb, 0x03, 0x9d, 0x79, 0xdf, 0x68, 0x63, + 0x65, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x58, + 0xa1, 0xff, 0x54, 0x43, 0x47, 0x80, 0x17, 0x00, + 0x22, 0x00, 0x0b, 0xdb, 0x1f, 0x74, 0x21, 0x4f, + 0xa9, 0x0d, 0x90, 0x64, 0xa2, 0x33, 0xbe, 0x3f, + 0xf1, 0x95, 0xb0, 0x4e, 0x3f, 0x02, 0xdc, 0xad, + 0xb0, 0x05, 0x13, 0xe6, 0x32, 0x5f, 0xed, 0x90, + 0x2c, 0xad, 0xc0, 0x00, 0x14, 0x58, 0x52, 0x07, + 0x5d, 0x64, 0x6c, 0x1f, 0xd1, 0x13, 0x7f, 0xc3, + 0x74, 0xf6, 0x4b, 0xe3, 0xa0, 0x2e, 0xb7, 0x71, + 0xda, 0x00, 0x00, 0x00, 0x00, 0x29, 0x3c, 0x64, + 0xdf, 0x95, 0x38, 0xba, 0x73, 0xe3, 0x57, 0x61, + 0xa0, 0x01, 0x24, 0x01, 0x08, 0xc9, 0xd6, 0xea, + 0x60, 0xe4, 0x00, 0x22, 0x00, 0x0b, 0xe1, 0x86, + 0xbb, 0x79, 0x27, 0xe5, 0x01, 0x19, 0x90, 0xb3, + 0xe9, 0x08, 0xb0, 0xee, 0xfa, 0x3a, 0x67, 0xa9, + 0xf3, 0xc8, 0x9e, 0x03, 0x41, 0x07, 0x75, 0x60, + 0xbc, 0x94, 0x0c, 0x2a, 0xb7, 0xad, 0x00, 0x22, + 0x00, 0x0b, 0x35, 0xb1, 0x72, 0xd6, 0x3c, 0xe9, + 0x85, 0xe8, 0x66, 0xed, 0x10, 0x7a, 0x5c, 0xa3, + 0xe6, 0xd9, 0x4d, 0xf0, 0x52, 0x69, 0x26, 0x14, + 0xb4, 0x36, 0x7e, 0xad, 0x76, 0x9e, 0x58, 0x68, + 0x3e, 0x91 +}; + /* * Security Key By Yubico * 5.1.X * f8a011f3-8c0a-4d15-8006-17111f9edc7d -*/ + */ const unsigned char aaguid[16] = { 0xf8, 0xa0, 0x11, 0xf3, 0x8c, 0x0a, 0x4d, 0x15, 0x80, 0x06, 0x17, 0x11, 0x1f, 0x9e, 0xdc, 0x7d, }; +/* + * Windows Hello by Microsoft + */ +const unsigned char aaguid_tpm[16] = { + 0x08, 0x98, 0x70, 0x58, 0xca, 0xdc, 0x4b, 0x81, + 0xb6, 0xe1, 0x30, 0xde, 0x50, 0xdc, 0xbe, 0x96, +}; + const char rp_id[] = "localhost"; const char rp_name[] = "sweet home localhost"; @@ -606,7 +1214,7 @@ junk_cdh(void) junk = malloc(sizeof(cdh)); assert(junk != NULL); memcpy(junk, cdh, sizeof(cdh)); - junk[0] = ~junk[0]; + junk[0] = (unsigned char)~junk[0]; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); @@ -708,7 +1316,7 @@ junk_authdata(void) junk = malloc(sizeof(authdata)); assert(junk != NULL); memcpy(junk, authdata, sizeof(authdata)); - junk[0] = ~junk[0]; + junk[0] = (unsigned char)~junk[0]; unset = calloc(1, sizeof(aaguid)); assert(unset != NULL); @@ -749,7 +1357,7 @@ junk_sig(void) junk = malloc(sizeof(sig)); assert(junk != NULL); memcpy(junk, sig, sizeof(sig)); - junk[0] = ~junk[0]; + junk[0] = (unsigned char)~junk[0]; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); @@ -781,7 +1389,7 @@ junk_x509(void) junk = malloc(sizeof(x509)); assert(junk != NULL); memcpy(junk, x509, sizeof(x509)); - junk[0] = ~junk[0]; + junk[0] = (unsigned char)~junk[0]; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); @@ -954,6 +1562,31 @@ fmt_none(void) free_cred(c); } +static void +valid_tpm_cred(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_RS256) == FIDO_OK); + assert(fido_cred_set_clientdata(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata_tpm, sizeof(authdata_tpm)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_TRUE) == FIDO_OK); + assert(fido_cred_set_fmt(c, "tpm") == FIDO_OK); + assert(fido_cred_set_attstmt(c, attstmt_tpm, sizeof(attstmt_tpm)) == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_OK); + assert(fido_cred_prot(c) == 0); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey_tpm)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey_tpm, sizeof(pubkey_tpm)) == 0); + assert(fido_cred_id_len(c) == sizeof(id_tpm)); + assert(memcmp(fido_cred_id_ptr(c), id_tpm, sizeof(id_tpm)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid_tpm)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid_tpm, sizeof(aaguid_tpm)) == 0); + free_cred(c); +} + int main(void) { @@ -983,6 +1616,7 @@ main(void) wrong_credprot(); raw_authdata(); fmt_none(); + valid_tpm_cred(); exit(0); } diff --git a/contrib/libfido2/regress/dev.c b/contrib/libfido2/regress/dev.c index 35061aabbb64..a5dc8d6e4529 100644 --- a/contrib/libfido2/regress/dev.c +++ b/contrib/libfido2/regress/dev.c @@ -1,12 +1,14 @@ /* - * Copyright (c) 2019 Yubico AB. All rights reserved. + * Copyright (c) 2019-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ #include <assert.h> +#include <err.h> #include <fido.h> #include <string.h> +#include <time.h> #include "../fuzz/wiredata_fido2.h" @@ -17,6 +19,7 @@ static uint8_t ctap_nonce[8]; static uint8_t *wiredata_ptr; static size_t wiredata_len; static int initialised; +static long interval_ms; static void * dummy_open(const char *path) @@ -35,9 +38,9 @@ dummy_close(void *handle) static int dummy_read(void *handle, unsigned char *ptr, size_t len, int ms) { - size_t n; - - (void)ms; + struct timespec tv; + size_t n; + long d; assert(handle == FAKE_DEV_HANDLE); assert(ptr != NULL); @@ -52,6 +55,21 @@ dummy_read(void *handle, unsigned char *ptr, size_t len, int ms) initialised = 1; } + if (ms >= 0 && ms < interval_ms) + d = ms; + else + d = interval_ms; + + if (d) { + tv.tv_sec = d / 1000; + tv.tv_nsec = (d % 1000) * 1000000; + if (nanosleep(&tv, NULL) == -1) + err(1, "nanosleep"); + } + + if (d != interval_ms) + return (-1); /* timeout */ + if (wiredata_len < len) n = wiredata_len; else @@ -67,6 +85,8 @@ dummy_read(void *handle, unsigned char *ptr, size_t len, int ms) static int dummy_write(void *handle, const unsigned char *ptr, size_t len) { + struct timespec tv; + assert(handle == FAKE_DEV_HANDLE); assert(ptr != NULL); assert(len == REPORT_LEN); @@ -74,6 +94,13 @@ dummy_write(void *handle, const unsigned char *ptr, size_t len) if (!initialised) memcpy(&ctap_nonce, &ptr[8], sizeof(ctap_nonce)); + if (interval_ms) { + tv.tv_sec = interval_ms / 1000; + tv.tv_nsec = (interval_ms % 1000) * 1000000; + if (nanosleep(&tv, NULL) == -1) + err(1, "nanosleep"); + } + return ((int)len); } @@ -153,6 +180,7 @@ reopen(void) wiredata = wiredata_setup(cbor_info_data, sizeof(cbor_info_data)); assert(fido_dev_open(dev, "dummy") == FIDO_OK); assert(fido_dev_close(dev) == FIDO_OK); + fido_dev_free(&dev); wiredata_clear(&wiredata); } @@ -177,6 +205,34 @@ double_open(void) assert(fido_dev_open(dev, "dummy") == FIDO_OK); assert(fido_dev_open(dev, "dummy") == FIDO_ERR_INVALID_ARGUMENT); assert(fido_dev_close(dev) == FIDO_OK); + fido_dev_free(&dev); + wiredata_clear(&wiredata); +} + +static void +double_close(void) +{ + const uint8_t cbor_info_data[] = { WIREDATA_CTAP_CBOR_INFO }; + uint8_t *wiredata; + fido_dev_t *dev = NULL; + fido_dev_io_t io; + + memset(&io, 0, sizeof(io)); + + io.open = dummy_open; + io.close = dummy_close; + io.read = dummy_read; + io.write = dummy_write; + + wiredata = wiredata_setup(cbor_info_data, sizeof(cbor_info_data)); + assert((dev = fido_dev_new()) != NULL); + assert(fido_dev_close(dev) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK); + assert(fido_dev_close(dev) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_dev_open(dev, "dummy") == FIDO_OK); + assert(fido_dev_close(dev) == FIDO_OK); + assert(fido_dev_close(dev) == FIDO_ERR_INVALID_ARGUMENT); + fido_dev_free(&dev); wiredata_clear(&wiredata); } @@ -215,6 +271,7 @@ is_fido2(void) assert(fido_dev_is_fido2(dev) == true); assert(fido_dev_supports_pin(dev) == false); assert(fido_dev_close(dev) == FIDO_OK); + fido_dev_free(&dev); wiredata_clear(&wiredata); } @@ -248,9 +305,94 @@ has_pin(void) assert(fido_dev_reset(dev) == FIDO_OK); assert(fido_dev_has_pin(dev) == false); assert(fido_dev_close(dev) == FIDO_OK); + fido_dev_free(&dev); wiredata_clear(&wiredata); } +static void +timeout_rx(void) +{ + const uint8_t timeout_rx_data[] = { + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_CBOR_STATUS + }; + uint8_t *wiredata; + fido_dev_t *dev = NULL; + fido_dev_io_t io; + + memset(&io, 0, sizeof(io)); + + io.open = dummy_open; + io.close = dummy_close; + io.read = dummy_read; + io.write = dummy_write; + + wiredata = wiredata_setup(timeout_rx_data, sizeof(timeout_rx_data)); + assert((dev = fido_dev_new()) != NULL); + assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK); + assert(fido_dev_open(dev, "dummy") == FIDO_OK); + assert(fido_dev_set_timeout(dev, 3 * 1000) == FIDO_OK); + interval_ms = 1000; + assert(fido_dev_reset(dev) == FIDO_ERR_RX); + assert(fido_dev_close(dev) == FIDO_OK); + fido_dev_free(&dev); + wiredata_clear(&wiredata); + interval_ms = 0; +} + +static void +timeout_ok(void) +{ + const uint8_t timeout_ok_data[] = { + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_CBOR_STATUS + }; + uint8_t *wiredata; + fido_dev_t *dev = NULL; + fido_dev_io_t io; + + memset(&io, 0, sizeof(io)); + + io.open = dummy_open; + io.close = dummy_close; + io.read = dummy_read; + io.write = dummy_write; + + wiredata = wiredata_setup(timeout_ok_data, sizeof(timeout_ok_data)); + assert((dev = fido_dev_new()) != NULL); + assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK); + assert(fido_dev_open(dev, "dummy") == FIDO_OK); + assert(fido_dev_set_timeout(dev, 30 * 1000) == FIDO_OK); + interval_ms = 1000; + assert(fido_dev_reset(dev) == FIDO_OK); + assert(fido_dev_close(dev) == FIDO_OK); + fido_dev_free(&dev); + wiredata_clear(&wiredata); + interval_ms = 0; +} + +static void +timeout_misc(void) +{ + fido_dev_t *dev; + + assert((dev = fido_dev_new()) != NULL); + assert(fido_dev_set_timeout(dev, -2) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_dev_set_timeout(dev, 3 * 1000) == FIDO_OK); + assert(fido_dev_set_timeout(dev, -1) == FIDO_OK); + fido_dev_free(&dev); +} + int main(void) { @@ -259,8 +401,12 @@ main(void) open_iff_ok(); reopen(); double_open(); + double_close(); is_fido2(); has_pin(); + timeout_rx(); + timeout_ok(); + timeout_misc(); exit(0); } diff --git a/contrib/libfido2/src/CMakeLists.txt b/contrib/libfido2/src/CMakeLists.txt index f9efd3f234ed..bd14a62f0c99 100644 --- a/contrib/libfido2/src/CMakeLists.txt +++ b/contrib/libfido2/src/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2018 Yubico AB. All rights reserved. +# Copyright (c) 2018-2021 Yubico AB. All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. @@ -30,11 +30,16 @@ list(APPEND FIDO_SOURCES pin.c random.c reset.c + rs1.c rs256.c + time.c + tpm.c + types.c u2f.c ) if(FUZZ) + list(APPEND FIDO_SOURCES ../fuzz/clock.c) list(APPEND FIDO_SOURCES ../fuzz/prng.c) list(APPEND FIDO_SOURCES ../fuzz/uniform_random.c) list(APPEND FIDO_SOURCES ../fuzz/udev.c) @@ -62,7 +67,8 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "NetBSD") list(APPEND FIDO_SOURCES hid_netbsd.c hid_unix.c) elseif(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") list(APPEND FIDO_SOURCES hid_openbsd.c hid_unix.c) -elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") +elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR + CMAKE_SYSTEM_NAME STREQUAL "MidnightBSD") list(APPEND FIDO_SOURCES hid_freebsd.c hid_unix.c) else() message(FATAL_ERROR "please define a hid backend for your platform") @@ -75,11 +81,11 @@ endif() list(APPEND COMPAT_SOURCES ../openbsd-compat/bsd-getpagesize.c + ../openbsd-compat/clock_gettime.c ../openbsd-compat/endian_win32.c ../openbsd-compat/explicit_bzero.c ../openbsd-compat/explicit_bzero_win32.c ../openbsd-compat/freezero.c - ../openbsd-compat/hkdf.c ../openbsd-compat/recallocarray.c ../openbsd-compat/strlcat.c ../openbsd-compat/timingsafe_bcmp.c @@ -87,9 +93,6 @@ list(APPEND COMPAT_SOURCES if(WIN32) list(APPEND BASE_LIBRARIES wsock32 ws2_32 bcrypt setupapi hid) - if(USE_WINHELLO) - list(APPEND BASE_LIBRARIES webauthn) - endif() elseif(APPLE) list(APPEND BASE_LIBRARIES "-framework CoreFoundation" "-framework IOKit") endif() diff --git a/contrib/libfido2/src/assert.c b/contrib/libfido2/src/assert.c index b36f8e324660..949af919d25e 100644 --- a/contrib/libfido2/src/assert.c +++ b/contrib/libfido2/src/assert.c @@ -4,7 +4,6 @@ * license that can be found in the LICENSE file. */ -#include <openssl/ecdsa.h> #include <openssl/sha.h> #include "fido.h" @@ -79,7 +78,7 @@ parse_assert_reply(const cbor_item_t *key, const cbor_item_t *val, void *arg) static int fido_dev_get_assert_tx(fido_dev_t *dev, fido_assert_t *assert, - const es256_pk_t *pk, const fido_blob_t *ecdh, const char *pin) + const es256_pk_t *pk, const fido_blob_t *ecdh, const char *pin, int *ms) { fido_blob_t f; fido_opt_t uv = assert->uv; @@ -127,7 +126,7 @@ fido_dev_get_assert_tx(fido_dev_t *dev, fido_assert_t *assert, if (pin != NULL || (uv == FIDO_OPT_TRUE && fido_dev_supports_permissions(dev))) { if ((r = cbor_add_uv_params(dev, cmd, &assert->cdh, pk, ecdh, - pin, assert->rp_id, &argv[5], &argv[6])) != FIDO_OK) { + pin, assert->rp_id, &argv[5], &argv[6], ms)) != FIDO_OK) { fido_log_debug("%s: cbor_add_uv_params", __func__); goto fail; } @@ -144,7 +143,7 @@ fido_dev_get_assert_tx(fido_dev_t *dev, fido_assert_t *assert, /* frame and transmit */ if (cbor_build_frame(cmd, argv, nitems(argv), &f) < 0 || - fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { + fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -159,7 +158,7 @@ fail: } static int -fido_dev_get_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int ms) +fido_dev_get_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; @@ -200,11 +199,11 @@ fido_dev_get_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int ms) } static int -fido_get_next_assert_tx(fido_dev_t *dev) +fido_get_next_assert_tx(fido_dev_t *dev, int *ms) { const unsigned char cbor[] = { CTAP_CBOR_NEXT_ASSERT }; - if (fido_tx(dev, CTAP_CMD_CBOR, cbor, sizeof(cbor)) < 0) { + if (fido_tx(dev, CTAP_CMD_CBOR, cbor, sizeof(cbor), ms) < 0) { fido_log_debug("%s: fido_tx", __func__); return (FIDO_ERR_TX); } @@ -213,7 +212,7 @@ fido_get_next_assert_tx(fido_dev_t *dev) } static int -fido_get_next_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int ms) +fido_get_next_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; @@ -243,16 +242,17 @@ fido_get_next_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int ms) static int fido_dev_get_assert_wait(fido_dev_t *dev, fido_assert_t *assert, - const es256_pk_t *pk, const fido_blob_t *ecdh, const char *pin, int ms) + const es256_pk_t *pk, const fido_blob_t *ecdh, const char *pin, int *ms) { int r; - if ((r = fido_dev_get_assert_tx(dev, assert, pk, ecdh, pin)) != FIDO_OK || + if ((r = fido_dev_get_assert_tx(dev, assert, pk, ecdh, pin, + ms)) != FIDO_OK || (r = fido_dev_get_assert_rx(dev, assert, ms)) != FIDO_OK) return (r); while (assert->stmt_len < assert->stmt_cnt) { - if ((r = fido_get_next_assert_tx(dev)) != FIDO_OK || + if ((r = fido_get_next_assert_tx(dev, ms)) != FIDO_OK || (r = fido_get_next_assert_rx(dev, assert, ms)) != FIDO_OK) return (r); assert->stmt_len++; @@ -286,11 +286,12 @@ fido_dev_get_assert(fido_dev_t *dev, fido_assert_t *assert, const char *pin) { fido_blob_t *ecdh = NULL; es256_pk_t *pk = NULL; + int ms = dev->timeout_ms; int r; #ifdef USE_WINHELLO if (dev->flags & FIDO_DEV_WINHELLO) - return (fido_winhello_get_assert(dev, assert, pin)); + return (fido_winhello_get_assert(dev, assert, pin, ms)); #endif if (assert->rp_id == NULL || assert->cdh.ptr == NULL) { @@ -302,19 +303,19 @@ fido_dev_get_assert(fido_dev_t *dev, fido_assert_t *assert, const char *pin) if (fido_dev_is_fido2(dev) == false) { if (pin != NULL || assert->ext.mask != 0) return (FIDO_ERR_UNSUPPORTED_OPTION); - return (u2f_authenticate(dev, assert, -1)); + return (u2f_authenticate(dev, assert, &ms)); } if (pin != NULL || (assert->uv == FIDO_OPT_TRUE && fido_dev_supports_permissions(dev)) || (assert->ext.mask & FIDO_EXT_HMAC_SECRET)) { - if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) { + if ((r = fido_do_ecdh(dev, &pk, &ecdh, &ms)) != FIDO_OK) { fido_log_debug("%s: fido_do_ecdh", __func__); goto fail; } } - r = fido_dev_get_assert_wait(dev, assert, pk, ecdh, pin, -1); + r = fido_dev_get_assert_wait(dev, assert, pk, ecdh, pin, &ms); if (r == FIDO_OK && (assert->ext.mask & FIDO_EXT_HMAC_SECRET)) if (decrypt_hmac_secrets(dev, assert, ecdh) < 0) { fido_log_debug("%s: decrypt_hmac_secrets", __func__); @@ -372,7 +373,8 @@ fido_get_signed_hash(int cose_alg, fido_blob_t *dgst, unsigned char *authdata_ptr = NULL; size_t authdata_len; struct cbor_load_result cbor; - SHA256_CTX ctx; + const EVP_MD *md = NULL; + EVP_MD_CTX *ctx = NULL; int ok = -1; if ((item = cbor_load(authdata_cbor->ptr, authdata_cbor->len, @@ -386,10 +388,13 @@ fido_get_signed_hash(int cose_alg, fido_blob_t *dgst, authdata_len = cbor_bytestring_length(item); if (cose_alg != COSE_EDDSA) { - if (dgst->len < SHA256_DIGEST_LENGTH || SHA256_Init(&ctx) == 0 || - SHA256_Update(&ctx, authdata_ptr, authdata_len) == 0 || - SHA256_Update(&ctx, clientdata->ptr, clientdata->len) == 0 || - SHA256_Final(dgst->ptr, &ctx) == 0) { + if (dgst->len < SHA256_DIGEST_LENGTH || + (md = EVP_sha256()) == NULL || + (ctx = EVP_MD_CTX_new()) == NULL || + EVP_DigestInit_ex(ctx, md, NULL) != 1 || + EVP_DigestUpdate(ctx, authdata_ptr, authdata_len) != 1 || + EVP_DigestUpdate(ctx, clientdata->ptr, clientdata->len) != 1 || + EVP_DigestFinal_ex(ctx, dgst->ptr, NULL) != 1) { fido_log_debug("%s: sha256", __func__); goto fail; } @@ -411,122 +416,7 @@ fail: if (item != NULL) cbor_decref(&item); - return (ok); -} - -int -fido_verify_sig_es256(const fido_blob_t *dgst, const es256_pk_t *pk, - const fido_blob_t *sig) -{ - EVP_PKEY *pkey = NULL; - EC_KEY *ec = NULL; - int ok = -1; - - /* ECDSA_verify needs ints */ - if (dgst->len > INT_MAX || sig->len > INT_MAX) { - fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__, - dgst->len, sig->len); - return (-1); - } - - if ((pkey = es256_pk_to_EVP_PKEY(pk)) == NULL || - (ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) { - fido_log_debug("%s: pk -> ec", __func__); - goto fail; - } - - if (ECDSA_verify(0, dgst->ptr, (int)dgst->len, sig->ptr, - (int)sig->len, ec) != 1) { - fido_log_debug("%s: ECDSA_verify", __func__); - goto fail; - } - - ok = 0; -fail: - if (pkey != NULL) - EVP_PKEY_free(pkey); - - return (ok); -} - -int -fido_verify_sig_rs256(const fido_blob_t *dgst, const rs256_pk_t *pk, - const fido_blob_t *sig) -{ - EVP_PKEY *pkey = NULL; - RSA *rsa = NULL; - int ok = -1; - - /* RSA_verify needs unsigned ints */ - if (dgst->len > UINT_MAX || sig->len > UINT_MAX) { - fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__, - dgst->len, sig->len); - return (-1); - } - - if ((pkey = rs256_pk_to_EVP_PKEY(pk)) == NULL || - (rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) { - fido_log_debug("%s: pk -> ec", __func__); - goto fail; - } - - if (RSA_verify(NID_sha256, dgst->ptr, (unsigned int)dgst->len, sig->ptr, - (unsigned int)sig->len, rsa) != 1) { - fido_log_debug("%s: RSA_verify", __func__); - goto fail; - } - - ok = 0; -fail: - if (pkey != NULL) - EVP_PKEY_free(pkey); - - return (ok); -} - -int -fido_verify_sig_eddsa(const fido_blob_t *dgst, const eddsa_pk_t *pk, - const fido_blob_t *sig) -{ - EVP_PKEY *pkey = NULL; - EVP_MD_CTX *mdctx = NULL; - int ok = -1; - - /* EVP_DigestVerify needs ints */ - if (dgst->len > INT_MAX || sig->len > INT_MAX) { - fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__, - dgst->len, sig->len); - return (-1); - } - - if ((pkey = eddsa_pk_to_EVP_PKEY(pk)) == NULL) { - fido_log_debug("%s: pk -> pkey", __func__); - goto fail; - } - - if ((mdctx = EVP_MD_CTX_new()) == NULL) { - fido_log_debug("%s: EVP_MD_CTX_new", __func__); - goto fail; - } - - if (EVP_DigestVerifyInit(mdctx, NULL, NULL, NULL, pkey) != 1) { - fido_log_debug("%s: EVP_DigestVerifyInit", __func__); - goto fail; - } - - if (EVP_DigestVerify(mdctx, sig->ptr, sig->len, dgst->ptr, - dgst->len) != 1) { - fido_log_debug("%s: EVP_DigestVerify", __func__); - goto fail; - } - - ok = 0; -fail: - if (mdctx != NULL) - EVP_MD_CTX_free(mdctx); - - if (pkey != NULL) - EVP_PKEY_free(pkey); + EVP_MD_CTX_free(ctx); return (ok); } @@ -589,13 +479,13 @@ fido_assert_verify(const fido_assert_t *assert, size_t idx, int cose_alg, switch (cose_alg) { case COSE_ES256: - ok = fido_verify_sig_es256(&dgst, pk, &stmt->sig); + ok = es256_pk_verify_sig(&dgst, pk, &stmt->sig); break; case COSE_RS256: - ok = fido_verify_sig_rs256(&dgst, pk, &stmt->sig); + ok = rs256_pk_verify_sig(&dgst, pk, &stmt->sig); break; case COSE_EDDSA: - ok = fido_verify_sig_eddsa(&dgst, pk, &stmt->sig); + ok = eddsa_pk_verify_sig(&dgst, pk, &stmt->sig); break; default: fido_log_debug("%s: unsupported cose_alg %d", __func__, diff --git a/contrib/libfido2/src/authkey.c b/contrib/libfido2/src/authkey.c index c3474ccafc01..33e0a8d44bd2 100644 --- a/contrib/libfido2/src/authkey.c +++ b/contrib/libfido2/src/authkey.c @@ -22,7 +22,7 @@ parse_authkey(const cbor_item_t *key, const cbor_item_t *val, void *arg) } static int -fido_dev_authkey_tx(fido_dev_t *dev) +fido_dev_authkey_tx(fido_dev_t *dev, int *ms) { fido_blob_t f; cbor_item_t *argv[2]; @@ -43,7 +43,7 @@ fido_dev_authkey_tx(fido_dev_t *dev) /* frame and transmit */ if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv), - &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { + &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -58,13 +58,13 @@ fail: } static int -fido_dev_authkey_rx(fido_dev_t *dev, es256_pk_t *authkey, int ms) +fido_dev_authkey_rx(fido_dev_t *dev, es256_pk_t *authkey, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; fido_log_debug("%s: dev=%p, authkey=%p, ms=%d", __func__, (void *)dev, - (void *)authkey, ms); + (void *)authkey, *ms); memset(authkey, 0, sizeof(*authkey)); @@ -79,11 +79,11 @@ fido_dev_authkey_rx(fido_dev_t *dev, es256_pk_t *authkey, int ms) } static int -fido_dev_authkey_wait(fido_dev_t *dev, es256_pk_t *authkey, int ms) +fido_dev_authkey_wait(fido_dev_t *dev, es256_pk_t *authkey, int *ms) { int r; - if ((r = fido_dev_authkey_tx(dev)) != FIDO_OK || + if ((r = fido_dev_authkey_tx(dev, ms)) != FIDO_OK || (r = fido_dev_authkey_rx(dev, authkey, ms)) != FIDO_OK) return (r); @@ -91,7 +91,7 @@ fido_dev_authkey_wait(fido_dev_t *dev, es256_pk_t *authkey, int ms) } int -fido_dev_authkey(fido_dev_t *dev, es256_pk_t *authkey) +fido_dev_authkey(fido_dev_t *dev, es256_pk_t *authkey, int *ms) { - return (fido_dev_authkey_wait(dev, authkey, -1)); + return (fido_dev_authkey_wait(dev, authkey, ms)); } diff --git a/contrib/libfido2/src/bio.c b/contrib/libfido2/src/bio.c index 06bc32eea7ed..4ddc93749cc3 100644 --- a/contrib/libfido2/src/bio.c +++ b/contrib/libfido2/src/bio.c @@ -58,7 +58,7 @@ fail: static int bio_tx(fido_dev_t *dev, uint8_t subcmd, cbor_item_t **sub_argv, size_t sub_argc, - const char *pin, const fido_blob_t *token) + const char *pin, const fido_blob_t *token, int *ms) { cbor_item_t *argv[5]; es256_pk_t *pk = NULL; @@ -90,12 +90,12 @@ bio_tx(fido_dev_t *dev, uint8_t subcmd, cbor_item_t **sub_argv, size_t sub_argc, /* pinProtocol, pinAuth */ if (pin) { - if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) { + if ((r = fido_do_ecdh(dev, &pk, &ecdh, ms)) != FIDO_OK) { fido_log_debug("%s: fido_do_ecdh", __func__); goto fail; } if ((r = cbor_add_uv_params(dev, cmd, &hmac, pk, ecdh, pin, - NULL, &argv[4], &argv[3])) != FIDO_OK) { + NULL, &argv[4], &argv[3], ms)) != FIDO_OK) { fido_log_debug("%s: cbor_add_uv_params", __func__); goto fail; } @@ -109,7 +109,7 @@ bio_tx(fido_dev_t *dev, uint8_t subcmd, cbor_item_t **sub_argv, size_t sub_argc, /* framing and transmission */ if (cbor_build_frame(cmd, argv, nitems(argv), &f) < 0 || - fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { + fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -231,7 +231,7 @@ bio_parse_template_array(const cbor_item_t *key, const cbor_item_t *val, } static int -bio_rx_template_array(fido_dev_t *dev, fido_bio_template_array_t *ta, int ms) +bio_rx_template_array(fido_dev_t *dev, fido_bio_template_array_t *ta, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; @@ -256,11 +256,11 @@ bio_rx_template_array(fido_dev_t *dev, fido_bio_template_array_t *ta, int ms) static int bio_get_template_array_wait(fido_dev_t *dev, fido_bio_template_array_t *ta, - const char *pin, int ms) + const char *pin, int *ms) { int r; - if ((r = bio_tx(dev, CMD_ENUM, NULL, 0, pin, NULL)) != FIDO_OK || + if ((r = bio_tx(dev, CMD_ENUM, NULL, 0, pin, NULL, ms)) != FIDO_OK || (r = bio_rx_template_array(dev, ta, ms)) != FIDO_OK) return (r); @@ -271,15 +271,17 @@ int fido_bio_dev_get_template_array(fido_dev_t *dev, fido_bio_template_array_t *ta, const char *pin) { + int ms = dev->timeout_ms; + if (pin == NULL) return (FIDO_ERR_INVALID_ARGUMENT); - return (bio_get_template_array_wait(dev, ta, pin, -1)); + return (bio_get_template_array_wait(dev, ta, pin, &ms)); } static int bio_set_template_name_wait(fido_dev_t *dev, const fido_bio_template_t *t, - const char *pin, int ms) + const char *pin, int *ms) { cbor_item_t *argv[2]; int r = FIDO_ERR_INTERNAL; @@ -292,7 +294,8 @@ bio_set_template_name_wait(fido_dev_t *dev, const fido_bio_template_t *t, goto fail; } - if ((r = bio_tx(dev, CMD_SET_NAME, argv, 2, pin, NULL)) != FIDO_OK || + if ((r = bio_tx(dev, CMD_SET_NAME, argv, 2, pin, NULL, + ms)) != FIDO_OK || (r = fido_rx_cbor_status(dev, ms)) != FIDO_OK) { fido_log_debug("%s: tx/rx", __func__); goto fail; @@ -309,10 +312,12 @@ int fido_bio_dev_set_template_name(fido_dev_t *dev, const fido_bio_template_t *t, const char *pin) { + int ms = dev->timeout_ms; + if (pin == NULL || t->name == NULL) return (FIDO_ERR_INVALID_ARGUMENT); - return (bio_set_template_name_wait(dev, t, pin, -1)); + return (bio_set_template_name_wait(dev, t, pin, &ms)); } static void @@ -378,7 +383,7 @@ bio_parse_template_id(const cbor_item_t *key, const cbor_item_t *val, static int bio_rx_enroll_begin(fido_dev_t *dev, fido_bio_template_t *t, - fido_bio_enroll_t *e, int ms) + fido_bio_enroll_t *e, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; @@ -411,7 +416,7 @@ bio_rx_enroll_begin(fido_dev_t *dev, fido_bio_template_t *t, static int bio_enroll_begin_wait(fido_dev_t *dev, fido_bio_template_t *t, - fido_bio_enroll_t *e, uint32_t timo_ms, int ms) + fido_bio_enroll_t *e, uint32_t timo_ms, int *ms) { cbor_item_t *argv[3]; const uint8_t cmd = CMD_ENROLL_BEGIN; @@ -424,7 +429,7 @@ bio_enroll_begin_wait(fido_dev_t *dev, fido_bio_template_t *t, goto fail; } - if ((r = bio_tx(dev, cmd, argv, 3, NULL, e->token)) != FIDO_OK || + if ((r = bio_tx(dev, cmd, argv, 3, NULL, e->token, ms)) != FIDO_OK || (r = bio_rx_enroll_begin(dev, t, e, ms)) != FIDO_OK) { fido_log_debug("%s: tx/rx", __func__); goto fail; @@ -444,6 +449,7 @@ fido_bio_dev_enroll_begin(fido_dev_t *dev, fido_bio_template_t *t, es256_pk_t *pk = NULL; fido_blob_t *ecdh = NULL; fido_blob_t *token = NULL; + int ms = dev->timeout_ms; int r; if (pin == NULL || e->token != NULL) @@ -454,13 +460,13 @@ fido_bio_dev_enroll_begin(fido_dev_t *dev, fido_bio_template_t *t, goto fail; } - if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) { + if ((r = fido_do_ecdh(dev, &pk, &ecdh, &ms)) != FIDO_OK) { fido_log_debug("%s: fido_do_ecdh", __func__); goto fail; } if ((r = fido_dev_get_uv_token(dev, CTAP_CBOR_BIO_ENROLL_PRE, pin, ecdh, - pk, NULL, token)) != FIDO_OK) { + pk, NULL, token, &ms)) != FIDO_OK) { fido_log_debug("%s: fido_dev_get_uv_token", __func__); goto fail; } @@ -475,11 +481,11 @@ fail: if (r != FIDO_OK) return (r); - return (bio_enroll_begin_wait(dev, t, e, timo_ms, -1)); + return (bio_enroll_begin_wait(dev, t, e, timo_ms, &ms)); } static int -bio_rx_enroll_continue(fido_dev_t *dev, fido_bio_enroll_t *e, int ms) +bio_rx_enroll_continue(fido_dev_t *dev, fido_bio_enroll_t *e, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; @@ -505,7 +511,7 @@ bio_rx_enroll_continue(fido_dev_t *dev, fido_bio_enroll_t *e, int ms) static int bio_enroll_continue_wait(fido_dev_t *dev, const fido_bio_template_t *t, - fido_bio_enroll_t *e, uint32_t timo_ms, int ms) + fido_bio_enroll_t *e, uint32_t timo_ms, int *ms) { cbor_item_t *argv[3]; const uint8_t cmd = CMD_ENROLL_NEXT; @@ -519,7 +525,7 @@ bio_enroll_continue_wait(fido_dev_t *dev, const fido_bio_template_t *t, goto fail; } - if ((r = bio_tx(dev, cmd, argv, 3, NULL, e->token)) != FIDO_OK || + if ((r = bio_tx(dev, cmd, argv, 3, NULL, e->token, ms)) != FIDO_OK || (r = bio_rx_enroll_continue(dev, e, ms)) != FIDO_OK) { fido_log_debug("%s: tx/rx", __func__); goto fail; @@ -536,19 +542,21 @@ int fido_bio_dev_enroll_continue(fido_dev_t *dev, const fido_bio_template_t *t, fido_bio_enroll_t *e, uint32_t timo_ms) { + int ms = dev->timeout_ms; + if (e->token == NULL) return (FIDO_ERR_INVALID_ARGUMENT); - return (bio_enroll_continue_wait(dev, t, e, timo_ms, -1)); + return (bio_enroll_continue_wait(dev, t, e, timo_ms, &ms)); } static int -bio_enroll_cancel_wait(fido_dev_t *dev, int ms) +bio_enroll_cancel_wait(fido_dev_t *dev, int *ms) { const uint8_t cmd = CMD_ENROLL_CANCEL; int r; - if ((r = bio_tx(dev, cmd, NULL, 0, NULL, NULL)) != FIDO_OK || + if ((r = bio_tx(dev, cmd, NULL, 0, NULL, NULL, ms)) != FIDO_OK || (r = fido_rx_cbor_status(dev, ms)) != FIDO_OK) { fido_log_debug("%s: tx/rx", __func__); return (r); @@ -560,12 +568,14 @@ bio_enroll_cancel_wait(fido_dev_t *dev, int ms) int fido_bio_dev_enroll_cancel(fido_dev_t *dev) { - return (bio_enroll_cancel_wait(dev, -1)); + int ms = dev->timeout_ms; + + return (bio_enroll_cancel_wait(dev, &ms)); } static int bio_enroll_remove_wait(fido_dev_t *dev, const fido_bio_template_t *t, - const char *pin, int ms) + const char *pin, int *ms) { cbor_item_t *argv[1]; const uint8_t cmd = CMD_ENROLL_REMOVE; @@ -578,7 +588,7 @@ bio_enroll_remove_wait(fido_dev_t *dev, const fido_bio_template_t *t, goto fail; } - if ((r = bio_tx(dev, cmd, argv, 1, pin, NULL)) != FIDO_OK || + if ((r = bio_tx(dev, cmd, argv, 1, pin, NULL, ms)) != FIDO_OK || (r = fido_rx_cbor_status(dev, ms)) != FIDO_OK) { fido_log_debug("%s: tx/rx", __func__); goto fail; @@ -595,7 +605,9 @@ int fido_bio_dev_enroll_remove(fido_dev_t *dev, const fido_bio_template_t *t, const char *pin) { - return (bio_enroll_remove_wait(dev, t, pin, -1)); + int ms = dev->timeout_ms; + + return (bio_enroll_remove_wait(dev, t, pin, &ms)); } static void @@ -640,7 +652,7 @@ bio_parse_info(const cbor_item_t *key, const cbor_item_t *val, void *arg) } static int -bio_rx_info(fido_dev_t *dev, fido_bio_info_t *i, int ms) +bio_rx_info(fido_dev_t *dev, fido_bio_info_t *i, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; @@ -664,11 +676,12 @@ bio_rx_info(fido_dev_t *dev, fido_bio_info_t *i, int ms) } static int -bio_get_info_wait(fido_dev_t *dev, fido_bio_info_t *i, int ms) +bio_get_info_wait(fido_dev_t *dev, fido_bio_info_t *i, int *ms) { int r; - if ((r = bio_tx(dev, CMD_GET_INFO, NULL, 0, NULL, NULL)) != FIDO_OK || + if ((r = bio_tx(dev, CMD_GET_INFO, NULL, 0, NULL, NULL, + ms)) != FIDO_OK || (r = bio_rx_info(dev, i, ms)) != FIDO_OK) { fido_log_debug("%s: tx/rx", __func__); return (r); @@ -680,7 +693,9 @@ bio_get_info_wait(fido_dev_t *dev, fido_bio_info_t *i, int ms) int fido_bio_dev_get_info(fido_dev_t *dev, fido_bio_info_t *i) { - return (bio_get_info_wait(dev, i, -1)); + int ms = dev->timeout_ms; + + return (bio_get_info_wait(dev, i, &ms)); } const char * diff --git a/contrib/libfido2/src/cbor.c b/contrib/libfido2/src/cbor.c index 5c1b11583e7b..7935e5017dcf 100644 --- a/contrib/libfido2/src/cbor.c +++ b/contrib/libfido2/src/cbor.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -560,6 +560,32 @@ fail: return (NULL); } +cbor_item_t * +cbor_encode_str_array(const fido_str_array_t *a) +{ + cbor_item_t *array = NULL; + cbor_item_t *entry = NULL; + + if ((array = cbor_new_definite_array(a->len)) == NULL) + goto fail; + + for (size_t i = 0; i < a->len; i++) { + if ((entry = cbor_build_string(a->ptr[i])) == NULL || + cbor_array_push(array, entry) == false) + goto fail; + cbor_decref(&entry); + } + + return (array); +fail: + if (entry != NULL) + cbor_decref(&entry); + if (array != NULL) + cbor_decref(&array); + + return (NULL); +} + static int cbor_encode_largeblob_key_ext(cbor_item_t *map) { @@ -584,6 +610,8 @@ cbor_encode_cred_ext(const fido_cred_ext_t *ext, const fido_blob_t *blob) size++; if (ext->mask & FIDO_EXT_LARGEBLOB_KEY) size++; + if (ext->mask & FIDO_EXT_MINPINLEN) + size++; if (size == 0 || (item = cbor_new_definite_map(size)) == NULL) return (NULL); @@ -615,6 +643,12 @@ cbor_encode_cred_ext(const fido_cred_ext_t *ext, const fido_blob_t *blob) return (NULL); } } + if (ext->mask & FIDO_EXT_MINPINLEN) { + if (cbor_add_bool(item, "minPinLength", FIDO_OPT_TRUE) < 0) { + cbor_decref(&item); + return (NULL); + } + } return (item); } @@ -706,11 +740,7 @@ cbor_encode_change_pin_auth(const fido_dev_t *dev, const fido_blob_t *secret, unsigned int dgst_len; cbor_item_t *item = NULL; const EVP_MD *md = NULL; -#if OPENSSL_VERSION_NUMBER < 0x10100000L - HMAC_CTX ctx; -#else HMAC_CTX *ctx = NULL; -#endif fido_blob_t key; uint8_t prot; size_t outlen; @@ -726,19 +756,6 @@ cbor_encode_change_pin_auth(const fido_dev_t *dev, const fido_blob_t *secret, if (prot == CTAP_PIN_PROTOCOL2 && key.len > 32) key.len = 32; -#if OPENSSL_VERSION_NUMBER < 0x10100000L - HMAC_CTX_init(&ctx); - - if ((md = EVP_sha256()) == NULL || - HMAC_Init_ex(&ctx, key.ptr, (int)key.len, md, NULL) == 0 || - HMAC_Update(&ctx, new_pin_enc->ptr, new_pin_enc->len) == 0 || - HMAC_Update(&ctx, pin_hash_enc->ptr, pin_hash_enc->len) == 0 || - HMAC_Final(&ctx, dgst, &dgst_len) == 0 || - dgst_len != SHA256_DIGEST_LENGTH) { - fido_log_debug("%s: HMAC", __func__); - goto fail; - } -#else if ((ctx = HMAC_CTX_new()) == NULL || (md = EVP_sha256()) == NULL || HMAC_Init_ex(ctx, key.ptr, (int)key.len, md, NULL) == 0 || @@ -749,7 +766,6 @@ cbor_encode_change_pin_auth(const fido_dev_t *dev, const fido_blob_t *secret, fido_log_debug("%s: HMAC", __func__); goto fail; } -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ outlen = (prot == CTAP_PIN_PROTOCOL1) ? 16 : dgst_len; @@ -759,10 +775,7 @@ cbor_encode_change_pin_auth(const fido_dev_t *dev, const fido_blob_t *secret, } fail: -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - if (ctx != NULL) - HMAC_CTX_free(ctx); -#endif + HMAC_CTX_free(ctx); return (item); } @@ -775,6 +788,7 @@ cbor_encode_hmac_secret_param(const fido_dev_t *dev, cbor_item_t *item, cbor_item_t *argv[4]; struct cbor_pair pair; fido_blob_t *enc = NULL; + uint8_t prot; int r; memset(argv, 0, sizeof(argv)); @@ -801,11 +815,17 @@ cbor_encode_hmac_secret_param(const fido_dev_t *dev, cbor_item_t *item, goto fail; } + if ((prot = fido_dev_get_pin_protocol(dev)) == 0) { + fido_log_debug("%s: fido_dev_get_pin_protocol", __func__); + r = FIDO_ERR_INTERNAL; + goto fail; + } + /* XXX not pin, but salt */ if ((argv[0] = es256_pk_encode(pk, 1)) == NULL || (argv[1] = fido_blob_encode(enc)) == NULL || (argv[2] = cbor_encode_pin_auth(dev, ecdh, enc)) == NULL || - (argv[3] = cbor_encode_pin_opt(dev)) == NULL) { + (prot != 1 && (argv[3] = cbor_build_uint8(prot)) == NULL)) { fido_log_debug("%s: cbor encode", __func__); r = FIDO_ERR_INTERNAL; goto fail; @@ -896,7 +916,7 @@ cbor_decode_fmt(const cbor_item_t *item, char **fmt) } if (strcmp(type, "packed") && strcmp(type, "fido-u2f") && - strcmp(type, "none")) { + strcmp(type, "none") && strcmp(type, "tpm")) { fido_log_debug("%s: type=%s", __func__, type); free(type); return (-1); @@ -1141,6 +1161,14 @@ decode_cred_extension(const cbor_item_t *key, const cbor_item_t *val, void *arg) } if (cbor_ctrl_value(val) == CBOR_CTRL_TRUE) authdata_ext->mask |= FIDO_EXT_CRED_BLOB; + } else if (strcmp(type, "minPinLength") == 0) { + if (cbor_isa_uint(val) == false || + cbor_int_get_width(val) != CBOR_INT_8) { + fido_log_debug("%s: cbor type", __func__); + goto out; + } + authdata_ext->mask |= FIDO_EXT_MINPINLEN; + authdata_ext->minpinlen = cbor_get_uint8(val); } ok = 0; @@ -1365,7 +1393,6 @@ decode_attstmt_entry(const cbor_item_t *key, const cbor_item_t *val, void *arg) { fido_attstmt_t *attstmt = arg; char *name = NULL; - int cose_alg = 0; int ok = -1; if (cbor_string_copy(key, &name) < 0) { @@ -1380,10 +1407,11 @@ decode_attstmt_entry(const cbor_item_t *key, const cbor_item_t *val, void *arg) fido_log_debug("%s: alg", __func__); goto out; } - if ((cose_alg = -(int)cbor_get_int(val) - 1) != COSE_ES256 && - cose_alg != COSE_RS256 && cose_alg != COSE_EDDSA) { - fido_log_debug("%s: unsupported cose_alg=%d", __func__, - cose_alg); + attstmt->alg = -(int)cbor_get_int(val) - 1; + if (attstmt->alg != COSE_ES256 && attstmt->alg != COSE_RS256 && + attstmt->alg != COSE_EDDSA && attstmt->alg != COSE_RS1) { + fido_log_debug("%s: unsupported attstmt->alg=%d", + __func__, attstmt->alg); goto out; } } else if (!strcmp(name, "sig")) { @@ -1398,6 +1426,16 @@ decode_attstmt_entry(const cbor_item_t *key, const cbor_item_t *val, void *arg) fido_log_debug("%s: x5c", __func__); goto out; } + } else if (!strcmp(name, "certInfo")) { + if (fido_blob_decode(val, &attstmt->certinfo) < 0) { + fido_log_debug("%s: certinfo", __func__); + goto out; + } + } else if (!strcmp(name, "pubArea")) { + if (fido_blob_decode(val, &attstmt->pubarea) < 0) { + fido_log_debug("%s: pubarea", __func__); + goto out; + } } ok = 0; @@ -1410,6 +1448,8 @@ out: int cbor_decode_attstmt(const cbor_item_t *item, fido_attstmt_t *attstmt) { + size_t alloc_len; + if (cbor_isa_map(item) == false || cbor_map_is_definite(item) == false || cbor_map_iter(item, attstmt, decode_attstmt_entry) < 0) { @@ -1417,6 +1457,13 @@ cbor_decode_attstmt(const cbor_item_t *item, fido_attstmt_t *attstmt) return (-1); } + if (attstmt->cbor.ptr != NULL || + (attstmt->cbor.len = cbor_serialize_alloc(item, + &attstmt->cbor.ptr, &alloc_len)) == 0) { + fido_log_debug("%s: cbor_serialize_alloc", __func__); + return (-1); + } + return (0); } diff --git a/contrib/libfido2/src/config.c b/contrib/libfido2/src/config.c index 0dda16163bc8..2baaab0fd62c 100644 --- a/contrib/libfido2/src/config.c +++ b/contrib/libfido2/src/config.c @@ -39,7 +39,7 @@ config_prepare_hmac(uint8_t subcmd, const cbor_item_t *item, fido_blob_t *hmac) static int config_tx(fido_dev_t *dev, uint8_t subcmd, cbor_item_t **paramv, size_t paramc, - const char *pin) + const char *pin, int *ms) { cbor_item_t *argv[4]; es256_pk_t *pk = NULL; @@ -68,12 +68,12 @@ config_tx(fido_dev_t *dev, uint8_t subcmd, cbor_item_t **paramv, size_t paramc, fido_log_debug("%s: config_prepare_hmac", __func__); goto fail; } - if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) { + if ((r = fido_do_ecdh(dev, &pk, &ecdh, ms)) != FIDO_OK) { fido_log_debug("%s: fido_do_ecdh", __func__); goto fail; } if ((r = cbor_add_uv_params(dev, cmd, &hmac, pk, ecdh, pin, - NULL, &argv[3], &argv[2])) != FIDO_OK) { + NULL, &argv[3], &argv[2], ms)) != FIDO_OK) { fido_log_debug("%s: cbor_add_uv_params", __func__); goto fail; } @@ -81,7 +81,7 @@ config_tx(fido_dev_t *dev, uint8_t subcmd, cbor_item_t **paramv, size_t paramc, /* framing and transmission */ if (cbor_build_frame(cmd, argv, nitems(argv), &f) < 0 || - fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { + fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -99,11 +99,12 @@ fail: } static int -config_enable_entattest_wait(fido_dev_t *dev, const char *pin, int ms) +config_enable_entattest_wait(fido_dev_t *dev, const char *pin, int *ms) { int r; - if ((r = config_tx(dev, CMD_ENABLE_ENTATTEST, NULL, 0, pin)) != FIDO_OK) + if ((r = config_tx(dev, CMD_ENABLE_ENTATTEST, NULL, 0, pin, + ms)) != FIDO_OK) return r; return fido_rx_cbor_status(dev, ms); @@ -112,15 +113,18 @@ config_enable_entattest_wait(fido_dev_t *dev, const char *pin, int ms) int fido_dev_enable_entattest(fido_dev_t *dev, const char *pin) { - return (config_enable_entattest_wait(dev, pin, -1)); + int ms = dev->timeout_ms; + + return (config_enable_entattest_wait(dev, pin, &ms)); } static int -config_toggle_always_uv_wait(fido_dev_t *dev, const char *pin, int ms) +config_toggle_always_uv_wait(fido_dev_t *dev, const char *pin, int *ms) { int r; - if ((r = config_tx(dev, CMD_TOGGLE_ALWAYS_UV, NULL, 0, pin)) != FIDO_OK) + if ((r = config_tx(dev, CMD_TOGGLE_ALWAYS_UV, NULL, 0, pin, + ms)) != FIDO_OK) return r; return (fido_rx_cbor_status(dev, ms)); @@ -129,18 +133,21 @@ config_toggle_always_uv_wait(fido_dev_t *dev, const char *pin, int ms) int fido_dev_toggle_always_uv(fido_dev_t *dev, const char *pin) { - return config_toggle_always_uv_wait(dev, pin, -1); + int ms = dev->timeout_ms; + + return config_toggle_always_uv_wait(dev, pin, &ms); } static int -config_pin_minlen_tx(fido_dev_t *dev, size_t len, bool force, const char *pin) +config_pin_minlen_tx(fido_dev_t *dev, size_t len, bool force, + const fido_str_array_t *rpid, const char *pin, int *ms) { cbor_item_t *argv[3]; int r; memset(argv, 0, sizeof(argv)); - if ((!len && !force) || len > UINT8_MAX) { + if ((rpid == NULL && len == 0 && !force) || len > UINT8_MAX) { r = FIDO_ERR_INVALID_ARGUMENT; goto fail; } @@ -149,13 +156,18 @@ config_pin_minlen_tx(fido_dev_t *dev, size_t len, bool force, const char *pin) r = FIDO_ERR_INTERNAL; goto fail; } + if (rpid != NULL && (argv[1] = cbor_encode_str_array(rpid)) == NULL) { + fido_log_debug("%s: cbor_encode_str_array", __func__); + r = FIDO_ERR_INTERNAL; + goto fail; + } if (force && (argv[2] = cbor_build_bool(true)) == NULL) { fido_log_debug("%s: cbor_build_bool", __func__); r = FIDO_ERR_INTERNAL; goto fail; } if ((r = config_tx(dev, CMD_SET_PIN_MINLEN, argv, nitems(argv), - pin)) != FIDO_OK) { + pin, ms)) != FIDO_OK) { fido_log_debug("%s: config_tx", __func__); goto fail; } @@ -167,12 +179,13 @@ fail: } static int -config_pin_minlen(fido_dev_t *dev, size_t len, bool force, const char *pin, - int ms) +config_pin_minlen(fido_dev_t *dev, size_t len, bool force, + const fido_str_array_t *rpid, const char *pin, int *ms) { int r; - if ((r = config_pin_minlen_tx(dev, len, force, pin)) != FIDO_OK) + if ((r = config_pin_minlen_tx(dev, len, force, rpid, pin, + ms)) != FIDO_OK) return r; return fido_rx_cbor_status(dev, ms); @@ -181,11 +194,36 @@ config_pin_minlen(fido_dev_t *dev, size_t len, bool force, const char *pin, int fido_dev_set_pin_minlen(fido_dev_t *dev, size_t len, const char *pin) { - return config_pin_minlen(dev, len, false, pin, -1); + int ms = dev->timeout_ms; + + return config_pin_minlen(dev, len, false, NULL, pin, &ms); } int fido_dev_force_pin_change(fido_dev_t *dev, const char *pin) { - return config_pin_minlen(dev, 0, true, pin, -1); + int ms = dev->timeout_ms; + + return config_pin_minlen(dev, 0, true, NULL, pin, &ms); +} + +int +fido_dev_set_pin_minlen_rpid(fido_dev_t *dev, const char * const *rpid, + size_t n, const char *pin) +{ + fido_str_array_t sa; + int ms = dev->timeout_ms; + int r; + + memset(&sa, 0, sizeof(sa)); + if (fido_str_array_pack(&sa, rpid, n) < 0) { + fido_log_debug("%s: fido_str_array_pack", __func__); + r = FIDO_ERR_INTERNAL; + goto fail; + } + r = config_pin_minlen(dev, 0, false, &sa, pin, &ms); +fail: + fido_str_array_free(&sa); + + return r; } diff --git a/contrib/libfido2/src/cred.c b/contrib/libfido2/src/cred.c index 5e65b08293b1..6da502c8d90a 100644 --- a/contrib/libfido2/src/cred.c +++ b/contrib/libfido2/src/cred.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -10,6 +10,10 @@ #include "fido.h" #include "fido/es256.h" +#ifndef FIDO_MAXMSG_CRED +#define FIDO_MAXMSG_CRED 4096 +#endif + static int parse_makecred_reply(const cbor_item_t *key, const cbor_item_t *val, void *arg) { @@ -43,7 +47,8 @@ parse_makecred_reply(const cbor_item_t *key, const cbor_item_t *val, void *arg) } static int -fido_dev_make_cred_tx(fido_dev_t *dev, fido_cred_t *cred, const char *pin) +fido_dev_make_cred_tx(fido_dev_t *dev, fido_cred_t *cred, const char *pin, + int *ms) { fido_blob_t f; fido_blob_t *ecdh = NULL; @@ -92,12 +97,12 @@ fido_dev_make_cred_tx(fido_dev_t *dev, fido_cred_t *cred, const char *pin) /* user verification */ if (pin != NULL || (uv == FIDO_OPT_TRUE && fido_dev_supports_permissions(dev))) { - if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) { + if ((r = fido_do_ecdh(dev, &pk, &ecdh, ms)) != FIDO_OK) { fido_log_debug("%s: fido_do_ecdh", __func__); goto fail; } if ((r = cbor_add_uv_params(dev, cmd, &cred->cdh, pk, ecdh, - pin, cred->rp.id, &argv[7], &argv[8])) != FIDO_OK) { + pin, cred->rp.id, &argv[7], &argv[8], ms)) != FIDO_OK) { fido_log_debug("%s: cbor_add_uv_params", __func__); goto fail; } @@ -114,7 +119,7 @@ fido_dev_make_cred_tx(fido_dev_t *dev, fido_cred_t *cred, const char *pin) /* framing and transmission */ if (cbor_build_frame(cmd, argv, nitems(argv), &f) < 0 || - fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { + fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -131,42 +136,55 @@ fail: } static int -fido_dev_make_cred_rx(fido_dev_t *dev, fido_cred_t *cred, int ms) +fido_dev_make_cred_rx(fido_dev_t *dev, fido_cred_t *cred, int *ms) { - unsigned char reply[FIDO_MAXMSG]; - int reply_len; - int r; + unsigned char *reply; + int reply_len; + int r; fido_cred_reset_rx(cred); - if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, &reply, sizeof(reply), + if ((reply = malloc(FIDO_MAXMSG_CRED)) == NULL) { + r = FIDO_ERR_INTERNAL; + goto fail; + } + + if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, reply, FIDO_MAXMSG_CRED, ms)) < 0) { fido_log_debug("%s: fido_rx", __func__); - return (FIDO_ERR_RX); + r = FIDO_ERR_RX; + goto fail; } if ((r = cbor_parse_reply(reply, (size_t)reply_len, cred, parse_makecred_reply)) != FIDO_OK) { fido_log_debug("%s: parse_makecred_reply", __func__); - return (r); + goto fail; } if (cred->fmt == NULL || fido_blob_is_empty(&cred->authdata_cbor) || fido_blob_is_empty(&cred->attcred.id)) { - fido_cred_reset_rx(cred); - return (FIDO_ERR_INVALID_CBOR); + r = FIDO_ERR_INVALID_CBOR; + goto fail; } - return (FIDO_OK); + r = FIDO_OK; +fail: + free(reply); + + if (r != FIDO_OK) + fido_cred_reset_rx(cred); + + return (r); } static int fido_dev_make_cred_wait(fido_dev_t *dev, fido_cred_t *cred, const char *pin, - int ms) + int *ms) { int r; - if ((r = fido_dev_make_cred_tx(dev, cred, pin)) != FIDO_OK || + if ((r = fido_dev_make_cred_tx(dev, cred, pin, ms)) != FIDO_OK || (r = fido_dev_make_cred_rx(dev, cred, ms)) != FIDO_OK) return (r); @@ -176,18 +194,20 @@ fido_dev_make_cred_wait(fido_dev_t *dev, fido_cred_t *cred, const char *pin, int fido_dev_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin) { + int ms = dev->timeout_ms; + #ifdef USE_WINHELLO if (dev->flags & FIDO_DEV_WINHELLO) - return (fido_winhello_make_cred(dev, cred, pin)); + return (fido_winhello_make_cred(dev, cred, pin, ms)); #endif if (fido_dev_is_fido2(dev) == false) { if (pin != NULL || cred->rk == FIDO_OPT_TRUE || cred->ext.mask != 0) return (FIDO_ERR_UNSUPPORTED_OPTION); - return (u2f_register(dev, cred, -1)); + return (u2f_register(dev, cred, &ms)); } - return (fido_dev_make_cred_wait(dev, cred, pin, -1)); + return (fido_dev_make_cred_wait(dev, cred, pin, &ms)); } static int @@ -225,66 +245,81 @@ get_signed_hash_u2f(fido_blob_t *dgst, const unsigned char *rp_id, size_t rp_id_len, const fido_blob_t *clientdata, const fido_blob_t *id, const es256_pk_t *pk) { - const uint8_t zero = 0; - const uint8_t four = 4; /* uncompressed point */ - SHA256_CTX ctx; - - if (dgst->len != SHA256_DIGEST_LENGTH || SHA256_Init(&ctx) == 0 || - SHA256_Update(&ctx, &zero, sizeof(zero)) == 0 || - SHA256_Update(&ctx, rp_id, rp_id_len) == 0 || - SHA256_Update(&ctx, clientdata->ptr, clientdata->len) == 0 || - SHA256_Update(&ctx, id->ptr, id->len) == 0 || - SHA256_Update(&ctx, &four, sizeof(four)) == 0 || - SHA256_Update(&ctx, pk->x, sizeof(pk->x)) == 0 || - SHA256_Update(&ctx, pk->y, sizeof(pk->y)) == 0 || - SHA256_Final(dgst->ptr, &ctx) == 0) { + const uint8_t zero = 0; + const uint8_t four = 4; /* uncompressed point */ + const EVP_MD *md = NULL; + EVP_MD_CTX *ctx = NULL; + int ok = -1; + + if (dgst->len != SHA256_DIGEST_LENGTH || + (md = EVP_sha256()) == NULL || + (ctx = EVP_MD_CTX_new()) == NULL || + EVP_DigestInit_ex(ctx, md, NULL) != 1 || + EVP_DigestUpdate(ctx, &zero, sizeof(zero)) != 1 || + EVP_DigestUpdate(ctx, rp_id, rp_id_len) != 1 || + EVP_DigestUpdate(ctx, clientdata->ptr, clientdata->len) != 1 || + EVP_DigestUpdate(ctx, id->ptr, id->len) != 1 || + EVP_DigestUpdate(ctx, &four, sizeof(four)) != 1 || + EVP_DigestUpdate(ctx, pk->x, sizeof(pk->x)) != 1 || + EVP_DigestUpdate(ctx, pk->y, sizeof(pk->y)) != 1 || + EVP_DigestFinal_ex(ctx, dgst->ptr, NULL) != 1) { fido_log_debug("%s: sha256", __func__); - return (-1); + goto fail; } - return (0); + ok = 0; +fail: + EVP_MD_CTX_free(ctx); + + return (ok); } static int -verify_sig(const fido_blob_t *dgst, const fido_blob_t *x5c, - const fido_blob_t *sig) +verify_attstmt(const fido_blob_t *dgst, const fido_attstmt_t *attstmt) { BIO *rawcert = NULL; X509 *cert = NULL; EVP_PKEY *pkey = NULL; - EC_KEY *ec; int ok = -1; /* openssl needs ints */ - if (dgst->len > INT_MAX || x5c->len > INT_MAX || sig->len > INT_MAX) { - fido_log_debug("%s: dgst->len=%zu, x5c->len=%zu, sig->len=%zu", - __func__, dgst->len, x5c->len, sig->len); + if (attstmt->x5c.len > INT_MAX) { + fido_log_debug("%s: x5c.len=%zu", __func__, attstmt->x5c.len); return (-1); } /* fetch key from x509 */ - if ((rawcert = BIO_new_mem_buf(x5c->ptr, (int)x5c->len)) == NULL || + if ((rawcert = BIO_new_mem_buf(attstmt->x5c.ptr, + (int)attstmt->x5c.len)) == NULL || (cert = d2i_X509_bio(rawcert, NULL)) == NULL || - (pkey = X509_get_pubkey(cert)) == NULL || - (ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) { + (pkey = X509_get_pubkey(cert)) == NULL) { fido_log_debug("%s: x509 key", __func__); goto fail; } - if (ECDSA_verify(0, dgst->ptr, (int)dgst->len, sig->ptr, - (int)sig->len, ec) != 1) { - fido_log_debug("%s: ECDSA_verify", __func__); - goto fail; + switch (attstmt->alg) { + case COSE_UNSPEC: + case COSE_ES256: + ok = es256_verify_sig(dgst, pkey, &attstmt->sig); + break; + case COSE_RS256: + ok = rs256_verify_sig(dgst, pkey, &attstmt->sig); + break; + case COSE_RS1: + ok = rs1_verify_sig(dgst, pkey, &attstmt->sig); + break; + case COSE_EDDSA: + ok = eddsa_verify_sig(dgst, pkey, &attstmt->sig); + break; + default: + fido_log_debug("%s: unknown alg %d", __func__, attstmt->alg); + break; } - ok = 0; fail: - if (rawcert != NULL) - BIO_free(rawcert); - if (cert != NULL) - X509_free(cert); - if (pkey != NULL) - EVP_PKEY_free(pkey); + BIO_free(rawcert); + X509_free(cert); + EVP_PKEY_free(pkey); return (ok); } @@ -348,14 +383,21 @@ fido_cred_verify(const fido_cred_t *cred) r = FIDO_ERR_INTERNAL; goto out; } + } else if (!strcmp(cred->fmt, "tpm")) { + if (fido_get_signed_hash_tpm(&dgst, &cred->cdh, + &cred->authdata_raw, &cred->attstmt, &cred->attcred) < 0) { + fido_log_debug("%s: fido_get_signed_hash_tpm", __func__); + r = FIDO_ERR_INTERNAL; + goto out; + } } else { fido_log_debug("%s: unknown fmt %s", __func__, cred->fmt); r = FIDO_ERR_INVALID_ARGUMENT; goto out; } - if (verify_sig(&dgst, &cred->attstmt.x5c, &cred->attstmt.sig) < 0) { - fido_log_debug("%s: verify_sig", __func__); + if (verify_attstmt(&dgst, &cred->attstmt) < 0) { + fido_log_debug("%s: verify_attstmt", __func__); r = FIDO_ERR_INVALID_SIG; goto out; } @@ -435,15 +477,15 @@ fido_cred_verify_self(const fido_cred_t *cred) switch (cred->attcred.type) { case COSE_ES256: - ok = fido_verify_sig_es256(&dgst, &cred->attcred.pubkey.es256, + ok = es256_pk_verify_sig(&dgst, &cred->attcred.pubkey.es256, &cred->attstmt.sig); break; case COSE_RS256: - ok = fido_verify_sig_rs256(&dgst, &cred->attcred.pubkey.rs256, + ok = rs256_pk_verify_sig(&dgst, &cred->attcred.pubkey.rs256, &cred->attstmt.sig); break; case COSE_EDDSA: - ok = fido_verify_sig_eddsa(&dgst, &cred->attcred.pubkey.eddsa, + ok = eddsa_pk_verify_sig(&dgst, &cred->attcred.pubkey.eddsa, &cred->attstmt.sig); break; default: @@ -482,6 +524,18 @@ fido_cred_clean_authdata(fido_cred_t *cred) memset(&cred->attcred, 0, sizeof(cred->attcred)); } +static void +fido_cred_clean_attstmt(fido_attstmt_t *attstmt) +{ + fido_blob_reset(&attstmt->certinfo); + fido_blob_reset(&attstmt->pubarea); + fido_blob_reset(&attstmt->cbor); + fido_blob_reset(&attstmt->x5c); + fido_blob_reset(&attstmt->sig); + + memset(attstmt, 0, sizeof(*attstmt)); +} + void fido_cred_reset_tx(fido_cred_t *cred) { @@ -513,8 +567,7 @@ fido_cred_reset_rx(fido_cred_t *cred) free(cred->fmt); cred->fmt = NULL; fido_cred_clean_authdata(cred); - fido_blob_reset(&cred->attstmt.x5c); - fido_blob_reset(&cred->attstmt.sig); + fido_cred_clean_attstmt(&cred->attstmt); fido_blob_reset(&cred->largeblob_key); } @@ -568,7 +621,6 @@ fail: fido_cred_clean_authdata(cred); return (r); - } int @@ -610,7 +662,6 @@ fail: fido_cred_clean_authdata(cred); return (r); - } int @@ -641,6 +692,39 @@ fido_cred_set_sig(fido_cred_t *cred, const unsigned char *ptr, size_t len) } int +fido_cred_set_attstmt(fido_cred_t *cred, const unsigned char *ptr, size_t len) +{ + cbor_item_t *item = NULL; + struct cbor_load_result cbor; + int r = FIDO_ERR_INVALID_ARGUMENT; + + fido_cred_clean_attstmt(&cred->attstmt); + + if (ptr == NULL || len == 0) + goto fail; + + if ((item = cbor_load(ptr, len, &cbor)) == NULL) { + fido_log_debug("%s: cbor_load", __func__); + goto fail; + } + + if (cbor_decode_attstmt(item, &cred->attstmt) < 0) { + fido_log_debug("%s: cbor_decode_attstmt", __func__); + goto fail; + } + + r = FIDO_OK; +fail: + if (item != NULL) + cbor_decref(&item); + + if (r != FIDO_OK) + fido_cred_clean_attstmt(&cred->attstmt); + + return (r); +} + +int fido_cred_exclude(fido_cred_t *cred, const unsigned char *id_ptr, size_t id_len) { fido_blob_t id_blob; @@ -834,6 +918,19 @@ fido_cred_set_prot(fido_cred_t *cred, int prot) } int +fido_cred_set_pin_minlen(fido_cred_t *cred, size_t len) +{ + if (len == 0) + cred->ext.mask &= ~FIDO_EXT_MINPINLEN; + else + cred->ext.mask |= FIDO_EXT_MINPINLEN; + + cred->ext.minpinlen = len; + + return (FIDO_OK); +} + +int fido_cred_set_blob(fido_cred_t *cred, const unsigned char *ptr, size_t len) { if (ptr == NULL || len == 0) @@ -856,7 +953,7 @@ fido_cred_set_fmt(fido_cred_t *cred, const char *fmt) return (FIDO_ERR_INVALID_ARGUMENT); if (strcmp(fmt, "packed") && strcmp(fmt, "fido-u2f") && - strcmp(fmt, "none")) + strcmp(fmt, "none") && strcmp(fmt, "tpm")) return (FIDO_ERR_INVALID_ARGUMENT); if ((cred->fmt = strdup(fmt)) == NULL) @@ -956,6 +1053,18 @@ fido_cred_authdata_raw_len(const fido_cred_t *cred) } const unsigned char * +fido_cred_attstmt_ptr(const fido_cred_t *cred) +{ + return (cred->attstmt.cbor.ptr); +} + +size_t +fido_cred_attstmt_len(const fido_cred_t *cred) +{ + return (cred->attstmt.cbor.len); +} + +const unsigned char * fido_cred_pubkey_ptr(const fido_cred_t *cred) { const void *ptr; @@ -1031,6 +1140,12 @@ fido_cred_prot(const fido_cred_t *cred) return (cred->ext.prot); } +size_t +fido_cred_pin_minlen(const fido_cred_t *cred) +{ + return (cred->ext.minpinlen); +} + const char * fido_cred_fmt(const fido_cred_t *cred) { diff --git a/contrib/libfido2/src/credman.c b/contrib/libfido2/src/credman.c index e48ca4543b10..8d2649a144f2 100644 --- a/contrib/libfido2/src/credman.c +++ b/contrib/libfido2/src/credman.c @@ -112,7 +112,7 @@ fail: static int credman_tx(fido_dev_t *dev, uint8_t subcmd, const void *param, const char *pin, - const char *rp_id, fido_opt_t uv) + const char *rp_id, fido_opt_t uv, int *ms) { fido_blob_t f; fido_blob_t *ecdh = NULL; @@ -144,12 +144,12 @@ credman_tx(fido_dev_t *dev, uint8_t subcmd, const void *param, const char *pin, fido_log_debug("%s: credman_prepare_hmac", __func__); goto fail; } - if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) { + if ((r = fido_do_ecdh(dev, &pk, &ecdh, ms)) != FIDO_OK) { fido_log_debug("%s: fido_do_ecdh", __func__); goto fail; } if ((r = cbor_add_uv_params(dev, cmd, &hmac, pk, ecdh, pin, - rp_id, &argv[3], &argv[2])) != FIDO_OK) { + rp_id, &argv[3], &argv[2], ms)) != FIDO_OK) { fido_log_debug("%s: cbor_add_uv_params", __func__); goto fail; } @@ -157,7 +157,7 @@ credman_tx(fido_dev_t *dev, uint8_t subcmd, const void *param, const char *pin, /* framing and transmission */ if (cbor_build_frame(cmd, argv, nitems(argv), &f) < 0 || - fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { + fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -198,7 +198,7 @@ credman_parse_metadata(const cbor_item_t *key, const cbor_item_t *val, } static int -credman_rx_metadata(fido_dev_t *dev, fido_credman_metadata_t *metadata, int ms) +credman_rx_metadata(fido_dev_t *dev, fido_credman_metadata_t *metadata, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; @@ -223,12 +223,12 @@ credman_rx_metadata(fido_dev_t *dev, fido_credman_metadata_t *metadata, int ms) static int credman_get_metadata_wait(fido_dev_t *dev, fido_credman_metadata_t *metadata, - const char *pin, int ms) + const char *pin, int *ms) { int r; if ((r = credman_tx(dev, CMD_CRED_METADATA, NULL, pin, NULL, - FIDO_OPT_TRUE)) != FIDO_OK || + FIDO_OPT_TRUE, ms)) != FIDO_OK || (r = credman_rx_metadata(dev, metadata, ms)) != FIDO_OK) return (r); @@ -239,7 +239,9 @@ int fido_credman_get_dev_metadata(fido_dev_t *dev, fido_credman_metadata_t *metadata, const char *pin) { - return (credman_get_metadata_wait(dev, metadata, pin, -1)); + int ms = dev->timeout_ms; + + return (credman_get_metadata_wait(dev, metadata, pin, &ms)); } static int @@ -321,7 +323,7 @@ credman_parse_rk_count(const cbor_item_t *key, const cbor_item_t *val, } static int -credman_rx_rk(fido_dev_t *dev, fido_credman_rk_t *rk, int ms) +credman_rx_rk(fido_dev_t *dev, fido_credman_rk_t *rk, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; @@ -360,7 +362,7 @@ credman_rx_rk(fido_dev_t *dev, fido_credman_rk_t *rk, int ms) } static int -credman_rx_next_rk(fido_dev_t *dev, fido_credman_rk_t *rk, int ms) +credman_rx_next_rk(fido_dev_t *dev, fido_credman_rk_t *rk, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; @@ -390,7 +392,7 @@ credman_rx_next_rk(fido_dev_t *dev, fido_credman_rk_t *rk, int ms) static int credman_get_rk_wait(fido_dev_t *dev, const char *rp_id, fido_credman_rk_t *rk, - const char *pin, int ms) + const char *pin, int *ms) { fido_blob_t rp_dgst; uint8_t dgst[SHA256_DIGEST_LENGTH]; @@ -405,13 +407,13 @@ credman_get_rk_wait(fido_dev_t *dev, const char *rp_id, fido_credman_rk_t *rk, rp_dgst.len = sizeof(dgst); if ((r = credman_tx(dev, CMD_RK_BEGIN, &rp_dgst, pin, rp_id, - FIDO_OPT_TRUE)) != FIDO_OK || + FIDO_OPT_TRUE, ms)) != FIDO_OK || (r = credman_rx_rk(dev, rk, ms)) != FIDO_OK) return (r); while (rk->n_rx < rk->n_alloc) { if ((r = credman_tx(dev, CMD_RK_NEXT, NULL, NULL, NULL, - FIDO_OPT_FALSE)) != FIDO_OK || + FIDO_OPT_FALSE, ms)) != FIDO_OK || (r = credman_rx_next_rk(dev, rk, ms)) != FIDO_OK) return (r); rk->n_rx++; @@ -424,12 +426,14 @@ int fido_credman_get_dev_rk(fido_dev_t *dev, const char *rp_id, fido_credman_rk_t *rk, const char *pin) { - return (credman_get_rk_wait(dev, rp_id, rk, pin, -1)); + int ms = dev->timeout_ms; + + return (credman_get_rk_wait(dev, rp_id, rk, pin, &ms)); } static int credman_del_rk_wait(fido_dev_t *dev, const unsigned char *cred_id, - size_t cred_id_len, const char *pin, int ms) + size_t cred_id_len, const char *pin, int *ms) { fido_blob_t cred; int r; @@ -440,7 +444,7 @@ credman_del_rk_wait(fido_dev_t *dev, const unsigned char *cred_id, return (FIDO_ERR_INVALID_ARGUMENT); if ((r = credman_tx(dev, CMD_DELETE_CRED, &cred, pin, NULL, - FIDO_OPT_TRUE)) != FIDO_OK || + FIDO_OPT_TRUE, ms)) != FIDO_OK || (r = fido_rx_cbor_status(dev, ms)) != FIDO_OK) goto fail; @@ -455,7 +459,9 @@ int fido_credman_del_dev_rk(fido_dev_t *dev, const unsigned char *cred_id, size_t cred_id_len, const char *pin) { - return (credman_del_rk_wait(dev, cred_id, cred_id_len, pin, -1)); + int ms = dev->timeout_ms; + + return (credman_del_rk_wait(dev, cred_id, cred_id_len, pin, &ms)); } static int @@ -526,7 +532,7 @@ credman_parse_rp_count(const cbor_item_t *key, const cbor_item_t *val, } static int -credman_rx_rp(fido_dev_t *dev, fido_credman_rp_t *rp, int ms) +credman_rx_rp(fido_dev_t *dev, fido_credman_rp_t *rp, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; @@ -565,7 +571,7 @@ credman_rx_rp(fido_dev_t *dev, fido_credman_rp_t *rp, int ms) } static int -credman_rx_next_rp(fido_dev_t *dev, fido_credman_rp_t *rp, int ms) +credman_rx_next_rp(fido_dev_t *dev, fido_credman_rp_t *rp, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; @@ -595,18 +601,18 @@ credman_rx_next_rp(fido_dev_t *dev, fido_credman_rp_t *rp, int ms) static int credman_get_rp_wait(fido_dev_t *dev, fido_credman_rp_t *rp, const char *pin, - int ms) + int *ms) { int r; if ((r = credman_tx(dev, CMD_RP_BEGIN, NULL, pin, NULL, - FIDO_OPT_TRUE)) != FIDO_OK || + FIDO_OPT_TRUE, ms)) != FIDO_OK || (r = credman_rx_rp(dev, rp, ms)) != FIDO_OK) return (r); while (rp->n_rx < rp->n_alloc) { if ((r = credman_tx(dev, CMD_RP_NEXT, NULL, NULL, NULL, - FIDO_OPT_FALSE)) != FIDO_OK || + FIDO_OPT_FALSE, ms)) != FIDO_OK || (r = credman_rx_next_rp(dev, rp, ms)) != FIDO_OK) return (r); rp->n_rx++; @@ -618,17 +624,19 @@ credman_get_rp_wait(fido_dev_t *dev, fido_credman_rp_t *rp, const char *pin, int fido_credman_get_dev_rp(fido_dev_t *dev, fido_credman_rp_t *rp, const char *pin) { - return (credman_get_rp_wait(dev, rp, pin, -1)); + int ms = dev->timeout_ms; + + return (credman_get_rp_wait(dev, rp, pin, &ms)); } static int credman_set_dev_rk_wait(fido_dev_t *dev, fido_cred_t *cred, const char *pin, - int ms) + int *ms) { int r; if ((r = credman_tx(dev, CMD_UPDATE_CRED, cred, pin, NULL, - FIDO_OPT_TRUE)) != FIDO_OK || + FIDO_OPT_TRUE, ms)) != FIDO_OK || (r = fido_rx_cbor_status(dev, ms)) != FIDO_OK) return (r); @@ -638,7 +646,9 @@ credman_set_dev_rk_wait(fido_dev_t *dev, fido_cred_t *cred, const char *pin, int fido_credman_set_dev_rk(fido_dev_t *dev, fido_cred_t *cred, const char *pin) { - return (credman_set_dev_rk_wait(dev, cred, pin, -1)); + int ms = dev->timeout_ms; + + return (credman_set_dev_rk_wait(dev, cred, pin, &ms)); } fido_credman_rk_t * diff --git a/contrib/libfido2/src/dev.c b/contrib/libfido2/src/dev.c index a003854f89d2..0c3cf64a462b 100644 --- a/contrib/libfido2/src/dev.c +++ b/contrib/libfido2/src/dev.c @@ -106,7 +106,7 @@ fido_dev_set_flags(fido_dev_t *dev, const fido_cbor_info_t *info) } static int -fido_dev_open_tx(fido_dev_t *dev, const char *path) +fido_dev_open_tx(fido_dev_t *dev, const char *path, int *ms) { int r; @@ -161,7 +161,8 @@ fido_dev_open_tx(fido_dev_t *dev, const char *path) goto fail; } - if (fido_tx(dev, CTAP_CMD_INIT, &dev->nonce, sizeof(dev->nonce)) < 0) { + if (fido_tx(dev, CTAP_CMD_INIT, &dev->nonce, sizeof(dev->nonce), + ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -176,7 +177,7 @@ fail: } static int -fido_dev_open_rx(fido_dev_t *dev, int ms) +fido_dev_open_rx(fido_dev_t *dev, int *ms) { fido_cbor_info_t *info = NULL; int reply_len; @@ -241,7 +242,7 @@ fail: } static int -fido_dev_open_wait(fido_dev_t *dev, const char *path, int ms) +fido_dev_open_wait(fido_dev_t *dev, const char *path, int *ms) { int r; @@ -249,7 +250,7 @@ fido_dev_open_wait(fido_dev_t *dev, const char *path, int ms) if (strcmp(path, FIDO_WINHELLO_PATH) == 0) return (fido_winhello_open(dev)); #endif - if ((r = fido_dev_open_tx(dev, path)) != FIDO_OK || + if ((r = fido_dev_open_tx(dev, path, ms)) != FIDO_OK || (r = fido_dev_open_rx(dev, ms)) != FIDO_OK) return (r); @@ -331,24 +332,21 @@ fido_dev_info_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen) int fido_dev_open_with_info(fido_dev_t *dev) { + int ms = dev->timeout_ms; + if (dev->path == NULL) return (FIDO_ERR_INVALID_ARGUMENT); - return (fido_dev_open_wait(dev, dev->path, -1)); + return (fido_dev_open_wait(dev, dev->path, &ms)); } int fido_dev_open(fido_dev_t *dev, const char *path) { + int ms = dev->timeout_ms; + #ifdef NFC_LINUX - /* - * this is a hack to get existing applications up and running with nfc; - * it will *NOT* be part of a libfido2 release. to support nfc in your - * application, please change it to use fido_dev_open_with_info(). - */ - if (strncmp(path, "/sys", strlen("/sys")) == 0 && strlen(path) > 4 && - path[strlen(path) - 4] == 'n' && path[strlen(path) - 3] == 'f' && - path[strlen(path) - 2] == 'c') { + if (strncmp(path, FIDO_NFC_PREFIX, strlen(FIDO_NFC_PREFIX)) == 0) { dev->io_own = true; dev->io = (fido_dev_io_t) { fido_nfc_open, @@ -363,7 +361,7 @@ fido_dev_open(fido_dev_t *dev, const char *path) } #endif - return (fido_dev_open_wait(dev, path, -1)); + return (fido_dev_open_wait(dev, path, &ms)); } int @@ -386,26 +384,31 @@ fido_dev_close(fido_dev_t *dev) int fido_dev_set_sigmask(fido_dev_t *dev, const fido_sigset_t *sigmask) { - if (dev->io_own || dev->io_handle == NULL || sigmask == NULL) + if (dev->io_handle == NULL || sigmask == NULL) return (FIDO_ERR_INVALID_ARGUMENT); #ifdef NFC_LINUX - if (dev->transport.rx == fido_nfc_rx) + if (dev->transport.rx == fido_nfc_rx && dev->io.read == fido_nfc_read) return (fido_nfc_set_sigmask(dev->io_handle, sigmask)); #endif - return (fido_hid_set_sigmask(dev->io_handle, sigmask)); + if (dev->transport.rx == NULL && dev->io.read == fido_hid_read) + return (fido_hid_set_sigmask(dev->io_handle, sigmask)); + + return (FIDO_ERR_INVALID_ARGUMENT); } int fido_dev_cancel(fido_dev_t *dev) { + int ms = dev->timeout_ms; + #ifdef USE_WINHELLO if (dev->flags & FIDO_DEV_WINHELLO) return (fido_winhello_cancel(dev)); #endif if (fido_dev_is_fido2(dev) == false) return (FIDO_ERR_INVALID_ARGUMENT); - if (fido_tx(dev, CTAP_CMD_CANCEL, NULL, 0) < 0) + if (fido_tx(dev, CTAP_CMD_CANCEL, NULL, 0, &ms) < 0) return (FIDO_ERR_TX); return (FIDO_OK); @@ -421,6 +424,7 @@ fido_dev_get_touch_begin(fido_dev_t *dev) unsigned char cdh[SHA256_DIGEST_LENGTH]; fido_rp_t rp; fido_user_t user; + int ms = dev->timeout_ms; int r = FIDO_ERR_INTERNAL; memset(&f, 0, sizeof(f)); @@ -430,7 +434,7 @@ fido_dev_get_touch_begin(fido_dev_t *dev) memset(&user, 0, sizeof(user)); if (fido_dev_is_fido2(dev) == false) - return (u2f_get_touch_begin(dev)); + return (u2f_get_touch_begin(dev, &ms)); if (SHA256((const void *)clientdata, strlen(clientdata), cdh) != cdh) { fido_log_debug("%s: sha256", __func__); @@ -465,7 +469,7 @@ fido_dev_get_touch_begin(fido_dev_t *dev) } if (cbor_build_frame(CTAP_CBOR_MAKECRED, argv, nitems(argv), &f) < 0 || - fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { + fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, &ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -490,9 +494,9 @@ fido_dev_get_touch_status(fido_dev_t *dev, int *touched, int ms) *touched = 0; if (fido_dev_is_fido2(dev) == false) - return (u2f_get_touch_status(dev, touched, ms)); + return (u2f_get_touch_status(dev, touched, &ms)); - switch ((r = fido_rx_cbor_status(dev, ms))) { + switch ((r = fido_rx_cbor_status(dev, &ms))) { case FIDO_ERR_PIN_AUTH_INVALID: case FIDO_ERR_PIN_INVALID: case FIDO_ERR_PIN_NOT_SET: @@ -562,6 +566,7 @@ fido_dev_new(void) return (NULL); dev->cid = CTAP_CID_BROADCAST; + dev->timeout_ms = -1; dev->io = (fido_dev_io_t) { &fido_hid_open, &fido_hid_close, @@ -593,6 +598,7 @@ fido_dev_new_with_info(const fido_dev_info_t *di) dev->io_own = di->transport.tx != NULL || di->transport.rx != NULL; dev->transport = di->transport; dev->cid = CTAP_CID_BROADCAST; + dev->timeout_ms = -1; if ((dev->path = strdup(di->path)) == NULL) { fido_log_debug("%s: strdup", __func__); @@ -730,3 +736,14 @@ fido_dev_maxmsgsize(const fido_dev_t *dev) { return (dev->maxmsgsize); } + +int +fido_dev_set_timeout(fido_dev_t *dev, int ms) +{ + if (ms < -1) + return (FIDO_ERR_INVALID_ARGUMENT); + + dev->timeout_ms = ms; + + return (FIDO_OK); +} diff --git a/contrib/libfido2/src/ecdh.c b/contrib/libfido2/src/ecdh.c index 3ea47ae6457e..9c4f2b99e1a9 100644 --- a/contrib/libfido2/src/ecdh.c +++ b/contrib/libfido2/src/ecdh.c @@ -8,14 +8,14 @@ #include <openssl/sha.h> #if defined(LIBRESSL_VERSION_NUMBER) #include <openssl/hkdf.h> -#elif OPENSSL_VERSION_NUMBER >= 0x10100000L +#else #include <openssl/kdf.h> #endif #include "fido.h" #include "fido/es256.h" -#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L +#if defined(LIBRESSL_VERSION_NUMBER) static int hkdf_sha256(uint8_t *key, const char *info, const fido_blob_t *secret) { @@ -56,7 +56,7 @@ hkdf_sha256(uint8_t *key, char *info, fido_blob_t *secret) EVP_PKEY_CTX_set_hkdf_md(ctx, md) < 1 || EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt, sizeof(salt)) < 1 || EVP_PKEY_CTX_set1_hkdf_key(ctx, secret->ptr, (int)secret->len) < 1 || - EVP_PKEY_CTX_add1_hkdf_info(ctx, info, (int)strlen(info)) < 1) { + EVP_PKEY_CTX_add1_hkdf_info(ctx, (void *)info, (int)strlen(info)) < 1) { fido_log_debug("%s: EVP_PKEY_CTX", __func__); goto fail; } @@ -74,7 +74,7 @@ fail: return ok; } -#endif /* defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L */ +#endif /* defined(LIBRESSL_VERSION_NUMBER) */ static int kdf(uint8_t prot, fido_blob_t *key, /* const */ fido_blob_t *secret) @@ -164,7 +164,7 @@ fail: } int -fido_do_ecdh(fido_dev_t *dev, es256_pk_t **pk, fido_blob_t **ecdh) +fido_do_ecdh(fido_dev_t *dev, es256_pk_t **pk, fido_blob_t **ecdh, int *ms) { es256_sk_t *sk = NULL; /* our private key */ es256_pk_t *ak = NULL; /* authenticator's public key */ @@ -182,7 +182,7 @@ fido_do_ecdh(fido_dev_t *dev, es256_pk_t **pk, fido_blob_t **ecdh) goto fail; } if ((ak = es256_pk_new()) == NULL || - fido_dev_authkey(dev, ak) != FIDO_OK) { + fido_dev_authkey(dev, ak, ms) != FIDO_OK) { fido_log_debug("%s: fido_dev_authkey", __func__); r = FIDO_ERR_INTERNAL; goto fail; diff --git a/contrib/libfido2/src/eddsa.c b/contrib/libfido2/src/eddsa.c index 89b84c5a6bd4..d228149ebf4d 100644 --- a/contrib/libfido2/src/eddsa.c +++ b/contrib/libfido2/src/eddsa.c @@ -10,7 +10,7 @@ #include "fido.h" #include "fido/eddsa.h" -#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10101000L +#if defined(LIBRESSL_VERSION_NUMBER) EVP_PKEY * EVP_PKEY_new_raw_public_key(int type, ENGINE *e, const unsigned char *key, size_t keylen) @@ -52,23 +52,7 @@ EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen, return (0); } -#endif /* LIBRESSL_VERSION_NUMBER || OPENSSL_VERSION_NUMBER < 0x10101000L */ - -#if OPENSSL_VERSION_NUMBER < 0x10100000L -EVP_MD_CTX * -EVP_MD_CTX_new(void) -{ - fido_log_debug("%s: unimplemented", __func__); - - return (NULL); -} - -void -EVP_MD_CTX_free(EVP_MD_CTX *ctx) -{ - (void)ctx; -} -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ +#endif /* LIBRESSL_VERSION_NUMBER */ static int decode_coord(const cbor_item_t *item, void *xy, size_t xy_len) @@ -170,3 +154,65 @@ eddsa_pk_from_EVP_PKEY(eddsa_pk_t *pk, const EVP_PKEY *pkey) return (FIDO_OK); } + +int +eddsa_verify_sig(const fido_blob_t *dgst, EVP_PKEY *pkey, + const fido_blob_t *sig) +{ + EVP_MD_CTX *mdctx = NULL; + int ok = -1; + + if (EVP_PKEY_base_id(pkey) != EVP_PKEY_ED25519) { + fido_log_debug("%s: EVP_PKEY_base_id", __func__); + goto fail; + } + + /* EVP_DigestVerify needs ints */ + if (dgst->len > INT_MAX || sig->len > INT_MAX) { + fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__, + dgst->len, sig->len); + return (-1); + } + + if ((mdctx = EVP_MD_CTX_new()) == NULL) { + fido_log_debug("%s: EVP_MD_CTX_new", __func__); + goto fail; + } + + if (EVP_DigestVerifyInit(mdctx, NULL, NULL, NULL, pkey) != 1) { + fido_log_debug("%s: EVP_DigestVerifyInit", __func__); + goto fail; + } + + if (EVP_DigestVerify(mdctx, sig->ptr, sig->len, dgst->ptr, + dgst->len) != 1) { + fido_log_debug("%s: EVP_DigestVerify", __func__); + goto fail; + } + + ok = 0; +fail: + EVP_MD_CTX_free(mdctx); + + return (ok); +} + +int +eddsa_pk_verify_sig(const fido_blob_t *dgst, const eddsa_pk_t *pk, + const fido_blob_t *sig) +{ + EVP_PKEY *pkey; + int ok = -1; + + if ((pkey = eddsa_pk_to_EVP_PKEY(pk)) == NULL || + eddsa_verify_sig(dgst, pkey, sig) < 0) { + fido_log_debug("%s: eddsa_verify_sig", __func__); + goto fail; + } + + ok = 0; +fail: + EVP_PKEY_free(pkey); + + return (ok); +} diff --git a/contrib/libfido2/src/es256.c b/contrib/libfido2/src/es256.c index 9cdb48e4832d..eb4cc63525aa 100644 --- a/contrib/libfido2/src/es256.c +++ b/contrib/libfido2/src/es256.c @@ -1,10 +1,11 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ #include <openssl/bn.h> +#include <openssl/ecdsa.h> #include <openssl/obj_mac.h> #include "fido.h" @@ -362,6 +363,18 @@ fail: return (ok); } +int +es256_pk_from_EVP_PKEY(es256_pk_t *pk, const EVP_PKEY *pkey) +{ + EC_KEY *ec; + + if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC || + (ec = EVP_PKEY_get0(pkey)) == NULL) + return (FIDO_ERR_INVALID_ARGUMENT); + + return (es256_pk_from_EC_KEY(pk, ec)); +} + EVP_PKEY * es256_sk_to_EVP_PKEY(const es256_sk_t *k) { @@ -451,3 +464,50 @@ fail: return (ok); } + +int +es256_verify_sig(const fido_blob_t *dgst, EVP_PKEY *pkey, + const fido_blob_t *sig) +{ + EVP_PKEY_CTX *pctx = NULL; + int ok = -1; + + if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) { + fido_log_debug("%s: EVP_PKEY_base_id", __func__); + goto fail; + } + + if ((pctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL || + EVP_PKEY_verify_init(pctx) != 1 || + EVP_PKEY_verify(pctx, sig->ptr, sig->len, dgst->ptr, + dgst->len) != 1) { + fido_log_debug("%s: EVP_PKEY_verify", __func__); + goto fail; + } + + ok = 0; +fail: + EVP_PKEY_CTX_free(pctx); + + return (ok); +} + +int +es256_pk_verify_sig(const fido_blob_t *dgst, const es256_pk_t *pk, + const fido_blob_t *sig) +{ + EVP_PKEY *pkey; + int ok = -1; + + if ((pkey = es256_pk_to_EVP_PKEY(pk)) == NULL || + es256_verify_sig(dgst, pkey, sig) < 0) { + fido_log_debug("%s: es256_verify_sig", __func__); + goto fail; + } + + ok = 0; +fail: + EVP_PKEY_free(pkey); + + return (ok); +} diff --git a/contrib/libfido2/src/export.gnu b/contrib/libfido2/src/export.gnu index 40dc7915e6e2..2a8ad24b4c3c 100644 --- a/contrib/libfido2/src/export.gnu +++ b/contrib/libfido2/src/export.gnu @@ -7,6 +7,7 @@ eddsa_pk_to_EVP_PKEY; es256_pk_free; es256_pk_from_EC_KEY; + es256_pk_from_EVP_PKEY; es256_pk_from_ptr; es256_pk_new; es256_pk_to_EVP_PKEY; @@ -99,6 +100,8 @@ fido_cbor_info_transports_ptr; fido_cbor_info_versions_len; fido_cbor_info_versions_ptr; + fido_cred_attstmt_len; + fido_cred_attstmt_ptr; fido_cred_authdata_len; fido_cred_authdata_ptr; fido_cred_authdata_raw_len; @@ -138,11 +141,13 @@ fido_credman_rp_new; fido_credman_set_dev_rk; fido_cred_new; + fido_cred_pin_minlen; fido_cred_prot; fido_cred_pubkey_len; fido_cred_pubkey_ptr; fido_cred_rp_id; fido_cred_rp_name; + fido_cred_set_attstmt; fido_cred_set_authdata; fido_cred_set_authdata_raw; fido_cred_set_blob; @@ -152,6 +157,7 @@ fido_cred_set_fmt; fido_cred_set_id; fido_cred_set_options; + fido_cred_set_pin_minlen; fido_cred_set_prot; fido_cred_set_rk; fido_cred_set_rp; @@ -208,7 +214,9 @@ fido_dev_set_io_functions; fido_dev_set_pin; fido_dev_set_pin_minlen; + fido_dev_set_pin_minlen_rpid; fido_dev_set_sigmask; + fido_dev_set_timeout; fido_dev_set_transport_functions; fido_dev_supports_cred_prot; fido_dev_supports_credman; @@ -226,6 +234,7 @@ fido_strerr; rs256_pk_free; rs256_pk_from_ptr; + rs256_pk_from_EVP_PKEY; rs256_pk_from_RSA; rs256_pk_new; rs256_pk_to_EVP_PKEY; diff --git a/contrib/libfido2/src/export.llvm b/contrib/libfido2/src/export.llvm index 8d3810f92ce9..e163afecedce 100644 --- a/contrib/libfido2/src/export.llvm +++ b/contrib/libfido2/src/export.llvm @@ -5,6 +5,7 @@ _eddsa_pk_new _eddsa_pk_to_EVP_PKEY _es256_pk_free _es256_pk_from_EC_KEY +_es256_pk_from_EVP_PKEY _es256_pk_from_ptr _es256_pk_new _es256_pk_to_EVP_PKEY @@ -97,6 +98,8 @@ _fido_cbor_info_transports_len _fido_cbor_info_transports_ptr _fido_cbor_info_versions_len _fido_cbor_info_versions_ptr +_fido_cred_attstmt_len +_fido_cred_attstmt_ptr _fido_cred_authdata_len _fido_cred_authdata_ptr _fido_cred_authdata_raw_len @@ -136,11 +139,13 @@ _fido_credman_rp_name _fido_credman_rp_new _fido_credman_set_dev_rk _fido_cred_new +_fido_cred_pin_minlen _fido_cred_prot _fido_cred_pubkey_len _fido_cred_pubkey_ptr _fido_cred_rp_id _fido_cred_rp_name +_fido_cred_set_attstmt _fido_cred_set_authdata _fido_cred_set_authdata_raw _fido_cred_set_blob @@ -150,6 +155,7 @@ _fido_cred_set_extensions _fido_cred_set_fmt _fido_cred_set_id _fido_cred_set_options +_fido_cred_set_pin_minlen _fido_cred_set_prot _fido_cred_set_rk _fido_cred_set_rp @@ -206,7 +212,9 @@ _fido_dev_reset _fido_dev_set_io_functions _fido_dev_set_pin _fido_dev_set_pin_minlen +_fido_dev_set_pin_minlen_rpid _fido_dev_set_sigmask +_fido_dev_set_timeout _fido_dev_set_transport_functions _fido_dev_supports_cred_prot _fido_dev_supports_credman @@ -224,6 +232,7 @@ _fido_set_log_handler _fido_strerr _rs256_pk_free _rs256_pk_from_ptr +_rs256_pk_from_EVP_PKEY _rs256_pk_from_RSA _rs256_pk_new _rs256_pk_to_EVP_PKEY diff --git a/contrib/libfido2/src/export.msvc b/contrib/libfido2/src/export.msvc index ca4971dec2d1..9fc24e335e8d 100644 --- a/contrib/libfido2/src/export.msvc +++ b/contrib/libfido2/src/export.msvc @@ -6,6 +6,7 @@ eddsa_pk_new eddsa_pk_to_EVP_PKEY es256_pk_free es256_pk_from_EC_KEY +es256_pk_from_EVP_PKEY es256_pk_from_ptr es256_pk_new es256_pk_to_EVP_PKEY @@ -98,6 +99,8 @@ fido_cbor_info_transports_len fido_cbor_info_transports_ptr fido_cbor_info_versions_len fido_cbor_info_versions_ptr +fido_cred_attstmt_len +fido_cred_attstmt_ptr fido_cred_authdata_len fido_cred_authdata_ptr fido_cred_authdata_raw_len @@ -137,11 +140,13 @@ fido_credman_rp_name fido_credman_rp_new fido_credman_set_dev_rk fido_cred_new +fido_cred_pin_minlen fido_cred_prot fido_cred_pubkey_len fido_cred_pubkey_ptr fido_cred_rp_id fido_cred_rp_name +fido_cred_set_attstmt fido_cred_set_authdata fido_cred_set_authdata_raw fido_cred_set_blob @@ -151,6 +156,7 @@ fido_cred_set_extensions fido_cred_set_fmt fido_cred_set_id fido_cred_set_options +fido_cred_set_pin_minlen fido_cred_set_prot fido_cred_set_rk fido_cred_set_rp @@ -207,7 +213,9 @@ fido_dev_reset fido_dev_set_io_functions fido_dev_set_pin fido_dev_set_pin_minlen +fido_dev_set_pin_minlen_rpid fido_dev_set_sigmask +fido_dev_set_timeout fido_dev_set_transport_functions fido_dev_supports_cred_prot fido_dev_supports_credman @@ -225,6 +233,7 @@ fido_set_log_handler fido_strerr rs256_pk_free rs256_pk_from_ptr +rs256_pk_from_EVP_PKEY rs256_pk_from_RSA rs256_pk_new rs256_pk_to_EVP_PKEY diff --git a/contrib/libfido2/src/extern.h b/contrib/libfido2/src/extern.h index 3be33236f2b1..dc6bddd7b912 100644 --- a/contrib/libfido2/src/extern.h +++ b/contrib/libfido2/src/extern.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -51,6 +51,7 @@ cbor_item_t *cbor_encode_pubkey(const fido_blob_t *); cbor_item_t *cbor_encode_pubkey_list(const fido_blob_array_t *); cbor_item_t *cbor_encode_pubkey_param(int); cbor_item_t *cbor_encode_rp_entity(const fido_rp_t *); +cbor_item_t *cbor_encode_str_array(const fido_str_array_t *); cbor_item_t *cbor_encode_user_entity(const fido_user_t *); cbor_item_t *es256_pk_encode(const es256_pk_t *, int); @@ -86,7 +87,7 @@ int cbor_parse_reply(const unsigned char *, size_t, void *, int(*)(const cbor_item_t *, const cbor_item_t *, void *)); int cbor_add_uv_params(fido_dev_t *, uint8_t, const fido_blob_t *, const es256_pk_t *, const fido_blob_t *, const char *, const char *, - cbor_item_t **, cbor_item_t **); + cbor_item_t **, cbor_item_t **, int *); void cbor_vector_free(cbor_item_t **, size_t); int cbor_array_append(cbor_item_t **, cbor_item_t *); int cbor_array_drop(cbor_item_t **, size_t); @@ -130,14 +131,14 @@ int fido_winhello_manifest(fido_dev_info_t *, size_t, size_t *); int fido_winhello_open(fido_dev_t *); int fido_winhello_close(fido_dev_t *); int fido_winhello_cancel(fido_dev_t *); -int fido_winhello_get_assert(fido_dev_t *, fido_assert_t *, const char *); +int fido_winhello_get_assert(fido_dev_t *, fido_assert_t *, const char *, int); int fido_winhello_get_cbor_info(fido_dev_t *, fido_cbor_info_t *); -int fido_winhello_make_cred(fido_dev_t *, fido_cred_t *, const char *); +int fido_winhello_make_cred(fido_dev_t *, fido_cred_t *, const char *, int); /* generic i/o */ -int fido_rx_cbor_status(fido_dev_t *, int); -int fido_rx(fido_dev_t *, uint8_t, void *, size_t, int); -int fido_tx(fido_dev_t *, uint8_t, const void *, size_t); +int fido_rx_cbor_status(fido_dev_t *, int *); +int fido_rx(fido_dev_t *, uint8_t, void *, size_t, int *); +int fido_tx(fido_dev_t *, uint8_t, const void *, size_t, int *); /* log */ #ifdef FIDO_NO_DIAGNOSTIC @@ -163,21 +164,30 @@ void fido_log_error(int, const char *, ...); #endif /* FIDO_NO_DIAGNOSTIC */ /* u2f */ -int u2f_register(fido_dev_t *, fido_cred_t *, int); -int u2f_authenticate(fido_dev_t *, fido_assert_t *, int); -int u2f_get_touch_begin(fido_dev_t *); -int u2f_get_touch_status(fido_dev_t *, int *, int); +int u2f_register(fido_dev_t *, fido_cred_t *, int *); +int u2f_authenticate(fido_dev_t *, fido_assert_t *, int *); +int u2f_get_touch_begin(fido_dev_t *, int *); +int u2f_get_touch_status(fido_dev_t *, int *, int *); /* unexposed fido ops */ uint8_t fido_dev_get_pin_protocol(const fido_dev_t *); -int fido_dev_authkey(fido_dev_t *, es256_pk_t *); -int fido_dev_get_cbor_info_wait(fido_dev_t *, fido_cbor_info_t *, int); +int fido_dev_authkey(fido_dev_t *, es256_pk_t *, int *); +int fido_dev_get_cbor_info_wait(fido_dev_t *, fido_cbor_info_t *, int *); int fido_dev_get_uv_token(fido_dev_t *, uint8_t, const char *, - const fido_blob_t *, const es256_pk_t *, const char *, fido_blob_t *); + const fido_blob_t *, const es256_pk_t *, const char *, fido_blob_t *, + int *); uint64_t fido_dev_maxmsgsize(const fido_dev_t *); -int fido_do_ecdh(fido_dev_t *, es256_pk_t **, fido_blob_t **); +int fido_do_ecdh(fido_dev_t *, es256_pk_t **, fido_blob_t **, int *); bool fido_dev_supports_permissions(const fido_dev_t *); +/* types */ +void fido_algo_array_free(fido_algo_array_t *); +void fido_byte_array_free(fido_byte_array_t *); +void fido_opt_array_free(fido_opt_array_t *); +void fido_str_array_free(fido_str_array_t *); +void fido_algo_free(fido_algo_t *); +int fido_str_array_pack(fido_str_array_t *, const char * const *, size_t); + /* misc */ void fido_assert_reset_rx(fido_assert_t *); void fido_assert_reset_tx(fido_assert_t *); @@ -189,16 +199,24 @@ int fido_check_flags(uint8_t, fido_opt_t, fido_opt_t); int fido_check_rp_id(const char *, const unsigned char *); int fido_get_random(void *, size_t); int fido_sha256(fido_blob_t *, const u_char *, size_t); +int fido_time_now(struct timespec *); +int fido_time_delta(const struct timespec *, int *); /* crypto */ -int fido_verify_sig_es256(const fido_blob_t *, const es256_pk_t *, +int es256_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *); +int rs256_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *); +int eddsa_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *); +int rs1_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *); +int es256_pk_verify_sig(const fido_blob_t *, const es256_pk_t *, const fido_blob_t *); -int fido_verify_sig_rs256(const fido_blob_t *, const rs256_pk_t *, +int rs256_pk_verify_sig(const fido_blob_t *, const rs256_pk_t *, const fido_blob_t *); -int fido_verify_sig_eddsa(const fido_blob_t *, const eddsa_pk_t *, +int eddsa_pk_verify_sig(const fido_blob_t *, const eddsa_pk_t *, const fido_blob_t *); int fido_get_signed_hash(int, fido_blob_t *, const fido_blob_t *, const fido_blob_t *); +int fido_get_signed_hash_tpm(fido_blob_t *, const fido_blob_t *, + const fido_blob_t *, const fido_attstmt_t *, const fido_attcred_t *); /* device manifest functions */ int fido_hid_manifest(fido_dev_info_t *, size_t, size_t *); @@ -232,6 +250,7 @@ uint32_t uniform_random(uint32_t); #define FIDO_DUMMY_USER_NAME "dummy" #define FIDO_DUMMY_USER_ID 1 #define FIDO_WINHELLO_PATH "windows://hello" +#define FIDO_NFC_PREFIX "nfc:" #ifdef __cplusplus } /* extern "C" */ diff --git a/contrib/libfido2/src/fido.h b/contrib/libfido2/src/fido.h index d5446516f972..51bdb526d3f0 100644 --- a/contrib/libfido2/src/fido.h +++ b/contrib/libfido2/src/fido.h @@ -86,16 +86,17 @@ const char *fido_dev_info_product_string(const fido_dev_info_t *); const fido_dev_info_t *fido_dev_info_ptr(const fido_dev_info_t *, size_t); const uint8_t *fido_cbor_info_protocols_ptr(const fido_cbor_info_t *); const unsigned char *fido_cbor_info_aaguid_ptr(const fido_cbor_info_t *); +const unsigned char *fido_cred_aaguid_ptr(const fido_cred_t *); +const unsigned char *fido_cred_attstmt_ptr(const fido_cred_t *); const unsigned char *fido_cred_authdata_ptr(const fido_cred_t *); const unsigned char *fido_cred_authdata_raw_ptr(const fido_cred_t *); const unsigned char *fido_cred_clientdata_hash_ptr(const fido_cred_t *); const unsigned char *fido_cred_id_ptr(const fido_cred_t *); -const unsigned char *fido_cred_aaguid_ptr(const fido_cred_t *); -const unsigned char *fido_cred_user_id_ptr(const fido_cred_t *); +const unsigned char *fido_cred_largeblob_key_ptr(const fido_cred_t *); const unsigned char *fido_cred_pubkey_ptr(const fido_cred_t *); const unsigned char *fido_cred_sig_ptr(const fido_cred_t *); +const unsigned char *fido_cred_user_id_ptr(const fido_cred_t *); const unsigned char *fido_cred_x5c_ptr(const fido_cred_t *); -const unsigned char *fido_cred_largeblob_key_ptr(const fido_cred_t *); int fido_assert_allow_cred(fido_assert_t *, const unsigned char *, size_t); int fido_assert_set_authdata(fido_assert_t *, size_t, const unsigned char *, @@ -119,6 +120,7 @@ int fido_assert_verify(const fido_assert_t *, size_t, int, const void *); int fido_cbor_info_algorithm_cose(const fido_cbor_info_t *, size_t); int fido_cred_exclude(fido_cred_t *, const unsigned char *, size_t); int fido_cred_prot(const fido_cred_t *); +int fido_cred_set_attstmt(fido_cred_t *, const unsigned char *, size_t); int fido_cred_set_authdata(fido_cred_t *, const unsigned char *, size_t); int fido_cred_set_authdata_raw(fido_cred_t *, const unsigned char *, size_t); int fido_cred_set_blob(fido_cred_t *, const unsigned char *, size_t); @@ -128,6 +130,7 @@ int fido_cred_set_extensions(fido_cred_t *, int); int fido_cred_set_fmt(fido_cred_t *, const char *); int fido_cred_set_id(fido_cred_t *, const unsigned char *, size_t); int fido_cred_set_options(fido_cred_t *, bool, bool); +int fido_cred_set_pin_minlen(fido_cred_t *, size_t); int fido_cred_set_prot(fido_cred_t *, int); int fido_cred_set_rk(fido_cred_t *, fido_opt_t); int fido_cred_set_rp(fido_cred_t *, const char *, const char *); @@ -157,6 +160,7 @@ int fido_dev_reset(fido_dev_t *); int fido_dev_set_io_functions(fido_dev_t *, const fido_dev_io_t *); int fido_dev_set_pin(fido_dev_t *, const char *, const char *); int fido_dev_set_transport_functions(fido_dev_t *, const fido_dev_transport_t *); +int fido_dev_set_timeout(fido_dev_t *, int); size_t fido_assert_authdata_len(const fido_assert_t *, size_t); size_t fido_assert_clientdata_hash_len(const fido_assert_t *); @@ -174,16 +178,18 @@ size_t fido_cbor_info_options_len(const fido_cbor_info_t *); size_t fido_cbor_info_protocols_len(const fido_cbor_info_t *); size_t fido_cbor_info_transports_len(const fido_cbor_info_t *); size_t fido_cbor_info_versions_len(const fido_cbor_info_t *); +size_t fido_cred_aaguid_len(const fido_cred_t *); +size_t fido_cred_attstmt_len(const fido_cred_t *); size_t fido_cred_authdata_len(const fido_cred_t *); size_t fido_cred_authdata_raw_len(const fido_cred_t *); size_t fido_cred_clientdata_hash_len(const fido_cred_t *); size_t fido_cred_id_len(const fido_cred_t *); -size_t fido_cred_aaguid_len(const fido_cred_t *); -size_t fido_cred_user_id_len(const fido_cred_t *); +size_t fido_cred_largeblob_key_len(const fido_cred_t *); +size_t fido_cred_pin_minlen(const fido_cred_t *); size_t fido_cred_pubkey_len(const fido_cred_t *); size_t fido_cred_sig_len(const fido_cred_t *); +size_t fido_cred_user_id_len(const fido_cred_t *); size_t fido_cred_x5c_len(const fido_cred_t *); -size_t fido_cred_largeblob_key_len(const fido_cred_t *); uint8_t fido_assert_flags(const fido_assert_t *, size_t); uint32_t fido_assert_sigcount(const fido_assert_t *, size_t); diff --git a/contrib/libfido2/src/fido/config.h b/contrib/libfido2/src/fido/config.h index 869927df914b..d8134a3c7b6c 100644 --- a/contrib/libfido2/src/fido/config.h +++ b/contrib/libfido2/src/fido/config.h @@ -26,6 +26,8 @@ int fido_dev_enable_entattest(fido_dev_t *, const char *); int fido_dev_force_pin_change(fido_dev_t *, const char *); int fido_dev_toggle_always_uv(fido_dev_t *, const char *); int fido_dev_set_pin_minlen(fido_dev_t *, size_t, const char *); +int fido_dev_set_pin_minlen_rpid(fido_dev_t *, const char * const *, size_t, + const char *); #ifdef __cplusplus } /* extern "C" */ diff --git a/contrib/libfido2/src/fido/eddsa.h b/contrib/libfido2/src/fido/eddsa.h index 4a810179b6fa..083721cc3d3f 100644 --- a/contrib/libfido2/src/fido/eddsa.h +++ b/contrib/libfido2/src/fido/eddsa.h @@ -31,19 +31,14 @@ int eddsa_pk_from_ptr(eddsa_pk_t *, const void *, size_t); #ifdef _FIDO_INTERNAL -#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10101000L +#if defined(LIBRESSL_VERSION_NUMBER) #define EVP_PKEY_ED25519 EVP_PKEY_NONE int EVP_PKEY_get_raw_public_key(const EVP_PKEY *, unsigned char *, size_t *); EVP_PKEY *EVP_PKEY_new_raw_public_key(int, ENGINE *, const unsigned char *, size_t); int EVP_DigestVerify(EVP_MD_CTX *, const unsigned char *, size_t, const unsigned char *, size_t); -#endif /* LIBRESSL_VERSION_NUMBER || OPENSSL_VERSION_NUMBER < 0x10101000L */ - -#if OPENSSL_VERSION_NUMBER < 0x10100000L -EVP_MD_CTX *EVP_MD_CTX_new(void); -void EVP_MD_CTX_free(EVP_MD_CTX *); -#endif +#endif /* LIBRESSL_VERSION_NUMBER */ #endif /* _FIDO_INTERNAL */ diff --git a/contrib/libfido2/src/fido/es256.h b/contrib/libfido2/src/fido/es256.h index 80f4db39c7b0..683494dadfe2 100644 --- a/contrib/libfido2/src/fido/es256.h +++ b/contrib/libfido2/src/fido/es256.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -27,6 +27,7 @@ void es256_pk_free(es256_pk_t **); EVP_PKEY *es256_pk_to_EVP_PKEY(const es256_pk_t *); int es256_pk_from_EC_KEY(es256_pk_t *, const EC_KEY *); +int es256_pk_from_EVP_PKEY(es256_pk_t *, const EVP_PKEY *); int es256_pk_from_ptr(es256_pk_t *, const void *, size_t); #ifdef _FIDO_INTERNAL diff --git a/contrib/libfido2/src/fido/param.h b/contrib/libfido2/src/fido/param.h index 025bb57dd81c..7c6db98cfd5d 100644 --- a/contrib/libfido2/src/fido/param.h +++ b/contrib/libfido2/src/fido/param.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -82,10 +82,12 @@ #define FIDO_CAP_NMSG 0x08 /* if set, device doesn't support CTAP_CMD_MSG */ /* Supported COSE algorithms. */ +#define COSE_UNSPEC 0 #define COSE_ES256 -7 #define COSE_EDDSA -8 #define COSE_ECDH_ES256 -25 #define COSE_RS256 -257 +#define COSE_RS1 -65535 /* Supported COSE types. */ #define COSE_KTY_OKP 1 @@ -101,6 +103,7 @@ #define FIDO_EXT_CRED_PROTECT 0x02 #define FIDO_EXT_LARGEBLOB_KEY 0x04 #define FIDO_EXT_CRED_BLOB 0x08 +#define FIDO_EXT_MINPINLEN 0x10 /* Supported credential protection policies. */ #define FIDO_CRED_PROT_UV_OPTIONAL 0x01 @@ -111,7 +114,8 @@ #define FIDO_EXT_ASSERT_MASK (FIDO_EXT_HMAC_SECRET|FIDO_EXT_LARGEBLOB_KEY| \ FIDO_EXT_CRED_BLOB) #define FIDO_EXT_CRED_MASK (FIDO_EXT_HMAC_SECRET|FIDO_EXT_CRED_PROTECT| \ - FIDO_EXT_LARGEBLOB_KEY|FIDO_EXT_CRED_BLOB) + FIDO_EXT_LARGEBLOB_KEY|FIDO_EXT_CRED_BLOB| \ + FIDO_EXT_MINPINLEN) #endif /* _FIDO_INTERNAL */ #endif /* !_FIDO_PARAM_H */ diff --git a/contrib/libfido2/src/fido/rs256.h b/contrib/libfido2/src/fido/rs256.h index 2b08d59980c1..039816191783 100644 --- a/contrib/libfido2/src/fido/rs256.h +++ b/contrib/libfido2/src/fido/rs256.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -26,6 +26,7 @@ rs256_pk_t *rs256_pk_new(void); void rs256_pk_free(rs256_pk_t **); EVP_PKEY *rs256_pk_to_EVP_PKEY(const rs256_pk_t *); +int rs256_pk_from_EVP_PKEY(rs256_pk_t *, const EVP_PKEY *); int rs256_pk_from_RSA(rs256_pk_t *, const RSA *); int rs256_pk_from_ptr(rs256_pk_t *, const void *, size_t); diff --git a/contrib/libfido2/src/fido/types.h b/contrib/libfido2/src/fido/types.h index 00b6058c7e13..92f55d979fdc 100644 --- a/contrib/libfido2/src/fido/types.h +++ b/contrib/libfido2/src/fido/types.h @@ -107,8 +107,12 @@ typedef struct fido_attcred { } fido_attcred_t; typedef struct fido_attstmt { - fido_blob_t x5c; /* attestation certificate */ - fido_blob_t sig; /* attestation signature */ + fido_blob_t certinfo; /* tpm attestation TPMS_ATTEST structure */ + fido_blob_t pubarea; /* tpm attestation TPMT_PUBLIC structure */ + fido_blob_t cbor; /* cbor-encoded attestation statement */ + fido_blob_t x5c; /* attestation certificate */ + fido_blob_t sig; /* attestation signature */ + int alg; /* attestation algorithm (cose) */ } fido_attstmt_t; typedef struct fido_rp { @@ -124,8 +128,9 @@ typedef struct fido_user { } fido_user_t; typedef struct fido_cred_ext { - int mask; /* enabled extensions */ - int prot; /* protection policy */ + int mask; /* enabled extensions */ + int prot; /* protection policy */ + size_t minpinlen; /* minimum pin length */ } fido_cred_ext_t; typedef struct fido_cred { @@ -260,6 +265,7 @@ typedef struct fido_dev { int flags; /* internal flags; see FIDO_DEV_* */ fido_dev_transport_t transport; /* transport functions */ uint64_t maxmsgsize; /* max message size */ + int timeout_ms; /* read timeout in ms */ } fido_dev_t; #else diff --git a/contrib/libfido2/src/hid_freebsd.c b/contrib/libfido2/src/hid_freebsd.c index 86c1854e9c8c..5aefe69c1bec 100644 --- a/contrib/libfido2/src/hid_freebsd.c +++ b/contrib/libfido2/src/hid_freebsd.c @@ -14,6 +14,12 @@ #include "fido.h" +#if defined(__MidnightBSD__) +#define UHID_VENDOR "MidnightBSD" +#else +#define UHID_VENDOR "FreeBSD" +#endif + #define MAX_UHID 64 struct hid_freebsd { @@ -66,7 +72,7 @@ copy_info(fido_dev_info_t *di, const char *path) if (ioctl(fd, IOCTL_REQ(USB_GET_DEVICEINFO), &udi) == -1) { fido_log_error(errno, "%s: ioctl", __func__); - strlcpy(udi.udi_vendor, "FreeBSD", sizeof(udi.udi_vendor)); + strlcpy(udi.udi_vendor, UHID_VENDOR, sizeof(udi.udi_vendor)); strlcpy(udi.udi_product, "uhid(4)", sizeof(udi.udi_product)); udi.udi_vendorNo = 0x0b5d; /* stolen from PCI_VENDOR_OPENBSD */ } diff --git a/contrib/libfido2/src/hid_linux.c b/contrib/libfido2/src/hid_linux.c index c622880a2594..c4ce4fd578a6 100644 --- a/contrib/libfido2/src/hid_linux.c +++ b/contrib/libfido2/src/hid_linux.c @@ -160,9 +160,9 @@ copy_info(fido_dev_info_t *di, struct udev *udev, di->path = strdup(path); if ((di->manufacturer = get_usb_attr(dev, "manufacturer")) == NULL) - di->manufacturer = strdup("unknown"); + di->manufacturer = strdup(""); if ((di->product = get_usb_attr(dev, "product")) == NULL) - di->product = strdup("unknown"); + di->product = strdup(""); if (di->path == NULL || di->manufacturer == NULL || di->product == NULL) goto fail; diff --git a/contrib/libfido2/src/hid_openbsd.c b/contrib/libfido2/src/hid_openbsd.c index fbf10fd11ab9..d3d3bff0fc8b 100644 --- a/contrib/libfido2/src/hid_openbsd.c +++ b/contrib/libfido2/src/hid_openbsd.c @@ -23,6 +23,8 @@ struct hid_openbsd { int fd; size_t report_in_len; size_t report_out_len; + sigset_t sigmask; + const sigset_t *sigmaskp; }; int @@ -185,10 +187,12 @@ fido_hid_close(void *handle) int fido_hid_set_sigmask(void *handle, const fido_sigset_t *sigmask) { - (void)handle; - (void)sigmask; + struct hid_openbsd *ctx = handle; + + ctx->sigmask = *sigmask; + ctx->sigmaskp = &ctx->sigmask; - return (FIDO_ERR_INTERNAL); + return (FIDO_OK); } int @@ -197,14 +201,17 @@ fido_hid_read(void *handle, unsigned char *buf, size_t len, int ms) struct hid_openbsd *ctx = (struct hid_openbsd *)handle; ssize_t r; - (void)ms; /* XXX */ - if (len != ctx->report_in_len) { fido_log_debug("%s: invalid len: got %zu, want %zu", __func__, len, ctx->report_in_len); return (-1); } + if (fido_hid_unix_wait(ctx->fd, ms, ctx->sigmaskp) < 0) { + fido_log_debug("%s: fd not ready", __func__); + return (-1); + } + if ((r = read(ctx->fd, buf, len)) == -1) { fido_log_error(errno, "%s: read", __func__); return (-1); diff --git a/contrib/libfido2/src/hid_osx.c b/contrib/libfido2/src/hid_osx.c index e9866658a4eb..1f8b37a65597 100644 --- a/contrib/libfido2/src/hid_osx.c +++ b/contrib/libfido2/src/hid_osx.c @@ -11,6 +11,7 @@ #include <signal.h> #include <unistd.h> +#include <Availability.h> #include <CoreFoundation/CoreFoundation.h> #include <IOKit/IOKitLib.h> #include <IOKit/hid/IOHIDKeys.h> @@ -18,6 +19,10 @@ #include "fido.h" +#if __MAC_OS_X_VERSION_MIN_REQUIRED < 120000 +#define kIOMainPortDefault kIOMasterPortDefault +#endif + struct hid_osx { IOHIDDeviceRef ref; CFStringRef loop_id; @@ -131,23 +136,18 @@ get_str(IOHIDDeviceRef dev, char **manufacturer, char **product) *manufacturer = NULL; *product = NULL; - if (get_utf8(dev, CFSTR(kIOHIDManufacturerKey), buf, sizeof(buf)) < 0) { - fido_log_debug("%s: get_utf8 manufacturer", __func__); - goto fail; - } - - if ((*manufacturer = strdup(buf)) == NULL) { - fido_log_debug("%s: strdup manufacturer", __func__); - goto fail; - } + if (get_utf8(dev, CFSTR(kIOHIDManufacturerKey), buf, sizeof(buf)) < 0) + *manufacturer = strdup(""); + else + *manufacturer = strdup(buf); - if (get_utf8(dev, CFSTR(kIOHIDProductKey), buf, sizeof(buf)) < 0) { - fido_log_debug("%s: get_utf8 product", __func__); - goto fail; - } + if (get_utf8(dev, CFSTR(kIOHIDProductKey), buf, sizeof(buf)) < 0) + *product = strdup(""); + else + *product = strdup(buf); - if ((*product = strdup(buf)) == NULL) { - fido_log_debug("%s: strdup product", __func__); + if (*manufacturer == NULL || *product == NULL) { + fido_log_debug("%s: strdup", __func__); goto fail; } @@ -398,7 +398,7 @@ fido_hid_open(const char *path) goto fail; } - if ((entry = IORegistryEntryFromPath(kIOMasterPortDefault, + if ((entry = IORegistryEntryFromPath(kIOMainPortDefault, path)) == MACH_PORT_NULL) { fido_log_debug("%s: IORegistryEntryFromPath", __func__); goto fail; diff --git a/contrib/libfido2/src/hid_unix.c b/contrib/libfido2/src/hid_unix.c index 4b2aff9d67f6..946b2dc3b65f 100644 --- a/contrib/libfido2/src/hid_unix.c +++ b/contrib/libfido2/src/hid_unix.c @@ -58,8 +58,7 @@ fido_hid_unix_wait(int fd, int ms, const fido_sigset_t *sigmask) pfd.fd = fd; #ifdef FIDO_FUZZ - if (ms < 0) - return (0); + return (0); #endif if (ms > -1) { ts.tv_sec = ms / 1000; diff --git a/contrib/libfido2/src/hid_win.c b/contrib/libfido2/src/hid_win.c index 455cf8bae835..c29ef70253d7 100644 --- a/contrib/libfido2/src/hid_win.c +++ b/contrib/libfido2/src/hid_win.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Yubico AB. All rights reserved. + * Copyright (c) 2019-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -103,7 +103,7 @@ fail: } static int -get_int(HANDLE dev, int16_t *vendor_id, int16_t *product_id) +get_id(HANDLE dev, int16_t *vendor_id, int16_t *product_id) { HIDD_ATTRIBUTES attr; @@ -121,14 +121,13 @@ get_int(HANDLE dev, int16_t *vendor_id, int16_t *product_id) } static int -get_str(HANDLE dev, char **manufacturer, char **product) +get_manufacturer(HANDLE dev, char **manufacturer) { wchar_t buf[512]; int utf8_len; int ok = -1; *manufacturer = NULL; - *product = NULL; if (HidD_GetManufacturerString(dev, &buf, sizeof(buf)) == false) { fido_log_debug("%s: HidD_GetManufacturerString", __func__); @@ -152,6 +151,25 @@ get_str(HANDLE dev, char **manufacturer, char **product) goto fail; } + ok = 0; +fail: + if (ok < 0) { + free(*manufacturer); + *manufacturer = NULL; + } + + return (ok); +} + +static int +get_product(HANDLE dev, char **product) +{ + wchar_t buf[512]; + int utf8_len; + int ok = -1; + + *product = NULL; + if (HidD_GetProductString(dev, &buf, sizeof(buf)) == false) { fido_log_debug("%s: HidD_GetProductString", __func__); goto fail; @@ -177,9 +195,7 @@ get_str(HANDLE dev, char **manufacturer, char **product) ok = 0; fail: if (ok < 0) { - free(*manufacturer); free(*product); - *manufacturer = NULL; *product = NULL; } @@ -313,9 +329,23 @@ copy_info(fido_dev_info_t *di, HDEVINFO devinfo, DWORD idx, goto fail; } - if (get_int(dev, &di->vendor_id, &di->product_id) < 0 || - get_str(dev, &di->manufacturer, &di->product) < 0) { - fido_log_debug("%s: get_int/get_str", __func__); + if (get_id(dev, &di->vendor_id, &di->product_id) < 0) { + fido_log_debug("%s: get_id", __func__); + goto fail; + } + + if (get_manufacturer(dev, &di->manufacturer) < 0) { + fido_log_debug("%s: get_manufacturer", __func__); + di->manufacturer = strdup(""); + } + + if (get_product(dev, &di->product) < 0) { + fido_log_debug("%s: get_product", __func__); + di->product = strdup(""); + } + + if (di->manufacturer == NULL || di->product == NULL) { + fido_log_debug("%s: manufacturer/product", __func__); goto fail; } diff --git a/contrib/libfido2/src/info.c b/contrib/libfido2/src/info.c index 57bc8de44063..167a1d30ecaa 100644 --- a/contrib/libfido2/src/info.c +++ b/contrib/libfido2/src/info.c @@ -186,14 +186,6 @@ out: return (ok); } -static void -free_algo(fido_algo_t *a) -{ - free(a->type); - a->type = NULL; - a->cose = 0; -} - static int decode_algorithm(const cbor_item_t *item, void *arg) { @@ -210,7 +202,7 @@ decode_algorithm(const cbor_item_t *item, void *arg) if (cbor_map_iter(item, &aa->ptr[i], decode_algorithm_entry) < 0) { fido_log_debug("%s: decode_algorithm_entry", __func__); - free_algo(&aa->ptr[i]); + fido_algo_free(&aa->ptr[i]); return (-1); } @@ -287,13 +279,13 @@ parse_reply_element(const cbor_item_t *key, const cbor_item_t *val, void *arg) } static int -fido_dev_get_cbor_info_tx(fido_dev_t *dev) +fido_dev_get_cbor_info_tx(fido_dev_t *dev, int *ms) { const unsigned char cbor[] = { CTAP_CBOR_GETINFO }; fido_log_debug("%s: dev=%p", __func__, (void *)dev); - if (fido_tx(dev, CTAP_CMD_CBOR, cbor, sizeof(cbor)) < 0) { + if (fido_tx(dev, CTAP_CMD_CBOR, cbor, sizeof(cbor), ms) < 0) { fido_log_debug("%s: fido_tx", __func__); return (FIDO_ERR_TX); } @@ -302,13 +294,13 @@ fido_dev_get_cbor_info_tx(fido_dev_t *dev) } static int -fido_dev_get_cbor_info_rx(fido_dev_t *dev, fido_cbor_info_t *ci, int ms) +fido_dev_get_cbor_info_rx(fido_dev_t *dev, fido_cbor_info_t *ci, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; fido_log_debug("%s: dev=%p, ci=%p, ms=%d", __func__, (void *)dev, - (void *)ci, ms); + (void *)ci, *ms); fido_cbor_info_reset(ci); @@ -323,7 +315,7 @@ fido_dev_get_cbor_info_rx(fido_dev_t *dev, fido_cbor_info_t *ci, int ms) } int -fido_dev_get_cbor_info_wait(fido_dev_t *dev, fido_cbor_info_t *ci, int ms) +fido_dev_get_cbor_info_wait(fido_dev_t *dev, fido_cbor_info_t *ci, int *ms) { int r; @@ -331,7 +323,7 @@ fido_dev_get_cbor_info_wait(fido_dev_t *dev, fido_cbor_info_t *ci, int ms) if (dev->flags & FIDO_DEV_WINHELLO) return (fido_winhello_get_cbor_info(dev, ci)); #endif - if ((r = fido_dev_get_cbor_info_tx(dev)) != FIDO_OK || + if ((r = fido_dev_get_cbor_info_tx(dev, ms)) != FIDO_OK || (r = fido_dev_get_cbor_info_rx(dev, ci, ms)) != FIDO_OK) return (r); @@ -341,7 +333,9 @@ fido_dev_get_cbor_info_wait(fido_dev_t *dev, fido_cbor_info_t *ci, int ms) int fido_dev_get_cbor_info(fido_dev_t *dev, fido_cbor_info_t *ci) { - return (fido_dev_get_cbor_info_wait(dev, ci, -1)); + int ms = dev->timeout_ms; + + return (fido_dev_get_cbor_info_wait(dev, ci, &ms)); } /* @@ -354,58 +348,15 @@ fido_cbor_info_new(void) return (calloc(1, sizeof(fido_cbor_info_t))); } -static void -free_str_array(fido_str_array_t *sa) -{ - for (size_t i = 0; i < sa->len; i++) - free(sa->ptr[i]); - - free(sa->ptr); - sa->ptr = NULL; - sa->len = 0; -} - -static void -free_opt_array(fido_opt_array_t *oa) -{ - for (size_t i = 0; i < oa->len; i++) - free(oa->name[i]); - - free(oa->name); - free(oa->value); - oa->name = NULL; - oa->value = NULL; -} - -static void -free_byte_array(fido_byte_array_t *ba) -{ - free(ba->ptr); - - ba->ptr = NULL; - ba->len = 0; -} - -static void -free_algo_array(fido_algo_array_t *aa) -{ - for (size_t i = 0; i < aa->len; i++) - free_algo(&aa->ptr[i]); - - free(aa->ptr); - aa->ptr = NULL; - aa->len = 0; -} - void fido_cbor_info_reset(fido_cbor_info_t *ci) { - free_str_array(&ci->versions); - free_str_array(&ci->extensions); - free_str_array(&ci->transports); - free_opt_array(&ci->options); - free_byte_array(&ci->protocols); - free_algo_array(&ci->algorithms); + fido_str_array_free(&ci->versions); + fido_str_array_free(&ci->extensions); + fido_str_array_free(&ci->transports); + fido_opt_array_free(&ci->options); + fido_byte_array_free(&ci->protocols); + fido_algo_array_free(&ci->algorithms); } void diff --git a/contrib/libfido2/src/io.c b/contrib/libfido2/src/io.c index e2594203efb0..70f777fb49a0 100644 --- a/contrib/libfido2/src/io.c +++ b/contrib/libfido2/src/io.c @@ -30,7 +30,24 @@ struct frame { #endif static int -tx_empty(fido_dev_t *d, uint8_t cmd) +tx_pkt(fido_dev_t *d, const void *pkt, size_t len, int *ms) +{ + struct timespec ts; + int n; + + if (fido_time_now(&ts) != 0) + return (-1); + + n = d->io.write(d->io_handle, pkt, len); + + if (fido_time_delta(&ts, ms) != 0) + return (-1); + + return (n); +} + +static int +tx_empty(fido_dev_t *d, uint8_t cmd, int *ms) { struct frame *fp; unsigned char pkt[sizeof(*fp) + 1]; @@ -42,15 +59,15 @@ tx_empty(fido_dev_t *d, uint8_t cmd) fp->cid = d->cid; fp->body.init.cmd = CTAP_FRAME_INIT | cmd; - if (len > sizeof(pkt) || (n = d->io.write(d->io_handle, pkt, - len)) < 0 || (size_t)n != len) + if (len > sizeof(pkt) || (n = tx_pkt(d, pkt, len, ms)) < 0 || + (size_t)n != len) return (-1); return (0); } static size_t -tx_preamble(fido_dev_t *d, uint8_t cmd, const void *buf, size_t count) +tx_preamble(fido_dev_t *d, uint8_t cmd, const void *buf, size_t count, int *ms) { struct frame *fp; unsigned char pkt[sizeof(*fp) + 1]; @@ -69,15 +86,15 @@ tx_preamble(fido_dev_t *d, uint8_t cmd, const void *buf, size_t count) count = MIN(count, d->tx_len - CTAP_INIT_HEADER_LEN); memcpy(&fp->body.init.data, buf, count); - if (len > sizeof(pkt) || (n = d->io.write(d->io_handle, pkt, - len)) < 0 || (size_t)n != len) + if (len > sizeof(pkt) || (n = tx_pkt(d, pkt, len, ms)) < 0 || + (size_t)n != len) return (0); return (count); } static size_t -tx_frame(fido_dev_t *d, uint8_t seq, const void *buf, size_t count) +tx_frame(fido_dev_t *d, uint8_t seq, const void *buf, size_t count, int *ms) { struct frame *fp; unsigned char pkt[sizeof(*fp) + 1]; @@ -94,19 +111,19 @@ tx_frame(fido_dev_t *d, uint8_t seq, const void *buf, size_t count) count = MIN(count, d->tx_len - CTAP_CONT_HEADER_LEN); memcpy(&fp->body.cont.data, buf, count); - if (len > sizeof(pkt) || (n = d->io.write(d->io_handle, pkt, - len)) < 0 || (size_t)n != len) + if (len > sizeof(pkt) || (n = tx_pkt(d, pkt, len, ms)) < 0 || + (size_t)n != len) return (0); return (count); } static int -tx(fido_dev_t *d, uint8_t cmd, const unsigned char *buf, size_t count) +tx(fido_dev_t *d, uint8_t cmd, const unsigned char *buf, size_t count, int *ms) { size_t n, sent; - if ((sent = tx_preamble(d, cmd, buf, count)) == 0) { + if ((sent = tx_preamble(d, cmd, buf, count, ms)) == 0) { fido_log_debug("%s: tx_preamble", __func__); return (-1); } @@ -116,7 +133,8 @@ tx(fido_dev_t *d, uint8_t cmd, const unsigned char *buf, size_t count) fido_log_debug("%s: seq & 0x80", __func__); return (-1); } - if ((n = tx_frame(d, seq++, buf + sent, count - sent)) == 0) { + if ((n = tx_frame(d, seq++, buf + sent, count - sent, + ms)) == 0) { fido_log_debug("%s: tx_frame", __func__); return (-1); } @@ -125,38 +143,59 @@ tx(fido_dev_t *d, uint8_t cmd, const unsigned char *buf, size_t count) return (0); } +static int +transport_tx(fido_dev_t *d, uint8_t cmd, const void *buf, size_t count, int *ms) +{ + struct timespec ts; + int n; + + if (fido_time_now(&ts) != 0) + return (-1); + + n = d->transport.tx(d, cmd, buf, count); + + if (fido_time_delta(&ts, ms) != 0) + return (-1); + + return (n); +} + int -fido_tx(fido_dev_t *d, uint8_t cmd, const void *buf, size_t count) +fido_tx(fido_dev_t *d, uint8_t cmd, const void *buf, size_t count, int *ms) { fido_log_debug("%s: dev=%p, cmd=0x%02x", __func__, (void *)d, cmd); fido_log_xxd(buf, count, "%s", __func__); if (d->transport.tx != NULL) - return (d->transport.tx(d, cmd, buf, count)); + return (transport_tx(d, cmd, buf, count, ms)); if (d->io_handle == NULL || d->io.write == NULL || count > UINT16_MAX) { fido_log_debug("%s: invalid argument", __func__); return (-1); } - return (count == 0 ? tx_empty(d, cmd) : tx(d, cmd, buf, count)); + return (count == 0 ? tx_empty(d, cmd, ms) : tx(d, cmd, buf, count, ms)); } static int -rx_frame(fido_dev_t *d, struct frame *fp, int ms) +rx_frame(fido_dev_t *d, struct frame *fp, int *ms) { + struct timespec ts; int n; memset(fp, 0, sizeof(*fp)); + if (fido_time_now(&ts) != 0) + return (-1); + if (d->rx_len > sizeof(*fp) || (n = d->io.read(d->io_handle, - (unsigned char *)fp, d->rx_len, ms)) < 0 || (size_t)n != d->rx_len) + (unsigned char *)fp, d->rx_len, *ms)) < 0 || (size_t)n != d->rx_len) return (-1); - return (0); + return (fido_time_delta(&ts, ms)); } static int -rx_preamble(fido_dev_t *d, uint8_t cmd, struct frame *fp, int ms) +rx_preamble(fido_dev_t *d, uint8_t cmd, struct frame *fp, int *ms) { do { if (rx_frame(d, fp, ms) < 0) @@ -185,7 +224,7 @@ rx_preamble(fido_dev_t *d, uint8_t cmd, struct frame *fp, int ms) } static int -rx(fido_dev_t *d, uint8_t cmd, unsigned char *buf, size_t count, int ms) +rx(fido_dev_t *d, uint8_t cmd, unsigned char *buf, size_t count, int *ms) { struct frame f; size_t r, payload_len, init_data_len, cont_data_len; @@ -252,16 +291,33 @@ rx(fido_dev_t *d, uint8_t cmd, unsigned char *buf, size_t count, int ms) return ((int)r); } +static int +transport_rx(fido_dev_t *d, uint8_t cmd, void *buf, size_t count, int *ms) +{ + struct timespec ts; + int n; + + if (fido_time_now(&ts) != 0) + return (-1); + + n = d->transport.rx(d, cmd, buf, count, *ms); + + if (fido_time_delta(&ts, ms) != 0) + return (-1); + + return (n); +} + int -fido_rx(fido_dev_t *d, uint8_t cmd, void *buf, size_t count, int ms) +fido_rx(fido_dev_t *d, uint8_t cmd, void *buf, size_t count, int *ms) { int n; fido_log_debug("%s: dev=%p, cmd=0x%02x, ms=%d", __func__, (void *)d, - cmd, ms); + cmd, *ms); if (d->transport.rx != NULL) - return (d->transport.rx(d, cmd, buf, count, ms)); + return (transport_rx(d, cmd, buf, count, ms)); if (d->io_handle == NULL || d->io.read == NULL || count > UINT16_MAX) { fido_log_debug("%s: invalid argument", __func__); return (-1); @@ -273,7 +329,7 @@ fido_rx(fido_dev_t *d, uint8_t cmd, void *buf, size_t count, int ms) } int -fido_rx_cbor_status(fido_dev_t *d, int ms) +fido_rx_cbor_status(fido_dev_t *d, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; diff --git a/contrib/libfido2/src/largeblob.c b/contrib/libfido2/src/largeblob.c index fa453f5de33a..c8173170766d 100644 --- a/contrib/libfido2/src/largeblob.c +++ b/contrib/libfido2/src/largeblob.c @@ -153,7 +153,7 @@ fail: } static int -largeblob_get_tx(fido_dev_t *dev, size_t offset, size_t count) +largeblob_get_tx(fido_dev_t *dev, size_t offset, size_t count, int *ms) { fido_blob_t f; cbor_item_t *argv[3]; @@ -169,7 +169,7 @@ largeblob_get_tx(fido_dev_t *dev, size_t offset, size_t count) goto fail; } if (cbor_build_frame(CTAP_CBOR_LARGEBLOB, argv, nitems(argv), &f) < 0 || - fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { + fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -198,7 +198,7 @@ parse_largeblob_reply(const cbor_item_t *key, const cbor_item_t *val, } static int -largeblob_get_rx(fido_dev_t *dev, fido_blob_t **chunk, int ms) +largeblob_get_rx(fido_dev_t *dev, fido_blob_t **chunk, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len, r; @@ -419,7 +419,7 @@ largeblob_array_check(const fido_blob_t *array) } static int -largeblob_get_array(fido_dev_t *dev, cbor_item_t **item) +largeblob_get_array(fido_dev_t *dev, cbor_item_t **item, int *ms) { fido_blob_t *array, *chunk = NULL; size_t n; @@ -432,8 +432,8 @@ largeblob_get_array(fido_dev_t *dev, cbor_item_t **item) return FIDO_ERR_INTERNAL; do { fido_blob_free(&chunk); - if ((r = largeblob_get_tx(dev, array->len, n)) != FIDO_OK || - (r = largeblob_get_rx(dev, &chunk, -1)) != FIDO_OK) { + if ((r = largeblob_get_tx(dev, array->len, n, ms)) != FIDO_OK || + (r = largeblob_get_rx(dev, &chunk, ms)) != FIDO_OK) { fido_log_debug("%s: largeblob_get_wait %zu/%zu", __func__, array->len, n); goto fail; @@ -491,7 +491,7 @@ prepare_hmac(size_t offset, const u_char *data, size_t len, fido_blob_t *hmac) static int largeblob_set_tx(fido_dev_t *dev, const fido_blob_t *token, const u_char *chunk, - size_t chunk_len, size_t offset, size_t totalsiz) + size_t chunk_len, size_t offset, size_t totalsiz, int *ms) { fido_blob_t *hmac = NULL, f; cbor_item_t *argv[6]; @@ -518,7 +518,7 @@ largeblob_set_tx(fido_dev_t *dev, const fido_blob_t *token, const u_char *chunk, } } if (cbor_build_frame(CTAP_CBOR_LARGEBLOB, argv, nitems(argv), &f) < 0 || - fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { + fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -534,7 +534,8 @@ fail: } static int -largeblob_get_uv_token(fido_dev_t *dev, const char *pin, fido_blob_t **token) +largeblob_get_uv_token(fido_dev_t *dev, const char *pin, fido_blob_t **token, + int *ms) { es256_pk_t *pk = NULL; fido_blob_t *ecdh = NULL; @@ -542,12 +543,12 @@ largeblob_get_uv_token(fido_dev_t *dev, const char *pin, fido_blob_t **token) if ((*token = fido_blob_new()) == NULL) return FIDO_ERR_INTERNAL; - if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) { + if ((r = fido_do_ecdh(dev, &pk, &ecdh, ms)) != FIDO_OK) { fido_log_debug("%s: fido_do_ecdh", __func__); goto fail; } if ((r = fido_dev_get_uv_token(dev, CTAP_CBOR_LARGEBLOB, pin, ecdh, pk, - NULL, *token)) != FIDO_OK) { + NULL, *token, ms)) != FIDO_OK) { fido_log_debug("%s: fido_dev_get_uv_token", __func__); goto fail; } @@ -564,7 +565,8 @@ fail: } static int -largeblob_set_array(fido_dev_t *dev, const cbor_item_t *item, const char *pin) +largeblob_set_array(fido_dev_t *dev, const cbor_item_t *item, const char *pin, + int *ms) { unsigned char dgst[SHA256_DIGEST_LENGTH]; fido_blob_t cbor, *token = NULL; @@ -600,7 +602,8 @@ largeblob_set_array(fido_dev_t *dev, const cbor_item_t *item, const char *pin) } totalsize = cbor.len + sizeof(dgst) - 16; /* the first 16 bytes only */ if (pin != NULL || fido_dev_supports_permissions(dev)) { - if ((r = largeblob_get_uv_token(dev, pin, &token)) != FIDO_OK) { + if ((r = largeblob_get_uv_token(dev, pin, &token, + ms)) != FIDO_OK) { fido_log_debug("%s: largeblob_get_uv_token", __func__); goto fail; } @@ -609,15 +612,15 @@ largeblob_set_array(fido_dev_t *dev, const cbor_item_t *item, const char *pin) if ((chunklen = cbor.len - offset) > maxchunklen) chunklen = maxchunklen; if ((r = largeblob_set_tx(dev, token, cbor.ptr + offset, - chunklen, offset, totalsize)) != FIDO_OK || - (r = fido_rx_cbor_status(dev, -1)) != FIDO_OK) { + chunklen, offset, totalsize, ms)) != FIDO_OK || + (r = fido_rx_cbor_status(dev, ms)) != FIDO_OK) { fido_log_debug("%s: body", __func__); goto fail; } } if ((r = largeblob_set_tx(dev, token, dgst, sizeof(dgst) - 16, cbor.len, - totalsize)) != FIDO_OK || - (r = fido_rx_cbor_status(dev, -1)) != FIDO_OK) { + totalsize, ms)) != FIDO_OK || + (r = fido_rx_cbor_status(dev, ms)) != FIDO_OK) { fido_log_debug("%s: dgst", __func__); goto fail; } @@ -632,13 +635,13 @@ fail: static int largeblob_add(fido_dev_t *dev, const fido_blob_t *key, cbor_item_t *item, - const char *pin) + const char *pin, int *ms) { cbor_item_t *array = NULL; size_t idx; int r; - if ((r = largeblob_get_array(dev, &array)) != FIDO_OK) { + if ((r = largeblob_get_array(dev, &array, ms)) != FIDO_OK) { fido_log_debug("%s: largeblob_get_array", __func__); goto fail; } @@ -661,7 +664,7 @@ largeblob_add(fido_dev_t *dev, const fido_blob_t *key, cbor_item_t *item, goto fail; } - if ((r = largeblob_set_array(dev, array, pin)) != FIDO_OK) { + if ((r = largeblob_set_array(dev, array, pin, ms)) != FIDO_OK) { fido_log_debug("%s: largeblob_set_array", __func__); goto fail; } @@ -675,13 +678,14 @@ fail: } static int -largeblob_drop(fido_dev_t *dev, const fido_blob_t *key, const char *pin) +largeblob_drop(fido_dev_t *dev, const fido_blob_t *key, const char *pin, + int *ms) { cbor_item_t *array = NULL; size_t idx; int r; - if ((r = largeblob_get_array(dev, &array)) != FIDO_OK) { + if ((r = largeblob_get_array(dev, &array, ms)) != FIDO_OK) { fido_log_debug("%s: largeblob_get_array", __func__); goto fail; } @@ -694,7 +698,7 @@ largeblob_drop(fido_dev_t *dev, const fido_blob_t *key, const char *pin) r = FIDO_ERR_INTERNAL; goto fail; } - if ((r = largeblob_set_array(dev, array, pin)) != FIDO_OK) { + if ((r = largeblob_set_array(dev, array, pin, ms)) != FIDO_OK) { fido_log_debug("%s: largeblob_set_array", __func__); goto fail; } @@ -713,6 +717,7 @@ fido_dev_largeblob_get(fido_dev_t *dev, const unsigned char *key_ptr, { cbor_item_t *item = NULL; fido_blob_t key, body; + int ms = dev->timeout_ms; int r; memset(&key, 0, sizeof(key)); @@ -733,7 +738,7 @@ fido_dev_largeblob_get(fido_dev_t *dev, const unsigned char *key_ptr, fido_log_debug("%s: fido_blob_set", __func__); return FIDO_ERR_INTERNAL; } - if ((r = largeblob_get_array(dev, &item)) != FIDO_OK) { + if ((r = largeblob_get_array(dev, &item, &ms)) != FIDO_OK) { fido_log_debug("%s: largeblob_get_array", __func__); goto fail; } @@ -759,6 +764,7 @@ fido_dev_largeblob_set(fido_dev_t *dev, const unsigned char *key_ptr, { cbor_item_t *item = NULL; fido_blob_t key, body; + int ms = dev->timeout_ms; int r; memset(&key, 0, sizeof(key)); @@ -784,7 +790,7 @@ fido_dev_largeblob_set(fido_dev_t *dev, const unsigned char *key_ptr, r = FIDO_ERR_INTERNAL; goto fail; } - if ((r = largeblob_add(dev, &key, item, pin)) != FIDO_OK) + if ((r = largeblob_add(dev, &key, item, pin, &ms)) != FIDO_OK) fido_log_debug("%s: largeblob_add", __func__); fail: if (item != NULL) @@ -801,6 +807,7 @@ fido_dev_largeblob_remove(fido_dev_t *dev, const unsigned char *key_ptr, size_t key_len, const char *pin) { fido_blob_t key; + int ms = dev->timeout_ms; int r; memset(&key, 0, sizeof(key)); @@ -813,7 +820,7 @@ fido_dev_largeblob_remove(fido_dev_t *dev, const unsigned char *key_ptr, fido_log_debug("%s: fido_blob_set", __func__); return FIDO_ERR_INTERNAL; } - if ((r = largeblob_drop(dev, &key, pin)) != FIDO_OK) + if ((r = largeblob_drop(dev, &key, pin, &ms)) != FIDO_OK) fido_log_debug("%s: largeblob_drop", __func__); fido_blob_reset(&key); @@ -827,6 +834,7 @@ fido_dev_largeblob_get_array(fido_dev_t *dev, unsigned char **cbor_ptr, { cbor_item_t *item = NULL; fido_blob_t cbor; + int ms = dev->timeout_ms; int r; memset(&cbor, 0, sizeof(cbor)); @@ -838,7 +846,7 @@ fido_dev_largeblob_get_array(fido_dev_t *dev, unsigned char **cbor_ptr, } *cbor_ptr = NULL; *cbor_len = 0; - if ((r = largeblob_get_array(dev, &item)) != FIDO_OK) { + if ((r = largeblob_get_array(dev, &item, &ms)) != FIDO_OK) { fido_log_debug("%s: largeblob_get_array", __func__); return r; } @@ -861,6 +869,7 @@ fido_dev_largeblob_set_array(fido_dev_t *dev, const unsigned char *cbor_ptr, { cbor_item_t *item = NULL; struct cbor_load_result cbor_result; + int ms = dev->timeout_ms; int r; if (cbor_ptr == NULL || cbor_len == 0) { @@ -872,7 +881,7 @@ fido_dev_largeblob_set_array(fido_dev_t *dev, const unsigned char *cbor_ptr, fido_log_debug("%s: cbor_load", __func__); return FIDO_ERR_INVALID_ARGUMENT; } - if ((r = largeblob_set_array(dev, item, pin)) != FIDO_OK) + if ((r = largeblob_set_array(dev, item, pin, &ms)) != FIDO_OK) fido_log_debug("%s: largeblob_set_array", __func__); cbor_decref(&item); diff --git a/contrib/libfido2/src/netlink.c b/contrib/libfido2/src/netlink.c index 6fd9f63cb937..8f14e2c3bac3 100644 --- a/contrib/libfido2/src/netlink.c +++ b/contrib/libfido2/src/netlink.c @@ -30,6 +30,8 @@ static ssize_t (*fuzz_write)(int, const void *, size_t); #define SOL_NETLINK 270 #endif +#define NETLINK_POLL_MS 100 + /* XXX avoid signed NLA_ALIGNTO */ #undef NLA_HDRLEN #define NLA_HDRLEN NLMSG_ALIGN(sizeof(struct nlattr)) @@ -694,7 +696,7 @@ fido_nl_get_nfc_target(fido_nl_t *nl, uint32_t dev, uint32_t *target) return (-1); } #endif - r = nlmsg_rx(nl->fd, reply, sizeof(reply), -1); + r = nlmsg_rx(nl->fd, reply, sizeof(reply), NETLINK_POLL_MS); #ifndef FIDO_FUZZ if (setsockopt(nl->fd, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP, &nl->nfc_mcastgrp, sizeof(nl->nfc_mcastgrp)) == -1) { diff --git a/contrib/libfido2/src/nfc_linux.c b/contrib/libfido2/src/nfc_linux.c index dea9f3f98fd0..d5f9ec048052 100644 --- a/contrib/libfido2/src/nfc_linux.c +++ b/contrib/libfido2/src/nfc_linux.c @@ -13,6 +13,8 @@ #include <errno.h> #include <libudev.h> #include <signal.h> +#include <stdio.h> +#include <string.h> #include <unistd.h> #include "fido.h" @@ -218,16 +220,23 @@ tx_get_response(fido_dev_t *d, uint8_t count) } static int -rx_apdu(fido_dev_t *d, uint8_t sw[2], unsigned char **buf, size_t *count, int ms) +rx_apdu(fido_dev_t *d, uint8_t sw[2], unsigned char **buf, size_t *count, int *ms) { uint8_t f[256 + 2]; + struct timespec ts; int n, ok = -1; - if ((n = d->io.read(d->io_handle, f, sizeof(f), ms)) < 2) { + if (fido_time_now(&ts) != 0) + goto fail; + + if ((n = d->io.read(d->io_handle, f, sizeof(f), *ms)) < 2) { fido_log_debug("%s: read", __func__); goto fail; } + if (fido_time_delta(&ts, ms) != 0) + goto fail; + if (fido_buf_write(buf, count, f, (size_t)(n - 2)) < 0) { fido_log_debug("%s: fido_buf_write", __func__); goto fail; @@ -248,14 +257,14 @@ rx_msg(fido_dev_t *d, unsigned char *buf, size_t count, int ms) uint8_t sw[2]; const size_t bufsiz = count; - if (rx_apdu(d, sw, &buf, &count, ms) < 0) { + if (rx_apdu(d, sw, &buf, &count, &ms) < 0) { fido_log_debug("%s: preamble", __func__); return (-1); } while (sw[0] == SW1_MORE_DATA) if (tx_get_response(d, sw[1]) < 0 || - rx_apdu(d, sw, &buf, &count, ms) < 0) { + rx_apdu(d, sw, &buf, &count, &ms) < 0) { fido_log_debug("%s: chain", __func__); return (-1); } @@ -347,6 +356,7 @@ copy_info(fido_dev_info_t *di, struct udev *udev, const char *name; char *str; struct udev_device *dev = NULL; + void *ctx = NULL; int id, ok = -1; memset(di, 0, sizeof(*di)); @@ -354,27 +364,35 @@ copy_info(fido_dev_info_t *di, struct udev *udev, if ((name = udev_list_entry_get_name(udev_entry)) == NULL || (dev = udev_device_new_from_syspath(udev, name)) == NULL) goto fail; - - if ((di->path = strdup(name)) == NULL || - (di->manufacturer = get_usb_attr(dev, "manufacturer")) == NULL || - (di->product = get_usb_attr(dev, "product")) == NULL) + if (asprintf(&di->path, "%s/%s", FIDO_NFC_PREFIX, name) == -1) + goto fail; + if ((di->manufacturer = get_usb_attr(dev, "manufacturer")) == NULL) + di->manufacturer = strdup(""); + if ((di->product = get_usb_attr(dev, "product")) == NULL) + di->product = strdup(""); + if (di->manufacturer == NULL || di->product == NULL) goto fail; - /* XXX assumes USB for vendor/product info */ if ((str = get_usb_attr(dev, "idVendor")) != NULL && (id = to_int(str, 16)) > 0 && id <= UINT16_MAX) di->vendor_id = (int16_t)id; free(str); - if ((str = get_usb_attr(dev, "idProduct")) != NULL && (id = to_int(str, 16)) > 0 && id <= UINT16_MAX) di->product_id = (int16_t)id; free(str); + if ((ctx = fido_nfc_open(di->path)) == NULL) { + fido_log_debug("%s: fido_nfc_open", __func__); + goto fail; + } + ok = 0; fail: if (dev != NULL) udev_device_unref(dev); + if (ctx != NULL) + fido_nfc_close(ctx); if (ok < 0) { free(di->path); @@ -532,7 +550,11 @@ fido_nfc_open(const char *path) struct nfc_linux *ctx = NULL; int idx; - if ((idx = sysnum_from_syspath(path)) < 0 || + if (strncmp(path, FIDO_NFC_PREFIX, strlen(FIDO_NFC_PREFIX)) != 0) { + fido_log_debug("%s: bad prefix", __func__); + goto fail; + } + if ((idx = sysnum_from_syspath(path + strlen(FIDO_NFC_PREFIX))) < 0 || (ctx = nfc_new((uint32_t)idx)) == NULL) { fido_log_debug("%s: nfc_new", __func__); goto fail; diff --git a/contrib/libfido2/src/pin.c b/contrib/libfido2/src/pin.c index d3104e0ca6ec..30eeb086a6ef 100644 --- a/contrib/libfido2/src/pin.c +++ b/contrib/libfido2/src/pin.c @@ -146,7 +146,7 @@ encode_uv_permission(uint8_t cmd) static int ctap20_uv_token_tx(fido_dev_t *dev, const char *pin, const fido_blob_t *ecdh, - const es256_pk_t *pk) + const es256_pk_t *pk, int *ms) { fido_blob_t f; fido_blob_t *p = NULL; @@ -185,7 +185,7 @@ ctap20_uv_token_tx(fido_dev_t *dev, const char *pin, const fido_blob_t *ecdh, } if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv), - &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { + &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -203,7 +203,7 @@ fail: static int ctap21_uv_token_tx(fido_dev_t *dev, const char *pin, const fido_blob_t *ecdh, - const es256_pk_t *pk, uint8_t cmd, const char *rpid) + const es256_pk_t *pk, uint8_t cmd, const char *rpid, int *ms) { fido_blob_t f; fido_blob_t *p = NULL; @@ -248,7 +248,7 @@ ctap21_uv_token_tx(fido_dev_t *dev, const char *pin, const fido_blob_t *ecdh, } if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv), - &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { + &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -281,7 +281,7 @@ parse_uv_token(const cbor_item_t *key, const cbor_item_t *val, void *arg) static int uv_token_rx(fido_dev_t *dev, const fido_blob_t *ecdh, fido_blob_t *token, - int ms) + int *ms) { fido_blob_t *aes_token = NULL; unsigned char reply[FIDO_MAXMSG]; @@ -322,16 +322,16 @@ fail: static int uv_token_wait(fido_dev_t *dev, uint8_t cmd, const char *pin, const fido_blob_t *ecdh, const es256_pk_t *pk, const char *rpid, - fido_blob_t *token, int ms) + fido_blob_t *token, int *ms) { int r; if (ecdh == NULL || pk == NULL) return (FIDO_ERR_INVALID_ARGUMENT); if (fido_dev_supports_permissions(dev)) - r = ctap21_uv_token_tx(dev, pin, ecdh, pk, cmd, rpid); + r = ctap21_uv_token_tx(dev, pin, ecdh, pk, cmd, rpid, ms); else - r = ctap20_uv_token_tx(dev, pin, ecdh, pk); + r = ctap20_uv_token_tx(dev, pin, ecdh, pk, ms); if (r != FIDO_OK) return (r); @@ -341,13 +341,14 @@ uv_token_wait(fido_dev_t *dev, uint8_t cmd, const char *pin, int fido_dev_get_uv_token(fido_dev_t *dev, uint8_t cmd, const char *pin, const fido_blob_t *ecdh, const es256_pk_t *pk, const char *rpid, - fido_blob_t *token) + fido_blob_t *token, int *ms) { - return (uv_token_wait(dev, cmd, pin, ecdh, pk, rpid, token, -1)); + return (uv_token_wait(dev, cmd, pin, ecdh, pk, rpid, token, ms)); } static int -fido_dev_change_pin_tx(fido_dev_t *dev, const char *pin, const char *oldpin) +fido_dev_change_pin_tx(fido_dev_t *dev, const char *pin, const char *oldpin, + int *ms) { fido_blob_t f; fido_blob_t *ppine = NULL; @@ -368,7 +369,7 @@ fido_dev_change_pin_tx(fido_dev_t *dev, const char *pin, const char *oldpin) goto fail; } - if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) { + if ((r = fido_do_ecdh(dev, &pk, &ecdh, ms)) != FIDO_OK) { fido_log_debug("%s: fido_do_ecdh", __func__); goto fail; } @@ -397,7 +398,7 @@ fido_dev_change_pin_tx(fido_dev_t *dev, const char *pin, const char *oldpin) } if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv), - &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { + &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -418,7 +419,7 @@ fail: } static int -fido_dev_set_pin_tx(fido_dev_t *dev, const char *pin) +fido_dev_set_pin_tx(fido_dev_t *dev, const char *pin, int *ms) { fido_blob_t f; fido_blob_t *ppine = NULL; @@ -430,7 +431,7 @@ fido_dev_set_pin_tx(fido_dev_t *dev, const char *pin) memset(&f, 0, sizeof(f)); memset(argv, 0, sizeof(argv)); - if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) { + if ((r = fido_do_ecdh(dev, &pk, &ecdh, ms)) != FIDO_OK) { fido_log_debug("%s: fido_do_ecdh", __func__); goto fail; } @@ -451,7 +452,7 @@ fido_dev_set_pin_tx(fido_dev_t *dev, const char *pin) } if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv), - &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { + &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -470,17 +471,18 @@ fail: static int fido_dev_set_pin_wait(fido_dev_t *dev, const char *pin, const char *oldpin, - int ms) + int *ms) { int r; if (oldpin != NULL) { - if ((r = fido_dev_change_pin_tx(dev, pin, oldpin)) != FIDO_OK) { + if ((r = fido_dev_change_pin_tx(dev, pin, oldpin, + ms)) != FIDO_OK) { fido_log_debug("%s: fido_dev_change_pin_tx", __func__); return (r); } } else { - if ((r = fido_dev_set_pin_tx(dev, pin)) != FIDO_OK) { + if ((r = fido_dev_set_pin_tx(dev, pin, ms)) != FIDO_OK) { fido_log_debug("%s: fido_dev_set_pin_tx", __func__); return (r); } @@ -502,7 +504,9 @@ fido_dev_set_pin_wait(fido_dev_t *dev, const char *pin, const char *oldpin, int fido_dev_set_pin(fido_dev_t *dev, const char *pin, const char *oldpin) { - return (fido_dev_set_pin_wait(dev, pin, oldpin, -1)); + int ms = dev->timeout_ms; + + return (fido_dev_set_pin_wait(dev, pin, oldpin, &ms)); } static int @@ -542,7 +546,7 @@ parse_uv_retry_count(const cbor_item_t *key, const cbor_item_t *val, void *arg) } static int -fido_dev_get_retry_count_tx(fido_dev_t *dev, uint8_t subcmd) +fido_dev_get_retry_count_tx(fido_dev_t *dev, uint8_t subcmd, int *ms) { fido_blob_t f; cbor_item_t *argv[2]; @@ -558,7 +562,7 @@ fido_dev_get_retry_count_tx(fido_dev_t *dev, uint8_t subcmd) } if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv), - &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { + &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -573,7 +577,7 @@ fail: } static int -fido_dev_get_pin_retry_count_rx(fido_dev_t *dev, int *retries, int ms) +fido_dev_get_pin_retry_count_rx(fido_dev_t *dev, int *retries, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; @@ -597,11 +601,11 @@ fido_dev_get_pin_retry_count_rx(fido_dev_t *dev, int *retries, int ms) } static int -fido_dev_get_pin_retry_count_wait(fido_dev_t *dev, int *retries, int ms) +fido_dev_get_pin_retry_count_wait(fido_dev_t *dev, int *retries, int *ms) { int r; - if ((r = fido_dev_get_retry_count_tx(dev, 1)) != FIDO_OK || + if ((r = fido_dev_get_retry_count_tx(dev, 1, ms)) != FIDO_OK || (r = fido_dev_get_pin_retry_count_rx(dev, retries, ms)) != FIDO_OK) return (r); @@ -611,11 +615,13 @@ fido_dev_get_pin_retry_count_wait(fido_dev_t *dev, int *retries, int ms) int fido_dev_get_retry_count(fido_dev_t *dev, int *retries) { - return (fido_dev_get_pin_retry_count_wait(dev, retries, -1)); + int ms = dev->timeout_ms; + + return (fido_dev_get_pin_retry_count_wait(dev, retries, &ms)); } static int -fido_dev_get_uv_retry_count_rx(fido_dev_t *dev, int *retries, int ms) +fido_dev_get_uv_retry_count_rx(fido_dev_t *dev, int *retries, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; @@ -639,11 +645,11 @@ fido_dev_get_uv_retry_count_rx(fido_dev_t *dev, int *retries, int ms) } static int -fido_dev_get_uv_retry_count_wait(fido_dev_t *dev, int *retries, int ms) +fido_dev_get_uv_retry_count_wait(fido_dev_t *dev, int *retries, int *ms) { int r; - if ((r = fido_dev_get_retry_count_tx(dev, 7)) != FIDO_OK || + if ((r = fido_dev_get_retry_count_tx(dev, 7, ms)) != FIDO_OK || (r = fido_dev_get_uv_retry_count_rx(dev, retries, ms)) != FIDO_OK) return (r); @@ -653,13 +659,15 @@ fido_dev_get_uv_retry_count_wait(fido_dev_t *dev, int *retries, int ms) int fido_dev_get_uv_retry_count(fido_dev_t *dev, int *retries) { - return (fido_dev_get_uv_retry_count_wait(dev, retries, -1)); + int ms = dev->timeout_ms; + + return (fido_dev_get_uv_retry_count_wait(dev, retries, &ms)); } int cbor_add_uv_params(fido_dev_t *dev, uint8_t cmd, const fido_blob_t *hmac_data, const es256_pk_t *pk, const fido_blob_t *ecdh, const char *pin, - const char *rpid, cbor_item_t **auth, cbor_item_t **opt) + const char *rpid, cbor_item_t **auth, cbor_item_t **opt, int *ms) { fido_blob_t *token = NULL; int r; @@ -670,7 +678,7 @@ cbor_add_uv_params(fido_dev_t *dev, uint8_t cmd, const fido_blob_t *hmac_data, } if ((r = fido_dev_get_uv_token(dev, cmd, pin, ecdh, pk, rpid, - token)) != FIDO_OK) { + token, ms)) != FIDO_OK) { fido_log_debug("%s: fido_dev_get_uv_token", __func__); goto fail; } diff --git a/contrib/libfido2/src/reset.c b/contrib/libfido2/src/reset.c index 11380cea0904..c5fe6dfe7ac1 100644 --- a/contrib/libfido2/src/reset.c +++ b/contrib/libfido2/src/reset.c @@ -7,11 +7,11 @@ #include "fido.h" static int -fido_dev_reset_tx(fido_dev_t *dev) +fido_dev_reset_tx(fido_dev_t *dev, int *ms) { const unsigned char cbor[] = { CTAP_CBOR_RESET }; - if (fido_tx(dev, CTAP_CMD_CBOR, cbor, sizeof(cbor)) < 0) { + if (fido_tx(dev, CTAP_CMD_CBOR, cbor, sizeof(cbor), ms) < 0) { fido_log_debug("%s: fido_tx", __func__); return (FIDO_ERR_TX); } @@ -20,11 +20,11 @@ fido_dev_reset_tx(fido_dev_t *dev) } static int -fido_dev_reset_wait(fido_dev_t *dev, int ms) +fido_dev_reset_wait(fido_dev_t *dev, int *ms) { int r; - if ((r = fido_dev_reset_tx(dev)) != FIDO_OK || + if ((r = fido_dev_reset_tx(dev, ms)) != FIDO_OK || (r = fido_rx_cbor_status(dev, ms)) != FIDO_OK) return (r); @@ -39,5 +39,7 @@ fido_dev_reset_wait(fido_dev_t *dev, int ms) int fido_dev_reset(fido_dev_t *dev) { - return (fido_dev_reset_wait(dev, -1)); + int ms = dev->timeout_ms; + + return (fido_dev_reset_wait(dev, &ms)); } diff --git a/contrib/libfido2/src/rs1.c b/contrib/libfido2/src/rs1.c new file mode 100644 index 000000000000..37aa9f073bed --- /dev/null +++ b/contrib/libfido2/src/rs1.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2021 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + +#include <openssl/rsa.h> +#include <openssl/obj_mac.h> + +#include "fido.h" + +#if defined(LIBRESSL_VERSION_NUMBER) +static EVP_MD * +rs1_get_EVP_MD(void) +{ + const EVP_MD *from; + EVP_MD *to = NULL; + + if ((from = EVP_sha1()) != NULL && (to = malloc(sizeof(*to))) != NULL) + memcpy(to, from, sizeof(*to)); + + return (to); +} + +static void +rs1_free_EVP_MD(EVP_MD *md) +{ + freezero(md, sizeof(*md)); +} +#elif OPENSSL_VERSION_NUMBER >= 0x30000000 +static EVP_MD * +rs1_get_EVP_MD(void) +{ + return (EVP_MD_fetch(NULL, "SHA-1", NULL)); +} + +static void +rs1_free_EVP_MD(EVP_MD *md) +{ + EVP_MD_free(md); +} +#else +static EVP_MD * +rs1_get_EVP_MD(void) +{ + const EVP_MD *md; + + if ((md = EVP_sha1()) == NULL) + return (NULL); + + return (EVP_MD_meth_dup(md)); +} + +static void +rs1_free_EVP_MD(EVP_MD *md) +{ + EVP_MD_meth_free(md); +} +#endif /* LIBRESSL_VERSION_NUMBER */ + +int +rs1_verify_sig(const fido_blob_t *dgst, EVP_PKEY *pkey, + const fido_blob_t *sig) +{ + EVP_PKEY_CTX *pctx = NULL; + EVP_MD *md = NULL; + int ok = -1; + + if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) { + fido_log_debug("%s: EVP_PKEY_base_id", __func__); + goto fail; + } + + if ((md = rs1_get_EVP_MD()) == NULL) { + fido_log_debug("%s: rs1_get_EVP_MD", __func__); + goto fail; + } + + if ((pctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL || + EVP_PKEY_verify_init(pctx) != 1 || + EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PADDING) != 1 || + EVP_PKEY_CTX_set_signature_md(pctx, md) != 1) { + fido_log_debug("%s: EVP_PKEY_CTX", __func__); + goto fail; + } + + if (EVP_PKEY_verify(pctx, sig->ptr, sig->len, dgst->ptr, + dgst->len) != 1) { + fido_log_debug("%s: EVP_PKEY_verify", __func__); + goto fail; + } + + ok = 0; +fail: + EVP_PKEY_CTX_free(pctx); + rs1_free_EVP_MD(md); + + return (ok); +} diff --git a/contrib/libfido2/src/rs256.c b/contrib/libfido2/src/rs256.c index c6d87a3ea22c..29fcedbdee20 100644 --- a/contrib/libfido2/src/rs256.c +++ b/contrib/libfido2/src/rs256.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -11,31 +11,54 @@ #include "fido.h" #include "fido/rs256.h" -#if OPENSSL_VERSION_NUMBER < 0x10100000L -static int -RSA_bits(const RSA *r) +#if defined(LIBRESSL_VERSION_NUMBER) +static EVP_MD * +rs256_get_EVP_MD(void) { - return (BN_num_bits(r->n)); + const EVP_MD *from; + EVP_MD *to = NULL; + + if ((from = EVP_sha256()) != NULL && (to = malloc(sizeof(*to))) != NULL) + memcpy(to, from, sizeof(*to)); + + return (to); } -static int -RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) +static void +rs256_free_EVP_MD(EVP_MD *md) +{ + freezero(md, sizeof(*md)); +} +#elif OPENSSL_VERSION_NUMBER >= 0x30000000 +static EVP_MD * +rs256_get_EVP_MD(void) { - r->n = n; - r->e = e; - r->d = d; + return (EVP_MD_fetch(NULL, "SHA2-256", NULL)); +} + +static void +rs256_free_EVP_MD(EVP_MD *md) +{ + EVP_MD_free(md); +} +#else +static EVP_MD * +rs256_get_EVP_MD(void) +{ + const EVP_MD *md; + + if ((md = EVP_sha256()) == NULL) + return (NULL); - return (1); + return (EVP_MD_meth_dup(md)); } static void -RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) +rs256_free_EVP_MD(EVP_MD *md) { - *n = r->n; - *e = r->e; - *d = r->d; + EVP_MD_meth_free(md); } -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ +#endif /* LIBRESSL_VERSION_NUMBER */ static int decode_bignum(const cbor_item_t *item, void *ptr, size_t len) @@ -198,3 +221,75 @@ rs256_pk_from_RSA(rs256_pk_t *pk, const RSA *rsa) return (FIDO_OK); } + +int +rs256_pk_from_EVP_PKEY(rs256_pk_t *pk, const EVP_PKEY *pkey) +{ + RSA *rsa; + + if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA || + (rsa = EVP_PKEY_get0(pkey)) == NULL) + return (FIDO_ERR_INVALID_ARGUMENT); + + return (rs256_pk_from_RSA(pk, rsa)); +} + +int +rs256_verify_sig(const fido_blob_t *dgst, EVP_PKEY *pkey, + const fido_blob_t *sig) +{ + EVP_PKEY_CTX *pctx = NULL; + EVP_MD *md = NULL; + int ok = -1; + + if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) { + fido_log_debug("%s: EVP_PKEY_base_id", __func__); + goto fail; + } + + if ((md = rs256_get_EVP_MD()) == NULL) { + fido_log_debug("%s: rs256_get_EVP_MD", __func__); + goto fail; + } + + if ((pctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL || + EVP_PKEY_verify_init(pctx) != 1 || + EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PADDING) != 1 || + EVP_PKEY_CTX_set_signature_md(pctx, md) != 1) { + fido_log_debug("%s: EVP_PKEY_CTX", __func__); + goto fail; + } + + if (EVP_PKEY_verify(pctx, sig->ptr, sig->len, dgst->ptr, + dgst->len) != 1) { + fido_log_debug("%s: EVP_PKEY_verify", __func__); + goto fail; + } + + ok = 0; +fail: + EVP_PKEY_CTX_free(pctx); + rs256_free_EVP_MD(md); + + return (ok); +} + +int +rs256_pk_verify_sig(const fido_blob_t *dgst, const rs256_pk_t *pk, + const fido_blob_t *sig) +{ + EVP_PKEY *pkey; + int ok = -1; + + if ((pkey = rs256_pk_to_EVP_PKEY(pk)) == NULL || + rs256_verify_sig(dgst, pkey, sig) < 0) { + fido_log_debug("%s: rs256_verify_sig", __func__); + goto fail; + } + + ok = 0; +fail: + EVP_PKEY_free(pkey); + + return (ok); +} diff --git a/contrib/libfido2/src/time.c b/contrib/libfido2/src/time.c new file mode 100644 index 000000000000..b82b61874498 --- /dev/null +++ b/contrib/libfido2/src/time.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + +#include <errno.h> +#include "fido.h" + +static int +timespec_to_ms(const struct timespec *ts) +{ + int64_t x, y; + + if (ts->tv_sec < 0 || ts->tv_nsec < 0 || + ts->tv_nsec >= 1000000000LL) + return -1; + + if ((uint64_t)ts->tv_sec >= INT64_MAX / 1000LL) + return -1; + + x = ts->tv_sec * 1000LL; + y = ts->tv_nsec / 1000000LL; + + if (INT64_MAX - x < y || x + y > INT_MAX) + return -1; + + return (int)(x + y); +} + +int +fido_time_now(struct timespec *ts_now) +{ + if (clock_gettime(CLOCK_MONOTONIC, ts_now) != 0) { + fido_log_error(errno, "%s: clock_gettime", __func__); + return -1; + } + + return 0; +} + +int +fido_time_delta(const struct timespec *ts_start, int *ms_remain) +{ + struct timespec ts_end, ts_delta; + int ms; + + if (*ms_remain < 0) + return 0; + + if (clock_gettime(CLOCK_MONOTONIC, &ts_end) != 0) { + fido_log_error(errno, "%s: clock_gettime", __func__); + return -1; + } + + if (timespeccmp(&ts_end, ts_start, <)) { + fido_log_debug("%s: timespeccmp", __func__); + return -1; + } + + timespecsub(&ts_end, ts_start, &ts_delta); + + if ((ms = timespec_to_ms(&ts_delta)) < 0) { + fido_log_debug("%s: timespec_to_ms", __func__); + return -1; + } + + if (ms > *ms_remain) + ms = *ms_remain; + + *ms_remain -= ms; + + return 0; +} diff --git a/contrib/libfido2/src/tpm.c b/contrib/libfido2/src/tpm.c new file mode 100644 index 000000000000..74620a5e4865 --- /dev/null +++ b/contrib/libfido2/src/tpm.c @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2021 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + +/* + * Trusted Platform Module (TPM) 2.0 attestation support. Documentation + * references are relative to revision 01.38 of the TPM 2.0 specification. + */ + +#include <openssl/sha.h> + +#include "packed.h" +#include "fido.h" + +/* Part 1, 4.89: TPM_GENERATED_VALUE */ +#define TPM_MAGIC 0xff544347 + +/* Part 2, 6.3: TPM_ALG_ID */ +#define TPM_ALG_RSA 0x0001 +#define TPM_ALG_SHA256 0x000b +#define TPM_ALG_NULL 0x0010 + +/* Part 2, 6.9: TPM_ST_ATTEST_CERTIFY */ +#define TPM_ST_CERTIFY 0x8017 + +/* Part 2, 8.3: TPMA_OBJECT */ +#define TPMA_RESERVED 0xfff8f309 /* reserved bits; must be zero */ +#define TPMA_FIXED 0x00000002 /* object has fixed hierarchy */ +#define TPMA_CLEAR 0x00000004 /* object persists */ +#define TPMA_FIXED_P 0x00000010 /* object has fixed parent */ +#define TPMA_SENSITIVE 0x00000020 /* data originates within tpm */ +#define TPMA_SIGN 0x00020000 /* object may sign */ + +/* Part 2, 10.4.2: TPM2B_DIGEST */ +PACKED_TYPE(tpm_sha256_digest_t, +struct tpm_sha256_digest { + uint16_t size; /* sizeof(body) */ + uint8_t body[32]; +}) + +/* Part 2, 10.4.3: TPM2B_DATA */ +PACKED_TYPE(tpm_sha1_data_t, +struct tpm_sha1_data { + uint16_t size; /* sizeof(body */ + uint8_t body[20]; +}) + +/* Part 2, 10.5.3: TPM2B_NAME */ +PACKED_TYPE(tpm_sha256_name_t, +struct tpm_sha256_name { + uint16_t size; /* sizeof(alg) + sizeof(body) */ + uint16_t alg; /* TPM_ALG_SHA256 */ + uint8_t body[32]; +}) + +/* Part 2, 10.11.1: TPMS_CLOCK_INFO */ +PACKED_TYPE(tpm_clock_info_t, +struct tpm_clock_info { + uint64_t timestamp_ms; + uint32_t reset_count; /* obfuscated by tpm */ + uint32_t restart_count; /* obfuscated by tpm */ + uint8_t safe; /* 1 if timestamp_ms is current */ +}) + +/* Part 2, 10.12.8 TPMS_ATTEST */ +PACKED_TYPE(tpm_sha1_attest_t, +struct tpm_sha1_attest { + uint32_t magic; /* TPM_MAGIC */ + uint16_t type; /* TPM_ST_ATTEST_CERTIFY */ + tpm_sha256_name_t signer; /* full tpm path of signing key */ + tpm_sha1_data_t data; /* signed sha1 */ + tpm_clock_info_t clock; + uint64_t fwversion; /* obfuscated by tpm */ + tpm_sha256_name_t name; /* sha256 of tpm_rsa2048_pubarea_t */ + tpm_sha256_name_t qual_name; /* full tpm path of attested key */ +}) + +/* Part 2, 11.2.4.5: TPM2B_PUBLIC_KEY_RSA */ +PACKED_TYPE(tpm_rsa2048_key_t, +struct tpm_rsa2048_key { + uint16_t size; /* sizeof(body) */ + uint8_t body[256]; +}) + +/* Part 2, 12.2.3.5: TPMS_RSA_PARMS */ +PACKED_TYPE(tpm_rsa2048_param_t, +struct tpm_rsa2048_param { + uint16_t symmetric; /* TPM_ALG_NULL */ + uint16_t scheme; /* TPM_ALG_NULL */ + uint16_t keybits; /* 2048 */ + uint32_t exponent; /* zero (meaning 2^16 + 1) */ +}) + +/* Part 2, 12.2.4: TPMT_PUBLIC */ +PACKED_TYPE(tpm_rsa2048_pubarea_t, +struct tpm_rsa2048_pubarea { + uint16_t alg; /* TPM_ALG_RSA */ + uint16_t hash; /* TPM_ALG_SHA256 */ + uint32_t attr; + tpm_sha256_digest_t policy; /* must be present? */ + tpm_rsa2048_param_t param; + tpm_rsa2048_key_t key; +}) + +static int +get_signed_sha1(tpm_sha1_data_t *dgst, const fido_blob_t *authdata, + const fido_blob_t *clientdata) +{ + const EVP_MD *md = NULL; + EVP_MD_CTX *ctx = NULL; + int ok = -1; + + if ((dgst->size = sizeof(dgst->body)) != SHA_DIGEST_LENGTH || + (md = EVP_sha1()) == NULL || + (ctx = EVP_MD_CTX_new()) == NULL || + EVP_DigestInit_ex(ctx, md, NULL) != 1 || + EVP_DigestUpdate(ctx, authdata->ptr, authdata->len) != 1 || + EVP_DigestUpdate(ctx, clientdata->ptr, clientdata->len) != 1 || + EVP_DigestFinal_ex(ctx, dgst->body, NULL) != 1) { + fido_log_debug("%s: sha1", __func__); + goto fail; + } + + ok = 0; +fail: + EVP_MD_CTX_free(ctx); + + return (ok); +} + +static int +get_signed_name(tpm_sha256_name_t *name, const fido_blob_t *pubarea) +{ + name->alg = TPM_ALG_SHA256; + name->size = sizeof(name->alg) + sizeof(name->body); + if (sizeof(name->body) != SHA256_DIGEST_LENGTH || + SHA256(pubarea->ptr, pubarea->len, name->body) != name->body) { + fido_log_debug("%s: sha256", __func__); + return -1; + } + + return 0; +} + +static void +bswap_rsa2048_pubarea(tpm_rsa2048_pubarea_t *x) +{ + x->alg = htobe16(x->alg); + x->hash = htobe16(x->hash); + x->attr = htobe32(x->attr); + x->policy.size = htobe16(x->policy.size); + x->param.symmetric = htobe16(x->param.symmetric); + x->param.scheme = htobe16(x->param.scheme); + x->param.keybits = htobe16(x->param.keybits); + x->key.size = htobe16(x->key.size); +} + +static void +bswap_sha1_certinfo(tpm_sha1_attest_t *x) +{ + x->magic = htobe32(x->magic); + x->type = htobe16(x->type); + x->signer.size = htobe16(x->signer.size); + x->data.size = htobe16(x->data.size); + x->name.alg = htobe16(x->name.alg); + x->name.size = htobe16(x->name.size); +} + +static int +check_rsa2048_pubarea(const fido_blob_t *buf, const rs256_pk_t *pk) +{ + const tpm_rsa2048_pubarea_t *actual; + tpm_rsa2048_pubarea_t expected; + int ok; + + if (buf->len != sizeof(*actual)) { + fido_log_debug("%s: buf->len=%zu", __func__, buf->len); + return -1; + } + actual = (const void *)buf->ptr; + + memset(&expected, 0, sizeof(expected)); + expected.alg = TPM_ALG_RSA; + expected.hash = TPM_ALG_SHA256; + expected.attr = be32toh(actual->attr); + expected.attr &= ~(TPMA_RESERVED|TPMA_CLEAR); + expected.attr |= (TPMA_FIXED|TPMA_FIXED_P|TPMA_SENSITIVE|TPMA_SIGN); + expected.policy = actual->policy; + expected.policy.size = sizeof(expected.policy.body); + expected.param.symmetric = TPM_ALG_NULL; + expected.param.scheme = TPM_ALG_NULL; + expected.param.keybits = 2048; + expected.param.exponent = 0; /* meaning 2^16+1 */ + expected.key.size = sizeof(expected.key.body); + memcpy(&expected.key.body, &pk->n, sizeof(expected.key.body)); + bswap_rsa2048_pubarea(&expected); + + ok = timingsafe_bcmp(&expected, actual, sizeof(expected)); + explicit_bzero(&expected, sizeof(expected)); + + return ok != 0 ? -1 : 0; +} + +static int +check_sha1_certinfo(const fido_blob_t *buf, const fido_blob_t *clientdata_hash, + const fido_blob_t *authdata_raw, const fido_blob_t *pubarea) +{ + const tpm_sha1_attest_t *actual; + tpm_sha1_attest_t expected; + tpm_sha1_data_t signed_data; + tpm_sha256_name_t signed_name; + int ok = -1; + + memset(&signed_data, 0, sizeof(signed_data)); + memset(&signed_name, 0, sizeof(signed_name)); + + if (get_signed_sha1(&signed_data, authdata_raw, clientdata_hash) < 0 || + get_signed_name(&signed_name, pubarea) < 0) { + fido_log_debug("%s: get_signed_sha1/name", __func__); + goto fail; + } + if (buf->len != sizeof(*actual)) { + fido_log_debug("%s: buf->len=%zu", __func__, buf->len); + goto fail; + } + actual = (const void *)buf->ptr; + + memset(&expected, 0, sizeof(expected)); + expected.magic = TPM_MAGIC; + expected.type = TPM_ST_CERTIFY; + expected.signer = actual->signer; + expected.signer.size = sizeof(expected.signer.alg) + + sizeof(expected.signer.body); + expected.data = signed_data; + expected.clock = actual->clock; + expected.clock.safe = 1; + expected.fwversion = actual->fwversion; + expected.name = signed_name; + expected.qual_name = actual->qual_name; + bswap_sha1_certinfo(&expected); + + ok = timingsafe_bcmp(&expected, actual, sizeof(expected)); +fail: + explicit_bzero(&expected, sizeof(expected)); + explicit_bzero(&signed_data, sizeof(signed_data)); + explicit_bzero(&signed_name, sizeof(signed_name)); + + return ok != 0 ? -1 : 0; +} + +int +fido_get_signed_hash_tpm(fido_blob_t *dgst, const fido_blob_t *clientdata_hash, + const fido_blob_t *authdata_raw, const fido_attstmt_t *attstmt, + const fido_attcred_t *attcred) +{ + const fido_blob_t *pubarea = &attstmt->pubarea; + const fido_blob_t *certinfo = &attstmt->certinfo; + + if (attstmt->alg != COSE_RS1 || attcred->type != COSE_RS256) { + fido_log_debug("%s: unsupported alg %d, type %d", __func__, + attstmt->alg, attcred->type); + return -1; + } + + if (check_rsa2048_pubarea(pubarea, &attcred->pubkey.rs256) < 0) { + fido_log_debug("%s: check_rsa2048_pubarea", __func__); + return -1; + } + + if (check_sha1_certinfo(certinfo, clientdata_hash, authdata_raw, + pubarea) < 0) { + fido_log_debug("%s: check_sha1_certinfo", __func__); + return -1; + } + + if (dgst->len < SHA_DIGEST_LENGTH || + SHA1(certinfo->ptr, certinfo->len, dgst->ptr) != dgst->ptr) { + fido_log_debug("%s: sha1", __func__); + return -1; + } + dgst->len = SHA_DIGEST_LENGTH; + + return 0; +} diff --git a/contrib/libfido2/src/types.c b/contrib/libfido2/src/types.c new file mode 100644 index 000000000000..54c0ca582865 --- /dev/null +++ b/contrib/libfido2/src/types.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + +#include "fido.h" + +void +fido_str_array_free(fido_str_array_t *sa) +{ + for (size_t i = 0; i < sa->len; i++) + free(sa->ptr[i]); + + free(sa->ptr); + sa->ptr = NULL; + sa->len = 0; +} + +void +fido_opt_array_free(fido_opt_array_t *oa) +{ + for (size_t i = 0; i < oa->len; i++) + free(oa->name[i]); + + free(oa->name); + free(oa->value); + oa->name = NULL; + oa->value = NULL; +} + +void +fido_byte_array_free(fido_byte_array_t *ba) +{ + free(ba->ptr); + + ba->ptr = NULL; + ba->len = 0; +} + +void +fido_algo_free(fido_algo_t *a) +{ + free(a->type); + a->type = NULL; + a->cose = 0; +} + +void +fido_algo_array_free(fido_algo_array_t *aa) +{ + for (size_t i = 0; i < aa->len; i++) + fido_algo_free(&aa->ptr[i]); + + free(aa->ptr); + aa->ptr = NULL; + aa->len = 0; +} + +int +fido_str_array_pack(fido_str_array_t *sa, const char * const *v, size_t n) +{ + if ((sa->ptr = calloc(n, sizeof(char *))) == NULL) { + fido_log_debug("%s: calloc", __func__); + return -1; + } + for (size_t i = 0; i < n; i++) { + if ((sa->ptr[i] = strdup(v[i])) == NULL) { + fido_log_debug("%s: strdup", __func__); + return -1; + } + sa->len++; + } + + return 0; +} diff --git a/contrib/libfido2/src/u2f.c b/contrib/libfido2/src/u2f.c index c5fbe0cfbb6c..6ebfcc7bb848 100644 --- a/contrib/libfido2/src/u2f.c +++ b/contrib/libfido2/src/u2f.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ @@ -10,10 +10,13 @@ #ifdef HAVE_UNISTD_H #include <unistd.h> #endif +#include <errno.h> #include "fido.h" #include "fido/es256.h" +#define U2F_PACE_MS (100) + #if defined(_MSC_VER) static int usleep(unsigned int usec) @@ -25,6 +28,28 @@ usleep(unsigned int usec) #endif static int +delay_ms(unsigned int ms, int *ms_remain) +{ + if (*ms_remain > -1 && (unsigned int)*ms_remain < ms) + ms = (unsigned int)*ms_remain; + + if (ms > UINT_MAX / 1000) { + fido_log_debug("%s: ms=%u", __func__, ms); + return (-1); + } + + if (usleep(ms * 1000) < 0) { + fido_log_error(errno, "%s: usleep", __func__); + return (-1); + } + + if (*ms_remain > -1) + *ms_remain -= (int)ms; + + return (0); +} + +static int sig_get(fido_blob_t *sig, const unsigned char **buf, size_t *len) { sig->len = *len; /* consume the whole buffer */ @@ -115,7 +140,7 @@ authdata_fake(const char *rp_id, uint8_t flags, uint32_t sigcount, /* TODO: use u2f_get_touch_begin & u2f_get_touch_status instead */ static int -send_dummy_register(fido_dev_t *dev, int ms) +send_dummy_register(fido_dev_t *dev, int *ms) { iso7816_apdu_t *apdu = NULL; unsigned char challenge[SHA256_DIGEST_LENGTH]; @@ -123,10 +148,6 @@ send_dummy_register(fido_dev_t *dev, int ms) unsigned char reply[FIDO_MAXMSG]; int r; -#ifdef FIDO_FUZZ - ms = 0; /* XXX */ -#endif - /* dummy challenge & application */ memset(&challenge, 0xff, sizeof(challenge)); memset(&application, 0xff, sizeof(application)); @@ -142,7 +163,7 @@ send_dummy_register(fido_dev_t *dev, int ms) do { if (fido_tx(dev, CTAP_CMD_MSG, iso7816_ptr(apdu), - iso7816_len(apdu)) < 0) { + iso7816_len(apdu), ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -152,8 +173,8 @@ send_dummy_register(fido_dev_t *dev, int ms) r = FIDO_ERR_RX; goto fail; } - if (usleep((unsigned)(ms == -1 ? 100 : ms) * 1000) < 0) { - fido_log_debug("%s: usleep", __func__); + if (delay_ms(U2F_PACE_MS, ms) != 0) { + fido_log_debug("%s: delay_ms", __func__); r = FIDO_ERR_RX; goto fail; } @@ -168,7 +189,7 @@ fail: static int key_lookup(fido_dev_t *dev, const char *rp_id, const fido_blob_t *key_id, - int *found, int ms) + int *found, int *ms) { iso7816_apdu_t *apdu = NULL; unsigned char challenge[SHA256_DIGEST_LENGTH]; @@ -208,7 +229,7 @@ key_lookup(fido_dev_t *dev, const char *rp_id, const fido_blob_t *key_id, } if (fido_tx(dev, CTAP_CMD_MSG, iso7816_ptr(apdu), - iso7816_len(apdu)) < 0) { + iso7816_len(apdu), ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -274,7 +295,7 @@ parse_auth_reply(fido_blob_t *sig, fido_blob_t *ad, const char *rp_id, static int do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id, - const fido_blob_t *key_id, fido_blob_t *sig, fido_blob_t *ad, int ms) + const fido_blob_t *key_id, fido_blob_t *sig, fido_blob_t *ad, int *ms) { iso7816_apdu_t *apdu = NULL; unsigned char rp_id_hash[SHA256_DIGEST_LENGTH]; @@ -284,7 +305,7 @@ do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id, int r; #ifdef FIDO_FUZZ - ms = 0; /* XXX */ + *ms = 0; /* XXX */ #endif if (cdh->len != SHA256_DIGEST_LENGTH || key_id->len > UINT8_MAX || @@ -317,7 +338,7 @@ do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id, do { if (fido_tx(dev, CTAP_CMD_MSG, iso7816_ptr(apdu), - iso7816_len(apdu)) < 0) { + iso7816_len(apdu), ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -328,8 +349,8 @@ do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id, r = FIDO_ERR_RX; goto fail; } - if (usleep((unsigned)(ms == -1 ? 100 : ms) * 1000) < 0) { - fido_log_debug("%s: usleep", __func__); + if (delay_ms(U2F_PACE_MS, ms) != 0) { + fido_log_debug("%s: delay_ms", __func__); r = FIDO_ERR_RX; goto fail; } @@ -391,6 +412,71 @@ fail: } static int +encode_cred_attstmt(int cose_alg, const fido_blob_t *x5c, + const fido_blob_t *sig, fido_blob_t *out) +{ + cbor_item_t *item = NULL; + cbor_item_t *x5c_cbor = NULL; + const uint8_t alg_cbor = (uint8_t)(-cose_alg - 1); + struct cbor_pair kv[3]; + size_t alloc_len; + int ok = -1; + + memset(&kv, 0, sizeof(kv)); + memset(out, 0, sizeof(*out)); + + if ((item = cbor_new_definite_map(3)) == NULL) { + fido_log_debug("%s: cbor_new_definite_map", __func__); + goto fail; + } + + if ((kv[0].key = cbor_build_string("alg")) == NULL || + (kv[0].value = cbor_build_negint8(alg_cbor)) == NULL || + !cbor_map_add(item, kv[0])) { + fido_log_debug("%s: alg", __func__); + goto fail; + } + + if ((kv[1].key = cbor_build_string("sig")) == NULL || + (kv[1].value = fido_blob_encode(sig)) == NULL || + !cbor_map_add(item, kv[1])) { + fido_log_debug("%s: sig", __func__); + goto fail; + } + + if ((kv[2].key = cbor_build_string("x5c")) == NULL || + (kv[2].value = cbor_new_definite_array(1)) == NULL || + (x5c_cbor = fido_blob_encode(x5c)) == NULL || + !cbor_array_push(kv[2].value, x5c_cbor) || + !cbor_map_add(item, kv[2])) { + fido_log_debug("%s: x5c", __func__); + goto fail; + } + + if ((out->len = cbor_serialize_alloc(item, &out->ptr, + &alloc_len)) == 0) { + fido_log_debug("%s: cbor_serialize_alloc", __func__); + goto fail; + } + + ok = 0; +fail: + if (item != NULL) + cbor_decref(&item); + if (x5c_cbor != NULL) + cbor_decref(&x5c_cbor); + + for (size_t i = 0; i < nitems(kv); i++) { + if (kv[i].key) + cbor_decref(&kv[i].key); + if (kv[i].value) + cbor_decref(&kv[i].value); + } + + return (ok); +} + +static int encode_cred_authdata(const char *rp_id, const uint8_t *kh, uint8_t kh_len, const uint8_t *pubkey, size_t pubkey_len, fido_blob_t *out) { @@ -476,6 +562,7 @@ parse_register_reply(fido_cred_t *cred, const unsigned char *reply, size_t len) fido_blob_t x5c; fido_blob_t sig; fido_blob_t ad; + fido_blob_t stmt; uint8_t dummy; uint8_t pubkey[65]; uint8_t kh_len = 0; @@ -485,6 +572,7 @@ parse_register_reply(fido_cred_t *cred, const unsigned char *reply, size_t len) memset(&x5c, 0, sizeof(x5c)); memset(&sig, 0, sizeof(sig)); memset(&ad, 0, sizeof(ad)); + memset(&stmt, 0, sizeof(stmt)); r = FIDO_ERR_RX; /* status word */ @@ -518,6 +606,12 @@ parse_register_reply(fido_cred_t *cred, const unsigned char *reply, size_t len) goto fail; } + /* attstmt */ + if (encode_cred_attstmt(COSE_ES256, &x5c, &sig, &stmt) < 0) { + fido_log_debug("%s: encode_cred_attstmt", __func__); + goto fail; + } + /* authdata */ if (encode_cred_authdata(cred->rp.id, kh, kh_len, pubkey, sizeof(pubkey), &ad) < 0) { @@ -527,8 +621,7 @@ parse_register_reply(fido_cred_t *cred, const unsigned char *reply, size_t len) if (fido_cred_set_fmt(cred, "fido-u2f") != FIDO_OK || fido_cred_set_authdata(cred, ad.ptr, ad.len) != FIDO_OK || - fido_cred_set_x509(cred, x5c.ptr, x5c.len) != FIDO_OK || - fido_cred_set_sig(cred, sig.ptr, sig.len) != FIDO_OK) { + fido_cred_set_attstmt(cred, stmt.ptr, stmt.len) != FIDO_OK) { fido_log_debug("%s: fido_cred_set", __func__); r = FIDO_ERR_INTERNAL; goto fail; @@ -540,12 +633,13 @@ fail: fido_blob_reset(&x5c); fido_blob_reset(&sig); fido_blob_reset(&ad); + fido_blob_reset(&stmt); return (r); } int -u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms) +u2f_register(fido_dev_t *dev, fido_cred_t *cred, int *ms) { iso7816_apdu_t *apdu = NULL; unsigned char rp_id_hash[SHA256_DIGEST_LENGTH]; @@ -554,10 +648,6 @@ u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms) int found; int r; -#ifdef FIDO_FUZZ - ms = 0; /* XXX */ -#endif - if (cred->rk == FIDO_OPT_TRUE || cred->uv == FIDO_OPT_TRUE) { fido_log_debug("%s: rk=%d, uv=%d", __func__, cred->rk, cred->uv); @@ -606,7 +696,7 @@ u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms) do { if (fido_tx(dev, CTAP_CMD_MSG, iso7816_ptr(apdu), - iso7816_len(apdu)) < 0) { + iso7816_len(apdu), ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -617,8 +707,8 @@ u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms) r = FIDO_ERR_RX; goto fail; } - if (usleep((unsigned)(ms == -1 ? 100 : ms) * 1000) < 0) { - fido_log_debug("%s: usleep", __func__); + if (delay_ms(U2F_PACE_MS, ms) != 0) { + fido_log_debug("%s: delay_ms", __func__); r = FIDO_ERR_RX; goto fail; } @@ -637,7 +727,7 @@ fail: static int u2f_authenticate_single(fido_dev_t *dev, const fido_blob_t *key_id, - fido_assert_t *fa, size_t idx, int ms) + fido_assert_t *fa, size_t idx, int *ms) { fido_blob_t sig; fido_blob_t ad; @@ -692,7 +782,7 @@ fail: } int -u2f_authenticate(fido_dev_t *dev, fido_assert_t *fa, int ms) +u2f_authenticate(fido_dev_t *dev, fido_assert_t *fa, int *ms) { size_t nfound = 0; size_t nauth_ok = 0; @@ -739,7 +829,7 @@ u2f_authenticate(fido_dev_t *dev, fido_assert_t *fa, int ms) } int -u2f_get_touch_begin(fido_dev_t *dev) +u2f_get_touch_begin(fido_dev_t *dev, int *ms) { iso7816_apdu_t *apdu = NULL; const char *clientdata = FIDO_DUMMY_CLIENTDATA; @@ -769,12 +859,12 @@ u2f_get_touch_begin(fido_dev_t *dev) } if (dev->attr.flags & FIDO_CAP_WINK) { - fido_tx(dev, CTAP_CMD_WINK, NULL, 0); - fido_rx(dev, CTAP_CMD_WINK, &reply, sizeof(reply), 200); + fido_tx(dev, CTAP_CMD_WINK, NULL, 0, ms); + fido_rx(dev, CTAP_CMD_WINK, &reply, sizeof(reply), ms); } if (fido_tx(dev, CTAP_CMD_MSG, iso7816_ptr(apdu), - iso7816_len(apdu)) < 0) { + iso7816_len(apdu), ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -788,7 +878,7 @@ fail: } int -u2f_get_touch_status(fido_dev_t *dev, int *touched, int ms) +u2f_get_touch_status(fido_dev_t *dev, int *touched, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; @@ -802,7 +892,7 @@ u2f_get_touch_status(fido_dev_t *dev, int *touched, int ms) switch ((reply[reply_len - 2] << 8) | reply[reply_len - 1]) { case SW_CONDITIONS_NOT_SATISFIED: - if ((r = u2f_get_touch_begin(dev)) != FIDO_OK) { + if ((r = u2f_get_touch_begin(dev, ms)) != FIDO_OK) { fido_log_debug("%s: u2f_get_touch_begin", __func__); return (r); } diff --git a/contrib/libfido2/src/webauthn.h b/contrib/libfido2/src/webauthn.h new file mode 100644 index 000000000000..5fbdd6faa927 --- /dev/null +++ b/contrib/libfido2/src/webauthn.h @@ -0,0 +1,839 @@ +// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#ifndef __WEBAUTHN_H_
+#define __WEBAUTHN_H_
+
+#pragma once
+
+#include <winapifamily.h>
+
+#pragma region Desktop Family or OneCore Family
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef WINAPI
+#define WINAPI __stdcall
+#endif
+
+#ifndef INITGUID
+#define INITGUID
+#include <guiddef.h>
+#undef INITGUID
+#else
+#include <guiddef.h>
+#endif
+
+//+------------------------------------------------------------------------------------------
+// API Version Information.
+// Caller should check for WebAuthNGetApiVersionNumber to check the presence of relevant APIs
+// and features for their usage.
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_API_VERSION_1 1
+// WEBAUTHN_API_VERSION_1 : Baseline Version
+// Data Structures and their sub versions:
+// - WEBAUTHN_RP_ENTITY_INFORMATION : 1
+// - WEBAUTHN_USER_ENTITY_INFORMATION : 1
+// - WEBAUTHN_CLIENT_DATA : 1
+// - WEBAUTHN_COSE_CREDENTIAL_PARAMETER : 1
+// - WEBAUTHN_COSE_CREDENTIAL_PARAMETERS : Not Applicable
+// - WEBAUTHN_CREDENTIAL : 1
+// - WEBAUTHN_CREDENTIALS : Not Applicable
+// - WEBAUTHN_CREDENTIAL_EX : 1
+// - WEBAUTHN_CREDENTIAL_LIST : Not Applicable
+// - WEBAUTHN_EXTENSION : Not Applicable
+// - WEBAUTHN_EXTENSIONS : Not Applicable
+// - WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS : 3
+// - WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS : 4
+// - WEBAUTHN_COMMON_ATTESTATION : 1
+// - WEBAUTHN_CREDENTIAL_ATTESTATION : 3
+// - WEBAUTHN_ASSERTION : 1
+// Extensions:
+// - WEBAUTHN_EXTENSIONS_IDENTIFIER_HMAC_SECRET
+// APIs:
+// - WebAuthNGetApiVersionNumber
+// - WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable
+// - WebAuthNAuthenticatorMakeCredential
+// - WebAuthNAuthenticatorGetAssertion
+// - WebAuthNFreeCredentialAttestation
+// - WebAuthNFreeAssertion
+// - WebAuthNGetCancellationId
+// - WebAuthNCancelCurrentOperation
+// - WebAuthNGetErrorName
+// - WebAuthNGetW3CExceptionDOMError
+
+#define WEBAUTHN_API_VERSION_2 2
+// WEBAUTHN_API_VERSION_2 : Delta From WEBAUTHN_API_VERSION_1
+// Added Extensions:
+// - WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT
+//
+
+#define WEBAUTHN_API_VERSION_3 3
+// WEBAUTHN_API_VERSION_3 : Delta From WEBAUTHN_API_VERSION_2
+// Data Structures and their sub versions:
+// - WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS : 4
+// - WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS : 5
+// - WEBAUTHN_CREDENTIAL_ATTESTATION : 4
+// - WEBAUTHN_ASSERTION : 2
+// Added Extensions:
+// - WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_BLOB
+// - WEBAUTHN_EXTENSIONS_IDENTIFIER_MIN_PIN_LENGTH
+//
+
+#define WEBAUTHN_API_CURRENT_VERSION WEBAUTHN_API_VERSION_3
+
+//+------------------------------------------------------------------------------------------
+// Information about an RP Entity
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_RP_ENTITY_INFORMATION_CURRENT_VERSION 1
+
+typedef struct _WEBAUTHN_RP_ENTITY_INFORMATION {
+ // Version of this structure, to allow for modifications in the future.
+ // This field is required and should be set to CURRENT_VERSION above.
+ DWORD dwVersion;
+
+ // Identifier for the RP. This field is required.
+ PCWSTR pwszId;
+
+ // Contains the friendly name of the Relying Party, such as "Acme Corporation", "Widgets Inc" or "Awesome Site".
+ // This field is required.
+ PCWSTR pwszName;
+
+ // Optional URL pointing to RP's logo.
+ PCWSTR pwszIcon;
+} WEBAUTHN_RP_ENTITY_INFORMATION, *PWEBAUTHN_RP_ENTITY_INFORMATION;
+typedef const WEBAUTHN_RP_ENTITY_INFORMATION *PCWEBAUTHN_RP_ENTITY_INFORMATION;
+
+//+------------------------------------------------------------------------------------------
+// Information about an User Entity
+//-------------------------------------------------------------------------------------------
+#define WEBAUTHN_MAX_USER_ID_LENGTH 64
+
+#define WEBAUTHN_USER_ENTITY_INFORMATION_CURRENT_VERSION 1
+
+typedef struct _WEBAUTHN_USER_ENTITY_INFORMATION {
+ // Version of this structure, to allow for modifications in the future.
+ // This field is required and should be set to CURRENT_VERSION above.
+ DWORD dwVersion;
+
+ // Identifier for the User. This field is required.
+ DWORD cbId;
+ _Field_size_bytes_(cbId)
+ PBYTE pbId;
+
+ // Contains a detailed name for this account, such as "john.p.smith@example.com".
+ PCWSTR pwszName;
+
+ // Optional URL that can be used to retrieve an image containing the user's current avatar,
+ // or a data URI that contains the image data.
+ PCWSTR pwszIcon;
+
+ // For User: Contains the friendly name associated with the user account by the Relying Party, such as "John P. Smith".
+ PCWSTR pwszDisplayName;
+} WEBAUTHN_USER_ENTITY_INFORMATION, *PWEBAUTHN_USER_ENTITY_INFORMATION;
+typedef const WEBAUTHN_USER_ENTITY_INFORMATION *PCWEBAUTHN_USER_ENTITY_INFORMATION;
+
+//+------------------------------------------------------------------------------------------
+// Information about client data.
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_HASH_ALGORITHM_SHA_256 L"SHA-256"
+#define WEBAUTHN_HASH_ALGORITHM_SHA_384 L"SHA-384"
+#define WEBAUTHN_HASH_ALGORITHM_SHA_512 L"SHA-512"
+
+#define WEBAUTHN_CLIENT_DATA_CURRENT_VERSION 1
+
+typedef struct _WEBAUTHN_CLIENT_DATA {
+ // Version of this structure, to allow for modifications in the future.
+ // This field is required and should be set to CURRENT_VERSION above.
+ DWORD dwVersion;
+
+ // Size of the pbClientDataJSON field.
+ DWORD cbClientDataJSON;
+ // UTF-8 encoded JSON serialization of the client data.
+ _Field_size_bytes_(cbClientDataJSON)
+ PBYTE pbClientDataJSON;
+
+ // Hash algorithm ID used to hash the pbClientDataJSON field.
+ LPCWSTR pwszHashAlgId;
+} WEBAUTHN_CLIENT_DATA, *PWEBAUTHN_CLIENT_DATA;
+typedef const WEBAUTHN_CLIENT_DATA *PCWEBAUTHN_CLIENT_DATA;
+
+//+------------------------------------------------------------------------------------------
+// Information about credential parameters.
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_CREDENTIAL_TYPE_PUBLIC_KEY L"public-key"
+
+#define WEBAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256 -7
+#define WEBAUTHN_COSE_ALGORITHM_ECDSA_P384_WITH_SHA384 -35
+#define WEBAUTHN_COSE_ALGORITHM_ECDSA_P521_WITH_SHA512 -36
+
+#define WEBAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA256 -257
+#define WEBAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA384 -258
+#define WEBAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA512 -259
+
+#define WEBAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA256 -37
+#define WEBAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA384 -38
+#define WEBAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA512 -39
+
+#define WEBAUTHN_COSE_CREDENTIAL_PARAMETER_CURRENT_VERSION 1
+
+typedef struct _WEBAUTHN_COSE_CREDENTIAL_PARAMETER {
+ // Version of this structure, to allow for modifications in the future.
+ DWORD dwVersion;
+
+ // Well-known credential type specifying a credential to create.
+ LPCWSTR pwszCredentialType;
+
+ // Well-known COSE algorithm specifying the algorithm to use for the credential.
+ LONG lAlg;
+} WEBAUTHN_COSE_CREDENTIAL_PARAMETER, *PWEBAUTHN_COSE_CREDENTIAL_PARAMETER;
+typedef const WEBAUTHN_COSE_CREDENTIAL_PARAMETER *PCWEBAUTHN_COSE_CREDENTIAL_PARAMETER;
+
+typedef struct _WEBAUTHN_COSE_CREDENTIAL_PARAMETERS {
+ DWORD cCredentialParameters;
+ _Field_size_(cCredentialParameters)
+ PWEBAUTHN_COSE_CREDENTIAL_PARAMETER pCredentialParameters;
+} WEBAUTHN_COSE_CREDENTIAL_PARAMETERS, *PWEBAUTHN_COSE_CREDENTIAL_PARAMETERS;
+typedef const WEBAUTHN_COSE_CREDENTIAL_PARAMETERS *PCWEBAUTHN_COSE_CREDENTIAL_PARAMETERS;
+
+//+------------------------------------------------------------------------------------------
+// Information about credential.
+//-------------------------------------------------------------------------------------------
+#define WEBAUTHN_CREDENTIAL_CURRENT_VERSION 1
+
+typedef struct _WEBAUTHN_CREDENTIAL {
+ // Version of this structure, to allow for modifications in the future.
+ DWORD dwVersion;
+
+ // Size of pbID.
+ DWORD cbId;
+ // Unique ID for this particular credential.
+ _Field_size_bytes_(cbId)
+ PBYTE pbId;
+
+ // Well-known credential type specifying what this particular credential is.
+ LPCWSTR pwszCredentialType;
+} WEBAUTHN_CREDENTIAL, *PWEBAUTHN_CREDENTIAL;
+typedef const WEBAUTHN_CREDENTIAL *PCWEBAUTHN_CREDENTIAL;
+
+typedef struct _WEBAUTHN_CREDENTIALS {
+ DWORD cCredentials;
+ _Field_size_(cCredentials)
+ PWEBAUTHN_CREDENTIAL pCredentials;
+} WEBAUTHN_CREDENTIALS, *PWEBAUTHN_CREDENTIALS;
+typedef const WEBAUTHN_CREDENTIALS *PCWEBAUTHN_CREDENTIALS;
+
+//+------------------------------------------------------------------------------------------
+// Information about credential with extra information, such as, dwTransports
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_CTAP_TRANSPORT_USB 0x00000001
+#define WEBAUTHN_CTAP_TRANSPORT_NFC 0x00000002
+#define WEBAUTHN_CTAP_TRANSPORT_BLE 0x00000004
+#define WEBAUTHN_CTAP_TRANSPORT_TEST 0x00000008
+#define WEBAUTHN_CTAP_TRANSPORT_INTERNAL 0x00000010
+#define WEBAUTHN_CTAP_TRANSPORT_FLAGS_MASK 0x0000001F
+
+#define WEBAUTHN_CREDENTIAL_EX_CURRENT_VERSION 1
+
+typedef struct _WEBAUTHN_CREDENTIAL_EX {
+ // Version of this structure, to allow for modifications in the future.
+ DWORD dwVersion;
+
+ // Size of pbID.
+ DWORD cbId;
+ // Unique ID for this particular credential.
+ _Field_size_bytes_(cbId)
+ PBYTE pbId;
+
+ // Well-known credential type specifying what this particular credential is.
+ LPCWSTR pwszCredentialType;
+
+ // Transports. 0 implies no transport restrictions.
+ DWORD dwTransports;
+} WEBAUTHN_CREDENTIAL_EX, *PWEBAUTHN_CREDENTIAL_EX;
+typedef const WEBAUTHN_CREDENTIAL_EX *PCWEBAUTHN_CREDENTIAL_EX;
+
+//+------------------------------------------------------------------------------------------
+// Information about credential list with extra information
+//-------------------------------------------------------------------------------------------
+
+typedef struct _WEBAUTHN_CREDENTIAL_LIST {
+ DWORD cCredentials;
+ _Field_size_(cCredentials)
+ PWEBAUTHN_CREDENTIAL_EX *ppCredentials;
+} WEBAUTHN_CREDENTIAL_LIST, *PWEBAUTHN_CREDENTIAL_LIST;
+typedef const WEBAUTHN_CREDENTIAL_LIST *PCWEBAUTHN_CREDENTIAL_LIST;
+
+//+------------------------------------------------------------------------------------------
+// Hmac-Secret extension
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_EXTENSIONS_IDENTIFIER_HMAC_SECRET L"hmac-secret"
+// Below type definitions is for WEBAUTHN_EXTENSIONS_IDENTIFIER_HMAC_SECRET
+// MakeCredential Input Type: BOOL.
+// - pvExtension must point to a BOOL with the value TRUE.
+// - cbExtension must contain the sizeof(BOOL).
+// MakeCredential Output Type: BOOL.
+// - pvExtension will point to a BOOL with the value TRUE if credential
+// was successfully created with HMAC_SECRET.
+// - cbExtension will contain the sizeof(BOOL).
+// GetAssertion Input Type: Not Supported
+// GetAssertion Output Type: Not Supported
+
+//+------------------------------------------------------------------------------------------
+// credProtect extension
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_USER_VERIFICATION_ANY 0
+#define WEBAUTHN_USER_VERIFICATION_OPTIONAL 1
+#define WEBAUTHN_USER_VERIFICATION_OPTIONAL_WITH_CREDENTIAL_ID_LIST 2
+#define WEBAUTHN_USER_VERIFICATION_REQUIRED 3
+
+typedef struct _WEBAUTHN_CRED_PROTECT_EXTENSION_IN {
+ // One of the above WEBAUTHN_USER_VERIFICATION_* values
+ DWORD dwCredProtect;
+ // Set the following to TRUE to require authenticator support for the credProtect extension
+ BOOL bRequireCredProtect;
+} WEBAUTHN_CRED_PROTECT_EXTENSION_IN, *PWEBAUTHN_CRED_PROTECT_EXTENSION_IN;
+typedef const WEBAUTHN_CRED_PROTECT_EXTENSION_IN *PCWEBAUTHN_CRED_PROTECT_EXTENSION_IN;
+
+
+#define WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT L"credProtect"
+// Below type definitions is for WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT
+// MakeCredential Input Type: WEBAUTHN_CRED_PROTECT_EXTENSION_IN.
+// - pvExtension must point to a WEBAUTHN_CRED_PROTECT_EXTENSION_IN struct
+// - cbExtension will contain the sizeof(WEBAUTHN_CRED_PROTECT_EXTENSION_IN).
+// MakeCredential Output Type: DWORD.
+// - pvExtension will point to a DWORD with one of the above WEBAUTHN_USER_VERIFICATION_* values
+// if credential was successfully created with CRED_PROTECT.
+// - cbExtension will contain the sizeof(DWORD).
+// GetAssertion Input Type: Not Supported
+// GetAssertion Output Type: Not Supported
+
+//+------------------------------------------------------------------------------------------
+// credBlob extension
+//-------------------------------------------------------------------------------------------
+
+typedef struct _WEBAUTHN_CRED_BLOB_EXTENSION {
+ // Size of pbCredBlob.
+ DWORD cbCredBlob;
+ _Field_size_bytes_(cbCredBlob)
+ PBYTE pbCredBlob;
+} WEBAUTHN_CRED_BLOB_EXTENSION, *PWEBAUTHN_CRED_BLOB_EXTENSION;
+typedef const WEBAUTHN_CRED_BLOB_EXTENSION *PCWEBAUTHN_CRED_BLOB_EXTENSION;
+
+
+#define WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_BLOB L"credBlob"
+// Below type definitions is for WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_BLOB
+// MakeCredential Input Type: WEBAUTHN_CRED_BLOB_EXTENSION.
+// - pvExtension must point to a WEBAUTHN_CRED_BLOB_EXTENSION struct
+// - cbExtension must contain the sizeof(WEBAUTHN_CRED_BLOB_EXTENSION).
+// MakeCredential Output Type: BOOL.
+// - pvExtension will point to a BOOL with the value TRUE if credBlob was successfully created
+// - cbExtension will contain the sizeof(BOOL).
+// GetAssertion Input Type: BOOL.
+// - pvExtension must point to a BOOL with the value TRUE to request the credBlob.
+// - cbExtension must contain the sizeof(BOOL).
+// GetAssertion Output Type: WEBAUTHN_CRED_BLOB_EXTENSION.
+// - pvExtension will point to a WEBAUTHN_CRED_BLOB_EXTENSION struct if the authenticator
+// returns the credBlob in the signed extensions
+// - cbExtension will contain the sizeof(WEBAUTHN_CRED_BLOB_EXTENSION).
+
+//+------------------------------------------------------------------------------------------
+// minPinLength extension
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_EXTENSIONS_IDENTIFIER_MIN_PIN_LENGTH L"minPinLength"
+// Below type definitions is for WEBAUTHN_EXTENSIONS_IDENTIFIER_MIN_PIN_LENGTH
+// MakeCredential Input Type: BOOL.
+// - pvExtension must point to a BOOL with the value TRUE to request the minPinLength.
+// - cbExtension must contain the sizeof(BOOL).
+// MakeCredential Output Type: DWORD.
+// - pvExtension will point to a DWORD with the minimum pin length if returned by the authenticator
+// - cbExtension will contain the sizeof(DWORD).
+// GetAssertion Input Type: Not Supported
+// GetAssertion Output Type: Not Supported
+
+//+------------------------------------------------------------------------------------------
+// Information about Extensions.
+//-------------------------------------------------------------------------------------------
+typedef struct _WEBAUTHN_EXTENSION {
+ LPCWSTR pwszExtensionIdentifier;
+ DWORD cbExtension;
+ PVOID pvExtension;
+} WEBAUTHN_EXTENSION, *PWEBAUTHN_EXTENSION;
+typedef const WEBAUTHN_EXTENSION *PCWEBAUTHN_EXTENSION;
+
+typedef struct _WEBAUTHN_EXTENSIONS {
+ DWORD cExtensions;
+ _Field_size_(cExtensions)
+ PWEBAUTHN_EXTENSION pExtensions;
+} WEBAUTHN_EXTENSIONS, *PWEBAUTHN_EXTENSIONS;
+typedef const WEBAUTHN_EXTENSIONS *PCWEBAUTHN_EXTENSIONS;
+
+//+------------------------------------------------------------------------------------------
+// Options.
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_AUTHENTICATOR_ATTACHMENT_ANY 0
+#define WEBAUTHN_AUTHENTICATOR_ATTACHMENT_PLATFORM 1
+#define WEBAUTHN_AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM 2
+#define WEBAUTHN_AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM_U2F_V2 3
+
+#define WEBAUTHN_USER_VERIFICATION_REQUIREMENT_ANY 0
+#define WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED 1
+#define WEBAUTHN_USER_VERIFICATION_REQUIREMENT_PREFERRED 2
+#define WEBAUTHN_USER_VERIFICATION_REQUIREMENT_DISCOURAGED 3
+
+#define WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_ANY 0
+#define WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_NONE 1
+#define WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_INDIRECT 2
+#define WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_DIRECT 3
+
+#define WEBAUTHN_ENTERPRISE_ATTESTATION_NONE 0
+#define WEBAUTHN_ENTERPRISE_ATTESTATION_VENDOR_FACILITATED 1
+#define WEBAUTHN_ENTERPRISE_ATTESTATION_PLATFORM_MANAGED 2
+
+#define WEBAUTHN_LARGE_BLOB_SUPPORT_NONE 0
+#define WEBAUTHN_LARGE_BLOB_SUPPORT_REQUIRED 1
+#define WEBAUTHN_LARGE_BLOB_SUPPORT_PREFERRED 2
+
+#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_1 1
+#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_2 2
+#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_3 3
+#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_4 4
+#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_4
+
+typedef struct _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS {
+ // Version of this structure, to allow for modifications in the future.
+ DWORD dwVersion;
+
+ // Time that the operation is expected to complete within.
+ // This is used as guidance, and can be overridden by the platform.
+ DWORD dwTimeoutMilliseconds;
+
+ // Credentials used for exclusion.
+ WEBAUTHN_CREDENTIALS CredentialList;
+
+ // Optional extensions to parse when performing the operation.
+ WEBAUTHN_EXTENSIONS Extensions;
+
+ // Optional. Platform vs Cross-Platform Authenticators.
+ DWORD dwAuthenticatorAttachment;
+
+ // Optional. Require key to be resident or not. Defaulting to FALSE.
+ BOOL bRequireResidentKey;
+
+ // User Verification Requirement.
+ DWORD dwUserVerificationRequirement;
+
+ // Attestation Conveyance Preference.
+ DWORD dwAttestationConveyancePreference;
+
+ // Reserved for future Use
+ DWORD dwFlags;
+
+ //
+ // The following fields have been added in WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_2
+ //
+
+ // Cancellation Id - Optional - See WebAuthNGetCancellationId
+ GUID *pCancellationId;
+
+ //
+ // The following fields have been added in WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_3
+ //
+
+ // Exclude Credential List. If present, "CredentialList" will be ignored.
+ PWEBAUTHN_CREDENTIAL_LIST pExcludeCredentialList;
+
+ //
+ // The following fields have been added in WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_4
+ //
+
+ // Enterprise Attestation
+ DWORD dwEnterpriseAttestation;
+
+ // Large Blob Support: none, required or preferred
+ //
+ // NTE_INVALID_PARAMETER when large blob required or preferred and
+ // both bRequireResidentKey and bPreferResidentKey are set to FALSE.
+ DWORD dwLargeBlobSupport;
+
+ // Optional. Prefer key to be resident. Defaulting to FALSE. When TRUE,
+ // overrides the above bRequireResidentKey.
+ BOOL bPreferResidentKey;
+
+} WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS, *PWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS;
+typedef const WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS *PCWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS;
+
+#define WEBAUTHN_CRED_LARGE_BLOB_OPERATION_NONE 0
+#define WEBAUTHN_CRED_LARGE_BLOB_OPERATION_GET 1
+#define WEBAUTHN_CRED_LARGE_BLOB_OPERATION_SET 2
+#define WEBAUTHN_CRED_LARGE_BLOB_OPERATION_DELETE 3
+
+#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_1 1
+#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_2 2
+#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_3 3
+#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_4 4
+#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_5 5
+#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_5
+
+typedef struct _WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS {
+ // Version of this structure, to allow for modifications in the future.
+ DWORD dwVersion;
+
+ // Time that the operation is expected to complete within.
+ // This is used as guidance, and can be overridden by the platform.
+ DWORD dwTimeoutMilliseconds;
+
+ // Allowed Credentials List.
+ WEBAUTHN_CREDENTIALS CredentialList;
+
+ // Optional extensions to parse when performing the operation.
+ WEBAUTHN_EXTENSIONS Extensions;
+
+ // Optional. Platform vs Cross-Platform Authenticators.
+ DWORD dwAuthenticatorAttachment;
+
+ // User Verification Requirement.
+ DWORD dwUserVerificationRequirement;
+
+ // Reserved for future Use
+ DWORD dwFlags;
+
+ //
+ // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_2
+ //
+
+ // Optional identifier for the U2F AppId. Converted to UTF8 before being hashed. Not lower cased.
+ PCWSTR pwszU2fAppId;
+
+ // If the following is non-NULL, then, set to TRUE if the above pwszU2fAppid was used instead of
+ // PCWSTR pwszRpId;
+ BOOL *pbU2fAppId;
+
+ //
+ // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_3
+ //
+
+ // Cancellation Id - Optional - See WebAuthNGetCancellationId
+ GUID *pCancellationId;
+
+ //
+ // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_4
+ //
+
+ // Allow Credential List. If present, "CredentialList" will be ignored.
+ PWEBAUTHN_CREDENTIAL_LIST pAllowCredentialList;
+
+ //
+ // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_5
+ //
+
+ DWORD dwCredLargeBlobOperation;
+
+ // Size of pbCredLargeBlob
+ DWORD cbCredLargeBlob;
+ _Field_size_bytes_(cbCredLargeBlob)
+ PBYTE pbCredLargeBlob;
+} WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS, *PWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS;
+typedef const WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS *PCWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS;
+
+
+//+------------------------------------------------------------------------------------------
+// Attestation Info.
+//
+//-------------------------------------------------------------------------------------------
+#define WEBAUTHN_ATTESTATION_DECODE_NONE 0
+#define WEBAUTHN_ATTESTATION_DECODE_COMMON 1
+// WEBAUTHN_ATTESTATION_DECODE_COMMON supports format types
+// L"packed"
+// L"fido-u2f"
+
+#define WEBAUTHN_ATTESTATION_VER_TPM_2_0 L"2.0"
+
+typedef struct _WEBAUTHN_X5C {
+ // Length of X.509 encoded certificate
+ DWORD cbData;
+ // X.509 encoded certificate bytes
+ _Field_size_bytes_(cbData)
+ PBYTE pbData;
+} WEBAUTHN_X5C, *PWEBAUTHN_X5C;
+
+// Supports either Self or Full Basic Attestation
+
+// Note, new fields will be added to the following data structure to
+// support additional attestation format types, such as, TPM.
+// When fields are added, the dwVersion will be incremented.
+//
+// Therefore, your code must make the following check:
+// "if (dwVersion >= WEBAUTHN_COMMON_ATTESTATION_CURRENT_VERSION)"
+
+#define WEBAUTHN_COMMON_ATTESTATION_CURRENT_VERSION 1
+
+typedef struct _WEBAUTHN_COMMON_ATTESTATION {
+ // Version of this structure, to allow for modifications in the future.
+ DWORD dwVersion;
+
+ // Hash and Padding Algorithm
+ //
+ // The following won't be set for "fido-u2f" which assumes "ES256".
+ PCWSTR pwszAlg;
+ LONG lAlg; // COSE algorithm
+
+ // Signature that was generated for this attestation.
+ DWORD cbSignature;
+ _Field_size_bytes_(cbSignature)
+ PBYTE pbSignature;
+
+ // Following is set for Full Basic Attestation. If not, set then, this is Self Attestation.
+ // Array of X.509 DER encoded certificates. The first certificate is the signer, leaf certificate.
+ DWORD cX5c;
+ _Field_size_(cX5c)
+ PWEBAUTHN_X5C pX5c;
+
+ // Following are also set for tpm
+ PCWSTR pwszVer; // L"2.0"
+ DWORD cbCertInfo;
+ _Field_size_bytes_(cbCertInfo)
+ PBYTE pbCertInfo;
+ DWORD cbPubArea;
+ _Field_size_bytes_(cbPubArea)
+ PBYTE pbPubArea;
+} WEBAUTHN_COMMON_ATTESTATION, *PWEBAUTHN_COMMON_ATTESTATION;
+typedef const WEBAUTHN_COMMON_ATTESTATION *PCWEBAUTHN_COMMON_ATTESTATION;
+
+#define WEBAUTHN_ATTESTATION_TYPE_PACKED L"packed"
+#define WEBAUTHN_ATTESTATION_TYPE_U2F L"fido-u2f"
+#define WEBAUTHN_ATTESTATION_TYPE_TPM L"tpm"
+#define WEBAUTHN_ATTESTATION_TYPE_NONE L"none"
+
+#define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_1 1
+#define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_2 2
+#define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_3 3
+#define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_4 4
+#define WEBAUTHN_CREDENTIAL_ATTESTATION_CURRENT_VERSION WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_4
+
+typedef struct _WEBAUTHN_CREDENTIAL_ATTESTATION {
+ // Version of this structure, to allow for modifications in the future.
+ DWORD dwVersion;
+
+ // Attestation format type
+ PCWSTR pwszFormatType;
+
+ // Size of cbAuthenticatorData.
+ DWORD cbAuthenticatorData;
+ // Authenticator data that was created for this credential.
+ _Field_size_bytes_(cbAuthenticatorData)
+ PBYTE pbAuthenticatorData;
+
+ // Size of CBOR encoded attestation information
+ //0 => encoded as CBOR null value.
+ DWORD cbAttestation;
+ //Encoded CBOR attestation information
+ _Field_size_bytes_(cbAttestation)
+ PBYTE pbAttestation;
+
+ DWORD dwAttestationDecodeType;
+ // Following depends on the dwAttestationDecodeType
+ // WEBAUTHN_ATTESTATION_DECODE_NONE
+ // NULL - not able to decode the CBOR attestation information
+ // WEBAUTHN_ATTESTATION_DECODE_COMMON
+ // PWEBAUTHN_COMMON_ATTESTATION;
+ PVOID pvAttestationDecode;
+
+ // The CBOR encoded Attestation Object to be returned to the RP.
+ DWORD cbAttestationObject;
+ _Field_size_bytes_(cbAttestationObject)
+ PBYTE pbAttestationObject;
+
+ // The CredentialId bytes extracted from the Authenticator Data.
+ // Used by Edge to return to the RP.
+ DWORD cbCredentialId;
+ _Field_size_bytes_(cbCredentialId)
+ PBYTE pbCredentialId;
+
+ //
+ // Following fields have been added in WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_2
+ //
+
+ WEBAUTHN_EXTENSIONS Extensions;
+
+ //
+ // Following fields have been added in WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_3
+ //
+
+ // One of the WEBAUTHN_CTAP_TRANSPORT_* bits will be set corresponding to
+ // the transport that was used.
+ DWORD dwUsedTransport;
+
+ //
+ // Following fields have been added in WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_4
+ //
+
+ BOOL bEpAtt;
+ BOOL bLargeBlobSupported;
+ BOOL bResidentKey;
+
+} WEBAUTHN_CREDENTIAL_ATTESTATION, *PWEBAUTHN_CREDENTIAL_ATTESTATION;
+typedef const WEBAUTHN_CREDENTIAL_ATTESTATION *PCWEBAUTHN_CREDENTIAL_ATTESTATION;
+
+
+//+------------------------------------------------------------------------------------------
+// authenticatorGetAssertion output.
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_NONE 0
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_SUCCESS 1
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_NOT_SUPPORTED 2
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_INVALID_DATA 3
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_INVALID_PARAMETER 4
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_NOT_FOUND 5
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_MULTIPLE_CREDENTIALS 6
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_LACK_OF_SPACE 7
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_PLATFORM_ERROR 8
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_AUTHENTICATOR_ERROR 9
+
+#define WEBAUTHN_ASSERTION_VERSION_1 1
+#define WEBAUTHN_ASSERTION_VERSION_2 2
+#define WEBAUTHN_ASSERTION_CURRENT_VERSION WEBAUTHN_ASSERTION_VERSION_2
+
+typedef struct _WEBAUTHN_ASSERTION {
+ // Version of this structure, to allow for modifications in the future.
+ DWORD dwVersion;
+
+ // Size of cbAuthenticatorData.
+ DWORD cbAuthenticatorData;
+ // Authenticator data that was created for this assertion.
+ _Field_size_bytes_(cbAuthenticatorData)
+ PBYTE pbAuthenticatorData;
+
+ // Size of pbSignature.
+ DWORD cbSignature;
+ // Signature that was generated for this assertion.
+ _Field_size_bytes_(cbSignature)
+ PBYTE pbSignature;
+
+ // Credential that was used for this assertion.
+ WEBAUTHN_CREDENTIAL Credential;
+
+ // Size of User Id
+ DWORD cbUserId;
+ // UserId
+ _Field_size_bytes_(cbUserId)
+ PBYTE pbUserId;
+
+ //
+ // Following fields have been added in WEBAUTHN_ASSERTION_VERSION_2
+ //
+
+ WEBAUTHN_EXTENSIONS Extensions;
+
+ // Size of pbCredLargeBlob
+ DWORD cbCredLargeBlob;
+ _Field_size_bytes_(cbCredLargeBlob)
+ PBYTE pbCredLargeBlob;
+
+ DWORD dwCredLargeBlobStatus;
+
+} WEBAUTHN_ASSERTION, *PWEBAUTHN_ASSERTION;
+typedef const WEBAUTHN_ASSERTION *PCWEBAUTHN_ASSERTION;
+
+//+------------------------------------------------------------------------------------------
+// APIs.
+//-------------------------------------------------------------------------------------------
+
+DWORD
+WINAPI
+WebAuthNGetApiVersionNumber();
+
+HRESULT
+WINAPI
+WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable(
+ _Out_ BOOL *pbIsUserVerifyingPlatformAuthenticatorAvailable);
+
+
+HRESULT
+WINAPI
+WebAuthNAuthenticatorMakeCredential(
+ _In_ HWND hWnd,
+ _In_ PCWEBAUTHN_RP_ENTITY_INFORMATION pRpInformation,
+ _In_ PCWEBAUTHN_USER_ENTITY_INFORMATION pUserInformation,
+ _In_ PCWEBAUTHN_COSE_CREDENTIAL_PARAMETERS pPubKeyCredParams,
+ _In_ PCWEBAUTHN_CLIENT_DATA pWebAuthNClientData,
+ _In_opt_ PCWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS pWebAuthNMakeCredentialOptions,
+ _Outptr_result_maybenull_ PWEBAUTHN_CREDENTIAL_ATTESTATION *ppWebAuthNCredentialAttestation);
+
+
+HRESULT
+WINAPI
+WebAuthNAuthenticatorGetAssertion(
+ _In_ HWND hWnd,
+ _In_ LPCWSTR pwszRpId,
+ _In_ PCWEBAUTHN_CLIENT_DATA pWebAuthNClientData,
+ _In_opt_ PCWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS pWebAuthNGetAssertionOptions,
+ _Outptr_result_maybenull_ PWEBAUTHN_ASSERTION *ppWebAuthNAssertion);
+
+void
+WINAPI
+WebAuthNFreeCredentialAttestation(
+ _In_opt_ PWEBAUTHN_CREDENTIAL_ATTESTATION pWebAuthNCredentialAttestation);
+
+void
+WINAPI
+WebAuthNFreeAssertion(
+ _In_ PWEBAUTHN_ASSERTION pWebAuthNAssertion);
+
+HRESULT
+WINAPI
+WebAuthNGetCancellationId(
+ _Out_ GUID* pCancellationId);
+
+HRESULT
+WINAPI
+WebAuthNCancelCurrentOperation(
+ _In_ const GUID* pCancellationId);
+
+//
+// Returns the following Error Names:
+// L"Success" - S_OK
+// L"InvalidStateError" - NTE_EXISTS
+// L"ConstraintError" - HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED),
+// NTE_NOT_SUPPORTED,
+// NTE_TOKEN_KEYSET_STORAGE_FULL
+// L"NotSupportedError" - NTE_INVALID_PARAMETER
+// L"NotAllowedError" - NTE_DEVICE_NOT_FOUND,
+// NTE_NOT_FOUND,
+// HRESULT_FROM_WIN32(ERROR_CANCELLED),
+// NTE_USER_CANCELLED,
+// HRESULT_FROM_WIN32(ERROR_TIMEOUT)
+// L"UnknownError" - All other hr values
+//
+PCWSTR
+WINAPI
+WebAuthNGetErrorName(
+ _In_ HRESULT hr);
+
+HRESULT
+WINAPI
+WebAuthNGetW3CExceptionDOMError(
+ _In_ HRESULT hr);
+
+
+#ifdef __cplusplus
+} // Balance extern "C" above
+#endif
+
+#endif // WINAPI_FAMILY_PARTITION
+#pragma endregion
+
+#endif // __WEBAUTHN_H_
diff --git a/contrib/libfido2/src/winhello.c b/contrib/libfido2/src/winhello.c index 0fe5b4cfe4c7..4797ac58281e 100644 --- a/contrib/libfido2/src/winhello.c +++ b/contrib/libfido2/src/winhello.c @@ -8,9 +8,9 @@ #include <stdlib.h> #include <windows.h> -#include <webauthn.h> #include "fido.h" +#include "webauthn.h" #define MAXCHARS 128 #define MAXCREDS 128 @@ -40,6 +40,87 @@ struct winhello_cred { wchar_t *display_name; }; +static TLS BOOL webauthn_loaded; +static TLS HMODULE webauthn_handle; +static TLS DWORD (*webauthn_get_api_version)(void); +static TLS PCWSTR (*webauthn_strerr)(HRESULT); +static TLS HRESULT (*webauthn_get_assert)(HWND, LPCWSTR, + PCWEBAUTHN_CLIENT_DATA, + PCWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS, + PWEBAUTHN_ASSERTION *); +static TLS HRESULT (*webauthn_make_cred)(HWND, + PCWEBAUTHN_RP_ENTITY_INFORMATION, + PCWEBAUTHN_USER_ENTITY_INFORMATION, + PCWEBAUTHN_COSE_CREDENTIAL_PARAMETERS, + PCWEBAUTHN_CLIENT_DATA, + PCWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS, + PWEBAUTHN_CREDENTIAL_ATTESTATION *); +static TLS void (*webauthn_free_assert)(PWEBAUTHN_ASSERTION); +static TLS void (*webauthn_free_attest)(PWEBAUTHN_CREDENTIAL_ATTESTATION); + +static int +webauthn_load(void) +{ + if (webauthn_loaded || webauthn_handle != NULL) { + fido_log_debug("%s: already loaded", __func__); + return -1; + } + if ((webauthn_handle = LoadLibrary("webauthn.dll")) == NULL) { + fido_log_debug("%s: LoadLibrary", __func__); + return -1; + } + + if ((webauthn_get_api_version = (void *)GetProcAddress(webauthn_handle, + "WebAuthNGetApiVersionNumber")) == NULL) { + fido_log_debug("%s: WebAuthNGetApiVersionNumber", __func__); + goto fail; + } + if ((webauthn_strerr = (void *)GetProcAddress(webauthn_handle, + "WebAuthNGetErrorName")) == NULL) { + fido_log_debug("%s: WebAuthNGetErrorName", __func__); + goto fail; + } + if ((webauthn_get_assert = (void *)GetProcAddress(webauthn_handle, + "WebAuthNAuthenticatorGetAssertion")) == NULL) { + fido_log_debug("%s: WebAuthNAuthenticatorGetAssertion", + __func__); + goto fail; + } + if ((webauthn_make_cred = (void *)GetProcAddress(webauthn_handle, + "WebAuthNAuthenticatorMakeCredential")) == NULL) { + fido_log_debug("%s: WebAuthNAuthenticatorMakeCredential", + __func__); + goto fail; + } + if ((webauthn_free_assert = (void *)GetProcAddress(webauthn_handle, + "WebAuthNFreeAssertion")) == NULL) { + fido_log_debug("%s: WebAuthNFreeAssertion", __func__); + goto fail; + } + if ((webauthn_free_attest = (void *)GetProcAddress(webauthn_handle, + "WebAuthNFreeCredentialAttestation")) == NULL) { + fido_log_debug("%s: WebAuthNFreeCredentialAttestation", + __func__); + goto fail; + } + + webauthn_loaded = true; + + return 0; +fail: + fido_log_debug("%s: GetProcAddress", __func__); + webauthn_get_api_version = NULL; + webauthn_strerr = NULL; + webauthn_get_assert = NULL; + webauthn_make_cred = NULL; + webauthn_free_assert = NULL; + webauthn_free_attest = NULL; + FreeLibrary(webauthn_handle); + webauthn_handle = NULL; + + return -1; +} + static wchar_t * to_utf16(const char *utf8) { @@ -98,24 +179,6 @@ to_utf8(const wchar_t *utf16) } static int -to_fido_str_array(fido_str_array_t *sa, const char **v, size_t n) -{ - if ((sa->ptr = calloc(n, sizeof(char *))) == NULL) { - fido_log_debug("%s: calloc", __func__); - return -1; - } - for (size_t i = 0; i < n; i++) { - if ((sa->ptr[i] = strdup(v[i])) == NULL) { - fido_log_debug("%s: strdup", __func__); - return -1; - } - sa->len++; - } - - return 0; -} - -static int to_fido(HRESULT hr) { switch (hr) { @@ -210,7 +273,7 @@ set_uv(DWORD *out, fido_opt_t uv, const char *pin) static int pack_rp(wchar_t **id, wchar_t **name, WEBAUTHN_RP_ENTITY_INFORMATION *out, - fido_rp_t *in) + const fido_rp_t *in) { /* keep non-const copies of pwsz* for free() */ out->dwVersion = WEBAUTHN_RP_ENTITY_INFORMATION_CURRENT_VERSION; @@ -227,7 +290,7 @@ pack_rp(wchar_t **id, wchar_t **name, WEBAUTHN_RP_ENTITY_INFORMATION *out, static int pack_user(wchar_t **name, wchar_t **icon, wchar_t **display_name, - WEBAUTHN_USER_ENTITY_INFORMATION *out, fido_user_t *in) + WEBAUTHN_USER_ENTITY_INFORMATION *out, const fido_user_t *in) { if (in->id.ptr == NULL || in->id.len > ULONG_MAX) { fido_log_debug("%s: id", __func__); @@ -287,7 +350,7 @@ pack_cose(WEBAUTHN_COSE_CREDENTIAL_PARAMETER *alg, } static int -pack_cred_ext(WEBAUTHN_EXTENSIONS *out, fido_cred_ext_t *in) +pack_cred_ext(WEBAUTHN_EXTENSIONS *out, const fido_cred_ext_t *in) { WEBAUTHN_EXTENSION *e; WEBAUTHN_CRED_PROTECT_EXTENSION_IN *p; @@ -342,94 +405,7 @@ pack_cred_ext(WEBAUTHN_EXTENSIONS *out, fido_cred_ext_t *in) } static int -unpack_fmt(fido_cred_t *cred, WEBAUTHN_CREDENTIAL_ATTESTATION *att) -{ - char *fmt; - int r; - - if ((fmt = to_utf8(att->pwszFormatType)) == NULL) { - fido_log_debug("%s: fmt", __func__); - return -1; - } - r = fido_cred_set_fmt(cred, fmt); - free(fmt); - fmt = NULL; - if (r != FIDO_OK) { - fido_log_debug("%s: fido_cred_set_fmt: %s", __func__, - fido_strerr(r)); - return -1; - } - - return 0; -} - -static int -unpack_cred_authdata(fido_cred_t *cred, WEBAUTHN_CREDENTIAL_ATTESTATION *att) -{ - int r; - - if (att->cbAuthenticatorData > SIZE_MAX) { - fido_log_debug("%s: cbAuthenticatorData", __func__); - return -1; - } - if ((r = fido_cred_set_authdata_raw(cred, att->pbAuthenticatorData, - (size_t)att->cbAuthenticatorData)) != FIDO_OK) { - fido_log_debug("%s: fido_cred_set_authdata_raw: %s", __func__, - fido_strerr(r)); - return -1; - } - - return 0; -} - -static int -unpack_cred_sig(fido_cred_t *cred, WEBAUTHN_COMMON_ATTESTATION *attr) -{ - int r; - - if (attr->cbSignature > SIZE_MAX) { - fido_log_debug("%s: cbSignature", __func__); - return -1; - } - if ((r = fido_cred_set_sig(cred, attr->pbSignature, - (size_t)attr->cbSignature)) != FIDO_OK) { - fido_log_debug("%s: fido_cred_set_sig: %s", __func__, - fido_strerr(r)); - return -1; - } - - return 0; -} - -static int -unpack_x5c(fido_cred_t *cred, WEBAUTHN_COMMON_ATTESTATION *attr) -{ - int r; - - fido_log_debug("%s: %u cert(s)", __func__, attr->cX5c); - - if (attr->cX5c == 0) - return 0; /* self-attestation */ - if (attr->lAlg != WEBAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256) { - fido_log_debug("%s: lAlg %d", __func__, attr->lAlg); - return -1; - } - if (attr->pX5c[0].cbData > SIZE_MAX) { - fido_log_debug("%s: cbData", __func__); - return -1; - } - if ((r = fido_cred_set_x509(cred, attr->pX5c[0].pbData, - (size_t)attr->pX5c[0].cbData)) != FIDO_OK) { - fido_log_debug("%s: fido_cred_set_x509: %s", __func__, - fido_strerr(r)); - return -1; - } - - return 0; -} - -static int -unpack_assert_authdata(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa) +unpack_assert_authdata(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) { int r; @@ -448,7 +424,7 @@ unpack_assert_authdata(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa) } static int -unpack_assert_sig(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa) +unpack_assert_sig(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) { int r; @@ -467,7 +443,7 @@ unpack_assert_sig(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa) } static int -unpack_cred_id(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa) +unpack_cred_id(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) { if (wa->Credential.cbId > SIZE_MAX) { fido_log_debug("%s: Credential.cbId", __func__); @@ -483,7 +459,7 @@ unpack_cred_id(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa) } static int -unpack_user_id(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa) +unpack_user_id(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) { if (wa->cbUserId == 0) return 0; /* user id absent */ @@ -501,8 +477,8 @@ unpack_user_id(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa) } static int -translate_fido_assert(struct winhello_assert *ctx, fido_assert_t *assert, - const char *pin) +translate_fido_assert(struct winhello_assert *ctx, const fido_assert_t *assert, + const char *pin, int ms) { WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS *opt; @@ -527,7 +503,7 @@ translate_fido_assert(struct winhello_assert *ctx, fido_assert_t *assert, /* options */ opt = &ctx->opt; opt->dwVersion = WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_1; - opt->dwTimeoutMilliseconds = MAXMSEC; + opt->dwTimeoutMilliseconds = ms < 0 ? MAXMSEC : (DWORD)ms; if (pack_credlist(&opt->CredentialList, &assert->allow_list) < 0) { fido_log_debug("%s: pack_credlist", __func__); return FIDO_ERR_INTERNAL; @@ -541,7 +517,7 @@ translate_fido_assert(struct winhello_assert *ctx, fido_assert_t *assert, } static int -translate_winhello_assert(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa) +translate_winhello_assert(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) { int r; @@ -575,8 +551,8 @@ translate_winhello_assert(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa) } static int -translate_fido_cred(struct winhello_cred *ctx, fido_cred_t *cred, - const char *pin) +translate_fido_cred(struct winhello_cred *ctx, const fido_cred_t *cred, + const char *pin, int ms) { WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS *opt; @@ -600,7 +576,9 @@ translate_fido_cred(struct winhello_cred *ctx, fido_cred_t *cred, /* options */ opt = &ctx->opt; opt->dwVersion = WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_1; - opt->dwTimeoutMilliseconds = MAXMSEC; + opt->dwTimeoutMilliseconds = ms < 0 ? MAXMSEC : (DWORD)ms; + opt->dwAttestationConveyancePreference = + WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_DIRECT; if (pack_credlist(&opt->CredentialList, &cred->excl) < 0) { fido_log_debug("%s: pack_credlist", __func__); return FIDO_ERR_INTERNAL; @@ -609,7 +587,8 @@ translate_fido_cred(struct winhello_cred *ctx, fido_cred_t *cred, fido_log_debug("%s: pack_cred_ext", __func__); return FIDO_ERR_UNSUPPORTED_EXTENSION; } - if (set_uv(&opt->dwUserVerificationRequirement, cred->uv, pin) < 0) { + if (set_uv(&opt->dwUserVerificationRequirement, (cred->ext.mask & + FIDO_EXT_CRED_PROTECT) ? FIDO_OPT_TRUE : cred->uv, pin) < 0) { fido_log_debug("%s: set_uv", __func__); return FIDO_ERR_INTERNAL; } @@ -621,67 +600,94 @@ translate_fido_cred(struct winhello_cred *ctx, fido_cred_t *cred, } static int -translate_winhello_cred(fido_cred_t *cred, WEBAUTHN_CREDENTIAL_ATTESTATION *att) +decode_attobj(const cbor_item_t *key, const cbor_item_t *val, void *arg) { - if (unpack_fmt(cred, att) < 0) { - fido_log_debug("%s: unpack_fmt", __func__); - return FIDO_ERR_INTERNAL; - } - if (unpack_cred_authdata(cred, att) < 0) { - fido_log_debug("%s: unpack_cred_authdata", __func__); - return FIDO_ERR_INTERNAL; + fido_cred_t *cred = arg; + char *name = NULL; + int ok = -1; + + if (cbor_string_copy(key, &name) < 0) { + fido_log_debug("%s: cbor type", __func__); + ok = 0; /* ignore */ + goto fail; } - switch (att->dwAttestationDecodeType) { - case WEBAUTHN_ATTESTATION_DECODE_NONE: - if (att->pvAttestationDecode != NULL) { - fido_log_debug("%s: pvAttestationDecode", __func__); - return FIDO_ERR_INTERNAL; + if (!strcmp(name, "fmt")) { + if (cbor_decode_fmt(val, &cred->fmt) < 0) { + fido_log_debug("%s: cbor_decode_fmt", __func__); + goto fail; } - break; - case WEBAUTHN_ATTESTATION_DECODE_COMMON: - if (att->pvAttestationDecode == NULL) { - fido_log_debug("%s: pvAttestationDecode", __func__); - return FIDO_ERR_INTERNAL; + } else if (!strcmp(name, "attStmt")) { + if (cbor_decode_attstmt(val, &cred->attstmt) < 0) { + fido_log_debug("%s: cbor_decode_attstmt", __func__); + goto fail; } - if (unpack_cred_sig(cred, att->pvAttestationDecode) < 0) { - fido_log_debug("%s: unpack_cred_sig", __func__); - return FIDO_ERR_INTERNAL; + } else if (!strcmp(name, "authData")) { + if (cbor_decode_cred_authdata(val, cred->type, + &cred->authdata_cbor, &cred->authdata, &cred->attcred, + &cred->authdata_ext) < 0) { + fido_log_debug("%s: cbor_decode_cred_authdata", + __func__); + goto fail; } - if (unpack_x5c(cred, att->pvAttestationDecode) < 0) { - fido_log_debug("%s: unpack_x5c", __func__); - return FIDO_ERR_INTERNAL; - } - break; - default: - fido_log_debug("%s: dwAttestationDecodeType: %u", __func__, - att->dwAttestationDecodeType); - return FIDO_ERR_INTERNAL; } - return FIDO_OK; + ok = 0; +fail: + free(name); + + return (ok); } static int -winhello_manifest(BOOL *present) +translate_winhello_cred(fido_cred_t *cred, const WEBAUTHN_CREDENTIAL_ATTESTATION *att) +{ + + cbor_item_t *item = NULL; + struct cbor_load_result cbor; + int r = FIDO_ERR_INTERNAL; + + if (att->pbAttestationObject == NULL || + att->cbAttestationObject > SIZE_MAX) { + fido_log_debug("%s: pbAttestationObject", __func__); + goto fail; + } + if ((item = cbor_load(att->pbAttestationObject, + (size_t)att->cbAttestationObject, &cbor)) == NULL) { + fido_log_debug("%s: cbor_load", __func__); + goto fail; + } + if (cbor_isa_map(item) == false || + cbor_map_is_definite(item) == false || + cbor_map_iter(item, cred, decode_attobj) < 0) { + fido_log_debug("%s: cbor type", __func__); + goto fail; + } + + r = FIDO_OK; +fail: + if (item != NULL) + cbor_decref(&item); + + return r; +} + +static int +winhello_manifest(void) { DWORD n; - HRESULT hr; - int r = FIDO_OK; - if ((n = WebAuthNGetApiVersionNumber()) < 1) { + if (!webauthn_loaded && webauthn_load() < 0) { + fido_log_debug("%s: webauthn_load", __func__); + return FIDO_ERR_INTERNAL; + } + if ((n = webauthn_get_api_version()) < 1) { fido_log_debug("%s: unsupported api %u", __func__, n); return FIDO_ERR_INTERNAL; } fido_log_debug("%s: api version %u", __func__, n); - hr = WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable(present); - if (hr != S_OK) { - r = to_fido(hr); - fido_log_debug("%s: %ls -> %s", __func__, - WebAuthNGetErrorName(hr), fido_strerr(r)); - } - return r; + return FIDO_OK; } static int @@ -690,12 +696,11 @@ winhello_get_assert(HWND w, struct winhello_assert *ctx) HRESULT hr; int r = FIDO_OK; - hr = WebAuthNAuthenticatorGetAssertion(w, ctx->rp_id, &ctx->cd, - &ctx->opt, &ctx->assert); - if (hr != S_OK) { + if ((hr = webauthn_get_assert(w, ctx->rp_id, &ctx->cd, &ctx->opt, + &ctx->assert)) != S_OK) { r = to_fido(hr); - fido_log_debug("%s: %ls -> %s", __func__, - WebAuthNGetErrorName(hr), fido_strerr(r)); + fido_log_debug("%s: %ls -> %s", __func__, webauthn_strerr(hr), + fido_strerr(r)); } return r; @@ -707,12 +712,11 @@ winhello_make_cred(HWND w, struct winhello_cred *ctx) HRESULT hr; int r = FIDO_OK; - hr = WebAuthNAuthenticatorMakeCredential(w, &ctx->rp, &ctx->user, - &ctx->cose, &ctx->cd, &ctx->opt, &ctx->att); - if (hr != S_OK) { + if ((hr = webauthn_make_cred(w, &ctx->rp, &ctx->user, &ctx->cose, + &ctx->cd, &ctx->opt, &ctx->att)) != S_OK) { r = to_fido(hr); - fido_log_debug("%s: %ls -> %s", __func__, - WebAuthNGetErrorName(hr), fido_strerr(r)); + fido_log_debug("%s: %ls -> %s", __func__, webauthn_strerr(hr), + fido_strerr(r)); } return r; @@ -724,7 +728,7 @@ winhello_assert_free(struct winhello_assert *ctx) if (ctx == NULL) return; if (ctx->assert != NULL) - WebAuthNFreeAssertion(ctx->assert); + webauthn_free_assert(ctx->assert); free(ctx->rp_id); free(ctx->opt.CredentialList.pCredentials); @@ -737,7 +741,7 @@ winhello_cred_free(struct winhello_cred *ctx) if (ctx == NULL) return; if (ctx->att != NULL) - WebAuthNFreeCredentialAttestation(ctx->att); + webauthn_free_attest(ctx->att); free(ctx->rp_id); free(ctx->rp_name); @@ -758,7 +762,6 @@ int fido_winhello_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen) { int r; - BOOL present; fido_dev_info_t *di; if (ilen == 0) { @@ -767,14 +770,10 @@ fido_winhello_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen) if (devlist == NULL) { return FIDO_ERR_INVALID_ARGUMENT; } - if ((r = winhello_manifest(&present)) != FIDO_OK) { + if ((r = winhello_manifest()) != FIDO_OK) { fido_log_debug("%s: winhello_manifest", __func__); return r; } - if (present == false) { - fido_log_debug("%s: not present", __func__); - return FIDO_OK; - } di = &devlist[*olen]; memset(di, 0, sizeof(*di)); @@ -799,9 +798,12 @@ fido_winhello_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen) int fido_winhello_open(fido_dev_t *dev) { + if (!webauthn_loaded && webauthn_load() < 0) { + fido_log_debug("%s: webauthn_load", __func__); + return FIDO_ERR_INTERNAL; + } if (dev->flags != 0) return FIDO_ERR_INVALID_ARGUMENT; - dev->attr.flags = FIDO_CAP_CBOR | FIDO_CAP_WINK; dev->flags = FIDO_DEV_WINHELLO | FIDO_DEV_CRED_PROT | FIDO_DEV_PIN_SET; @@ -826,7 +828,7 @@ fido_winhello_cancel(fido_dev_t *dev) int fido_winhello_get_assert(fido_dev_t *dev, fido_assert_t *assert, - const char *pin) + const char *pin, int ms) { HWND w; struct winhello_assert *ctx; @@ -834,6 +836,8 @@ fido_winhello_get_assert(fido_dev_t *dev, fido_assert_t *assert, (void)dev; + fido_assert_reset_rx(assert); + if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { fido_log_debug("%s: calloc", __func__); goto fail; @@ -842,7 +846,7 @@ fido_winhello_get_assert(fido_dev_t *dev, fido_assert_t *assert, fido_log_debug("%s: GetForegroundWindow", __func__); goto fail; } - if ((r = translate_fido_assert(ctx, assert, pin)) != FIDO_OK) { + if ((r = translate_fido_assert(ctx, assert, pin, ms)) != FIDO_OK) { fido_log_debug("%s: translate_fido_assert", __func__); goto fail; } @@ -873,10 +877,10 @@ fido_winhello_get_cbor_info(fido_dev_t *dev, fido_cbor_info_t *ci) fido_cbor_info_reset(ci); - if (to_fido_str_array(&ci->versions, v, nitems(v)) < 0 || - to_fido_str_array(&ci->extensions, e, nitems(e)) < 0 || - to_fido_str_array(&ci->transports, t, nitems(t)) < 0) { - fido_log_debug("%s: to_fido_str_array", __func__); + if (fido_str_array_pack(&ci->versions, v, nitems(v)) < 0 || + fido_str_array_pack(&ci->extensions, e, nitems(e)) < 0 || + fido_str_array_pack(&ci->transports, t, nitems(t)) < 0) { + fido_log_debug("%s: fido_str_array_pack", __func__); return FIDO_ERR_INTERNAL; } if ((ci->options.name = calloc(nitems(o), sizeof(char *))) == NULL || @@ -897,7 +901,8 @@ fido_winhello_get_cbor_info(fido_dev_t *dev, fido_cbor_info_t *ci) } int -fido_winhello_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin) +fido_winhello_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin, + int ms) { HWND w; struct winhello_cred *ctx; @@ -905,6 +910,8 @@ fido_winhello_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin) (void)dev; + fido_cred_reset_rx(cred); + if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { fido_log_debug("%s: calloc", __func__); goto fail; @@ -913,7 +920,7 @@ fido_winhello_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin) fido_log_debug("%s: GetForegroundWindow", __func__); goto fail; } - if ((r = translate_fido_cred(ctx, cred, pin)) != FIDO_OK) { + if ((r = translate_fido_cred(ctx, cred, pin, ms)) != FIDO_OK) { fido_log_debug("%s: translate_fido_cred", __func__); goto fail; } diff --git a/contrib/libfido2/tools/CMakeLists.txt b/contrib/libfido2/tools/CMakeLists.txt index b1dde9949c4f..f37aa1d87c97 100644 --- a/contrib/libfido2/tools/CMakeLists.txt +++ b/contrib/libfido2/tools/CMakeLists.txt @@ -3,10 +3,13 @@ # license that can be found in the LICENSE file. list(APPEND COMPAT_SOURCES + ../openbsd-compat/bsd-getpagesize.c ../openbsd-compat/explicit_bzero.c ../openbsd-compat/freezero.c + ../openbsd-compat/recallocarray.c ../openbsd-compat/strlcat.c ../openbsd-compat/strlcpy.c + ../openbsd-compat/strsep.c ) if(WIN32 AND NOT CYGWIN AND NOT MSYS) diff --git a/contrib/libfido2/tools/config.c b/contrib/libfido2/tools/config.c index 17dfe4457902..3eea4c9b6cf6 100644 --- a/contrib/libfido2/tools/config.c +++ b/contrib/libfido2/tools/config.c @@ -147,3 +147,51 @@ out: exit(ok); } + +int +config_pin_minlen_rpid(char *path, const char *rpids) +{ + fido_dev_t *dev; + char *otmp, *tmp, *cp; + char *pin = NULL, **rpid = NULL; + int r, ok = 1; + size_t n; + + if ((tmp = strdup(rpids)) == NULL) + err(1, "strdup"); + otmp = tmp; + for (n = 0; (cp = strsep(&tmp, ",")) != NULL; n++) { + if (n == SIZE_MAX || (rpid = recallocarray(rpid, n, n + 1, + sizeof(*rpid))) == NULL) + err(1, "recallocarray"); + if ((rpid[n] = strdup(cp)) == NULL) + err(1, "strdup"); + if (*rpid[n] == '\0') + errx(1, "empty rpid"); + } + free(otmp); + if (rpid == NULL || n == 0) + errx(1, "could not parse rp_id"); + dev = open_dev(path); + if ((r = fido_dev_set_pin_minlen_rpid(dev, (const char * const *)rpid, + n, NULL)) != FIDO_OK && should_retry_with_pin(dev, r)) { + if ((pin = get_pin(path)) == NULL) + goto out; + r = fido_dev_set_pin_minlen_rpid(dev, (const char * const *)rpid, + n, pin); + freezero(pin, PINBUF_LEN); + pin = NULL; + } + if (r != FIDO_OK) { + warnx("fido_dev_set_pin_minlen_rpid: %s (0x%x)", + fido_strerr(r), r); + goto out; + } + + ok = 0; +out: + fido_dev_close(dev); + fido_dev_free(&dev); + + exit(ok); +} diff --git a/contrib/libfido2/tools/extern.h b/contrib/libfido2/tools/extern.h index 207c35894f8b..8b25dadd45ac 100644 --- a/contrib/libfido2/tools/extern.h +++ b/contrib/libfido2/tools/extern.h @@ -20,7 +20,7 @@ struct blob { size_t len; }; -#define TOKEN_OPT "CDGILPRSVabcdefi:k:l:n:p:ru" +#define TOKEN_OPT "CDGILPRSVabcdefi:k:l:m:n:p:ru" #define FLAG_DEBUG 0x01 #define FLAG_QUIET 0x02 @@ -62,6 +62,7 @@ int config_always_uv(char *, int); int config_entattest(char *); int config_force_pin_change(char *); int config_pin_minlen(char *, const char *); +int config_pin_minlen_rpid(char *, const char *); int cose_type(const char *, int *); int cred_make(int, char **); int cred_verify(int, char **); diff --git a/contrib/libfido2/tools/fido2-token.c b/contrib/libfido2/tools/fido2-token.c index c1539b8bc08e..e6d9f9f96381 100644 --- a/contrib/libfido2/tools/fido2-token.c +++ b/contrib/libfido2/tools/fido2-token.c @@ -28,6 +28,7 @@ usage(void) " fido2-token -S [-adefu] [-l pin_length] [-i template_id -n template_name] device\n" " fido2-token -Sb [-k key_path] [-i cred_id -n rp_id] blob_path device\n" " fido2-token -Sc -i cred_id -k user_id -n name -p display_name device\n" +" fido2-token -Sm rp_id device\n" " fido2-token -V\n" ); @@ -59,6 +60,7 @@ main(int argc, char **argv) case 'i': case 'k': case 'l': + case 'm': case 'n': case 'p': case 'r': diff --git a/contrib/libfido2/tools/token.c b/contrib/libfido2/tools/token.c index 4dcc2fea6dbd..3d165623fdbf 100644 --- a/contrib/libfido2/tools/token.c +++ b/contrib/libfido2/tools/token.c @@ -352,6 +352,7 @@ token_set(int argc, char **argv, char *path) char *len = NULL; char *display_name = NULL; char *name = NULL; + char *rpid = NULL; int blob = 0; int cred = 0; int ch; @@ -391,6 +392,9 @@ token_set(int argc, char **argv, char *path) case 'p': display_name = optarg; break; + case 'm': + rpid = optarg; + break; case 'n': name = optarg; break; @@ -440,6 +444,8 @@ token_set(int argc, char **argv, char *path) if (len) return (config_pin_minlen(path, len)); + if (rpid) + return (config_pin_minlen_rpid(path, rpid)); if (force) return (config_force_pin_change(path)); if (uv) diff --git a/contrib/libfido2/windows/build.ps1 b/contrib/libfido2/windows/build.ps1 index 55aac9d96bc5..87d0c31e5311 100644 --- a/contrib/libfido2/windows/build.ps1 +++ b/contrib/libfido2/windows/build.ps1 @@ -1,140 +1,136 @@ +# Copyright (c) 2021 Yubico AB. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + param( [string]$CMakePath = "C:\Program Files\CMake\bin\cmake.exe", [string]$GitPath = "C:\Program Files\Git\bin\git.exe", [string]$SevenZPath = "C:\Program Files\7-Zip\7z.exe", [string]$GPGPath = "C:\Program Files (x86)\GnuPG\bin\gpg.exe", [string]$WinSDK = "", + [string]$Config = "Release", + [string]$Arch = "x64", + [string]$Type = "dynamic", [string]$Fido2Flags = "" ) -$ErrorActionPreference = "Continue" - +$ErrorActionPreference = "Stop" [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -# LibreSSL coordinates. -New-Variable -Name 'LIBRESSL_URL' ` - -Value 'https://fastly.cdn.openbsd.org/pub/OpenBSD/LibreSSL' -Option Constant -New-Variable -Name 'LIBRESSL' -Value 'libressl-3.2.5' -Option Constant +. "$PSScriptRoot\const.ps1" -# libcbor coordinates. -New-Variable -Name 'LIBCBOR' -Value 'libcbor-0.8.0' -Option Constant -New-Variable -Name 'LIBCBOR_BRANCH' -Value 'v0.8.0' -Option Constant -New-Variable -Name 'LIBCBOR_GIT' -Value 'https://github.com/pjk/libcbor' ` - -Option Constant +Function ExitOnError() { + if ($LastExitCode -ne 0) { + throw "A command exited with status $LastExitCode" + } +} -# zlib coordinates. -New-Variable -Name 'ZLIB' -Value 'zlib-1.2.11' -Option Constant -New-Variable -Name 'ZLIB_BRANCH' -Value 'v1.2.11' -Option Constant -New-Variable -Name 'ZLIB_GIT' -Value 'https://github.com/madler/zlib' ` - -Option Constant +Function GitClone(${REPO}, ${BRANCH}, ${DIR}) { + Write-Host "Cloning ${REPO}..." + & $Git -c advice.detachedHead=false clone --quiet --depth=1 ` + --branch "${BRANCH}" "${REPO}" "${DIR}" + Write-Host "${REPO}'s ${BRANCH} HEAD is:" + & $Git -C "${DIR}" show -s HEAD +} -# Work directories. -New-Variable -Name 'BUILD' -Value "$PSScriptRoot\..\build" -Option Constant -New-Variable -Name 'OUTPUT' -Value "$PSScriptRoot\..\output" -Option Constant +# Find Git. +$Git = $(Get-Command git -ErrorAction Ignore | ` + Select-Object -ExpandProperty Source) +if ([string]::IsNullOrEmpty($Git)) { + $Git = $GitPath +} +if (-Not (Test-Path $Git)) { + throw "Unable to find Git at $Git" +} # Find CMake. -$CMake = $(Get-Command cmake -ErrorAction Ignore | Select-Object -ExpandProperty Source) -if([string]::IsNullOrEmpty($CMake)) { +$CMake = $(Get-Command cmake -ErrorAction Ignore | ` + Select-Object -ExpandProperty Source) +if ([string]::IsNullOrEmpty($CMake)) { $CMake = $CMakePath } - -# Find Git. -$Git = $(Get-Command git -ErrorAction Ignore | Select-Object -ExpandProperty Source) -if([string]::IsNullOrEmpty($Git)) { - $Git = $GitPath +if (-Not (Test-Path $CMake)) { + throw "Unable to find CMake at $CMake" } # Find 7z. -$SevenZ = $(Get-Command 7z -ErrorAction Ignore | Select-Object -ExpandProperty Source) -if([string]::IsNullOrEmpty($SevenZ)) { +$SevenZ = $(Get-Command 7z -ErrorAction Ignore | ` + Select-Object -ExpandProperty Source) +if ([string]::IsNullOrEmpty($SevenZ)) { $SevenZ = $SevenZPath } +if (-Not (Test-Path $SevenZ)) { + throw "Unable to find 7z at $SevenZ" +} # Find GPG. -$GPG = $(Get-Command gpg -ErrorAction Ignore | Select-Object -ExpandProperty Source) -if([string]::IsNullOrEmpty($GPG)) { +$GPG = $(Get-Command gpg -ErrorAction Ignore | ` + Select-Object -ExpandProperty Source) +if ([string]::IsNullOrEmpty($GPG)) { $GPG = $GPGPath } +if (-Not (Test-Path $GPG)) { + throw "Unable to find GPG at $GPG" +} # Override CMAKE_SYSTEM_VERSION if $WinSDK is set. -if(-Not ([string]::IsNullOrEmpty($WinSDK))) { +if (-Not ([string]::IsNullOrEmpty($WinSDK))) { $CMAKE_SYSTEM_VERSION = "-DCMAKE_SYSTEM_VERSION='$WinSDK'" } else { $CMAKE_SYSTEM_VERSION = '' } -if(-Not (Test-Path $CMake)) { - throw "Unable to find CMake at $CMake" -} - -if(-Not (Test-Path $Git)) { - throw "Unable to find Git at $Git" -} - -if(-Not (Test-Path $SevenZ)) { - throw "Unable to find 7z at $SevenZ" -} - -if(-Not (Test-Path $GPG)) { - throw "Unable to find GPG at $GPG" -} - +Write-Host "WinSDK: $WinSDK" +Write-Host "Config: $Config" +Write-Host "Arch: $Arch" +Write-Host "Type: $Type" Write-Host "Git: $Git" Write-Host "CMake: $CMake" Write-Host "7z: $SevenZ" Write-Host "GPG: $GPG" -New-Item -Type Directory ${BUILD} -New-Item -Type Directory ${BUILD}\32 -New-Item -Type Directory ${BUILD}\32\dynamic -New-Item -Type Directory ${BUILD}\32\static -New-Item -Type Directory ${BUILD}\64 -New-Item -Type Directory ${BUILD}\64\dynamic -New-Item -Type Directory ${BUILD}\64\static -New-Item -Type Directory ${OUTPUT} -New-Item -Type Directory ${OUTPUT}\pkg\Win64\Release\v142\dynamic -New-Item -Type Directory ${OUTPUT}\pkg\Win32\Release\v142\dynamic -New-Item -Type Directory ${OUTPUT}\pkg\Win64\Release\v142\static -New-Item -Type Directory ${OUTPUT}\pkg\Win32\Release\v142\static +# Create build directories. +New-Item -Type Directory "${BUILD}" -Force +New-Item -Type Directory "${BUILD}\${Arch}" -Force +New-Item -Type Directory "${BUILD}\${Arch}\${Type}" -Force +New-Item -Type Directory "${STAGE}\${LIBRESSL}" -Force +New-Item -Type Directory "${STAGE}\${LIBCBOR}" -Force +New-Item -Type Directory "${STAGE}\${ZLIB}" -Force -Push-Location ${BUILD} +# Create output directories. +New-Item -Type Directory "${OUTPUT}" -Force +New-Item -Type Directory "${OUTPUT}\${Arch}" -Force +New-Item -Type Directory "${OUTPUT}\${Arch}\${Type}" -force +# Fetch and verify dependencies. +Push-Location ${BUILD} try { - if (Test-Path .\${LIBRESSL}) { - Remove-Item .\${LIBRESSL} -Recurse -ErrorAction Stop - } - - if(-Not (Test-Path .\${LIBRESSL}.tar.gz -PathType leaf)) { - Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz ` - -OutFile .\${LIBRESSL}.tar.gz - } - if(-Not (Test-Path .\${LIBRESSL}.tar.gz.asc -PathType leaf)) { - Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz.asc ` - -OutFile .\${LIBRESSL}.tar.gz.asc - } - - Copy-Item "$PSScriptRoot\libressl.gpg" -Destination "${BUILD}" - & $GPG --list-keys - & $GPG -v --no-default-keyring --keyring ./libressl.gpg ` - --verify .\${LIBRESSL}.tar.gz.asc .\${LIBRESSL}.tar.gz - if ($LastExitCode -ne 0) { - throw "GPG signature verification failed" + if (-Not (Test-Path .\${LIBRESSL})) { + if (-Not (Test-Path .\${LIBRESSL}.tar.gz -PathType leaf)) { + Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz ` + -OutFile .\${LIBRESSL}.tar.gz + } + if (-Not (Test-Path .\${LIBRESSL}.tar.gz.asc -PathType leaf)) { + Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz.asc ` + -OutFile .\${LIBRESSL}.tar.gz.asc + } + + Copy-Item "$PSScriptRoot\libressl.gpg" -Destination "${BUILD}" + & $GPG --list-keys + & $GPG --quiet --no-default-keyring --keyring ./libressl.gpg ` + --verify .\${LIBRESSL}.tar.gz.asc .\${LIBRESSL}.tar.gz + if ($LastExitCode -ne 0) { + throw "GPG signature verification failed" + } + & $SevenZ e .\${LIBRESSL}.tar.gz + & $SevenZ x .\${LIBRESSL}.tar + Remove-Item -Force .\${LIBRESSL}.tar } - - & $SevenZ e .\${LIBRESSL}.tar.gz - & $SevenZ x .\${LIBRESSL}.tar - Remove-Item -Force .\${LIBRESSL}.tar - - if(-Not (Test-Path .\${LIBCBOR})) { - Write-Host "Cloning ${LIBCBOR}..." - & $Git clone --branch ${LIBCBOR_BRANCH} ${LIBCBOR_GIT} ` - .\${LIBCBOR} + if (-Not (Test-Path .\${LIBCBOR})) { + GitClone "${LIBCBOR_GIT}" "${LIBCBOR_BRANCH}" ".\${LIBCBOR}" } - - if(-Not (Test-Path .\${ZLIB})) { - Write-Host "Cloning ${ZLIB}..." - & $Git clone --branch ${ZLIB_BRANCH} ${ZLIB_GIT} ` - .\${ZLIB} + if (-Not (Test-Path .\${ZLIB})) { + GitClone "${ZLIB_GIT}" "${ZLIB_BRANCH}" ".\${ZLIB}" } } catch { throw "Failed to fetch and verify dependencies" @@ -142,131 +138,103 @@ try { Pop-Location } -Function Build(${OUTPUT}, ${GENERATOR}, ${ARCH}, ${SHARED}, ${FLAGS}) { - if (-Not (Test-Path .\${LIBRESSL})) { - New-Item -Type Directory .\${LIBRESSL} -ErrorAction Stop - } - - Push-Location .\${LIBRESSL} - & $CMake ..\..\..\${LIBRESSL} -G "${GENERATOR}" -A "${ARCH}" ` - -DBUILD_SHARED_LIBS="${SHARED}" -DLIBRESSL_TESTS=OFF ` - -DCMAKE_C_FLAGS_RELEASE="${FLAGS} /Zi /guard:cf /sdl" ` - -DCMAKE_INSTALL_PREFIX="${OUTPUT}" "${CMAKE_SYSTEM_VERSION}" - & $CMake --build . --config Release --verbose - & $CMake --build . --config Release --target install --verbose +# Build LibreSSL. +Push-Location ${STAGE}\${LIBRESSL} +try { + & $CMake ..\..\..\${LIBRESSL} -A "${Arch}" ` + -DBUILD_SHARED_LIBS="${SHARED}" -DLIBRESSL_TESTS=OFF ` + -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" ` + -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" ` + -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; ` + ExitOnError + & $CMake --build . --config ${Config} --verbose; ExitOnError + & $CMake --build . --config ${Config} --target install --verbose; ` + ExitOnError +} catch { + throw "Failed to build LibreSSL" +} finally { Pop-Location +} - if (-Not (Test-Path .\${LIBCBOR})) { - New-Item -Type Directory .\${LIBCBOR} -ErrorAction Stop - } - - Push-Location .\${LIBCBOR} - & $CMake ..\..\..\${LIBCBOR} -G "${GENERATOR}" -A "${ARCH}" ` - -DBUILD_SHARED_LIBS="${SHARED}" ` - -DCMAKE_C_FLAGS_RELEASE="${FLAGS} /Zi /guard:cf /sdl" ` - -DCMAKE_INSTALL_PREFIX="${OUTPUT}" "${CMAKE_SYSTEM_VERSION}" - & $CMake --build . --config Release --verbose - & $CMake --build . --config Release --target install --verbose +# Build libcbor. +Push-Location ${STAGE}\${LIBCBOR} +try { + & $CMake ..\..\..\${LIBCBOR} -A "${Arch}" ` + -DWITH_EXAMPLES=OFF ` + -DBUILD_SHARED_LIBS="${SHARED}" ` + -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" ` + -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" ` + -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; ` + ExitOnError + & $CMake --build . --config ${Config} --verbose; ExitOnError + & $CMake --build . --config ${Config} --target install --verbose; ` + ExitOnError +} catch { + throw "Failed to build libcbor" +} finally { Pop-Location +} - if(-Not (Test-Path .\${ZLIB})) { - New-Item -Type Directory .\${ZLIB} -ErrorAction Stop +# Build zlib. +Push-Location ${STAGE}\${ZLIB} +try { + & $CMake ..\..\..\${ZLIB} -A "${Arch}" ` + -DBUILD_SHARED_LIBS="${SHARED}" ` + -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" ` + -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" ` + -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; ` + ExitOnError + & $CMake --build . --config ${Config} --verbose; ExitOnError + & $CMake --build . --config ${Config} --target install --verbose; ` + ExitOnError + # Patch up zlib's resulting names when built with --config Debug. + if ("${Config}" -eq "Debug") { + if ("${Type}" -eq "Dynamic") { + Copy-Item "${PREFIX}/lib/zlibd.lib" ` + -Destination "${PREFIX}/lib/zlib.lib" -Force + Copy-Item "${PREFIX}/bin/zlibd1.dll" ` + -Destination "${PREFIX}/bin/zlib1.dll" -Force + } else { + Copy-Item "${PREFIX}/lib/zlibstaticd.lib" ` + -Destination "${PREFIX}/lib/zlib.lib" -Force + } } - - Push-Location .\${ZLIB} - & $CMake ..\..\..\${ZLIB} -G "${GENERATOR}" -A "${ARCH}" ` - -DBUILD_SHARED_LIBS="${SHARED}" ` - -DCMAKE_C_FLAGS_RELEASE="${FLAGS} /Zi /guard:cf /sdl" ` - -DCMAKE_INSTALL_PREFIX="${OUTPUT}" "${CMAKE_SYSTEM_VERSION}" - & $CMake --build . --config Release --verbose - & $CMake --build . --config Release --target install --verbose +} catch { + throw "Failed to build zlib" +} finally { Pop-Location +} - & $CMake ..\..\.. -G "${GENERATOR}" -A "${ARCH}" ` - -DBUILD_SHARED_LIBS="${SHARED}" ` - -DCBOR_INCLUDE_DIRS="${OUTPUT}\include" ` - -DCBOR_LIBRARY_DIRS="${OUTPUT}\lib" ` - -DZLIB_INCLUDE_DIRS="${OUTPUT}\include" ` - -DZLIB_LIBRARY_DIRS="${OUTPUT}\lib" ` - -DCRYPTO_INCLUDE_DIRS="${OUTPUT}\include" ` - -DCRYPTO_LIBRARY_DIRS="${OUTPUT}\lib" ` - -DCMAKE_C_FLAGS_RELEASE="${FLAGS} /Zi /guard:cf /sdl ${Fido2Flags}" ` - -DCMAKE_INSTALL_PREFIX="${OUTPUT}" "${CMAKE_SYSTEM_VERSION}" - & $CMake --build . --config Release --verbose - & $CMake --build . --config Release --target install --verbose +# Build libfido2. +Push-Location ${STAGE} +try { + & $CMake ..\..\.. -A "${Arch}" ` + -DCMAKE_BUILD_TYPE="${Config}" ` + -DBUILD_SHARED_LIBS="${SHARED}" ` + -DCBOR_INCLUDE_DIRS="${PREFIX}\include" ` + -DCBOR_LIBRARY_DIRS="${PREFIX}\lib" ` + -DCBOR_BIN_DIRS="${PREFIX}\bin" ` + -DZLIB_INCLUDE_DIRS="${PREFIX}\include" ` + -DZLIB_LIBRARY_DIRS="${PREFIX}\lib" ` + -DZLIB_BIN_DIRS="${PREFIX}\bin" ` + -DCRYPTO_INCLUDE_DIRS="${PREFIX}\include" ` + -DCRYPTO_LIBRARY_DIRS="${PREFIX}\lib" ` + -DCRYPTO_BIN_DIRS="${PREFIX}\bin" ` + -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG} ${Fido2Flags}" ` + -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE} ${Fido2Flags}" ` + -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; ` + ExitOnError + & $CMake --build . --config ${Config} --verbose; ExitOnError + & $CMake --build . --config ${Config} --target install --verbose; ` + ExitOnError + # Copy DLLs. if ("${SHARED}" -eq "ON") { - "cbor.dll", "crypto-46.dll", "zlib1.dll" | %{ Copy-Item "${OUTPUT}\bin\$_" ` - -Destination "examples\Release" } + "cbor.dll", "crypto-46.dll", "zlib1.dll" | ` + %{ Copy-Item "${PREFIX}\bin\$_" ` + -Destination "examples\${Config}" } } +} catch { + throw "Failed to build libfido2" +} finally { + Pop-Location } - -Function Package-Headers() { - Copy-Item "${OUTPUT}\64\dynamic\include" -Destination "${OUTPUT}\pkg" ` - -Recurse -ErrorAction Stop -} - -Function Package-Dynamic(${SRC}, ${DEST}) { - Copy-Item "${SRC}\bin\cbor.dll" "${DEST}" -ErrorAction Stop - Copy-Item "${SRC}\lib\cbor.lib" "${DEST}" -ErrorAction Stop - Copy-Item "${SRC}\bin\zlib1.dll" "${DEST}" -ErrorAction Stop - Copy-Item "${SRC}\lib\zlib.lib" "${DEST}" -ErrorAction Stop - Copy-Item "${SRC}\bin\crypto-46.dll" "${DEST}" -ErrorAction Stop - Copy-Item "${SRC}\lib\crypto-46.lib" "${DEST}" -ErrorAction Stop - Copy-Item "${SRC}\bin\fido2.dll" "${DEST}" -ErrorAction Stop - Copy-Item "${SRC}\lib\fido2.lib" "${DEST}" -ErrorAction Stop -} - -Function Package-Static(${SRC}, ${DEST}) { - Copy-Item "${SRC}/lib/cbor.lib" "${DEST}" -ErrorAction Stop - Copy-Item "${SRC}/lib/zlib.lib" "${DEST}" -ErrorAction Stop - Copy-Item "${SRC}/lib/crypto-46.lib" "${DEST}" -ErrorAction Stop - Copy-Item "${SRC}/lib/fido2_static.lib" "${DEST}/fido2.lib" ` - -ErrorAction Stop -} - -Function Package-PDBs(${SRC}, ${DEST}) { - Copy-Item "${SRC}\${LIBRESSL}\crypto\crypto.dir\Release\vc142.pdb" ` - "${DEST}\crypto-46.pdb" -ErrorAction Stop - Copy-Item "${SRC}\${LIBCBOR}\src\cbor.dir\Release\vc142.pdb" ` - "${DEST}\cbor.pdb" -ErrorAction Stop - Copy-Item "${SRC}\${ZLIB}\zlib.dir\Release\vc142.pdb" ` - "${DEST}\zlib.pdb" -ErrorAction Stop - Copy-Item "${SRC}\src\fido2_shared.dir\Release\vc142.pdb" ` - "${DEST}\fido2.pdb" -ErrorAction Stop -} - -Function Package-Tools(${SRC}, ${DEST}) { - Copy-Item "${SRC}\tools\Release\fido2-assert.exe" ` - "${DEST}\fido2-assert.exe" -ErrorAction stop - Copy-Item "${SRC}\tools\Release\fido2-cred.exe" ` - "${DEST}\fido2-cred.exe" -ErrorAction stop - Copy-Item "${SRC}\tools\Release\fido2-token.exe" ` - "${DEST}\fido2-token.exe" -ErrorAction stop -} - -Push-Location ${BUILD}\64\dynamic -Build ${OUTPUT}\64\dynamic "Visual Studio 16 2019" "x64" "ON" "/MD" -Pop-Location -Push-Location ${BUILD}\32\dynamic -Build ${OUTPUT}\32\dynamic "Visual Studio 16 2019" "Win32" "ON" "/MD" -Pop-Location - -Push-Location ${BUILD}\64\static -Build ${OUTPUT}\64\static "Visual Studio 16 2019" "x64" "OFF" "/MT" -Pop-Location -Push-Location ${BUILD}\32\static -Build ${OUTPUT}\32\static "Visual Studio 16 2019" "Win32" "OFF" "/MT" -Pop-Location - -Package-Headers - -Package-Dynamic ${OUTPUT}\64\dynamic ${OUTPUT}\pkg\Win64\Release\v142\dynamic -Package-PDBs ${BUILD}\64\dynamic ${OUTPUT}\pkg\Win64\Release\v142\dynamic -Package-Tools ${BUILD}\64\dynamic ${OUTPUT}\pkg\Win64\Release\v142\dynamic - -Package-Dynamic ${OUTPUT}\32\dynamic ${OUTPUT}\pkg\Win32\Release\v142\dynamic -Package-PDBs ${BUILD}\32\dynamic ${OUTPUT}\pkg\Win32\Release\v142\dynamic -Package-Tools ${BUILD}\32\dynamic ${OUTPUT}\pkg\Win32\Release\v142\dynamic - -Package-Static ${OUTPUT}\64\static ${OUTPUT}\pkg\Win64\Release\v142\static -Package-Static ${OUTPUT}\32\static ${OUTPUT}\pkg\Win32\Release\v142\static diff --git a/contrib/libfido2/windows/const.ps1 b/contrib/libfido2/windows/const.ps1 new file mode 100644 index 000000000000..6d2a8189d362 --- /dev/null +++ b/contrib/libfido2/windows/const.ps1 @@ -0,0 +1,42 @@ +# Copyright (c) 2021 Yubico AB. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +# LibreSSL coordinates. +New-Variable -Name 'LIBRESSL_URL' ` + -Value 'https://fastly.cdn.openbsd.org/pub/OpenBSD/LibreSSL' ` + -Option Constant +New-Variable -Name 'LIBRESSL' -Value 'libressl-3.3.4' -Option Constant + +# libcbor coordinates. +New-Variable -Name 'LIBCBOR' -Value 'libcbor-0.8.0' -Option Constant +New-Variable -Name 'LIBCBOR_BRANCH' -Value 'v0.8.0' -Option Constant +New-Variable -Name 'LIBCBOR_GIT' -Value 'https://github.com/pjk/libcbor' ` + -Option Constant + +# zlib coordinates. +New-Variable -Name 'ZLIB' -Value 'zlib-1.2.11' -Option Constant +New-Variable -Name 'ZLIB_BRANCH' -Value 'v1.2.11' -Option Constant +New-Variable -Name 'ZLIB_GIT' -Value 'https://github.com/madler/zlib' ` + -Option Constant + +# Work directories. +New-Variable -Name 'BUILD' -Value "$PSScriptRoot\..\build" -Option Constant +New-Variable -Name 'OUTPUT' -Value "$PSScriptRoot\..\output" -Option Constant + +# Prefixes. +New-Variable -Name 'STAGE' -Value "${BUILD}\${Arch}\${Type}" -Option Constant +New-Variable -Name 'PREFIX' -Value "${OUTPUT}\${Arch}\${Type}" -Option Constant + +# Build flags. +if ("${Type}" -eq "dynamic") { + New-Variable -Name 'RUNTIME' -Value '/MD' -Option Constant + New-Variable -Name 'SHARED' -Value 'ON' -Option Constant +} else { + New-Variable -Name 'RUNTIME' -Value '/MT' -Option Constant + New-Variable -Name 'SHARED' -Value 'OFF' -Option Constant +} +New-Variable -Name 'CFLAGS_DEBUG' -Value "${RUNTIME}d /Zi /guard:cf /sdl" ` + -Option Constant +New-Variable -Name 'CFLAGS_RELEASE' -Value "${RUNTIME} /Zi /guard:cf /sdl" ` + -Option Constant diff --git a/contrib/libfido2/windows/release.ps1 b/contrib/libfido2/windows/release.ps1 new file mode 100644 index 000000000000..32e88e256274 --- /dev/null +++ b/contrib/libfido2/windows/release.ps1 @@ -0,0 +1,84 @@ +# Copyright (c) 2021 Yubico AB. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +$ErrorActionPreference = "Stop" +$Architectures = @('x64', 'Win32', 'ARM64', 'ARM') +$InstallPrefixes = @('Win64', 'Win32', 'ARM64', 'ARM') +$Types = @('dynamic', 'static') +$Config = 'Release' +$LibCrypto = '46' +$SDK = '142' + +. "$PSScriptRoot\const.ps1" + +foreach ($Arch in $Architectures) { + foreach ($Type in $Types) { + ./build.ps1 -Arch ${Arch} -Type ${Type} -Config ${Config} + } +} + +foreach ($InstallPrefix in $InstallPrefixes) { + foreach ($Type in $Types) { + New-Item -Type Directory ` + "${OUTPUT}/pkg/${InstallPrefix}/${Config}/v${SDK}/${Type}" + } +} + +Function Package-Headers() { + Copy-Item "${OUTPUT}\x64\dynamic\include" -Destination "${OUTPUT}\pkg" ` + -Recurse -ErrorAction Stop +} + +Function Package-Dynamic(${SRC}, ${DEST}) { + Copy-Item "${SRC}\bin\cbor.dll" "${DEST}" + Copy-Item "${SRC}\lib\cbor.lib" "${DEST}" + Copy-Item "${SRC}\bin\zlib1.dll" "${DEST}" + Copy-Item "${SRC}\lib\zlib.lib" "${DEST}" + Copy-Item "${SRC}\bin\crypto-${LibCrypto}.dll" "${DEST}" + Copy-Item "${SRC}\lib\crypto-${LibCrypto}.lib" "${DEST}" + Copy-Item "${SRC}\bin\fido2.dll" "${DEST}" + Copy-Item "${SRC}\lib\fido2.lib" "${DEST}" +} + +Function Package-Static(${SRC}, ${DEST}) { + Copy-Item "${SRC}/lib/cbor.lib" "${DEST}" + Copy-Item "${SRC}/lib/zlib.lib" "${DEST}" + Copy-Item "${SRC}/lib/crypto-${LibCrypto}.lib" "${DEST}" + Copy-Item "${SRC}/lib/fido2_static.lib" "${DEST}/fido2.lib" +} + +Function Package-PDBs(${SRC}, ${DEST}) { + Copy-Item "${SRC}\${LIBRESSL}\crypto\crypto.dir\${Config}\vc${SDK}.pdb" ` + "${DEST}\crypto-${LibCrypto}.pdb" + Copy-Item "${SRC}\${LIBCBOR}\src\cbor.dir\${Config}\vc${SDK}.pdb" ` + "${DEST}\cbor.pdb" + Copy-Item "${SRC}\${ZLIB}\zlib.dir\${Config}\vc${SDK}.pdb" ` + "${DEST}\zlib.pdb" + Copy-Item "${SRC}\src\fido2_shared.dir\${Config}\vc${SDK}.pdb" ` + "${DEST}\fido2.pdb" +} + +Function Package-Tools(${SRC}, ${DEST}) { + Copy-Item "${SRC}\tools\${Config}\fido2-assert.exe" ` + "${DEST}\fido2-assert.exe" + Copy-Item "${SRC}\tools\${Config}\fido2-cred.exe" ` + "${DEST}\fido2-cred.exe" + Copy-Item "${SRC}\tools\${Config}\fido2-token.exe" ` + "${DEST}\fido2-token.exe" +} + +Package-Headers + +for ($i = 0; $i -lt $Architectures.Length; $i++) { + $Arch = $Architectures[$i] + $InstallPrefix = $InstallPrefixes[$i] + Package-Dynamic "${OUTPUT}\${Arch}\dynamic" ` + "${OUTPUT}\pkg\${InstallPrefix}\${Config}\v${SDK}\dynamic" + Package-PDBs "${BUILD}\${Arch}\dynamic" ` + "${OUTPUT}\pkg\${InstallPrefix}\${Config}\v${SDK}\dynamic" + Package-Tools "${BUILD}\${Arch}\dynamic" ` + "${OUTPUT}\pkg\${InstallPrefix}\${Config}\v${SDK}\dynamic" + Package-Static "${OUTPUT}\${Arch}\static" ` + "${OUTPUT}\pkg\${InstallPrefix}\${Config}\v${SDK}\static" +} diff --git a/lib/libfido2/Makefile b/lib/libfido2/Makefile index edf737b9dafc..9a0e4a57bd9a 100644 --- a/lib/libfido2/Makefile +++ b/lib/libfido2/Makefile @@ -32,7 +32,11 @@ SRCS+= log.c SRCS+= pin.c SRCS+= random.c SRCS+= reset.c +SRCS+= rs1.c SRCS+= rs256.c +SRCS+= time.c +SRCS+= tpm.c +SRCS+= types.c SRCS+= u2f.c SRCS+= openbsd-compat/freezero.c |