diff --git a/contrib/libfido2/CMakeLists.txt b/contrib/libfido2/CMakeLists.txt index d775a98c5b48..11a51ac5a645 100644 --- a/contrib/libfido2/CMakeLists.txt +++ b/contrib/libfido2/CMakeLists.txt @@ -1,415 +1,428 @@ # 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. # detect AppleClang; needs to come before project() cmake_policy(SET CMP0025 NEW) project(libfido2 C) cmake_minimum_required(VERSION 3.0) # Set PIE flags for POSITION_INDEPENDENT_CODE targets, added in CMake 3.14. if(POLICY CMP0083) - cmake_policy(SET CMP0083 NEW) + cmake_policy(SET CMP0083 NEW) endif() include(CheckCCompilerFlag) include(CheckFunctionExists) include(CheckLibraryExists) include(CheckSymbolExists) include(CheckIncludeFiles) include(CheckTypeSize) include(GNUInstallDirs) include(CheckPIESupported OPTIONAL RESULT_VARIABLE CHECK_PIE_SUPPORTED) if(CHECK_PIE_SUPPORTED) - check_pie_supported(LANGUAGES C) + check_pie_supported(LANGUAGES C) endif() set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_COLOR_MAKEFILE OFF) set(CMAKE_VERBOSE_MAKEFILE ON) set(FIDO_MAJOR "1") -set(FIDO_MINOR "9") +set(FIDO_MINOR "10") set(FIDO_PATCH "0") set(FIDO_VERSION ${FIDO_MAJOR}.${FIDO_MINOR}.${FIDO_PATCH}) option(BUILD_EXAMPLES "Build example programs" ON) option(BUILD_MANPAGES "Build man pages" ON) option(BUILD_SHARED_LIBS "Build the shared library" ON) option(BUILD_STATIC_LIBS "Build the static library" ON) option(BUILD_TOOLS "Build tool programs" ON) option(FUZZ "Enable fuzzing instrumentation" OFF) option(LIBFUZZER "Build libfuzzer harnesses" OFF) option(USE_HIDAPI "Use hidapi as the HID backend" OFF) -option(USE_WINHELLO "Abstract Windows Hello as a FIDO device" OFF) -option(NFC_LINUX "Experimental NFC support on Linux" OFF) +option(USE_WINHELLO "Abstract Windows Hello as a FIDO device" ON) +option(NFC_LINUX "Enable NFC support on Linux" ON) add_definitions(-D_FIDO_MAJOR=${FIDO_MAJOR}) add_definitions(-D_FIDO_MINOR=${FIDO_MINOR}) add_definitions(-D_FIDO_PATCH=${FIDO_PATCH}) -if(CYGWIN OR MSYS) +if(CYGWIN OR MSYS OR MINGW) set(WIN32 1) - add_definitions(-DWINVER=0x0a00) endif() if(WIN32) add_definitions(-DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=0x0600) endif() if(APPLE) set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") endif() if(NOT MSVC) set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_POSIX_C_SOURCE=200809L") set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_BSD_SOURCE") if(APPLE) 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 ON) set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_GNU_SOURCE") set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_DEFAULT_SOURCE") elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "MidnightBSD") set(FIDO_CFLAGS "${FIDO_CFLAGS} -D__BSD_VISIBLE=1") + elseif(CMAKE_SYSTEM_NAME STREQUAL "NetBSD") + set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_NETBSD_SOURCE") endif() set(FIDO_CFLAGS "${FIDO_CFLAGS} -std=c99") set(CMAKE_C_FLAGS "${FIDO_CFLAGS} ${CMAKE_C_FLAGS}") endif() check_c_compiler_flag("-Wshorten-64-to-32" HAVE_SHORTEN_64_TO_32) 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) check_include_files(err.h HAVE_ERR_H) 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_symbol_exists(arc4random_buf stdlib.h HAVE_ARC4RANDOM_BUF) check_symbol_exists(clock_gettime time.h HAVE_CLOCK_GETTIME) check_symbol_exists(explicit_bzero string.h HAVE_EXPLICIT_BZERO) check_symbol_exists(freezero stdlib.h HAVE_FREEZERO) check_symbol_exists(getline stdio.h HAVE_GETLINE) check_symbol_exists(getopt unistd.h HAVE_GETOPT) check_symbol_exists(getpagesize unistd.h HAVE_GETPAGESIZE) 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(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_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) try_compile(HAVE_POSIX_IOCTL "${CMAKE_CURRENT_BINARY_DIR}/posix_ioctl_check.o" "${CMAKE_CURRENT_SOURCE_DIR}/openbsd-compat/posix_ioctl_check.c" COMPILE_DEFINITIONS "-Werror -Woverflow -Wsign-conversion") list(APPEND CHECK_VARIABLES HAVE_ARC4RANDOM_BUF HAVE_CBOR_H HAVE_CLOCK_GETTIME HAVE_ENDIAN_H HAVE_ERR_H HAVE_FREEZERO HAVE_GETLINE HAVE_GETOPT HAVE_GETPAGESIZE HAVE_GETRANDOM HAVE_MEMSET_S HAVE_OPENSSLV_H HAVE_POSIX_IOCTL HAVE_READPASSPHRASE HAVE_RECALLOCARRAY HAVE_SIGNAL_H HAVE_STRLCAT HAVE_STRLCPY HAVE_STRSEP HAVE_SYSCONF HAVE_SYS_RANDOM_H HAVE_TIMESPECSUB HAVE_TIMINGSAFE_BCMP HAVE_UNISTD_H ) foreach(v ${CHECK_VARIABLES}) if (${v}) add_definitions(-D${v}) endif() endforeach() if(HAVE_EXPLICIT_BZERO AND NOT LIBFUZZER) add_definitions(-DHAVE_EXPLICIT_BZERO) endif() if(UNIX) add_definitions(-DHAVE_DEV_URANDOM) endif() if(MSVC) if((NOT CBOR_INCLUDE_DIRS) OR (NOT CBOR_LIBRARY_DIRS) OR (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(CRYPTO_LIBRARIES crypto-47) 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; + "C4201" # nonstandard extension used: nameless struct/union; "C4204" # nonstandard extension used: non-constant aggregate # initializer; "C4706" # assignment within conditional expression; "C4996" # The POSIX name for this item is deprecated. Instead, # use the ISO C and C++ conformant name; "C6287" # redundant code: the left and right subexpressions are identical ) # The construction in the following 3 lines was taken from LibreSSL's # CMakeLists.txt. string(REPLACE "C" " -wd" MSVC_DISABLED_WARNINGS_STR ${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} /Od /Z7 /guard:cf /sdl /RTCcsu") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Zi /guard:cf /sdl") - add_definitions(-DUSE_WINHELLO) - set(USE_WINHELLO ON) + if(USE_WINHELLO) + add_definitions(-DUSE_WINHELLO) + endif() + set(NFC_LINUX OFF) else() include(FindPkgConfig) pkg_search_module(CBOR libcbor) pkg_search_module(CRYPTO libcrypto) pkg_search_module(ZLIB zlib) if(NOT CBOR_FOUND AND NOT HAVE_CBOR_H) message(FATAL_ERROR "could not find libcbor") endif() if(NOT CRYPTO_FOUND AND NOT HAVE_OPENSSLV_H) message(FATAL_ERROR "could not find libcrypto") endif() if(NOT ZLIB_FOUND) message(FATAL_ERROR "could not find zlib") endif() set(CBOR_LIBRARIES "cbor") set(CRYPTO_LIBRARIES "crypto") if(CMAKE_SYSTEM_NAME STREQUAL "Linux") pkg_search_module(UDEV libudev REQUIRED) set(UDEV_NAME "udev") # If using hidapi, use hidapi-hidraw. set(HIDAPI_SUFFIX -hidraw) if(NOT HAVE_CLOCK_GETTIME) # Look for clock_gettime in librt. check_library_exists(rt clock_gettime "time.h" HAVE_CLOCK_GETTIME) if (HAVE_CLOCK_GETTIME) add_definitions(-DHAVE_CLOCK_GETTIME) set(BASE_LIBRARIES ${BASE_LIBRARIES} rt) endif() endif() + else() + set(NFC_LINUX OFF) endif() if(MINGW) # MinGW is stuck with a flavour of C89. add_definitions(-DFIDO_NO_DIAGNOSTIC) add_definitions(-DWC_ERR_INVALID_CHARS=0x80) add_compile_options(-Wno-unused-parameter) endif() if(USE_HIDAPI) add_definitions(-DUSE_HIDAPI) pkg_search_module(HIDAPI hidapi${HIDAPI_SUFFIX} REQUIRED) set(HIDAPI_LIBRARIES hidapi${HIDAPI_SUFFIX}) endif() - if(FUZZ) - set(NFC_LINUX ON) - endif() - if(NFC_LINUX) add_definitions(-DNFC_LINUX) endif() + if(WIN32) + if(USE_WINHELLO) + add_definitions(-DUSE_WINHELLO) + endif() + else() + set(USE_WINHELLO OFF) + endif() + add_compile_options(-Wall) add_compile_options(-Wextra) add_compile_options(-Werror) add_compile_options(-Wshadow) add_compile_options(-Wcast-qual) add_compile_options(-Wwrite-strings) add_compile_options(-Wmissing-prototypes) add_compile_options(-Wbad-function-cast) add_compile_options(-pedantic) add_compile_options(-pedantic-errors) + if(WIN32) + add_compile_options(-Wno-type-limits) + add_compile_options(-Wno-cast-function-type) + endif() if(HAVE_SHORTEN_64_TO_32) add_compile_options(-Wshorten-64-to-32) endif() if(HAVE_STACK_PROTECTOR_ALL) add_compile_options(-fstack-protector-all) endif() set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g2") 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() endif() # Avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 if(CMAKE_COMPILER_IS_GNUCC) add_compile_options(-Wno-unused-result) endif() # Decide which keyword to use for thread-local storage. if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang") set(TLS "__thread") elseif(WIN32) set(TLS "__declspec(thread)") endif() add_definitions(-DTLS=${TLS}) # export list if(APPLE AND (CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")) # clang + lld string(CONCAT CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} " -exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/src/export.llvm") elseif(NOT MSVC) # clang/gcc + gnu ld if(FUZZ) string(CONCAT CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} - " -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/fuzz/export.gnu") + " -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/fuzz/export.gnu") else() string(CONCAT CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} - " -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/export.gnu") + " -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/export.gnu") endif() if(NOT WIN32) string(CONCAT CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} " -Wl,-z,noexecstack -Wl,-z,relro,-z,now") string(CONCAT CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} " -Wl,-z,noexecstack -Wl,-z,relro,-z,now") if(FUZZ) file(STRINGS fuzz/wrapped.sym WRAPPED_SYMBOLS) foreach(s ${WRAPPED_SYMBOLS}) string(CONCAT CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} " -Wl,--wrap=${s}") endforeach() endif() endif() else() string(CONCAT CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} " /def:\"${CMAKE_CURRENT_SOURCE_DIR}/src/export.msvc\"") endif() include_directories(${CMAKE_SOURCE_DIR}/src) include_directories(${CBOR_INCLUDE_DIRS}) include_directories(${CRYPTO_INCLUDE_DIRS}) include_directories(${HIDAPI_INCLUDE_DIRS}) include_directories(${UDEV_INCLUDE_DIRS}) include_directories(${ZLIB_INCLUDE_DIRS}) link_directories(${CBOR_LIBRARY_DIRS}) link_directories(${CRYPTO_LIBRARY_DIRS}) link_directories(${HIDAPI_LIBRARY_DIRS}) link_directories(${UDEV_LIBRARY_DIRS}) link_directories(${ZLIB_LIBRARY_DIRS}) message(STATUS "BASE_LIBRARIES: ${BASE_LIBRARIES}") message(STATUS "BUILD_EXAMPLES: ${BUILD_EXAMPLES}") message(STATUS "BUILD_MANPAGES: ${BUILD_MANPAGES}") message(STATUS "BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}") message(STATUS "BUILD_STATIC_LIBS: ${BUILD_STATIC_LIBS}") message(STATUS "BUILD_TOOLS: ${BUILD_TOOLS}") message(STATUS "CBOR_INCLUDE_DIRS: ${CBOR_INCLUDE_DIRS}") message(STATUS "CBOR_LIBRARIES: ${CBOR_LIBRARIES}") message(STATUS "CBOR_LIBRARY_DIRS: ${CBOR_LIBRARY_DIRS}") message(STATUS "CBOR_VERSION: ${CBOR_VERSION}") message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}") message(STATUS "CMAKE_C_COMPILER_ID: ${CMAKE_C_COMPILER_ID}") message(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") message(STATUS "CMAKE_INSTALL_LIBDIR: ${CMAKE_INSTALL_LIBDIR}") message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") message(STATUS "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}") message(STATUS "CMAKE_SYSTEM_VERSION: ${CMAKE_SYSTEM_VERSION}") message(STATUS "CRYPTO_INCLUDE_DIRS: ${CRYPTO_INCLUDE_DIRS}") message(STATUS "CRYPTO_LIBRARIES: ${CRYPTO_LIBRARIES}") message(STATUS "CRYPTO_LIBRARY_DIRS: ${CRYPTO_LIBRARY_DIRS}") message(STATUS "CRYPTO_VERSION: ${CRYPTO_VERSION}") message(STATUS "FIDO_VERSION: ${FIDO_VERSION}") message(STATUS "FUZZ: ${FUZZ}") message(STATUS "ZLIB_INCLUDE_DIRS: ${ZLIB_INCLUDE_DIRS}") message(STATUS "ZLIB_LIBRARIES: ${ZLIB_LIBRARIES}") message(STATUS "ZLIB_LIBRARY_DIRS: ${ZLIB_LIBRARY_DIRS}") message(STATUS "ZLIB_VERSION: ${ZLIB_VERSION}") if(USE_HIDAPI) message(STATUS "HIDAPI_INCLUDE_DIRS: ${HIDAPI_INCLUDE_DIRS}") message(STATUS "HIDAPI_LIBRARIES: ${HIDAPI_LIBRARIES}") message(STATUS "HIDAPI_LIBRARY_DIRS: ${HIDAPI_LIBRARY_DIRS}") message(STATUS "HIDAPI_VERSION: ${HIDAPI_VERSION}") endif() message(STATUS "LIBFUZZER: ${LIBFUZZER}") message(STATUS "TLS: ${TLS}") message(STATUS "UDEV_INCLUDE_DIRS: ${UDEV_INCLUDE_DIRS}") message(STATUS "UDEV_LIBRARIES: ${UDEV_LIBRARIES}") message(STATUS "UDEV_LIBRARY_DIRS: ${UDEV_LIBRARY_DIRS}") message(STATUS "UDEV_RULES_DIR: ${UDEV_RULES_DIR}") message(STATUS "UDEV_VERSION: ${UDEV_VERSION}") message(STATUS "USE_HIDAPI: ${USE_HIDAPI}") message(STATUS "USE_WINHELLO: ${USE_WINHELLO}") message(STATUS "NFC_LINUX: ${NFC_LINUX}") subdirs(src) if(BUILD_EXAMPLES) subdirs(examples) endif() if(BUILD_TOOLS) subdirs(tools) endif() if(BUILD_MANPAGES) subdirs(man) endif() if(NOT WIN32) if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT FUZZ) enable_testing() subdirs(regress) endif() if(FUZZ) subdirs(fuzz) endif() if(CMAKE_SYSTEM_NAME STREQUAL "Linux") subdirs(udev) endif() endif() diff --git a/contrib/libfido2/LICENSE b/contrib/libfido2/LICENSE index 4224f20992c0..75a03f87e3af 100644 --- a/contrib/libfido2/LICENSE +++ b/contrib/libfido2/LICENSE @@ -1,24 +1,24 @@ -Copyright (c) 2018-2021 Yubico AB. All rights reserved. +Copyright (c) 2018-2022 Yubico AB. 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. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. diff --git a/contrib/libfido2/NEWS b/contrib/libfido2/NEWS index 04cda4e0e83a..a48b685156c1 100644 --- a/contrib/libfido2/NEWS +++ b/contrib/libfido2/NEWS @@ -1,201 +1,215 @@ +* Version 1.10.0 (2022-01-17) + ** hid_osx: handle devices with paths > 511 bytes; gh#462. + ** bio: fix CTAP2 canonical CBOR encoding in fido_bio_dev_enroll_*(); gh#480. + ** winhello: fallback to GetTopWindow() if GetForegroundWindow() fails. + ** winhello: fallback to hid_win.c if webauthn.dll isn't available. + ** New API calls: + - fido_dev_info_set; + - fido_dev_io_handle; + - fido_dev_new_with_info; + - fido_dev_open_with_info. + ** Cygwin and NetBSD build fixes. + ** Documentation and reliability fixes. + ** Support for TPM 2.0 attestation of COSE_ES256 credentials. + * 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. ** Support for Windows's native webauthn API. ** Support for attestation format 'none'. ** New API calls: - fido_assert_set_clientdata; - fido_cbor_info_algorithm_cose; - fido_cbor_info_algorithm_count; - fido_cbor_info_algorithm_type; - fido_cbor_info_transports_len; - fido_cbor_info_transports_ptr; - fido_cred_set_clientdata; - fido_cred_set_id; - fido_credman_set_dev_rk; - fido_dev_is_winhello. ** fido2-token: new -Sc option to update a resident credential. ** Documentation and reliability fixes. ** HID access serialisation on Linux. * Version 1.7.0 (2021-03-29) ** New dependency on zlib. ** Fixed musl build; gh#259. ** hid_win: detect devices with vendor or product IDs > 0x7fff; gh#264. ** Support for FIDO 2.1 authenticator configuration. ** Support for FIDO 2.1 UV token permissions. ** Support for FIDO 2.1 "credBlobs" and "largeBlobs" extensions. ** New API calls: - fido_assert_blob_len; - fido_assert_blob_ptr; - fido_assert_largeblob_key_len; - fido_assert_largeblob_key_ptr; - fido_assert_set_hmac_secret; - fido_cbor_info_maxcredbloblen; - fido_cred_largeblob_key_len; - fido_cred_largeblob_key_ptr; - fido_cred_set_blob; - fido_dev_enable_entattest; - fido_dev_force_pin_change; - fido_dev_has_uv; - fido_dev_largeblob_get; - fido_dev_largeblob_get_array; - fido_dev_largeblob_remove; - fido_dev_largeblob_set; - fido_dev_largeblob_set_array; - fido_dev_set_pin_minlen; - fido_dev_set_sigmask; - fido_dev_supports_credman; - fido_dev_supports_permissions; - fido_dev_supports_uv; - fido_dev_toggle_always_uv. ** New fido_init flag to disable fido_dev_open's U2F fallback; gh#282. ** Experimental NFC support on Linux; enable with -DNFC_LINUX. * Version 1.6.0 (2020-12-22) ** Fix OpenSSL 1.0 and Cygwin builds. ** hid_linux: fix build on 32-bit systems. ** hid_osx: allow reads from spawned threads. ** Documentation and reliability fixes. ** New API calls: - fido_cred_authdata_raw_len; - fido_cred_authdata_raw_ptr; - fido_cred_sigcount; - fido_dev_get_uv_retry_count; - fido_dev_supports_credman. ** Hardened Windows build. ** Native FreeBSD and NetBSD support. ** Use CTAP2 canonical CBOR when combining hmac-secret and credProtect. * Version 1.5.0 (2020-09-01) ** hid_linux: return FIDO_OK if no devices are found. ** hid_osx: - repair communication with U2F tokens, gh#166; - reliability fixes. ** fido2-{assert,cred}: new options to explicitly toggle UP, UV. ** Support for configurable report lengths. ** New API calls: - fido_cbor_info_maxcredcntlst; - fido_cbor_info_maxcredidlen; - fido_cred_aaguid_len; - fido_cred_aaguid_ptr; - fido_dev_get_touch_begin; - fido_dev_get_touch_status. ** Use COSE_ECDH_ES256 with CTAP_CBOR_CLIENT_PIN; gh#154. ** Allow CTAP messages up to 2048 bytes; gh#171. ** Ensure we only list USB devices by default. * Version 1.4.0 (2020-04-15) ** hid_hidapi: hidapi backend; enable with -DUSE_HIDAPI=1. ** Fall back to U2F if the key claims to, but does not support FIDO2. ** FIDO2 credential protection (credprot) support. ** New API calls: - fido_cbor_info_fwversion; - fido_cred_prot; - fido_cred_set_prot; - fido_dev_set_transport_functions; - fido_set_log_handler. ** Support for FreeBSD. ** Support for C++. ** Support for MSYS. ** Fixed EdDSA and RSA self-attestation. * Version 1.3.1 (2020-02-19) ** fix zero-ing of le1 and le2 when talking to a U2F device. ** dropping sk-libfido2 middleware, please find it in the openssh tree. * Version 1.3.0 (2019-11-28) ** assert/hmac: encode public key as per spec, gh#60. ** fido2-cred: fix creation of resident keys. ** fido2-{assert,cred}: support for hmac-secret extension. ** hid_osx: detect device removal, gh#56. ** hid_osx: fix device detection in MacOS Catalina. ** New API calls: - fido_assert_set_authdata_raw; - fido_assert_sigcount; - fido_cred_set_authdata_raw; - fido_dev_cancel. ** Middleware library for use by OpenSSH. ** Support for biometric enrollment. ** Support for OpenBSD. ** Support for self-attestation. * Version 1.2.0 (released 2019-07-26) ** Credential management support. ** New API reflecting FIDO's 3-state booleans (true, false, absent): - fido_assert_set_up; - fido_assert_set_uv; - fido_cred_set_rk; - fido_cred_set_uv. ** Command-line tools for Windows. ** Documentation and reliability fixes. ** fido_{assert,cred}_set_options() are now marked as deprecated. * Version 1.1.0 (released 2019-05-08) ** MacOS: fix IOKit crash on HID read. ** Windows: fix contents of release file. ** EdDSA (Ed25519) support. ** fido_dev_make_cred: fix order of CBOR map keys. ** fido_dev_get_assert: plug memory leak when operating on U2F devices. * Version 1.0.0 (released 2019-03-21) ** Native HID support on Linux, MacOS, and Windows. ** fido2-{assert,cred}: new -u option to force U2F on dual authenticators. ** fido2-assert: support for multiple resident keys with the same RP. ** Strict checks for CTAP2 compliance on received CBOR payloads. ** Better fuzzing harnesses. ** Documentation and reliability fixes. * Version 0.4.0 (released 2019-01-07) ** fido2-assert: print the user id for resident credentials. ** Fix encoding of COSE algorithms when making a credential. ** Rework purpose of fido_cred_set_type; no ABI change. ** Minor documentation and code fixes. * Version 0.3.0 (released 2018-09-11) ** Various reliability fixes. ** Merged fuzzing instrumentation. ** Added regress tests. ** Added support for FIDO 2's hmac-secret extension. ** New API calls: - fido_assert_hmac_secret_len; - fido_assert_hmac_secret_ptr; - fido_assert_set_extensions; - fido_assert_set_hmac_salt; - fido_cred_set_extensions; - fido_dev_force_fido2. ** Support for native builds with Microsoft Visual Studio 17. * Version 0.2.0 (released 2018-06-20) ** Added command-line tools. ** Added a couple of missing get functions. * Version 0.1.1 (released 2018-06-05) ** Added documentation. ** Added OpenSSL 1.0 support. ** Minor fixes. * Version 0.1.0 (released 2018-05-18) ** First beta release. diff --git a/contrib/libfido2/README.adoc b/contrib/libfido2/README.adoc index a0e188bf8774..114cc5eed762 100644 --- a/contrib/libfido2/README.adoc +++ b/contrib/libfido2/README.adoc @@ -1,96 +1,96 @@ == libfido2 image:https://github.com/yubico/libfido2/workflows/linux/badge.svg["Linux Build Status (github actions)", link="https://github.com/Yubico/libfido2/actions"] image:https://github.com/yubico/libfido2/workflows/macos/badge.svg["macOS Build Status (github actions)", link="https://github.com/Yubico/libfido2/actions"] image:https://github.com/yubico/libfido2/workflows/windows/badge.svg["Windows Build Status (github actions)", link="https://github.com/Yubico/libfido2/actions"] image:https://github.com/yubico/libfido2/workflows/fuzzer/badge.svg["Fuzz Status (github actions)", link="https://github.com/Yubico/libfido2/actions"] image:https://oss-fuzz-build-logs.storage.googleapis.com/badges/libfido2.svg["Fuzz Status (oss-fuzz)", link="https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:libfido2"] *libfido2* provides library functionality and command-line tools to communicate with a FIDO device over USB, and to verify attestation and assertion signatures. -*libfido2* supports the FIDO U2F (CTAP 1) and FIDO 2.0 (CTAP 2) protocols. +*libfido2* supports the FIDO U2F (CTAP 1) and FIDO2 (CTAP 2) protocols. For usage, see the `examples/` directory. === License *libfido2* is licensed under the BSD 2-clause license. See the LICENSE file for the full license text. === Supported Platforms *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 https://developers.yubico.com/libfido2/Manuals/[online mirror of *libfido2*'s documentation] is also available. === Bindings * .NET: https://github.com/borrrden/Fido2Net[Fido2Net] * Go: https://github.com/keys-pub/go-libfido2[go-libfido2] * Perl: https://github.com/jacquesg/p5-FIDO-Raw[p5-FIDO-Raw] * Rust: https://github.com/PvdBerg1998/libfido2[libfido2] === Installation ==== Releases -The current release of *libfido2* is 1.9.0. Please consult Yubico's +The current release of *libfido2* is 1.10.0. Please consult Yubico's https://developers.yubico.com/libfido2/Releases[release page] for source and binary releases. ==== Ubuntu 20.04 (Focal) $ sudo apt install libfido2-1 $ sudo apt install libfido2-dev $ sudo apt install libfido2-doc Alternatively, newer versions of *libfido2* are available in Yubico's PPA. Follow the instructions for Ubuntu 18.04 (Bionic) below. ==== Ubuntu 18.04 (Bionic) $ sudo apt install software-properties-common $ sudo apt-add-repository ppa:yubico/stable $ sudo apt update $ sudo apt install libfido2-dev ==== macOS $ brew install libfido2 Or from source, on UNIX-like systems: $ cmake -B build $ make -C build $ sudo make -C build install Depending on the platform, 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] 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. For complete, OS-specific installation instructions, please refer to the `.actions/` (Linux, macOS) and `windows/` directories. On Linux, you will need to add a udev rule to be able to access the FIDO device, or run as root. For example, the udev rule may contain the following: ---- #udev rule for allowing HID access to Yubico devices for FIDO support. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", \ MODE="0664", GROUP="plugdev", ATTRS{idVendor}=="1050" ---- diff --git a/contrib/libfido2/SECURITY.md b/contrib/libfido2/SECURITY.md new file mode 100644 index 000000000000..e12a48a847ba --- /dev/null +++ b/contrib/libfido2/SECURITY.md @@ -0,0 +1,5 @@ +# Reporting libfido2 Security Issues + +To report security issues in libfido2, please contact security@yubico.com. +A PGP public key can be found at +https://www.yubico.com/support/security-advisories/issue-rating-system/. diff --git a/contrib/libfido2/examples/README.adoc b/contrib/libfido2/examples/README.adoc index bcecb22f5258..44ee52743a0d 100644 --- a/contrib/libfido2/examples/README.adoc +++ b/contrib/libfido2/examples/README.adoc @@ -1,98 +1,98 @@ = Examples === Definitions The following definitions are used in the description below: - The file system path or subsystem-specific identification string of a FIDO device. - , [oldpin] Strings passed directly in the executed command's argument vector. - The file system path of a file containing a FIDO credential ID in binary representation. - The file system path of a file containing a NIST P-256 public key in PEM format. - - A credential's associated FIDO 2.1 "largeBlob" symmetric key. + A credential's associated CTAP 2.1 "largeBlob" symmetric key. === Description The following examples are provided: - manifest Prints a list of configured FIDO devices. - info Prints information about . - reset Performs a factory reset on . - setpin [oldpin] Configures as the new PIN of . If [oldpin] is provided, the device's PIN is changed from [oldpin] to . - cred [-t ecdsa|rsa|eddsa] [-k pubkey] [-ei cred_id] [-P pin] [-T seconds] [-b blobkey] [-hruv] Creates a new credential on and verify that the credential was signed by the authenticator. The device's attestation certificate is not verified. If option -k is specified, the credential's public key is stored in . If option -i is specified, the credential ID is stored in . The -e option may be used to add to the list of excluded credentials. If option -h is specified, the hmac-secret FIDO2 extension is enabled on the generated credential. If option -r is specified, the generated credential will involve a resident key. User verification may be requested through the -v option. If option -u is specified, the credential is generated using U2F (CTAP1) instead of FIDO2 (CTAP2) commands. The -T option may be used to enforce a timeout of . If the option -b is specified, the credential's "largeBlob" key is stored in . - assert [-t ecdsa|rsa|eddsa] [-a cred_id] [-h hmac_secret] [-s hmac_salt] [-P pin] [-T seconds] [-b blobkey] [-puv] Asks for a FIDO2 assertion corresponding to [cred_id], which may be omitted for resident keys. The obtained assertion is verified using . The -p option requests that the user be present. User verification may be requested through the -v option. If option -u is specified, the assertion is generated using U2F (CTAP1) instead of FIDO2 (CTAP2) commands. If option -s is specified, a FIDO2 hmac-secret is requested from the authenticator, and the contents of are used as the salt. If option -h is specified, the resulting hmac-secret is stored in . The -T option may be used to enforce a timeout of . If the option -b specified, the credential's "largeBlob" key is stored in . - retries Get the number of PIN attempts left on before lockout. - select Enumerates available FIDO devices and, if more than one is present, simultaneously requests touch on all of them, printing information about the device touched. Debugging is possible through the use of the FIDO_DEBUG environment variable. If set, libfido2 will produce a log of its transactions with the authenticator. Additionally, an example of a WebAuthn client using libfido2 is available at https://github.com/martelletto/fido2-webauthn-client. diff --git a/contrib/libfido2/fuzz/Dockerfile b/contrib/libfido2/fuzz/Dockerfile index f175991d0462..aefe1980ada4 100644 --- a/contrib/libfido2/fuzz/Dockerfile +++ b/contrib/libfido2/fuzz/Dockerfile @@ -1,12 +1,12 @@ # 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-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 --branch v0.9.0 https://github.com/PJK/libcbor RUN git clone https://github.com/yubico/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 1a974a2bf557..ce3fee73c69c 100644 --- a/contrib/libfido2/fuzz/Makefile +++ b/contrib/libfido2/fuzz/Makefile @@ -1,81 +1,81 @@ # 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.9.1 +IMAGE := libfido2-coverage:1.10.0 RUNNER := libfido2-runner 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) MINIFY := $(foreach f,${TARGETS},/minify/${f}/corpus) REMOTE := gs://libfido2-corpus.clusterfuzz-external.appspot.com .DEFAULT_GOAL := all all: ${TARGETS} build: docker build -t ${IMAGE} - < Dockerfile run: build -docker run -it -d --name ${RUNNER} ${IMAGE} docker start ${RUNNER} sync: run tar Ccf .. - src fuzz | docker exec -i ${RUNNER} tar Cxf /libfido2 - docker exec ${RUNNER} make -C libfido2/build corpus: sync docker exec ${RUNNER} /bin/sh -c 'cd /libfido2/fuzz && rm -rf ${TARGETS}' docker exec ${RUNNER} tar Czxf /libfido2/fuzz /libfido2/fuzz/corpus.tgz ${TARGETS}: corpus sync docker exec -e LLVM_PROFILE_FILE=/profraw/$@ ${RUNNER} \ /bin/sh -c 'rm -f /profraw/$@ && /libfido2/build/fuzz/$@ \ -runs=1 /libfido2/fuzz/$@' ${MINIFY}: /minify/%/corpus: % docker exec ${RUNNER} /bin/sh -c 'rm -rf $@ && mkdir -p $@ && \ /libfido2/build/fuzz/$< -use_value_profile=1 -merge=1 $@ \ /libfido2/fuzz/$ $@ profdata: run docker exec ${RUNNER} /bin/sh -c 'rm -f /$@ && ${PROFDATA} \ merge -sparse profraw/* -o $@' report.tgz: profdata docker exec ${RUNNER} /bin/sh -c 'rm -rf /report && mkdir /report && \ ${COV} show -format=html -tab-size=8 -instr-profile=/$< \ --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 \ --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 --show-branch-summary=false -instr-profile=/$< \ /libfido2/build/src/libfido2.so /libfido2/src/*.[ch]' > $@ clean: run docker exec ${RUNNER} /bin/sh -c 'rm -rf /profraw /profdata && \ make -C /libfido2/build clean' -docker stop ${RUNNER} rm -rf ${TARGETS} ${CORPORA}: -mkdir -p $@ gsutil -q -m rsync -d -r ${REMOTE}/libFuzzer/libfido2_$(@:/corpus=) $@ corpus.tgz: ${CORPORA} tar zcf $@ ${TARGETS} .PHONY: build run sync corpus ${TARGETS} ${CORPORA} .PHONY: report.tgz summary.txt functions.txt diff --git a/contrib/libfido2/fuzz/export.gnu b/contrib/libfido2/fuzz/export.gnu index 0c712b30a429..cac142ae970e 100644 --- a/contrib/libfido2/fuzz/export.gnu +++ b/contrib/libfido2/fuzz/export.gnu @@ -1,254 +1,255 @@ { global: eddsa_pk_free; eddsa_pk_from_EVP_PKEY; eddsa_pk_from_ptr; 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; fido_assert_allow_cred; fido_assert_authdata_len; fido_assert_authdata_ptr; fido_assert_blob_len; fido_assert_blob_ptr; fido_assert_clientdata_hash_len; fido_assert_clientdata_hash_ptr; fido_assert_count; fido_assert_flags; fido_assert_free; fido_assert_hmac_secret_len; fido_assert_hmac_secret_ptr; fido_assert_id_len; fido_assert_id_ptr; fido_assert_largeblob_key_len; fido_assert_largeblob_key_ptr; fido_assert_new; 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; fido_assert_set_hmac_salt; fido_assert_set_hmac_secret; fido_assert_set_options; fido_assert_set_rp; fido_assert_set_sig; fido_assert_set_up; fido_assert_set_uv; fido_assert_sigcount; fido_assert_sig_len; fido_assert_sig_ptr; fido_assert_user_display_name; fido_assert_user_icon; fido_assert_user_id_len; fido_assert_user_id_ptr; fido_assert_user_name; fido_assert_verify; fido_bio_dev_enroll_begin; fido_bio_dev_enroll_cancel; fido_bio_dev_enroll_continue; fido_bio_dev_enroll_remove; fido_bio_dev_get_info; fido_bio_dev_get_template_array; fido_bio_dev_set_template_name; fido_bio_enroll_free; fido_bio_enroll_last_status; fido_bio_enroll_new; fido_bio_enroll_remaining_samples; fido_bio_info_free; fido_bio_info_max_samples; fido_bio_info_new; fido_bio_info_type; fido_bio_template; fido_bio_template_array_count; fido_bio_template_array_free; fido_bio_template_array_new; fido_bio_template_free; fido_bio_template_id_len; fido_bio_template_id_ptr; fido_bio_template_name; fido_bio_template_new; fido_bio_template_set_id; fido_bio_template_set_name; fido_cbor_info_aaguid_len; fido_cbor_info_aaguid_ptr; fido_cbor_info_algorithm_cose; fido_cbor_info_algorithm_count; fido_cbor_info_algorithm_type; fido_cbor_info_extensions_len; fido_cbor_info_extensions_ptr; fido_cbor_info_free; fido_cbor_info_maxmsgsiz; fido_cbor_info_maxcredbloblen; fido_cbor_info_maxcredcntlst; fido_cbor_info_maxcredidlen; fido_cbor_info_fwversion; fido_cbor_info_new; fido_cbor_info_options_len; fido_cbor_info_options_name_ptr; fido_cbor_info_options_value_ptr; fido_cbor_info_protocols_len; fido_cbor_info_protocols_ptr; 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; fido_cred_authdata_raw_ptr; fido_cred_clientdata_hash_len; fido_cred_clientdata_hash_ptr; fido_cred_display_name; fido_cred_exclude; fido_cred_flags; fido_cred_largeblob_key_len; fido_cred_largeblob_key_ptr; fido_cred_sigcount; fido_cred_fmt; fido_cred_free; fido_cred_id_len; fido_cred_id_ptr; fido_cred_aaguid_len; fido_cred_aaguid_ptr; fido_credman_del_dev_rk; fido_credman_get_dev_metadata; fido_credman_get_dev_rk; fido_credman_get_dev_rp; fido_credman_metadata_free; fido_credman_metadata_new; fido_credman_rk; fido_credman_rk_count; fido_credman_rk_existing; fido_credman_rk_free; fido_credman_rk_new; fido_credman_rk_remaining; fido_credman_rp_count; fido_credman_rp_free; fido_credman_rp_id; fido_credman_rp_id_hash_len; fido_credman_rp_id_hash_ptr; 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; 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; fido_cred_set_sig; fido_cred_set_type; fido_cred_set_user; fido_cred_set_uv; fido_cred_set_x509; fido_cred_sig_len; fido_cred_sig_ptr; fido_cred_type; fido_cred_user_id_len; fido_cred_user_id_ptr; fido_cred_user_name; fido_cred_verify; fido_cred_verify_self; fido_cred_x5c_len; fido_cred_x5c_ptr; fido_dev_build; fido_dev_cancel; fido_dev_close; fido_dev_enable_entattest; fido_dev_flags; fido_dev_force_fido2; fido_dev_force_pin_change; fido_dev_force_u2f; fido_dev_free; fido_dev_get_assert; fido_dev_get_cbor_info; fido_dev_get_retry_count; fido_dev_get_uv_retry_count; fido_dev_get_touch_begin; fido_dev_get_touch_status; fido_dev_has_pin; fido_dev_has_uv; fido_dev_info_free; fido_dev_info_manifest; fido_dev_info_manufacturer_string; fido_dev_info_new; fido_dev_info_path; fido_dev_info_product; fido_dev_info_product_string; fido_dev_info_ptr; + fido_dev_info_set; fido_dev_info_vendor; fido_dev_is_fido2; fido_dev_major; fido_dev_make_cred; fido_dev_minor; fido_dev_new; fido_dev_open; fido_dev_protocol; 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_timeout; fido_dev_set_transport_functions; fido_dev_supports_cred_prot; fido_dev_supports_credman; fido_dev_supports_permissions; fido_dev_supports_pin; fido_dev_supports_uv; fido_dev_toggle_always_uv; fido_dev_largeblob_get; fido_dev_largeblob_get_array; fido_dev_largeblob_remove; fido_dev_largeblob_set; fido_dev_largeblob_set_array; fido_hid_get_report_len; fido_hid_get_usage; fido_init; fido_nfc_rx; fido_nfc_tx; fido_nl_free; fido_nl_get_nfc_target; fido_nl_new; fido_nl_power_nfc; 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; prng_init; fuzz_clock_reset; set_netlink_io_functions; set_udev_parameters; uniform_random; local: *; }; diff --git a/contrib/libfido2/fuzz/functions.txt b/contrib/libfido2/fuzz/functions.txt index 886893b1d11d..946682d07d00 100644 --- a/contrib/libfido2/fuzz/functions.txt +++ b/contrib/libfido2/fuzz/functions.txt @@ -1,866 +1,871 @@ 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% 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% 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% 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% 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 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% 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% 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% 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% 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% 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% 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% 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% 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% 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% 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% 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% 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% 18 0 100.00% -cbor_string_copy 14 1 92.86% 18 3 83.33% +cbor_string_copy 14 0 100.00% 18 0 100.00% 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_build_uint 10 1 90.00% 9 2 77.78% 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:get_cose_alg 36 0 100.00% 38 0 100.00% 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% +TOTAL 1047 23 97.80% 1237 46 96.28% 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% 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% 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% 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% 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% fido_cred_clientdata_hash_ptr 1 0 100.00% 3 0 100.00% fido_cred_clientdata_hash_len 1 0 100.00% 3 0 100.00% fido_cred_x5c_ptr 1 0 100.00% 3 0 100.00% fido_cred_x5c_len 1 0 100.00% 3 0 100.00% fido_cred_sig_ptr 1 0 100.00% 3 0 100.00% fido_cred_sig_len 1 0 100.00% 3 0 100.00% fido_cred_authdata_ptr 1 0 100.00% 3 0 100.00% 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_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% fido_cred_user_name 1 0 100.00% 3 0 100.00% fido_cred_display_name 1 0 100.00% 3 0 100.00% fido_cred_user_id_ptr 1 0 100.00% 3 0 100.00% 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% 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% 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% 8 0 100.00% fido_credman_rk_count 1 0 100.00% 3 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% 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% 8 0 100.00% fido_credman_rp_count 1 0 100.00% 3 0 100.00% 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% 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 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% 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_dev_io_handle 1 1 0.00% 3 3 0.00% 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% fido_dev_build 1 0 100.00% 3 0 100.00% fido_dev_flags 1 0 100.00% 3 0 100.00% fido_dev_is_fido2 2 0 100.00% 3 0 100.00% fido_dev_is_winhello 2 2 0.00% 3 3 0.00% fido_dev_supports_pin 3 0 100.00% 3 0 100.00% fido_dev_has_pin 2 0 100.00% 3 0 100.00% fido_dev_supports_cred_prot 2 0 100.00% 3 0 100.00% fido_dev_supports_credman 2 0 100.00% 3 0 100.00% fido_dev_supports_uv 3 0 100.00% 3 0 100.00% fido_dev_has_uv 2 0 100.00% 3 0 100.00% 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% 7 0 100.00% fido_dev_maxmsgsize 1 0 100.00% 3 0 100.00% 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% 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% 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% +TOTAL 421 79 81.24% 491 105 78.62% File '/libfido2/src/ecdh.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- 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% 9 0 100.00% eddsa_pk_new 1 0 100.00% 3 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% 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% 7 0 100.00% es256_pk_new 1 0 100.00% 3 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% 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% 14 0 100.00% +fido_dev_info_free 9 0 100.00% 9 0 100.00% fido_dev_info_ptr 1 0 100.00% 3 0 100.00% +fido_dev_info_set 26 2 92.31% 30 3 90.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% 12 0 100.00% hid.c:get_key_val 6 0 100.00% 18 0 100.00% +hid.c:fido_dev_info_reset 1 0 100.00% 6 0 100.00% ------------------------------------------------------------------------------------------------------------------- -TOTAL 60 0 100.00% 114 0 100.00% +TOTAL 87 2 97.70% 145 3 97.93% File '/libfido2/src/hid_linux.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- 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% 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% 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% 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% 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% fido_cbor_info_extensions_len 1 0 100.00% 3 0 100.00% fido_cbor_info_transports_ptr 1 0 100.00% 3 0 100.00% fido_cbor_info_transports_len 1 0 100.00% 3 0 100.00% fido_cbor_info_aaguid_ptr 1 0 100.00% 3 0 100.00% fido_cbor_info_aaguid_len 1 0 100.00% 3 0 100.00% fido_cbor_info_options_name_ptr 1 0 100.00% 3 0 100.00% fido_cbor_info_options_value_ptr 1 0 100.00% 3 0 100.00% fido_cbor_info_options_len 1 0 100.00% 3 0 100.00% fido_cbor_info_maxcredbloblen 1 0 100.00% 3 0 100.00% fido_cbor_info_maxmsgsiz 1 0 100.00% 3 0 100.00% fido_cbor_info_maxcredcntlst 1 0 100.00% 3 0 100.00% fido_cbor_info_maxcredidlen 1 0 100.00% 3 0 100.00% fido_cbor_info_fwversion 1 0 100.00% 3 0 100.00% 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% 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% 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% 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% 38 0 100.00% File '/libfido2/src/largeblob.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- 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_set 27 0 100.00% 36 0 100.00% 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% 21 0 100.00% largeblob.c:largeblob_new 1 0 100.00% 3 0 100.00% 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% +TOTAL 513 19 96.30% 684 43 93.71% 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% 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% 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% 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% 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% 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% 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% 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% 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% 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% 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% 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% 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% 43 0 100.00% fido_nfc_rx 8 1 87.50% 13 3 76.92% 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% 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% 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% 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% 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% 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% 495 3 99.39% File '/libfido2/src/random.c': Name Regions Miss Cover Lines Miss Cover --------------------------------------------------------------------------------------------------------------------- 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% 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_verify_sig 20 0 100.00% 30 0 100.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% +TOTAL 25 0 100.00% 39 0 100.00% File '/libfido2/src/rs256.c': Name Regions Miss Cover Lines Miss Cover --------------------------------------------------------------------------------------------------------------------- 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% 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% +fido_get_signed_hash_tpm 25 0 100.00% 39 0 100.00% +tpm.c:check_es256_pubarea 18 0 100.00% 30 0 100.00% +tpm.c:bswap_es256_pubarea 1 0 100.00% 12 0 100.00% +tpm.c:check_rs256_pubarea 16 0 100.00% 28 0 100.00% +tpm.c:bswap_rs256_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% +TOTAL 100 0 100.00% 194 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 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_hid.c b/contrib/libfido2/fuzz/fuzz_hid.c index 556e62ac4cd3..eaf00dc92de8 100644 --- a/contrib/libfido2/fuzz/fuzz_hid.c +++ b/contrib/libfido2/fuzz/fuzz_hid.c @@ -1,229 +1,238 @@ /* * 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. */ #include #include #include #include #include #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 *); extern void set_udev_parameters(const char *, const struct blob *); struct param { int seed; char uevent[MAXSTR]; struct blob report_descriptor; struct blob netlink_wiredata; }; /* * Sample HID report descriptor from the FIDO HID interface of a YubiKey 5. */ static const uint8_t dummy_report_descriptor[] = { 0x06, 0xd0, 0xf1, 0x09, 0x01, 0xa1, 0x01, 0x09, 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x40, 0x81, 0x02, 0x09, 0x21, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x40, 0x91, 0x02, 0xc0 }; /* * Sample uevent file from a Yubico Security Key. */ static const char dummy_uevent[] = "DRIVER=hid-generic\n" "HID_ID=0003:00001050:00000120\n" "HID_NAME=Yubico Security Key by Yubico\n" "HID_PHYS=usb-0000:00:14.0-3/input0\n" "HID_UNIQ=\n" "MODALIAS=hid:b0003g0001v00001050p00000120\n"; struct param * unpack(const uint8_t *ptr, size_t len) { cbor_item_t *item = NULL, **v; struct cbor_load_result cbor; struct param *p; int ok = -1; if ((p = calloc(1, sizeof(*p))) == NULL || (item = cbor_load(ptr, len, &cbor)) == NULL || cbor.read != len || cbor_isa_array(item) == false || cbor_array_is_definite(item) == false || 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[3], &p->netlink_wiredata) < 0) goto fail; ok = 0; fail: if (ok < 0) { free(p); p = NULL; } if (item) cbor_decref(&item); return p; } size_t pack(uint8_t *ptr, size_t len, const struct param *p) { 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(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[3] = pack_blob(&p->netlink_wiredata)) == NULL) goto fail; for (size_t i = 0; i < 4; i++) if (cbor_array_push(array, argv[i]) == false) goto fail; if ((cbor_len = cbor_serialize_alloc(array, &cbor, &cbor_alloc_len)) > len) { cbor_len = 0; goto fail; } memcpy(ptr, cbor, cbor_len); fail: for (size_t i = 0; i < 4; i++) if (argv[i]) cbor_decref(&argv[i]); if (array) cbor_decref(&array); free(cbor); return cbor_len; } size_t pack_dummy(uint8_t *ptr, size_t len) { struct param dummy; uint8_t blob[4096]; size_t blob_len; memset(&dummy, 0, sizeof(dummy)); dummy.report_descriptor.len = sizeof(dummy_report_descriptor); 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) blob_len = len; memcpy(ptr, blob, blob_len); return blob_len; } static void get_usage(const struct param *p) { uint32_t usage_page = 0; fido_hid_get_usage(p->report_descriptor.body, p->report_descriptor.len, &usage_page); consume(&usage_page, sizeof(usage_page)); } static void get_report_len(const struct param *p) { size_t report_in_len = 0; size_t report_out_len = 0; fido_hid_get_report_len(p->report_descriptor.body, p->report_descriptor.len, &report_in_len, &report_out_len); consume(&report_in_len, sizeof(report_in_len)); consume(&report_out_len, sizeof(report_out_len)); } static void manifest(const struct param *p) { size_t ndevs, nfound; - fido_dev_info_t *devlist; + fido_dev_info_t *devlist = NULL, *devlist_set = NULL; int16_t vendor_id, product_id; + fido_dev_io_t io; + fido_dev_transport_t t; + memset(&io, 0, sizeof(io)); + memset(&t, 0, sizeof(t)); 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 || + (devlist_set = fido_dev_info_new(1)) == NULL || fido_dev_info_manifest(devlist, ndevs, &nfound) != FIDO_OK) goto out; for (size_t i = 0; i < nfound; i++) { const fido_dev_info_t *di = fido_dev_info_ptr(devlist, i); consume_str(fido_dev_info_path(di)); consume_str(fido_dev_info_manufacturer_string(di)); consume_str(fido_dev_info_product_string(di)); vendor_id = fido_dev_info_vendor(di); product_id = fido_dev_info_product(di); consume(&vendor_id, sizeof(vendor_id)); consume(&product_id, sizeof(product_id)); + fido_dev_info_set(devlist_set, 0, fido_dev_info_path(di), + fido_dev_info_manufacturer_string(di), + fido_dev_info_product_string(di), &io, &t); } out: fido_dev_info_free(&devlist, ndevs); + fido_dev_info_free(&devlist_set, 1); } 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); get_usage(p); get_report_len(p); manifest(p); } void mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN { if (flags & MUTATE_SEED) p->seed = (int)seed; if (flags & MUTATE_PARAM) { mutate_blob(&p->report_descriptor); mutate_string(p->uevent); } if (flags & MUTATE_WIREDATA) mutate_blob(&p->netlink_wiredata); } diff --git a/contrib/libfido2/fuzz/report.tgz b/contrib/libfido2/fuzz/report.tgz index cf74f315cb80..d78f4628de59 100644 Binary files a/contrib/libfido2/fuzz/report.tgz and b/contrib/libfido2/fuzz/report.tgz differ diff --git a/contrib/libfido2/fuzz/summary.txt b/contrib/libfido2/fuzz/summary.txt index 298c8377379f..05c000aa7757 100644 --- a/contrib/libfido2/fuzz/summary.txt +++ b/contrib/libfido2/fuzz/summary.txt @@ -1,57 +1,57 @@ Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 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% 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% 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/cbor.c 1047 23 97.80% 54 0 100.00% 1237 46 96.28% 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/dev.c 421 79 81.24% 45 7 84.44% 491 105 78.62% 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 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.c 87 2 97.70% 14 0 100.00% 145 3 97.93% 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/largeblob.c 513 19 96.30% 30 0 100.00% 684 43 93.71% 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/rs1.c 25 0 100.00% 3 0 100.00% 39 0 100.00% 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/tpm.c 100 0 100.00% 9 0 100.00% 194 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 7809 481 93.84% 679 26 96.17% 10180 708 93.05% +TOTAL 7861 476 93.94% 684 27 96.05% 10270 699 93.19% diff --git a/contrib/libfido2/man/CMakeLists.txt b/contrib/libfido2/man/CMakeLists.txt index 3e50c50d37a0..5ce2fc7b83ed 100644 --- a/contrib/libfido2/man/CMakeLists.txt +++ b/contrib/libfido2/man/CMakeLists.txt @@ -1,380 +1,391 @@ # Copyright (c) 2018 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. find_program(MANDOC_PATH mandoc) find_program(GZIP_PATH gzip) message(STATUS "MANDOC_PATH: ${MANDOC_PATH}") message(STATUS "GZIP_PATH: ${GZIP_PATH}") list(APPEND MAN_SOURCES eddsa_pk_new.3 es256_pk_new.3 fido2-assert.1 fido2-cred.1 fido2-token.1 fido_init.3 fido_assert_new.3 fido_assert_allow_cred.3 fido_assert_set_authdata.3 fido_assert_verify.3 fido_bio_dev_get_info.3 fido_bio_enroll_new.3 fido_bio_info_new.3 fido_bio_template.3 fido_cbor_info_new.3 fido_cred_new.3 fido_cred_exclude.3 fido_credman_metadata_new.3 fido_cred_set_authdata.3 fido_cred_verify.3 fido_dev_enable_entattest.3 fido_dev_get_assert.3 fido_dev_get_touch_begin.3 fido_dev_info_manifest.3 fido_dev_largeblob_get.3 fido_dev_make_cred.3 fido_dev_open.3 fido_dev_set_io_functions.3 fido_dev_set_pin.3 fido_strerr.3 rs256_pk_new.3 ) list(APPEND MAN_ALIAS eddsa_pk_new eddsa_pk_free + eddsa_pk_new eddsa_pk_from_EVP_PKEY eddsa_pk_new eddsa_pk_from_ptr 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 fido_assert_new fido_assert_authdata_ptr fido_assert_new fido_assert_blob_len fido_assert_new fido_assert_blob_ptr fido_assert_new fido_assert_clientdata_hash_len fido_assert_new fido_assert_clientdata_hash_ptr fido_assert_new fido_assert_count fido_assert_new fido_assert_flags fido_assert_new fido_assert_free fido_assert_new fido_assert_hmac_secret_len fido_assert_new fido_assert_hmac_secret_ptr fido_assert_new fido_assert_id_len fido_assert_new fido_assert_id_ptr fido_assert_new fido_assert_largeblob_key_len fido_assert_new fido_assert_largeblob_key_ptr fido_assert_new fido_assert_rp_id fido_assert_new fido_assert_sigcount fido_assert_new fido_assert_sig_len fido_assert_new fido_assert_sig_ptr fido_assert_new fido_assert_user_display_name fido_assert_new fido_assert_user_icon fido_assert_new fido_assert_user_id_len fido_assert_new fido_assert_user_id_ptr fido_assert_new fido_assert_user_name + fido_assert_set_authdata fido_assert_set_authdata_raw fido_assert_set_authdata fido_assert_set_clientdata fido_assert_set_authdata fido_assert_set_clientdata_hash fido_assert_set_authdata fido_assert_set_count fido_assert_set_authdata fido_assert_set_extensions fido_assert_set_authdata fido_assert_set_hmac_salt fido_assert_set_authdata fido_assert_set_hmac_secret fido_assert_set_authdata fido_assert_set_rp fido_assert_set_authdata fido_assert_set_sig fido_assert_set_authdata fido_assert_set_up fido_assert_set_authdata fido_assert_set_uv fido_bio_dev_get_info fido_bio_dev_enroll_begin fido_bio_dev_get_info fido_bio_dev_enroll_cancel fido_bio_dev_get_info fido_bio_dev_enroll_continue fido_bio_dev_get_info fido_bio_dev_enroll_remove fido_bio_dev_get_info fido_bio_dev_get_template_array fido_bio_dev_get_info fido_bio_dev_set_template_name fido_bio_enroll_new fido_bio_enroll_free fido_bio_enroll_new fido_bio_enroll_last_status fido_bio_enroll_new fido_bio_enroll_remaining_samples fido_bio_info_new fido_bio_info_free fido_bio_info_new fido_bio_info_max_samples fido_bio_info_new fido_bio_info_type fido_bio_template fido_bio_template_array_count fido_bio_template fido_bio_template_array_free fido_bio_template fido_bio_template_array_new fido_bio_template fido_bio_template_free fido_bio_template fido_bio_template_id_len fido_bio_template fido_bio_template_id_ptr fido_bio_template fido_bio_template_name fido_bio_template fido_bio_template_new fido_bio_template fido_bio_template_set_id fido_bio_template fido_bio_template_set_name fido_cbor_info_new fido_cbor_info_aaguid_len fido_cbor_info_new fido_cbor_info_aaguid_ptr fido_cbor_info_new fido_cbor_info_algorithm_cose fido_cbor_info_new fido_cbor_info_algorithm_count fido_cbor_info_new fido_cbor_info_algorithm_type fido_cbor_info_new fido_cbor_info_extensions_len fido_cbor_info_new fido_cbor_info_extensions_ptr fido_cbor_info_new fido_cbor_info_free fido_cbor_info_new fido_cbor_info_maxmsgsiz fido_cbor_info_new fido_cbor_info_maxcredbloblen - fido_cbor_info_new fido_cbor_info_maxcredcntlst; - fido_cbor_info_new fido_cbor_info_maxcredidlen; + fido_cbor_info_new fido_cbor_info_maxcredcntlst + fido_cbor_info_new fido_cbor_info_maxcredidlen fido_cbor_info_new fido_cbor_info_fwversion fido_cbor_info_new fido_cbor_info_options_len fido_cbor_info_new fido_cbor_info_options_name_ptr fido_cbor_info_new fido_cbor_info_options_value_ptr fido_cbor_info_new fido_cbor_info_protocols_len fido_cbor_info_new fido_cbor_info_protocols_ptr fido_cbor_info_new fido_cbor_info_transports_len fido_cbor_info_new fido_cbor_info_transports_ptr 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 fido_cred_new fido_cred_authdata_raw_ptr fido_cred_new fido_cred_clientdata_hash_len 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_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_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_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_cred_verify fido_cred_verify_self fido_credman_metadata_new fido_credman_del_dev_rk fido_credman_metadata_new fido_credman_get_dev_metadata fido_credman_metadata_new fido_credman_get_dev_rk fido_credman_metadata_new fido_credman_get_dev_rp fido_credman_metadata_new fido_credman_metadata_free fido_credman_metadata_new fido_credman_rk fido_credman_metadata_new fido_credman_rk_count fido_credman_metadata_new fido_credman_rk_existing fido_credman_metadata_new fido_credman_rk_free fido_credman_metadata_new fido_credman_rk_new fido_credman_metadata_new fido_credman_rk_remaining fido_credman_metadata_new fido_credman_rp_count fido_credman_metadata_new fido_credman_rp_free fido_credman_metadata_new fido_credman_rp_id fido_credman_metadata_new fido_credman_rp_id_hash_len fido_credman_metadata_new fido_credman_rp_id_hash_ptr 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 fido_cred_set_authdata fido_cred_set_clientdata_hash 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 fido_cred_set_authdata fido_cred_set_sig fido_cred_set_authdata fido_cred_set_type fido_cred_set_authdata fido_cred_set_user fido_cred_set_authdata fido_cred_set_uv fido_cred_set_authdata fido_cred_set_x509 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 fido_dev_info_manifest fido_dev_info_new fido_dev_info_manifest fido_dev_info_path fido_dev_info_manifest fido_dev_info_product fido_dev_info_manifest fido_dev_info_product_string fido_dev_info_manifest fido_dev_info_ptr + fido_dev_info_manifest fido_dev_info_set fido_dev_info_manifest fido_dev_info_vendor fido_dev_open fido_dev_build fido_dev_open fido_dev_cancel fido_dev_open fido_dev_close fido_dev_open fido_dev_flags fido_dev_open fido_dev_force_fido2 fido_dev_open fido_dev_force_u2f fido_dev_open fido_dev_free + fido_dev_open fido_dev_has_pin + fido_dev_open fido_dev_has_uv fido_dev_open fido_dev_is_fido2 fido_dev_open fido_dev_is_winhello fido_dev_open fido_dev_major fido_dev_open fido_dev_minor fido_dev_open fido_dev_new + fido_dev_open fido_dev_new_with_info + fido_dev_open fido_dev_open_with_info fido_dev_open fido_dev_protocol fido_dev_open fido_dev_supports_cred_prot fido_dev_open fido_dev_supports_credman + fido_dev_open fido_dev_supports_permissions fido_dev_open fido_dev_supports_pin fido_dev_open fido_dev_supports_uv - fido_dev_open fido_dev_has_uv fido_dev_set_pin fido_dev_get_retry_count fido_dev_set_pin fido_dev_get_uv_retry_count fido_dev_set_pin fido_dev_reset + fido_dev_set_io_functions fido_dev_io_handle fido_dev_set_io_functions fido_dev_set_sigmask fido_dev_set_io_functions fido_dev_set_timeout + fido_dev_set_io_functions fido_dev_set_transport_functions 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 + fido_init fido_set_log_handler 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 ) list(LENGTH MAN_ALIAS MAN_ALIAS_LEN) math(EXPR MAN_ALIAS_MAX "${MAN_ALIAS_LEN} - 2") # man_copy foreach(f ${MAN_SOURCES}) add_custom_command(OUTPUT ${f} COMMAND cp -f ${CMAKE_SOURCE_DIR}/man/${f} . DEPENDS ${f}) list(APPEND COPY_FILES ${f}) endforeach() # man_lint foreach(f ${MAN_SOURCES}) add_custom_command(OUTPUT ${f}.lint COMMAND mandoc -T lint -W warning ${f} > ${f}.lint DEPENDS ${f}) list(APPEND LINT_FILES ${f}.lint) endforeach() # man_html foreach(f ${MAN_SOURCES}) string(REGEX REPLACE ".[13]" "" g ${f}) add_custom_command(OUTPUT ${g}.html COMMAND mandoc -T html -O man="%N.html",style=style.css -I os="Yubico AB" ${f} > ${g}.html DEPENDS ${f}) list(APPEND HTML_FILES ${g}.html) endforeach() # man_html_partial foreach(f ${MAN_SOURCES}) string(REGEX REPLACE ".[13]" "" g ${f}) add_custom_command(OUTPUT ${g}.partial COMMAND cat ${CMAKE_SOURCE_DIR}/man/dyc.css > ${g}.partial COMMAND mandoc -T html -O man="%N.html",fragment ${f} >> ${g}.partial DEPENDS ${f}) list(APPEND HTML_PARTIAL_FILES ${g}.partial) endforeach() # man_gzip foreach(f ${MAN_SOURCES}) add_custom_command(OUTPUT ${f}.gz COMMAND gzip -cn ${f} > ${f}.gz DEPENDS ${f}) list(APPEND GZ_FILES ${f}.gz) endforeach() macro(define_symlink_target NAME EXT) foreach(i RANGE 0 ${MAN_ALIAS_MAX} 2) math(EXPR j "${i} + 1") list(GET MAN_ALIAS ${i} SRC) list(GET MAN_ALIAS ${j} DST) add_custom_command(OUTPUT ${DST}.${EXT} COMMAND ln -sf ${SRC}.${EXT} ${DST}.${EXT}) list(APPEND ${NAME}_LINK_FILES ${DST}.${EXT}) endforeach() add_custom_target(${NAME} DEPENDS ${${NAME}_LINK_FILES}) endmacro() add_custom_target(man_copy DEPENDS ${COPY_FILES}) add_custom_target(man_lint DEPENDS ${LINT_FILES}) add_custom_target(man_html DEPENDS ${HTML_FILES}) add_custom_target(man_html_partial DEPENDS ${HTML_PARTIAL_FILES}) add_custom_target(man_gzip DEPENDS ${GZ_FILES}) define_symlink_target(man_symlink 3) define_symlink_target(man_symlink_html html) define_symlink_target(man_symlink_html_partial partial) define_symlink_target(man_symlink_gzip 3.gz) add_dependencies(man_symlink man_copy) add_dependencies(man_lint man_symlink) add_dependencies(man_html man_lint) add_dependencies(man_symlink_html man_html) add_dependencies(man_html_partial man_lint) add_dependencies(man_symlink_html_partial man_html_partial) add_custom_target(man ALL) if(MANDOC_PATH) add_dependencies(man man_symlink_html) add_dependencies(man_gzip man_lint) install(FILES ${CMAKE_SOURCE_DIR}/man/style.css DESTINATION "${CMAKE_INSTALL_DOCDIR}/html") foreach(f ${MAN_SOURCES}) string(REGEX REPLACE ".[13]" "" f ${f}) install(FILES ${CMAKE_BINARY_DIR}/man/${f}.html DESTINATION "${CMAKE_INSTALL_DOCDIR}/html") endforeach() foreach(i RANGE 0 ${MAN_ALIAS_MAX} 2) math(EXPR j "${i} + 1") list(GET MAN_ALIAS ${j} DST) install(FILES ${CMAKE_BINARY_DIR}/man/${DST}.html DESTINATION "${CMAKE_INSTALL_DOCDIR}/html") endforeach() endif() if(GZIP_PATH) add_dependencies(man_gzip man_copy) add_dependencies(man_symlink_gzip man_gzip) add_dependencies(man man_symlink_gzip) foreach(f ${MAN_SOURCES}) if (${f} MATCHES ".1$") install(FILES ${CMAKE_BINARY_DIR}/man/${f}.gz DESTINATION "${CMAKE_INSTALL_MANDIR}/man1") elseif(${f} MATCHES ".3$") install(FILES ${CMAKE_BINARY_DIR}/man/${f}.gz DESTINATION "${CMAKE_INSTALL_MANDIR}/man3") endif() endforeach() foreach(i RANGE 0 ${MAN_ALIAS_MAX} 2) math(EXPR j "${i} + 1") list(GET MAN_ALIAS ${j} DST) install(FILES ${CMAKE_BINARY_DIR}/man/${DST}.3.gz DESTINATION "${CMAKE_INSTALL_MANDIR}/man3") endforeach() elseif(NOT MSVC) add_dependencies(man man_symlink) foreach(f ${MAN_SOURCES}) if (${f} MATCHES ".1$") install(FILES ${CMAKE_BINARY_DIR}/man/${f} DESTINATION "${CMAKE_INSTALL_MANDIR}/man1") elseif(${f} MATCHES ".3$") install(FILES ${CMAKE_BINARY_DIR}/man/${f} DESTINATION "${CMAKE_INSTALL_MANDIR}/man3") endif() endforeach() foreach(i RANGE 0 ${MAN_ALIAS_MAX} 2) math(EXPR j "${i} + 1") list(GET MAN_ALIAS ${j} DST) install(FILES ${CMAKE_BINARY_DIR}/man/${DST}.3 DESTINATION "${CMAKE_INSTALL_MANDIR}/man3") endforeach() endif() diff --git a/contrib/libfido2/man/check.sh b/contrib/libfido2/man/check.sh new file mode 100755 index 000000000000..951afeb88e0b --- /dev/null +++ b/contrib/libfido2/man/check.sh @@ -0,0 +1,42 @@ +#!/bin/sh -u + +# Copyright (c) 2022 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. + +T=$(mktemp -d) || exit 1 +find . -maxdepth 1 -type f -name '*.3' -print0 > "$T/files" + +xargs -0 awk '/^.Sh NAME/,/^.Nd/' < "$T/files" | \ + awk '/^.Nm/ { print $2 }' | sort -u > "$T/Nm" +xargs -0 awk '/^.Fn/ { print $2 }' < "$T/files" | sort -u > "$T/Fn" +(cd "$T" && diff -u Nm Fn) + +cut -c2- ../src/export.llvm | sort > "$T/exports" +(cd "$T" && diff -u Nm exports) + +awk '/^list\(APPEND MAN_SOURCES/,/^\)/' CMakeLists.txt | \ + awk '/.3$/ { print $1 }' | sort > "$T/listed_sources" +xargs -0 -n1 basename < "$T/files" | sort > "$T/actual_sources" +(cd "$T" && diff -u listed_sources actual_sources) + +awk '/^list\(APPEND MAN_ALIAS/,/^\)/' CMakeLists.txt | \ + sed '1d;$d' | awk '{ print $1, $2 }' | sort > "$T/listed_aliases" +xargs -0 grep -o "^.Fn [A-Za-z0-9_]* \"" < "$T/files" | \ + cut -c3- | sed 's/\.3:\.Fn//;s/ "//' | awk '$1 != $2' | \ + sort > "$T/actual_aliases" +(cd "$T" && diff -u listed_aliases actual_aliases) + +xargs -0 grep -hB1 "^.Fn [A-Za-z0-9_]* \"" < "$T/files" | \ + sed -E 's/^.F[tn] //;s/\*[^"\*]+"/\*"/g;s/ [^" \*]+"/"/g;/^--$/d' | \ + paste -d " " - - | sed 's/\* /\*/' | sort > "$T/documented_prototypes" +while read -r f; do + awk "/\/\*/ { next } /$f\(/,/;/" ../src/fido.h ../src/fido/*.h | \ + sed -E 's/^[ ]+//;s/[ ]+/ /' | tr '\n' ' ' | \ + sed 's/(/ "/;s/, /" "/g;s/);/"/;s/ $/\n/' +done < "$T/exports" | sort > "$T/actual_prototypes" +(cd "$T" && diff -u documented_prototypes actual_prototypes) + +(cd "$T" && rm files Nm Fn exports listed_sources actual_sources \ + listed_aliases actual_aliases documented_prototypes actual_prototypes) +rmdir -- "$T" diff --git a/contrib/libfido2/man/eddsa_pk_new.3 b/contrib/libfido2/man/eddsa_pk_new.3 index 65bf9a9f753d..998def484790 100644 --- a/contrib/libfido2/man/eddsa_pk_new.3 +++ b/contrib/libfido2/man/eddsa_pk_new.3 @@ -1,122 +1,122 @@ .\" Copyright (c) 2019 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. .\" .Dd $Mdocdate: May 15 2019 $ .Dt EDDSA_PK_NEW 3 .Os .Sh NAME .Nm eddsa_pk_new , .Nm eddsa_pk_free , .Nm eddsa_pk_from_EVP_PKEY , .Nm eddsa_pk_from_ptr , .Nm eddsa_pk_to_EVP_PKEY -.Nd FIDO 2 COSE EDDSA API +.Nd FIDO2 COSE EDDSA API .Sh SYNOPSIS .In openssl/evp.h .In fido/eddsa.h .Ft eddsa_pk_t * .Fn eddsa_pk_new "void" .Ft void .Fn eddsa_pk_free "eddsa_pk_t **pkp" .Ft int .Fn eddsa_pk_from_EVP_PKEY "eddsa_pk_t *pk" "const EVP_PKEY *pkey" .Ft int .Fn eddsa_pk_from_ptr "eddsa_pk_t *pk" "const void *ptr" "size_t len" .Ft EVP_PKEY * .Fn eddsa_pk_to_EVP_PKEY "const eddsa_pk_t *pk" .Sh DESCRIPTION EDDSA is the name given in the CBOR Object Signing and Encryption (COSE) RFC to EDDSA over Curve25519 with SHA-512. The COSE EDDSA API of .Em libfido2 is an auxiliary API with routines to convert between the different EDDSA public key types used in .Em libfido2 and .Em OpenSSL . .Pp In .Em libfido2 , EDDSA public keys are abstracted by the .Vt eddsa_pk_t type. .Pp The .Fn eddsa_pk_new function returns a pointer to a newly allocated, empty .Vt eddsa_pk_t type. If memory cannot be allocated, NULL is returned. .Pp The .Fn eddsa_pk_free function releases the memory backing .Fa *pkp , where .Fa *pkp must have been previously allocated by .Fn eddsa_pk_new . On return, .Fa *pkp is set to NULL. Either .Fa pkp or .Fa *pkp may be NULL, in which case .Fn eddsa_pk_free is a NOP. .Pp The .Fn eddsa_pk_from_EVP_PKEY function fills .Fa pk with the contents of .Fa pkey . No references to .Fa pkey are kept. .Pp The .Fn eddsa_pk_from_ptr function fills .Fa pk with the contents of .Fa ptr , where .Fa ptr points to .Fa len bytes. No references to .Fa ptr are kept. .Pp The .Fn eddsa_pk_to_EVP_PKEY function converts .Fa pk to a newly allocated .Fa EVP_PKEY type with a reference count of 1. No internal references to the returned pointer are kept. If an error occurs, .Fn eddsa_pk_to_EVP_PKEY returns NULL. .Sh RETURN VALUES The -.Fn eddsa_pk_from_EC_KEY +.Fn eddsa_pk_from_EVP_PKEY and .Fn eddsa_pk_from_ptr functions return .Dv FIDO_OK on success. On error, a different error code defined in .In fido/err.h is returned. .Sh SEE ALSO .Xr es256_pk_new 3 , .Xr fido_assert_verify 3 , .Xr fido_cred_pubkey_ptr 3 , .Xr rs256_pk_new 3 diff --git a/contrib/libfido2/man/es256_pk_new.3 b/contrib/libfido2/man/es256_pk_new.3 index 6c1bac0f57f9..5e184340a575 100644 --- a/contrib/libfido2/man/es256_pk_new.3 +++ b/contrib/libfido2/man/es256_pk_new.3 @@ -1,140 +1,140 @@ .\" 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. .\" .Dd $Mdocdate: May 24 2018 $ .Dt ES256_PK_NEW 3 .Os .Sh NAME .Nm es256_pk_new , .Nm es256_pk_free , .Nm es256_pk_from_EC_KEY , -.Nm es256_pk_from_EVP_KEY , +.Nm es256_pk_from_EVP_PKEY , .Nm es256_pk_from_ptr , .Nm es256_pk_to_EVP_PKEY -.Nd FIDO 2 COSE ES256 API +.Nd FIDO2 COSE ES256 API .Sh SYNOPSIS .In openssl/ec.h .In fido/es256.h .Ft es256_pk_t * .Fn es256_pk_new "void" .Ft void .Fn es256_pk_free "es256_pk_t **pkp" .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" .Sh DESCRIPTION ES256 is the name given in the CBOR Object Signing and Encryption (COSE) RFC to ECDSA over P-256 with SHA-256. The COSE ES256 API of .Em libfido2 is an auxiliary API with routines to convert between the different ECDSA public key types used in .Em libfido2 and .Em OpenSSL . .Pp In .Em libfido2 , ES256 public keys are abstracted by the .Vt es256_pk_t type. .Pp The .Fn es256_pk_new function returns a pointer to a newly allocated, empty .Vt es256_pk_t type. If memory cannot be allocated, NULL is returned. .Pp The .Fn es256_pk_free function releases the memory backing .Fa *pkp , where .Fa *pkp must have been previously allocated by .Fn es256_pk_new . On return, .Fa *pkp is set to NULL. Either .Fa pkp or .Fa *pkp may be NULL, in which case .Fn es256_pk_free is a NOP. .Pp The .Fn es256_pk_from_EC_KEY function fills .Fa pk with the contents of .Fa ec . No references to .Fa ec are kept. .Pp The -.Fn es256_pk_from_EVP_KEY +.Fn es256_pk_from_EVP_PKEY 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 with the contents of .Fa ptr , where .Fa ptr points to .Fa len bytes. The .Fa ptr pointer may point to an uncompressed point, or to the concatenation of the x and y coordinates. No references to .Fa ptr are kept. .Pp The .Fn es256_pk_to_EVP_PKEY function converts .Fa pk to a newly allocated .Fa EVP_PKEY type with a reference count of 1. No internal references to the returned pointer are kept. If an error occurs, .Fn es256_pk_to_EVP_PKEY returns NULL. .Sh RETURN VALUES The .Fn es256_pk_from_EC_KEY , -.Fn es256_pk_from_EVP_KEY , +.Fn es256_pk_from_EVP_PKEY , and .Fn es256_pk_from_ptr functions return .Dv FIDO_OK on success. On error, a different error code defined in .In fido/err.h is returned. .Sh SEE ALSO .Xr eddsa_pk_new 3 , .Xr fido_assert_verify 3 , .Xr fido_cred_pubkey_ptr 3 , .Xr rs256_pk_new 3 diff --git a/contrib/libfido2/man/fido2-assert.1 b/contrib/libfido2/man/fido2-assert.1 index da47d6f19dd3..ee8135c18483 100644 --- a/contrib/libfido2/man/fido2-assert.1 +++ b/contrib/libfido2/man/fido2-assert.1 @@ -1,256 +1,256 @@ .\" Copyright (c) 2018 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. .\" .Dd $Mdocdate: November 5 2019 $ .Dt FIDO2-ASSERT 1 .Os .Sh NAME .Nm fido2-assert -.Nd get/verify a FIDO 2 assertion +.Nd get/verify a FIDO2 assertion .Sh SYNOPSIS .Nm .Fl G .Op Fl bdhpruv .Op Fl t Ar option .Op Fl i Ar input_file .Op Fl o Ar output_file .Ar device .Nm .Fl V .Op Fl dhpv .Op Fl i Ar input_file .Ar key_file .Op Ar type .Sh DESCRIPTION .Nm -gets or verifies a FIDO 2 assertion. +gets or verifies a FIDO2 assertion. .Pp The input of .Nm is defined by the parameters of the assertion to be obtained/verified. See the .Sx INPUT FORMAT section for details. .Pp The output of .Nm is defined by the result of the selected operation. See the .Sx OUTPUT FORMAT section for details. .Pp If an assertion is successfully obtained or verified, .Nm exits 0. Otherwise, .Nm exits 1. .Pp The options are as follows: .Bl -tag -width Ds .It Fl G Tells .Nm to obtain a new assertion from .Ar device . .It Fl V Tells .Nm to verify an assertion using the PEM-encoded public key in .Ar key_file of type .Ar type , where .Ar type may be .Em es256 (denoting ECDSA over NIST P-256 with SHA-256), .Em rs256 (denoting 2048-bit RSA with PKCS#1.5 padding and SHA-256), or .Em eddsa (denoting EDDSA over Curve25519 with SHA-512). If .Ar type is not specified, .Em es256 is assumed. .It Fl b Request the credential's .Dq largeBlobKey , a 32-byte symmetric key associated with the asserted credential. .It Fl h If obtaining an assertion, enable the FIDO2 hmac-secret extension. If verifying an assertion, check whether the extension data bit was signed by the authenticator. .It Fl d Causes .Nm to emit debugging output on .Em stderr . .It Fl i Ar input_file Tells .Nm to read the parameters of the assertion from .Ar input_file instead of .Em stdin . .It Fl o Ar output_file Tells .Nm to write output on .Ar output_file instead of .Em stdout . .It Fl p If obtaining an assertion, request user presence. If verifying an assertion, check whether the user presence bit was signed by the authenticator. .It Fl r Obtain an assertion using a resident credential. If .Fl r is specified, .Nm will not expect a credential id in its input, and may output multiple assertions. Resident credentials are called .Dq discoverable credentials -in FIDO 2.1. +in CTAP 2.1. .It Fl t Ar option Toggles a key/value .Ar option , where .Ar option is a string of the form .Dq key=value . The options supported at present are: .Bl -tag -width Ds .It Cm up Ns = Ns Ar true|false Asks the authenticator for user presence to be enabled or disabled. .It Cm uv Ns = Ns Ar true|false Asks the authenticator for user verification to be enabled or disabled. .It Cm pin Ns = Ns Ar true|false Tells .Nm whether to prompt for a PIN and request user verification. .El .Pp The .Fl t option may be specified multiple times. .It Fl u Obtain an assertion using U2F. By default, .Nm will use FIDO2 if supported by the authenticator, and fallback to U2F otherwise. .It Fl v If obtaining an assertion, prompt the user for a PIN and request user verification from the authenticator. If verifying an assertion, check whether the user verification bit was signed by the authenticator. .El .Pp If a .Em tty is available, .Nm will use it to obtain the PIN. Otherwise, .Em stdin is used. .Sh INPUT FORMAT The input of .Nm consists of base64 blobs and UTF-8 strings separated by newline characters ('\\n'). .Pp When obtaining an assertion, .Nm expects its input to consist of: .Pp .Bl -enum -offset indent -compact .It client data hash (base64 blob); .It relying party id (UTF-8 string); .It credential id, if credential not resident (base64 blob); .It hmac salt, if the FIDO2 hmac-secret extension is enabled (base64 blob); .El .Pp When verifying an assertion, .Nm expects its input to consist of: .Pp .Bl -enum -offset indent -compact .It client data hash (base64 blob); .It relying party id (UTF-8 string); .It authenticator data (base64 blob); .It assertion signature (base64 blob); .El .Pp UTF-8 strings passed to .Nm must not contain embedded newline or NUL characters. .Sh OUTPUT FORMAT The output of .Nm consists of base64 blobs and UTF-8 strings separated by newline characters ('\\n'). .Pp For each generated assertion, .Nm outputs: .Pp .Bl -enum -offset indent -compact .It client data hash (base64 blob); .It relying party id (UTF-8 string); .It authenticator data (base64 blob); .It assertion signature (base64 blob); .It user id, if credential resident (base64 blob); .It hmac secret, if the FIDO2 hmac-secret extension is enabled (base64 blob); .It the credential's associated 32-byte symmetric key .Pq Dq largeBlobKey , if requested (base64 blob). .El .Pp When verifying an assertion, .Nm produces no output. .Sh EXAMPLES Assuming .Pa cred contains a .Em es256 credential created according to the steps outlined in .Xr fido2-cred 1 , obtain an assertion from an authenticator at .Pa /dev/hidraw5 and verify it: .Pp .Dl $ echo assertion challenge | openssl sha256 -binary | base64 > assert_param .Dl $ echo relying party >> assert_param .Dl $ head -1 cred >> assert_param .Dl $ tail -n +2 cred > pubkey .Dl $ fido2-assert -G -i assert_param /dev/hidraw5 | fido2-assert -V pubkey es256 .Sh SEE ALSO .Xr fido2-cred 1 , .Xr fido2-token 1 diff --git a/contrib/libfido2/man/fido2-cred.1 b/contrib/libfido2/man/fido2-cred.1 index 301564d688e5..0b10e74a0507 100644 --- a/contrib/libfido2/man/fido2-cred.1 +++ b/contrib/libfido2/man/fido2-cred.1 @@ -1,267 +1,267 @@ .\" Copyright (c) 2018 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. .\" .Dd $Mdocdate: November 5 2019 $ .Dt FIDO2-CRED 1 .Os .Sh NAME .Nm fido2-cred -.Nd make/verify a FIDO 2 credential +.Nd make/verify a FIDO2 credential .Sh SYNOPSIS .Nm .Fl M .Op Fl bdhqruv .Op Fl c Ar cred_protect .Op Fl i Ar input_file .Op Fl o Ar output_file .Ar device .Op Ar type .Nm .Fl V .Op Fl dhv .Op Fl c Ar cred_protect .Op Fl i Ar input_file .Op Fl o Ar output_file .Op Ar type .Sh DESCRIPTION .Nm -makes or verifies a FIDO 2 credential. +makes or verifies a FIDO2 credential. .Pp A credential .Ar type may be .Em es256 (denoting ECDSA over NIST P-256 with SHA-256), .Em rs256 (denoting 2048-bit RSA with PKCS#1.5 padding and SHA-256), or .Em eddsa (denoting EDDSA over Curve25519 with SHA-512). If .Ar type is not specified, .Em es256 is assumed. .Pp When making a credential, the authenticator may require the user to authenticate with a PIN. If the .Fl q option is not specified, .Nm will prompt the user for the PIN. If a .Em tty is available, .Nm will use it to obtain the PIN. Otherwise, .Em stdin is used. .Pp The input of .Nm is defined by the parameters of the credential to be made/verified. See the .Sx INPUT FORMAT section for details. .Pp The output of .Nm is defined by the result of the selected operation. See the .Sx OUTPUT FORMAT section for details. .Pp If a credential is successfully created or verified, .Nm exits 0. Otherwise, .Nm exits 1. .Pp The options are as follows: .Bl -tag -width Ds .It Fl M Tells .Nm to make a new credential on .Ar device . .It Fl V Tells .Nm to verify a credential. .It Fl b Request the credential's .Dq largeBlobKey , a 32-byte symmetric key associated with the generated credential. .It Fl c Ar cred_protect If making a credential, set the credential's protection level to .Ar cred_protect , where .Ar cred_protect is the credential's protection level in decimal notation. Please refer to .In fido/param.h for the set of possible values. If verifying a credential, check whether the credential's protection level was signed by the authenticator as .Ar cred_protect . .It Fl d Causes .Nm to emit debugging output on .Em stderr . .It Fl h If making a credential, enable the FIDO2 hmac-secret extension. If verifying a credential, check whether the extension data bit was signed by the authenticator. .It Fl i Ar input_file Tells .Nm to read the parameters of the credential from .Ar input_file instead of .Em stdin . .It Fl o Ar output_file Tells .Nm to write output on .Ar output_file instead of .Em stdout . .It Fl q Tells .Nm to be quiet. If a PIN is required and .Fl q is specified, .Nm will fail. .It Fl r Create a resident credential. Resident credentials are called .Dq discoverable credentials -in FIDO 2.1. +in CTAP 2.1. .It Fl u Create a U2F credential. By default, .Nm will use FIDO2 if supported by the authenticator, and fallback to U2F otherwise. .It Fl v If making a credential, request user verification. If verifying a credential, check whether the user verification bit was signed by the authenticator. .El .Sh INPUT FORMAT The input of .Nm consists of base64 blobs and UTF-8 strings separated by newline characters ('\\n'). .Pp When making a credential, .Nm expects its input to consist of: .Pp .Bl -enum -offset indent -compact .It client data hash (base64 blob); .It relying party id (UTF-8 string); .It user name (UTF-8 string); .It user id (base64 blob). .El .Pp When verifying a credential, .Nm expects its input to consist of: .Pp .Bl -enum -offset indent -compact .It client data hash (base64 blob); .It relying party id (UTF-8 string); .It credential format (UTF-8 string); .It authenticator data (base64 blob); .It credential id (base64 blob); .It attestation signature (base64 blob); .It attestation certificate (optional, base64 blob). .El .Pp UTF-8 strings passed to .Nm must not contain embedded newline or NUL characters. .Sh OUTPUT FORMAT The output of .Nm consists of base64 blobs, UTF-8 strings, and PEM-encoded public keys separated by newline characters ('\\n'). .Pp Upon the successful generation of a credential, .Nm outputs: .Pp .Bl -enum -offset indent -compact .It client data hash (base64 blob); .It relying party id (UTF-8 string); .It credential format (UTF-8 string); .It authenticator data (base64 blob); .It credential id (base64 blob); .It attestation signature (base64 blob); .It attestation certificate, if present (base64 blob). .It the credential's associated 32-byte symmetric key .Pq Dq largeBlobKey , if present (base64 blob). .El .Pp Upon the successful verification of a credential, .Nm outputs: .Pp .Bl -enum -offset indent -compact .It credential id (base64 blob); .It PEM-encoded credential key. .El .Sh EXAMPLES Create a new .Em es256 credential on .Pa /dev/hidraw5 , verify it, and save the id and the public key of the credential in .Em cred : .Pp .Dl $ echo credential challenge | openssl sha256 -binary | base64 > cred_param .Dl $ echo relying party >> cred_param .Dl $ echo user name >> cred_param .Dl $ dd if=/dev/urandom bs=1 count=32 | base64 >> cred_param .Dl $ fido2-cred -M -i cred_param /dev/hidraw5 | fido2-cred -V -o cred .Sh SEE ALSO .Xr fido2-assert 1 , .Xr fido2-token 1 .Sh CAVEATS Please note that .Nm handles Basic Attestation and Self Attestation transparently. In the case of Basic Attestation, the validity of the authenticator's attestation certificate is .Em not verified. diff --git a/contrib/libfido2/man/fido2-token.1 b/contrib/libfido2/man/fido2-token.1 index fd82c23cffb7..1aa2feb86859 100644 --- a/contrib/libfido2/man/fido2-token.1 +++ b/contrib/libfido2/man/fido2-token.1 @@ -1,400 +1,400 @@ .\" 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. .\" .Dd $Mdocdate: September 13 2019 $ .Dt FIDO2-TOKEN 1 .Os .Sh NAME .Nm fido2-token -.Nd find and manage a FIDO 2 authenticator +.Nd find and manage a FIDO2 authenticator .Sh SYNOPSIS .Nm .Fl C .Op Fl d .Ar device .Nm .Fl D .Op Fl d .Fl i .Ar cred_id .Ar device .Nm .Fl D .Fl b .Op Fl d .Fl k Ar key_path .Ar device .Nm .Fl D .Fl b .Op Fl d .Fl n Ar rp_id .Op Fl i Ar cred_id .Ar device .Nm .Fl D .Fl e .Op Fl d .Fl i .Ar template_id .Ar device .Nm .Fl D .Fl u .Op Fl d .Ar device .Nm .Fl G .Fl b .Op Fl d .Fl k Ar key_path .Ar blob_path .Ar device .Nm .Fl G .Fl b .Op Fl d .Fl n Ar rp_id .Op Fl i Ar cred_id .Ar blob_path .Ar device .Nm .Fl I .Op Fl cd .Op Fl k Ar rp_id Fl i Ar cred_id .Ar device .Nm .Fl L .Op Fl bder .Op Fl k Ar rp_id .Op device .Nm .Fl R .Op Fl d .Ar device .Nm .Fl S .Op Fl adefu .Ar device .Nm .Fl S .Op Fl d .Fl i Ar template_id .Fl n Ar template_name .Ar device .Nm .Fl S .Op Fl d .Fl l Ar pin_length .Ar device .Nm .Fl S .Fl b .Op Fl d .Fl k Ar key_path .Ar blob_path .Ar device .Nm .Fl S .Fl b .Op Fl d .Fl n Ar rp_id .Op Fl i Ar cred_id .Ar blob_path .Ar device .Nm .Fl S .Fl c .Op Fl d .Fl i Ar cred_id .Fl k Ar user_id .Fl n Ar name .Fl p Ar display_name .Ar device .Nm .Fl S .Fl m .Ar rp_id .Ar device .Nm .Fl V .Sh DESCRIPTION .Nm -manages a FIDO 2 authenticator. +manages a FIDO2 authenticator. .Pp The options are as follows: .Bl -tag -width Ds .It Fl C Ar device Changes the PIN of .Ar device . The user will be prompted for the current and new PINs. .It Fl D Fl i Ar id Ar device Deletes the resident credential specified by .Ar id from .Ar device , where .Ar id is the credential's base64-encoded id. The user will be prompted for the PIN. .It Fl D Fl b Fl k Ar key_path Ar device Deletes a .Dq largeBlob encrypted with .Ar key_path from .Ar device , where .Ar key_path must hold the blob's base64-encoded encryption key. A PIN or equivalent user-verification gesture is required. .It Fl D Fl b Fl n Ar rp_id Oo Fl i Ar cred_id Oc Ar device Deletes a .Dq largeBlob corresponding to .Ar rp_id from .Ar device . If .Ar rp_id has multiple credentials enrolled on .Ar device , the credential ID must be specified using .Fl i Ar cred_id , where .Ar cred_id is a base64-encoded blob. A PIN or equivalent user-verification gesture is required. .It Fl D Fl e Fl i Ar id Ar device Deletes the biometric enrollment specified by .Ar id from .Ar device , where .Ar id is the enrollment's template base64-encoded id. The user will be prompted for the PIN. .It Fl D Fl u Ar device -Disables the FIDO 2.1 +Disables the CTAP 2.1 .Dq user verification always feature on .Ar device . .It Fl G Fl b Fl k Ar key_path Ar blob_path Ar device -Gets a FIDO 2.1 +Gets a CTAP 2.1 .Dq largeBlob encrypted with .Ar key_path from .Ar device , where .Ar key_path must hold the blob's base64-encoded encryption key. The blob is written to .Ar blob_path . A PIN or equivalent user-verification gesture is required. .It Fl G Fl b Fl n Ar rp_id Oo Fl i Ar cred_id Oc Ar blob_path Ar device -Gets a FIDO 2.1 +Gets a CTAP 2.1 .Dq largeBlob associated with .Ar rp_id from .Ar device . If .Ar rp_id has multiple credentials enrolled on .Ar device , the credential ID must be specified using .Fl i Ar cred_id , where .Ar cred_id is a base64-encoded blob. The blob is written to .Ar blob_path . A PIN or equivalent user-verification gesture is required. .It Fl I Ar device Retrieves information on .Ar device . .It Fl I Fl c Ar device Retrieves resident credential metadata from .Ar device . The user will be prompted for the PIN. .It Fl I Fl k Ar rp_id Fl i Ar cred_id Ar device Prints the credential id (base64-encoded) and public key (PEM encoded) of the resident credential specified by .Ar rp_id and .Ar cred_id , where .Ar rp_id is a UTF-8 relying party id, and .Ar cred_id is a base64-encoded credential id. The user will be prompted for the PIN. .It Fl L Produces a list of authenticators found by the operating system. .It Fl L Fl b Ar device -Produces a list of FIDO 2.1 +Produces a list of CTAP 2.1 .Dq largeBlobs on .Ar device . A PIN or equivalent user-verification gesture is required. .It Fl L Fl e Ar device Produces a list of biometric enrollments on .Ar device . The user will be prompted for the PIN. .It Fl L Fl r Ar device Produces a list of relying parties with resident credentials on .Ar device . The user will be prompted for the PIN. .It Fl L Fl k Ar rp_id Ar device Produces a list of resident credentials corresponding to relying party .Ar rp_id on .Ar device . The user will be prompted for the PIN. .It Fl R Performs a reset on .Ar device . .Nm will NOT prompt for confirmation. .It Fl S Sets the PIN of .Ar device . The user will be prompted for the PIN. .It Fl S Fl a Ar device -Enables FIDO 2.1 Enterprise Attestation on +Enables CTAP 2.1 Enterprise Attestation on .Ar device . .It Fl S Fl b Fl k Ar key_path Ar blob_path Ar device Sets .Ar blob_path -as a FIDO 2.1 +as a CTAP 2.1 .Dq largeBlob encrypted with .Ar key_path on .Ar device , where .Ar blob_path holds the blob's plaintext, and .Ar key_path the blob's base64-encoded encryption. A PIN or equivalent user-verification gesture is required. .It Fl S Fl b Fl n Ar rp_id Oo Fl i Ar cred_id Oc Ar blob_path Ar device Sets .Ar blob_path -as a FIDO 2.1 +as a CTAP 2.1 .Dq largeBlob associated with .Ar rp_id on .Ar device . If .Ar rp_id has multiple credentials enrolled on .Ar device , the credential ID must be specified using .Fl i Ar cred_id , where .Ar cred_id is a base64-encoded blob. A PIN or equivalent user-verification gesture is required. .It Fl S Fl c Fl i Ar cred_id Fl k Ar user_id Fl n Ar name Fl p Ar display_name Ar device Sets the .Ar name and .Ar display_name attributes of the resident credential identified by .Ar cred_id and .Ar user_id , where .Ar name and .Ar display_name are UTF-8 strings and .Ar cred_id and .Ar user_id are base64-encoded blobs. A PIN or equivalent user-verification gesture is required. .It Fl S Fl e Ar device Performs a new biometric enrollment on .Ar device . The user will be prompted for the PIN. .It Fl S Fl e Fl i Ar template_id Fl n Ar template_name Ar device Sets the friendly name of the biometric enrollment specified by .Ar template_id to .Ar template_name on .Ar device , where .Ar template_id is base64-encoded and .Ar template_name is a UTF-8 string. The user will be prompted for the PIN. .It Fl S Fl f Ar device Forces a PIN change on .Ar device . The user will be prompted for the PIN. .It Fl S Fl l Ar pin_length Ar device Sets the minimum PIN length of .Ar device 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 +Enables the CTAP 2.1 .Dq user verification always feature on .Ar device . .It Fl V Prints version information. .It Fl d Causes .Nm to emit debugging output on .Em stderr . .El .Pp If a .Em tty is available, .Nm will use it to prompt for PINs. Otherwise, .Em stdin is used. .Pp .Nm exits 0 on success and 1 on error. .Sh SEE ALSO .Xr fido2-assert 1 , .Xr fido2-cred 1 .Sh CAVEATS The actual user-flow to perform a reset is outside the scope of the FIDO2 specification, and may therefore vary depending on the authenticator. Yubico authenticators do not allow resets after 5 seconds from power-up, and expect a reset to be confirmed by the user through touch within 30 seconds. .Pp An authenticator's path may contain spaces. .Pp Resident credentials are called .Dq discoverable credentials -in FIDO 2.1. +in CTAP 2.1. .Pp -Whether the FIDO 2.1 +Whether the CTAP 2.1 .Dq user verification always feature is activated or deactivated after an authenticator reset is vendor-specific. diff --git a/contrib/libfido2/man/fido_assert_allow_cred.3 b/contrib/libfido2/man/fido_assert_allow_cred.3 index bbe6e4d8929a..7fd730c3f63c 100644 --- a/contrib/libfido2/man/fido_assert_allow_cred.3 +++ b/contrib/libfido2/man/fido_assert_allow_cred.3 @@ -1,47 +1,47 @@ .\" Copyright (c) 2018 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. .\" .Dd $Mdocdate: May 23 2018 $ .Dt FIDO_ASSERT_ALLOW_CRED 3 .Os .Sh NAME .Nm fido_assert_allow_cred -.Nd appends a credential ID to the list of credentials allowed in an assertion +.Nd allow a credential in a FIDO2 assertion .Sh SYNOPSIS .In fido.h .Ft int .Fn fido_assert_allow_cred "fido_assert_t *assert" "const unsigned char *ptr" "size_t len" .Sh DESCRIPTION The .Fn fido_assert_allow_cred function adds .Fa ptr to the list of credentials allowed in .Fa assert , where .Fa ptr points to a credential ID of .Fa len bytes. A copy of .Fa ptr is made, and no references to the passed pointer are kept. If .Fn fido_assert_allow_cred fails, the existing list of allowed credentials is preserved. .Pp -For the format of a FIDO 2 credential ID, please refer to the +For the format of a FIDO2 credential ID, please refer to the Web Authentication (webauthn) standard. .Sh RETURN VALUES The error codes returned by .Fn fido_assert_allow_cred are defined in .In fido/err.h . On success, .Dv FIDO_OK is returned. .Sh SEE ALSO .Xr fido_assert_new 3 , .Xr fido_assert_set_authdata 3 , .Xr fido_dev_get_assert 3 diff --git a/contrib/libfido2/man/fido_assert_new.3 b/contrib/libfido2/man/fido_assert_new.3 index 16f4e3a6e46d..a1a3c101ba33 100644 --- a/contrib/libfido2/man/fido_assert_new.3 +++ b/contrib/libfido2/man/fido_assert_new.3 @@ -1,243 +1,256 @@ .\" Copyright (c) 2018 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. .\" .Dd $Mdocdate: October 22 2019 $ .Dt FIDO_ASSERT_NEW 3 .Os .Sh NAME .Nm fido_assert_new , .Nm fido_assert_free , .Nm fido_assert_count , .Nm fido_assert_rp_id , .Nm fido_assert_user_display_name , .Nm fido_assert_user_icon , .Nm fido_assert_user_name , .Nm fido_assert_authdata_ptr , .Nm fido_assert_blob_ptr , .Nm fido_assert_clientdata_hash_ptr , .Nm fido_assert_hmac_secret_ptr , .Nm fido_assert_largeblob_key_ptr , .Nm fido_assert_user_id_ptr , .Nm fido_assert_sig_ptr , .Nm fido_assert_id_ptr , .Nm fido_assert_authdata_len , .Nm fido_assert_blob_len , .Nm fido_assert_clientdata_hash_len , .Nm fido_assert_hmac_secret_len , .Nm fido_assert_largeblob_key_len , .Nm fido_assert_user_id_len , .Nm fido_assert_sig_len , .Nm fido_assert_id_len , .Nm fido_assert_sigcount , .Nm fido_assert_flags -.Nd FIDO 2 assertion API +.Nd FIDO2 assertion API .Sh SYNOPSIS .In fido.h .Ft fido_assert_t * .Fn fido_assert_new "void" .Ft void .Fn fido_assert_free "fido_assert_t **assert_p" .Ft size_t .Fn fido_assert_count "const fido_assert_t *assert" .Ft const char * .Fn fido_assert_rp_id "const fido_assert_t *assert" .Ft const char * .Fn fido_assert_user_display_name "const fido_assert_t *assert" "size_t idx" .Ft const char * .Fn fido_assert_user_icon "const fido_assert_t *assert" "size_t idx" .Ft const char * .Fn fido_assert_user_name "const fido_assert_t *assert" "size_t idx" .Ft const unsigned char * .Fn fido_assert_authdata_ptr "const fido_assert_t *assert" "size_t idx" .Ft const unsigned char * .Fn fido_assert_clientdata_hash_ptr "const fido_assert_t *assert" .Ft const unsigned char * .Fn fido_assert_blob_ptr "const fido_assert_t *assert" "size_t idx" .Ft const unsigned char * .Fn fido_assert_hmac_secret_ptr "const fido_assert_t *assert" "size_t idx" .Ft const unsigned char * .Fn fido_assert_largeblob_key_ptr "const fido_assert_t *assert" "size_t idx" .Ft const unsigned char * .Fn fido_assert_user_id_ptr "const fido_assert_t *assert" "size_t idx" .Ft const unsigned char * .Fn fido_assert_sig_ptr "const fido_assert_t *assert" "size_t idx" .Ft const unsigned char * .Fn fido_assert_id_ptr "const fido_assert_t *assert" "size_t idx" .Ft size_t .Fn fido_assert_authdata_len "const fido_assert_t *assert" "size_t idx" .Ft size_t .Fn fido_assert_clientdata_hash_len "const fido_assert_t *assert" .Ft size_t .Fn fido_assert_blob_len "const fido_assert_t *assert" "size_t idx" .Ft size_t .Fn fido_assert_hmac_secret_len "const fido_assert_t *assert" "size_t idx" .Ft size_t .Fn fido_assert_largeblob_key_len "const fido_assert_t *assert" "size_t idx" .Ft size_t .Fn fido_assert_user_id_len "const fido_assert_t *assert" "size_t idx" .Ft size_t .Fn fido_assert_sig_len "const fido_assert_t *assert" "size_t idx" .Ft size_t .Fn fido_assert_id_len "const fido_assert_t *assert" "size_t idx" .Ft uint32_t .Fn fido_assert_sigcount "const fido_assert_t *assert" "size_t idx" .Ft uint8_t .Fn fido_assert_flags "const fido_assert_t *assert" "size_t idx" .Sh DESCRIPTION -FIDO 2 assertions are abstracted in -.Em libfido2 -by the +A FIDO2 assertion is a collection of statements, each statement a +map between a challenge, a credential, a signature, and ancillary +attributes. +In +.Em libfido2 , +a FIDO2 assertion is abstracted by the .Vt fido_assert_t type. The functions described in this page allow a .Vt fido_assert_t type to be allocated, deallocated, and inspected. For other operations on .Vt fido_assert_t , please refer to .Xr fido_assert_set_authdata 3 , .Xr fido_assert_allow_cred 3 , .Xr fido_assert_verify 3 , and .Xr fido_dev_get_assert 3 . .Pp The .Fn fido_assert_new function returns a pointer to a newly allocated, empty .Vt fido_assert_t type. If memory cannot be allocated, NULL is returned. .Pp The .Fn fido_assert_free function releases the memory backing .Fa *assert_p , where .Fa *assert_p must have been previously allocated by .Fn fido_assert_new . On return, .Fa *assert_p is set to NULL. Either .Fa assert_p or .Fa *assert_p may be NULL, in which case .Fn fido_assert_free is a NOP. .Pp The .Fn fido_assert_count function returns the number of statements in .Fa assert . .Pp The .Fn fido_assert_rp_id function returns a pointer to a NUL-terminated string holding the relying party ID of .Fa assert . .Pp The .Fn fido_assert_user_display_name , .Fn fido_assert_user_icon , and .Fn fido_assert_user_name , functions return pointers to the user display name, icon, and name attributes of statement .Fa idx in .Fa assert . If not NULL, the values returned by these functions point to NUL-terminated UTF-8 strings. .Pp The -.Fn fido_assert_user_id_ptr , .Fn fido_assert_authdata_ptr , -.Fn fido_assert_blob_ptr , -.Fn fido_assert_hmac_secret_ptr , -.Fn fido_assert_largeblob_key_ptr , +.Fn fido_assert_clientdata_hash_ptr , +.Fn fido_assert_id_ptr , +.Fn fido_assert_user_id_ptr , .Fn fido_assert_sig_ptr , +.Fn fido_assert_sigcount , and -.Fn fido_assert_id_ptr -functions return pointers to the user ID, CBOR-encoded -authenticator data, cred blob, hmac-secret, -.Dq largeBlobKey , -signature, and credential ID attributes of statement +.Fn fido_assert_flags +functions return pointers to the CBOR-encoded authenticator data, +client data hash, credential ID, user ID, signature, signature +count, and authenticator data flags of statement .Fa idx in .Fa assert . .Pp The -.Fn fido_assert_user_id_len , -.Fn fido_assert_authdata_len , -.Fn fido_assert_blob_len , -.Fn fido_assert_hmac_secret_len , -.Fn fido_assert_largeblob_key_len , -.Fn fido_assert_sig_len , -and -.Fn fido_assert_id_len -functions can be used to retrieve the corresponding length of a -specific attribute. -.Pp -The -.Fn fido_assert_sigcount -function can be used to obtain the signature counter of statement +.Fn fido_assert_hmac_secret_ptr +function returns a pointer to the hmac-secret attribute of statement .Fa idx in .Fa assert . +The HMAC Secret Extension +.Pq hmac-secret +is a CTAP 2.0 extension. .Pp The -.Fn fido_assert_flags -function returns the authenticator data flags of statement +.Fn fido_assert_blob_ptr +and +.Fn fido_assert_largeblob_key_ptr +functions return pointers to the +.Dq credBlob +and +.Dq largeBlobKey +attributes of statement .Fa idx in .Fa assert . +Credential Blob +.Pq credBlob +and +Large Blob Key +.Pq largeBlobKey +are CTAP 2.1 extensions. +.Pp +The +.Fn fido_assert_authdata_len , +.Fn fido_assert_clientdata_hash_len , +.Fn fido_assert_id_len , +.Fn fido_assert_user_id_len , +.Fn fido_assert_sig_len , +.Fn fido_assert_hmac_secret_len , +.Fn fido_assert_blob_len , +and +.Fn fido_assert_largeblob_key_len +functions return the length of a given attribute. .Pp Please note that the first statement in .Fa assert has an .Fa idx (index) value of 0. .Pp The authenticator data and signature parts of an assertion -statement are typically passed to a FIDO 2 server for verification. -.Pp -The -.Fn fido_assert_clientdata_hash_ptr -function returns a pointer to the client data hash of -.Fa assert . -The corresponding length can be obtained by -.Fn fido_assert_clientdata_hash_len . +statement are typically passed to a FIDO2 server for verification. .Sh RETURN VALUES The authenticator data returned by .Fn fido_assert_authdata_ptr is a CBOR-encoded byte string, as obtained from the authenticator. .Pp The +.Fn fido_assert_rp_id , .Fn fido_assert_user_display_name , .Fn fido_assert_user_icon , .Fn fido_assert_user_name , .Fn fido_assert_authdata_ptr , .Fn fido_assert_clientdata_hash_ptr , -.Fn fido_assert_hmac_secret_ptr , -.Fn fido_assert_largeblob_key_ptr , +.Fn fido_assert_id_ptr , .Fn fido_assert_user_id_ptr , +.Fn fido_assert_sig_ptr , +.Fn fido_assert_hmac_secret_ptr , +.Fn fido_assert_blob_ptr , and -.Fn fido_assert_sig_ptr -functions return NULL if the respective field in +.Fn fido_assert_largeblob_key_ptr +functions may return NULL if the respective field in .Fa assert is not set. If not NULL, returned pointers are guaranteed to exist until any API function that takes .Fa assert without the .Em const qualifier is invoked. .Sh SEE ALSO .Xr fido_assert_allow_cred 3 , .Xr fido_assert_set_authdata 3 , .Xr fido_assert_verify 3 , .Xr fido_dev_get_assert 3 , .Xr fido_dev_largeblob_get 3 diff --git a/contrib/libfido2/man/fido_assert_set_authdata.3 b/contrib/libfido2/man/fido_assert_set_authdata.3 index 2f2ca5b45d6e..51cdcc97c292 100644 --- a/contrib/libfido2/man/fido_assert_set_authdata.3 +++ b/contrib/libfido2/man/fido_assert_set_authdata.3 @@ -1,221 +1,236 @@ .\" Copyright (c) 2018 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. .\" .Dd $Mdocdate: May 23 2018 $ .Dt FIDO_ASSERT_SET_AUTHDATA 3 .Os .Sh NAME .Nm fido_assert_set_authdata , .Nm fido_assert_set_authdata_raw , .Nm fido_assert_set_clientdata , .Nm fido_assert_set_clientdata_hash , .Nm fido_assert_set_count , .Nm fido_assert_set_extensions , .Nm fido_assert_set_hmac_salt , .Nm fido_assert_set_hmac_secret , .Nm fido_assert_set_up , .Nm fido_assert_set_uv , .Nm fido_assert_set_rp , .Nm fido_assert_set_sig -.Nd set parameters of a FIDO 2 assertion +.Nd set parameters of a FIDO2 assertion .Sh SYNOPSIS .In fido.h .Bd -literal typedef enum { FIDO_OPT_OMIT = 0, /* use authenticator's default */ FIDO_OPT_FALSE, /* explicitly set option to false */ FIDO_OPT_TRUE, /* explicitly set option to true */ } fido_opt_t; .Ed .Ft int -.Fn fido_assert_set_authdata "fido_assert_t *assert" " size_t idx" "const unsigned char *ptr" "size_t len" +.Fn fido_assert_set_authdata "fido_assert_t *assert" "size_t idx" "const unsigned char *ptr" "size_t len" .Ft int -.Fn fido_assert_set_authdata_raw "fido_assert_t *assert" " size_t idx" "const unsigned char *ptr" "size_t len" +.Fn fido_assert_set_authdata_raw "fido_assert_t *assert" "size_t idx" "const unsigned char *ptr" "size_t len" .Ft int .Fn fido_assert_set_clientdata "fido_assert_t *assert" "const unsigned char *ptr" "size_t len" .Ft int .Fn fido_assert_set_clientdata_hash "fido_assert_t *assert" "const unsigned char *ptr" "size_t len" .Ft int .Fn fido_assert_set_count "fido_assert_t *assert" "size_t n" .Ft int .Fn fido_assert_set_extensions "fido_assert_t *assert" "int flags" .Ft int .Fn fido_assert_set_hmac_salt "fido_assert_t *assert" "const unsigned char *ptr" "size_t len" .Ft int -.Fn fido_assert_set_hmac_secret "fido_assert_t *assert" "const unsigned char *ptr" "size_t len" +.Fn fido_assert_set_hmac_secret "fido_assert_t *assert" "size_t idx" "const unsigned char *ptr" "size_t len" .Ft int .Fn fido_assert_set_up "fido_assert_t *assert" "fido_opt_t up" .Ft int .Fn fido_assert_set_uv "fido_assert_t *assert" "fido_opt_t uv" .Ft int .Fn fido_assert_set_rp "fido_assert_t *assert" "const char *id" .Ft int .Fn fido_assert_set_sig "fido_assert_t *assert" "size_t idx" "const unsigned char *ptr" "size_t len" .Sh DESCRIPTION The .Nm -set of functions define the various parameters of a FIDO 2 +set of functions define the various parameters of a FIDO2 assertion, allowing a .Fa fido_assert_t type to be prepared for a subsequent call to .Xr fido_dev_get_assert 3 or .Xr fido_assert_verify 3 . -For the complete specification of a FIDO 2 assertion and the format +For the complete specification of a FIDO2 assertion and the format of its constituent parts, please refer to the Web Authentication (webauthn) standard. .Pp The .Fn fido_assert_set_count function sets the number of assertion statements in .Fa assert to .Fa n . .Pp The .Fn fido_assert_set_authdata and .Fn fido_assert_set_sig functions set the authenticator data and signature parts of the statement with index .Fa idx of .Fa assert to .Fa ptr , where .Fa ptr points to .Fa len bytes. A copy of .Fa ptr is made, and no references to the passed pointer are kept. Please note that the first assertion statement of .Fa assert has an .Fa idx of .Em 0 . The authenticator data passed to .Fn fido_assert_set_authdata must be a CBOR-encoded byte string, as obtained from .Fn fido_assert_authdata_ptr . Alternatively, a raw binary blob may be passed to .Fn fido_assert_set_authdata_raw . .Pp The -.Fn fido_assert_set_clientdata_hash , -.Fn fido_assert_set_hmac_salt , -and -.Fn fido_assert_set_hmac_secret -functions set the client data hash and hmac-salt parts of +.Fn fido_assert_set_clientdata_hash +function sets the client data hash of .Fa assert to .Fa ptr , where .Fa ptr points to .Fa len bytes. A copy of .Fa ptr is made, and no references to the passed pointer are kept. .Pp The .Fn fido_assert_set_clientdata function allows an application to set the client data hash of .Fa assert by specifying the assertion's unhashed client data. This is required by Windows Hello, which calculates the client data hash internally. For compatibility with Windows Hello, applications should use .Fn fido_assert_set_clientdata instead of .Fn fido_assert_set_clientdata_hash . .Pp The .Fn fido_assert_set_rp function sets the relying party .Fa id of .Fa assert , where .Fa id is a NUL-terminated UTF-8 string. The content of .Fa id is copied, and no references to the passed pointer are kept. .Pp The .Fn fido_assert_set_extensions function sets the extensions of .Fa assert to the bitmask .Fa flags . At the moment, only the .Dv FIDO_EXT_CRED_BLOB , .Dv FIDO_EXT_HMAC_SECRET , and .Dv FIDO_EXT_LARGEBLOB_KEY extensions are supported. If .Fa flags is zero, the extensions of .Fa assert are cleared. .Pp The +.Fn fido_assert_set_hmac_salt +and +.Fn fido_assert_set_hmac_secret +functions set the hmac-salt and hmac-secret parts of +.Fa assert +to +.Fa ptr , +where +.Fa ptr +points to +.Fa len +bytes. +A copy of +.Fa ptr +is made, and no references to the passed pointer are kept. +The HMAC Secret +.Pq hmac-secret +Extension is a CTAP 2.0 extension. +The +.Fn fido_assert_set_hmac_secret +function is normally only useful when writing tests. +.Pp +The .Fn fido_assert_set_up and .Fn fido_assert_set_uv functions set the .Fa up (user presence) and .Fa uv (user verification) attributes of .Fa assert . Both are .Dv FIDO_OPT_OMIT by default, allowing the authenticator to use its default settings. .Pp Use of the .Nm set of functions may happen in two distinct situations: -when asking a FIDO device to produce a series of assertion +when asking a FIDO2 device to produce a series of assertion statements, prior to .Xr fido_dev_get_assert 3 -(i.e, in the context of a FIDO client), or when verifying assertion +(i.e, in the context of a FIDO2 client), or when verifying assertion statements using .Xr fido_assert_verify 3 -(i.e, in the context of a FIDO server). +(i.e, in the context of a FIDO2 server). .Pp -For a complete description of the generation of a FIDO 2 assertion -and its verification, please refer to the FIDO 2 specification. +For a complete description of the generation of a FIDO2 assertion +and its verification, please refer to the FIDO2 specification. An example of how to use the .Nm set of functions can be found in the .Pa examples/assert.c file shipped with .Em libfido2 . -.Pp -.Fn fido_assert_set_hmac_secret -is not normally useful in a FIDO client or server \(em it is provided -to enable testing other functionality that relies on retrieving the -HMAC secret from an assertion obtained from an authenticator. .Sh RETURN VALUES The .Nm functions return .Dv FIDO_OK on success. The error codes returned by the .Nm set of functions are defined in .In fido/err.h . .Sh SEE ALSO .Xr fido_assert_allow_cred 3 , .Xr fido_assert_verify 3 , .Xr fido_dev_get_assert 3 diff --git a/contrib/libfido2/man/fido_assert_verify.3 b/contrib/libfido2/man/fido_assert_verify.3 index 82e64e12e27a..8c0823703434 100644 --- a/contrib/libfido2/man/fido_assert_verify.3 +++ b/contrib/libfido2/man/fido_assert_verify.3 @@ -1,79 +1,79 @@ .\" Copyright (c) 2018 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. .\" .Dd $Mdocdate: May 24 2018 $ .Dt FIDO_ASSERT_VERIFY 3 .Os .Sh NAME .Nm fido_assert_verify -.Nd verifies the signature of a FIDO 2 assertion statement +.Nd verifies the signature of a FIDO2 assertion statement .Sh SYNOPSIS .In fido.h .Ft int -.Fn fido_assert_verify "fido_assert_t *assert" "size_t idx" "int cose_alg" "const void *pk" +.Fn fido_assert_verify "const fido_assert_t *assert" "size_t idx" "int cose_alg" "const void *pk" .Sh DESCRIPTION The .Fn fido_assert_verify function verifies whether the signature contained in statement index .Fa idx of .Fa assert matches the parameters of the assertion. Before using .Fn fido_assert_verify in a sensitive context, the reader is strongly encouraged to make -herself familiar with the FIDO 2 assertion statement process +herself familiar with the FIDO2 assertion statement process as defined in the Web Authentication (webauthn) standard. .Pp A brief description follows: .Pp The .Fn fido_assert_verify function verifies whether the client data hash, relying party ID, user presence and user verification attributes of .Fa assert have been attested by the holder of the private counterpart of the public key .Fa pk of COSE type .Fa cose_alg , where .Fa cose_alg is .Dv COSE_ES256 , .Dv COSE_RS256 , or .Dv COSE_EDDSA , and .Fa pk points to a .Vt es256_pk_t , .Vt rs256_pk_t , or .Vt eddsa_pk_t type accordingly. .Pp Please note that the first statement in .Fa assert has an .Fa idx of 0. .Sh RETURN VALUES The error codes returned by .Fn fido_assert_verify are defined in .In fido/err.h . If statement .Fa idx of .Fa assert passes verification with .Fa pk , then .Dv FIDO_OK is returned. .Sh SEE ALSO .Xr fido_assert_new 3 , .Xr fido_assert_set_authdata 3 diff --git a/contrib/libfido2/man/fido_bio_dev_get_info.3 b/contrib/libfido2/man/fido_bio_dev_get_info.3 index 1fe3e8ebc18f..7f1696fc12a4 100644 --- a/contrib/libfido2/man/fido_bio_dev_get_info.3 +++ b/contrib/libfido2/man/fido_bio_dev_get_info.3 @@ -1,122 +1,122 @@ .\" Copyright (c) 2019 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. .\" .Dd $Mdocdate: September 13 2019 $ .Dt FIDO_BIO_DEV_GET_INFO 3 .Os .Sh NAME .Nm fido_bio_dev_get_info , .Nm fido_bio_dev_enroll_begin , .Nm fido_bio_dev_enroll_continue , .Nm fido_bio_dev_enroll_cancel , .Nm fido_bio_dev_enroll_remove , .Nm fido_bio_dev_get_template_array , .Nm fido_bio_dev_set_template_name -.Nd FIDO 2 biometric authenticator API +.Nd FIDO2 biometric authenticator API .Sh SYNOPSIS .In fido.h .In fido/bio.h .Ft int .Fn fido_bio_dev_get_info "fido_dev_t *dev" "fido_bio_info_t *info" .Ft int .Fn fido_bio_dev_enroll_begin "fido_dev_t *dev" "fido_bio_template_t *template" "fido_bio_enroll_t *enroll" "uint32_t timeout_ms" "const char *pin" .Ft int .Fn fido_bio_dev_enroll_continue "fido_dev_t *dev" "const fido_bio_template_t *template" "fido_bio_enroll_t *enroll" "uint32_t timeout_ms" .Ft int .Fn fido_bio_dev_enroll_cancel "fido_dev_t *dev" .Ft int .Fn fido_bio_dev_enroll_remove "fido_dev_t *dev" "const fido_bio_template_t *template" "const char *pin" .Ft int .Fn fido_bio_dev_get_template_array "fido_dev_t *dev" "fido_bio_template_array_t *template_array" "const char *pin" .Ft int .Fn fido_bio_dev_set_template_name "fido_dev_t *dev" "const fido_bio_template_t *template" "const char *pin" .Sh DESCRIPTION The functions described in this page allow biometric templates on a FIDO2 authenticator to be listed, created, removed, and customised. Please note that not all FIDO2 authenticators support biometric enrollment. For a description of the types involved, please refer to .Xr fido_bio_info_new 3 , .Xr fido_bio_enroll_new 3 , and .Xr fido_bio_template 3 . .Pp The .Fn fido_bio_dev_get_info function populates .Fa info with sensor information from .Fa dev . .Pp The .Fn fido_bio_dev_enroll_begin function initiates a biometric enrollment on .Fa dev , instructing the authenticator to wait .Fa timeout_ms milliseconds. On success, .Fa template and .Fa enroll will be populated with the newly created template's information and enrollment status, respectively. .Pp The .Fn fido_bio_dev_enroll_continue function continues an ongoing enrollment on .Fa dev , instructing the authenticator to wait .Fa timeout_ms milliseconds. On success, .Fa enroll will be updated to reflect the status of the biometric enrollment. .Pp The .Fn fido_bio_dev_enroll_cancel function cancels an ongoing enrollment on .Fa dev . .Pp The .Fn fido_bio_dev_enroll_remove function removes .Fa template from .Fa dev . .Pp The .Fn fido_bio_dev_get_template_array function populates .Fa template_array with the templates currently enrolled on .Fa dev . .Pp The .Fn fido_bio_dev_set_template_name function sets the friendly name of .Fa template on .Fa dev . .Sh RETURN VALUES The error codes returned by .Fn fido_bio_dev_get_info , .Fn fido_bio_dev_enroll_begin , .Fn fido_bio_dev_enroll_continue , .Fn fido_bio_dev_enroll_cancel , .Fn fido_bio_dev_enroll_remove , .Fn fido_bio_dev_get_template_array , and .Fn fido_bio_dev_set_template_name are defined in .In fido/err.h . On success, .Dv FIDO_OK is returned. .Sh SEE ALSO .Xr fido_bio_enroll_new 3 , .Xr fido_bio_info_new 3 , .Xr fido_bio_template 3 diff --git a/contrib/libfido2/man/fido_bio_enroll_new.3 b/contrib/libfido2/man/fido_bio_enroll_new.3 index 3db3e7acd45d..37b842e644fd 100644 --- a/contrib/libfido2/man/fido_bio_enroll_new.3 +++ b/contrib/libfido2/man/fido_bio_enroll_new.3 @@ -1,95 +1,95 @@ .\" Copyright (c) 2019 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. .\" .Dd $Mdocdate: September 13 2019 $ .Dt FIDO_BIO_ENROLL_NEW 3 .Os .Sh NAME .Nm fido_bio_enroll_new , .Nm fido_bio_enroll_free , .Nm fido_bio_enroll_last_status , .Nm fido_bio_enroll_remaining_samples -.Nd FIDO 2 biometric enrollment API +.Nd FIDO2 biometric enrollment API .Sh SYNOPSIS .In fido.h .In fido/bio.h .Bd -literal #define FIDO_BIO_ENROLL_FP_GOOD 0x00 #define FIDO_BIO_ENROLL_FP_TOO_HIGH 0x01 #define FIDO_BIO_ENROLL_FP_TOO_LOW 0x02 #define FIDO_BIO_ENROLL_FP_TOO_LEFT 0x03 #define FIDO_BIO_ENROLL_FP_TOO_RIGHT 0x04 #define FIDO_BIO_ENROLL_FP_TOO_FAST 0x05 #define FIDO_BIO_ENROLL_FP_TOO_SLOW 0x06 #define FIDO_BIO_ENROLL_FP_POOR_QUALITY 0x07 #define FIDO_BIO_ENROLL_FP_TOO_SKEWED 0x08 #define FIDO_BIO_ENROLL_FP_TOO_SHORT 0x09 #define FIDO_BIO_ENROLL_FP_MERGE_FAILURE 0x0a #define FIDO_BIO_ENROLL_FP_EXISTS 0x0b #define FIDO_BIO_ENROLL_FP_DATABASE_FULL 0x0c #define FIDO_BIO_ENROLL_NO_USER_ACTIVITY 0x0d #define FIDO_BIO_ENROLL_NO_USER_PRESENCE_TRANSITION 0x0e .Ed .Ft fido_bio_enroll_t * .Fn fido_bio_enroll_new "void" .Ft void .Fn fido_bio_enroll_free "fido_bio_enroll_t **enroll_p" .Ft uint8_t .Fn fido_bio_enroll_last_status "const fido_bio_enroll_t *enroll" .Ft uint8_t .Fn fido_bio_enroll_remaining_samples "const fido_bio_enroll_t *enroll" .Sh DESCRIPTION -Ongoing FIDO 2 biometric enrollments are abstracted in +Ongoing FIDO2 biometric enrollments are abstracted in .Em libfido2 by the .Vt fido_bio_enroll_t type. .Pp The functions described in this page allow a .Vt fido_bio_enroll_t type to be allocated, deallocated, and inspected. For device operations on .Vt fido_bio_enroll_t , please refer to .Xr fido_bio_dev_get_info 3 . .Pp The .Fn fido_bio_enroll_new function returns a pointer to a newly allocated, empty .Vt fido_bio_enroll_t type. If memory cannot be allocated, NULL is returned. .Pp The .Fn fido_bio_enroll_free function releases the memory backing .Fa *enroll_p , where .Fa *enroll_p must have been previously allocated by .Fn fido_bio_enroll_new . On return, .Fa *enroll_p is set to NULL. Either .Fa enroll_p or .Fa *enroll_p may be NULL, in which case .Fn fido_bio_enroll_free is a NOP. .Pp The .Fn fido_bio_enroll_last_status function returns the enrollment status of .Fa enroll . .Pp The .Fn fido_bio_enroll_remaining_samples function returns the number of samples left for .Fa enroll to complete. .Sh SEE ALSO .Xr fido_bio_dev_get_info 3 , .Xr fido_bio_template 3 diff --git a/contrib/libfido2/man/fido_bio_info_new.3 b/contrib/libfido2/man/fido_bio_info_new.3 index c82733337b4e..a7435fd615e7 100644 --- a/contrib/libfido2/man/fido_bio_info_new.3 +++ b/contrib/libfido2/man/fido_bio_info_new.3 @@ -1,81 +1,81 @@ .\" Copyright (c) 2019 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. .\" .Dd $Mdocdate: September 13 2019 $ .Dt FIDO_BIO_INFO_NEW 3 .Os .Sh NAME .Nm fido_bio_info_new , .Nm fido_bio_info_free , .Nm fido_bio_info_type , .Nm fido_bio_info_max_samples -.Nd FIDO 2 biometric sensor information API +.Nd FIDO2 biometric sensor information API .Sh SYNOPSIS .In fido.h .In fido/bio.h .Ft fido_bio_info_t * .Fn fido_bio_info_new "void" .Ft void .Fn fido_bio_info_free "fido_bio_info_t **info_p" .Ft uint8_t .Fn fido_bio_info_type "const fido_bio_info_t *info" .Ft uint8_t .Fn fido_bio_info_max_samples "const fido_bio_info_t *info" .Sh DESCRIPTION Biometric sensor metadata is abstracted in .Em libfido2 by the .Vt fido_bio_info_t type. .Pp The functions described in this page allow a .Vt fido_bio_info_t type to be allocated, deallocated, and inspected. For device operations on .Vt fido_bio_info_t , please refer to .Xr fido_bio_dev_get_info 3 . .Pp The .Fn fido_bio_info_new function returns a pointer to a newly allocated, empty .Vt fido_bio_info_t type. If memory cannot be allocated, NULL is returned. .Pp The .Fn fido_bio_info_free function releases the memory backing .Fa *info_p , where .Fa *info_p must have been previously allocated by .Fn fido_bio_info_new . On return, .Fa *info_p is set to NULL. Either .Fa info_p or .Fa *info_p may be NULL, in which case .Fn fido_bio_info_free is a NOP. .Pp The .Fn fido_bio_info_type function returns the fingerprint sensor type, which is .Dv 1 for touch sensors, and .Dv 2 for swipe sensors. .Pp The .Fn fido_bio_info_max_samples function returns the maximum number of successful samples required for enrollment. .Sh SEE ALSO .Xr fido_bio_dev_get_info 3 , .Xr fido_bio_enroll_new 3 , .Xr fido_bio_template 3 diff --git a/contrib/libfido2/man/fido_bio_template.3 b/contrib/libfido2/man/fido_bio_template.3 index 12a379e9a46a..232f3ead2ab3 100644 --- a/contrib/libfido2/man/fido_bio_template.3 +++ b/contrib/libfido2/man/fido_bio_template.3 @@ -1,179 +1,179 @@ .\" Copyright (c) 2019 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. .\" .Dd $Mdocdate: September 13 2019 $ .Dt FIDO_BIO_TEMPLATE 3 .Os .Sh NAME .Nm fido_bio_template , .Nm fido_bio_template_array_count , .Nm fido_bio_template_array_free , .Nm fido_bio_template_array_new , .Nm fido_bio_template_free , .Nm fido_bio_template_id_len , .Nm fido_bio_template_id_ptr , .Nm fido_bio_template_name , .Nm fido_bio_template_new , .Nm fido_bio_template_set_id , .Nm fido_bio_template_set_name -.Nd FIDO 2 biometric template API +.Nd FIDO2 biometric template API .Sh SYNOPSIS .In fido.h .In fido/bio.h .Ft fido_bio_template_t * .Fn fido_bio_template_new "void" .Ft void .Fn fido_bio_template_free "fido_bio_template_t **template_p" .Ft const char * .Fn fido_bio_template_name "const fido_bio_template_t *template" .Ft const unsigned char * .Fn fido_bio_template_id_ptr "const fido_bio_template_t *template" .Ft size_t .Fn fido_bio_template_id_len "const fido_bio_template_t *template" .Ft int .Fn fido_bio_template_set_id "fido_bio_template_t *template" "const unsigned char *ptr" "size_t len" .Ft int .Fn fido_bio_template_set_name "fido_bio_template_t *template" "const char *name" .Ft fido_bio_template_array_t * .Fn fido_bio_template_array_new "void" .Ft void .Fn fido_bio_template_array_free "fido_bio_template_array_t **array_p" .Ft size_t .Fn fido_bio_template_array_count "const fido_bio_template_array_t *array" .Ft const fido_bio_template_t * .Fn fido_bio_template "const fido_bio_template_array_t *array" "size_t idx" .Sh DESCRIPTION -Existing FIDO 2 biometric enrollments are abstracted in +Existing FIDO2 biometric enrollments are abstracted in .Em libfido2 by the .Vt fido_bio_template_t and .Vt fido_bio_template_array_t types. .Pp The functions described in this page allow a .Vt fido_bio_template_t type to be allocated, deallocated, changed, and inspected, and a .Vt fido_bio_template_array_t type to be allocated, deallocated, and inspected. For device operations on .Vt fido_bio_template_t and .Vt fido_bio_template_array_t , please refer to .Xr fido_bio_dev_get_info 3 . .Pp The .Fn fido_bio_template_new function returns a pointer to a newly allocated, empty .Vt fido_bio_template_t type. If memory cannot be allocated, NULL is returned. .Pp The .Fn fido_bio_template_free function releases the memory backing .Fa *template_p , where .Fa *template_p must have been previously allocated by .Fn fido_bio_template_new . On return, .Fa *template_p is set to NULL. Either .Fa template_p or .Fa *template_p may be NULL, in which case .Fn fido_bio_template_free is a NOP. .Pp The .Fn fido_bio_template_name function returns a pointer to a NUL-terminated string containing the friendly name of .Fa template , or NULL if .Fa template does not have a friendly name set. .Pp The .Fn fido_bio_template_id_ptr function returns a pointer to the template id of .Fa template , or NULL if .Fa template does not have an id. The corresponding length can be obtained by .Fn fido_bio_template_id_len . .Pp The .Fn fido_bio_template_set_name function sets the friendly name of .Fa template to .Fa name . If .Fa name is NULL, the friendly name of .Fa template is unset. .Pp The .Fn fido_bio_template_array_new function returns a pointer to a newly allocated, empty .Vt fido_bio_template_array_t type. If memory cannot be allocated, NULL is returned. .Pp The .Fn fido_bio_template_array_free function releases the memory backing .Fa *array_p , where .Fa *array_p must have been previously allocated by .Fn fido_bio_template_array_new . On return, .Fa *array_p is set to NULL. Either .Fa array_p or .Fa *array_p may be NULL, in which case .Fn fido_bio_template_array_free is a NOP. .Pp The .Fn fido_bio_template_array_count function returns the number of templates in .Fa array . .Pp The .Fn fido_bio_template function returns a pointer to the template at index .Fa idx in .Fa array . Please note that the first template in .Fa array has an .Fa idx (index) value of 0. .Sh RETURN VALUES The error codes returned by .Fn fido_bio_template_set_id and .Fn fido_bio_template_set_name are defined in .In fido/err.h . On success, .Dv FIDO_OK is returned. .Sh SEE ALSO .Xr fido_bio_dev_get_info 3 , .Xr fido_bio_enroll_new 3 diff --git a/contrib/libfido2/man/fido_cbor_info_new.3 b/contrib/libfido2/man/fido_cbor_info_new.3 index ecba77291f53..86f2a887f99a 100644 --- a/contrib/libfido2/man/fido_cbor_info_new.3 +++ b/contrib/libfido2/man/fido_cbor_info_new.3 @@ -1,231 +1,232 @@ .\" Copyright (c) 2018 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. .\" .Dd $Mdocdate: May 24 2018 $ .Dt FIDO_CBOR_INFO_NEW 3 .Os .Sh NAME .Nm fido_cbor_info_new , .Nm fido_cbor_info_free , .Nm fido_dev_get_cbor_info , .Nm fido_cbor_info_aaguid_ptr , .Nm fido_cbor_info_extensions_ptr , .Nm fido_cbor_info_protocols_ptr , .Nm fido_cbor_info_transports_ptr , .Nm fido_cbor_info_versions_ptr , .Nm fido_cbor_info_options_name_ptr , .Nm fido_cbor_info_options_value_ptr , .Nm fido_cbor_info_algorithm_type , .Nm fido_cbor_info_algorithm_cose , .Nm fido_cbor_info_algorithm_count , .Nm fido_cbor_info_aaguid_len , .Nm fido_cbor_info_extensions_len , .Nm fido_cbor_info_protocols_len , .Nm fido_cbor_info_transports_len , .Nm fido_cbor_info_versions_len , .Nm fido_cbor_info_options_len , .Nm fido_cbor_info_maxmsgsiz , +.Nm fido_cbor_info_maxcredbloblen , .Nm fido_cbor_info_maxcredcntlst , .Nm fido_cbor_info_maxcredidlen , .Nm fido_cbor_info_fwversion -.Nd FIDO 2 CBOR Info API +.Nd FIDO2 CBOR Info API .Sh SYNOPSIS .In fido.h .Ft fido_cbor_info_t * .Fn fido_cbor_info_new "void" .Ft void .Fn fido_cbor_info_free "fido_cbor_info_t **ci_p" .Ft int .Fn fido_dev_get_cbor_info "fido_dev_t *dev" "fido_cbor_info_t *ci" .Ft const unsigned char * .Fn fido_cbor_info_aaguid_ptr "const fido_cbor_info_t *ci" .Ft char ** .Fn fido_cbor_info_extensions_ptr "const fido_cbor_info_t *ci" .Ft const uint8_t * .Fn fido_cbor_info_protocols_ptr "const fido_cbor_info_t *ci" .Ft char ** .Fn fido_cbor_info_transports_ptr "const fido_cbor_info_t *ci" .Ft char ** .Fn fido_cbor_info_versions_ptr "const fido_cbor_info_t *ci" .Ft char ** .Fn fido_cbor_info_options_name_ptr "const fido_cbor_info_t *ci" .Ft const bool * .Fn fido_cbor_info_options_value_ptr "const fido_cbor_info_t *ci" .Ft const char * .Fn fido_cbor_info_algorithm_type "const fido_cbor_info_t *ci" "size_t idx" .Ft int .Fn fido_cbor_info_algorithm_cose "const fido_cbor_info_t *ci" "size_t idx" .Ft size_t .Fn fido_cbor_info_algorithm_count "const fido_cbor_info_t *ci" .Ft size_t .Fn fido_cbor_info_aaguid_len "const fido_cbor_info_t *ci" .Ft size_t .Fn fido_cbor_info_extensions_len "const fido_cbor_info_t *ci" .Ft size_t .Fn fido_cbor_info_protocols_len "const fido_cbor_info_t *ci" .Ft size_t .Fn fido_cbor_info_transports_len "const fido_cbor_info_t *ci" .Ft size_t .Fn fido_cbor_info_versions_len "const fido_cbor_info_t *ci" .Ft size_t .Fn fido_cbor_info_options_len "const fido_cbor_info_t *ci" .Ft uint64_t .Fn fido_cbor_info_maxmsgsiz "const fido_cbor_info_t *ci" .Ft uint64_t .Fn fido_cbor_info_maxcredbloblen "const fido_cbor_info_t *ci" .Ft uint64_t .Fn fido_cbor_info_maxcredcntlst "const fido_cbor_info_t *ci" .Ft uint64_t .Fn fido_cbor_info_maxcredidlen "const fido_cbor_info_t *ci" .Ft uint64_t .Fn fido_cbor_info_fwversion "const fido_cbor_info_t *ci" .Sh DESCRIPTION The .Fn fido_cbor_info_new function returns a pointer to a newly allocated, empty .Vt fido_cbor_info_t type. If memory cannot be allocated, NULL is returned. .Pp The .Fn fido_cbor_info_free function releases the memory backing .Fa *ci_p , where .Fa *ci_p must have been previously allocated by .Fn fido_cbor_info_new . On return, .Fa *ci_p is set to NULL. Either .Fa ci_p or .Fa *ci_p may be NULL, in which case .Fn fido_cbor_info_free is a NOP. .Pp The .Fn fido_dev_get_cbor_info function transmits a .Dv CTAP_CBOR_GETINFO command to .Fa dev and fills .Fa ci with attributes retrieved from the command's response. The .Fn fido_dev_get_cbor_info function may block. .Pp The .Fn fido_cbor_info_aaguid_ptr , .Fn fido_cbor_info_extensions_ptr , .Fn fido_cbor_info_protocols_ptr , .Fn fido_cbor_info_transports_ptr , and .Fn fido_cbor_info_versions_ptr functions return pointers to the authenticator attestation GUID, supported extensions, PIN protocol, transports, and CTAP version strings of .Fa ci . The corresponding length of a given attribute can be obtained by .Fn fido_cbor_info_aaguid_len , .Fn fido_cbor_info_extensions_len , .Fn fido_cbor_info_protocols_len , .Fn fido_cbor_info_transports_len , or .Fn fido_cbor_info_versions_len . .Pp The .Fn fido_cbor_info_options_name_ptr and .Fn fido_cbor_info_options_value_ptr functions return pointers to the array of option names and their respective values in .Fa ci . The length of the options array is returned by .Fn fido_cbor_info_options_len . .Pp The .Fn fido_cbor_info_algorithm_count function returns the number of supported algorithms in .Fa ci . The .Fn fido_cbor_info_algorithm_cose function returns the COSE identifier of algorithm .Fa idx in .Fa ci , or 0 if the COSE identifier is unknown or unset. The .Fn fido_cbor_info_algorithm_type function returns the type of algorithm .Fa idx in .Fa ci , or NULL if the type is unset. Please note that the first algorithm in .Fa ci has an .Fa idx (index) value of 0. .Pp The .Fn fido_cbor_info_maxmsgsiz function returns the maximum message size attribute of .Fa ci . .Pp The .Fn fido_cbor_info_maxcredbloblen function returns the maximum .Dq credBlob length in bytes supported by the authenticator as reported in .Fa ci . .Pp The .Fn fido_cbor_info_maxcredcntlst function returns the maximum supported number of credentials in a single credential ID list as reported in .Fa ci . .Pp The .Fn fido_cbor_info_maxcredidlen function returns the maximum supported length of a credential ID as reported in .Fa ci . .Pp The .Fn fido_cbor_info_fwversion function returns the firmware version attribute of .Fa ci . .Pp A complete example of how to use these functions can be found in the .Pa example/info.c file shipped with .Em libfido2 . .Sh RETURN VALUES The .Fn fido_cbor_info_aaguid_ptr , .Fn fido_cbor_info_extensions_ptr , .Fn fido_cbor_info_protocols_ptr , .Fn fido_cbor_info_transports_ptr , .Fn fido_cbor_info_versions_ptr , .Fn fido_cbor_info_options_name_ptr , and .Fn fido_cbor_info_options_value_ptr functions return NULL if the respective field in .Fa ci is absent. If not NULL, returned pointers are guaranteed to exist until any API function that takes .Fa ci without the .Em const qualifier is invoked. .Sh SEE ALSO .Xr fido_dev_open 3 diff --git a/contrib/libfido2/man/fido_cred_exclude.3 b/contrib/libfido2/man/fido_cred_exclude.3 index 700d6afd8746..2aa87f28976f 100644 --- a/contrib/libfido2/man/fido_cred_exclude.3 +++ b/contrib/libfido2/man/fido_cred_exclude.3 @@ -1,60 +1,60 @@ .\" Copyright (c) 2018 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. .\" .Dd $Mdocdate: May 23 2018 $ .Dt FIDO_CRED_EXCLUDE 3 .Os .Sh NAME .Nm fido_cred_exclude .Nd appends a credential ID to a credential's list of excluded credentials .Sh SYNOPSIS .In fido.h .Ft int .Fn fido_cred_exclude "fido_cred_t *cred" "const unsigned char *ptr" "size_t len" .Sh DESCRIPTION The .Fn fido_cred_exclude function adds .Fa ptr to the list of credentials excluded by .Fa cred , where .Fa ptr points to a credential ID of .Fa len bytes. A copy of .Fa ptr is made, and no references to the passed pointer are kept. If .Fn fido_cred_exclude fails, the existing list of excluded credentials is preserved. .Pp If .Nm returns success and .Fa cred is later passed to .Xr fido_dev_make_cred 3 on a device that contains the credential denoted by .Fa ptr , then .Xr fido_dev_make_cred 3 will fail. .Pp -For the format of a FIDO 2 credential ID, please refer to the +For the format of a FIDO2 credential ID, please refer to the Web Authentication (webauthn) standard. .Sh RETURN VALUES The error codes returned by .Fn fido_cred_exclude are defined in .In fido/err.h . On success, .Dv FIDO_OK is returned. .Sh SEE ALSO .Xr fido_cred_new 3 , .Xr fido_cred_set_authdata 3 , .Xr fido_dev_make_cred 3 diff --git a/contrib/libfido2/man/fido_cred_new.3 b/contrib/libfido2/man/fido_cred_new.3 index d779cb2c659d..ee7ac96a6b0b 100644 --- a/contrib/libfido2/man/fido_cred_new.3 +++ b/contrib/libfido2/man/fido_cred_new.3 @@ -1,293 +1,293 @@ .\" 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. .\" .Dd $Mdocdate: May 23 2018 $ .Dt FIDO_CRED_NEW 3 .Os .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 , .Nm fido_cred_rp_name , .Nm fido_cred_user_name , .Nm fido_cred_display_name , .Nm fido_cred_authdata_ptr , .Nm fido_cred_authdata_raw_ptr , .Nm fido_cred_clientdata_hash_ptr , .Nm fido_cred_id_ptr , .Nm fido_cred_aaguid_ptr , .Nm fido_cred_largeblob_key_ptr , .Nm fido_cred_pubkey_ptr , .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 , .Nm fido_cred_id_len , .Nm fido_cred_aaguid_len , .Nm fido_cred_largeblob_key_len , .Nm fido_cred_pubkey_len , .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 -.Nd FIDO 2 credential API +.Nd FIDO2 credential API .Sh SYNOPSIS .In fido.h .Ft fido_cred_t * .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 "const fido_cred_t *cred" .Ft const char * .Fn fido_cred_fmt "const fido_cred_t *cred" .Ft const char * .Fn fido_cred_rp_id "const fido_cred_t *cred" .Ft const char * .Fn fido_cred_rp_name "const fido_cred_t *cred" .Ft const char * .Fn fido_cred_user_name "const fido_cred_t *cred" .Ft const char * .Fn fido_cred_display_name "const fido_cred_t *cred" .Ft const unsigned char * .Fn fido_cred_authdata_ptr "const fido_cred_t *cred" .Ft const unsigned char * .Fn fido_cred_authdata_raw_ptr "const fido_cred_t *cred" .Ft const unsigned char * .Fn fido_cred_clientdata_hash_ptr "const fido_cred_t *cred" .Ft const unsigned char * .Fn fido_cred_id_ptr "const fido_cred_t *cred" .Ft const unsigned char * .Fn fido_cred_aaguid_ptr "const fido_cred_t *cred" .Ft const unsigned char * .Fn fido_cred_largeblob_key_ptr "const fido_cred_t *cred" .Ft const unsigned char * .Fn fido_cred_pubkey_ptr "const fido_cred_t *cred" .Ft const unsigned char * .Fn fido_cred_sig_ptr "const fido_cred_t *cred" .Ft const unsigned char * .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 .Fn fido_cred_authdata_raw_len "const fido_cred_t *cred" .Ft size_t .Fn fido_cred_clientdata_hash_len "const fido_cred_t *cred" .Ft size_t .Fn fido_cred_id_len "const fido_cred_t *cred" .Ft size_t .Fn fido_cred_aaguid_len "const fido_cred_t *cred" .Ft size_t .Fn fido_cred_largeblob_key_len "const fido_cred_t *cred" .Ft size_t .Fn fido_cred_pubkey_len "const fido_cred_t *cred" .Ft size_t .Fn fido_cred_sig_len "const fido_cred_t *cred" .Ft size_t .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 .Fn fido_cred_flags "const fido_cred_t *cred" .Ft uint32_t .Fn fido_cred_sigcount "const fido_cred_t *cred" .Sh DESCRIPTION -FIDO 2 credentials are abstracted in +FIDO2 credentials are abstracted in .Em libfido2 by the .Vt fido_cred_t type. The functions described in this page allow a .Vt fido_cred_t type to be allocated, deallocated, and inspected. For other operations on .Vt fido_cred_t , please refer to .Xr fido_cred_set_authdata 3 , .Xr fido_cred_exclude 3 , .Xr fido_cred_verify 3 , and .Xr fido_dev_make_cred 3 . .Pp The .Fn fido_cred_new function returns a pointer to a newly allocated, empty .Vt fido_cred_t type. If memory cannot be allocated, NULL is returned. .Pp The .Fn fido_cred_free function releases the memory backing .Fa *cred_p , where .Fa *cred_p must have been previously allocated by .Fn fido_cred_new . On return, .Fa *cred_p is set to NULL. Either .Fa cred_p or .Fa *cred_p may be NULL, in which case .Fn fido_cred_free is a NOP. .Pp -If the FIDO 2.1 +If the CTAP 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 +If the CTAP 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 protection policies understood by .Em libfido2 . .Pp The .Fn fido_cred_fmt function returns a pointer to a NUL-terminated string containing the format of .Fa cred , or NULL if .Fa cred does not have a format set. .Pp The .Fn fido_cred_rp_id , .Fn fido_cred_rp_name , .Fn fido_cred_user_name , and .Fn fido_cred_display_name functions return pointers to NUL-terminated strings holding the relying party ID, relying party name, user name, and user display name attributes of .Fa cred , or NULL if the respective entry is not set. .Pp The .Fn fido_cred_authdata_ptr , .Fn fido_cred_authdata_raw_ptr , .Fn fido_cred_clientdata_hash_ptr , .Fn fido_cred_id_ptr , .Fn fido_cred_aaguid_ptr , .Fn fido_cred_largeblob_key_ptr , .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_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, x509 certificate, and attestation statement parts of .Fa cred , or NULL if the respective entry is not set. .Pp The corresponding length can be obtained by .Fn fido_cred_authdata_len , .Fn fido_cred_authdata_raw_len , .Fn fido_cred_clientdata_hash_len , .Fn fido_cred_id_len , .Fn fido_cred_aaguid_len , .Fn fido_cred_largeblob_key_len , .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_attstmt_len . .Pp The authenticator data, x509 certificate, and signature parts of a -credential are typically passed to a FIDO 2 server for verification. +credential are typically passed to a FIDO2 server for verification. .Pp The .Fn fido_cred_type function returns the COSE algorithm of .Fa cred . .Pp The .Fn fido_cred_flags function returns the authenticator data flags of .Fa cred . .Pp The .Fn fido_cred_sigcount function returns the authenticator data signature counter of .Fa cred . .Sh RETURN VALUES The authenticator data returned by .Fn fido_cred_authdata_ptr is a CBOR-encoded byte string, as obtained from the authenticator. To obtain the decoded byte string, use .Fn fido_cred_authdata_raw_ptr . .Pp If not NULL, pointers returned by .Fn fido_cred_fmt , .Fn fido_cred_authdata_ptr , .Fn fido_cred_clientdata_hash_ptr , .Fn fido_cred_id_ptr , .Fn fido_cred_aaguid_ptr , .Fn fido_cred_largeblob_key_ptr , .Fn fido_cred_pubkey_ptr , .Fn fido_cred_sig_ptr , and .Fn fido_cred_x5c_ptr are guaranteed to exist until any API function that takes .Fa cred without the .Em const 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 , .Xr fido_dev_make_cred 3 diff --git a/contrib/libfido2/man/fido_cred_set_authdata.3 b/contrib/libfido2/man/fido_cred_set_authdata.3 index 7bae51f43674..921a682f8f91 100644 --- a/contrib/libfido2/man/fido_cred_set_authdata.3 +++ b/contrib/libfido2/man/fido_cred_set_authdata.3 @@ -1,354 +1,354 @@ .\" 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. .\" .Dd $Mdocdate: May 23 2018 $ .Dt FIDO_CRED_SET_AUTHDATA 3 .Os .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 , .Nm fido_cred_set_clientdata , .Nm fido_cred_set_clientdata_hash , .Nm fido_cred_set_rp , .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 , .Nm fido_cred_set_fmt , .Nm fido_cred_set_type -.Nd set parameters of a FIDO 2 credential +.Nd set parameters of a FIDO2 credential .Sh SYNOPSIS .In fido.h .Bd -literal typedef enum { FIDO_OPT_OMIT = 0, /* use authenticator's default */ FIDO_OPT_FALSE, /* explicitly set option to false */ FIDO_OPT_TRUE, /* explicitly set option to true */ } fido_opt_t; .Ed .Ft int .Fn fido_cred_set_authdata "fido_cred_t *cred" "const unsigned char *ptr" "size_t len" .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" .Ft int .Fn fido_cred_set_id "fido_cred_t *cred" "const unsigned char *ptr" "size_t len" .Ft int .Fn fido_cred_set_clientdata "fido_cred_t *cred" "const unsigned char *ptr" "size_t len" .Ft int .Fn fido_cred_set_clientdata_hash "fido_cred_t *cred" "const unsigned char *ptr" "size_t len" .Ft int .Fn fido_cred_set_rp "fido_cred_t *cred" "const char *id" "const char *name" .Ft int .Fn fido_cred_set_user "fido_cred_t *cred" "const unsigned char *user_id" "size_t user_id_len" "const char *name" "const char *display_name" "const char *icon" .Ft int .Fn fido_cred_set_extensions "fido_cred_t *cred" "int flags" .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" .Ft int .Fn fido_cred_set_uv "fido_cred_t *cred" "fido_opt_t uv" .Ft int .Fn fido_cred_set_fmt "fido_cred_t *cred" "const char *ptr" .Ft int .Fn fido_cred_set_type "fido_cred_t *cred" "int cose_alg" .Sh DESCRIPTION The .Nm -set of functions define the various parameters of a FIDO 2 +set of functions define the various parameters of a FIDO2 credential, allowing a .Fa fido_cred_t type to be prepared for a subsequent call to .Xr fido_dev_make_cred 3 or .Xr fido_cred_verify 3 . -For the complete specification of a FIDO 2 credential and the format +For the complete specification of a FIDO2 credential and the format of its constituent parts, please refer to the Web Authentication (webauthn) standard. .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 statement, attestation certificate, attestation signature, id, and client data hash parts of .Fa cred to .Fa ptr , where .Fa ptr points to .Fa len 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 . An application calling .Fn fido_cred_set_authdata does not need to call .Fn fido_cred_set_id . 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 .Fa cred by specifying the credential's unhashed client data. This is required by Windows Hello, which calculates the client data hash internally. For compatibility with Windows Hello, applications should use .Fn fido_cred_set_clientdata instead of .Fn fido_cred_set_clientdata_hash . .Pp The .Fn fido_cred_set_rp function sets the relying party .Fa id and .Fa name parameters of .Fa cred , where .Fa id and .Fa name are NUL-terminated UTF-8 strings. The contents of .Fa id and .Fa name are copied, and no references to the passed pointers are kept. .Pp The .Fn fido_cred_set_user function sets the user attributes of .Fa cred , where .Fa user_id points to .Fa user_id_len bytes and .Fa name , .Fa display_name , and .Fa icon are NUL-terminated UTF-8 strings. The contents of .Fa user_id , .Fa name , .Fa display_name , and .Fa icon are copied, and no references to the passed pointers are kept. Previously set user attributes are flushed. The .Fa user_id , .Fa name , .Fa display_name , and .Fa icon parameters may be NULL. .Pp The .Fn fido_cred_set_extensions function sets the extensions of .Fa cred to the bitmask .Fa flags . 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. If .Fa flags is zero, the extensions of .Fa cred are cleared. .Pp The .Fn fido_cred_set_blob function sets the .Dq credBlob to be stored with .Fa cred to the data pointed to by .Fa ptr , which must be .Fa len bytes long. .Pp The .Fn fido_cred_set_pin_minlen -function enables the FIDO 2.1 +function enables the CTAP 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 enables the FIDO 2.1 +function enables the CTAP 2.1 .Dv FIDO_EXT_CRED_PROTECT extension on .Fa cred and sets the protection of .Fa cred to the scalar .Fa prot . At the moment, only the .Dv FIDO_CRED_PROT_UV_OPTIONAL , .Dv FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID , and .Dv FIDO_CRED_PROT_UV_REQUIRED protections are supported. If .Fa prot is zero, the protection of .Fa cred is cleared. .Pp The .Fn fido_cred_set_rk and .Fn fido_cred_set_uv functions set the .Em rk .Pq resident/discoverable key and .Em uv .Pq user verification attributes of .Fa cred . Both are .Dv FIDO_OPT_OMIT by default, allowing the authenticator to use its default settings. .Pp The .Fn fido_cred_set_fmt function sets the attestation format of .Fa cred to .Fa fmt , where .Fa fmt must be .Vt "packed" .Pq the format used in FIDO2 , .Vt "fido-u2f" .Pq the format used by U2F , or .Vt "none" . A copy of .Fa fmt is made, and no references to the passed pointer are kept. Note that not all authenticators support FIDO2 and therefore may not be able to generate .Vt "packed" . .Pp The .Fn fido_cred_set_type function sets the type of .Fa cred to .Fa cose_alg , where .Fa cose_alg is .Dv COSE_ES256 , .Dv COSE_RS256 , or .Dv COSE_EDDSA . The type of a credential may only be set once. Note that not all authenticators support COSE_RS256 or COSE_EDDSA. .Pp Use of the .Nm set of functions may happen in two distinct situations: -when generating a new credential on a FIDO device, prior to +when generating a new credential on a FIDO2 device, prior to .Xr fido_dev_make_cred 3 -(i.e, in the context of a FIDO client), or when validating +(i.e, in the context of a FIDO2 client), or when validating a generated credential using .Xr fido_cred_verify 3 -(i.e, in the context of a FIDO server). +(i.e, in the context of a FIDO2 server). .Pp -For a complete description of the generation of a FIDO 2 credential -and its verification, please refer to the FIDO 2 specification. +For a complete description of the generation of a FIDO2 credential +and its verification, please refer to the FIDO2 specification. A concrete utilisation example of the .Nm set of functions can be found in the .Pa cred.c example shipped with .Em libfido2 . .Sh RETURN VALUES The error codes returned by the .Nm set of functions are defined in .In fido/err.h . On success, .Dv FIDO_OK is returned. .Sh SEE ALSO .Xr fido_cred_exclude 3 , .Xr fido_cred_verify 3 , .Xr fido_dev_make_cred 3 diff --git a/contrib/libfido2/man/fido_cred_verify.3 b/contrib/libfido2/man/fido_cred_verify.3 index ec95e134572e..696dec293e4d 100644 --- a/contrib/libfido2/man/fido_cred_verify.3 +++ b/contrib/libfido2/man/fido_cred_verify.3 @@ -1,69 +1,91 @@ .\" 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. .\" .Dd $Mdocdate: May 23 2018 $ .Dt FIDO_CRED_VERIFY 3 .Os .Sh NAME -.Nm fido_cred_verify -.Nd verifies the attestation signature of a FIDO 2 credential +.Nm fido_cred_verify , +.Nm fido_cred_verify_self +.Nd verify the attestation signature of a FIDO2 credential .Sh SYNOPSIS .In fido.h .Ft int .Fn fido_cred_verify "const fido_cred_t *cred" +.Ft int +.Fn fido_cred_verify_self "const fido_cred_t *cred" .Sh DESCRIPTION The .Fn fido_cred_verify -function verifies whether the attestation signature contained in +and +.Fn fido_cred_verify_self +functions verify whether the attestation signature contained in .Fa cred matches the attributes of the credential. Before using .Fn fido_cred_verify +or +.Fn fido_cred_verify_self in a sensitive context, the reader is strongly encouraged to make -herself familiar with the FIDO 2 credential attestation process +herself familiar with the FIDO2 credential attestation process as defined in the Web Authentication (webauthn) standard. .Pp -A brief description follows: -.Pp The .Fn fido_cred_verify function verifies whether the client data hash, relying party ID, 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. .Pp Please note that the x509 certificate itself is not verified. .Pp The attestation statement formats supported by .Fn fido_cred_verify are .Em packed , .Em fido-u2f , and .Em tpm . The attestation type implemented by .Fn fido_cred_verify is .Em Basic Attestation . +.Pp +The +.Fn fido_cred_verify_self +function verifies whether the client data hash, relying party ID, +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 credential's private key. +.Pp +The attestation statement formats supported by +.Fn fido_cred_verify_self +are +.Em packed +and +.Em fido-u2f . +The attestation type implemented by +.Fn fido_cred_verify_self +is +.Em Self Attestation . +.Pp Other attestation formats and types are not supported. .Sh RETURN VALUES The error codes returned by .Fn fido_cred_verify +and +.Fn fido_cred_verify_self are defined in .In fido/err.h . If .Fa cred -does not contain attestation data, then -.Dv FIDO_ERR_INVALID_ARGUMENT -is returned. -If -.Fa cred passes verification, then .Dv FIDO_OK is returned. .Sh SEE ALSO .Xr fido_cred_new 3 , .Xr fido_cred_set_authdata 3 diff --git a/contrib/libfido2/man/fido_credman_metadata_new.3 b/contrib/libfido2/man/fido_credman_metadata_new.3 index 31f240fbbe8c..cd6722e24aa8 100644 --- a/contrib/libfido2/man/fido_credman_metadata_new.3 +++ b/contrib/libfido2/man/fido_credman_metadata_new.3 @@ -1,326 +1,326 @@ .\" 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. .\" .Dd $Mdocdate: June 28 2019 $ .Dt FIDO_CREDMAN_METADATA_NEW 3 .Os .Sh NAME .Nm fido_credman_metadata_new , .Nm fido_credman_rk_new , .Nm fido_credman_rp_new , .Nm fido_credman_metadata_free , .Nm fido_credman_rk_free , .Nm fido_credman_rp_free , .Nm fido_credman_rk_existing , .Nm fido_credman_rk_remaining , .Nm fido_credman_rk , .Nm fido_credman_rk_count , .Nm fido_credman_rp_id , .Nm fido_credman_rp_name , .Nm fido_credman_rp_count , .Nm fido_credman_rp_id_hash_ptr , .Nm fido_credman_rp_id_hash_len , .Nm fido_credman_get_dev_metadata , .Nm fido_credman_get_dev_rk , .Nm fido_credman_set_dev_rk , .Nm fido_credman_del_dev_rk , .Nm fido_credman_get_dev_rp -.Nd FIDO 2 credential management API +.Nd FIDO2 credential management API .Sh SYNOPSIS .In fido.h .In fido/credman.h .Ft fido_credman_metadata_t * .Fn fido_credman_metadata_new "void" .Ft fido_credman_rk_t * .Fn fido_credman_rk_new "void" .Ft fido_credman_rp_t * .Fn fido_credman_rp_new "void" .Ft void .Fn fido_credman_metadata_free "fido_credman_metadata_t **metadata_p" .Ft void .Fn fido_credman_rk_free "fido_credman_rk_t **rk_p" .Ft void .Fn fido_credman_rp_free "fido_credman_rp_t **rp_p" .Ft uint64_t .Fn fido_credman_rk_existing "const fido_credman_metadata_t *metadata" .Ft uint64_t .Fn fido_credman_rk_remaining "const fido_credman_metadata_t *metadata" .Ft const fido_cred_t * .Fn fido_credman_rk "const fido_credman_rk_t *rk" "size_t idx" .Ft size_t .Fn fido_credman_rk_count "const fido_credman_rk_t *rk" .Ft const char * .Fn fido_credman_rp_id "const fido_credman_rp_t *rp" "size_t idx" .Ft const char * .Fn fido_credman_rp_name "const fido_credman_rp_t *rp" "size_t idx" .Ft size_t .Fn fido_credman_rp_count "const fido_credman_rp_t *rp" .Ft const unsigned char * .Fn fido_credman_rp_id_hash_ptr "const fido_credman_rp_t *rp" "size_t idx" .Ft size_t .Fn fido_credman_rp_id_hash_len "const fido_credman_rp_t *" "size_t idx" .Ft int .Fn fido_credman_get_dev_metadata "fido_dev_t *dev" "fido_credman_metadata_t *metadata" "const char *pin" .Ft int .Fn fido_credman_get_dev_rk "fido_dev_t *dev" "const char *rp_id" "fido_credman_rk_t *rk" "const char *pin" .Ft int .Fn fido_credman_set_dev_rk "fido_dev_t *dev" "fido_cred_t *cred" "const char *pin" .Ft int .Fn fido_credman_del_dev_rk "fido_dev_t *dev" "const unsigned char *cred_id" "size_t cred_id_len" "const char *pin" .Ft int .Fn fido_credman_get_dev_rp "fido_dev_t *dev" "fido_credman_rp_t *rp" "const char *pin" .Sh DESCRIPTION The credential management API of .Em libfido2 allows resident credentials on a FIDO2 authenticator to be listed, inspected, modified, and removed. Please note that not all FIDO2 authenticators support credential management. To obtain information on what an authenticator supports, please refer to .Xr fido_cbor_info_new 3 . .Pp The .Vt fido_credman_metadata_t type abstracts credential management metadata. .Pp The .Fn fido_credman_metadata_new function returns a pointer to a newly allocated, empty .Vt fido_credman_metadata_t type. If memory cannot be allocated, NULL is returned. .Pp The .Fn fido_credman_metadata_free function releases the memory backing .Fa *metadata_p , where .Fa *metadata_p must have been previously allocated by .Fn fido_credman_metadata_new . On return, .Fa *metadata_p is set to NULL. Either .Fa metadata_p or .Fa *metadata_p may be NULL, in which case .Fn fido_credman_metadata_free is a NOP. .Pp The .Fn fido_credman_get_dev_metadata function populates .Fa metadata with information retrieved from .Fa dev . A valid .Fa pin must be provided. .Pp The .Fn fido_credman_rk_existing function inspects .Fa metadata and returns the number of resident credentials on the authenticator. The .Fn fido_credman_rk_remaining function inspects .Fa metadata and returns the estimated number of resident credentials that can be created on the authenticator. .Pp The .Vt fido_credman_rk_t type abstracts the set of resident credentials belonging to a given relying party. .Pp The .Fn fido_credman_rk_new function returns a pointer to a newly allocated, empty .Vt fido_credman_rk_t type. If memory cannot be allocated, NULL is returned. .Pp The .Fn fido_credman_rk_free function releases the memory backing .Fa *rk_p , where .Fa *rk_p must have been previously allocated by .Fn fido_credman_rk_new . On return, .Fa *rk_p is set to NULL. Either .Fa rk_p or .Fa *rk_p may be NULL, in which case .Fn fido_credman_rk_free is a NOP. .Pp The .Fn fido_credman_get_dev_rk function populates .Fa rk with the set of resident credentials belonging to .Fa rp_id in .Fa dev . A valid .Fa pin must be provided. .Pp The .Fn fido_credman_rk_count function returns the number of resident credentials in .Fa rk . The .Fn fido_credman_rk function returns a pointer to the credential at index .Fa idx in .Fa rk . Please note that the first credential in .Fa rk has an .Fa idx (index) value of 0. .Pp The .Fn fido_credman_set_dev_rk function updates the credential pointed to by .Fa cred in .Fa dev . The credential id and user id attributes of .Fa cred must be set. See .Xr fido_cred_set_id 3 and .Xr fido_cred_set_user 3 for details. Only a credential's user attributes (name, display name) may be updated at this time. .Pp The .Fn fido_credman_del_dev_rk function deletes the resident credential identified by .Fa cred_id from .Fa dev , where .Fa cred_id points to .Fa cred_id_len bytes. A valid .Fa pin must be provided. .Pp The .Vt fido_credman_rp_t type abstracts information about a relying party. .Pp The .Fn fido_credman_rp_new function returns a pointer to a newly allocated, empty .Vt fido_credman_rp_t type. If memory cannot be allocated, NULL is returned. .Pp The .Fn fido_credman_rp_free function releases the memory backing .Fa *rp_p , where .Fa *rp_p must have been previously allocated by .Fn fido_credman_rp_new . On return, .Fa *rp_p is set to NULL. Either .Fa rp_p or .Fa *rp_p may be NULL, in which case .Fn fido_credman_rp_free is a NOP. .Pp The .Fn fido_credman_get_dev_rp function populates .Fa rp with information about relying parties with resident credentials in .Fa dev . A valid .Fa pin must be provided. .Pp The .Fn fido_credman_rp_count function returns the number of relying parties in .Fa rp . .Pp The .Fn fido_credman_rp_id and .Fn fido_credman_rp_name functions return pointers to the id and name of relying party .Fa idx in .Fa rp . If not NULL, the values returned by these functions point to NUL-terminated UTF-8 strings. Please note that the first relying party in .Fa rp has an .Fa idx (index) value of 0. .Pp The .Fn fido_credman_rp_id_hash_ptr function returns a pointer to the hashed id of relying party .Fa idx in .Fa rp . The corresponding length can be obtained by .Fn fido_credman_rp_id_hash_len . Please note that the first relying party in .Fa rp has an .Fa idx (index) value of 0. .Sh RETURN VALUES The .Fn fido_credman_get_dev_metadata , .Fn fido_credman_get_dev_rk , .Fn fido_credman_set_dev_rk , .Fn fido_credman_del_dev_rk , and -.Fn fido_credman_get_dev_rp +.Fn fido_credman_get_dev_rp functions return .Dv FIDO_OK on success. On error, a different error code defined in .In fido/err.h is returned. Functions returning pointers are not guaranteed to succeed, and should have their return values checked for NULL. .Sh SEE ALSO .Xr fido_cbor_info_new 3 , .Xr fido_cred_new 3 , .Xr fido_dev_supports_credman 3 .Sh CAVEATS Resident credentials are called .Dq discoverable credentials -in FIDO 2.1. +in CTAP 2.1. diff --git a/contrib/libfido2/man/fido_dev_enable_entattest.3 b/contrib/libfido2/man/fido_dev_enable_entattest.3 index 17962d3d35d5..bfc1b2834e55 100644 --- a/contrib/libfido2/man/fido_dev_enable_entattest.3 +++ b/contrib/libfido2/man/fido_dev_enable_entattest.3 @@ -1,121 +1,121 @@ .\" Copyright (c) 2020 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. .\" .Dd $Mdocdate: September 22 2020 $ .Dt FIDO_DEV_ENABLE_ENTATTEST 3 .Os .Sh NAME .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_rpid -.Nd FIDO 2.1 configuration authenticator API +.Nd CTAP 2.1 configuration authenticator API .Sh SYNOPSIS .In fido.h .In fido/config.h .Ft int .Fn fido_dev_enable_entattest "fido_dev_t *dev" "const char *pin" .Ft int .Fn fido_dev_toggle_always_uv "fido_dev_t *dev" "const char *pin" .Ft int .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. +CTAP 2.1 authenticator. .Pp The .Fn fido_dev_enable_entattest function enables the .Em Enterprise Attestation feature on .Fa dev . .Em Enterprise Attestation instructs the authenticator to include uniquely identifying information in subsequent attestation statements. The .Fa pin parameter may be NULL if .Fa dev does not have a PIN set. .Pp The .Fn fido_dev_toggle_always_uv function toggles the .Dq user verification always feature on .Fa dev . When set, this toggle enforces user verification at the authenticator level for all known credentials. If .Fa dev supports U2F (CTAP1) and the user verification methods supported by the authenticator do not allow protection of U2F credentials, the U2F subsystem will be disabled by the authenticator. The .Fa pin parameter may be NULL if .Fa dev does not have a PIN set. .Pp The .Fn fido_dev_force_pin_change instructs .Fa dev to require a PIN change. Subsequent PIN authentication attempts against .Fa dev will fail until its PIN is changed. .Pp The .Fn fido_dev_set_pin_minlen function sets the minimum PIN length of .Fa dev 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 +through the CTAP 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 call. .Sh RETURN VALUES 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_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_get_assert.3 b/contrib/libfido2/man/fido_dev_get_assert.3 index 2e33fc516e7d..bc67e441cca3 100644 --- a/contrib/libfido2/man/fido_dev_get_assert.3 +++ b/contrib/libfido2/man/fido_dev_get_assert.3 @@ -1,76 +1,76 @@ .\" Copyright (c) 2018 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. .\" .Dd $Mdocdate: May 24 2018 $ .Dt FIDO_DEV_GET_ASSERT 3 .Os .Sh NAME .Nm fido_dev_get_assert -.Nd obtains an assertion from a FIDO device +.Nd obtains an assertion from a FIDO2 device .Sh SYNOPSIS .In fido.h .Ft int -.Fn fido_dev_get_assert "fido_dev_t *dev" " fido_assert_t *assert" "const char *pin" +.Fn fido_dev_get_assert "fido_dev_t *dev" "fido_assert_t *assert" "const char *pin" .Sh DESCRIPTION The .Fn fido_dev_get_assert -function asks the FIDO device represented by +function asks the FIDO2 device represented by .Fa dev for an assertion according to the following parameters defined in .Fa assert : .Pp .Bl -dash -compact .It .Nm relying party ID ; .It .Nm client data hash ; .It .Nm list of allowed credential IDs ; .It .Nm user presence and user verification attributes . .El .Pp See .Xr fido_assert_set_authdata 3 for information on how these values are set. .Pp If a PIN is not needed to authenticate the request against .Fa dev , then .Fa pin may be NULL. Otherwise .Fa pin must point to a NUL-terminated UTF-8 string. .Pp After a successful call to .Fn fido_dev_get_assert , the .Xr fido_assert_count 3 , .Xr fido_assert_user_display_name 3 , .Xr fido_assert_user_icon 3 , .Xr fido_assert_user_name 3 , .Xr fido_assert_authdata_ptr 3 , .Xr fido_assert_user_id_ptr 3 , .Xr fido_assert_sig_ptr 3 , and .Xr fido_assert_sigcount 3 functions may be invoked on .Fa assert to retrieve the various attributes of the generated assertion. .Pp Please note that .Fn fido_dev_get_assert is synchronous and will block if necessary. .Sh RETURN VALUES The error codes returned by .Fn fido_dev_get_assert are defined in .In fido/err.h . On success, .Dv FIDO_OK is returned. .Sh SEE ALSO .Xr fido_assert_new 3 , .Xr fido_assert_set_authdata 3 diff --git a/contrib/libfido2/man/fido_dev_get_touch_begin.3 b/contrib/libfido2/man/fido_dev_get_touch_begin.3 index 8372c6ff010b..f3b8335cec12 100644 --- a/contrib/libfido2/man/fido_dev_get_touch_begin.3 +++ b/contrib/libfido2/man/fido_dev_get_touch_begin.3 @@ -1,73 +1,73 @@ .\" Copyright (c) 2020 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. .\" .Dd $Mdocdate: August 5 2020 $ .Dt FIDO_DEV_GET_TOUCH_BEGIN 3 .Os .Sh NAME .Nm fido_dev_get_touch_begin , .Nm fido_dev_get_touch_status -.Nd asynchronously wait for touch on a FIDO 2 authenticator +.Nd asynchronously wait for touch on a FIDO2 authenticator .Sh SYNOPSIS .In fido.h .Ft int .Fn fido_dev_get_touch_begin "fido_dev_t *dev" .Ft int .Fn fido_dev_get_touch_status "fido_dev_t *dev" "int *touched" "int ms" .Sh DESCRIPTION The functions described in this page allow an application to -asynchronously wait for touch on a FIDO authenticator. +asynchronously wait for touch on a FIDO2 authenticator. This is useful when multiple authenticators are present and the application needs to know which one to use. .Pp The .Fn fido_dev_get_touch_begin function initiates a touch request on .Fa dev . .Pp The .Fn fido_dev_get_touch_status function continues an ongoing touch request on .Fa dev , blocking up to .Fa ms milliseconds. On success, .Fa touched will be updated to reflect the touch request status. If .Fa touched is 1, the device was touched, and the touch request is terminated. If .Fa touched is 0, the application may call .Fn fido_dev_get_touch_status to continue the touch request, or .Fn fido_dev_cancel to terminate it. .Sh RETURN VALUES The error codes returned by .Fn fido_dev_get_touch_begin and .Fn fido_dev_get_touch_status are defined in .In fido/err.h . On success, .Dv FIDO_OK is returned. .Sh EXAMPLES Please refer to .Em examples/select.c in .Em libfido2's source tree. .Sh SEE ALSO .Xr fido_dev_cancel 3 .Sh CAVEATS The .Fn fido_dev_get_touch_status function will cause a command to be transmitted to U2F authenticators. These transmissions should not exceed a frequency of 5Hz. diff --git a/contrib/libfido2/man/fido_dev_info_manifest.3 b/contrib/libfido2/man/fido_dev_info_manifest.3 index 76e399cec319..9539a0dda7c5 100644 --- a/contrib/libfido2/man/fido_dev_info_manifest.3 +++ b/contrib/libfido2/man/fido_dev_info_manifest.3 @@ -1,153 +1,188 @@ .\" Copyright (c) 2018 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. .\" .Dd $Mdocdate: May 25 2018 $ .Dt FIDO_DEV_INFO_MANIFEST 3 .Os .Sh NAME .Nm fido_dev_info_manifest , .Nm fido_dev_info_new , .Nm fido_dev_info_free , .Nm fido_dev_info_ptr , .Nm fido_dev_info_path , .Nm fido_dev_info_product , .Nm fido_dev_info_vendor , .Nm fido_dev_info_manufacturer_string , -.Nm fido_dev_info_product_string -.Nd FIDO 2 device discovery functions +.Nm fido_dev_info_product_string , +.Nm fido_dev_info_set +.Nd FIDO2 device discovery functions .Sh SYNOPSIS .In fido.h .Ft int .Fn fido_dev_info_manifest "fido_dev_info_t *devlist" "size_t ilen" "size_t *olen" .Ft fido_dev_info_t * .Fn fido_dev_info_new "size_t n" .Ft void .Fn fido_dev_info_free "fido_dev_info_t **devlist_p" "size_t n" .Ft const fido_dev_info_t * .Fn fido_dev_info_ptr "const fido_dev_info_t *devlist" "size_t i" .Ft const char * .Fn fido_dev_info_path "const fido_dev_info_t *di" .Ft int16_t .Fn fido_dev_info_product "const fido_dev_info_t *di" .Ft int16_t .Fn fido_dev_info_vendor "const fido_dev_info_t *di" .Ft const char * .Fn fido_dev_info_manufacturer_string "const fido_dev_info_t *di" .Ft const char * .Fn fido_dev_info_product_string "const fido_dev_info_t *di" +.Ft int +.Fn fido_dev_info_set "fido_dev_info_t *devlist" "size_t i" "const char *path" "const char *manufacturer" "const char *product" "const fido_dev_io_t *io" "const fido_dev_transport_t *transport" .Sh DESCRIPTION The .Fn fido_dev_info_manifest function fills .Fa devlist with up to .Fa ilen -FIDO devices found by the underlying operating system. +FIDO2 devices found by the underlying operating system. Currently only USB HID devices are supported. The number of discovered devices is returned in .Fa olen , where .Fa olen is an addressable pointer. .Pp The .Fn fido_dev_info_new function returns a pointer to a newly allocated, empty device list with .Fa n available slots. If memory is not available, NULL is returned. .Pp The .Fn fido_dev_info_free function releases the memory backing .Fa *devlist_p , where .Fa *devlist_p must have been previously allocated by .Fn fido_dev_info_new . The number .Fa n of allocated slots must also be provided. On return, .Fa *devlist_p is set to NULL. Either .Fa devlist_p or .Fa *devlist_p may be NULL, in which case .Fn fido_dev_info_free is a NOP. .Pp The .Fn fido_dev_info_ptr function returns a pointer to slot number .Fa i of .Fa devlist . It is the caller's responsibility to ensure that .Fa i is bounded. Please note that the first slot has index 0. .Pp The .Fn fido_dev_info_path returns the filesystem path or subsystem-specific identification string of .Fa di . .Pp The .Fn fido_dev_info_product function returns the product ID of .Fa di . .Pp The .Fn fido_dev_info_vendor function returns the vendor ID of .Fa di . .Pp 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 .Pa examples/manifest.c file shipped with .Em libfido2 . +.Pp +The +.Fn fido_dev_info_set +function initializes an entry in a device list allocated by +.Fn fido_dev_info_new +with the specified path, manufacturer, and product strings, and with +the specified I/O handlers and, optionally, transport functions, as +described in +.Xr fido_dev_set_io_functions 3 . +The +.Fa io +argument must be specified; the +.Fa transport +argument may be +.Dv NULL . +The path, I/O handlers, and transport functions will be used +automatically by +.Xr fido_dev_new_with_info 3 +and +.Xr fido_dev_open_with_info 3 . +An application can use this, for example, to substitute mock FIDO2 +devices in testing for the real ones that +.Fn fido_dev_info_manifest +would discover. .Sh RETURN VALUES The .Fn fido_dev_info_manifest function always returns .Dv FIDO_OK . If a discovery error occurs, the .Fa olen pointer is set to 0. .Pp +On success, the +.Fn fido_dev_info_set +function returns +.Dv FIDO_OK . +On error, a different error code defined in +.In fido/err.h +is returned. +.Pp The pointers returned by .Fn fido_dev_info_ptr , .Fn fido_dev_info_path , .Fn fido_dev_info_manufacturer_string , and .Fn fido_dev_info_product_string are guaranteed to exist until .Fn fido_dev_info_free is called on the corresponding device list. diff --git a/contrib/libfido2/man/fido_dev_largeblob_get.3 b/contrib/libfido2/man/fido_dev_largeblob_get.3 index 830534ed0e7b..c42208158c5e 100644 --- a/contrib/libfido2/man/fido_dev_largeblob_get.3 +++ b/contrib/libfido2/man/fido_dev_largeblob_get.3 @@ -1,194 +1,194 @@ .\" Copyright (c) 2020 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. .\" .Dd $Mdocdate: October 26 2020 $ .Dt FIDO_LARGEBLOB_GET 3 .Os .Sh NAME .Nm fido_dev_largeblob_get , .Nm fido_dev_largeblob_set , .Nm fido_dev_largeblob_remove , .Nm fido_dev_largeblob_get_array , .Nm fido_dev_largeblob_set_array -.Nd FIDO 2 large blob API +.Nd FIDO2 large blob API .Sh SYNOPSIS .In fido.h .Ft int .Fn fido_dev_largeblob_get "fido_dev_t *dev" "const unsigned char *key_ptr" "size_t key_len" "unsigned char **blob_ptr" "size_t *blob_len" .Ft int .Fn fido_dev_largeblob_set "fido_dev_t *dev" "const unsigned char *key_ptr" "size_t key_len" "const unsigned char *blob_ptr" "size_t blob_len" "const char *pin" .Ft int .Fn fido_dev_largeblob_remove "fido_dev_t *dev" "const unsigned char *key_ptr" "size_t key_len" "const char *pin" .Ft int .Fn fido_dev_largeblob_get_array "fido_dev_t *dev" "unsigned char **cbor_ptr" "size_t *cbor_len" .Ft int .Fn fido_dev_largeblob_set_array "fido_dev_t *dev" "const unsigned char *cbor_ptr" "size_t cbor_len" "const char *pin" .Sh DESCRIPTION The .Dq largeBlobs API of .Em libfido2 -allows binary blobs residing on a FIDO 2.1 authenticator to be +allows binary blobs residing on a CTAP 2.1 authenticator to be read, written, and inspected. .Dq largeBlobs -is a FIDO 2.1 extension. +is a CTAP 2.1 extension. .Pp .Dq largeBlobs are stored as elements of a CBOR array. Confidentiality is ensured by encrypting each element with a distinct, credential-bound 256-bit AES-GCM key. The array is otherwise shared between different credentials and FIDO2 relying parties. .Pp Retrieval of a credential's encryption key is possible during enrollment with .Xr fido_cred_set_extensions 3 and .Xr fido_cred_largeblob_key_ptr 3 , during assertion with .Xr fido_assert_set_extensions 3 and .Xr fido_assert_largeblob_key_ptr 3 , or, in the case of a resident credential, via .Em libfido2's credential management API. .Pp The .Dq largeBlobs CBOR array is opaque to the authenticator. Management of the array is left at the discretion of FIDO2 clients. -For further details on FIDO 2.1's +For further details on CTAP 2.1's .Dq largeBlobs -extension, please refer to the FIDO 2.1 spec. +extension, please refer to the CTAP 2.1 spec. .Pp The .Fn fido_dev_largeblob_get function retrieves the authenticator's .Dq largeBlobs CBOR array and, on success, returns the first blob .Pq iterating from array index zero that can be decrypted by .Fa key_ptr , where .Fa key_ptr points to .Fa key_len bytes. On success, .Fn fido_dev_largeblob_get sets .Fa blob_ptr to the body of the decrypted blob, and .Fa blob_len to the length of the decrypted blob in bytes. It is the caller's responsibility to free .Fa blob_ptr . .Pp The .Fn fido_dev_largeblob_set function uses .Fa key_ptr to encrypt .Fa blob_ptr and inserts the result in the authenticator's .Dq largeBlobs CBOR array. Insertion happens at the end of the array if no existing element can be decrypted by .Fa key_ptr , or at the position of the first element .Pq iterating from array index zero that can be decrypted by .Fa key_ptr . .Fa key_len holds the length of .Fa key_ptr in bytes, and .Fa blob_len the length of .Fa blob_ptr in bytes. A .Fa pin or equivalent user-verification gesture is required. .Pp The .Fn fido_dev_largeblob_remove function retrieves the authenticator's .Dq largeBlobs CBOR array and, on success, drops the first blob .Pq iterating from array index zero that can be decrypted by .Fa key_ptr , where .Fa key_ptr points to .Fa key_len bytes. A .Fa pin or equivalent user-verification gesture is required. .Pp The .Fn fido_dev_largeblob_get_array function retrieves the authenticator's .Dq largeBlobs CBOR array and, on success, sets .Fa cbor_ptr to the body of the CBOR array, and .Fa cbor_len to its corresponding length in bytes. It is the caller's responsibility to free .Fa cbor_ptr . .Pp Finally, the .Fn fido_dev_largeblob_set_array function sets the authenticator's .Dq largeBlobs CBOR array to the data pointed to by .Fa cbor_ptr , where .Fa cbor_ptr points to .Fa cbor_len bytes. A .Fa pin or equivalent user-verification gesture is required. .Sh RETURN VALUES The functions .Fn fido_dev_largeblob_set , .Fn fido_dev_largeblob_get , .Fn fido_dev_largeblob_remove , .Fn fido_dev_largeblob_get_array , and .Fn fido_dev_largeblob_set_array return .Dv FIDO_OK on success. On error, an error code defined in .In fido/err.h is returned. .Sh SEE ALSO .Xr fido_assert_largeblob_key_len 3 , .Xr fido_assert_largeblob_key_ptr 3 , .Xr fido_assert_set_extensions 3 , .Xr fido_cred_largeblob_key_len 3 , .Xr fido_cred_largeblob_key_ptr 3 , .Xr fido_cred_set_extensions 3 , .Xr fido_credman_dev_get_rk 3 , .Xr fido_credman_dev_get_rp 3 , .Xr fido_dev_get_assert 3 , .Xr fido_dev_make_cred 3 .Sh CAVEATS The .Dq largeBlobs extension is not meant to be used to store sensitive data. When retrieved, a credential's .Dq largeBlobs encryption key is transmitted in the clear, and an authenticator's .Dq largeBlobs CBOR array can be read without user interaction or verification. diff --git a/contrib/libfido2/man/fido_dev_make_cred.3 b/contrib/libfido2/man/fido_dev_make_cred.3 index cd156dc94f89..60b77fb9c010 100644 --- a/contrib/libfido2/man/fido_dev_make_cred.3 +++ b/contrib/libfido2/man/fido_dev_make_cred.3 @@ -1,77 +1,77 @@ .\" Copyright (c) 2018 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. .\" .Dd $Mdocdate: May 23 2018 $ .Dt FIDO_DEV_MAKE_CRED 3 .Os .Sh NAME .Nm fido_dev_make_cred -.Nd generates a new credential on a FIDO device +.Nd generates a new credential on a FIDO2 device .Sh SYNOPSIS .In fido.h .Ft int -.Fn fido_dev_make_cred "fido_dev_t *dev" " fido_cred_t *cred" "const char *pin" +.Fn fido_dev_make_cred "fido_dev_t *dev" "fido_cred_t *cred" "const char *pin" .Sh DESCRIPTION The .Fn fido_dev_make_cred -function asks the FIDO device represented by +function asks the FIDO2 device represented by .Fa dev to generate a new credential according to the following parameters defined in .Fa cred : .Pp .Bl -dash -compact .It .Nm type ; .It .Nm client data hash ; .It .Nm relying party ; .It .Nm user attributes ; .It .Nm list of excluded credential IDs ; .It .Nm resident/discoverable key and user verification attributes . .El .Pp See .Xr fido_cred_set_authdata 3 for information on how these values are set. .Pp If a PIN is not needed to authenticate the request against .Fa dev , then .Fa pin may be NULL. Otherwise .Fa pin must point to a NUL-terminated UTF-8 string. .Pp After a successful call to .Fn fido_dev_make_cred , the .Xr fido_cred_authdata_ptr 3 , .Xr fido_cred_pubkey_ptr 3 , .Xr fido_cred_x5c_ptr 3 , and .Xr fido_cred_sig_ptr 3 functions may be invoked on .Fa cred to retrieve the various parts of the generated credential. .Pp Please note that .Fn fido_dev_make_cred is synchronous and will block if necessary. .Sh RETURN VALUES The error codes returned by .Fn fido_dev_make_cred are defined in .In fido/err.h . On success, .Dv FIDO_OK is returned. .Sh SEE ALSO .Xr fido_cred_new 3 , .Xr fido_cred_set_authdata 3 diff --git a/contrib/libfido2/man/fido_dev_open.3 b/contrib/libfido2/man/fido_dev_open.3 index f2af7817d801..cdb148fe8b16 100644 --- a/contrib/libfido2/man/fido_dev_open.3 +++ b/contrib/libfido2/man/fido_dev_open.3 @@ -1,250 +1,293 @@ .\" Copyright (c) 2018 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. .\" .Dd $Mdocdate: May 25 2018 $ .Dt FIDO_DEV_OPEN 3 .Os .Sh NAME .Nm fido_dev_open , +.Nm fido_dev_open_with_info , .Nm fido_dev_close , .Nm fido_dev_cancel , .Nm fido_dev_new , +.Nm fido_dev_new_with_info , .Nm fido_dev_free , .Nm fido_dev_force_fido2 , .Nm fido_dev_force_u2f , .Nm fido_dev_is_fido2 , .Nm fido_dev_is_winhello , .Nm fido_dev_supports_credman , .Nm fido_dev_supports_cred_prot , +.Nm fido_dev_supports_permissions , .Nm fido_dev_supports_pin , -.Nm fido_dev_has_pin , .Nm fido_dev_supports_uv , +.Nm fido_dev_has_pin , .Nm fido_dev_has_uv , .Nm fido_dev_protocol , .Nm fido_dev_build , .Nm fido_dev_flags , .Nm fido_dev_major , .Nm fido_dev_minor -.Nd FIDO 2 device open/close and related functions +.Nd FIDO2 device open/close and related functions .Sh SYNOPSIS .In fido.h .Ft int .Fn fido_dev_open "fido_dev_t *dev" "const char *path" .Ft int +.Fn fido_dev_open_with_info "fido_dev_t *dev" +.Ft int .Fn fido_dev_close "fido_dev_t *dev" .Ft int .Fn fido_dev_cancel "fido_dev_t *dev" .Ft fido_dev_t * .Fn fido_dev_new "void" +.Ft fido_dev_t * +.Fn fido_dev_new_with_info "const fido_dev_info_t *" .Ft void .Fn fido_dev_free "fido_dev_t **dev_p" .Ft void .Fn fido_dev_force_fido2 "fido_dev_t *dev" .Ft void .Fn fido_dev_force_u2f "fido_dev_t *dev" .Ft bool .Fn fido_dev_is_fido2 "const fido_dev_t *dev" .Ft bool .Fn fido_dev_is_winhello "const fido_dev_t *dev" .Ft bool .Fn fido_dev_supports_credman "const fido_dev_t *dev" .Ft bool .Fn fido_dev_supports_cred_prot "const fido_dev_t *dev" .Ft bool -.Fn fido_dev_supports_pin "const fido_dev_t *dev" +.Fn fido_dev_supports_permissions "const fido_dev_t *dev" .Ft bool -.Fn fido_dev_has_pin "const fido_dev_t *dev" +.Fn fido_dev_supports_pin "const fido_dev_t *dev" .Ft bool .Fn fido_dev_supports_uv "const fido_dev_t *dev" .Ft bool +.Fn fido_dev_has_pin "const fido_dev_t *dev" +.Ft bool .Fn fido_dev_has_uv "const fido_dev_t *dev" .Ft uint8_t .Fn fido_dev_protocol "const fido_dev_t *dev" .Ft uint8_t .Fn fido_dev_build "const fido_dev_t *dev" .Ft uint8_t .Fn fido_dev_flags "const fido_dev_t *dev" .Ft uint8_t .Fn fido_dev_major "const fido_dev_t *dev" .Ft uint8_t .Fn fido_dev_minor "const fido_dev_t *dev" .Sh DESCRIPTION The .Fn fido_dev_open function opens the device pointed to by .Fa path , where .Fa dev is a freshly allocated or otherwise closed .Vt fido_dev_t . If .Fa dev claims to be FIDO2, .Em libfido2 will attempt to speak FIDO2 to .Fa dev . If that fails, .Em libfido2 will fallback to U2F unless the .Dv FIDO_DISABLE_U2F_FALLBACK flag was set in .Xr fido_init 3 . .Pp The +.Fn fido_dev_open_with_info +function opens +.Fa dev +as previously allocated using +.Fn fido_dev_new_with_info . +.Pp +The .Fn fido_dev_close function closes the device represented by .Fa dev . If .Fa dev is already closed, .Fn fido_dev_close is a NOP. .Pp The .Fn fido_dev_cancel function cancels any pending requests on .Fa dev . .Pp The .Fn fido_dev_new function returns a pointer to a newly allocated, empty .Vt fido_dev_t . If memory cannot be allocated, NULL is returned. .Pp The +.Fn fido_dev_new_with_info +function returns a pointer to a newly allocated +.Vt fido_dev_t +with +.Vt fido_dev_info_t +parameters, for use with +.Xr fido_dev_info_manifest 3 +and +.Fn fido_dev_open_with_info . +If memory cannot be allocated, NULL is returned. +.Pp +The .Fn fido_dev_free function releases the memory backing .Fa *dev_p , where .Fa *dev_p must have been previously allocated by .Fn fido_dev_new . On return, .Fa *dev_p is set to NULL. Either .Fa dev_p or .Fa *dev_p may be NULL, in which case .Fn fido_dev_free is a NOP. .Pp The .Fn fido_dev_force_fido2 function can be used to force CTAP2 communication with -.Fa dev . +.Fa dev , +where +.Fa dev +is an open device. .Pp The .Fn fido_dev_force_u2f function can be used to force CTAP1 (U2F) communication with -.Fa dev . +.Fa dev , +where +.Fa dev +is an open device. .Pp The .Fn fido_dev_is_fido2 function returns .Dv true if .Fa dev -is a FIDO 2 device. +is a FIDO2 device. .Pp The .Fn fido_dev_is_winhello function returns .Dv true if .Fa dev is a Windows Hello device. .Pp The .Fn fido_dev_supports_credman function returns .Dv true if .Fa dev -supports FIDO 2.1 Credential Management. +supports CTAP 2.1 Credential Management. .Pp The .Fn fido_dev_supports_cred_prot function returns .Dv true if .Fa dev -supports FIDO 2.1 Credential Protection. +supports CTAP 2.1 Credential Protection. .Pp The -.Fn fido_dev_supports_pin +.Fn fido_dev_supports_permissions function returns .Dv true if .Fa dev -supports FIDO 2.0 Client PINs. +supports CTAP 2.1 UV token permissions. .Pp The -.Fn fido_dev_has_pin +.Fn fido_dev_supports_pin function returns .Dv true if .Fa dev -has a FIDO 2.0 Client PIN set. +supports CTAP 2.0 Client PINs. .Pp The .Fn fido_dev_supports_uv function returns .Dv true if .Fa dev supports a built-in user verification method. .Pp The +.Fn fido_dev_has_pin +function returns +.Dv true +if +.Fa dev +has a CTAP 2.0 Client PIN set. +.Pp +The .Fn fido_dev_has_uv function returns .Dv true if .Fa dev supports built-in user verification and its user verification feature is configured. .Pp The .Fn fido_dev_protocol function returns the CTAPHID protocol version identifier of .Fa dev . .Pp The .Fn fido_dev_build function returns the CTAPHID build version number of .Fa dev . .Pp The .Fn fido_dev_flags function returns the CTAPHID capabilities flags of .Fa dev . .Pp The .Fn fido_dev_major function returns the CTAPHID major version number of .Fa dev . .Pp The .Fn fido_dev_minor function returns the CTAPHID minor version number of .Fa dev . .Pp For the format and meaning of the CTAPHID parameters returned by functions above, please refer to the FIDO Client to Authenticator Protocol (CTAP) specification. .Sh RETURN VALUES On success, -.Fn fido_dev_open +.Fn fido_dev_open , +.Fn fido_dev_open_with_info , and .Fn fido_dev_close return .Dv FIDO_OK . On error, a different error code defined in .In fido/err.h is returned. .Sh SEE ALSO .Xr fido_dev_info_manifest 3 , .Xr fido_dev_set_io_functions 3 , .Xr fido_init 3 diff --git a/contrib/libfido2/man/fido_dev_set_io_functions.3 b/contrib/libfido2/man/fido_dev_set_io_functions.3 index 52081f126e78..8c2067c41f66 100644 --- a/contrib/libfido2/man/fido_dev_set_io_functions.3 +++ b/contrib/libfido2/man/fido_dev_set_io_functions.3 @@ -1,161 +1,238 @@ .\" 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. .\" .Dd $Mdocdate: May 25 2018 $ .Dt FIDO_DEV_SET_IO_FUNCTIONS 3 .Os .Sh NAME .Nm fido_dev_set_io_functions , .Nm fido_dev_set_sigmask , -.Nm fido_dev_set_timeout -.Nd FIDO 2 device I/O interface +.Nm fido_dev_set_timeout , +.Nm fido_dev_set_transport_functions , +.Nm fido_dev_io_handle +.Nd FIDO2 device I/O interface .Sh SYNOPSIS .In fido.h .Bd -literal typedef void *fido_dev_io_open_t(const char *); typedef void fido_dev_io_close_t(void *); typedef int fido_dev_io_read_t(void *, unsigned char *, size_t, int); typedef int fido_dev_io_write_t(void *, const unsigned char *, size_t); typedef struct fido_dev_io { fido_dev_io_open_t *open; fido_dev_io_close_t *close; fido_dev_io_read_t *read; fido_dev_io_write_t *write; } fido_dev_io_t; #ifdef _WIN32 typedef int fido_sigset_t; #else typedef sigset_t fido_sigset_t; #endif + +typedef int fido_dev_rx_t(struct fido_dev *, + uint8_t, unsigned char *, size_t, int); +typedef int fido_dev_tx_t(struct fido_dev *, + uint8_t, const unsigned char *, size_t); + +typedef struct fido_dev_transport { + fido_dev_rx_t *rx; + fido_dev_tx_t *tx; +} fido_dev_transport_t; .Ed +.Pp .Ft int .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" +.Ft int +.Fn fido_dev_set_transport_functions "fido_dev_t *dev" "const fido_dev_transport_t *t" +.Ft void * +.Fn fido_dev_io_handle "const fido_dev_t *dev" .Sh DESCRIPTION The .Fn fido_dev_set_io_functions function sets the I/O handlers used by .Em libfido2 to talk to .Fa dev . By default, these handlers are set to the operating system's native HID or NFC interfaces. They are defined as follows: .Bl -tag -width Ds .It Vt fido_dev_open_t Receives a .Vt const char * holding a path and opens the corresponding device, returning a non-NULL opaque pointer on success and NULL on error. .It Vt fido_dev_close_t Receives the opaque pointer returned by .Vt fido_dev_open_t and closes the device. .It Vt fido_dev_read_t Reads a single transmission unit (HID report, APDU) from a device. The first parameter is the opaque pointer returned by .Vt fido_dev_open_t . The second parameter is the read buffer, and the third parameter is the read buffer size. The fourth parameter is the number of milliseconds the caller is willing to sleep, should the call need to block. If this value holds -1, .Vt fido_dev_read_t may block indefinitely. On success, the number of bytes read is returned. On error, -1 is returned. .It Vt fido_dev_write_t Writes a single transmission unit (HID report, APDU) to .Fa dev . The first parameter is the opaque pointer returned by .Vt fido_dev_open_t . The second parameter is the write buffer, and the third parameter is the number of bytes to be written. A .Vt fido_dev_write_t may block. On success, the number of bytes written is returned. On error, -1 is returned. .El .Pp When calling .Fn fido_dev_set_io_functions , the .Fa open , .Fa close , .Fa read , and .Fa write fields of .Fa io may not be NULL. .Pp No references to .Fa io are held by .Fn fido_dev_set_io_functions . .Pp The .Fn fido_dev_set_sigmask function may be used to specify a non-NULL signal mask .Fa sigmask to be used while .Em libfido2's default I/O handlers wait on .Fa dev . On UNIX-like operating systems, .Vt fido_sigset_t is defined as .Vt sigset_t . On Windows, .Vt fido_sigset_t is defined as .Vt int and .Fn fido_dev_set_sigmask is a no-op. .Pp 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. +.Pp +The +.Fn fido_dev_set_transport_functions +function sets the transport functions used by +.Em libfido2 +to talk to +.Fa dev . +While the I/O handlers are responsible for sending and receiving +transmission units of initialization and continuation packets already +formatted by +.Em libfido2 , +the transport handlers are responsible for sending and receiving +the CTAPHID commands and data directly, as defined in the FIDO Client +to Authenticator Protocol (CTAP) standard. +They are defined as follows: +.Bl -tag -width Ds +.It Vt fido_dev_tx_t +Receives a device, a CTAPHID command to transmit, a data buffer to +transmit, and the length of the data buffer. +On success, 0 is returned. +On error, -1 is returned. +.It Vt fido_dev_rx_t +Receives a device, a CTAPHID command whose response the caller expects +to receive, a data buffer to receive into, the size of the data buffer +determining the maximum length of a response, and the maximum number of +milliseconds to wait for a response. +On success, the number of bytes read into the data buffer is returned. +On error, -1 is returned. +.El +.Pp +When transport functions are specified, +.Em libfido2 +will use them instead of the +.Dv read +and +.Dv write +functions of the I/O handlers. +However, the I/O handlers must still be specified to open and close the +device. +.Pp +The +.Fn fido_dev_io_handle +function returns the opaque pointer returned by the +.Dv open +function of the I/O handlers. +This is useful mainly for the transport functions, which unlike the I/O +handlers are passed the +.Vt fido_dev_t +pointer instead of the opaque I/O handle. .Sh RETURN VALUES On success, .Fn fido_dev_set_io_functions , +.Fn fido_dev_set_transport_functions , .Fn fido_dev_set_sigmask , and .Fn fido_dev_set_timeout return .Dv FIDO_OK . On error, a different error code defined in .In fido/err.h is returned. +.Sh SEE ALSO +.Xr fido_dev_info_manifest 3 , +.Xr fido_dev_open 3 +.Rs +.%D 2021-06-15 +.%O Proposed Standard, Version 2.1 +.%Q FIDO Alliance +.%R Client to Authenticator Protocol (CTAP) +.%U https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html +.Re diff --git a/contrib/libfido2/man/fido_dev_set_pin.3 b/contrib/libfido2/man/fido_dev_set_pin.3 index f5ef94ff6fb5..b58ba6c86f89 100644 --- a/contrib/libfido2/man/fido_dev_set_pin.3 +++ b/contrib/libfido2/man/fido_dev_set_pin.3 @@ -1,103 +1,103 @@ .\" Copyright (c) 2018 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. .\" .Dd $Mdocdate: May 25 2018 $ .Dt FIDO_DEV_SET_PIN 3 .Os .Sh NAME .Nm fido_dev_set_pin , .Nm fido_dev_get_retry_count , .Nm fido_dev_get_uv_retry_count , .Nm fido_dev_reset -.Nd FIDO 2 device management functions +.Nd FIDO2 device management functions .Sh SYNOPSIS .In fido.h .Ft int .Fn fido_dev_set_pin "fido_dev_t *dev" "const char *pin" "const char *oldpin" .Ft int .Fn fido_dev_get_retry_count "fido_dev_t *dev" "int *retries" .Ft int .Fn fido_dev_get_uv_retry_count "fido_dev_t *dev" "int *retries" .Ft int .Fn fido_dev_reset "fido_dev_t *dev" .Sh DESCRIPTION The .Fn fido_dev_set_pin function sets the PIN of device .Fa dev to .Fa pin , where .Fa pin is a NUL-terminated UTF-8 string. If .Fa oldpin is not NULL, the device's PIN is changed from .Fa oldpin to .Fa pin , where .Fa pin and .Fa oldpin are NUL-terminated UTF-8 strings. .Pp The .Fn fido_dev_get_retry_count function fills .Fa retries with the number of PIN retries left in .Fa dev before lock-out, where .Fa retries is an addressable pointer. .Pp The .Fn fido_dev_get_uv_retry_count function fills .Fa retries with the number of built-in UV retries left in .Fa dev before built-in UV is disabled, where .Fa retries is an addressable pointer. .Pp The .Fn fido_dev_reset function performs a reset on .Fa dev , resetting the device's PIN and erasing credentials stored on the device. .Pp Please note that .Fn fido_dev_set_pin , .Fn fido_dev_get_retry_count , .Fn fido_dev_get_uv_retry_count , and .Fn fido_dev_reset are synchronous and will block if necessary. .Sh RETURN VALUES The error codes returned by .Fn fido_dev_set_pin , .Fn fido_dev_get_retry_count , .Fn fido_dev_get_uv_retry_count , and .Fn fido_dev_reset are defined in .In fido/err.h . On success, .Dv FIDO_OK is returned. .Sh CAVEATS Regarding .Fn fido_dev_reset , the actual user-flow to perform a reset is outside the scope of the FIDO2 specification, and may therefore vary depending on the authenticator. Yubico authenticators will return .Dv FIDO_ERR_NOT_ALLOWED if a reset is issued later than 5 seconds after power-up, and .Dv FIDO_ERR_ACTION_TIMEOUT if the user fails to confirm the reset by touching the key within 30 seconds. diff --git a/contrib/libfido2/man/fido_init.3 b/contrib/libfido2/man/fido_init.3 index dcfc530c59ae..1254f934b73b 100644 --- a/contrib/libfido2/man/fido_init.3 +++ b/contrib/libfido2/man/fido_init.3 @@ -1,52 +1,72 @@ .\" Copyright (c) 2018 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. .\" .Dd $Mdocdate: May 25 2018 $ .Dt FIDO_INIT 3 .Os .Sh NAME -.Nm fido_init -.Nd initialise the FIDO 2 library +.Nm fido_init , +.Nm fido_set_log_handler +.Nd initialise the FIDO2 library .Sh SYNOPSIS .In fido.h +.Bd -literal +typedef void fido_log_handler_t(const char *); +.Ed +.Pp .Ft void .Fn fido_init "int flags" +.Ft void +.Fn fido_set_log_handler "fido_log_handler_t *handler" .Sh DESCRIPTION The .Fn fido_init function initialises the .Em libfido2 library. Its invocation must precede that of any other .Em libfido2 function in the context of the executing thread. .Pp If .Dv FIDO_DEBUG is set in .Fa flags , then debug output will be emitted by .Em libfido2 on .Em stderr . Alternatively, the .Ev FIDO_DEBUG environment variable may be set. .Pp If .Dv FIDO_DISABLE_U2F_FALLBACK is set in .Fa flags , then .Em libfido2 will not fallback to U2F in .Xr fido_dev_open 3 -if a device claims to be FIDO2 but fails to respond to a -FIDO2 command. +if a device claims to support FIDO2 but fails to respond to +a CTAP 2.0 greeting. +.Pp +The +.Fn fido_set_log_handler +function causes +.Fa handler +to be called for each log line generated in the context of the +executing thread. +Lines passed to +.Fa handler +include a trailing newline character and are not printed by +.Em libfido2 +on +.Em stderr . .Sh SEE ALSO .Xr fido_assert_new 3 , .Xr fido_cred_new 3 , .Xr fido_dev_info_manifest 3 , .Xr fido_dev_open 3 diff --git a/contrib/libfido2/man/fido_strerr.3 b/contrib/libfido2/man/fido_strerr.3 index 05c86b92a158..9d4ef35aa402 100644 --- a/contrib/libfido2/man/fido_strerr.3 +++ b/contrib/libfido2/man/fido_strerr.3 @@ -1,27 +1,27 @@ .\" Copyright (c) 2018 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. .\" .Dd $Mdocdate: May 25 2018 $ .Dt FIDO_STRERR 3 .Os .Sh NAME .Nm fido_strerr -.Nd FIDO 2 error codes +.Nd FIDO2 error codes .Sh SYNOPSIS .In fido.h .Ft const char * .Fn fido_strerr "int n" .Sh DESCRIPTION The .Fn fido_strerr function translates the error code .Fa n into a readable string, where .Fa n is an error code defined in .In fido/err.h . .Fn fido_strerr never returns NULL. Returned pointers point to static strings. diff --git a/contrib/libfido2/man/rs256_pk_new.3 b/contrib/libfido2/man/rs256_pk_new.3 index ad33ee66ba7b..24a27bf8cdab 100644 --- a/contrib/libfido2/man/rs256_pk_new.3 +++ b/contrib/libfido2/man/rs256_pk_new.3 @@ -1,136 +1,136 @@ .\" 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. .\" .Dd $Mdocdate: May 24 2018 $ .Dt RS256_PK_NEW 3 .Os .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_EVP_PKEY , .Nm rs256_pk_from_ptr , .Nm rs256_pk_to_EVP_PKEY -.Nd FIDO 2 COSE RS256 API +.Nd FIDO2 COSE RS256 API .Sh SYNOPSIS .In openssl/rsa.h .In fido/rs256.h .Ft rs256_pk_t * .Fn rs256_pk_new "void" .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" .Ft EVP_PKEY * .Fn rs256_pk_to_EVP_PKEY "const rs256_pk_t *pk" .Sh DESCRIPTION RS256 is the name given in the CBOR Object Signing and Encryption (COSE) RFC to PKCS#1.5 2048-bit RSA with SHA-256. The COSE RS256 API of .Em libfido2 is an auxiliary API with routines to convert between the different RSA public key types used in .Em libfido2 and .Em OpenSSL . .Pp In .Em libfido2 , RS256 public keys are abstracted by the .Vt rs256_pk_t type. .Pp The .Fn rs256_pk_new function returns a pointer to a newly allocated, empty .Vt rs256_pk_t type. If memory cannot be allocated, NULL is returned. .Pp The .Fn rs256_pk_free function releases the memory backing .Fa *pkp , where .Fa *pkp must have been previously allocated by .Fn rs256_pk_new . On return, .Fa *pkp is set to NULL. Either .Fa pkp or .Fa *pkp may be NULL, in which case .Fn rs256_pk_free 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 with the contents of .Fa rsa . No references to .Fa rsa are kept. .Pp The .Fn rs256_pk_from_ptr function fills .Fa pk with the contents of .Fa ptr , where .Fa ptr points to .Fa len bytes. No references to .Fa ptr are kept. .Pp The .Fn rs256_pk_to_EVP_PKEY function converts .Fa pk to a newly allocated .Fa EVP_PKEY type with a reference count of 1. No internal references to the returned pointer are kept. If an error occurs, .Fn rs256_pk_to_EVP_PKEY returns NULL. .Sh RETURN VALUES The .Fn rs256_pk_from_EVP_PKEY , .Fn rs256_pk_from_RSA , and .Fn rs256_pk_from_ptr functions return .Dv FIDO_OK on success. On error, a different error code defined in .In fido/err.h is returned. .Sh SEE ALSO .Xr eddsa_pk_new 3 , .Xr es256_pk_new 3 , .Xr fido_assert_verify 3 , .Xr fido_cred_pubkey_ptr 3 diff --git a/contrib/libfido2/regress/cred.c b/contrib/libfido2/regress/cred.c index b0df1481636a..07a2ca0c0237 100644 --- a/contrib/libfido2/regress/cred.c +++ b/contrib/libfido2/regress/cred.c @@ -1,1622 +1,2174 @@ /* * 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 #include #include #include #define FAKE_DEV_HANDLE ((void *)0xdeadbeef) static const unsigned char cdh[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, 0x2f, 0x99, 0xdc, 0xaf, 0x3e, 0x8a, 0x91, 0x6b, }; static const unsigned char authdata[198] = { 0x58, 0xc4, 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, 0x41, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa0, 0x11, 0xf3, 0x8c, 0x0a, 0x4d, 0x15, 0x80, 0x06, 0x17, 0x11, 0x1f, 0x9e, 0xdc, 0x7d, 0x00, 0x40, 0x53, 0xfb, 0xdf, 0xaa, 0xce, 0x63, 0xde, 0xc5, 0xfe, 0x47, 0xe6, 0x52, 0xeb, 0xf3, 0x5d, 0x53, 0xa8, 0xbf, 0x9d, 0xd6, 0x09, 0x6b, 0x5e, 0x7f, 0xe0, 0x0d, 0x51, 0x30, 0x85, 0x6a, 0xda, 0x68, 0x70, 0x85, 0xb0, 0xdb, 0x08, 0x0b, 0x83, 0x2c, 0xef, 0x44, 0xe2, 0x36, 0x88, 0xee, 0x76, 0x90, 0x6e, 0x7b, 0x50, 0x3e, 0x9a, 0xa0, 0xd6, 0x3c, 0x34, 0xe3, 0x83, 0xe7, 0xd1, 0xbd, 0x9f, 0x25, 0xa5, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, 0x17, 0x5b, 0x27, 0xa6, 0x56, 0xb2, 0x26, 0x0c, 0x26, 0x0c, 0x55, 0x42, 0x78, 0x17, 0x5d, 0x4c, 0xf8, 0xa2, 0xfd, 0x1b, 0xb9, 0x54, 0xdf, 0xd5, 0xeb, 0xbf, 0x22, 0x64, 0xf5, 0x21, 0x9a, 0xc6, 0x22, 0x58, 0x20, 0x87, 0x5f, 0x90, 0xe6, 0xfd, 0x71, 0x27, 0x9f, 0xeb, 0xe3, 0x03, 0x44, 0xbc, 0x8d, 0x49, 0xc6, 0x1c, 0x31, 0x3b, 0x72, 0xae, 0xd4, 0x53, 0xb1, 0xfe, 0x5d, 0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2, }; static const unsigned char authdata_dupkeys[200] = { 0x58, 0xc6, 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, 0x41, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa0, 0x11, 0xf3, 0x8c, 0x0a, 0x4d, 0x15, 0x80, 0x06, 0x17, 0x11, 0x1f, 0x9e, 0xdc, 0x7d, 0x00, 0x40, 0x53, 0xfb, 0xdf, 0xaa, 0xce, 0x63, 0xde, 0xc5, 0xfe, 0x47, 0xe6, 0x52, 0xeb, 0xf3, 0x5d, 0x53, 0xa8, 0xbf, 0x9d, 0xd6, 0x09, 0x6b, 0x5e, 0x7f, 0xe0, 0x0d, 0x51, 0x30, 0x85, 0x6a, 0xda, 0x68, 0x70, 0x85, 0xb0, 0xdb, 0x08, 0x0b, 0x83, 0x2c, 0xef, 0x44, 0xe2, 0x36, 0x88, 0xee, 0x76, 0x90, 0x6e, 0x7b, 0x50, 0x3e, 0x9a, 0xa0, 0xd6, 0x3c, 0x34, 0xe3, 0x83, 0xe7, 0xd1, 0xbd, 0x9f, 0x25, 0xa6, 0x01, 0x02, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, 0x17, 0x5b, 0x27, 0xa6, 0x56, 0xb2, 0x26, 0x0c, 0x26, 0x0c, 0x55, 0x42, 0x78, 0x17, 0x5d, 0x4c, 0xf8, 0xa2, 0xfd, 0x1b, 0xb9, 0x54, 0xdf, 0xd5, 0xeb, 0xbf, 0x22, 0x64, 0xf5, 0x21, 0x9a, 0xc6, 0x22, 0x58, 0x20, 0x87, 0x5f, 0x90, 0xe6, 0xfd, 0x71, 0x27, 0x9f, 0xeb, 0xe3, 0x03, 0x44, 0xbc, 0x8d, 0x49, 0xc6, 0x1c, 0x31, 0x3b, 0x72, 0xae, 0xd4, 0x53, 0xb1, 0xfe, 0x5d, 0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2, }; static const unsigned char authdata_unsorted_keys[198] = { 0x58, 0xc4, 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, 0x41, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa0, 0x11, 0xf3, 0x8c, 0x0a, 0x4d, 0x15, 0x80, 0x06, 0x17, 0x11, 0x1f, 0x9e, 0xdc, 0x7d, 0x00, 0x40, 0x53, 0xfb, 0xdf, 0xaa, 0xce, 0x63, 0xde, 0xc5, 0xfe, 0x47, 0xe6, 0x52, 0xeb, 0xf3, 0x5d, 0x53, 0xa8, 0xbf, 0x9d, 0xd6, 0x09, 0x6b, 0x5e, 0x7f, 0xe0, 0x0d, 0x51, 0x30, 0x85, 0x6a, 0xda, 0x68, 0x70, 0x85, 0xb0, 0xdb, 0x08, 0x0b, 0x83, 0x2c, 0xef, 0x44, 0xe2, 0x36, 0x88, 0xee, 0x76, 0x90, 0x6e, 0x7b, 0x50, 0x3e, 0x9a, 0xa0, 0xd6, 0x3c, 0x34, 0xe3, 0x83, 0xe7, 0xd1, 0xbd, 0x9f, 0x25, 0xa5, 0x03, 0x26, 0x01, 0x02, 0x20, 0x01, 0x21, 0x58, 0x20, 0x17, 0x5b, 0x27, 0xa6, 0x56, 0xb2, 0x26, 0x0c, 0x26, 0x0c, 0x55, 0x42, 0x78, 0x17, 0x5d, 0x4c, 0xf8, 0xa2, 0xfd, 0x1b, 0xb9, 0x54, 0xdf, 0xd5, 0xeb, 0xbf, 0x22, 0x64, 0xf5, 0x21, 0x9a, 0xc6, 0x22, 0x58, 0x20, 0x87, 0x5f, 0x90, 0xe6, 0xfd, 0x71, 0x27, 0x9f, 0xeb, 0xe3, 0x03, 0x44, 0xbc, 0x8d, 0x49, 0xc6, 0x1c, 0x31, 0x3b, 0x72, 0xae, 0xd4, 0x53, 0xb1, 0xfe, 0x5d, 0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2, }; -const unsigned char authdata_tpm[362] = { +const unsigned char authdata_tpm_rs256[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 authdata_tpm_es256[166] = { + 0x58, 0xa4, 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, 0xa8, 0xdf, 0x03, 0xf7, 0xbf, 0x39, 0x51, + 0x94, 0x95, 0x8f, 0xa4, 0x84, 0x97, 0x30, 0xbc, + 0x3c, 0x7e, 0x1c, 0x99, 0x91, 0x4d, 0xae, 0x6d, + 0xfb, 0xdf, 0x53, 0xb5, 0xb6, 0x1f, 0x3a, 0x4e, + 0x6a, 0xa5, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, + 0x21, 0x58, 0x20, 0xfb, 0xd6, 0xba, 0x74, 0xe6, + 0x6e, 0x5c, 0x87, 0xef, 0x89, 0xa2, 0xe8, 0x3d, + 0x0b, 0xe9, 0x69, 0x2c, 0x07, 0x07, 0x7a, 0x8a, + 0x1e, 0xce, 0x12, 0xea, 0x3b, 0xb3, 0xf1, 0xf3, + 0xd9, 0xc3, 0xe6, 0x22, 0x58, 0x20, 0x3c, 0x68, + 0x51, 0x94, 0x54, 0x8d, 0xeb, 0x9f, 0xb2, 0x2c, + 0x66, 0x75, 0xb6, 0xb7, 0x55, 0x22, 0x0d, 0x87, + 0x59, 0xc4, 0x39, 0x91, 0x62, 0x17, 0xc2, 0xc3, + 0x53, 0xa5, 0x26, 0x97, 0x4f, 0x2d +}; + static const unsigned char x509[742] = { 0x30, 0x82, 0x02, 0xe2, 0x30, 0x81, 0xcb, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x59, 0x75, 0x62, 0x69, 0x63, 0x6f, 0x20, 0x55, 0x32, 0x46, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x35, 0x31, 0x35, 0x31, 0x32, 0x35, 0x38, 0x35, 0x34, 0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x36, 0x31, 0x34, 0x31, 0x32, 0x35, 0x38, 0x35, 0x34, 0x5a, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x59, 0x75, 0x62, 0x69, 0x63, 0x6f, 0x20, 0x55, 0x32, 0x46, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x45, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xdb, 0x0a, 0xdb, 0xf5, 0x21, 0xc7, 0x5c, 0xce, 0x63, 0xdc, 0xa6, 0xe1, 0xe8, 0x25, 0x06, 0x0d, 0x94, 0xe6, 0x27, 0x54, 0x19, 0x4f, 0x9d, 0x24, 0xaf, 0x26, 0x1a, 0xbe, 0xad, 0x99, 0x44, 0x1f, 0x95, 0xa3, 0x71, 0x91, 0x0a, 0x3a, 0x20, 0xe7, 0x3e, 0x91, 0x5e, 0x13, 0xe8, 0xbe, 0x38, 0x05, 0x7a, 0xd5, 0x7a, 0xa3, 0x7e, 0x76, 0x90, 0x8f, 0xaf, 0xe2, 0x8a, 0x94, 0xb6, 0x30, 0xeb, 0x9d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x95, 0x40, 0x6b, 0x50, 0x61, 0x7d, 0xad, 0x84, 0xa3, 0xb4, 0xeb, 0x88, 0x0f, 0xe3, 0x30, 0x0f, 0x2d, 0xa2, 0x0a, 0x00, 0xd9, 0x25, 0x04, 0xee, 0x72, 0xfa, 0x67, 0xdf, 0x58, 0x51, 0x0f, 0x0b, 0x47, 0x02, 0x9c, 0x3e, 0x41, 0x29, 0x4a, 0x93, 0xac, 0x29, 0x85, 0x89, 0x2d, 0xa4, 0x7a, 0x81, 0x32, 0x28, 0x57, 0x71, 0x01, 0xef, 0xa8, 0x42, 0x88, 0x16, 0x96, 0x37, 0x91, 0xd5, 0xdf, 0xe0, 0x8f, 0xc9, 0x3c, 0x8d, 0xb0, 0xcd, 0x89, 0x70, 0x82, 0xec, 0x79, 0xd3, 0xc6, 0x78, 0x73, 0x29, 0x32, 0xe5, 0xab, 0x6c, 0xbd, 0x56, 0x9f, 0xd5, 0x45, 0x91, 0xce, 0xc1, 0xdd, 0x8d, 0x64, 0xdc, 0xe9, 0x9c, 0x1f, 0x5e, 0x3c, 0xd2, 0xaf, 0x51, 0xa5, 0x82, 0x18, 0xaf, 0xe0, 0x37, 0xe7, 0x32, 0x9e, 0x76, 0x05, 0x77, 0x02, 0x7b, 0xe6, 0x24, 0xa0, 0x31, 0x56, 0x1b, 0xfd, 0x19, 0xc5, 0x71, 0xd3, 0xf0, 0x9e, 0xc0, 0x73, 0x05, 0x4e, 0xbc, 0x85, 0xb8, 0x53, 0x9e, 0xef, 0xc5, 0xbc, 0x9c, 0x56, 0xa3, 0xba, 0xd9, 0x27, 0x6a, 0xbb, 0xa9, 0x7a, 0x40, 0xd7, 0x47, 0x8b, 0x55, 0x72, 0x6b, 0xe3, 0xfe, 0x28, 0x49, 0x71, 0x24, 0xf4, 0x8f, 0xf4, 0x20, 0x81, 0xea, 0x38, 0xff, 0x7c, 0x0a, 0x4f, 0xdf, 0x02, 0x82, 0x39, 0x81, 0x82, 0x3b, 0xca, 0x09, 0xdd, 0xca, 0xaa, 0x0f, 0x27, 0xf5, 0xa4, 0x83, 0x55, 0x6c, 0x9a, 0x39, 0x9b, 0x15, 0x3a, 0x16, 0x63, 0xdc, 0x5b, 0xf9, 0xac, 0x5b, 0xbc, 0xf7, 0x9f, 0xbe, 0x0f, 0x8a, 0xa2, 0x3c, 0x31, 0x13, 0xa3, 0x32, 0x48, 0xca, 0x58, 0x87, 0xf8, 0x7b, 0xa0, 0xa1, 0x0a, 0x6a, 0x60, 0x96, 0x93, 0x5f, 0x5d, 0x26, 0x9e, 0x63, 0x1d, 0x09, 0xae, 0x9a, 0x41, 0xe5, 0xbd, 0x08, 0x47, 0xfe, 0xe5, 0x09, 0x9b, 0x20, 0xfd, 0x12, 0xe2, 0xe6, 0x40, 0x7f, 0xba, 0x4a, 0x61, 0x33, 0x66, 0x0d, 0x0e, 0x73, 0xdb, 0xb0, 0xd5, 0xa2, 0x9a, 0x9a, 0x17, 0x0d, 0x34, 0x30, 0x85, 0x6a, 0x42, 0x46, 0x9e, 0xff, 0x34, 0x8f, 0x5f, 0x87, 0x6c, 0x35, 0xe7, 0xa8, 0x4d, 0x35, 0xeb, 0xc1, 0x41, 0xaa, 0x8a, 0xd2, 0xda, 0x19, 0xaa, 0x79, 0xa2, 0x5f, 0x35, 0x2c, 0xa0, 0xfd, 0x25, 0xd3, 0xf7, 0x9d, 0x25, 0x18, 0x2d, 0xfa, 0xb4, 0xbc, 0xbb, 0x07, 0x34, 0x3c, 0x8d, 0x81, 0xbd, 0xf4, 0xe9, 0x37, 0xdb, 0x39, 0xe9, 0xd1, 0x45, 0x5b, 0x20, 0x41, 0x2f, 0x2d, 0x27, 0x22, 0xdc, 0x92, 0x74, 0x8a, 0x92, 0xd5, 0x83, 0xfd, 0x09, 0xfb, 0x13, 0x9b, 0xe3, 0x39, 0x7a, 0x6b, 0x5c, 0xfa, 0xe6, 0x76, 0x9e, 0xe0, 0xe4, 0xe3, 0xef, 0xad, 0xbc, 0xfd, 0x42, 0x45, 0x9a, 0xd4, 0x94, 0xd1, 0x7e, 0x8d, 0xa7, 0xd8, 0x05, 0xd5, 0xd3, 0x62, 0xcf, 0x15, 0xcf, 0x94, 0x7d, 0x1f, 0x5b, 0x58, 0x20, 0x44, 0x20, 0x90, 0x71, 0xbe, 0x66, 0xe9, 0x9a, 0xab, 0x74, 0x32, 0x70, 0x53, 0x1d, 0x69, 0xed, 0x87, 0x66, 0xf4, 0x09, 0x4f, 0xca, 0x25, 0x30, 0xc2, 0x63, 0x79, 0x00, 0x3c, 0xb1, 0x9b, 0x39, 0x3f, 0x00, 0xe0, 0xa8, 0x88, 0xef, 0x7a, 0x51, 0x5b, 0xe7, 0xbd, 0x49, 0x64, 0xda, 0x41, 0x7b, 0x24, 0xc3, 0x71, 0x22, 0xfd, 0xd1, 0xd1, 0x20, 0xb3, 0x3f, 0x97, 0xd3, 0x97, 0xb2, 0xaa, 0x18, 0x1c, 0x9e, 0x03, 0x77, 0x7b, 0x5b, 0x7e, 0xf9, 0xa3, 0xa0, 0xd6, 0x20, 0x81, 0x2c, 0x38, 0x8f, 0x9d, 0x25, 0xde, 0xe9, 0xc8, 0xf5, 0xdd, 0x6a, 0x47, 0x9c, 0x65, 0x04, 0x5a, 0x56, 0xe6, 0xc2, 0xeb, 0xf2, 0x02, 0x97, 0xe1, 0xb9, 0xd8, 0xe1, 0x24, 0x76, 0x9f, 0x23, 0x62, 0x39, 0x03, 0x4b, 0xc8, 0xf7, 0x34, 0x07, 0x49, 0xd6, 0xe7, 0x4d, 0x9a, }; const unsigned char sig[70] = { 0x30, 0x44, 0x02, 0x20, 0x54, 0x92, 0x28, 0x3b, 0x83, 0x33, 0x47, 0x56, 0x68, 0x79, 0xb2, 0x0c, 0x84, 0x80, 0xcc, 0x67, 0x27, 0x8b, 0xfa, 0x48, 0x43, 0x0d, 0x3c, 0xb4, 0x02, 0x36, 0x87, 0x97, 0x3e, 0xdf, 0x2f, 0x65, 0x02, 0x20, 0x1b, 0x56, 0x17, 0x06, 0xe2, 0x26, 0x0f, 0x6a, 0xe9, 0xa9, 0x70, 0x99, 0x62, 0xeb, 0x3a, 0x04, 0x1a, 0xc4, 0xa7, 0x03, 0x28, 0x56, 0x7c, 0xed, 0x47, 0x08, 0x68, 0x73, 0x6a, 0xb6, 0x89, 0x0d, }; const unsigned char pubkey[64] = { 0x17, 0x5b, 0x27, 0xa6, 0x56, 0xb2, 0x26, 0x0c, 0x26, 0x0c, 0x55, 0x42, 0x78, 0x17, 0x5d, 0x4c, 0xf8, 0xa2, 0xfd, 0x1b, 0xb9, 0x54, 0xdf, 0xd5, 0xeb, 0xbf, 0x22, 0x64, 0xf5, 0x21, 0x9a, 0xc6, 0x87, 0x5f, 0x90, 0xe6, 0xfd, 0x71, 0x27, 0x9f, 0xeb, 0xe3, 0x03, 0x44, 0xbc, 0x8d, 0x49, 0xc6, 0x1c, 0x31, 0x3b, 0x72, 0xae, 0xd4, 0x53, 0xb1, 0xfe, 0x5d, 0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2, }; -const unsigned char pubkey_tpm[259] = { +const unsigned char pubkey_tpm_rs256[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 pubkey_tpm_es256[64] = { + 0xfb, 0xd6, 0xba, 0x74, 0xe6, 0x6e, 0x5c, 0x87, + 0xef, 0x89, 0xa2, 0xe8, 0x3d, 0x0b, 0xe9, 0x69, + 0x2c, 0x07, 0x07, 0x7a, 0x8a, 0x1e, 0xce, 0x12, + 0xea, 0x3b, 0xb3, 0xf1, 0xf3, 0xd9, 0xc3, 0xe6, + 0x3c, 0x68, 0x51, 0x94, 0x54, 0x8d, 0xeb, 0x9f, + 0xb2, 0x2c, 0x66, 0x75, 0xb6, 0xb7, 0x55, 0x22, + 0x0d, 0x87, 0x59, 0xc4, 0x39, 0x91, 0x62, 0x17, + 0xc2, 0xc3, 0x53, 0xa5, 0x26, 0x97, 0x4f, 0x2d +}; + const unsigned char id[64] = { 0x53, 0xfb, 0xdf, 0xaa, 0xce, 0x63, 0xde, 0xc5, 0xfe, 0x47, 0xe6, 0x52, 0xeb, 0xf3, 0x5d, 0x53, 0xa8, 0xbf, 0x9d, 0xd6, 0x09, 0x6b, 0x5e, 0x7f, 0xe0, 0x0d, 0x51, 0x30, 0x85, 0x6a, 0xda, 0x68, 0x70, 0x85, 0xb0, 0xdb, 0x08, 0x0b, 0x83, 0x2c, 0xef, 0x44, 0xe2, 0x36, 0x88, 0xee, 0x76, 0x90, 0x6e, 0x7b, 0x50, 0x3e, 0x9a, 0xa0, 0xd6, 0x3c, 0x34, 0xe3, 0x83, 0xe7, 0xd1, 0xbd, 0x9f, 0x25, }; -const unsigned char id_tpm[32] = { +const unsigned char id_tpm_rs256[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] = { +const unsigned char id_tpm_es256[32] = { + 0xa8, 0xdf, 0x03, 0xf7, 0xbf, 0x39, 0x51, 0x94, + 0x95, 0x8f, 0xa4, 0x84, 0x97, 0x30, 0xbc, 0x3c, + 0x7e, 0x1c, 0x99, 0x91, 0x4d, 0xae, 0x6d, 0xfb, + 0xdf, 0x53, 0xb5, 0xb6, 0x1f, 0x3a, 0x4e, 0x6a +}; + +const unsigned char attstmt_tpm_rs256[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 }; +const unsigned char attstmt_tpm_es256[3841] = { + 0xa6, 0x63, 0x61, 0x6c, 0x67, 0x39, 0xff, 0xfe, + 0x63, 0x73, 0x69, 0x67, 0x59, 0x01, 0x00, 0x6d, + 0x11, 0x61, 0x1f, 0x45, 0xb9, 0x7f, 0x65, 0x6f, + 0x97, 0x46, 0xfe, 0xbb, 0x8a, 0x98, 0x07, 0xa3, + 0xbc, 0x67, 0x5c, 0xd7, 0x65, 0xa4, 0xf4, 0x6c, + 0x5b, 0x37, 0x75, 0xa4, 0x7f, 0x08, 0x52, 0xeb, + 0x1e, 0x12, 0xe2, 0x78, 0x8c, 0x7d, 0x94, 0xab, + 0x7b, 0xed, 0x05, 0x17, 0x67, 0x7e, 0xaa, 0x02, + 0x89, 0x6d, 0xe8, 0x6d, 0x43, 0x30, 0x99, 0xc6, + 0xf9, 0x59, 0xe5, 0x82, 0x3c, 0x56, 0x4e, 0x77, + 0x11, 0x25, 0xe4, 0x43, 0x6a, 0xae, 0x92, 0x4f, + 0x60, 0x92, 0x50, 0xf9, 0x65, 0x0e, 0x44, 0x38, + 0x3d, 0xf7, 0xaf, 0x66, 0x89, 0xc7, 0xe6, 0xe6, + 0x01, 0x07, 0x9e, 0x90, 0xfd, 0x6d, 0xaa, 0x35, + 0x51, 0x51, 0xbf, 0x54, 0x13, 0x95, 0xc2, 0x17, + 0xfa, 0x32, 0x0f, 0xa7, 0x82, 0x17, 0x58, 0x6c, + 0x3d, 0xea, 0x88, 0xd8, 0x64, 0xc7, 0xf8, 0xc2, + 0xd6, 0x1c, 0xbb, 0xea, 0x1e, 0xb3, 0xd9, 0x4c, + 0xa7, 0xce, 0x18, 0x1e, 0xcb, 0x42, 0x5f, 0xbf, + 0x44, 0xe7, 0xf1, 0x22, 0xe0, 0x5b, 0xeb, 0xff, + 0xb6, 0x1e, 0x6f, 0x60, 0x12, 0x16, 0x63, 0xfe, + 0xab, 0x5e, 0x31, 0x13, 0xdb, 0x72, 0xc6, 0x9a, + 0xf8, 0x8f, 0x19, 0x6b, 0x2e, 0xaf, 0x7d, 0xca, + 0x9f, 0xbc, 0x6b, 0x1a, 0x8b, 0x5e, 0xe3, 0x9e, + 0xaa, 0x8c, 0x79, 0x9c, 0x4e, 0xed, 0xe4, 0xff, + 0x3d, 0x12, 0x79, 0x90, 0x09, 0x61, 0x97, 0x67, + 0xbf, 0x04, 0xac, 0x37, 0xea, 0xa9, 0x1f, 0x9f, + 0x52, 0x64, 0x0b, 0xeb, 0xc3, 0x61, 0xd4, 0x13, + 0xb0, 0x84, 0xf1, 0x3c, 0x74, 0x83, 0xcc, 0xa8, + 0x1c, 0x14, 0xe6, 0x9d, 0xfe, 0xec, 0xee, 0xa1, + 0xd2, 0xc2, 0x0a, 0xa6, 0x36, 0x08, 0xbb, 0x17, + 0xa5, 0x7b, 0x53, 0x34, 0x0e, 0xc9, 0x09, 0xe5, + 0x10, 0xa6, 0x85, 0x01, 0x71, 0x66, 0xff, 0xd0, + 0x6d, 0x4b, 0x93, 0xdb, 0x81, 0x25, 0x01, 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, 0x30, 0xcd, + 0xf2, 0x7e, 0x81, 0xc0, 0x43, 0x85, 0xa2, 0xd7, + 0x29, 0xef, 0xf7, 0x9f, 0xa5, 0x2b, 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, 0x31, 0x31, + 0x30, 0x32, 0x31, 0x35, 0x30, 0x36, 0x35, 0x33, + 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x36, 0x30, + 0x33, 0x31, 0x39, 0x34, 0x30, 0x31, 0x36, 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, 0xdb, 0xd5, 0x9a, 0xfc, 0x09, + 0xa7, 0xc4, 0xa5, 0x5f, 0xbe, 0x5f, 0xa2, 0xeb, + 0xd6, 0x8e, 0xed, 0xc5, 0x67, 0xa6, 0xa7, 0xd9, + 0xb2, 0x46, 0xc6, 0xe0, 0xae, 0x0c, 0x02, 0x25, + 0x0a, 0xf2, 0xc5, 0x96, 0xdc, 0xb7, 0x0e, 0xb9, + 0x86, 0xd3, 0x51, 0xbb, 0x63, 0xf0, 0x4f, 0x8a, + 0x5e, 0xd7, 0xf7, 0xff, 0xbb, 0x29, 0xbd, 0x58, + 0xcf, 0x75, 0x02, 0x39, 0xcb, 0x80, 0xf1, 0xd4, + 0xb6, 0x75, 0x67, 0x2f, 0x27, 0x4d, 0x0c, 0xcc, + 0x18, 0x59, 0x87, 0xfa, 0x51, 0xd1, 0x80, 0xb5, + 0x1a, 0xac, 0xac, 0x29, 0x51, 0xcf, 0x27, 0xaa, + 0x74, 0xac, 0x3e, 0x59, 0x56, 0x67, 0xe4, 0x42, + 0xe8, 0x30, 0x35, 0xb2, 0xf6, 0x27, 0x91, 0x62, + 0x60, 0x42, 0x42, 0x12, 0xde, 0xfe, 0xdd, 0xee, + 0xe8, 0xa8, 0x82, 0xf9, 0xb1, 0x08, 0xd5, 0x8d, + 0x57, 0x9a, 0x29, 0xb9, 0xb4, 0xe9, 0x19, 0x1e, + 0x33, 0x7d, 0x37, 0xa0, 0xce, 0x2e, 0x53, 0x13, + 0x39, 0xb6, 0x12, 0x61, 0x63, 0xbf, 0xd3, 0x42, + 0xeb, 0x6f, 0xed, 0xc1, 0x8e, 0x26, 0xba, 0x7d, + 0x8b, 0x37, 0x7c, 0xbb, 0x42, 0x1e, 0x56, 0x76, + 0xda, 0xdb, 0x35, 0x6b, 0x80, 0xe1, 0x8e, 0x00, + 0xac, 0xd2, 0xfc, 0x22, 0x96, 0x14, 0x0c, 0xf4, + 0xe4, 0xc5, 0xad, 0x14, 0xb7, 0x4d, 0x46, 0x63, + 0x30, 0x79, 0x3a, 0x7c, 0x33, 0xb5, 0xe5, 0x2e, + 0xbb, 0x5f, 0xca, 0xf2, 0x75, 0xe3, 0x4e, 0x99, + 0x64, 0x1b, 0x26, 0x99, 0x60, 0x1a, 0x79, 0xcc, + 0x30, 0x2c, 0xb3, 0x4c, 0x59, 0xf7, 0x77, 0x59, + 0xd5, 0x90, 0x70, 0x21, 0x79, 0x8c, 0x1f, 0x79, + 0x0a, 0x12, 0x8b, 0x3b, 0x37, 0x2d, 0x97, 0x39, + 0x89, 0x92, 0x0c, 0x44, 0x7c, 0xe9, 0x9f, 0xce, + 0x6d, 0xad, 0xc5, 0xae, 0xea, 0x8e, 0x50, 0x22, + 0x37, 0xe0, 0xd1, 0x9e, 0xd6, 0xe6, 0xa8, 0xcc, + 0x21, 0xfb, 0xff, 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, 0x45, + 0x1a, 0xec, 0xfc, 0x91, 0x70, 0xf8, 0x83, 0x8b, + 0x9c, 0x47, 0x2f, 0x0b, 0x9f, 0x07, 0xf3, 0x2f, + 0x7c, 0xa2, 0x8a, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x55, 0xa6, + 0xee, 0xe3, 0x28, 0xdd, 0x40, 0x7f, 0x21, 0xd2, + 0x7b, 0x8c, 0x69, 0x2f, 0x8c, 0x08, 0x29, 0xbc, + 0x95, 0xb8, 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, 0x62, + 0x36, 0x63, 0x30, 0x64, 0x39, 0x38, 0x64, 0x2d, + 0x35, 0x37, 0x38, 0x61, 0x2d, 0x34, 0x62, 0x66, + 0x62, 0x2d, 0x61, 0x32, 0x64, 0x33, 0x2d, 0x65, + 0x64, 0x66, 0x65, 0x35, 0x66, 0x38, 0x32, 0x30, + 0x36, 0x30, 0x31, 0x2e, 0x63, 0x65, 0x72, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, + 0x02, 0x01, 0x00, 0x2a, 0x08, 0x30, 0x1f, 0xfd, + 0x8f, 0x80, 0x9b, 0x4b, 0x37, 0x82, 0x61, 0x86, + 0x36, 0x57, 0x90, 0xb5, 0x1d, 0x1f, 0xa3, 0xae, + 0x68, 0xac, 0xa7, 0x96, 0x6a, 0x25, 0x5e, 0xc5, + 0x82, 0x7c, 0x36, 0x64, 0x58, 0x11, 0xcb, 0xa5, + 0xee, 0xbf, 0xc4, 0xdb, 0xa0, 0xc7, 0x82, 0x3b, + 0xa3, 0x85, 0x9b, 0xc4, 0xee, 0x07, 0x36, 0xd7, + 0xc7, 0xb6, 0x23, 0xed, 0xc2, 0x73, 0xab, 0xbe, + 0xbe, 0xee, 0x63, 0x17, 0xf9, 0xd7, 0x7a, 0x23, + 0x7b, 0xf8, 0x09, 0x7a, 0xaa, 0x7f, 0x67, 0xc3, + 0x04, 0x84, 0x71, 0x9b, 0x06, 0x9c, 0x07, 0x42, + 0x4b, 0x65, 0x41, 0x56, 0x58, 0x14, 0x92, 0xb0, + 0xb9, 0xaf, 0xa1, 0x39, 0xd4, 0x08, 0x2d, 0x71, + 0xd5, 0x6c, 0x56, 0xb9, 0x2b, 0x1e, 0xf3, 0x93, + 0xa5, 0xe9, 0xb2, 0x9b, 0x4d, 0x05, 0x2b, 0xbc, + 0xd2, 0x20, 0x57, 0x3b, 0xa4, 0x01, 0x68, 0x8c, + 0x23, 0x20, 0x7d, 0xbb, 0x71, 0xe4, 0x2a, 0x24, + 0xba, 0x75, 0x0c, 0x89, 0x54, 0x22, 0xeb, 0x0e, + 0xb2, 0xf4, 0xc2, 0x1f, 0x02, 0xb7, 0xe3, 0x06, + 0x41, 0x15, 0x6b, 0xf3, 0xc8, 0x2d, 0x5b, 0xc2, + 0x21, 0x82, 0x3e, 0xe8, 0x95, 0x40, 0x39, 0x9e, + 0x91, 0x68, 0x33, 0x0c, 0x3d, 0x45, 0xef, 0x99, + 0x79, 0xe6, 0x32, 0xc9, 0x00, 0x84, 0x36, 0xfb, + 0x0a, 0x8d, 0x41, 0x1c, 0x32, 0x64, 0x06, 0x9e, + 0x0f, 0xb5, 0x04, 0xcc, 0x08, 0xb1, 0xb6, 0x2b, + 0xcf, 0x36, 0x0f, 0x73, 0x14, 0x8e, 0x25, 0x44, + 0xb3, 0x0c, 0x34, 0x14, 0x96, 0x0c, 0x8a, 0x65, + 0xa1, 0xde, 0x8e, 0xc8, 0x9d, 0xbe, 0x66, 0xdf, + 0x06, 0x91, 0xca, 0x15, 0x0f, 0x92, 0xd5, 0x2a, + 0x0b, 0xdc, 0x4c, 0x6a, 0xf3, 0x16, 0x4a, 0x3e, + 0xb9, 0x76, 0xbc, 0xfe, 0x62, 0xd4, 0xa8, 0xcd, + 0x94, 0x78, 0x0d, 0xdd, 0x94, 0xfd, 0x5e, 0x63, + 0x57, 0x27, 0x05, 0x9c, 0xd0, 0x80, 0x91, 0x91, + 0x79, 0xe8, 0x5e, 0x18, 0x64, 0x22, 0xe4, 0x2c, + 0x13, 0x65, 0xa4, 0x51, 0x5a, 0x1e, 0x3b, 0x71, + 0x2e, 0x70, 0x9f, 0xc4, 0xa5, 0x20, 0xcd, 0xef, + 0xd8, 0x3f, 0xa4, 0xf5, 0x89, 0x8a, 0xa5, 0x4f, + 0x76, 0x2d, 0x49, 0x56, 0x00, 0x8d, 0xde, 0x40, + 0xba, 0x24, 0x46, 0x51, 0x38, 0xad, 0xdb, 0xc4, + 0x04, 0xf4, 0x6e, 0xc0, 0x29, 0x48, 0x07, 0x6a, + 0x1b, 0x26, 0x32, 0x0a, 0xfb, 0xea, 0x71, 0x2a, + 0x11, 0xfc, 0x98, 0x7c, 0x44, 0x87, 0xbc, 0x06, + 0x3a, 0x4d, 0xbd, 0x91, 0x63, 0x4f, 0x26, 0x48, + 0x54, 0x47, 0x1b, 0xbd, 0xf0, 0xf1, 0x56, 0x05, + 0xc5, 0x0f, 0x8f, 0x20, 0xa5, 0xcc, 0xfb, 0x76, + 0xb0, 0xbd, 0x83, 0xde, 0x7f, 0x39, 0x4f, 0xcf, + 0x61, 0x74, 0x52, 0xa7, 0x1d, 0xf6, 0xb5, 0x5e, + 0x4a, 0x82, 0x20, 0xc1, 0x94, 0xaa, 0x2c, 0x33, + 0xd6, 0x0a, 0xf9, 0x8f, 0x92, 0xc6, 0x29, 0x80, + 0xf5, 0xa2, 0xb1, 0xff, 0xb6, 0x2b, 0xaa, 0x04, + 0x00, 0x72, 0xb4, 0x12, 0xbb, 0xb1, 0xf1, 0x3c, + 0x88, 0xa3, 0xab, 0x49, 0x17, 0x90, 0x80, 0x59, + 0xa2, 0x96, 0x41, 0x69, 0x74, 0x33, 0x8a, 0x28, + 0x33, 0x7e, 0xb3, 0x19, 0x92, 0x28, 0xc1, 0xf0, + 0xd1, 0x82, 0xd5, 0x42, 0xff, 0xe7, 0xa5, 0x3f, + 0x1e, 0xb6, 0x4a, 0x23, 0xcc, 0x6a, 0x7f, 0x15, + 0x15, 0x52, 0x25, 0xb1, 0xca, 0x21, 0x95, 0x11, + 0x53, 0x3e, 0x1f, 0x50, 0x33, 0x12, 0x7a, 0x62, + 0xce, 0xcc, 0x71, 0xc2, 0x5f, 0x34, 0x47, 0xc6, + 0x7c, 0x71, 0xfa, 0xa0, 0x54, 0x00, 0xb2, 0xdf, + 0xc5, 0x54, 0xac, 0x6c, 0x53, 0xef, 0x64, 0x6b, + 0x08, 0x82, 0xd8, 0x16, 0x1e, 0xca, 0x40, 0xf3, + 0x1f, 0xdf, 0x56, 0x63, 0x10, 0xbc, 0xd7, 0xa0, + 0xeb, 0xee, 0xd1, 0x95, 0xe5, 0xef, 0xf1, 0x6a, + 0x83, 0x2d, 0x5a, 0x59, 0x06, 0xef, 0x30, 0x82, + 0x06, 0xeb, 0x30, 0x82, 0x04, 0xd3, 0xa0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x13, 0x33, 0x00, 0x00, + 0x05, 0x23, 0xbf, 0xe8, 0xa1, 0x1a, 0x2a, 0x68, + 0xbd, 0x09, 0x00, 0x00, 0x00, 0x00, 0x05, 0x23, + 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, 0x32, 0x31, 0x30, 0x36, 0x30, 0x33, + 0x31, 0x39, 0x34, 0x30, 0x31, 0x36, 0x5a, 0x17, + 0x0d, 0x32, 0x37, 0x30, 0x36, 0x30, 0x33, 0x31, + 0x39, 0x34, 0x30, 0x31, 0x36, 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, 0x03, 0x34, 0x82, 0xfa, 0x81, + 0x1c, 0x84, 0x0b, 0xa0, 0x0e, 0x60, 0xd8, 0x9d, + 0x84, 0xf4, 0x81, 0xc4, 0xe9, 0xff, 0xcf, 0xe9, + 0xa3, 0x57, 0x53, 0x60, 0xa8, 0x19, 0xce, 0xbe, + 0xe1, 0x97, 0xee, 0x5d, 0x8c, 0x9f, 0xe4, 0xbd, + 0xef, 0xbd, 0x94, 0x14, 0xe4, 0x74, 0x41, 0x02, + 0xe9, 0x03, 0x19, 0x9f, 0xdd, 0x48, 0x2d, 0xbd, + 0xca, 0x26, 0x47, 0x2c, 0x01, 0x31, 0x5f, 0x34, + 0xef, 0x59, 0x35, 0x48, 0x36, 0x3d, 0x1e, 0xdf, + 0xd8, 0x13, 0xf0, 0xd0, 0x67, 0xc1, 0xb0, 0x47, + 0x67, 0xa2, 0xd6, 0x62, 0xc8, 0xe1, 0x00, 0x36, + 0x8b, 0x45, 0xf6, 0x3b, 0x96, 0x60, 0xa0, 0x45, + 0x26, 0xcb, 0xc7, 0x0b, 0x5b, 0x97, 0xd1, 0xaf, + 0x54, 0x25, 0x7a, 0x67, 0xe4, 0x2a, 0xd8, 0x9d, + 0x53, 0x05, 0xbd, 0x12, 0xac, 0xa2, 0x8e, 0x95, + 0xb4, 0x2a, 0xca, 0x89, 0x93, 0x64, 0x97, 0x25, + 0xdc, 0x1f, 0xa9, 0xe0, 0x55, 0x07, 0x38, 0x1d, + 0xee, 0x02, 0x90, 0x22, 0xf5, 0xad, 0x4e, 0x5c, + 0xf8, 0xc5, 0x1f, 0x9e, 0x84, 0x7e, 0x13, 0x47, + 0x52, 0xa2, 0x36, 0xf9, 0xf6, 0xbf, 0x76, 0x9e, + 0x0f, 0xdd, 0x14, 0x99, 0xb9, 0xd8, 0x5a, 0x42, + 0x3d, 0xd8, 0xbf, 0xdd, 0xb4, 0x9b, 0xbf, 0x6a, + 0x9f, 0x89, 0x13, 0x75, 0xaf, 0x96, 0xd2, 0x72, + 0xdf, 0xb3, 0x80, 0x6f, 0x84, 0x1a, 0x9d, 0x06, + 0x55, 0x09, 0x29, 0xea, 0xa7, 0x05, 0x31, 0xec, + 0x47, 0x3a, 0xcf, 0x3f, 0x9c, 0x2c, 0xbd, 0xd0, + 0x7d, 0xe4, 0x75, 0x5b, 0x33, 0xbe, 0x12, 0x86, + 0x09, 0xcf, 0x66, 0x9a, 0xeb, 0xf8, 0xf8, 0x72, + 0x91, 0x88, 0x4a, 0x5e, 0x89, 0x62, 0x6a, 0x94, + 0xdc, 0x48, 0x37, 0x13, 0xd8, 0x91, 0x02, 0xe3, + 0x42, 0x41, 0x7c, 0x2f, 0xe3, 0xb6, 0x0f, 0xb4, + 0x96, 0x06, 0x80, 0xca, 0x28, 0x01, 0x6f, 0x4b, + 0xcd, 0x28, 0xd4, 0x2c, 0x94, 0x7e, 0x40, 0x7e, + 0xdf, 0x01, 0xe5, 0xf2, 0x33, 0xd4, 0xda, 0xf4, + 0x1a, 0x17, 0xf7, 0x5d, 0xcb, 0x66, 0x2c, 0x2a, + 0xeb, 0xe1, 0xb1, 0x4a, 0xc3, 0x85, 0x63, 0xb2, + 0xac, 0xd0, 0x3f, 0x1a, 0x8d, 0xa5, 0x0c, 0xee, + 0x4f, 0xde, 0x74, 0x9c, 0xe0, 0x5a, 0x10, 0xc7, + 0xb8, 0xe4, 0xec, 0xe7, 0x73, 0xa6, 0x41, 0x42, + 0x37, 0xe1, 0xdf, 0xb9, 0xc7, 0xb5, 0x14, 0xa8, + 0x80, 0x95, 0xa0, 0x12, 0x67, 0x99, 0xf5, 0xba, + 0x25, 0x0a, 0x74, 0x86, 0x71, 0x9c, 0x7f, 0x59, + 0x97, 0xd2, 0x3f, 0x10, 0xfe, 0x6a, 0xb9, 0xe4, + 0x47, 0x36, 0xfb, 0x0f, 0x50, 0xee, 0xfc, 0x87, + 0x99, 0x7e, 0x36, 0x64, 0x1b, 0xc7, 0x13, 0xb3, + 0x33, 0x18, 0x71, 0xa4, 0xc3, 0xb0, 0xfc, 0x45, + 0x37, 0x11, 0x40, 0xb3, 0xde, 0x2c, 0x9f, 0x0a, + 0xcd, 0xaf, 0x5e, 0xfb, 0xd5, 0x9c, 0xea, 0xd7, + 0x24, 0x19, 0x3a, 0x92, 0x80, 0xa5, 0x63, 0xc5, + 0x3e, 0xdd, 0x51, 0xd0, 0x9f, 0xb8, 0x5e, 0xd5, + 0xf1, 0xfe, 0xa5, 0x93, 0xfb, 0x7f, 0xd9, 0xb8, + 0xb7, 0x0e, 0x0d, 0x12, 0x71, 0xf0, 0x52, 0x9d, + 0xe9, 0xd0, 0xd2, 0x8b, 0x38, 0x8b, 0x85, 0x83, + 0x98, 0x24, 0x88, 0xe8, 0x42, 0x30, 0x83, 0x12, + 0xef, 0x09, 0x96, 0x2f, 0x21, 0x81, 0x05, 0x30, + 0x0c, 0xbb, 0xba, 0x21, 0x39, 0x16, 0x12, 0xe8, + 0x4b, 0x7b, 0x7a, 0x66, 0xb8, 0x22, 0x2c, 0x71, + 0xaf, 0x59, 0xa1, 0xfc, 0x61, 0xf1, 0xb4, 0x5e, + 0xfc, 0x43, 0x19, 0x45, 0x6e, 0xa3, 0x45, 0xe4, + 0xcb, 0x66, 0x5f, 0xe0, 0x57, 0xf6, 0x0a, 0x30, + 0xa3, 0xd6, 0x51, 0x24, 0xc9, 0x07, 0x55, 0x82, + 0x4a, 0x66, 0x0e, 0x9d, 0xb2, 0x2f, 0x84, 0x56, + 0x6c, 0x3e, 0x71, 0xef, 0x9b, 0x35, 0x4d, 0x72, + 0xdc, 0x46, 0x2a, 0xe3, 0x7b, 0x13, 0x20, 0xbf, + 0xab, 0x77, 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, 0x45, 0x1a, 0xec, 0xfc, 0x91, + 0x70, 0xf8, 0x83, 0x8b, 0x9c, 0x47, 0x2f, 0x0b, + 0x9f, 0x07, 0xf3, 0x2f, 0x7c, 0xa2, 0x8a, 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, 0x48, 0x24, 0x32, + 0xe8, 0xd6, 0x38, 0xda, 0x65, 0xec, 0x1b, 0x18, + 0x8e, 0x37, 0x07, 0xd5, 0x18, 0x5a, 0xc8, 0xb9, + 0xbb, 0x24, 0x8a, 0x4d, 0xa1, 0x3c, 0x9e, 0x46, + 0x76, 0xcf, 0xa5, 0xdf, 0xd7, 0x61, 0xba, 0x05, + 0x89, 0x3c, 0x13, 0xc2, 0x1f, 0x71, 0xe3, 0xec, + 0x5d, 0x54, 0x9e, 0xd9, 0x01, 0x5a, 0x10, 0x3b, + 0x17, 0x75, 0xde, 0xa1, 0x45, 0xbf, 0x1d, 0x1b, + 0x41, 0x21, 0x42, 0x68, 0x22, 0x6b, 0xbb, 0xcb, + 0x11, 0x04, 0xd2, 0xae, 0x86, 0xcf, 0x73, 0x5a, + 0xf2, 0x80, 0x18, 0x00, 0xf0, 0xd6, 0x6c, 0x5a, + 0x1e, 0xb3, 0x4d, 0x30, 0x02, 0x4a, 0x6a, 0x03, + 0x36, 0x42, 0xde, 0xb2, 0x52, 0x55, 0xff, 0x71, + 0xeb, 0x7b, 0x8b, 0x55, 0x6c, 0xdf, 0x05, 0x35, + 0x47, 0x70, 0x53, 0xfb, 0x6c, 0xba, 0x06, 0xb2, + 0x61, 0x86, 0xdc, 0x2a, 0x64, 0x81, 0x24, 0x79, + 0x46, 0x73, 0x04, 0x55, 0x59, 0xed, 0xd6, 0x06, + 0x61, 0x15, 0xf9, 0x8d, 0x78, 0x39, 0x7b, 0x84, + 0x7a, 0x40, 0x45, 0x13, 0x1a, 0x91, 0x71, 0x8f, + 0xd1, 0x4f, 0x78, 0x10, 0x68, 0x9b, 0x15, 0x79, + 0x3f, 0x79, 0x2d, 0x9b, 0xc7, 0x5d, 0xa3, 0xcf, + 0xa9, 0x14, 0xb0, 0xc4, 0xdb, 0xa9, 0x45, 0x6a, + 0x6e, 0x60, 0x45, 0x0b, 0x14, 0x25, 0xc7, 0x74, + 0xd0, 0x36, 0xaf, 0xc5, 0xbd, 0x4f, 0x7b, 0xc0, + 0x04, 0x43, 0x85, 0xbb, 0x06, 0x36, 0x77, 0x26, + 0x02, 0x23, 0x0b, 0xf8, 0x57, 0x8f, 0x1f, 0x27, + 0x30, 0x95, 0xff, 0x83, 0x23, 0x2b, 0x49, 0x33, + 0x43, 0x62, 0x87, 0x5d, 0x27, 0x12, 0x1a, 0x68, + 0x7b, 0xba, 0x2d, 0xf6, 0xed, 0x2c, 0x26, 0xb5, + 0xbb, 0xe2, 0x6f, 0xc2, 0x61, 0x17, 0xfc, 0x72, + 0x14, 0x57, 0x2c, 0x2c, 0x5a, 0x92, 0x13, 0x41, + 0xc4, 0x7e, 0xb5, 0x64, 0x5b, 0x86, 0x57, 0x13, + 0x14, 0xff, 0xf5, 0x04, 0xb9, 0x3d, 0x2d, 0xc3, + 0xe9, 0x75, 0x1f, 0x68, 0x0b, 0xb5, 0x76, 0xe1, + 0x7d, 0xe3, 0xb0, 0x14, 0xa8, 0x45, 0x05, 0x98, + 0x81, 0x32, 0xc1, 0xf5, 0x49, 0x4d, 0x58, 0xa4, + 0xee, 0xd8, 0x84, 0xba, 0x65, 0x07, 0x8d, 0xf7, + 0x9a, 0xff, 0x7d, 0xa5, 0xbc, 0x9a, 0xed, 0x4a, + 0x5d, 0xa4, 0x97, 0x4b, 0x4d, 0x31, 0x90, 0xb5, + 0x7d, 0x28, 0x77, 0x25, 0x88, 0x1c, 0xbf, 0x78, + 0x22, 0xb2, 0xb5, 0x5c, 0x9a, 0xc9, 0x63, 0x17, + 0x96, 0xe9, 0xc2, 0x52, 0x30, 0xb8, 0x9b, 0x37, + 0x69, 0x1a, 0x6a, 0x66, 0x76, 0x18, 0xac, 0xc0, + 0x48, 0xee, 0x46, 0x5b, 0xbe, 0x6a, 0xd5, 0x72, + 0x07, 0xdc, 0x7d, 0x05, 0xbe, 0x76, 0x7d, 0xa5, + 0x5e, 0x53, 0xb5, 0x47, 0x80, 0x58, 0xf0, 0xaf, + 0x6f, 0x4e, 0xc0, 0xf1, 0x1e, 0x37, 0x64, 0x15, + 0x42, 0x96, 0x18, 0x3a, 0x89, 0xc8, 0x14, 0x48, + 0x89, 0x5c, 0x12, 0x88, 0x98, 0x0b, 0x7b, 0x4e, + 0xce, 0x1c, 0xda, 0xd5, 0xa4, 0xd3, 0x32, 0x32, + 0x74, 0x5b, 0xcc, 0xfd, 0x2b, 0x02, 0xfb, 0xae, + 0xd0, 0x5a, 0x4c, 0xc9, 0xc1, 0x35, 0x19, 0x90, + 0x5f, 0xca, 0x14, 0xeb, 0x4c, 0x17, 0xd7, 0xe3, + 0xe2, 0x5d, 0xb4, 0x49, 0xaa, 0xf0, 0x50, 0x87, + 0xc3, 0x20, 0x00, 0xda, 0xe9, 0x04, 0x80, 0x64, + 0xac, 0x9f, 0xcd, 0x26, 0x41, 0x48, 0xe8, 0x4c, + 0x46, 0xcc, 0x5b, 0xd7, 0xca, 0x4c, 0x1b, 0x43, + 0x43, 0x1e, 0xbd, 0x94, 0xe7, 0xa7, 0xa6, 0x86, + 0xe5, 0xd1, 0x78, 0x29, 0xa2, 0x40, 0xc5, 0xc5, + 0x47, 0xb6, 0x6d, 0x53, 0xde, 0xac, 0x97, 0x74, + 0x24, 0x57, 0xcc, 0x05, 0x93, 0xfd, 0x52, 0x35, + 0x29, 0xd5, 0xe0, 0xfa, 0x23, 0x0d, 0xd7, 0xaa, + 0x8b, 0x07, 0x4b, 0xf6, 0x64, 0xc7, 0xad, 0x3c, + 0xa1, 0xb5, 0xc5, 0x70, 0xaf, 0x46, 0xfe, 0x9a, + 0x82, 0x4d, 0x75, 0xb8, 0x6d, 0x67, 0x70, 0x75, + 0x62, 0x41, 0x72, 0x65, 0x61, 0x58, 0x76, 0x00, + 0x23, 0x00, 0x0b, 0x00, 0x04, 0x00, 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, 0x00, 0x03, 0x00, + 0x10, 0x00, 0x20, 0xfb, 0xd6, 0xba, 0x74, 0xe6, + 0x6e, 0x5c, 0x87, 0xef, 0x89, 0xa2, 0xe8, 0x3d, + 0x0b, 0xe9, 0x69, 0x2c, 0x07, 0x07, 0x7a, 0x8a, + 0x1e, 0xce, 0x12, 0xea, 0x3b, 0xb3, 0xf1, 0xf3, + 0xd9, 0xc3, 0xe6, 0x00, 0x20, 0x3c, 0x68, 0x51, + 0x94, 0x54, 0x8d, 0xeb, 0x9f, 0xb2, 0x2c, 0x66, + 0x75, 0xb6, 0xb7, 0x55, 0x22, 0x0d, 0x87, 0x59, + 0xc4, 0x39, 0x91, 0x62, 0x17, 0xc2, 0xc3, 0x53, + 0xa5, 0x26, 0x97, 0x4f, 0x2d, 0x68, 0x63, 0x65, + 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x58, 0xa1, + 0xff, 0x54, 0x43, 0x47, 0x80, 0x17, 0x00, 0x22, + 0x00, 0x0b, 0x73, 0xbe, 0xb7, 0x40, 0x82, 0xc0, + 0x49, 0x9a, 0xf7, 0xf2, 0xd0, 0x79, 0x6c, 0x88, + 0xf3, 0x56, 0x7b, 0x7a, 0x7d, 0xcd, 0x70, 0xd1, + 0xbc, 0x41, 0x88, 0x48, 0x51, 0x03, 0xf3, 0x58, + 0x3e, 0xb8, 0x00, 0x14, 0x9f, 0x57, 0x39, 0x67, + 0xa8, 0x7b, 0xd8, 0xf6, 0x9e, 0x75, 0xc9, 0x85, + 0xab, 0xe3, 0x55, 0xc7, 0x9c, 0xf6, 0xd8, 0x4f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x1c, 0x12, + 0xfd, 0xc6, 0x05, 0xc6, 0x2b, 0xf5, 0xe9, 0x88, + 0x01, 0x1f, 0x70, 0x8d, 0x98, 0x2a, 0x04, 0x21, + 0x30, 0x00, 0x22, 0x00, 0x0b, 0xf4, 0xfd, 0x9a, + 0x33, 0x55, 0x21, 0x08, 0x27, 0x48, 0x55, 0x01, + 0x56, 0xf9, 0x0b, 0x4e, 0x47, 0x55, 0x08, 0x2e, + 0x3c, 0x91, 0x3d, 0x6e, 0x53, 0xcf, 0x08, 0xe9, + 0x0a, 0x4b, 0xc9, 0x7e, 0x99, 0x00, 0x22, 0x00, + 0x0b, 0x51, 0xd3, 0x38, 0xfe, 0xaa, 0xda, 0xc6, + 0x68, 0x84, 0x39, 0xe7, 0xb1, 0x03, 0x22, 0x5e, + 0xc4, 0xd3, 0xf1, 0x0c, 0xec, 0x35, 0x5d, 0x50, + 0xa3, 0x9d, 0xab, 0xa1, 0x7b, 0x61, 0x51, 0x8f, + 0x4e +}; + /* * 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"; static void * dummy_open(const char *path) { (void)path; return (FAKE_DEV_HANDLE); } static void dummy_close(void *handle) { assert(handle == FAKE_DEV_HANDLE); } static int dummy_read(void *handle, unsigned char *buf, size_t len, int ms) { (void)handle; (void)buf; (void)len; (void)ms; abort(); /* NOTREACHED */ } static int dummy_write(void *handle, const unsigned char *buf, size_t len) { (void)handle; (void)buf; (void)len; abort(); /* NOTREACHED */ } static fido_cred_t * alloc_cred(void) { fido_cred_t *c; c = fido_cred_new(); assert(c != NULL); return (c); } static void free_cred(fido_cred_t *c) { fido_cred_free(&c); assert(c == NULL); } static fido_dev_t * alloc_dev(void) { fido_dev_t *d; d = fido_dev_new(); assert(d != NULL); return (d); } static void free_dev(fido_dev_t *d) { fido_dev_free(&d); assert(d == NULL); } static void empty_cred(void) { fido_cred_t *c; fido_dev_t *d; fido_dev_io_t io_f; c = alloc_cred(); assert(fido_cred_authdata_len(c) == 0); assert(fido_cred_authdata_ptr(c) == NULL); assert(fido_cred_authdata_raw_len(c) == 0); assert(fido_cred_authdata_raw_ptr(c) == NULL); assert(fido_cred_clientdata_hash_len(c) == 0); assert(fido_cred_clientdata_hash_ptr(c) == NULL); assert(fido_cred_flags(c) == 0); assert(fido_cred_fmt(c) == NULL); assert(fido_cred_id_len(c) == 0); assert(fido_cred_id_ptr(c) == NULL); assert(fido_cred_prot(c) == 0); assert(fido_cred_pubkey_len(c) == 0); assert(fido_cred_pubkey_ptr(c) == NULL); assert(fido_cred_rp_id(c) == NULL); assert(fido_cred_rp_name(c) == NULL); assert(fido_cred_sig_len(c) == 0); assert(fido_cred_sig_ptr(c) == NULL); assert(fido_cred_x5c_len(c) == 0); assert(fido_cred_x5c_ptr(c) == NULL); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); memset(&io_f, 0, sizeof(io_f)); io_f.open = dummy_open; io_f.close = dummy_close; io_f.read = dummy_read; io_f.write = dummy_write; d = alloc_dev(); fido_dev_force_u2f(d); assert(fido_dev_set_io_functions(d, &io_f) == FIDO_OK); assert(fido_dev_make_cred(d, c, NULL) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_dev_make_cred(d, c, "") == FIDO_ERR_UNSUPPORTED_OPTION); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); fido_dev_force_fido2(d); assert(fido_dev_set_io_functions(d, &io_f) == FIDO_OK); assert(fido_dev_make_cred(d, c, NULL) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_dev_make_cred(d, c, "") == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); free_cred(c); free_dev(d); } static void valid_cred(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(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, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_OK); assert(fido_cred_prot(c) == 0); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void no_cdh(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void no_rp_id(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void no_rp_name(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, NULL) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_OK); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void no_authdata(void) { fido_cred_t *c; unsigned char *unset; unset = calloc(1, sizeof(aaguid)); assert(unset != NULL); c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_pubkey_len(c) == 0); assert(fido_cred_pubkey_ptr(c) == NULL); assert(fido_cred_id_len(c) == 0); assert(fido_cred_id_ptr(c) == NULL); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), unset, sizeof(aaguid)) == 0); free_cred(c); free(unset); } static void no_x509(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(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, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void no_sig(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(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, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void no_fmt(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(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, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void wrong_options(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(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, sizeof(authdata)) == 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_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_PARAM); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void junk_cdh(void) { fido_cred_t *c; unsigned char *junk; junk = malloc(sizeof(cdh)); assert(junk != NULL); memcpy(junk, cdh, sizeof(cdh)); junk[0] = (unsigned char)~junk[0]; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, junk, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_SIG); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); free(junk); } static void junk_fmt(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(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, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "junk") == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); free_cred(c); } static void junk_rp_id(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, "potato", rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_PARAM); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void junk_rp_name(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, "potato") == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_OK); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void junk_authdata(void) { fido_cred_t *c; unsigned char *junk; unsigned char *unset; junk = malloc(sizeof(authdata)); assert(junk != NULL); memcpy(junk, authdata, sizeof(authdata)); junk[0] = (unsigned char)~junk[0]; unset = calloc(1, sizeof(aaguid)); assert(unset != NULL); c = alloc_cred(); assert(fido_cred_set_authdata(c, junk, sizeof(authdata)) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_authdata_len(c) == 0); assert(fido_cred_authdata_ptr(c) == NULL); assert(fido_cred_authdata_raw_len(c) == 0); assert(fido_cred_authdata_raw_ptr(c) == NULL); assert(fido_cred_flags(c) == 0); assert(fido_cred_fmt(c) == NULL); assert(fido_cred_id_len(c) == 0); assert(fido_cred_id_ptr(c) == NULL); assert(fido_cred_pubkey_len(c) == 0); assert(fido_cred_pubkey_ptr(c) == NULL); assert(fido_cred_rp_id(c) == NULL); assert(fido_cred_rp_name(c) == NULL); assert(fido_cred_sig_len(c) == 0); assert(fido_cred_sig_ptr(c) == NULL); assert(fido_cred_x5c_len(c) == 0); assert(fido_cred_x5c_ptr(c) == NULL); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), unset, sizeof(aaguid)) == 0); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); free_cred(c); free(junk); free(unset); } static void junk_sig(void) { fido_cred_t *c; unsigned char *junk; junk = malloc(sizeof(sig)); assert(junk != NULL); memcpy(junk, sig, sizeof(sig)); junk[0] = (unsigned char)~junk[0]; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(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, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, junk, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_SIG); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); free(junk); } static void junk_x509(void) { fido_cred_t *c; unsigned char *junk; junk = malloc(sizeof(x509)); assert(junk != NULL); memcpy(junk, x509, sizeof(x509)); junk[0] = (unsigned char)~junk[0]; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(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, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, junk, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_SIG); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); free(junk); } /* github issue #6 */ static void invalid_type(void) { fido_cred_t *c; unsigned char *unset; unset = calloc(1, sizeof(aaguid)); assert(unset != NULL); c = alloc_cred(); assert(fido_cred_set_type(c, COSE_RS256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(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, sizeof(authdata)) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_pubkey_len(c) == 0); assert(fido_cred_pubkey_ptr(c) == NULL); assert(fido_cred_id_len(c) == 0); assert(fido_cred_id_ptr(c) == NULL); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), unset, sizeof(aaguid)) == 0); free_cred(c); free(unset); } /* cbor_serialize_alloc misuse */ static void bad_cbor_serialize(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_authdata_len(c) == sizeof(authdata)); free_cred(c); } static void duplicate_keys(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata_dupkeys, sizeof(authdata_dupkeys)) == FIDO_ERR_INVALID_ARGUMENT); free_cred(c); } static void unsorted_keys(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata_unsorted_keys, sizeof(authdata_unsorted_keys)) == FIDO_ERR_INVALID_ARGUMENT); free_cred(c); } static void wrong_credprot(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_set_prot(c, FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_PARAM); free_cred(c); } static void raw_authdata(void) { fido_cred_t *c; cbor_item_t *item; struct cbor_load_result cbor_result; const unsigned char *ptr; unsigned char *cbor; size_t len; size_t cbor_len; size_t alloclen; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert((ptr = fido_cred_authdata_ptr(c)) != NULL); assert((len = fido_cred_authdata_len(c)) != 0); assert((item = cbor_load(ptr, len, &cbor_result)) != NULL); assert(cbor_result.read == len); assert(cbor_isa_bytestring(item)); assert((ptr = fido_cred_authdata_raw_ptr(c)) != NULL); assert((len = fido_cred_authdata_raw_len(c)) != 0); assert(cbor_bytestring_length(item) == len); assert(memcmp(ptr, cbor_bytestring_handle(item), len) == 0); assert((len = fido_cred_authdata_len(c)) != 0); assert((cbor_len = cbor_serialize_alloc(item, &cbor, &alloclen)) == len); assert((ptr = cbor_bytestring_handle(item)) != NULL); assert((len = cbor_bytestring_length(item)) != 0); assert(fido_cred_set_authdata_raw(c, ptr, len) == FIDO_OK); assert((ptr = fido_cred_authdata_ptr(c)) != NULL); assert((len = fido_cred_authdata_len(c)) != 0); assert(len == cbor_len); assert(memcmp(cbor, ptr, len) == 0); assert(cbor_len == sizeof(authdata)); assert(memcmp(cbor, authdata, cbor_len) == 0); cbor_decref(&item); free(cbor); free_cred(c); } static void fmt_none(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(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, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_fmt(c, "none") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_prot(c) == 0); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void -valid_tpm_cred(void) +valid_tpm_rs256_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_authdata(c, authdata_tpm_rs256, sizeof(authdata_tpm_rs256)) == 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_rs256, sizeof(attstmt_tpm_rs256)) == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_OK); + assert(fido_cred_prot(c) == 0); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey_tpm_rs256)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey_tpm_rs256, sizeof(pubkey_tpm_rs256)) == 0); + assert(fido_cred_id_len(c) == sizeof(id_tpm_rs256)); + assert(memcmp(fido_cred_id_ptr(c), id_tpm_rs256, sizeof(id_tpm_rs256)) == 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); +} + +static void +valid_tpm_es256_cred(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == 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_es256, sizeof(authdata_tpm_es256)) == 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_set_attstmt(c, attstmt_tpm_es256, sizeof(attstmt_tpm_es256)) == 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_pubkey_len(c) == sizeof(pubkey_tpm_es256)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey_tpm_es256, sizeof(pubkey_tpm_es256)) == 0); + assert(fido_cred_id_len(c) == sizeof(id_tpm_es256)); + assert(memcmp(fido_cred_id_ptr(c), id_tpm_es256, sizeof(id_tpm_es256)) == 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) { fido_init(0); empty_cred(); valid_cred(); no_cdh(); no_rp_id(); no_rp_name(); no_authdata(); no_x509(); no_sig(); no_fmt(); junk_cdh(); junk_fmt(); junk_rp_id(); junk_rp_name(); junk_authdata(); junk_x509(); junk_sig(); wrong_options(); invalid_type(); bad_cbor_serialize(); duplicate_keys(); unsorted_keys(); wrong_credprot(); raw_authdata(); fmt_none(); - valid_tpm_cred(); + valid_tpm_rs256_cred(); + valid_tpm_es256_cred(); exit(0); } diff --git a/contrib/libfido2/src/CMakeLists.txt b/contrib/libfido2/src/CMakeLists.txt index bd14a62f0c99..796ec69a9dbe 100644 --- a/contrib/libfido2/src/CMakeLists.txt +++ b/contrib/libfido2/src/CMakeLists.txt @@ -1,139 +1,139 @@ # 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. add_definitions(-D_FIDO_INTERNAL) list(APPEND FIDO_SOURCES aes256.c assert.c authkey.c bio.c blob.c buf.c cbor.c compress.c config.c cred.c credman.c dev.c ecdh.c eddsa.c err.c es256.c hid.c info.c io.c iso7816.c largeblob.c log.c 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) list(APPEND FIDO_SOURCES ../fuzz/wrap.c) endif() if(NFC_LINUX) list(APPEND FIDO_SOURCES netlink.c nfc_linux.c) endif() if(USE_HIDAPI) list(APPEND FIDO_SOURCES hid_hidapi.c) if(NOT WIN32 AND NOT APPLE) list(APPEND FIDO_SOURCES hid_unix.c) endif() elseif(WIN32) list(APPEND FIDO_SOURCES hid_win.c) if(USE_WINHELLO) list(APPEND FIDO_SOURCES winhello.c) endif() elseif(APPLE) list(APPEND FIDO_SOURCES hid_osx.c) elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") list(APPEND FIDO_SOURCES hid_linux.c hid_unix.c) 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" 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") endif() if(NOT MSVC) set_source_files_properties(${FIDO_SOURCES} PROPERTIES COMPILE_FLAGS "-Wconversion -Wsign-conversion") 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/recallocarray.c ../openbsd-compat/strlcat.c ../openbsd-compat/timingsafe_bcmp.c ) if(WIN32) list(APPEND BASE_LIBRARIES wsock32 ws2_32 bcrypt setupapi hid) elseif(APPLE) list(APPEND BASE_LIBRARIES "-framework CoreFoundation" "-framework IOKit") endif() list(APPEND TARGET_LIBRARIES ${CBOR_LIBRARIES} ${CRYPTO_LIBRARIES} ${UDEV_LIBRARIES} ${BASE_LIBRARIES} ${HIDAPI_LIBRARIES} ${ZLIB_LIBRARIES} ) # static library if(BUILD_STATIC_LIBS) add_library(fido2 STATIC ${FIDO_SOURCES} ${COMPAT_SOURCES}) if(WIN32 AND NOT MINGW) set_target_properties(fido2 PROPERTIES OUTPUT_NAME fido2_static) endif() target_link_libraries(fido2 ${TARGET_LIBRARIES}) install(TARGETS fido2 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() # dynamic library if(BUILD_SHARED_LIBS) add_library(fido2_shared SHARED ${FIDO_SOURCES} ${COMPAT_SOURCES}) set_target_properties(fido2_shared PROPERTIES OUTPUT_NAME fido2 VERSION ${FIDO_VERSION} SOVERSION ${FIDO_MAJOR}) target_link_libraries(fido2_shared ${TARGET_LIBRARIES}) install(TARGETS fido2_shared ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() install(FILES fido.h DESTINATION include) install(DIRECTORY fido DESTINATION include) -if(NOT WIN32) +if(NOT MSVC) configure_file(libfido2.pc.in libfido2.pc @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libfido2.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") endif() diff --git a/contrib/libfido2/src/bio.c b/contrib/libfido2/src/bio.c index 4ddc93749cc3..8c52de5d76c3 100644 --- a/contrib/libfido2/src/bio.c +++ b/contrib/libfido2/src/bio.c @@ -1,856 +1,856 @@ /* * Copyright (c) 2019 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" #include "fido/bio.h" #include "fido/es256.h" #define CMD_ENROLL_BEGIN 0x01 #define CMD_ENROLL_NEXT 0x02 #define CMD_ENROLL_CANCEL 0x03 #define CMD_ENUM 0x04 #define CMD_SET_NAME 0x05 #define CMD_ENROLL_REMOVE 0x06 #define CMD_GET_INFO 0x07 static int bio_prepare_hmac(uint8_t cmd, cbor_item_t **argv, size_t argc, cbor_item_t **param, fido_blob_t *hmac_data) { const uint8_t prefix[2] = { 0x01 /* modality */, cmd }; int ok = -1; size_t cbor_alloc_len; size_t cbor_len; unsigned char *cbor = NULL; if (argv == NULL || param == NULL) return (fido_blob_set(hmac_data, prefix, sizeof(prefix))); if ((*param = cbor_flatten_vector(argv, argc)) == NULL) { fido_log_debug("%s: cbor_flatten_vector", __func__); goto fail; } if ((cbor_len = cbor_serialize_alloc(*param, &cbor, &cbor_alloc_len)) == 0 || cbor_len > SIZE_MAX - sizeof(prefix)) { fido_log_debug("%s: cbor_serialize_alloc", __func__); goto fail; } if ((hmac_data->ptr = malloc(cbor_len + sizeof(prefix))) == NULL) { fido_log_debug("%s: malloc", __func__); goto fail; } memcpy(hmac_data->ptr, prefix, sizeof(prefix)); memcpy(hmac_data->ptr + sizeof(prefix), cbor, cbor_len); hmac_data->len = cbor_len + sizeof(prefix); ok = 0; fail: free(cbor); return (ok); } 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, int *ms) { cbor_item_t *argv[5]; es256_pk_t *pk = NULL; fido_blob_t *ecdh = NULL; fido_blob_t f; fido_blob_t hmac; const uint8_t cmd = CTAP_CBOR_BIO_ENROLL_PRE; int r = FIDO_ERR_INTERNAL; memset(&f, 0, sizeof(f)); memset(&hmac, 0, sizeof(hmac)); memset(&argv, 0, sizeof(argv)); /* modality, subCommand */ if ((argv[0] = cbor_build_uint8(1)) == NULL || (argv[1] = cbor_build_uint8(subcmd)) == NULL) { fido_log_debug("%s: cbor encode", __func__); goto fail; } /* subParams */ if (pin || token) { if (bio_prepare_hmac(subcmd, sub_argv, sub_argc, &argv[2], &hmac) < 0) { fido_log_debug("%s: bio_prepare_hmac", __func__); goto fail; } } /* pinProtocol, pinAuth */ if (pin) { 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], ms)) != FIDO_OK) { fido_log_debug("%s: cbor_add_uv_params", __func__); goto fail; } } else if (token) { if ((argv[3] = cbor_encode_pin_opt(dev)) == NULL || (argv[4] = cbor_encode_pin_auth(dev, token, &hmac)) == NULL) { fido_log_debug("%s: encode pin", __func__); goto fail; } } /* framing and transmission */ if (cbor_build_frame(cmd, argv, nitems(argv), &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; } r = FIDO_OK; fail: cbor_vector_free(argv, nitems(argv)); es256_pk_free(&pk); fido_blob_free(&ecdh); free(f.ptr); free(hmac.ptr); return (r); } static void bio_reset_template(fido_bio_template_t *t) { free(t->name); t->name = NULL; fido_blob_reset(&t->id); } static void bio_reset_template_array(fido_bio_template_array_t *ta) { for (size_t i = 0; i < ta->n_alloc; i++) bio_reset_template(&ta->ptr[i]); free(ta->ptr); ta->ptr = NULL; memset(ta, 0, sizeof(*ta)); } static int decode_template(const cbor_item_t *key, const cbor_item_t *val, void *arg) { fido_bio_template_t *t = arg; if (cbor_isa_uint(key) == false || cbor_int_get_width(key) != CBOR_INT_8) { fido_log_debug("%s: cbor type", __func__); return (0); /* ignore */ } switch (cbor_get_uint8(key)) { case 1: /* id */ return (fido_blob_decode(val, &t->id)); case 2: /* name */ return (cbor_string_copy(val, &t->name)); } return (0); /* ignore */ } static int decode_template_array(const cbor_item_t *item, void *arg) { fido_bio_template_array_t *ta = arg; if (cbor_isa_map(item) == false || cbor_map_is_definite(item) == false) { fido_log_debug("%s: cbor type", __func__); return (-1); } if (ta->n_rx >= ta->n_alloc) { fido_log_debug("%s: n_rx >= n_alloc", __func__); return (-1); } if (cbor_map_iter(item, &ta->ptr[ta->n_rx], decode_template) < 0) { fido_log_debug("%s: decode_template", __func__); return (-1); } ta->n_rx++; return (0); } static int bio_parse_template_array(const cbor_item_t *key, const cbor_item_t *val, void *arg) { fido_bio_template_array_t *ta = arg; if (cbor_isa_uint(key) == false || cbor_int_get_width(key) != CBOR_INT_8 || cbor_get_uint8(key) != 7) { fido_log_debug("%s: cbor type", __func__); return (0); /* ignore */ } if (cbor_isa_array(val) == false || cbor_array_is_definite(val) == false) { fido_log_debug("%s: cbor type", __func__); return (-1); } if (ta->ptr != NULL || ta->n_alloc != 0 || ta->n_rx != 0) { fido_log_debug("%s: ptr != NULL || n_alloc != 0 || n_rx != 0", __func__); return (-1); } if ((ta->ptr = calloc(cbor_array_size(val), sizeof(*ta->ptr))) == NULL) return (-1); ta->n_alloc = cbor_array_size(val); if (cbor_array_iter(val, ta, decode_template_array) < 0) { fido_log_debug("%s: decode_template_array", __func__); return (-1); } return (0); } static int bio_rx_template_array(fido_dev_t *dev, fido_bio_template_array_t *ta, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; int r; bio_reset_template_array(ta); if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, &reply, sizeof(reply), ms)) < 0) { fido_log_debug("%s: fido_rx", __func__); return (FIDO_ERR_RX); } if ((r = cbor_parse_reply(reply, (size_t)reply_len, ta, bio_parse_template_array)) != FIDO_OK) { fido_log_debug("%s: bio_parse_template_array" , __func__); return (r); } return (FIDO_OK); } static int bio_get_template_array_wait(fido_dev_t *dev, fido_bio_template_array_t *ta, const char *pin, int *ms) { int r; 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); return (FIDO_OK); } 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, &ms)); } static int bio_set_template_name_wait(fido_dev_t *dev, const fido_bio_template_t *t, const char *pin, int *ms) { cbor_item_t *argv[2]; int r = FIDO_ERR_INTERNAL; memset(&argv, 0, sizeof(argv)); if ((argv[0] = fido_blob_encode(&t->id)) == NULL || (argv[1] = cbor_build_string(t->name)) == NULL) { fido_log_debug("%s: cbor encode", __func__); goto fail; } 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; } r = FIDO_OK; fail: cbor_vector_free(argv, nitems(argv)); return (r); } 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, &ms)); } static void bio_reset_enroll(fido_bio_enroll_t *e) { e->remaining_samples = 0; e->last_status = 0; if (e->token) fido_blob_free(&e->token); } static int bio_parse_enroll_status(const cbor_item_t *key, const cbor_item_t *val, void *arg) { fido_bio_enroll_t *e = arg; uint64_t x; if (cbor_isa_uint(key) == false || cbor_int_get_width(key) != CBOR_INT_8) { fido_log_debug("%s: cbor type", __func__); return (0); /* ignore */ } switch (cbor_get_uint8(key)) { case 5: if (cbor_decode_uint64(val, &x) < 0 || x > UINT8_MAX) { fido_log_debug("%s: cbor_decode_uint64", __func__); return (-1); } e->last_status = (uint8_t)x; break; case 6: if (cbor_decode_uint64(val, &x) < 0 || x > UINT8_MAX) { fido_log_debug("%s: cbor_decode_uint64", __func__); return (-1); } e->remaining_samples = (uint8_t)x; break; default: return (0); /* ignore */ } return (0); } static int bio_parse_template_id(const cbor_item_t *key, const cbor_item_t *val, void *arg) { fido_blob_t *id = arg; if (cbor_isa_uint(key) == false || cbor_int_get_width(key) != CBOR_INT_8 || cbor_get_uint8(key) != 4) { fido_log_debug("%s: cbor type", __func__); return (0); /* ignore */ } return (fido_blob_decode(val, id)); } static int bio_rx_enroll_begin(fido_dev_t *dev, fido_bio_template_t *t, fido_bio_enroll_t *e, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; int r; bio_reset_template(t); e->remaining_samples = 0; e->last_status = 0; if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, &reply, sizeof(reply), ms)) < 0) { fido_log_debug("%s: fido_rx", __func__); return (FIDO_ERR_RX); } if ((r = cbor_parse_reply(reply, (size_t)reply_len, e, bio_parse_enroll_status)) != FIDO_OK) { fido_log_debug("%s: bio_parse_enroll_status", __func__); return (r); } if ((r = cbor_parse_reply(reply, (size_t)reply_len, &t->id, bio_parse_template_id)) != FIDO_OK) { fido_log_debug("%s: bio_parse_template_id", __func__); return (r); } return (FIDO_OK); } 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) { cbor_item_t *argv[3]; const uint8_t cmd = CMD_ENROLL_BEGIN; int r = FIDO_ERR_INTERNAL; memset(&argv, 0, sizeof(argv)); - if ((argv[2] = cbor_build_uint32(timo_ms)) == NULL) { + if ((argv[2] = cbor_build_uint(timo_ms)) == NULL) { fido_log_debug("%s: cbor encode", __func__); goto fail; } 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; } r = FIDO_OK; fail: cbor_vector_free(argv, nitems(argv)); return (r); } int fido_bio_dev_enroll_begin(fido_dev_t *dev, fido_bio_template_t *t, fido_bio_enroll_t *e, uint32_t timo_ms, const char *pin) { 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) return (FIDO_ERR_INVALID_ARGUMENT); if ((token = fido_blob_new()) == NULL) { r = FIDO_ERR_INTERNAL; goto fail; } 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, &ms)) != FIDO_OK) { fido_log_debug("%s: fido_dev_get_uv_token", __func__); goto fail; } e->token = token; token = NULL; fail: es256_pk_free(&pk); fido_blob_free(&ecdh); fido_blob_free(&token); if (r != FIDO_OK) return (r); 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) { unsigned char reply[FIDO_MAXMSG]; int reply_len; int r; e->remaining_samples = 0; e->last_status = 0; if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, &reply, sizeof(reply), ms)) < 0) { fido_log_debug("%s: fido_rx", __func__); return (FIDO_ERR_RX); } if ((r = cbor_parse_reply(reply, (size_t)reply_len, e, bio_parse_enroll_status)) != FIDO_OK) { fido_log_debug("%s: bio_parse_enroll_status", __func__); return (r); } return (FIDO_OK); } 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) { cbor_item_t *argv[3]; const uint8_t cmd = CMD_ENROLL_NEXT; int r = FIDO_ERR_INTERNAL; memset(&argv, 0, sizeof(argv)); if ((argv[0] = fido_blob_encode(&t->id)) == NULL || - (argv[2] = cbor_build_uint32(timo_ms)) == NULL) { + (argv[2] = cbor_build_uint(timo_ms)) == NULL) { fido_log_debug("%s: cbor encode", __func__); goto fail; } 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; } r = FIDO_OK; fail: cbor_vector_free(argv, nitems(argv)); return (r); } 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, &ms)); } static int 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, ms)) != FIDO_OK || (r = fido_rx_cbor_status(dev, ms)) != FIDO_OK) { fido_log_debug("%s: tx/rx", __func__); return (r); } return (FIDO_OK); } int fido_bio_dev_enroll_cancel(fido_dev_t *dev) { 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) { cbor_item_t *argv[1]; const uint8_t cmd = CMD_ENROLL_REMOVE; int r = FIDO_ERR_INTERNAL; memset(&argv, 0, sizeof(argv)); if ((argv[0] = fido_blob_encode(&t->id)) == NULL) { fido_log_debug("%s: cbor encode", __func__); goto fail; } 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; } r = FIDO_OK; fail: cbor_vector_free(argv, nitems(argv)); return (r); } int fido_bio_dev_enroll_remove(fido_dev_t *dev, const fido_bio_template_t *t, const char *pin) { int ms = dev->timeout_ms; return (bio_enroll_remove_wait(dev, t, pin, &ms)); } static void bio_reset_info(fido_bio_info_t *i) { i->type = 0; i->max_samples = 0; } static int bio_parse_info(const cbor_item_t *key, const cbor_item_t *val, void *arg) { fido_bio_info_t *i = arg; uint64_t x; if (cbor_isa_uint(key) == false || cbor_int_get_width(key) != CBOR_INT_8) { fido_log_debug("%s: cbor type", __func__); return (0); /* ignore */ } switch (cbor_get_uint8(key)) { case 2: if (cbor_decode_uint64(val, &x) < 0 || x > UINT8_MAX) { fido_log_debug("%s: cbor_decode_uint64", __func__); return (-1); } i->type = (uint8_t)x; break; case 3: if (cbor_decode_uint64(val, &x) < 0 || x > UINT8_MAX) { fido_log_debug("%s: cbor_decode_uint64", __func__); return (-1); } i->max_samples = (uint8_t)x; break; default: return (0); /* ignore */ } return (0); } static int bio_rx_info(fido_dev_t *dev, fido_bio_info_t *i, int *ms) { unsigned char reply[FIDO_MAXMSG]; int reply_len; int r; bio_reset_info(i); if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, &reply, sizeof(reply), ms)) < 0) { fido_log_debug("%s: fido_rx", __func__); return (FIDO_ERR_RX); } if ((r = cbor_parse_reply(reply, (size_t)reply_len, i, bio_parse_info)) != FIDO_OK) { fido_log_debug("%s: bio_parse_info" , __func__); return (r); } return (FIDO_OK); } static int 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, ms)) != FIDO_OK || (r = bio_rx_info(dev, i, ms)) != FIDO_OK) { fido_log_debug("%s: tx/rx", __func__); return (r); } return (FIDO_OK); } int fido_bio_dev_get_info(fido_dev_t *dev, fido_bio_info_t *i) { int ms = dev->timeout_ms; return (bio_get_info_wait(dev, i, &ms)); } const char * fido_bio_template_name(const fido_bio_template_t *t) { return (t->name); } const unsigned char * fido_bio_template_id_ptr(const fido_bio_template_t *t) { return (t->id.ptr); } size_t fido_bio_template_id_len(const fido_bio_template_t *t) { return (t->id.len); } size_t fido_bio_template_array_count(const fido_bio_template_array_t *ta) { return (ta->n_rx); } fido_bio_template_array_t * fido_bio_template_array_new(void) { return (calloc(1, sizeof(fido_bio_template_array_t))); } fido_bio_template_t * fido_bio_template_new(void) { return (calloc(1, sizeof(fido_bio_template_t))); } void fido_bio_template_array_free(fido_bio_template_array_t **tap) { fido_bio_template_array_t *ta; if (tap == NULL || (ta = *tap) == NULL) return; bio_reset_template_array(ta); free(ta); *tap = NULL; } void fido_bio_template_free(fido_bio_template_t **tp) { fido_bio_template_t *t; if (tp == NULL || (t = *tp) == NULL) return; bio_reset_template(t); free(t); *tp = NULL; } int fido_bio_template_set_name(fido_bio_template_t *t, const char *name) { free(t->name); t->name = NULL; if (name && (t->name = strdup(name)) == NULL) return (FIDO_ERR_INTERNAL); return (FIDO_OK); } int fido_bio_template_set_id(fido_bio_template_t *t, const unsigned char *ptr, size_t len) { fido_blob_reset(&t->id); if (ptr && fido_blob_set(&t->id, ptr, len) < 0) return (FIDO_ERR_INTERNAL); return (FIDO_OK); } const fido_bio_template_t * fido_bio_template(const fido_bio_template_array_t *ta, size_t idx) { if (idx >= ta->n_alloc) return (NULL); return (&ta->ptr[idx]); } fido_bio_enroll_t * fido_bio_enroll_new(void) { return (calloc(1, sizeof(fido_bio_enroll_t))); } fido_bio_info_t * fido_bio_info_new(void) { return (calloc(1, sizeof(fido_bio_info_t))); } uint8_t fido_bio_info_type(const fido_bio_info_t *i) { return (i->type); } uint8_t fido_bio_info_max_samples(const fido_bio_info_t *i) { return (i->max_samples); } void fido_bio_enroll_free(fido_bio_enroll_t **ep) { fido_bio_enroll_t *e; if (ep == NULL || (e = *ep) == NULL) return; bio_reset_enroll(e); free(e); *ep = NULL; } void fido_bio_info_free(fido_bio_info_t **ip) { fido_bio_info_t *i; if (ip == NULL || (i = *ip) == NULL) return; free(i); *ip = NULL; } uint8_t fido_bio_enroll_remaining_samples(const fido_bio_enroll_t *e) { return (e->remaining_samples); } uint8_t fido_bio_enroll_last_status(const fido_bio_enroll_t *e) { return (e->last_status); } diff --git a/contrib/libfido2/src/cbor.c b/contrib/libfido2/src/cbor.c index 7935e5017dcf..8b7edece3d8e 100644 --- a/contrib/libfido2/src/cbor.c +++ b/contrib/libfido2/src/cbor.c @@ -1,1682 +1,1681 @@ /* * 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 #include #include "fido.h" static int check_key_type(cbor_item_t *item) { if (item->type == CBOR_TYPE_UINT || item->type == CBOR_TYPE_NEGINT || item->type == CBOR_TYPE_STRING) return (0); fido_log_debug("%s: invalid type: %d", __func__, item->type); return (-1); } /* * Validate CTAP2 canonical CBOR encoding rules for maps. */ static int ctap_check_cbor(cbor_item_t *prev, cbor_item_t *curr) { size_t curr_len; size_t prev_len; if (check_key_type(prev) < 0 || check_key_type(curr) < 0) return (-1); if (prev->type != curr->type) { if (prev->type < curr->type) return (0); fido_log_debug("%s: unsorted types", __func__); return (-1); } if (curr->type == CBOR_TYPE_UINT || curr->type == CBOR_TYPE_NEGINT) { if (cbor_int_get_width(curr) >= cbor_int_get_width(prev) && cbor_get_int(curr) > cbor_get_int(prev)) return (0); } else { curr_len = cbor_string_length(curr); prev_len = cbor_string_length(prev); if (curr_len > prev_len || (curr_len == prev_len && memcmp(cbor_string_handle(prev), cbor_string_handle(curr), curr_len) < 0)) return (0); } fido_log_debug("%s: invalid cbor", __func__); return (-1); } int cbor_map_iter(const cbor_item_t *item, void *arg, int(*f)(const cbor_item_t *, const cbor_item_t *, void *)) { struct cbor_pair *v; size_t n; if ((v = cbor_map_handle(item)) == NULL) { fido_log_debug("%s: cbor_map_handle", __func__); return (-1); } n = cbor_map_size(item); for (size_t i = 0; i < n; i++) { if (v[i].key == NULL || v[i].value == NULL) { fido_log_debug("%s: key=%p, value=%p for i=%zu", __func__, (void *)v[i].key, (void *)v[i].value, i); return (-1); } if (i && ctap_check_cbor(v[i - 1].key, v[i].key) < 0) { fido_log_debug("%s: ctap_check_cbor", __func__); return (-1); } if (f(v[i].key, v[i].value, arg) < 0) { fido_log_debug("%s: iterator < 0 on i=%zu", __func__, i); return (-1); } } return (0); } int cbor_array_iter(const cbor_item_t *item, void *arg, int(*f)(const cbor_item_t *, void *)) { cbor_item_t **v; size_t n; if ((v = cbor_array_handle(item)) == NULL) { fido_log_debug("%s: cbor_array_handle", __func__); return (-1); } n = cbor_array_size(item); for (size_t i = 0; i < n; i++) if (v[i] == NULL || f(v[i], arg) < 0) { fido_log_debug("%s: iterator < 0 on i=%zu,%p", __func__, i, (void *)v[i]); return (-1); } return (0); } int cbor_parse_reply(const unsigned char *blob, size_t blob_len, void *arg, int(*parser)(const cbor_item_t *, const cbor_item_t *, void *)) { cbor_item_t *item = NULL; struct cbor_load_result cbor; int r; if (blob_len < 1) { fido_log_debug("%s: blob_len=%zu", __func__, blob_len); r = FIDO_ERR_RX; goto fail; } if (blob[0] != FIDO_OK) { fido_log_debug("%s: blob[0]=0x%02x", __func__, blob[0]); r = blob[0]; goto fail; } if ((item = cbor_load(blob + 1, blob_len - 1, &cbor)) == NULL) { fido_log_debug("%s: cbor_load", __func__); r = FIDO_ERR_RX_NOT_CBOR; goto fail; } if (cbor_isa_map(item) == false || cbor_map_is_definite(item) == false) { fido_log_debug("%s: cbor type", __func__); r = FIDO_ERR_RX_INVALID_CBOR; goto fail; } if (cbor_map_iter(item, arg, parser) < 0) { fido_log_debug("%s: cbor_map_iter", __func__); r = FIDO_ERR_RX_INVALID_CBOR; goto fail; } r = FIDO_OK; fail: if (item != NULL) cbor_decref(&item); return (r); } void cbor_vector_free(cbor_item_t **item, size_t len) { for (size_t i = 0; i < len; i++) if (item[i] != NULL) cbor_decref(&item[i]); } int cbor_bytestring_copy(const cbor_item_t *item, unsigned char **buf, size_t *len) { if (*buf != NULL || *len != 0) { fido_log_debug("%s: dup", __func__); return (-1); } if (cbor_isa_bytestring(item) == false || cbor_bytestring_is_definite(item) == false) { fido_log_debug("%s: cbor type", __func__); return (-1); } *len = cbor_bytestring_length(item); if ((*buf = malloc(*len)) == NULL) { *len = 0; return (-1); } memcpy(*buf, cbor_bytestring_handle(item), *len); return (0); } int cbor_string_copy(const cbor_item_t *item, char **str) { size_t len; if (*str != NULL) { fido_log_debug("%s: dup", __func__); return (-1); } if (cbor_isa_string(item) == false || cbor_string_is_definite(item) == false) { fido_log_debug("%s: cbor type", __func__); return (-1); } if ((len = cbor_string_length(item)) == SIZE_MAX || (*str = malloc(len + 1)) == NULL) return (-1); memcpy(*str, cbor_string_handle(item), len); (*str)[len] = '\0'; return (0); } int cbor_add_bytestring(cbor_item_t *item, const char *key, const unsigned char *value, size_t value_len) { struct cbor_pair pair; int ok = -1; memset(&pair, 0, sizeof(pair)); if ((pair.key = cbor_build_string(key)) == NULL || (pair.value = cbor_build_bytestring(value, value_len)) == NULL) { fido_log_debug("%s: cbor_build", __func__); goto fail; } if (!cbor_map_add(item, pair)) { fido_log_debug("%s: cbor_map_add", __func__); goto fail; } ok = 0; fail: if (pair.key) cbor_decref(&pair.key); if (pair.value) cbor_decref(&pair.value); return (ok); } int cbor_add_string(cbor_item_t *item, const char *key, const char *value) { struct cbor_pair pair; int ok = -1; memset(&pair, 0, sizeof(pair)); if ((pair.key = cbor_build_string(key)) == NULL || (pair.value = cbor_build_string(value)) == NULL) { fido_log_debug("%s: cbor_build", __func__); goto fail; } if (!cbor_map_add(item, pair)) { fido_log_debug("%s: cbor_map_add", __func__); goto fail; } ok = 0; fail: if (pair.key) cbor_decref(&pair.key); if (pair.value) cbor_decref(&pair.value); return (ok); } int cbor_add_bool(cbor_item_t *item, const char *key, fido_opt_t value) { struct cbor_pair pair; int ok = -1; memset(&pair, 0, sizeof(pair)); if ((pair.key = cbor_build_string(key)) == NULL || (pair.value = cbor_build_bool(value == FIDO_OPT_TRUE)) == NULL) { fido_log_debug("%s: cbor_build", __func__); goto fail; } if (!cbor_map_add(item, pair)) { fido_log_debug("%s: cbor_map_add", __func__); goto fail; } ok = 0; fail: if (pair.key) cbor_decref(&pair.key); if (pair.value) cbor_decref(&pair.value); return (ok); } static int cbor_add_uint8(cbor_item_t *item, const char *key, uint8_t value) { struct cbor_pair pair; int ok = -1; memset(&pair, 0, sizeof(pair)); if ((pair.key = cbor_build_string(key)) == NULL || (pair.value = cbor_build_uint8(value)) == NULL) { fido_log_debug("%s: cbor_build", __func__); goto fail; } if (!cbor_map_add(item, pair)) { fido_log_debug("%s: cbor_map_add", __func__); goto fail; } ok = 0; fail: if (pair.key) cbor_decref(&pair.key); if (pair.value) cbor_decref(&pair.value); return (ok); } static int cbor_add_arg(cbor_item_t *item, uint8_t n, cbor_item_t *arg) { struct cbor_pair pair; int ok = -1; memset(&pair, 0, sizeof(pair)); if (arg == NULL) return (0); /* empty argument */ if ((pair.key = cbor_build_uint8(n)) == NULL) { fido_log_debug("%s: cbor_build", __func__); goto fail; } pair.value = arg; if (!cbor_map_add(item, pair)) { fido_log_debug("%s: cbor_map_add", __func__); goto fail; } ok = 0; fail: if (pair.key) cbor_decref(&pair.key); return (ok); } cbor_item_t * cbor_flatten_vector(cbor_item_t *argv[], size_t argc) { cbor_item_t *map; uint8_t i; if (argc > UINT8_MAX - 1) return (NULL); if ((map = cbor_new_definite_map(argc)) == NULL) return (NULL); for (i = 0; i < argc; i++) if (cbor_add_arg(map, (uint8_t)(i + 1), argv[i]) < 0) break; if (i != argc) { cbor_decref(&map); map = NULL; } return (map); } int cbor_build_frame(uint8_t cmd, cbor_item_t *argv[], size_t argc, fido_blob_t *f) { cbor_item_t *flat = NULL; unsigned char *cbor = NULL; size_t cbor_len; size_t cbor_alloc_len; int ok = -1; if ((flat = cbor_flatten_vector(argv, argc)) == NULL) goto fail; cbor_len = cbor_serialize_alloc(flat, &cbor, &cbor_alloc_len); if (cbor_len == 0 || cbor_len == SIZE_MAX) { fido_log_debug("%s: cbor_len=%zu", __func__, cbor_len); goto fail; } if ((f->ptr = malloc(cbor_len + 1)) == NULL) goto fail; f->len = cbor_len + 1; f->ptr[0] = cmd; memcpy(f->ptr + 1, cbor, f->len - 1); ok = 0; fail: if (flat != NULL) cbor_decref(&flat); free(cbor); return (ok); } cbor_item_t * cbor_encode_rp_entity(const fido_rp_t *rp) { cbor_item_t *item = NULL; if ((item = cbor_new_definite_map(2)) == NULL) return (NULL); if ((rp->id && cbor_add_string(item, "id", rp->id) < 0) || (rp->name && cbor_add_string(item, "name", rp->name) < 0)) { cbor_decref(&item); return (NULL); } return (item); } cbor_item_t * cbor_encode_user_entity(const fido_user_t *user) { cbor_item_t *item = NULL; const fido_blob_t *id = &user->id; const char *display = user->display_name; if ((item = cbor_new_definite_map(4)) == NULL) return (NULL); if ((id->ptr && cbor_add_bytestring(item, "id", id->ptr, id->len) < 0) || (user->icon && cbor_add_string(item, "icon", user->icon) < 0) || (user->name && cbor_add_string(item, "name", user->name) < 0) || (display && cbor_add_string(item, "displayName", display) < 0)) { cbor_decref(&item); return (NULL); } return (item); } cbor_item_t * cbor_encode_pubkey_param(int cose_alg) { cbor_item_t *item = NULL; cbor_item_t *body = NULL; struct cbor_pair alg; int ok = -1; memset(&alg, 0, sizeof(alg)); if ((item = cbor_new_definite_array(1)) == NULL || (body = cbor_new_definite_map(2)) == NULL || cose_alg > -1 || cose_alg < INT16_MIN) goto fail; alg.key = cbor_build_string("alg"); if (-cose_alg - 1 > UINT8_MAX) alg.value = cbor_build_negint16((uint16_t)(-cose_alg - 1)); else alg.value = cbor_build_negint8((uint8_t)(-cose_alg - 1)); if (alg.key == NULL || alg.value == NULL) { fido_log_debug("%s: cbor_build", __func__); goto fail; } if (cbor_map_add(body, alg) == false || cbor_add_string(body, "type", "public-key") < 0 || cbor_array_push(item, body) == false) goto fail; ok = 0; fail: if (ok < 0) { if (item != NULL) { cbor_decref(&item); item = NULL; } } if (body != NULL) cbor_decref(&body); if (alg.key != NULL) cbor_decref(&alg.key); if (alg.value != NULL) cbor_decref(&alg.value); return (item); } cbor_item_t * cbor_encode_pubkey(const fido_blob_t *pubkey) { cbor_item_t *cbor_key = NULL; if ((cbor_key = cbor_new_definite_map(2)) == NULL || cbor_add_bytestring(cbor_key, "id", pubkey->ptr, pubkey->len) < 0 || cbor_add_string(cbor_key, "type", "public-key") < 0) { if (cbor_key) cbor_decref(&cbor_key); return (NULL); } return (cbor_key); } cbor_item_t * cbor_encode_pubkey_list(const fido_blob_array_t *list) { cbor_item_t *array = NULL; cbor_item_t *key = NULL; if ((array = cbor_new_definite_array(list->len)) == NULL) goto fail; for (size_t i = 0; i < list->len; i++) { if ((key = cbor_encode_pubkey(&list->ptr[i])) == NULL || cbor_array_push(array, key) == false) goto fail; cbor_decref(&key); } return (array); fail: if (key != NULL) cbor_decref(&key); if (array != NULL) cbor_decref(&array); 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) { if (map == NULL || cbor_add_bool(map, "largeBlobKey", FIDO_OPT_TRUE) < 0) return (-1); return (0); } cbor_item_t * cbor_encode_cred_ext(const fido_cred_ext_t *ext, const fido_blob_t *blob) { cbor_item_t *item = NULL; size_t size = 0; if (ext->mask & FIDO_EXT_CRED_BLOB) size++; if (ext->mask & FIDO_EXT_HMAC_SECRET) size++; if (ext->mask & FIDO_EXT_CRED_PROTECT) 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); if (ext->mask & FIDO_EXT_CRED_BLOB) { if (cbor_add_bytestring(item, "credBlob", blob->ptr, blob->len) < 0) { cbor_decref(&item); return (NULL); } } if (ext->mask & FIDO_EXT_CRED_PROTECT) { if (ext->prot < 0 || ext->prot > UINT8_MAX || cbor_add_uint8(item, "credProtect", (uint8_t)ext->prot) < 0) { cbor_decref(&item); return (NULL); } } if (ext->mask & FIDO_EXT_HMAC_SECRET) { if (cbor_add_bool(item, "hmac-secret", FIDO_OPT_TRUE) < 0) { cbor_decref(&item); return (NULL); } } if (ext->mask & FIDO_EXT_LARGEBLOB_KEY) { if (cbor_encode_largeblob_key_ext(item) < 0) { cbor_decref(&item); 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); } cbor_item_t * cbor_encode_cred_opt(fido_opt_t rk, fido_opt_t uv) { cbor_item_t *item = NULL; if ((item = cbor_new_definite_map(2)) == NULL) return (NULL); if ((rk != FIDO_OPT_OMIT && cbor_add_bool(item, "rk", rk) < 0) || (uv != FIDO_OPT_OMIT && cbor_add_bool(item, "uv", uv) < 0)) { cbor_decref(&item); return (NULL); } return (item); } cbor_item_t * cbor_encode_assert_opt(fido_opt_t up, fido_opt_t uv) { cbor_item_t *item = NULL; if ((item = cbor_new_definite_map(2)) == NULL) return (NULL); if ((up != FIDO_OPT_OMIT && cbor_add_bool(item, "up", up) < 0) || (uv != FIDO_OPT_OMIT && cbor_add_bool(item, "uv", uv) < 0)) { cbor_decref(&item); return (NULL); } return (item); } cbor_item_t * cbor_encode_pin_auth(const fido_dev_t *dev, const fido_blob_t *secret, const fido_blob_t *data) { const EVP_MD *md = NULL; unsigned char dgst[SHA256_DIGEST_LENGTH]; unsigned int dgst_len; size_t outlen; uint8_t prot; fido_blob_t key; - key.ptr = secret->ptr; key.len = secret->len; if ((prot = fido_dev_get_pin_protocol(dev)) == 0) { fido_log_debug("%s: fido_dev_get_pin_protocol", __func__); return (NULL); } /* select hmac portion of the shared secret */ if (prot == CTAP_PIN_PROTOCOL2 && key.len > 32) key.len = 32; if ((md = EVP_sha256()) == NULL || HMAC(md, key.ptr, (int)key.len, data->ptr, data->len, dgst, &dgst_len) == NULL || dgst_len != SHA256_DIGEST_LENGTH) return (NULL); outlen = (prot == CTAP_PIN_PROTOCOL1) ? 16 : dgst_len; return (cbor_build_bytestring(dgst, outlen)); } cbor_item_t * cbor_encode_pin_opt(const fido_dev_t *dev) { uint8_t prot; if ((prot = fido_dev_get_pin_protocol(dev)) == 0) { fido_log_debug("%s: fido_dev_get_pin_protocol", __func__); return (NULL); } return (cbor_build_uint8(prot)); } cbor_item_t * cbor_encode_change_pin_auth(const fido_dev_t *dev, const fido_blob_t *secret, const fido_blob_t *new_pin_enc, const fido_blob_t *pin_hash_enc) { unsigned char dgst[SHA256_DIGEST_LENGTH]; unsigned int dgst_len; cbor_item_t *item = NULL; const EVP_MD *md = NULL; HMAC_CTX *ctx = NULL; fido_blob_t key; uint8_t prot; size_t outlen; key.ptr = secret->ptr; key.len = secret->len; if ((prot = fido_dev_get_pin_protocol(dev)) == 0) { fido_log_debug("%s: fido_dev_get_pin_protocol", __func__); goto fail; } if (prot == CTAP_PIN_PROTOCOL2 && key.len > 32) key.len = 32; if ((ctx = HMAC_CTX_new()) == NULL || (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; } outlen = (prot == CTAP_PIN_PROTOCOL1) ? 16 : dgst_len; if ((item = cbor_build_bytestring(dgst, outlen)) == NULL) { fido_log_debug("%s: cbor_build_bytestring", __func__); goto fail; } fail: HMAC_CTX_free(ctx); return (item); } static int cbor_encode_hmac_secret_param(const fido_dev_t *dev, cbor_item_t *item, const fido_blob_t *ecdh, const es256_pk_t *pk, const fido_blob_t *salt) { cbor_item_t *param = NULL; cbor_item_t *argv[4]; struct cbor_pair pair; fido_blob_t *enc = NULL; uint8_t prot; int r; memset(argv, 0, sizeof(argv)); memset(&pair, 0, sizeof(pair)); if (item == NULL || ecdh == NULL || pk == NULL || salt->ptr == NULL) { fido_log_debug("%s: ecdh=%p, pk=%p, salt->ptr=%p", __func__, (const void *)ecdh, (const void *)pk, (const void *)salt->ptr); r = FIDO_ERR_INTERNAL; goto fail; } if (salt->len != 32 && salt->len != 64) { fido_log_debug("%s: salt->len=%zu", __func__, salt->len); r = FIDO_ERR_INTERNAL; goto fail; } if ((enc = fido_blob_new()) == NULL || aes256_cbc_enc(dev, ecdh, salt, enc) < 0) { fido_log_debug("%s: aes256_cbc_enc", __func__); r = FIDO_ERR_INTERNAL; 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 || (prot != 1 && (argv[3] = cbor_build_uint8(prot)) == NULL)) { fido_log_debug("%s: cbor encode", __func__); r = FIDO_ERR_INTERNAL; goto fail; } if ((param = cbor_flatten_vector(argv, nitems(argv))) == NULL) { fido_log_debug("%s: cbor_flatten_vector", __func__); r = FIDO_ERR_INTERNAL; goto fail; } if ((pair.key = cbor_build_string("hmac-secret")) == NULL) { fido_log_debug("%s: cbor_build", __func__); r = FIDO_ERR_INTERNAL; goto fail; } pair.value = param; if (!cbor_map_add(item, pair)) { fido_log_debug("%s: cbor_map_add", __func__); r = FIDO_ERR_INTERNAL; goto fail; } r = FIDO_OK; fail: cbor_vector_free(argv, nitems(argv)); if (param != NULL) cbor_decref(¶m); if (pair.key != NULL) cbor_decref(&pair.key); fido_blob_free(&enc); return (r); } cbor_item_t * cbor_encode_assert_ext(fido_dev_t *dev, const fido_assert_ext_t *ext, const fido_blob_t *ecdh, const es256_pk_t *pk) { cbor_item_t *item = NULL; size_t size = 0; if (ext->mask & FIDO_EXT_CRED_BLOB) size++; if (ext->mask & FIDO_EXT_HMAC_SECRET) size++; if (ext->mask & FIDO_EXT_LARGEBLOB_KEY) size++; if (size == 0 || (item = cbor_new_definite_map(size)) == NULL) return (NULL); if (ext->mask & FIDO_EXT_CRED_BLOB) { if (cbor_add_bool(item, "credBlob", FIDO_OPT_TRUE) < 0) { cbor_decref(&item); return (NULL); } } if (ext->mask & FIDO_EXT_HMAC_SECRET) { if (cbor_encode_hmac_secret_param(dev, item, ecdh, pk, &ext->hmac_salt) < 0) { cbor_decref(&item); return (NULL); } } if (ext->mask & FIDO_EXT_LARGEBLOB_KEY) { if (cbor_encode_largeblob_key_ext(item) < 0) { cbor_decref(&item); return (NULL); } } return (item); } int cbor_decode_fmt(const cbor_item_t *item, char **fmt) { char *type = NULL; if (cbor_string_copy(item, &type) < 0) { fido_log_debug("%s: cbor_string_copy", __func__); return (-1); } if (strcmp(type, "packed") && strcmp(type, "fido-u2f") && strcmp(type, "none") && strcmp(type, "tpm")) { fido_log_debug("%s: type=%s", __func__, type); free(type); return (-1); } *fmt = type; return (0); } struct cose_key { int kty; int alg; int crv; }; static int find_cose_alg(const cbor_item_t *key, const cbor_item_t *val, void *arg) { struct cose_key *cose_key = arg; if (cbor_isa_uint(key) == true && cbor_int_get_width(key) == CBOR_INT_8) { switch (cbor_get_uint8(key)) { case 1: if (cbor_isa_uint(val) == false || cbor_get_int(val) > INT_MAX || cose_key->kty != 0) { fido_log_debug("%s: kty", __func__); return (-1); } cose_key->kty = (int)cbor_get_int(val); break; case 3: if (cbor_isa_negint(val) == false || cbor_get_int(val) > INT_MAX || cose_key->alg != 0) { fido_log_debug("%s: alg", __func__); return (-1); } cose_key->alg = -(int)cbor_get_int(val) - 1; break; } } else if (cbor_isa_negint(key) == true && cbor_int_get_width(key) == CBOR_INT_8) { if (cbor_get_uint8(key) == 0) { /* get crv if not rsa, otherwise ignore */ if (cbor_isa_uint(val) == true && cbor_get_int(val) <= INT_MAX && cose_key->crv == 0) cose_key->crv = (int)cbor_get_int(val); } } return (0); } static int get_cose_alg(const cbor_item_t *item, int *cose_alg) { struct cose_key cose_key; memset(&cose_key, 0, sizeof(cose_key)); *cose_alg = 0; if (cbor_isa_map(item) == false || cbor_map_is_definite(item) == false || cbor_map_iter(item, &cose_key, find_cose_alg) < 0) { fido_log_debug("%s: cbor type", __func__); return (-1); } switch (cose_key.alg) { case COSE_ES256: if (cose_key.kty != COSE_KTY_EC2 || cose_key.crv != COSE_P256) { fido_log_debug("%s: invalid kty/crv", __func__); return (-1); } break; case COSE_EDDSA: if (cose_key.kty != COSE_KTY_OKP || cose_key.crv != COSE_ED25519) { fido_log_debug("%s: invalid kty/crv", __func__); return (-1); } break; case COSE_RS256: if (cose_key.kty != COSE_KTY_RSA) { fido_log_debug("%s: invalid kty/crv", __func__); return (-1); } break; default: fido_log_debug("%s: unknown alg %d", __func__, cose_key.alg); return (-1); } *cose_alg = cose_key.alg; return (0); } int cbor_decode_pubkey(const cbor_item_t *item, int *type, void *key) { if (get_cose_alg(item, type) < 0) { fido_log_debug("%s: get_cose_alg", __func__); return (-1); } switch (*type) { case COSE_ES256: if (es256_pk_decode(item, key) < 0) { fido_log_debug("%s: es256_pk_decode", __func__); return (-1); } break; case COSE_RS256: if (rs256_pk_decode(item, key) < 0) { fido_log_debug("%s: rs256_pk_decode", __func__); return (-1); } break; case COSE_EDDSA: if (eddsa_pk_decode(item, key) < 0) { fido_log_debug("%s: eddsa_pk_decode", __func__); return (-1); } break; default: fido_log_debug("%s: invalid cose_alg %d", __func__, *type); return (-1); } return (0); } static int decode_attcred(const unsigned char **buf, size_t *len, int cose_alg, fido_attcred_t *attcred) { cbor_item_t *item = NULL; struct cbor_load_result cbor; uint16_t id_len; int ok = -1; fido_log_xxd(*buf, *len, "%s", __func__); if (fido_buf_read(buf, len, &attcred->aaguid, sizeof(attcred->aaguid)) < 0) { fido_log_debug("%s: fido_buf_read aaguid", __func__); return (-1); } if (fido_buf_read(buf, len, &id_len, sizeof(id_len)) < 0) { fido_log_debug("%s: fido_buf_read id_len", __func__); return (-1); } attcred->id.len = (size_t)be16toh(id_len); if ((attcred->id.ptr = malloc(attcred->id.len)) == NULL) return (-1); fido_log_debug("%s: attcred->id.len=%zu", __func__, attcred->id.len); if (fido_buf_read(buf, len, attcred->id.ptr, attcred->id.len) < 0) { fido_log_debug("%s: fido_buf_read id", __func__); return (-1); } if ((item = cbor_load(*buf, *len, &cbor)) == NULL) { fido_log_debug("%s: cbor_load", __func__); goto fail; } if (cbor_decode_pubkey(item, &attcred->type, &attcred->pubkey) < 0) { fido_log_debug("%s: cbor_decode_pubkey", __func__); goto fail; } if (attcred->type != cose_alg) { fido_log_debug("%s: cose_alg mismatch (%d != %d)", __func__, attcred->type, cose_alg); goto fail; } *buf += cbor.read; *len -= cbor.read; ok = 0; fail: if (item != NULL) cbor_decref(&item); return (ok); } static int decode_cred_extension(const cbor_item_t *key, const cbor_item_t *val, void *arg) { fido_cred_ext_t *authdata_ext = arg; char *type = NULL; int ok = -1; if (cbor_string_copy(key, &type) < 0) { fido_log_debug("%s: cbor type", __func__); ok = 0; /* ignore */ goto out; } if (strcmp(type, "hmac-secret") == 0) { if (cbor_isa_float_ctrl(val) == false || cbor_float_get_width(val) != CBOR_FLOAT_0 || cbor_is_bool(val) == false) { fido_log_debug("%s: cbor type", __func__); goto out; } if (cbor_ctrl_value(val) == CBOR_CTRL_TRUE) authdata_ext->mask |= FIDO_EXT_HMAC_SECRET; } else if (strcmp(type, "credProtect") == 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_CRED_PROTECT; authdata_ext->prot = cbor_get_uint8(val); } else if (strcmp(type, "credBlob") == 0) { if (cbor_isa_float_ctrl(val) == false || cbor_float_get_width(val) != CBOR_FLOAT_0 || cbor_is_bool(val) == false) { fido_log_debug("%s: cbor type", __func__); goto out; } 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; out: free(type); return (ok); } static int decode_cred_extensions(const unsigned char **buf, size_t *len, fido_cred_ext_t *authdata_ext) { cbor_item_t *item = NULL; struct cbor_load_result cbor; int ok = -1; memset(authdata_ext, 0, sizeof(*authdata_ext)); fido_log_xxd(*buf, *len, "%s", __func__); if ((item = cbor_load(*buf, *len, &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, authdata_ext, decode_cred_extension) < 0) { fido_log_debug("%s: cbor type", __func__); goto fail; } *buf += cbor.read; *len -= cbor.read; ok = 0; fail: if (item != NULL) cbor_decref(&item); return (ok); } static int decode_assert_extension(const cbor_item_t *key, const cbor_item_t *val, void *arg) { fido_assert_extattr_t *authdata_ext = arg; char *type = NULL; int ok = -1; if (cbor_string_copy(key, &type) < 0) { fido_log_debug("%s: cbor type", __func__); ok = 0; /* ignore */ goto out; } if (strcmp(type, "hmac-secret") == 0) { if (fido_blob_decode(val, &authdata_ext->hmac_secret_enc) < 0) { fido_log_debug("%s: fido_blob_decode", __func__); goto out; } authdata_ext->mask |= FIDO_EXT_HMAC_SECRET; } else if (strcmp(type, "credBlob") == 0) { if (fido_blob_decode(val, &authdata_ext->blob) < 0) { fido_log_debug("%s: fido_blob_decode", __func__); goto out; } authdata_ext->mask |= FIDO_EXT_CRED_BLOB; } ok = 0; out: free(type); return (ok); } static int decode_assert_extensions(const unsigned char **buf, size_t *len, fido_assert_extattr_t *authdata_ext) { cbor_item_t *item = NULL; struct cbor_load_result cbor; int ok = -1; fido_log_xxd(*buf, *len, "%s", __func__); if ((item = cbor_load(*buf, *len, &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, authdata_ext, decode_assert_extension) < 0) { fido_log_debug("%s: cbor type", __func__); goto fail; } *buf += cbor.read; *len -= cbor.read; ok = 0; fail: if (item != NULL) cbor_decref(&item); return (ok); } int cbor_decode_cred_authdata(const cbor_item_t *item, int cose_alg, fido_blob_t *authdata_cbor, fido_authdata_t *authdata, fido_attcred_t *attcred, fido_cred_ext_t *authdata_ext) { const unsigned char *buf = NULL; size_t len; size_t alloc_len; if (cbor_isa_bytestring(item) == false || cbor_bytestring_is_definite(item) == false) { fido_log_debug("%s: cbor type", __func__); return (-1); } if (authdata_cbor->ptr != NULL || (authdata_cbor->len = cbor_serialize_alloc(item, &authdata_cbor->ptr, &alloc_len)) == 0) { fido_log_debug("%s: cbor_serialize_alloc", __func__); return (-1); } buf = cbor_bytestring_handle(item); len = cbor_bytestring_length(item); fido_log_xxd(buf, len, "%s", __func__); if (fido_buf_read(&buf, &len, authdata, sizeof(*authdata)) < 0) { fido_log_debug("%s: fido_buf_read", __func__); return (-1); } authdata->sigcount = be32toh(authdata->sigcount); if (attcred != NULL) { if ((authdata->flags & CTAP_AUTHDATA_ATT_CRED) == 0 || decode_attcred(&buf, &len, cose_alg, attcred) < 0) return (-1); } if (authdata_ext != NULL) { if ((authdata->flags & CTAP_AUTHDATA_EXT_DATA) != 0 && decode_cred_extensions(&buf, &len, authdata_ext) < 0) return (-1); } /* XXX we should probably ensure that len == 0 at this point */ return (FIDO_OK); } int cbor_decode_assert_authdata(const cbor_item_t *item, fido_blob_t *authdata_cbor, fido_authdata_t *authdata, fido_assert_extattr_t *authdata_ext) { const unsigned char *buf = NULL; size_t len; size_t alloc_len; if (cbor_isa_bytestring(item) == false || cbor_bytestring_is_definite(item) == false) { fido_log_debug("%s: cbor type", __func__); return (-1); } if (authdata_cbor->ptr != NULL || (authdata_cbor->len = cbor_serialize_alloc(item, &authdata_cbor->ptr, &alloc_len)) == 0) { fido_log_debug("%s: cbor_serialize_alloc", __func__); return (-1); } buf = cbor_bytestring_handle(item); len = cbor_bytestring_length(item); fido_log_debug("%s: buf=%p, len=%zu", __func__, (const void *)buf, len); if (fido_buf_read(&buf, &len, authdata, sizeof(*authdata)) < 0) { fido_log_debug("%s: fido_buf_read", __func__); return (-1); } authdata->sigcount = be32toh(authdata->sigcount); if ((authdata->flags & CTAP_AUTHDATA_EXT_DATA) != 0) { if (decode_assert_extensions(&buf, &len, authdata_ext) < 0) { fido_log_debug("%s: decode_assert_extensions", __func__); return (-1); } } /* XXX we should probably ensure that len == 0 at this point */ return (FIDO_OK); } static int decode_x5c(const cbor_item_t *item, void *arg) { fido_blob_t *x5c = arg; if (x5c->len) return (0); /* ignore */ return (fido_blob_decode(item, x5c)); } static int decode_attstmt_entry(const cbor_item_t *key, const cbor_item_t *val, void *arg) { fido_attstmt_t *attstmt = 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 out; } if (!strcmp(name, "alg")) { if (cbor_isa_negint(val) == false || cbor_get_int(val) > UINT16_MAX) { fido_log_debug("%s: alg", __func__); goto out; } 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")) { if (fido_blob_decode(val, &attstmt->sig) < 0) { fido_log_debug("%s: sig", __func__); goto out; } } else if (!strcmp(name, "x5c")) { if (cbor_isa_array(val) == false || cbor_array_is_definite(val) == false || cbor_array_iter(val, &attstmt->x5c, decode_x5c) < 0) { 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; out: free(name); return (ok); } 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) { fido_log_debug("%s: cbor type", __func__); 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); } int cbor_decode_uint64(const cbor_item_t *item, uint64_t *n) { if (cbor_isa_uint(item) == false) { fido_log_debug("%s: cbor type", __func__); return (-1); } *n = cbor_get_int(item); return (0); } static int decode_cred_id_entry(const cbor_item_t *key, const cbor_item_t *val, void *arg) { fido_blob_t *id = 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 out; } if (!strcmp(name, "id")) if (fido_blob_decode(val, id) < 0) { fido_log_debug("%s: cbor_bytestring_copy", __func__); goto out; } ok = 0; out: free(name); return (ok); } int cbor_decode_cred_id(const cbor_item_t *item, fido_blob_t *id) { if (cbor_isa_map(item) == false || cbor_map_is_definite(item) == false || cbor_map_iter(item, id, decode_cred_id_entry) < 0) { fido_log_debug("%s: cbor type", __func__); return (-1); } return (0); } static int decode_user_entry(const cbor_item_t *key, const cbor_item_t *val, void *arg) { fido_user_t *user = 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 out; } if (!strcmp(name, "icon")) { if (cbor_string_copy(val, &user->icon) < 0) { fido_log_debug("%s: icon", __func__); goto out; } } else if (!strcmp(name, "name")) { if (cbor_string_copy(val, &user->name) < 0) { fido_log_debug("%s: name", __func__); goto out; } } else if (!strcmp(name, "displayName")) { if (cbor_string_copy(val, &user->display_name) < 0) { fido_log_debug("%s: display_name", __func__); goto out; } } else if (!strcmp(name, "id")) { if (fido_blob_decode(val, &user->id) < 0) { fido_log_debug("%s: id", __func__); goto out; } } ok = 0; out: free(name); return (ok); } int cbor_decode_user(const cbor_item_t *item, fido_user_t *user) { if (cbor_isa_map(item) == false || cbor_map_is_definite(item) == false || cbor_map_iter(item, user, decode_user_entry) < 0) { fido_log_debug("%s: cbor type", __func__); return (-1); } return (0); } static int decode_rp_entity_entry(const cbor_item_t *key, const cbor_item_t *val, void *arg) { fido_rp_t *rp = 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 out; } if (!strcmp(name, "id")) { if (cbor_string_copy(val, &rp->id) < 0) { fido_log_debug("%s: id", __func__); goto out; } } else if (!strcmp(name, "name")) { if (cbor_string_copy(val, &rp->name) < 0) { fido_log_debug("%s: name", __func__); goto out; } } ok = 0; out: free(name); return (ok); } int cbor_decode_rp_entity(const cbor_item_t *item, fido_rp_t *rp) { if (cbor_isa_map(item) == false || cbor_map_is_definite(item) == false || cbor_map_iter(item, rp, decode_rp_entity_entry) < 0) { fido_log_debug("%s: cbor type", __func__); return (-1); } return (0); } cbor_item_t * cbor_build_uint(const uint64_t value) { if (value <= UINT8_MAX) return cbor_build_uint8((uint8_t)value); else if (value <= UINT16_MAX) return cbor_build_uint16((uint16_t)value); else if (value <= UINT32_MAX) return cbor_build_uint32((uint32_t)value); return cbor_build_uint64(value); } int cbor_array_append(cbor_item_t **array, cbor_item_t *item) { cbor_item_t **v, *ret; size_t n; if ((v = cbor_array_handle(*array)) == NULL || (n = cbor_array_size(*array)) == SIZE_MAX || (ret = cbor_new_definite_array(n + 1)) == NULL) return -1; for (size_t i = 0; i < n; i++) { if (cbor_array_push(ret, v[i]) == 0) { cbor_decref(&ret); return -1; } } if (cbor_array_push(ret, item) == 0) { cbor_decref(&ret); return -1; } cbor_decref(array); *array = ret; return 0; } int cbor_array_drop(cbor_item_t **array, size_t idx) { cbor_item_t **v, *ret; size_t n; if ((v = cbor_array_handle(*array)) == NULL || (n = cbor_array_size(*array)) == 0 || idx >= n || (ret = cbor_new_definite_array(n - 1)) == NULL) return -1; for (size_t i = 0; i < n; i++) { if (i != idx && cbor_array_push(ret, v[i]) == 0) { cbor_decref(&ret); return -1; } } cbor_decref(array); *array = ret; return 0; } diff --git a/contrib/libfido2/src/dev.c b/contrib/libfido2/src/dev.c index 0c3cf64a462b..fb8faba0a06c 100644 --- a/contrib/libfido2/src/dev.c +++ b/contrib/libfido2/src/dev.c @@ -1,749 +1,756 @@ /* * Copyright (c) 2018 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 #include "fido.h" #ifndef TLS #define TLS #endif typedef struct dev_manifest_func_node { dev_manifest_func_t manifest_func; struct dev_manifest_func_node *next; } dev_manifest_func_node_t; static TLS dev_manifest_func_node_t *manifest_funcs = NULL; static TLS bool disable_u2f_fallback; static void find_manifest_func_node(dev_manifest_func_t f, dev_manifest_func_node_t **curr, dev_manifest_func_node_t **prev) { *prev = NULL; *curr = manifest_funcs; while (*curr != NULL && (*curr)->manifest_func != f) { *prev = *curr; *curr = (*curr)->next; } } #ifdef FIDO_FUZZ static void set_random_report_len(fido_dev_t *dev) { dev->rx_len = CTAP_MIN_REPORT_LEN + uniform_random(CTAP_MAX_REPORT_LEN - CTAP_MIN_REPORT_LEN + 1); dev->tx_len = CTAP_MIN_REPORT_LEN + uniform_random(CTAP_MAX_REPORT_LEN - CTAP_MIN_REPORT_LEN + 1); } #endif static void fido_dev_set_extension_flags(fido_dev_t *dev, const fido_cbor_info_t *info) { char * const *ptr = fido_cbor_info_extensions_ptr(info); size_t len = fido_cbor_info_extensions_len(info); for (size_t i = 0; i < len; i++) if (strcmp(ptr[i], "credProtect") == 0) dev->flags |= FIDO_DEV_CRED_PROT; } static void fido_dev_set_option_flags(fido_dev_t *dev, const fido_cbor_info_t *info) { char * const *ptr = fido_cbor_info_options_name_ptr(info); const bool *val = fido_cbor_info_options_value_ptr(info); size_t len = fido_cbor_info_options_len(info); for (size_t i = 0; i < len; i++) if (strcmp(ptr[i], "clientPin") == 0) { dev->flags |= val[i] ? FIDO_DEV_PIN_SET : FIDO_DEV_PIN_UNSET; } else if (strcmp(ptr[i], "credMgmt") == 0 || strcmp(ptr[i], "credentialMgmtPreview") == 0) { if (val[i]) dev->flags |= FIDO_DEV_CREDMAN; } else if (strcmp(ptr[i], "uv") == 0) { dev->flags |= val[i] ? FIDO_DEV_UV_SET : FIDO_DEV_UV_UNSET; } else if (strcmp(ptr[i], "pinUvAuthToken") == 0) { if (val[i]) dev->flags |= FIDO_DEV_TOKEN_PERMS; } } static void fido_dev_set_protocol_flags(fido_dev_t *dev, const fido_cbor_info_t *info) { const uint8_t *ptr = fido_cbor_info_protocols_ptr(info); size_t len = fido_cbor_info_protocols_len(info); for (size_t i = 0; i < len; i++) switch (ptr[i]) { case CTAP_PIN_PROTOCOL1: dev->flags |= FIDO_DEV_PIN_PROTOCOL1; break; case CTAP_PIN_PROTOCOL2: dev->flags |= FIDO_DEV_PIN_PROTOCOL2; break; default: fido_log_debug("%s: unknown protocol %u", __func__, ptr[i]); break; } } static void fido_dev_set_flags(fido_dev_t *dev, const fido_cbor_info_t *info) { fido_dev_set_extension_flags(dev, info); fido_dev_set_option_flags(dev, info); fido_dev_set_protocol_flags(dev, info); } static int fido_dev_open_tx(fido_dev_t *dev, const char *path, int *ms) { int r; if (dev->io_handle != NULL) { fido_log_debug("%s: handle=%p", __func__, dev->io_handle); return (FIDO_ERR_INVALID_ARGUMENT); } if (dev->io.open == NULL || dev->io.close == NULL) { fido_log_debug("%s: NULL open/close", __func__); return (FIDO_ERR_INVALID_ARGUMENT); } if (dev->cid != CTAP_CID_BROADCAST) { fido_log_debug("%s: cid=0x%x", __func__, dev->cid); return (FIDO_ERR_INVALID_ARGUMENT); } if (fido_get_random(&dev->nonce, sizeof(dev->nonce)) < 0) { fido_log_debug("%s: fido_get_random", __func__); return (FIDO_ERR_INTERNAL); } if ((dev->io_handle = dev->io.open(path)) == NULL) { fido_log_debug("%s: dev->io.open", __func__); return (FIDO_ERR_INTERNAL); } if (dev->io_own) { dev->rx_len = CTAP_MAX_REPORT_LEN; dev->tx_len = CTAP_MAX_REPORT_LEN; } else { dev->rx_len = fido_hid_report_in_len(dev->io_handle); dev->tx_len = fido_hid_report_out_len(dev->io_handle); } #ifdef FIDO_FUZZ set_random_report_len(dev); #endif if (dev->rx_len < CTAP_MIN_REPORT_LEN || dev->rx_len > CTAP_MAX_REPORT_LEN) { fido_log_debug("%s: invalid rx_len %zu", __func__, dev->rx_len); r = FIDO_ERR_RX; goto fail; } if (dev->tx_len < CTAP_MIN_REPORT_LEN || dev->tx_len > CTAP_MAX_REPORT_LEN) { fido_log_debug("%s: invalid tx_len %zu", __func__, dev->tx_len); r = FIDO_ERR_TX; goto fail; } 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; } return (FIDO_OK); fail: dev->io.close(dev->io_handle); dev->io_handle = NULL; return (r); } static int fido_dev_open_rx(fido_dev_t *dev, int *ms) { fido_cbor_info_t *info = NULL; int reply_len; int r; if ((reply_len = fido_rx(dev, CTAP_CMD_INIT, &dev->attr, sizeof(dev->attr), ms)) < 0) { fido_log_debug("%s: fido_rx", __func__); r = FIDO_ERR_RX; goto fail; } #ifdef FIDO_FUZZ dev->attr.nonce = dev->nonce; #endif if ((size_t)reply_len != sizeof(dev->attr) || dev->attr.nonce != dev->nonce) { fido_log_debug("%s: invalid nonce", __func__); r = FIDO_ERR_RX; goto fail; } dev->flags = 0; dev->cid = dev->attr.cid; if (fido_dev_is_fido2(dev)) { if ((info = fido_cbor_info_new()) == NULL) { fido_log_debug("%s: fido_cbor_info_new", __func__); r = FIDO_ERR_INTERNAL; goto fail; } if ((r = fido_dev_get_cbor_info_wait(dev, info, ms)) != FIDO_OK) { fido_log_debug("%s: fido_dev_cbor_info_wait: %d", __func__, r); if (disable_u2f_fallback) goto fail; fido_log_debug("%s: falling back to u2f", __func__); fido_dev_force_u2f(dev); } else { fido_dev_set_flags(dev, info); } } if (fido_dev_is_fido2(dev) && info != NULL) { dev->maxmsgsize = fido_cbor_info_maxmsgsiz(info); fido_log_debug("%s: FIDO_MAXMSG=%d, maxmsgsiz=%lu", __func__, FIDO_MAXMSG, (unsigned long)dev->maxmsgsize); } r = FIDO_OK; fail: fido_cbor_info_free(&info); if (r != FIDO_OK) { dev->io.close(dev->io_handle); dev->io_handle = NULL; } return (r); } static int fido_dev_open_wait(fido_dev_t *dev, const char *path, int *ms) { int r; #ifdef USE_WINHELLO if (strcmp(path, FIDO_WINHELLO_PATH) == 0) return (fido_winhello_open(dev)); #endif if ((r = fido_dev_open_tx(dev, path, ms)) != FIDO_OK || (r = fido_dev_open_rx(dev, ms)) != FIDO_OK) return (r); return (FIDO_OK); } int fido_dev_register_manifest_func(const dev_manifest_func_t f) { dev_manifest_func_node_t *prev, *curr, *n; find_manifest_func_node(f, &curr, &prev); if (curr != NULL) return (FIDO_OK); if ((n = calloc(1, sizeof(*n))) == NULL) { fido_log_debug("%s: calloc", __func__); return (FIDO_ERR_INTERNAL); } n->manifest_func = f; n->next = manifest_funcs; manifest_funcs = n; return (FIDO_OK); } void fido_dev_unregister_manifest_func(const dev_manifest_func_t f) { dev_manifest_func_node_t *prev, *curr; find_manifest_func_node(f, &curr, &prev); if (curr == NULL) return; if (prev != NULL) prev->next = curr->next; else manifest_funcs = curr->next; free(curr); } int fido_dev_info_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen) { dev_manifest_func_node_t *curr = NULL; dev_manifest_func_t m_func; size_t curr_olen; int r; *olen = 0; if (fido_dev_register_manifest_func(fido_hid_manifest) != FIDO_OK) return (FIDO_ERR_INTERNAL); #ifdef NFC_LINUX if (fido_dev_register_manifest_func(fido_nfc_manifest) != FIDO_OK) return (FIDO_ERR_INTERNAL); #endif #ifdef USE_WINHELLO if (fido_dev_register_manifest_func(fido_winhello_manifest) != FIDO_OK) return (FIDO_ERR_INTERNAL); #endif for (curr = manifest_funcs; curr != NULL; curr = curr->next) { curr_olen = 0; m_func = curr->manifest_func; r = m_func(devlist + *olen, ilen - *olen, &curr_olen); if (r != FIDO_OK) return (r); *olen += curr_olen; if (*olen == ilen) break; } return (FIDO_OK); } 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, &ms)); } int fido_dev_open(fido_dev_t *dev, const char *path) { int ms = dev->timeout_ms; #ifdef NFC_LINUX if (strncmp(path, FIDO_NFC_PREFIX, strlen(FIDO_NFC_PREFIX)) == 0) { dev->io_own = true; dev->io = (fido_dev_io_t) { fido_nfc_open, fido_nfc_close, fido_nfc_read, fido_nfc_write, }; dev->transport = (fido_dev_transport_t) { fido_nfc_rx, fido_nfc_tx, }; } #endif return (fido_dev_open_wait(dev, path, &ms)); } int fido_dev_close(fido_dev_t *dev) { #ifdef USE_WINHELLO if (dev->flags & FIDO_DEV_WINHELLO) return (fido_winhello_close(dev)); #endif if (dev->io_handle == NULL || dev->io.close == NULL) return (FIDO_ERR_INVALID_ARGUMENT); dev->io.close(dev->io_handle); dev->io_handle = NULL; dev->cid = CTAP_CID_BROADCAST; return (FIDO_OK); } int fido_dev_set_sigmask(fido_dev_t *dev, const fido_sigset_t *sigmask) { if (dev->io_handle == NULL || sigmask == NULL) return (FIDO_ERR_INVALID_ARGUMENT); #ifdef NFC_LINUX if (dev->transport.rx == fido_nfc_rx && dev->io.read == fido_nfc_read) return (fido_nfc_set_sigmask(dev->io_handle, sigmask)); #endif 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, &ms) < 0) return (FIDO_ERR_TX); return (FIDO_OK); } int fido_dev_get_touch_begin(fido_dev_t *dev) { fido_blob_t f; cbor_item_t *argv[9]; const char *clientdata = FIDO_DUMMY_CLIENTDATA; const uint8_t user_id = FIDO_DUMMY_USER_ID; 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)); memset(argv, 0, sizeof(argv)); memset(cdh, 0, sizeof(cdh)); memset(&rp, 0, sizeof(rp)); memset(&user, 0, sizeof(user)); if (fido_dev_is_fido2(dev) == false) return (u2f_get_touch_begin(dev, &ms)); if (SHA256((const void *)clientdata, strlen(clientdata), cdh) != cdh) { fido_log_debug("%s: sha256", __func__); return (FIDO_ERR_INTERNAL); } if ((rp.id = strdup(FIDO_DUMMY_RP_ID)) == NULL || (user.name = strdup(FIDO_DUMMY_USER_NAME)) == NULL) { fido_log_debug("%s: strdup", __func__); goto fail; } if (fido_blob_set(&user.id, &user_id, sizeof(user_id)) < 0) { fido_log_debug("%s: fido_blob_set", __func__); goto fail; } if ((argv[0] = cbor_build_bytestring(cdh, sizeof(cdh))) == NULL || (argv[1] = cbor_encode_rp_entity(&rp)) == NULL || (argv[2] = cbor_encode_user_entity(&user)) == NULL || (argv[3] = cbor_encode_pubkey_param(COSE_ES256)) == NULL) { fido_log_debug("%s: cbor encode", __func__); goto fail; } if (fido_dev_supports_pin(dev)) { if ((argv[7] = cbor_new_definite_bytestring()) == NULL || (argv[8] = cbor_encode_pin_opt(dev)) == NULL) { fido_log_debug("%s: cbor encode", __func__); goto fail; } } if (cbor_build_frame(CTAP_CBOR_MAKECRED, argv, nitems(argv), &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; } r = FIDO_OK; fail: cbor_vector_free(argv, nitems(argv)); free(f.ptr); free(rp.id); free(user.name); free(user.id.ptr); return (r); } int fido_dev_get_touch_status(fido_dev_t *dev, int *touched, int ms) { int r; *touched = 0; if (fido_dev_is_fido2(dev) == false) return (u2f_get_touch_status(dev, touched, &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: case FIDO_ERR_SUCCESS: *touched = 1; break; case FIDO_ERR_RX: /* ignore */ break; default: fido_log_debug("%s: fido_rx_cbor_status", __func__); return (r); } return (FIDO_OK); } int fido_dev_set_io_functions(fido_dev_t *dev, const fido_dev_io_t *io) { if (dev->io_handle != NULL) { fido_log_debug("%s: non-NULL handle", __func__); return (FIDO_ERR_INVALID_ARGUMENT); } if (io == NULL || io->open == NULL || io->close == NULL || io->read == NULL || io->write == NULL) { fido_log_debug("%s: NULL function", __func__); return (FIDO_ERR_INVALID_ARGUMENT); } dev->io = *io; dev->io_own = true; return (FIDO_OK); } int fido_dev_set_transport_functions(fido_dev_t *dev, const fido_dev_transport_t *t) { if (dev->io_handle != NULL) { fido_log_debug("%s: non-NULL handle", __func__); return (FIDO_ERR_INVALID_ARGUMENT); } dev->transport = *t; dev->io_own = true; return (FIDO_OK); } +void * +fido_dev_io_handle(const fido_dev_t *dev) +{ + + return (dev->io_handle); +} + void fido_init(int flags) { if (flags & FIDO_DEBUG || getenv("FIDO_DEBUG") != NULL) fido_log_init(); disable_u2f_fallback = (flags & FIDO_DISABLE_U2F_FALLBACK); } fido_dev_t * fido_dev_new(void) { fido_dev_t *dev; if ((dev = calloc(1, sizeof(*dev))) == NULL) return (NULL); dev->cid = CTAP_CID_BROADCAST; dev->timeout_ms = -1; dev->io = (fido_dev_io_t) { &fido_hid_open, &fido_hid_close, &fido_hid_read, &fido_hid_write, }; return (dev); } fido_dev_t * fido_dev_new_with_info(const fido_dev_info_t *di) { fido_dev_t *dev; if ((dev = calloc(1, sizeof(*dev))) == NULL) return (NULL); #if 0 if (di->io.open == NULL || di->io.close == NULL || di->io.read == NULL || di->io.write == NULL) { fido_log_debug("%s: NULL function", __func__); fido_dev_free(&dev); return (NULL); } #endif dev->io = di->io; 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__); fido_dev_free(&dev); return (NULL); } return (dev); } void fido_dev_free(fido_dev_t **dev_p) { fido_dev_t *dev; if (dev_p == NULL || (dev = *dev_p) == NULL) return; free(dev->path); free(dev); *dev_p = NULL; } uint8_t fido_dev_protocol(const fido_dev_t *dev) { return (dev->attr.protocol); } uint8_t fido_dev_major(const fido_dev_t *dev) { return (dev->attr.major); } uint8_t fido_dev_minor(const fido_dev_t *dev) { return (dev->attr.minor); } uint8_t fido_dev_build(const fido_dev_t *dev) { return (dev->attr.build); } uint8_t fido_dev_flags(const fido_dev_t *dev) { return (dev->attr.flags); } bool fido_dev_is_fido2(const fido_dev_t *dev) { return (dev->attr.flags & FIDO_CAP_CBOR); } bool fido_dev_is_winhello(const fido_dev_t *dev) { return (dev->flags & FIDO_DEV_WINHELLO); } bool fido_dev_supports_pin(const fido_dev_t *dev) { return (dev->flags & (FIDO_DEV_PIN_SET|FIDO_DEV_PIN_UNSET)); } bool fido_dev_has_pin(const fido_dev_t *dev) { return (dev->flags & FIDO_DEV_PIN_SET); } bool fido_dev_supports_cred_prot(const fido_dev_t *dev) { return (dev->flags & FIDO_DEV_CRED_PROT); } bool fido_dev_supports_credman(const fido_dev_t *dev) { return (dev->flags & FIDO_DEV_CREDMAN); } bool fido_dev_supports_uv(const fido_dev_t *dev) { return (dev->flags & (FIDO_DEV_UV_SET|FIDO_DEV_UV_UNSET)); } bool fido_dev_has_uv(const fido_dev_t *dev) { return (dev->flags & FIDO_DEV_UV_SET); } bool fido_dev_supports_permissions(const fido_dev_t *dev) { return (dev->flags & FIDO_DEV_TOKEN_PERMS); } void fido_dev_force_u2f(fido_dev_t *dev) { dev->attr.flags &= (uint8_t)~FIDO_CAP_CBOR; dev->flags = 0; } void fido_dev_force_fido2(fido_dev_t *dev) { dev->attr.flags |= FIDO_CAP_CBOR; } uint8_t fido_dev_get_pin_protocol(const fido_dev_t *dev) { if (dev->flags & FIDO_DEV_PIN_PROTOCOL2) return (CTAP_PIN_PROTOCOL2); else if (dev->flags & FIDO_DEV_PIN_PROTOCOL1) return (CTAP_PIN_PROTOCOL1); return (0); } uint64_t 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/eddsa.c b/contrib/libfido2/src/eddsa.c index d228149ebf4d..a7b4f4f900ce 100644 --- a/contrib/libfido2/src/eddsa.c +++ b/contrib/libfido2/src/eddsa.c @@ -1,218 +1,220 @@ /* - * 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 #include #include "fido.h" #include "fido/eddsa.h" #if defined(LIBRESSL_VERSION_NUMBER) EVP_PKEY * EVP_PKEY_new_raw_public_key(int type, ENGINE *e, const unsigned char *key, size_t keylen) { (void)type; (void)e; (void)key; (void)keylen; fido_log_debug("%s: unimplemented", __func__); return (NULL); } int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, size_t *len) { (void)pkey; (void)pub; (void)len; fido_log_debug("%s: unimplemented", __func__); return (0); } +#endif /* LIBRESSL_VERSION_NUMBER */ +#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3040000f int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen) { (void)ctx; (void)sigret; (void)siglen; (void)tbs; (void)tbslen; fido_log_debug("%s: unimplemented", __func__); return (0); } -#endif /* LIBRESSL_VERSION_NUMBER */ +#endif /* LIBRESSL_VERSION_NUMBER < 0x3040000f */ static int decode_coord(const cbor_item_t *item, void *xy, size_t xy_len) { if (cbor_isa_bytestring(item) == false || cbor_bytestring_is_definite(item) == false || cbor_bytestring_length(item) != xy_len) { fido_log_debug("%s: cbor type", __func__); return (-1); } memcpy(xy, cbor_bytestring_handle(item), xy_len); return (0); } static int decode_pubkey_point(const cbor_item_t *key, const cbor_item_t *val, void *arg) { eddsa_pk_t *k = arg; if (cbor_isa_negint(key) == false || cbor_int_get_width(key) != CBOR_INT_8) return (0); /* ignore */ switch (cbor_get_uint8(key)) { case 1: /* x coordinate */ return (decode_coord(val, &k->x, sizeof(k->x))); } return (0); /* ignore */ } int eddsa_pk_decode(const cbor_item_t *item, eddsa_pk_t *k) { if (cbor_isa_map(item) == false || cbor_map_is_definite(item) == false || cbor_map_iter(item, k, decode_pubkey_point) < 0) { fido_log_debug("%s: cbor type", __func__); return (-1); } return (0); } eddsa_pk_t * eddsa_pk_new(void) { return (calloc(1, sizeof(eddsa_pk_t))); } void eddsa_pk_free(eddsa_pk_t **pkp) { eddsa_pk_t *pk; if (pkp == NULL || (pk = *pkp) == NULL) return; freezero(pk, sizeof(*pk)); *pkp = NULL; } int eddsa_pk_from_ptr(eddsa_pk_t *pk, const void *ptr, size_t len) { if (len < sizeof(*pk)) return (FIDO_ERR_INVALID_ARGUMENT); memcpy(pk, ptr, sizeof(*pk)); return (FIDO_OK); } EVP_PKEY * eddsa_pk_to_EVP_PKEY(const eddsa_pk_t *k) { EVP_PKEY *pkey = NULL; if ((pkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, k->x, sizeof(k->x))) == NULL) fido_log_debug("%s: EVP_PKEY_new_raw_public_key", __func__); return (pkey); } int eddsa_pk_from_EVP_PKEY(eddsa_pk_t *pk, const EVP_PKEY *pkey) { size_t len = 0; if (EVP_PKEY_get_raw_public_key(pkey, NULL, &len) != 1 || len != sizeof(pk->x)) return (FIDO_ERR_INTERNAL); if (EVP_PKEY_get_raw_public_key(pkey, pk->x, &len) != 1 || len != sizeof(pk->x)) return (FIDO_ERR_INTERNAL); 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/export.gnu b/contrib/libfido2/src/export.gnu index 2a8ad24b4c3c..0a8d46a20fad 100644 --- a/contrib/libfido2/src/export.gnu +++ b/contrib/libfido2/src/export.gnu @@ -1,243 +1,247 @@ { global: eddsa_pk_free; eddsa_pk_from_EVP_PKEY; eddsa_pk_from_ptr; 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; fido_assert_allow_cred; fido_assert_authdata_len; fido_assert_authdata_ptr; fido_assert_blob_len; fido_assert_blob_ptr; fido_assert_clientdata_hash_len; fido_assert_clientdata_hash_ptr; fido_assert_count; fido_assert_flags; fido_assert_free; fido_assert_hmac_secret_len; fido_assert_hmac_secret_ptr; fido_assert_id_len; fido_assert_id_ptr; fido_assert_largeblob_key_len; fido_assert_largeblob_key_ptr; fido_assert_new; 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; fido_assert_set_hmac_salt; fido_assert_set_hmac_secret; fido_assert_set_options; fido_assert_set_rp; fido_assert_set_sig; fido_assert_set_up; fido_assert_set_uv; fido_assert_sigcount; fido_assert_sig_len; fido_assert_sig_ptr; fido_assert_user_display_name; fido_assert_user_icon; fido_assert_user_id_len; fido_assert_user_id_ptr; fido_assert_user_name; fido_assert_verify; fido_bio_dev_enroll_begin; fido_bio_dev_enroll_cancel; fido_bio_dev_enroll_continue; fido_bio_dev_enroll_remove; fido_bio_dev_get_info; fido_bio_dev_get_template_array; fido_bio_dev_set_template_name; fido_bio_enroll_free; fido_bio_enroll_last_status; fido_bio_enroll_new; fido_bio_enroll_remaining_samples; fido_bio_info_free; fido_bio_info_max_samples; fido_bio_info_new; fido_bio_info_type; fido_bio_template; fido_bio_template_array_count; fido_bio_template_array_free; fido_bio_template_array_new; fido_bio_template_free; fido_bio_template_id_len; fido_bio_template_id_ptr; fido_bio_template_name; fido_bio_template_new; fido_bio_template_set_id; fido_bio_template_set_name; fido_cbor_info_aaguid_len; fido_cbor_info_aaguid_ptr; fido_cbor_info_algorithm_cose; fido_cbor_info_algorithm_count; fido_cbor_info_algorithm_type; fido_cbor_info_extensions_len; fido_cbor_info_extensions_ptr; fido_cbor_info_free; fido_cbor_info_maxmsgsiz; fido_cbor_info_maxcredbloblen; fido_cbor_info_maxcredcntlst; fido_cbor_info_maxcredidlen; fido_cbor_info_fwversion; fido_cbor_info_new; fido_cbor_info_options_len; fido_cbor_info_options_name_ptr; fido_cbor_info_options_value_ptr; fido_cbor_info_protocols_len; fido_cbor_info_protocols_ptr; 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; fido_cred_authdata_raw_ptr; fido_cred_clientdata_hash_len; fido_cred_clientdata_hash_ptr; fido_cred_display_name; fido_cred_exclude; fido_cred_flags; fido_cred_largeblob_key_len; fido_cred_largeblob_key_ptr; fido_cred_sigcount; fido_cred_fmt; fido_cred_free; fido_cred_id_len; fido_cred_id_ptr; fido_cred_aaguid_len; fido_cred_aaguid_ptr; fido_credman_del_dev_rk; fido_credman_get_dev_metadata; fido_credman_get_dev_rk; fido_credman_get_dev_rp; fido_credman_metadata_free; fido_credman_metadata_new; fido_credman_rk; fido_credman_rk_count; fido_credman_rk_existing; fido_credman_rk_free; fido_credman_rk_new; fido_credman_rk_remaining; fido_credman_rp_count; fido_credman_rp_free; fido_credman_rp_id; fido_credman_rp_id_hash_len; fido_credman_rp_id_hash_ptr; 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; 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; fido_cred_set_sig; fido_cred_set_type; fido_cred_set_user; fido_cred_set_uv; fido_cred_set_x509; fido_cred_sig_len; fido_cred_sig_ptr; fido_cred_type; fido_cred_user_id_len; fido_cred_user_id_ptr; fido_cred_user_name; fido_cred_verify; fido_cred_verify_self; fido_cred_x5c_len; fido_cred_x5c_ptr; fido_dev_build; fido_dev_cancel; fido_dev_close; fido_dev_enable_entattest; fido_dev_flags; fido_dev_force_fido2; fido_dev_force_pin_change; fido_dev_force_u2f; fido_dev_free; fido_dev_get_assert; fido_dev_get_cbor_info; fido_dev_get_retry_count; fido_dev_get_uv_retry_count; fido_dev_get_touch_begin; fido_dev_get_touch_status; fido_dev_has_pin; fido_dev_has_uv; fido_dev_info_free; fido_dev_info_manifest; fido_dev_info_manufacturer_string; fido_dev_info_new; fido_dev_info_path; fido_dev_info_product; fido_dev_info_product_string; fido_dev_info_ptr; + fido_dev_info_set; fido_dev_info_vendor; + fido_dev_io_handle; fido_dev_is_fido2; fido_dev_is_winhello; fido_dev_major; fido_dev_make_cred; fido_dev_minor; fido_dev_new; + fido_dev_new_with_info; fido_dev_open; + fido_dev_open_with_info; fido_dev_protocol; 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; fido_dev_supports_permissions; fido_dev_supports_pin; fido_dev_supports_uv; fido_dev_toggle_always_uv; fido_dev_largeblob_get; fido_dev_largeblob_get_array; fido_dev_largeblob_remove; fido_dev_largeblob_set; fido_dev_largeblob_set_array; fido_init; 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; local: *; }; diff --git a/contrib/libfido2/src/export.llvm b/contrib/libfido2/src/export.llvm index e163afecedce..80507346edee 100644 --- a/contrib/libfido2/src/export.llvm +++ b/contrib/libfido2/src/export.llvm @@ -1,238 +1,242 @@ _eddsa_pk_free _eddsa_pk_from_EVP_PKEY _eddsa_pk_from_ptr _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 _fido_assert_allow_cred _fido_assert_authdata_len _fido_assert_authdata_ptr _fido_assert_blob_len _fido_assert_blob_ptr _fido_assert_clientdata_hash_len _fido_assert_clientdata_hash_ptr _fido_assert_count _fido_assert_flags _fido_assert_free _fido_assert_hmac_secret_len _fido_assert_hmac_secret_ptr _fido_assert_id_len _fido_assert_id_ptr _fido_assert_largeblob_key_len _fido_assert_largeblob_key_ptr _fido_assert_new _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 _fido_assert_set_hmac_salt _fido_assert_set_hmac_secret _fido_assert_set_options _fido_assert_set_rp _fido_assert_set_sig _fido_assert_set_up _fido_assert_set_uv _fido_assert_sigcount _fido_assert_sig_len _fido_assert_sig_ptr _fido_assert_user_display_name _fido_assert_user_icon _fido_assert_user_id_len _fido_assert_user_id_ptr _fido_assert_user_name _fido_assert_verify _fido_bio_dev_enroll_begin _fido_bio_dev_enroll_cancel _fido_bio_dev_enroll_continue _fido_bio_dev_enroll_remove _fido_bio_dev_get_info _fido_bio_dev_get_template_array _fido_bio_dev_set_template_name _fido_bio_enroll_free _fido_bio_enroll_last_status _fido_bio_enroll_new _fido_bio_enroll_remaining_samples _fido_bio_info_free _fido_bio_info_max_samples _fido_bio_info_new _fido_bio_info_type _fido_bio_template _fido_bio_template_array_count _fido_bio_template_array_free _fido_bio_template_array_new _fido_bio_template_free _fido_bio_template_id_len _fido_bio_template_id_ptr _fido_bio_template_name _fido_bio_template_new _fido_bio_template_set_id _fido_bio_template_set_name _fido_cbor_info_aaguid_len _fido_cbor_info_aaguid_ptr _fido_cbor_info_algorithm_cose _fido_cbor_info_algorithm_count _fido_cbor_info_algorithm_type _fido_cbor_info_extensions_len _fido_cbor_info_extensions_ptr _fido_cbor_info_free _fido_cbor_info_maxmsgsiz _fido_cbor_info_maxcredbloblen _fido_cbor_info_maxcredcntlst _fido_cbor_info_maxcredidlen _fido_cbor_info_fwversion _fido_cbor_info_new _fido_cbor_info_options_len _fido_cbor_info_options_name_ptr _fido_cbor_info_options_value_ptr _fido_cbor_info_protocols_len _fido_cbor_info_protocols_ptr _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 _fido_cred_authdata_raw_ptr _fido_cred_clientdata_hash_len _fido_cred_clientdata_hash_ptr _fido_cred_display_name _fido_cred_exclude _fido_cred_flags _fido_cred_largeblob_key_len _fido_cred_largeblob_key_ptr _fido_cred_sigcount _fido_cred_fmt _fido_cred_free _fido_cred_id_len _fido_cred_id_ptr _fido_cred_aaguid_len _fido_cred_aaguid_ptr _fido_credman_del_dev_rk _fido_credman_get_dev_metadata _fido_credman_get_dev_rk _fido_credman_get_dev_rp _fido_credman_metadata_free _fido_credman_metadata_new _fido_credman_rk _fido_credman_rk_count _fido_credman_rk_existing _fido_credman_rk_free _fido_credman_rk_new _fido_credman_rk_remaining _fido_credman_rp_count _fido_credman_rp_free _fido_credman_rp_id _fido_credman_rp_id_hash_len _fido_credman_rp_id_hash_ptr _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 _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 _fido_cred_set_sig _fido_cred_set_type _fido_cred_set_user _fido_cred_set_uv _fido_cred_set_x509 _fido_cred_sig_len _fido_cred_sig_ptr _fido_cred_type _fido_cred_user_id_len _fido_cred_user_id_ptr _fido_cred_user_name _fido_cred_verify _fido_cred_verify_self _fido_cred_x5c_len _fido_cred_x5c_ptr _fido_dev_build _fido_dev_cancel _fido_dev_close _fido_dev_enable_entattest _fido_dev_flags _fido_dev_force_fido2 _fido_dev_force_pin_change _fido_dev_force_u2f _fido_dev_free _fido_dev_get_assert _fido_dev_get_cbor_info _fido_dev_get_retry_count _fido_dev_get_uv_retry_count _fido_dev_get_touch_begin _fido_dev_get_touch_status _fido_dev_has_pin _fido_dev_has_uv _fido_dev_info_free _fido_dev_info_manifest _fido_dev_info_manufacturer_string _fido_dev_info_new _fido_dev_info_path _fido_dev_info_product _fido_dev_info_product_string _fido_dev_info_ptr +_fido_dev_info_set _fido_dev_info_vendor +_fido_dev_io_handle _fido_dev_is_fido2 _fido_dev_is_winhello _fido_dev_major _fido_dev_make_cred _fido_dev_minor _fido_dev_new +_fido_dev_new_with_info _fido_dev_open +_fido_dev_open_with_info _fido_dev_protocol _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 _fido_dev_supports_permissions _fido_dev_supports_pin _fido_dev_supports_uv _fido_dev_toggle_always_uv _fido_dev_largeblob_get _fido_dev_largeblob_get_array _fido_dev_largeblob_remove _fido_dev_largeblob_set _fido_dev_largeblob_set_array _fido_init _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 9fc24e335e8d..14602164fd45 100644 --- a/contrib/libfido2/src/export.msvc +++ b/contrib/libfido2/src/export.msvc @@ -1,239 +1,243 @@ EXPORTS eddsa_pk_free eddsa_pk_from_EVP_PKEY eddsa_pk_from_ptr 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 fido_assert_allow_cred fido_assert_authdata_len fido_assert_authdata_ptr fido_assert_blob_len fido_assert_blob_ptr fido_assert_clientdata_hash_len fido_assert_clientdata_hash_ptr fido_assert_count fido_assert_flags fido_assert_free fido_assert_hmac_secret_len fido_assert_hmac_secret_ptr fido_assert_id_len fido_assert_id_ptr fido_assert_largeblob_key_len fido_assert_largeblob_key_ptr fido_assert_new 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 fido_assert_set_hmac_salt fido_assert_set_hmac_secret fido_assert_set_options fido_assert_set_rp fido_assert_set_sig fido_assert_set_up fido_assert_set_uv fido_assert_sigcount fido_assert_sig_len fido_assert_sig_ptr fido_assert_user_display_name fido_assert_user_icon fido_assert_user_id_len fido_assert_user_id_ptr fido_assert_user_name fido_assert_verify fido_bio_dev_enroll_begin fido_bio_dev_enroll_cancel fido_bio_dev_enroll_continue fido_bio_dev_enroll_remove fido_bio_dev_get_info fido_bio_dev_get_template_array fido_bio_dev_set_template_name fido_bio_enroll_free fido_bio_enroll_last_status fido_bio_enroll_new fido_bio_enroll_remaining_samples fido_bio_info_free fido_bio_info_max_samples fido_bio_info_new fido_bio_info_type fido_bio_template fido_bio_template_array_count fido_bio_template_array_free fido_bio_template_array_new fido_bio_template_free fido_bio_template_id_len fido_bio_template_id_ptr fido_bio_template_name fido_bio_template_new fido_bio_template_set_id fido_bio_template_set_name fido_cbor_info_aaguid_len fido_cbor_info_aaguid_ptr fido_cbor_info_algorithm_cose fido_cbor_info_algorithm_count fido_cbor_info_algorithm_type fido_cbor_info_extensions_len fido_cbor_info_extensions_ptr fido_cbor_info_free fido_cbor_info_maxmsgsiz fido_cbor_info_maxcredbloblen fido_cbor_info_maxcredcntlst fido_cbor_info_maxcredidlen fido_cbor_info_fwversion fido_cbor_info_new fido_cbor_info_options_len fido_cbor_info_options_name_ptr fido_cbor_info_options_value_ptr fido_cbor_info_protocols_len fido_cbor_info_protocols_ptr 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 fido_cred_authdata_raw_ptr fido_cred_clientdata_hash_len fido_cred_clientdata_hash_ptr fido_cred_display_name fido_cred_exclude fido_cred_flags fido_cred_largeblob_key_len fido_cred_largeblob_key_ptr fido_cred_sigcount fido_cred_fmt fido_cred_free fido_cred_id_len fido_cred_id_ptr fido_cred_aaguid_len fido_cred_aaguid_ptr fido_credman_del_dev_rk fido_credman_get_dev_metadata fido_credman_get_dev_rk fido_credman_get_dev_rp fido_credman_metadata_free fido_credman_metadata_new fido_credman_rk fido_credman_rk_count fido_credman_rk_existing fido_credman_rk_free fido_credman_rk_new fido_credman_rk_remaining fido_credman_rp_count fido_credman_rp_free fido_credman_rp_id fido_credman_rp_id_hash_len fido_credman_rp_id_hash_ptr 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 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 fido_cred_set_sig fido_cred_set_type fido_cred_set_user fido_cred_set_uv fido_cred_set_x509 fido_cred_sig_len fido_cred_sig_ptr fido_cred_type fido_cred_user_id_len fido_cred_user_id_ptr fido_cred_user_name fido_cred_verify fido_cred_verify_self fido_cred_x5c_len fido_cred_x5c_ptr fido_dev_build fido_dev_cancel fido_dev_close fido_dev_enable_entattest fido_dev_flags fido_dev_force_fido2 fido_dev_force_pin_change fido_dev_force_u2f fido_dev_free fido_dev_get_assert fido_dev_get_cbor_info fido_dev_get_retry_count fido_dev_get_uv_retry_count fido_dev_get_touch_begin fido_dev_get_touch_status fido_dev_has_pin fido_dev_has_uv fido_dev_info_free fido_dev_info_manifest fido_dev_info_manufacturer_string fido_dev_info_new fido_dev_info_path fido_dev_info_product fido_dev_info_product_string fido_dev_info_ptr +fido_dev_info_set fido_dev_info_vendor +fido_dev_io_handle fido_dev_is_fido2 fido_dev_is_winhello fido_dev_major fido_dev_make_cred fido_dev_minor fido_dev_new +fido_dev_new_with_info fido_dev_open +fido_dev_open_with_info fido_dev_protocol 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 fido_dev_supports_permissions fido_dev_supports_pin fido_dev_supports_uv fido_dev_toggle_always_uv fido_dev_largeblob_get fido_dev_largeblob_get_array fido_dev_largeblob_remove fido_dev_largeblob_set fido_dev_largeblob_set_array fido_init 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 dc6bddd7b912..6f86d7642950 100644 --- a/contrib/libfido2/src/extern.h +++ b/contrib/libfido2/src/extern.h @@ -1,259 +1,258 @@ /* * 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. */ #ifndef _EXTERN_H #define _EXTERN_H #ifdef __MINGW32__ #include #endif #ifdef HAVE_SIGNAL_H #include #endif #include #include "fido/types.h" #include "blob.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* aes256 */ int aes256_cbc_dec(const fido_dev_t *dev, const fido_blob_t *, const fido_blob_t *, fido_blob_t *); int aes256_cbc_enc(const fido_dev_t *dev, const fido_blob_t *, const fido_blob_t *, fido_blob_t *); int aes256_gcm_dec(const fido_blob_t *, const fido_blob_t *, const fido_blob_t *, const fido_blob_t *, fido_blob_t *); int aes256_gcm_enc(const fido_blob_t *, const fido_blob_t *, const fido_blob_t *, const fido_blob_t *, fido_blob_t *); /* cbor encoding functions */ cbor_item_t *cbor_build_uint(const uint64_t); cbor_item_t *cbor_flatten_vector(cbor_item_t **, size_t); cbor_item_t *cbor_encode_assert_opt(fido_opt_t, fido_opt_t); cbor_item_t *cbor_encode_change_pin_auth(const fido_dev_t *, const fido_blob_t *, const fido_blob_t *, const fido_blob_t *); cbor_item_t *cbor_encode_cred_ext(const fido_cred_ext_t *, const fido_blob_t *); cbor_item_t *cbor_encode_assert_ext(fido_dev_t *, const fido_assert_ext_t *, const fido_blob_t *, const es256_pk_t *); cbor_item_t *cbor_encode_cred_opt(fido_opt_t, fido_opt_t); cbor_item_t *cbor_encode_pin_auth(const fido_dev_t *, const fido_blob_t *, const fido_blob_t *); cbor_item_t *cbor_encode_pin_opt(const fido_dev_t *); 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); /* cbor decoding functions */ int cbor_decode_attstmt(const cbor_item_t *, fido_attstmt_t *); int cbor_decode_cred_authdata(const cbor_item_t *, int, fido_blob_t *, fido_authdata_t *, fido_attcred_t *, fido_cred_ext_t *); int cbor_decode_assert_authdata(const cbor_item_t *, fido_blob_t *, fido_authdata_t *, fido_assert_extattr_t *); int cbor_decode_cred_id(const cbor_item_t *, fido_blob_t *); int cbor_decode_fmt(const cbor_item_t *, char **); int cbor_decode_pubkey(const cbor_item_t *, int *, void *); int cbor_decode_rp_entity(const cbor_item_t *, fido_rp_t *); int cbor_decode_uint64(const cbor_item_t *, uint64_t *); int cbor_decode_user(const cbor_item_t *, fido_user_t *); int es256_pk_decode(const cbor_item_t *, es256_pk_t *); int rs256_pk_decode(const cbor_item_t *, rs256_pk_t *); int eddsa_pk_decode(const cbor_item_t *, eddsa_pk_t *); /* auxiliary cbor routines */ int cbor_add_bool(cbor_item_t *, const char *, fido_opt_t); int cbor_add_bytestring(cbor_item_t *, const char *, const unsigned char *, size_t); int cbor_add_string(cbor_item_t *, const char *, const char *); int cbor_array_iter(const cbor_item_t *, void *, int(*)(const cbor_item_t *, void *)); int cbor_build_frame(uint8_t, cbor_item_t *[], size_t, fido_blob_t *); int cbor_bytestring_copy(const cbor_item_t *, unsigned char **, size_t *); int cbor_map_iter(const cbor_item_t *, void *, int(*)(const cbor_item_t *, const cbor_item_t *, void *)); int cbor_string_copy(const cbor_item_t *, char **); 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 **, 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); /* deflate */ int fido_compress(fido_blob_t *, const fido_blob_t *); int fido_uncompress(fido_blob_t *, const fido_blob_t *, size_t); #ifndef nitems #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) #endif /* buf */ int fido_buf_read(const unsigned char **, size_t *, void *, size_t); int fido_buf_write(unsigned char **, size_t *, const void *, size_t); /* hid i/o */ void *fido_hid_open(const char *); void fido_hid_close(void *); int fido_hid_read(void *, unsigned char *, size_t, int); int fido_hid_write(void *, const unsigned char *, size_t); int fido_hid_get_usage(const uint8_t *, size_t, uint32_t *); int fido_hid_get_report_len(const uint8_t *, size_t, size_t *, size_t *); int fido_hid_unix_open(const char *); int fido_hid_unix_wait(int, int, const fido_sigset_t *); int fido_hid_set_sigmask(void *, const fido_sigset_t *); size_t fido_hid_report_in_len(void *); size_t fido_hid_report_out_len(void *); /* nfc i/o */ void *fido_nfc_open(const char *); void fido_nfc_close(void *); int fido_nfc_read(void *, unsigned char *, size_t, int); int fido_nfc_write(void *, const unsigned char *, size_t); int fido_nfc_rx(fido_dev_t *, uint8_t, unsigned char *, size_t, int); int fido_nfc_tx(fido_dev_t *, uint8_t, const unsigned char *, size_t); int fido_nfc_set_sigmask(void *, const fido_sigset_t *); /* windows hello */ 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); 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); /* 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 *); /* log */ #ifdef FIDO_NO_DIAGNOSTIC #define fido_log_init(...) do { /* nothing */ } while (0) #define fido_log_debug(...) do { /* nothing */ } while (0) #define fido_log_xxd(...) do { /* nothing */ } while (0) #define fido_log_error(...) do { /* nothing */ } while (0) #else #ifdef __GNUC__ void fido_log_init(void); void fido_log_debug(const char *, ...) __attribute__((__format__ (printf, 1, 2))); void fido_log_xxd(const void *, size_t, const char *, ...) __attribute__((__format__ (printf, 3, 4))); void fido_log_error(int, const char *, ...) __attribute__((__format__ (printf, 2, 3))); #else void fido_log_init(void); void fido_log_debug(const char *, ...); void fido_log_xxd(const void *, size_t, const char *, ...); void fido_log_error(int, const char *, ...); #endif /* __GNUC__ */ #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 *); 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 *); 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 *, int *); uint64_t fido_dev_maxmsgsize(const fido_dev_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 *); void fido_cred_reset_rx(fido_cred_t *); void fido_cred_reset_tx(fido_cred_t *); void fido_cbor_info_reset(fido_cbor_info_t *); int fido_blob_serialise(fido_blob_t *, const cbor_item_t *); 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 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 rs256_pk_verify_sig(const fido_blob_t *, const rs256_pk_t *, const fido_blob_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 *); int fido_nfc_manifest(fido_dev_info_t *, size_t, size_t *); /* device manifest registration */ typedef int (*dev_manifest_func_t)(fido_dev_info_t *, size_t, size_t *); int fido_dev_register_manifest_func(const dev_manifest_func_t); void fido_dev_unregister_manifest_func(const dev_manifest_func_t); /* fuzzing instrumentation */ #ifdef FIDO_FUZZ uint32_t uniform_random(uint32_t); #endif /* internal device capability flags */ #define FIDO_DEV_PIN_SET 0x001 #define FIDO_DEV_PIN_UNSET 0x002 #define FIDO_DEV_CRED_PROT 0x004 #define FIDO_DEV_CREDMAN 0x008 #define FIDO_DEV_PIN_PROTOCOL1 0x010 #define FIDO_DEV_PIN_PROTOCOL2 0x020 #define FIDO_DEV_UV_SET 0x040 #define FIDO_DEV_UV_UNSET 0x080 #define FIDO_DEV_TOKEN_PERMS 0x100 #define FIDO_DEV_WINHELLO 0x200 /* miscellanea */ #define FIDO_DUMMY_CLIENTDATA "" #define FIDO_DUMMY_RP_ID "localhost" #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" */ #endif /* __cplusplus */ #endif /* !_EXTERN_H */ diff --git a/contrib/libfido2/src/fido.h b/contrib/libfido2/src/fido.h index 51bdb526d3f0..4bd2aeebfccb 100644 --- a/contrib/libfido2/src/fido.h +++ b/contrib/libfido2/src/fido.h @@ -1,234 +1,238 @@ /* * Copyright (c) 2018 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. */ #ifndef _FIDO_H #define _FIDO_H #include #include #include #include #include #ifdef _FIDO_INTERNAL #include #include #include #include "../openbsd-compat/openbsd-compat.h" #include "blob.h" #include "iso7816.h" #include "extern.h" #endif #include "fido/err.h" #include "fido/param.h" #include "fido/types.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ fido_assert_t *fido_assert_new(void); fido_cred_t *fido_cred_new(void); fido_dev_t *fido_dev_new(void); fido_dev_t *fido_dev_new_with_info(const fido_dev_info_t *); fido_dev_info_t *fido_dev_info_new(size_t); fido_cbor_info_t *fido_cbor_info_new(void); +void *fido_dev_io_handle(const fido_dev_t *); void fido_assert_free(fido_assert_t **); void fido_cbor_info_free(fido_cbor_info_t **); void fido_cred_free(fido_cred_t **); void fido_dev_force_fido2(fido_dev_t *); void fido_dev_force_u2f(fido_dev_t *); void fido_dev_free(fido_dev_t **); void fido_dev_info_free(fido_dev_info_t **, size_t); /* fido_init() flags. */ #define FIDO_DEBUG 0x01 #define FIDO_DISABLE_U2F_FALLBACK 0x02 void fido_init(int); void fido_set_log_handler(fido_log_handler_t *); const unsigned char *fido_assert_authdata_ptr(const fido_assert_t *, size_t); const unsigned char *fido_assert_clientdata_hash_ptr(const fido_assert_t *); const unsigned char *fido_assert_hmac_secret_ptr(const fido_assert_t *, size_t); const unsigned char *fido_assert_id_ptr(const fido_assert_t *, size_t); const unsigned char *fido_assert_largeblob_key_ptr(const fido_assert_t *, size_t); const unsigned char *fido_assert_sig_ptr(const fido_assert_t *, size_t); const unsigned char *fido_assert_user_id_ptr(const fido_assert_t *, size_t); const unsigned char *fido_assert_blob_ptr(const fido_assert_t *, size_t); char **fido_cbor_info_extensions_ptr(const fido_cbor_info_t *); char **fido_cbor_info_options_name_ptr(const fido_cbor_info_t *); char **fido_cbor_info_transports_ptr(const fido_cbor_info_t *); char **fido_cbor_info_versions_ptr(const fido_cbor_info_t *); const bool *fido_cbor_info_options_value_ptr(const fido_cbor_info_t *); const char *fido_assert_rp_id(const fido_assert_t *); const char *fido_assert_user_display_name(const fido_assert_t *, size_t); const char *fido_assert_user_icon(const fido_assert_t *, size_t); const char *fido_assert_user_name(const fido_assert_t *, size_t); const char *fido_cbor_info_algorithm_type(const fido_cbor_info_t *, size_t); const char *fido_cred_display_name(const fido_cred_t *); const char *fido_cred_fmt(const fido_cred_t *); const char *fido_cred_rp_id(const fido_cred_t *); const char *fido_cred_rp_name(const fido_cred_t *); const char *fido_cred_user_name(const fido_cred_t *); const char *fido_dev_info_manufacturer_string(const fido_dev_info_t *); const char *fido_dev_info_path(const fido_dev_info_t *); 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_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 *); 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 *, size_t); int fido_assert_set_authdata_raw(fido_assert_t *, size_t, const unsigned char *, size_t); int fido_assert_set_clientdata(fido_assert_t *, const unsigned char *, size_t); int fido_assert_set_clientdata_hash(fido_assert_t *, const unsigned char *, size_t); int fido_assert_set_count(fido_assert_t *, size_t); int fido_assert_set_extensions(fido_assert_t *, int); int fido_assert_set_hmac_salt(fido_assert_t *, const unsigned char *, size_t); int fido_assert_set_hmac_secret(fido_assert_t *, size_t, const unsigned char *, size_t); int fido_assert_set_options(fido_assert_t *, bool, bool); int fido_assert_set_rp(fido_assert_t *, const char *); int fido_assert_set_up(fido_assert_t *, fido_opt_t); int fido_assert_set_uv(fido_assert_t *, fido_opt_t); int fido_assert_set_sig(fido_assert_t *, size_t, const unsigned char *, size_t); 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); int fido_cred_set_clientdata(fido_cred_t *, const unsigned char *, size_t); int fido_cred_set_clientdata_hash(fido_cred_t *, const unsigned char *, size_t); 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 *); int fido_cred_set_sig(fido_cred_t *, const unsigned char *, size_t); int fido_cred_set_type(fido_cred_t *, int); int fido_cred_set_uv(fido_cred_t *, fido_opt_t); int fido_cred_type(const fido_cred_t *); int fido_cred_set_user(fido_cred_t *, const unsigned char *, size_t, const char *, const char *, const char *); int fido_cred_set_x509(fido_cred_t *, const unsigned char *, size_t); int fido_cred_verify(const fido_cred_t *); int fido_cred_verify_self(const fido_cred_t *); int fido_dev_set_sigmask(fido_dev_t *, const fido_sigset_t *); int fido_dev_cancel(fido_dev_t *); int fido_dev_close(fido_dev_t *); int fido_dev_get_assert(fido_dev_t *, fido_assert_t *, const char *); int fido_dev_get_cbor_info(fido_dev_t *, fido_cbor_info_t *); int fido_dev_get_retry_count(fido_dev_t *, int *); int fido_dev_get_uv_retry_count(fido_dev_t *, int *); int fido_dev_get_touch_begin(fido_dev_t *); int fido_dev_get_touch_status(fido_dev_t *, int *, int); int fido_dev_info_manifest(fido_dev_info_t *, size_t, size_t *); +int fido_dev_info_set(fido_dev_info_t *, size_t, const char *, const char *, + const char *, const fido_dev_io_t *, const fido_dev_transport_t *); int fido_dev_make_cred(fido_dev_t *, fido_cred_t *, const char *); int fido_dev_open_with_info(fido_dev_t *); int fido_dev_open(fido_dev_t *, const char *); 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 *); size_t fido_assert_count(const fido_assert_t *); size_t fido_assert_hmac_secret_len(const fido_assert_t *, size_t); size_t fido_assert_id_len(const fido_assert_t *, size_t); size_t fido_assert_largeblob_key_len(const fido_assert_t *, size_t); size_t fido_assert_sig_len(const fido_assert_t *, size_t); size_t fido_assert_user_id_len(const fido_assert_t *, size_t); size_t fido_assert_blob_len(const fido_assert_t *, size_t); size_t fido_cbor_info_aaguid_len(const fido_cbor_info_t *); size_t fido_cbor_info_algorithm_count(const fido_cbor_info_t *); size_t fido_cbor_info_extensions_len(const fido_cbor_info_t *); 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_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 *); uint8_t fido_assert_flags(const fido_assert_t *, size_t); uint32_t fido_assert_sigcount(const fido_assert_t *, size_t); uint8_t fido_cred_flags(const fido_cred_t *); uint32_t fido_cred_sigcount(const fido_cred_t *); uint8_t fido_dev_protocol(const fido_dev_t *); uint8_t fido_dev_major(const fido_dev_t *); uint8_t fido_dev_minor(const fido_dev_t *); uint8_t fido_dev_build(const fido_dev_t *); uint8_t fido_dev_flags(const fido_dev_t *); int16_t fido_dev_info_vendor(const fido_dev_info_t *); int16_t fido_dev_info_product(const fido_dev_info_t *); uint64_t fido_cbor_info_maxmsgsiz(const fido_cbor_info_t *); uint64_t fido_cbor_info_maxcredbloblen(const fido_cbor_info_t *); uint64_t fido_cbor_info_maxcredcntlst(const fido_cbor_info_t *); uint64_t fido_cbor_info_maxcredidlen(const fido_cbor_info_t *); uint64_t fido_cbor_info_fwversion(const fido_cbor_info_t *); bool fido_dev_has_pin(const fido_dev_t *); bool fido_dev_has_uv(const fido_dev_t *); bool fido_dev_is_fido2(const fido_dev_t *); bool fido_dev_is_winhello(const fido_dev_t *); -bool fido_dev_supports_pin(const fido_dev_t *); -bool fido_dev_supports_cred_prot(const fido_dev_t *); bool fido_dev_supports_credman(const fido_dev_t *); +bool fido_dev_supports_cred_prot(const fido_dev_t *); +bool fido_dev_supports_permissions(const fido_dev_t *); +bool fido_dev_supports_pin(const fido_dev_t *); bool fido_dev_supports_uv(const fido_dev_t *); int fido_dev_largeblob_get(fido_dev_t *, const unsigned char *, size_t, unsigned char **, size_t *); int fido_dev_largeblob_set(fido_dev_t *, const unsigned char *, size_t, const unsigned char *, size_t, const char *); int fido_dev_largeblob_remove(fido_dev_t *, const unsigned char *, size_t, const char *); int fido_dev_largeblob_get_array(fido_dev_t *, unsigned char **, size_t *); int fido_dev_largeblob_set_array(fido_dev_t *, const unsigned char *, size_t, const char *); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* !_FIDO_H */ diff --git a/contrib/libfido2/src/fido/types.h b/contrib/libfido2/src/fido/types.h index 92f55d979fdc..4a216b4b9786 100644 --- a/contrib/libfido2/src/fido/types.h +++ b/contrib/libfido2/src/fido/types.h @@ -1,287 +1,287 @@ /* * Copyright (c) 2018 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. */ #ifndef _FIDO_TYPES_H #define _FIDO_TYPES_H #ifdef __MINGW32__ #include #endif #include #include #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct fido_dev; typedef void *fido_dev_io_open_t(const char *); typedef void fido_dev_io_close_t(void *); typedef int fido_dev_io_read_t(void *, unsigned char *, size_t, int); typedef int fido_dev_io_write_t(void *, const unsigned char *, size_t); typedef int fido_dev_rx_t(struct fido_dev *, uint8_t, unsigned char *, size_t, int); typedef int fido_dev_tx_t(struct fido_dev *, uint8_t, const unsigned char *, size_t); typedef struct fido_dev_io { fido_dev_io_open_t *open; fido_dev_io_close_t *close; fido_dev_io_read_t *read; fido_dev_io_write_t *write; } fido_dev_io_t; typedef struct fido_dev_transport { fido_dev_rx_t *rx; fido_dev_tx_t *tx; } fido_dev_transport_t; typedef enum { FIDO_OPT_OMIT = 0, /* use authenticator's default */ FIDO_OPT_FALSE, /* explicitly set option to false */ FIDO_OPT_TRUE, /* explicitly set option to true */ } fido_opt_t; typedef void fido_log_handler_t(const char *); #ifdef _WIN32 typedef int fido_sigset_t; #else typedef sigset_t fido_sigset_t; #endif #ifdef _FIDO_INTERNAL #include "packed.h" #include "blob.h" /* COSE ES256 (ECDSA over P-256 with SHA-256) public key */ typedef struct es256_pk { unsigned char x[32]; unsigned char y[32]; } es256_pk_t; /* COSE ES256 (ECDSA over P-256 with SHA-256) (secret) key */ typedef struct es256_sk { unsigned char d[32]; } es256_sk_t; /* COSE RS256 (2048-bit RSA with PKCS1 padding and SHA-256) public key */ typedef struct rs256_pk { unsigned char n[256]; unsigned char e[3]; } rs256_pk_t; /* COSE EDDSA (ED25519) */ typedef struct eddsa_pk { unsigned char x[32]; } eddsa_pk_t; PACKED_TYPE(fido_authdata_t, struct fido_authdata { unsigned char rp_id_hash[32]; /* sha256 of fido_rp.id */ uint8_t flags; /* user present/verified */ uint32_t sigcount; /* signature counter */ /* actually longer */ }) PACKED_TYPE(fido_attcred_raw_t, struct fido_attcred_raw { unsigned char aaguid[16]; /* credential's aaguid */ uint16_t id_len; /* credential id length */ uint8_t body[]; /* credential id + pubkey */ }) typedef struct fido_attcred { unsigned char aaguid[16]; /* credential's aaguid */ fido_blob_t id; /* credential id */ int type; /* credential's cose algorithm */ union { /* credential's public key */ es256_pk_t es256; rs256_pk_t rs256; eddsa_pk_t eddsa; } pubkey; } fido_attcred_t; typedef struct fido_attstmt { 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 { char *id; /* relying party id */ char *name; /* relying party name */ } fido_rp_t; typedef struct fido_user { fido_blob_t id; /* required */ char *icon; /* optional */ char *name; /* optional */ char *display_name; /* required */ } fido_user_t; typedef struct fido_cred_ext { int mask; /* enabled extensions */ int prot; /* protection policy */ size_t minpinlen; /* minimum pin length */ } fido_cred_ext_t; typedef struct fido_cred { fido_blob_t cd; /* client data */ fido_blob_t cdh; /* client data hash */ fido_rp_t rp; /* relying party */ fido_user_t user; /* user entity */ fido_blob_array_t excl; /* list of credential ids to exclude */ fido_opt_t rk; /* resident key */ fido_opt_t uv; /* user verification */ fido_cred_ext_t ext; /* extensions */ int type; /* cose algorithm */ char *fmt; /* credential format */ fido_cred_ext_t authdata_ext; /* decoded extensions */ fido_blob_t authdata_cbor; /* cbor-encoded payload */ fido_blob_t authdata_raw; /* cbor-decoded payload */ fido_authdata_t authdata; /* decoded authdata payload */ fido_attcred_t attcred; /* returned credential (key + id) */ fido_attstmt_t attstmt; /* attestation statement (x509 + sig) */ fido_blob_t largeblob_key; /* decoded large blob key */ - fido_blob_t blob; /* FIDO 2.1 credBlob */ + fido_blob_t blob; /* CTAP 2.1 credBlob */ } fido_cred_t; typedef struct fido_assert_extattr { int mask; /* decoded extensions */ fido_blob_t hmac_secret_enc; /* hmac secret, encrypted */ - fido_blob_t blob; /* decoded FIDO 2.1 credBlob */ + fido_blob_t blob; /* decoded CTAP 2.1 credBlob */ } fido_assert_extattr_t; typedef struct _fido_assert_stmt { fido_blob_t id; /* credential id */ fido_user_t user; /* user attributes */ fido_blob_t hmac_secret; /* hmac secret */ fido_assert_extattr_t authdata_ext; /* decoded extensions */ fido_blob_t authdata_cbor; /* raw cbor payload */ fido_authdata_t authdata; /* decoded authdata payload */ fido_blob_t sig; /* signature of cdh + authdata */ fido_blob_t largeblob_key; /* decoded large blob key */ } fido_assert_stmt; typedef struct fido_assert_ext { int mask; /* enabled extensions */ fido_blob_t hmac_salt; /* optional hmac-secret salt */ } fido_assert_ext_t; typedef struct fido_assert { char *rp_id; /* relying party id */ fido_blob_t cd; /* client data */ fido_blob_t cdh; /* client data hash */ fido_blob_array_t allow_list; /* list of allowed credentials */ fido_opt_t up; /* user presence */ fido_opt_t uv; /* user verification */ fido_assert_ext_t ext; /* enabled extensions */ fido_assert_stmt *stmt; /* array of expected assertions */ size_t stmt_cnt; /* number of allocated assertions */ size_t stmt_len; /* number of received assertions */ } fido_assert_t; typedef struct fido_opt_array { char **name; bool *value; size_t len; } fido_opt_array_t; typedef struct fido_str_array { char **ptr; size_t len; } fido_str_array_t; typedef struct fido_byte_array { uint8_t *ptr; size_t len; } fido_byte_array_t; typedef struct fido_algo { char *type; int cose; } fido_algo_t; typedef struct fido_algo_array { fido_algo_t *ptr; size_t len; } fido_algo_array_t; typedef struct fido_cbor_info { fido_str_array_t versions; /* supported versions: fido2|u2f */ fido_str_array_t extensions; /* list of supported extensions */ fido_str_array_t transports; /* list of supported transports */ unsigned char aaguid[16]; /* aaguid */ fido_opt_array_t options; /* list of supported options */ uint64_t maxmsgsiz; /* maximum message size */ fido_byte_array_t protocols; /* supported pin protocols */ fido_algo_array_t algorithms; /* list of supported algorithms */ uint64_t maxcredcntlst; /* max number of credentials in list */ uint64_t maxcredidlen; /* max credential ID length */ uint64_t fwversion; /* firmware version */ uint64_t maxcredbloblen; /* max credBlob length */ } fido_cbor_info_t; typedef struct fido_dev_info { char *path; /* device path */ int16_t vendor_id; /* 2-byte vendor id */ int16_t product_id; /* 2-byte product id */ char *manufacturer; /* manufacturer string */ char *product; /* product string */ fido_dev_io_t io; /* i/o functions */ fido_dev_transport_t transport; /* transport functions */ } fido_dev_info_t; PACKED_TYPE(fido_ctap_info_t, /* defined in section 8.1.9.1.3 (CTAPHID_INIT) of the fido2 ctap spec */ struct fido_ctap_info { uint64_t nonce; /* echoed nonce */ uint32_t cid; /* channel id */ uint8_t protocol; /* ctaphid protocol id */ uint8_t major; /* major version number */ uint8_t minor; /* minor version number */ uint8_t build; /* build version number */ uint8_t flags; /* capabilities flags; see FIDO_CAP_* */ }) typedef struct fido_dev { uint64_t nonce; /* issued nonce */ fido_ctap_info_t attr; /* device attributes */ uint32_t cid; /* assigned channel id */ char *path; /* device path */ void *io_handle; /* abstract i/o handle */ fido_dev_io_t io; /* i/o functions */ bool io_own; /* device has own io/transport */ size_t rx_len; /* length of HID input reports */ size_t tx_len; /* length of HID output reports */ 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 typedef struct fido_assert fido_assert_t; typedef struct fido_cbor_info fido_cbor_info_t; typedef struct fido_cred fido_cred_t; typedef struct fido_dev fido_dev_t; typedef struct fido_dev_info fido_dev_info_t; typedef struct es256_pk es256_pk_t; typedef struct es256_sk es256_sk_t; typedef struct rs256_pk rs256_pk_t; typedef struct eddsa_pk eddsa_pk_t; #endif /* _FIDO_INTERNAL */ #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* !_FIDO_TYPES_H */ diff --git a/contrib/libfido2/src/hid.c b/contrib/libfido2/src/hid.c index a3768ad3cae8..926272b6b3ed 100644 --- a/contrib/libfido2/src/hid.c +++ b/contrib/libfido2/src/hid.c @@ -1,179 +1,221 @@ /* * Copyright (c) 2018 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" static int get_key_len(uint8_t tag, uint8_t *key, size_t *key_len) { *key = tag & 0xfc; if ((*key & 0xf0) == 0xf0) { fido_log_debug("%s: *key=0x%02x", __func__, *key); return (-1); } *key_len = tag & 0x3; if (*key_len == 3) { *key_len = 4; } return (0); } static int get_key_val(const void *body, size_t key_len, uint32_t *val) { const uint8_t *ptr = body; switch (key_len) { case 0: *val = 0; break; case 1: *val = ptr[0]; break; case 2: *val = (uint32_t)((ptr[1] << 8) | ptr[0]); break; default: fido_log_debug("%s: key_len=%zu", __func__, key_len); return (-1); } return (0); } int fido_hid_get_usage(const uint8_t *report_ptr, size_t report_len, uint32_t *usage_page) { const uint8_t *ptr = report_ptr; size_t len = report_len; while (len > 0) { const uint8_t tag = ptr[0]; ptr++; len--; uint8_t key; size_t key_len; uint32_t key_val; if (get_key_len(tag, &key, &key_len) < 0 || key_len > len || get_key_val(ptr, key_len, &key_val) < 0) { return (-1); } if (key == 0x4) { *usage_page = key_val; } ptr += key_len; len -= key_len; } return (0); } int fido_hid_get_report_len(const uint8_t *report_ptr, size_t report_len, size_t *report_in_len, size_t *report_out_len) { const uint8_t *ptr = report_ptr; size_t len = report_len; uint32_t report_size = 0; while (len > 0) { const uint8_t tag = ptr[0]; ptr++; len--; uint8_t key; size_t key_len; uint32_t key_val; if (get_key_len(tag, &key, &key_len) < 0 || key_len > len || get_key_val(ptr, key_len, &key_val) < 0) { return (-1); } if (key == 0x94) { report_size = key_val; } else if (key == 0x80) { *report_in_len = (size_t)report_size; } else if (key == 0x90) { *report_out_len = (size_t)report_size; } ptr += key_len; len -= key_len; } return (0); } fido_dev_info_t * fido_dev_info_new(size_t n) { return (calloc(n, sizeof(fido_dev_info_t))); } +static void +fido_dev_info_reset(fido_dev_info_t *di) +{ + free(di->path); + free(di->manufacturer); + free(di->product); + memset(di, 0, sizeof(*di)); +} + void fido_dev_info_free(fido_dev_info_t **devlist_p, size_t n) { fido_dev_info_t *devlist; if (devlist_p == NULL || (devlist = *devlist_p) == NULL) return; - for (size_t i = 0; i < n; i++) { - const fido_dev_info_t *di; - di = &devlist[i]; - free(di->path); - free(di->manufacturer); - free(di->product); - } + for (size_t i = 0; i < n; i++) + fido_dev_info_reset(&devlist[i]); free(devlist); *devlist_p = NULL; } const fido_dev_info_t * fido_dev_info_ptr(const fido_dev_info_t *devlist, size_t i) { return (&devlist[i]); } +int +fido_dev_info_set(fido_dev_info_t *devlist, size_t i, + const char *path, const char *manufacturer, const char *product, + const fido_dev_io_t *io, const fido_dev_transport_t *transport) +{ + char *path_copy = NULL, *manu_copy = NULL, *prod_copy = NULL; + int r; + + if (path == NULL || manufacturer == NULL || product == NULL || + io == NULL) { + r = FIDO_ERR_INVALID_ARGUMENT; + goto out; + } + + if ((path_copy = strdup(path)) == NULL || + (manu_copy = strdup(manufacturer)) == NULL || + (prod_copy = strdup(product)) == NULL) { + r = FIDO_ERR_INTERNAL; + goto out; + } + + fido_dev_info_reset(&devlist[i]); + devlist[i].path = path_copy; + devlist[i].manufacturer = manu_copy; + devlist[i].product = prod_copy; + devlist[i].io = *io; + if (transport) + devlist[i].transport = *transport; + r = FIDO_OK; +out: + if (r != FIDO_OK) { + free(prod_copy); + free(manu_copy); + free(path_copy); + } + return (r); +} + const char * fido_dev_info_path(const fido_dev_info_t *di) { return (di->path); } int16_t fido_dev_info_vendor(const fido_dev_info_t *di) { return (di->vendor_id); } int16_t fido_dev_info_product(const fido_dev_info_t *di) { return (di->product_id); } const char * fido_dev_info_manufacturer_string(const fido_dev_info_t *di) { return (di->manufacturer); } const char * fido_dev_info_product_string(const fido_dev_info_t *di) { return (di->product); } diff --git a/contrib/libfido2/src/hid_osx.c b/contrib/libfido2/src/hid_osx.c index 1f8b37a65597..7f3652e39620 100644 --- a/contrib/libfido2/src/hid_osx.c +++ b/contrib/libfido2/src/hid_osx.c @@ -1,571 +1,615 @@ /* - * 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 #include #include #include #include #include #include #include #include #include #include "fido.h" #if __MAC_OS_X_VERSION_MIN_REQUIRED < 120000 #define kIOMainPortDefault kIOMasterPortDefault #endif +#define IOREG "ioreg://" + struct hid_osx { IOHIDDeviceRef ref; CFStringRef loop_id; int report_pipe[2]; size_t report_in_len; size_t report_out_len; unsigned char report[CTAP_MAX_REPORT_LEN]; }; static int get_int32(IOHIDDeviceRef dev, CFStringRef key, int32_t *v) { CFTypeRef ref; if ((ref = IOHIDDeviceGetProperty(dev, key)) == NULL || CFGetTypeID(ref) != CFNumberGetTypeID()) { fido_log_debug("%s: IOHIDDeviceGetProperty", __func__); return (-1); } if (CFNumberGetType(ref) != kCFNumberSInt32Type && CFNumberGetType(ref) != kCFNumberSInt64Type) { fido_log_debug("%s: CFNumberGetType", __func__); return (-1); } if (CFNumberGetValue(ref, kCFNumberSInt32Type, v) == false) { fido_log_debug("%s: CFNumberGetValue", __func__); return (-1); } return (0); } static int get_utf8(IOHIDDeviceRef dev, CFStringRef key, void *buf, size_t len) { CFTypeRef ref; memset(buf, 0, len); if ((ref = IOHIDDeviceGetProperty(dev, key)) == NULL || CFGetTypeID(ref) != CFStringGetTypeID()) { fido_log_debug("%s: IOHIDDeviceGetProperty", __func__); return (-1); } if (CFStringGetCString(ref, buf, (long)len, kCFStringEncodingUTF8) == false) { fido_log_debug("%s: CFStringGetCString", __func__); return (-1); } return (0); } static int get_report_len(IOHIDDeviceRef dev, int dir, size_t *report_len) { CFStringRef key; int32_t v; if (dir == 0) key = CFSTR(kIOHIDMaxInputReportSizeKey); else key = CFSTR(kIOHIDMaxOutputReportSizeKey); if (get_int32(dev, key, &v) < 0) { fido_log_debug("%s: get_int32/%d", __func__, dir); return (-1); } if ((*report_len = (size_t)v) > CTAP_MAX_REPORT_LEN) { fido_log_debug("%s: report_len=%zu", __func__, *report_len); return (-1); } return (0); } static int get_id(IOHIDDeviceRef dev, int16_t *vendor_id, int16_t *product_id) { int32_t vendor; int32_t product; if (get_int32(dev, CFSTR(kIOHIDVendorIDKey), &vendor) < 0 || vendor > UINT16_MAX) { fido_log_debug("%s: get_int32 vendor", __func__); return (-1); } if (get_int32(dev, CFSTR(kIOHIDProductIDKey), &product) < 0 || product > UINT16_MAX) { fido_log_debug("%s: get_int32 product", __func__); return (-1); } *vendor_id = (int16_t)vendor; *product_id = (int16_t)product; return (0); } static int get_str(IOHIDDeviceRef dev, char **manufacturer, char **product) { char buf[512]; int ok = -1; *manufacturer = NULL; *product = NULL; 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) *product = strdup(""); else *product = strdup(buf); if (*manufacturer == NULL || *product == NULL) { fido_log_debug("%s: strdup", __func__); goto fail; } ok = 0; fail: if (ok < 0) { free(*manufacturer); free(*product); *manufacturer = NULL; *product = NULL; } return (ok); } static char * get_path(IOHIDDeviceRef dev) { - io_service_t s; - io_string_t path; + io_service_t s; + uint64_t id; + char *path; if ((s = IOHIDDeviceGetService(dev)) == MACH_PORT_NULL) { fido_log_debug("%s: IOHIDDeviceGetService", __func__); return (NULL); } - if (IORegistryEntryGetPath(s, kIOServicePlane, path) != KERN_SUCCESS) { - fido_log_debug("%s: IORegistryEntryGetPath", __func__); + if (IORegistryEntryGetRegistryEntryID(s, &id) != KERN_SUCCESS) { + fido_log_debug("%s: IORegistryEntryGetRegistryEntryID", + __func__); + return (NULL); + } + + if (asprintf(&path, "%s%llu", IOREG, (unsigned long long)id) == -1) { + fido_log_error(errno, "%s: asprintf", __func__); return (NULL); } - return (strdup(path)); + return (path); } static bool is_fido(IOHIDDeviceRef dev) { char buf[32]; uint32_t usage_page; if (get_int32(dev, CFSTR(kIOHIDPrimaryUsagePageKey), (int32_t *)&usage_page) < 0 || usage_page != 0xf1d0) return (false); if (get_utf8(dev, CFSTR(kIOHIDTransportKey), buf, sizeof(buf)) < 0) { fido_log_debug("%s: get_utf8 transport", __func__); return (false); } #ifndef FIDO_HID_ANY if (strcasecmp(buf, "usb") != 0) { fido_log_debug("%s: transport", __func__); return (false); } #endif return (true); } static int copy_info(fido_dev_info_t *di, IOHIDDeviceRef dev) { memset(di, 0, sizeof(*di)); if (is_fido(dev) == false) return (-1); if (get_id(dev, &di->vendor_id, &di->product_id) < 0 || get_str(dev, &di->manufacturer, &di->product) < 0 || (di->path = get_path(dev)) == NULL) { free(di->path); free(di->manufacturer); free(di->product); explicit_bzero(di, sizeof(*di)); return (-1); } return (0); } int fido_hid_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen) { IOHIDManagerRef manager = NULL; CFSetRef devset = NULL; size_t devcnt; CFIndex n; IOHIDDeviceRef *devs = NULL; int r = FIDO_ERR_INTERNAL; *olen = 0; if (ilen == 0) return (FIDO_OK); /* nothing to do */ if (devlist == NULL) return (FIDO_ERR_INVALID_ARGUMENT); if ((manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDManagerOptionNone)) == NULL) { fido_log_debug("%s: IOHIDManagerCreate", __func__); goto fail; } IOHIDManagerSetDeviceMatching(manager, NULL); if ((devset = IOHIDManagerCopyDevices(manager)) == NULL) { fido_log_debug("%s: IOHIDManagerCopyDevices", __func__); goto fail; } if ((n = CFSetGetCount(devset)) < 0) { fido_log_debug("%s: CFSetGetCount", __func__); goto fail; } devcnt = (size_t)n; if ((devs = calloc(devcnt, sizeof(*devs))) == NULL) { fido_log_debug("%s: calloc", __func__); goto fail; } CFSetGetValues(devset, (void *)devs); for (size_t i = 0; i < devcnt; i++) { if (copy_info(&devlist[*olen], devs[i]) == 0) { devlist[*olen].io = (fido_dev_io_t) { fido_hid_open, fido_hid_close, fido_hid_read, fido_hid_write, }; if (++(*olen) == ilen) break; } } r = FIDO_OK; fail: if (manager != NULL) CFRelease(manager); if (devset != NULL) CFRelease(devset); free(devs); return (r); } static void report_callback(void *context, IOReturn result, void *dev, IOHIDReportType type, uint32_t id, uint8_t *ptr, CFIndex len) { struct hid_osx *ctx = context; ssize_t r; (void)dev; if (result != kIOReturnSuccess || type != kIOHIDReportTypeInput || id != 0 || len < 0 || (size_t)len != ctx->report_in_len) { fido_log_debug("%s: io error", __func__); return; } if ((r = write(ctx->report_pipe[1], ptr, (size_t)len)) == -1) { fido_log_error(errno, "%s: write", __func__); return; } if (r < 0 || (size_t)r != (size_t)len) { fido_log_debug("%s: %zd != %zu", __func__, r, (size_t)len); return; } } static void removal_callback(void *context, IOReturn result, void *sender) { (void)context; (void)result; (void)sender; CFRunLoopStop(CFRunLoopGetCurrent()); } static int set_nonblock(int fd) { int flags; if ((flags = fcntl(fd, F_GETFL)) == -1) { fido_log_error(errno, "%s: fcntl F_GETFL", __func__); return (-1); } if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { fido_log_error(errno, "%s: fcntl F_SETFL", __func__); return (-1); } return (0); } static int disable_sigpipe(int fd) { int disabled = 1; if (fcntl(fd, F_SETNOSIGPIPE, &disabled) == -1) { fido_log_error(errno, "%s: fcntl F_SETNOSIGPIPE", __func__); return (-1); } return (0); } +static int +to_uint64(const char *str, uint64_t *out) +{ + char *ep; + unsigned long long ull; + + errno = 0; + ull = strtoull(str, &ep, 10); + if (str == ep || *ep != '\0') + return (-1); + else if (ull == ULLONG_MAX && errno == ERANGE) + return (-1); + else if (ull > UINT64_MAX) + return (-1); + *out = (uint64_t)ull; + + return (0); +} + +static io_registry_entry_t +get_ioreg_entry(const char *path) +{ + uint64_t id; + + if (strncmp(path, IOREG, strlen(IOREG)) != 0) + return (IORegistryEntryFromPath(kIOMainPortDefault, path)); + + if (to_uint64(path + strlen(IOREG), &id) == -1) { + fido_log_debug("%s: to_uint64", __func__); + return (MACH_PORT_NULL); + } + + return (IOServiceGetMatchingService(kIOMainPortDefault, + IORegistryEntryIDMatching(id))); +} + void * fido_hid_open(const char *path) { struct hid_osx *ctx; io_registry_entry_t entry = MACH_PORT_NULL; char loop_id[32]; int ok = -1; int r; if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { fido_log_debug("%s: calloc", __func__); goto fail; } ctx->report_pipe[0] = -1; ctx->report_pipe[1] = -1; if (pipe(ctx->report_pipe) == -1) { fido_log_error(errno, "%s: pipe", __func__); goto fail; } if (set_nonblock(ctx->report_pipe[0]) < 0 || set_nonblock(ctx->report_pipe[1]) < 0) { fido_log_debug("%s: set_nonblock", __func__); goto fail; } if (disable_sigpipe(ctx->report_pipe[1]) < 0) { fido_log_debug("%s: disable_sigpipe", __func__); goto fail; } - if ((entry = IORegistryEntryFromPath(kIOMainPortDefault, - path)) == MACH_PORT_NULL) { - fido_log_debug("%s: IORegistryEntryFromPath", __func__); + if ((entry = get_ioreg_entry(path)) == MACH_PORT_NULL) { + fido_log_debug("%s: get_ioreg_entry: %s", __func__, path); goto fail; } if ((ctx->ref = IOHIDDeviceCreate(kCFAllocatorDefault, entry)) == NULL) { fido_log_debug("%s: IOHIDDeviceCreate", __func__); goto fail; } if (get_report_len(ctx->ref, 0, &ctx->report_in_len) < 0 || get_report_len(ctx->ref, 1, &ctx->report_out_len) < 0) { fido_log_debug("%s: get_report_len", __func__); goto fail; } if (ctx->report_in_len > sizeof(ctx->report)) { fido_log_debug("%s: report_in_len=%zu", __func__, ctx->report_in_len); goto fail; } if (IOHIDDeviceOpen(ctx->ref, kIOHIDOptionsTypeSeizeDevice) != kIOReturnSuccess) { fido_log_debug("%s: IOHIDDeviceOpen", __func__); goto fail; } if ((r = snprintf(loop_id, sizeof(loop_id), "fido2-%p", (void *)ctx->ref)) < 0 || (size_t)r >= sizeof(loop_id)) { fido_log_debug("%s: snprintf", __func__); goto fail; } if ((ctx->loop_id = CFStringCreateWithCString(NULL, loop_id, kCFStringEncodingASCII)) == NULL) { fido_log_debug("%s: CFStringCreateWithCString", __func__); goto fail; } IOHIDDeviceRegisterInputReportCallback(ctx->ref, ctx->report, (long)ctx->report_in_len, &report_callback, ctx); IOHIDDeviceRegisterRemovalCallback(ctx->ref, &removal_callback, ctx); ok = 0; fail: if (entry != MACH_PORT_NULL) IOObjectRelease(entry); if (ok < 0 && ctx != NULL) { if (ctx->ref != NULL) CFRelease(ctx->ref); if (ctx->loop_id != NULL) CFRelease(ctx->loop_id); if (ctx->report_pipe[0] != -1) close(ctx->report_pipe[0]); if (ctx->report_pipe[1] != -1) close(ctx->report_pipe[1]); free(ctx); ctx = NULL; } return (ctx); } void fido_hid_close(void *handle) { struct hid_osx *ctx = handle; IOHIDDeviceRegisterInputReportCallback(ctx->ref, ctx->report, (long)ctx->report_in_len, NULL, ctx); IOHIDDeviceRegisterRemovalCallback(ctx->ref, NULL, ctx); if (IOHIDDeviceClose(ctx->ref, kIOHIDOptionsTypeSeizeDevice) != kIOReturnSuccess) fido_log_debug("%s: IOHIDDeviceClose", __func__); CFRelease(ctx->ref); CFRelease(ctx->loop_id); explicit_bzero(ctx->report, sizeof(ctx->report)); close(ctx->report_pipe[0]); close(ctx->report_pipe[1]); free(ctx); } int fido_hid_set_sigmask(void *handle, const fido_sigset_t *sigmask) { (void)handle; (void)sigmask; return (FIDO_ERR_INTERNAL); } int fido_hid_read(void *handle, unsigned char *buf, size_t len, int ms) { struct hid_osx *ctx = handle; ssize_t r; explicit_bzero(buf, len); explicit_bzero(ctx->report, sizeof(ctx->report)); if (len != ctx->report_in_len || len > sizeof(ctx->report)) { fido_log_debug("%s: len %zu", __func__, len); return (-1); } IOHIDDeviceScheduleWithRunLoop(ctx->ref, CFRunLoopGetCurrent(), ctx->loop_id); if (ms == -1) ms = 5000; /* wait 5 seconds by default */ CFRunLoopRunInMode(ctx->loop_id, (double)ms/1000.0, true); IOHIDDeviceUnscheduleFromRunLoop(ctx->ref, CFRunLoopGetCurrent(), ctx->loop_id); if ((r = read(ctx->report_pipe[0], buf, len)) == -1) { fido_log_error(errno, "%s: read", __func__); return (-1); } if (r < 0 || (size_t)r != len) { fido_log_debug("%s: %zd != %zu", __func__, r, len); return (-1); } return ((int)len); } int fido_hid_write(void *handle, const unsigned char *buf, size_t len) { struct hid_osx *ctx = handle; if (len != ctx->report_out_len + 1 || len > LONG_MAX) { fido_log_debug("%s: len %zu", __func__, len); return (-1); } if (IOHIDDeviceSetReport(ctx->ref, kIOHIDReportTypeOutput, 0, buf + 1, (long)(len - 1)) != kIOReturnSuccess) { fido_log_debug("%s: IOHIDDeviceSetReport", __func__); return (-1); } return ((int)len); } size_t fido_hid_report_in_len(void *handle) { struct hid_osx *ctx = handle; return (ctx->report_in_len); } size_t fido_hid_report_out_len(void *handle) { struct hid_osx *ctx = handle; return (ctx->report_out_len); } diff --git a/contrib/libfido2/src/hid_win.c b/contrib/libfido2/src/hid_win.c index c29ef70253d7..fe403bcf46f1 100644 --- a/contrib/libfido2/src/hid_win.c +++ b/contrib/libfido2/src/hid_win.c @@ -1,570 +1,570 @@ /* * 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 #include #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include #include #include #include #include "fido.h" #if defined(__MINGW32__) && __MINGW64_VERSION_MAJOR < 6 WINSETUPAPI WINBOOL WINAPI SetupDiGetDevicePropertyW(HDEVINFO, PSP_DEVINFO_DATA, const DEVPROPKEY *, DEVPROPTYPE *, PBYTE, DWORD, PDWORD, DWORD); #endif #if defined(__MINGW32__) DEFINE_DEVPROPKEY(DEVPKEY_Device_Parent, 0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 8); #endif struct hid_win { HANDLE dev; OVERLAPPED overlap; int report_pending; size_t report_in_len; size_t report_out_len; unsigned char report[1 + CTAP_MAX_REPORT_LEN]; }; static bool is_fido(HANDLE dev) { PHIDP_PREPARSED_DATA data = NULL; HIDP_CAPS caps; int fido = 0; if (HidD_GetPreparsedData(dev, &data) == false) { fido_log_debug("%s: HidD_GetPreparsedData", __func__); goto fail; } if (HidP_GetCaps(data, &caps) != HIDP_STATUS_SUCCESS) { fido_log_debug("%s: HidP_GetCaps", __func__); goto fail; } fido = (uint16_t)caps.UsagePage == 0xf1d0; fail: if (data != NULL) HidD_FreePreparsedData(data); return (fido); } static int get_report_len(HANDLE dev, int dir, size_t *report_len) { PHIDP_PREPARSED_DATA data = NULL; HIDP_CAPS caps; USHORT v; int ok = -1; if (HidD_GetPreparsedData(dev, &data) == false) { fido_log_debug("%s: HidD_GetPreparsedData/%d", __func__, dir); goto fail; } if (HidP_GetCaps(data, &caps) != HIDP_STATUS_SUCCESS) { fido_log_debug("%s: HidP_GetCaps/%d", __func__, dir); goto fail; } if (dir == 0) v = caps.InputReportByteLength; else v = caps.OutputReportByteLength; if ((*report_len = (size_t)v) == 0) { fido_log_debug("%s: report_len == 0", __func__); goto fail; } ok = 0; fail: if (data != NULL) HidD_FreePreparsedData(data); return (ok); } static int get_id(HANDLE dev, int16_t *vendor_id, int16_t *product_id) { HIDD_ATTRIBUTES attr; attr.Size = sizeof(attr); if (HidD_GetAttributes(dev, &attr) == false) { fido_log_debug("%s: HidD_GetAttributes", __func__); return (-1); } *vendor_id = (int16_t)attr.VendorID; *product_id = (int16_t)attr.ProductID; return (0); } static int get_manufacturer(HANDLE dev, char **manufacturer) { wchar_t buf[512]; int utf8_len; int ok = -1; *manufacturer = NULL; if (HidD_GetManufacturerString(dev, &buf, sizeof(buf)) == false) { fido_log_debug("%s: HidD_GetManufacturerString", __func__); goto fail; } if ((utf8_len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, buf, -1, NULL, 0, NULL, NULL)) <= 0 || utf8_len > 128) { fido_log_debug("%s: WideCharToMultiByte", __func__); goto fail; } if ((*manufacturer = malloc((size_t)utf8_len)) == NULL) { fido_log_debug("%s: malloc", __func__); goto fail; } if (WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, buf, -1, *manufacturer, utf8_len, NULL, NULL) != utf8_len) { fido_log_debug("%s: WideCharToMultiByte", __func__); 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; } if ((utf8_len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, buf, -1, NULL, 0, NULL, NULL)) <= 0 || utf8_len > 128) { fido_log_debug("%s: WideCharToMultiByte", __func__); goto fail; } if ((*product = malloc((size_t)utf8_len)) == NULL) { fido_log_debug("%s: malloc", __func__); goto fail; } if (WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, buf, -1, *product, utf8_len, NULL, NULL) != utf8_len) { fido_log_debug("%s: WideCharToMultiByte", __func__); goto fail; } ok = 0; fail: if (ok < 0) { free(*product); *product = NULL; } return (ok); } static char * get_path(HDEVINFO devinfo, SP_DEVICE_INTERFACE_DATA *ifdata) { SP_DEVICE_INTERFACE_DETAIL_DATA_A *ifdetail = NULL; char *path = NULL; DWORD len = 0; /* * "Get the required buffer size. Call SetupDiGetDeviceInterfaceDetail * with a NULL DeviceInterfaceDetailData pointer, a * DeviceInterfaceDetailDataSize of zero, and a valid RequiredSize * variable. In response to such a call, this function returns the * required buffer size at RequiredSize and fails with GetLastError * returning ERROR_INSUFFICIENT_BUFFER." */ if (SetupDiGetDeviceInterfaceDetailA(devinfo, ifdata, NULL, 0, &len, NULL) != false || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { fido_log_debug("%s: SetupDiGetDeviceInterfaceDetailA 1", __func__); goto fail; } if ((ifdetail = malloc(len)) == NULL) { fido_log_debug("%s: malloc", __func__); goto fail; } ifdetail->cbSize = sizeof(*ifdetail); if (SetupDiGetDeviceInterfaceDetailA(devinfo, ifdata, ifdetail, len, NULL, NULL) == false) { fido_log_debug("%s: SetupDiGetDeviceInterfaceDetailA 2", __func__); goto fail; } if ((path = strdup(ifdetail->DevicePath)) == NULL) { fido_log_debug("%s: strdup", __func__); goto fail; } fail: free(ifdetail); return (path); } #ifndef FIDO_HID_ANY static bool hid_ok(HDEVINFO devinfo, DWORD idx) { SP_DEVINFO_DATA devinfo_data; wchar_t *parent = NULL; DWORD parent_type = DEVPROP_TYPE_STRING; DWORD len = 0; bool ok = false; memset(&devinfo_data, 0, sizeof(devinfo_data)); devinfo_data.cbSize = sizeof(devinfo_data); if (SetupDiEnumDeviceInfo(devinfo, idx, &devinfo_data) == false) { fido_log_debug("%s: SetupDiEnumDeviceInfo", __func__); goto fail; } if (SetupDiGetDevicePropertyW(devinfo, &devinfo_data, &DEVPKEY_Device_Parent, &parent_type, NULL, 0, &len, 0) != false || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { fido_log_debug("%s: SetupDiGetDevicePropertyW 1", __func__); goto fail; } if ((parent = malloc(len)) == NULL) { fido_log_debug("%s: malloc", __func__); goto fail; } if (SetupDiGetDevicePropertyW(devinfo, &devinfo_data, &DEVPKEY_Device_Parent, &parent_type, (PBYTE)parent, len, NULL, 0) == false) { fido_log_debug("%s: SetupDiGetDevicePropertyW 2", __func__); goto fail; } ok = wcsncmp(parent, L"USB\\", 4) == 0; fail: free(parent); return (ok); } #endif static int copy_info(fido_dev_info_t *di, HDEVINFO devinfo, DWORD idx, SP_DEVICE_INTERFACE_DATA *ifdata) { HANDLE dev = INVALID_HANDLE_VALUE; int ok = -1; memset(di, 0, sizeof(*di)); if ((di->path = get_path(devinfo, ifdata)) == NULL) { fido_log_debug("%s: get_path", __func__); goto fail; } fido_log_debug("%s: path=%s", __func__, di->path); #ifndef FIDO_HID_ANY if (hid_ok(devinfo, idx) == false) { fido_log_debug("%s: hid_ok", __func__); goto fail; } #endif dev = CreateFileA(di->path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (dev == INVALID_HANDLE_VALUE) { fido_log_debug("%s: CreateFileA", __func__); goto fail; } if (is_fido(dev) == false) { fido_log_debug("%s: is_fido", __func__); goto fail; } 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; } ok = 0; fail: if (dev != INVALID_HANDLE_VALUE) CloseHandle(dev); if (ok < 0) { free(di->path); free(di->manufacturer); free(di->product); explicit_bzero(di, sizeof(*di)); } return (ok); } int fido_hid_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen) { GUID hid_guid = GUID_DEVINTERFACE_HID; HDEVINFO devinfo = INVALID_HANDLE_VALUE; SP_DEVICE_INTERFACE_DATA ifdata; DWORD idx; int r = FIDO_ERR_INTERNAL; *olen = 0; if (ilen == 0) return (FIDO_OK); /* nothing to do */ if (devlist == NULL) return (FIDO_ERR_INVALID_ARGUMENT); if ((devinfo = SetupDiGetClassDevsA(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)) == INVALID_HANDLE_VALUE) { fido_log_debug("%s: SetupDiGetClassDevsA", __func__); goto fail; } ifdata.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); for (idx = 0; SetupDiEnumDeviceInterfaces(devinfo, NULL, &hid_guid, idx, &ifdata) == true; idx++) { if (copy_info(&devlist[*olen], devinfo, idx, &ifdata) == 0) { devlist[*olen].io = (fido_dev_io_t) { fido_hid_open, fido_hid_close, fido_hid_read, fido_hid_write, }; if (++(*olen) == ilen) break; } } r = FIDO_OK; fail: if (devinfo != INVALID_HANDLE_VALUE) SetupDiDestroyDeviceInfoList(devinfo); return (r); } void * fido_hid_open(const char *path) { struct hid_win *ctx; if ((ctx = calloc(1, sizeof(*ctx))) == NULL) return (NULL); ctx->dev = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (ctx->dev == INVALID_HANDLE_VALUE) { free(ctx); return (NULL); } if ((ctx->overlap.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL)) == NULL) { fido_log_debug("%s: CreateEventA", __func__); fido_hid_close(ctx); return (NULL); } if (get_report_len(ctx->dev, 0, &ctx->report_in_len) < 0 || get_report_len(ctx->dev, 1, &ctx->report_out_len) < 0) { fido_log_debug("%s: get_report_len", __func__); fido_hid_close(ctx); return (NULL); } return (ctx); } void fido_hid_close(void *handle) { struct hid_win *ctx = handle; if (ctx->overlap.hEvent != NULL) { if (ctx->report_pending) { fido_log_debug("%s: report_pending", __func__); if (CancelIoEx(ctx->dev, &ctx->overlap) == 0) fido_log_debug("%s CancelIoEx: 0x%lx", - __func__, GetLastError()); + __func__, (u_long)GetLastError()); } CloseHandle(ctx->overlap.hEvent); } explicit_bzero(ctx->report, sizeof(ctx->report)); CloseHandle(ctx->dev); free(ctx); } int fido_hid_set_sigmask(void *handle, const fido_sigset_t *sigmask) { (void)handle; (void)sigmask; return (FIDO_ERR_INTERNAL); } int fido_hid_read(void *handle, unsigned char *buf, size_t len, int ms) { struct hid_win *ctx = handle; DWORD n; if (len != ctx->report_in_len - 1 || len > sizeof(ctx->report) - 1) { fido_log_debug("%s: len %zu", __func__, len); return (-1); } if (ctx->report_pending == 0) { memset(&ctx->report, 0, sizeof(ctx->report)); ResetEvent(ctx->overlap.hEvent); if (ReadFile(ctx->dev, ctx->report, (DWORD)(len + 1), &n, &ctx->overlap) == 0 && GetLastError() != ERROR_IO_PENDING) { CancelIo(ctx->dev); fido_log_debug("%s: ReadFile", __func__); return (-1); } ctx->report_pending = 1; } if (ms > -1 && WaitForSingleObject(ctx->overlap.hEvent, (DWORD)ms) != WAIT_OBJECT_0) return (0); ctx->report_pending = 0; if (GetOverlappedResult(ctx->dev, &ctx->overlap, &n, TRUE) == 0) { fido_log_debug("%s: GetOverlappedResult", __func__); return (-1); } if (n != len + 1) { fido_log_debug("%s: expected %zu, got %zu", __func__, len + 1, (size_t)n); return (-1); } memcpy(buf, ctx->report + 1, len); explicit_bzero(ctx->report, sizeof(ctx->report)); return ((int)len); } int fido_hid_write(void *handle, const unsigned char *buf, size_t len) { struct hid_win *ctx = handle; OVERLAPPED overlap; DWORD n; memset(&overlap, 0, sizeof(overlap)); if (len != ctx->report_out_len) { fido_log_debug("%s: len %zu", __func__, len); return (-1); } if (WriteFile(ctx->dev, buf, (DWORD)len, NULL, &overlap) == 0 && GetLastError() != ERROR_IO_PENDING) { fido_log_debug("%s: WriteFile", __func__); return (-1); } if (GetOverlappedResult(ctx->dev, &overlap, &n, TRUE) == 0) { fido_log_debug("%s: GetOverlappedResult", __func__); return (-1); } if (n != len) { fido_log_debug("%s: expected %zu, got %zu", __func__, len, (size_t)n); return (-1); } return ((int)len); } size_t fido_hid_report_in_len(void *handle) { struct hid_win *ctx = handle; return (ctx->report_in_len - 1); } size_t fido_hid_report_out_len(void *handle) { struct hid_win *ctx = handle; return (ctx->report_out_len - 1); } diff --git a/contrib/libfido2/src/tpm.c b/contrib/libfido2/src/tpm.c index 74620a5e4865..74244f8cbf08 100644 --- a/contrib/libfido2/src/tpm.c +++ b/contrib/libfido2/src/tpm.c @@ -1,286 +1,390 @@ /* * 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 #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 +#define TPM_ALG_ECC 0x0023 + +/* Part 2, 6.4: TPM_ECC_CURVE */ +#define TPM_ECC_P256 0x0003 /* 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 */ +#define TPMA_SIGN 0x00040000 /* 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 name; /* sha256 of tpm_rs256_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 { +PACKED_TYPE(tpm_rs256_key_t, +struct tpm_rs256_key { uint16_t size; /* sizeof(body) */ uint8_t body[256]; }) +/* Part 2, 11.2.5.1: TPM2B_ECC_PARAMETER */ +PACKED_TYPE(tpm_es256_coord_t, +struct tpm_es256_coord { + uint16_t size; /* sizeof(body) */ + uint8_t body[32]; +}) + +/* Part 2, 11.2.5.2: TPMS_ECC_POINT */ +PACKED_TYPE(tpm_es256_point_t, +struct tpm_es256_point { + tpm_es256_coord_t x; + tpm_es256_coord_t y; +}) + /* Part 2, 12.2.3.5: TPMS_RSA_PARMS */ -PACKED_TYPE(tpm_rsa2048_param_t, -struct tpm_rsa2048_param { +PACKED_TYPE(tpm_rs256_param_t, +struct tpm_rs256_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.3.6: TPMS_ECC_PARMS */ +PACKED_TYPE(tpm_es256_param_t, +struct tpm_es256_param { + uint16_t symmetric; /* TPM_ALG_NULL */ + uint16_t scheme; /* TPM_ALG_NULL */ + uint16_t curve_id; /* TPM_ECC_P256 */ + uint16_t kdf; /* TPM_ALG_NULL */ +}) + /* Part 2, 12.2.4: TPMT_PUBLIC */ -PACKED_TYPE(tpm_rsa2048_pubarea_t, -struct tpm_rsa2048_pubarea { +PACKED_TYPE(tpm_rs256_pubarea_t, +struct tpm_rs256_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; + tpm_rs256_param_t param; + tpm_rs256_key_t key; +}) + +/* Part 2, 12.2.4: TPMT_PUBLIC */ +PACKED_TYPE(tpm_es256_pubarea_t, +struct tpm_es256_pubarea { + uint16_t alg; /* TPM_ALG_ECC */ + uint16_t hash; /* TPM_ALG_SHA256 */ + uint32_t attr; + tpm_sha256_digest_t policy; /* must be present? */ + tpm_es256_param_t param; + tpm_es256_point_t point; }) 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) +bswap_rs256_pubarea(tpm_rs256_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_es256_pubarea(tpm_es256_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.curve_id = htobe16(x->param.curve_id); + x->param.kdf = htobe16(x->param.kdf); + x->point.x.size = htobe16(x->point.x.size); + x->point.y.size = htobe16(x->point.y.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) +check_rs256_pubarea(const fido_blob_t *buf, const rs256_pk_t *pk) { - const tpm_rsa2048_pubarea_t *actual; - tpm_rsa2048_pubarea_t expected; + const tpm_rs256_pubarea_t *actual; + tpm_rs256_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); + bswap_rs256_pubarea(&expected); + + ok = timingsafe_bcmp(&expected, actual, sizeof(expected)); + explicit_bzero(&expected, sizeof(expected)); + + return ok != 0 ? -1 : 0; +} + +static int +check_es256_pubarea(const fido_blob_t *buf, const es256_pk_t *pk) +{ + const tpm_es256_pubarea_t *actual; + tpm_es256_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_ECC; + 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; /* TCG Alg. Registry, 5.2.4 */ + expected.param.curve_id = TPM_ECC_P256; + expected.param.kdf = TPM_ALG_NULL; + expected.point.x.size = sizeof(expected.point.x.body); + expected.point.y.size = sizeof(expected.point.y.body); + memcpy(&expected.point.x.body, &pk->x, sizeof(expected.point.x.body)); + memcpy(&expected.point.y.body, &pk->y, sizeof(expected.point.y.body)); + bswap_es256_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); + if (attstmt->alg != COSE_RS1) { + fido_log_debug("%s: unsupported alg %d", __func__, + attstmt->alg); return -1; } - if (check_rsa2048_pubarea(pubarea, &attcred->pubkey.rs256) < 0) { - fido_log_debug("%s: check_rsa2048_pubarea", __func__); + switch (attcred->type) { + case COSE_ES256: + if (check_es256_pubarea(pubarea, &attcred->pubkey.es256) < 0) { + fido_log_debug("%s: check_es256_pubarea", __func__); + return -1; + } + break; + case COSE_RS256: + if (check_rs256_pubarea(pubarea, &attcred->pubkey.rs256) < 0) { + fido_log_debug("%s: check_rs256_pubarea", __func__); + return -1; + } + break; + default: + fido_log_debug("%s: unsupported type %d", __func__, + attcred->type); 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/webauthn.h b/contrib/libfido2/src/webauthn.h index 5fbdd6faa927..22bf6e346a73 100644 --- a/contrib/libfido2/src/webauthn.h +++ b/contrib/libfido2/src/webauthn.h @@ -1,839 +1,917 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #ifndef __WEBAUTHN_H_ #define __WEBAUTHN_H_ #pragma once #include +#ifdef _MSC_VER #pragma region Desktop Family or OneCore Family +#endif #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 #undef INITGUID #else #include #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 +#define WEBAUTHN_API_VERSION_4 4 +// WEBAUTHN_API_VERSION_4 : Delta From WEBAUTHN_API_VERSION_3 +// Data Structures and their sub versions: +// - WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS : 5 +// - WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS : 6 +// - WEBAUTHN_ASSERTION : 3 +// + +#define WEBAUTHN_API_CURRENT_VERSION WEBAUTHN_API_VERSION_4 //+------------------------------------------------------------------------------------------ // 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; +//+------------------------------------------------------------------------------------------ +// PRF values. +//------------------------------------------------------------------------------------------- + +#define WEBAUTHN_CTAP_ONE_HMAC_SECRET_LENGTH 32 + +typedef struct _WEBAUTHN_HMAC_SECRET_SALT { + // Size of pbFirst. + DWORD cbFirst; + _Field_size_bytes_(cbFirst) + PBYTE pbFirst; // Required + + // Size of pbSecond. + DWORD cbSecond; + _Field_size_bytes_(cbSecond) + PBYTE pbSecond; +} WEBAUTHN_HMAC_SECRET_SALT, *PWEBAUTHN_HMAC_SECRET_SALT; +typedef const WEBAUTHN_HMAC_SECRET_SALT *PCWEBAUTHN_HMAC_SECRET_SALT; + +typedef struct _WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT { + // Size of pbCredID. + DWORD cbCredID; + _Field_size_bytes_(cbCredID) + PBYTE pbCredID; // Required + + // PRF Values for above credential + PWEBAUTHN_HMAC_SECRET_SALT pHmacSecretSalt; // Required +} WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT, *PWEBAUTHN_CRED_WITH_HMAC_SECRET_SALT; +typedef const WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT *PCWEBAUTHN_CRED_WITH_HMAC_SECRET_SALT; + +typedef struct _WEBAUTHN_HMAC_SECRET_SALT_VALUES { + PWEBAUTHN_HMAC_SECRET_SALT pGlobalHmacSalt; + + DWORD cCredWithHmacSecretSaltList; + _Field_size_(cCredWithHmacSecretSaltList) + PWEBAUTHN_CRED_WITH_HMAC_SECRET_SALT pCredWithHmacSecretSaltList; +} WEBAUTHN_HMAC_SECRET_SALT_VALUES, *PWEBAUTHN_HMAC_SECRET_SALT_VALUES; +typedef const WEBAUTHN_HMAC_SECRET_SALT_VALUES *PCWEBAUTHN_HMAC_SECRET_SALT_VALUES; + //+------------------------------------------------------------------------------------------ // 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 +#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_5 5 +#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_5 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. + // bRequireResidentKey isn't set to TRUE DWORD dwLargeBlobSupport; // Optional. Prefer key to be resident. Defaulting to FALSE. When TRUE, // overrides the above bRequireResidentKey. BOOL bPreferResidentKey; + // + // The following fields have been added in WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_5 + // + + // Optional. BrowserInPrivate Mode. Defaulting to FALSE. + BOOL bBrowserInPrivateMode; + } 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 +#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_6 6 +#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_6 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; + + // + // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_6 + // + + // PRF values which will be converted into HMAC-SECRET values according to WebAuthn Spec. + PWEBAUTHN_HMAC_SECRET_SALT_VALUES pHmacSecretSaltValues; + + // Optional. BrowserInPrivate Mode. Defaulting to FALSE. + BOOL bBrowserInPrivateMode; + } 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 +#define WEBAUTHN_ASSERTION_VERSION_3 3 +#define WEBAUTHN_ASSERTION_CURRENT_VERSION WEBAUTHN_ASSERTION_VERSION_3 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; + // + // Following fields have been added in WEBAUTHN_ASSERTION_VERSION_3 + // + + PWEBAUTHN_HMAC_SECRET_SALT pHmacSecret; + } 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 +#ifdef _MSC_VER #pragma endregion +#endif #endif // __WEBAUTHN_H_ diff --git a/contrib/libfido2/src/winhello.c b/contrib/libfido2/src/winhello.c index 4797ac58281e..9de6c6c9b983 100644 --- a/contrib/libfido2/src/winhello.c +++ b/contrib/libfido2/src/winhello.c @@ -1,941 +1,956 @@ /* * 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 #include #include #include "fido.h" #include "webauthn.h" +#ifndef NTE_INVALID_PARAMETER +#define NTE_INVALID_PARAMETER _HRESULT_TYPEDEF_(0x80090027) +#endif +#ifndef NTE_NOT_SUPPORTED +#define NTE_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x80090029) +#endif +#ifndef NTE_DEVICE_NOT_FOUND +#define NTE_DEVICE_NOT_FOUND _HRESULT_TYPEDEF_(0x80090035) +#endif + #define MAXCHARS 128 #define MAXCREDS 128 #define MAXMSEC 6000 * 1000 #define VENDORID 0x045e #define PRODID 0x0001 struct winhello_assert { WEBAUTHN_CLIENT_DATA cd; WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS opt; WEBAUTHN_ASSERTION *assert; wchar_t *rp_id; }; struct winhello_cred { WEBAUTHN_RP_ENTITY_INFORMATION rp; WEBAUTHN_USER_ENTITY_INFORMATION user; WEBAUTHN_COSE_CREDENTIAL_PARAMETER alg; WEBAUTHN_COSE_CREDENTIAL_PARAMETERS cose; WEBAUTHN_CLIENT_DATA cd; WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS opt; WEBAUTHN_CREDENTIAL_ATTESTATION *att; wchar_t *rp_id; wchar_t *rp_name; wchar_t *user_name; wchar_t *user_icon; 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, +typedef DWORD WINAPI webauthn_get_api_version_t(void); +typedef PCWSTR WINAPI webauthn_strerr_t(HRESULT); +typedef HRESULT WINAPI webauthn_get_assert_t(HWND, LPCWSTR, PCWEBAUTHN_CLIENT_DATA, PCWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS, PWEBAUTHN_ASSERTION *); -static TLS HRESULT (*webauthn_make_cred)(HWND, +typedef HRESULT WINAPI webauthn_make_cred_t(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); +typedef void WINAPI webauthn_free_assert_t(PWEBAUTHN_ASSERTION); +typedef void WINAPI webauthn_free_attest_t(PWEBAUTHN_CREDENTIAL_ATTESTATION); + +static TLS BOOL webauthn_loaded; +static TLS HMODULE webauthn_handle; +static TLS webauthn_get_api_version_t *webauthn_get_api_version; +static TLS webauthn_strerr_t *webauthn_strerr; +static TLS webauthn_get_assert_t *webauthn_get_assert; +static TLS webauthn_make_cred_t *webauthn_make_cred; +static TLS webauthn_free_assert_t *webauthn_free_assert; +static TLS webauthn_free_attest_t *webauthn_free_attest; static int webauthn_load(void) { + DWORD n = 1; + 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, + if ((webauthn_get_api_version = + (webauthn_get_api_version_t *)GetProcAddress(webauthn_handle, "WebAuthNGetApiVersionNumber")) == NULL) { fido_log_debug("%s: WebAuthNGetApiVersionNumber", __func__); + /* WebAuthNGetApiVersionNumber might not exist */ + } + if (webauthn_get_api_version != NULL && + (n = webauthn_get_api_version()) < 1) { + fido_log_debug("%s: unsupported api %lu", __func__, (u_long)n); goto fail; } - if ((webauthn_strerr = (void *)GetProcAddress(webauthn_handle, + fido_log_debug("%s: api version %lu", __func__, (u_long)n); + if ((webauthn_strerr = + (webauthn_strerr_t *)GetProcAddress(webauthn_handle, "WebAuthNGetErrorName")) == NULL) { fido_log_debug("%s: WebAuthNGetErrorName", __func__); goto fail; } - if ((webauthn_get_assert = (void *)GetProcAddress(webauthn_handle, + if ((webauthn_get_assert = + (webauthn_get_assert_t *)GetProcAddress(webauthn_handle, "WebAuthNAuthenticatorGetAssertion")) == NULL) { fido_log_debug("%s: WebAuthNAuthenticatorGetAssertion", __func__); goto fail; } - if ((webauthn_make_cred = (void *)GetProcAddress(webauthn_handle, + if ((webauthn_make_cred = + (webauthn_make_cred_t *)GetProcAddress(webauthn_handle, "WebAuthNAuthenticatorMakeCredential")) == NULL) { fido_log_debug("%s: WebAuthNAuthenticatorMakeCredential", __func__); goto fail; } - if ((webauthn_free_assert = (void *)GetProcAddress(webauthn_handle, + if ((webauthn_free_assert = + (webauthn_free_assert_t *)GetProcAddress(webauthn_handle, "WebAuthNFreeAssertion")) == NULL) { fido_log_debug("%s: WebAuthNFreeAssertion", __func__); goto fail; } - if ((webauthn_free_attest = (void *)GetProcAddress(webauthn_handle, + if ((webauthn_free_attest = + (webauthn_free_attest_t *)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) { int nch; wchar_t *utf16; if (utf8 == NULL) { fido_log_debug("%s: NULL", __func__); return NULL; } if ((nch = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0)) < 1 || (size_t)nch > MAXCHARS) { fido_log_debug("%s: MultiByteToWideChar %d", __func__, nch); return NULL; } if ((utf16 = calloc((size_t)nch, sizeof(*utf16))) == NULL) { fido_log_debug("%s: calloc", __func__); return NULL; } if (MultiByteToWideChar(CP_UTF8, 0, utf8, -1, utf16, nch) != nch) { fido_log_debug("%s: MultiByteToWideChar", __func__); free(utf16); return NULL; } return utf16; } -static char * -to_utf8(const wchar_t *utf16) -{ - int nch; - char *utf8; - - if (utf16 == NULL) { - fido_log_debug("%s: NULL", __func__); - return NULL; - } - if ((nch = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, utf16, - -1, NULL, 0, NULL, NULL)) < 1 || (size_t)nch > MAXCHARS) { - fido_log_debug("%s: WideCharToMultiByte %d", __func__); - return NULL; - } - if ((utf8 = calloc((size_t)nch, sizeof(*utf8))) == NULL) { - fido_log_debug("%s: calloc", __func__); - return NULL; - } - if (WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, utf16, -1, - utf8, nch, NULL, NULL) != nch) { - fido_log_debug("%s: WideCharToMultiByte", __func__); - free(utf8); - return NULL; - } - - return utf8; -} - static int to_fido(HRESULT hr) { switch (hr) { case NTE_NOT_SUPPORTED: return FIDO_ERR_UNSUPPORTED_OPTION; case NTE_INVALID_PARAMETER: return FIDO_ERR_INVALID_PARAMETER; case NTE_TOKEN_KEYSET_STORAGE_FULL: return FIDO_ERR_KEY_STORE_FULL; case NTE_DEVICE_NOT_FOUND: case NTE_NOT_FOUND: return FIDO_ERR_NOT_ALLOWED; default: - fido_log_debug("%s: hr=0x%x", __func__, hr); + fido_log_debug("%s: hr=0x%lx", __func__, (u_long)hr); return FIDO_ERR_INTERNAL; } } static int pack_cd(WEBAUTHN_CLIENT_DATA *out, const fido_blob_t *in) { if (in->ptr == NULL) { fido_log_debug("%s: NULL", __func__); return -1; } if (in->len > ULONG_MAX) { fido_log_debug("%s: in->len=%zu", __func__, in->len); return -1; } out->dwVersion = WEBAUTHN_CLIENT_DATA_CURRENT_VERSION; out->cbClientDataJSON = (DWORD)in->len; out->pbClientDataJSON = in->ptr; out->pwszHashAlgId = WEBAUTHN_HASH_ALGORITHM_SHA_256; return 0; } static int pack_credlist(WEBAUTHN_CREDENTIALS *out, const fido_blob_array_t *in) { WEBAUTHN_CREDENTIAL *c; if (in->len == 0) { return 0; /* nothing to do */ } if (in->len > MAXCREDS) { fido_log_debug("%s: in->len=%zu", __func__, in->len); return -1; } if ((out->pCredentials = calloc(in->len, sizeof(*c))) == NULL) { fido_log_debug("%s: calloc", __func__); return -1; } out->cCredentials = (DWORD)in->len; for (size_t i = 0; i < in->len; i++) { if (in->ptr[i].len > ULONG_MAX) { fido_log_debug("%s: %zu", __func__, in->ptr[i].len); return -1; } c = &out->pCredentials[i]; c->dwVersion = WEBAUTHN_CREDENTIAL_CURRENT_VERSION; c->cbId = (DWORD)in->ptr[i].len; c->pbId = in->ptr[i].ptr; c->pwszCredentialType = WEBAUTHN_CREDENTIAL_TYPE_PUBLIC_KEY; } return 0; } static int -set_uv(DWORD *out, fido_opt_t uv, const char *pin) +set_cred_uv(DWORD *out, fido_opt_t uv, const char *pin) +{ + if (pin) { + *out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED; + return 0; + } + + switch (uv) { + case FIDO_OPT_OMIT: + case FIDO_OPT_FALSE: + *out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_DISCOURAGED; + break; + case FIDO_OPT_TRUE: + *out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED; + break; + } + + return 0; +} + +static int +set_assert_uv(DWORD *out, fido_opt_t uv, const char *pin) { if (pin) { *out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED; return 0; } switch (uv) { case FIDO_OPT_OMIT: - *out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_ANY; + *out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_PREFERRED; break; case FIDO_OPT_FALSE: *out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_DISCOURAGED; break; case FIDO_OPT_TRUE: *out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED; break; } return 0; } static int pack_rp(wchar_t **id, wchar_t **name, WEBAUTHN_RP_ENTITY_INFORMATION *out, const fido_rp_t *in) { /* keep non-const copies of pwsz* for free() */ out->dwVersion = WEBAUTHN_RP_ENTITY_INFORMATION_CURRENT_VERSION; if ((out->pwszId = *id = to_utf16(in->id)) == NULL) { fido_log_debug("%s: id", __func__); return -1; } if (in->name && (out->pwszName = *name = to_utf16(in->name)) == NULL) { fido_log_debug("%s: name", __func__); return -1; } return 0; } static int pack_user(wchar_t **name, wchar_t **icon, wchar_t **display_name, 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__); return -1; } out->dwVersion = WEBAUTHN_USER_ENTITY_INFORMATION_CURRENT_VERSION; out->cbId = (DWORD)in->id.len; out->pbId = in->id.ptr; /* keep non-const copies of pwsz* for free() */ if (in->name != NULL) { if ((out->pwszName = *name = to_utf16(in->name)) == NULL) { fido_log_debug("%s: name", __func__); return -1; } } if (in->icon != NULL) { if ((out->pwszIcon = *icon = to_utf16(in->icon)) == NULL) { fido_log_debug("%s: icon", __func__); return -1; } } if (in->display_name != NULL) { if ((out->pwszDisplayName = *display_name = to_utf16(in->display_name)) == NULL) { fido_log_debug("%s: display_name", __func__); return -1; } } return 0; } static int pack_cose(WEBAUTHN_COSE_CREDENTIAL_PARAMETER *alg, WEBAUTHN_COSE_CREDENTIAL_PARAMETERS *cose, int type) { switch (type) { case COSE_ES256: alg->lAlg = WEBAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256; break; case COSE_EDDSA: alg->lAlg = -8; /* XXX */; break; case COSE_RS256: alg->lAlg = WEBAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA256; break; default: fido_log_debug("%s: type %d", __func__, type); return -1; } alg->dwVersion = WEBAUTHN_COSE_CREDENTIAL_PARAMETER_CURRENT_VERSION; alg->pwszCredentialType = WEBAUTHN_CREDENTIAL_TYPE_PUBLIC_KEY; cose->cCredentialParameters = 1; cose->pCredentialParameters = alg; return 0; } static int pack_cred_ext(WEBAUTHN_EXTENSIONS *out, const fido_cred_ext_t *in) { WEBAUTHN_EXTENSION *e; WEBAUTHN_CRED_PROTECT_EXTENSION_IN *p; BOOL *b; size_t n = 0, i = 0; if (in->mask == 0) { return 0; /* nothing to do */ } if (in->mask & ~(FIDO_EXT_HMAC_SECRET | FIDO_EXT_CRED_PROTECT)) { - fido_log_debug("%s: mask 0x%x", in->mask); + fido_log_debug("%s: mask 0x%x", __func__, in->mask); return -1; } if (in->mask & FIDO_EXT_HMAC_SECRET) n++; if (in->mask & FIDO_EXT_CRED_PROTECT) n++; if ((out->pExtensions = calloc(n, sizeof(*e))) == NULL) { fido_log_debug("%s: calloc", __func__); return -1; } out->cExtensions = (DWORD)n; if (in->mask & FIDO_EXT_HMAC_SECRET) { if ((b = calloc(1, sizeof(*b))) == NULL) { fido_log_debug("%s: calloc", __func__); return -1; } *b = true; e = &out->pExtensions[i]; e->pwszExtensionIdentifier = WEBAUTHN_EXTENSIONS_IDENTIFIER_HMAC_SECRET; e->pvExtension = b; e->cbExtension = sizeof(*b); i++; } if (in->mask & FIDO_EXT_CRED_PROTECT) { if ((p = calloc(1, sizeof(*p))) == NULL) { fido_log_debug("%s: calloc", __func__); return -1; } p->dwCredProtect = (DWORD)in->prot; p->bRequireCredProtect = true; e = &out->pExtensions[i]; e->pwszExtensionIdentifier = WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT; e->pvExtension = p; e->cbExtension = sizeof(*p); i++; } return 0; } static int unpack_assert_authdata(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) { int r; if (wa->cbAuthenticatorData > SIZE_MAX) { fido_log_debug("%s: cbAuthenticatorData", __func__); return -1; } if ((r = fido_assert_set_authdata_raw(assert, 0, wa->pbAuthenticatorData, (size_t)wa->cbAuthenticatorData)) != FIDO_OK) { fido_log_debug("%s: fido_assert_set_authdata_raw: %s", __func__, fido_strerr(r)); return -1; } return 0; } static int unpack_assert_sig(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) { int r; if (wa->cbSignature > SIZE_MAX) { fido_log_debug("%s: cbSignature", __func__); return -1; } if ((r = fido_assert_set_sig(assert, 0, wa->pbSignature, (size_t)wa->cbSignature)) != FIDO_OK) { fido_log_debug("%s: fido_assert_set_sig: %s", __func__, fido_strerr(r)); return -1; } return 0; } static int unpack_cred_id(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) { if (wa->Credential.cbId > SIZE_MAX) { fido_log_debug("%s: Credential.cbId", __func__); return -1; } if (fido_blob_set(&assert->stmt[0].id, wa->Credential.pbId, (size_t)wa->Credential.cbId) < 0) { fido_log_debug("%s: fido_blob_set", __func__); return -1; } return 0; } static int unpack_user_id(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) { if (wa->cbUserId == 0) return 0; /* user id absent */ if (wa->cbUserId > SIZE_MAX) { fido_log_debug("%s: cbUserId", __func__); return -1; } if (fido_blob_set(&assert->stmt[0].user.id, wa->pbUserId, (size_t)wa->cbUserId) < 0) { fido_log_debug("%s: fido_blob_set", __func__); return -1; } return 0; } static int translate_fido_assert(struct winhello_assert *ctx, const fido_assert_t *assert, const char *pin, int ms) { WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS *opt; /* not supported by webauthn.h */ if (assert->up == FIDO_OPT_FALSE) { fido_log_debug("%s: up %d", __func__, assert->up); return FIDO_ERR_UNSUPPORTED_OPTION; } /* not implemented */ if (assert->ext.mask) { fido_log_debug("%s: ext 0x%x", __func__, assert->ext.mask); return FIDO_ERR_UNSUPPORTED_EXTENSION; } if ((ctx->rp_id = to_utf16(assert->rp_id)) == NULL) { fido_log_debug("%s: rp_id", __func__); return FIDO_ERR_INTERNAL; } if (pack_cd(&ctx->cd, &assert->cd) < 0) { fido_log_debug("%s: pack_cd", __func__); return FIDO_ERR_INTERNAL; } /* options */ opt = &ctx->opt; opt->dwVersion = WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_1; 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; } - if (set_uv(&opt->dwUserVerificationRequirement, assert->uv, pin) < 0) { - fido_log_debug("%s: set_uv", __func__); + if (set_assert_uv(&opt->dwUserVerificationRequirement, assert->uv, + pin) < 0) { + fido_log_debug("%s: set_assert_uv", __func__); return FIDO_ERR_INTERNAL; } return FIDO_OK; } static int translate_winhello_assert(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) { int r; if (assert->stmt_len > 0) { fido_log_debug("%s: stmt_len=%zu", __func__, assert->stmt_len); return FIDO_ERR_INTERNAL; } if ((r = fido_assert_set_count(assert, 1)) != FIDO_OK) { fido_log_debug("%s: fido_assert_set_count: %s", __func__, fido_strerr(r)); return FIDO_ERR_INTERNAL; } if (unpack_assert_authdata(assert, wa) < 0) { fido_log_debug("%s: unpack_assert_authdata", __func__); return FIDO_ERR_INTERNAL; } if (unpack_assert_sig(assert, wa) < 0) { fido_log_debug("%s: unpack_assert_sig", __func__); return FIDO_ERR_INTERNAL; } if (unpack_cred_id(assert, wa) < 0) { fido_log_debug("%s: unpack_cred_id", __func__); return FIDO_ERR_INTERNAL; } if (unpack_user_id(assert, wa) < 0) { fido_log_debug("%s: unpack_user_id", __func__); return FIDO_ERR_INTERNAL; } return FIDO_OK; } static int translate_fido_cred(struct winhello_cred *ctx, const fido_cred_t *cred, const char *pin, int ms) { WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS *opt; if (pack_rp(&ctx->rp_id, &ctx->rp_name, &ctx->rp, &cred->rp) < 0) { fido_log_debug("%s: pack_rp", __func__); return FIDO_ERR_INTERNAL; } if (pack_user(&ctx->user_name, &ctx->user_icon, &ctx->display_name, &ctx->user, &cred->user) < 0) { fido_log_debug("%s: pack_user", __func__); return FIDO_ERR_INTERNAL; } if (pack_cose(&ctx->alg, &ctx->cose, cred->type) < 0) { fido_log_debug("%s: pack_cose", __func__); return FIDO_ERR_INTERNAL; } if (pack_cd(&ctx->cd, &cred->cd) < 0) { fido_log_debug("%s: pack_cd", __func__); return FIDO_ERR_INTERNAL; } /* options */ opt = &ctx->opt; opt->dwVersion = WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_1; 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; } if (pack_cred_ext(&opt->Extensions, &cred->ext) < 0) { fido_log_debug("%s: pack_cred_ext", __func__); return FIDO_ERR_UNSUPPORTED_EXTENSION; } - if (set_uv(&opt->dwUserVerificationRequirement, (cred->ext.mask & + if (set_cred_uv(&opt->dwUserVerificationRequirement, (cred->ext.mask & FIDO_EXT_CRED_PROTECT) ? FIDO_OPT_TRUE : cred->uv, pin) < 0) { - fido_log_debug("%s: set_uv", __func__); + fido_log_debug("%s: set_cred_uv", __func__); return FIDO_ERR_INTERNAL; } if (cred->rk == FIDO_OPT_TRUE) { opt->bRequireResidentKey = true; } return FIDO_OK; } static int decode_attobj(const cbor_item_t *key, const cbor_item_t *val, void *arg) { 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; } if (!strcmp(name, "fmt")) { if (cbor_decode_fmt(val, &cred->fmt) < 0) { fido_log_debug("%s: cbor_decode_fmt", __func__); goto fail; } } else if (!strcmp(name, "attStmt")) { if (cbor_decode_attstmt(val, &cred->attstmt) < 0) { fido_log_debug("%s: cbor_decode_attstmt", __func__); goto fail; } } else if (!strcmp(name, "authData")) { + if (fido_blob_decode(val, &cred->authdata_raw) < 0) { + fido_log_debug("%s: fido_blob_decode", __func__); + goto fail; + } 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; } } ok = 0; fail: free(name); return (ok); } static int -translate_winhello_cred(fido_cred_t *cred, const WEBAUTHN_CREDENTIAL_ATTESTATION *att) +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; - - 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); - - return FIDO_OK; -} - static int winhello_get_assert(HWND w, struct winhello_assert *ctx) { HRESULT hr; int r = FIDO_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__, webauthn_strerr(hr), fido_strerr(r)); } return r; } static int winhello_make_cred(HWND w, struct winhello_cred *ctx) { HRESULT hr; int r = FIDO_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__, webauthn_strerr(hr), fido_strerr(r)); } return r; } static void winhello_assert_free(struct winhello_assert *ctx) { if (ctx == NULL) return; if (ctx->assert != NULL) webauthn_free_assert(ctx->assert); free(ctx->rp_id); free(ctx->opt.CredentialList.pCredentials); free(ctx); } static void winhello_cred_free(struct winhello_cred *ctx) { if (ctx == NULL) return; if (ctx->att != NULL) webauthn_free_attest(ctx->att); free(ctx->rp_id); free(ctx->rp_name); free(ctx->user_name); free(ctx->user_icon); free(ctx->display_name); free(ctx->opt.CredentialList.pCredentials); for (size_t i = 0; i < ctx->opt.Extensions.cExtensions; i++) { WEBAUTHN_EXTENSION *e; e = &ctx->opt.Extensions.pExtensions[i]; free(e->pvExtension); } free(ctx->opt.Extensions.pExtensions); free(ctx); } int fido_winhello_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen) { - int r; fido_dev_info_t *di; if (ilen == 0) { return FIDO_OK; } if (devlist == NULL) { return FIDO_ERR_INVALID_ARGUMENT; } - if ((r = winhello_manifest()) != FIDO_OK) { - fido_log_debug("%s: winhello_manifest", __func__); - return r; + if (!webauthn_loaded && webauthn_load() < 0) { + fido_log_debug("%s: webauthn_load", __func__); + return FIDO_OK; /* not an error */ } di = &devlist[*olen]; memset(di, 0, sizeof(*di)); di->path = strdup(FIDO_WINHELLO_PATH); di->manufacturer = strdup("Microsoft Corporation"); di->product = strdup("Windows Hello"); di->vendor_id = VENDORID; di->product_id = PRODID; if (di->path == NULL || di->manufacturer == NULL || di->product == NULL) { free(di->path); free(di->manufacturer); free(di->product); explicit_bzero(di, sizeof(*di)); return FIDO_ERR_INTERNAL; } ++(*olen); return FIDO_OK; } 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; return FIDO_OK; } int fido_winhello_close(fido_dev_t *dev) { memset(dev, 0, sizeof(*dev)); return FIDO_OK; } int fido_winhello_cancel(fido_dev_t *dev) { (void)dev; return FIDO_ERR_INTERNAL; } int fido_winhello_get_assert(fido_dev_t *dev, fido_assert_t *assert, const char *pin, int ms) { HWND w; struct winhello_assert *ctx; int r = FIDO_ERR_INTERNAL; (void)dev; fido_assert_reset_rx(assert); if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { fido_log_debug("%s: calloc", __func__); goto fail; } if ((w = GetForegroundWindow()) == NULL) { fido_log_debug("%s: GetForegroundWindow", __func__); - goto fail; + if ((w = GetTopWindow(NULL)) == NULL) { + fido_log_debug("%s: GetTopWindow", __func__); + goto fail; + } } if ((r = translate_fido_assert(ctx, assert, pin, ms)) != FIDO_OK) { fido_log_debug("%s: translate_fido_assert", __func__); goto fail; } - if ((r = winhello_get_assert(w, ctx)) != S_OK) { + if ((r = winhello_get_assert(w, ctx)) != FIDO_OK) { fido_log_debug("%s: winhello_get_assert", __func__); goto fail; } if ((r = translate_winhello_assert(assert, ctx->assert)) != FIDO_OK) { fido_log_debug("%s: translate_winhello_assert", __func__); goto fail; } fail: winhello_assert_free(ctx); return r; } int fido_winhello_get_cbor_info(fido_dev_t *dev, fido_cbor_info_t *ci) { const char *v[3] = { "U2F_V2", "FIDO_2_0", "FIDO_2_1_PRE" }; const char *e[2] = { "credProtect", "hmac-secret" }; const char *t[2] = { "nfc", "usb" }; const char *o[4] = { "rk", "up", "plat", "clientPin" }; (void)dev; fido_cbor_info_reset(ci); 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 || (ci->options.value = calloc(nitems(o), sizeof(bool))) == NULL) { fido_log_debug("%s: calloc", __func__); return FIDO_ERR_INTERNAL; } for (size_t i = 0; i < nitems(o); i++) { if ((ci->options.name[i] = strdup(o[i])) == NULL) { fido_log_debug("%s: strdup", __func__); return FIDO_ERR_INTERNAL; } ci->options.value[i] = true; ci->options.len++; } return FIDO_OK; } int fido_winhello_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin, int ms) { HWND w; struct winhello_cred *ctx; int r = FIDO_ERR_INTERNAL; (void)dev; fido_cred_reset_rx(cred); if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { fido_log_debug("%s: calloc", __func__); goto fail; } if ((w = GetForegroundWindow()) == NULL) { fido_log_debug("%s: GetForegroundWindow", __func__); - goto fail; + if ((w = GetTopWindow(NULL)) == NULL) { + fido_log_debug("%s: GetTopWindow", __func__); + goto fail; + } } if ((r = translate_fido_cred(ctx, cred, pin, ms)) != FIDO_OK) { fido_log_debug("%s: translate_fido_cred", __func__); goto fail; } if ((r = winhello_make_cred(w, ctx)) != FIDO_OK) { fido_log_debug("%s: winhello_make_cred", __func__); goto fail; } if ((r = translate_winhello_cred(cred, ctx->att)) != FIDO_OK) { fido_log_debug("%s: translate_winhello_cred", __func__); goto fail; } r = FIDO_OK; fail: winhello_cred_free(ctx); return r; } diff --git a/contrib/libfido2/tools/test.sh b/contrib/libfido2/tools/test.sh index 656bff2c1596..02d82d5a18cd 100755 --- a/contrib/libfido2/tools/test.sh +++ b/contrib/libfido2/tools/test.sh @@ -1,296 +1,296 @@ #!/bin/sh -ex # 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. # usage: ./test.sh "$(mktemp -d fido2test-XXXXXXXX)" device # Please note that this test script: # - is incomplete; # - assumes CTAP 2.1-like hmac-secret; # - should pass as-is on a YubiKey with a PIN set; # - may otherwise require set +e above; # - can be executed with UV=1 to run additional UV tests; -# - was last tested on 2021-07-21 with firmware 5.2.7. +# - was last tested on 2022-01-11 with firmware 5.4.3. cd "$1" DEV="$2" make_cred() { - cat > cred_param << EOF + sed /^$/d > cred_param << EOF $(dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64) $1 some user name $(dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64) EOF fido2-cred -M $2 "${DEV}" > "$3" < cred_param } verify_cred() { fido2-cred -V $1 > cred_out < "$2" head -1 cred_out > "$3" tail -n +2 cred_out > "$4" } get_assert() { - cat > assert_param << EOF + sed /^$/d > assert_param << EOF $(dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64) $1 $(cat $3) $(cat $4) EOF fido2-assert -G $2 "${DEV}" > "$5" < assert_param } verify_assert() { fido2-assert -V $1 "$2" < "$3" } dd if=/dev/urandom bs=32 count=1 | base64 > hmac-salt # u2f make_cred no.tld "-u" u2f ! make_cred no.tld "-ru" /dev/null ! make_cred no.tld "-uc1" /dev/null ! make_cred no.tld "-uc2" /dev/null verify_cred "--" u2f u2f-cred u2f-pubkey ! verify_cred "-h" u2f /dev/null /dev/null ! verify_cred "-v" u2f /dev/null /dev/null verify_cred "-c0" u2f /dev/null /dev/null ! verify_cred "-c1" u2f /dev/null /dev/null ! verify_cred "-c2" u2f /dev/null /dev/null ! verify_cred "-c3" u2f /dev/null /dev/null # wrap (non-resident) make_cred no.tld "--" wrap verify_cred "--" wrap wrap-cred wrap-pubkey ! verify_cred "-h" wrap /dev/null /dev/null ! verify_cred "-v" wrap /dev/null /dev/null verify_cred "-c0" wrap /dev/null /dev/null ! verify_cred "-c1" wrap /dev/null /dev/null ! verify_cred "-c2" wrap /dev/null /dev/null ! verify_cred "-c3" wrap /dev/null /dev/null # wrap (non-resident) + hmac-secret make_cred no.tld "-h" wrap-hs ! verify_cred "--" wrap-hs /dev/null /dev/null verify_cred "-h" wrap-hs wrap-hs-cred wrap-hs-pubkey ! verify_cred "-v" wrap-hs /dev/null /dev/null verify_cred "-hc0" wrap-hs /dev/null /dev/null ! verify_cred "-c0" wrap-hs /dev/null /dev/null ! verify_cred "-c1" wrap-hs /dev/null /dev/null ! verify_cred "-c2" wrap-hs /dev/null /dev/null ! verify_cred "-c3" wrap-hs /dev/null /dev/null # resident make_cred no.tld "-r" rk verify_cred "--" rk rk-cred rk-pubkey ! verify_cred "-h" rk /dev/null /dev/null ! verify_cred "-v" rk /dev/null /dev/null verify_cred "-c0" rk /dev/null /dev/null ! verify_cred "-c1" rk /dev/null /dev/null ! verify_cred "-c2" rk /dev/null /dev/null ! verify_cred "-c3" rk /dev/null /dev/null # resident + hmac-secret make_cred no.tld "-hr" rk-hs ! verify_cred "--" rk-hs rk-hs-cred rk-hs-pubkey verify_cred "-h" rk-hs /dev/null /dev/null ! verify_cred "-v" rk-hs /dev/null /dev/null verify_cred "-hc0" rk-hs /dev/null /dev/null ! verify_cred "-c0" rk-hs /dev/null /dev/null ! verify_cred "-c1" rk-hs /dev/null /dev/null ! verify_cred "-c2" rk-hs /dev/null /dev/null ! verify_cred "-c3" rk-hs /dev/null /dev/null # u2f get_assert no.tld "-u" u2f-cred /dev/null u2f-assert ! get_assert no.tld "-u -t up=false" u2f-cred /dev/null /dev/null verify_assert "--" u2f-pubkey u2f-assert verify_assert "-p" u2f-pubkey u2f-assert # wrap (non-resident) get_assert no.tld "--" wrap-cred /dev/null wrap-assert verify_assert "--" wrap-pubkey wrap-assert get_assert no.tld "-t pin=true" wrap-cred /dev/null wrap-assert verify_assert "--" wrap-pubkey wrap-assert verify_assert "-v" wrap-pubkey wrap-assert get_assert no.tld "-t pin=false" wrap-cred /dev/null wrap-assert verify_assert "--" wrap-pubkey wrap-assert get_assert no.tld "-t up=true" wrap-cred /dev/null wrap-assert verify_assert "-p" wrap-pubkey wrap-assert get_assert no.tld "-t up=true -t pin=true" wrap-cred /dev/null wrap-assert verify_assert "--" wrap-pubkey wrap-assert verify_assert "-p" wrap-pubkey wrap-assert verify_assert "-v" wrap-pubkey wrap-assert verify_assert "-pv" wrap-pubkey wrap-assert get_assert no.tld "-t up=true -t pin=false" wrap-cred /dev/null wrap-assert verify_assert "--" wrap-pubkey wrap-assert verify_assert "-p" wrap-pubkey wrap-assert get_assert no.tld "-t up=false" wrap-cred /dev/null wrap-assert verify_assert "--" wrap-pubkey wrap-assert ! verify_assert "-p" wrap-pubkey wrap-assert get_assert no.tld "-t up=false -t pin=true" wrap-cred /dev/null wrap-assert ! verify_assert "-p" wrap-pubkey wrap-assert verify_assert "-v" wrap-pubkey wrap-assert ! verify_assert "-pv" wrap-pubkey wrap-assert get_assert no.tld "-t up=false -t pin=false" wrap-cred /dev/null wrap-assert ! verify_assert "-p" wrap-pubkey wrap-assert get_assert no.tld "-h" wrap-cred hmac-salt wrap-assert ! verify_assert "--" wrap-pubkey wrap-assert verify_assert "-h" wrap-pubkey wrap-assert get_assert no.tld "-h -t pin=true" wrap-cred hmac-salt wrap-assert ! verify_assert "--" wrap-pubkey wrap-assert verify_assert "-h" wrap-pubkey wrap-assert verify_assert "-hv" wrap-pubkey wrap-assert get_assert no.tld "-h -t pin=false" wrap-cred hmac-salt wrap-assert ! verify_assert "--" wrap-pubkey wrap-assert verify_assert "-h" wrap-pubkey wrap-assert get_assert no.tld "-h -t up=true" wrap-cred hmac-salt wrap-assert ! verify_assert "--" wrap-pubkey wrap-assert verify_assert "-h" wrap-pubkey wrap-assert verify_assert "-hp" wrap-pubkey wrap-assert get_assert no.tld "-h -t up=true -t pin=true" wrap-cred hmac-salt wrap-assert ! verify_assert "--" wrap-pubkey wrap-assert verify_assert "-h" wrap-pubkey wrap-assert verify_assert "-hp" wrap-pubkey wrap-assert verify_assert "-hv" wrap-pubkey wrap-assert verify_assert "-hpv" wrap-pubkey wrap-assert get_assert no.tld "-h -t up=true -t pin=false" wrap-cred hmac-salt wrap-assert ! verify_assert "--" wrap-pubkey wrap-assert verify_assert "-h" wrap-pubkey wrap-assert verify_assert "-hp" wrap-pubkey wrap-assert ! get_assert no.tld "-h -t up=false" wrap-cred hmac-salt wrap-assert ! get_assert no.tld "-h -t up=false -t pin=true" wrap-cred hmac-salt wrap-assert ! get_assert no.tld "-h -t up=false -t pin=false" wrap-cred hmac-salt wrap-assert if [ "x${UV}" != "x" ]; then get_assert no.tld "-t uv=true" wrap-cred /dev/null wrap-assert verify_assert "-v" wrap-pubkey wrap-assert get_assert no.tld "-t uv=true -t pin=true" wrap-cred /dev/null wrap-assert verify_assert "-v" wrap-pubkey wrap-assert get_assert no.tld "-t uv=true -t pin=false" wrap-cred /dev/null wrap-assert verify_assert "-v" wrap-pubkey wrap-assert get_assert no.tld "-t uv=false" wrap-cred /dev/null wrap-assert verify_assert "--" wrap-pubkey wrap-assert get_assert no.tld "-t uv=false -t pin=true" wrap-cred /dev/null wrap-assert verify_assert "-v" wrap-pubkey wrap-assert get_assert no.tld "-t uv=false -t pin=false" wrap-cred /dev/null wrap-assert verify_assert "--" wrap-pubkey wrap-assert get_assert no.tld "-t up=true -t uv=true" wrap-cred /dev/null wrap-assert verify_assert "-pv" wrap-pubkey wrap-assert get_assert no.tld "-t up=true -t uv=true -t pin=true" wrap-cred /dev/null wrap-assert verify_assert "-pv" wrap-pubkey wrap-assert get_assert no.tld "-t up=true -t uv=true -t pin=false" wrap-cred /dev/null wrap-assert verify_assert "-pv" wrap-pubkey wrap-assert get_assert no.tld "-t up=true -t uv=false" wrap-cred /dev/null wrap-assert verify_assert "-p" wrap-pubkey wrap-assert get_assert no.tld "-t up=true -t uv=false -t pin=true" wrap-cred /dev/null wrap-assert verify_assert "-pv" wrap-pubkey wrap-assert get_assert no.tld "-t up=true -t uv=false -t pin=false" wrap-cred /dev/null wrap-assert verify_assert "-p" wrap-pubkey wrap-assert get_assert no.tld "-t up=false -t uv=true" wrap-cred /dev/null wrap-assert verify_assert "-v" wrap-pubkey wrap-assert get_assert no.tld "-t up=false -t uv=true -t pin=true" wrap-cred /dev/null wrap-assert verify_assert "-v" wrap-pubkey wrap-assert get_assert no.tld "-t up=false -t uv=true -t pin=false" wrap-cred /dev/null wrap-assert verify_assert "-v" wrap-pubkey wrap-assert get_assert no.tld "-t up=false -t uv=false" wrap-cred /dev/null wrap-assert ! verify_assert "--" wrap-pubkey wrap-assert get_assert no.tld "-t up=false -t uv=false -t pin=true" wrap-cred /dev/null wrap-assert verify_assert "-v" wrap-pubkey wrap-assert get_assert no.tld "-t up=false -t uv=false -t pin=false" wrap-cred /dev/null wrap-assert ! verify_assert "--" wrap-pubkey wrap-assert get_assert no.tld "-h -t uv=true" wrap-cred hmac-salt wrap-assert verify_assert "-hv" wrap-pubkey wrap-assert get_assert no.tld "-h -t uv=true -t pin=true" wrap-cred hmac-salt wrap-assert verify_assert "-hv" wrap-pubkey wrap-assert get_assert no.tld "-h -t uv=true -t pin=false" wrap-cred hmac-salt wrap-assert verify_assert "-hv" wrap-pubkey wrap-assert get_assert no.tld "-h -t uv=false" wrap-cred hmac-salt wrap-assert verify_assert "-h" wrap-pubkey wrap-assert get_assert no.tld "-h -t uv=false -t pin=true" wrap-cred hmac-salt wrap-assert verify_assert "-hv" wrap-pubkey wrap-assert get_assert no.tld "-h -t uv=false -t pin=false" wrap-cred hmac-salt wrap-assert verify_assert "-h" wrap-pubkey wrap-assert get_assert no.tld "-h -t up=true -t uv=true" wrap-cred hmac-salt wrap-assert verify_assert "-hpv" wrap-pubkey wrap-assert get_assert no.tld "-h -t up=true -t uv=true -t pin=true" wrap-cred hmac-salt wrap-assert verify_assert "-hpv" wrap-pubkey wrap-assert get_assert no.tld "-h -t up=true -t uv=true -t pin=false" wrap-cred hmac-salt wrap-assert verify_assert "-hpv" wrap-pubkey wrap-assert get_assert no.tld "-h -t up=true -t uv=false" wrap-cred hmac-salt wrap-assert verify_assert "-hp" wrap-pubkey wrap-assert get_assert no.tld "-h -t up=true -t uv=false -t pin=true" wrap-cred hmac-salt wrap-assert verify_assert "-hpv" wrap-pubkey wrap-assert get_assert no.tld "-h -t up=true -t uv=false -t pin=false" wrap-cred hmac-salt wrap-assert verify_assert "-hp" wrap-pubkey wrap-assert ! get_assert no.tld "-h -t up=false -t uv=true" wrap-cred hmac-salt wrap-assert ! get_assert no.tld "-h -t up=false -t uv=true -t pin=true" wrap-cred hmac-salt wrap-assert ! get_assert no.tld "-h -t up=false -t uv=true -t pin=false" wrap-cred hmac-salt wrap-assert ! get_assert no.tld "-h -t up=false -t uv=false" wrap-cred hmac-salt wrap-assert ! get_assert no.tld "-h -t up=false -t uv=false -t pin=true" wrap-cred hmac-salt wrap-assert ! get_assert no.tld "-h -t up=false -t uv=false -t pin=false" wrap-cred hmac-salt wrap-assert fi # resident get_assert no.tld "-r" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t pin=true" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t pin=false" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=true" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=true -t pin=true" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=true -t pin=false" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=false" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=false -t pin=true" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=false -t pin=false" /dev/null /dev/null wrap-assert get_assert no.tld "-r -h" /dev/null hmac-salt wrap-assert get_assert no.tld "-r -h -t pin=true" /dev/null hmac-salt wrap-assert get_assert no.tld "-r -h -t pin=false" /dev/null hmac-salt wrap-assert get_assert no.tld "-r -h -t up=true" /dev/null hmac-salt wrap-assert get_assert no.tld "-r -h -t up=true -t pin=true" /dev/null hmac-salt wrap-assert get_assert no.tld "-r -h -t up=true -t pin=false" /dev/null hmac-salt wrap-assert ! get_assert no.tld "-r -h -t up=false" /dev/null hmac-salt wrap-assert ! get_assert no.tld "-r -h -t up=false -t pin=true" /dev/null hmac-salt wrap-assert ! get_assert no.tld "-r -h -t up=false -t pin=false" /dev/null hmac-salt wrap-assert if [ "x${UV}" != "x" ]; then get_assert no.tld "-r -t uv=true" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t uv=true -t pin=true" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t uv=true -t pin=false" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t uv=false" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t uv=false -t pin=true" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t uv=false -t pin=false" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=true -t uv=true" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=true -t uv=true -t pin=true" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=true -t uv=true -t pin=false" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=true -t uv=false" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=true -t uv=false -t pin=true" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=true -t uv=false -t pin=false" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=false -t uv=true" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=false -t uv=true -t pin=true" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=false -t uv=true -t pin=false" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=false -t uv=false" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=false -t uv=false -t pin=true" /dev/null /dev/null wrap-assert get_assert no.tld "-r -t up=false -t uv=false -t pin=false" /dev/null /dev/null wrap-assert get_assert no.tld "-r -h -t uv=true" /dev/null hmac-salt wrap-assert get_assert no.tld "-r -h -t uv=true -t pin=true" /dev/null hmac-salt wrap-assert get_assert no.tld "-r -h -t uv=true -t pin=false" /dev/null hmac-salt wrap-assert get_assert no.tld "-r -h -t uv=false" /dev/null hmac-salt wrap-assert get_assert no.tld "-r -h -t uv=false -t pin=true" /dev/null hmac-salt wrap-assert get_assert no.tld "-r -h -t uv=false -t pin=false" /dev/null hmac-salt wrap-assert get_assert no.tld "-r -h -t up=true -t uv=true" /dev/null hmac-salt wrap-assert get_assert no.tld "-r -h -t up=true -t uv=true -t pin=true" /dev/null hmac-salt wrap-assert get_assert no.tld "-r -h -t up=true -t uv=true -t pin=false" /dev/null hmac-salt wrap-assert get_assert no.tld "-r -h -t up=true -t uv=false" /dev/null hmac-salt wrap-assert get_assert no.tld "-r -h -t up=true -t uv=false -t pin=true" /dev/null hmac-salt wrap-assert get_assert no.tld "-r -h -t up=true -t uv=false -t pin=false" /dev/null hmac-salt wrap-assert ! get_assert no.tld "-r -h -t up=false -t uv=true" /dev/null hmac-salt wrap-assert ! get_assert no.tld "-r -h -t up=false -t uv=true -t pin=true" /dev/null hmac-salt wrap-assert ! get_assert no.tld "-r -h -t up=false -t uv=true -t pin=false" /dev/null hmac-salt wrap-assert ! get_assert no.tld "-r -h -t up=false -t uv=false" /dev/null hmac-salt wrap-assert ! get_assert no.tld "-r -h -t up=false -t uv=false -t pin=true" /dev/null hmac-salt wrap-assert ! get_assert no.tld "-r -h -t up=false -t uv=false -t pin=false" /dev/null hmac-salt wrap-assert fi exit 0 diff --git a/contrib/libfido2/windows/build.ps1 b/contrib/libfido2/windows/build.ps1 index 87d0c31e5311..56302444c80b 100644 --- a/contrib/libfido2/windows/build.ps1 +++ b/contrib/libfido2/windows/build.ps1 @@ -1,240 +1,240 @@ # 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 = "Stop" [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 . "$PSScriptRoot\const.ps1" Function ExitOnError() { if ($LastExitCode -ne 0) { throw "A command exited with status $LastExitCode" } } 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 } # 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 = $CMakePath } 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 = $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 = $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))) { $CMAKE_SYSTEM_VERSION = "-DCMAKE_SYSTEM_VERSION='$WinSDK'" } else { $CMAKE_SYSTEM_VERSION = '' } 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" # 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 # 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 (-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 } if (-Not (Test-Path .\${LIBCBOR})) { GitClone "${LIBCBOR_GIT}" "${LIBCBOR_BRANCH}" ".\${LIBCBOR}" } if (-Not (Test-Path .\${ZLIB})) { GitClone "${ZLIB_GIT}" "${ZLIB_BRANCH}" ".\${ZLIB}" } } catch { throw "Failed to fetch and verify dependencies" } finally { Pop-Location } # 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 } # 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 } # 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 } } } catch { throw "Failed to build zlib" } finally { Pop-Location } # 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" | ` + "cbor.dll", "crypto-47.dll", "zlib1.dll" | ` %{ Copy-Item "${PREFIX}\bin\$_" ` -Destination "examples\${Config}" } } } catch { throw "Failed to build libfido2" } finally { Pop-Location } diff --git a/contrib/libfido2/windows/const.ps1 b/contrib/libfido2/windows/const.ps1 index 6d2a8189d362..4aac8bb2853e 100644 --- a/contrib/libfido2/windows/const.ps1 +++ b/contrib/libfido2/windows/const.ps1 @@ -1,42 +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 +New-Variable -Name 'LIBRESSL' -Value 'libressl-3.4.2' -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' -Value 'libcbor-0.9.0' -Option Constant +New-Variable -Name 'LIBCBOR_BRANCH' -Value 'v0.9.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/cygwin.gpg b/contrib/libfido2/windows/cygwin.gpg new file mode 100755 index 000000000000..1e87237a6e03 Binary files /dev/null and b/contrib/libfido2/windows/cygwin.gpg differ diff --git a/contrib/libfido2/windows/cygwin.ps1 b/contrib/libfido2/windows/cygwin.ps1 new file mode 100755 index 000000000000..aada60b6f06f --- /dev/null +++ b/contrib/libfido2/windows/cygwin.ps1 @@ -0,0 +1,68 @@ +# 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]$GPGPath = "C:\Program Files (x86)\GnuPG\bin\gpg.exe", + [string]$Config = "Release" +) + +$ErrorActionPreference = "Stop" +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + +# Cygwin coordinates. +$URL = 'https://www.cygwin.com' +$Setup = 'setup-x86_64.exe' +$Mirror = 'https://mirrors.kernel.org/sourceware/cygwin/' +$Packages = 'gcc-core,pkg-config,cmake,make,libcbor-devel,libssl-devel,zlib-devel' + +# Work directories. +$Cygwin = "$PSScriptRoot\..\cygwin" +$Root = "${Cygwin}\root" + +# Find 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" +} + +Write-Host "Config: $Config" +Write-Host "GPG: $GPG" + +# Create work directories. +New-Item -Type Directory "${Cygwin}" -Force +New-Item -Type Directory "${Root}" -Force + +# Fetch and verify Cygwin. +try { + if (-Not (Test-Path ${Cygwin}\${Setup} -PathType leaf)) { + Invoke-WebRequest ${URL}/${Setup} ` + -OutFile ${Cygwin}\${Setup} + } + if (-Not (Test-Path ${Cygwin}\${Setup}.sig -PathType leaf)) { + Invoke-WebRequest ${URL}/${Setup}.sig ` + -OutFile ${Cygwin}\${Setup}.sig + } + & $GPG --list-keys + & $GPG --quiet --no-default-keyring ` + --keyring ${PSScriptRoot}/cygwin.gpg ` + --verify ${Cygwin}\${Setup}.sig ${Cygwin}\${Setup} + if ($LastExitCode -ne 0) { + throw "GPG signature verification failed" + } +} catch { + throw "Failed to fetch and verify Cygwin" +} + +# Bootstrap Cygwin. +Start-Process "${Cygwin}\${Setup}" -Wait -NoNewWindow ` + -ArgumentList "-dnNOqW -s ${Mirror} -R ${Root} -P ${Packages}" + +# Build libfido2. +$Env:PATH = "${Root}\bin\;" + $Env:PATH +cmake "-DCMAKE_BUILD_TYPE=${Config}" -B "build-${Config}" +make -C "build-${Config}" diff --git a/contrib/libfido2/windows/release.ps1 b/contrib/libfido2/windows/release.ps1 index 32e88e256274..9221bcaa3413 100644 --- a/contrib/libfido2/windows/release.ps1 +++ b/contrib/libfido2/windows/release.ps1 @@ -1,84 +1,97 @@ # 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' +$LibCrypto = '47' +$SDK = '143' . "$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" ` + Copy-Item "${SRC}\${LIBRESSL}\crypto\crypto_obj.dir\${Config}\crypto_obj.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-StaticPDBs(${SRC}, ${DEST}) { + Copy-Item "${SRC}\${LIBRESSL}\crypto\Release\crypto-${LibCrypto}.pdb" ` + "${DEST}\crypto-${LibCrypto}.pdb" + Copy-Item "${SRC}\${LIBCBOR}\src\Release\cbor.pdb" ` + "${DEST}\cbor.pdb" + Copy-Item "${SRC}\${ZLIB}\Release\zlibstatic.pdb" ` + "${DEST}\zlib.pdb" + Copy-Item "${SRC}\src\Release\fido2_static.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" + Package-StaticPDBs "${BUILD}\${Arch}\static" ` + "${OUTPUT}\pkg\${InstallPrefix}\${Config}\v${SDK}\static" } diff --git a/lib/libfido2/Makefile b/lib/libfido2/Makefile index 9a0e4a57bd9a..a9e1c526d45d 100644 --- a/lib/libfido2/Makefile +++ b/lib/libfido2/Makefile @@ -1,77 +1,77 @@ PACKAGE=ssh LIB= fido2 PRIVATELIB= DIST= ${SRCTOP}/contrib/libfido2 .PATH: ${DIST}/src ${DIST} SRCS+= aes256.c SRCS+= assert.c SRCS+= authkey.c SRCS+= bio.c SRCS+= blob.c SRCS+= buf.c SRCS+= cbor.c SRCS+= compress.c SRCS+= config.c SRCS+= cred.c SRCS+= credman.c SRCS+= dev.c SRCS+= ecdh.c SRCS+= eddsa.c SRCS+= err.c SRCS+= es256.c SRCS+= hid_freebsd.c SRCS+= hid_unix.c SRCS+= hid.c SRCS+= info.c SRCS+= io.c SRCS+= iso7816.c SRCS+= largeblob.c 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 SRCS+= openbsd-compat/recallocarray.c CFLAGS+= -I ${DIST}/src -I${SRCTOP}/contrib/libcbor/src -I${.CURDIR}/../libcbor CFLAGS+= -D_FIDO_INTERNAL CFLAGS+= -DHAVE_ARC4RANDOM_BUF CFLAGS+= -DHAVE_CLOCK_GETTIME CFLAGS+= -DHAVE_DEV_URANDOM CFLAGS+= -DHAVE_ERR_H CFLAGS+= -DHAVE_EXPLICIT_BZERO CFLAGS+= -DHAVE_GETLINE CFLAGS+= -DHAVE_GETOPT CFLAGS+= -DHAVE_GETPAGESIZE CFLAGS+= -DHAVE_GETRANDOM CFLAGS+= -DHAVE_OPENSSLV_H CFLAGS+= -DHAVE_READPASSPHRASE CFLAGS+= -DHAVE_SIGNAL_H CFLAGS+= -DHAVE_STRLCAT CFLAGS+= -DHAVE_STRLCPY CFLAGS+= -DHAVE_STRSEP CFLAGS+= -DHAVE_SYSCONF CFLAGS+= -DHAVE_SYS_RANDOM_H CFLAGS+= -DHAVE_TIMESPECSUB CFLAGS+= -DHAVE_TIMINGSAFE_BCMP CFLAGS+= -DHAVE_UNISTD_H CFLAGS+= -DTLS=__thread CFLAGS+= -D_FIDO_MAJOR=1 -CFLAGS+= -D_FIDO_MINOR=9 +CFLAGS+= -D_FIDO_MINOR=10 CFLAGS+= -D_FIDO_PATCH=0 LIBADD= crypto z WARNS=2 MAN= .include