diff options
70 files changed, 1638 insertions, 373 deletions
| diff --git a/CMakeLists.txt b/CMakeLists.txt index d775a98c5b48..11a51ac5a645 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ 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) @@ -21,14 +21,14 @@ 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}) @@ -40,16 +40,15 @@ 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) @@ -68,12 +67,13 @@ if(NOT MSVC)  		set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_DARWIN_C_SOURCE")  		set(FIDO_CFLAGS "${FIDO_CFLAGS} -D__STDC_WANT_LIB_EXT1__=1")  	elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") -		set(NFC_LINUX 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}") @@ -167,12 +167,13 @@ if(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; @@ -188,8 +189,10 @@ if(MSVC)  	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) @@ -223,6 +226,8 @@ else()  				set(BASE_LIBRARIES ${BASE_LIBRARIES} rt)  			endif()  		endif() +	else() +		set(NFC_LINUX OFF)  	endif()  	if(MINGW) @@ -238,14 +243,18 @@ else()  		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) @@ -257,6 +266,10 @@ else()  	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() @@ -306,10 +319,10 @@ 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 @@ -1,4 +1,4 @@ -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 @@ -1,3 +1,17 @@ +* 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. diff --git a/README.adoc b/README.adoc index a0e188bf8774..114cc5eed762 100644 --- a/README.adoc +++ b/README.adoc @@ -10,7 +10,7 @@ image:https://oss-fuzz-build-logs.storage.googleapis.com/badges/libfido2.svg["Fu  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. @@ -42,7 +42,7 @@ is also available.  ==== 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. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000000..e12a48a847ba --- /dev/null +++ b/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/examples/README.adoc b/examples/README.adoc index bcecb22f5258..44ee52743a0d 100644 --- a/examples/README.adoc +++ b/examples/README.adoc @@ -25,7 +25,7 @@ The following definitions are used in the description below:  - <blobkey> -	A credential's associated FIDO 2.1 "largeBlob" symmetric key. +	A credential's associated CTAP 2.1 "largeBlob" symmetric key.  === Description diff --git a/fuzz/Dockerfile b/fuzz/Dockerfile index f175991d0462..aefe1980ada4 100644 --- a/fuzz/Dockerfile +++ b/fuzz/Dockerfile @@ -7,6 +7,6 @@ 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/fuzz/Makefile b/fuzz/Makefile index 1a974a2bf557..ce3fee73c69c 100644 --- a/fuzz/Makefile +++ b/fuzz/Makefile @@ -2,7 +2,7 @@  # 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 diff --git a/fuzz/export.gnu b/fuzz/export.gnu index 0c712b30a429..cac142ae970e 100644 --- a/fuzz/export.gnu +++ b/fuzz/export.gnu @@ -201,6 +201,7 @@  		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; diff --git a/fuzz/functions.txt b/fuzz/functions.txt index 886893b1d11d..946682d07d00 100644 --- a/fuzz/functions.txt +++ b/fuzz/functions.txt @@ -172,7 +172,7 @@ cbor_array_iter                             12       0 100.00%        16       0  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% @@ -200,7 +200,7 @@ cbor_decode_uint64                           4       0 100.00%         8       0  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% @@ -209,7 +209,7 @@ cbor.c:cbor_add_arg                         13       0 100.00%        21       0  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% @@ -222,7 +222,7 @@ cbor.c:decode_cred_id_entry                 10       0 100.00%        19       0  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 @@ -386,6 +386,7 @@ fido_dev_get_touch_begin                     50       0 100.00%        59  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% @@ -419,7 +420,7 @@ dev.c:fido_dev_set_extension_flags            7       0 100.00%         7  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 @@ -493,8 +494,9 @@ Name                                    Regions    Miss   Cover     Lines    Mis  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% @@ -502,8 +504,9 @@ fido_dev_info_manufacturer_string             1       0 100.00%         3  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 @@ -612,7 +615,7 @@ 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% @@ -642,7 +645,7 @@ largeblob.c:largeblob_get_uv_token           19       0 100.00%        23  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 @@ -783,11 +786,11 @@ TOTAL                                          24       0 100.00%        23  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 @@ -820,15 +823,17 @@ TOTAL                                          43       3  93.02%        43  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 diff --git a/fuzz/fuzz_hid.c b/fuzz/fuzz_hid.c index 556e62ac4cd3..eaf00dc92de8 100644 --- a/fuzz/fuzz_hid.c +++ b/fuzz/fuzz_hid.c @@ -175,15 +175,20 @@ 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++) { @@ -195,9 +200,13 @@ manifest(const struct param *p)  		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 diff --git a/fuzz/report.tgz b/fuzz/report.tgzBinary files differ index cf74f315cb80..d78f4628de59 100644 --- a/fuzz/report.tgz +++ b/fuzz/report.tgz diff --git a/fuzz/summary.txt b/fuzz/summary.txt index 298c8377379f..05c000aa7757 100644 --- a/fuzz/summary.txt +++ b/fuzz/summary.txt @@ -16,33 +16,33 @@ src/authkey.c                             44                 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% @@ -54,4 +54,4 @@ src/fido.h                                 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/man/CMakeLists.txt b/man/CMakeLists.txt index 3e50c50d37a0..5ce2fc7b83ed 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -44,6 +44,7 @@ list(APPEND MAN_SOURCES  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 @@ -75,6 +76,7 @@ list(APPEND MAN_ALIAS  	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 @@ -117,8 +119,8 @@ list(APPEND MAN_ALIAS  	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 @@ -163,6 +165,7 @@ list(APPEND MAN_ALIAS  	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 @@ -211,6 +214,7 @@ list(APPEND MAN_ALIAS  	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 @@ -219,26 +223,33 @@ list(APPEND MAN_ALIAS  	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 diff --git a/man/check.sh b/man/check.sh new file mode 100755 index 000000000000..951afeb88e0b --- /dev/null +++ b/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/man/eddsa_pk_new.3 b/man/eddsa_pk_new.3 index 65bf9a9f753d..998def484790 100644 --- a/man/eddsa_pk_new.3 +++ b/man/eddsa_pk_new.3 @@ -11,7 +11,7 @@  .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 @@ -106,7 +106,7 @@ If an error occurs,  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 diff --git a/man/es256_pk_new.3 b/man/es256_pk_new.3 index 6c1bac0f57f9..5e184340a575 100644 --- a/man/es256_pk_new.3 +++ b/man/es256_pk_new.3 @@ -9,10 +9,10 @@  .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 @@ -82,7 +82,7 @@ No references to  are kept.  .Pp  The -.Fn es256_pk_from_EVP_KEY +.Fn es256_pk_from_EVP_PKEY  function fills  .Fa pk  with the contents of @@ -124,7 +124,7 @@ 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 diff --git a/man/fido2-assert.1 b/man/fido2-assert.1 index da47d6f19dd3..ee8135c18483 100644 --- a/man/fido2-assert.1 +++ b/man/fido2-assert.1 @@ -7,7 +7,7 @@  .Os  .Sh NAME  .Nm fido2-assert -.Nd get/verify a FIDO 2 assertion +.Nd get/verify a FIDO2 assertion  .Sh SYNOPSIS  .Nm  .Fl G @@ -24,7 +24,7 @@  .Op Ar type  .Sh DESCRIPTION  .Nm -gets or verifies a FIDO 2 assertion. +gets or verifies a FIDO2 assertion.  .Pp  The input of  .Nm @@ -117,7 +117,7 @@ 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 , diff --git a/man/fido2-cred.1 b/man/fido2-cred.1 index 301564d688e5..0b10e74a0507 100644 --- a/man/fido2-cred.1 +++ b/man/fido2-cred.1 @@ -7,7 +7,7 @@  .Os  .Sh NAME  .Nm fido2-cred -.Nd make/verify a FIDO 2 credential +.Nd make/verify a FIDO2 credential  .Sh SYNOPSIS  .Nm  .Fl M @@ -26,7 +26,7 @@  .Op Ar type  .Sh DESCRIPTION  .Nm -makes or verifies a FIDO 2 credential. +makes or verifies a FIDO2 credential.  .Pp  A credential  .Ar type @@ -143,7 +143,7 @@ will fail.  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, diff --git a/man/fido2-token.1 b/man/fido2-token.1 index fd82c23cffb7..1aa2feb86859 100644 --- a/man/fido2-token.1 +++ b/man/fido2-token.1 @@ -7,7 +7,7 @@  .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 @@ -121,7 +121,7 @@  .Fl V  .Sh DESCRIPTION  .Nm -manages a FIDO 2 authenticator. +manages a FIDO2 authenticator.  .Pp  The options are as follows:  .Bl -tag -width Ds @@ -176,12 +176,12 @@ where  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 @@ -194,7 +194,7 @@ 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 @@ -234,7 +234,7 @@ 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 . @@ -264,12 +264,12 @@ 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 @@ -284,7 +284,7 @@ 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 @@ -353,7 +353,7 @@ the minimum PIN length of  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 . @@ -392,9 +392,9 @@ 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/man/fido_assert_allow_cred.3 b/man/fido_assert_allow_cred.3 index bbe6e4d8929a..7fd730c3f63c 100644 --- a/man/fido_assert_allow_cred.3 +++ b/man/fido_assert_allow_cred.3 @@ -7,7 +7,7 @@  .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 @@ -31,7 +31,7 @@ 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 diff --git a/man/fido_assert_new.3 b/man/fido_assert_new.3 index 16f4e3a6e46d..a1a3c101ba33 100644 --- a/man/fido_assert_new.3 +++ b/man/fido_assert_new.3 @@ -31,7 +31,7 @@  .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 * @@ -85,9 +85,12 @@  .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 @@ -153,47 +156,61 @@ 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 @@ -202,31 +219,27 @@ has an  (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 diff --git a/man/fido_assert_set_authdata.3 b/man/fido_assert_set_authdata.3 index 2f2ca5b45d6e..51cdcc97c292 100644 --- a/man/fido_assert_set_authdata.3 +++ b/man/fido_assert_set_authdata.3 @@ -18,7 +18,7 @@  .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 @@ -29,9 +29,9 @@ typedef enum {  } 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 @@ -43,7 +43,7 @@ typedef enum {  .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 @@ -55,14 +55,14 @@ typedef enum {  .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 @@ -106,11 +106,8 @@ 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 , @@ -167,6 +164,29 @@ is zero, the extensions of  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 @@ -184,27 +204,22 @@ by default, allowing the authenticator to use its default settings.  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 diff --git a/man/fido_assert_verify.3 b/man/fido_assert_verify.3 index 82e64e12e27a..8c0823703434 100644 --- a/man/fido_assert_verify.3 +++ b/man/fido_assert_verify.3 @@ -7,11 +7,11 @@  .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 @@ -23,7 +23,7 @@ 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: diff --git a/man/fido_bio_dev_get_info.3 b/man/fido_bio_dev_get_info.3 index 1fe3e8ebc18f..7f1696fc12a4 100644 --- a/man/fido_bio_dev_get_info.3 +++ b/man/fido_bio_dev_get_info.3 @@ -13,7 +13,7 @@  .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 diff --git a/man/fido_bio_enroll_new.3 b/man/fido_bio_enroll_new.3 index 3db3e7acd45d..37b842e644fd 100644 --- a/man/fido_bio_enroll_new.3 +++ b/man/fido_bio_enroll_new.3 @@ -10,7 +10,7 @@  .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 @@ -40,7 +40,7 @@  .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 diff --git a/man/fido_bio_info_new.3 b/man/fido_bio_info_new.3 index c82733337b4e..a7435fd615e7 100644 --- a/man/fido_bio_info_new.3 +++ b/man/fido_bio_info_new.3 @@ -10,7 +10,7 @@  .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 diff --git a/man/fido_bio_template.3 b/man/fido_bio_template.3 index 12a379e9a46a..232f3ead2ab3 100644 --- a/man/fido_bio_template.3 +++ b/man/fido_bio_template.3 @@ -17,7 +17,7 @@  .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 @@ -44,7 +44,7 @@  .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 diff --git a/man/fido_cbor_info_new.3 b/man/fido_cbor_info_new.3 index ecba77291f53..86f2a887f99a 100644 --- a/man/fido_cbor_info_new.3 +++ b/man/fido_cbor_info_new.3 @@ -26,10 +26,11 @@  .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 * diff --git a/man/fido_cred_exclude.3 b/man/fido_cred_exclude.3 index 700d6afd8746..2aa87f28976f 100644 --- a/man/fido_cred_exclude.3 +++ b/man/fido_cred_exclude.3 @@ -44,7 +44,7 @@ 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 diff --git a/man/fido_cred_new.3 b/man/fido_cred_new.3 index d779cb2c659d..ee7ac96a6b0b 100644 --- a/man/fido_cred_new.3 +++ b/man/fido_cred_new.3 @@ -40,7 +40,7 @@  .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 * @@ -112,7 +112,7 @@  .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 @@ -155,7 +155,7 @@ 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 , @@ -170,7 +170,7 @@ 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 , @@ -243,7 +243,7 @@ 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 diff --git a/man/fido_cred_set_authdata.3 b/man/fido_cred_set_authdata.3 index 7bae51f43674..921a682f8f91 100644 --- a/man/fido_cred_set_authdata.3 +++ b/man/fido_cred_set_authdata.3 @@ -24,7 +24,7 @@  .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 @@ -73,14 +73,14 @@ typedef enum {  .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 @@ -229,7 +229,7 @@ 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 @@ -249,7 +249,7 @@ extension is disabled on  .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 @@ -325,15 +325,15 @@ Note that not all authenticators support COSE_RS256 or COSE_EDDSA.  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 diff --git a/man/fido_cred_verify.3 b/man/fido_cred_verify.3 index ec95e134572e..696dec293e4d 100644 --- a/man/fido_cred_verify.3 +++ b/man/fido_cred_verify.3 @@ -6,26 +6,31 @@  .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, @@ -48,19 +53,36 @@ 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. diff --git a/man/fido_credman_metadata_new.3 b/man/fido_credman_metadata_new.3 index 31f240fbbe8c..cd6722e24aa8 100644 --- a/man/fido_credman_metadata_new.3 +++ b/man/fido_credman_metadata_new.3 @@ -26,7 +26,7 @@  .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 @@ -307,7 +307,7 @@ The  .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. @@ -323,4 +323,4 @@ should have their return values checked for NULL.  .Sh CAVEATS  Resident credentials are called  .Dq discoverable credentials -in FIDO 2.1. +in CTAP 2.1. diff --git a/man/fido_dev_enable_entattest.3 b/man/fido_dev_enable_entattest.3 index 17962d3d35d5..bfc1b2834e55 100644 --- a/man/fido_dev_enable_entattest.3 +++ b/man/fido_dev_enable_entattest.3 @@ -11,7 +11,7 @@  .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 @@ -27,7 +27,7 @@  .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 @@ -86,7 +86,7 @@ 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 diff --git a/man/fido_dev_get_assert.3 b/man/fido_dev_get_assert.3 index 2e33fc516e7d..bc67e441cca3 100644 --- a/man/fido_dev_get_assert.3 +++ b/man/fido_dev_get_assert.3 @@ -7,15 +7,15 @@  .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 : diff --git a/man/fido_dev_get_touch_begin.3 b/man/fido_dev_get_touch_begin.3 index 8372c6ff010b..f3b8335cec12 100644 --- a/man/fido_dev_get_touch_begin.3 +++ b/man/fido_dev_get_touch_begin.3 @@ -8,7 +8,7 @@  .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 @@ -17,7 +17,7 @@  .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 diff --git a/man/fido_dev_info_manifest.3 b/man/fido_dev_info_manifest.3 index 76e399cec319..9539a0dda7c5 100644 --- a/man/fido_dev_info_manifest.3 +++ b/man/fido_dev_info_manifest.3 @@ -14,8 +14,9 @@  .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 @@ -36,6 +37,8 @@  .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 @@ -43,7 +46,7 @@ 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 , @@ -133,6 +136,30 @@ 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 @@ -142,6 +169,14 @@ 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 , diff --git a/man/fido_dev_largeblob_get.3 b/man/fido_dev_largeblob_get.3 index 830534ed0e7b..c42208158c5e 100644 --- a/man/fido_dev_largeblob_get.3 +++ b/man/fido_dev_largeblob_get.3 @@ -11,7 +11,7 @@  .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 @@ -29,10 +29,10 @@ 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. @@ -58,9 +58,9 @@ 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 diff --git a/man/fido_dev_make_cred.3 b/man/fido_dev_make_cred.3 index cd156dc94f89..60b77fb9c010 100644 --- a/man/fido_dev_make_cred.3 +++ b/man/fido_dev_make_cred.3 @@ -7,15 +7,15 @@  .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 diff --git a/man/fido_dev_open.3 b/man/fido_dev_open.3 index f2af7817d801..cdb148fe8b16 100644 --- a/man/fido_dev_open.3 +++ b/man/fido_dev_open.3 @@ -7,9 +7,11 @@  .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 , @@ -17,26 +19,31 @@  .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 @@ -52,12 +59,14 @@  .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" @@ -92,6 +101,13 @@ 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 . @@ -113,6 +129,18 @@ function returns a pointer to a newly allocated, empty  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 , @@ -134,12 +162,18 @@ is a NOP.  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 @@ -147,7 +181,7 @@ function returns  .Dv true  if  .Fa dev -is a FIDO 2 device. +is a FIDO2 device.  .Pp  The  .Fn fido_dev_is_winhello @@ -163,7 +197,7 @@ 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 @@ -171,23 +205,23 @@ 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 @@ -198,6 +232,14 @@ if  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 @@ -236,7 +278,8 @@ 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 diff --git a/man/fido_dev_set_io_functions.3 b/man/fido_dev_set_io_functions.3 index 52081f126e78..8c2067c41f66 100644 --- a/man/fido_dev_set_io_functions.3 +++ b/man/fido_dev_set_io_functions.3 @@ -8,8 +8,10 @@  .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 @@ -30,13 +32,28 @@ 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 @@ -148,9 +165,59 @@ 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 @@ -159,3 +226,13 @@ return  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/man/fido_dev_set_pin.3 b/man/fido_dev_set_pin.3 index f5ef94ff6fb5..b58ba6c86f89 100644 --- a/man/fido_dev_set_pin.3 +++ b/man/fido_dev_set_pin.3 @@ -10,7 +10,7 @@  .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 diff --git a/man/fido_init.3 b/man/fido_init.3 index dcfc530c59ae..1254f934b73b 100644 --- a/man/fido_init.3 +++ b/man/fido_init.3 @@ -6,12 +6,19 @@  .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 @@ -43,8 +50,21 @@ 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 , diff --git a/man/fido_strerr.3 b/man/fido_strerr.3 index 05c86b92a158..9d4ef35aa402 100644 --- a/man/fido_strerr.3 +++ b/man/fido_strerr.3 @@ -7,7 +7,7 @@  .Os  .Sh NAME  .Nm fido_strerr -.Nd FIDO 2 error codes +.Nd FIDO2 error codes  .Sh SYNOPSIS  .In fido.h  .Ft const char * diff --git a/man/rs256_pk_new.3 b/man/rs256_pk_new.3 index ad33ee66ba7b..24a27bf8cdab 100644 --- a/man/rs256_pk_new.3 +++ b/man/rs256_pk_new.3 @@ -8,11 +8,11 @@  .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 diff --git a/regress/cred.c b/regress/cred.c index b0df1481636a..07a2ca0c0237 100644 --- a/regress/cred.c +++ b/regress/cred.c @@ -102,7 +102,7 @@ static const unsigned char authdata_unsorted_keys[198] = {  	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, @@ -151,6 +151,30 @@ const unsigned char authdata_tpm[362] = {  	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, @@ -270,7 +294,7 @@ const unsigned char pubkey[64] = {  	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, @@ -306,6 +330,17 @@ const unsigned char pubkey_tpm[259] = {  	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, @@ -317,14 +352,21 @@ const unsigned char id[64] = {  	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, @@ -832,6 +874,490 @@ const unsigned char attstmt_tpm[4034] = {  	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 @@ -1563,7 +2089,7 @@ fmt_none(void)  }  static void -valid_tpm_cred(void) +valid_tpm_rs256_cred(void)  {  	fido_cred_t *c; @@ -1571,17 +2097,42 @@ valid_tpm_cred(void)  	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); @@ -1616,7 +2167,8 @@ main(void)  	wrong_credprot();  	raw_authdata();  	fmt_none(); -	valid_tpm_cred(); +	valid_tpm_rs256_cred(); +	valid_tpm_es256_cred();  	exit(0);  } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bd14a62f0c99..796ec69a9dbe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -132,7 +132,7 @@ 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") diff --git a/src/bio.c b/src/bio.c index 4ddc93749cc3..8c52de5d76c3 100644 --- a/src/bio.c +++ b/src/bio.c @@ -424,7 +424,7 @@ bio_enroll_begin_wait(fido_dev_t *dev, fido_bio_template_t *t,  	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;  	} @@ -520,7 +520,7 @@ bio_enroll_continue_wait(fido_dev_t *dev, const fido_bio_template_t *t,  	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;  	} diff --git a/src/cbor.c b/src/cbor.c index 7935e5017dcf..8b7edece3d8e 100644 --- a/src/cbor.c +++ b/src/cbor.c @@ -696,7 +696,6 @@ cbor_encode_pin_auth(const fido_dev_t *dev, const fido_blob_t *secret,  	uint8_t		 prot;  	fido_blob_t	 key; -  	key.ptr = secret->ptr;  	key.len = secret->len; diff --git a/src/dev.c b/src/dev.c index 0c3cf64a462b..fb8faba0a06c 100644 --- a/src/dev.c +++ b/src/dev.c @@ -548,6 +548,13 @@ fido_dev_set_transport_functions(fido_dev_t *dev, const fido_dev_transport_t *t)  	return (FIDO_OK);  } +void * +fido_dev_io_handle(const fido_dev_t *dev) +{ + +	return (dev->io_handle); +} +  void  fido_init(int flags)  { diff --git a/src/eddsa.c b/src/eddsa.c index d228149ebf4d..a7b4f4f900ce 100644 --- a/src/eddsa.c +++ b/src/eddsa.c @@ -1,5 +1,5 @@  /* - * Copyright (c) 2019 Yubico AB. All rights reserved. + * Copyright (c) 2019-2021 Yubico AB. All rights reserved.   * Use of this source code is governed by a BSD-style   * license that can be found in the LICENSE file.   */ @@ -37,7 +37,9 @@ EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,  	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) @@ -52,7 +54,7 @@ EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen,  	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) diff --git a/src/export.gnu b/src/export.gnu index 2a8ad24b4c3c..0a8d46a20fad 100644 --- a/src/export.gnu +++ b/src/export.gnu @@ -201,14 +201,18 @@  		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; diff --git a/src/export.llvm b/src/export.llvm index e163afecedce..80507346edee 100644 --- a/src/export.llvm +++ b/src/export.llvm @@ -199,14 +199,18 @@ _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 diff --git a/src/export.msvc b/src/export.msvc index 9fc24e335e8d..14602164fd45 100644 --- a/src/export.msvc +++ b/src/export.msvc @@ -200,14 +200,18 @@ 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 diff --git a/src/extern.h b/src/extern.h index dc6bddd7b912..6f86d7642950 100644 --- a/src/extern.h +++ b/src/extern.h @@ -178,7 +178,6 @@ int fido_dev_get_uv_token(fido_dev_t *, uint8_t, const char *,      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 *); diff --git a/src/fido.h b/src/fido.h index 51bdb526d3f0..4bd2aeebfccb 100644 --- a/src/fido.h +++ b/src/fido.h @@ -40,6 +40,7 @@ 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 **); @@ -153,6 +154,8 @@ 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 *); @@ -212,9 +215,10 @@ 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, diff --git a/src/fido/types.h b/src/fido/types.h index 92f55d979fdc..4a216b4b9786 100644 --- a/src/fido/types.h +++ b/src/fido/types.h @@ -151,13 +151,13 @@ typedef struct fido_cred {  	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 { diff --git a/src/hid.c b/src/hid.c index a3768ad3cae8..926272b6b3ed 100644 --- a/src/hid.c +++ b/src/hid.c @@ -121,6 +121,15 @@ 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)  { @@ -129,13 +138,8 @@ fido_dev_info_free(fido_dev_info_t **devlist_p, size_t n)  	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); @@ -148,6 +152,44 @@ 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)  { diff --git a/src/hid_osx.c b/src/hid_osx.c index 1f8b37a65597..7f3652e39620 100644 --- a/src/hid_osx.c +++ b/src/hid_osx.c @@ -1,5 +1,5 @@  /* - * Copyright (c) 2019 Yubico AB. All rights reserved. + * Copyright (c) 2019-2021 Yubico AB. All rights reserved.   * Use of this source code is governed by a BSD-style   * license that can be found in the LICENSE file.   */ @@ -23,6 +23,8 @@  #define kIOMainPortDefault kIOMasterPortDefault  #endif +#define IOREG "ioreg://" +  struct hid_osx {  	IOHIDDeviceRef	ref;  	CFStringRef	loop_id; @@ -166,20 +168,27 @@ fail:  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 @@ -365,6 +374,42 @@ disable_sigpipe(int fd)  	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)  { @@ -398,9 +443,8 @@ fido_hid_open(const char *path)  		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;  	} diff --git a/src/hid_win.c b/src/hid_win.c index c29ef70253d7..fe403bcf46f1 100644 --- a/src/hid_win.c +++ b/src/hid_win.c @@ -454,7 +454,7 @@ fido_hid_close(void *handle)  			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);  	} diff --git a/src/tpm.c b/src/tpm.c index 74620a5e4865..74244f8cbf08 100644 --- a/src/tpm.c +++ b/src/tpm.c @@ -21,6 +21,10 @@  #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 @@ -31,7 +35,7 @@  #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, @@ -73,35 +77,69 @@ struct tpm_sha1_attest {  	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 @@ -145,7 +183,7 @@ get_signed_name(tpm_sha256_name_t *name, const fido_blob_t *pubarea)  }  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); @@ -158,6 +196,21 @@ bswap_rsa2048_pubarea(tpm_rsa2048_pubarea_t *x)  }  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); @@ -169,10 +222,10 @@ bswap_sha1_certinfo(tpm_sha1_attest_t *x)  }  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)) { @@ -195,7 +248,44 @@ check_rsa2048_pubarea(const fido_blob_t *buf, const rs256_pk_t *pk)  	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)); @@ -258,14 +348,28 @@ fido_get_signed_hash_tpm(fido_blob_t *dgst, const fido_blob_t *clientdata_hash,  	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;  	} diff --git a/src/webauthn.h b/src/webauthn.h index 5fbdd6faa927..22bf6e346a73 100644 --- a/src/webauthn.h +++ b/src/webauthn.h @@ -8,7 +8,9 @@  #include <winapifamily.h>
 +#ifdef _MSC_VER
  #pragma region Desktop Family or OneCore Family
 +#endif
  #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)
  #ifdef __cplusplus
 @@ -84,7 +86,15 @@ extern "C" {  //          - 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
 @@ -273,6 +283,45 @@ typedef struct _WEBAUTHN_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
  //-------------------------------------------------------------------------------------------
 @@ -410,7 +459,8 @@ typedef const WEBAUTHN_EXTENSIONS *PCWEBAUTHN_EXTENSIONS;  #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.
 @@ -465,13 +515,20 @@ typedef struct _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS {      // 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;
 @@ -485,7 +542,8 @@ typedef const WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS *PCWEBAUTHN_AUTHENT  #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.
 @@ -545,6 +603,17 @@ typedef struct _WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS {      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;
 @@ -705,7 +774,8 @@ typedef const WEBAUTHN_CREDENTIAL_ATTESTATION *PCWEBAUTHN_CREDENTIAL_ATTESTATION  #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.
 @@ -745,6 +815,12 @@ typedef struct _WEBAUTHN_ASSERTION {      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;
 @@ -834,6 +910,8 @@ WebAuthNGetW3CExceptionDOMError(  #endif
  #endif // WINAPI_FAMILY_PARTITION
 +#ifdef _MSC_VER
  #pragma endregion
 +#endif
  #endif // __WEBAUTHN_H_
 diff --git a/src/winhello.c b/src/winhello.c index 4797ac58281e..9de6c6c9b983 100644 --- a/src/winhello.c +++ b/src/winhello.c @@ -12,6 +12,16 @@  #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 @@ -40,27 +50,36 @@ struct winhello_cred {  	wchar_t						*display_name;  }; -static TLS BOOL		  webauthn_loaded; -static TLS HMODULE	  webauthn_handle; -static TLS DWORD	(*webauthn_get_api_version)(void); -static TLS PCWSTR	(*webauthn_strerr)(HRESULT); -static TLS HRESULT	(*webauthn_get_assert)(HWND, LPCWSTR, +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; @@ -70,34 +89,46 @@ webauthn_load(void)  		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__); @@ -149,35 +180,6 @@ to_utf16(const char *utf8)  	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)  { @@ -192,7 +194,7 @@ to_fido(HRESULT hr)  	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;  	}  } @@ -249,7 +251,28 @@ pack_credlist(WEBAUTHN_CREDENTIALS *out, const fido_blob_array_t *in)  }  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; @@ -258,7 +281,7 @@ set_uv(DWORD *out, fido_opt_t uv, const char *pin)  	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; @@ -361,7 +384,7 @@ pack_cred_ext(WEBAUTHN_EXTENSIONS *out, const fido_cred_ext_t *in)  		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) @@ -508,8 +531,9 @@ translate_fido_assert(struct winhello_assert *ctx, const fido_assert_t *assert,  		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;  	} @@ -587,9 +611,9 @@ translate_fido_cred(struct winhello_cred *ctx, const fido_cred_t *cred,  		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) { @@ -623,6 +647,10 @@ decode_attobj(const cbor_item_t *key, const cbor_item_t *val, void *arg)  			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) { @@ -640,9 +668,9 @@ fail:  }  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; @@ -673,24 +701,6 @@ fail:  }  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; @@ -761,7 +771,6 @@ winhello_cred_free(struct winhello_cred *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) { @@ -770,9 +779,9 @@ fido_winhello_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)  	if (devlist == NULL) {  		return FIDO_ERR_INVALID_ARGUMENT;  	} -	if ((r = winhello_manifest()) != 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]; @@ -844,13 +853,16 @@ fido_winhello_get_assert(fido_dev_t *dev, fido_assert_t *assert,  	}  	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;  	} @@ -918,7 +930,10 @@ fido_winhello_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin,  	}  	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__); diff --git a/tools/test.sh b/tools/test.sh index 656bff2c1596..02d82d5a18cd 100755 --- a/tools/test.sh +++ b/tools/test.sh @@ -12,13 +12,13 @@  # - 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 @@ -34,7 +34,7 @@ verify_cred() {  }  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) diff --git a/windows/build.ps1 b/windows/build.ps1 index 87d0c31e5311..56302444c80b 100644 --- a/windows/build.ps1 +++ b/windows/build.ps1 @@ -229,7 +229,7 @@ try {  	    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}" }  	} diff --git a/windows/const.ps1 b/windows/const.ps1 index 6d2a8189d362..4aac8bb2853e 100644 --- a/windows/const.ps1 +++ b/windows/const.ps1 @@ -6,11 +6,11 @@  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 diff --git a/windows/cygwin.gpg b/windows/cygwin.gpgBinary files differ new file mode 100755 index 000000000000..1e87237a6e03 --- /dev/null +++ b/windows/cygwin.gpg diff --git a/windows/cygwin.ps1 b/windows/cygwin.ps1 new file mode 100755 index 000000000000..aada60b6f06f --- /dev/null +++ b/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/windows/release.ps1 b/windows/release.ps1 index 32e88e256274..9221bcaa3413 100644 --- a/windows/release.ps1 +++ b/windows/release.ps1 @@ -7,8 +7,8 @@ $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" @@ -49,7 +49,7 @@ Function Package-Static(${SRC}, ${DEST}) {  }  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" @@ -59,6 +59,17 @@ Function Package-PDBs(${SRC}, ${DEST}) {  	    "${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" @@ -81,4 +92,6 @@ for ($i = 0; $i -lt $Architectures.Length; $i++) {  	    "${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"  } | 
