aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2023-05-05 23:11:52 +0000
committerEd Maste <emaste@FreeBSD.org>2023-05-05 23:11:52 +0000
commitf540a43052c12c76d3453ead881248d5467a1ab0 (patch)
tree3095d517d1742f500df2b5421b62ae1bde7bc04d
parent648a208ef3a171585f3446464646832f0e0ed3dc (diff)
parent7248ec417c7d81cfb19038eee0db15723a85550e (diff)
downloadsrc-f540a43052c1.tar.gz
src-f540a43052c1.zip
libfido2: update to 1.9.0
Some highlights from NEWS: ** Added OpenSSL 3.0 compatibility. ** Removed OpenSSL 1.0 compatibility. ** Support for FIDO 2.1 "minPinLength" extension. ** Support for COSE_EDDSA, COSE_ES256, and COSE_RS1 attestation. ** Support for TPM 2.0 attestation. ** Support for device timeouts; see fido_dev_set_timeout(). ** New API calls: - es256_pk_from_EVP_PKEY; - fido_cred_attstmt_len; - fido_cred_attstmt_ptr; - fido_cred_pin_minlen; - fido_cred_set_attstmt; - fido_cred_set_pin_minlen; - fido_dev_set_pin_minlen_rpid; - fido_dev_set_timeout; - rs256_pk_from_EVP_PKEY. ** Reliability and portability fixes. ** Better handling of HID devices without identification strings; gh#381. Relnotes: Yes Sponsored by: The FreeBSD Foundation
-rw-r--r--contrib/libfido2/CMakeLists.txt59
-rw-r--r--contrib/libfido2/NEWS22
-rw-r--r--contrib/libfido2/README.adoc9
-rw-r--r--contrib/libfido2/examples/assert.c44
-rw-r--r--contrib/libfido2/examples/cred.c110
-rw-r--r--contrib/libfido2/examples/extern.h8
-rw-r--r--contrib/libfido2/examples/reset.c13
-rw-r--r--contrib/libfido2/examples/util.c28
-rw-r--r--contrib/libfido2/fuzz/Dockerfile6
-rw-r--r--contrib/libfido2/fuzz/Makefile16
-rw-r--r--contrib/libfido2/fuzz/clock.c79
-rw-r--r--contrib/libfido2/fuzz/dummy.h83
-rw-r--r--contrib/libfido2/fuzz/export.gnu12
-rw-r--r--contrib/libfido2/fuzz/functions.txt1165
-rw-r--r--contrib/libfido2/fuzz/fuzz_assert.c48
-rw-r--r--contrib/libfido2/fuzz/fuzz_bio.c1
-rw-r--r--contrib/libfido2/fuzz/fuzz_cred.c39
-rw-r--r--contrib/libfido2/fuzz/fuzz_credman.c1
-rw-r--r--contrib/libfido2/fuzz/fuzz_hid.c30
-rw-r--r--contrib/libfido2/fuzz/fuzz_largeblob.c1
-rw-r--r--contrib/libfido2/fuzz/fuzz_mgmt.c28
-rw-r--r--contrib/libfido2/fuzz/fuzz_netlink.c94
-rw-r--r--contrib/libfido2/fuzz/mutator_aux.c5
-rw-r--r--contrib/libfido2/fuzz/mutator_aux.h5
-rw-r--r--contrib/libfido2/fuzz/report.tgzbin303082 -> 320981 bytes
-rw-r--r--contrib/libfido2/fuzz/summary.txt86
-rw-r--r--contrib/libfido2/fuzz/wrap.c201
-rw-r--r--contrib/libfido2/fuzz/wrapped.sym25
-rw-r--r--contrib/libfido2/man/CMakeLists.txt17
-rw-r--r--contrib/libfido2/man/es256_pk_new.318
-rw-r--r--contrib/libfido2/man/fido2-token.112
-rw-r--r--contrib/libfido2/man/fido_cred_new.350
-rw-r--r--contrib/libfido2/man/fido_cred_set_authdata.357
-rw-r--r--contrib/libfido2/man/fido_cred_verify.312
-rw-r--r--contrib/libfido2/man/fido_dev_enable_entattest.327
-rw-r--r--contrib/libfido2/man/fido_dev_info_manifest.310
-rw-r--r--contrib/libfido2/man/fido_dev_set_io_functions.335
-rw-r--r--contrib/libfido2/man/rs256_pk_new.318
-rw-r--r--contrib/libfido2/openbsd-compat/hkdf.c124
-rw-r--r--contrib/libfido2/openbsd-compat/hkdf.h65
-rw-r--r--contrib/libfido2/openbsd-compat/openbsd-compat.h17
-rw-r--r--contrib/libfido2/openbsd-compat/strsep.c79
-rw-r--r--contrib/libfido2/regress/CMakeLists.txt10
-rw-r--r--contrib/libfido2/regress/assert.c88
-rw-r--r--contrib/libfido2/regress/cred.c646
-rw-r--r--contrib/libfido2/regress/dev.c154
-rw-r--r--contrib/libfido2/src/CMakeLists.txt15
-rw-r--r--contrib/libfido2/src/assert.c168
-rw-r--r--contrib/libfido2/src/authkey.c16
-rw-r--r--contrib/libfido2/src/bio.c77
-rw-r--r--contrib/libfido2/src/cbor.c107
-rw-r--r--contrib/libfido2/src/config.c74
-rw-r--r--contrib/libfido2/src/cred.c245
-rw-r--r--contrib/libfido2/src/credman.c62
-rw-r--r--contrib/libfido2/src/dev.c63
-rw-r--r--contrib/libfido2/src/ecdh.c12
-rw-r--r--contrib/libfido2/src/eddsa.c82
-rw-r--r--contrib/libfido2/src/es256.c62
-rw-r--r--contrib/libfido2/src/export.gnu9
-rw-r--r--contrib/libfido2/src/export.llvm9
-rw-r--r--contrib/libfido2/src/export.msvc9
-rw-r--r--contrib/libfido2/src/extern.h55
-rw-r--r--contrib/libfido2/src/fido.h18
-rw-r--r--contrib/libfido2/src/fido/config.h2
-rw-r--r--contrib/libfido2/src/fido/eddsa.h9
-rw-r--r--contrib/libfido2/src/fido/es256.h3
-rw-r--r--contrib/libfido2/src/fido/param.h8
-rw-r--r--contrib/libfido2/src/fido/rs256.h3
-rw-r--r--contrib/libfido2/src/fido/types.h14
-rw-r--r--contrib/libfido2/src/hid_freebsd.c8
-rw-r--r--contrib/libfido2/src/hid_linux.c4
-rw-r--r--contrib/libfido2/src/hid_openbsd.c17
-rw-r--r--contrib/libfido2/src/hid_osx.c32
-rw-r--r--contrib/libfido2/src/hid_unix.c3
-rw-r--r--contrib/libfido2/src/hid_win.c48
-rw-r--r--contrib/libfido2/src/info.c81
-rw-r--r--contrib/libfido2/src/io.c104
-rw-r--r--contrib/libfido2/src/largeblob.c65
-rw-r--r--contrib/libfido2/src/netlink.c4
-rw-r--r--contrib/libfido2/src/nfc_linux.c44
-rw-r--r--contrib/libfido2/src/pin.c72
-rw-r--r--contrib/libfido2/src/reset.c12
-rw-r--r--contrib/libfido2/src/rs1.c99
-rw-r--r--contrib/libfido2/src/rs256.c127
-rw-r--r--contrib/libfido2/src/time.c74
-rw-r--r--contrib/libfido2/src/tpm.c286
-rw-r--r--contrib/libfido2/src/types.c76
-rw-r--r--contrib/libfido2/src/u2f.c158
-rw-r--r--contrib/libfido2/src/webauthn.h839
-rw-r--r--contrib/libfido2/src/winhello.c387
-rw-r--r--contrib/libfido2/tools/CMakeLists.txt3
-rw-r--r--contrib/libfido2/tools/config.c48
-rw-r--r--contrib/libfido2/tools/extern.h3
-rw-r--r--contrib/libfido2/tools/fido2-token.c2
-rw-r--r--contrib/libfido2/tools/token.c6
-rw-r--r--contrib/libfido2/windows/build.ps1390
-rw-r--r--contrib/libfido2/windows/const.ps142
-rw-r--r--contrib/libfido2/windows/release.ps184
-rw-r--r--lib/libfido2/Makefile4
99 files changed, 5599 insertions, 2302 deletions
diff --git a/contrib/libfido2/CMakeLists.txt b/contrib/libfido2/CMakeLists.txt
index 101b7b33e2fc..d775a98c5b48 100644
--- a/contrib/libfido2/CMakeLists.txt
+++ b/contrib/libfido2/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Yubico AB. All rights reserved.
+# Copyright (c) 2018-2021 Yubico AB. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
@@ -28,7 +28,7 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_COLOR_MAKEFILE OFF)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(FIDO_MAJOR "1")
-set(FIDO_MINOR "8")
+set(FIDO_MINOR "9")
set(FIDO_PATCH "0")
set(FIDO_VERSION ${FIDO_MAJOR}.${FIDO_MINOR}.${FIDO_PATCH})
@@ -68,10 +68,11 @@ if(NOT MSVC)
set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_DARWIN_C_SOURCE")
set(FIDO_CFLAGS "${FIDO_CFLAGS} -D__STDC_WANT_LIB_EXT1__=1")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
- set(NFC_LINUX OFF)
+ set(NFC_LINUX ON)
set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_GNU_SOURCE")
set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_DEFAULT_SOURCE")
- elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
+ elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
+ CMAKE_SYSTEM_NAME STREQUAL "MidnightBSD")
set(FIDO_CFLAGS "${FIDO_CFLAGS} -D__BSD_VISIBLE=1")
endif()
set(FIDO_CFLAGS "${FIDO_CFLAGS} -std=c99")
@@ -79,7 +80,7 @@ if(NOT MSVC)
endif()
check_c_compiler_flag("-Wshorten-64-to-32" HAVE_SHORTEN_64_TO_32)
-check_c_compiler_flag("-fstack-protector-all" HAVE_STACK_PROTECTOR_ALL)
+check_c_compiler_flag("-Werror -fstack-protector-all" HAVE_STACK_PROTECTOR_ALL)
check_include_files(cbor.h HAVE_CBOR_H)
check_include_files(endian.h HAVE_ENDIAN_H)
@@ -88,7 +89,6 @@ check_include_files(openssl/opensslv.h HAVE_OPENSSLV_H)
check_include_files(signal.h HAVE_SIGNAL_H)
check_include_files(sys/random.h HAVE_SYS_RANDOM_H)
check_include_files(unistd.h HAVE_UNISTD_H)
-check_include_files("windows.h;webauthn.h" HAVE_WEBAUTHN_H)
check_symbol_exists(arc4random_buf stdlib.h HAVE_ARC4RANDOM_BUF)
check_symbol_exists(clock_gettime time.h HAVE_CLOCK_GETTIME)
@@ -101,17 +101,13 @@ check_symbol_exists(getrandom sys/random.h HAVE_GETRANDOM)
check_symbol_exists(memset_s string.h HAVE_MEMSET_S)
check_symbol_exists(readpassphrase readpassphrase.h HAVE_READPASSPHRASE)
check_symbol_exists(recallocarray stdlib.h HAVE_RECALLOCARRAY)
-check_symbol_exists(sigaction signal.h HAVE_SIGACTION)
check_symbol_exists(strlcat string.h HAVE_STRLCAT)
check_symbol_exists(strlcpy string.h HAVE_STRLCPY)
+check_symbol_exists(strsep string.h HAVE_STRSEP)
check_symbol_exists(sysconf unistd.h HAVE_SYSCONF)
check_symbol_exists(timespecsub sys/time.h HAVE_TIMESPECSUB)
check_symbol_exists(timingsafe_bcmp string.h HAVE_TIMINGSAFE_BCMP)
-set(CMAKE_EXTRA_INCLUDE_FILES signal.h)
-check_type_size("sig_atomic_t" HAVE_SIG_ATOMIC_T)
-set(CMAKE_EXTRA_INCLUDE_FILES)
-
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
try_compile(HAVE_POSIX_IOCTL
"${CMAKE_CURRENT_BINARY_DIR}/posix_ioctl_check.o"
@@ -134,16 +130,15 @@ list(APPEND CHECK_VARIABLES
HAVE_POSIX_IOCTL
HAVE_READPASSPHRASE
HAVE_RECALLOCARRAY
- HAVE_SIGACTION
HAVE_SIGNAL_H
HAVE_STRLCAT
HAVE_STRLCPY
+ HAVE_STRSEP
HAVE_SYSCONF
HAVE_SYS_RANDOM_H
HAVE_TIMESPECSUB
HAVE_TIMINGSAFE_BCMP
HAVE_UNISTD_H
- HAVE_WEBAUTHN_H
)
foreach(v ${CHECK_VARIABLES})
@@ -156,26 +151,26 @@ if(HAVE_EXPLICIT_BZERO AND NOT LIBFUZZER)
add_definitions(-DHAVE_EXPLICIT_BZERO)
endif()
-if(HAVE_SIGACTION AND (NOT HAVE_SIG_ATOMIC_T STREQUAL ""))
- add_definitions(-DSIGNAL_EXAMPLE)
-endif()
-
if(UNIX)
add_definitions(-DHAVE_DEV_URANDOM)
endif()
if(MSVC)
if((NOT CBOR_INCLUDE_DIRS) OR (NOT CBOR_LIBRARY_DIRS) OR
- (NOT CRYPTO_INCLUDE_DIRS) OR (NOT CRYPTO_LIBRARY_DIRS) OR
- (NOT ZLIB_INCLUDE_DIRS) OR (NOT ZLIB_LIBRARY_DIRS))
- message(FATAL_ERROR "please provide definitions for "
- "{CBOR,CRYPTO,ZLIB}_{INCLUDE,LIBRARY}_DIRS when building "
- "under msvc")
+ (NOT CBOR_BIN_DIRS) OR (NOT CRYPTO_INCLUDE_DIRS) OR
+ (NOT CRYPTO_LIBRARY_DIRS) OR (NOT CRYPTO_BIN_DIRS) OR
+ (NOT ZLIB_INCLUDE_DIRS) OR (NOT ZLIB_LIBRARY_DIRS) OR
+ (NOT ZLIB_BIN_DIRS))
+ message(FATAL_ERROR "please define "
+ "{CBOR,CRYPTO,ZLIB}_{INCLUDE,LIBRARY,BIN}_DIRS when "
+ "building under msvc")
endif()
set(CBOR_LIBRARIES cbor)
set(ZLIB_LIBRARIES zlib)
set(CRYPTO_LIBRARIES crypto-46)
set(MSVC_DISABLED_WARNINGS_LIST
+ "C4152" # nonstandard extension used: function/data pointer
+ # conversion in expression;
"C4200" # nonstandard extension used: zero-sized array in
# struct/union;
"C4204" # nonstandard extension used: non-constant aggregate
@@ -191,12 +186,10 @@ if(MSVC)
${MSVC_DISABLED_WARNINGS_LIST})
string(REGEX REPLACE "[/-]W[1234][ ]?" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -MP -W4 -WX ${MSVC_DISABLED_WARNINGS_STR}")
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Z7 /guard:cf /sdl /RTCcsu")
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Od /Z7 /guard:cf /sdl /RTCcsu")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Zi /guard:cf /sdl")
- if (HAVE_WEBAUTHN_H)
- add_definitions(-DUSE_WINHELLO)
- set(USE_WINHELLO ON)
- endif()
+ add_definitions(-DUSE_WINHELLO)
+ set(USE_WINHELLO ON)
else()
include(FindPkgConfig)
pkg_search_module(CBOR libcbor)
@@ -275,9 +268,14 @@ else()
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -D_FORTIFY_SOURCE=2")
+ if(CRYPTO_VERSION VERSION_GREATER_EQUAL 3.0)
+ add_definitions(-DOPENSSL_API_COMPAT=0x10100000L)
+ endif()
+
if(FUZZ)
add_definitions(-DFIDO_FUZZ)
endif()
+
if(LIBFUZZER)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=fuzzer-no-link")
endif()
@@ -404,10 +402,9 @@ if(BUILD_MANPAGES)
endif()
if(NOT WIN32)
- if(CMAKE_BUILD_TYPE STREQUAL "Debug")
- if(NOT LIBFUZZER AND NOT FUZZ)
- subdirs(regress)
- endif()
+ if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT FUZZ)
+ enable_testing()
+ subdirs(regress)
endif()
if(FUZZ)
subdirs(fuzz)
diff --git a/contrib/libfido2/NEWS b/contrib/libfido2/NEWS
index a89766b72e89..04cda4e0e83a 100644
--- a/contrib/libfido2/NEWS
+++ b/contrib/libfido2/NEWS
@@ -1,3 +1,25 @@
+* Version 1.9.0 (2021-10-27)
+ ** Enabled NFC support on Linux.
+ ** Added OpenSSL 3.0 compatibility.
+ ** Removed OpenSSL 1.0 compatibility.
+ ** Support for FIDO 2.1 "minPinLength" extension.
+ ** Support for COSE_EDDSA, COSE_ES256, and COSE_RS1 attestation.
+ ** Support for TPM 2.0 attestation.
+ ** Support for device timeouts; see fido_dev_set_timeout().
+ ** New API calls:
+ - es256_pk_from_EVP_PKEY;
+ - fido_cred_attstmt_len;
+ - fido_cred_attstmt_ptr;
+ - fido_cred_pin_minlen;
+ - fido_cred_set_attstmt;
+ - fido_cred_set_pin_minlen;
+ - fido_dev_set_pin_minlen_rpid;
+ - fido_dev_set_timeout;
+ - rs256_pk_from_EVP_PKEY.
+ ** Reliability and portability fixes.
+ ** Better handling of HID devices without identification strings; gh#381.
+ ** Fixed detection of Windows's native webauthn API; gh#382.
+
* Version 1.8.0 (2021-07-22)
** Dropped 'Requires.private' entry from pkg-config file.
** Better support for FIDO 2.1 authenticators.
diff --git a/contrib/libfido2/README.adoc b/contrib/libfido2/README.adoc
index f5ffa7e4e602..a0e188bf8774 100644
--- a/contrib/libfido2/README.adoc
+++ b/contrib/libfido2/README.adoc
@@ -23,6 +23,8 @@ file for the full license text.
*libfido2* is known to work on Linux, macOS, Windows, OpenBSD, and FreeBSD.
+NFC support is available on Linux and Windows.
+
=== Documentation
Documentation is available in troff and HTML formats. An
@@ -40,7 +42,7 @@ is also available.
==== Releases
-The current release of *libfido2* is 1.8.0. Please consult Yubico's
+The current release of *libfido2* is 1.9.0. Please consult Yubico's
https://developers.yubico.com/libfido2/Releases[release page] for source
and binary releases.
@@ -66,7 +68,7 @@ Follow the instructions for Ubuntu 18.04 (Bionic) below.
Or from source, on UNIX-like systems:
- $ (rm -rf build && mkdir build && cd build && cmake ..)
+ $ cmake -B build
$ make -C build
$ sudo make -C build install
@@ -75,7 +77,8 @@ https://www.freedesktop.org/wiki/Software/pkg-config/[pkg-config] may need to
be installed, or the PKG_CONFIG_PATH environment variable set.
*libfido2* depends on https://github.com/pjk/libcbor[libcbor],
-https://www.openssl.org[OpenSSL], and https://zlib.net[zlib]. On Linux, libudev
+https://www.openssl.org[OpenSSL] 1.1 or newer, and https://zlib.net[zlib].
+On Linux, libudev
(part of https://www.freedesktop.org/wiki/Software/systemd[systemd]) is also
required.
diff --git a/contrib/libfido2/examples/assert.c b/contrib/libfido2/examples/assert.c
index dc3fda3ac447..8b0dbd9f6eb2 100644
--- a/contrib/libfido2/examples/assert.c
+++ b/contrib/libfido2/examples/assert.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -20,7 +20,7 @@
#include "../openbsd-compat/openbsd-compat.h"
#include "extern.h"
-static const unsigned char cdh[32] = {
+static const unsigned char cd[32] = {
0xec, 0x8d, 0x8f, 0x78, 0x42, 0x4a, 0x2b, 0xb7,
0x82, 0x34, 0xaa, 0xca, 0x07, 0xa1, 0xf6, 0x56,
0x42, 0x1c, 0xb6, 0xf6, 0xb3, 0x00, 0x86, 0x52,
@@ -106,10 +106,9 @@ verify_assert(int type, const unsigned char *authdata_ptr, size_t authdata_len,
errx(1, "fido_assert_new");
/* client data hash */
- r = fido_assert_set_clientdata_hash(assert, cdh, sizeof(cdh));
+ r = fido_assert_set_clientdata(assert, cd, sizeof(cd));
if (r != FIDO_OK)
- errx(1, "fido_assert_set_clientdata_hash: %s (0x%x)",
- fido_strerr(r), r);
+ errx(1, "fido_assert_set_clientdata: %s (0x%x)", fido_strerr(r), r);
/* relying party */
r = fido_assert_set_rp(assert, "localhost");
@@ -166,7 +165,7 @@ main(int argc, char **argv)
const char *blobkey_out = NULL;
const char *hmac_out = NULL;
unsigned char *body = NULL;
- long long seconds = 0;
+ long long ms = 0;
size_t len;
int type = COSE_ES256;
int ext = 0;
@@ -182,16 +181,12 @@ main(int argc, char **argv)
pin = optarg;
break;
case 'T':
-#ifndef SIGNAL_EXAMPLE
- (void)seconds;
- errx(1, "-T not supported");
-#else
- if (base10(optarg, &seconds) < 0)
+ if (base10(optarg, &ms) < 0)
errx(1, "base10: %s", optarg);
- if (seconds <= 0 || seconds > 30)
+ if (ms <= 0 || ms > 30)
errx(1, "-T: %s must be in (0,30]", optarg);
+ ms *= 1000; /* seconds to milliseconds */
break;
-#endif
case 'a':
if (read_blob(optarg, &body, &len) < 0)
errx(1, "read_blob: %s", optarg);
@@ -262,10 +257,9 @@ main(int argc, char **argv)
fido_dev_force_u2f(dev);
/* client data hash */
- r = fido_assert_set_clientdata_hash(assert, cdh, sizeof(cdh));
+ r = fido_assert_set_clientdata(assert, cd, sizeof(cd));
if (r != FIDO_OK)
- errx(1, "fido_assert_set_clientdata_hash: %s (0x%x)",
- fido_strerr(r), r);
+ errx(1, "fido_assert_set_clientdata: %s (0x%x)", fido_strerr(r), r);
/* relying party */
r = fido_assert_set_rp(assert, "localhost");
@@ -286,20 +280,12 @@ main(int argc, char **argv)
if (uv && (r = fido_assert_set_uv(assert, FIDO_OPT_TRUE)) != FIDO_OK)
errx(1, "fido_assert_set_uv: %s (0x%x)", fido_strerr(r), r);
-#ifdef SIGNAL_EXAMPLE
- prepare_signal_handler(SIGINT);
- if (seconds) {
- prepare_signal_handler(SIGALRM);
- alarm((unsigned)seconds);
- }
-#endif
+ /* timeout */
+ if (ms != 0 && (r = fido_dev_set_timeout(dev, (int)ms)) != FIDO_OK)
+ errx(1, "fido_dev_set_timeout: %s (0x%x)", fido_strerr(r), r);
- r = fido_dev_get_assert(dev, assert, pin);
- if (r != FIDO_OK) {
-#ifdef SIGNAL_EXAMPLE
- if (got_signal)
- fido_dev_cancel(dev);
-#endif
+ if ((r = fido_dev_get_assert(dev, assert, pin)) != FIDO_OK) {
+ fido_dev_cancel(dev);
errx(1, "fido_dev_get_assert: %s (0x%x)", fido_strerr(r), r);
}
diff --git a/contrib/libfido2/examples/cred.c b/contrib/libfido2/examples/cred.c
index 74145c761380..4a9d8bf4b25a 100644
--- a/contrib/libfido2/examples/cred.c
+++ b/contrib/libfido2/examples/cred.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -17,7 +17,7 @@
#include "../openbsd-compat/openbsd-compat.h"
#include "extern.h"
-static const unsigned char cdh[32] = {
+static const unsigned char cd[32] = {
0xf9, 0x64, 0x57, 0xe7, 0x2d, 0x97, 0xf6, 0xbb,
0xdd, 0xd7, 0xfb, 0x06, 0x37, 0x62, 0xea, 0x26,
0x20, 0x44, 0x8e, 0x69, 0x7c, 0x03, 0xf2, 0x31,
@@ -42,9 +42,8 @@ usage(void)
static void
verify_cred(int type, const char *fmt, const unsigned char *authdata_ptr,
- size_t authdata_len, const unsigned char *x509_ptr, size_t x509_len,
- const unsigned char *sig_ptr, size_t sig_len, bool rk, bool uv, int ext,
- const char *key_out, const char *id_out)
+ size_t authdata_len, const unsigned char *attstmt_ptr, size_t attstmt_len,
+ bool rk, bool uv, int ext, const char *key_out, const char *id_out)
{
fido_cred_t *cred;
int r;
@@ -57,11 +56,10 @@ verify_cred(int type, const char *fmt, const unsigned char *authdata_ptr,
if (r != FIDO_OK)
errx(1, "fido_cred_set_type: %s (0x%x)", fido_strerr(r), r);
- /* client data hash */
- r = fido_cred_set_clientdata_hash(cred, cdh, sizeof(cdh));
+ /* client data */
+ r = fido_cred_set_clientdata(cred, cd, sizeof(cd));
if (r != FIDO_OK)
- errx(1, "fido_cred_set_clientdata_hash: %s (0x%x)",
- fido_strerr(r), r);
+ errx(1, "fido_cred_set_clientdata: %s (0x%x)", fido_strerr(r), r);
/* relying party */
r = fido_cred_set_rp(cred, "localhost", "sweet home localhost");
@@ -96,15 +94,10 @@ verify_cred(int type, const char *fmt, const unsigned char *authdata_ptr,
goto out;
}
- /* x509 */
- r = fido_cred_set_x509(cred, x509_ptr, x509_len);
+ /* attestation statement */
+ r = fido_cred_set_attstmt(cred, attstmt_ptr, attstmt_len);
if (r != FIDO_OK)
- errx(1, "fido_cred_set_x509: %s (0x%x)", fido_strerr(r), r);
-
- /* sig */
- r = fido_cred_set_sig(cred, sig_ptr, sig_len);
- if (r != FIDO_OK)
- errx(1, "fido_cred_set_sig: %s (0x%x)", fido_strerr(r), r);
+ errx(1, "fido_cred_set_attstmt: %s (0x%x)", fido_strerr(r), r);
r = fido_cred_verify(cred);
if (r != FIDO_OK)
@@ -138,27 +131,6 @@ out:
fido_cred_free(&cred);
}
-static fido_dev_t *
-open_from_manifest(const fido_dev_info_t *dev_infos, size_t len,
- const char *path)
-{
- size_t i;
- fido_dev_t *dev;
-
- for (i = 0; i < len; i++) {
- const fido_dev_info_t *curr = fido_dev_info_ptr(dev_infos, i);
- if (path == NULL ||
- strcmp(path, fido_dev_info_path(curr)) == 0) {
- dev = fido_dev_new_with_info(curr);
- if (fido_dev_open_with_info(dev) == FIDO_OK)
- return (dev);
- fido_dev_free(&dev);
- }
- }
-
- return (NULL);
-}
-
int
main(int argc, char **argv)
{
@@ -171,16 +143,13 @@ main(int argc, char **argv)
const char *blobkey_out = NULL;
const char *key_out = NULL;
const char *id_out = NULL;
- const char *path = NULL;
unsigned char *body = NULL;
- long long seconds = 0;
+ long long ms = 0;
size_t len;
int type = COSE_ES256;
int ext = 0;
int ch;
int r;
- fido_dev_info_t *dev_infos = NULL;
- size_t dev_infos_len = 0;
if ((cred = fido_cred_new()) == NULL)
errx(1, "fido_cred_new");
@@ -191,16 +160,12 @@ main(int argc, char **argv)
pin = optarg;
break;
case 'T':
-#ifndef SIGNAL_EXAMPLE
- (void)seconds;
- errx(1, "-T not supported");
-#else
- if (base10(optarg, &seconds) < 0)
+ if (base10(optarg, &ms) < 0)
errx(1, "base10: %s", optarg);
- if (seconds <= 0 || seconds > 30)
+ if (ms <= 0 || ms > 30)
errx(1, "-T: %s must be in (0,30]", optarg);
+ ms *= 1000; /* seconds to milliseconds */
break;
-#endif
case 'b':
ext |= FIDO_EXT_LARGEBLOB_KEY;
blobkey_out = optarg;
@@ -248,21 +213,20 @@ main(int argc, char **argv)
}
}
- fido_init(0);
-
argc -= optind;
argv += optind;
- if (argc > 1)
+ if (argc != 1)
usage();
- dev_infos = fido_dev_info_new(16);
- fido_dev_info_manifest(dev_infos, 16, &dev_infos_len);
- if (argc == 1)
- path = argv[0];
- if ((dev = open_from_manifest(dev_infos, dev_infos_len, path)) == NULL)
- errx(1, "open_from_manifest");
+ fido_init(0);
+
+ if ((dev = fido_dev_new()) == NULL)
+ errx(1, "fido_dev_new");
+ r = fido_dev_open(dev, argv[0]);
+ if (r != FIDO_OK)
+ errx(1, "fido_dev_open: %s (0x%x)", fido_strerr(r), r);
if (u2f)
fido_dev_force_u2f(dev);
@@ -271,11 +235,10 @@ main(int argc, char **argv)
if (r != FIDO_OK)
errx(1, "fido_cred_set_type: %s (0x%x)", fido_strerr(r), r);
- /* client data hash */
- r = fido_cred_set_clientdata_hash(cred, cdh, sizeof(cdh));
+ /* client data */
+ r = fido_cred_set_clientdata(cred, cd, sizeof(cd));
if (r != FIDO_OK)
- errx(1, "fido_cred_set_clientdata_hash: %s (0x%x)",
- fido_strerr(r), r);
+ errx(1, "fido_cred_set_clientdata: %s (0x%x)", fido_strerr(r), r);
/* relying party */
r = fido_cred_set_rp(cred, "localhost", "sweet home localhost");
@@ -301,20 +264,12 @@ main(int argc, char **argv)
if (uv && (r = fido_cred_set_uv(cred, FIDO_OPT_TRUE)) != FIDO_OK)
errx(1, "fido_cred_set_uv: %s (0x%x)", fido_strerr(r), r);
-#ifdef SIGNAL_EXAMPLE
- prepare_signal_handler(SIGINT);
- if (seconds) {
- prepare_signal_handler(SIGALRM);
- alarm((unsigned)seconds);
- }
-#endif
+ /* timeout */
+ if (ms != 0 && (r = fido_dev_set_timeout(dev, (int)ms)) != FIDO_OK)
+ errx(1, "fido_dev_set_timeout: %s (0x%x)", fido_strerr(r), r);
- r = fido_dev_make_cred(dev, cred, pin);
- if (r != FIDO_OK) {
-#ifdef SIGNAL_EXAMPLE
- if (got_signal)
- fido_dev_cancel(dev);
-#endif
+ if ((r = fido_dev_make_cred(dev, cred, pin)) != FIDO_OK) {
+ fido_dev_cancel(dev);
errx(1, "fido_makecred: %s (0x%x)", fido_strerr(r), r);
}
@@ -329,9 +284,8 @@ main(int argc, char **argv)
uv = true;
verify_cred(type, fido_cred_fmt(cred), fido_cred_authdata_ptr(cred),
- fido_cred_authdata_len(cred), fido_cred_x5c_ptr(cred),
- fido_cred_x5c_len(cred), fido_cred_sig_ptr(cred),
- fido_cred_sig_len(cred), rk, uv, ext, key_out, id_out);
+ fido_cred_authdata_len(cred), fido_cred_attstmt_ptr(cred),
+ fido_cred_attstmt_len(cred), rk, uv, ext, key_out, id_out);
if (blobkey_out != NULL) {
/* extract the "largeBlob" key */
diff --git a/contrib/libfido2/examples/extern.h b/contrib/libfido2/examples/extern.h
index 0ea68c4fb585..5633b23d2003 100644
--- a/contrib/libfido2/examples/extern.h
+++ b/contrib/libfido2/examples/extern.h
@@ -11,10 +11,6 @@
#include <openssl/evp.h>
#include <openssl/rsa.h>
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-
/* util.c */
EC_KEY *read_ec_pubkey(const char *);
RSA *read_rsa_pubkey(const char *);
@@ -25,9 +21,5 @@ int write_blob(const char *, const unsigned char *, size_t);
int write_ec_pubkey(const char *, const void *, size_t);
int write_rsa_pubkey(const char *, const void *, size_t);
int write_eddsa_pubkey(const char *, const void *, size_t);
-#ifdef SIGNAL_EXAMPLE
-void prepare_signal_handler(int);
-extern volatile sig_atomic_t got_signal;
-#endif
#endif /* _EXTERN_H_ */
diff --git a/contrib/libfido2/examples/reset.c b/contrib/libfido2/examples/reset.c
index eb341c26c0cd..b429d05f0fe4 100644
--- a/contrib/libfido2/examples/reset.c
+++ b/contrib/libfido2/examples/reset.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -34,16 +34,9 @@ main(int argc, char **argv)
if ((r = fido_dev_open(dev, argv[1])) != FIDO_OK)
errx(1, "fido_dev_open: %s (0x%x)", fido_strerr(r), r);
-#ifdef SIGNAL_EXAMPLE
- prepare_signal_handler(SIGINT);
-#endif
-
if ((r = fido_dev_reset(dev)) != FIDO_OK) {
-#ifdef SIGNAL_EXAMPLE
- if (got_signal)
- fido_dev_cancel(dev);
-#endif
- errx(1, "fido_reset: %s (0x%x)", fido_strerr(r), r);
+ fido_dev_cancel(dev);
+ errx(1, "fido_dev_reset: %s (0x%x)", fido_strerr(r), r);
}
if ((r = fido_dev_close(dev)) != FIDO_OK)
diff --git a/contrib/libfido2/examples/util.c b/contrib/libfido2/examples/util.c
index caa68aa880ee..8b360af21c7a 100644
--- a/contrib/libfido2/examples/util.c
+++ b/contrib/libfido2/examples/util.c
@@ -21,9 +21,6 @@
#include <limits.h>
#include <stdlib.h>
#include <string.h>
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -33,31 +30,6 @@
#include "../openbsd-compat/openbsd-compat.h"
#include "extern.h"
-#ifdef SIGNAL_EXAMPLE
-volatile sig_atomic_t got_signal = 0;
-
-static void
-signal_handler(int signo)
-{
- (void)signo;
- got_signal = 1;
-}
-
-void
-prepare_signal_handler(int signo)
-{
- struct sigaction sa;
-
- memset(&sa, 0, sizeof(sa));
-
- sigemptyset(&sa.sa_mask);
- sa.sa_handler = signal_handler;
-
- if (sigaction(signo, &sa, NULL) < 0)
- err(1, "sigaction");
-}
-#endif
-
int
base10(const char *str, long long *ll)
{
diff --git a/contrib/libfido2/fuzz/Dockerfile b/contrib/libfido2/fuzz/Dockerfile
index 895da69e4c4c..f175991d0462 100644
--- a/contrib/libfido2/fuzz/Dockerfile
+++ b/contrib/libfido2/fuzz/Dockerfile
@@ -1,12 +1,12 @@
-# Copyright (c) 2019 Yubico AB. All rights reserved.
+# Copyright (c) 2019-2021 Yubico AB. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
FROM ubuntu:focal
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update
-RUN apt-get install -y clang-11 cmake git libssl-dev libudev-dev make pkg-config
+RUN apt-get install -y clang-12 cmake git libssl-dev libudev-dev make pkg-config
RUN apt-get install -y zlib1g-dev
RUN git clone --branch v0.8.0 https://github.com/PJK/libcbor
RUN git clone https://github.com/yubico/libfido2
-RUN CC=clang-11 CXX=clang++-11 /libfido2/fuzz/build-coverage /libcbor /libfido2
+RUN CC=clang-12 CXX=clang++-12 /libfido2/fuzz/build-coverage /libcbor /libfido2
diff --git a/contrib/libfido2/fuzz/Makefile b/contrib/libfido2/fuzz/Makefile
index 4b067c23aac2..1a974a2bf557 100644
--- a/contrib/libfido2/fuzz/Makefile
+++ b/contrib/libfido2/fuzz/Makefile
@@ -1,11 +1,11 @@
-# Copyright (c) 2019 Yubico AB. All rights reserved.
+# Copyright (c) 2019-2021 Yubico AB. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
-IMAGE := libfido2-coverage:1.8.0
+IMAGE := libfido2-coverage:1.9.1
RUNNER := libfido2-runner
-PROFDATA := llvm-profdata-11
-COV := llvm-cov-11
+PROFDATA := llvm-profdata-12
+COV := llvm-cov-12
TARGETS := fuzz_assert fuzz_bio fuzz_cred fuzz_credman fuzz_hid \
fuzz_largeblob fuzz_netlink fuzz_mgmt
CORPORA := $(foreach f,${TARGETS},${f}/corpus)
@@ -50,16 +50,18 @@ profdata: run
report.tgz: profdata
docker exec ${RUNNER} /bin/sh -c 'rm -rf /report && mkdir /report && \
${COV} show -format=html -tab-size=8 -instr-profile=/$< \
- -output-dir=/report /libfido2/build/src/libfido2.so'
+ --show-branch-summary=false -output-dir=/report \
+ /libfido2/build/src/libfido2.so'
docker exec -i ${RUNNER} tar Czcf / - report > $@
summary.txt: profdata
docker exec ${RUNNER} ${COV} report -use-color=false \
- /libfido2/build/src/libfido2.so -instr-profile=/$< > $@
+ --show-branch-summary=false /libfido2/build/src/libfido2.so \
+ -instr-profile=/$< > $@
functions.txt: profdata
docker exec ${RUNNER} /bin/sh -c '${COV} report -use-color=false \
- -show-functions -instr-profile=/$< \
+ -show-functions --show-branch-summary=false -instr-profile=/$< \
/libfido2/build/src/libfido2.so /libfido2/src/*.[ch]' > $@
clean: run
diff --git a/contrib/libfido2/fuzz/clock.c b/contrib/libfido2/fuzz/clock.c
new file mode 100644
index 000000000000..23803c2ee3e5
--- /dev/null
+++ b/contrib/libfido2/fuzz/clock.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2021 Yubico AB. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+#include <stdint.h>
+#include <time.h>
+
+#include "mutator_aux.h"
+
+/*
+ * A pseudo-random monotonic clock with a probabilistic discontinuity to
+ * the end of time (as measured by struct timespec).
+ */
+
+extern int prng_up;
+extern int __wrap_clock_gettime(clockid_t, struct timespec *);
+extern int __real_clock_gettime(clockid_t, struct timespec *);
+extern int __wrap_usleep(unsigned int);
+static TLS struct timespec fuzz_clock;
+
+static void
+tick(unsigned int usec)
+{
+ long long drift;
+
+ /*
+ * Simulate a jump to the end of time with 0.125% probability.
+ * This condition should be gracefully handled by callers of
+ * clock_gettime().
+ */
+ if (uniform_random(800) < 1) {
+ fuzz_clock.tv_sec = LLONG_MAX;
+ fuzz_clock.tv_nsec = LONG_MAX;
+ return;
+ }
+
+ drift = usec * 1000LL + (long long)uniform_random(10000000); /* 10ms */
+ if (LLONG_MAX - drift < (long long)fuzz_clock.tv_nsec) {
+ fuzz_clock_reset(); /* Not much we can do here. */
+ } else if (drift + (long long)fuzz_clock.tv_nsec < 1000000000) {
+ fuzz_clock.tv_nsec += (long)(drift);
+ } else {
+ fuzz_clock.tv_sec += (long)(drift / 1000000000);
+ fuzz_clock.tv_nsec += (long)(drift % 1000000000);
+ }
+}
+
+int
+__wrap_clock_gettime(clockid_t clk_id, struct timespec *tp)
+{
+ if (!prng_up || clk_id != CLOCK_MONOTONIC)
+ return __real_clock_gettime(clk_id, tp);
+ if (uniform_random(400) < 1)
+ return -1;
+
+ tick(0);
+ *tp = fuzz_clock;
+
+ return 0;
+}
+
+int
+__wrap_usleep(unsigned int usec)
+{
+ if (uniform_random(400) < 1)
+ return -1;
+
+ tick(usec);
+
+ return 0;
+}
+
+void
+fuzz_clock_reset(void)
+{
+ memset(&fuzz_clock, 0, sizeof(fuzz_clock));
+}
diff --git a/contrib/libfido2/fuzz/dummy.h b/contrib/libfido2/fuzz/dummy.h
index 981cceec37b5..95744eba634b 100644
--- a/contrib/libfido2/fuzz/dummy.h
+++ b/contrib/libfido2/fuzz/dummy.h
@@ -93,4 +93,87 @@ const uint8_t dummy_eddsa[] = {
0xe2, 0x39, 0xdf, 0x2f, 0x87, 0x19, 0xb3, 0x02,
};
+const uint8_t dummy_netlink_wiredata[] = {
+ 0xd8, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x9d, 0x2e, 0x00, 0x00,
+ 0x01, 0x02, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x6e, 0x66, 0x63, 0x00, 0x06, 0x00, 0x01, 0x00,
+ 0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00,
+ 0x1f, 0x00, 0x00, 0x00, 0x80, 0x01, 0x06, 0x00,
+ 0x14, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00,
+ 0x08, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x04, 0x00,
+ 0x08, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x05, 0x00, 0x08, 0x00, 0x01, 0x00,
+ 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x06, 0x00,
+ 0x08, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x07, 0x00, 0x08, 0x00, 0x01, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x08, 0x00,
+ 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x09, 0x00, 0x08, 0x00, 0x01, 0x00,
+ 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0a, 0x00,
+ 0x08, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x01, 0x00,
+ 0x13, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0c, 0x00,
+ 0x08, 0x00, 0x01, 0x00, 0x15, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x01, 0x00,
+ 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0e, 0x00,
+ 0x08, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x01, 0x00,
+ 0x1a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x0c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x10, 0x00,
+ 0x08, 0x00, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x11, 0x00, 0x08, 0x00, 0x01, 0x00,
+ 0x1c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00,
+ 0x08, 0x00, 0x01, 0x00, 0x1d, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x13, 0x00, 0x08, 0x00, 0x01, 0x00,
+ 0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x0a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x07, 0x00,
+ 0x18, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00,
+ 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x00, 0x00,
+ 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x9d, 0x2e, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
+ 0x1e, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x9d, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x24, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x05, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x09, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+ 0x1e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9d, 0x2e, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00,
+ 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x06, 0x00, 0x05, 0x00, 0x44, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x06, 0x00, 0x20, 0x00, 0x00, 0x00,
+ 0x0b, 0x00, 0x07, 0x00, 0x27, 0x00, 0x00, 0x00,
+ 0x93, 0xb9, 0x25, 0x00
+};
+
#endif /* !_DUMMY_H */
diff --git a/contrib/libfido2/fuzz/export.gnu b/contrib/libfido2/fuzz/export.gnu
index bd70d1c7eaac..0c712b30a429 100644
--- a/contrib/libfido2/fuzz/export.gnu
+++ b/contrib/libfido2/fuzz/export.gnu
@@ -7,6 +7,7 @@
eddsa_pk_to_EVP_PKEY;
es256_pk_free;
es256_pk_from_EC_KEY;
+ es256_pk_from_EVP_PKEY;
es256_pk_from_ptr;
es256_pk_new;
es256_pk_to_EVP_PKEY;
@@ -30,6 +31,7 @@
fido_assert_rp_id;
fido_assert_set_authdata;
fido_assert_set_authdata_raw;
+ fido_assert_set_clientdata;
fido_assert_set_clientdata_hash;
fido_assert_set_count;
fido_assert_set_extensions;
@@ -98,6 +100,8 @@
fido_cbor_info_transports_ptr;
fido_cbor_info_versions_len;
fido_cbor_info_versions_ptr;
+ fido_cred_attstmt_len;
+ fido_cred_attstmt_ptr;
fido_cred_authdata_len;
fido_cred_authdata_ptr;
fido_cred_authdata_raw_len;
@@ -137,19 +141,23 @@
fido_credman_rp_new;
fido_credman_set_dev_rk;
fido_cred_new;
+ fido_cred_pin_minlen;
fido_cred_prot;
fido_cred_pubkey_len;
fido_cred_pubkey_ptr;
fido_cred_rp_id;
fido_cred_rp_name;
+ fido_cred_set_attstmt;
fido_cred_set_authdata;
fido_cred_set_authdata_raw;
fido_cred_set_blob;
+ fido_cred_set_clientdata;
fido_cred_set_clientdata_hash;
fido_cred_set_extensions;
fido_cred_set_fmt;
fido_cred_set_id;
fido_cred_set_options;
+ fido_cred_set_pin_minlen;
fido_cred_set_prot;
fido_cred_set_rk;
fido_cred_set_rp;
@@ -205,6 +213,8 @@
fido_dev_set_io_functions;
fido_dev_set_pin;
fido_dev_set_pin_minlen;
+ fido_dev_set_pin_minlen_rpid;
+ fido_dev_set_timeout;
fido_dev_set_transport_functions;
fido_dev_supports_cred_prot;
fido_dev_supports_credman;
@@ -230,10 +240,12 @@
fido_strerr;
rs256_pk_free;
rs256_pk_from_ptr;
+ rs256_pk_from_EVP_PKEY;
rs256_pk_from_RSA;
rs256_pk_new;
rs256_pk_to_EVP_PKEY;
prng_init;
+ fuzz_clock_reset;
set_netlink_io_functions;
set_udev_parameters;
uniform_random;
diff --git a/contrib/libfido2/fuzz/functions.txt b/contrib/libfido2/fuzz/functions.txt
index 28fe4f6af17b..886893b1d11d 100644
--- a/contrib/libfido2/fuzz/functions.txt
+++ b/contrib/libfido2/fuzz/functions.txt
@@ -1,285 +1,286 @@
File '/libfido2/src/aes256.c':
Name Regions Miss Cover Lines Miss Cover
-------------------------------------------------------------------------------
+--------------------------------------------------------------------------------------------------------
aes256_cbc_enc 3 0 100.00% 4 0 100.00%
aes256_cbc_dec 3 0 100.00% 4 0 100.00%
aes256_gcm_enc 1 0 100.00% 3 0 100.00%
aes256_gcm_dec 1 0 100.00% 3 0 100.00%
-aes256.c:aes256_cbc_fips 26 2 92.31% 45 7 84.44%
-aes256.c:aes256_cbc 29 1 96.55% 40 3 92.50%
-aes256.c:aes256_cbc_proto1 1 0 100.00% 7 0 100.00%
-aes256.c:aes256_gcm 51 1 98.04% 69 4 94.20%
-------------------------------------------------------------------------------
-TOTAL 115 4 96.52% 175 14 92.00%
+aes256.c:aes256_cbc_fips 26 2 92.31% 42 7 83.33%
+aes256.c:aes256_cbc 29 1 96.55% 36 3 91.67%
+aes256.c:aes256_cbc_proto1 1 0 100.00% 5 0 100.00%
+aes256.c:aes256_gcm 51 1 98.04% 60 4 93.33%
+--------------------------------------------------------------------------------------------------------
+TOTAL 115 4 96.52% 157 14 91.08%
File '/libfido2/src/assert.c':
Name Regions Miss Cover Lines Miss Cover
----------------------------------------------------------------------------------------
-fido_dev_get_assert 40 0 100.00% 41 0 100.00%
-fido_check_flags 13 0 100.00% 18 0 100.00%
-fido_get_signed_hash 32 0 100.00% 46 0 100.00%
-fido_verify_sig_es256 17 2 88.24% 31 7 77.42%
-fido_verify_sig_rs256 17 2 88.24% 31 7 77.42%
-fido_verify_sig_eddsa 23 2 91.30% 43 7 83.72%
-fido_assert_verify 48 4 91.67% 79 5 93.67%
-fido_assert_set_clientdata 12 12 0.00% 12 12 0.00%
-fido_assert_set_clientdata_hash 8 0 100.00% 7 0 100.00%
-fido_assert_set_hmac_salt 10 0 100.00% 7 0 100.00%
-fido_assert_set_hmac_secret 12 12 0.00% 8 8 0.00%
-fido_assert_set_rp 12 0 100.00% 14 0 100.00%
-fido_assert_allow_cred 13 2 84.62% 29 3 89.66%
-fido_assert_set_extensions 14 0 100.00% 11 0 100.00%
-fido_assert_set_options 6 6 0.00% 6 6 0.00%
-fido_assert_set_up 2 0 100.00% 5 0 100.00%
-fido_assert_set_uv 2 0 100.00% 5 0 100.00%
+-----------------------------------------------------------------------------------------------------------------
+fido_dev_get_assert 40 0 100.00% 35 0 100.00%
+fido_check_flags 13 0 100.00% 15 0 100.00%
+fido_get_signed_hash 36 0 100.00% 46 0 100.00%
+fido_assert_verify 48 4 91.67% 67 5 92.54%
+fido_assert_set_clientdata 12 12 0.00% 11 11 0.00%
+fido_assert_set_clientdata_hash 8 0 100.00% 6 0 100.00%
+fido_assert_set_hmac_salt 10 0 100.00% 6 0 100.00%
+fido_assert_set_hmac_secret 12 12 0.00% 7 7 0.00%
+fido_assert_set_rp 12 0 100.00% 11 0 100.00%
+fido_assert_allow_cred 13 2 84.62% 22 3 86.36%
+fido_assert_set_extensions 14 0 100.00% 10 0 100.00%
+fido_assert_set_options 6 6 0.00% 5 5 0.00%
+fido_assert_set_up 2 0 100.00% 4 0 100.00%
+fido_assert_set_uv 2 0 100.00% 4 0 100.00%
fido_assert_clientdata_hash_ptr 1 0 100.00% 3 0 100.00%
fido_assert_clientdata_hash_len 1 0 100.00% 3 0 100.00%
fido_assert_new 1 0 100.00% 3 0 100.00%
fido_assert_reset_tx 1 0 100.00% 12 0 100.00%
fido_assert_reset_rx 4 0 100.00% 19 0 100.00%
-fido_assert_free 6 0 100.00% 10 0 100.00%
+fido_assert_free 6 0 100.00% 9 0 100.00%
fido_assert_count 1 0 100.00% 3 0 100.00%
fido_assert_rp_id 1 0 100.00% 3 0 100.00%
-fido_assert_flags 4 0 100.00% 6 0 100.00%
-fido_assert_sigcount 4 0 100.00% 6 0 100.00%
-fido_assert_authdata_ptr 4 0 100.00% 6 0 100.00%
-fido_assert_authdata_len 4 0 100.00% 6 0 100.00%
-fido_assert_sig_ptr 4 0 100.00% 6 0 100.00%
-fido_assert_sig_len 4 0 100.00% 6 0 100.00%
-fido_assert_id_ptr 4 0 100.00% 6 0 100.00%
-fido_assert_id_len 4 0 100.00% 6 0 100.00%
-fido_assert_user_id_ptr 4 0 100.00% 6 0 100.00%
-fido_assert_user_id_len 4 0 100.00% 6 0 100.00%
-fido_assert_user_icon 4 0 100.00% 6 0 100.00%
-fido_assert_user_name 4 0 100.00% 6 0 100.00%
-fido_assert_user_display_name 4 0 100.00% 6 0 100.00%
-fido_assert_hmac_secret_ptr 4 0 100.00% 6 0 100.00%
-fido_assert_hmac_secret_len 4 0 100.00% 6 0 100.00%
-fido_assert_largeblob_key_ptr 4 0 100.00% 6 0 100.00%
-fido_assert_largeblob_key_len 4 0 100.00% 6 0 100.00%
-fido_assert_blob_ptr 4 0 100.00% 6 0 100.00%
-fido_assert_blob_len 4 0 100.00% 6 0 100.00%
-fido_assert_set_authdata 24 0 100.00% 35 0 100.00%
-fido_assert_set_authdata_raw 24 0 100.00% 34 0 100.00%
-fido_assert_set_sig 14 0 100.00% 8 0 100.00%
-fido_assert_set_count 10 0 100.00% 21 0 100.00%
-assert.c:fido_dev_get_assert_wait 21 0 100.00% 16 0 100.00%
-assert.c:fido_dev_get_assert_tx 56 2 96.43% 77 5 93.51%
-assert.c:fido_dev_get_assert_rx 19 0 100.00% 38 0 100.00%
-assert.c:adjust_assert_count 24 0 100.00% 33 0 100.00%
-assert.c:parse_assert_reply 12 0 100.00% 26 0 100.00%
-assert.c:fido_get_next_assert_tx 8 0 100.00% 10 0 100.00%
-assert.c:fido_get_next_assert_rx 15 2 86.67% 26 4 84.62%
-assert.c:decrypt_hmac_secrets 9 0 100.00% 16 0 100.00%
-assert.c:check_extensions 5 0 100.00% 11 0 100.00%
+fido_assert_flags 4 0 100.00% 5 0 100.00%
+fido_assert_sigcount 4 0 100.00% 5 0 100.00%
+fido_assert_authdata_ptr 4 0 100.00% 5 0 100.00%
+fido_assert_authdata_len 4 0 100.00% 5 0 100.00%
+fido_assert_sig_ptr 4 0 100.00% 5 0 100.00%
+fido_assert_sig_len 4 0 100.00% 5 0 100.00%
+fido_assert_id_ptr 4 0 100.00% 5 0 100.00%
+fido_assert_id_len 4 0 100.00% 5 0 100.00%
+fido_assert_user_id_ptr 4 0 100.00% 5 0 100.00%
+fido_assert_user_id_len 4 0 100.00% 5 0 100.00%
+fido_assert_user_icon 4 0 100.00% 5 0 100.00%
+fido_assert_user_name 4 0 100.00% 5 0 100.00%
+fido_assert_user_display_name 4 0 100.00% 5 0 100.00%
+fido_assert_hmac_secret_ptr 4 0 100.00% 5 0 100.00%
+fido_assert_hmac_secret_len 4 0 100.00% 5 0 100.00%
+fido_assert_largeblob_key_ptr 4 0 100.00% 5 0 100.00%
+fido_assert_largeblob_key_len 4 0 100.00% 5 0 100.00%
+fido_assert_blob_ptr 4 0 100.00% 5 0 100.00%
+fido_assert_blob_len 4 0 100.00% 5 0 100.00%
+fido_assert_set_authdata 24 0 100.00% 28 0 100.00%
+fido_assert_set_authdata_raw 24 0 100.00% 27 0 100.00%
+fido_assert_set_sig 14 0 100.00% 7 0 100.00%
+fido_assert_set_count 10 0 100.00% 17 0 100.00%
+assert.c:fido_dev_get_assert_wait 21 0 100.00% 14 0 100.00%
+assert.c:fido_dev_get_assert_tx 56 2 96.43% 62 5 91.94%
+assert.c:fido_dev_get_assert_rx 19 0 100.00% 27 0 100.00%
+assert.c:adjust_assert_count 24 0 100.00% 26 0 100.00%
+assert.c:parse_assert_reply 12 0 100.00% 24 0 100.00%
+assert.c:fido_get_next_assert_tx 8 0 100.00% 8 0 100.00%
+assert.c:fido_get_next_assert_rx 15 2 86.67% 21 4 80.95%
+assert.c:decrypt_hmac_secrets 9 0 100.00% 15 0 100.00%
+assert.c:check_extensions 5 0 100.00% 9 0 100.00%
assert.c:fido_assert_reset_extattr 1 0 100.00% 5 0 100.00%
assert.c:fido_assert_clean_authdata 1 0 100.00% 5 0 100.00%
----------------------------------------------------------------------------------------
-TOTAL 616 46 92.53% 924 64 93.07%
+-----------------------------------------------------------------------------------------------------------------
+TOTAL 563 40 92.90% 694 40 94.24%
File '/libfido2/src/authkey.c':
Name Regions Miss Cover Lines Miss Cover
----------------------------------------------------------------------------------------
+-----------------------------------------------------------------------------------------------------------------
fido_dev_authkey 1 0 100.00% 3 0 100.00%
-authkey.c:fido_dev_authkey_wait 10 0 100.00% 9 0 100.00%
-authkey.c:fido_dev_authkey_tx 19 0 100.00% 33 0 100.00%
-authkey.c:fido_dev_authkey_rx 6 0 100.00% 18 0 100.00%
-authkey.c:parse_authkey 8 0 100.00% 12 0 100.00%
----------------------------------------------------------------------------------------
-TOTAL 44 0 100.00% 75 0 100.00%
+authkey.c:fido_dev_authkey_wait 10 0 100.00% 7 0 100.00%
+authkey.c:fido_dev_authkey_tx 19 0 100.00% 25 0 100.00%
+authkey.c:fido_dev_authkey_rx 6 0 100.00% 14 0 100.00%
+authkey.c:parse_authkey 8 0 100.00% 10 0 100.00%
+-----------------------------------------------------------------------------------------------------------------
+TOTAL 44 0 100.00% 59 0 100.00%
File '/libfido2/src/bio.c':
Name Regions Miss Cover Lines Miss Cover
----------------------------------------------------------------------------------------
+-----------------------------------------------------------------------------------------------------------------
fido_bio_dev_get_template_array 5 2 60.00% 6 0 100.00%
fido_bio_dev_set_template_name 7 0 100.00% 6 0 100.00%
-fido_bio_dev_enroll_begin 25 2 92.00% 37 0 100.00%
+fido_bio_dev_enroll_begin 25 2 92.00% 31 0 100.00%
fido_bio_dev_enroll_continue 5 2 60.00% 6 0 100.00%
-fido_bio_dev_enroll_cancel 1 1 0.00% 3 3 0.00%
-fido_bio_dev_enroll_remove 1 0 100.00% 3 0 100.00%
-fido_bio_dev_get_info 1 0 100.00% 3 0 100.00%
+fido_bio_dev_enroll_cancel 1 1 0.00% 4 4 0.00%
+fido_bio_dev_enroll_remove 1 0 100.00% 4 0 100.00%
+fido_bio_dev_get_info 1 0 100.00% 4 0 100.00%
fido_bio_template_name 1 0 100.00% 3 0 100.00%
fido_bio_template_id_ptr 1 0 100.00% 3 0 100.00%
fido_bio_template_id_len 1 0 100.00% 3 0 100.00%
fido_bio_template_array_count 1 0 100.00% 3 0 100.00%
fido_bio_template_array_new 1 0 100.00% 3 0 100.00%
fido_bio_template_new 1 0 100.00% 3 0 100.00%
-fido_bio_template_array_free 6 0 100.00% 10 0 100.00%
-fido_bio_template_free 6 0 100.00% 10 0 100.00%
-fido_bio_template_set_name 8 0 100.00% 9 0 100.00%
-fido_bio_template_set_id 8 0 100.00% 8 0 100.00%
-fido_bio_template 4 0 100.00% 6 0 100.00%
+fido_bio_template_array_free 6 0 100.00% 8 0 100.00%
+fido_bio_template_free 6 0 100.00% 8 0 100.00%
+fido_bio_template_set_name 8 0 100.00% 7 0 100.00%
+fido_bio_template_set_id 8 0 100.00% 6 0 100.00%
+fido_bio_template 4 0 100.00% 5 0 100.00%
fido_bio_enroll_new 1 0 100.00% 3 0 100.00%
fido_bio_info_new 1 0 100.00% 3 0 100.00%
fido_bio_info_type 1 0 100.00% 3 0 100.00%
fido_bio_info_max_samples 1 0 100.00% 3 0 100.00%
-fido_bio_enroll_free 6 0 100.00% 11 0 100.00%
-fido_bio_info_free 6 0 100.00% 9 0 100.00%
+fido_bio_enroll_free 6 0 100.00% 8 0 100.00%
+fido_bio_info_free 6 0 100.00% 7 0 100.00%
fido_bio_enroll_remaining_samples 1 0 100.00% 3 0 100.00%
fido_bio_enroll_last_status 1 0 100.00% 3 0 100.00%
-bio.c:bio_get_template_array_wait 11 0 100.00% 9 0 100.00%
-bio.c:bio_tx 43 0 100.00% 66 0 100.00%
-bio.c:bio_prepare_hmac 18 0 100.00% 36 0 100.00%
-bio.c:bio_rx_template_array 11 0 100.00% 21 0 100.00%
-bio.c:bio_parse_template_array 26 1 96.15% 34 4 88.24%
-bio.c:decode_template_array 12 1 91.67% 23 3 86.96%
-bio.c:decode_template 9 0 100.00% 18 0 100.00%
-bio.c:bio_set_template_name_wait 19 0 100.00% 24 0 100.00%
-bio.c:bio_enroll_begin_wait 17 0 100.00% 24 0 100.00%
-bio.c:bio_rx_enroll_begin 15 0 100.00% 29 0 100.00%
-bio.c:bio_parse_enroll_status 20 0 100.00% 31 0 100.00%
-bio.c:bio_parse_template_id 8 0 100.00% 12 0 100.00%
-bio.c:bio_enroll_continue_wait 19 0 100.00% 25 0 100.00%
-bio.c:bio_rx_enroll_continue 11 0 100.00% 22 0 100.00%
-bio.c:bio_enroll_cancel_wait 11 11 0.00% 12 12 0.00%
-bio.c:bio_enroll_remove_wait 17 0 100.00% 24 0 100.00%
-bio.c:bio_get_info_wait 11 0 100.00% 11 0 100.00%
-bio.c:bio_rx_info 11 0 100.00% 21 0 100.00%
+bio.c:bio_get_template_array_wait 11 0 100.00% 7 0 100.00%
+bio.c:bio_tx 43 0 100.00% 55 0 100.00%
+bio.c:bio_prepare_hmac 18 0 100.00% 29 0 100.00%
+bio.c:bio_rx_template_array 11 0 100.00% 17 0 100.00%
+bio.c:bio_parse_template_array 26 1 96.15% 27 4 85.19%
+bio.c:decode_template_array 12 1 91.67% 18 3 83.33%
+bio.c:decode_template 9 0 100.00% 15 0 100.00%
+bio.c:bio_set_template_name_wait 19 0 100.00% 20 0 100.00%
+bio.c:bio_enroll_begin_wait 17 0 100.00% 19 0 100.00%
+bio.c:bio_rx_enroll_begin 15 0 100.00% 24 0 100.00%
+bio.c:bio_parse_enroll_status 20 0 100.00% 28 0 100.00%
+bio.c:bio_parse_template_id 8 0 100.00% 10 0 100.00%
+bio.c:bio_enroll_continue_wait 19 0 100.00% 20 0 100.00%
+bio.c:bio_rx_enroll_continue 11 0 100.00% 18 0 100.00%
+bio.c:bio_enroll_cancel_wait 11 11 0.00% 10 10 0.00%
+bio.c:bio_enroll_remove_wait 17 0 100.00% 19 0 100.00%
+bio.c:bio_get_info_wait 11 0 100.00% 10 0 100.00%
+bio.c:bio_rx_info 11 0 100.00% 17 0 100.00%
bio.c:bio_reset_info 1 0 100.00% 4 0 100.00%
-bio.c:bio_parse_info 20 0 100.00% 31 0 100.00%
-bio.c:bio_reset_template_array 4 0 100.00% 8 0 100.00%
+bio.c:bio_parse_info 20 0 100.00% 28 0 100.00%
+bio.c:bio_reset_template_array 4 0 100.00% 7 0 100.00%
bio.c:bio_reset_template 1 0 100.00% 5 0 100.00%
-bio.c:bio_reset_enroll 3 0 100.00% 7 0 100.00%
----------------------------------------------------------------------------------------
-TOTAL 419 20 95.23% 660 22 96.67%
+bio.c:bio_reset_enroll 3 0 100.00% 6 0 100.00%
+-----------------------------------------------------------------------------------------------------------------
+TOTAL 419 20 95.23% 559 21 96.24%
File '/libfido2/src/blob.c':
Name Regions Miss Cover Lines Miss Cover
----------------------------------------------------------------------------------------
+-----------------------------------------------------------------------------------------------------------------
fido_blob_new 1 0 100.00% 3 0 100.00%
fido_blob_reset 1 0 100.00% 4 0 100.00%
-fido_blob_set 9 0 100.00% 19 0 100.00%
-fido_blob_append 12 2 83.33% 22 6 72.73%
-fido_blob_free 6 0 100.00% 10 0 100.00%
-fido_free_blob_array 7 0 100.00% 14 0 100.00%
-fido_blob_encode 6 0 100.00% 6 0 100.00%
+fido_blob_set 9 0 100.00% 15 0 100.00%
+fido_blob_append 12 1 91.67% 20 3 85.00%
+fido_blob_free 6 0 100.00% 8 0 100.00%
+fido_free_blob_array 7 0 100.00% 12 0 100.00%
+fido_blob_encode 6 0 100.00% 5 0 100.00%
fido_blob_decode 1 0 100.00% 3 0 100.00%
fido_blob_is_empty 3 0 100.00% 3 0 100.00%
-fido_blob_serialise 7 1 85.71% 12 1 91.67%
----------------------------------------------------------------------------------------
-TOTAL 53 3 94.34% 96 7 92.71%
+fido_blob_serialise 7 1 85.71% 10 1 90.00%
+-----------------------------------------------------------------------------------------------------------------
+TOTAL 53 2 96.23% 83 4 95.18%
File '/libfido2/src/buf.c':
Name Regions Miss Cover Lines Miss Cover
----------------------------------------------------------------------------------------
-fido_buf_read 4 0 100.00% 10 0 100.00%
-fido_buf_write 4 1 75.00% 10 1 90.00%
----------------------------------------------------------------------------------------
-TOTAL 8 1 87.50% 20 1 95.00%
+-----------------------------------------------------------------------------------------------------------------
+fido_buf_read 4 0 100.00% 8 0 100.00%
+fido_buf_write 4 1 75.00% 8 1 87.50%
+-----------------------------------------------------------------------------------------------------------------
+TOTAL 8 1 87.50% 16 1 93.75%
File '/libfido2/src/cbor.c':
Name Regions Miss Cover Lines Miss Cover
-----------------------------------------------------------------------------------------
-cbor_map_iter 20 1 95.00% 30 4 86.67%
-cbor_array_iter 12 0 100.00% 20 0 100.00%
-cbor_parse_reply 27 0 100.00% 43 0 100.00%
+------------------------------------------------------------------------------------------------------------------
+cbor_map_iter 20 1 95.00% 26 4 84.62%
+cbor_array_iter 12 0 100.00% 16 0 100.00%
+cbor_parse_reply 27 0 100.00% 36 0 100.00%
cbor_vector_free 6 0 100.00% 5 0 100.00%
-cbor_bytestring_copy 14 0 100.00% 22 0 100.00%
-cbor_string_copy 14 0 100.00% 23 0 100.00%
-cbor_add_bytestring 14 0 100.00% 26 0 100.00%
-cbor_add_string 14 0 100.00% 26 0 100.00%
-cbor_add_bool 14 0 100.00% 26 0 100.00%
-cbor_flatten_vector 14 1 92.86% 21 1 95.24%
-cbor_build_frame 15 0 100.00% 32 0 100.00%
-cbor_encode_rp_entity 13 0 100.00% 14 0 100.00%
-cbor_encode_user_entity 21 0 100.00% 18 0 100.00%
-cbor_encode_pubkey_param 36 0 100.00% 48 0 100.00%
-cbor_encode_pubkey 10 0 100.00% 13 0 100.00%
-cbor_encode_pubkey_list 18 0 100.00% 23 0 100.00%
-cbor_encode_cred_ext 46 0 100.00% 46 0 100.00%
-cbor_encode_cred_opt 13 0 100.00% 13 0 100.00%
-cbor_encode_assert_opt 13 0 100.00% 13 0 100.00%
-cbor_encode_pin_auth 20 1 95.00% 30 3 90.00%
-cbor_encode_pin_opt 4 0 100.00% 10 0 100.00%
-cbor_encode_change_pin_auth 33 1 96.97% 49 3 93.88%
-cbor_encode_assert_ext 33 0 100.00% 35 0 100.00%
-cbor_decode_fmt 11 0 100.00% 19 0 100.00%
-cbor_decode_pubkey 21 1 95.24% 32 2 93.75%
-cbor_decode_cred_authdata 31 1 96.77% 45 3 93.33%
-cbor_decode_assert_authdata 21 0 100.00% 42 0 100.00%
-cbor_decode_attstmt 8 0 100.00% 10 0 100.00%
-cbor_decode_uint64 4 0 100.00% 10 0 100.00%
-cbor_decode_cred_id 8 0 100.00% 10 0 100.00%
-cbor_decode_user 8 0 100.00% 10 0 100.00%
-cbor_decode_rp_entity 8 0 100.00% 10 0 100.00%
-cbor_build_uint 10 4 60.00% 10 5 50.00%
-cbor_array_append 17 0 100.00% 23 0 100.00%
-cbor_array_drop 18 2 88.89% 19 3 84.21%
-cbor.c:ctap_check_cbor 28 0 100.00% 32 0 100.00%
-cbor.c:check_key_type 8 0 100.00% 9 0 100.00%
-cbor.c:cbor_add_arg 13 0 100.00% 28 0 100.00%
-cbor.c:cbor_add_uint8 14 0 100.00% 26 0 100.00%
-cbor.c:cbor_encode_largeblob_key_ext 6 0 100.00% 7 0 100.00%
-cbor.c:cbor_encode_hmac_secret_param 53 2 96.23% 75 4 94.67%
-cbor.c:get_cose_alg 36 0 100.00% 48 0 100.00%
-cbor.c:find_cose_alg 35 0 100.00% 40 0 100.00%
-cbor.c:decode_attcred 25 0 100.00% 56 0 100.00%
-cbor.c:decode_cred_extensions 14 0 100.00% 31 0 100.00%
-cbor.c:decode_cred_extension 40 3 92.50% 45 9 80.00%
-cbor.c:decode_assert_extensions 14 0 100.00% 29 0 100.00%
-cbor.c:decode_assert_extension 19 0 100.00% 31 0 100.00%
-cbor.c:decode_attstmt_entry 38 0 100.00% 44 0 100.00%
-cbor.c:decode_x5c 4 0 100.00% 8 0 100.00%
-cbor.c:decode_cred_id_entry 10 0 100.00% 23 0 100.00%
-cbor.c:decode_user_entry 25 0 100.00% 39 0 100.00%
-cbor.c:decode_rp_entity_entry 15 0 100.00% 29 0 100.00%
-----------------------------------------------------------------------------------------
-TOTAL 986 17 98.28% 1426 37 97.41%
+cbor_bytestring_copy 14 0 100.00% 18 0 100.00%
+cbor_string_copy 14 1 92.86% 18 3 83.33%
+cbor_add_bytestring 14 0 100.00% 21 0 100.00%
+cbor_add_string 14 0 100.00% 21 0 100.00%
+cbor_add_bool 14 0 100.00% 21 0 100.00%
+cbor_flatten_vector 14 1 92.86% 16 1 93.75%
+cbor_build_frame 15 0 100.00% 25 0 100.00%
+cbor_encode_rp_entity 13 0 100.00% 11 0 100.00%
+cbor_encode_user_entity 21 0 100.00% 15 0 100.00%
+cbor_encode_pubkey_param 36 0 100.00% 39 0 100.00%
+cbor_encode_pubkey 10 0 100.00% 11 0 100.00%
+cbor_encode_pubkey_list 18 0 100.00% 19 0 100.00%
+cbor_encode_str_array 18 0 100.00% 19 0 100.00%
+cbor_encode_cred_ext 55 0 100.00% 50 0 100.00%
+cbor_encode_cred_opt 13 0 100.00% 11 0 100.00%
+cbor_encode_assert_opt 13 0 100.00% 11 0 100.00%
+cbor_encode_pin_auth 20 1 95.00% 22 3 86.36%
+cbor_encode_pin_opt 4 0 100.00% 8 0 100.00%
+cbor_encode_change_pin_auth 31 1 96.77% 36 3 91.67%
+cbor_encode_assert_ext 33 0 100.00% 32 0 100.00%
+cbor_decode_fmt 13 0 100.00% 15 0 100.00%
+cbor_decode_pubkey 21 1 95.24% 30 2 93.33%
+cbor_decode_cred_authdata 31 1 96.77% 35 3 91.43%
+cbor_decode_assert_authdata 21 0 100.00% 32 0 100.00%
+cbor_decode_attstmt 13 0 100.00% 16 0 100.00%
+cbor_decode_uint64 4 0 100.00% 8 0 100.00%
+cbor_decode_cred_id 8 0 100.00% 9 0 100.00%
+cbor_decode_user 8 0 100.00% 9 0 100.00%
+cbor_decode_rp_entity 8 0 100.00% 9 0 100.00%
+cbor_build_uint 10 4 60.00% 9 4 55.56%
+cbor_array_append 17 0 100.00% 21 0 100.00%
+cbor_array_drop 18 2 88.89% 17 3 82.35%
+cbor.c:ctap_check_cbor 28 0 100.00% 26 0 100.00%
+cbor.c:check_key_type 8 0 100.00% 7 0 100.00%
+cbor.c:cbor_add_arg 13 0 100.00% 21 0 100.00%
+cbor.c:cbor_add_uint8 14 0 100.00% 21 0 100.00%
+cbor.c:cbor_encode_largeblob_key_ext 6 0 100.00% 6 0 100.00%
+cbor.c:cbor_encode_hmac_secret_param 59 4 93.22% 66 8 87.88%
+cbor.c:get_cose_alg 36 1 97.22% 38 3 92.11%
+cbor.c:find_cose_alg 35 0 100.00% 33 0 100.00%
+cbor.c:decode_attcred 25 0 100.00% 44 0 100.00%
+cbor.c:decode_cred_extensions 14 0 100.00% 24 0 100.00%
+cbor.c:decode_cred_extension 49 10 79.59% 49 17 65.31%
+cbor.c:decode_assert_extensions 14 0 100.00% 23 0 100.00%
+cbor.c:decode_assert_extension 19 0 100.00% 27 0 100.00%
+cbor.c:decode_attstmt_entry 52 0 100.00% 50 0 100.00%
+cbor.c:decode_x5c 4 0 100.00% 6 0 100.00%
+cbor.c:decode_cred_id_entry 10 0 100.00% 19 0 100.00%
+cbor.c:decode_user_entry 25 0 100.00% 35 0 100.00%
+cbor.c:decode_rp_entity_entry 15 0 100.00% 25 0 100.00%
+------------------------------------------------------------------------------------------------------------------
+TOTAL 1047 28 97.33% 1237 54 95.63%
File '/libfido2/src/compress.c':
Name Regions Miss Cover Lines Miss Cover
-----------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------------------------------
fido_compress 1 0 100.00% 3 0 100.00%
fido_uncompress 1 0 100.00% 3 0 100.00%
-compress.c:do_compress 32 4 87.50% 24 3 87.50%
-----------------------------------------------------------------------------------------
-TOTAL 34 4 88.24% 30 3 90.00%
+compress.c:do_compress 32 4 87.50% 22 3 86.36%
+------------------------------------------------------------------------------------------------------------------
+TOTAL 34 4 88.24% 28 3 89.29%
File '/libfido2/src/config.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
-fido_dev_enable_entattest 1 0 100.00% 3 0 100.00%
-fido_dev_toggle_always_uv 1 0 100.00% 3 0 100.00%
-fido_dev_set_pin_minlen 1 0 100.00% 3 0 100.00%
-fido_dev_force_pin_change 1 0 100.00% 3 0 100.00%
-config.c:config_enable_entattest_wait 6 0 100.00% 8 0 100.00%
-config.c:config_tx 37 0 100.00% 57 0 100.00%
-config.c:config_prepare_hmac 8 1 87.50% 22 3 86.36%
-config.c:config_toggle_always_uv_wait 6 0 100.00% 8 0 100.00%
-config.c:config_pin_minlen 5 0 100.00% 8 0 100.00%
-config.c:config_pin_minlen_tx 28 0 100.00% 31 0 100.00%
------------------------------------------------------------------------------------------
-TOTAL 94 1 98.94% 146 3 97.95%
+-------------------------------------------------------------------------------------------------------------------
+fido_dev_enable_entattest 1 0 100.00% 4 0 100.00%
+fido_dev_toggle_always_uv 1 0 100.00% 4 0 100.00%
+fido_dev_set_pin_minlen 1 0 100.00% 4 0 100.00%
+fido_dev_force_pin_change 1 0 100.00% 4 0 100.00%
+fido_dev_set_pin_minlen_rpid 6 0 100.00% 15 0 100.00%
+config.c:config_enable_entattest_wait 6 0 100.00% 7 0 100.00%
+config.c:config_tx 37 0 100.00% 48 0 100.00%
+config.c:config_prepare_hmac 8 0 100.00% 19 0 100.00%
+config.c:config_toggle_always_uv_wait 6 0 100.00% 7 0 100.00%
+config.c:config_pin_minlen 5 0 100.00% 7 0 100.00%
+config.c:config_pin_minlen_tx 36 0 100.00% 32 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 108 0 100.00% 151 0 100.00%
File '/libfido2/src/cred.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------
fido_dev_make_cred 12 0 100.00% 10 0 100.00%
-fido_check_rp_id 4 0 100.00% 14 0 100.00%
-fido_cred_verify 50 4 92.00% 75 8 89.33%
-fido_cred_verify_self 58 6 89.66% 94 10 89.36%
+fido_check_rp_id 4 0 100.00% 11 0 100.00%
+fido_cred_verify 56 2 96.43% 72 5 93.06%
+fido_cred_verify_self 58 4 93.10% 83 5 93.98%
fido_cred_new 1 0 100.00% 3 0 100.00%
-fido_cred_reset_tx 1 0 100.00% 22 0 100.00%
-fido_cred_reset_rx 1 0 100.00% 8 0 100.00%
-fido_cred_free 6 0 100.00% 10 0 100.00%
-fido_cred_set_authdata 23 0 100.00% 37 0 100.00%
-fido_cred_set_authdata_raw 25 0 100.00% 38 0 100.00%
-fido_cred_set_id 6 0 100.00% 6 0 100.00%
-fido_cred_set_x509 6 0 100.00% 6 0 100.00%
-fido_cred_set_sig 6 0 100.00% 6 0 100.00%
-fido_cred_exclude 14 2 85.71% 25 3 88.00%
-fido_cred_set_clientdata 12 12 0.00% 12 12 0.00%
-fido_cred_set_clientdata_hash 8 0 100.00% 7 0 100.00%
-fido_cred_set_rp 18 0 100.00% 26 0 100.00%
-fido_cred_set_user 32 0 100.00% 46 0 100.00%
-fido_cred_set_extensions 15 0 100.00% 11 0 100.00%
-fido_cred_set_options 6 6 0.00% 6 6 0.00%
-fido_cred_set_rk 2 0 100.00% 5 0 100.00%
-fido_cred_set_uv 2 0 100.00% 5 0 100.00%
-fido_cred_set_prot 21 0 100.00% 16 0 100.00%
-fido_cred_set_blob 13 2 84.62% 10 1 90.00%
-fido_cred_set_fmt 18 4 77.78% 16 1 93.75%
-fido_cred_set_type 17 0 100.00% 9 0 100.00%
+fido_cred_reset_tx 1 0 100.00% 19 0 100.00%
+fido_cred_reset_rx 1 0 100.00% 7 0 100.00%
+fido_cred_free 6 0 100.00% 9 0 100.00%
+fido_cred_set_authdata 23 0 100.00% 28 0 100.00%
+fido_cred_set_authdata_raw 25 0 100.00% 29 0 100.00%
+fido_cred_set_id 6 0 100.00% 5 0 100.00%
+fido_cred_set_x509 6 0 100.00% 5 0 100.00%
+fido_cred_set_sig 6 0 100.00% 5 0 100.00%
+fido_cred_set_attstmt 20 0 100.00% 23 0 100.00%
+fido_cred_exclude 14 2 85.71% 19 3 84.21%
+fido_cred_set_clientdata 12 12 0.00% 11 11 0.00%
+fido_cred_set_clientdata_hash 8 0 100.00% 6 0 100.00%
+fido_cred_set_rp 18 0 100.00% 22 0 100.00%
+fido_cred_set_user 32 0 100.00% 41 0 100.00%
+fido_cred_set_extensions 16 0 100.00% 10 0 100.00%
+fido_cred_set_options 6 6 0.00% 5 5 0.00%
+fido_cred_set_rk 2 0 100.00% 4 0 100.00%
+fido_cred_set_uv 2 0 100.00% 4 0 100.00%
+fido_cred_set_prot 21 0 100.00% 14 0 100.00%
+fido_cred_set_pin_minlen 7 0 100.00% 8 0 100.00%
+fido_cred_set_blob 13 2 84.62% 8 1 87.50%
+fido_cred_set_fmt 20 4 80.00% 12 1 91.67%
+fido_cred_set_type 17 0 100.00% 7 0 100.00%
fido_cred_type 1 0 100.00% 3 0 100.00%
fido_cred_flags 1 0 100.00% 3 0 100.00%
fido_cred_sigcount 1 0 100.00% 3 0 100.00%
@@ -293,13 +294,16 @@ fido_cred_authdata_ptr 1 0 100.00% 3
fido_cred_authdata_len 1 0 100.00% 3 0 100.00%
fido_cred_authdata_raw_ptr 1 0 100.00% 3 0 100.00%
fido_cred_authdata_raw_len 1 0 100.00% 3 0 100.00%
-fido_cred_pubkey_ptr 9 0 100.00% 20 0 100.00%
-fido_cred_pubkey_len 9 0 100.00% 20 0 100.00%
+fido_cred_attstmt_ptr 1 0 100.00% 3 0 100.00%
+fido_cred_attstmt_len 1 0 100.00% 3 0 100.00%
+fido_cred_pubkey_ptr 9 0 100.00% 18 0 100.00%
+fido_cred_pubkey_len 9 0 100.00% 18 0 100.00%
fido_cred_id_ptr 1 0 100.00% 3 0 100.00%
fido_cred_id_len 1 0 100.00% 3 0 100.00%
fido_cred_aaguid_ptr 1 0 100.00% 3 0 100.00%
fido_cred_aaguid_len 1 0 100.00% 3 0 100.00%
fido_cred_prot 1 0 100.00% 3 0 100.00%
+fido_cred_pin_minlen 1 0 100.00% 3 0 100.00%
fido_cred_fmt 1 0 100.00% 3 0 100.00%
fido_cred_rp_id 1 0 100.00% 3 0 100.00%
fido_cred_rp_name 1 0 100.00% 3 0 100.00%
@@ -309,82 +313,83 @@ fido_cred_user_id_ptr 1 0 100.00% 3
fido_cred_user_id_len 1 0 100.00% 3 0 100.00%
fido_cred_largeblob_key_ptr 1 0 100.00% 3 0 100.00%
fido_cred_largeblob_key_len 1 0 100.00% 3 0 100.00%
-cred.c:fido_dev_make_cred_wait 10 0 100.00% 9 0 100.00%
-cred.c:fido_dev_make_cred_tx 64 0 100.00% 85 0 100.00%
-cred.c:fido_dev_make_cred_rx 19 0 100.00% 27 0 100.00%
-cred.c:parse_makecred_reply 14 0 100.00% 29 0 100.00%
-cred.c:check_extensions 2 0 100.00% 9 0 100.00%
-cred.c:get_signed_hash_u2f 22 0 100.00% 20 0 100.00%
-cred.c:verify_sig 27 2 92.59% 40 7 82.50%
-cred.c:fido_cred_clean_authdata 1 0 100.00% 9 0 100.00%
------------------------------------------------------------------------------------------
-TOTAL 581 38 93.46% 872 48 94.50%
+cred.c:fido_dev_make_cred_wait 10 0 100.00% 7 0 100.00%
+cred.c:fido_dev_make_cred_tx 64 0 100.00% 70 0 100.00%
+cred.c:fido_dev_make_cred_rx 29 0 100.00% 32 0 100.00%
+cred.c:parse_makecred_reply 14 0 100.00% 27 0 100.00%
+cred.c:check_extensions 2 0 100.00% 6 0 100.00%
+cred.c:get_signed_hash_u2f 27 0 100.00% 26 0 100.00%
+cred.c:verify_attstmt 23 2 91.30% 40 5 87.50%
+cred.c:fido_cred_clean_authdata 1 0 100.00% 8 0 100.00%
+cred.c:fido_cred_clean_attstmt 1 0 100.00% 8 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 632 34 94.62% 830 36 95.66%
File '/libfido2/src/credman.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
-fido_credman_get_dev_metadata 1 0 100.00% 3 0 100.00%
-fido_credman_get_dev_rk 1 0 100.00% 3 0 100.00%
-fido_credman_del_dev_rk 1 0 100.00% 3 0 100.00%
-fido_credman_get_dev_rp 1 0 100.00% 3 0 100.00%
-fido_credman_set_dev_rk 1 0 100.00% 3 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+fido_credman_get_dev_metadata 1 0 100.00% 4 0 100.00%
+fido_credman_get_dev_rk 1 0 100.00% 4 0 100.00%
+fido_credman_del_dev_rk 1 0 100.00% 4 0 100.00%
+fido_credman_get_dev_rp 1 0 100.00% 4 0 100.00%
+fido_credman_set_dev_rk 1 0 100.00% 4 0 100.00%
fido_credman_rk_new 1 0 100.00% 3 0 100.00%
-fido_credman_rk_free 6 1 83.33% 10 0 100.00%
+fido_credman_rk_free 6 1 83.33% 8 0 100.00%
fido_credman_rk_count 1 0 100.00% 3 0 100.00%
-fido_credman_rk 4 0 100.00% 6 0 100.00%
+fido_credman_rk 4 0 100.00% 5 0 100.00%
fido_credman_metadata_new 1 0 100.00% 3 0 100.00%
-fido_credman_metadata_free 6 1 83.33% 9 0 100.00%
+fido_credman_metadata_free 6 1 83.33% 7 0 100.00%
fido_credman_rk_existing 1 0 100.00% 3 0 100.00%
fido_credman_rk_remaining 1 0 100.00% 3 0 100.00%
fido_credman_rp_new 1 0 100.00% 3 0 100.00%
-fido_credman_rp_free 6 1 83.33% 10 0 100.00%
+fido_credman_rp_free 6 1 83.33% 8 0 100.00%
fido_credman_rp_count 1 0 100.00% 3 0 100.00%
-fido_credman_rp_id 4 0 100.00% 6 0 100.00%
-fido_credman_rp_name 4 0 100.00% 6 0 100.00%
-fido_credman_rp_id_hash_len 4 0 100.00% 6 0 100.00%
-fido_credman_rp_id_hash_ptr 4 0 100.00% 6 0 100.00%
-credman.c:credman_get_metadata_wait 11 0 100.00% 10 0 100.00%
-credman.c:credman_tx 36 0 100.00% 60 0 100.00%
-credman.c:credman_prepare_hmac 31 1 96.77% 56 2 96.43%
-credman.c:credman_rx_metadata 11 0 100.00% 21 0 100.00%
-credman.c:credman_parse_metadata 9 0 100.00% 19 0 100.00%
-credman.c:credman_get_rk_wait 27 0 100.00% 28 0 100.00%
-credman.c:credman_rx_rk 19 0 100.00% 36 0 100.00%
-credman.c:credman_parse_rk_count 16 0 100.00% 25 0 100.00%
-credman.c:credman_grow_array 17 2 88.24% 28 5 82.14%
-credman.c:credman_parse_rk 23 0 100.00% 33 0 100.00%
-credman.c:credman_rx_next_rk 15 2 86.67% 26 4 84.62%
-credman.c:credman_del_rk_wait 16 0 100.00% 20 0 100.00%
-credman.c:credman_get_rp_wait 23 0 100.00% 18 0 100.00%
-credman.c:credman_rx_rp 19 0 100.00% 36 0 100.00%
-credman.c:credman_parse_rp_count 16 0 100.00% 25 0 100.00%
-credman.c:credman_parse_rp 9 0 100.00% 19 0 100.00%
-credman.c:credman_rx_next_rp 15 2 86.67% 26 4 84.62%
-credman.c:credman_set_dev_rk_wait 11 0 100.00% 10 0 100.00%
-credman.c:credman_reset_rk 4 0 100.00% 10 0 100.00%
-credman.c:credman_reset_rp 4 0 100.00% 13 0 100.00%
------------------------------------------------------------------------------------------
-TOTAL 382 10 97.38% 614 15 97.56%
+fido_credman_rp_id 4 0 100.00% 5 0 100.00%
+fido_credman_rp_name 4 0 100.00% 5 0 100.00%
+fido_credman_rp_id_hash_len 4 0 100.00% 5 0 100.00%
+fido_credman_rp_id_hash_ptr 4 0 100.00% 5 0 100.00%
+credman.c:credman_get_metadata_wait 11 0 100.00% 8 0 100.00%
+credman.c:credman_tx 36 0 100.00% 50 0 100.00%
+credman.c:credman_prepare_hmac 31 1 96.77% 50 2 96.00%
+credman.c:credman_rx_metadata 11 0 100.00% 17 0 100.00%
+credman.c:credman_parse_metadata 9 0 100.00% 17 0 100.00%
+credman.c:credman_get_rk_wait 27 0 100.00% 23 0 100.00%
+credman.c:credman_rx_rk 19 0 100.00% 27 0 100.00%
+credman.c:credman_parse_rk_count 16 0 100.00% 20 0 100.00%
+credman.c:credman_grow_array 17 2 88.24% 21 5 76.19%
+credman.c:credman_parse_rk 23 0 100.00% 31 0 100.00%
+credman.c:credman_rx_next_rk 15 2 86.67% 21 4 80.95%
+credman.c:credman_del_rk_wait 16 0 100.00% 15 0 100.00%
+credman.c:credman_get_rp_wait 23 0 100.00% 15 0 100.00%
+credman.c:credman_rx_rp 19 0 100.00% 27 0 100.00%
+credman.c:credman_parse_rp_count 16 0 100.00% 20 0 100.00%
+credman.c:credman_parse_rp 9 0 100.00% 17 0 100.00%
+credman.c:credman_rx_next_rp 15 2 86.67% 21 4 80.95%
+credman.c:credman_set_dev_rk_wait 11 0 100.00% 8 0 100.00%
+credman.c:credman_reset_rk 4 0 100.00% 9 0 100.00%
+credman.c:credman_reset_rp 4 0 100.00% 12 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 382 10 97.38% 518 15 97.10%
File '/libfido2/src/dev.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
-fido_dev_register_manifest_func 10 2 80.00% 18 3 83.33%
-fido_dev_unregister_manifest_func 7 7 0.00% 13 13 0.00%
-fido_dev_info_manifest 22 4 81.82% 28 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+fido_dev_register_manifest_func 10 2 80.00% 14 3 78.57%
+fido_dev_unregister_manifest_func 7 7 0.00% 11 11 0.00%
+fido_dev_info_manifest 22 4 81.82% 24 0 100.00%
fido_dev_open_with_info 5 5 0.00% 6 6 0.00%
-fido_dev_open 11 5 54.55% 26 12 53.85%
-fido_dev_close 9 2 77.78% 10 0 100.00%
-fido_dev_set_sigmask 12 12 0.00% 10 10 0.00%
+fido_dev_open 5 1 80.00% 19 12 36.84%
+fido_dev_close 9 2 77.78% 8 0 100.00%
+fido_dev_set_sigmask 18 18 0.00% 11 11 0.00%
fido_dev_cancel 11 0 100.00% 8 0 100.00%
-fido_dev_get_touch_begin 50 0 100.00% 68 0 100.00%
-fido_dev_get_touch_status 17 0 100.00% 25 0 100.00%
-fido_dev_set_io_functions 18 4 77.78% 17 6 64.71%
-fido_dev_set_transport_functions 6 2 66.67% 11 3 72.73%
-fido_init 8 1 87.50% 6 0 100.00%
-fido_dev_new 5 0 100.00% 16 0 100.00%
-fido_dev_new_with_info 10 10 0.00% 20 20 0.00%
-fido_dev_free 6 0 100.00% 11 0 100.00%
+fido_dev_get_touch_begin 50 0 100.00% 59 0 100.00%
+fido_dev_get_touch_status 17 0 100.00% 20 0 100.00%
+fido_dev_set_io_functions 18 4 77.78% 14 6 57.14%
+fido_dev_set_transport_functions 6 2 66.67% 9 3 66.67%
+fido_init 8 1 87.50% 5 0 100.00%
+fido_dev_new 5 0 100.00% 14 0 100.00%
+fido_dev_new_with_info 10 10 0.00% 16 16 0.00%
+fido_dev_free 6 0 100.00% 8 0 100.00%
fido_dev_protocol 1 0 100.00% 3 0 100.00%
fido_dev_major 1 0 100.00% 3 0 100.00%
fido_dev_minor 1 0 100.00% 3 0 100.00%
@@ -401,135 +406,141 @@ fido_dev_has_uv 2 0 100.00% 3
fido_dev_supports_permissions 2 0 100.00% 3 0 100.00%
fido_dev_force_u2f 2 0 100.00% 4 0 100.00%
fido_dev_force_fido2 2 2 0.00% 3 3 0.00%
-fido_dev_get_pin_protocol 11 0 100.00% 8 0 100.00%
+fido_dev_get_pin_protocol 11 0 100.00% 7 0 100.00%
fido_dev_maxmsgsize 1 0 100.00% 3 0 100.00%
-dev.c:find_manifest_func_node 5 0 100.00% 9 0 100.00%
-dev.c:fido_dev_open_wait 10 0 100.00% 9 0 100.00%
-dev.c:fido_dev_open_tx 56 15 73.21% 67 26 61.19%
+fido_dev_set_timeout 6 2 66.67% 6 1 83.33%
+dev.c:find_manifest_func_node 5 0 100.00% 8 0 100.00%
+dev.c:fido_dev_open_wait 10 0 100.00% 7 0 100.00%
+dev.c:fido_dev_open_tx 56 15 73.21% 56 26 53.57%
dev.c:set_random_report_len 11 0 100.00% 6 0 100.00%
-dev.c:fido_dev_open_rx 36 1 97.22% 62 1 98.39%
+dev.c:fido_dev_open_rx 36 1 97.22% 53 1 98.11%
dev.c:fido_dev_set_flags 1 0 100.00% 5 0 100.00%
-dev.c:fido_dev_set_extension_flags 7 0 100.00% 8 0 100.00%
-dev.c:fido_dev_set_option_flags 29 0 100.00% 19 0 100.00%
-dev.c:fido_dev_set_protocol_flags 11 0 100.00% 18 0 100.00%
------------------------------------------------------------------------------------------
-TOTAL 414 74 82.13% 556 106 80.94%
+dev.c:fido_dev_set_extension_flags 7 0 100.00% 7 0 100.00%
+dev.c:fido_dev_set_option_flags 29 0 100.00% 18 0 100.00%
+dev.c:fido_dev_set_protocol_flags 11 0 100.00% 17 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 420 78 81.43% 488 102 79.10%
File '/libfido2/src/ecdh.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
-fido_do_ecdh 29 0 100.00% 40 0 100.00%
-ecdh.c:do_ecdh 37 0 100.00% 48 0 100.00%
-ecdh.c:kdf 19 1 94.74% 32 2 93.75%
-ecdh.c:hkdf_sha256 32 1 96.88% 41 3 92.68%
------------------------------------------------------------------------------------------
-TOTAL 117 2 98.29% 161 5 96.89%
+-------------------------------------------------------------------------------------------------------------------
+fido_do_ecdh 29 0 100.00% 36 0 100.00%
+ecdh.c:do_ecdh 37 0 100.00% 44 0 100.00%
+ecdh.c:kdf 19 1 94.74% 28 2 92.86%
+ecdh.c:hkdf_sha256 32 1 96.88% 38 3 92.11%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 117 2 98.29% 146 5 96.58%
File '/libfido2/src/eddsa.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
-eddsa_pk_decode 8 0 100.00% 10 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+eddsa_pk_decode 8 0 100.00% 9 0 100.00%
eddsa_pk_new 1 0 100.00% 3 0 100.00%
-eddsa_pk_free 6 0 100.00% 9 0 100.00%
-eddsa_pk_from_ptr 6 0 100.00% 8 0 100.00%
-eddsa_pk_to_EVP_PKEY 3 0 100.00% 9 0 100.00%
-eddsa_pk_from_EVP_PKEY 14 0 100.00% 12 0 100.00%
-eddsa.c:decode_pubkey_point 8 0 100.00% 14 0 100.00%
-eddsa.c:decode_coord 8 0 100.00% 12 0 100.00%
------------------------------------------------------------------------------------------
-TOTAL 54 0 100.00% 77 0 100.00%
+eddsa_pk_free 6 0 100.00% 7 0 100.00%
+eddsa_pk_from_ptr 6 0 100.00% 6 0 100.00%
+eddsa_pk_to_EVP_PKEY 3 0 100.00% 7 0 100.00%
+eddsa_pk_from_EVP_PKEY 14 0 100.00% 10 0 100.00%
+eddsa_verify_sig 19 2 89.47% 30 6 80.00%
+eddsa_pk_verify_sig 7 1 85.71% 13 2 84.62%
+eddsa.c:decode_pubkey_point 8 0 100.00% 11 0 100.00%
+eddsa.c:decode_coord 8 0 100.00% 10 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 80 3 96.25% 106 8 92.45%
File '/libfido2/src/err.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------
fido_strerr 122 10 91.80% 126 10 92.06%
------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------
TOTAL 122 10 91.80% 126 10 92.06%
File '/libfido2/src/es256.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
-es256_pk_decode 8 0 100.00% 10 0 100.00%
-es256_pk_encode 56 0 100.00% 70 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+es256_pk_decode 8 0 100.00% 9 0 100.00%
+es256_pk_encode 56 0 100.00% 48 0 100.00%
es256_sk_new 1 0 100.00% 3 0 100.00%
-es256_sk_free 6 0 100.00% 9 0 100.00%
+es256_sk_free 6 0 100.00% 7 0 100.00%
es256_pk_new 1 0 100.00% 3 0 100.00%
-es256_pk_free 6 0 100.00% 9 0 100.00%
-es256_pk_from_ptr 11 0 100.00% 13 0 100.00%
-es256_pk_set_x 1 0 100.00% 5 0 100.00%
-es256_pk_set_y 1 0 100.00% 5 0 100.00%
-es256_sk_create 39 0 100.00% 46 0 100.00%
-es256_pk_to_EVP_PKEY 42 0 100.00% 66 0 100.00%
-es256_pk_from_EC_KEY 38 0 100.00% 43 0 100.00%
-es256_sk_to_EVP_PKEY 28 0 100.00% 50 0 100.00%
-es256_derive_pk 25 0 100.00% 34 0 100.00%
-es256.c:decode_pubkey_point 9 0 100.00% 16 0 100.00%
-es256.c:decode_coord 8 0 100.00% 12 0 100.00%
------------------------------------------------------------------------------------------
-TOTAL 280 0 100.00% 394 0 100.00%
+es256_pk_free 6 0 100.00% 7 0 100.00%
+es256_pk_from_ptr 11 0 100.00% 10 0 100.00%
+es256_pk_set_x 1 0 100.00% 4 0 100.00%
+es256_pk_set_y 1 0 100.00% 4 0 100.00%
+es256_sk_create 39 0 100.00% 41 0 100.00%
+es256_pk_to_EVP_PKEY 42 0 100.00% 54 0 100.00%
+es256_pk_from_EC_KEY 38 0 100.00% 36 0 100.00%
+es256_pk_from_EVP_PKEY 7 2 71.43% 7 0 100.00%
+es256_sk_to_EVP_PKEY 28 0 100.00% 40 0 100.00%
+es256_derive_pk 25 0 100.00% 30 0 100.00%
+es256_verify_sig 12 2 83.33% 19 5 73.68%
+es256_pk_verify_sig 7 1 85.71% 13 2 84.62%
+es256.c:decode_pubkey_point 9 0 100.00% 13 0 100.00%
+es256.c:decode_coord 8 0 100.00% 10 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 306 5 98.37% 358 7 98.04%
File '/libfido2/src/extern.h':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------
File '/libfido2/src/fido.h':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------
File '/libfido2/src/hid.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
-fido_hid_get_usage 13 0 100.00% 28 0 100.00%
-fido_hid_get_report_len 19 0 100.00% 33 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+fido_hid_get_usage 13 0 100.00% 22 0 100.00%
+fido_hid_get_report_len 19 0 100.00% 27 0 100.00%
fido_dev_info_new 1 0 100.00% 3 0 100.00%
-fido_dev_info_free 9 0 100.00% 18 0 100.00%
+fido_dev_info_free 9 0 100.00% 14 0 100.00%
fido_dev_info_ptr 1 0 100.00% 3 0 100.00%
fido_dev_info_path 1 0 100.00% 3 0 100.00%
fido_dev_info_vendor 1 0 100.00% 3 0 100.00%
fido_dev_info_product 1 0 100.00% 3 0 100.00%
fido_dev_info_manufacturer_string 1 0 100.00% 3 0 100.00%
fido_dev_info_product_string 1 0 100.00% 3 0 100.00%
-hid.c:get_key_len 6 0 100.00% 14 0 100.00%
-hid.c:get_key_val 6 0 100.00% 20 0 100.00%
------------------------------------------------------------------------------------------
-TOTAL 60 0 100.00% 134 0 100.00%
+hid.c:get_key_len 6 0 100.00% 12 0 100.00%
+hid.c:get_key_val 6 0 100.00% 18 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 60 0 100.00% 114 0 100.00%
File '/libfido2/src/hid_linux.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
-fido_hid_manifest 35 4 88.57% 50 1 98.00%
-fido_hid_open 27 27 0.00% 44 44 0.00%
-fido_hid_close 3 3 0.00% 8 8 0.00%
-fido_hid_set_sigmask 2 2 0.00% 8 8 0.00%
-fido_hid_read 15 15 0.00% 26 26 0.00%
-fido_hid_write 12 12 0.00% 21 21 0.00%
-fido_hid_report_in_len 1 1 0.00% 5 5 0.00%
-fido_hid_report_out_len 1 1 0.00% 5 5 0.00%
-hid_linux.c:copy_info 34 0 100.00% 53 0 100.00%
-hid_linux.c:is_fido 10 2 80.00% 19 2 89.47%
-hid_linux.c:get_parent_attr 6 0 100.00% 11 0 100.00%
-hid_linux.c:parse_uevent 12 0 100.00% 28 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+fido_hid_manifest 35 4 88.57% 41 1 97.56%
+fido_hid_open 27 27 0.00% 40 40 0.00%
+fido_hid_close 3 3 0.00% 6 6 0.00%
+fido_hid_set_sigmask 2 2 0.00% 6 6 0.00%
+fido_hid_read 15 15 0.00% 21 21 0.00%
+fido_hid_write 12 12 0.00% 17 17 0.00%
+fido_hid_report_in_len 1 1 0.00% 4 4 0.00%
+fido_hid_report_out_len 1 1 0.00% 4 4 0.00%
+hid_linux.c:copy_info 34 0 100.00% 44 0 100.00%
+hid_linux.c:is_fido 10 2 80.00% 14 2 85.71%
+hid_linux.c:get_parent_attr 6 0 100.00% 9 0 100.00%
+hid_linux.c:parse_uevent 12 0 100.00% 24 0 100.00%
hid_linux.c:get_usb_attr 1 0 100.00% 3 0 100.00%
-hid_linux.c:get_report_descriptor 14 1 92.86% 22 3 86.36%
------------------------------------------------------------------------------------------
-TOTAL 173 68 60.69% 303 123 59.41%
+hid_linux.c:get_report_descriptor 14 1 92.86% 17 3 82.35%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 173 68 60.69% 250 104 58.40%
File '/libfido2/src/hid_unix.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
-fido_hid_unix_open 18 11 38.89% 26 14 46.15%
-fido_hid_unix_wait 12 9 25.00% 26 14 46.15%
------------------------------------------------------------------------------------------
-TOTAL 30 20 33.33% 52 28 46.15%
+-------------------------------------------------------------------------------------------------------------------
+fido_hid_unix_open 18 11 38.89% 22 14 36.36%
+fido_hid_unix_wait 10 9 10.00% 21 10 52.38%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 28 20 28.57% 43 24 44.19%
File '/libfido2/src/info.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
-fido_dev_get_cbor_info_wait 10 0 100.00% 9 0 100.00%
-fido_dev_get_cbor_info 1 0 100.00% 3 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+fido_dev_get_cbor_info_wait 10 0 100.00% 7 0 100.00%
+fido_dev_get_cbor_info 1 0 100.00% 4 0 100.00%
fido_cbor_info_new 1 0 100.00% 3 0 100.00%
fido_cbor_info_reset 1 0 100.00% 8 0 100.00%
-fido_cbor_info_free 6 0 100.00% 9 0 100.00%
+fido_cbor_info_free 6 0 100.00% 8 0 100.00%
fido_cbor_info_versions_ptr 1 0 100.00% 3 0 100.00%
fido_cbor_info_versions_len 1 0 100.00% 3 0 100.00%
fido_cbor_info_extensions_ptr 1 0 100.00% 3 0 100.00%
@@ -549,259 +560,307 @@ fido_cbor_info_fwversion 1 0 100.00% 3
fido_cbor_info_protocols_ptr 1 0 100.00% 3 0 100.00%
fido_cbor_info_protocols_len 1 0 100.00% 3 0 100.00%
fido_cbor_info_algorithm_count 1 0 100.00% 3 0 100.00%
-fido_cbor_info_algorithm_type 4 0 100.00% 6 0 100.00%
-fido_cbor_info_algorithm_cose 4 0 100.00% 6 0 100.00%
-info.c:fido_dev_get_cbor_info_tx 8 0 100.00% 12 0 100.00%
-info.c:fido_dev_get_cbor_info_rx 6 0 100.00% 18 0 100.00%
-info.c:parse_reply_element 19 0 100.00% 39 0 100.00%
-info.c:decode_string_array 12 0 100.00% 21 0 100.00%
-info.c:decode_string 4 0 100.00% 14 0 100.00%
-info.c:decode_aaguid 8 0 100.00% 12 0 100.00%
-info.c:decode_options 11 0 100.00% 18 0 100.00%
-info.c:decode_option 11 0 100.00% 22 0 100.00%
-info.c:decode_protocols 12 0 100.00% 21 0 100.00%
-info.c:decode_protocol 6 0 100.00% 16 0 100.00%
-info.c:decode_algorithms 12 0 100.00% 21 0 100.00%
-info.c:decode_algorithm 9 0 100.00% 23 0 100.00%
-info.c:decode_algorithm_entry 20 0 100.00% 31 0 100.00%
-info.c:free_algo 1 0 100.00% 5 0 100.00%
-info.c:free_str_array 4 0 100.00% 8 0 100.00%
-info.c:free_opt_array 4 0 100.00% 9 0 100.00%
-info.c:free_byte_array 1 0 100.00% 6 0 100.00%
-info.c:free_algo_array 4 0 100.00% 8 0 100.00%
------------------------------------------------------------------------------------------
-TOTAL 198 0 100.00% 405 0 100.00%
+fido_cbor_info_algorithm_type 4 0 100.00% 5 0 100.00%
+fido_cbor_info_algorithm_cose 4 0 100.00% 5 0 100.00%
+info.c:fido_dev_get_cbor_info_tx 8 0 100.00% 9 0 100.00%
+info.c:fido_dev_get_cbor_info_rx 6 0 100.00% 14 0 100.00%
+info.c:parse_reply_element 19 0 100.00% 37 0 100.00%
+info.c:decode_string_array 12 0 100.00% 17 0 100.00%
+info.c:decode_string 4 0 100.00% 10 0 100.00%
+info.c:decode_aaguid 8 0 100.00% 10 0 100.00%
+info.c:decode_options 11 0 100.00% 15 0 100.00%
+info.c:decode_option 11 0 100.00% 17 0 100.00%
+info.c:decode_protocols 12 0 100.00% 17 0 100.00%
+info.c:decode_protocol 6 0 100.00% 12 0 100.00%
+info.c:decode_algorithms 12 0 100.00% 17 0 100.00%
+info.c:decode_algorithm 9 0 100.00% 17 0 100.00%
+info.c:decode_algorithm_entry 20 0 100.00% 27 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 184 0 100.00% 316 0 100.00%
File '/libfido2/src/io.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
-fido_tx 13 0 100.00% 13 0 100.00%
-fido_rx 13 1 92.31% 17 3 82.35%
-fido_rx_cbor_status 8 0 100.00% 12 0 100.00%
-io.c:tx_empty 9 0 100.00% 17 0 100.00%
-io.c:tx 13 0 100.00% 21 0 100.00%
-io.c:tx_preamble 16 1 93.75% 24 1 95.83%
-io.c:tx_frame 15 1 93.33% 22 1 95.45%
-io.c:rx 40 2 95.00% 65 1 98.46%
-io.c:rx_preamble 23 2 91.30% 26 5 80.77%
-io.c:rx_frame 8 0 100.00% 11 0 100.00%
------------------------------------------------------------------------------------------
-TOTAL 158 7 95.57% 228 11 95.18%
+-------------------------------------------------------------------------------------------------------------------
+fido_tx 13 0 100.00% 11 0 100.00%
+fido_rx 13 1 92.31% 14 3 78.57%
+fido_rx_cbor_status 8 0 100.00% 10 0 100.00%
+io.c:transport_tx 7 0 100.00% 10 0 100.00%
+io.c:tx_empty 9 0 100.00% 14 0 100.00%
+io.c:tx_pkt 7 0 100.00% 10 0 100.00%
+io.c:tx 13 0 100.00% 19 0 100.00%
+io.c:tx_preamble 16 1 93.75% 20 1 95.00%
+io.c:tx_frame 15 1 93.33% 18 1 94.44%
+io.c:transport_rx 7 0 100.00% 10 0 100.00%
+io.c:rx 40 2 95.00% 52 1 98.08%
+io.c:rx_preamble 23 2 91.30% 22 5 77.27%
+io.c:rx_frame 11 0 100.00% 11 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 182 7 96.15% 221 11 95.02%
File '/libfido2/src/iso7816.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
-iso7816_new 4 0 100.00% 18 0 100.00%
-iso7816_free 6 0 100.00% 8 0 100.00%
-iso7816_add 6 1 83.33% 9 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+iso7816_new 4 0 100.00% 16 0 100.00%
+iso7816_free 6 0 100.00% 7 0 100.00%
+iso7816_add 6 1 83.33% 8 0 100.00%
iso7816_ptr 1 0 100.00% 3 0 100.00%
iso7816_len 1 0 100.00% 4 0 100.00%
------------------------------------------------------------------------------------------
-TOTAL 18 1 94.44% 42 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 18 1 94.44% 38 0 100.00%
File '/libfido2/src/largeblob.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
-fido_dev_largeblob_get 26 2 92.31% 41 4 90.24%
-fido_dev_largeblob_set 27 0 100.00% 39 0 100.00%
-fido_dev_largeblob_remove 12 0 100.00% 21 0 100.00%
-fido_dev_largeblob_get_array 15 2 86.67% 30 4 86.67%
-fido_dev_largeblob_set_array 14 0 100.00% 21 0 100.00%
-largeblob.c:largeblob_get_array 32 0 100.00% 39 0 100.00%
-largeblob.c:get_chunklen 9 1 88.89% 11 0 100.00%
-largeblob.c:largeblob_get_tx 19 0 100.00% 28 0 100.00%
-largeblob.c:largeblob_get_rx 15 0 100.00% 23 0 100.00%
-largeblob.c:parse_largeblob_reply 8 0 100.00% 10 0 100.00%
-largeblob.c:largeblob_array_check 7 0 100.00% 18 0 100.00%
-largeblob.c:largeblob_array_digest 10 0 100.00% 11 0 100.00%
-largeblob.c:largeblob_array_load 14 2 85.71% 21 7 66.67%
-largeblob.c:largeblob_array_lookup 25 0 100.00% 36 0 100.00%
-largeblob.c:largeblob_decode 16 2 87.50% 17 6 64.71%
-largeblob.c:largeblob_do_decode 27 3 88.89% 32 5 84.38%
-largeblob.c:largeblob_decrypt 15 0 100.00% 28 0 100.00%
-largeblob.c:largeblob_aad 1 0 100.00% 12 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+fido_dev_largeblob_get 26 2 92.31% 38 4 89.47%
+fido_dev_largeblob_set 27 2 92.59% 36 4 88.89%
+fido_dev_largeblob_remove 12 0 100.00% 18 0 100.00%
+fido_dev_largeblob_get_array 15 2 86.67% 27 4 85.19%
+fido_dev_largeblob_set_array 14 0 100.00% 19 0 100.00%
+largeblob.c:largeblob_get_array 32 0 100.00% 36 0 100.00%
+largeblob.c:get_chunklen 9 1 88.89% 9 0 100.00%
+largeblob.c:largeblob_get_tx 19 0 100.00% 24 0 100.00%
+largeblob.c:largeblob_get_rx 15 0 100.00% 21 0 100.00%
+largeblob.c:parse_largeblob_reply 8 0 100.00% 9 0 100.00%
+largeblob.c:largeblob_array_check 7 0 100.00% 16 0 100.00%
+largeblob.c:largeblob_array_digest 10 0 100.00% 9 0 100.00%
+largeblob.c:largeblob_array_load 14 2 85.71% 19 7 63.16%
+largeblob.c:largeblob_array_lookup 25 0 100.00% 33 0 100.00%
+largeblob.c:largeblob_decode 16 2 87.50% 16 6 62.50%
+largeblob.c:largeblob_do_decode 27 3 88.89% 30 5 83.33%
+largeblob.c:largeblob_decrypt 15 0 100.00% 24 0 100.00%
+largeblob.c:largeblob_aad 1 0 100.00% 10 0 100.00%
largeblob.c:largeblob_reset 1 0 100.00% 5 0 100.00%
-largeblob.c:largeblob_encode 16 0 100.00% 23 0 100.00%
+largeblob.c:largeblob_encode 16 0 100.00% 21 0 100.00%
largeblob.c:largeblob_new 1 0 100.00% 3 0 100.00%
-largeblob.c:largeblob_seal 20 0 100.00% 35 0 100.00%
-largeblob.c:largeblob_get_nonce 8 1 87.50% 19 3 84.21%
-largeblob.c:largeblob_free 6 0 100.00% 9 0 100.00%
-largeblob.c:largeblob_add 27 2 92.59% 40 3 92.50%
-largeblob.c:largeblob_drop 21 0 100.00% 30 0 100.00%
-largeblob.c:largeblob_set_array 54 2 96.30% 64 4 93.75%
-largeblob.c:largeblob_get_uv_token 19 0 100.00% 27 0 100.00%
-largeblob.c:largeblob_set_tx 35 0 100.00% 40 0 100.00%
-largeblob.c:prepare_hmac 13 2 84.62% 26 7 73.08%
------------------------------------------------------------------------------------------
-TOTAL 513 19 96.30% 759 43 94.33%
+largeblob.c:largeblob_seal 20 0 100.00% 32 0 100.00%
+largeblob.c:largeblob_get_nonce 8 1 87.50% 16 3 81.25%
+largeblob.c:largeblob_free 6 0 100.00% 8 0 100.00%
+largeblob.c:largeblob_add 27 2 92.59% 35 3 91.43%
+largeblob.c:largeblob_drop 21 0 100.00% 27 0 100.00%
+largeblob.c:largeblob_set_array 54 2 96.30% 61 4 93.44%
+largeblob.c:largeblob_get_uv_token 19 0 100.00% 23 0 100.00%
+largeblob.c:largeblob_set_tx 35 0 100.00% 36 0 100.00%
+largeblob.c:prepare_hmac 13 2 84.62% 23 7 69.57%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 513 21 95.91% 684 47 93.13%
File '/libfido2/src/log.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------
fido_log_init 1 0 100.00% 4 0 100.00%
-fido_log_debug 6 1 83.33% 10 0 100.00%
-fido_log_xxd 16 1 93.75% 27 0 100.00%
-fido_log_error 8 2 75.00% 13 1 92.31%
+fido_log_debug 6 1 83.33% 8 0 100.00%
+fido_log_xxd 16 1 93.75% 24 0 100.00%
+fido_log_error 8 2 75.00% 11 1 90.91%
fido_set_log_handler 3 0 100.00% 4 0 100.00%
log.c:log_on_stderr 1 1 0.00% 3 3 0.00%
-log.c:do_log 4 0 100.00% 12 0 100.00%
------------------------------------------------------------------------------------------
-TOTAL 39 5 87.18% 73 4 94.52%
+log.c:do_log 4 0 100.00% 9 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 39 5 87.18% 63 4 93.65%
File '/libfido2/src/netlink.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
-fido_nl_power_nfc 18 1 94.44% 26 3 88.46%
-fido_nl_get_nfc_target 16 1 93.75% 33 3 90.91%
-fido_nl_free 10 2 80.00% 11 1 90.91%
-fido_nl_new 16 2 87.50% 29 6 79.31%
+-------------------------------------------------------------------------------------------------------------------
+fido_nl_power_nfc 18 1 94.44% 24 3 87.50%
+fido_nl_get_nfc_target 17 1 94.12% 31 3 90.32%
+fido_nl_free 10 2 80.00% 9 1 88.89%
+fido_nl_new 16 1 93.75% 26 3 88.46%
set_netlink_io_functions 1 0 100.00% 4 0 100.00%
-netlink.c:nlmsg_new 8 0 100.00% 18 0 100.00%
-netlink.c:nlmsg_set_genl 1 0 100.00% 9 0 100.00%
-netlink.c:nlmsg_write 6 1 83.33% 9 1 88.89%
+netlink.c:nlmsg_new 8 0 100.00% 15 0 100.00%
+netlink.c:nlmsg_set_genl 1 0 100.00% 7 0 100.00%
+netlink.c:nlmsg_write 6 1 83.33% 7 1 85.71%
netlink.c:nlmsg_set_u32 1 0 100.00% 3 0 100.00%
-netlink.c:nlmsg_setattr 14 1 92.86% 21 0 100.00%
-netlink.c:nlmsg_tx 10 1 90.00% 15 3 80.00%
+netlink.c:nlmsg_setattr 14 1 92.86% 17 0 100.00%
+netlink.c:nlmsg_tx 10 1 90.00% 13 3 76.92%
netlink.c:nlmsg_ptr 1 0 100.00% 3 0 100.00%
netlink.c:nlmsg_len 1 0 100.00% 3 0 100.00%
-netlink.c:nlmsg_rx 11 3 72.73% 19 9 52.63%
-netlink.c:nl_parse_reply 20 0 100.00% 30 0 100.00%
-netlink.c:nlmsg_from_buf 15 0 100.00% 22 0 100.00%
+netlink.c:nlmsg_rx 11 3 72.73% 17 9 47.06%
+netlink.c:nl_parse_reply 20 0 100.00% 28 0 100.00%
+netlink.c:nlmsg_from_buf 15 0 100.00% 17 0 100.00%
netlink.c:nlmsg_type 1 0 100.00% 3 0 100.00%
-netlink.c:nlmsg_get_status 8 0 100.00% 10 0 100.00%
-netlink.c:nlmsg_read 6 0 100.00% 9 0 100.00%
-netlink.c:nlmsg_get_genl 6 0 100.00% 10 0 100.00%
-netlink.c:nlmsg_iter 6 0 100.00% 15 0 100.00%
+netlink.c:nlmsg_get_status 8 0 100.00% 8 0 100.00%
+netlink.c:nlmsg_read 6 0 100.00% 7 0 100.00%
+netlink.c:nlmsg_get_genl 6 0 100.00% 7 0 100.00%
+netlink.c:nlmsg_iter 6 0 100.00% 13 0 100.00%
netlink.c:nlmsg_getattr 1 0 100.00% 3 0 100.00%
-netlink.c:nla_from_buf 17 0 100.00% 26 0 100.00%
-netlink.c:nl_nfc_poll 18 1 94.44% 27 3 88.89%
-netlink.c:parse_nfc_event 10 0 100.00% 19 0 100.00%
+netlink.c:nla_from_buf 17 0 100.00% 21 0 100.00%
+netlink.c:nl_nfc_poll 18 1 94.44% 25 3 88.00%
+netlink.c:parse_nfc_event 10 0 100.00% 17 0 100.00%
netlink.c:nla_type 1 0 100.00% 3 0 100.00%
netlink.c:nla_get_u32 1 0 100.00% 3 0 100.00%
-netlink.c:nla_read 6 0 100.00% 9 0 100.00%
-netlink.c:nl_dump_nfc_target 19 1 94.74% 33 3 90.91%
-netlink.c:parse_target 9 0 100.00% 15 0 100.00%
-netlink.c:nl_get_nfc_family 23 1 95.65% 35 3 91.43%
+netlink.c:nla_read 6 0 100.00% 7 0 100.00%
+netlink.c:nl_dump_nfc_target 19 1 94.74% 31 3 90.32%
+netlink.c:parse_target 9 0 100.00% 13 0 100.00%
+netlink.c:nl_get_nfc_family 23 1 95.65% 33 3 90.91%
netlink.c:nlmsg_set_u16 1 0 100.00% 3 0 100.00%
netlink.c:nlmsg_set_str 1 0 100.00% 3 0 100.00%
-netlink.c:parse_family 10 0 100.00% 20 0 100.00%
+netlink.c:parse_family 10 0 100.00% 17 0 100.00%
netlink.c:nla_get_u16 1 0 100.00% 3 0 100.00%
-netlink.c:nla_iter 6 0 100.00% 15 0 100.00%
+netlink.c:nla_iter 6 0 100.00% 13 0 100.00%
netlink.c:nla_getattr 1 0 100.00% 3 0 100.00%
netlink.c:parse_mcastgrps 1 0 100.00% 3 0 100.00%
-netlink.c:parse_mcastgrp 15 0 100.00% 27 0 100.00%
-netlink.c:nla_get_str 10 0 100.00% 13 0 100.00%
------------------------------------------------------------------------------------------
-TOTAL 327 15 95.41% 565 35 93.81%
+netlink.c:parse_mcastgrp 15 0 100.00% 24 0 100.00%
+netlink.c:nla_get_str 10 0 100.00% 11 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 328 14 95.73% 498 32 93.57%
File '/libfido2/src/nfc_linux.c':
Name Regions Miss Cover Lines Miss Cover
------------------------------------------------------------------------------------------
-fido_nfc_tx 28 0 100.00% 48 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+fido_nfc_tx 28 0 100.00% 43 0 100.00%
fido_nfc_rx 8 1 87.50% 13 3 76.92%
-fido_nfc_manifest 35 2 94.29% 54 0 100.00%
-fido_nfc_open 14 14 0.00% 21 21 0.00%
-fido_nfc_close 1 1 0.00% 5 5 0.00%
-fido_nfc_set_sigmask 2 2 0.00% 8 8 0.00%
-fido_nfc_read 14 14 0.00% 34 34 0.00%
-fido_nfc_write 12 12 0.00% 21 21 0.00%
-nfc_linux.c:nfc_do_tx 20 2 90.00% 30 6 80.00%
-nfc_linux.c:tx_short_apdu 14 0 100.00% 37 0 100.00%
-nfc_linux.c:rx_init 25 6 76.00% 34 5 85.29%
-nfc_linux.c:rx_cbor 4 0 100.00% 8 0 100.00%
-nfc_linux.c:rx_msg 18 2 88.89% 28 6 78.57%
-nfc_linux.c:rx_apdu 8 1 87.50% 22 3 86.36%
-nfc_linux.c:tx_get_response 4 0 100.00% 14 0 100.00%
-nfc_linux.c:copy_info 30 6 80.00% 42 0 100.00%
+fido_nfc_manifest 35 5 85.71% 45 13 71.11%
+fido_nfc_open 20 3 85.00% 23 5 78.26%
+fido_nfc_close 1 1 0.00% 4 4 0.00%
+fido_nfc_set_sigmask 2 2 0.00% 6 6 0.00%
+fido_nfc_read 14 14 0.00% 30 30 0.00%
+fido_nfc_write 12 12 0.00% 18 18 0.00%
+nfc_linux.c:nfc_do_tx 20 2 90.00% 25 6 76.00%
+nfc_linux.c:tx_short_apdu 14 0 100.00% 32 0 100.00%
+nfc_linux.c:rx_init 25 6 76.00% 27 5 81.48%
+nfc_linux.c:rx_cbor 4 0 100.00% 6 0 100.00%
+nfc_linux.c:rx_msg 18 2 88.89% 23 6 73.91%
+nfc_linux.c:rx_apdu 14 1 92.86% 22 3 86.36%
+nfc_linux.c:tx_get_response 4 0 100.00% 11 0 100.00%
+nfc_linux.c:copy_info 41 9 78.05% 44 3 93.18%
nfc_linux.c:get_usb_attr 1 0 100.00% 3 0 100.00%
-nfc_linux.c:get_parent_attr 6 0 100.00% 11 0 100.00%
-nfc_linux.c:to_int 21 21 0.00% 16 16 0.00%
-nfc_linux.c:sysnum_from_syspath 12 12 0.00% 20 20 0.00%
-nfc_linux.c:nfc_new 6 6 0.00% 14 14 0.00%
-nfc_linux.c:nfc_target_connect 9 9 0.00% 24 24 0.00%
-nfc_linux.c:nfc_free 12 12 0.00% 13 13 0.00%
------------------------------------------------------------------------------------------
-TOTAL 304 123 59.54% 520 199 61.73%
+nfc_linux.c:get_parent_attr 6 0 100.00% 9 0 100.00%
+nfc_linux.c:to_int 21 6 71.43% 14 1 92.86%
+nfc_linux.c:sysnum_from_syspath 12 0 100.00% 17 0 100.00%
+nfc_linux.c:nfc_new 6 0 100.00% 11 0 100.00%
+nfc_linux.c:nfc_target_connect 9 9 0.00% 21 21 0.00%
+nfc_linux.c:nfc_free 12 0 100.00% 11 0 100.00%
+-------------------------------------------------------------------------------------------------------------------
+TOTAL 327 73 77.68% 458 124 72.93%
File '/libfido2/src/pin.c':
Name Regions Miss Cover Lines Miss Cover
--------------------------------------------------------------------------------------------
-fido_sha256 7 0 100.00% 13 0 100.00%
+---------------------------------------------------------------------------------------------------------------------
+fido_sha256 7 0 100.00% 10 0 100.00%
fido_dev_get_uv_token 1 0 100.00% 3 0 100.00%
-fido_dev_set_pin 1 0 100.00% 3 0 100.00%
-fido_dev_get_retry_count 1 0 100.00% 3 0 100.00%
-fido_dev_get_uv_retry_count 1 0 100.00% 3 0 100.00%
-cbor_add_uv_params 17 0 100.00% 28 0 100.00%
-pin.c:uv_token_wait 14 2 85.71% 14 0 100.00%
-pin.c:ctap21_uv_token_tx 49 0 100.00% 59 0 100.00%
-pin.c:pin_sha256_enc 19 0 100.00% 30 0 100.00%
+fido_dev_set_pin 1 0 100.00% 4 0 100.00%
+fido_dev_get_retry_count 1 0 100.00% 4 0 100.00%
+fido_dev_get_uv_retry_count 1 0 100.00% 4 0 100.00%
+cbor_add_uv_params 17 0 100.00% 23 0 100.00%
+pin.c:uv_token_wait 14 2 85.71% 12 0 100.00%
+pin.c:ctap21_uv_token_tx 49 0 100.00% 53 0 100.00%
+pin.c:pin_sha256_enc 19 0 100.00% 24 0 100.00%
pin.c:encode_uv_permission 20 1 95.00% 19 3 84.21%
-pin.c:ctap20_uv_token_tx 37 0 100.00% 53 0 100.00%
-pin.c:uv_token_rx 20 0 100.00% 36 0 100.00%
-pin.c:parse_uv_token 8 0 100.00% 12 0 100.00%
-pin.c:fido_dev_set_pin_wait 21 0 100.00% 27 0 100.00%
-pin.c:fido_dev_change_pin_tx 45 0 100.00% 68 0 100.00%
-pin.c:pin_pad64_enc 15 0 100.00% 26 0 100.00%
-pin.c:pad64 18 0 100.00% 24 0 100.00%
-pin.c:fido_dev_set_pin_tx 33 0 100.00% 48 0 100.00%
-pin.c:fido_dev_get_pin_retry_count_wait 10 0 100.00% 9 0 100.00%
-pin.c:fido_dev_get_retry_count_tx 19 0 100.00% 28 0 100.00%
-pin.c:fido_dev_get_pin_retry_count_rx 11 0 100.00% 21 0 100.00%
+pin.c:ctap20_uv_token_tx 37 0 100.00% 45 0 100.00%
+pin.c:uv_token_rx 20 0 100.00% 30 0 100.00%
+pin.c:parse_uv_token 8 0 100.00% 10 0 100.00%
+pin.c:fido_dev_set_pin_wait 21 0 100.00% 24 0 100.00%
+pin.c:fido_dev_change_pin_tx 45 0 100.00% 56 0 100.00%
+pin.c:pin_pad64_enc 15 0 100.00% 21 0 100.00%
+pin.c:pad64 18 0 100.00% 19 0 100.00%
+pin.c:fido_dev_set_pin_tx 33 0 100.00% 41 0 100.00%
+pin.c:fido_dev_get_pin_retry_count_wait 10 0 100.00% 7 0 100.00%
+pin.c:fido_dev_get_retry_count_tx 19 0 100.00% 23 0 100.00%
+pin.c:fido_dev_get_pin_retry_count_rx 11 0 100.00% 17 0 100.00%
pin.c:parse_pin_retry_count 1 0 100.00% 3 0 100.00%
-pin.c:parse_retry_count 13 0 100.00% 20 0 100.00%
-pin.c:fido_dev_get_uv_retry_count_wait 10 0 100.00% 9 0 100.00%
-pin.c:fido_dev_get_uv_retry_count_rx 11 0 100.00% 21 0 100.00%
+pin.c:parse_retry_count 13 0 100.00% 16 0 100.00%
+pin.c:fido_dev_get_uv_retry_count_wait 10 0 100.00% 7 0 100.00%
+pin.c:fido_dev_get_uv_retry_count_rx 11 0 100.00% 17 0 100.00%
pin.c:parse_uv_retry_count 1 0 100.00% 3 0 100.00%
--------------------------------------------------------------------------------------------
-TOTAL 403 3 99.26% 583 3 99.49%
+---------------------------------------------------------------------------------------------------------------------
+TOTAL 403 3 99.26% 495 3 99.39%
File '/libfido2/src/random.c':
Name Regions Miss Cover Lines Miss Cover
--------------------------------------------------------------------------------------------
-fido_get_random 6 1 83.33% 8 1 87.50%
--------------------------------------------------------------------------------------------
-TOTAL 6 1 83.33% 8 1 87.50%
+---------------------------------------------------------------------------------------------------------------------
+fido_get_random 6 1 83.33% 6 1 83.33%
+---------------------------------------------------------------------------------------------------------------------
+TOTAL 6 1 83.33% 6 1 83.33%
File '/libfido2/src/reset.c':
Name Regions Miss Cover Lines Miss Cover
--------------------------------------------------------------------------------------------
-fido_dev_reset 1 0 100.00% 3 0 100.00%
-reset.c:fido_dev_reset_wait 15 0 100.00% 14 0 100.00%
-reset.c:fido_dev_reset_tx 8 0 100.00% 10 0 100.00%
--------------------------------------------------------------------------------------------
-TOTAL 24 0 100.00% 27 0 100.00%
+---------------------------------------------------------------------------------------------------------------------
+fido_dev_reset 1 0 100.00% 4 0 100.00%
+reset.c:fido_dev_reset_wait 15 0 100.00% 11 0 100.00%
+reset.c:fido_dev_reset_tx 8 0 100.00% 8 0 100.00%
+---------------------------------------------------------------------------------------------------------------------
+TOTAL 24 0 100.00% 23 0 100.00%
+
+File '/libfido2/src/rs1.c':
+Name Regions Miss Cover Lines Miss Cover
+---------------------------------------------------------------------------------------------------------------------
+rs1_verify_sig 20 1 95.00% 30 3 90.00%
+rs1.c:rs1_get_EVP_MD 4 0 100.00% 6 0 100.00%
+rs1.c:rs1_free_EVP_MD 1 0 100.00% 3 0 100.00%
+---------------------------------------------------------------------------------------------------------------------
+TOTAL 25 1 96.00% 39 3 92.31%
File '/libfido2/src/rs256.c':
Name Regions Miss Cover Lines Miss Cover
--------------------------------------------------------------------------------------------
-rs256_pk_decode 8 0 100.00% 10 0 100.00%
+---------------------------------------------------------------------------------------------------------------------
+rs256_pk_decode 8 0 100.00% 9 0 100.00%
rs256_pk_new 1 0 100.00% 3 0 100.00%
-rs256_pk_free 6 0 100.00% 9 0 100.00%
-rs256_pk_from_ptr 6 0 100.00% 8 0 100.00%
-rs256_pk_to_EVP_PKEY 32 0 100.00% 48 0 100.00%
-rs256_pk_from_RSA 32 4 87.50% 32 6 81.25%
-rs256.c:decode_rsa_pubkey 9 0 100.00% 16 0 100.00%
-rs256.c:decode_bignum 8 0 100.00% 12 0 100.00%
--------------------------------------------------------------------------------------------
-TOTAL 102 4 96.08% 138 6 95.65%
+rs256_pk_free 6 0 100.00% 7 0 100.00%
+rs256_pk_from_ptr 6 0 100.00% 6 0 100.00%
+rs256_pk_to_EVP_PKEY 32 0 100.00% 39 0 100.00%
+rs256_pk_from_RSA 32 4 87.50% 26 6 76.92%
+rs256_pk_from_EVP_PKEY 7 2 71.43% 7 0 100.00%
+rs256_verify_sig 20 1 95.00% 30 2 93.33%
+rs256_pk_verify_sig 7 1 85.71% 13 2 84.62%
+rs256.c:decode_rsa_pubkey 9 0 100.00% 13 0 100.00%
+rs256.c:decode_bignum 8 0 100.00% 10 0 100.00%
+rs256.c:rs256_get_EVP_MD 4 0 100.00% 6 0 100.00%
+rs256.c:rs256_free_EVP_MD 1 0 100.00% 3 0 100.00%
+---------------------------------------------------------------------------------------------------------------------
+TOTAL 141 8 94.33% 172 10 94.19%
+
+File '/libfido2/src/time.c':
+Name Regions Miss Cover Lines Miss Cover
+---------------------------------------------------------------------------------------------------------------------
+fido_time_now 4 0 100.00% 7 0 100.00%
+fido_time_delta 23 1 95.65% 23 0 100.00%
+time.c:timespec_to_ms 16 2 87.50% 13 1 92.31%
+---------------------------------------------------------------------------------------------------------------------
+TOTAL 43 3 93.02% 43 1 97.67%
+
+File '/libfido2/src/tpm.c':
+Name Regions Miss Cover Lines Miss Cover
+---------------------------------------------------------------------------------------------------------------------
+fido_get_signed_hash_tpm 20 0 100.00% 25 0 100.00%
+tpm.c:check_rsa2048_pubarea 16 0 100.00% 28 0 100.00%
+tpm.c:bswap_rsa2048_pubarea 1 0 100.00% 10 0 100.00%
+tpm.c:check_sha1_certinfo 14 0 100.00% 38 0 100.00%
+tpm.c:get_signed_sha1 17 0 100.00% 19 0 100.00%
+tpm.c:get_signed_name 7 0 100.00% 10 0 100.00%
+tpm.c:bswap_sha1_certinfo 1 0 100.00% 8 0 100.00%
+---------------------------------------------------------------------------------------------------------------------
+TOTAL 76 0 100.00% 138 0 100.00%
+
+File '/libfido2/src/types.c':
+Name Regions Miss Cover Lines Miss Cover
+---------------------------------------------------------------------------------------------------------------------
+fido_str_array_free 4 0 100.00% 7 0 100.00%
+fido_opt_array_free 4 0 100.00% 8 0 100.00%
+fido_byte_array_free 1 0 100.00% 5 0 100.00%
+fido_algo_free 1 0 100.00% 5 0 100.00%
+fido_algo_array_free 4 0 100.00% 7 0 100.00%
+fido_str_array_pack 11 0 100.00% 14 0 100.00%
+---------------------------------------------------------------------------------------------------------------------
+TOTAL 25 0 100.00% 46 0 100.00%
File '/libfido2/src/u2f.c':
Name Regions Miss Cover Lines Miss Cover
--------------------------------------------------------------------------------------------
-u2f_register 70 1 98.57% 88 0 100.00%
-u2f_authenticate 32 0 100.00% 44 0 100.00%
-u2f_get_touch_begin 30 0 100.00% 46 0 100.00%
-u2f_get_touch_status 18 0 100.00% 29 0 100.00%
-u2f.c:key_lookup 44 0 100.00% 69 0 100.00%
-u2f.c:send_dummy_register 31 1 96.77% 49 0 100.00%
-u2f.c:parse_register_reply 49 0 100.00% 71 0 100.00%
-u2f.c:x5c_get 21 1 95.24% 34 3 91.18%
-u2f.c:sig_get 6 0 100.00% 11 0 100.00%
-u2f.c:encode_cred_authdata 33 2 93.94% 76 6 92.11%
-u2f.c:cbor_blob_from_ec_point 22 0 100.00% 39 0 100.00%
-u2f.c:u2f_authenticate_single 32 0 100.00% 52 0 100.00%
-u2f.c:do_auth 50 1 98.00% 71 0 100.00%
-u2f.c:parse_auth_reply 23 0 100.00% 29 0 100.00%
-u2f.c:authdata_fake 12 0 100.00% 34 0 100.00%
--------------------------------------------------------------------------------------------
-TOTAL 473 6 98.73% 742 9 98.79%
+---------------------------------------------------------------------------------------------------------------------
+u2f_register 69 0 100.00% 75 0 100.00%
+u2f_authenticate 32 0 100.00% 36 0 100.00%
+u2f_get_touch_begin 30 0 100.00% 39 0 100.00%
+u2f_get_touch_status 18 0 100.00% 26 0 100.00%
+u2f.c:key_lookup 44 0 100.00% 59 0 100.00%
+u2f.c:send_dummy_register 30 0 100.00% 39 0 100.00%
+u2f.c:delay_ms 13 1 92.31% 15 3 80.00%
+u2f.c:parse_register_reply 49 0 100.00% 62 0 100.00%
+u2f.c:x5c_get 21 1 95.24% 26 3 88.46%
+u2f.c:sig_get 6 0 100.00% 10 0 100.00%
+u2f.c:encode_cred_attstmt 45 0 100.00% 52 0 100.00%
+u2f.c:encode_cred_authdata 33 2 93.94% 61 6 90.16%
+u2f.c:cbor_blob_from_ec_point 22 0 100.00% 31 0 100.00%
+u2f.c:u2f_authenticate_single 32 0 100.00% 43 0 100.00%
+u2f.c:do_auth 49 0 100.00% 61 0 100.00%
+u2f.c:parse_auth_reply 23 0 100.00% 23 0 100.00%
+u2f.c:authdata_fake 12 0 100.00% 27 0 100.00%
+---------------------------------------------------------------------------------------------------------------------
+TOTAL 528 4 99.24% 685 12 98.25%
diff --git a/contrib/libfido2/fuzz/fuzz_assert.c b/contrib/libfido2/fuzz/fuzz_assert.c
index 1ecbde38bd0a..4331148b5e06 100644
--- a/contrib/libfido2/fuzz/fuzz_assert.c
+++ b/contrib/libfido2/fuzz/fuzz_assert.c
@@ -255,6 +255,7 @@ verify_assert(int type, const unsigned char *cdh_ptr, size_t cdh_len,
int ext, void *pk)
{
fido_assert_t *assert = NULL;
+ int r;
if ((assert = fido_assert_new()) == NULL)
return;
@@ -285,33 +286,52 @@ verify_assert(int type, const unsigned char *cdh_ptr, size_t cdh_len,
}
fido_assert_set_sig(assert, 0, sig_ptr, sig_len);
- assert(fido_assert_verify(assert, 0, type, pk) != FIDO_OK);
+ r = fido_assert_verify(assert, 0, type, pk);
+ consume(&r, sizeof(r));
fido_assert_free(&assert);
}
/*
- * Do a dummy conversion to exercise rs256_pk_from_RSA().
+ * Do a dummy conversion to exercise es256_pk_from_EVP_PKEY().
+ */
+static void
+es256_convert(const es256_pk_t *k)
+{
+ EVP_PKEY *pkey = NULL;
+ es256_pk_t *pk = NULL;
+ int r;
+
+ if ((pkey = es256_pk_to_EVP_PKEY(k)) == NULL ||
+ (pk = es256_pk_new()) == NULL)
+ goto out;
+
+ r = es256_pk_from_EVP_PKEY(pk, pkey);
+ consume(&r, sizeof(r));
+out:
+ es256_pk_free(&pk);
+ EVP_PKEY_free(pkey);
+}
+
+/*
+ * Do a dummy conversion to exercise rs256_pk_from_EVP_PKEY().
*/
static void
rs256_convert(const rs256_pk_t *k)
{
EVP_PKEY *pkey = NULL;
rs256_pk_t *pk = NULL;
- RSA *rsa = NULL;
- volatile int r;
+ int r;
if ((pkey = rs256_pk_to_EVP_PKEY(k)) == NULL ||
- (pk = rs256_pk_new()) == NULL ||
- (rsa = EVP_PKEY_get0_RSA(pkey)) == NULL)
+ (pk = rs256_pk_new()) == NULL)
goto out;
- r = rs256_pk_from_RSA(pk, rsa);
+ r = rs256_pk_from_EVP_PKEY(pk, pkey);
+ consume(&r, sizeof(r));
out:
- if (pk)
- rs256_pk_free(&pk);
- if (pkey)
- EVP_PKEY_free(pkey);
+ rs256_pk_free(&pk);
+ EVP_PKEY_free(pkey);
}
/*
@@ -322,13 +342,14 @@ eddsa_convert(const eddsa_pk_t *k)
{
EVP_PKEY *pkey = NULL;
eddsa_pk_t *pk = NULL;
- volatile int r;
+ int r;
if ((pkey = eddsa_pk_to_EVP_PKEY(k)) == NULL ||
(pk = eddsa_pk_new()) == NULL)
goto out;
r = eddsa_pk_from_EVP_PKEY(pk, pkey);
+ consume(&r, sizeof(r));
out:
if (pk)
eddsa_pk_free(&pk);
@@ -349,6 +370,7 @@ test(const struct param *p)
void *pk;
prng_init((unsigned int)p->seed);
+ fuzz_clock_reset();
fido_init(FIDO_DEBUG);
fido_set_log_handler(consume_str);
@@ -362,6 +384,8 @@ test(const struct param *p)
es256_pk_from_ptr(es256_pk, p->es256.body, p->es256.len);
pk = es256_pk;
+ es256_convert(pk);
+
break;
case 1:
cose_alg = COSE_RS256;
diff --git a/contrib/libfido2/fuzz/fuzz_bio.c b/contrib/libfido2/fuzz/fuzz_bio.c
index ed3deec93693..49a50932a543 100644
--- a/contrib/libfido2/fuzz/fuzz_bio.c
+++ b/contrib/libfido2/fuzz/fuzz_bio.c
@@ -408,6 +408,7 @@ void
test(const struct param *p)
{
prng_init((unsigned int)p->seed);
+ fuzz_clock_reset();
fido_init(FIDO_DEBUG);
fido_set_log_handler(consume_str);
diff --git a/contrib/libfido2/fuzz/fuzz_cred.c b/contrib/libfido2/fuzz/fuzz_cred.c
index 004852d3451a..d7b630224054 100644
--- a/contrib/libfido2/fuzz/fuzz_cred.c
+++ b/contrib/libfido2/fuzz/fuzz_cred.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019 Yubico AB. All rights reserved.
+ * Copyright (c) 2019-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -231,12 +231,15 @@ make_cred(fido_cred_t *cred, uint8_t opt, int type, const struct blob *cdh,
fido_cred_set_rp(cred, rp_id, rp_name);
fido_cred_set_user(cred, user_id->body, user_id->len, user_name,
user_nick, user_icon);
+
if (ext & FIDO_EXT_HMAC_SECRET)
fido_cred_set_extensions(cred, FIDO_EXT_HMAC_SECRET);
if (ext & FIDO_EXT_CRED_BLOB)
fido_cred_set_blob(cred, user_id->body, user_id->len);
if (ext & FIDO_EXT_LARGEBLOB_KEY)
fido_cred_set_extensions(cred, FIDO_EXT_LARGEBLOB_KEY);
+ if (ext & FIDO_EXT_MINPINLEN)
+ fido_cred_set_pin_minlen(cred, strlen(pin));
if (rk & 1)
fido_cred_set_rk(cred, FIDO_OPT_TRUE);
@@ -268,11 +271,13 @@ verify_cred(int type, const unsigned char *cdh_ptr, size_t cdh_len,
size_t authdata_len, const unsigned char *authdata_raw_ptr,
size_t authdata_raw_len, int ext, uint8_t rk, uint8_t uv,
const unsigned char *x5c_ptr, size_t x5c_len, const unsigned char *sig_ptr,
- size_t sig_len, const char *fmt, int prot)
+ size_t sig_len, const unsigned char *attstmt_ptr, size_t attstmt_len,
+ const char *fmt, int prot, size_t minpinlen)
{
fido_cred_t *cred;
uint8_t flags;
uint32_t sigcount;
+ int r;
if ((cred = fido_cred_new()) == NULL)
return;
@@ -282,13 +287,19 @@ verify_cred(int type, const unsigned char *cdh_ptr, size_t cdh_len,
fido_cred_set_rp(cred, rp_id, rp_name);
consume(authdata_ptr, authdata_len);
consume(authdata_raw_ptr, authdata_raw_len);
+ consume(x5c_ptr, x5c_len);
+ consume(sig_ptr, sig_len);
+ consume(attstmt_ptr, attstmt_len);
if (fido_cred_set_authdata(cred, authdata_ptr, authdata_len) != FIDO_OK)
fido_cred_set_authdata_raw(cred, authdata_raw_ptr,
authdata_raw_len);
fido_cred_set_extensions(cred, ext);
- fido_cred_set_x509(cred, x5c_ptr, x5c_len);
- fido_cred_set_sig(cred, sig_ptr, sig_len);
+ if (fido_cred_set_attstmt(cred, attstmt_ptr, attstmt_len) != FIDO_OK) {
+ fido_cred_set_x509(cred, x5c_ptr, x5c_len);
+ fido_cred_set_sig(cred, sig_ptr, sig_len);
+ }
fido_cred_set_prot(cred, prot);
+ fido_cred_set_pin_minlen(cred, minpinlen);
if (rk & 1)
fido_cred_set_rk(cred, FIDO_OPT_TRUE);
@@ -299,12 +310,19 @@ verify_cred(int type, const unsigned char *cdh_ptr, size_t cdh_len,
/* repeat memory operations to trigger reallocation paths */
if (fido_cred_set_authdata(cred, authdata_ptr, authdata_len) != FIDO_OK)
- fido_cred_set_authdata_raw(cred, authdata_ptr, authdata_len);
+ fido_cred_set_authdata_raw(cred, authdata_raw_ptr,
+ authdata_raw_len);
+ if (fido_cred_set_attstmt(cred, attstmt_ptr, attstmt_len) != FIDO_OK) {
+ fido_cred_set_x509(cred, x5c_ptr, x5c_len);
+ fido_cred_set_sig(cred, sig_ptr, sig_len);
+ }
fido_cred_set_x509(cred, x5c_ptr, x5c_len);
fido_cred_set_sig(cred, sig_ptr, sig_len);
- assert(fido_cred_verify(cred) != FIDO_OK);
- assert(fido_cred_verify_self(cred) != FIDO_OK);
+ r = fido_cred_verify(cred);
+ consume(&r, sizeof(r));
+ r = fido_cred_verify_self(cred);
+ consume(&r, sizeof(r));
consume(fido_cred_pubkey_ptr(cred), fido_cred_pubkey_len(cred));
consume(fido_cred_id_ptr(cred), fido_cred_id_len(cred));
@@ -321,6 +339,8 @@ verify_cred(int type, const unsigned char *cdh_ptr, size_t cdh_len,
consume(&sigcount, sizeof(sigcount));
type = fido_cred_type(cred);
consume(&type, sizeof(type));
+ minpinlen = fido_cred_pin_minlen(cred);
+ consume(&minpinlen, sizeof(minpinlen));
fido_cred_free(&cred);
}
@@ -360,7 +380,9 @@ test_cred(const struct param *p)
fido_cred_authdata_raw_len(cred), p->ext, p->rk, p->uv,
fido_cred_x5c_ptr(cred), fido_cred_x5c_len(cred),
fido_cred_sig_ptr(cred), fido_cred_sig_len(cred),
- fido_cred_fmt(cred), fido_cred_prot(cred));
+ fido_cred_attstmt_ptr(cred), fido_cred_attstmt_len(cred),
+ fido_cred_fmt(cred), fido_cred_prot(cred),
+ fido_cred_pin_minlen(cred));
fido_cred_free(&cred);
}
@@ -408,6 +430,7 @@ void
test(const struct param *p)
{
prng_init((unsigned int)p->seed);
+ fuzz_clock_reset();
fido_init(FIDO_DEBUG);
fido_set_log_handler(consume_str);
diff --git a/contrib/libfido2/fuzz/fuzz_credman.c b/contrib/libfido2/fuzz/fuzz_credman.c
index 89a37379d87f..fb34f22f8147 100644
--- a/contrib/libfido2/fuzz/fuzz_credman.c
+++ b/contrib/libfido2/fuzz/fuzz_credman.c
@@ -374,6 +374,7 @@ void
test(const struct param *p)
{
prng_init((unsigned int)p->seed);
+ fuzz_clock_reset();
fido_init(FIDO_DEBUG);
fido_set_log_handler(consume_str);
diff --git a/contrib/libfido2/fuzz/fuzz_hid.c b/contrib/libfido2/fuzz/fuzz_hid.c
index 6aca7ef5da5b..556e62ac4cd3 100644
--- a/contrib/libfido2/fuzz/fuzz_hid.c
+++ b/contrib/libfido2/fuzz/fuzz_hid.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 Yubico AB. All rights reserved.
+ * Copyright (c) 2020-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -12,6 +12,7 @@
#include "../openbsd-compat/openbsd-compat.h"
#include "mutator_aux.h"
+#include "dummy.h"
extern int fido_hid_get_usage(const uint8_t *, size_t, uint32_t *);
extern int fido_hid_get_report_len(const uint8_t *, size_t, size_t *, size_t *);
@@ -21,6 +22,7 @@ struct param {
int seed;
char uevent[MAXSTR];
struct blob report_descriptor;
+ struct blob netlink_wiredata;
};
/*
@@ -58,13 +60,14 @@ unpack(const uint8_t *ptr, size_t len)
cbor.read != len ||
cbor_isa_array(item) == false ||
cbor_array_is_definite(item) == false ||
- cbor_array_size(item) != 3 ||
+ cbor_array_size(item) != 4 ||
(v = cbor_array_handle(item)) == NULL)
goto fail;
if (unpack_int(v[0], &p->seed) < 0 ||
unpack_string(v[1], p->uevent) < 0 ||
- unpack_blob(v[2], &p->report_descriptor) < 0)
+ unpack_blob(v[2], &p->report_descriptor) < 0 ||
+ unpack_blob(v[3], &p->netlink_wiredata) < 0)
goto fail;
ok = 0;
@@ -83,19 +86,20 @@ fail:
size_t
pack(uint8_t *ptr, size_t len, const struct param *p)
{
- cbor_item_t *argv[3], *array = NULL;
+ cbor_item_t *argv[4], *array = NULL;
size_t cbor_alloc_len, cbor_len = 0;
unsigned char *cbor = NULL;
memset(argv, 0, sizeof(argv));
- if ((array = cbor_new_definite_array(3)) == NULL ||
+ if ((array = cbor_new_definite_array(4)) == NULL ||
(argv[0] = pack_int(p->seed)) == NULL ||
(argv[1] = pack_string(p->uevent)) == NULL ||
- (argv[2] = pack_blob(&p->report_descriptor)) == NULL)
+ (argv[2] = pack_blob(&p->report_descriptor)) == NULL ||
+ (argv[3] = pack_blob(&p->netlink_wiredata)) == NULL)
goto fail;
- for (size_t i = 0; i < 3; i++)
+ for (size_t i = 0; i < 4; i++)
if (cbor_array_push(array, argv[i]) == false)
goto fail;
@@ -107,7 +111,7 @@ pack(uint8_t *ptr, size_t len, const struct param *p)
memcpy(ptr, cbor, cbor_len);
fail:
- for (size_t i = 0; i < 3; i++)
+ for (size_t i = 0; i < 4; i++)
if (argv[i])
cbor_decref(&argv[i]);
@@ -132,6 +136,9 @@ pack_dummy(uint8_t *ptr, size_t len)
strlcpy(dummy.uevent, dummy_uevent, sizeof(dummy.uevent));
memcpy(&dummy.report_descriptor.body, &dummy_report_descriptor,
dummy.report_descriptor.len);
+ dummy.netlink_wiredata.len = sizeof(dummy_netlink_wiredata);
+ memcpy(&dummy.netlink_wiredata.body, &dummy_netlink_wiredata,
+ dummy.netlink_wiredata.len);
assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0);
if (blob_len > len)
@@ -171,7 +178,10 @@ manifest(const struct param *p)
fido_dev_info_t *devlist;
int16_t vendor_id, product_id;
+ set_netlink_io_functions(fd_read, fd_write);
+ set_wire_data(p->netlink_wiredata.body, p->netlink_wiredata.len);
set_udev_parameters(p->uevent, &p->report_descriptor);
+
ndevs = uniform_random(64);
if ((devlist = fido_dev_info_new(ndevs)) == NULL ||
fido_dev_info_manifest(devlist, ndevs, &nfound) != FIDO_OK)
@@ -194,6 +204,7 @@ void
test(const struct param *p)
{
prng_init((unsigned int)p->seed);
+ fuzz_clock_reset();
fido_init(FIDO_DEBUG);
fido_set_log_handler(consume_str);
@@ -212,4 +223,7 @@ mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN
mutate_blob(&p->report_descriptor);
mutate_string(p->uevent);
}
+
+ if (flags & MUTATE_WIREDATA)
+ mutate_blob(&p->netlink_wiredata);
}
diff --git a/contrib/libfido2/fuzz/fuzz_largeblob.c b/contrib/libfido2/fuzz/fuzz_largeblob.c
index 6886261bf529..3289ed46e2a7 100644
--- a/contrib/libfido2/fuzz/fuzz_largeblob.c
+++ b/contrib/libfido2/fuzz/fuzz_largeblob.c
@@ -242,6 +242,7 @@ void
test(const struct param *p)
{
prng_init((unsigned int)p->seed);
+ fuzz_clock_reset();
fido_init(FIDO_DEBUG);
fido_set_log_handler(consume_str);
diff --git a/contrib/libfido2/fuzz/fuzz_mgmt.c b/contrib/libfido2/fuzz/fuzz_mgmt.c
index 28afbc6aae5f..7c28979fb624 100644
--- a/contrib/libfido2/fuzz/fuzz_mgmt.c
+++ b/contrib/libfido2/fuzz/fuzz_mgmt.c
@@ -16,6 +16,8 @@
#include "../openbsd-compat/openbsd-compat.h"
+#define MAXRPID 64
+
struct param {
char pin1[MAXSTR];
char pin2[MAXSTR];
@@ -440,10 +442,35 @@ dev_set_pin_minlen(const struct param *p)
fido_dev_free(&dev);
}
+static void
+dev_set_pin_minlen_rpid(const struct param *p)
+{
+ fido_dev_t *dev;
+ const char *rpid[MAXRPID];
+ const char *pin;
+ size_t n;
+ int r;
+
+ set_wire_data(p->config_wire_data.body, p->config_wire_data.len);
+ if ((dev = open_dev(0)) == NULL)
+ return;
+ n = uniform_random(MAXRPID);
+ for (size_t i = 0; i < n; i++)
+ rpid[i] = dummy_rp_id;
+ pin = p->pin1;
+ if (strlen(pin) == 0)
+ pin = NULL;
+ r = fido_dev_set_pin_minlen_rpid(dev, rpid, n, pin);
+ consume_str(fido_strerr(r));
+ fido_dev_close(dev);
+ fido_dev_free(&dev);
+}
+
void
test(const struct param *p)
{
prng_init((unsigned int)p->seed);
+ fuzz_clock_reset();
fido_init(FIDO_DEBUG);
fido_set_log_handler(consume_str);
@@ -457,6 +484,7 @@ test(const struct param *p)
dev_toggle_always_uv(p);
dev_force_pin_change(p);
dev_set_pin_minlen(p);
+ dev_set_pin_minlen_rpid(p);
}
void
diff --git a/contrib/libfido2/fuzz/fuzz_netlink.c b/contrib/libfido2/fuzz/fuzz_netlink.c
index 9b7f930cde38..2447215a2471 100644
--- a/contrib/libfido2/fuzz/fuzz_netlink.c
+++ b/contrib/libfido2/fuzz/fuzz_netlink.c
@@ -12,6 +12,7 @@
#include "../openbsd-compat/openbsd-compat.h"
#include "mutator_aux.h"
+#include "dummy.h"
struct param {
int seed;
@@ -19,94 +20,6 @@ struct param {
struct blob wiredata;
};
-/*
- * Sample netlink messages. These are unlikely to get the harness very far in
- * terms of coverage, but serve to give libFuzzer a sense of the underlying
- * structure.
- */
-static const uint8_t sample_netlink_wiredata[] = {
- 0xd8, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x9d, 0x2e, 0x00, 0x00,
- 0x01, 0x02, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
- 0x6e, 0x66, 0x63, 0x00, 0x06, 0x00, 0x01, 0x00,
- 0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00,
- 0x1f, 0x00, 0x00, 0x00, 0x80, 0x01, 0x06, 0x00,
- 0x14, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
- 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00,
- 0x08, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x00,
- 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
- 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x04, 0x00,
- 0x08, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x05, 0x00, 0x08, 0x00, 0x01, 0x00,
- 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
- 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x06, 0x00,
- 0x08, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x07, 0x00, 0x08, 0x00, 0x01, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
- 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x08, 0x00,
- 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x09, 0x00, 0x08, 0x00, 0x01, 0x00,
- 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
- 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0a, 0x00,
- 0x08, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x01, 0x00,
- 0x13, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
- 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0c, 0x00,
- 0x08, 0x00, 0x01, 0x00, 0x15, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x01, 0x00,
- 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
- 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0e, 0x00,
- 0x08, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x01, 0x00,
- 0x1a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
- 0x0c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x10, 0x00,
- 0x08, 0x00, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x11, 0x00, 0x08, 0x00, 0x01, 0x00,
- 0x1c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
- 0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00,
- 0x08, 0x00, 0x01, 0x00, 0x1d, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x00,
- 0x14, 0x00, 0x13, 0x00, 0x08, 0x00, 0x01, 0x00,
- 0x1e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
- 0x0a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x07, 0x00,
- 0x18, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00,
- 0x05, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00,
- 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x00, 0x00,
- 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x9d, 0x2e, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
- 0x1e, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x9d, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x24, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x05, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x1c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x09, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
- 0x1e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x9d, 0x2e, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00,
- 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x08, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00,
- 0x06, 0x00, 0x05, 0x00, 0x44, 0x00, 0x00, 0x00,
- 0x05, 0x00, 0x06, 0x00, 0x20, 0x00, 0x00, 0x00,
- 0x0b, 0x00, 0x07, 0x00, 0x27, 0x00, 0x00, 0x00,
- 0x93, 0xb9, 0x25, 0x00
-};
-
struct param *
unpack(const uint8_t *ptr, size_t len)
{
@@ -190,8 +103,8 @@ pack_dummy(uint8_t *ptr, size_t len)
memset(&dummy, 0, sizeof(dummy));
- dummy.wiredata.len = sizeof(sample_netlink_wiredata);
- memcpy(&dummy.wiredata.body, &sample_netlink_wiredata,
+ dummy.wiredata.len = sizeof(dummy_netlink_wiredata);
+ memcpy(&dummy.wiredata.body, &dummy_netlink_wiredata,
dummy.wiredata.len);
assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0);
@@ -213,6 +126,7 @@ test(const struct param *p)
uint32_t target;
prng_init((unsigned int)p->seed);
+ fuzz_clock_reset();
fido_init(FIDO_DEBUG);
fido_set_log_handler(consume_str);
diff --git a/contrib/libfido2/fuzz/mutator_aux.c b/contrib/libfido2/fuzz/mutator_aux.c
index 0dc3ae1bf054..92a67be78106 100644
--- a/contrib/libfido2/fuzz/mutator_aux.c
+++ b/contrib/libfido2/fuzz/mutator_aux.c
@@ -37,6 +37,8 @@ consume(const void *body, size_t len)
while (len--)
x ^= *ptr++;
+
+ (void)x;
}
void
@@ -308,7 +310,8 @@ open_dev(int nfc)
goto fail;
}
- if (fido_dev_open(dev, "nodev") != FIDO_OK)
+ if (fido_dev_set_timeout(dev, 300) != FIDO_OK ||
+ fido_dev_open(dev, "nodev") != FIDO_OK)
goto fail;
return dev;
diff --git a/contrib/libfido2/fuzz/mutator_aux.h b/contrib/libfido2/fuzz/mutator_aux.h
index 6b1a98215b07..a9bebe232bae 100644
--- a/contrib/libfido2/fuzz/mutator_aux.h
+++ b/contrib/libfido2/fuzz/mutator_aux.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019 Yubico AB. All rights reserved.
+ * Copyright (c) 2019-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -49,7 +49,7 @@
#define MUTATE_ALL (MUTATE_SEED | MUTATE_PARAM | MUTATE_WIREDATA)
#define MAXSTR 1024
-#define MAXBLOB 3072
+#define MAXBLOB 3600
struct blob {
uint8_t body[MAXBLOB];
@@ -88,6 +88,7 @@ ssize_t fd_write(int, const void *, size_t);
fido_dev_t *open_dev(int);
void set_wire_data(const uint8_t *, size_t);
+void fuzz_clock_reset(void);
void prng_init(unsigned long);
unsigned long prng_uint32(void);
diff --git a/contrib/libfido2/fuzz/report.tgz b/contrib/libfido2/fuzz/report.tgz
index c8d4d3f38028..cf74f315cb80 100644
--- a/contrib/libfido2/fuzz/report.tgz
+++ b/contrib/libfido2/fuzz/report.tgz
Binary files differ
diff --git a/contrib/libfido2/fuzz/summary.txt b/contrib/libfido2/fuzz/summary.txt
index 8516bf3723aa..298c8377379f 100644
--- a/contrib/libfido2/fuzz/summary.txt
+++ b/contrib/libfido2/fuzz/summary.txt
@@ -1,51 +1,57 @@
Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-fuzz/prng.c 31 0 100.00% 2 0 100.00% 49 0 100.00%
-fuzz/udev.c 103 5 95.15% 17 1 94.12% 141 7 95.04%
-fuzz/uniform_random.c 7 1 85.71% 1 0 100.00% 23 1 95.65%
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+fuzz/clock.c 24 1 95.83% 4 0 100.00% 35 0 100.00%
+fuzz/prng.c 31 0 100.00% 2 0 100.00% 35 0 100.00%
+fuzz/udev.c 103 1 99.03% 17 0 100.00% 126 3 97.62%
+fuzz/uniform_random.c 7 1 85.71% 1 0 100.00% 12 1 91.67%
fuzz/wrap.c 6 0 100.00% 1 0 100.00% 7 0 100.00%
-openbsd-compat/explicit_bzero.c 4 0 100.00% 1 0 100.00% 13 0 100.00%
+openbsd-compat/explicit_bzero.c 4 0 100.00% 1 0 100.00% 7 0 100.00%
openbsd-compat/freezero.c 4 0 100.00% 1 0 100.00% 6 0 100.00%
-openbsd-compat/recallocarray.c 41 7 82.93% 1 0 100.00% 49 7 85.71%
-openbsd-compat/strlcat.c 12 1 91.67% 1 0 100.00% 25 1 96.00%
-openbsd-compat/timingsafe_bcmp.c 4 0 100.00% 1 0 100.00% 8 0 100.00%
-src/aes256.c 115 4 96.52% 8 0 100.00% 175 14 92.00%
-src/assert.c 616 46 92.53% 59 3 94.92% 924 64 93.07%
-src/authkey.c 44 0 100.00% 5 0 100.00% 75 0 100.00%
-src/bio.c 419 20 95.23% 49 2 95.92% 660 22 96.67%
-src/blob.c 53 3 94.34% 10 0 100.00% 96 7 92.71%
-src/buf.c 8 1 87.50% 2 0 100.00% 20 1 95.00%
-src/cbor.c 986 17 98.28% 53 0 100.00% 1426 37 97.41%
-src/compress.c 34 4 88.24% 3 0 100.00% 30 3 90.00%
-src/config.c 94 1 98.94% 10 0 100.00% 146 3 97.95%
-src/cred.c 581 38 93.46% 63 2 96.83% 872 48 94.50%
-src/credman.c 382 10 97.38% 40 0 100.00% 614 15 97.56%
-src/dev.c 414 74 82.13% 43 6 86.05% 556 106 80.94%
-src/ecdh.c 117 2 98.29% 4 0 100.00% 161 5 96.89%
-src/eddsa.c 54 0 100.00% 8 0 100.00% 77 0 100.00%
+openbsd-compat/recallocarray.c 41 7 82.93% 1 0 100.00% 36 7 80.56%
+openbsd-compat/strlcat.c 12 1 91.67% 1 0 100.00% 21 1 95.24%
+openbsd-compat/timingsafe_bcmp.c 4 0 100.00% 1 0 100.00% 7 0 100.00%
+src/aes256.c 115 4 96.52% 8 0 100.00% 157 14 91.08%
+src/assert.c 563 40 92.90% 56 3 94.64% 694 40 94.24%
+src/authkey.c 44 0 100.00% 5 0 100.00% 59 0 100.00%
+src/bio.c 419 20 95.23% 49 2 95.92% 559 21 96.24%
+src/blob.c 53 2 96.23% 10 0 100.00% 83 4 95.18%
+src/buf.c 8 1 87.50% 2 0 100.00% 16 1 93.75%
+src/cbor.c 1047 28 97.33% 54 0 100.00% 1237 54 95.63%
+src/compress.c 34 4 88.24% 3 0 100.00% 28 3 89.29%
+src/config.c 108 0 100.00% 11 0 100.00% 151 0 100.00%
+src/cred.c 632 34 94.62% 69 2 97.10% 830 36 95.66%
+src/credman.c 382 10 97.38% 40 0 100.00% 518 15 97.10%
+src/dev.c 420 78 81.43% 44 6 86.36% 488 102 79.10%
+src/ecdh.c 117 2 98.29% 4 0 100.00% 146 5 96.58%
+src/eddsa.c 80 3 96.25% 10 0 100.00% 106 8 92.45%
src/err.c 122 10 91.80% 1 0 100.00% 126 10 92.06%
-src/es256.c 280 0 100.00% 16 0 100.00% 394 0 100.00%
-src/hid.c 60 0 100.00% 12 0 100.00% 134 0 100.00%
-src/hid_linux.c 173 68 60.69% 14 7 50.00% 303 123 59.41%
-src/hid_unix.c 30 20 33.33% 2 0 100.00% 52 28 46.15%
-src/info.c 198 0 100.00% 44 0 100.00% 405 0 100.00%
-src/io.c 158 7 95.57% 10 0 100.00% 228 11 95.18%
-src/iso7816.c 18 1 94.44% 5 0 100.00% 42 0 100.00%
-src/largeblob.c 513 19 96.30% 30 0 100.00% 759 43 94.33%
-src/log.c 39 5 87.18% 7 1 85.71% 73 4 94.52%
-src/netlink.c 327 15 95.41% 40 0 100.00% 565 35 93.81%
-src/nfc_linux.c 304 123 59.54% 23 10 56.52% 520 199 61.73%
-src/pin.c 403 3 99.26% 26 0 100.00% 583 3 99.49%
-src/random.c 6 1 83.33% 1 0 100.00% 8 1 87.50%
-src/reset.c 24 0 100.00% 3 0 100.00% 27 0 100.00%
-src/rs256.c 102 4 96.08% 8 0 100.00% 138 6 95.65%
-src/u2f.c 473 6 98.73% 15 0 100.00% 742 9 98.79%
+src/es256.c 306 5 98.37% 19 0 100.00% 358 7 98.04%
+src/hid.c 60 0 100.00% 12 0 100.00% 114 0 100.00%
+src/hid_linux.c 173 68 60.69% 14 7 50.00% 250 104 58.40%
+src/hid_unix.c 28 20 28.57% 2 0 100.00% 43 24 44.19%
+src/info.c 184 0 100.00% 39 0 100.00% 316 0 100.00%
+src/io.c 182 7 96.15% 13 0 100.00% 221 11 95.02%
+src/iso7816.c 18 1 94.44% 5 0 100.00% 38 0 100.00%
+src/largeblob.c 513 21 95.91% 30 0 100.00% 684 47 93.13%
+src/log.c 39 5 87.18% 7 1 85.71% 63 4 93.65%
+src/netlink.c 328 14 95.73% 40 0 100.00% 498 32 93.57%
+src/nfc_linux.c 327 73 77.68% 23 5 78.26% 458 124 72.93%
+src/pin.c 403 3 99.26% 26 0 100.00% 495 3 99.39%
+src/random.c 6 1 83.33% 1 0 100.00% 6 1 83.33%
+src/reset.c 24 0 100.00% 3 0 100.00% 23 0 100.00%
+src/rs1.c 25 1 96.00% 3 0 100.00% 39 3 92.31%
+src/rs256.c 141 8 94.33% 13 0 100.00% 172 10 94.19%
+src/time.c 43 3 93.02% 3 0 100.00% 43 1 97.67%
+src/tpm.c 76 0 100.00% 7 0 100.00% 138 0 100.00%
+src/types.c 25 0 100.00% 6 0 100.00% 46 0 100.00%
+src/u2f.c 528 4 99.24% 17 0 100.00% 685 12 98.25%
Files which contain no functions:
openbsd-compat/openbsd-compat.h 0 0 - 0 0 - 0 0 -
+openbsd-compat/time.h 0 0 - 0 0 - 0 0 -
src/extern.h 0 0 - 0 0 - 0 0 -
src/fido.h 0 0 - 0 0 - 0 0 -
src/fido/err.h 0 0 - 0 0 - 0 0 -
src/fido/param.h 0 0 - 0 0 - 0 0 -
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-TOTAL 7359 516 92.99% 640 32 95.00% 11252 813 92.77%
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+TOTAL 7809 481 93.84% 679 26 96.17% 10180 708 93.05%
diff --git a/contrib/libfido2/fuzz/wrap.c b/contrib/libfido2/fuzz/wrap.c
index 5b91a64dbf4b..8d7be6bb6247 100644
--- a/contrib/libfido2/fuzz/wrap.c
+++ b/contrib/libfido2/fuzz/wrap.c
@@ -4,6 +4,9 @@
* license that can be found in the LICENSE file.
*/
+#include <sys/types.h>
+#include <sys/socket.h>
+
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
@@ -50,6 +53,14 @@ WRAP(void *,
1
)
+WRAP(void *,
+ realloc,
+ (void *ptr, size_t size),
+ NULL,
+ (ptr, size),
+ 1
+)
+
WRAP(char *,
strdup,
(const char *s),
@@ -84,32 +95,6 @@ WRAP(EVP_CIPHER_CTX *,
)
WRAP(int,
- EVP_EncryptInit_ex,
- (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl,
- const unsigned char *key, const unsigned char *iv),
- 0,
- (ctx, type, impl, key, iv),
- 1
-)
-
-WRAP(int,
- EVP_CIPHER_CTX_set_padding,
- (EVP_CIPHER_CTX *x, int padding),
- 0,
- (x, padding),
- 1
-)
-
-WRAP(int,
- EVP_EncryptUpdate,
- (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
- const unsigned char *in, int inl),
- 0,
- (ctx, out, outl, in, inl),
- 1
-)
-
-WRAP(int,
EVP_CipherInit,
(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
const unsigned char *key, const unsigned char *iv, int enc),
@@ -118,48 +103,6 @@ WRAP(int,
1
)
-WRAP(int,
- EVP_DecryptInit_ex,
- (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl,
- const unsigned char *key, const unsigned char *iv),
- 0,
- (ctx, type, impl, key, iv),
- 1
-)
-
-WRAP(int,
- EVP_DecryptUpdate,
- (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
- const unsigned char *in, int inl),
- 0,
- (ctx, out, outl, in, inl),
- 1
-)
-
-WRAP(int,
- SHA256_Init,
- (SHA256_CTX *c),
- 0,
- (c),
- 1
-)
-
-WRAP(int,
- SHA256_Update,
- (SHA256_CTX *c, const void *data, size_t len),
- 0,
- (c, data, len),
- 1
-)
-
-WRAP(int,
- SHA256_Final,
- (unsigned char *md, SHA256_CTX *c),
- 0,
- (md, c),
- 1
-)
-
WRAP(RSA *,
EVP_PKEY_get0_RSA,
(EVP_PKEY *pkey),
@@ -201,6 +144,30 @@ WRAP(int,
1
)
+WRAP(int,
+ EVP_DigestInit_ex,
+ (EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl),
+ 0,
+ (ctx, type, impl),
+ 1
+)
+
+WRAP(int,
+ EVP_DigestUpdate,
+ (EVP_MD_CTX *ctx, const void *data, size_t count),
+ 0,
+ (ctx, data, count),
+ 1
+)
+
+WRAP(int,
+ EVP_DigestFinal_ex,
+ (EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize),
+ 0,
+ (ctx, md, isize),
+ 1
+)
+
WRAP(BIGNUM *,
BN_bin2bn,
(const unsigned char *s, int len, BIGNUM *ret),
@@ -241,6 +208,14 @@ WRAP(BIGNUM *,
1
)
+WRAP(RSA *,
+ RSA_new,
+ (void),
+ NULL,
+ (),
+ 1
+)
+
WRAP(int,
RSA_set0_key,
(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d),
@@ -249,6 +224,14 @@ WRAP(int,
1
)
+WRAP(int,
+ RSA_pkey_ctx_ctrl,
+ (EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2),
+ -1,
+ (ctx, optype, cmd, p1, p2),
+ 1
+)
+
WRAP(EC_KEY *,
EC_KEY_new_by_curve_name,
(int nid),
@@ -385,6 +368,30 @@ WRAP(int,
1
)
+WRAP(int,
+ EVP_PKEY_verify_init,
+ (EVP_PKEY_CTX *ctx),
+ 0,
+ (ctx),
+ 1
+)
+
+WRAP(int,
+ EVP_PKEY_CTX_ctrl,
+ (EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2),
+ -1,
+ (ctx, keytype, optype, cmd, p1, p2),
+ 1
+)
+
+WRAP(const EVP_MD *,
+ EVP_sha1,
+ (void),
+ NULL,
+ (),
+ 1
+)
+
WRAP(const EVP_MD *,
EVP_sha256,
(void),
@@ -393,6 +400,22 @@ WRAP(const EVP_MD *,
1
)
+WRAP(const EVP_CIPHER *,
+ EVP_aes_256_cbc,
+ (void),
+ NULL,
+ (),
+ 1
+)
+
+WRAP(const EVP_CIPHER *,
+ EVP_aes_256_gcm,
+ (void),
+ NULL,
+ (),
+ 1
+)
+
WRAP(unsigned char *,
HMAC,
(const EVP_MD *evp_md, const void *key, int key_len,
@@ -437,6 +460,14 @@ WRAP(int,
)
WRAP(unsigned char *,
+ SHA1,
+ (const unsigned char *d, size_t n, unsigned char *md),
+ NULL,
+ (d, n, md),
+ 1
+)
+
+WRAP(unsigned char *,
SHA256,
(const unsigned char *d, size_t n, unsigned char *md),
NULL,
@@ -501,6 +532,14 @@ WRAP(cbor_item_t *,
)
WRAP(cbor_item_t *,
+ cbor_build_uint16,
+ (uint16_t value),
+ NULL,
+ (value),
+ 1
+)
+
+WRAP(cbor_item_t *,
cbor_build_uint32,
(uint32_t value),
NULL,
@@ -508,6 +547,14 @@ WRAP(cbor_item_t *,
1
)
+WRAP(cbor_item_t *,
+ cbor_build_uint64,
+ (uint64_t value),
+ NULL,
+ (value),
+ 1
+)
+
WRAP(struct cbor_pair *,
cbor_map_handle,
(const cbor_item_t *item),
@@ -556,6 +603,14 @@ WRAP(cbor_item_t *,
1
)
+WRAP(cbor_item_t *,
+ cbor_new_definite_bytestring,
+ (void),
+ NULL,
+ (),
+ 1
+)
+
WRAP(size_t,
cbor_serialize_alloc,
(const cbor_item_t *item, cbor_mutable_data *buffer,
@@ -567,16 +622,16 @@ WRAP(size_t,
WRAP(int,
fido_tx,
- (fido_dev_t *d, uint8_t cmd, const void *buf, size_t count),
+ (fido_dev_t *d, uint8_t cmd, const void *buf, size_t count, int *ms),
-1,
- (d, cmd, buf, count),
+ (d, cmd, buf, count, ms),
1
)
WRAP(int,
- usleep,
- (unsigned int usec),
+ bind,
+ (int sockfd, const struct sockaddr *addr, socklen_t addrlen),
-1,
- (usec),
+ (sockfd, addr, addrlen),
1
)
diff --git a/contrib/libfido2/fuzz/wrapped.sym b/contrib/libfido2/fuzz/wrapped.sym
index de4f24ae0355..0e9d34627f86 100644
--- a/contrib/libfido2/fuzz/wrapped.sym
+++ b/contrib/libfido2/fuzz/wrapped.sym
@@ -1,3 +1,4 @@
+bind
BN_bin2bn
BN_bn2bin
BN_CTX_get
@@ -11,31 +12,36 @@ cbor_build_bytestring
cbor_build_negint16
cbor_build_negint8
cbor_build_string
+cbor_build_uint16
cbor_build_uint32
+cbor_build_uint64
cbor_build_uint8
cbor_load
cbor_map_add
cbor_map_handle
cbor_new_definite_array
+cbor_new_definite_bytestring
cbor_new_definite_map
cbor_serialize_alloc
+clock_gettime
EC_KEY_get0_group
EC_KEY_get0_private_key
EC_KEY_new_by_curve_name
EC_POINT_get_affine_coordinates_GFp
EC_POINT_new
+EVP_aes_256_cbc
+EVP_aes_256_gcm
EVP_Cipher
EVP_CIPHER_CTX_ctrl
EVP_CIPHER_CTX_new
-EVP_CIPHER_CTX_set_padding
EVP_CipherInit
-EVP_DecryptInit_ex
-EVP_DecryptUpdate
+EVP_DigestFinal_ex
+EVP_DigestInit_ex
+EVP_DigestUpdate
EVP_DigestVerifyInit
-EVP_EncryptInit_ex
-EVP_EncryptUpdate
EVP_MD_CTX_new
EVP_PKEY_assign
+EVP_PKEY_CTX_ctrl
EVP_PKEY_CTX_new
EVP_PKEY_CTX_new_id
EVP_PKEY_derive
@@ -50,6 +56,8 @@ EVP_PKEY_new
EVP_PKEY_new_raw_public_key
EVP_PKEY_paramgen
EVP_PKEY_paramgen_init
+EVP_PKEY_verify_init
+EVP_sha1
EVP_sha256
fido_tx
HMAC
@@ -59,11 +67,12 @@ HMAC_Init_ex
HMAC_Update
ioctl
malloc
+realloc
+RSA_new
+RSA_pkey_ctx_ctrl
RSA_set0_key
+SHA1
SHA256
-SHA256_Final
-SHA256_Init
-SHA256_Update
strdup
udev_device_get_devnode
udev_device_get_parent_with_subsystem_devtype
diff --git a/contrib/libfido2/man/CMakeLists.txt b/contrib/libfido2/man/CMakeLists.txt
index ad9f339e6f9b..3e50c50d37a0 100644
--- a/contrib/libfido2/man/CMakeLists.txt
+++ b/contrib/libfido2/man/CMakeLists.txt
@@ -48,6 +48,7 @@ list(APPEND MAN_ALIAS
eddsa_pk_new eddsa_pk_to_EVP_PKEY
es256_pk_new es256_pk_free
es256_pk_new es256_pk_from_EC_KEY
+ es256_pk_new es256_pk_from_EVP_PKEY
es256_pk_new es256_pk_from_ptr
es256_pk_new es256_pk_to_EVP_PKEY
fido_assert_new fido_assert_authdata_len
@@ -129,6 +130,10 @@ list(APPEND MAN_ALIAS
fido_cbor_info_new fido_cbor_info_versions_len
fido_cbor_info_new fido_cbor_info_versions_ptr
fido_cbor_info_new fido_dev_get_cbor_info
+ fido_cred_new fido_cred_aaguid_len
+ fido_cred_new fido_cred_aaguid_ptr
+ fido_cred_new fido_cred_attstmt_len
+ fido_cred_new fido_cred_attstmt_ptr
fido_cred_new fido_cred_authdata_len
fido_cred_new fido_cred_authdata_ptr
fido_cred_new fido_cred_authdata_raw_len
@@ -137,26 +142,25 @@ list(APPEND MAN_ALIAS
fido_cred_new fido_cred_clientdata_hash_ptr
fido_cred_new fido_cred_display_name
fido_cred_new fido_cred_flags
- fido_cred_new fido_cred_sigcount
fido_cred_new fido_cred_fmt
fido_cred_new fido_cred_free
fido_cred_new fido_cred_id_len
fido_cred_new fido_cred_id_ptr
- fido_cred_new fido_cred_aaguid_len
- fido_cred_new fido_cred_aaguid_ptr
fido_cred_new fido_cred_largeblob_key_len
fido_cred_new fido_cred_largeblob_key_ptr
+ fido_cred_new fido_cred_pin_minlen
fido_cred_new fido_cred_prot
fido_cred_new fido_cred_pubkey_len
fido_cred_new fido_cred_pubkey_ptr
fido_cred_new fido_cred_rp_id
fido_cred_new fido_cred_rp_name
+ fido_cred_new fido_cred_sigcount
fido_cred_new fido_cred_sig_len
fido_cred_new fido_cred_sig_ptr
fido_cred_new fido_cred_type
- fido_cred_new fido_cred_user_name
fido_cred_new fido_cred_user_id_len
fido_cred_new fido_cred_user_id_ptr
+ fido_cred_new fido_cred_user_name
fido_cred_new fido_cred_x5c_len
fido_cred_new fido_cred_x5c_ptr
fido_credman_metadata_new fido_credman_del_dev_rk
@@ -178,6 +182,7 @@ list(APPEND MAN_ALIAS
fido_credman_metadata_new fido_credman_rp_name
fido_credman_metadata_new fido_credman_rp_new
fido_credman_metadata_new fido_credman_set_dev_rk
+ fido_cred_set_authdata fido_cred_set_attstmt
fido_cred_set_authdata fido_cred_set_authdata_raw
fido_cred_set_authdata fido_cred_set_blob
fido_cred_set_authdata fido_cred_set_clientdata
@@ -185,6 +190,7 @@ list(APPEND MAN_ALIAS
fido_cred_set_authdata fido_cred_set_extensions
fido_cred_set_authdata fido_cred_set_fmt
fido_cred_set_authdata fido_cred_set_id
+ fido_cred_set_authdata fido_cred_set_pin_minlen
fido_cred_set_authdata fido_cred_set_prot
fido_cred_set_authdata fido_cred_set_rk
fido_cred_set_authdata fido_cred_set_rp
@@ -196,6 +202,7 @@ list(APPEND MAN_ALIAS
fido_dev_enable_entattest fido_dev_toggle_always_uv
fido_dev_enable_entattest fido_dev_force_pin_change
fido_dev_enable_entattest fido_dev_set_pin_minlen
+ fido_dev_enable_entattest fido_dev_set_pin_minlen_rpid
fido_dev_get_touch_begin fido_dev_get_touch_status
fido_dev_info_manifest fido_dev_info_free
fido_dev_info_manifest fido_dev_info_manufacturer_string
@@ -227,12 +234,14 @@ list(APPEND MAN_ALIAS
fido_dev_set_pin fido_dev_get_uv_retry_count
fido_dev_set_pin fido_dev_reset
fido_dev_set_io_functions fido_dev_set_sigmask
+ fido_dev_set_io_functions fido_dev_set_timeout
fido_dev_largeblob_get fido_dev_largeblob_set
fido_dev_largeblob_get fido_dev_largeblob_remove
fido_dev_largeblob_get fido_dev_largeblob_get_array
fido_dev_largeblob_get fido_dev_largeblob_set_array
rs256_pk_new rs256_pk_free
rs256_pk_new rs256_pk_from_ptr
+ rs256_pk_new rs256_pk_from_EVP_PKEY
rs256_pk_new rs256_pk_from_RSA
rs256_pk_new rs256_pk_to_EVP_PKEY
)
diff --git a/contrib/libfido2/man/es256_pk_new.3 b/contrib/libfido2/man/es256_pk_new.3
index 54439cd300cf..6c1bac0f57f9 100644
--- a/contrib/libfido2/man/es256_pk_new.3
+++ b/contrib/libfido2/man/es256_pk_new.3
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2018 Yubico AB. All rights reserved.
+.\" Copyright (c) 2018-2021 Yubico AB. All rights reserved.
.\" Use of this source code is governed by a BSD-style
.\" license that can be found in the LICENSE file.
.\"
@@ -9,6 +9,7 @@
.Nm es256_pk_new ,
.Nm es256_pk_free ,
.Nm es256_pk_from_EC_KEY ,
+.Nm es256_pk_from_EVP_KEY ,
.Nm es256_pk_from_ptr ,
.Nm es256_pk_to_EVP_PKEY
.Nd FIDO 2 COSE ES256 API
@@ -22,6 +23,8 @@
.Ft int
.Fn es256_pk_from_EC_KEY "es256_pk_t *pk" "const EC_KEY *ec"
.Ft int
+.Fn es256_pk_from_EVP_PKEY "es256_pk_t *pk" "const EVP_PKEY *pkey"
+.Ft int
.Fn es256_pk_from_ptr "es256_pk_t *pk" "const void *ptr" "size_t len"
.Ft EVP_PKEY *
.Fn es256_pk_to_EVP_PKEY "const es256_pk_t *pk"
@@ -79,6 +82,16 @@ No references to
are kept.
.Pp
The
+.Fn es256_pk_from_EVP_KEY
+function fills
+.Fa pk
+with the contents of
+.Fa pkey .
+No references to
+.Fa pkey
+are kept.
+.Pp
+The
.Fn es256_pk_from_ptr
function fills
.Fa pk
@@ -110,7 +123,8 @@ If an error occurs,
returns NULL.
.Sh RETURN VALUES
The
-.Fn es256_pk_from_EC_KEY
+.Fn es256_pk_from_EC_KEY ,
+.Fn es256_pk_from_EVP_KEY ,
and
.Fn es256_pk_from_ptr
functions return
diff --git a/contrib/libfido2/man/fido2-token.1 b/contrib/libfido2/man/fido2-token.1
index 43f1c0ea48b7..fd82c23cffb7 100644
--- a/contrib/libfido2/man/fido2-token.1
+++ b/contrib/libfido2/man/fido2-token.1
@@ -82,6 +82,7 @@
.Op Fl d
.Fl i Ar template_id
.Fl n Ar template_name
+.Ar device
.Nm
.Fl S
.Op Fl d
@@ -112,6 +113,11 @@
.Fl p Ar display_name
.Ar device
.Nm
+.Fl S
+.Fl m
+.Ar rp_id
+.Ar device
+.Nm
.Fl V
.Sh DESCRIPTION
.Nm
@@ -340,6 +346,12 @@ Sets the minimum PIN length of
to
.Ar pin_length .
The user will be prompted for the PIN.
+.It Fl S Fl m Ar rp_id Ar device
+Sets the list of relying party IDs that are allowed to retrieve
+the minimum PIN length of
+.Ar device .
+Multiple IDs may be specified, separated by commas.
+The user will be prompted for the PIN.
.It Fl S Fl u Ar device
Enables the FIDO 2.1
.Dq user verification always
diff --git a/contrib/libfido2/man/fido_cred_new.3 b/contrib/libfido2/man/fido_cred_new.3
index 8cecf5f29850..d779cb2c659d 100644
--- a/contrib/libfido2/man/fido_cred_new.3
+++ b/contrib/libfido2/man/fido_cred_new.3
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2018 Yubico AB. All rights reserved.
+.\" Copyright (c) 2018-2021 Yubico AB. All rights reserved.
.\" Use of this source code is governed by a BSD-style
.\" license that can be found in the LICENSE file.
.\"
@@ -8,6 +8,7 @@
.Sh NAME
.Nm fido_cred_new ,
.Nm fido_cred_free ,
+.Nm fido_cred_pin_minlen ,
.Nm fido_cred_prot ,
.Nm fido_cred_fmt ,
.Nm fido_cred_rp_id ,
@@ -24,6 +25,7 @@
.Nm fido_cred_sig_ptr ,
.Nm fido_cred_user_id_ptr ,
.Nm fido_cred_x5c_ptr ,
+.Nm fido_cred_attstmt_ptr ,
.Nm fido_cred_authdata_len ,
.Nm fido_cred_authdata_raw_len ,
.Nm fido_cred_clientdata_hash_len ,
@@ -34,6 +36,7 @@
.Nm fido_cred_sig_len ,
.Nm fido_cred_user_id_len ,
.Nm fido_cred_x5c_len ,
+.Nm fido_cred_attstmt_len ,
.Nm fido_cred_type ,
.Nm fido_cred_flags ,
.Nm fido_cred_sigcount
@@ -44,8 +47,10 @@
.Fn fido_cred_new "void"
.Ft void
.Fn fido_cred_free "fido_cred_t **cred_p"
+.Ft size_t
+.Fn fido_cred_pin_minlen "const fido_cred_t *cred"
.Ft int
-.Fn fido_cred_prot "fido_cred_t *cred"
+.Fn fido_cred_prot "const fido_cred_t *cred"
.Ft const char *
.Fn fido_cred_fmt "const fido_cred_t *cred"
.Ft const char *
@@ -76,6 +81,8 @@
.Fn fido_cred_user_id_ptr "const fido_cred_t *cred"
.Ft const unsigned char *
.Fn fido_cred_x5c_ptr "const fido_cred_t *cred"
+.Ft const unsigned char *
+.Fn fido_cred_attstmt_ptr "const fido_cred_t *cred"
.Ft size_t
.Fn fido_cred_authdata_len "const fido_cred_t *cred"
.Ft size_t
@@ -96,6 +103,8 @@
.Fn fido_cred_user_id_len "const fido_cred_t *cred"
.Ft size_t
.Fn fido_cred_x5c_len "const fido_cred_t *cred"
+.Ft size_t
+.Fn fido_cred_attstmt_len "const fido_cred_t *cred"
.Ft int
.Fn fido_cred_type "const fido_cred_t *cred"
.Ft uint8_t
@@ -146,13 +155,35 @@ may be NULL, in which case
.Fn fido_cred_free
is a NOP.
.Pp
-The
+If the FIDO 2.1
+.Dv FIDO_EXT_MINPINLEN
+extension is enabled on
+.Fa cred ,
+then the
+.Fn fido_cred_pin_minlen
+function returns the minimum PIN length of
+.Fa cred .
+Otherwise,
+.Fn fido_cred_pin_minlen
+returns zero.
+See
+.Xr fido_cred_set_pin_minlen 3
+on how to enable this extension.
+.Pp
+If the FIDO 2.1
+.Dv FIDO_EXT_CRED_PROTECT
+extension is enabled on
+.Fa cred ,
+then the
.Fn fido_cred_prot
function returns the protection of
.Fa cred .
+Otherwise,
+.Fn fido_cred_prot
+returns zero.
See
.Xr fido_cred_set_prot 3
-for the values understood by
+for the protection policies understood by
.Em libfido2 .
.Pp
The
@@ -186,12 +217,14 @@ The
.Fn fido_cred_pubkey_ptr ,
.Fn fido_cred_sig_ptr ,
.Fn fido_cred_user_id_ptr ,
+.Fn fido_cred_x5c_ptr ,
and
-.Fn fido_cred_x5c_ptr
+.Fn fido_cred_attstmt_ptr
functions return pointers to the CBOR-encoded and raw authenticator
data, client data hash, ID, authenticator attestation GUID,
.Dq largeBlobKey ,
-public key, signature, user ID, and x509 certificate parts of
+public key, signature, user ID, x509 certificate, and attestation
+statement parts of
.Fa cred ,
or NULL if the respective entry is not set.
.Pp
@@ -205,8 +238,9 @@ The corresponding length can be obtained by
.Fn fido_cred_pubkey_len ,
.Fn fido_cred_sig_len ,
.Fn fido_cred_user_id_len ,
+.Fn fido_cred_x5c_len ,
and
-.Fn fido_cred_x5c_len .
+.Fn fido_cred_attstmt_len .
.Pp
The authenticator data, x509 certificate, and signature parts of a
credential are typically passed to a FIDO 2 server for verification.
@@ -251,6 +285,8 @@ qualifier is invoked.
.Sh SEE ALSO
.Xr fido_cred_exclude 3 ,
.Xr fido_cred_set_authdata 3 ,
+.Xr fido_cred_set_pin_minlen 3 ,
+.Xr fido_cred_set_prot 3 ,
.Xr fido_cred_verify 3 ,
.Xr fido_credman_metadata_new 3 ,
.Xr fido_dev_largeblob_get 3 ,
diff --git a/contrib/libfido2/man/fido_cred_set_authdata.3 b/contrib/libfido2/man/fido_cred_set_authdata.3
index 91e1edbaf810..7bae51f43674 100644
--- a/contrib/libfido2/man/fido_cred_set_authdata.3
+++ b/contrib/libfido2/man/fido_cred_set_authdata.3
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2018 Yubico AB. All rights reserved.
+.\" Copyright (c) 2018-2021 Yubico AB. All rights reserved.
.\" Use of this source code is governed by a BSD-style
.\" license that can be found in the LICENSE file.
.\"
@@ -8,6 +8,7 @@
.Sh NAME
.Nm fido_cred_set_authdata ,
.Nm fido_cred_set_authdata_raw ,
+.Nm fido_cred_set_attstmt ,
.Nm fido_cred_set_x509 ,
.Nm fido_cred_set_sig ,
.Nm fido_cred_set_id ,
@@ -17,6 +18,7 @@
.Nm fido_cred_set_user ,
.Nm fido_cred_set_extensions ,
.Nm fido_cred_set_blob ,
+.Nm fido_cred_set_pin_minlen ,
.Nm fido_cred_set_prot ,
.Nm fido_cred_set_rk ,
.Nm fido_cred_set_uv ,
@@ -37,6 +39,8 @@ typedef enum {
.Ft int
.Fn fido_cred_set_authdata_raw "fido_cred_t *cred" "const unsigned char *ptr" "size_t len"
.Ft int
+.Fn fido_cred_set_attstmt "fido_cred_t *cred" "const unsigned char *ptr" "size_t len"
+.Ft int
.Fn fido_cred_set_x509 "fido_cred_t *cred" "const unsigned char *ptr" "size_t len"
.Ft int
.Fn fido_cred_set_sig "fido_cred_t *cred" "const unsigned char *ptr" "size_t len"
@@ -55,6 +59,8 @@ typedef enum {
.Ft int
.Fn fido_cred_set_blob "fido_cred_t *cred" "const unsigned char *ptr" "size_t len"
.Ft int
+.Fn fido_cred_set_pin_minlen "fido_cred_t *cred" "size_t len"
+.Ft int
.Fn fido_cred_set_prot "fido_cred_t *cred" "int prot"
.Ft int
.Fn fido_cred_set_rk "fido_cred_t *cred" "fido_opt_t rk"
@@ -80,13 +86,15 @@ of its constituent parts, please refer to the Web Authentication
.Pp
The
.Fn fido_cred_set_authdata ,
+.Fn fido_cred_set_attstmt ,
.Fn fido_cred_set_x509 ,
.Fn fido_cred_set_sig ,
.Fn fido_cred_set_id ,
and
.Fn fido_cred_set_clientdata_hash
-functions set the authenticator data, attestation certificate,
-signature, id, and client data hash parts of
+functions set the authenticator data, attestation statement,
+attestation certificate, attestation signature, id, and client
+data hash parts of
.Fa cred
to
.Fa ptr ,
@@ -98,13 +106,13 @@ bytes.
A copy of
.Fa ptr
is made, and no references to the passed pointer are kept.
+.Pp
The authenticator data passed to
.Fn fido_cred_set_authdata
must be a CBOR-encoded byte string, as obtained from
.Fn fido_cred_authdata_ptr .
Alternatively, a raw binary blob may be passed to
.Fn fido_cred_set_authdata_raw .
-.Pp
An application calling
.Fn fido_cred_set_authdata
does not need to call
@@ -112,6 +120,20 @@ does not need to call
The latter is meant to be used in contexts where the
credential's authenticator data is not available.
.Pp
+The attestation statement passed to
+.Fn fido_cred_set_attstmt
+must be a CBOR-encoded map, as obtained from
+.Fn fido_cred_attstmt_ptr .
+An application calling
+.Fn fido_cred_set_attstmt
+does not need to call
+.Fn fido_cred_set_x509
+or
+.Fn fido_cred_set_sig .
+The latter two are meant to be used in contexts where the
+credential's complete attestation statement is not available or
+required.
+.Pp
The
.Fn fido_cred_set_clientdata
function allows an application to set the client data hash of
@@ -183,6 +205,7 @@ At the moment, only the
.Dv FIDO_EXT_CRED_BLOB ,
.Dv FIDO_EXT_CRED_PROTECT ,
.Dv FIDO_EXT_HMAC_SECRET ,
+.Dv FIDO_EXT_MINPINLEN ,
and
.Dv FIDO_EXT_LARGEBLOB_KEY
extensions are supported.
@@ -205,8 +228,32 @@ which must be
bytes long.
.Pp
The
+.Fn fido_cred_set_pin_minlen
+function enables the FIDO 2.1
+.Dv FIDO_EXT_MINPINLEN
+extension on
+.Fa cred
+and sets the expected minimum PIN length of
+.Fa cred
+to
+.Fa len ,
+where
+.Fa len
+is greater than zero.
+If
+.Fa len
+is zero, the
+.Dv FIDO_EXT_MINPINLEN
+extension is disabled on
+.Fa cred .
+.Pp
+The
.Fn fido_cred_set_prot
-function sets the protection of
+function enables the FIDO 2.1
+.Dv FIDO_EXT_CRED_PROTECT
+extension on
+.Fa cred
+and sets the protection of
.Fa cred
to the scalar
.Fa prot .
diff --git a/contrib/libfido2/man/fido_cred_verify.3 b/contrib/libfido2/man/fido_cred_verify.3
index 6b720f2132ea..ec95e134572e 100644
--- a/contrib/libfido2/man/fido_cred_verify.3
+++ b/contrib/libfido2/man/fido_cred_verify.3
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2018 Yubico AB. All rights reserved.
+.\" Copyright (c) 2018-2021 Yubico AB. All rights reserved.
.\" Use of this source code is governed by a BSD-style
.\" license that can be found in the LICENSE file.
.\"
@@ -29,8 +29,8 @@ A brief description follows:
The
.Fn fido_cred_verify
function verifies whether the client data hash, relying party ID,
-credential ID, type, and resident/discoverable key and user verification
-attributes of
+credential ID, type, protection policy, minimum PIN length, and
+resident/discoverable key and user verification attributes of
.Fa cred
have been attested by the holder of the private counterpart of
the public key contained in the credential's x509 certificate.
@@ -40,14 +40,14 @@ Please note that the x509 certificate itself is not verified.
The attestation statement formats supported by
.Fn fido_cred_verify
are
-.Em packed
+.Em packed ,
+.Em fido-u2f ,
and
-.Em fido-u2f .
+.Em tpm .
The attestation type implemented by
.Fn fido_cred_verify
is
.Em Basic Attestation .
-The attestation key pair is assumed to be of the type ES256.
Other attestation formats and types are not supported.
.Sh RETURN VALUES
The error codes returned by
diff --git a/contrib/libfido2/man/fido_dev_enable_entattest.3 b/contrib/libfido2/man/fido_dev_enable_entattest.3
index 7cb766d41d0c..17962d3d35d5 100644
--- a/contrib/libfido2/man/fido_dev_enable_entattest.3
+++ b/contrib/libfido2/man/fido_dev_enable_entattest.3
@@ -9,7 +9,8 @@
.Nm fido_dev_enable_entattest ,
.Nm fido_dev_toggle_always_uv ,
.Nm fido_dev_force_pin_change ,
-.Nm fido_dev_set_pin_minlen
+.Nm fido_dev_set_pin_minlen ,
+.Nm fido_dev_set_pin_minlen_rpid
.Nd FIDO 2.1 configuration authenticator API
.Sh SYNOPSIS
.In fido.h
@@ -22,6 +23,8 @@
.Fn fido_dev_force_pin_change "fido_dev_t *dev" "const char *pin"
.Ft int
.Fn fido_dev_set_pin_minlen "fido_dev_t *dev" "size_t len" "const char *pin"
+.Ft int
+.Fn fido_dev_set_pin_minlen_rpid "fido_dev_t *dev" "const char * const *rpid" "size_t n" "const char *pin"
.Sh DESCRIPTION
The functions described in this page allow configuration of a
FIDO 2.1 authenticator.
@@ -77,6 +80,24 @@ to
.Fa len .
Minimum PIN lengths may only be increased.
.Pp
+The
+.Fn fido_dev_set_pin_minlen_rpid
+function sets the list of relying party identifiers
+.Pq RP IDs
+that are allowed to obtain the minimum PIN length of
+.Fa dev
+through the FIDO 2.1
+.Dv FIDO_EXT_MINPINLEN
+extension.
+The list of RP identifiers is denoted by
+.Fa rpid ,
+a vector of
+.Fa n
+NUL-terminated UTF-8 strings.
+A copy of
+.Fa rpid
+is made, and no reference to it or its contents is kept.
+.Pp
Configuration settings are reflected in the payload returned by the
authenticator in response to a
.Xr fido_dev_get_cbor_info 3
@@ -86,13 +107,15 @@ The error codes returned by
.Fn fido_dev_enable_entattest ,
.Fn fido_dev_toggle_always_uv ,
.Fn fido_dev_force_pin_change ,
+.Fn fido_dev_set_pin_minlen ,
and
-.Fn fido_dev_set_pin_minlen
+.Fn fido_dev_set_pin_minlen_rpid
are defined in
.In fido/err.h .
On success,
.Dv FIDO_OK
is returned.
.Sh SEE ALSO
+.Xr fido_cred_pin_minlen 3 ,
.Xr fido_dev_get_cbor_info 3 ,
.Xr fido_dev_reset 3
diff --git a/contrib/libfido2/man/fido_dev_info_manifest.3 b/contrib/libfido2/man/fido_dev_info_manifest.3
index 22519e29b9fa..76e399cec319 100644
--- a/contrib/libfido2/man/fido_dev_info_manifest.3
+++ b/contrib/libfido2/man/fido_dev_info_manifest.3
@@ -112,11 +112,21 @@ The
.Fn fido_dev_info_manufacturer_string
function returns the manufacturer string of
.Fa di .
+If
+.Fa di
+does not have an associated manufacturer string,
+.Fn fido_dev_info_manufacturer_string
+returns an empty string.
.Pp
The
.Fn fido_dev_info_product_string
function returns the product string of
.Fa di .
+If
+.Fa di
+does not have an associated product string,
+.Fn fido_dev_info_product_string
+returns an empty string.
.Pp
An example of how to use the functions described in this document
can be found in the
diff --git a/contrib/libfido2/man/fido_dev_set_io_functions.3 b/contrib/libfido2/man/fido_dev_set_io_functions.3
index 231ae2411be8..52081f126e78 100644
--- a/contrib/libfido2/man/fido_dev_set_io_functions.3
+++ b/contrib/libfido2/man/fido_dev_set_io_functions.3
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2018 Yubico AB. All rights reserved.
+.\" Copyright (c) 2018-2021 Yubico AB. All rights reserved.
.\" Use of this source code is governed by a BSD-style
.\" license that can be found in the LICENSE file.
.\"
@@ -7,7 +7,8 @@
.Os
.Sh NAME
.Nm fido_dev_set_io_functions ,
-.Nm fido_dev_set_sigmask
+.Nm fido_dev_set_sigmask ,
+.Nm fido_dev_set_timeout
.Nd FIDO 2 device I/O interface
.Sh SYNOPSIS
.In fido.h
@@ -34,6 +35,8 @@ typedef sigset_t fido_sigset_t;
.Fn fido_dev_set_io_functions "fido_dev_t *dev" "const fido_dev_io_t *io"
.Ft int
.Fn fido_dev_set_sigmask "fido_dev_t *dev" "const fido_sigset_t *sigmask"
+.Ft int
+.Fn fido_dev_set_timeout "fido_dev_t *dev" "int ms"
.Sh DESCRIPTION
The
.Fn fido_dev_set_io_functions
@@ -122,11 +125,35 @@ No references to
.Fa sigmask
are held by
.Fn fido_dev_set_sigmask .
+.Pp
+The
+.Fn fido_dev_set_timeout
+function informs
+.Em libfido2
+not to block for more than
+.Fa ms
+milliseconds while communicating with
+.Fa dev .
+If a timeout occurs, the corresponding
+.Em fido_dev_*
+function will fail with
+.Dv FIDO_ERR_RX .
+If
+.Fa ms
+is -1,
+then
+.Em libfido2
+may block indefinitely.
+This is the default behaviour.
+When using the Windows Hello backend,
+.Fa ms
+is used as a guidance and may be overwritten by the platform.
.Sh RETURN VALUES
On success,
-.Fn fido_dev_set_io_functions
+.Fn fido_dev_set_io_functions ,
+.Fn fido_dev_set_sigmask ,
and
-.Fn fido_dev_set_sigmask
+.Fn fido_dev_set_timeout
return
.Dv FIDO_OK .
On error, a different error code defined in
diff --git a/contrib/libfido2/man/rs256_pk_new.3 b/contrib/libfido2/man/rs256_pk_new.3
index 4ad0ebe936f3..ad33ee66ba7b 100644
--- a/contrib/libfido2/man/rs256_pk_new.3
+++ b/contrib/libfido2/man/rs256_pk_new.3
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2018 Yubico AB. All rights reserved.
+.\" Copyright (c) 2018-2021 Yubico AB. All rights reserved.
.\" Use of this source code is governed by a BSD-style
.\" license that can be found in the LICENSE file.
.\"
@@ -8,6 +8,7 @@
.Sh NAME
.Nm rs256_pk_new ,
.Nm rs256_pk_free ,
+.Nm rs256_pk_from_EVP_PKEY ,
.Nm rs256_pk_from_RSA ,
.Nm rs256_pk_from_ptr ,
.Nm rs256_pk_to_EVP_PKEY
@@ -20,6 +21,8 @@
.Ft void
.Fn rs256_pk_free "rs256_pk_t **pkp"
.Ft int
+.Fn rs256_pk_from_EVP_PKEY "rs256_pk_t *pk" "const EVP_PKEY *pkey"
+.Ft int
.Fn rs256_pk_from_RSA "rs256_pk_t *pk" "const RSA *rsa"
.Ft int
.Fn rs256_pk_from_ptr "rs256_pk_t *pk" "const void *ptr" "size_t len"
@@ -69,6 +72,16 @@ may be NULL, in which case
is a NOP.
.Pp
The
+.Fn rs256_pk_from_EVP_PKEY
+function fills
+.Fa pk
+with the contents of
+.Fa pkey .
+No references to
+.Fa pkey
+are kept.
+.Pp
+The
.Fn rs256_pk_from_RSA
function fills
.Fa pk
@@ -106,7 +119,8 @@ If an error occurs,
returns NULL.
.Sh RETURN VALUES
The
-.Fn rs256_pk_from_RSA
+.Fn rs256_pk_from_EVP_PKEY ,
+.Fn rs256_pk_from_RSA ,
and
.Fn rs256_pk_from_ptr
functions return
diff --git a/contrib/libfido2/openbsd-compat/hkdf.c b/contrib/libfido2/openbsd-compat/hkdf.c
deleted file mode 100644
index 745b420f3747..000000000000
--- a/contrib/libfido2/openbsd-compat/hkdf.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/* $OpenBSD: hkdf.c,v 1.4 2019/11/21 20:02:20 tim Exp $ */
-/* Copyright (c) 2014, Google Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "openbsd-compat.h"
-#include "fido.h"
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-
-#include <assert.h>
-#include <string.h>
-
-#include <openssl/err.h>
-#include <openssl/hmac.h>
-
-#define CRYPTOerror(r) CRYPTOerr(ERR_LIB_CRYPTO, (r))
-
-/* https://tools.ietf.org/html/rfc5869#section-2 */
-int
-HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest,
- const uint8_t *secret, size_t secret_len, const uint8_t *salt,
- size_t salt_len, const uint8_t *info, size_t info_len)
-{
- uint8_t prk[EVP_MAX_MD_SIZE];
- size_t prk_len;
-
- if (!HKDF_extract(prk, &prk_len, digest, secret, secret_len, salt,
- salt_len))
- return 0;
- if (!HKDF_expand(out_key, out_len, digest, prk, prk_len, info,
- info_len))
- return 0;
-
- return 1;
-}
-
-/* https://tools.ietf.org/html/rfc5869#section-2.2 */
-int
-HKDF_extract(uint8_t *out_key, size_t *out_len,
- const EVP_MD *digest, const uint8_t *secret, size_t secret_len,
- const uint8_t *salt, size_t salt_len)
-{
- unsigned int len;
-
- /*
- * If salt is not given, HashLength zeros are used. However, HMAC does
- * that internally already so we can ignore it.
- */
- if (salt_len > INT_MAX || HMAC(digest, salt, (int)salt_len, secret,
- secret_len, out_key, &len) == NULL) {
- CRYPTOerror(ERR_R_CRYPTO_LIB);
- return 0;
- }
- *out_len = len;
- return 1;
-}
-
-/* https://tools.ietf.org/html/rfc5869#section-2.3 */
-int
-HKDF_expand(uint8_t *out_key, size_t out_len,
- const EVP_MD *digest, const uint8_t *prk, size_t prk_len,
- const uint8_t *info, size_t info_len)
-{
- const size_t digest_len = EVP_MD_size(digest);
- uint8_t previous[EVP_MAX_MD_SIZE];
- size_t n, done = 0;
- unsigned int i;
- int ret = 0;
- HMAC_CTX hmac;
-
- /* Expand key material to desired length. */
- n = (out_len + digest_len - 1) / digest_len;
- if (out_len + digest_len < out_len || n > 255 || prk_len > INT_MAX) {
- CRYPTOerror(EVP_R_TOO_LARGE);
- return 0;
- }
-
- HMAC_CTX_init(&hmac);
- if (!HMAC_Init_ex(&hmac, prk, (int)prk_len, digest, NULL))
- goto out;
-
- for (i = 0; i < n; i++) {
- uint8_t ctr = i + 1;
- size_t todo;
-
- if (i != 0 && (!HMAC_Init_ex(&hmac, NULL, 0, NULL, NULL) ||
- !HMAC_Update(&hmac, previous, digest_len)))
- goto out;
-
- if (!HMAC_Update(&hmac, info, info_len) ||
- !HMAC_Update(&hmac, &ctr, 1) ||
- !HMAC_Final(&hmac, previous, NULL))
- goto out;
-
- todo = digest_len;
- if (done + todo > out_len)
- todo = out_len - done;
-
- memcpy(out_key + done, previous, todo);
- done += todo;
- }
-
- ret = 1;
-
- out:
- HMAC_CTX_cleanup(&hmac);
- explicit_bzero(previous, sizeof(previous));
- if (ret != 1)
- CRYPTOerror(ERR_R_CRYPTO_LIB);
- return ret;
-}
-#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
diff --git a/contrib/libfido2/openbsd-compat/hkdf.h b/contrib/libfido2/openbsd-compat/hkdf.h
deleted file mode 100644
index 34450f9dd7f0..000000000000
--- a/contrib/libfido2/openbsd-compat/hkdf.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* $OpenBSD: hkdf.h,v 1.2 2018/04/03 13:33:53 tb Exp $ */
-/* Copyright (c) 2014, Google Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-
-#ifndef OPENSSL_HEADER_HKDF_H
-#define OPENSSL_HEADER_HKDF_H
-
-#include <openssl/evp.h>
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-/*
- * HKDF computes HKDF (as specified by RFC 5869) of initial keying
- * material |secret| with |salt| and |info| using |digest|, and
- * outputs |out_len| bytes to |out_key|. It returns one on success and
- * zero on error.
- *
- * HKDF is an Extract-and-Expand algorithm. It does not do any key
- * stretching, and as such, is not suited to be used alone to generate
- * a key from a password.
- */
-
-int HKDF(uint8_t *out_key, size_t out_len, const struct env_md_st *digest,
- const uint8_t *secret, size_t secret_len, const uint8_t *salt,
- size_t salt_len, const uint8_t *info, size_t info_len);
-
-/*
- * HKDF_extract computes a HKDF PRK (as specified by RFC 5869) from
- * initial keying material |secret| and salt |salt| using |digest|,
- * and outputs |out_len| bytes to |out_key|. The maximum output size
- * is |EVP_MAX_MD_SIZE|. It returns one on success and zero on error.
- */
-int HKDF_extract(uint8_t *out_key, size_t *out_len,
- const struct env_md_st *digest, const uint8_t *secret,
- size_t secret_len, const uint8_t *salt, size_t salt_len);
-
-/*
- * HKDF_expand computes a HKDF OKM (as specified by RFC 5869) of
- * length |out_len| from the PRK |prk| and info |info| using |digest|,
- * and outputs the result to |out_key|. It returns one on success and
- * zero on error.
- */
-int HKDF_expand(uint8_t *out_key, size_t out_len,
- const EVP_MD *digest, const uint8_t *prk, size_t prk_len,
- const uint8_t *info, size_t info_len);
-
-
-#if defined(__cplusplus)
-} /* extern C */
-#endif
-
-#endif /* OPENSSL_HEADER_HKDF_H */
diff --git a/contrib/libfido2/openbsd-compat/openbsd-compat.h b/contrib/libfido2/openbsd-compat/openbsd-compat.h
index 1be3aa295051..dc9acec4c0a8 100644
--- a/contrib/libfido2/openbsd-compat/openbsd-compat.h
+++ b/contrib/libfido2/openbsd-compat/openbsd-compat.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -20,6 +20,7 @@
#define be16toh(x) OSSwapBigToHostInt16((x))
#define htobe16(x) OSSwapHostToBigInt16((x))
#define be32toh(x) OSSwapBigToHostInt32((x))
+#define htobe32(x) OSSwapHostToBigInt32((x))
#define htole32(x) OSSwapHostToLittleInt32((x))
#define htole64(x) OSSwapHostToLittleInt64((x))
#endif /* __APPLE__ && !HAVE_ENDIAN_H */
@@ -33,11 +34,12 @@
#define be16toh(x) ntohs((x))
#define htobe16(x) htons((x))
#define be32toh(x) ntohl((x))
+#define htobe32(x) htonl((x))
uint32_t htole32(uint32_t);
uint64_t htole64(uint64_t);
#endif /* _WIN32 && !HAVE_ENDIAN_H */
-#if defined(__FreeBSD__) && !defined(HAVE_ENDIAN_H)
+#if (defined(__FreeBSD__) || defined(__MidnightBSD__)) && !defined(HAVE_ENDIAN_H)
#include <sys/endian.h>
#endif
@@ -52,6 +54,10 @@ size_t strlcat(char *, const char *, size_t);
size_t strlcpy(char *, const char *, size_t);
#endif
+#if !defined(HAVE_STRSEP)
+char *strsep(char **, const char *);
+#endif
+
#if !defined(HAVE_RECALLOCARRAY)
void *recallocarray(void *, size_t, size_t, size_t);
#endif
@@ -80,13 +86,6 @@ int timingsafe_bcmp(const void *, const void *, size_t);
#include <openssl/opensslv.h>
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-#include <stdint.h>
-#include "hkdf.h"
-#define EVP_PKEY_get0_EC_KEY(x) ((x)->pkey.ec)
-#define EVP_PKEY_get0_RSA(x) ((x)->pkey.rsa)
-#endif
-
#if !defined(HAVE_ERR_H)
#include "err.h"
#else
diff --git a/contrib/libfido2/openbsd-compat/strsep.c b/contrib/libfido2/openbsd-compat/strsep.c
new file mode 100644
index 000000000000..578668c8ac7b
--- /dev/null
+++ b/contrib/libfido2/openbsd-compat/strsep.c
@@ -0,0 +1,79 @@
+/* $OpenBSD: strsep.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* OPENBSD ORIGINAL: lib/libc/string/strsep.c */
+
+#include "openbsd-compat.h"
+
+#if !defined(HAVE_STRSEP)
+
+#include <string.h>
+#include <stdio.h>
+
+/*
+ * Get next token from string *stringp, where tokens are possibly-empty
+ * strings separated by characters from delim.
+ *
+ * Writes NULs into the string at *stringp to end tokens.
+ * delim need not remain constant from call to call.
+ * On return, *stringp points past the last NUL written (if there might
+ * be further tokens), or is NULL (if there are definitely no more tokens).
+ *
+ * If *stringp is NULL, strsep returns NULL.
+ */
+char *
+strsep(char **stringp, const char *delim)
+{
+ char *s;
+ const char *spanp;
+ int c, sc;
+ char *tok;
+
+ if ((s = *stringp) == NULL)
+ return (NULL);
+ for (tok = s;;) {
+ c = *s++;
+ spanp = delim;
+ do {
+ if ((sc = *spanp++) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = 0;
+ *stringp = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
+
+#endif /* !defined(HAVE_STRSEP) */
diff --git a/contrib/libfido2/regress/CMakeLists.txt b/contrib/libfido2/regress/CMakeLists.txt
index 0314c38f7161..c550b3141822 100644
--- a/contrib/libfido2/regress/CMakeLists.txt
+++ b/contrib/libfido2/regress/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Yubico AB. All rights reserved.
+# Copyright (c) 2018-2021 Yubico AB. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
@@ -7,10 +7,14 @@ add_custom_target(regress ALL)
macro(add_regress_test NAME SOURCES)
add_executable(${NAME} ${SOURCES})
target_link_libraries(${NAME} fido2_shared)
- add_custom_command(TARGET regress POST_BUILD COMMAND ${NAME}
- DEPENDS ${NAME})
+ add_test(${NAME} ${NAME})
+ add_dependencies(regress ${NAME})
endmacro()
+add_custom_command(TARGET regress POST_BUILD
+ COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
+
add_regress_test(regress_cred cred.c)
add_regress_test(regress_assert assert.c)
add_regress_test(regress_dev dev.c)
diff --git a/contrib/libfido2/regress/assert.c b/contrib/libfido2/regress/assert.c
index dfaf50662c76..23d666a61173 100644
--- a/contrib/libfido2/regress/assert.c
+++ b/contrib/libfido2/regress/assert.c
@@ -1,9 +1,11 @@
/*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
+#define _FIDO_INTERNAL
+
#include <assert.h>
#include <fido.h>
#include <fido/es256.h>
@@ -24,6 +26,42 @@ static const unsigned char es256_pk[64] = {
0x64, 0x1a, 0x1d, 0xf8, 0xbe, 0x14, 0x90, 0x8a,
};
+static const unsigned char rs256_pk[259] = {
+ 0x9e, 0x54, 0x78, 0xb2, 0x51, 0xbe, 0x19, 0x7c,
+ 0xcb, 0x1a, 0x9a, 0xc3, 0x49, 0x2a, 0x2f, 0xfd,
+ 0x99, 0x64, 0x76, 0xc6, 0xdb, 0xca, 0x38, 0x3f,
+ 0xb0, 0x6a, 0xc9, 0xc0, 0x07, 0x9f, 0x5c, 0x4d,
+ 0xfc, 0xd1, 0x01, 0x7f, 0x69, 0x65, 0xab, 0x9c,
+ 0x2a, 0xc2, 0x95, 0xd9, 0x44, 0xf3, 0xea, 0x94,
+ 0x6b, 0x25, 0x66, 0x54, 0x81, 0xee, 0x24, 0x1d,
+ 0xe1, 0x7d, 0x7f, 0xbe, 0xea, 0x76, 0x90, 0x5c,
+ 0xbf, 0x59, 0x22, 0xd3, 0xa0, 0x68, 0x1a, 0x65,
+ 0x8b, 0x2f, 0xb6, 0xa8, 0x30, 0x2d, 0x26, 0x81,
+ 0xfa, 0x9e, 0x59, 0xec, 0x2f, 0xee, 0x59, 0x39,
+ 0xe2, 0x79, 0x19, 0x54, 0x54, 0xdf, 0x24, 0x83,
+ 0xee, 0x61, 0x5a, 0x66, 0x24, 0x2b, 0x7b, 0xfb,
+ 0x82, 0x66, 0xe4, 0x85, 0x18, 0x20, 0x76, 0xe5,
+ 0x4a, 0xb6, 0xcb, 0xec, 0x43, 0xbe, 0xfd, 0xb0,
+ 0x8f, 0xfd, 0x2f, 0x69, 0xda, 0x06, 0x9c, 0x09,
+ 0x68, 0x7a, 0x94, 0x6c, 0xb7, 0x51, 0x6d, 0x4c,
+ 0xf7, 0x13, 0xe8, 0xd5, 0x22, 0x6b, 0x1e, 0xba,
+ 0xb9, 0x85, 0xe8, 0x5f, 0xa1, 0x66, 0xe3, 0x20,
+ 0x75, 0x30, 0x11, 0xb5, 0xa3, 0xc3, 0xb0, 0x72,
+ 0x08, 0xff, 0xa3, 0xbb, 0xf1, 0x32, 0x0b, 0x06,
+ 0xc4, 0x12, 0xa3, 0x49, 0x30, 0x19, 0xb9, 0xfe,
+ 0x69, 0x0c, 0xd6, 0xe1, 0x58, 0x36, 0xe6, 0x41,
+ 0x22, 0x41, 0xbf, 0x96, 0x50, 0x35, 0x56, 0x0d,
+ 0x92, 0x8c, 0x34, 0xea, 0x28, 0x91, 0x88, 0x9e,
+ 0x8a, 0xaa, 0x36, 0xd0, 0x0f, 0xbe, 0x16, 0xde,
+ 0x9d, 0x5f, 0x7b, 0xda, 0x52, 0xf7, 0xf1, 0xb6,
+ 0x28, 0x10, 0x05, 0x8f, 0xb9, 0x19, 0x7a, 0xcf,
+ 0x18, 0x9b, 0x40, 0xcd, 0xff, 0x78, 0xea, 0x61,
+ 0x24, 0x3b, 0x80, 0x68, 0x04, 0x9b, 0x40, 0x07,
+ 0x98, 0xd4, 0x94, 0xd1, 0x18, 0x44, 0xa5, 0xed,
+ 0xee, 0x18, 0xc2, 0x25, 0x52, 0x66, 0x42, 0xdf,
+ 0x01, 0x00, 0x01,
+};
+
static const unsigned char cdh[32] = {
0xec, 0x8d, 0x8f, 0x78, 0x42, 0x4a, 0x2b, 0xb7,
0x82, 0x34, 0xaa, 0xca, 0x07, 0xa1, 0xf6, 0x56,
@@ -397,7 +435,7 @@ junk_cdh(void)
junk = malloc(sizeof(cdh));
assert(junk != NULL);
memcpy(junk, cdh, sizeof(cdh));
- junk[0] = ~junk[0];
+ junk[0] = (unsigned char)~junk[0];
a = alloc_assert();
pk = alloc_es256_pk();
@@ -448,7 +486,7 @@ junk_authdata(void)
junk = malloc(sizeof(authdata));
assert(junk != NULL);
memcpy(junk, authdata, sizeof(authdata));
- junk[0] = ~junk[0];
+ junk[0] = (unsigned char)~junk[0];
a = alloc_assert();
assert(fido_assert_set_count(a, 1) == FIDO_OK);
@@ -468,7 +506,7 @@ junk_sig(void)
junk = malloc(sizeof(sig));
assert(junk != NULL);
memcpy(junk, sig, sizeof(sig));
- junk[0] = ~junk[0];
+ junk[0] = (unsigned char)~junk[0];
a = alloc_assert();
pk = alloc_es256_pk();
@@ -531,6 +569,46 @@ bad_cbor_serialize(void)
free_assert(a);
}
+/* rs256 <-> EVP_PKEY transformations */
+static void
+rs256_PKEY(void)
+{
+ rs256_pk_t *pk1, *pk2;
+ EVP_PKEY *pkey;
+
+ pk1 = alloc_rs256_pk();
+ pk2 = alloc_rs256_pk();
+
+ assert(rs256_pk_from_ptr(pk1, rs256_pk, sizeof(rs256_pk)) == FIDO_OK);
+ assert((pkey = rs256_pk_to_EVP_PKEY(pk1)) != NULL);
+ assert(rs256_pk_from_EVP_PKEY(pk2, pkey) == FIDO_OK);
+ assert(memcmp(pk1, pk2, sizeof(*pk1)) == 0);
+
+ free_rs256_pk(pk1);
+ free_rs256_pk(pk2);
+ EVP_PKEY_free(pkey);
+}
+
+/* es256 <-> EVP_PKEY transformations */
+static void
+es256_PKEY(void)
+{
+ es256_pk_t *pk1, *pk2;
+ EVP_PKEY *pkey;
+
+ pk1 = alloc_es256_pk();
+ pk2 = alloc_es256_pk();
+
+ assert(es256_pk_from_ptr(pk1, es256_pk, sizeof(es256_pk)) == FIDO_OK);
+ assert((pkey = es256_pk_to_EVP_PKEY(pk1)) != NULL);
+ assert(es256_pk_from_EVP_PKEY(pk2, pkey) == FIDO_OK);
+ assert(memcmp(pk1, pk2, sizeof(*pk1)) == 0);
+
+ free_es256_pk(pk1);
+ free_es256_pk(pk2);
+ EVP_PKEY_free(pkey);
+}
+
int
main(void)
{
@@ -548,6 +626,8 @@ main(void)
junk_sig();
wrong_options();
bad_cbor_serialize();
+ rs256_PKEY();
+ es256_PKEY();
exit(0);
}
diff --git a/contrib/libfido2/regress/cred.c b/contrib/libfido2/regress/cred.c
index 01df1ef9320d..b0df1481636a 100644
--- a/contrib/libfido2/regress/cred.c
+++ b/contrib/libfido2/regress/cred.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -102,6 +102,55 @@ static const unsigned char authdata_unsorted_keys[198] = {
0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2,
};
+const unsigned char authdata_tpm[362] = {
+ 0x59, 0x01, 0x67, 0x49, 0x96, 0x0d, 0xe5, 0x88,
+ 0x0e, 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64,
+ 0x76, 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2,
+ 0x86, 0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, 0x83,
+ 0x1d, 0x97, 0x63, 0x45, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x98, 0x70, 0x58, 0xca, 0xdc, 0x4b, 0x81,
+ 0xb6, 0xe1, 0x30, 0xde, 0x50, 0xdc, 0xbe, 0x96,
+ 0x00, 0x20, 0x89, 0x99, 0x6d, 0x5a, 0x00, 0x29,
+ 0xe5, 0x3e, 0x6a, 0x1c, 0x72, 0x6d, 0x71, 0x4a,
+ 0x4f, 0x03, 0x9b, 0x68, 0x17, 0xdb, 0x29, 0x1a,
+ 0x6b, 0x02, 0x6c, 0x26, 0xf9, 0xbd, 0xc3, 0x0e,
+ 0x38, 0x1a, 0xa4, 0x01, 0x03, 0x03, 0x39, 0x01,
+ 0x00, 0x20, 0x59, 0x01, 0x00, 0xc5, 0xb6, 0x9c,
+ 0x06, 0x1d, 0xcf, 0xb9, 0xf2, 0x5e, 0x99, 0x7d,
+ 0x6d, 0x73, 0xd8, 0x36, 0xc1, 0x4a, 0x90, 0x05,
+ 0x4d, 0x82, 0x57, 0xc1, 0xb6, 0x6a, 0xd1, 0x43,
+ 0x03, 0x85, 0xf8, 0x52, 0x4f, 0xd2, 0x27, 0x91,
+ 0x0b, 0xb5, 0x93, 0xa0, 0x68, 0xf8, 0x80, 0x1b,
+ 0xaa, 0x65, 0x97, 0x45, 0x11, 0x86, 0x34, 0xd6,
+ 0x67, 0xf8, 0xd5, 0x12, 0x79, 0x84, 0xee, 0x70,
+ 0x99, 0x00, 0x63, 0xa8, 0xb4, 0x43, 0x0b, 0x4c,
+ 0x57, 0x4a, 0xd6, 0x9b, 0x75, 0x63, 0x8a, 0x46,
+ 0x57, 0xdb, 0x14, 0xc8, 0x71, 0xd1, 0xb3, 0x07,
+ 0x68, 0x58, 0xbc, 0x55, 0x84, 0x80, 0x2a, 0xd2,
+ 0x36, 0x9f, 0xc1, 0x64, 0xa0, 0x11, 0x4b, 0xc9,
+ 0x32, 0x31, 0x3a, 0xd6, 0x87, 0x26, 0x1a, 0x3a,
+ 0x78, 0x3d, 0x89, 0xdb, 0x00, 0x28, 0x3b, 0xae,
+ 0x2b, 0x1b, 0x56, 0xe2, 0x8c, 0x4c, 0x63, 0xac,
+ 0x6e, 0x6c, 0xf7, 0xb5, 0x7d, 0x4d, 0x0b, 0x9f,
+ 0x06, 0xa0, 0x10, 0x35, 0x38, 0x20, 0x4d, 0xcc,
+ 0x07, 0xd7, 0x00, 0x4e, 0x86, 0xba, 0xfe, 0x8b,
+ 0xe4, 0x3f, 0x4a, 0xd6, 0xca, 0xbf, 0x67, 0x40,
+ 0x1a, 0xa4, 0xda, 0x82, 0x52, 0x15, 0xb8, 0x14,
+ 0x3a, 0x7c, 0xa9, 0x02, 0xc1, 0x01, 0x69, 0xc6,
+ 0x51, 0xd4, 0xbc, 0x1f, 0x95, 0xb2, 0xee, 0x1f,
+ 0xdd, 0xb5, 0x73, 0x16, 0x5e, 0x29, 0x3f, 0x47,
+ 0xac, 0x65, 0xfb, 0x63, 0x5c, 0xb9, 0xc8, 0x13,
+ 0x2d, 0xec, 0x85, 0xde, 0x71, 0x0d, 0x84, 0x93,
+ 0x74, 0x76, 0x91, 0xdd, 0x1d, 0x6d, 0x3d, 0xc7,
+ 0x36, 0x19, 0x19, 0x86, 0xde, 0x7c, 0xca, 0xd6,
+ 0xc6, 0x65, 0x7e, 0x4b, 0x24, 0x9c, 0xce, 0x92,
+ 0x6b, 0x1c, 0xe0, 0xa0, 0xa9, 0x6c, 0xc3, 0xed,
+ 0x4f, 0x2a, 0x54, 0x07, 0x00, 0x32, 0x5e, 0x1b,
+ 0x94, 0x37, 0xcd, 0xe2, 0x32, 0xa8, 0xd5, 0x2c,
+ 0xfb, 0x03, 0x9d, 0x79, 0xdf, 0x21, 0x43, 0x01,
+ 0x00, 0x01
+};
+
static const unsigned char x509[742] = {
0x30, 0x82, 0x02, 0xe2, 0x30, 0x81, 0xcb, 0x02,
0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
@@ -221,6 +270,42 @@ const unsigned char pubkey[64] = {
0xfe, 0x5d, 0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2,
};
+const unsigned char pubkey_tpm[259] = {
+ 0xc5, 0xb6, 0x9c, 0x06, 0x1d, 0xcf, 0xb9, 0xf2,
+ 0x5e, 0x99, 0x7d, 0x6d, 0x73, 0xd8, 0x36, 0xc1,
+ 0x4a, 0x90, 0x05, 0x4d, 0x82, 0x57, 0xc1, 0xb6,
+ 0x6a, 0xd1, 0x43, 0x03, 0x85, 0xf8, 0x52, 0x4f,
+ 0xd2, 0x27, 0x91, 0x0b, 0xb5, 0x93, 0xa0, 0x68,
+ 0xf8, 0x80, 0x1b, 0xaa, 0x65, 0x97, 0x45, 0x11,
+ 0x86, 0x34, 0xd6, 0x67, 0xf8, 0xd5, 0x12, 0x79,
+ 0x84, 0xee, 0x70, 0x99, 0x00, 0x63, 0xa8, 0xb4,
+ 0x43, 0x0b, 0x4c, 0x57, 0x4a, 0xd6, 0x9b, 0x75,
+ 0x63, 0x8a, 0x46, 0x57, 0xdb, 0x14, 0xc8, 0x71,
+ 0xd1, 0xb3, 0x07, 0x68, 0x58, 0xbc, 0x55, 0x84,
+ 0x80, 0x2a, 0xd2, 0x36, 0x9f, 0xc1, 0x64, 0xa0,
+ 0x11, 0x4b, 0xc9, 0x32, 0x31, 0x3a, 0xd6, 0x87,
+ 0x26, 0x1a, 0x3a, 0x78, 0x3d, 0x89, 0xdb, 0x00,
+ 0x28, 0x3b, 0xae, 0x2b, 0x1b, 0x56, 0xe2, 0x8c,
+ 0x4c, 0x63, 0xac, 0x6e, 0x6c, 0xf7, 0xb5, 0x7d,
+ 0x4d, 0x0b, 0x9f, 0x06, 0xa0, 0x10, 0x35, 0x38,
+ 0x20, 0x4d, 0xcc, 0x07, 0xd7, 0x00, 0x4e, 0x86,
+ 0xba, 0xfe, 0x8b, 0xe4, 0x3f, 0x4a, 0xd6, 0xca,
+ 0xbf, 0x67, 0x40, 0x1a, 0xa4, 0xda, 0x82, 0x52,
+ 0x15, 0xb8, 0x14, 0x3a, 0x7c, 0xa9, 0x02, 0xc1,
+ 0x01, 0x69, 0xc6, 0x51, 0xd4, 0xbc, 0x1f, 0x95,
+ 0xb2, 0xee, 0x1f, 0xdd, 0xb5, 0x73, 0x16, 0x5e,
+ 0x29, 0x3f, 0x47, 0xac, 0x65, 0xfb, 0x63, 0x5c,
+ 0xb9, 0xc8, 0x13, 0x2d, 0xec, 0x85, 0xde, 0x71,
+ 0x0d, 0x84, 0x93, 0x74, 0x76, 0x91, 0xdd, 0x1d,
+ 0x6d, 0x3d, 0xc7, 0x36, 0x19, 0x19, 0x86, 0xde,
+ 0x7c, 0xca, 0xd6, 0xc6, 0x65, 0x7e, 0x4b, 0x24,
+ 0x9c, 0xce, 0x92, 0x6b, 0x1c, 0xe0, 0xa0, 0xa9,
+ 0x6c, 0xc3, 0xed, 0x4f, 0x2a, 0x54, 0x07, 0x00,
+ 0x32, 0x5e, 0x1b, 0x94, 0x37, 0xcd, 0xe2, 0x32,
+ 0xa8, 0xd5, 0x2c, 0xfb, 0x03, 0x9d, 0x79, 0xdf,
+ 0x01, 0x00, 0x01,
+};
+
const unsigned char id[64] = {
0x53, 0xfb, 0xdf, 0xaa, 0xce, 0x63, 0xde, 0xc5,
0xfe, 0x47, 0xe6, 0x52, 0xeb, 0xf3, 0x5d, 0x53,
@@ -232,16 +317,539 @@ const unsigned char id[64] = {
0x34, 0xe3, 0x83, 0xe7, 0xd1, 0xbd, 0x9f, 0x25,
};
+const unsigned char id_tpm[32] = {
+ 0x89, 0x99, 0x6d, 0x5a, 0x00, 0x29, 0xe5, 0x3e,
+ 0x6a, 0x1c, 0x72, 0x6d, 0x71, 0x4a, 0x4f, 0x03,
+ 0x9b, 0x68, 0x17, 0xdb, 0x29, 0x1a, 0x6b, 0x02,
+ 0x6c, 0x26, 0xf9, 0xbd, 0xc3, 0x0e, 0x38, 0x1a
+};
+
+const unsigned char attstmt_tpm[4034] = {
+ 0xa6, 0x63, 0x61, 0x6c, 0x67, 0x39, 0xff, 0xfe,
+ 0x63, 0x73, 0x69, 0x67, 0x59, 0x01, 0x00, 0x1c,
+ 0x09, 0x0d, 0x35, 0x97, 0x22, 0xfc, 0xfe, 0xc0,
+ 0x58, 0x49, 0x9e, 0xd4, 0x7e, 0x6a, 0x7d, 0xdb,
+ 0x6d, 0x20, 0x95, 0x5c, 0x0b, 0xd0, 0xd5, 0x72,
+ 0x4f, 0x15, 0x22, 0x38, 0x97, 0xb2, 0x4b, 0xd0,
+ 0xef, 0x31, 0x7c, 0xf2, 0x42, 0x19, 0x41, 0xa1,
+ 0xe2, 0xc5, 0xca, 0xc6, 0x74, 0x95, 0xcf, 0xf9,
+ 0x41, 0x75, 0x0b, 0x56, 0x39, 0x82, 0x78, 0xf6,
+ 0x59, 0xf1, 0x09, 0x96, 0x9e, 0x38, 0x7f, 0x14,
+ 0x9b, 0xf5, 0x36, 0xbb, 0x92, 0x32, 0xc4, 0x64,
+ 0xe8, 0xff, 0xb4, 0xc7, 0xcf, 0xcd, 0x17, 0x48,
+ 0x0f, 0x83, 0xd9, 0x44, 0x03, 0x35, 0x26, 0xad,
+ 0x01, 0xb7, 0x57, 0x06, 0xb3, 0x9c, 0xa0, 0x6e,
+ 0x2f, 0x58, 0xcb, 0x5c, 0xaa, 0x7c, 0xea, 0x7e,
+ 0x3f, 0xbc, 0x76, 0xc9, 0x0e, 0x52, 0x39, 0x81,
+ 0xa9, 0x9e, 0x37, 0x14, 0x1f, 0x50, 0x6a, 0x4f,
+ 0xd7, 0xfc, 0xd4, 0xfa, 0xf2, 0x18, 0x60, 0xd5,
+ 0xc3, 0x57, 0x7d, 0x6d, 0x05, 0x28, 0x25, 0xc3,
+ 0xde, 0x86, 0x85, 0x06, 0x71, 0xfb, 0x84, 0xa2,
+ 0x07, 0xb6, 0x77, 0xc9, 0x68, 0x41, 0x53, 0x32,
+ 0x4c, 0xa8, 0x4b, 0xf7, 0x08, 0x84, 0x62, 0x6c,
+ 0x8a, 0xb6, 0xcf, 0xc1, 0xde, 0x6b, 0x61, 0xc8,
+ 0xdd, 0xc0, 0x13, 0x70, 0x22, 0x28, 0xe1, 0x0f,
+ 0x46, 0x02, 0xc6, 0xb1, 0xfa, 0x30, 0xcb, 0xec,
+ 0xd1, 0x82, 0xfa, 0x51, 0xcb, 0x71, 0x5e, 0x1f,
+ 0x1b, 0x5f, 0xe0, 0xb0, 0x02, 0x8a, 0x7c, 0x78,
+ 0xd1, 0xb7, 0x4d, 0x56, 0xb0, 0x92, 0x3e, 0xda,
+ 0xc7, 0xb1, 0x74, 0xcf, 0x6a, 0x40, 0xeb, 0x98,
+ 0x1c, 0x2e, 0xf2, 0x86, 0x76, 0xf8, 0x2e, 0x6a,
+ 0x9f, 0x77, 0x51, 0x64, 0xce, 0xdc, 0x12, 0x85,
+ 0x84, 0x6b, 0x01, 0xc8, 0xeb, 0xbc, 0x57, 0x6c,
+ 0x32, 0x26, 0xcb, 0xb2, 0x84, 0x02, 0x2a, 0x33,
+ 0x15, 0xd9, 0xe3, 0x15, 0xfc, 0x3a, 0x24, 0x63,
+ 0x76, 0x65, 0x72, 0x63, 0x32, 0x2e, 0x30, 0x63,
+ 0x78, 0x35, 0x63, 0x82, 0x59, 0x05, 0xc4, 0x30,
+ 0x82, 0x05, 0xc0, 0x30, 0x82, 0x03, 0xa8, 0xa0,
+ 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x78, 0xd9,
+ 0xa8, 0xb2, 0x64, 0xf9, 0x4d, 0x28, 0x82, 0xc0,
+ 0xd3, 0x1b, 0x40, 0x3c, 0xc8, 0xd9, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x41, 0x31,
+ 0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x36, 0x45, 0x55, 0x53, 0x2d, 0x53, 0x54,
+ 0x4d, 0x2d, 0x4b, 0x45, 0x59, 0x49, 0x44, 0x2d,
+ 0x31, 0x41, 0x44, 0x42, 0x39, 0x39, 0x34, 0x41,
+ 0x42, 0x35, 0x38, 0x42, 0x45, 0x35, 0x37, 0x41,
+ 0x30, 0x43, 0x43, 0x39, 0x42, 0x39, 0x30, 0x30,
+ 0x45, 0x37, 0x38, 0x35, 0x31, 0x45, 0x31, 0x41,
+ 0x34, 0x33, 0x43, 0x30, 0x38, 0x36, 0x36, 0x30,
+ 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x37,
+ 0x31, 0x35, 0x31, 0x31, 0x31, 0x32, 0x31, 0x33,
+ 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x33, 0x32,
+ 0x31, 0x32, 0x30, 0x32, 0x39, 0x31, 0x35, 0x5a,
+ 0x30, 0x00, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+ 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+ 0x01, 0x01, 0x00, 0xca, 0xbe, 0x77, 0x9f, 0x45,
+ 0x97, 0x17, 0x8d, 0x01, 0xe1, 0x18, 0xcc, 0xf0,
+ 0xb5, 0xed, 0x9a, 0xb7, 0x36, 0xac, 0x05, 0x26,
+ 0xbe, 0x35, 0xd9, 0x5c, 0x00, 0x5c, 0x5d, 0x8b,
+ 0x6f, 0x2a, 0xb8, 0xf6, 0x02, 0x4f, 0x33, 0xfe,
+ 0x84, 0x45, 0x4c, 0x4f, 0x7a, 0xdb, 0xa9, 0x6a,
+ 0x62, 0x0f, 0x19, 0x35, 0x5d, 0xd2, 0x34, 0x1a,
+ 0x9d, 0x73, 0x55, 0xe5, 0x3e, 0x04, 0xa2, 0xd6,
+ 0xbe, 0xe7, 0x5a, 0xb9, 0x16, 0x6c, 0x55, 0x18,
+ 0xa8, 0x4b, 0xb2, 0x37, 0xb9, 0xa3, 0x87, 0xfc,
+ 0x76, 0xa8, 0x55, 0xc9, 0xe7, 0x30, 0xe5, 0x0e,
+ 0x3c, 0x7b, 0x74, 0xd2, 0x1e, 0xa8, 0x05, 0xd5,
+ 0xe2, 0xe3, 0xcb, 0xaf, 0x63, 0x33, 0x12, 0xaa,
+ 0xfd, 0x31, 0x32, 0x71, 0x4f, 0x41, 0x96, 0x05,
+ 0xb5, 0x69, 0x73, 0x45, 0xbe, 0x6f, 0x90, 0xd9,
+ 0x10, 0x36, 0xaf, 0x7a, 0x1c, 0xf1, 0x6d, 0x14,
+ 0xb0, 0x1e, 0xbb, 0xae, 0x1c, 0x35, 0xec, 0x1c,
+ 0xb5, 0x0e, 0xf6, 0x33, 0x98, 0x13, 0x4e, 0x44,
+ 0x7b, 0x5c, 0x97, 0x47, 0xed, 0x4f, 0xfe, 0xbd,
+ 0x08, 0xd2, 0xa9, 0xc6, 0xbe, 0x8c, 0x04, 0x9e,
+ 0xdc, 0x3d, 0xbe, 0x98, 0xe9, 0x2a, 0xb1, 0xf4,
+ 0xfa, 0x45, 0xf9, 0xc8, 0x9a, 0x55, 0x85, 0x26,
+ 0xfc, 0x5f, 0xad, 0x00, 0x8b, 0xc8, 0x41, 0xf2,
+ 0x86, 0x4e, 0xba, 0x55, 0x1c, 0xb2, 0x89, 0xe8,
+ 0x85, 0x6e, 0x1e, 0x02, 0x9f, 0x55, 0x70, 0xbe,
+ 0xfd, 0xe7, 0x9f, 0xba, 0x59, 0xa0, 0x2e, 0x9a,
+ 0x74, 0x11, 0xe7, 0xad, 0xa9, 0xc7, 0x7b, 0x58,
+ 0xc4, 0x16, 0xd3, 0x35, 0xcb, 0x61, 0x00, 0xec,
+ 0x36, 0x4a, 0xa3, 0x51, 0xa3, 0xdd, 0x61, 0xb6,
+ 0xd6, 0x29, 0xcb, 0x76, 0xe1, 0xab, 0x51, 0x3a,
+ 0xe8, 0xbf, 0xdb, 0x09, 0x4a, 0x39, 0x96, 0xd9,
+ 0xac, 0x8f, 0x6c, 0x62, 0xe0, 0x03, 0x23, 0x24,
+ 0xbe, 0xd4, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01,
+ 0xa3, 0x82, 0x01, 0xf3, 0x30, 0x82, 0x01, 0xef,
+ 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
+ 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80,
+ 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+ 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x6d,
+ 0x06, 0x03, 0x55, 0x1d, 0x20, 0x01, 0x01, 0xff,
+ 0x04, 0x63, 0x30, 0x61, 0x30, 0x5f, 0x06, 0x09,
+ 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15,
+ 0x1f, 0x30, 0x52, 0x30, 0x50, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30,
+ 0x44, 0x1e, 0x42, 0x00, 0x54, 0x00, 0x43, 0x00,
+ 0x50, 0x00, 0x41, 0x00, 0x20, 0x00, 0x20, 0x00,
+ 0x54, 0x00, 0x72, 0x00, 0x75, 0x00, 0x73, 0x00,
+ 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00,
+ 0x20, 0x00, 0x50, 0x00, 0x6c, 0x00, 0x61, 0x00,
+ 0x74, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00,
+ 0x6d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x49, 0x00,
+ 0x64, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00,
+ 0x69, 0x00, 0x74, 0x00, 0x79, 0x30, 0x10, 0x06,
+ 0x03, 0x55, 0x1d, 0x25, 0x04, 0x09, 0x30, 0x07,
+ 0x06, 0x05, 0x67, 0x81, 0x05, 0x08, 0x03, 0x30,
+ 0x59, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x01, 0x01,
+ 0xff, 0x04, 0x4f, 0x30, 0x4d, 0xa4, 0x4b, 0x30,
+ 0x49, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67,
+ 0x81, 0x05, 0x02, 0x01, 0x0c, 0x0b, 0x69, 0x64,
+ 0x3a, 0x35, 0x33, 0x35, 0x34, 0x34, 0x44, 0x32,
+ 0x30, 0x31, 0x17, 0x30, 0x15, 0x06, 0x05, 0x67,
+ 0x81, 0x05, 0x02, 0x02, 0x0c, 0x0c, 0x53, 0x54,
+ 0x33, 0x33, 0x48, 0x54, 0x50, 0x48, 0x41, 0x48,
+ 0x42, 0x34, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05,
+ 0x67, 0x81, 0x05, 0x02, 0x03, 0x0c, 0x0b, 0x69,
+ 0x64, 0x3a, 0x30, 0x30, 0x34, 0x39, 0x30, 0x30,
+ 0x30, 0x34, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+ 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb8,
+ 0x5f, 0xd5, 0x67, 0xca, 0x92, 0xc4, 0x0e, 0xcf,
+ 0x0c, 0xd8, 0x1f, 0x6d, 0x3f, 0x03, 0x55, 0x6f,
+ 0x38, 0xa6, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd4, 0x04,
+ 0x64, 0xfc, 0x6e, 0x50, 0x0a, 0x56, 0x48, 0x0f,
+ 0x05, 0xa9, 0x00, 0xb7, 0x1d, 0x5e, 0x57, 0x08,
+ 0xd5, 0xdc, 0x30, 0x81, 0xb2, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+ 0x81, 0xa5, 0x30, 0x81, 0xa2, 0x30, 0x81, 0x9f,
+ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+ 0x30, 0x02, 0x86, 0x81, 0x92, 0x68, 0x74, 0x74,
+ 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x7a, 0x63, 0x73,
+ 0x70, 0x72, 0x6f, 0x64, 0x65, 0x75, 0x73, 0x61,
+ 0x69, 0x6b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73,
+ 0x68, 0x2e, 0x62, 0x6c, 0x6f, 0x62, 0x2e, 0x63,
+ 0x6f, 0x72, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64,
+ 0x6f, 0x77, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x2f,
+ 0x65, 0x75, 0x73, 0x2d, 0x73, 0x74, 0x6d, 0x2d,
+ 0x6b, 0x65, 0x79, 0x69, 0x64, 0x2d, 0x31, 0x61,
+ 0x64, 0x62, 0x39, 0x39, 0x34, 0x61, 0x62, 0x35,
+ 0x38, 0x62, 0x65, 0x35, 0x37, 0x61, 0x30, 0x63,
+ 0x63, 0x39, 0x62, 0x39, 0x30, 0x30, 0x65, 0x37,
+ 0x38, 0x35, 0x31, 0x65, 0x31, 0x61, 0x34, 0x33,
+ 0x63, 0x30, 0x38, 0x36, 0x36, 0x30, 0x2f, 0x61,
+ 0x62, 0x64, 0x36, 0x31, 0x35, 0x66, 0x32, 0x2d,
+ 0x31, 0x35, 0x38, 0x61, 0x2d, 0x34, 0x35, 0x38,
+ 0x65, 0x2d, 0x61, 0x31, 0x35, 0x35, 0x2d, 0x37,
+ 0x63, 0x34, 0x63, 0x38, 0x63, 0x62, 0x31, 0x33,
+ 0x63, 0x36, 0x35, 0x2e, 0x63, 0x65, 0x72, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
+ 0x02, 0x01, 0x00, 0xa2, 0x10, 0xc5, 0xbf, 0x41,
+ 0xa6, 0xba, 0x8c, 0x72, 0xca, 0x0f, 0x3e, 0x5e,
+ 0x7f, 0xe2, 0xcb, 0x60, 0xb8, 0x3f, 0xfb, 0xde,
+ 0x03, 0xe2, 0xfe, 0x20, 0x29, 0xdf, 0x11, 0xf5,
+ 0xb0, 0x50, 0x6d, 0x32, 0xe8, 0x1b, 0x05, 0xad,
+ 0x6b, 0x60, 0xb5, 0xed, 0xf3, 0xa4, 0x4a, 0xea,
+ 0x09, 0xe5, 0x65, 0x7e, 0xe0, 0xd5, 0x3a, 0x6a,
+ 0xdb, 0x64, 0xb7, 0x07, 0x8f, 0xa1, 0x63, 0xb3,
+ 0x89, 0x8a, 0xac, 0x49, 0x97, 0xa0, 0x9a, 0xa3,
+ 0xd3, 0x3a, 0xc2, 0x13, 0xb2, 0xbb, 0xab, 0x0d,
+ 0xf2, 0x35, 0xc5, 0x03, 0xde, 0x1c, 0xad, 0x6a,
+ 0x03, 0x0a, 0x4c, 0xe1, 0x37, 0x8f, 0xbc, 0x13,
+ 0xc0, 0x9a, 0x17, 0xd4, 0x2e, 0x36, 0x17, 0x51,
+ 0x12, 0xb0, 0x79, 0xbf, 0x9b, 0xb3, 0xb0, 0x74,
+ 0x25, 0x81, 0x7e, 0x21, 0x31, 0xb7, 0xc2, 0x5e,
+ 0xfb, 0x36, 0xab, 0xf3, 0x7a, 0x5f, 0xa4, 0x5e,
+ 0x8f, 0x0c, 0xbd, 0xcf, 0xf5, 0x50, 0xe7, 0x0c,
+ 0x51, 0x55, 0x48, 0xe6, 0x15, 0xb6, 0xd4, 0xaf,
+ 0x95, 0x72, 0x56, 0x94, 0xf7, 0x0e, 0xd6, 0x90,
+ 0xe3, 0xd3, 0x5d, 0xbd, 0x93, 0xa1, 0xbd, 0x6c,
+ 0xe4, 0xf2, 0x39, 0x4d, 0x54, 0x74, 0xcf, 0xf5,
+ 0xeb, 0x70, 0xdb, 0x4f, 0x52, 0xcd, 0x39, 0x8f,
+ 0x11, 0x54, 0x28, 0x06, 0x29, 0x8f, 0x23, 0xde,
+ 0x9e, 0x2f, 0x7b, 0xb6, 0x5f, 0xa3, 0x89, 0x04,
+ 0x99, 0x0a, 0xf1, 0x2d, 0xf9, 0x66, 0xd3, 0x13,
+ 0x45, 0xbd, 0x6c, 0x22, 0x57, 0xf5, 0xb1, 0xb9,
+ 0xdf, 0x5b, 0x7b, 0x1a, 0x3a, 0xdd, 0x6b, 0xc7,
+ 0x35, 0x88, 0xed, 0xc4, 0x09, 0x70, 0x4e, 0x5f,
+ 0xb5, 0x3e, 0xd1, 0x0b, 0xd0, 0xca, 0xef, 0x0b,
+ 0xe9, 0x8b, 0x6f, 0xc3, 0x16, 0xc3, 0x3d, 0x79,
+ 0x06, 0xef, 0x81, 0xf0, 0x60, 0x0b, 0x32, 0xe3,
+ 0x86, 0x6b, 0x92, 0x38, 0x90, 0x62, 0xed, 0x84,
+ 0x3a, 0xb7, 0x45, 0x43, 0x2e, 0xd0, 0x3a, 0x71,
+ 0x9e, 0x80, 0xcc, 0x9c, 0xac, 0x27, 0x10, 0x91,
+ 0xb7, 0xb2, 0xbd, 0x41, 0x40, 0xa7, 0xb7, 0xcf,
+ 0xe7, 0x38, 0xca, 0x68, 0xdd, 0x62, 0x09, 0xff,
+ 0x68, 0xce, 0xba, 0xe2, 0x07, 0x49, 0x09, 0xe7,
+ 0x1f, 0xdf, 0xe6, 0x26, 0xe5, 0x0f, 0xa9, 0xbf,
+ 0x2a, 0x5b, 0x67, 0x92, 0xa1, 0x10, 0x53, 0xb2,
+ 0x7a, 0x07, 0x29, 0x9d, 0xfd, 0x6d, 0xb6, 0x3b,
+ 0x45, 0xc1, 0x94, 0xcb, 0x1c, 0xc3, 0xce, 0xf6,
+ 0x8a, 0x1a, 0x81, 0x66, 0xb0, 0xa5, 0x14, 0xc7,
+ 0x9e, 0x1f, 0x6e, 0xb6, 0xff, 0x8b, 0x90, 0x87,
+ 0x3a, 0x3f, 0xa8, 0xc2, 0x2d, 0x8f, 0x6f, 0xdb,
+ 0xb4, 0xc4, 0x14, 0x3c, 0x1d, 0x12, 0x1d, 0x6d,
+ 0xcf, 0xa6, 0x04, 0x6a, 0xa8, 0x13, 0x5e, 0xf2,
+ 0x5e, 0x77, 0x80, 0x6b, 0x85, 0x83, 0xfe, 0xbb,
+ 0xeb, 0x70, 0xcb, 0x5f, 0xe4, 0x95, 0xaa, 0x0f,
+ 0x61, 0x36, 0x7c, 0xbb, 0x22, 0x1e, 0xba, 0x98,
+ 0x43, 0x52, 0x33, 0xae, 0xed, 0x5d, 0x10, 0x2c,
+ 0xb3, 0xa9, 0x31, 0x8e, 0x60, 0x54, 0xaf, 0x40,
+ 0x6d, 0x2e, 0x18, 0xc2, 0x6a, 0xf4, 0x7b, 0x9a,
+ 0x73, 0x0f, 0x58, 0x69, 0x23, 0xbb, 0xc4, 0x84,
+ 0x53, 0x30, 0xe2, 0xd6, 0x1e, 0x10, 0xc1, 0xec,
+ 0x82, 0x13, 0xab, 0x53, 0x86, 0xa2, 0xb9, 0xda,
+ 0xbb, 0x3a, 0xa2, 0xbe, 0xb0, 0x10, 0x99, 0x0e,
+ 0xe5, 0x9c, 0xc9, 0xf1, 0xce, 0x76, 0x46, 0xea,
+ 0x86, 0xaa, 0x36, 0x83, 0x99, 0x09, 0x9b, 0x30,
+ 0xd3, 0x26, 0xc7, 0xdf, 0x66, 0xc7, 0xf0, 0xdd,
+ 0x08, 0x09, 0x15, 0x15, 0x21, 0x49, 0x46, 0xd8,
+ 0x8a, 0x66, 0xca, 0x62, 0x9c, 0x79, 0x1d, 0x81,
+ 0xea, 0x5d, 0x82, 0xb0, 0xa6, 0x6b, 0x5c, 0xf5,
+ 0xb8, 0x8c, 0xf6, 0x16, 0x01, 0x2c, 0xf8, 0x27,
+ 0xf8, 0xcf, 0x88, 0xfe, 0xf3, 0xa4, 0xfc, 0x17,
+ 0x97, 0xe7, 0x07, 0x59, 0x06, 0xef, 0x30, 0x82,
+ 0x06, 0xeb, 0x30, 0x82, 0x04, 0xd3, 0xa0, 0x03,
+ 0x02, 0x01, 0x02, 0x02, 0x13, 0x33, 0x00, 0x00,
+ 0x02, 0x39, 0xf9, 0xbb, 0x6a, 0x1d, 0x49, 0x64,
+ 0x47, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
+ 0x81, 0x8c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+ 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
+ 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e,
+ 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e,
+ 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52,
+ 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e,
+ 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+ 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f,
+ 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f,
+ 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x36,
+ 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+ 0x2d, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f,
+ 0x66, 0x74, 0x20, 0x54, 0x50, 0x4d, 0x20, 0x52,
+ 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74,
+ 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20,
+ 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+ 0x79, 0x20, 0x32, 0x30, 0x31, 0x34, 0x30, 0x1e,
+ 0x17, 0x0d, 0x31, 0x39, 0x30, 0x33, 0x32, 0x31,
+ 0x32, 0x30, 0x32, 0x39, 0x31, 0x35, 0x5a, 0x17,
+ 0x0d, 0x32, 0x35, 0x30, 0x33, 0x32, 0x31, 0x32,
+ 0x30, 0x32, 0x39, 0x31, 0x35, 0x5a, 0x30, 0x41,
+ 0x31, 0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x13, 0x36, 0x45, 0x55, 0x53, 0x2d, 0x53,
+ 0x54, 0x4d, 0x2d, 0x4b, 0x45, 0x59, 0x49, 0x44,
+ 0x2d, 0x31, 0x41, 0x44, 0x42, 0x39, 0x39, 0x34,
+ 0x41, 0x42, 0x35, 0x38, 0x42, 0x45, 0x35, 0x37,
+ 0x41, 0x30, 0x43, 0x43, 0x39, 0x42, 0x39, 0x30,
+ 0x30, 0x45, 0x37, 0x38, 0x35, 0x31, 0x45, 0x31,
+ 0x41, 0x34, 0x33, 0x43, 0x30, 0x38, 0x36, 0x36,
+ 0x30, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06,
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f,
+ 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02,
+ 0x01, 0x00, 0xdb, 0xe2, 0x23, 0xf9, 0x86, 0x8f,
+ 0xa9, 0x71, 0x9f, 0x8b, 0xf9, 0x7c, 0xe9, 0x45,
+ 0x2d, 0x59, 0x56, 0x5e, 0x96, 0xf4, 0xdd, 0x9a,
+ 0x12, 0xcd, 0x90, 0x1a, 0x0c, 0xb5, 0x03, 0xbf,
+ 0x09, 0xbe, 0xbf, 0xf7, 0x55, 0x52, 0xe8, 0x39,
+ 0x4c, 0xbe, 0x2a, 0x28, 0x88, 0x78, 0x39, 0xa7,
+ 0xcb, 0xf9, 0x4c, 0x55, 0xd2, 0x31, 0x96, 0x3b,
+ 0x48, 0xa2, 0xf3, 0xf6, 0xd3, 0x1a, 0x81, 0x7f,
+ 0x90, 0x62, 0xab, 0xec, 0x5a, 0xc7, 0xa0, 0x7f,
+ 0x81, 0x32, 0x27, 0x9b, 0x29, 0x75, 0x7d, 0x1e,
+ 0x96, 0xc5, 0xfa, 0x0e, 0x7c, 0xe0, 0x60, 0x96,
+ 0x7a, 0xca, 0x94, 0xba, 0xe6, 0xb2, 0x69, 0xdd,
+ 0xc4, 0x7d, 0xbb, 0xd3, 0xc4, 0xb4, 0x6e, 0x00,
+ 0x86, 0x1f, 0x9d, 0x25, 0xe8, 0xae, 0xc7, 0x10,
+ 0x84, 0xdc, 0xc0, 0x34, 0x24, 0x6e, 0xf7, 0xfc,
+ 0xdd, 0x3d, 0x32, 0x7a, 0x43, 0x96, 0xd6, 0xc8,
+ 0x7b, 0xf4, 0x9b, 0x3d, 0xa7, 0x1e, 0xba, 0x4d,
+ 0xd0, 0x3b, 0x3d, 0x84, 0x9a, 0xd1, 0x25, 0x22,
+ 0x5d, 0x00, 0x44, 0xb0, 0x59, 0xb7, 0x40, 0xc5,
+ 0xa3, 0x53, 0x53, 0xaf, 0x8f, 0x9e, 0xfd, 0x8f,
+ 0x1e, 0x02, 0xd3, 0x4f, 0xf7, 0x09, 0xce, 0xc5,
+ 0xc6, 0x71, 0x5c, 0xe9, 0xe8, 0x7a, 0xb5, 0x6b,
+ 0xa4, 0xbf, 0x0b, 0xd9, 0xb6, 0xfa, 0x24, 0xb0,
+ 0xcd, 0x52, 0x22, 0x1d, 0x7e, 0xe8, 0x15, 0x2f,
+ 0x1e, 0x5e, 0xa2, 0xec, 0xd3, 0xa8, 0x02, 0x77,
+ 0xb9, 0x55, 0x9a, 0xcf, 0xcc, 0xd7, 0x08, 0x20,
+ 0xa5, 0xda, 0x39, 0x9a, 0x30, 0x76, 0x90, 0x37,
+ 0xa7, 0x60, 0xdf, 0x18, 0x12, 0x65, 0x17, 0xaa,
+ 0xdd, 0x48, 0xd5, 0x12, 0x1d, 0x4c, 0x83, 0x5d,
+ 0x81, 0x07, 0x1d, 0x18, 0x81, 0x40, 0x55, 0x60,
+ 0x8f, 0xa3, 0x6b, 0x34, 0x1e, 0xd5, 0xe6, 0xcf,
+ 0x52, 0x73, 0x77, 0x4a, 0x50, 0x4f, 0x1b, 0x0f,
+ 0x39, 0xc3, 0x0d, 0x16, 0xf9, 0xbb, 0x4c, 0x77,
+ 0xf6, 0x4e, 0xac, 0x9c, 0xfe, 0xe8, 0xbb, 0x52,
+ 0xa5, 0x0a, 0x0e, 0x9b, 0xf0, 0x0d, 0xef, 0xfb,
+ 0x6f, 0x89, 0x34, 0x7d, 0x47, 0xec, 0x14, 0x6a,
+ 0xf4, 0x0a, 0xe1, 0x60, 0x44, 0x73, 0x7b, 0xa0,
+ 0xab, 0x5b, 0x8c, 0x43, 0xa6, 0x05, 0x42, 0x61,
+ 0x46, 0xaa, 0x1c, 0xf5, 0xec, 0x2c, 0x86, 0x85,
+ 0x21, 0x99, 0xdf, 0x45, 0x8e, 0xf4, 0xd1, 0x1e,
+ 0xfb, 0xcd, 0x9b, 0x94, 0x32, 0xe0, 0xa0, 0xcc,
+ 0x4f, 0xad, 0xae, 0x44, 0x8b, 0x86, 0x27, 0x91,
+ 0xfe, 0x60, 0x9f, 0xf2, 0x63, 0x30, 0x6c, 0x5d,
+ 0x8d, 0xbc, 0xab, 0xd4, 0xf5, 0xa2, 0xb2, 0x74,
+ 0xe8, 0xd4, 0x95, 0xf2, 0xd6, 0x03, 0x8b, 0xc9,
+ 0xa3, 0x52, 0xe7, 0x63, 0x05, 0x64, 0x50, 0xe5,
+ 0x0a, 0x6a, 0xa0, 0x6c, 0x50, 0xcd, 0x37, 0x98,
+ 0xa8, 0x87, 0x02, 0x38, 0x5b, 0x6c, 0x02, 0x69,
+ 0x3d, 0x1f, 0x95, 0x74, 0x4d, 0x46, 0x76, 0x2a,
+ 0x9d, 0x62, 0xd4, 0xc7, 0x1b, 0xf9, 0x31, 0xa6,
+ 0x51, 0xee, 0x7b, 0xc8, 0xe4, 0x6e, 0x3a, 0xcf,
+ 0x4f, 0x4f, 0x49, 0x8a, 0xf5, 0x4f, 0x25, 0x93,
+ 0x23, 0x02, 0xef, 0x79, 0xa6, 0x27, 0xbe, 0x5a,
+ 0xe7, 0x74, 0xb7, 0xd7, 0xa8, 0xc1, 0xae, 0x55,
+ 0x88, 0xa4, 0xc7, 0x4d, 0xb7, 0x62, 0xf0, 0xf9,
+ 0x5b, 0xbf, 0x47, 0x5b, 0xfe, 0xcc, 0x0b, 0x89,
+ 0x19, 0x65, 0x4b, 0x6f, 0xdf, 0x4f, 0x7d, 0x4d,
+ 0x96, 0x42, 0x0d, 0x2a, 0xa1, 0xbd, 0x3e, 0x70,
+ 0x92, 0xba, 0xc8, 0x59, 0xd5, 0x1d, 0x3a, 0x98,
+ 0x53, 0x75, 0xa6, 0x32, 0xc8, 0x72, 0x03, 0x46,
+ 0x5f, 0x5c, 0x13, 0xa4, 0xdb, 0xc7, 0x55, 0x35,
+ 0x22, 0x0d, 0xc6, 0x17, 0x85, 0xbd, 0x46, 0x4b,
+ 0xfa, 0x1e, 0x49, 0xc2, 0xfe, 0x1e, 0xf9, 0x62,
+ 0x89, 0x56, 0x84, 0xdf, 0xa0, 0xfb, 0xfd, 0x93,
+ 0xa4, 0x25, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+ 0x82, 0x01, 0x8e, 0x30, 0x82, 0x01, 0x8a, 0x30,
+ 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
+ 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x84, 0x30,
+ 0x1b, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x14,
+ 0x30, 0x12, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04,
+ 0x01, 0x82, 0x37, 0x15, 0x24, 0x06, 0x05, 0x67,
+ 0x81, 0x05, 0x08, 0x03, 0x30, 0x16, 0x06, 0x03,
+ 0x55, 0x1d, 0x20, 0x04, 0x0f, 0x30, 0x0d, 0x30,
+ 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01,
+ 0x82, 0x37, 0x15, 0x1f, 0x30, 0x12, 0x06, 0x03,
+ 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08,
+ 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00,
+ 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+ 0x16, 0x04, 0x14, 0xb8, 0x5f, 0xd5, 0x67, 0xca,
+ 0x92, 0xc4, 0x0e, 0xcf, 0x0c, 0xd8, 0x1f, 0x6d,
+ 0x3f, 0x03, 0x55, 0x6f, 0x38, 0xa6, 0x51, 0x30,
+ 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+ 0x30, 0x16, 0x80, 0x14, 0x7a, 0x8c, 0x0a, 0xce,
+ 0x2f, 0x48, 0x62, 0x17, 0xe2, 0x94, 0xd1, 0xae,
+ 0x55, 0xc1, 0x52, 0xec, 0x71, 0x74, 0xa4, 0x56,
+ 0x30, 0x70, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04,
+ 0x69, 0x30, 0x67, 0x30, 0x65, 0xa0, 0x63, 0xa0,
+ 0x61, 0x86, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x3a,
+ 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69,
+ 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x6f,
+ 0x70, 0x73, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x4d,
+ 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
+ 0x25, 0x32, 0x30, 0x54, 0x50, 0x4d, 0x25, 0x32,
+ 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30,
+ 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+ 0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75,
+ 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x25,
+ 0x32, 0x30, 0x32, 0x30, 0x31, 0x34, 0x2e, 0x63,
+ 0x72, 0x6c, 0x30, 0x7d, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x71,
+ 0x30, 0x6f, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x61,
+ 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
+ 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f,
+ 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x70, 0x6b, 0x69, 0x6f, 0x70, 0x73, 0x2f,
+ 0x63, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x4d, 0x69,
+ 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x25,
+ 0x32, 0x30, 0x54, 0x50, 0x4d, 0x25, 0x32, 0x30,
+ 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43,
+ 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+ 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74,
+ 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x25, 0x32,
+ 0x30, 0x32, 0x30, 0x31, 0x34, 0x2e, 0x63, 0x72,
+ 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
+ 0x03, 0x82, 0x02, 0x01, 0x00, 0x41, 0xaa, 0xfe,
+ 0x28, 0x6c, 0xf7, 0x6b, 0x53, 0xde, 0x77, 0xc0,
+ 0x80, 0x50, 0x94, 0xd9, 0xdb, 0x46, 0x8e, 0x6a,
+ 0x93, 0xa9, 0x10, 0x37, 0x27, 0x1f, 0xf5, 0x70,
+ 0xf1, 0xa8, 0xcf, 0xa1, 0x45, 0x86, 0x2a, 0xdd,
+ 0x8f, 0xb8, 0xb5, 0xc1, 0xe6, 0xcf, 0x8a, 0xfa,
+ 0x32, 0xa1, 0x4b, 0xb7, 0xa4, 0xbf, 0x0a, 0x48,
+ 0xcb, 0x42, 0x63, 0x71, 0xc1, 0x96, 0xb9, 0x3a,
+ 0x37, 0x84, 0x0e, 0x24, 0x39, 0xeb, 0x58, 0xce,
+ 0x3d, 0xb7, 0xa9, 0x44, 0x92, 0x59, 0xb9, 0xff,
+ 0xdb, 0x18, 0xbe, 0x6a, 0x5e, 0xe7, 0xce, 0xef,
+ 0xb8, 0x40, 0x53, 0xaf, 0xc1, 0x9b, 0xfb, 0x42,
+ 0x99, 0x7e, 0x9d, 0x05, 0x2b, 0x71, 0x0a, 0x7a,
+ 0x7a, 0x44, 0xd1, 0x31, 0xca, 0xf0, 0x5f, 0x74,
+ 0x85, 0xa9, 0xe2, 0xbc, 0xc8, 0x0c, 0xad, 0x57,
+ 0xd1, 0xe9, 0x48, 0x90, 0x88, 0x57, 0x86, 0xd7,
+ 0xc5, 0xc9, 0xe6, 0xb2, 0x5e, 0x5f, 0x13, 0xdc,
+ 0x10, 0x7f, 0xdf, 0x63, 0x8a, 0xd5, 0x9e, 0x90,
+ 0xc2, 0x75, 0x53, 0x1e, 0x68, 0x17, 0x2b, 0x03,
+ 0x29, 0x15, 0x03, 0xc5, 0x8c, 0x66, 0x3e, 0xae,
+ 0xbd, 0x4a, 0x32, 0x7e, 0x59, 0x89, 0x0b, 0x84,
+ 0xc2, 0xd9, 0x90, 0xfa, 0x02, 0x22, 0x90, 0x8d,
+ 0x9c, 0xb6, 0x0c, 0x4d, 0xe1, 0x28, 0x76, 0xd7,
+ 0x82, 0xc3, 0x36, 0xc2, 0xa3, 0x2a, 0x52, 0xe5,
+ 0xfe, 0x3c, 0x8f, 0xe3, 0x4b, 0xda, 0x6a, 0xdb,
+ 0xc0, 0x7a, 0x3c, 0x57, 0xfa, 0x85, 0x8f, 0xfb,
+ 0x62, 0xc3, 0xa1, 0x38, 0xce, 0x84, 0xf2, 0xba,
+ 0x12, 0xf4, 0x30, 0x2a, 0x4a, 0x94, 0xa9, 0x35,
+ 0x2c, 0x7d, 0x11, 0xc7, 0x68, 0x1f, 0x47, 0xaa,
+ 0x57, 0x43, 0x06, 0x70, 0x79, 0x8c, 0xb6, 0x3b,
+ 0x5d, 0x57, 0xf3, 0xf3, 0xc0, 0x2c, 0xc5, 0xde,
+ 0x41, 0x99, 0xf6, 0xdd, 0x55, 0x8a, 0xe4, 0x13,
+ 0xca, 0xc9, 0xec, 0x69, 0x93, 0x13, 0x48, 0xf0,
+ 0x5f, 0xda, 0x2e, 0xfd, 0xfb, 0xa9, 0x1b, 0x92,
+ 0xde, 0x49, 0x71, 0x37, 0x8c, 0x3f, 0xc2, 0x08,
+ 0x0a, 0x83, 0x25, 0xf1, 0x6e, 0x0a, 0xe3, 0x55,
+ 0x85, 0x96, 0x9a, 0x2d, 0xa2, 0xc0, 0xa1, 0xee,
+ 0xfe, 0x23, 0x3b, 0x69, 0x22, 0x03, 0xfd, 0xcc,
+ 0x8a, 0xdd, 0xb4, 0x53, 0x8d, 0x84, 0xa6, 0xac,
+ 0xe0, 0x1e, 0x07, 0xe5, 0xd7, 0xf9, 0xcb, 0xb9,
+ 0xe3, 0x9a, 0xb7, 0x84, 0x70, 0xa1, 0x93, 0xd6,
+ 0x02, 0x1e, 0xfe, 0xdb, 0x28, 0x7c, 0xf7, 0xd4,
+ 0x62, 0x6f, 0x80, 0x75, 0xc8, 0xd8, 0x35, 0x26,
+ 0x0c, 0xcb, 0x84, 0xed, 0xbb, 0x95, 0xdf, 0x7f,
+ 0xd5, 0xbb, 0x00, 0x96, 0x97, 0x32, 0xe7, 0xba,
+ 0xe8, 0x29, 0xb5, 0x1a, 0x51, 0x81, 0xbb, 0x04,
+ 0xd1, 0x21, 0x76, 0x34, 0x6d, 0x1e, 0x93, 0x96,
+ 0x1f, 0x96, 0x53, 0x5f, 0x5c, 0x9e, 0xf3, 0x9d,
+ 0x82, 0x1c, 0x39, 0x36, 0x59, 0xae, 0xc9, 0x3c,
+ 0x53, 0x4a, 0x67, 0x65, 0x6e, 0xbf, 0xa6, 0xac,
+ 0x3e, 0xda, 0xb2, 0xa7, 0x63, 0x07, 0x17, 0xe1,
+ 0x5b, 0xda, 0x6a, 0x31, 0x9f, 0xfb, 0xb4, 0xea,
+ 0xa1, 0x97, 0x08, 0x6e, 0xb2, 0x68, 0xf3, 0x72,
+ 0x76, 0x99, 0xe8, 0x00, 0x46, 0x88, 0x26, 0xe1,
+ 0x3c, 0x07, 0x2b, 0x78, 0x49, 0xda, 0x79, 0x3a,
+ 0xbd, 0x6f, 0xca, 0x5c, 0xa0, 0xa8, 0xed, 0x34,
+ 0xcc, 0xdb, 0x13, 0xe2, 0x51, 0x9b, 0x3d, 0x03,
+ 0xac, 0xc7, 0xf6, 0x32, 0xe1, 0x11, 0x5d, 0xe1,
+ 0xc5, 0xfd, 0x9e, 0x7a, 0xcd, 0x06, 0xb9, 0xe6,
+ 0xfc, 0xe0, 0x03, 0x31, 0xf4, 0x4a, 0xa9, 0x3b,
+ 0x79, 0x01, 0xb0, 0x64, 0x68, 0x9f, 0x6e, 0x76,
+ 0xa1, 0xcc, 0xec, 0x17, 0x41, 0x9d, 0xd4, 0x5b,
+ 0x4e, 0x9d, 0xe5, 0x46, 0xd4, 0x6b, 0x60, 0x2a,
+ 0x23, 0xb5, 0x7a, 0x89, 0x7c, 0x27, 0x96, 0x65,
+ 0x97, 0x56, 0xec, 0x98, 0xe3, 0x67, 0x70, 0x75,
+ 0x62, 0x41, 0x72, 0x65, 0x61, 0x59, 0x01, 0x36,
+ 0x00, 0x01, 0x00, 0x0b, 0x00, 0x06, 0x04, 0x72,
+ 0x00, 0x20, 0x9d, 0xff, 0xcb, 0xf3, 0x6c, 0x38,
+ 0x3a, 0xe6, 0x99, 0xfb, 0x98, 0x68, 0xdc, 0x6d,
+ 0xcb, 0x89, 0xd7, 0x15, 0x38, 0x84, 0xbe, 0x28,
+ 0x03, 0x92, 0x2c, 0x12, 0x41, 0x58, 0xbf, 0xad,
+ 0x22, 0xae, 0x00, 0x10, 0x00, 0x10, 0x08, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc5, 0xb6,
+ 0x9c, 0x06, 0x1d, 0xcf, 0xb9, 0xf2, 0x5e, 0x99,
+ 0x7d, 0x6d, 0x73, 0xd8, 0x36, 0xc1, 0x4a, 0x90,
+ 0x05, 0x4d, 0x82, 0x57, 0xc1, 0xb6, 0x6a, 0xd1,
+ 0x43, 0x03, 0x85, 0xf8, 0x52, 0x4f, 0xd2, 0x27,
+ 0x91, 0x0b, 0xb5, 0x93, 0xa0, 0x68, 0xf8, 0x80,
+ 0x1b, 0xaa, 0x65, 0x97, 0x45, 0x11, 0x86, 0x34,
+ 0xd6, 0x67, 0xf8, 0xd5, 0x12, 0x79, 0x84, 0xee,
+ 0x70, 0x99, 0x00, 0x63, 0xa8, 0xb4, 0x43, 0x0b,
+ 0x4c, 0x57, 0x4a, 0xd6, 0x9b, 0x75, 0x63, 0x8a,
+ 0x46, 0x57, 0xdb, 0x14, 0xc8, 0x71, 0xd1, 0xb3,
+ 0x07, 0x68, 0x58, 0xbc, 0x55, 0x84, 0x80, 0x2a,
+ 0xd2, 0x36, 0x9f, 0xc1, 0x64, 0xa0, 0x11, 0x4b,
+ 0xc9, 0x32, 0x31, 0x3a, 0xd6, 0x87, 0x26, 0x1a,
+ 0x3a, 0x78, 0x3d, 0x89, 0xdb, 0x00, 0x28, 0x3b,
+ 0xae, 0x2b, 0x1b, 0x56, 0xe2, 0x8c, 0x4c, 0x63,
+ 0xac, 0x6e, 0x6c, 0xf7, 0xb5, 0x7d, 0x4d, 0x0b,
+ 0x9f, 0x06, 0xa0, 0x10, 0x35, 0x38, 0x20, 0x4d,
+ 0xcc, 0x07, 0xd7, 0x00, 0x4e, 0x86, 0xba, 0xfe,
+ 0x8b, 0xe4, 0x3f, 0x4a, 0xd6, 0xca, 0xbf, 0x67,
+ 0x40, 0x1a, 0xa4, 0xda, 0x82, 0x52, 0x15, 0xb8,
+ 0x14, 0x3a, 0x7c, 0xa9, 0x02, 0xc1, 0x01, 0x69,
+ 0xc6, 0x51, 0xd4, 0xbc, 0x1f, 0x95, 0xb2, 0xee,
+ 0x1f, 0xdd, 0xb5, 0x73, 0x16, 0x5e, 0x29, 0x3f,
+ 0x47, 0xac, 0x65, 0xfb, 0x63, 0x5c, 0xb9, 0xc8,
+ 0x13, 0x2d, 0xec, 0x85, 0xde, 0x71, 0x0d, 0x84,
+ 0x93, 0x74, 0x76, 0x91, 0xdd, 0x1d, 0x6d, 0x3d,
+ 0xc7, 0x36, 0x19, 0x19, 0x86, 0xde, 0x7c, 0xca,
+ 0xd6, 0xc6, 0x65, 0x7e, 0x4b, 0x24, 0x9c, 0xce,
+ 0x92, 0x6b, 0x1c, 0xe0, 0xa0, 0xa9, 0x6c, 0xc3,
+ 0xed, 0x4f, 0x2a, 0x54, 0x07, 0x00, 0x32, 0x5e,
+ 0x1b, 0x94, 0x37, 0xcd, 0xe2, 0x32, 0xa8, 0xd5,
+ 0x2c, 0xfb, 0x03, 0x9d, 0x79, 0xdf, 0x68, 0x63,
+ 0x65, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x58,
+ 0xa1, 0xff, 0x54, 0x43, 0x47, 0x80, 0x17, 0x00,
+ 0x22, 0x00, 0x0b, 0xdb, 0x1f, 0x74, 0x21, 0x4f,
+ 0xa9, 0x0d, 0x90, 0x64, 0xa2, 0x33, 0xbe, 0x3f,
+ 0xf1, 0x95, 0xb0, 0x4e, 0x3f, 0x02, 0xdc, 0xad,
+ 0xb0, 0x05, 0x13, 0xe6, 0x32, 0x5f, 0xed, 0x90,
+ 0x2c, 0xad, 0xc0, 0x00, 0x14, 0x58, 0x52, 0x07,
+ 0x5d, 0x64, 0x6c, 0x1f, 0xd1, 0x13, 0x7f, 0xc3,
+ 0x74, 0xf6, 0x4b, 0xe3, 0xa0, 0x2e, 0xb7, 0x71,
+ 0xda, 0x00, 0x00, 0x00, 0x00, 0x29, 0x3c, 0x64,
+ 0xdf, 0x95, 0x38, 0xba, 0x73, 0xe3, 0x57, 0x61,
+ 0xa0, 0x01, 0x24, 0x01, 0x08, 0xc9, 0xd6, 0xea,
+ 0x60, 0xe4, 0x00, 0x22, 0x00, 0x0b, 0xe1, 0x86,
+ 0xbb, 0x79, 0x27, 0xe5, 0x01, 0x19, 0x90, 0xb3,
+ 0xe9, 0x08, 0xb0, 0xee, 0xfa, 0x3a, 0x67, 0xa9,
+ 0xf3, 0xc8, 0x9e, 0x03, 0x41, 0x07, 0x75, 0x60,
+ 0xbc, 0x94, 0x0c, 0x2a, 0xb7, 0xad, 0x00, 0x22,
+ 0x00, 0x0b, 0x35, 0xb1, 0x72, 0xd6, 0x3c, 0xe9,
+ 0x85, 0xe8, 0x66, 0xed, 0x10, 0x7a, 0x5c, 0xa3,
+ 0xe6, 0xd9, 0x4d, 0xf0, 0x52, 0x69, 0x26, 0x14,
+ 0xb4, 0x36, 0x7e, 0xad, 0x76, 0x9e, 0x58, 0x68,
+ 0x3e, 0x91
+};
+
/*
* Security Key By Yubico
* 5.1.X
* f8a011f3-8c0a-4d15-8006-17111f9edc7d
-*/
+ */
const unsigned char aaguid[16] = {
0xf8, 0xa0, 0x11, 0xf3, 0x8c, 0x0a, 0x4d, 0x15,
0x80, 0x06, 0x17, 0x11, 0x1f, 0x9e, 0xdc, 0x7d,
};
+/*
+ * Windows Hello by Microsoft
+ */
+const unsigned char aaguid_tpm[16] = {
+ 0x08, 0x98, 0x70, 0x58, 0xca, 0xdc, 0x4b, 0x81,
+ 0xb6, 0xe1, 0x30, 0xde, 0x50, 0xdc, 0xbe, 0x96,
+};
+
const char rp_id[] = "localhost";
const char rp_name[] = "sweet home localhost";
@@ -606,7 +1214,7 @@ junk_cdh(void)
junk = malloc(sizeof(cdh));
assert(junk != NULL);
memcpy(junk, cdh, sizeof(cdh));
- junk[0] = ~junk[0];
+ junk[0] = (unsigned char)~junk[0];
c = alloc_cred();
assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK);
@@ -708,7 +1316,7 @@ junk_authdata(void)
junk = malloc(sizeof(authdata));
assert(junk != NULL);
memcpy(junk, authdata, sizeof(authdata));
- junk[0] = ~junk[0];
+ junk[0] = (unsigned char)~junk[0];
unset = calloc(1, sizeof(aaguid));
assert(unset != NULL);
@@ -749,7 +1357,7 @@ junk_sig(void)
junk = malloc(sizeof(sig));
assert(junk != NULL);
memcpy(junk, sig, sizeof(sig));
- junk[0] = ~junk[0];
+ junk[0] = (unsigned char)~junk[0];
c = alloc_cred();
assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK);
@@ -781,7 +1389,7 @@ junk_x509(void)
junk = malloc(sizeof(x509));
assert(junk != NULL);
memcpy(junk, x509, sizeof(x509));
- junk[0] = ~junk[0];
+ junk[0] = (unsigned char)~junk[0];
c = alloc_cred();
assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK);
@@ -954,6 +1562,31 @@ fmt_none(void)
free_cred(c);
}
+static void
+valid_tpm_cred(void)
+{
+ fido_cred_t *c;
+
+ c = alloc_cred();
+ assert(fido_cred_set_type(c, COSE_RS256) == FIDO_OK);
+ assert(fido_cred_set_clientdata(c, cdh, sizeof(cdh)) == FIDO_OK);
+ assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK);
+ assert(fido_cred_set_authdata(c, authdata_tpm, sizeof(authdata_tpm)) == FIDO_OK);
+ assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK);
+ assert(fido_cred_set_uv(c, FIDO_OPT_TRUE) == FIDO_OK);
+ assert(fido_cred_set_fmt(c, "tpm") == FIDO_OK);
+ assert(fido_cred_set_attstmt(c, attstmt_tpm, sizeof(attstmt_tpm)) == FIDO_OK);
+ assert(fido_cred_verify(c) == FIDO_OK);
+ assert(fido_cred_prot(c) == 0);
+ assert(fido_cred_pubkey_len(c) == sizeof(pubkey_tpm));
+ assert(memcmp(fido_cred_pubkey_ptr(c), pubkey_tpm, sizeof(pubkey_tpm)) == 0);
+ assert(fido_cred_id_len(c) == sizeof(id_tpm));
+ assert(memcmp(fido_cred_id_ptr(c), id_tpm, sizeof(id_tpm)) == 0);
+ assert(fido_cred_aaguid_len(c) == sizeof(aaguid_tpm));
+ assert(memcmp(fido_cred_aaguid_ptr(c), aaguid_tpm, sizeof(aaguid_tpm)) == 0);
+ free_cred(c);
+}
+
int
main(void)
{
@@ -983,6 +1616,7 @@ main(void)
wrong_credprot();
raw_authdata();
fmt_none();
+ valid_tpm_cred();
exit(0);
}
diff --git a/contrib/libfido2/regress/dev.c b/contrib/libfido2/regress/dev.c
index 35061aabbb64..a5dc8d6e4529 100644
--- a/contrib/libfido2/regress/dev.c
+++ b/contrib/libfido2/regress/dev.c
@@ -1,12 +1,14 @@
/*
- * Copyright (c) 2019 Yubico AB. All rights reserved.
+ * Copyright (c) 2019-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
#include <assert.h>
+#include <err.h>
#include <fido.h>
#include <string.h>
+#include <time.h>
#include "../fuzz/wiredata_fido2.h"
@@ -17,6 +19,7 @@ static uint8_t ctap_nonce[8];
static uint8_t *wiredata_ptr;
static size_t wiredata_len;
static int initialised;
+static long interval_ms;
static void *
dummy_open(const char *path)
@@ -35,9 +38,9 @@ dummy_close(void *handle)
static int
dummy_read(void *handle, unsigned char *ptr, size_t len, int ms)
{
- size_t n;
-
- (void)ms;
+ struct timespec tv;
+ size_t n;
+ long d;
assert(handle == FAKE_DEV_HANDLE);
assert(ptr != NULL);
@@ -52,6 +55,21 @@ dummy_read(void *handle, unsigned char *ptr, size_t len, int ms)
initialised = 1;
}
+ if (ms >= 0 && ms < interval_ms)
+ d = ms;
+ else
+ d = interval_ms;
+
+ if (d) {
+ tv.tv_sec = d / 1000;
+ tv.tv_nsec = (d % 1000) * 1000000;
+ if (nanosleep(&tv, NULL) == -1)
+ err(1, "nanosleep");
+ }
+
+ if (d != interval_ms)
+ return (-1); /* timeout */
+
if (wiredata_len < len)
n = wiredata_len;
else
@@ -67,6 +85,8 @@ dummy_read(void *handle, unsigned char *ptr, size_t len, int ms)
static int
dummy_write(void *handle, const unsigned char *ptr, size_t len)
{
+ struct timespec tv;
+
assert(handle == FAKE_DEV_HANDLE);
assert(ptr != NULL);
assert(len == REPORT_LEN);
@@ -74,6 +94,13 @@ dummy_write(void *handle, const unsigned char *ptr, size_t len)
if (!initialised)
memcpy(&ctap_nonce, &ptr[8], sizeof(ctap_nonce));
+ if (interval_ms) {
+ tv.tv_sec = interval_ms / 1000;
+ tv.tv_nsec = (interval_ms % 1000) * 1000000;
+ if (nanosleep(&tv, NULL) == -1)
+ err(1, "nanosleep");
+ }
+
return ((int)len);
}
@@ -153,6 +180,7 @@ reopen(void)
wiredata = wiredata_setup(cbor_info_data, sizeof(cbor_info_data));
assert(fido_dev_open(dev, "dummy") == FIDO_OK);
assert(fido_dev_close(dev) == FIDO_OK);
+ fido_dev_free(&dev);
wiredata_clear(&wiredata);
}
@@ -177,6 +205,34 @@ double_open(void)
assert(fido_dev_open(dev, "dummy") == FIDO_OK);
assert(fido_dev_open(dev, "dummy") == FIDO_ERR_INVALID_ARGUMENT);
assert(fido_dev_close(dev) == FIDO_OK);
+ fido_dev_free(&dev);
+ wiredata_clear(&wiredata);
+}
+
+static void
+double_close(void)
+{
+ const uint8_t cbor_info_data[] = { WIREDATA_CTAP_CBOR_INFO };
+ uint8_t *wiredata;
+ fido_dev_t *dev = NULL;
+ fido_dev_io_t io;
+
+ memset(&io, 0, sizeof(io));
+
+ io.open = dummy_open;
+ io.close = dummy_close;
+ io.read = dummy_read;
+ io.write = dummy_write;
+
+ wiredata = wiredata_setup(cbor_info_data, sizeof(cbor_info_data));
+ assert((dev = fido_dev_new()) != NULL);
+ assert(fido_dev_close(dev) == FIDO_ERR_INVALID_ARGUMENT);
+ assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK);
+ assert(fido_dev_close(dev) == FIDO_ERR_INVALID_ARGUMENT);
+ assert(fido_dev_open(dev, "dummy") == FIDO_OK);
+ assert(fido_dev_close(dev) == FIDO_OK);
+ assert(fido_dev_close(dev) == FIDO_ERR_INVALID_ARGUMENT);
+ fido_dev_free(&dev);
wiredata_clear(&wiredata);
}
@@ -215,6 +271,7 @@ is_fido2(void)
assert(fido_dev_is_fido2(dev) == true);
assert(fido_dev_supports_pin(dev) == false);
assert(fido_dev_close(dev) == FIDO_OK);
+ fido_dev_free(&dev);
wiredata_clear(&wiredata);
}
@@ -248,9 +305,94 @@ has_pin(void)
assert(fido_dev_reset(dev) == FIDO_OK);
assert(fido_dev_has_pin(dev) == false);
assert(fido_dev_close(dev) == FIDO_OK);
+ fido_dev_free(&dev);
wiredata_clear(&wiredata);
}
+static void
+timeout_rx(void)
+{
+ const uint8_t timeout_rx_data[] = {
+ WIREDATA_CTAP_CBOR_INFO,
+ WIREDATA_CTAP_KEEPALIVE,
+ WIREDATA_CTAP_KEEPALIVE,
+ WIREDATA_CTAP_KEEPALIVE,
+ WIREDATA_CTAP_KEEPALIVE,
+ WIREDATA_CTAP_KEEPALIVE,
+ WIREDATA_CTAP_CBOR_STATUS
+ };
+ uint8_t *wiredata;
+ fido_dev_t *dev = NULL;
+ fido_dev_io_t io;
+
+ memset(&io, 0, sizeof(io));
+
+ io.open = dummy_open;
+ io.close = dummy_close;
+ io.read = dummy_read;
+ io.write = dummy_write;
+
+ wiredata = wiredata_setup(timeout_rx_data, sizeof(timeout_rx_data));
+ assert((dev = fido_dev_new()) != NULL);
+ assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK);
+ assert(fido_dev_open(dev, "dummy") == FIDO_OK);
+ assert(fido_dev_set_timeout(dev, 3 * 1000) == FIDO_OK);
+ interval_ms = 1000;
+ assert(fido_dev_reset(dev) == FIDO_ERR_RX);
+ assert(fido_dev_close(dev) == FIDO_OK);
+ fido_dev_free(&dev);
+ wiredata_clear(&wiredata);
+ interval_ms = 0;
+}
+
+static void
+timeout_ok(void)
+{
+ const uint8_t timeout_ok_data[] = {
+ WIREDATA_CTAP_CBOR_INFO,
+ WIREDATA_CTAP_KEEPALIVE,
+ WIREDATA_CTAP_KEEPALIVE,
+ WIREDATA_CTAP_KEEPALIVE,
+ WIREDATA_CTAP_KEEPALIVE,
+ WIREDATA_CTAP_KEEPALIVE,
+ WIREDATA_CTAP_CBOR_STATUS
+ };
+ uint8_t *wiredata;
+ fido_dev_t *dev = NULL;
+ fido_dev_io_t io;
+
+ memset(&io, 0, sizeof(io));
+
+ io.open = dummy_open;
+ io.close = dummy_close;
+ io.read = dummy_read;
+ io.write = dummy_write;
+
+ wiredata = wiredata_setup(timeout_ok_data, sizeof(timeout_ok_data));
+ assert((dev = fido_dev_new()) != NULL);
+ assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK);
+ assert(fido_dev_open(dev, "dummy") == FIDO_OK);
+ assert(fido_dev_set_timeout(dev, 30 * 1000) == FIDO_OK);
+ interval_ms = 1000;
+ assert(fido_dev_reset(dev) == FIDO_OK);
+ assert(fido_dev_close(dev) == FIDO_OK);
+ fido_dev_free(&dev);
+ wiredata_clear(&wiredata);
+ interval_ms = 0;
+}
+
+static void
+timeout_misc(void)
+{
+ fido_dev_t *dev;
+
+ assert((dev = fido_dev_new()) != NULL);
+ assert(fido_dev_set_timeout(dev, -2) == FIDO_ERR_INVALID_ARGUMENT);
+ assert(fido_dev_set_timeout(dev, 3 * 1000) == FIDO_OK);
+ assert(fido_dev_set_timeout(dev, -1) == FIDO_OK);
+ fido_dev_free(&dev);
+}
+
int
main(void)
{
@@ -259,8 +401,12 @@ main(void)
open_iff_ok();
reopen();
double_open();
+ double_close();
is_fido2();
has_pin();
+ timeout_rx();
+ timeout_ok();
+ timeout_misc();
exit(0);
}
diff --git a/contrib/libfido2/src/CMakeLists.txt b/contrib/libfido2/src/CMakeLists.txt
index f9efd3f234ed..bd14a62f0c99 100644
--- a/contrib/libfido2/src/CMakeLists.txt
+++ b/contrib/libfido2/src/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Yubico AB. All rights reserved.
+# Copyright (c) 2018-2021 Yubico AB. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
@@ -30,11 +30,16 @@ list(APPEND FIDO_SOURCES
pin.c
random.c
reset.c
+ rs1.c
rs256.c
+ time.c
+ tpm.c
+ types.c
u2f.c
)
if(FUZZ)
+ list(APPEND FIDO_SOURCES ../fuzz/clock.c)
list(APPEND FIDO_SOURCES ../fuzz/prng.c)
list(APPEND FIDO_SOURCES ../fuzz/uniform_random.c)
list(APPEND FIDO_SOURCES ../fuzz/udev.c)
@@ -62,7 +67,8 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
list(APPEND FIDO_SOURCES hid_netbsd.c hid_unix.c)
elseif(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
list(APPEND FIDO_SOURCES hid_openbsd.c hid_unix.c)
-elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
+elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
+ CMAKE_SYSTEM_NAME STREQUAL "MidnightBSD")
list(APPEND FIDO_SOURCES hid_freebsd.c hid_unix.c)
else()
message(FATAL_ERROR "please define a hid backend for your platform")
@@ -75,11 +81,11 @@ endif()
list(APPEND COMPAT_SOURCES
../openbsd-compat/bsd-getpagesize.c
+ ../openbsd-compat/clock_gettime.c
../openbsd-compat/endian_win32.c
../openbsd-compat/explicit_bzero.c
../openbsd-compat/explicit_bzero_win32.c
../openbsd-compat/freezero.c
- ../openbsd-compat/hkdf.c
../openbsd-compat/recallocarray.c
../openbsd-compat/strlcat.c
../openbsd-compat/timingsafe_bcmp.c
@@ -87,9 +93,6 @@ list(APPEND COMPAT_SOURCES
if(WIN32)
list(APPEND BASE_LIBRARIES wsock32 ws2_32 bcrypt setupapi hid)
- if(USE_WINHELLO)
- list(APPEND BASE_LIBRARIES webauthn)
- endif()
elseif(APPLE)
list(APPEND BASE_LIBRARIES "-framework CoreFoundation" "-framework IOKit")
endif()
diff --git a/contrib/libfido2/src/assert.c b/contrib/libfido2/src/assert.c
index b36f8e324660..949af919d25e 100644
--- a/contrib/libfido2/src/assert.c
+++ b/contrib/libfido2/src/assert.c
@@ -4,7 +4,6 @@
* license that can be found in the LICENSE file.
*/
-#include <openssl/ecdsa.h>
#include <openssl/sha.h>
#include "fido.h"
@@ -79,7 +78,7 @@ parse_assert_reply(const cbor_item_t *key, const cbor_item_t *val, void *arg)
static int
fido_dev_get_assert_tx(fido_dev_t *dev, fido_assert_t *assert,
- const es256_pk_t *pk, const fido_blob_t *ecdh, const char *pin)
+ const es256_pk_t *pk, const fido_blob_t *ecdh, const char *pin, int *ms)
{
fido_blob_t f;
fido_opt_t uv = assert->uv;
@@ -127,7 +126,7 @@ fido_dev_get_assert_tx(fido_dev_t *dev, fido_assert_t *assert,
if (pin != NULL || (uv == FIDO_OPT_TRUE &&
fido_dev_supports_permissions(dev))) {
if ((r = cbor_add_uv_params(dev, cmd, &assert->cdh, pk, ecdh,
- pin, assert->rp_id, &argv[5], &argv[6])) != FIDO_OK) {
+ pin, assert->rp_id, &argv[5], &argv[6], ms)) != FIDO_OK) {
fido_log_debug("%s: cbor_add_uv_params", __func__);
goto fail;
}
@@ -144,7 +143,7 @@ fido_dev_get_assert_tx(fido_dev_t *dev, fido_assert_t *assert,
/* frame and transmit */
if (cbor_build_frame(cmd, argv, nitems(argv), &f) < 0 ||
- fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
+ fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -159,7 +158,7 @@ fail:
}
static int
-fido_dev_get_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int ms)
+fido_dev_get_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
@@ -200,11 +199,11 @@ fido_dev_get_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int ms)
}
static int
-fido_get_next_assert_tx(fido_dev_t *dev)
+fido_get_next_assert_tx(fido_dev_t *dev, int *ms)
{
const unsigned char cbor[] = { CTAP_CBOR_NEXT_ASSERT };
- if (fido_tx(dev, CTAP_CMD_CBOR, cbor, sizeof(cbor)) < 0) {
+ if (fido_tx(dev, CTAP_CMD_CBOR, cbor, sizeof(cbor), ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
return (FIDO_ERR_TX);
}
@@ -213,7 +212,7 @@ fido_get_next_assert_tx(fido_dev_t *dev)
}
static int
-fido_get_next_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int ms)
+fido_get_next_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
@@ -243,16 +242,17 @@ fido_get_next_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int ms)
static int
fido_dev_get_assert_wait(fido_dev_t *dev, fido_assert_t *assert,
- const es256_pk_t *pk, const fido_blob_t *ecdh, const char *pin, int ms)
+ const es256_pk_t *pk, const fido_blob_t *ecdh, const char *pin, int *ms)
{
int r;
- if ((r = fido_dev_get_assert_tx(dev, assert, pk, ecdh, pin)) != FIDO_OK ||
+ if ((r = fido_dev_get_assert_tx(dev, assert, pk, ecdh, pin,
+ ms)) != FIDO_OK ||
(r = fido_dev_get_assert_rx(dev, assert, ms)) != FIDO_OK)
return (r);
while (assert->stmt_len < assert->stmt_cnt) {
- if ((r = fido_get_next_assert_tx(dev)) != FIDO_OK ||
+ if ((r = fido_get_next_assert_tx(dev, ms)) != FIDO_OK ||
(r = fido_get_next_assert_rx(dev, assert, ms)) != FIDO_OK)
return (r);
assert->stmt_len++;
@@ -286,11 +286,12 @@ fido_dev_get_assert(fido_dev_t *dev, fido_assert_t *assert, const char *pin)
{
fido_blob_t *ecdh = NULL;
es256_pk_t *pk = NULL;
+ int ms = dev->timeout_ms;
int r;
#ifdef USE_WINHELLO
if (dev->flags & FIDO_DEV_WINHELLO)
- return (fido_winhello_get_assert(dev, assert, pin));
+ return (fido_winhello_get_assert(dev, assert, pin, ms));
#endif
if (assert->rp_id == NULL || assert->cdh.ptr == NULL) {
@@ -302,19 +303,19 @@ fido_dev_get_assert(fido_dev_t *dev, fido_assert_t *assert, const char *pin)
if (fido_dev_is_fido2(dev) == false) {
if (pin != NULL || assert->ext.mask != 0)
return (FIDO_ERR_UNSUPPORTED_OPTION);
- return (u2f_authenticate(dev, assert, -1));
+ return (u2f_authenticate(dev, assert, &ms));
}
if (pin != NULL || (assert->uv == FIDO_OPT_TRUE &&
fido_dev_supports_permissions(dev)) ||
(assert->ext.mask & FIDO_EXT_HMAC_SECRET)) {
- if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) {
+ if ((r = fido_do_ecdh(dev, &pk, &ecdh, &ms)) != FIDO_OK) {
fido_log_debug("%s: fido_do_ecdh", __func__);
goto fail;
}
}
- r = fido_dev_get_assert_wait(dev, assert, pk, ecdh, pin, -1);
+ r = fido_dev_get_assert_wait(dev, assert, pk, ecdh, pin, &ms);
if (r == FIDO_OK && (assert->ext.mask & FIDO_EXT_HMAC_SECRET))
if (decrypt_hmac_secrets(dev, assert, ecdh) < 0) {
fido_log_debug("%s: decrypt_hmac_secrets", __func__);
@@ -372,7 +373,8 @@ fido_get_signed_hash(int cose_alg, fido_blob_t *dgst,
unsigned char *authdata_ptr = NULL;
size_t authdata_len;
struct cbor_load_result cbor;
- SHA256_CTX ctx;
+ const EVP_MD *md = NULL;
+ EVP_MD_CTX *ctx = NULL;
int ok = -1;
if ((item = cbor_load(authdata_cbor->ptr, authdata_cbor->len,
@@ -386,10 +388,13 @@ fido_get_signed_hash(int cose_alg, fido_blob_t *dgst,
authdata_len = cbor_bytestring_length(item);
if (cose_alg != COSE_EDDSA) {
- if (dgst->len < SHA256_DIGEST_LENGTH || SHA256_Init(&ctx) == 0 ||
- SHA256_Update(&ctx, authdata_ptr, authdata_len) == 0 ||
- SHA256_Update(&ctx, clientdata->ptr, clientdata->len) == 0 ||
- SHA256_Final(dgst->ptr, &ctx) == 0) {
+ if (dgst->len < SHA256_DIGEST_LENGTH ||
+ (md = EVP_sha256()) == NULL ||
+ (ctx = EVP_MD_CTX_new()) == NULL ||
+ EVP_DigestInit_ex(ctx, md, NULL) != 1 ||
+ EVP_DigestUpdate(ctx, authdata_ptr, authdata_len) != 1 ||
+ EVP_DigestUpdate(ctx, clientdata->ptr, clientdata->len) != 1 ||
+ EVP_DigestFinal_ex(ctx, dgst->ptr, NULL) != 1) {
fido_log_debug("%s: sha256", __func__);
goto fail;
}
@@ -411,122 +416,7 @@ fail:
if (item != NULL)
cbor_decref(&item);
- return (ok);
-}
-
-int
-fido_verify_sig_es256(const fido_blob_t *dgst, const es256_pk_t *pk,
- const fido_blob_t *sig)
-{
- EVP_PKEY *pkey = NULL;
- EC_KEY *ec = NULL;
- int ok = -1;
-
- /* ECDSA_verify needs ints */
- if (dgst->len > INT_MAX || sig->len > INT_MAX) {
- fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__,
- dgst->len, sig->len);
- return (-1);
- }
-
- if ((pkey = es256_pk_to_EVP_PKEY(pk)) == NULL ||
- (ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) {
- fido_log_debug("%s: pk -> ec", __func__);
- goto fail;
- }
-
- if (ECDSA_verify(0, dgst->ptr, (int)dgst->len, sig->ptr,
- (int)sig->len, ec) != 1) {
- fido_log_debug("%s: ECDSA_verify", __func__);
- goto fail;
- }
-
- ok = 0;
-fail:
- if (pkey != NULL)
- EVP_PKEY_free(pkey);
-
- return (ok);
-}
-
-int
-fido_verify_sig_rs256(const fido_blob_t *dgst, const rs256_pk_t *pk,
- const fido_blob_t *sig)
-{
- EVP_PKEY *pkey = NULL;
- RSA *rsa = NULL;
- int ok = -1;
-
- /* RSA_verify needs unsigned ints */
- if (dgst->len > UINT_MAX || sig->len > UINT_MAX) {
- fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__,
- dgst->len, sig->len);
- return (-1);
- }
-
- if ((pkey = rs256_pk_to_EVP_PKEY(pk)) == NULL ||
- (rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) {
- fido_log_debug("%s: pk -> ec", __func__);
- goto fail;
- }
-
- if (RSA_verify(NID_sha256, dgst->ptr, (unsigned int)dgst->len, sig->ptr,
- (unsigned int)sig->len, rsa) != 1) {
- fido_log_debug("%s: RSA_verify", __func__);
- goto fail;
- }
-
- ok = 0;
-fail:
- if (pkey != NULL)
- EVP_PKEY_free(pkey);
-
- return (ok);
-}
-
-int
-fido_verify_sig_eddsa(const fido_blob_t *dgst, const eddsa_pk_t *pk,
- const fido_blob_t *sig)
-{
- EVP_PKEY *pkey = NULL;
- EVP_MD_CTX *mdctx = NULL;
- int ok = -1;
-
- /* EVP_DigestVerify needs ints */
- if (dgst->len > INT_MAX || sig->len > INT_MAX) {
- fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__,
- dgst->len, sig->len);
- return (-1);
- }
-
- if ((pkey = eddsa_pk_to_EVP_PKEY(pk)) == NULL) {
- fido_log_debug("%s: pk -> pkey", __func__);
- goto fail;
- }
-
- if ((mdctx = EVP_MD_CTX_new()) == NULL) {
- fido_log_debug("%s: EVP_MD_CTX_new", __func__);
- goto fail;
- }
-
- if (EVP_DigestVerifyInit(mdctx, NULL, NULL, NULL, pkey) != 1) {
- fido_log_debug("%s: EVP_DigestVerifyInit", __func__);
- goto fail;
- }
-
- if (EVP_DigestVerify(mdctx, sig->ptr, sig->len, dgst->ptr,
- dgst->len) != 1) {
- fido_log_debug("%s: EVP_DigestVerify", __func__);
- goto fail;
- }
-
- ok = 0;
-fail:
- if (mdctx != NULL)
- EVP_MD_CTX_free(mdctx);
-
- if (pkey != NULL)
- EVP_PKEY_free(pkey);
+ EVP_MD_CTX_free(ctx);
return (ok);
}
@@ -589,13 +479,13 @@ fido_assert_verify(const fido_assert_t *assert, size_t idx, int cose_alg,
switch (cose_alg) {
case COSE_ES256:
- ok = fido_verify_sig_es256(&dgst, pk, &stmt->sig);
+ ok = es256_pk_verify_sig(&dgst, pk, &stmt->sig);
break;
case COSE_RS256:
- ok = fido_verify_sig_rs256(&dgst, pk, &stmt->sig);
+ ok = rs256_pk_verify_sig(&dgst, pk, &stmt->sig);
break;
case COSE_EDDSA:
- ok = fido_verify_sig_eddsa(&dgst, pk, &stmt->sig);
+ ok = eddsa_pk_verify_sig(&dgst, pk, &stmt->sig);
break;
default:
fido_log_debug("%s: unsupported cose_alg %d", __func__,
diff --git a/contrib/libfido2/src/authkey.c b/contrib/libfido2/src/authkey.c
index c3474ccafc01..33e0a8d44bd2 100644
--- a/contrib/libfido2/src/authkey.c
+++ b/contrib/libfido2/src/authkey.c
@@ -22,7 +22,7 @@ parse_authkey(const cbor_item_t *key, const cbor_item_t *val, void *arg)
}
static int
-fido_dev_authkey_tx(fido_dev_t *dev)
+fido_dev_authkey_tx(fido_dev_t *dev, int *ms)
{
fido_blob_t f;
cbor_item_t *argv[2];
@@ -43,7 +43,7 @@ fido_dev_authkey_tx(fido_dev_t *dev)
/* frame and transmit */
if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv),
- &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
+ &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -58,13 +58,13 @@ fail:
}
static int
-fido_dev_authkey_rx(fido_dev_t *dev, es256_pk_t *authkey, int ms)
+fido_dev_authkey_rx(fido_dev_t *dev, es256_pk_t *authkey, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
fido_log_debug("%s: dev=%p, authkey=%p, ms=%d", __func__, (void *)dev,
- (void *)authkey, ms);
+ (void *)authkey, *ms);
memset(authkey, 0, sizeof(*authkey));
@@ -79,11 +79,11 @@ fido_dev_authkey_rx(fido_dev_t *dev, es256_pk_t *authkey, int ms)
}
static int
-fido_dev_authkey_wait(fido_dev_t *dev, es256_pk_t *authkey, int ms)
+fido_dev_authkey_wait(fido_dev_t *dev, es256_pk_t *authkey, int *ms)
{
int r;
- if ((r = fido_dev_authkey_tx(dev)) != FIDO_OK ||
+ if ((r = fido_dev_authkey_tx(dev, ms)) != FIDO_OK ||
(r = fido_dev_authkey_rx(dev, authkey, ms)) != FIDO_OK)
return (r);
@@ -91,7 +91,7 @@ fido_dev_authkey_wait(fido_dev_t *dev, es256_pk_t *authkey, int ms)
}
int
-fido_dev_authkey(fido_dev_t *dev, es256_pk_t *authkey)
+fido_dev_authkey(fido_dev_t *dev, es256_pk_t *authkey, int *ms)
{
- return (fido_dev_authkey_wait(dev, authkey, -1));
+ return (fido_dev_authkey_wait(dev, authkey, ms));
}
diff --git a/contrib/libfido2/src/bio.c b/contrib/libfido2/src/bio.c
index 06bc32eea7ed..4ddc93749cc3 100644
--- a/contrib/libfido2/src/bio.c
+++ b/contrib/libfido2/src/bio.c
@@ -58,7 +58,7 @@ fail:
static int
bio_tx(fido_dev_t *dev, uint8_t subcmd, cbor_item_t **sub_argv, size_t sub_argc,
- const char *pin, const fido_blob_t *token)
+ const char *pin, const fido_blob_t *token, int *ms)
{
cbor_item_t *argv[5];
es256_pk_t *pk = NULL;
@@ -90,12 +90,12 @@ bio_tx(fido_dev_t *dev, uint8_t subcmd, cbor_item_t **sub_argv, size_t sub_argc,
/* pinProtocol, pinAuth */
if (pin) {
- if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) {
+ if ((r = fido_do_ecdh(dev, &pk, &ecdh, ms)) != FIDO_OK) {
fido_log_debug("%s: fido_do_ecdh", __func__);
goto fail;
}
if ((r = cbor_add_uv_params(dev, cmd, &hmac, pk, ecdh, pin,
- NULL, &argv[4], &argv[3])) != FIDO_OK) {
+ NULL, &argv[4], &argv[3], ms)) != FIDO_OK) {
fido_log_debug("%s: cbor_add_uv_params", __func__);
goto fail;
}
@@ -109,7 +109,7 @@ bio_tx(fido_dev_t *dev, uint8_t subcmd, cbor_item_t **sub_argv, size_t sub_argc,
/* framing and transmission */
if (cbor_build_frame(cmd, argv, nitems(argv), &f) < 0 ||
- fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
+ fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -231,7 +231,7 @@ bio_parse_template_array(const cbor_item_t *key, const cbor_item_t *val,
}
static int
-bio_rx_template_array(fido_dev_t *dev, fido_bio_template_array_t *ta, int ms)
+bio_rx_template_array(fido_dev_t *dev, fido_bio_template_array_t *ta, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
@@ -256,11 +256,11 @@ bio_rx_template_array(fido_dev_t *dev, fido_bio_template_array_t *ta, int ms)
static int
bio_get_template_array_wait(fido_dev_t *dev, fido_bio_template_array_t *ta,
- const char *pin, int ms)
+ const char *pin, int *ms)
{
int r;
- if ((r = bio_tx(dev, CMD_ENUM, NULL, 0, pin, NULL)) != FIDO_OK ||
+ if ((r = bio_tx(dev, CMD_ENUM, NULL, 0, pin, NULL, ms)) != FIDO_OK ||
(r = bio_rx_template_array(dev, ta, ms)) != FIDO_OK)
return (r);
@@ -271,15 +271,17 @@ int
fido_bio_dev_get_template_array(fido_dev_t *dev, fido_bio_template_array_t *ta,
const char *pin)
{
+ int ms = dev->timeout_ms;
+
if (pin == NULL)
return (FIDO_ERR_INVALID_ARGUMENT);
- return (bio_get_template_array_wait(dev, ta, pin, -1));
+ return (bio_get_template_array_wait(dev, ta, pin, &ms));
}
static int
bio_set_template_name_wait(fido_dev_t *dev, const fido_bio_template_t *t,
- const char *pin, int ms)
+ const char *pin, int *ms)
{
cbor_item_t *argv[2];
int r = FIDO_ERR_INTERNAL;
@@ -292,7 +294,8 @@ bio_set_template_name_wait(fido_dev_t *dev, const fido_bio_template_t *t,
goto fail;
}
- if ((r = bio_tx(dev, CMD_SET_NAME, argv, 2, pin, NULL)) != FIDO_OK ||
+ if ((r = bio_tx(dev, CMD_SET_NAME, argv, 2, pin, NULL,
+ ms)) != FIDO_OK ||
(r = fido_rx_cbor_status(dev, ms)) != FIDO_OK) {
fido_log_debug("%s: tx/rx", __func__);
goto fail;
@@ -309,10 +312,12 @@ int
fido_bio_dev_set_template_name(fido_dev_t *dev, const fido_bio_template_t *t,
const char *pin)
{
+ int ms = dev->timeout_ms;
+
if (pin == NULL || t->name == NULL)
return (FIDO_ERR_INVALID_ARGUMENT);
- return (bio_set_template_name_wait(dev, t, pin, -1));
+ return (bio_set_template_name_wait(dev, t, pin, &ms));
}
static void
@@ -378,7 +383,7 @@ bio_parse_template_id(const cbor_item_t *key, const cbor_item_t *val,
static int
bio_rx_enroll_begin(fido_dev_t *dev, fido_bio_template_t *t,
- fido_bio_enroll_t *e, int ms)
+ fido_bio_enroll_t *e, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
@@ -411,7 +416,7 @@ bio_rx_enroll_begin(fido_dev_t *dev, fido_bio_template_t *t,
static int
bio_enroll_begin_wait(fido_dev_t *dev, fido_bio_template_t *t,
- fido_bio_enroll_t *e, uint32_t timo_ms, int ms)
+ fido_bio_enroll_t *e, uint32_t timo_ms, int *ms)
{
cbor_item_t *argv[3];
const uint8_t cmd = CMD_ENROLL_BEGIN;
@@ -424,7 +429,7 @@ bio_enroll_begin_wait(fido_dev_t *dev, fido_bio_template_t *t,
goto fail;
}
- if ((r = bio_tx(dev, cmd, argv, 3, NULL, e->token)) != FIDO_OK ||
+ if ((r = bio_tx(dev, cmd, argv, 3, NULL, e->token, ms)) != FIDO_OK ||
(r = bio_rx_enroll_begin(dev, t, e, ms)) != FIDO_OK) {
fido_log_debug("%s: tx/rx", __func__);
goto fail;
@@ -444,6 +449,7 @@ fido_bio_dev_enroll_begin(fido_dev_t *dev, fido_bio_template_t *t,
es256_pk_t *pk = NULL;
fido_blob_t *ecdh = NULL;
fido_blob_t *token = NULL;
+ int ms = dev->timeout_ms;
int r;
if (pin == NULL || e->token != NULL)
@@ -454,13 +460,13 @@ fido_bio_dev_enroll_begin(fido_dev_t *dev, fido_bio_template_t *t,
goto fail;
}
- if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) {
+ if ((r = fido_do_ecdh(dev, &pk, &ecdh, &ms)) != FIDO_OK) {
fido_log_debug("%s: fido_do_ecdh", __func__);
goto fail;
}
if ((r = fido_dev_get_uv_token(dev, CTAP_CBOR_BIO_ENROLL_PRE, pin, ecdh,
- pk, NULL, token)) != FIDO_OK) {
+ pk, NULL, token, &ms)) != FIDO_OK) {
fido_log_debug("%s: fido_dev_get_uv_token", __func__);
goto fail;
}
@@ -475,11 +481,11 @@ fail:
if (r != FIDO_OK)
return (r);
- return (bio_enroll_begin_wait(dev, t, e, timo_ms, -1));
+ return (bio_enroll_begin_wait(dev, t, e, timo_ms, &ms));
}
static int
-bio_rx_enroll_continue(fido_dev_t *dev, fido_bio_enroll_t *e, int ms)
+bio_rx_enroll_continue(fido_dev_t *dev, fido_bio_enroll_t *e, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
@@ -505,7 +511,7 @@ bio_rx_enroll_continue(fido_dev_t *dev, fido_bio_enroll_t *e, int ms)
static int
bio_enroll_continue_wait(fido_dev_t *dev, const fido_bio_template_t *t,
- fido_bio_enroll_t *e, uint32_t timo_ms, int ms)
+ fido_bio_enroll_t *e, uint32_t timo_ms, int *ms)
{
cbor_item_t *argv[3];
const uint8_t cmd = CMD_ENROLL_NEXT;
@@ -519,7 +525,7 @@ bio_enroll_continue_wait(fido_dev_t *dev, const fido_bio_template_t *t,
goto fail;
}
- if ((r = bio_tx(dev, cmd, argv, 3, NULL, e->token)) != FIDO_OK ||
+ if ((r = bio_tx(dev, cmd, argv, 3, NULL, e->token, ms)) != FIDO_OK ||
(r = bio_rx_enroll_continue(dev, e, ms)) != FIDO_OK) {
fido_log_debug("%s: tx/rx", __func__);
goto fail;
@@ -536,19 +542,21 @@ int
fido_bio_dev_enroll_continue(fido_dev_t *dev, const fido_bio_template_t *t,
fido_bio_enroll_t *e, uint32_t timo_ms)
{
+ int ms = dev->timeout_ms;
+
if (e->token == NULL)
return (FIDO_ERR_INVALID_ARGUMENT);
- return (bio_enroll_continue_wait(dev, t, e, timo_ms, -1));
+ return (bio_enroll_continue_wait(dev, t, e, timo_ms, &ms));
}
static int
-bio_enroll_cancel_wait(fido_dev_t *dev, int ms)
+bio_enroll_cancel_wait(fido_dev_t *dev, int *ms)
{
const uint8_t cmd = CMD_ENROLL_CANCEL;
int r;
- if ((r = bio_tx(dev, cmd, NULL, 0, NULL, NULL)) != FIDO_OK ||
+ if ((r = bio_tx(dev, cmd, NULL, 0, NULL, NULL, ms)) != FIDO_OK ||
(r = fido_rx_cbor_status(dev, ms)) != FIDO_OK) {
fido_log_debug("%s: tx/rx", __func__);
return (r);
@@ -560,12 +568,14 @@ bio_enroll_cancel_wait(fido_dev_t *dev, int ms)
int
fido_bio_dev_enroll_cancel(fido_dev_t *dev)
{
- return (bio_enroll_cancel_wait(dev, -1));
+ int ms = dev->timeout_ms;
+
+ return (bio_enroll_cancel_wait(dev, &ms));
}
static int
bio_enroll_remove_wait(fido_dev_t *dev, const fido_bio_template_t *t,
- const char *pin, int ms)
+ const char *pin, int *ms)
{
cbor_item_t *argv[1];
const uint8_t cmd = CMD_ENROLL_REMOVE;
@@ -578,7 +588,7 @@ bio_enroll_remove_wait(fido_dev_t *dev, const fido_bio_template_t *t,
goto fail;
}
- if ((r = bio_tx(dev, cmd, argv, 1, pin, NULL)) != FIDO_OK ||
+ if ((r = bio_tx(dev, cmd, argv, 1, pin, NULL, ms)) != FIDO_OK ||
(r = fido_rx_cbor_status(dev, ms)) != FIDO_OK) {
fido_log_debug("%s: tx/rx", __func__);
goto fail;
@@ -595,7 +605,9 @@ int
fido_bio_dev_enroll_remove(fido_dev_t *dev, const fido_bio_template_t *t,
const char *pin)
{
- return (bio_enroll_remove_wait(dev, t, pin, -1));
+ int ms = dev->timeout_ms;
+
+ return (bio_enroll_remove_wait(dev, t, pin, &ms));
}
static void
@@ -640,7 +652,7 @@ bio_parse_info(const cbor_item_t *key, const cbor_item_t *val, void *arg)
}
static int
-bio_rx_info(fido_dev_t *dev, fido_bio_info_t *i, int ms)
+bio_rx_info(fido_dev_t *dev, fido_bio_info_t *i, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
@@ -664,11 +676,12 @@ bio_rx_info(fido_dev_t *dev, fido_bio_info_t *i, int ms)
}
static int
-bio_get_info_wait(fido_dev_t *dev, fido_bio_info_t *i, int ms)
+bio_get_info_wait(fido_dev_t *dev, fido_bio_info_t *i, int *ms)
{
int r;
- if ((r = bio_tx(dev, CMD_GET_INFO, NULL, 0, NULL, NULL)) != FIDO_OK ||
+ if ((r = bio_tx(dev, CMD_GET_INFO, NULL, 0, NULL, NULL,
+ ms)) != FIDO_OK ||
(r = bio_rx_info(dev, i, ms)) != FIDO_OK) {
fido_log_debug("%s: tx/rx", __func__);
return (r);
@@ -680,7 +693,9 @@ bio_get_info_wait(fido_dev_t *dev, fido_bio_info_t *i, int ms)
int
fido_bio_dev_get_info(fido_dev_t *dev, fido_bio_info_t *i)
{
- return (bio_get_info_wait(dev, i, -1));
+ int ms = dev->timeout_ms;
+
+ return (bio_get_info_wait(dev, i, &ms));
}
const char *
diff --git a/contrib/libfido2/src/cbor.c b/contrib/libfido2/src/cbor.c
index 5c1b11583e7b..7935e5017dcf 100644
--- a/contrib/libfido2/src/cbor.c
+++ b/contrib/libfido2/src/cbor.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -560,6 +560,32 @@ fail:
return (NULL);
}
+cbor_item_t *
+cbor_encode_str_array(const fido_str_array_t *a)
+{
+ cbor_item_t *array = NULL;
+ cbor_item_t *entry = NULL;
+
+ if ((array = cbor_new_definite_array(a->len)) == NULL)
+ goto fail;
+
+ for (size_t i = 0; i < a->len; i++) {
+ if ((entry = cbor_build_string(a->ptr[i])) == NULL ||
+ cbor_array_push(array, entry) == false)
+ goto fail;
+ cbor_decref(&entry);
+ }
+
+ return (array);
+fail:
+ if (entry != NULL)
+ cbor_decref(&entry);
+ if (array != NULL)
+ cbor_decref(&array);
+
+ return (NULL);
+}
+
static int
cbor_encode_largeblob_key_ext(cbor_item_t *map)
{
@@ -584,6 +610,8 @@ cbor_encode_cred_ext(const fido_cred_ext_t *ext, const fido_blob_t *blob)
size++;
if (ext->mask & FIDO_EXT_LARGEBLOB_KEY)
size++;
+ if (ext->mask & FIDO_EXT_MINPINLEN)
+ size++;
if (size == 0 || (item = cbor_new_definite_map(size)) == NULL)
return (NULL);
@@ -615,6 +643,12 @@ cbor_encode_cred_ext(const fido_cred_ext_t *ext, const fido_blob_t *blob)
return (NULL);
}
}
+ if (ext->mask & FIDO_EXT_MINPINLEN) {
+ if (cbor_add_bool(item, "minPinLength", FIDO_OPT_TRUE) < 0) {
+ cbor_decref(&item);
+ return (NULL);
+ }
+ }
return (item);
}
@@ -706,11 +740,7 @@ cbor_encode_change_pin_auth(const fido_dev_t *dev, const fido_blob_t *secret,
unsigned int dgst_len;
cbor_item_t *item = NULL;
const EVP_MD *md = NULL;
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- HMAC_CTX ctx;
-#else
HMAC_CTX *ctx = NULL;
-#endif
fido_blob_t key;
uint8_t prot;
size_t outlen;
@@ -726,19 +756,6 @@ cbor_encode_change_pin_auth(const fido_dev_t *dev, const fido_blob_t *secret,
if (prot == CTAP_PIN_PROTOCOL2 && key.len > 32)
key.len = 32;
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- HMAC_CTX_init(&ctx);
-
- if ((md = EVP_sha256()) == NULL ||
- HMAC_Init_ex(&ctx, key.ptr, (int)key.len, md, NULL) == 0 ||
- HMAC_Update(&ctx, new_pin_enc->ptr, new_pin_enc->len) == 0 ||
- HMAC_Update(&ctx, pin_hash_enc->ptr, pin_hash_enc->len) == 0 ||
- HMAC_Final(&ctx, dgst, &dgst_len) == 0 ||
- dgst_len != SHA256_DIGEST_LENGTH) {
- fido_log_debug("%s: HMAC", __func__);
- goto fail;
- }
-#else
if ((ctx = HMAC_CTX_new()) == NULL ||
(md = EVP_sha256()) == NULL ||
HMAC_Init_ex(ctx, key.ptr, (int)key.len, md, NULL) == 0 ||
@@ -749,7 +766,6 @@ cbor_encode_change_pin_auth(const fido_dev_t *dev, const fido_blob_t *secret,
fido_log_debug("%s: HMAC", __func__);
goto fail;
}
-#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
outlen = (prot == CTAP_PIN_PROTOCOL1) ? 16 : dgst_len;
@@ -759,10 +775,7 @@ cbor_encode_change_pin_auth(const fido_dev_t *dev, const fido_blob_t *secret,
}
fail:
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
- if (ctx != NULL)
- HMAC_CTX_free(ctx);
-#endif
+ HMAC_CTX_free(ctx);
return (item);
}
@@ -775,6 +788,7 @@ cbor_encode_hmac_secret_param(const fido_dev_t *dev, cbor_item_t *item,
cbor_item_t *argv[4];
struct cbor_pair pair;
fido_blob_t *enc = NULL;
+ uint8_t prot;
int r;
memset(argv, 0, sizeof(argv));
@@ -801,11 +815,17 @@ cbor_encode_hmac_secret_param(const fido_dev_t *dev, cbor_item_t *item,
goto fail;
}
+ if ((prot = fido_dev_get_pin_protocol(dev)) == 0) {
+ fido_log_debug("%s: fido_dev_get_pin_protocol", __func__);
+ r = FIDO_ERR_INTERNAL;
+ goto fail;
+ }
+
/* XXX not pin, but salt */
if ((argv[0] = es256_pk_encode(pk, 1)) == NULL ||
(argv[1] = fido_blob_encode(enc)) == NULL ||
(argv[2] = cbor_encode_pin_auth(dev, ecdh, enc)) == NULL ||
- (argv[3] = cbor_encode_pin_opt(dev)) == NULL) {
+ (prot != 1 && (argv[3] = cbor_build_uint8(prot)) == NULL)) {
fido_log_debug("%s: cbor encode", __func__);
r = FIDO_ERR_INTERNAL;
goto fail;
@@ -896,7 +916,7 @@ cbor_decode_fmt(const cbor_item_t *item, char **fmt)
}
if (strcmp(type, "packed") && strcmp(type, "fido-u2f") &&
- strcmp(type, "none")) {
+ strcmp(type, "none") && strcmp(type, "tpm")) {
fido_log_debug("%s: type=%s", __func__, type);
free(type);
return (-1);
@@ -1141,6 +1161,14 @@ decode_cred_extension(const cbor_item_t *key, const cbor_item_t *val, void *arg)
}
if (cbor_ctrl_value(val) == CBOR_CTRL_TRUE)
authdata_ext->mask |= FIDO_EXT_CRED_BLOB;
+ } else if (strcmp(type, "minPinLength") == 0) {
+ if (cbor_isa_uint(val) == false ||
+ cbor_int_get_width(val) != CBOR_INT_8) {
+ fido_log_debug("%s: cbor type", __func__);
+ goto out;
+ }
+ authdata_ext->mask |= FIDO_EXT_MINPINLEN;
+ authdata_ext->minpinlen = cbor_get_uint8(val);
}
ok = 0;
@@ -1365,7 +1393,6 @@ decode_attstmt_entry(const cbor_item_t *key, const cbor_item_t *val, void *arg)
{
fido_attstmt_t *attstmt = arg;
char *name = NULL;
- int cose_alg = 0;
int ok = -1;
if (cbor_string_copy(key, &name) < 0) {
@@ -1380,10 +1407,11 @@ decode_attstmt_entry(const cbor_item_t *key, const cbor_item_t *val, void *arg)
fido_log_debug("%s: alg", __func__);
goto out;
}
- if ((cose_alg = -(int)cbor_get_int(val) - 1) != COSE_ES256 &&
- cose_alg != COSE_RS256 && cose_alg != COSE_EDDSA) {
- fido_log_debug("%s: unsupported cose_alg=%d", __func__,
- cose_alg);
+ attstmt->alg = -(int)cbor_get_int(val) - 1;
+ if (attstmt->alg != COSE_ES256 && attstmt->alg != COSE_RS256 &&
+ attstmt->alg != COSE_EDDSA && attstmt->alg != COSE_RS1) {
+ fido_log_debug("%s: unsupported attstmt->alg=%d",
+ __func__, attstmt->alg);
goto out;
}
} else if (!strcmp(name, "sig")) {
@@ -1398,6 +1426,16 @@ decode_attstmt_entry(const cbor_item_t *key, const cbor_item_t *val, void *arg)
fido_log_debug("%s: x5c", __func__);
goto out;
}
+ } else if (!strcmp(name, "certInfo")) {
+ if (fido_blob_decode(val, &attstmt->certinfo) < 0) {
+ fido_log_debug("%s: certinfo", __func__);
+ goto out;
+ }
+ } else if (!strcmp(name, "pubArea")) {
+ if (fido_blob_decode(val, &attstmt->pubarea) < 0) {
+ fido_log_debug("%s: pubarea", __func__);
+ goto out;
+ }
}
ok = 0;
@@ -1410,6 +1448,8 @@ out:
int
cbor_decode_attstmt(const cbor_item_t *item, fido_attstmt_t *attstmt)
{
+ size_t alloc_len;
+
if (cbor_isa_map(item) == false ||
cbor_map_is_definite(item) == false ||
cbor_map_iter(item, attstmt, decode_attstmt_entry) < 0) {
@@ -1417,6 +1457,13 @@ cbor_decode_attstmt(const cbor_item_t *item, fido_attstmt_t *attstmt)
return (-1);
}
+ if (attstmt->cbor.ptr != NULL ||
+ (attstmt->cbor.len = cbor_serialize_alloc(item,
+ &attstmt->cbor.ptr, &alloc_len)) == 0) {
+ fido_log_debug("%s: cbor_serialize_alloc", __func__);
+ return (-1);
+ }
+
return (0);
}
diff --git a/contrib/libfido2/src/config.c b/contrib/libfido2/src/config.c
index 0dda16163bc8..2baaab0fd62c 100644
--- a/contrib/libfido2/src/config.c
+++ b/contrib/libfido2/src/config.c
@@ -39,7 +39,7 @@ config_prepare_hmac(uint8_t subcmd, const cbor_item_t *item, fido_blob_t *hmac)
static int
config_tx(fido_dev_t *dev, uint8_t subcmd, cbor_item_t **paramv, size_t paramc,
- const char *pin)
+ const char *pin, int *ms)
{
cbor_item_t *argv[4];
es256_pk_t *pk = NULL;
@@ -68,12 +68,12 @@ config_tx(fido_dev_t *dev, uint8_t subcmd, cbor_item_t **paramv, size_t paramc,
fido_log_debug("%s: config_prepare_hmac", __func__);
goto fail;
}
- if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) {
+ if ((r = fido_do_ecdh(dev, &pk, &ecdh, ms)) != FIDO_OK) {
fido_log_debug("%s: fido_do_ecdh", __func__);
goto fail;
}
if ((r = cbor_add_uv_params(dev, cmd, &hmac, pk, ecdh, pin,
- NULL, &argv[3], &argv[2])) != FIDO_OK) {
+ NULL, &argv[3], &argv[2], ms)) != FIDO_OK) {
fido_log_debug("%s: cbor_add_uv_params", __func__);
goto fail;
}
@@ -81,7 +81,7 @@ config_tx(fido_dev_t *dev, uint8_t subcmd, cbor_item_t **paramv, size_t paramc,
/* framing and transmission */
if (cbor_build_frame(cmd, argv, nitems(argv), &f) < 0 ||
- fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
+ fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -99,11 +99,12 @@ fail:
}
static int
-config_enable_entattest_wait(fido_dev_t *dev, const char *pin, int ms)
+config_enable_entattest_wait(fido_dev_t *dev, const char *pin, int *ms)
{
int r;
- if ((r = config_tx(dev, CMD_ENABLE_ENTATTEST, NULL, 0, pin)) != FIDO_OK)
+ if ((r = config_tx(dev, CMD_ENABLE_ENTATTEST, NULL, 0, pin,
+ ms)) != FIDO_OK)
return r;
return fido_rx_cbor_status(dev, ms);
@@ -112,15 +113,18 @@ config_enable_entattest_wait(fido_dev_t *dev, const char *pin, int ms)
int
fido_dev_enable_entattest(fido_dev_t *dev, const char *pin)
{
- return (config_enable_entattest_wait(dev, pin, -1));
+ int ms = dev->timeout_ms;
+
+ return (config_enable_entattest_wait(dev, pin, &ms));
}
static int
-config_toggle_always_uv_wait(fido_dev_t *dev, const char *pin, int ms)
+config_toggle_always_uv_wait(fido_dev_t *dev, const char *pin, int *ms)
{
int r;
- if ((r = config_tx(dev, CMD_TOGGLE_ALWAYS_UV, NULL, 0, pin)) != FIDO_OK)
+ if ((r = config_tx(dev, CMD_TOGGLE_ALWAYS_UV, NULL, 0, pin,
+ ms)) != FIDO_OK)
return r;
return (fido_rx_cbor_status(dev, ms));
@@ -129,18 +133,21 @@ config_toggle_always_uv_wait(fido_dev_t *dev, const char *pin, int ms)
int
fido_dev_toggle_always_uv(fido_dev_t *dev, const char *pin)
{
- return config_toggle_always_uv_wait(dev, pin, -1);
+ int ms = dev->timeout_ms;
+
+ return config_toggle_always_uv_wait(dev, pin, &ms);
}
static int
-config_pin_minlen_tx(fido_dev_t *dev, size_t len, bool force, const char *pin)
+config_pin_minlen_tx(fido_dev_t *dev, size_t len, bool force,
+ const fido_str_array_t *rpid, const char *pin, int *ms)
{
cbor_item_t *argv[3];
int r;
memset(argv, 0, sizeof(argv));
- if ((!len && !force) || len > UINT8_MAX) {
+ if ((rpid == NULL && len == 0 && !force) || len > UINT8_MAX) {
r = FIDO_ERR_INVALID_ARGUMENT;
goto fail;
}
@@ -149,13 +156,18 @@ config_pin_minlen_tx(fido_dev_t *dev, size_t len, bool force, const char *pin)
r = FIDO_ERR_INTERNAL;
goto fail;
}
+ if (rpid != NULL && (argv[1] = cbor_encode_str_array(rpid)) == NULL) {
+ fido_log_debug("%s: cbor_encode_str_array", __func__);
+ r = FIDO_ERR_INTERNAL;
+ goto fail;
+ }
if (force && (argv[2] = cbor_build_bool(true)) == NULL) {
fido_log_debug("%s: cbor_build_bool", __func__);
r = FIDO_ERR_INTERNAL;
goto fail;
}
if ((r = config_tx(dev, CMD_SET_PIN_MINLEN, argv, nitems(argv),
- pin)) != FIDO_OK) {
+ pin, ms)) != FIDO_OK) {
fido_log_debug("%s: config_tx", __func__);
goto fail;
}
@@ -167,12 +179,13 @@ fail:
}
static int
-config_pin_minlen(fido_dev_t *dev, size_t len, bool force, const char *pin,
- int ms)
+config_pin_minlen(fido_dev_t *dev, size_t len, bool force,
+ const fido_str_array_t *rpid, const char *pin, int *ms)
{
int r;
- if ((r = config_pin_minlen_tx(dev, len, force, pin)) != FIDO_OK)
+ if ((r = config_pin_minlen_tx(dev, len, force, rpid, pin,
+ ms)) != FIDO_OK)
return r;
return fido_rx_cbor_status(dev, ms);
@@ -181,11 +194,36 @@ config_pin_minlen(fido_dev_t *dev, size_t len, bool force, const char *pin,
int
fido_dev_set_pin_minlen(fido_dev_t *dev, size_t len, const char *pin)
{
- return config_pin_minlen(dev, len, false, pin, -1);
+ int ms = dev->timeout_ms;
+
+ return config_pin_minlen(dev, len, false, NULL, pin, &ms);
}
int
fido_dev_force_pin_change(fido_dev_t *dev, const char *pin)
{
- return config_pin_minlen(dev, 0, true, pin, -1);
+ int ms = dev->timeout_ms;
+
+ return config_pin_minlen(dev, 0, true, NULL, pin, &ms);
+}
+
+int
+fido_dev_set_pin_minlen_rpid(fido_dev_t *dev, const char * const *rpid,
+ size_t n, const char *pin)
+{
+ fido_str_array_t sa;
+ int ms = dev->timeout_ms;
+ int r;
+
+ memset(&sa, 0, sizeof(sa));
+ if (fido_str_array_pack(&sa, rpid, n) < 0) {
+ fido_log_debug("%s: fido_str_array_pack", __func__);
+ r = FIDO_ERR_INTERNAL;
+ goto fail;
+ }
+ r = config_pin_minlen(dev, 0, false, &sa, pin, &ms);
+fail:
+ fido_str_array_free(&sa);
+
+ return r;
}
diff --git a/contrib/libfido2/src/cred.c b/contrib/libfido2/src/cred.c
index 5e65b08293b1..6da502c8d90a 100644
--- a/contrib/libfido2/src/cred.c
+++ b/contrib/libfido2/src/cred.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -10,6 +10,10 @@
#include "fido.h"
#include "fido/es256.h"
+#ifndef FIDO_MAXMSG_CRED
+#define FIDO_MAXMSG_CRED 4096
+#endif
+
static int
parse_makecred_reply(const cbor_item_t *key, const cbor_item_t *val, void *arg)
{
@@ -43,7 +47,8 @@ parse_makecred_reply(const cbor_item_t *key, const cbor_item_t *val, void *arg)
}
static int
-fido_dev_make_cred_tx(fido_dev_t *dev, fido_cred_t *cred, const char *pin)
+fido_dev_make_cred_tx(fido_dev_t *dev, fido_cred_t *cred, const char *pin,
+ int *ms)
{
fido_blob_t f;
fido_blob_t *ecdh = NULL;
@@ -92,12 +97,12 @@ fido_dev_make_cred_tx(fido_dev_t *dev, fido_cred_t *cred, const char *pin)
/* user verification */
if (pin != NULL || (uv == FIDO_OPT_TRUE &&
fido_dev_supports_permissions(dev))) {
- if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) {
+ if ((r = fido_do_ecdh(dev, &pk, &ecdh, ms)) != FIDO_OK) {
fido_log_debug("%s: fido_do_ecdh", __func__);
goto fail;
}
if ((r = cbor_add_uv_params(dev, cmd, &cred->cdh, pk, ecdh,
- pin, cred->rp.id, &argv[7], &argv[8])) != FIDO_OK) {
+ pin, cred->rp.id, &argv[7], &argv[8], ms)) != FIDO_OK) {
fido_log_debug("%s: cbor_add_uv_params", __func__);
goto fail;
}
@@ -114,7 +119,7 @@ fido_dev_make_cred_tx(fido_dev_t *dev, fido_cred_t *cred, const char *pin)
/* framing and transmission */
if (cbor_build_frame(cmd, argv, nitems(argv), &f) < 0 ||
- fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
+ fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -131,42 +136,55 @@ fail:
}
static int
-fido_dev_make_cred_rx(fido_dev_t *dev, fido_cred_t *cred, int ms)
+fido_dev_make_cred_rx(fido_dev_t *dev, fido_cred_t *cred, int *ms)
{
- unsigned char reply[FIDO_MAXMSG];
- int reply_len;
- int r;
+ unsigned char *reply;
+ int reply_len;
+ int r;
fido_cred_reset_rx(cred);
- if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, &reply, sizeof(reply),
+ if ((reply = malloc(FIDO_MAXMSG_CRED)) == NULL) {
+ r = FIDO_ERR_INTERNAL;
+ goto fail;
+ }
+
+ if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, reply, FIDO_MAXMSG_CRED,
ms)) < 0) {
fido_log_debug("%s: fido_rx", __func__);
- return (FIDO_ERR_RX);
+ r = FIDO_ERR_RX;
+ goto fail;
}
if ((r = cbor_parse_reply(reply, (size_t)reply_len, cred,
parse_makecred_reply)) != FIDO_OK) {
fido_log_debug("%s: parse_makecred_reply", __func__);
- return (r);
+ goto fail;
}
if (cred->fmt == NULL || fido_blob_is_empty(&cred->authdata_cbor) ||
fido_blob_is_empty(&cred->attcred.id)) {
- fido_cred_reset_rx(cred);
- return (FIDO_ERR_INVALID_CBOR);
+ r = FIDO_ERR_INVALID_CBOR;
+ goto fail;
}
- return (FIDO_OK);
+ r = FIDO_OK;
+fail:
+ free(reply);
+
+ if (r != FIDO_OK)
+ fido_cred_reset_rx(cred);
+
+ return (r);
}
static int
fido_dev_make_cred_wait(fido_dev_t *dev, fido_cred_t *cred, const char *pin,
- int ms)
+ int *ms)
{
int r;
- if ((r = fido_dev_make_cred_tx(dev, cred, pin)) != FIDO_OK ||
+ if ((r = fido_dev_make_cred_tx(dev, cred, pin, ms)) != FIDO_OK ||
(r = fido_dev_make_cred_rx(dev, cred, ms)) != FIDO_OK)
return (r);
@@ -176,18 +194,20 @@ fido_dev_make_cred_wait(fido_dev_t *dev, fido_cred_t *cred, const char *pin,
int
fido_dev_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin)
{
+ int ms = dev->timeout_ms;
+
#ifdef USE_WINHELLO
if (dev->flags & FIDO_DEV_WINHELLO)
- return (fido_winhello_make_cred(dev, cred, pin));
+ return (fido_winhello_make_cred(dev, cred, pin, ms));
#endif
if (fido_dev_is_fido2(dev) == false) {
if (pin != NULL || cred->rk == FIDO_OPT_TRUE ||
cred->ext.mask != 0)
return (FIDO_ERR_UNSUPPORTED_OPTION);
- return (u2f_register(dev, cred, -1));
+ return (u2f_register(dev, cred, &ms));
}
- return (fido_dev_make_cred_wait(dev, cred, pin, -1));
+ return (fido_dev_make_cred_wait(dev, cred, pin, &ms));
}
static int
@@ -225,66 +245,81 @@ get_signed_hash_u2f(fido_blob_t *dgst, const unsigned char *rp_id,
size_t rp_id_len, const fido_blob_t *clientdata, const fido_blob_t *id,
const es256_pk_t *pk)
{
- const uint8_t zero = 0;
- const uint8_t four = 4; /* uncompressed point */
- SHA256_CTX ctx;
-
- if (dgst->len != SHA256_DIGEST_LENGTH || SHA256_Init(&ctx) == 0 ||
- SHA256_Update(&ctx, &zero, sizeof(zero)) == 0 ||
- SHA256_Update(&ctx, rp_id, rp_id_len) == 0 ||
- SHA256_Update(&ctx, clientdata->ptr, clientdata->len) == 0 ||
- SHA256_Update(&ctx, id->ptr, id->len) == 0 ||
- SHA256_Update(&ctx, &four, sizeof(four)) == 0 ||
- SHA256_Update(&ctx, pk->x, sizeof(pk->x)) == 0 ||
- SHA256_Update(&ctx, pk->y, sizeof(pk->y)) == 0 ||
- SHA256_Final(dgst->ptr, &ctx) == 0) {
+ const uint8_t zero = 0;
+ const uint8_t four = 4; /* uncompressed point */
+ const EVP_MD *md = NULL;
+ EVP_MD_CTX *ctx = NULL;
+ int ok = -1;
+
+ if (dgst->len != SHA256_DIGEST_LENGTH ||
+ (md = EVP_sha256()) == NULL ||
+ (ctx = EVP_MD_CTX_new()) == NULL ||
+ EVP_DigestInit_ex(ctx, md, NULL) != 1 ||
+ EVP_DigestUpdate(ctx, &zero, sizeof(zero)) != 1 ||
+ EVP_DigestUpdate(ctx, rp_id, rp_id_len) != 1 ||
+ EVP_DigestUpdate(ctx, clientdata->ptr, clientdata->len) != 1 ||
+ EVP_DigestUpdate(ctx, id->ptr, id->len) != 1 ||
+ EVP_DigestUpdate(ctx, &four, sizeof(four)) != 1 ||
+ EVP_DigestUpdate(ctx, pk->x, sizeof(pk->x)) != 1 ||
+ EVP_DigestUpdate(ctx, pk->y, sizeof(pk->y)) != 1 ||
+ EVP_DigestFinal_ex(ctx, dgst->ptr, NULL) != 1) {
fido_log_debug("%s: sha256", __func__);
- return (-1);
+ goto fail;
}
- return (0);
+ ok = 0;
+fail:
+ EVP_MD_CTX_free(ctx);
+
+ return (ok);
}
static int
-verify_sig(const fido_blob_t *dgst, const fido_blob_t *x5c,
- const fido_blob_t *sig)
+verify_attstmt(const fido_blob_t *dgst, const fido_attstmt_t *attstmt)
{
BIO *rawcert = NULL;
X509 *cert = NULL;
EVP_PKEY *pkey = NULL;
- EC_KEY *ec;
int ok = -1;
/* openssl needs ints */
- if (dgst->len > INT_MAX || x5c->len > INT_MAX || sig->len > INT_MAX) {
- fido_log_debug("%s: dgst->len=%zu, x5c->len=%zu, sig->len=%zu",
- __func__, dgst->len, x5c->len, sig->len);
+ if (attstmt->x5c.len > INT_MAX) {
+ fido_log_debug("%s: x5c.len=%zu", __func__, attstmt->x5c.len);
return (-1);
}
/* fetch key from x509 */
- if ((rawcert = BIO_new_mem_buf(x5c->ptr, (int)x5c->len)) == NULL ||
+ if ((rawcert = BIO_new_mem_buf(attstmt->x5c.ptr,
+ (int)attstmt->x5c.len)) == NULL ||
(cert = d2i_X509_bio(rawcert, NULL)) == NULL ||
- (pkey = X509_get_pubkey(cert)) == NULL ||
- (ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) {
+ (pkey = X509_get_pubkey(cert)) == NULL) {
fido_log_debug("%s: x509 key", __func__);
goto fail;
}
- if (ECDSA_verify(0, dgst->ptr, (int)dgst->len, sig->ptr,
- (int)sig->len, ec) != 1) {
- fido_log_debug("%s: ECDSA_verify", __func__);
- goto fail;
+ switch (attstmt->alg) {
+ case COSE_UNSPEC:
+ case COSE_ES256:
+ ok = es256_verify_sig(dgst, pkey, &attstmt->sig);
+ break;
+ case COSE_RS256:
+ ok = rs256_verify_sig(dgst, pkey, &attstmt->sig);
+ break;
+ case COSE_RS1:
+ ok = rs1_verify_sig(dgst, pkey, &attstmt->sig);
+ break;
+ case COSE_EDDSA:
+ ok = eddsa_verify_sig(dgst, pkey, &attstmt->sig);
+ break;
+ default:
+ fido_log_debug("%s: unknown alg %d", __func__, attstmt->alg);
+ break;
}
- ok = 0;
fail:
- if (rawcert != NULL)
- BIO_free(rawcert);
- if (cert != NULL)
- X509_free(cert);
- if (pkey != NULL)
- EVP_PKEY_free(pkey);
+ BIO_free(rawcert);
+ X509_free(cert);
+ EVP_PKEY_free(pkey);
return (ok);
}
@@ -348,14 +383,21 @@ fido_cred_verify(const fido_cred_t *cred)
r = FIDO_ERR_INTERNAL;
goto out;
}
+ } else if (!strcmp(cred->fmt, "tpm")) {
+ if (fido_get_signed_hash_tpm(&dgst, &cred->cdh,
+ &cred->authdata_raw, &cred->attstmt, &cred->attcred) < 0) {
+ fido_log_debug("%s: fido_get_signed_hash_tpm", __func__);
+ r = FIDO_ERR_INTERNAL;
+ goto out;
+ }
} else {
fido_log_debug("%s: unknown fmt %s", __func__, cred->fmt);
r = FIDO_ERR_INVALID_ARGUMENT;
goto out;
}
- if (verify_sig(&dgst, &cred->attstmt.x5c, &cred->attstmt.sig) < 0) {
- fido_log_debug("%s: verify_sig", __func__);
+ if (verify_attstmt(&dgst, &cred->attstmt) < 0) {
+ fido_log_debug("%s: verify_attstmt", __func__);
r = FIDO_ERR_INVALID_SIG;
goto out;
}
@@ -435,15 +477,15 @@ fido_cred_verify_self(const fido_cred_t *cred)
switch (cred->attcred.type) {
case COSE_ES256:
- ok = fido_verify_sig_es256(&dgst, &cred->attcred.pubkey.es256,
+ ok = es256_pk_verify_sig(&dgst, &cred->attcred.pubkey.es256,
&cred->attstmt.sig);
break;
case COSE_RS256:
- ok = fido_verify_sig_rs256(&dgst, &cred->attcred.pubkey.rs256,
+ ok = rs256_pk_verify_sig(&dgst, &cred->attcred.pubkey.rs256,
&cred->attstmt.sig);
break;
case COSE_EDDSA:
- ok = fido_verify_sig_eddsa(&dgst, &cred->attcred.pubkey.eddsa,
+ ok = eddsa_pk_verify_sig(&dgst, &cred->attcred.pubkey.eddsa,
&cred->attstmt.sig);
break;
default:
@@ -482,6 +524,18 @@ fido_cred_clean_authdata(fido_cred_t *cred)
memset(&cred->attcred, 0, sizeof(cred->attcred));
}
+static void
+fido_cred_clean_attstmt(fido_attstmt_t *attstmt)
+{
+ fido_blob_reset(&attstmt->certinfo);
+ fido_blob_reset(&attstmt->pubarea);
+ fido_blob_reset(&attstmt->cbor);
+ fido_blob_reset(&attstmt->x5c);
+ fido_blob_reset(&attstmt->sig);
+
+ memset(attstmt, 0, sizeof(*attstmt));
+}
+
void
fido_cred_reset_tx(fido_cred_t *cred)
{
@@ -513,8 +567,7 @@ fido_cred_reset_rx(fido_cred_t *cred)
free(cred->fmt);
cred->fmt = NULL;
fido_cred_clean_authdata(cred);
- fido_blob_reset(&cred->attstmt.x5c);
- fido_blob_reset(&cred->attstmt.sig);
+ fido_cred_clean_attstmt(&cred->attstmt);
fido_blob_reset(&cred->largeblob_key);
}
@@ -568,7 +621,6 @@ fail:
fido_cred_clean_authdata(cred);
return (r);
-
}
int
@@ -610,7 +662,6 @@ fail:
fido_cred_clean_authdata(cred);
return (r);
-
}
int
@@ -641,6 +692,39 @@ fido_cred_set_sig(fido_cred_t *cred, const unsigned char *ptr, size_t len)
}
int
+fido_cred_set_attstmt(fido_cred_t *cred, const unsigned char *ptr, size_t len)
+{
+ cbor_item_t *item = NULL;
+ struct cbor_load_result cbor;
+ int r = FIDO_ERR_INVALID_ARGUMENT;
+
+ fido_cred_clean_attstmt(&cred->attstmt);
+
+ if (ptr == NULL || len == 0)
+ goto fail;
+
+ if ((item = cbor_load(ptr, len, &cbor)) == NULL) {
+ fido_log_debug("%s: cbor_load", __func__);
+ goto fail;
+ }
+
+ if (cbor_decode_attstmt(item, &cred->attstmt) < 0) {
+ fido_log_debug("%s: cbor_decode_attstmt", __func__);
+ goto fail;
+ }
+
+ r = FIDO_OK;
+fail:
+ if (item != NULL)
+ cbor_decref(&item);
+
+ if (r != FIDO_OK)
+ fido_cred_clean_attstmt(&cred->attstmt);
+
+ return (r);
+}
+
+int
fido_cred_exclude(fido_cred_t *cred, const unsigned char *id_ptr, size_t id_len)
{
fido_blob_t id_blob;
@@ -834,6 +918,19 @@ fido_cred_set_prot(fido_cred_t *cred, int prot)
}
int
+fido_cred_set_pin_minlen(fido_cred_t *cred, size_t len)
+{
+ if (len == 0)
+ cred->ext.mask &= ~FIDO_EXT_MINPINLEN;
+ else
+ cred->ext.mask |= FIDO_EXT_MINPINLEN;
+
+ cred->ext.minpinlen = len;
+
+ return (FIDO_OK);
+}
+
+int
fido_cred_set_blob(fido_cred_t *cred, const unsigned char *ptr, size_t len)
{
if (ptr == NULL || len == 0)
@@ -856,7 +953,7 @@ fido_cred_set_fmt(fido_cred_t *cred, const char *fmt)
return (FIDO_ERR_INVALID_ARGUMENT);
if (strcmp(fmt, "packed") && strcmp(fmt, "fido-u2f") &&
- strcmp(fmt, "none"))
+ strcmp(fmt, "none") && strcmp(fmt, "tpm"))
return (FIDO_ERR_INVALID_ARGUMENT);
if ((cred->fmt = strdup(fmt)) == NULL)
@@ -956,6 +1053,18 @@ fido_cred_authdata_raw_len(const fido_cred_t *cred)
}
const unsigned char *
+fido_cred_attstmt_ptr(const fido_cred_t *cred)
+{
+ return (cred->attstmt.cbor.ptr);
+}
+
+size_t
+fido_cred_attstmt_len(const fido_cred_t *cred)
+{
+ return (cred->attstmt.cbor.len);
+}
+
+const unsigned char *
fido_cred_pubkey_ptr(const fido_cred_t *cred)
{
const void *ptr;
@@ -1031,6 +1140,12 @@ fido_cred_prot(const fido_cred_t *cred)
return (cred->ext.prot);
}
+size_t
+fido_cred_pin_minlen(const fido_cred_t *cred)
+{
+ return (cred->ext.minpinlen);
+}
+
const char *
fido_cred_fmt(const fido_cred_t *cred)
{
diff --git a/contrib/libfido2/src/credman.c b/contrib/libfido2/src/credman.c
index e48ca4543b10..8d2649a144f2 100644
--- a/contrib/libfido2/src/credman.c
+++ b/contrib/libfido2/src/credman.c
@@ -112,7 +112,7 @@ fail:
static int
credman_tx(fido_dev_t *dev, uint8_t subcmd, const void *param, const char *pin,
- const char *rp_id, fido_opt_t uv)
+ const char *rp_id, fido_opt_t uv, int *ms)
{
fido_blob_t f;
fido_blob_t *ecdh = NULL;
@@ -144,12 +144,12 @@ credman_tx(fido_dev_t *dev, uint8_t subcmd, const void *param, const char *pin,
fido_log_debug("%s: credman_prepare_hmac", __func__);
goto fail;
}
- if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) {
+ if ((r = fido_do_ecdh(dev, &pk, &ecdh, ms)) != FIDO_OK) {
fido_log_debug("%s: fido_do_ecdh", __func__);
goto fail;
}
if ((r = cbor_add_uv_params(dev, cmd, &hmac, pk, ecdh, pin,
- rp_id, &argv[3], &argv[2])) != FIDO_OK) {
+ rp_id, &argv[3], &argv[2], ms)) != FIDO_OK) {
fido_log_debug("%s: cbor_add_uv_params", __func__);
goto fail;
}
@@ -157,7 +157,7 @@ credman_tx(fido_dev_t *dev, uint8_t subcmd, const void *param, const char *pin,
/* framing and transmission */
if (cbor_build_frame(cmd, argv, nitems(argv), &f) < 0 ||
- fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
+ fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -198,7 +198,7 @@ credman_parse_metadata(const cbor_item_t *key, const cbor_item_t *val,
}
static int
-credman_rx_metadata(fido_dev_t *dev, fido_credman_metadata_t *metadata, int ms)
+credman_rx_metadata(fido_dev_t *dev, fido_credman_metadata_t *metadata, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
@@ -223,12 +223,12 @@ credman_rx_metadata(fido_dev_t *dev, fido_credman_metadata_t *metadata, int ms)
static int
credman_get_metadata_wait(fido_dev_t *dev, fido_credman_metadata_t *metadata,
- const char *pin, int ms)
+ const char *pin, int *ms)
{
int r;
if ((r = credman_tx(dev, CMD_CRED_METADATA, NULL, pin, NULL,
- FIDO_OPT_TRUE)) != FIDO_OK ||
+ FIDO_OPT_TRUE, ms)) != FIDO_OK ||
(r = credman_rx_metadata(dev, metadata, ms)) != FIDO_OK)
return (r);
@@ -239,7 +239,9 @@ int
fido_credman_get_dev_metadata(fido_dev_t *dev, fido_credman_metadata_t *metadata,
const char *pin)
{
- return (credman_get_metadata_wait(dev, metadata, pin, -1));
+ int ms = dev->timeout_ms;
+
+ return (credman_get_metadata_wait(dev, metadata, pin, &ms));
}
static int
@@ -321,7 +323,7 @@ credman_parse_rk_count(const cbor_item_t *key, const cbor_item_t *val,
}
static int
-credman_rx_rk(fido_dev_t *dev, fido_credman_rk_t *rk, int ms)
+credman_rx_rk(fido_dev_t *dev, fido_credman_rk_t *rk, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
@@ -360,7 +362,7 @@ credman_rx_rk(fido_dev_t *dev, fido_credman_rk_t *rk, int ms)
}
static int
-credman_rx_next_rk(fido_dev_t *dev, fido_credman_rk_t *rk, int ms)
+credman_rx_next_rk(fido_dev_t *dev, fido_credman_rk_t *rk, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
@@ -390,7 +392,7 @@ credman_rx_next_rk(fido_dev_t *dev, fido_credman_rk_t *rk, int ms)
static int
credman_get_rk_wait(fido_dev_t *dev, const char *rp_id, fido_credman_rk_t *rk,
- const char *pin, int ms)
+ const char *pin, int *ms)
{
fido_blob_t rp_dgst;
uint8_t dgst[SHA256_DIGEST_LENGTH];
@@ -405,13 +407,13 @@ credman_get_rk_wait(fido_dev_t *dev, const char *rp_id, fido_credman_rk_t *rk,
rp_dgst.len = sizeof(dgst);
if ((r = credman_tx(dev, CMD_RK_BEGIN, &rp_dgst, pin, rp_id,
- FIDO_OPT_TRUE)) != FIDO_OK ||
+ FIDO_OPT_TRUE, ms)) != FIDO_OK ||
(r = credman_rx_rk(dev, rk, ms)) != FIDO_OK)
return (r);
while (rk->n_rx < rk->n_alloc) {
if ((r = credman_tx(dev, CMD_RK_NEXT, NULL, NULL, NULL,
- FIDO_OPT_FALSE)) != FIDO_OK ||
+ FIDO_OPT_FALSE, ms)) != FIDO_OK ||
(r = credman_rx_next_rk(dev, rk, ms)) != FIDO_OK)
return (r);
rk->n_rx++;
@@ -424,12 +426,14 @@ int
fido_credman_get_dev_rk(fido_dev_t *dev, const char *rp_id,
fido_credman_rk_t *rk, const char *pin)
{
- return (credman_get_rk_wait(dev, rp_id, rk, pin, -1));
+ int ms = dev->timeout_ms;
+
+ return (credman_get_rk_wait(dev, rp_id, rk, pin, &ms));
}
static int
credman_del_rk_wait(fido_dev_t *dev, const unsigned char *cred_id,
- size_t cred_id_len, const char *pin, int ms)
+ size_t cred_id_len, const char *pin, int *ms)
{
fido_blob_t cred;
int r;
@@ -440,7 +444,7 @@ credman_del_rk_wait(fido_dev_t *dev, const unsigned char *cred_id,
return (FIDO_ERR_INVALID_ARGUMENT);
if ((r = credman_tx(dev, CMD_DELETE_CRED, &cred, pin, NULL,
- FIDO_OPT_TRUE)) != FIDO_OK ||
+ FIDO_OPT_TRUE, ms)) != FIDO_OK ||
(r = fido_rx_cbor_status(dev, ms)) != FIDO_OK)
goto fail;
@@ -455,7 +459,9 @@ int
fido_credman_del_dev_rk(fido_dev_t *dev, const unsigned char *cred_id,
size_t cred_id_len, const char *pin)
{
- return (credman_del_rk_wait(dev, cred_id, cred_id_len, pin, -1));
+ int ms = dev->timeout_ms;
+
+ return (credman_del_rk_wait(dev, cred_id, cred_id_len, pin, &ms));
}
static int
@@ -526,7 +532,7 @@ credman_parse_rp_count(const cbor_item_t *key, const cbor_item_t *val,
}
static int
-credman_rx_rp(fido_dev_t *dev, fido_credman_rp_t *rp, int ms)
+credman_rx_rp(fido_dev_t *dev, fido_credman_rp_t *rp, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
@@ -565,7 +571,7 @@ credman_rx_rp(fido_dev_t *dev, fido_credman_rp_t *rp, int ms)
}
static int
-credman_rx_next_rp(fido_dev_t *dev, fido_credman_rp_t *rp, int ms)
+credman_rx_next_rp(fido_dev_t *dev, fido_credman_rp_t *rp, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
@@ -595,18 +601,18 @@ credman_rx_next_rp(fido_dev_t *dev, fido_credman_rp_t *rp, int ms)
static int
credman_get_rp_wait(fido_dev_t *dev, fido_credman_rp_t *rp, const char *pin,
- int ms)
+ int *ms)
{
int r;
if ((r = credman_tx(dev, CMD_RP_BEGIN, NULL, pin, NULL,
- FIDO_OPT_TRUE)) != FIDO_OK ||
+ FIDO_OPT_TRUE, ms)) != FIDO_OK ||
(r = credman_rx_rp(dev, rp, ms)) != FIDO_OK)
return (r);
while (rp->n_rx < rp->n_alloc) {
if ((r = credman_tx(dev, CMD_RP_NEXT, NULL, NULL, NULL,
- FIDO_OPT_FALSE)) != FIDO_OK ||
+ FIDO_OPT_FALSE, ms)) != FIDO_OK ||
(r = credman_rx_next_rp(dev, rp, ms)) != FIDO_OK)
return (r);
rp->n_rx++;
@@ -618,17 +624,19 @@ credman_get_rp_wait(fido_dev_t *dev, fido_credman_rp_t *rp, const char *pin,
int
fido_credman_get_dev_rp(fido_dev_t *dev, fido_credman_rp_t *rp, const char *pin)
{
- return (credman_get_rp_wait(dev, rp, pin, -1));
+ int ms = dev->timeout_ms;
+
+ return (credman_get_rp_wait(dev, rp, pin, &ms));
}
static int
credman_set_dev_rk_wait(fido_dev_t *dev, fido_cred_t *cred, const char *pin,
- int ms)
+ int *ms)
{
int r;
if ((r = credman_tx(dev, CMD_UPDATE_CRED, cred, pin, NULL,
- FIDO_OPT_TRUE)) != FIDO_OK ||
+ FIDO_OPT_TRUE, ms)) != FIDO_OK ||
(r = fido_rx_cbor_status(dev, ms)) != FIDO_OK)
return (r);
@@ -638,7 +646,9 @@ credman_set_dev_rk_wait(fido_dev_t *dev, fido_cred_t *cred, const char *pin,
int
fido_credman_set_dev_rk(fido_dev_t *dev, fido_cred_t *cred, const char *pin)
{
- return (credman_set_dev_rk_wait(dev, cred, pin, -1));
+ int ms = dev->timeout_ms;
+
+ return (credman_set_dev_rk_wait(dev, cred, pin, &ms));
}
fido_credman_rk_t *
diff --git a/contrib/libfido2/src/dev.c b/contrib/libfido2/src/dev.c
index a003854f89d2..0c3cf64a462b 100644
--- a/contrib/libfido2/src/dev.c
+++ b/contrib/libfido2/src/dev.c
@@ -106,7 +106,7 @@ fido_dev_set_flags(fido_dev_t *dev, const fido_cbor_info_t *info)
}
static int
-fido_dev_open_tx(fido_dev_t *dev, const char *path)
+fido_dev_open_tx(fido_dev_t *dev, const char *path, int *ms)
{
int r;
@@ -161,7 +161,8 @@ fido_dev_open_tx(fido_dev_t *dev, const char *path)
goto fail;
}
- if (fido_tx(dev, CTAP_CMD_INIT, &dev->nonce, sizeof(dev->nonce)) < 0) {
+ if (fido_tx(dev, CTAP_CMD_INIT, &dev->nonce, sizeof(dev->nonce),
+ ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -176,7 +177,7 @@ fail:
}
static int
-fido_dev_open_rx(fido_dev_t *dev, int ms)
+fido_dev_open_rx(fido_dev_t *dev, int *ms)
{
fido_cbor_info_t *info = NULL;
int reply_len;
@@ -241,7 +242,7 @@ fail:
}
static int
-fido_dev_open_wait(fido_dev_t *dev, const char *path, int ms)
+fido_dev_open_wait(fido_dev_t *dev, const char *path, int *ms)
{
int r;
@@ -249,7 +250,7 @@ fido_dev_open_wait(fido_dev_t *dev, const char *path, int ms)
if (strcmp(path, FIDO_WINHELLO_PATH) == 0)
return (fido_winhello_open(dev));
#endif
- if ((r = fido_dev_open_tx(dev, path)) != FIDO_OK ||
+ if ((r = fido_dev_open_tx(dev, path, ms)) != FIDO_OK ||
(r = fido_dev_open_rx(dev, ms)) != FIDO_OK)
return (r);
@@ -331,24 +332,21 @@ fido_dev_info_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)
int
fido_dev_open_with_info(fido_dev_t *dev)
{
+ int ms = dev->timeout_ms;
+
if (dev->path == NULL)
return (FIDO_ERR_INVALID_ARGUMENT);
- return (fido_dev_open_wait(dev, dev->path, -1));
+ return (fido_dev_open_wait(dev, dev->path, &ms));
}
int
fido_dev_open(fido_dev_t *dev, const char *path)
{
+ int ms = dev->timeout_ms;
+
#ifdef NFC_LINUX
- /*
- * this is a hack to get existing applications up and running with nfc;
- * it will *NOT* be part of a libfido2 release. to support nfc in your
- * application, please change it to use fido_dev_open_with_info().
- */
- if (strncmp(path, "/sys", strlen("/sys")) == 0 && strlen(path) > 4 &&
- path[strlen(path) - 4] == 'n' && path[strlen(path) - 3] == 'f' &&
- path[strlen(path) - 2] == 'c') {
+ if (strncmp(path, FIDO_NFC_PREFIX, strlen(FIDO_NFC_PREFIX)) == 0) {
dev->io_own = true;
dev->io = (fido_dev_io_t) {
fido_nfc_open,
@@ -363,7 +361,7 @@ fido_dev_open(fido_dev_t *dev, const char *path)
}
#endif
- return (fido_dev_open_wait(dev, path, -1));
+ return (fido_dev_open_wait(dev, path, &ms));
}
int
@@ -386,26 +384,31 @@ fido_dev_close(fido_dev_t *dev)
int
fido_dev_set_sigmask(fido_dev_t *dev, const fido_sigset_t *sigmask)
{
- if (dev->io_own || dev->io_handle == NULL || sigmask == NULL)
+ if (dev->io_handle == NULL || sigmask == NULL)
return (FIDO_ERR_INVALID_ARGUMENT);
#ifdef NFC_LINUX
- if (dev->transport.rx == fido_nfc_rx)
+ if (dev->transport.rx == fido_nfc_rx && dev->io.read == fido_nfc_read)
return (fido_nfc_set_sigmask(dev->io_handle, sigmask));
#endif
- return (fido_hid_set_sigmask(dev->io_handle, sigmask));
+ if (dev->transport.rx == NULL && dev->io.read == fido_hid_read)
+ return (fido_hid_set_sigmask(dev->io_handle, sigmask));
+
+ return (FIDO_ERR_INVALID_ARGUMENT);
}
int
fido_dev_cancel(fido_dev_t *dev)
{
+ int ms = dev->timeout_ms;
+
#ifdef USE_WINHELLO
if (dev->flags & FIDO_DEV_WINHELLO)
return (fido_winhello_cancel(dev));
#endif
if (fido_dev_is_fido2(dev) == false)
return (FIDO_ERR_INVALID_ARGUMENT);
- if (fido_tx(dev, CTAP_CMD_CANCEL, NULL, 0) < 0)
+ if (fido_tx(dev, CTAP_CMD_CANCEL, NULL, 0, &ms) < 0)
return (FIDO_ERR_TX);
return (FIDO_OK);
@@ -421,6 +424,7 @@ fido_dev_get_touch_begin(fido_dev_t *dev)
unsigned char cdh[SHA256_DIGEST_LENGTH];
fido_rp_t rp;
fido_user_t user;
+ int ms = dev->timeout_ms;
int r = FIDO_ERR_INTERNAL;
memset(&f, 0, sizeof(f));
@@ -430,7 +434,7 @@ fido_dev_get_touch_begin(fido_dev_t *dev)
memset(&user, 0, sizeof(user));
if (fido_dev_is_fido2(dev) == false)
- return (u2f_get_touch_begin(dev));
+ return (u2f_get_touch_begin(dev, &ms));
if (SHA256((const void *)clientdata, strlen(clientdata), cdh) != cdh) {
fido_log_debug("%s: sha256", __func__);
@@ -465,7 +469,7 @@ fido_dev_get_touch_begin(fido_dev_t *dev)
}
if (cbor_build_frame(CTAP_CBOR_MAKECRED, argv, nitems(argv), &f) < 0 ||
- fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
+ fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, &ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -490,9 +494,9 @@ fido_dev_get_touch_status(fido_dev_t *dev, int *touched, int ms)
*touched = 0;
if (fido_dev_is_fido2(dev) == false)
- return (u2f_get_touch_status(dev, touched, ms));
+ return (u2f_get_touch_status(dev, touched, &ms));
- switch ((r = fido_rx_cbor_status(dev, ms))) {
+ switch ((r = fido_rx_cbor_status(dev, &ms))) {
case FIDO_ERR_PIN_AUTH_INVALID:
case FIDO_ERR_PIN_INVALID:
case FIDO_ERR_PIN_NOT_SET:
@@ -562,6 +566,7 @@ fido_dev_new(void)
return (NULL);
dev->cid = CTAP_CID_BROADCAST;
+ dev->timeout_ms = -1;
dev->io = (fido_dev_io_t) {
&fido_hid_open,
&fido_hid_close,
@@ -593,6 +598,7 @@ fido_dev_new_with_info(const fido_dev_info_t *di)
dev->io_own = di->transport.tx != NULL || di->transport.rx != NULL;
dev->transport = di->transport;
dev->cid = CTAP_CID_BROADCAST;
+ dev->timeout_ms = -1;
if ((dev->path = strdup(di->path)) == NULL) {
fido_log_debug("%s: strdup", __func__);
@@ -730,3 +736,14 @@ fido_dev_maxmsgsize(const fido_dev_t *dev)
{
return (dev->maxmsgsize);
}
+
+int
+fido_dev_set_timeout(fido_dev_t *dev, int ms)
+{
+ if (ms < -1)
+ return (FIDO_ERR_INVALID_ARGUMENT);
+
+ dev->timeout_ms = ms;
+
+ return (FIDO_OK);
+}
diff --git a/contrib/libfido2/src/ecdh.c b/contrib/libfido2/src/ecdh.c
index 3ea47ae6457e..9c4f2b99e1a9 100644
--- a/contrib/libfido2/src/ecdh.c
+++ b/contrib/libfido2/src/ecdh.c
@@ -8,14 +8,14 @@
#include <openssl/sha.h>
#if defined(LIBRESSL_VERSION_NUMBER)
#include <openssl/hkdf.h>
-#elif OPENSSL_VERSION_NUMBER >= 0x10100000L
+#else
#include <openssl/kdf.h>
#endif
#include "fido.h"
#include "fido/es256.h"
-#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L
+#if defined(LIBRESSL_VERSION_NUMBER)
static int
hkdf_sha256(uint8_t *key, const char *info, const fido_blob_t *secret)
{
@@ -56,7 +56,7 @@ hkdf_sha256(uint8_t *key, char *info, fido_blob_t *secret)
EVP_PKEY_CTX_set_hkdf_md(ctx, md) < 1 ||
EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt, sizeof(salt)) < 1 ||
EVP_PKEY_CTX_set1_hkdf_key(ctx, secret->ptr, (int)secret->len) < 1 ||
- EVP_PKEY_CTX_add1_hkdf_info(ctx, info, (int)strlen(info)) < 1) {
+ EVP_PKEY_CTX_add1_hkdf_info(ctx, (void *)info, (int)strlen(info)) < 1) {
fido_log_debug("%s: EVP_PKEY_CTX", __func__);
goto fail;
}
@@ -74,7 +74,7 @@ fail:
return ok;
}
-#endif /* defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L */
+#endif /* defined(LIBRESSL_VERSION_NUMBER) */
static int
kdf(uint8_t prot, fido_blob_t *key, /* const */ fido_blob_t *secret)
@@ -164,7 +164,7 @@ fail:
}
int
-fido_do_ecdh(fido_dev_t *dev, es256_pk_t **pk, fido_blob_t **ecdh)
+fido_do_ecdh(fido_dev_t *dev, es256_pk_t **pk, fido_blob_t **ecdh, int *ms)
{
es256_sk_t *sk = NULL; /* our private key */
es256_pk_t *ak = NULL; /* authenticator's public key */
@@ -182,7 +182,7 @@ fido_do_ecdh(fido_dev_t *dev, es256_pk_t **pk, fido_blob_t **ecdh)
goto fail;
}
if ((ak = es256_pk_new()) == NULL ||
- fido_dev_authkey(dev, ak) != FIDO_OK) {
+ fido_dev_authkey(dev, ak, ms) != FIDO_OK) {
fido_log_debug("%s: fido_dev_authkey", __func__);
r = FIDO_ERR_INTERNAL;
goto fail;
diff --git a/contrib/libfido2/src/eddsa.c b/contrib/libfido2/src/eddsa.c
index 89b84c5a6bd4..d228149ebf4d 100644
--- a/contrib/libfido2/src/eddsa.c
+++ b/contrib/libfido2/src/eddsa.c
@@ -10,7 +10,7 @@
#include "fido.h"
#include "fido/eddsa.h"
-#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10101000L
+#if defined(LIBRESSL_VERSION_NUMBER)
EVP_PKEY *
EVP_PKEY_new_raw_public_key(int type, ENGINE *e, const unsigned char *key,
size_t keylen)
@@ -52,23 +52,7 @@ EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen,
return (0);
}
-#endif /* LIBRESSL_VERSION_NUMBER || OPENSSL_VERSION_NUMBER < 0x10101000L */
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-EVP_MD_CTX *
-EVP_MD_CTX_new(void)
-{
- fido_log_debug("%s: unimplemented", __func__);
-
- return (NULL);
-}
-
-void
-EVP_MD_CTX_free(EVP_MD_CTX *ctx)
-{
- (void)ctx;
-}
-#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+#endif /* LIBRESSL_VERSION_NUMBER */
static int
decode_coord(const cbor_item_t *item, void *xy, size_t xy_len)
@@ -170,3 +154,65 @@ eddsa_pk_from_EVP_PKEY(eddsa_pk_t *pk, const EVP_PKEY *pkey)
return (FIDO_OK);
}
+
+int
+eddsa_verify_sig(const fido_blob_t *dgst, EVP_PKEY *pkey,
+ const fido_blob_t *sig)
+{
+ EVP_MD_CTX *mdctx = NULL;
+ int ok = -1;
+
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_ED25519) {
+ fido_log_debug("%s: EVP_PKEY_base_id", __func__);
+ goto fail;
+ }
+
+ /* EVP_DigestVerify needs ints */
+ if (dgst->len > INT_MAX || sig->len > INT_MAX) {
+ fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__,
+ dgst->len, sig->len);
+ return (-1);
+ }
+
+ if ((mdctx = EVP_MD_CTX_new()) == NULL) {
+ fido_log_debug("%s: EVP_MD_CTX_new", __func__);
+ goto fail;
+ }
+
+ if (EVP_DigestVerifyInit(mdctx, NULL, NULL, NULL, pkey) != 1) {
+ fido_log_debug("%s: EVP_DigestVerifyInit", __func__);
+ goto fail;
+ }
+
+ if (EVP_DigestVerify(mdctx, sig->ptr, sig->len, dgst->ptr,
+ dgst->len) != 1) {
+ fido_log_debug("%s: EVP_DigestVerify", __func__);
+ goto fail;
+ }
+
+ ok = 0;
+fail:
+ EVP_MD_CTX_free(mdctx);
+
+ return (ok);
+}
+
+int
+eddsa_pk_verify_sig(const fido_blob_t *dgst, const eddsa_pk_t *pk,
+ const fido_blob_t *sig)
+{
+ EVP_PKEY *pkey;
+ int ok = -1;
+
+ if ((pkey = eddsa_pk_to_EVP_PKEY(pk)) == NULL ||
+ eddsa_verify_sig(dgst, pkey, sig) < 0) {
+ fido_log_debug("%s: eddsa_verify_sig", __func__);
+ goto fail;
+ }
+
+ ok = 0;
+fail:
+ EVP_PKEY_free(pkey);
+
+ return (ok);
+}
diff --git a/contrib/libfido2/src/es256.c b/contrib/libfido2/src/es256.c
index 9cdb48e4832d..eb4cc63525aa 100644
--- a/contrib/libfido2/src/es256.c
+++ b/contrib/libfido2/src/es256.c
@@ -1,10 +1,11 @@
/*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
#include <openssl/bn.h>
+#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
#include "fido.h"
@@ -362,6 +363,18 @@ fail:
return (ok);
}
+int
+es256_pk_from_EVP_PKEY(es256_pk_t *pk, const EVP_PKEY *pkey)
+{
+ EC_KEY *ec;
+
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC ||
+ (ec = EVP_PKEY_get0(pkey)) == NULL)
+ return (FIDO_ERR_INVALID_ARGUMENT);
+
+ return (es256_pk_from_EC_KEY(pk, ec));
+}
+
EVP_PKEY *
es256_sk_to_EVP_PKEY(const es256_sk_t *k)
{
@@ -451,3 +464,50 @@ fail:
return (ok);
}
+
+int
+es256_verify_sig(const fido_blob_t *dgst, EVP_PKEY *pkey,
+ const fido_blob_t *sig)
+{
+ EVP_PKEY_CTX *pctx = NULL;
+ int ok = -1;
+
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) {
+ fido_log_debug("%s: EVP_PKEY_base_id", __func__);
+ goto fail;
+ }
+
+ if ((pctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL ||
+ EVP_PKEY_verify_init(pctx) != 1 ||
+ EVP_PKEY_verify(pctx, sig->ptr, sig->len, dgst->ptr,
+ dgst->len) != 1) {
+ fido_log_debug("%s: EVP_PKEY_verify", __func__);
+ goto fail;
+ }
+
+ ok = 0;
+fail:
+ EVP_PKEY_CTX_free(pctx);
+
+ return (ok);
+}
+
+int
+es256_pk_verify_sig(const fido_blob_t *dgst, const es256_pk_t *pk,
+ const fido_blob_t *sig)
+{
+ EVP_PKEY *pkey;
+ int ok = -1;
+
+ if ((pkey = es256_pk_to_EVP_PKEY(pk)) == NULL ||
+ es256_verify_sig(dgst, pkey, sig) < 0) {
+ fido_log_debug("%s: es256_verify_sig", __func__);
+ goto fail;
+ }
+
+ ok = 0;
+fail:
+ EVP_PKEY_free(pkey);
+
+ return (ok);
+}
diff --git a/contrib/libfido2/src/export.gnu b/contrib/libfido2/src/export.gnu
index 40dc7915e6e2..2a8ad24b4c3c 100644
--- a/contrib/libfido2/src/export.gnu
+++ b/contrib/libfido2/src/export.gnu
@@ -7,6 +7,7 @@
eddsa_pk_to_EVP_PKEY;
es256_pk_free;
es256_pk_from_EC_KEY;
+ es256_pk_from_EVP_PKEY;
es256_pk_from_ptr;
es256_pk_new;
es256_pk_to_EVP_PKEY;
@@ -99,6 +100,8 @@
fido_cbor_info_transports_ptr;
fido_cbor_info_versions_len;
fido_cbor_info_versions_ptr;
+ fido_cred_attstmt_len;
+ fido_cred_attstmt_ptr;
fido_cred_authdata_len;
fido_cred_authdata_ptr;
fido_cred_authdata_raw_len;
@@ -138,11 +141,13 @@
fido_credman_rp_new;
fido_credman_set_dev_rk;
fido_cred_new;
+ fido_cred_pin_minlen;
fido_cred_prot;
fido_cred_pubkey_len;
fido_cred_pubkey_ptr;
fido_cred_rp_id;
fido_cred_rp_name;
+ fido_cred_set_attstmt;
fido_cred_set_authdata;
fido_cred_set_authdata_raw;
fido_cred_set_blob;
@@ -152,6 +157,7 @@
fido_cred_set_fmt;
fido_cred_set_id;
fido_cred_set_options;
+ fido_cred_set_pin_minlen;
fido_cred_set_prot;
fido_cred_set_rk;
fido_cred_set_rp;
@@ -208,7 +214,9 @@
fido_dev_set_io_functions;
fido_dev_set_pin;
fido_dev_set_pin_minlen;
+ fido_dev_set_pin_minlen_rpid;
fido_dev_set_sigmask;
+ fido_dev_set_timeout;
fido_dev_set_transport_functions;
fido_dev_supports_cred_prot;
fido_dev_supports_credman;
@@ -226,6 +234,7 @@
fido_strerr;
rs256_pk_free;
rs256_pk_from_ptr;
+ rs256_pk_from_EVP_PKEY;
rs256_pk_from_RSA;
rs256_pk_new;
rs256_pk_to_EVP_PKEY;
diff --git a/contrib/libfido2/src/export.llvm b/contrib/libfido2/src/export.llvm
index 8d3810f92ce9..e163afecedce 100644
--- a/contrib/libfido2/src/export.llvm
+++ b/contrib/libfido2/src/export.llvm
@@ -5,6 +5,7 @@ _eddsa_pk_new
_eddsa_pk_to_EVP_PKEY
_es256_pk_free
_es256_pk_from_EC_KEY
+_es256_pk_from_EVP_PKEY
_es256_pk_from_ptr
_es256_pk_new
_es256_pk_to_EVP_PKEY
@@ -97,6 +98,8 @@ _fido_cbor_info_transports_len
_fido_cbor_info_transports_ptr
_fido_cbor_info_versions_len
_fido_cbor_info_versions_ptr
+_fido_cred_attstmt_len
+_fido_cred_attstmt_ptr
_fido_cred_authdata_len
_fido_cred_authdata_ptr
_fido_cred_authdata_raw_len
@@ -136,11 +139,13 @@ _fido_credman_rp_name
_fido_credman_rp_new
_fido_credman_set_dev_rk
_fido_cred_new
+_fido_cred_pin_minlen
_fido_cred_prot
_fido_cred_pubkey_len
_fido_cred_pubkey_ptr
_fido_cred_rp_id
_fido_cred_rp_name
+_fido_cred_set_attstmt
_fido_cred_set_authdata
_fido_cred_set_authdata_raw
_fido_cred_set_blob
@@ -150,6 +155,7 @@ _fido_cred_set_extensions
_fido_cred_set_fmt
_fido_cred_set_id
_fido_cred_set_options
+_fido_cred_set_pin_minlen
_fido_cred_set_prot
_fido_cred_set_rk
_fido_cred_set_rp
@@ -206,7 +212,9 @@ _fido_dev_reset
_fido_dev_set_io_functions
_fido_dev_set_pin
_fido_dev_set_pin_minlen
+_fido_dev_set_pin_minlen_rpid
_fido_dev_set_sigmask
+_fido_dev_set_timeout
_fido_dev_set_transport_functions
_fido_dev_supports_cred_prot
_fido_dev_supports_credman
@@ -224,6 +232,7 @@ _fido_set_log_handler
_fido_strerr
_rs256_pk_free
_rs256_pk_from_ptr
+_rs256_pk_from_EVP_PKEY
_rs256_pk_from_RSA
_rs256_pk_new
_rs256_pk_to_EVP_PKEY
diff --git a/contrib/libfido2/src/export.msvc b/contrib/libfido2/src/export.msvc
index ca4971dec2d1..9fc24e335e8d 100644
--- a/contrib/libfido2/src/export.msvc
+++ b/contrib/libfido2/src/export.msvc
@@ -6,6 +6,7 @@ eddsa_pk_new
eddsa_pk_to_EVP_PKEY
es256_pk_free
es256_pk_from_EC_KEY
+es256_pk_from_EVP_PKEY
es256_pk_from_ptr
es256_pk_new
es256_pk_to_EVP_PKEY
@@ -98,6 +99,8 @@ fido_cbor_info_transports_len
fido_cbor_info_transports_ptr
fido_cbor_info_versions_len
fido_cbor_info_versions_ptr
+fido_cred_attstmt_len
+fido_cred_attstmt_ptr
fido_cred_authdata_len
fido_cred_authdata_ptr
fido_cred_authdata_raw_len
@@ -137,11 +140,13 @@ fido_credman_rp_name
fido_credman_rp_new
fido_credman_set_dev_rk
fido_cred_new
+fido_cred_pin_minlen
fido_cred_prot
fido_cred_pubkey_len
fido_cred_pubkey_ptr
fido_cred_rp_id
fido_cred_rp_name
+fido_cred_set_attstmt
fido_cred_set_authdata
fido_cred_set_authdata_raw
fido_cred_set_blob
@@ -151,6 +156,7 @@ fido_cred_set_extensions
fido_cred_set_fmt
fido_cred_set_id
fido_cred_set_options
+fido_cred_set_pin_minlen
fido_cred_set_prot
fido_cred_set_rk
fido_cred_set_rp
@@ -207,7 +213,9 @@ fido_dev_reset
fido_dev_set_io_functions
fido_dev_set_pin
fido_dev_set_pin_minlen
+fido_dev_set_pin_minlen_rpid
fido_dev_set_sigmask
+fido_dev_set_timeout
fido_dev_set_transport_functions
fido_dev_supports_cred_prot
fido_dev_supports_credman
@@ -225,6 +233,7 @@ fido_set_log_handler
fido_strerr
rs256_pk_free
rs256_pk_from_ptr
+rs256_pk_from_EVP_PKEY
rs256_pk_from_RSA
rs256_pk_new
rs256_pk_to_EVP_PKEY
diff --git a/contrib/libfido2/src/extern.h b/contrib/libfido2/src/extern.h
index 3be33236f2b1..dc6bddd7b912 100644
--- a/contrib/libfido2/src/extern.h
+++ b/contrib/libfido2/src/extern.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -51,6 +51,7 @@ cbor_item_t *cbor_encode_pubkey(const fido_blob_t *);
cbor_item_t *cbor_encode_pubkey_list(const fido_blob_array_t *);
cbor_item_t *cbor_encode_pubkey_param(int);
cbor_item_t *cbor_encode_rp_entity(const fido_rp_t *);
+cbor_item_t *cbor_encode_str_array(const fido_str_array_t *);
cbor_item_t *cbor_encode_user_entity(const fido_user_t *);
cbor_item_t *es256_pk_encode(const es256_pk_t *, int);
@@ -86,7 +87,7 @@ int cbor_parse_reply(const unsigned char *, size_t, void *,
int(*)(const cbor_item_t *, const cbor_item_t *, void *));
int cbor_add_uv_params(fido_dev_t *, uint8_t, const fido_blob_t *,
const es256_pk_t *, const fido_blob_t *, const char *, const char *,
- cbor_item_t **, cbor_item_t **);
+ cbor_item_t **, cbor_item_t **, int *);
void cbor_vector_free(cbor_item_t **, size_t);
int cbor_array_append(cbor_item_t **, cbor_item_t *);
int cbor_array_drop(cbor_item_t **, size_t);
@@ -130,14 +131,14 @@ int fido_winhello_manifest(fido_dev_info_t *, size_t, size_t *);
int fido_winhello_open(fido_dev_t *);
int fido_winhello_close(fido_dev_t *);
int fido_winhello_cancel(fido_dev_t *);
-int fido_winhello_get_assert(fido_dev_t *, fido_assert_t *, const char *);
+int fido_winhello_get_assert(fido_dev_t *, fido_assert_t *, const char *, int);
int fido_winhello_get_cbor_info(fido_dev_t *, fido_cbor_info_t *);
-int fido_winhello_make_cred(fido_dev_t *, fido_cred_t *, const char *);
+int fido_winhello_make_cred(fido_dev_t *, fido_cred_t *, const char *, int);
/* generic i/o */
-int fido_rx_cbor_status(fido_dev_t *, int);
-int fido_rx(fido_dev_t *, uint8_t, void *, size_t, int);
-int fido_tx(fido_dev_t *, uint8_t, const void *, size_t);
+int fido_rx_cbor_status(fido_dev_t *, int *);
+int fido_rx(fido_dev_t *, uint8_t, void *, size_t, int *);
+int fido_tx(fido_dev_t *, uint8_t, const void *, size_t, int *);
/* log */
#ifdef FIDO_NO_DIAGNOSTIC
@@ -163,21 +164,30 @@ void fido_log_error(int, const char *, ...);
#endif /* FIDO_NO_DIAGNOSTIC */
/* u2f */
-int u2f_register(fido_dev_t *, fido_cred_t *, int);
-int u2f_authenticate(fido_dev_t *, fido_assert_t *, int);
-int u2f_get_touch_begin(fido_dev_t *);
-int u2f_get_touch_status(fido_dev_t *, int *, int);
+int u2f_register(fido_dev_t *, fido_cred_t *, int *);
+int u2f_authenticate(fido_dev_t *, fido_assert_t *, int *);
+int u2f_get_touch_begin(fido_dev_t *, int *);
+int u2f_get_touch_status(fido_dev_t *, int *, int *);
/* unexposed fido ops */
uint8_t fido_dev_get_pin_protocol(const fido_dev_t *);
-int fido_dev_authkey(fido_dev_t *, es256_pk_t *);
-int fido_dev_get_cbor_info_wait(fido_dev_t *, fido_cbor_info_t *, int);
+int fido_dev_authkey(fido_dev_t *, es256_pk_t *, int *);
+int fido_dev_get_cbor_info_wait(fido_dev_t *, fido_cbor_info_t *, int *);
int fido_dev_get_uv_token(fido_dev_t *, uint8_t, const char *,
- const fido_blob_t *, const es256_pk_t *, const char *, fido_blob_t *);
+ const fido_blob_t *, const es256_pk_t *, const char *, fido_blob_t *,
+ int *);
uint64_t fido_dev_maxmsgsize(const fido_dev_t *);
-int fido_do_ecdh(fido_dev_t *, es256_pk_t **, fido_blob_t **);
+int fido_do_ecdh(fido_dev_t *, es256_pk_t **, fido_blob_t **, int *);
bool fido_dev_supports_permissions(const fido_dev_t *);
+/* types */
+void fido_algo_array_free(fido_algo_array_t *);
+void fido_byte_array_free(fido_byte_array_t *);
+void fido_opt_array_free(fido_opt_array_t *);
+void fido_str_array_free(fido_str_array_t *);
+void fido_algo_free(fido_algo_t *);
+int fido_str_array_pack(fido_str_array_t *, const char * const *, size_t);
+
/* misc */
void fido_assert_reset_rx(fido_assert_t *);
void fido_assert_reset_tx(fido_assert_t *);
@@ -189,16 +199,24 @@ int fido_check_flags(uint8_t, fido_opt_t, fido_opt_t);
int fido_check_rp_id(const char *, const unsigned char *);
int fido_get_random(void *, size_t);
int fido_sha256(fido_blob_t *, const u_char *, size_t);
+int fido_time_now(struct timespec *);
+int fido_time_delta(const struct timespec *, int *);
/* crypto */
-int fido_verify_sig_es256(const fido_blob_t *, const es256_pk_t *,
+int es256_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *);
+int rs256_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *);
+int eddsa_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *);
+int rs1_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *);
+int es256_pk_verify_sig(const fido_blob_t *, const es256_pk_t *,
const fido_blob_t *);
-int fido_verify_sig_rs256(const fido_blob_t *, const rs256_pk_t *,
+int rs256_pk_verify_sig(const fido_blob_t *, const rs256_pk_t *,
const fido_blob_t *);
-int fido_verify_sig_eddsa(const fido_blob_t *, const eddsa_pk_t *,
+int eddsa_pk_verify_sig(const fido_blob_t *, const eddsa_pk_t *,
const fido_blob_t *);
int fido_get_signed_hash(int, fido_blob_t *, const fido_blob_t *,
const fido_blob_t *);
+int fido_get_signed_hash_tpm(fido_blob_t *, const fido_blob_t *,
+ const fido_blob_t *, const fido_attstmt_t *, const fido_attcred_t *);
/* device manifest functions */
int fido_hid_manifest(fido_dev_info_t *, size_t, size_t *);
@@ -232,6 +250,7 @@ uint32_t uniform_random(uint32_t);
#define FIDO_DUMMY_USER_NAME "dummy"
#define FIDO_DUMMY_USER_ID 1
#define FIDO_WINHELLO_PATH "windows://hello"
+#define FIDO_NFC_PREFIX "nfc:"
#ifdef __cplusplus
} /* extern "C" */
diff --git a/contrib/libfido2/src/fido.h b/contrib/libfido2/src/fido.h
index d5446516f972..51bdb526d3f0 100644
--- a/contrib/libfido2/src/fido.h
+++ b/contrib/libfido2/src/fido.h
@@ -86,16 +86,17 @@ const char *fido_dev_info_product_string(const fido_dev_info_t *);
const fido_dev_info_t *fido_dev_info_ptr(const fido_dev_info_t *, size_t);
const uint8_t *fido_cbor_info_protocols_ptr(const fido_cbor_info_t *);
const unsigned char *fido_cbor_info_aaguid_ptr(const fido_cbor_info_t *);
+const unsigned char *fido_cred_aaguid_ptr(const fido_cred_t *);
+const unsigned char *fido_cred_attstmt_ptr(const fido_cred_t *);
const unsigned char *fido_cred_authdata_ptr(const fido_cred_t *);
const unsigned char *fido_cred_authdata_raw_ptr(const fido_cred_t *);
const unsigned char *fido_cred_clientdata_hash_ptr(const fido_cred_t *);
const unsigned char *fido_cred_id_ptr(const fido_cred_t *);
-const unsigned char *fido_cred_aaguid_ptr(const fido_cred_t *);
-const unsigned char *fido_cred_user_id_ptr(const fido_cred_t *);
+const unsigned char *fido_cred_largeblob_key_ptr(const fido_cred_t *);
const unsigned char *fido_cred_pubkey_ptr(const fido_cred_t *);
const unsigned char *fido_cred_sig_ptr(const fido_cred_t *);
+const unsigned char *fido_cred_user_id_ptr(const fido_cred_t *);
const unsigned char *fido_cred_x5c_ptr(const fido_cred_t *);
-const unsigned char *fido_cred_largeblob_key_ptr(const fido_cred_t *);
int fido_assert_allow_cred(fido_assert_t *, const unsigned char *, size_t);
int fido_assert_set_authdata(fido_assert_t *, size_t, const unsigned char *,
@@ -119,6 +120,7 @@ int fido_assert_verify(const fido_assert_t *, size_t, int, const void *);
int fido_cbor_info_algorithm_cose(const fido_cbor_info_t *, size_t);
int fido_cred_exclude(fido_cred_t *, const unsigned char *, size_t);
int fido_cred_prot(const fido_cred_t *);
+int fido_cred_set_attstmt(fido_cred_t *, const unsigned char *, size_t);
int fido_cred_set_authdata(fido_cred_t *, const unsigned char *, size_t);
int fido_cred_set_authdata_raw(fido_cred_t *, const unsigned char *, size_t);
int fido_cred_set_blob(fido_cred_t *, const unsigned char *, size_t);
@@ -128,6 +130,7 @@ int fido_cred_set_extensions(fido_cred_t *, int);
int fido_cred_set_fmt(fido_cred_t *, const char *);
int fido_cred_set_id(fido_cred_t *, const unsigned char *, size_t);
int fido_cred_set_options(fido_cred_t *, bool, bool);
+int fido_cred_set_pin_minlen(fido_cred_t *, size_t);
int fido_cred_set_prot(fido_cred_t *, int);
int fido_cred_set_rk(fido_cred_t *, fido_opt_t);
int fido_cred_set_rp(fido_cred_t *, const char *, const char *);
@@ -157,6 +160,7 @@ int fido_dev_reset(fido_dev_t *);
int fido_dev_set_io_functions(fido_dev_t *, const fido_dev_io_t *);
int fido_dev_set_pin(fido_dev_t *, const char *, const char *);
int fido_dev_set_transport_functions(fido_dev_t *, const fido_dev_transport_t *);
+int fido_dev_set_timeout(fido_dev_t *, int);
size_t fido_assert_authdata_len(const fido_assert_t *, size_t);
size_t fido_assert_clientdata_hash_len(const fido_assert_t *);
@@ -174,16 +178,18 @@ size_t fido_cbor_info_options_len(const fido_cbor_info_t *);
size_t fido_cbor_info_protocols_len(const fido_cbor_info_t *);
size_t fido_cbor_info_transports_len(const fido_cbor_info_t *);
size_t fido_cbor_info_versions_len(const fido_cbor_info_t *);
+size_t fido_cred_aaguid_len(const fido_cred_t *);
+size_t fido_cred_attstmt_len(const fido_cred_t *);
size_t fido_cred_authdata_len(const fido_cred_t *);
size_t fido_cred_authdata_raw_len(const fido_cred_t *);
size_t fido_cred_clientdata_hash_len(const fido_cred_t *);
size_t fido_cred_id_len(const fido_cred_t *);
-size_t fido_cred_aaguid_len(const fido_cred_t *);
-size_t fido_cred_user_id_len(const fido_cred_t *);
+size_t fido_cred_largeblob_key_len(const fido_cred_t *);
+size_t fido_cred_pin_minlen(const fido_cred_t *);
size_t fido_cred_pubkey_len(const fido_cred_t *);
size_t fido_cred_sig_len(const fido_cred_t *);
+size_t fido_cred_user_id_len(const fido_cred_t *);
size_t fido_cred_x5c_len(const fido_cred_t *);
-size_t fido_cred_largeblob_key_len(const fido_cred_t *);
uint8_t fido_assert_flags(const fido_assert_t *, size_t);
uint32_t fido_assert_sigcount(const fido_assert_t *, size_t);
diff --git a/contrib/libfido2/src/fido/config.h b/contrib/libfido2/src/fido/config.h
index 869927df914b..d8134a3c7b6c 100644
--- a/contrib/libfido2/src/fido/config.h
+++ b/contrib/libfido2/src/fido/config.h
@@ -26,6 +26,8 @@ int fido_dev_enable_entattest(fido_dev_t *, const char *);
int fido_dev_force_pin_change(fido_dev_t *, const char *);
int fido_dev_toggle_always_uv(fido_dev_t *, const char *);
int fido_dev_set_pin_minlen(fido_dev_t *, size_t, const char *);
+int fido_dev_set_pin_minlen_rpid(fido_dev_t *, const char * const *, size_t,
+ const char *);
#ifdef __cplusplus
} /* extern "C" */
diff --git a/contrib/libfido2/src/fido/eddsa.h b/contrib/libfido2/src/fido/eddsa.h
index 4a810179b6fa..083721cc3d3f 100644
--- a/contrib/libfido2/src/fido/eddsa.h
+++ b/contrib/libfido2/src/fido/eddsa.h
@@ -31,19 +31,14 @@ int eddsa_pk_from_ptr(eddsa_pk_t *, const void *, size_t);
#ifdef _FIDO_INTERNAL
-#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10101000L
+#if defined(LIBRESSL_VERSION_NUMBER)
#define EVP_PKEY_ED25519 EVP_PKEY_NONE
int EVP_PKEY_get_raw_public_key(const EVP_PKEY *, unsigned char *, size_t *);
EVP_PKEY *EVP_PKEY_new_raw_public_key(int, ENGINE *, const unsigned char *,
size_t);
int EVP_DigestVerify(EVP_MD_CTX *, const unsigned char *, size_t,
const unsigned char *, size_t);
-#endif /* LIBRESSL_VERSION_NUMBER || OPENSSL_VERSION_NUMBER < 0x10101000L */
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-EVP_MD_CTX *EVP_MD_CTX_new(void);
-void EVP_MD_CTX_free(EVP_MD_CTX *);
-#endif
+#endif /* LIBRESSL_VERSION_NUMBER */
#endif /* _FIDO_INTERNAL */
diff --git a/contrib/libfido2/src/fido/es256.h b/contrib/libfido2/src/fido/es256.h
index 80f4db39c7b0..683494dadfe2 100644
--- a/contrib/libfido2/src/fido/es256.h
+++ b/contrib/libfido2/src/fido/es256.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -27,6 +27,7 @@ void es256_pk_free(es256_pk_t **);
EVP_PKEY *es256_pk_to_EVP_PKEY(const es256_pk_t *);
int es256_pk_from_EC_KEY(es256_pk_t *, const EC_KEY *);
+int es256_pk_from_EVP_PKEY(es256_pk_t *, const EVP_PKEY *);
int es256_pk_from_ptr(es256_pk_t *, const void *, size_t);
#ifdef _FIDO_INTERNAL
diff --git a/contrib/libfido2/src/fido/param.h b/contrib/libfido2/src/fido/param.h
index 025bb57dd81c..7c6db98cfd5d 100644
--- a/contrib/libfido2/src/fido/param.h
+++ b/contrib/libfido2/src/fido/param.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -82,10 +82,12 @@
#define FIDO_CAP_NMSG 0x08 /* if set, device doesn't support CTAP_CMD_MSG */
/* Supported COSE algorithms. */
+#define COSE_UNSPEC 0
#define COSE_ES256 -7
#define COSE_EDDSA -8
#define COSE_ECDH_ES256 -25
#define COSE_RS256 -257
+#define COSE_RS1 -65535
/* Supported COSE types. */
#define COSE_KTY_OKP 1
@@ -101,6 +103,7 @@
#define FIDO_EXT_CRED_PROTECT 0x02
#define FIDO_EXT_LARGEBLOB_KEY 0x04
#define FIDO_EXT_CRED_BLOB 0x08
+#define FIDO_EXT_MINPINLEN 0x10
/* Supported credential protection policies. */
#define FIDO_CRED_PROT_UV_OPTIONAL 0x01
@@ -111,7 +114,8 @@
#define FIDO_EXT_ASSERT_MASK (FIDO_EXT_HMAC_SECRET|FIDO_EXT_LARGEBLOB_KEY| \
FIDO_EXT_CRED_BLOB)
#define FIDO_EXT_CRED_MASK (FIDO_EXT_HMAC_SECRET|FIDO_EXT_CRED_PROTECT| \
- FIDO_EXT_LARGEBLOB_KEY|FIDO_EXT_CRED_BLOB)
+ FIDO_EXT_LARGEBLOB_KEY|FIDO_EXT_CRED_BLOB| \
+ FIDO_EXT_MINPINLEN)
#endif /* _FIDO_INTERNAL */
#endif /* !_FIDO_PARAM_H */
diff --git a/contrib/libfido2/src/fido/rs256.h b/contrib/libfido2/src/fido/rs256.h
index 2b08d59980c1..039816191783 100644
--- a/contrib/libfido2/src/fido/rs256.h
+++ b/contrib/libfido2/src/fido/rs256.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -26,6 +26,7 @@ rs256_pk_t *rs256_pk_new(void);
void rs256_pk_free(rs256_pk_t **);
EVP_PKEY *rs256_pk_to_EVP_PKEY(const rs256_pk_t *);
+int rs256_pk_from_EVP_PKEY(rs256_pk_t *, const EVP_PKEY *);
int rs256_pk_from_RSA(rs256_pk_t *, const RSA *);
int rs256_pk_from_ptr(rs256_pk_t *, const void *, size_t);
diff --git a/contrib/libfido2/src/fido/types.h b/contrib/libfido2/src/fido/types.h
index 00b6058c7e13..92f55d979fdc 100644
--- a/contrib/libfido2/src/fido/types.h
+++ b/contrib/libfido2/src/fido/types.h
@@ -107,8 +107,12 @@ typedef struct fido_attcred {
} fido_attcred_t;
typedef struct fido_attstmt {
- fido_blob_t x5c; /* attestation certificate */
- fido_blob_t sig; /* attestation signature */
+ fido_blob_t certinfo; /* tpm attestation TPMS_ATTEST structure */
+ fido_blob_t pubarea; /* tpm attestation TPMT_PUBLIC structure */
+ fido_blob_t cbor; /* cbor-encoded attestation statement */
+ fido_blob_t x5c; /* attestation certificate */
+ fido_blob_t sig; /* attestation signature */
+ int alg; /* attestation algorithm (cose) */
} fido_attstmt_t;
typedef struct fido_rp {
@@ -124,8 +128,9 @@ typedef struct fido_user {
} fido_user_t;
typedef struct fido_cred_ext {
- int mask; /* enabled extensions */
- int prot; /* protection policy */
+ int mask; /* enabled extensions */
+ int prot; /* protection policy */
+ size_t minpinlen; /* minimum pin length */
} fido_cred_ext_t;
typedef struct fido_cred {
@@ -260,6 +265,7 @@ typedef struct fido_dev {
int flags; /* internal flags; see FIDO_DEV_* */
fido_dev_transport_t transport; /* transport functions */
uint64_t maxmsgsize; /* max message size */
+ int timeout_ms; /* read timeout in ms */
} fido_dev_t;
#else
diff --git a/contrib/libfido2/src/hid_freebsd.c b/contrib/libfido2/src/hid_freebsd.c
index 86c1854e9c8c..5aefe69c1bec 100644
--- a/contrib/libfido2/src/hid_freebsd.c
+++ b/contrib/libfido2/src/hid_freebsd.c
@@ -14,6 +14,12 @@
#include "fido.h"
+#if defined(__MidnightBSD__)
+#define UHID_VENDOR "MidnightBSD"
+#else
+#define UHID_VENDOR "FreeBSD"
+#endif
+
#define MAX_UHID 64
struct hid_freebsd {
@@ -66,7 +72,7 @@ copy_info(fido_dev_info_t *di, const char *path)
if (ioctl(fd, IOCTL_REQ(USB_GET_DEVICEINFO), &udi) == -1) {
fido_log_error(errno, "%s: ioctl", __func__);
- strlcpy(udi.udi_vendor, "FreeBSD", sizeof(udi.udi_vendor));
+ strlcpy(udi.udi_vendor, UHID_VENDOR, sizeof(udi.udi_vendor));
strlcpy(udi.udi_product, "uhid(4)", sizeof(udi.udi_product));
udi.udi_vendorNo = 0x0b5d; /* stolen from PCI_VENDOR_OPENBSD */
}
diff --git a/contrib/libfido2/src/hid_linux.c b/contrib/libfido2/src/hid_linux.c
index c622880a2594..c4ce4fd578a6 100644
--- a/contrib/libfido2/src/hid_linux.c
+++ b/contrib/libfido2/src/hid_linux.c
@@ -160,9 +160,9 @@ copy_info(fido_dev_info_t *di, struct udev *udev,
di->path = strdup(path);
if ((di->manufacturer = get_usb_attr(dev, "manufacturer")) == NULL)
- di->manufacturer = strdup("unknown");
+ di->manufacturer = strdup("");
if ((di->product = get_usb_attr(dev, "product")) == NULL)
- di->product = strdup("unknown");
+ di->product = strdup("");
if (di->path == NULL || di->manufacturer == NULL || di->product == NULL)
goto fail;
diff --git a/contrib/libfido2/src/hid_openbsd.c b/contrib/libfido2/src/hid_openbsd.c
index fbf10fd11ab9..d3d3bff0fc8b 100644
--- a/contrib/libfido2/src/hid_openbsd.c
+++ b/contrib/libfido2/src/hid_openbsd.c
@@ -23,6 +23,8 @@ struct hid_openbsd {
int fd;
size_t report_in_len;
size_t report_out_len;
+ sigset_t sigmask;
+ const sigset_t *sigmaskp;
};
int
@@ -185,10 +187,12 @@ fido_hid_close(void *handle)
int
fido_hid_set_sigmask(void *handle, const fido_sigset_t *sigmask)
{
- (void)handle;
- (void)sigmask;
+ struct hid_openbsd *ctx = handle;
+
+ ctx->sigmask = *sigmask;
+ ctx->sigmaskp = &ctx->sigmask;
- return (FIDO_ERR_INTERNAL);
+ return (FIDO_OK);
}
int
@@ -197,14 +201,17 @@ fido_hid_read(void *handle, unsigned char *buf, size_t len, int ms)
struct hid_openbsd *ctx = (struct hid_openbsd *)handle;
ssize_t r;
- (void)ms; /* XXX */
-
if (len != ctx->report_in_len) {
fido_log_debug("%s: invalid len: got %zu, want %zu", __func__,
len, ctx->report_in_len);
return (-1);
}
+ if (fido_hid_unix_wait(ctx->fd, ms, ctx->sigmaskp) < 0) {
+ fido_log_debug("%s: fd not ready", __func__);
+ return (-1);
+ }
+
if ((r = read(ctx->fd, buf, len)) == -1) {
fido_log_error(errno, "%s: read", __func__);
return (-1);
diff --git a/contrib/libfido2/src/hid_osx.c b/contrib/libfido2/src/hid_osx.c
index e9866658a4eb..1f8b37a65597 100644
--- a/contrib/libfido2/src/hid_osx.c
+++ b/contrib/libfido2/src/hid_osx.c
@@ -11,6 +11,7 @@
#include <signal.h>
#include <unistd.h>
+#include <Availability.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/hid/IOHIDKeys.h>
@@ -18,6 +19,10 @@
#include "fido.h"
+#if __MAC_OS_X_VERSION_MIN_REQUIRED < 120000
+#define kIOMainPortDefault kIOMasterPortDefault
+#endif
+
struct hid_osx {
IOHIDDeviceRef ref;
CFStringRef loop_id;
@@ -131,23 +136,18 @@ get_str(IOHIDDeviceRef dev, char **manufacturer, char **product)
*manufacturer = NULL;
*product = NULL;
- if (get_utf8(dev, CFSTR(kIOHIDManufacturerKey), buf, sizeof(buf)) < 0) {
- fido_log_debug("%s: get_utf8 manufacturer", __func__);
- goto fail;
- }
-
- if ((*manufacturer = strdup(buf)) == NULL) {
- fido_log_debug("%s: strdup manufacturer", __func__);
- goto fail;
- }
+ if (get_utf8(dev, CFSTR(kIOHIDManufacturerKey), buf, sizeof(buf)) < 0)
+ *manufacturer = strdup("");
+ else
+ *manufacturer = strdup(buf);
- if (get_utf8(dev, CFSTR(kIOHIDProductKey), buf, sizeof(buf)) < 0) {
- fido_log_debug("%s: get_utf8 product", __func__);
- goto fail;
- }
+ if (get_utf8(dev, CFSTR(kIOHIDProductKey), buf, sizeof(buf)) < 0)
+ *product = strdup("");
+ else
+ *product = strdup(buf);
- if ((*product = strdup(buf)) == NULL) {
- fido_log_debug("%s: strdup product", __func__);
+ if (*manufacturer == NULL || *product == NULL) {
+ fido_log_debug("%s: strdup", __func__);
goto fail;
}
@@ -398,7 +398,7 @@ fido_hid_open(const char *path)
goto fail;
}
- if ((entry = IORegistryEntryFromPath(kIOMasterPortDefault,
+ if ((entry = IORegistryEntryFromPath(kIOMainPortDefault,
path)) == MACH_PORT_NULL) {
fido_log_debug("%s: IORegistryEntryFromPath", __func__);
goto fail;
diff --git a/contrib/libfido2/src/hid_unix.c b/contrib/libfido2/src/hid_unix.c
index 4b2aff9d67f6..946b2dc3b65f 100644
--- a/contrib/libfido2/src/hid_unix.c
+++ b/contrib/libfido2/src/hid_unix.c
@@ -58,8 +58,7 @@ fido_hid_unix_wait(int fd, int ms, const fido_sigset_t *sigmask)
pfd.fd = fd;
#ifdef FIDO_FUZZ
- if (ms < 0)
- return (0);
+ return (0);
#endif
if (ms > -1) {
ts.tv_sec = ms / 1000;
diff --git a/contrib/libfido2/src/hid_win.c b/contrib/libfido2/src/hid_win.c
index 455cf8bae835..c29ef70253d7 100644
--- a/contrib/libfido2/src/hid_win.c
+++ b/contrib/libfido2/src/hid_win.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019 Yubico AB. All rights reserved.
+ * Copyright (c) 2019-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -103,7 +103,7 @@ fail:
}
static int
-get_int(HANDLE dev, int16_t *vendor_id, int16_t *product_id)
+get_id(HANDLE dev, int16_t *vendor_id, int16_t *product_id)
{
HIDD_ATTRIBUTES attr;
@@ -121,14 +121,13 @@ get_int(HANDLE dev, int16_t *vendor_id, int16_t *product_id)
}
static int
-get_str(HANDLE dev, char **manufacturer, char **product)
+get_manufacturer(HANDLE dev, char **manufacturer)
{
wchar_t buf[512];
int utf8_len;
int ok = -1;
*manufacturer = NULL;
- *product = NULL;
if (HidD_GetManufacturerString(dev, &buf, sizeof(buf)) == false) {
fido_log_debug("%s: HidD_GetManufacturerString", __func__);
@@ -152,6 +151,25 @@ get_str(HANDLE dev, char **manufacturer, char **product)
goto fail;
}
+ ok = 0;
+fail:
+ if (ok < 0) {
+ free(*manufacturer);
+ *manufacturer = NULL;
+ }
+
+ return (ok);
+}
+
+static int
+get_product(HANDLE dev, char **product)
+{
+ wchar_t buf[512];
+ int utf8_len;
+ int ok = -1;
+
+ *product = NULL;
+
if (HidD_GetProductString(dev, &buf, sizeof(buf)) == false) {
fido_log_debug("%s: HidD_GetProductString", __func__);
goto fail;
@@ -177,9 +195,7 @@ get_str(HANDLE dev, char **manufacturer, char **product)
ok = 0;
fail:
if (ok < 0) {
- free(*manufacturer);
free(*product);
- *manufacturer = NULL;
*product = NULL;
}
@@ -313,9 +329,23 @@ copy_info(fido_dev_info_t *di, HDEVINFO devinfo, DWORD idx,
goto fail;
}
- if (get_int(dev, &di->vendor_id, &di->product_id) < 0 ||
- get_str(dev, &di->manufacturer, &di->product) < 0) {
- fido_log_debug("%s: get_int/get_str", __func__);
+ if (get_id(dev, &di->vendor_id, &di->product_id) < 0) {
+ fido_log_debug("%s: get_id", __func__);
+ goto fail;
+ }
+
+ if (get_manufacturer(dev, &di->manufacturer) < 0) {
+ fido_log_debug("%s: get_manufacturer", __func__);
+ di->manufacturer = strdup("");
+ }
+
+ if (get_product(dev, &di->product) < 0) {
+ fido_log_debug("%s: get_product", __func__);
+ di->product = strdup("");
+ }
+
+ if (di->manufacturer == NULL || di->product == NULL) {
+ fido_log_debug("%s: manufacturer/product", __func__);
goto fail;
}
diff --git a/contrib/libfido2/src/info.c b/contrib/libfido2/src/info.c
index 57bc8de44063..167a1d30ecaa 100644
--- a/contrib/libfido2/src/info.c
+++ b/contrib/libfido2/src/info.c
@@ -186,14 +186,6 @@ out:
return (ok);
}
-static void
-free_algo(fido_algo_t *a)
-{
- free(a->type);
- a->type = NULL;
- a->cose = 0;
-}
-
static int
decode_algorithm(const cbor_item_t *item, void *arg)
{
@@ -210,7 +202,7 @@ decode_algorithm(const cbor_item_t *item, void *arg)
if (cbor_map_iter(item, &aa->ptr[i], decode_algorithm_entry) < 0) {
fido_log_debug("%s: decode_algorithm_entry", __func__);
- free_algo(&aa->ptr[i]);
+ fido_algo_free(&aa->ptr[i]);
return (-1);
}
@@ -287,13 +279,13 @@ parse_reply_element(const cbor_item_t *key, const cbor_item_t *val, void *arg)
}
static int
-fido_dev_get_cbor_info_tx(fido_dev_t *dev)
+fido_dev_get_cbor_info_tx(fido_dev_t *dev, int *ms)
{
const unsigned char cbor[] = { CTAP_CBOR_GETINFO };
fido_log_debug("%s: dev=%p", __func__, (void *)dev);
- if (fido_tx(dev, CTAP_CMD_CBOR, cbor, sizeof(cbor)) < 0) {
+ if (fido_tx(dev, CTAP_CMD_CBOR, cbor, sizeof(cbor), ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
return (FIDO_ERR_TX);
}
@@ -302,13 +294,13 @@ fido_dev_get_cbor_info_tx(fido_dev_t *dev)
}
static int
-fido_dev_get_cbor_info_rx(fido_dev_t *dev, fido_cbor_info_t *ci, int ms)
+fido_dev_get_cbor_info_rx(fido_dev_t *dev, fido_cbor_info_t *ci, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
fido_log_debug("%s: dev=%p, ci=%p, ms=%d", __func__, (void *)dev,
- (void *)ci, ms);
+ (void *)ci, *ms);
fido_cbor_info_reset(ci);
@@ -323,7 +315,7 @@ fido_dev_get_cbor_info_rx(fido_dev_t *dev, fido_cbor_info_t *ci, int ms)
}
int
-fido_dev_get_cbor_info_wait(fido_dev_t *dev, fido_cbor_info_t *ci, int ms)
+fido_dev_get_cbor_info_wait(fido_dev_t *dev, fido_cbor_info_t *ci, int *ms)
{
int r;
@@ -331,7 +323,7 @@ fido_dev_get_cbor_info_wait(fido_dev_t *dev, fido_cbor_info_t *ci, int ms)
if (dev->flags & FIDO_DEV_WINHELLO)
return (fido_winhello_get_cbor_info(dev, ci));
#endif
- if ((r = fido_dev_get_cbor_info_tx(dev)) != FIDO_OK ||
+ if ((r = fido_dev_get_cbor_info_tx(dev, ms)) != FIDO_OK ||
(r = fido_dev_get_cbor_info_rx(dev, ci, ms)) != FIDO_OK)
return (r);
@@ -341,7 +333,9 @@ fido_dev_get_cbor_info_wait(fido_dev_t *dev, fido_cbor_info_t *ci, int ms)
int
fido_dev_get_cbor_info(fido_dev_t *dev, fido_cbor_info_t *ci)
{
- return (fido_dev_get_cbor_info_wait(dev, ci, -1));
+ int ms = dev->timeout_ms;
+
+ return (fido_dev_get_cbor_info_wait(dev, ci, &ms));
}
/*
@@ -354,58 +348,15 @@ fido_cbor_info_new(void)
return (calloc(1, sizeof(fido_cbor_info_t)));
}
-static void
-free_str_array(fido_str_array_t *sa)
-{
- for (size_t i = 0; i < sa->len; i++)
- free(sa->ptr[i]);
-
- free(sa->ptr);
- sa->ptr = NULL;
- sa->len = 0;
-}
-
-static void
-free_opt_array(fido_opt_array_t *oa)
-{
- for (size_t i = 0; i < oa->len; i++)
- free(oa->name[i]);
-
- free(oa->name);
- free(oa->value);
- oa->name = NULL;
- oa->value = NULL;
-}
-
-static void
-free_byte_array(fido_byte_array_t *ba)
-{
- free(ba->ptr);
-
- ba->ptr = NULL;
- ba->len = 0;
-}
-
-static void
-free_algo_array(fido_algo_array_t *aa)
-{
- for (size_t i = 0; i < aa->len; i++)
- free_algo(&aa->ptr[i]);
-
- free(aa->ptr);
- aa->ptr = NULL;
- aa->len = 0;
-}
-
void
fido_cbor_info_reset(fido_cbor_info_t *ci)
{
- free_str_array(&ci->versions);
- free_str_array(&ci->extensions);
- free_str_array(&ci->transports);
- free_opt_array(&ci->options);
- free_byte_array(&ci->protocols);
- free_algo_array(&ci->algorithms);
+ fido_str_array_free(&ci->versions);
+ fido_str_array_free(&ci->extensions);
+ fido_str_array_free(&ci->transports);
+ fido_opt_array_free(&ci->options);
+ fido_byte_array_free(&ci->protocols);
+ fido_algo_array_free(&ci->algorithms);
}
void
diff --git a/contrib/libfido2/src/io.c b/contrib/libfido2/src/io.c
index e2594203efb0..70f777fb49a0 100644
--- a/contrib/libfido2/src/io.c
+++ b/contrib/libfido2/src/io.c
@@ -30,7 +30,24 @@ struct frame {
#endif
static int
-tx_empty(fido_dev_t *d, uint8_t cmd)
+tx_pkt(fido_dev_t *d, const void *pkt, size_t len, int *ms)
+{
+ struct timespec ts;
+ int n;
+
+ if (fido_time_now(&ts) != 0)
+ return (-1);
+
+ n = d->io.write(d->io_handle, pkt, len);
+
+ if (fido_time_delta(&ts, ms) != 0)
+ return (-1);
+
+ return (n);
+}
+
+static int
+tx_empty(fido_dev_t *d, uint8_t cmd, int *ms)
{
struct frame *fp;
unsigned char pkt[sizeof(*fp) + 1];
@@ -42,15 +59,15 @@ tx_empty(fido_dev_t *d, uint8_t cmd)
fp->cid = d->cid;
fp->body.init.cmd = CTAP_FRAME_INIT | cmd;
- if (len > sizeof(pkt) || (n = d->io.write(d->io_handle, pkt,
- len)) < 0 || (size_t)n != len)
+ if (len > sizeof(pkt) || (n = tx_pkt(d, pkt, len, ms)) < 0 ||
+ (size_t)n != len)
return (-1);
return (0);
}
static size_t
-tx_preamble(fido_dev_t *d, uint8_t cmd, const void *buf, size_t count)
+tx_preamble(fido_dev_t *d, uint8_t cmd, const void *buf, size_t count, int *ms)
{
struct frame *fp;
unsigned char pkt[sizeof(*fp) + 1];
@@ -69,15 +86,15 @@ tx_preamble(fido_dev_t *d, uint8_t cmd, const void *buf, size_t count)
count = MIN(count, d->tx_len - CTAP_INIT_HEADER_LEN);
memcpy(&fp->body.init.data, buf, count);
- if (len > sizeof(pkt) || (n = d->io.write(d->io_handle, pkt,
- len)) < 0 || (size_t)n != len)
+ if (len > sizeof(pkt) || (n = tx_pkt(d, pkt, len, ms)) < 0 ||
+ (size_t)n != len)
return (0);
return (count);
}
static size_t
-tx_frame(fido_dev_t *d, uint8_t seq, const void *buf, size_t count)
+tx_frame(fido_dev_t *d, uint8_t seq, const void *buf, size_t count, int *ms)
{
struct frame *fp;
unsigned char pkt[sizeof(*fp) + 1];
@@ -94,19 +111,19 @@ tx_frame(fido_dev_t *d, uint8_t seq, const void *buf, size_t count)
count = MIN(count, d->tx_len - CTAP_CONT_HEADER_LEN);
memcpy(&fp->body.cont.data, buf, count);
- if (len > sizeof(pkt) || (n = d->io.write(d->io_handle, pkt,
- len)) < 0 || (size_t)n != len)
+ if (len > sizeof(pkt) || (n = tx_pkt(d, pkt, len, ms)) < 0 ||
+ (size_t)n != len)
return (0);
return (count);
}
static int
-tx(fido_dev_t *d, uint8_t cmd, const unsigned char *buf, size_t count)
+tx(fido_dev_t *d, uint8_t cmd, const unsigned char *buf, size_t count, int *ms)
{
size_t n, sent;
- if ((sent = tx_preamble(d, cmd, buf, count)) == 0) {
+ if ((sent = tx_preamble(d, cmd, buf, count, ms)) == 0) {
fido_log_debug("%s: tx_preamble", __func__);
return (-1);
}
@@ -116,7 +133,8 @@ tx(fido_dev_t *d, uint8_t cmd, const unsigned char *buf, size_t count)
fido_log_debug("%s: seq & 0x80", __func__);
return (-1);
}
- if ((n = tx_frame(d, seq++, buf + sent, count - sent)) == 0) {
+ if ((n = tx_frame(d, seq++, buf + sent, count - sent,
+ ms)) == 0) {
fido_log_debug("%s: tx_frame", __func__);
return (-1);
}
@@ -125,38 +143,59 @@ tx(fido_dev_t *d, uint8_t cmd, const unsigned char *buf, size_t count)
return (0);
}
+static int
+transport_tx(fido_dev_t *d, uint8_t cmd, const void *buf, size_t count, int *ms)
+{
+ struct timespec ts;
+ int n;
+
+ if (fido_time_now(&ts) != 0)
+ return (-1);
+
+ n = d->transport.tx(d, cmd, buf, count);
+
+ if (fido_time_delta(&ts, ms) != 0)
+ return (-1);
+
+ return (n);
+}
+
int
-fido_tx(fido_dev_t *d, uint8_t cmd, const void *buf, size_t count)
+fido_tx(fido_dev_t *d, uint8_t cmd, const void *buf, size_t count, int *ms)
{
fido_log_debug("%s: dev=%p, cmd=0x%02x", __func__, (void *)d, cmd);
fido_log_xxd(buf, count, "%s", __func__);
if (d->transport.tx != NULL)
- return (d->transport.tx(d, cmd, buf, count));
+ return (transport_tx(d, cmd, buf, count, ms));
if (d->io_handle == NULL || d->io.write == NULL || count > UINT16_MAX) {
fido_log_debug("%s: invalid argument", __func__);
return (-1);
}
- return (count == 0 ? tx_empty(d, cmd) : tx(d, cmd, buf, count));
+ return (count == 0 ? tx_empty(d, cmd, ms) : tx(d, cmd, buf, count, ms));
}
static int
-rx_frame(fido_dev_t *d, struct frame *fp, int ms)
+rx_frame(fido_dev_t *d, struct frame *fp, int *ms)
{
+ struct timespec ts;
int n;
memset(fp, 0, sizeof(*fp));
+ if (fido_time_now(&ts) != 0)
+ return (-1);
+
if (d->rx_len > sizeof(*fp) || (n = d->io.read(d->io_handle,
- (unsigned char *)fp, d->rx_len, ms)) < 0 || (size_t)n != d->rx_len)
+ (unsigned char *)fp, d->rx_len, *ms)) < 0 || (size_t)n != d->rx_len)
return (-1);
- return (0);
+ return (fido_time_delta(&ts, ms));
}
static int
-rx_preamble(fido_dev_t *d, uint8_t cmd, struct frame *fp, int ms)
+rx_preamble(fido_dev_t *d, uint8_t cmd, struct frame *fp, int *ms)
{
do {
if (rx_frame(d, fp, ms) < 0)
@@ -185,7 +224,7 @@ rx_preamble(fido_dev_t *d, uint8_t cmd, struct frame *fp, int ms)
}
static int
-rx(fido_dev_t *d, uint8_t cmd, unsigned char *buf, size_t count, int ms)
+rx(fido_dev_t *d, uint8_t cmd, unsigned char *buf, size_t count, int *ms)
{
struct frame f;
size_t r, payload_len, init_data_len, cont_data_len;
@@ -252,16 +291,33 @@ rx(fido_dev_t *d, uint8_t cmd, unsigned char *buf, size_t count, int ms)
return ((int)r);
}
+static int
+transport_rx(fido_dev_t *d, uint8_t cmd, void *buf, size_t count, int *ms)
+{
+ struct timespec ts;
+ int n;
+
+ if (fido_time_now(&ts) != 0)
+ return (-1);
+
+ n = d->transport.rx(d, cmd, buf, count, *ms);
+
+ if (fido_time_delta(&ts, ms) != 0)
+ return (-1);
+
+ return (n);
+}
+
int
-fido_rx(fido_dev_t *d, uint8_t cmd, void *buf, size_t count, int ms)
+fido_rx(fido_dev_t *d, uint8_t cmd, void *buf, size_t count, int *ms)
{
int n;
fido_log_debug("%s: dev=%p, cmd=0x%02x, ms=%d", __func__, (void *)d,
- cmd, ms);
+ cmd, *ms);
if (d->transport.rx != NULL)
- return (d->transport.rx(d, cmd, buf, count, ms));
+ return (transport_rx(d, cmd, buf, count, ms));
if (d->io_handle == NULL || d->io.read == NULL || count > UINT16_MAX) {
fido_log_debug("%s: invalid argument", __func__);
return (-1);
@@ -273,7 +329,7 @@ fido_rx(fido_dev_t *d, uint8_t cmd, void *buf, size_t count, int ms)
}
int
-fido_rx_cbor_status(fido_dev_t *d, int ms)
+fido_rx_cbor_status(fido_dev_t *d, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
diff --git a/contrib/libfido2/src/largeblob.c b/contrib/libfido2/src/largeblob.c
index fa453f5de33a..c8173170766d 100644
--- a/contrib/libfido2/src/largeblob.c
+++ b/contrib/libfido2/src/largeblob.c
@@ -153,7 +153,7 @@ fail:
}
static int
-largeblob_get_tx(fido_dev_t *dev, size_t offset, size_t count)
+largeblob_get_tx(fido_dev_t *dev, size_t offset, size_t count, int *ms)
{
fido_blob_t f;
cbor_item_t *argv[3];
@@ -169,7 +169,7 @@ largeblob_get_tx(fido_dev_t *dev, size_t offset, size_t count)
goto fail;
}
if (cbor_build_frame(CTAP_CBOR_LARGEBLOB, argv, nitems(argv), &f) < 0 ||
- fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
+ fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -198,7 +198,7 @@ parse_largeblob_reply(const cbor_item_t *key, const cbor_item_t *val,
}
static int
-largeblob_get_rx(fido_dev_t *dev, fido_blob_t **chunk, int ms)
+largeblob_get_rx(fido_dev_t *dev, fido_blob_t **chunk, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len, r;
@@ -419,7 +419,7 @@ largeblob_array_check(const fido_blob_t *array)
}
static int
-largeblob_get_array(fido_dev_t *dev, cbor_item_t **item)
+largeblob_get_array(fido_dev_t *dev, cbor_item_t **item, int *ms)
{
fido_blob_t *array, *chunk = NULL;
size_t n;
@@ -432,8 +432,8 @@ largeblob_get_array(fido_dev_t *dev, cbor_item_t **item)
return FIDO_ERR_INTERNAL;
do {
fido_blob_free(&chunk);
- if ((r = largeblob_get_tx(dev, array->len, n)) != FIDO_OK ||
- (r = largeblob_get_rx(dev, &chunk, -1)) != FIDO_OK) {
+ if ((r = largeblob_get_tx(dev, array->len, n, ms)) != FIDO_OK ||
+ (r = largeblob_get_rx(dev, &chunk, ms)) != FIDO_OK) {
fido_log_debug("%s: largeblob_get_wait %zu/%zu",
__func__, array->len, n);
goto fail;
@@ -491,7 +491,7 @@ prepare_hmac(size_t offset, const u_char *data, size_t len, fido_blob_t *hmac)
static int
largeblob_set_tx(fido_dev_t *dev, const fido_blob_t *token, const u_char *chunk,
- size_t chunk_len, size_t offset, size_t totalsiz)
+ size_t chunk_len, size_t offset, size_t totalsiz, int *ms)
{
fido_blob_t *hmac = NULL, f;
cbor_item_t *argv[6];
@@ -518,7 +518,7 @@ largeblob_set_tx(fido_dev_t *dev, const fido_blob_t *token, const u_char *chunk,
}
}
if (cbor_build_frame(CTAP_CBOR_LARGEBLOB, argv, nitems(argv), &f) < 0 ||
- fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
+ fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -534,7 +534,8 @@ fail:
}
static int
-largeblob_get_uv_token(fido_dev_t *dev, const char *pin, fido_blob_t **token)
+largeblob_get_uv_token(fido_dev_t *dev, const char *pin, fido_blob_t **token,
+ int *ms)
{
es256_pk_t *pk = NULL;
fido_blob_t *ecdh = NULL;
@@ -542,12 +543,12 @@ largeblob_get_uv_token(fido_dev_t *dev, const char *pin, fido_blob_t **token)
if ((*token = fido_blob_new()) == NULL)
return FIDO_ERR_INTERNAL;
- if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) {
+ if ((r = fido_do_ecdh(dev, &pk, &ecdh, ms)) != FIDO_OK) {
fido_log_debug("%s: fido_do_ecdh", __func__);
goto fail;
}
if ((r = fido_dev_get_uv_token(dev, CTAP_CBOR_LARGEBLOB, pin, ecdh, pk,
- NULL, *token)) != FIDO_OK) {
+ NULL, *token, ms)) != FIDO_OK) {
fido_log_debug("%s: fido_dev_get_uv_token", __func__);
goto fail;
}
@@ -564,7 +565,8 @@ fail:
}
static int
-largeblob_set_array(fido_dev_t *dev, const cbor_item_t *item, const char *pin)
+largeblob_set_array(fido_dev_t *dev, const cbor_item_t *item, const char *pin,
+ int *ms)
{
unsigned char dgst[SHA256_DIGEST_LENGTH];
fido_blob_t cbor, *token = NULL;
@@ -600,7 +602,8 @@ largeblob_set_array(fido_dev_t *dev, const cbor_item_t *item, const char *pin)
}
totalsize = cbor.len + sizeof(dgst) - 16; /* the first 16 bytes only */
if (pin != NULL || fido_dev_supports_permissions(dev)) {
- if ((r = largeblob_get_uv_token(dev, pin, &token)) != FIDO_OK) {
+ if ((r = largeblob_get_uv_token(dev, pin, &token,
+ ms)) != FIDO_OK) {
fido_log_debug("%s: largeblob_get_uv_token", __func__);
goto fail;
}
@@ -609,15 +612,15 @@ largeblob_set_array(fido_dev_t *dev, const cbor_item_t *item, const char *pin)
if ((chunklen = cbor.len - offset) > maxchunklen)
chunklen = maxchunklen;
if ((r = largeblob_set_tx(dev, token, cbor.ptr + offset,
- chunklen, offset, totalsize)) != FIDO_OK ||
- (r = fido_rx_cbor_status(dev, -1)) != FIDO_OK) {
+ chunklen, offset, totalsize, ms)) != FIDO_OK ||
+ (r = fido_rx_cbor_status(dev, ms)) != FIDO_OK) {
fido_log_debug("%s: body", __func__);
goto fail;
}
}
if ((r = largeblob_set_tx(dev, token, dgst, sizeof(dgst) - 16, cbor.len,
- totalsize)) != FIDO_OK ||
- (r = fido_rx_cbor_status(dev, -1)) != FIDO_OK) {
+ totalsize, ms)) != FIDO_OK ||
+ (r = fido_rx_cbor_status(dev, ms)) != FIDO_OK) {
fido_log_debug("%s: dgst", __func__);
goto fail;
}
@@ -632,13 +635,13 @@ fail:
static int
largeblob_add(fido_dev_t *dev, const fido_blob_t *key, cbor_item_t *item,
- const char *pin)
+ const char *pin, int *ms)
{
cbor_item_t *array = NULL;
size_t idx;
int r;
- if ((r = largeblob_get_array(dev, &array)) != FIDO_OK) {
+ if ((r = largeblob_get_array(dev, &array, ms)) != FIDO_OK) {
fido_log_debug("%s: largeblob_get_array", __func__);
goto fail;
}
@@ -661,7 +664,7 @@ largeblob_add(fido_dev_t *dev, const fido_blob_t *key, cbor_item_t *item,
goto fail;
}
- if ((r = largeblob_set_array(dev, array, pin)) != FIDO_OK) {
+ if ((r = largeblob_set_array(dev, array, pin, ms)) != FIDO_OK) {
fido_log_debug("%s: largeblob_set_array", __func__);
goto fail;
}
@@ -675,13 +678,14 @@ fail:
}
static int
-largeblob_drop(fido_dev_t *dev, const fido_blob_t *key, const char *pin)
+largeblob_drop(fido_dev_t *dev, const fido_blob_t *key, const char *pin,
+ int *ms)
{
cbor_item_t *array = NULL;
size_t idx;
int r;
- if ((r = largeblob_get_array(dev, &array)) != FIDO_OK) {
+ if ((r = largeblob_get_array(dev, &array, ms)) != FIDO_OK) {
fido_log_debug("%s: largeblob_get_array", __func__);
goto fail;
}
@@ -694,7 +698,7 @@ largeblob_drop(fido_dev_t *dev, const fido_blob_t *key, const char *pin)
r = FIDO_ERR_INTERNAL;
goto fail;
}
- if ((r = largeblob_set_array(dev, array, pin)) != FIDO_OK) {
+ if ((r = largeblob_set_array(dev, array, pin, ms)) != FIDO_OK) {
fido_log_debug("%s: largeblob_set_array", __func__);
goto fail;
}
@@ -713,6 +717,7 @@ fido_dev_largeblob_get(fido_dev_t *dev, const unsigned char *key_ptr,
{
cbor_item_t *item = NULL;
fido_blob_t key, body;
+ int ms = dev->timeout_ms;
int r;
memset(&key, 0, sizeof(key));
@@ -733,7 +738,7 @@ fido_dev_largeblob_get(fido_dev_t *dev, const unsigned char *key_ptr,
fido_log_debug("%s: fido_blob_set", __func__);
return FIDO_ERR_INTERNAL;
}
- if ((r = largeblob_get_array(dev, &item)) != FIDO_OK) {
+ if ((r = largeblob_get_array(dev, &item, &ms)) != FIDO_OK) {
fido_log_debug("%s: largeblob_get_array", __func__);
goto fail;
}
@@ -759,6 +764,7 @@ fido_dev_largeblob_set(fido_dev_t *dev, const unsigned char *key_ptr,
{
cbor_item_t *item = NULL;
fido_blob_t key, body;
+ int ms = dev->timeout_ms;
int r;
memset(&key, 0, sizeof(key));
@@ -784,7 +790,7 @@ fido_dev_largeblob_set(fido_dev_t *dev, const unsigned char *key_ptr,
r = FIDO_ERR_INTERNAL;
goto fail;
}
- if ((r = largeblob_add(dev, &key, item, pin)) != FIDO_OK)
+ if ((r = largeblob_add(dev, &key, item, pin, &ms)) != FIDO_OK)
fido_log_debug("%s: largeblob_add", __func__);
fail:
if (item != NULL)
@@ -801,6 +807,7 @@ fido_dev_largeblob_remove(fido_dev_t *dev, const unsigned char *key_ptr,
size_t key_len, const char *pin)
{
fido_blob_t key;
+ int ms = dev->timeout_ms;
int r;
memset(&key, 0, sizeof(key));
@@ -813,7 +820,7 @@ fido_dev_largeblob_remove(fido_dev_t *dev, const unsigned char *key_ptr,
fido_log_debug("%s: fido_blob_set", __func__);
return FIDO_ERR_INTERNAL;
}
- if ((r = largeblob_drop(dev, &key, pin)) != FIDO_OK)
+ if ((r = largeblob_drop(dev, &key, pin, &ms)) != FIDO_OK)
fido_log_debug("%s: largeblob_drop", __func__);
fido_blob_reset(&key);
@@ -827,6 +834,7 @@ fido_dev_largeblob_get_array(fido_dev_t *dev, unsigned char **cbor_ptr,
{
cbor_item_t *item = NULL;
fido_blob_t cbor;
+ int ms = dev->timeout_ms;
int r;
memset(&cbor, 0, sizeof(cbor));
@@ -838,7 +846,7 @@ fido_dev_largeblob_get_array(fido_dev_t *dev, unsigned char **cbor_ptr,
}
*cbor_ptr = NULL;
*cbor_len = 0;
- if ((r = largeblob_get_array(dev, &item)) != FIDO_OK) {
+ if ((r = largeblob_get_array(dev, &item, &ms)) != FIDO_OK) {
fido_log_debug("%s: largeblob_get_array", __func__);
return r;
}
@@ -861,6 +869,7 @@ fido_dev_largeblob_set_array(fido_dev_t *dev, const unsigned char *cbor_ptr,
{
cbor_item_t *item = NULL;
struct cbor_load_result cbor_result;
+ int ms = dev->timeout_ms;
int r;
if (cbor_ptr == NULL || cbor_len == 0) {
@@ -872,7 +881,7 @@ fido_dev_largeblob_set_array(fido_dev_t *dev, const unsigned char *cbor_ptr,
fido_log_debug("%s: cbor_load", __func__);
return FIDO_ERR_INVALID_ARGUMENT;
}
- if ((r = largeblob_set_array(dev, item, pin)) != FIDO_OK)
+ if ((r = largeblob_set_array(dev, item, pin, &ms)) != FIDO_OK)
fido_log_debug("%s: largeblob_set_array", __func__);
cbor_decref(&item);
diff --git a/contrib/libfido2/src/netlink.c b/contrib/libfido2/src/netlink.c
index 6fd9f63cb937..8f14e2c3bac3 100644
--- a/contrib/libfido2/src/netlink.c
+++ b/contrib/libfido2/src/netlink.c
@@ -30,6 +30,8 @@ static ssize_t (*fuzz_write)(int, const void *, size_t);
#define SOL_NETLINK 270
#endif
+#define NETLINK_POLL_MS 100
+
/* XXX avoid signed NLA_ALIGNTO */
#undef NLA_HDRLEN
#define NLA_HDRLEN NLMSG_ALIGN(sizeof(struct nlattr))
@@ -694,7 +696,7 @@ fido_nl_get_nfc_target(fido_nl_t *nl, uint32_t dev, uint32_t *target)
return (-1);
}
#endif
- r = nlmsg_rx(nl->fd, reply, sizeof(reply), -1);
+ r = nlmsg_rx(nl->fd, reply, sizeof(reply), NETLINK_POLL_MS);
#ifndef FIDO_FUZZ
if (setsockopt(nl->fd, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP,
&nl->nfc_mcastgrp, sizeof(nl->nfc_mcastgrp)) == -1) {
diff --git a/contrib/libfido2/src/nfc_linux.c b/contrib/libfido2/src/nfc_linux.c
index dea9f3f98fd0..d5f9ec048052 100644
--- a/contrib/libfido2/src/nfc_linux.c
+++ b/contrib/libfido2/src/nfc_linux.c
@@ -13,6 +13,8 @@
#include <errno.h>
#include <libudev.h>
#include <signal.h>
+#include <stdio.h>
+#include <string.h>
#include <unistd.h>
#include "fido.h"
@@ -218,16 +220,23 @@ tx_get_response(fido_dev_t *d, uint8_t count)
}
static int
-rx_apdu(fido_dev_t *d, uint8_t sw[2], unsigned char **buf, size_t *count, int ms)
+rx_apdu(fido_dev_t *d, uint8_t sw[2], unsigned char **buf, size_t *count, int *ms)
{
uint8_t f[256 + 2];
+ struct timespec ts;
int n, ok = -1;
- if ((n = d->io.read(d->io_handle, f, sizeof(f), ms)) < 2) {
+ if (fido_time_now(&ts) != 0)
+ goto fail;
+
+ if ((n = d->io.read(d->io_handle, f, sizeof(f), *ms)) < 2) {
fido_log_debug("%s: read", __func__);
goto fail;
}
+ if (fido_time_delta(&ts, ms) != 0)
+ goto fail;
+
if (fido_buf_write(buf, count, f, (size_t)(n - 2)) < 0) {
fido_log_debug("%s: fido_buf_write", __func__);
goto fail;
@@ -248,14 +257,14 @@ rx_msg(fido_dev_t *d, unsigned char *buf, size_t count, int ms)
uint8_t sw[2];
const size_t bufsiz = count;
- if (rx_apdu(d, sw, &buf, &count, ms) < 0) {
+ if (rx_apdu(d, sw, &buf, &count, &ms) < 0) {
fido_log_debug("%s: preamble", __func__);
return (-1);
}
while (sw[0] == SW1_MORE_DATA)
if (tx_get_response(d, sw[1]) < 0 ||
- rx_apdu(d, sw, &buf, &count, ms) < 0) {
+ rx_apdu(d, sw, &buf, &count, &ms) < 0) {
fido_log_debug("%s: chain", __func__);
return (-1);
}
@@ -347,6 +356,7 @@ copy_info(fido_dev_info_t *di, struct udev *udev,
const char *name;
char *str;
struct udev_device *dev = NULL;
+ void *ctx = NULL;
int id, ok = -1;
memset(di, 0, sizeof(*di));
@@ -354,27 +364,35 @@ copy_info(fido_dev_info_t *di, struct udev *udev,
if ((name = udev_list_entry_get_name(udev_entry)) == NULL ||
(dev = udev_device_new_from_syspath(udev, name)) == NULL)
goto fail;
-
- if ((di->path = strdup(name)) == NULL ||
- (di->manufacturer = get_usb_attr(dev, "manufacturer")) == NULL ||
- (di->product = get_usb_attr(dev, "product")) == NULL)
+ if (asprintf(&di->path, "%s/%s", FIDO_NFC_PREFIX, name) == -1)
+ goto fail;
+ if ((di->manufacturer = get_usb_attr(dev, "manufacturer")) == NULL)
+ di->manufacturer = strdup("");
+ if ((di->product = get_usb_attr(dev, "product")) == NULL)
+ di->product = strdup("");
+ if (di->manufacturer == NULL || di->product == NULL)
goto fail;
-
/* XXX assumes USB for vendor/product info */
if ((str = get_usb_attr(dev, "idVendor")) != NULL &&
(id = to_int(str, 16)) > 0 && id <= UINT16_MAX)
di->vendor_id = (int16_t)id;
free(str);
-
if ((str = get_usb_attr(dev, "idProduct")) != NULL &&
(id = to_int(str, 16)) > 0 && id <= UINT16_MAX)
di->product_id = (int16_t)id;
free(str);
+ if ((ctx = fido_nfc_open(di->path)) == NULL) {
+ fido_log_debug("%s: fido_nfc_open", __func__);
+ goto fail;
+ }
+
ok = 0;
fail:
if (dev != NULL)
udev_device_unref(dev);
+ if (ctx != NULL)
+ fido_nfc_close(ctx);
if (ok < 0) {
free(di->path);
@@ -532,7 +550,11 @@ fido_nfc_open(const char *path)
struct nfc_linux *ctx = NULL;
int idx;
- if ((idx = sysnum_from_syspath(path)) < 0 ||
+ if (strncmp(path, FIDO_NFC_PREFIX, strlen(FIDO_NFC_PREFIX)) != 0) {
+ fido_log_debug("%s: bad prefix", __func__);
+ goto fail;
+ }
+ if ((idx = sysnum_from_syspath(path + strlen(FIDO_NFC_PREFIX))) < 0 ||
(ctx = nfc_new((uint32_t)idx)) == NULL) {
fido_log_debug("%s: nfc_new", __func__);
goto fail;
diff --git a/contrib/libfido2/src/pin.c b/contrib/libfido2/src/pin.c
index d3104e0ca6ec..30eeb086a6ef 100644
--- a/contrib/libfido2/src/pin.c
+++ b/contrib/libfido2/src/pin.c
@@ -146,7 +146,7 @@ encode_uv_permission(uint8_t cmd)
static int
ctap20_uv_token_tx(fido_dev_t *dev, const char *pin, const fido_blob_t *ecdh,
- const es256_pk_t *pk)
+ const es256_pk_t *pk, int *ms)
{
fido_blob_t f;
fido_blob_t *p = NULL;
@@ -185,7 +185,7 @@ ctap20_uv_token_tx(fido_dev_t *dev, const char *pin, const fido_blob_t *ecdh,
}
if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv),
- &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
+ &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -203,7 +203,7 @@ fail:
static int
ctap21_uv_token_tx(fido_dev_t *dev, const char *pin, const fido_blob_t *ecdh,
- const es256_pk_t *pk, uint8_t cmd, const char *rpid)
+ const es256_pk_t *pk, uint8_t cmd, const char *rpid, int *ms)
{
fido_blob_t f;
fido_blob_t *p = NULL;
@@ -248,7 +248,7 @@ ctap21_uv_token_tx(fido_dev_t *dev, const char *pin, const fido_blob_t *ecdh,
}
if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv),
- &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
+ &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -281,7 +281,7 @@ parse_uv_token(const cbor_item_t *key, const cbor_item_t *val, void *arg)
static int
uv_token_rx(fido_dev_t *dev, const fido_blob_t *ecdh, fido_blob_t *token,
- int ms)
+ int *ms)
{
fido_blob_t *aes_token = NULL;
unsigned char reply[FIDO_MAXMSG];
@@ -322,16 +322,16 @@ fail:
static int
uv_token_wait(fido_dev_t *dev, uint8_t cmd, const char *pin,
const fido_blob_t *ecdh, const es256_pk_t *pk, const char *rpid,
- fido_blob_t *token, int ms)
+ fido_blob_t *token, int *ms)
{
int r;
if (ecdh == NULL || pk == NULL)
return (FIDO_ERR_INVALID_ARGUMENT);
if (fido_dev_supports_permissions(dev))
- r = ctap21_uv_token_tx(dev, pin, ecdh, pk, cmd, rpid);
+ r = ctap21_uv_token_tx(dev, pin, ecdh, pk, cmd, rpid, ms);
else
- r = ctap20_uv_token_tx(dev, pin, ecdh, pk);
+ r = ctap20_uv_token_tx(dev, pin, ecdh, pk, ms);
if (r != FIDO_OK)
return (r);
@@ -341,13 +341,14 @@ uv_token_wait(fido_dev_t *dev, uint8_t cmd, const char *pin,
int
fido_dev_get_uv_token(fido_dev_t *dev, uint8_t cmd, const char *pin,
const fido_blob_t *ecdh, const es256_pk_t *pk, const char *rpid,
- fido_blob_t *token)
+ fido_blob_t *token, int *ms)
{
- return (uv_token_wait(dev, cmd, pin, ecdh, pk, rpid, token, -1));
+ return (uv_token_wait(dev, cmd, pin, ecdh, pk, rpid, token, ms));
}
static int
-fido_dev_change_pin_tx(fido_dev_t *dev, const char *pin, const char *oldpin)
+fido_dev_change_pin_tx(fido_dev_t *dev, const char *pin, const char *oldpin,
+ int *ms)
{
fido_blob_t f;
fido_blob_t *ppine = NULL;
@@ -368,7 +369,7 @@ fido_dev_change_pin_tx(fido_dev_t *dev, const char *pin, const char *oldpin)
goto fail;
}
- if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) {
+ if ((r = fido_do_ecdh(dev, &pk, &ecdh, ms)) != FIDO_OK) {
fido_log_debug("%s: fido_do_ecdh", __func__);
goto fail;
}
@@ -397,7 +398,7 @@ fido_dev_change_pin_tx(fido_dev_t *dev, const char *pin, const char *oldpin)
}
if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv),
- &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
+ &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -418,7 +419,7 @@ fail:
}
static int
-fido_dev_set_pin_tx(fido_dev_t *dev, const char *pin)
+fido_dev_set_pin_tx(fido_dev_t *dev, const char *pin, int *ms)
{
fido_blob_t f;
fido_blob_t *ppine = NULL;
@@ -430,7 +431,7 @@ fido_dev_set_pin_tx(fido_dev_t *dev, const char *pin)
memset(&f, 0, sizeof(f));
memset(argv, 0, sizeof(argv));
- if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) {
+ if ((r = fido_do_ecdh(dev, &pk, &ecdh, ms)) != FIDO_OK) {
fido_log_debug("%s: fido_do_ecdh", __func__);
goto fail;
}
@@ -451,7 +452,7 @@ fido_dev_set_pin_tx(fido_dev_t *dev, const char *pin)
}
if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv),
- &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
+ &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -470,17 +471,18 @@ fail:
static int
fido_dev_set_pin_wait(fido_dev_t *dev, const char *pin, const char *oldpin,
- int ms)
+ int *ms)
{
int r;
if (oldpin != NULL) {
- if ((r = fido_dev_change_pin_tx(dev, pin, oldpin)) != FIDO_OK) {
+ if ((r = fido_dev_change_pin_tx(dev, pin, oldpin,
+ ms)) != FIDO_OK) {
fido_log_debug("%s: fido_dev_change_pin_tx", __func__);
return (r);
}
} else {
- if ((r = fido_dev_set_pin_tx(dev, pin)) != FIDO_OK) {
+ if ((r = fido_dev_set_pin_tx(dev, pin, ms)) != FIDO_OK) {
fido_log_debug("%s: fido_dev_set_pin_tx", __func__);
return (r);
}
@@ -502,7 +504,9 @@ fido_dev_set_pin_wait(fido_dev_t *dev, const char *pin, const char *oldpin,
int
fido_dev_set_pin(fido_dev_t *dev, const char *pin, const char *oldpin)
{
- return (fido_dev_set_pin_wait(dev, pin, oldpin, -1));
+ int ms = dev->timeout_ms;
+
+ return (fido_dev_set_pin_wait(dev, pin, oldpin, &ms));
}
static int
@@ -542,7 +546,7 @@ parse_uv_retry_count(const cbor_item_t *key, const cbor_item_t *val, void *arg)
}
static int
-fido_dev_get_retry_count_tx(fido_dev_t *dev, uint8_t subcmd)
+fido_dev_get_retry_count_tx(fido_dev_t *dev, uint8_t subcmd, int *ms)
{
fido_blob_t f;
cbor_item_t *argv[2];
@@ -558,7 +562,7 @@ fido_dev_get_retry_count_tx(fido_dev_t *dev, uint8_t subcmd)
}
if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv),
- &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
+ &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -573,7 +577,7 @@ fail:
}
static int
-fido_dev_get_pin_retry_count_rx(fido_dev_t *dev, int *retries, int ms)
+fido_dev_get_pin_retry_count_rx(fido_dev_t *dev, int *retries, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
@@ -597,11 +601,11 @@ fido_dev_get_pin_retry_count_rx(fido_dev_t *dev, int *retries, int ms)
}
static int
-fido_dev_get_pin_retry_count_wait(fido_dev_t *dev, int *retries, int ms)
+fido_dev_get_pin_retry_count_wait(fido_dev_t *dev, int *retries, int *ms)
{
int r;
- if ((r = fido_dev_get_retry_count_tx(dev, 1)) != FIDO_OK ||
+ if ((r = fido_dev_get_retry_count_tx(dev, 1, ms)) != FIDO_OK ||
(r = fido_dev_get_pin_retry_count_rx(dev, retries, ms)) != FIDO_OK)
return (r);
@@ -611,11 +615,13 @@ fido_dev_get_pin_retry_count_wait(fido_dev_t *dev, int *retries, int ms)
int
fido_dev_get_retry_count(fido_dev_t *dev, int *retries)
{
- return (fido_dev_get_pin_retry_count_wait(dev, retries, -1));
+ int ms = dev->timeout_ms;
+
+ return (fido_dev_get_pin_retry_count_wait(dev, retries, &ms));
}
static int
-fido_dev_get_uv_retry_count_rx(fido_dev_t *dev, int *retries, int ms)
+fido_dev_get_uv_retry_count_rx(fido_dev_t *dev, int *retries, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
@@ -639,11 +645,11 @@ fido_dev_get_uv_retry_count_rx(fido_dev_t *dev, int *retries, int ms)
}
static int
-fido_dev_get_uv_retry_count_wait(fido_dev_t *dev, int *retries, int ms)
+fido_dev_get_uv_retry_count_wait(fido_dev_t *dev, int *retries, int *ms)
{
int r;
- if ((r = fido_dev_get_retry_count_tx(dev, 7)) != FIDO_OK ||
+ if ((r = fido_dev_get_retry_count_tx(dev, 7, ms)) != FIDO_OK ||
(r = fido_dev_get_uv_retry_count_rx(dev, retries, ms)) != FIDO_OK)
return (r);
@@ -653,13 +659,15 @@ fido_dev_get_uv_retry_count_wait(fido_dev_t *dev, int *retries, int ms)
int
fido_dev_get_uv_retry_count(fido_dev_t *dev, int *retries)
{
- return (fido_dev_get_uv_retry_count_wait(dev, retries, -1));
+ int ms = dev->timeout_ms;
+
+ return (fido_dev_get_uv_retry_count_wait(dev, retries, &ms));
}
int
cbor_add_uv_params(fido_dev_t *dev, uint8_t cmd, const fido_blob_t *hmac_data,
const es256_pk_t *pk, const fido_blob_t *ecdh, const char *pin,
- const char *rpid, cbor_item_t **auth, cbor_item_t **opt)
+ const char *rpid, cbor_item_t **auth, cbor_item_t **opt, int *ms)
{
fido_blob_t *token = NULL;
int r;
@@ -670,7 +678,7 @@ cbor_add_uv_params(fido_dev_t *dev, uint8_t cmd, const fido_blob_t *hmac_data,
}
if ((r = fido_dev_get_uv_token(dev, cmd, pin, ecdh, pk, rpid,
- token)) != FIDO_OK) {
+ token, ms)) != FIDO_OK) {
fido_log_debug("%s: fido_dev_get_uv_token", __func__);
goto fail;
}
diff --git a/contrib/libfido2/src/reset.c b/contrib/libfido2/src/reset.c
index 11380cea0904..c5fe6dfe7ac1 100644
--- a/contrib/libfido2/src/reset.c
+++ b/contrib/libfido2/src/reset.c
@@ -7,11 +7,11 @@
#include "fido.h"
static int
-fido_dev_reset_tx(fido_dev_t *dev)
+fido_dev_reset_tx(fido_dev_t *dev, int *ms)
{
const unsigned char cbor[] = { CTAP_CBOR_RESET };
- if (fido_tx(dev, CTAP_CMD_CBOR, cbor, sizeof(cbor)) < 0) {
+ if (fido_tx(dev, CTAP_CMD_CBOR, cbor, sizeof(cbor), ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
return (FIDO_ERR_TX);
}
@@ -20,11 +20,11 @@ fido_dev_reset_tx(fido_dev_t *dev)
}
static int
-fido_dev_reset_wait(fido_dev_t *dev, int ms)
+fido_dev_reset_wait(fido_dev_t *dev, int *ms)
{
int r;
- if ((r = fido_dev_reset_tx(dev)) != FIDO_OK ||
+ if ((r = fido_dev_reset_tx(dev, ms)) != FIDO_OK ||
(r = fido_rx_cbor_status(dev, ms)) != FIDO_OK)
return (r);
@@ -39,5 +39,7 @@ fido_dev_reset_wait(fido_dev_t *dev, int ms)
int
fido_dev_reset(fido_dev_t *dev)
{
- return (fido_dev_reset_wait(dev, -1));
+ int ms = dev->timeout_ms;
+
+ return (fido_dev_reset_wait(dev, &ms));
}
diff --git a/contrib/libfido2/src/rs1.c b/contrib/libfido2/src/rs1.c
new file mode 100644
index 000000000000..37aa9f073bed
--- /dev/null
+++ b/contrib/libfido2/src/rs1.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2021 Yubico AB. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+#include <openssl/rsa.h>
+#include <openssl/obj_mac.h>
+
+#include "fido.h"
+
+#if defined(LIBRESSL_VERSION_NUMBER)
+static EVP_MD *
+rs1_get_EVP_MD(void)
+{
+ const EVP_MD *from;
+ EVP_MD *to = NULL;
+
+ if ((from = EVP_sha1()) != NULL && (to = malloc(sizeof(*to))) != NULL)
+ memcpy(to, from, sizeof(*to));
+
+ return (to);
+}
+
+static void
+rs1_free_EVP_MD(EVP_MD *md)
+{
+ freezero(md, sizeof(*md));
+}
+#elif OPENSSL_VERSION_NUMBER >= 0x30000000
+static EVP_MD *
+rs1_get_EVP_MD(void)
+{
+ return (EVP_MD_fetch(NULL, "SHA-1", NULL));
+}
+
+static void
+rs1_free_EVP_MD(EVP_MD *md)
+{
+ EVP_MD_free(md);
+}
+#else
+static EVP_MD *
+rs1_get_EVP_MD(void)
+{
+ const EVP_MD *md;
+
+ if ((md = EVP_sha1()) == NULL)
+ return (NULL);
+
+ return (EVP_MD_meth_dup(md));
+}
+
+static void
+rs1_free_EVP_MD(EVP_MD *md)
+{
+ EVP_MD_meth_free(md);
+}
+#endif /* LIBRESSL_VERSION_NUMBER */
+
+int
+rs1_verify_sig(const fido_blob_t *dgst, EVP_PKEY *pkey,
+ const fido_blob_t *sig)
+{
+ EVP_PKEY_CTX *pctx = NULL;
+ EVP_MD *md = NULL;
+ int ok = -1;
+
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) {
+ fido_log_debug("%s: EVP_PKEY_base_id", __func__);
+ goto fail;
+ }
+
+ if ((md = rs1_get_EVP_MD()) == NULL) {
+ fido_log_debug("%s: rs1_get_EVP_MD", __func__);
+ goto fail;
+ }
+
+ if ((pctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL ||
+ EVP_PKEY_verify_init(pctx) != 1 ||
+ EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PADDING) != 1 ||
+ EVP_PKEY_CTX_set_signature_md(pctx, md) != 1) {
+ fido_log_debug("%s: EVP_PKEY_CTX", __func__);
+ goto fail;
+ }
+
+ if (EVP_PKEY_verify(pctx, sig->ptr, sig->len, dgst->ptr,
+ dgst->len) != 1) {
+ fido_log_debug("%s: EVP_PKEY_verify", __func__);
+ goto fail;
+ }
+
+ ok = 0;
+fail:
+ EVP_PKEY_CTX_free(pctx);
+ rs1_free_EVP_MD(md);
+
+ return (ok);
+}
diff --git a/contrib/libfido2/src/rs256.c b/contrib/libfido2/src/rs256.c
index c6d87a3ea22c..29fcedbdee20 100644
--- a/contrib/libfido2/src/rs256.c
+++ b/contrib/libfido2/src/rs256.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -11,31 +11,54 @@
#include "fido.h"
#include "fido/rs256.h"
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-static int
-RSA_bits(const RSA *r)
+#if defined(LIBRESSL_VERSION_NUMBER)
+static EVP_MD *
+rs256_get_EVP_MD(void)
{
- return (BN_num_bits(r->n));
+ const EVP_MD *from;
+ EVP_MD *to = NULL;
+
+ if ((from = EVP_sha256()) != NULL && (to = malloc(sizeof(*to))) != NULL)
+ memcpy(to, from, sizeof(*to));
+
+ return (to);
}
-static int
-RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
+static void
+rs256_free_EVP_MD(EVP_MD *md)
+{
+ freezero(md, sizeof(*md));
+}
+#elif OPENSSL_VERSION_NUMBER >= 0x30000000
+static EVP_MD *
+rs256_get_EVP_MD(void)
{
- r->n = n;
- r->e = e;
- r->d = d;
+ return (EVP_MD_fetch(NULL, "SHA2-256", NULL));
+}
+
+static void
+rs256_free_EVP_MD(EVP_MD *md)
+{
+ EVP_MD_free(md);
+}
+#else
+static EVP_MD *
+rs256_get_EVP_MD(void)
+{
+ const EVP_MD *md;
+
+ if ((md = EVP_sha256()) == NULL)
+ return (NULL);
- return (1);
+ return (EVP_MD_meth_dup(md));
}
static void
-RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
+rs256_free_EVP_MD(EVP_MD *md)
{
- *n = r->n;
- *e = r->e;
- *d = r->d;
+ EVP_MD_meth_free(md);
}
-#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+#endif /* LIBRESSL_VERSION_NUMBER */
static int
decode_bignum(const cbor_item_t *item, void *ptr, size_t len)
@@ -198,3 +221,75 @@ rs256_pk_from_RSA(rs256_pk_t *pk, const RSA *rsa)
return (FIDO_OK);
}
+
+int
+rs256_pk_from_EVP_PKEY(rs256_pk_t *pk, const EVP_PKEY *pkey)
+{
+ RSA *rsa;
+
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA ||
+ (rsa = EVP_PKEY_get0(pkey)) == NULL)
+ return (FIDO_ERR_INVALID_ARGUMENT);
+
+ return (rs256_pk_from_RSA(pk, rsa));
+}
+
+int
+rs256_verify_sig(const fido_blob_t *dgst, EVP_PKEY *pkey,
+ const fido_blob_t *sig)
+{
+ EVP_PKEY_CTX *pctx = NULL;
+ EVP_MD *md = NULL;
+ int ok = -1;
+
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) {
+ fido_log_debug("%s: EVP_PKEY_base_id", __func__);
+ goto fail;
+ }
+
+ if ((md = rs256_get_EVP_MD()) == NULL) {
+ fido_log_debug("%s: rs256_get_EVP_MD", __func__);
+ goto fail;
+ }
+
+ if ((pctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL ||
+ EVP_PKEY_verify_init(pctx) != 1 ||
+ EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PADDING) != 1 ||
+ EVP_PKEY_CTX_set_signature_md(pctx, md) != 1) {
+ fido_log_debug("%s: EVP_PKEY_CTX", __func__);
+ goto fail;
+ }
+
+ if (EVP_PKEY_verify(pctx, sig->ptr, sig->len, dgst->ptr,
+ dgst->len) != 1) {
+ fido_log_debug("%s: EVP_PKEY_verify", __func__);
+ goto fail;
+ }
+
+ ok = 0;
+fail:
+ EVP_PKEY_CTX_free(pctx);
+ rs256_free_EVP_MD(md);
+
+ return (ok);
+}
+
+int
+rs256_pk_verify_sig(const fido_blob_t *dgst, const rs256_pk_t *pk,
+ const fido_blob_t *sig)
+{
+ EVP_PKEY *pkey;
+ int ok = -1;
+
+ if ((pkey = rs256_pk_to_EVP_PKEY(pk)) == NULL ||
+ rs256_verify_sig(dgst, pkey, sig) < 0) {
+ fido_log_debug("%s: rs256_verify_sig", __func__);
+ goto fail;
+ }
+
+ ok = 0;
+fail:
+ EVP_PKEY_free(pkey);
+
+ return (ok);
+}
diff --git a/contrib/libfido2/src/time.c b/contrib/libfido2/src/time.c
new file mode 100644
index 000000000000..b82b61874498
--- /dev/null
+++ b/contrib/libfido2/src/time.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2021 Yubico AB. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+#include <errno.h>
+#include "fido.h"
+
+static int
+timespec_to_ms(const struct timespec *ts)
+{
+ int64_t x, y;
+
+ if (ts->tv_sec < 0 || ts->tv_nsec < 0 ||
+ ts->tv_nsec >= 1000000000LL)
+ return -1;
+
+ if ((uint64_t)ts->tv_sec >= INT64_MAX / 1000LL)
+ return -1;
+
+ x = ts->tv_sec * 1000LL;
+ y = ts->tv_nsec / 1000000LL;
+
+ if (INT64_MAX - x < y || x + y > INT_MAX)
+ return -1;
+
+ return (int)(x + y);
+}
+
+int
+fido_time_now(struct timespec *ts_now)
+{
+ if (clock_gettime(CLOCK_MONOTONIC, ts_now) != 0) {
+ fido_log_error(errno, "%s: clock_gettime", __func__);
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+fido_time_delta(const struct timespec *ts_start, int *ms_remain)
+{
+ struct timespec ts_end, ts_delta;
+ int ms;
+
+ if (*ms_remain < 0)
+ return 0;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &ts_end) != 0) {
+ fido_log_error(errno, "%s: clock_gettime", __func__);
+ return -1;
+ }
+
+ if (timespeccmp(&ts_end, ts_start, <)) {
+ fido_log_debug("%s: timespeccmp", __func__);
+ return -1;
+ }
+
+ timespecsub(&ts_end, ts_start, &ts_delta);
+
+ if ((ms = timespec_to_ms(&ts_delta)) < 0) {
+ fido_log_debug("%s: timespec_to_ms", __func__);
+ return -1;
+ }
+
+ if (ms > *ms_remain)
+ ms = *ms_remain;
+
+ *ms_remain -= ms;
+
+ return 0;
+}
diff --git a/contrib/libfido2/src/tpm.c b/contrib/libfido2/src/tpm.c
new file mode 100644
index 000000000000..74620a5e4865
--- /dev/null
+++ b/contrib/libfido2/src/tpm.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2021 Yubico AB. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+/*
+ * Trusted Platform Module (TPM) 2.0 attestation support. Documentation
+ * references are relative to revision 01.38 of the TPM 2.0 specification.
+ */
+
+#include <openssl/sha.h>
+
+#include "packed.h"
+#include "fido.h"
+
+/* Part 1, 4.89: TPM_GENERATED_VALUE */
+#define TPM_MAGIC 0xff544347
+
+/* Part 2, 6.3: TPM_ALG_ID */
+#define TPM_ALG_RSA 0x0001
+#define TPM_ALG_SHA256 0x000b
+#define TPM_ALG_NULL 0x0010
+
+/* Part 2, 6.9: TPM_ST_ATTEST_CERTIFY */
+#define TPM_ST_CERTIFY 0x8017
+
+/* Part 2, 8.3: TPMA_OBJECT */
+#define TPMA_RESERVED 0xfff8f309 /* reserved bits; must be zero */
+#define TPMA_FIXED 0x00000002 /* object has fixed hierarchy */
+#define TPMA_CLEAR 0x00000004 /* object persists */
+#define TPMA_FIXED_P 0x00000010 /* object has fixed parent */
+#define TPMA_SENSITIVE 0x00000020 /* data originates within tpm */
+#define TPMA_SIGN 0x00020000 /* object may sign */
+
+/* Part 2, 10.4.2: TPM2B_DIGEST */
+PACKED_TYPE(tpm_sha256_digest_t,
+struct tpm_sha256_digest {
+ uint16_t size; /* sizeof(body) */
+ uint8_t body[32];
+})
+
+/* Part 2, 10.4.3: TPM2B_DATA */
+PACKED_TYPE(tpm_sha1_data_t,
+struct tpm_sha1_data {
+ uint16_t size; /* sizeof(body */
+ uint8_t body[20];
+})
+
+/* Part 2, 10.5.3: TPM2B_NAME */
+PACKED_TYPE(tpm_sha256_name_t,
+struct tpm_sha256_name {
+ uint16_t size; /* sizeof(alg) + sizeof(body) */
+ uint16_t alg; /* TPM_ALG_SHA256 */
+ uint8_t body[32];
+})
+
+/* Part 2, 10.11.1: TPMS_CLOCK_INFO */
+PACKED_TYPE(tpm_clock_info_t,
+struct tpm_clock_info {
+ uint64_t timestamp_ms;
+ uint32_t reset_count; /* obfuscated by tpm */
+ uint32_t restart_count; /* obfuscated by tpm */
+ uint8_t safe; /* 1 if timestamp_ms is current */
+})
+
+/* Part 2, 10.12.8 TPMS_ATTEST */
+PACKED_TYPE(tpm_sha1_attest_t,
+struct tpm_sha1_attest {
+ uint32_t magic; /* TPM_MAGIC */
+ uint16_t type; /* TPM_ST_ATTEST_CERTIFY */
+ tpm_sha256_name_t signer; /* full tpm path of signing key */
+ tpm_sha1_data_t data; /* signed sha1 */
+ tpm_clock_info_t clock;
+ uint64_t fwversion; /* obfuscated by tpm */
+ tpm_sha256_name_t name; /* sha256 of tpm_rsa2048_pubarea_t */
+ tpm_sha256_name_t qual_name; /* full tpm path of attested key */
+})
+
+/* Part 2, 11.2.4.5: TPM2B_PUBLIC_KEY_RSA */
+PACKED_TYPE(tpm_rsa2048_key_t,
+struct tpm_rsa2048_key {
+ uint16_t size; /* sizeof(body) */
+ uint8_t body[256];
+})
+
+/* Part 2, 12.2.3.5: TPMS_RSA_PARMS */
+PACKED_TYPE(tpm_rsa2048_param_t,
+struct tpm_rsa2048_param {
+ uint16_t symmetric; /* TPM_ALG_NULL */
+ uint16_t scheme; /* TPM_ALG_NULL */
+ uint16_t keybits; /* 2048 */
+ uint32_t exponent; /* zero (meaning 2^16 + 1) */
+})
+
+/* Part 2, 12.2.4: TPMT_PUBLIC */
+PACKED_TYPE(tpm_rsa2048_pubarea_t,
+struct tpm_rsa2048_pubarea {
+ uint16_t alg; /* TPM_ALG_RSA */
+ uint16_t hash; /* TPM_ALG_SHA256 */
+ uint32_t attr;
+ tpm_sha256_digest_t policy; /* must be present? */
+ tpm_rsa2048_param_t param;
+ tpm_rsa2048_key_t key;
+})
+
+static int
+get_signed_sha1(tpm_sha1_data_t *dgst, const fido_blob_t *authdata,
+ const fido_blob_t *clientdata)
+{
+ const EVP_MD *md = NULL;
+ EVP_MD_CTX *ctx = NULL;
+ int ok = -1;
+
+ if ((dgst->size = sizeof(dgst->body)) != SHA_DIGEST_LENGTH ||
+ (md = EVP_sha1()) == NULL ||
+ (ctx = EVP_MD_CTX_new()) == NULL ||
+ EVP_DigestInit_ex(ctx, md, NULL) != 1 ||
+ EVP_DigestUpdate(ctx, authdata->ptr, authdata->len) != 1 ||
+ EVP_DigestUpdate(ctx, clientdata->ptr, clientdata->len) != 1 ||
+ EVP_DigestFinal_ex(ctx, dgst->body, NULL) != 1) {
+ fido_log_debug("%s: sha1", __func__);
+ goto fail;
+ }
+
+ ok = 0;
+fail:
+ EVP_MD_CTX_free(ctx);
+
+ return (ok);
+}
+
+static int
+get_signed_name(tpm_sha256_name_t *name, const fido_blob_t *pubarea)
+{
+ name->alg = TPM_ALG_SHA256;
+ name->size = sizeof(name->alg) + sizeof(name->body);
+ if (sizeof(name->body) != SHA256_DIGEST_LENGTH ||
+ SHA256(pubarea->ptr, pubarea->len, name->body) != name->body) {
+ fido_log_debug("%s: sha256", __func__);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void
+bswap_rsa2048_pubarea(tpm_rsa2048_pubarea_t *x)
+{
+ x->alg = htobe16(x->alg);
+ x->hash = htobe16(x->hash);
+ x->attr = htobe32(x->attr);
+ x->policy.size = htobe16(x->policy.size);
+ x->param.symmetric = htobe16(x->param.symmetric);
+ x->param.scheme = htobe16(x->param.scheme);
+ x->param.keybits = htobe16(x->param.keybits);
+ x->key.size = htobe16(x->key.size);
+}
+
+static void
+bswap_sha1_certinfo(tpm_sha1_attest_t *x)
+{
+ x->magic = htobe32(x->magic);
+ x->type = htobe16(x->type);
+ x->signer.size = htobe16(x->signer.size);
+ x->data.size = htobe16(x->data.size);
+ x->name.alg = htobe16(x->name.alg);
+ x->name.size = htobe16(x->name.size);
+}
+
+static int
+check_rsa2048_pubarea(const fido_blob_t *buf, const rs256_pk_t *pk)
+{
+ const tpm_rsa2048_pubarea_t *actual;
+ tpm_rsa2048_pubarea_t expected;
+ int ok;
+
+ if (buf->len != sizeof(*actual)) {
+ fido_log_debug("%s: buf->len=%zu", __func__, buf->len);
+ return -1;
+ }
+ actual = (const void *)buf->ptr;
+
+ memset(&expected, 0, sizeof(expected));
+ expected.alg = TPM_ALG_RSA;
+ expected.hash = TPM_ALG_SHA256;
+ expected.attr = be32toh(actual->attr);
+ expected.attr &= ~(TPMA_RESERVED|TPMA_CLEAR);
+ expected.attr |= (TPMA_FIXED|TPMA_FIXED_P|TPMA_SENSITIVE|TPMA_SIGN);
+ expected.policy = actual->policy;
+ expected.policy.size = sizeof(expected.policy.body);
+ expected.param.symmetric = TPM_ALG_NULL;
+ expected.param.scheme = TPM_ALG_NULL;
+ expected.param.keybits = 2048;
+ expected.param.exponent = 0; /* meaning 2^16+1 */
+ expected.key.size = sizeof(expected.key.body);
+ memcpy(&expected.key.body, &pk->n, sizeof(expected.key.body));
+ bswap_rsa2048_pubarea(&expected);
+
+ ok = timingsafe_bcmp(&expected, actual, sizeof(expected));
+ explicit_bzero(&expected, sizeof(expected));
+
+ return ok != 0 ? -1 : 0;
+}
+
+static int
+check_sha1_certinfo(const fido_blob_t *buf, const fido_blob_t *clientdata_hash,
+ const fido_blob_t *authdata_raw, const fido_blob_t *pubarea)
+{
+ const tpm_sha1_attest_t *actual;
+ tpm_sha1_attest_t expected;
+ tpm_sha1_data_t signed_data;
+ tpm_sha256_name_t signed_name;
+ int ok = -1;
+
+ memset(&signed_data, 0, sizeof(signed_data));
+ memset(&signed_name, 0, sizeof(signed_name));
+
+ if (get_signed_sha1(&signed_data, authdata_raw, clientdata_hash) < 0 ||
+ get_signed_name(&signed_name, pubarea) < 0) {
+ fido_log_debug("%s: get_signed_sha1/name", __func__);
+ goto fail;
+ }
+ if (buf->len != sizeof(*actual)) {
+ fido_log_debug("%s: buf->len=%zu", __func__, buf->len);
+ goto fail;
+ }
+ actual = (const void *)buf->ptr;
+
+ memset(&expected, 0, sizeof(expected));
+ expected.magic = TPM_MAGIC;
+ expected.type = TPM_ST_CERTIFY;
+ expected.signer = actual->signer;
+ expected.signer.size = sizeof(expected.signer.alg) +
+ sizeof(expected.signer.body);
+ expected.data = signed_data;
+ expected.clock = actual->clock;
+ expected.clock.safe = 1;
+ expected.fwversion = actual->fwversion;
+ expected.name = signed_name;
+ expected.qual_name = actual->qual_name;
+ bswap_sha1_certinfo(&expected);
+
+ ok = timingsafe_bcmp(&expected, actual, sizeof(expected));
+fail:
+ explicit_bzero(&expected, sizeof(expected));
+ explicit_bzero(&signed_data, sizeof(signed_data));
+ explicit_bzero(&signed_name, sizeof(signed_name));
+
+ return ok != 0 ? -1 : 0;
+}
+
+int
+fido_get_signed_hash_tpm(fido_blob_t *dgst, const fido_blob_t *clientdata_hash,
+ const fido_blob_t *authdata_raw, const fido_attstmt_t *attstmt,
+ const fido_attcred_t *attcred)
+{
+ const fido_blob_t *pubarea = &attstmt->pubarea;
+ const fido_blob_t *certinfo = &attstmt->certinfo;
+
+ if (attstmt->alg != COSE_RS1 || attcred->type != COSE_RS256) {
+ fido_log_debug("%s: unsupported alg %d, type %d", __func__,
+ attstmt->alg, attcred->type);
+ return -1;
+ }
+
+ if (check_rsa2048_pubarea(pubarea, &attcred->pubkey.rs256) < 0) {
+ fido_log_debug("%s: check_rsa2048_pubarea", __func__);
+ return -1;
+ }
+
+ if (check_sha1_certinfo(certinfo, clientdata_hash, authdata_raw,
+ pubarea) < 0) {
+ fido_log_debug("%s: check_sha1_certinfo", __func__);
+ return -1;
+ }
+
+ if (dgst->len < SHA_DIGEST_LENGTH ||
+ SHA1(certinfo->ptr, certinfo->len, dgst->ptr) != dgst->ptr) {
+ fido_log_debug("%s: sha1", __func__);
+ return -1;
+ }
+ dgst->len = SHA_DIGEST_LENGTH;
+
+ return 0;
+}
diff --git a/contrib/libfido2/src/types.c b/contrib/libfido2/src/types.c
new file mode 100644
index 000000000000..54c0ca582865
--- /dev/null
+++ b/contrib/libfido2/src/types.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+#include "fido.h"
+
+void
+fido_str_array_free(fido_str_array_t *sa)
+{
+ for (size_t i = 0; i < sa->len; i++)
+ free(sa->ptr[i]);
+
+ free(sa->ptr);
+ sa->ptr = NULL;
+ sa->len = 0;
+}
+
+void
+fido_opt_array_free(fido_opt_array_t *oa)
+{
+ for (size_t i = 0; i < oa->len; i++)
+ free(oa->name[i]);
+
+ free(oa->name);
+ free(oa->value);
+ oa->name = NULL;
+ oa->value = NULL;
+}
+
+void
+fido_byte_array_free(fido_byte_array_t *ba)
+{
+ free(ba->ptr);
+
+ ba->ptr = NULL;
+ ba->len = 0;
+}
+
+void
+fido_algo_free(fido_algo_t *a)
+{
+ free(a->type);
+ a->type = NULL;
+ a->cose = 0;
+}
+
+void
+fido_algo_array_free(fido_algo_array_t *aa)
+{
+ for (size_t i = 0; i < aa->len; i++)
+ fido_algo_free(&aa->ptr[i]);
+
+ free(aa->ptr);
+ aa->ptr = NULL;
+ aa->len = 0;
+}
+
+int
+fido_str_array_pack(fido_str_array_t *sa, const char * const *v, size_t n)
+{
+ if ((sa->ptr = calloc(n, sizeof(char *))) == NULL) {
+ fido_log_debug("%s: calloc", __func__);
+ return -1;
+ }
+ for (size_t i = 0; i < n; i++) {
+ if ((sa->ptr[i] = strdup(v[i])) == NULL) {
+ fido_log_debug("%s: strdup", __func__);
+ return -1;
+ }
+ sa->len++;
+ }
+
+ return 0;
+}
diff --git a/contrib/libfido2/src/u2f.c b/contrib/libfido2/src/u2f.c
index c5fbe0cfbb6c..6ebfcc7bb848 100644
--- a/contrib/libfido2/src/u2f.c
+++ b/contrib/libfido2/src/u2f.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@@ -10,10 +10,13 @@
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+#include <errno.h>
#include "fido.h"
#include "fido/es256.h"
+#define U2F_PACE_MS (100)
+
#if defined(_MSC_VER)
static int
usleep(unsigned int usec)
@@ -25,6 +28,28 @@ usleep(unsigned int usec)
#endif
static int
+delay_ms(unsigned int ms, int *ms_remain)
+{
+ if (*ms_remain > -1 && (unsigned int)*ms_remain < ms)
+ ms = (unsigned int)*ms_remain;
+
+ if (ms > UINT_MAX / 1000) {
+ fido_log_debug("%s: ms=%u", __func__, ms);
+ return (-1);
+ }
+
+ if (usleep(ms * 1000) < 0) {
+ fido_log_error(errno, "%s: usleep", __func__);
+ return (-1);
+ }
+
+ if (*ms_remain > -1)
+ *ms_remain -= (int)ms;
+
+ return (0);
+}
+
+static int
sig_get(fido_blob_t *sig, const unsigned char **buf, size_t *len)
{
sig->len = *len; /* consume the whole buffer */
@@ -115,7 +140,7 @@ authdata_fake(const char *rp_id, uint8_t flags, uint32_t sigcount,
/* TODO: use u2f_get_touch_begin & u2f_get_touch_status instead */
static int
-send_dummy_register(fido_dev_t *dev, int ms)
+send_dummy_register(fido_dev_t *dev, int *ms)
{
iso7816_apdu_t *apdu = NULL;
unsigned char challenge[SHA256_DIGEST_LENGTH];
@@ -123,10 +148,6 @@ send_dummy_register(fido_dev_t *dev, int ms)
unsigned char reply[FIDO_MAXMSG];
int r;
-#ifdef FIDO_FUZZ
- ms = 0; /* XXX */
-#endif
-
/* dummy challenge & application */
memset(&challenge, 0xff, sizeof(challenge));
memset(&application, 0xff, sizeof(application));
@@ -142,7 +163,7 @@ send_dummy_register(fido_dev_t *dev, int ms)
do {
if (fido_tx(dev, CTAP_CMD_MSG, iso7816_ptr(apdu),
- iso7816_len(apdu)) < 0) {
+ iso7816_len(apdu), ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -152,8 +173,8 @@ send_dummy_register(fido_dev_t *dev, int ms)
r = FIDO_ERR_RX;
goto fail;
}
- if (usleep((unsigned)(ms == -1 ? 100 : ms) * 1000) < 0) {
- fido_log_debug("%s: usleep", __func__);
+ if (delay_ms(U2F_PACE_MS, ms) != 0) {
+ fido_log_debug("%s: delay_ms", __func__);
r = FIDO_ERR_RX;
goto fail;
}
@@ -168,7 +189,7 @@ fail:
static int
key_lookup(fido_dev_t *dev, const char *rp_id, const fido_blob_t *key_id,
- int *found, int ms)
+ int *found, int *ms)
{
iso7816_apdu_t *apdu = NULL;
unsigned char challenge[SHA256_DIGEST_LENGTH];
@@ -208,7 +229,7 @@ key_lookup(fido_dev_t *dev, const char *rp_id, const fido_blob_t *key_id,
}
if (fido_tx(dev, CTAP_CMD_MSG, iso7816_ptr(apdu),
- iso7816_len(apdu)) < 0) {
+ iso7816_len(apdu), ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -274,7 +295,7 @@ parse_auth_reply(fido_blob_t *sig, fido_blob_t *ad, const char *rp_id,
static int
do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id,
- const fido_blob_t *key_id, fido_blob_t *sig, fido_blob_t *ad, int ms)
+ const fido_blob_t *key_id, fido_blob_t *sig, fido_blob_t *ad, int *ms)
{
iso7816_apdu_t *apdu = NULL;
unsigned char rp_id_hash[SHA256_DIGEST_LENGTH];
@@ -284,7 +305,7 @@ do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id,
int r;
#ifdef FIDO_FUZZ
- ms = 0; /* XXX */
+ *ms = 0; /* XXX */
#endif
if (cdh->len != SHA256_DIGEST_LENGTH || key_id->len > UINT8_MAX ||
@@ -317,7 +338,7 @@ do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id,
do {
if (fido_tx(dev, CTAP_CMD_MSG, iso7816_ptr(apdu),
- iso7816_len(apdu)) < 0) {
+ iso7816_len(apdu), ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -328,8 +349,8 @@ do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id,
r = FIDO_ERR_RX;
goto fail;
}
- if (usleep((unsigned)(ms == -1 ? 100 : ms) * 1000) < 0) {
- fido_log_debug("%s: usleep", __func__);
+ if (delay_ms(U2F_PACE_MS, ms) != 0) {
+ fido_log_debug("%s: delay_ms", __func__);
r = FIDO_ERR_RX;
goto fail;
}
@@ -391,6 +412,71 @@ fail:
}
static int
+encode_cred_attstmt(int cose_alg, const fido_blob_t *x5c,
+ const fido_blob_t *sig, fido_blob_t *out)
+{
+ cbor_item_t *item = NULL;
+ cbor_item_t *x5c_cbor = NULL;
+ const uint8_t alg_cbor = (uint8_t)(-cose_alg - 1);
+ struct cbor_pair kv[3];
+ size_t alloc_len;
+ int ok = -1;
+
+ memset(&kv, 0, sizeof(kv));
+ memset(out, 0, sizeof(*out));
+
+ if ((item = cbor_new_definite_map(3)) == NULL) {
+ fido_log_debug("%s: cbor_new_definite_map", __func__);
+ goto fail;
+ }
+
+ if ((kv[0].key = cbor_build_string("alg")) == NULL ||
+ (kv[0].value = cbor_build_negint8(alg_cbor)) == NULL ||
+ !cbor_map_add(item, kv[0])) {
+ fido_log_debug("%s: alg", __func__);
+ goto fail;
+ }
+
+ if ((kv[1].key = cbor_build_string("sig")) == NULL ||
+ (kv[1].value = fido_blob_encode(sig)) == NULL ||
+ !cbor_map_add(item, kv[1])) {
+ fido_log_debug("%s: sig", __func__);
+ goto fail;
+ }
+
+ if ((kv[2].key = cbor_build_string("x5c")) == NULL ||
+ (kv[2].value = cbor_new_definite_array(1)) == NULL ||
+ (x5c_cbor = fido_blob_encode(x5c)) == NULL ||
+ !cbor_array_push(kv[2].value, x5c_cbor) ||
+ !cbor_map_add(item, kv[2])) {
+ fido_log_debug("%s: x5c", __func__);
+ goto fail;
+ }
+
+ if ((out->len = cbor_serialize_alloc(item, &out->ptr,
+ &alloc_len)) == 0) {
+ fido_log_debug("%s: cbor_serialize_alloc", __func__);
+ goto fail;
+ }
+
+ ok = 0;
+fail:
+ if (item != NULL)
+ cbor_decref(&item);
+ if (x5c_cbor != NULL)
+ cbor_decref(&x5c_cbor);
+
+ for (size_t i = 0; i < nitems(kv); i++) {
+ if (kv[i].key)
+ cbor_decref(&kv[i].key);
+ if (kv[i].value)
+ cbor_decref(&kv[i].value);
+ }
+
+ return (ok);
+}
+
+static int
encode_cred_authdata(const char *rp_id, const uint8_t *kh, uint8_t kh_len,
const uint8_t *pubkey, size_t pubkey_len, fido_blob_t *out)
{
@@ -476,6 +562,7 @@ parse_register_reply(fido_cred_t *cred, const unsigned char *reply, size_t len)
fido_blob_t x5c;
fido_blob_t sig;
fido_blob_t ad;
+ fido_blob_t stmt;
uint8_t dummy;
uint8_t pubkey[65];
uint8_t kh_len = 0;
@@ -485,6 +572,7 @@ parse_register_reply(fido_cred_t *cred, const unsigned char *reply, size_t len)
memset(&x5c, 0, sizeof(x5c));
memset(&sig, 0, sizeof(sig));
memset(&ad, 0, sizeof(ad));
+ memset(&stmt, 0, sizeof(stmt));
r = FIDO_ERR_RX;
/* status word */
@@ -518,6 +606,12 @@ parse_register_reply(fido_cred_t *cred, const unsigned char *reply, size_t len)
goto fail;
}
+ /* attstmt */
+ if (encode_cred_attstmt(COSE_ES256, &x5c, &sig, &stmt) < 0) {
+ fido_log_debug("%s: encode_cred_attstmt", __func__);
+ goto fail;
+ }
+
/* authdata */
if (encode_cred_authdata(cred->rp.id, kh, kh_len, pubkey,
sizeof(pubkey), &ad) < 0) {
@@ -527,8 +621,7 @@ parse_register_reply(fido_cred_t *cred, const unsigned char *reply, size_t len)
if (fido_cred_set_fmt(cred, "fido-u2f") != FIDO_OK ||
fido_cred_set_authdata(cred, ad.ptr, ad.len) != FIDO_OK ||
- fido_cred_set_x509(cred, x5c.ptr, x5c.len) != FIDO_OK ||
- fido_cred_set_sig(cred, sig.ptr, sig.len) != FIDO_OK) {
+ fido_cred_set_attstmt(cred, stmt.ptr, stmt.len) != FIDO_OK) {
fido_log_debug("%s: fido_cred_set", __func__);
r = FIDO_ERR_INTERNAL;
goto fail;
@@ -540,12 +633,13 @@ fail:
fido_blob_reset(&x5c);
fido_blob_reset(&sig);
fido_blob_reset(&ad);
+ fido_blob_reset(&stmt);
return (r);
}
int
-u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms)
+u2f_register(fido_dev_t *dev, fido_cred_t *cred, int *ms)
{
iso7816_apdu_t *apdu = NULL;
unsigned char rp_id_hash[SHA256_DIGEST_LENGTH];
@@ -554,10 +648,6 @@ u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms)
int found;
int r;
-#ifdef FIDO_FUZZ
- ms = 0; /* XXX */
-#endif
-
if (cred->rk == FIDO_OPT_TRUE || cred->uv == FIDO_OPT_TRUE) {
fido_log_debug("%s: rk=%d, uv=%d", __func__, cred->rk,
cred->uv);
@@ -606,7 +696,7 @@ u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms)
do {
if (fido_tx(dev, CTAP_CMD_MSG, iso7816_ptr(apdu),
- iso7816_len(apdu)) < 0) {
+ iso7816_len(apdu), ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -617,8 +707,8 @@ u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms)
r = FIDO_ERR_RX;
goto fail;
}
- if (usleep((unsigned)(ms == -1 ? 100 : ms) * 1000) < 0) {
- fido_log_debug("%s: usleep", __func__);
+ if (delay_ms(U2F_PACE_MS, ms) != 0) {
+ fido_log_debug("%s: delay_ms", __func__);
r = FIDO_ERR_RX;
goto fail;
}
@@ -637,7 +727,7 @@ fail:
static int
u2f_authenticate_single(fido_dev_t *dev, const fido_blob_t *key_id,
- fido_assert_t *fa, size_t idx, int ms)
+ fido_assert_t *fa, size_t idx, int *ms)
{
fido_blob_t sig;
fido_blob_t ad;
@@ -692,7 +782,7 @@ fail:
}
int
-u2f_authenticate(fido_dev_t *dev, fido_assert_t *fa, int ms)
+u2f_authenticate(fido_dev_t *dev, fido_assert_t *fa, int *ms)
{
size_t nfound = 0;
size_t nauth_ok = 0;
@@ -739,7 +829,7 @@ u2f_authenticate(fido_dev_t *dev, fido_assert_t *fa, int ms)
}
int
-u2f_get_touch_begin(fido_dev_t *dev)
+u2f_get_touch_begin(fido_dev_t *dev, int *ms)
{
iso7816_apdu_t *apdu = NULL;
const char *clientdata = FIDO_DUMMY_CLIENTDATA;
@@ -769,12 +859,12 @@ u2f_get_touch_begin(fido_dev_t *dev)
}
if (dev->attr.flags & FIDO_CAP_WINK) {
- fido_tx(dev, CTAP_CMD_WINK, NULL, 0);
- fido_rx(dev, CTAP_CMD_WINK, &reply, sizeof(reply), 200);
+ fido_tx(dev, CTAP_CMD_WINK, NULL, 0, ms);
+ fido_rx(dev, CTAP_CMD_WINK, &reply, sizeof(reply), ms);
}
if (fido_tx(dev, CTAP_CMD_MSG, iso7816_ptr(apdu),
- iso7816_len(apdu)) < 0) {
+ iso7816_len(apdu), ms) < 0) {
fido_log_debug("%s: fido_tx", __func__);
r = FIDO_ERR_TX;
goto fail;
@@ -788,7 +878,7 @@ fail:
}
int
-u2f_get_touch_status(fido_dev_t *dev, int *touched, int ms)
+u2f_get_touch_status(fido_dev_t *dev, int *touched, int *ms)
{
unsigned char reply[FIDO_MAXMSG];
int reply_len;
@@ -802,7 +892,7 @@ u2f_get_touch_status(fido_dev_t *dev, int *touched, int ms)
switch ((reply[reply_len - 2] << 8) | reply[reply_len - 1]) {
case SW_CONDITIONS_NOT_SATISFIED:
- if ((r = u2f_get_touch_begin(dev)) != FIDO_OK) {
+ if ((r = u2f_get_touch_begin(dev, ms)) != FIDO_OK) {
fido_log_debug("%s: u2f_get_touch_begin", __func__);
return (r);
}
diff --git a/contrib/libfido2/src/webauthn.h b/contrib/libfido2/src/webauthn.h
new file mode 100644
index 000000000000..5fbdd6faa927
--- /dev/null
+++ b/contrib/libfido2/src/webauthn.h
@@ -0,0 +1,839 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#ifndef __WEBAUTHN_H_
+#define __WEBAUTHN_H_
+
+#pragma once
+
+#include <winapifamily.h>
+
+#pragma region Desktop Family or OneCore Family
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef WINAPI
+#define WINAPI __stdcall
+#endif
+
+#ifndef INITGUID
+#define INITGUID
+#include <guiddef.h>
+#undef INITGUID
+#else
+#include <guiddef.h>
+#endif
+
+//+------------------------------------------------------------------------------------------
+// API Version Information.
+// Caller should check for WebAuthNGetApiVersionNumber to check the presence of relevant APIs
+// and features for their usage.
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_API_VERSION_1 1
+// WEBAUTHN_API_VERSION_1 : Baseline Version
+// Data Structures and their sub versions:
+// - WEBAUTHN_RP_ENTITY_INFORMATION : 1
+// - WEBAUTHN_USER_ENTITY_INFORMATION : 1
+// - WEBAUTHN_CLIENT_DATA : 1
+// - WEBAUTHN_COSE_CREDENTIAL_PARAMETER : 1
+// - WEBAUTHN_COSE_CREDENTIAL_PARAMETERS : Not Applicable
+// - WEBAUTHN_CREDENTIAL : 1
+// - WEBAUTHN_CREDENTIALS : Not Applicable
+// - WEBAUTHN_CREDENTIAL_EX : 1
+// - WEBAUTHN_CREDENTIAL_LIST : Not Applicable
+// - WEBAUTHN_EXTENSION : Not Applicable
+// - WEBAUTHN_EXTENSIONS : Not Applicable
+// - WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS : 3
+// - WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS : 4
+// - WEBAUTHN_COMMON_ATTESTATION : 1
+// - WEBAUTHN_CREDENTIAL_ATTESTATION : 3
+// - WEBAUTHN_ASSERTION : 1
+// Extensions:
+// - WEBAUTHN_EXTENSIONS_IDENTIFIER_HMAC_SECRET
+// APIs:
+// - WebAuthNGetApiVersionNumber
+// - WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable
+// - WebAuthNAuthenticatorMakeCredential
+// - WebAuthNAuthenticatorGetAssertion
+// - WebAuthNFreeCredentialAttestation
+// - WebAuthNFreeAssertion
+// - WebAuthNGetCancellationId
+// - WebAuthNCancelCurrentOperation
+// - WebAuthNGetErrorName
+// - WebAuthNGetW3CExceptionDOMError
+
+#define WEBAUTHN_API_VERSION_2 2
+// WEBAUTHN_API_VERSION_2 : Delta From WEBAUTHN_API_VERSION_1
+// Added Extensions:
+// - WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT
+//
+
+#define WEBAUTHN_API_VERSION_3 3
+// WEBAUTHN_API_VERSION_3 : Delta From WEBAUTHN_API_VERSION_2
+// Data Structures and their sub versions:
+// - WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS : 4
+// - WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS : 5
+// - WEBAUTHN_CREDENTIAL_ATTESTATION : 4
+// - WEBAUTHN_ASSERTION : 2
+// Added Extensions:
+// - WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_BLOB
+// - WEBAUTHN_EXTENSIONS_IDENTIFIER_MIN_PIN_LENGTH
+//
+
+#define WEBAUTHN_API_CURRENT_VERSION WEBAUTHN_API_VERSION_3
+
+//+------------------------------------------------------------------------------------------
+// Information about an RP Entity
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_RP_ENTITY_INFORMATION_CURRENT_VERSION 1
+
+typedef struct _WEBAUTHN_RP_ENTITY_INFORMATION {
+ // Version of this structure, to allow for modifications in the future.
+ // This field is required and should be set to CURRENT_VERSION above.
+ DWORD dwVersion;
+
+ // Identifier for the RP. This field is required.
+ PCWSTR pwszId;
+
+ // Contains the friendly name of the Relying Party, such as "Acme Corporation", "Widgets Inc" or "Awesome Site".
+ // This field is required.
+ PCWSTR pwszName;
+
+ // Optional URL pointing to RP's logo.
+ PCWSTR pwszIcon;
+} WEBAUTHN_RP_ENTITY_INFORMATION, *PWEBAUTHN_RP_ENTITY_INFORMATION;
+typedef const WEBAUTHN_RP_ENTITY_INFORMATION *PCWEBAUTHN_RP_ENTITY_INFORMATION;
+
+//+------------------------------------------------------------------------------------------
+// Information about an User Entity
+//-------------------------------------------------------------------------------------------
+#define WEBAUTHN_MAX_USER_ID_LENGTH 64
+
+#define WEBAUTHN_USER_ENTITY_INFORMATION_CURRENT_VERSION 1
+
+typedef struct _WEBAUTHN_USER_ENTITY_INFORMATION {
+ // Version of this structure, to allow for modifications in the future.
+ // This field is required and should be set to CURRENT_VERSION above.
+ DWORD dwVersion;
+
+ // Identifier for the User. This field is required.
+ DWORD cbId;
+ _Field_size_bytes_(cbId)
+ PBYTE pbId;
+
+ // Contains a detailed name for this account, such as "john.p.smith@example.com".
+ PCWSTR pwszName;
+
+ // Optional URL that can be used to retrieve an image containing the user's current avatar,
+ // or a data URI that contains the image data.
+ PCWSTR pwszIcon;
+
+ // For User: Contains the friendly name associated with the user account by the Relying Party, such as "John P. Smith".
+ PCWSTR pwszDisplayName;
+} WEBAUTHN_USER_ENTITY_INFORMATION, *PWEBAUTHN_USER_ENTITY_INFORMATION;
+typedef const WEBAUTHN_USER_ENTITY_INFORMATION *PCWEBAUTHN_USER_ENTITY_INFORMATION;
+
+//+------------------------------------------------------------------------------------------
+// Information about client data.
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_HASH_ALGORITHM_SHA_256 L"SHA-256"
+#define WEBAUTHN_HASH_ALGORITHM_SHA_384 L"SHA-384"
+#define WEBAUTHN_HASH_ALGORITHM_SHA_512 L"SHA-512"
+
+#define WEBAUTHN_CLIENT_DATA_CURRENT_VERSION 1
+
+typedef struct _WEBAUTHN_CLIENT_DATA {
+ // Version of this structure, to allow for modifications in the future.
+ // This field is required and should be set to CURRENT_VERSION above.
+ DWORD dwVersion;
+
+ // Size of the pbClientDataJSON field.
+ DWORD cbClientDataJSON;
+ // UTF-8 encoded JSON serialization of the client data.
+ _Field_size_bytes_(cbClientDataJSON)
+ PBYTE pbClientDataJSON;
+
+ // Hash algorithm ID used to hash the pbClientDataJSON field.
+ LPCWSTR pwszHashAlgId;
+} WEBAUTHN_CLIENT_DATA, *PWEBAUTHN_CLIENT_DATA;
+typedef const WEBAUTHN_CLIENT_DATA *PCWEBAUTHN_CLIENT_DATA;
+
+//+------------------------------------------------------------------------------------------
+// Information about credential parameters.
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_CREDENTIAL_TYPE_PUBLIC_KEY L"public-key"
+
+#define WEBAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256 -7
+#define WEBAUTHN_COSE_ALGORITHM_ECDSA_P384_WITH_SHA384 -35
+#define WEBAUTHN_COSE_ALGORITHM_ECDSA_P521_WITH_SHA512 -36
+
+#define WEBAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA256 -257
+#define WEBAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA384 -258
+#define WEBAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA512 -259
+
+#define WEBAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA256 -37
+#define WEBAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA384 -38
+#define WEBAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA512 -39
+
+#define WEBAUTHN_COSE_CREDENTIAL_PARAMETER_CURRENT_VERSION 1
+
+typedef struct _WEBAUTHN_COSE_CREDENTIAL_PARAMETER {
+ // Version of this structure, to allow for modifications in the future.
+ DWORD dwVersion;
+
+ // Well-known credential type specifying a credential to create.
+ LPCWSTR pwszCredentialType;
+
+ // Well-known COSE algorithm specifying the algorithm to use for the credential.
+ LONG lAlg;
+} WEBAUTHN_COSE_CREDENTIAL_PARAMETER, *PWEBAUTHN_COSE_CREDENTIAL_PARAMETER;
+typedef const WEBAUTHN_COSE_CREDENTIAL_PARAMETER *PCWEBAUTHN_COSE_CREDENTIAL_PARAMETER;
+
+typedef struct _WEBAUTHN_COSE_CREDENTIAL_PARAMETERS {
+ DWORD cCredentialParameters;
+ _Field_size_(cCredentialParameters)
+ PWEBAUTHN_COSE_CREDENTIAL_PARAMETER pCredentialParameters;
+} WEBAUTHN_COSE_CREDENTIAL_PARAMETERS, *PWEBAUTHN_COSE_CREDENTIAL_PARAMETERS;
+typedef const WEBAUTHN_COSE_CREDENTIAL_PARAMETERS *PCWEBAUTHN_COSE_CREDENTIAL_PARAMETERS;
+
+//+------------------------------------------------------------------------------------------
+// Information about credential.
+//-------------------------------------------------------------------------------------------
+#define WEBAUTHN_CREDENTIAL_CURRENT_VERSION 1
+
+typedef struct _WEBAUTHN_CREDENTIAL {
+ // Version of this structure, to allow for modifications in the future.
+ DWORD dwVersion;
+
+ // Size of pbID.
+ DWORD cbId;
+ // Unique ID for this particular credential.
+ _Field_size_bytes_(cbId)
+ PBYTE pbId;
+
+ // Well-known credential type specifying what this particular credential is.
+ LPCWSTR pwszCredentialType;
+} WEBAUTHN_CREDENTIAL, *PWEBAUTHN_CREDENTIAL;
+typedef const WEBAUTHN_CREDENTIAL *PCWEBAUTHN_CREDENTIAL;
+
+typedef struct _WEBAUTHN_CREDENTIALS {
+ DWORD cCredentials;
+ _Field_size_(cCredentials)
+ PWEBAUTHN_CREDENTIAL pCredentials;
+} WEBAUTHN_CREDENTIALS, *PWEBAUTHN_CREDENTIALS;
+typedef const WEBAUTHN_CREDENTIALS *PCWEBAUTHN_CREDENTIALS;
+
+//+------------------------------------------------------------------------------------------
+// Information about credential with extra information, such as, dwTransports
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_CTAP_TRANSPORT_USB 0x00000001
+#define WEBAUTHN_CTAP_TRANSPORT_NFC 0x00000002
+#define WEBAUTHN_CTAP_TRANSPORT_BLE 0x00000004
+#define WEBAUTHN_CTAP_TRANSPORT_TEST 0x00000008
+#define WEBAUTHN_CTAP_TRANSPORT_INTERNAL 0x00000010
+#define WEBAUTHN_CTAP_TRANSPORT_FLAGS_MASK 0x0000001F
+
+#define WEBAUTHN_CREDENTIAL_EX_CURRENT_VERSION 1
+
+typedef struct _WEBAUTHN_CREDENTIAL_EX {
+ // Version of this structure, to allow for modifications in the future.
+ DWORD dwVersion;
+
+ // Size of pbID.
+ DWORD cbId;
+ // Unique ID for this particular credential.
+ _Field_size_bytes_(cbId)
+ PBYTE pbId;
+
+ // Well-known credential type specifying what this particular credential is.
+ LPCWSTR pwszCredentialType;
+
+ // Transports. 0 implies no transport restrictions.
+ DWORD dwTransports;
+} WEBAUTHN_CREDENTIAL_EX, *PWEBAUTHN_CREDENTIAL_EX;
+typedef const WEBAUTHN_CREDENTIAL_EX *PCWEBAUTHN_CREDENTIAL_EX;
+
+//+------------------------------------------------------------------------------------------
+// Information about credential list with extra information
+//-------------------------------------------------------------------------------------------
+
+typedef struct _WEBAUTHN_CREDENTIAL_LIST {
+ DWORD cCredentials;
+ _Field_size_(cCredentials)
+ PWEBAUTHN_CREDENTIAL_EX *ppCredentials;
+} WEBAUTHN_CREDENTIAL_LIST, *PWEBAUTHN_CREDENTIAL_LIST;
+typedef const WEBAUTHN_CREDENTIAL_LIST *PCWEBAUTHN_CREDENTIAL_LIST;
+
+//+------------------------------------------------------------------------------------------
+// Hmac-Secret extension
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_EXTENSIONS_IDENTIFIER_HMAC_SECRET L"hmac-secret"
+// Below type definitions is for WEBAUTHN_EXTENSIONS_IDENTIFIER_HMAC_SECRET
+// MakeCredential Input Type: BOOL.
+// - pvExtension must point to a BOOL with the value TRUE.
+// - cbExtension must contain the sizeof(BOOL).
+// MakeCredential Output Type: BOOL.
+// - pvExtension will point to a BOOL with the value TRUE if credential
+// was successfully created with HMAC_SECRET.
+// - cbExtension will contain the sizeof(BOOL).
+// GetAssertion Input Type: Not Supported
+// GetAssertion Output Type: Not Supported
+
+//+------------------------------------------------------------------------------------------
+// credProtect extension
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_USER_VERIFICATION_ANY 0
+#define WEBAUTHN_USER_VERIFICATION_OPTIONAL 1
+#define WEBAUTHN_USER_VERIFICATION_OPTIONAL_WITH_CREDENTIAL_ID_LIST 2
+#define WEBAUTHN_USER_VERIFICATION_REQUIRED 3
+
+typedef struct _WEBAUTHN_CRED_PROTECT_EXTENSION_IN {
+ // One of the above WEBAUTHN_USER_VERIFICATION_* values
+ DWORD dwCredProtect;
+ // Set the following to TRUE to require authenticator support for the credProtect extension
+ BOOL bRequireCredProtect;
+} WEBAUTHN_CRED_PROTECT_EXTENSION_IN, *PWEBAUTHN_CRED_PROTECT_EXTENSION_IN;
+typedef const WEBAUTHN_CRED_PROTECT_EXTENSION_IN *PCWEBAUTHN_CRED_PROTECT_EXTENSION_IN;
+
+
+#define WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT L"credProtect"
+// Below type definitions is for WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT
+// MakeCredential Input Type: WEBAUTHN_CRED_PROTECT_EXTENSION_IN.
+// - pvExtension must point to a WEBAUTHN_CRED_PROTECT_EXTENSION_IN struct
+// - cbExtension will contain the sizeof(WEBAUTHN_CRED_PROTECT_EXTENSION_IN).
+// MakeCredential Output Type: DWORD.
+// - pvExtension will point to a DWORD with one of the above WEBAUTHN_USER_VERIFICATION_* values
+// if credential was successfully created with CRED_PROTECT.
+// - cbExtension will contain the sizeof(DWORD).
+// GetAssertion Input Type: Not Supported
+// GetAssertion Output Type: Not Supported
+
+//+------------------------------------------------------------------------------------------
+// credBlob extension
+//-------------------------------------------------------------------------------------------
+
+typedef struct _WEBAUTHN_CRED_BLOB_EXTENSION {
+ // Size of pbCredBlob.
+ DWORD cbCredBlob;
+ _Field_size_bytes_(cbCredBlob)
+ PBYTE pbCredBlob;
+} WEBAUTHN_CRED_BLOB_EXTENSION, *PWEBAUTHN_CRED_BLOB_EXTENSION;
+typedef const WEBAUTHN_CRED_BLOB_EXTENSION *PCWEBAUTHN_CRED_BLOB_EXTENSION;
+
+
+#define WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_BLOB L"credBlob"
+// Below type definitions is for WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_BLOB
+// MakeCredential Input Type: WEBAUTHN_CRED_BLOB_EXTENSION.
+// - pvExtension must point to a WEBAUTHN_CRED_BLOB_EXTENSION struct
+// - cbExtension must contain the sizeof(WEBAUTHN_CRED_BLOB_EXTENSION).
+// MakeCredential Output Type: BOOL.
+// - pvExtension will point to a BOOL with the value TRUE if credBlob was successfully created
+// - cbExtension will contain the sizeof(BOOL).
+// GetAssertion Input Type: BOOL.
+// - pvExtension must point to a BOOL with the value TRUE to request the credBlob.
+// - cbExtension must contain the sizeof(BOOL).
+// GetAssertion Output Type: WEBAUTHN_CRED_BLOB_EXTENSION.
+// - pvExtension will point to a WEBAUTHN_CRED_BLOB_EXTENSION struct if the authenticator
+// returns the credBlob in the signed extensions
+// - cbExtension will contain the sizeof(WEBAUTHN_CRED_BLOB_EXTENSION).
+
+//+------------------------------------------------------------------------------------------
+// minPinLength extension
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_EXTENSIONS_IDENTIFIER_MIN_PIN_LENGTH L"minPinLength"
+// Below type definitions is for WEBAUTHN_EXTENSIONS_IDENTIFIER_MIN_PIN_LENGTH
+// MakeCredential Input Type: BOOL.
+// - pvExtension must point to a BOOL with the value TRUE to request the minPinLength.
+// - cbExtension must contain the sizeof(BOOL).
+// MakeCredential Output Type: DWORD.
+// - pvExtension will point to a DWORD with the minimum pin length if returned by the authenticator
+// - cbExtension will contain the sizeof(DWORD).
+// GetAssertion Input Type: Not Supported
+// GetAssertion Output Type: Not Supported
+
+//+------------------------------------------------------------------------------------------
+// Information about Extensions.
+//-------------------------------------------------------------------------------------------
+typedef struct _WEBAUTHN_EXTENSION {
+ LPCWSTR pwszExtensionIdentifier;
+ DWORD cbExtension;
+ PVOID pvExtension;
+} WEBAUTHN_EXTENSION, *PWEBAUTHN_EXTENSION;
+typedef const WEBAUTHN_EXTENSION *PCWEBAUTHN_EXTENSION;
+
+typedef struct _WEBAUTHN_EXTENSIONS {
+ DWORD cExtensions;
+ _Field_size_(cExtensions)
+ PWEBAUTHN_EXTENSION pExtensions;
+} WEBAUTHN_EXTENSIONS, *PWEBAUTHN_EXTENSIONS;
+typedef const WEBAUTHN_EXTENSIONS *PCWEBAUTHN_EXTENSIONS;
+
+//+------------------------------------------------------------------------------------------
+// Options.
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_AUTHENTICATOR_ATTACHMENT_ANY 0
+#define WEBAUTHN_AUTHENTICATOR_ATTACHMENT_PLATFORM 1
+#define WEBAUTHN_AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM 2
+#define WEBAUTHN_AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM_U2F_V2 3
+
+#define WEBAUTHN_USER_VERIFICATION_REQUIREMENT_ANY 0
+#define WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED 1
+#define WEBAUTHN_USER_VERIFICATION_REQUIREMENT_PREFERRED 2
+#define WEBAUTHN_USER_VERIFICATION_REQUIREMENT_DISCOURAGED 3
+
+#define WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_ANY 0
+#define WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_NONE 1
+#define WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_INDIRECT 2
+#define WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_DIRECT 3
+
+#define WEBAUTHN_ENTERPRISE_ATTESTATION_NONE 0
+#define WEBAUTHN_ENTERPRISE_ATTESTATION_VENDOR_FACILITATED 1
+#define WEBAUTHN_ENTERPRISE_ATTESTATION_PLATFORM_MANAGED 2
+
+#define WEBAUTHN_LARGE_BLOB_SUPPORT_NONE 0
+#define WEBAUTHN_LARGE_BLOB_SUPPORT_REQUIRED 1
+#define WEBAUTHN_LARGE_BLOB_SUPPORT_PREFERRED 2
+
+#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_1 1
+#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_2 2
+#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_3 3
+#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_4 4
+#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_4
+
+typedef struct _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS {
+ // Version of this structure, to allow for modifications in the future.
+ DWORD dwVersion;
+
+ // Time that the operation is expected to complete within.
+ // This is used as guidance, and can be overridden by the platform.
+ DWORD dwTimeoutMilliseconds;
+
+ // Credentials used for exclusion.
+ WEBAUTHN_CREDENTIALS CredentialList;
+
+ // Optional extensions to parse when performing the operation.
+ WEBAUTHN_EXTENSIONS Extensions;
+
+ // Optional. Platform vs Cross-Platform Authenticators.
+ DWORD dwAuthenticatorAttachment;
+
+ // Optional. Require key to be resident or not. Defaulting to FALSE.
+ BOOL bRequireResidentKey;
+
+ // User Verification Requirement.
+ DWORD dwUserVerificationRequirement;
+
+ // Attestation Conveyance Preference.
+ DWORD dwAttestationConveyancePreference;
+
+ // Reserved for future Use
+ DWORD dwFlags;
+
+ //
+ // The following fields have been added in WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_2
+ //
+
+ // Cancellation Id - Optional - See WebAuthNGetCancellationId
+ GUID *pCancellationId;
+
+ //
+ // The following fields have been added in WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_3
+ //
+
+ // Exclude Credential List. If present, "CredentialList" will be ignored.
+ PWEBAUTHN_CREDENTIAL_LIST pExcludeCredentialList;
+
+ //
+ // The following fields have been added in WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_4
+ //
+
+ // Enterprise Attestation
+ DWORD dwEnterpriseAttestation;
+
+ // Large Blob Support: none, required or preferred
+ //
+ // NTE_INVALID_PARAMETER when large blob required or preferred and
+ // both bRequireResidentKey and bPreferResidentKey are set to FALSE.
+ DWORD dwLargeBlobSupport;
+
+ // Optional. Prefer key to be resident. Defaulting to FALSE. When TRUE,
+ // overrides the above bRequireResidentKey.
+ BOOL bPreferResidentKey;
+
+} WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS, *PWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS;
+typedef const WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS *PCWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS;
+
+#define WEBAUTHN_CRED_LARGE_BLOB_OPERATION_NONE 0
+#define WEBAUTHN_CRED_LARGE_BLOB_OPERATION_GET 1
+#define WEBAUTHN_CRED_LARGE_BLOB_OPERATION_SET 2
+#define WEBAUTHN_CRED_LARGE_BLOB_OPERATION_DELETE 3
+
+#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_1 1
+#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_2 2
+#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_3 3
+#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_4 4
+#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_5 5
+#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_5
+
+typedef struct _WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS {
+ // Version of this structure, to allow for modifications in the future.
+ DWORD dwVersion;
+
+ // Time that the operation is expected to complete within.
+ // This is used as guidance, and can be overridden by the platform.
+ DWORD dwTimeoutMilliseconds;
+
+ // Allowed Credentials List.
+ WEBAUTHN_CREDENTIALS CredentialList;
+
+ // Optional extensions to parse when performing the operation.
+ WEBAUTHN_EXTENSIONS Extensions;
+
+ // Optional. Platform vs Cross-Platform Authenticators.
+ DWORD dwAuthenticatorAttachment;
+
+ // User Verification Requirement.
+ DWORD dwUserVerificationRequirement;
+
+ // Reserved for future Use
+ DWORD dwFlags;
+
+ //
+ // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_2
+ //
+
+ // Optional identifier for the U2F AppId. Converted to UTF8 before being hashed. Not lower cased.
+ PCWSTR pwszU2fAppId;
+
+ // If the following is non-NULL, then, set to TRUE if the above pwszU2fAppid was used instead of
+ // PCWSTR pwszRpId;
+ BOOL *pbU2fAppId;
+
+ //
+ // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_3
+ //
+
+ // Cancellation Id - Optional - See WebAuthNGetCancellationId
+ GUID *pCancellationId;
+
+ //
+ // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_4
+ //
+
+ // Allow Credential List. If present, "CredentialList" will be ignored.
+ PWEBAUTHN_CREDENTIAL_LIST pAllowCredentialList;
+
+ //
+ // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_5
+ //
+
+ DWORD dwCredLargeBlobOperation;
+
+ // Size of pbCredLargeBlob
+ DWORD cbCredLargeBlob;
+ _Field_size_bytes_(cbCredLargeBlob)
+ PBYTE pbCredLargeBlob;
+} WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS, *PWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS;
+typedef const WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS *PCWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS;
+
+
+//+------------------------------------------------------------------------------------------
+// Attestation Info.
+//
+//-------------------------------------------------------------------------------------------
+#define WEBAUTHN_ATTESTATION_DECODE_NONE 0
+#define WEBAUTHN_ATTESTATION_DECODE_COMMON 1
+// WEBAUTHN_ATTESTATION_DECODE_COMMON supports format types
+// L"packed"
+// L"fido-u2f"
+
+#define WEBAUTHN_ATTESTATION_VER_TPM_2_0 L"2.0"
+
+typedef struct _WEBAUTHN_X5C {
+ // Length of X.509 encoded certificate
+ DWORD cbData;
+ // X.509 encoded certificate bytes
+ _Field_size_bytes_(cbData)
+ PBYTE pbData;
+} WEBAUTHN_X5C, *PWEBAUTHN_X5C;
+
+// Supports either Self or Full Basic Attestation
+
+// Note, new fields will be added to the following data structure to
+// support additional attestation format types, such as, TPM.
+// When fields are added, the dwVersion will be incremented.
+//
+// Therefore, your code must make the following check:
+// "if (dwVersion >= WEBAUTHN_COMMON_ATTESTATION_CURRENT_VERSION)"
+
+#define WEBAUTHN_COMMON_ATTESTATION_CURRENT_VERSION 1
+
+typedef struct _WEBAUTHN_COMMON_ATTESTATION {
+ // Version of this structure, to allow for modifications in the future.
+ DWORD dwVersion;
+
+ // Hash and Padding Algorithm
+ //
+ // The following won't be set for "fido-u2f" which assumes "ES256".
+ PCWSTR pwszAlg;
+ LONG lAlg; // COSE algorithm
+
+ // Signature that was generated for this attestation.
+ DWORD cbSignature;
+ _Field_size_bytes_(cbSignature)
+ PBYTE pbSignature;
+
+ // Following is set for Full Basic Attestation. If not, set then, this is Self Attestation.
+ // Array of X.509 DER encoded certificates. The first certificate is the signer, leaf certificate.
+ DWORD cX5c;
+ _Field_size_(cX5c)
+ PWEBAUTHN_X5C pX5c;
+
+ // Following are also set for tpm
+ PCWSTR pwszVer; // L"2.0"
+ DWORD cbCertInfo;
+ _Field_size_bytes_(cbCertInfo)
+ PBYTE pbCertInfo;
+ DWORD cbPubArea;
+ _Field_size_bytes_(cbPubArea)
+ PBYTE pbPubArea;
+} WEBAUTHN_COMMON_ATTESTATION, *PWEBAUTHN_COMMON_ATTESTATION;
+typedef const WEBAUTHN_COMMON_ATTESTATION *PCWEBAUTHN_COMMON_ATTESTATION;
+
+#define WEBAUTHN_ATTESTATION_TYPE_PACKED L"packed"
+#define WEBAUTHN_ATTESTATION_TYPE_U2F L"fido-u2f"
+#define WEBAUTHN_ATTESTATION_TYPE_TPM L"tpm"
+#define WEBAUTHN_ATTESTATION_TYPE_NONE L"none"
+
+#define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_1 1
+#define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_2 2
+#define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_3 3
+#define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_4 4
+#define WEBAUTHN_CREDENTIAL_ATTESTATION_CURRENT_VERSION WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_4
+
+typedef struct _WEBAUTHN_CREDENTIAL_ATTESTATION {
+ // Version of this structure, to allow for modifications in the future.
+ DWORD dwVersion;
+
+ // Attestation format type
+ PCWSTR pwszFormatType;
+
+ // Size of cbAuthenticatorData.
+ DWORD cbAuthenticatorData;
+ // Authenticator data that was created for this credential.
+ _Field_size_bytes_(cbAuthenticatorData)
+ PBYTE pbAuthenticatorData;
+
+ // Size of CBOR encoded attestation information
+ //0 => encoded as CBOR null value.
+ DWORD cbAttestation;
+ //Encoded CBOR attestation information
+ _Field_size_bytes_(cbAttestation)
+ PBYTE pbAttestation;
+
+ DWORD dwAttestationDecodeType;
+ // Following depends on the dwAttestationDecodeType
+ // WEBAUTHN_ATTESTATION_DECODE_NONE
+ // NULL - not able to decode the CBOR attestation information
+ // WEBAUTHN_ATTESTATION_DECODE_COMMON
+ // PWEBAUTHN_COMMON_ATTESTATION;
+ PVOID pvAttestationDecode;
+
+ // The CBOR encoded Attestation Object to be returned to the RP.
+ DWORD cbAttestationObject;
+ _Field_size_bytes_(cbAttestationObject)
+ PBYTE pbAttestationObject;
+
+ // The CredentialId bytes extracted from the Authenticator Data.
+ // Used by Edge to return to the RP.
+ DWORD cbCredentialId;
+ _Field_size_bytes_(cbCredentialId)
+ PBYTE pbCredentialId;
+
+ //
+ // Following fields have been added in WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_2
+ //
+
+ WEBAUTHN_EXTENSIONS Extensions;
+
+ //
+ // Following fields have been added in WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_3
+ //
+
+ // One of the WEBAUTHN_CTAP_TRANSPORT_* bits will be set corresponding to
+ // the transport that was used.
+ DWORD dwUsedTransport;
+
+ //
+ // Following fields have been added in WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_4
+ //
+
+ BOOL bEpAtt;
+ BOOL bLargeBlobSupported;
+ BOOL bResidentKey;
+
+} WEBAUTHN_CREDENTIAL_ATTESTATION, *PWEBAUTHN_CREDENTIAL_ATTESTATION;
+typedef const WEBAUTHN_CREDENTIAL_ATTESTATION *PCWEBAUTHN_CREDENTIAL_ATTESTATION;
+
+
+//+------------------------------------------------------------------------------------------
+// authenticatorGetAssertion output.
+//-------------------------------------------------------------------------------------------
+
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_NONE 0
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_SUCCESS 1
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_NOT_SUPPORTED 2
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_INVALID_DATA 3
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_INVALID_PARAMETER 4
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_NOT_FOUND 5
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_MULTIPLE_CREDENTIALS 6
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_LACK_OF_SPACE 7
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_PLATFORM_ERROR 8
+#define WEBAUTHN_CRED_LARGE_BLOB_STATUS_AUTHENTICATOR_ERROR 9
+
+#define WEBAUTHN_ASSERTION_VERSION_1 1
+#define WEBAUTHN_ASSERTION_VERSION_2 2
+#define WEBAUTHN_ASSERTION_CURRENT_VERSION WEBAUTHN_ASSERTION_VERSION_2
+
+typedef struct _WEBAUTHN_ASSERTION {
+ // Version of this structure, to allow for modifications in the future.
+ DWORD dwVersion;
+
+ // Size of cbAuthenticatorData.
+ DWORD cbAuthenticatorData;
+ // Authenticator data that was created for this assertion.
+ _Field_size_bytes_(cbAuthenticatorData)
+ PBYTE pbAuthenticatorData;
+
+ // Size of pbSignature.
+ DWORD cbSignature;
+ // Signature that was generated for this assertion.
+ _Field_size_bytes_(cbSignature)
+ PBYTE pbSignature;
+
+ // Credential that was used for this assertion.
+ WEBAUTHN_CREDENTIAL Credential;
+
+ // Size of User Id
+ DWORD cbUserId;
+ // UserId
+ _Field_size_bytes_(cbUserId)
+ PBYTE pbUserId;
+
+ //
+ // Following fields have been added in WEBAUTHN_ASSERTION_VERSION_2
+ //
+
+ WEBAUTHN_EXTENSIONS Extensions;
+
+ // Size of pbCredLargeBlob
+ DWORD cbCredLargeBlob;
+ _Field_size_bytes_(cbCredLargeBlob)
+ PBYTE pbCredLargeBlob;
+
+ DWORD dwCredLargeBlobStatus;
+
+} WEBAUTHN_ASSERTION, *PWEBAUTHN_ASSERTION;
+typedef const WEBAUTHN_ASSERTION *PCWEBAUTHN_ASSERTION;
+
+//+------------------------------------------------------------------------------------------
+// APIs.
+//-------------------------------------------------------------------------------------------
+
+DWORD
+WINAPI
+WebAuthNGetApiVersionNumber();
+
+HRESULT
+WINAPI
+WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable(
+ _Out_ BOOL *pbIsUserVerifyingPlatformAuthenticatorAvailable);
+
+
+HRESULT
+WINAPI
+WebAuthNAuthenticatorMakeCredential(
+ _In_ HWND hWnd,
+ _In_ PCWEBAUTHN_RP_ENTITY_INFORMATION pRpInformation,
+ _In_ PCWEBAUTHN_USER_ENTITY_INFORMATION pUserInformation,
+ _In_ PCWEBAUTHN_COSE_CREDENTIAL_PARAMETERS pPubKeyCredParams,
+ _In_ PCWEBAUTHN_CLIENT_DATA pWebAuthNClientData,
+ _In_opt_ PCWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS pWebAuthNMakeCredentialOptions,
+ _Outptr_result_maybenull_ PWEBAUTHN_CREDENTIAL_ATTESTATION *ppWebAuthNCredentialAttestation);
+
+
+HRESULT
+WINAPI
+WebAuthNAuthenticatorGetAssertion(
+ _In_ HWND hWnd,
+ _In_ LPCWSTR pwszRpId,
+ _In_ PCWEBAUTHN_CLIENT_DATA pWebAuthNClientData,
+ _In_opt_ PCWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS pWebAuthNGetAssertionOptions,
+ _Outptr_result_maybenull_ PWEBAUTHN_ASSERTION *ppWebAuthNAssertion);
+
+void
+WINAPI
+WebAuthNFreeCredentialAttestation(
+ _In_opt_ PWEBAUTHN_CREDENTIAL_ATTESTATION pWebAuthNCredentialAttestation);
+
+void
+WINAPI
+WebAuthNFreeAssertion(
+ _In_ PWEBAUTHN_ASSERTION pWebAuthNAssertion);
+
+HRESULT
+WINAPI
+WebAuthNGetCancellationId(
+ _Out_ GUID* pCancellationId);
+
+HRESULT
+WINAPI
+WebAuthNCancelCurrentOperation(
+ _In_ const GUID* pCancellationId);
+
+//
+// Returns the following Error Names:
+// L"Success" - S_OK
+// L"InvalidStateError" - NTE_EXISTS
+// L"ConstraintError" - HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED),
+// NTE_NOT_SUPPORTED,
+// NTE_TOKEN_KEYSET_STORAGE_FULL
+// L"NotSupportedError" - NTE_INVALID_PARAMETER
+// L"NotAllowedError" - NTE_DEVICE_NOT_FOUND,
+// NTE_NOT_FOUND,
+// HRESULT_FROM_WIN32(ERROR_CANCELLED),
+// NTE_USER_CANCELLED,
+// HRESULT_FROM_WIN32(ERROR_TIMEOUT)
+// L"UnknownError" - All other hr values
+//
+PCWSTR
+WINAPI
+WebAuthNGetErrorName(
+ _In_ HRESULT hr);
+
+HRESULT
+WINAPI
+WebAuthNGetW3CExceptionDOMError(
+ _In_ HRESULT hr);
+
+
+#ifdef __cplusplus
+} // Balance extern "C" above
+#endif
+
+#endif // WINAPI_FAMILY_PARTITION
+#pragma endregion
+
+#endif // __WEBAUTHN_H_
diff --git a/contrib/libfido2/src/winhello.c b/contrib/libfido2/src/winhello.c
index 0fe5b4cfe4c7..4797ac58281e 100644
--- a/contrib/libfido2/src/winhello.c
+++ b/contrib/libfido2/src/winhello.c
@@ -8,9 +8,9 @@
#include <stdlib.h>
#include <windows.h>
-#include <webauthn.h>
#include "fido.h"
+#include "webauthn.h"
#define MAXCHARS 128
#define MAXCREDS 128
@@ -40,6 +40,87 @@ struct winhello_cred {
wchar_t *display_name;
};
+static TLS BOOL webauthn_loaded;
+static TLS HMODULE webauthn_handle;
+static TLS DWORD (*webauthn_get_api_version)(void);
+static TLS PCWSTR (*webauthn_strerr)(HRESULT);
+static TLS HRESULT (*webauthn_get_assert)(HWND, LPCWSTR,
+ PCWEBAUTHN_CLIENT_DATA,
+ PCWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS,
+ PWEBAUTHN_ASSERTION *);
+static TLS HRESULT (*webauthn_make_cred)(HWND,
+ PCWEBAUTHN_RP_ENTITY_INFORMATION,
+ PCWEBAUTHN_USER_ENTITY_INFORMATION,
+ PCWEBAUTHN_COSE_CREDENTIAL_PARAMETERS,
+ PCWEBAUTHN_CLIENT_DATA,
+ PCWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS,
+ PWEBAUTHN_CREDENTIAL_ATTESTATION *);
+static TLS void (*webauthn_free_assert)(PWEBAUTHN_ASSERTION);
+static TLS void (*webauthn_free_attest)(PWEBAUTHN_CREDENTIAL_ATTESTATION);
+
+static int
+webauthn_load(void)
+{
+ if (webauthn_loaded || webauthn_handle != NULL) {
+ fido_log_debug("%s: already loaded", __func__);
+ return -1;
+ }
+ if ((webauthn_handle = LoadLibrary("webauthn.dll")) == NULL) {
+ fido_log_debug("%s: LoadLibrary", __func__);
+ return -1;
+ }
+
+ if ((webauthn_get_api_version = (void *)GetProcAddress(webauthn_handle,
+ "WebAuthNGetApiVersionNumber")) == NULL) {
+ fido_log_debug("%s: WebAuthNGetApiVersionNumber", __func__);
+ goto fail;
+ }
+ if ((webauthn_strerr = (void *)GetProcAddress(webauthn_handle,
+ "WebAuthNGetErrorName")) == NULL) {
+ fido_log_debug("%s: WebAuthNGetErrorName", __func__);
+ goto fail;
+ }
+ if ((webauthn_get_assert = (void *)GetProcAddress(webauthn_handle,
+ "WebAuthNAuthenticatorGetAssertion")) == NULL) {
+ fido_log_debug("%s: WebAuthNAuthenticatorGetAssertion",
+ __func__);
+ goto fail;
+ }
+ if ((webauthn_make_cred = (void *)GetProcAddress(webauthn_handle,
+ "WebAuthNAuthenticatorMakeCredential")) == NULL) {
+ fido_log_debug("%s: WebAuthNAuthenticatorMakeCredential",
+ __func__);
+ goto fail;
+ }
+ if ((webauthn_free_assert = (void *)GetProcAddress(webauthn_handle,
+ "WebAuthNFreeAssertion")) == NULL) {
+ fido_log_debug("%s: WebAuthNFreeAssertion", __func__);
+ goto fail;
+ }
+ if ((webauthn_free_attest = (void *)GetProcAddress(webauthn_handle,
+ "WebAuthNFreeCredentialAttestation")) == NULL) {
+ fido_log_debug("%s: WebAuthNFreeCredentialAttestation",
+ __func__);
+ goto fail;
+ }
+
+ webauthn_loaded = true;
+
+ return 0;
+fail:
+ fido_log_debug("%s: GetProcAddress", __func__);
+ webauthn_get_api_version = NULL;
+ webauthn_strerr = NULL;
+ webauthn_get_assert = NULL;
+ webauthn_make_cred = NULL;
+ webauthn_free_assert = NULL;
+ webauthn_free_attest = NULL;
+ FreeLibrary(webauthn_handle);
+ webauthn_handle = NULL;
+
+ return -1;
+}
+
static wchar_t *
to_utf16(const char *utf8)
{
@@ -98,24 +179,6 @@ to_utf8(const wchar_t *utf16)
}
static int
-to_fido_str_array(fido_str_array_t *sa, const char **v, size_t n)
-{
- if ((sa->ptr = calloc(n, sizeof(char *))) == NULL) {
- fido_log_debug("%s: calloc", __func__);
- return -1;
- }
- for (size_t i = 0; i < n; i++) {
- if ((sa->ptr[i] = strdup(v[i])) == NULL) {
- fido_log_debug("%s: strdup", __func__);
- return -1;
- }
- sa->len++;
- }
-
- return 0;
-}
-
-static int
to_fido(HRESULT hr)
{
switch (hr) {
@@ -210,7 +273,7 @@ set_uv(DWORD *out, fido_opt_t uv, const char *pin)
static int
pack_rp(wchar_t **id, wchar_t **name, WEBAUTHN_RP_ENTITY_INFORMATION *out,
- fido_rp_t *in)
+ const fido_rp_t *in)
{
/* keep non-const copies of pwsz* for free() */
out->dwVersion = WEBAUTHN_RP_ENTITY_INFORMATION_CURRENT_VERSION;
@@ -227,7 +290,7 @@ pack_rp(wchar_t **id, wchar_t **name, WEBAUTHN_RP_ENTITY_INFORMATION *out,
static int
pack_user(wchar_t **name, wchar_t **icon, wchar_t **display_name,
- WEBAUTHN_USER_ENTITY_INFORMATION *out, fido_user_t *in)
+ WEBAUTHN_USER_ENTITY_INFORMATION *out, const fido_user_t *in)
{
if (in->id.ptr == NULL || in->id.len > ULONG_MAX) {
fido_log_debug("%s: id", __func__);
@@ -287,7 +350,7 @@ pack_cose(WEBAUTHN_COSE_CREDENTIAL_PARAMETER *alg,
}
static int
-pack_cred_ext(WEBAUTHN_EXTENSIONS *out, fido_cred_ext_t *in)
+pack_cred_ext(WEBAUTHN_EXTENSIONS *out, const fido_cred_ext_t *in)
{
WEBAUTHN_EXTENSION *e;
WEBAUTHN_CRED_PROTECT_EXTENSION_IN *p;
@@ -342,94 +405,7 @@ pack_cred_ext(WEBAUTHN_EXTENSIONS *out, fido_cred_ext_t *in)
}
static int
-unpack_fmt(fido_cred_t *cred, WEBAUTHN_CREDENTIAL_ATTESTATION *att)
-{
- char *fmt;
- int r;
-
- if ((fmt = to_utf8(att->pwszFormatType)) == NULL) {
- fido_log_debug("%s: fmt", __func__);
- return -1;
- }
- r = fido_cred_set_fmt(cred, fmt);
- free(fmt);
- fmt = NULL;
- if (r != FIDO_OK) {
- fido_log_debug("%s: fido_cred_set_fmt: %s", __func__,
- fido_strerr(r));
- return -1;
- }
-
- return 0;
-}
-
-static int
-unpack_cred_authdata(fido_cred_t *cred, WEBAUTHN_CREDENTIAL_ATTESTATION *att)
-{
- int r;
-
- if (att->cbAuthenticatorData > SIZE_MAX) {
- fido_log_debug("%s: cbAuthenticatorData", __func__);
- return -1;
- }
- if ((r = fido_cred_set_authdata_raw(cred, att->pbAuthenticatorData,
- (size_t)att->cbAuthenticatorData)) != FIDO_OK) {
- fido_log_debug("%s: fido_cred_set_authdata_raw: %s", __func__,
- fido_strerr(r));
- return -1;
- }
-
- return 0;
-}
-
-static int
-unpack_cred_sig(fido_cred_t *cred, WEBAUTHN_COMMON_ATTESTATION *attr)
-{
- int r;
-
- if (attr->cbSignature > SIZE_MAX) {
- fido_log_debug("%s: cbSignature", __func__);
- return -1;
- }
- if ((r = fido_cred_set_sig(cred, attr->pbSignature,
- (size_t)attr->cbSignature)) != FIDO_OK) {
- fido_log_debug("%s: fido_cred_set_sig: %s", __func__,
- fido_strerr(r));
- return -1;
- }
-
- return 0;
-}
-
-static int
-unpack_x5c(fido_cred_t *cred, WEBAUTHN_COMMON_ATTESTATION *attr)
-{
- int r;
-
- fido_log_debug("%s: %u cert(s)", __func__, attr->cX5c);
-
- if (attr->cX5c == 0)
- return 0; /* self-attestation */
- if (attr->lAlg != WEBAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256) {
- fido_log_debug("%s: lAlg %d", __func__, attr->lAlg);
- return -1;
- }
- if (attr->pX5c[0].cbData > SIZE_MAX) {
- fido_log_debug("%s: cbData", __func__);
- return -1;
- }
- if ((r = fido_cred_set_x509(cred, attr->pX5c[0].pbData,
- (size_t)attr->pX5c[0].cbData)) != FIDO_OK) {
- fido_log_debug("%s: fido_cred_set_x509: %s", __func__,
- fido_strerr(r));
- return -1;
- }
-
- return 0;
-}
-
-static int
-unpack_assert_authdata(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa)
+unpack_assert_authdata(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa)
{
int r;
@@ -448,7 +424,7 @@ unpack_assert_authdata(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa)
}
static int
-unpack_assert_sig(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa)
+unpack_assert_sig(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa)
{
int r;
@@ -467,7 +443,7 @@ unpack_assert_sig(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa)
}
static int
-unpack_cred_id(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa)
+unpack_cred_id(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa)
{
if (wa->Credential.cbId > SIZE_MAX) {
fido_log_debug("%s: Credential.cbId", __func__);
@@ -483,7 +459,7 @@ unpack_cred_id(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa)
}
static int
-unpack_user_id(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa)
+unpack_user_id(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa)
{
if (wa->cbUserId == 0)
return 0; /* user id absent */
@@ -501,8 +477,8 @@ unpack_user_id(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa)
}
static int
-translate_fido_assert(struct winhello_assert *ctx, fido_assert_t *assert,
- const char *pin)
+translate_fido_assert(struct winhello_assert *ctx, const fido_assert_t *assert,
+ const char *pin, int ms)
{
WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS *opt;
@@ -527,7 +503,7 @@ translate_fido_assert(struct winhello_assert *ctx, fido_assert_t *assert,
/* options */
opt = &ctx->opt;
opt->dwVersion = WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_1;
- opt->dwTimeoutMilliseconds = MAXMSEC;
+ opt->dwTimeoutMilliseconds = ms < 0 ? MAXMSEC : (DWORD)ms;
if (pack_credlist(&opt->CredentialList, &assert->allow_list) < 0) {
fido_log_debug("%s: pack_credlist", __func__);
return FIDO_ERR_INTERNAL;
@@ -541,7 +517,7 @@ translate_fido_assert(struct winhello_assert *ctx, fido_assert_t *assert,
}
static int
-translate_winhello_assert(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa)
+translate_winhello_assert(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa)
{
int r;
@@ -575,8 +551,8 @@ translate_winhello_assert(fido_assert_t *assert, WEBAUTHN_ASSERTION *wa)
}
static int
-translate_fido_cred(struct winhello_cred *ctx, fido_cred_t *cred,
- const char *pin)
+translate_fido_cred(struct winhello_cred *ctx, const fido_cred_t *cred,
+ const char *pin, int ms)
{
WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS *opt;
@@ -600,7 +576,9 @@ translate_fido_cred(struct winhello_cred *ctx, fido_cred_t *cred,
/* options */
opt = &ctx->opt;
opt->dwVersion = WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_1;
- opt->dwTimeoutMilliseconds = MAXMSEC;
+ opt->dwTimeoutMilliseconds = ms < 0 ? MAXMSEC : (DWORD)ms;
+ opt->dwAttestationConveyancePreference =
+ WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_DIRECT;
if (pack_credlist(&opt->CredentialList, &cred->excl) < 0) {
fido_log_debug("%s: pack_credlist", __func__);
return FIDO_ERR_INTERNAL;
@@ -609,7 +587,8 @@ translate_fido_cred(struct winhello_cred *ctx, fido_cred_t *cred,
fido_log_debug("%s: pack_cred_ext", __func__);
return FIDO_ERR_UNSUPPORTED_EXTENSION;
}
- if (set_uv(&opt->dwUserVerificationRequirement, cred->uv, pin) < 0) {
+ if (set_uv(&opt->dwUserVerificationRequirement, (cred->ext.mask &
+ FIDO_EXT_CRED_PROTECT) ? FIDO_OPT_TRUE : cred->uv, pin) < 0) {
fido_log_debug("%s: set_uv", __func__);
return FIDO_ERR_INTERNAL;
}
@@ -621,67 +600,94 @@ translate_fido_cred(struct winhello_cred *ctx, fido_cred_t *cred,
}
static int
-translate_winhello_cred(fido_cred_t *cred, WEBAUTHN_CREDENTIAL_ATTESTATION *att)
+decode_attobj(const cbor_item_t *key, const cbor_item_t *val, void *arg)
{
- if (unpack_fmt(cred, att) < 0) {
- fido_log_debug("%s: unpack_fmt", __func__);
- return FIDO_ERR_INTERNAL;
- }
- if (unpack_cred_authdata(cred, att) < 0) {
- fido_log_debug("%s: unpack_cred_authdata", __func__);
- return FIDO_ERR_INTERNAL;
+ fido_cred_t *cred = arg;
+ char *name = NULL;
+ int ok = -1;
+
+ if (cbor_string_copy(key, &name) < 0) {
+ fido_log_debug("%s: cbor type", __func__);
+ ok = 0; /* ignore */
+ goto fail;
}
- switch (att->dwAttestationDecodeType) {
- case WEBAUTHN_ATTESTATION_DECODE_NONE:
- if (att->pvAttestationDecode != NULL) {
- fido_log_debug("%s: pvAttestationDecode", __func__);
- return FIDO_ERR_INTERNAL;
+ if (!strcmp(name, "fmt")) {
+ if (cbor_decode_fmt(val, &cred->fmt) < 0) {
+ fido_log_debug("%s: cbor_decode_fmt", __func__);
+ goto fail;
}
- break;
- case WEBAUTHN_ATTESTATION_DECODE_COMMON:
- if (att->pvAttestationDecode == NULL) {
- fido_log_debug("%s: pvAttestationDecode", __func__);
- return FIDO_ERR_INTERNAL;
+ } else if (!strcmp(name, "attStmt")) {
+ if (cbor_decode_attstmt(val, &cred->attstmt) < 0) {
+ fido_log_debug("%s: cbor_decode_attstmt", __func__);
+ goto fail;
}
- if (unpack_cred_sig(cred, att->pvAttestationDecode) < 0) {
- fido_log_debug("%s: unpack_cred_sig", __func__);
- return FIDO_ERR_INTERNAL;
+ } else if (!strcmp(name, "authData")) {
+ if (cbor_decode_cred_authdata(val, cred->type,
+ &cred->authdata_cbor, &cred->authdata, &cred->attcred,
+ &cred->authdata_ext) < 0) {
+ fido_log_debug("%s: cbor_decode_cred_authdata",
+ __func__);
+ goto fail;
}
- if (unpack_x5c(cred, att->pvAttestationDecode) < 0) {
- fido_log_debug("%s: unpack_x5c", __func__);
- return FIDO_ERR_INTERNAL;
- }
- break;
- default:
- fido_log_debug("%s: dwAttestationDecodeType: %u", __func__,
- att->dwAttestationDecodeType);
- return FIDO_ERR_INTERNAL;
}
- return FIDO_OK;
+ ok = 0;
+fail:
+ free(name);
+
+ return (ok);
}
static int
-winhello_manifest(BOOL *present)
+translate_winhello_cred(fido_cred_t *cred, const WEBAUTHN_CREDENTIAL_ATTESTATION *att)
+{
+
+ cbor_item_t *item = NULL;
+ struct cbor_load_result cbor;
+ int r = FIDO_ERR_INTERNAL;
+
+ if (att->pbAttestationObject == NULL ||
+ att->cbAttestationObject > SIZE_MAX) {
+ fido_log_debug("%s: pbAttestationObject", __func__);
+ goto fail;
+ }
+ if ((item = cbor_load(att->pbAttestationObject,
+ (size_t)att->cbAttestationObject, &cbor)) == NULL) {
+ fido_log_debug("%s: cbor_load", __func__);
+ goto fail;
+ }
+ if (cbor_isa_map(item) == false ||
+ cbor_map_is_definite(item) == false ||
+ cbor_map_iter(item, cred, decode_attobj) < 0) {
+ fido_log_debug("%s: cbor type", __func__);
+ goto fail;
+ }
+
+ r = FIDO_OK;
+fail:
+ if (item != NULL)
+ cbor_decref(&item);
+
+ return r;
+}
+
+static int
+winhello_manifest(void)
{
DWORD n;
- HRESULT hr;
- int r = FIDO_OK;
- if ((n = WebAuthNGetApiVersionNumber()) < 1) {
+ if (!webauthn_loaded && webauthn_load() < 0) {
+ fido_log_debug("%s: webauthn_load", __func__);
+ return FIDO_ERR_INTERNAL;
+ }
+ if ((n = webauthn_get_api_version()) < 1) {
fido_log_debug("%s: unsupported api %u", __func__, n);
return FIDO_ERR_INTERNAL;
}
fido_log_debug("%s: api version %u", __func__, n);
- hr = WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable(present);
- if (hr != S_OK) {
- r = to_fido(hr);
- fido_log_debug("%s: %ls -> %s", __func__,
- WebAuthNGetErrorName(hr), fido_strerr(r));
- }
- return r;
+ return FIDO_OK;
}
static int
@@ -690,12 +696,11 @@ winhello_get_assert(HWND w, struct winhello_assert *ctx)
HRESULT hr;
int r = FIDO_OK;
- hr = WebAuthNAuthenticatorGetAssertion(w, ctx->rp_id, &ctx->cd,
- &ctx->opt, &ctx->assert);
- if (hr != S_OK) {
+ if ((hr = webauthn_get_assert(w, ctx->rp_id, &ctx->cd, &ctx->opt,
+ &ctx->assert)) != S_OK) {
r = to_fido(hr);
- fido_log_debug("%s: %ls -> %s", __func__,
- WebAuthNGetErrorName(hr), fido_strerr(r));
+ fido_log_debug("%s: %ls -> %s", __func__, webauthn_strerr(hr),
+ fido_strerr(r));
}
return r;
@@ -707,12 +712,11 @@ winhello_make_cred(HWND w, struct winhello_cred *ctx)
HRESULT hr;
int r = FIDO_OK;
- hr = WebAuthNAuthenticatorMakeCredential(w, &ctx->rp, &ctx->user,
- &ctx->cose, &ctx->cd, &ctx->opt, &ctx->att);
- if (hr != S_OK) {
+ if ((hr = webauthn_make_cred(w, &ctx->rp, &ctx->user, &ctx->cose,
+ &ctx->cd, &ctx->opt, &ctx->att)) != S_OK) {
r = to_fido(hr);
- fido_log_debug("%s: %ls -> %s", __func__,
- WebAuthNGetErrorName(hr), fido_strerr(r));
+ fido_log_debug("%s: %ls -> %s", __func__, webauthn_strerr(hr),
+ fido_strerr(r));
}
return r;
@@ -724,7 +728,7 @@ winhello_assert_free(struct winhello_assert *ctx)
if (ctx == NULL)
return;
if (ctx->assert != NULL)
- WebAuthNFreeAssertion(ctx->assert);
+ webauthn_free_assert(ctx->assert);
free(ctx->rp_id);
free(ctx->opt.CredentialList.pCredentials);
@@ -737,7 +741,7 @@ winhello_cred_free(struct winhello_cred *ctx)
if (ctx == NULL)
return;
if (ctx->att != NULL)
- WebAuthNFreeCredentialAttestation(ctx->att);
+ webauthn_free_attest(ctx->att);
free(ctx->rp_id);
free(ctx->rp_name);
@@ -758,7 +762,6 @@ int
fido_winhello_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)
{
int r;
- BOOL present;
fido_dev_info_t *di;
if (ilen == 0) {
@@ -767,14 +770,10 @@ fido_winhello_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)
if (devlist == NULL) {
return FIDO_ERR_INVALID_ARGUMENT;
}
- if ((r = winhello_manifest(&present)) != FIDO_OK) {
+ if ((r = winhello_manifest()) != FIDO_OK) {
fido_log_debug("%s: winhello_manifest", __func__);
return r;
}
- if (present == false) {
- fido_log_debug("%s: not present", __func__);
- return FIDO_OK;
- }
di = &devlist[*olen];
memset(di, 0, sizeof(*di));
@@ -799,9 +798,12 @@ fido_winhello_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)
int
fido_winhello_open(fido_dev_t *dev)
{
+ if (!webauthn_loaded && webauthn_load() < 0) {
+ fido_log_debug("%s: webauthn_load", __func__);
+ return FIDO_ERR_INTERNAL;
+ }
if (dev->flags != 0)
return FIDO_ERR_INVALID_ARGUMENT;
-
dev->attr.flags = FIDO_CAP_CBOR | FIDO_CAP_WINK;
dev->flags = FIDO_DEV_WINHELLO | FIDO_DEV_CRED_PROT | FIDO_DEV_PIN_SET;
@@ -826,7 +828,7 @@ fido_winhello_cancel(fido_dev_t *dev)
int
fido_winhello_get_assert(fido_dev_t *dev, fido_assert_t *assert,
- const char *pin)
+ const char *pin, int ms)
{
HWND w;
struct winhello_assert *ctx;
@@ -834,6 +836,8 @@ fido_winhello_get_assert(fido_dev_t *dev, fido_assert_t *assert,
(void)dev;
+ fido_assert_reset_rx(assert);
+
if ((ctx = calloc(1, sizeof(*ctx))) == NULL) {
fido_log_debug("%s: calloc", __func__);
goto fail;
@@ -842,7 +846,7 @@ fido_winhello_get_assert(fido_dev_t *dev, fido_assert_t *assert,
fido_log_debug("%s: GetForegroundWindow", __func__);
goto fail;
}
- if ((r = translate_fido_assert(ctx, assert, pin)) != FIDO_OK) {
+ if ((r = translate_fido_assert(ctx, assert, pin, ms)) != FIDO_OK) {
fido_log_debug("%s: translate_fido_assert", __func__);
goto fail;
}
@@ -873,10 +877,10 @@ fido_winhello_get_cbor_info(fido_dev_t *dev, fido_cbor_info_t *ci)
fido_cbor_info_reset(ci);
- if (to_fido_str_array(&ci->versions, v, nitems(v)) < 0 ||
- to_fido_str_array(&ci->extensions, e, nitems(e)) < 0 ||
- to_fido_str_array(&ci->transports, t, nitems(t)) < 0) {
- fido_log_debug("%s: to_fido_str_array", __func__);
+ if (fido_str_array_pack(&ci->versions, v, nitems(v)) < 0 ||
+ fido_str_array_pack(&ci->extensions, e, nitems(e)) < 0 ||
+ fido_str_array_pack(&ci->transports, t, nitems(t)) < 0) {
+ fido_log_debug("%s: fido_str_array_pack", __func__);
return FIDO_ERR_INTERNAL;
}
if ((ci->options.name = calloc(nitems(o), sizeof(char *))) == NULL ||
@@ -897,7 +901,8 @@ fido_winhello_get_cbor_info(fido_dev_t *dev, fido_cbor_info_t *ci)
}
int
-fido_winhello_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin)
+fido_winhello_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin,
+ int ms)
{
HWND w;
struct winhello_cred *ctx;
@@ -905,6 +910,8 @@ fido_winhello_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin)
(void)dev;
+ fido_cred_reset_rx(cred);
+
if ((ctx = calloc(1, sizeof(*ctx))) == NULL) {
fido_log_debug("%s: calloc", __func__);
goto fail;
@@ -913,7 +920,7 @@ fido_winhello_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin)
fido_log_debug("%s: GetForegroundWindow", __func__);
goto fail;
}
- if ((r = translate_fido_cred(ctx, cred, pin)) != FIDO_OK) {
+ if ((r = translate_fido_cred(ctx, cred, pin, ms)) != FIDO_OK) {
fido_log_debug("%s: translate_fido_cred", __func__);
goto fail;
}
diff --git a/contrib/libfido2/tools/CMakeLists.txt b/contrib/libfido2/tools/CMakeLists.txt
index b1dde9949c4f..f37aa1d87c97 100644
--- a/contrib/libfido2/tools/CMakeLists.txt
+++ b/contrib/libfido2/tools/CMakeLists.txt
@@ -3,10 +3,13 @@
# license that can be found in the LICENSE file.
list(APPEND COMPAT_SOURCES
+ ../openbsd-compat/bsd-getpagesize.c
../openbsd-compat/explicit_bzero.c
../openbsd-compat/freezero.c
+ ../openbsd-compat/recallocarray.c
../openbsd-compat/strlcat.c
../openbsd-compat/strlcpy.c
+ ../openbsd-compat/strsep.c
)
if(WIN32 AND NOT CYGWIN AND NOT MSYS)
diff --git a/contrib/libfido2/tools/config.c b/contrib/libfido2/tools/config.c
index 17dfe4457902..3eea4c9b6cf6 100644
--- a/contrib/libfido2/tools/config.c
+++ b/contrib/libfido2/tools/config.c
@@ -147,3 +147,51 @@ out:
exit(ok);
}
+
+int
+config_pin_minlen_rpid(char *path, const char *rpids)
+{
+ fido_dev_t *dev;
+ char *otmp, *tmp, *cp;
+ char *pin = NULL, **rpid = NULL;
+ int r, ok = 1;
+ size_t n;
+
+ if ((tmp = strdup(rpids)) == NULL)
+ err(1, "strdup");
+ otmp = tmp;
+ for (n = 0; (cp = strsep(&tmp, ",")) != NULL; n++) {
+ if (n == SIZE_MAX || (rpid = recallocarray(rpid, n, n + 1,
+ sizeof(*rpid))) == NULL)
+ err(1, "recallocarray");
+ if ((rpid[n] = strdup(cp)) == NULL)
+ err(1, "strdup");
+ if (*rpid[n] == '\0')
+ errx(1, "empty rpid");
+ }
+ free(otmp);
+ if (rpid == NULL || n == 0)
+ errx(1, "could not parse rp_id");
+ dev = open_dev(path);
+ if ((r = fido_dev_set_pin_minlen_rpid(dev, (const char * const *)rpid,
+ n, NULL)) != FIDO_OK && should_retry_with_pin(dev, r)) {
+ if ((pin = get_pin(path)) == NULL)
+ goto out;
+ r = fido_dev_set_pin_minlen_rpid(dev, (const char * const *)rpid,
+ n, pin);
+ freezero(pin, PINBUF_LEN);
+ pin = NULL;
+ }
+ if (r != FIDO_OK) {
+ warnx("fido_dev_set_pin_minlen_rpid: %s (0x%x)",
+ fido_strerr(r), r);
+ goto out;
+ }
+
+ ok = 0;
+out:
+ fido_dev_close(dev);
+ fido_dev_free(&dev);
+
+ exit(ok);
+}
diff --git a/contrib/libfido2/tools/extern.h b/contrib/libfido2/tools/extern.h
index 207c35894f8b..8b25dadd45ac 100644
--- a/contrib/libfido2/tools/extern.h
+++ b/contrib/libfido2/tools/extern.h
@@ -20,7 +20,7 @@ struct blob {
size_t len;
};
-#define TOKEN_OPT "CDGILPRSVabcdefi:k:l:n:p:ru"
+#define TOKEN_OPT "CDGILPRSVabcdefi:k:l:m:n:p:ru"
#define FLAG_DEBUG 0x01
#define FLAG_QUIET 0x02
@@ -62,6 +62,7 @@ int config_always_uv(char *, int);
int config_entattest(char *);
int config_force_pin_change(char *);
int config_pin_minlen(char *, const char *);
+int config_pin_minlen_rpid(char *, const char *);
int cose_type(const char *, int *);
int cred_make(int, char **);
int cred_verify(int, char **);
diff --git a/contrib/libfido2/tools/fido2-token.c b/contrib/libfido2/tools/fido2-token.c
index c1539b8bc08e..e6d9f9f96381 100644
--- a/contrib/libfido2/tools/fido2-token.c
+++ b/contrib/libfido2/tools/fido2-token.c
@@ -28,6 +28,7 @@ usage(void)
" fido2-token -S [-adefu] [-l pin_length] [-i template_id -n template_name] device\n"
" fido2-token -Sb [-k key_path] [-i cred_id -n rp_id] blob_path device\n"
" fido2-token -Sc -i cred_id -k user_id -n name -p display_name device\n"
+" fido2-token -Sm rp_id device\n"
" fido2-token -V\n"
);
@@ -59,6 +60,7 @@ main(int argc, char **argv)
case 'i':
case 'k':
case 'l':
+ case 'm':
case 'n':
case 'p':
case 'r':
diff --git a/contrib/libfido2/tools/token.c b/contrib/libfido2/tools/token.c
index 4dcc2fea6dbd..3d165623fdbf 100644
--- a/contrib/libfido2/tools/token.c
+++ b/contrib/libfido2/tools/token.c
@@ -352,6 +352,7 @@ token_set(int argc, char **argv, char *path)
char *len = NULL;
char *display_name = NULL;
char *name = NULL;
+ char *rpid = NULL;
int blob = 0;
int cred = 0;
int ch;
@@ -391,6 +392,9 @@ token_set(int argc, char **argv, char *path)
case 'p':
display_name = optarg;
break;
+ case 'm':
+ rpid = optarg;
+ break;
case 'n':
name = optarg;
break;
@@ -440,6 +444,8 @@ token_set(int argc, char **argv, char *path)
if (len)
return (config_pin_minlen(path, len));
+ if (rpid)
+ return (config_pin_minlen_rpid(path, rpid));
if (force)
return (config_force_pin_change(path));
if (uv)
diff --git a/contrib/libfido2/windows/build.ps1 b/contrib/libfido2/windows/build.ps1
index 55aac9d96bc5..87d0c31e5311 100644
--- a/contrib/libfido2/windows/build.ps1
+++ b/contrib/libfido2/windows/build.ps1
@@ -1,140 +1,136 @@
+# Copyright (c) 2021 Yubico AB. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
param(
[string]$CMakePath = "C:\Program Files\CMake\bin\cmake.exe",
[string]$GitPath = "C:\Program Files\Git\bin\git.exe",
[string]$SevenZPath = "C:\Program Files\7-Zip\7z.exe",
[string]$GPGPath = "C:\Program Files (x86)\GnuPG\bin\gpg.exe",
[string]$WinSDK = "",
+ [string]$Config = "Release",
+ [string]$Arch = "x64",
+ [string]$Type = "dynamic",
[string]$Fido2Flags = ""
)
-$ErrorActionPreference = "Continue"
-
+$ErrorActionPreference = "Stop"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
-# LibreSSL coordinates.
-New-Variable -Name 'LIBRESSL_URL' `
- -Value 'https://fastly.cdn.openbsd.org/pub/OpenBSD/LibreSSL' -Option Constant
-New-Variable -Name 'LIBRESSL' -Value 'libressl-3.2.5' -Option Constant
+. "$PSScriptRoot\const.ps1"
-# libcbor coordinates.
-New-Variable -Name 'LIBCBOR' -Value 'libcbor-0.8.0' -Option Constant
-New-Variable -Name 'LIBCBOR_BRANCH' -Value 'v0.8.0' -Option Constant
-New-Variable -Name 'LIBCBOR_GIT' -Value 'https://github.com/pjk/libcbor' `
- -Option Constant
+Function ExitOnError() {
+ if ($LastExitCode -ne 0) {
+ throw "A command exited with status $LastExitCode"
+ }
+}
-# zlib coordinates.
-New-Variable -Name 'ZLIB' -Value 'zlib-1.2.11' -Option Constant
-New-Variable -Name 'ZLIB_BRANCH' -Value 'v1.2.11' -Option Constant
-New-Variable -Name 'ZLIB_GIT' -Value 'https://github.com/madler/zlib' `
- -Option Constant
+Function GitClone(${REPO}, ${BRANCH}, ${DIR}) {
+ Write-Host "Cloning ${REPO}..."
+ & $Git -c advice.detachedHead=false clone --quiet --depth=1 `
+ --branch "${BRANCH}" "${REPO}" "${DIR}"
+ Write-Host "${REPO}'s ${BRANCH} HEAD is:"
+ & $Git -C "${DIR}" show -s HEAD
+}
-# Work directories.
-New-Variable -Name 'BUILD' -Value "$PSScriptRoot\..\build" -Option Constant
-New-Variable -Name 'OUTPUT' -Value "$PSScriptRoot\..\output" -Option Constant
+# Find Git.
+$Git = $(Get-Command git -ErrorAction Ignore | `
+ Select-Object -ExpandProperty Source)
+if ([string]::IsNullOrEmpty($Git)) {
+ $Git = $GitPath
+}
+if (-Not (Test-Path $Git)) {
+ throw "Unable to find Git at $Git"
+}
# Find CMake.
-$CMake = $(Get-Command cmake -ErrorAction Ignore | Select-Object -ExpandProperty Source)
-if([string]::IsNullOrEmpty($CMake)) {
+$CMake = $(Get-Command cmake -ErrorAction Ignore | `
+ Select-Object -ExpandProperty Source)
+if ([string]::IsNullOrEmpty($CMake)) {
$CMake = $CMakePath
}
-
-# Find Git.
-$Git = $(Get-Command git -ErrorAction Ignore | Select-Object -ExpandProperty Source)
-if([string]::IsNullOrEmpty($Git)) {
- $Git = $GitPath
+if (-Not (Test-Path $CMake)) {
+ throw "Unable to find CMake at $CMake"
}
# Find 7z.
-$SevenZ = $(Get-Command 7z -ErrorAction Ignore | Select-Object -ExpandProperty Source)
-if([string]::IsNullOrEmpty($SevenZ)) {
+$SevenZ = $(Get-Command 7z -ErrorAction Ignore | `
+ Select-Object -ExpandProperty Source)
+if ([string]::IsNullOrEmpty($SevenZ)) {
$SevenZ = $SevenZPath
}
+if (-Not (Test-Path $SevenZ)) {
+ throw "Unable to find 7z at $SevenZ"
+}
# Find GPG.
-$GPG = $(Get-Command gpg -ErrorAction Ignore | Select-Object -ExpandProperty Source)
-if([string]::IsNullOrEmpty($GPG)) {
+$GPG = $(Get-Command gpg -ErrorAction Ignore | `
+ Select-Object -ExpandProperty Source)
+if ([string]::IsNullOrEmpty($GPG)) {
$GPG = $GPGPath
}
+if (-Not (Test-Path $GPG)) {
+ throw "Unable to find GPG at $GPG"
+}
# Override CMAKE_SYSTEM_VERSION if $WinSDK is set.
-if(-Not ([string]::IsNullOrEmpty($WinSDK))) {
+if (-Not ([string]::IsNullOrEmpty($WinSDK))) {
$CMAKE_SYSTEM_VERSION = "-DCMAKE_SYSTEM_VERSION='$WinSDK'"
} else {
$CMAKE_SYSTEM_VERSION = ''
}
-if(-Not (Test-Path $CMake)) {
- throw "Unable to find CMake at $CMake"
-}
-
-if(-Not (Test-Path $Git)) {
- throw "Unable to find Git at $Git"
-}
-
-if(-Not (Test-Path $SevenZ)) {
- throw "Unable to find 7z at $SevenZ"
-}
-
-if(-Not (Test-Path $GPG)) {
- throw "Unable to find GPG at $GPG"
-}
-
+Write-Host "WinSDK: $WinSDK"
+Write-Host "Config: $Config"
+Write-Host "Arch: $Arch"
+Write-Host "Type: $Type"
Write-Host "Git: $Git"
Write-Host "CMake: $CMake"
Write-Host "7z: $SevenZ"
Write-Host "GPG: $GPG"
-New-Item -Type Directory ${BUILD}
-New-Item -Type Directory ${BUILD}\32
-New-Item -Type Directory ${BUILD}\32\dynamic
-New-Item -Type Directory ${BUILD}\32\static
-New-Item -Type Directory ${BUILD}\64
-New-Item -Type Directory ${BUILD}\64\dynamic
-New-Item -Type Directory ${BUILD}\64\static
-New-Item -Type Directory ${OUTPUT}
-New-Item -Type Directory ${OUTPUT}\pkg\Win64\Release\v142\dynamic
-New-Item -Type Directory ${OUTPUT}\pkg\Win32\Release\v142\dynamic
-New-Item -Type Directory ${OUTPUT}\pkg\Win64\Release\v142\static
-New-Item -Type Directory ${OUTPUT}\pkg\Win32\Release\v142\static
+# Create build directories.
+New-Item -Type Directory "${BUILD}" -Force
+New-Item -Type Directory "${BUILD}\${Arch}" -Force
+New-Item -Type Directory "${BUILD}\${Arch}\${Type}" -Force
+New-Item -Type Directory "${STAGE}\${LIBRESSL}" -Force
+New-Item -Type Directory "${STAGE}\${LIBCBOR}" -Force
+New-Item -Type Directory "${STAGE}\${ZLIB}" -Force
-Push-Location ${BUILD}
+# Create output directories.
+New-Item -Type Directory "${OUTPUT}" -Force
+New-Item -Type Directory "${OUTPUT}\${Arch}" -Force
+New-Item -Type Directory "${OUTPUT}\${Arch}\${Type}" -force
+# Fetch and verify dependencies.
+Push-Location ${BUILD}
try {
- if (Test-Path .\${LIBRESSL}) {
- Remove-Item .\${LIBRESSL} -Recurse -ErrorAction Stop
- }
-
- if(-Not (Test-Path .\${LIBRESSL}.tar.gz -PathType leaf)) {
- Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz `
- -OutFile .\${LIBRESSL}.tar.gz
- }
- if(-Not (Test-Path .\${LIBRESSL}.tar.gz.asc -PathType leaf)) {
- Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz.asc `
- -OutFile .\${LIBRESSL}.tar.gz.asc
- }
-
- Copy-Item "$PSScriptRoot\libressl.gpg" -Destination "${BUILD}"
- & $GPG --list-keys
- & $GPG -v --no-default-keyring --keyring ./libressl.gpg `
- --verify .\${LIBRESSL}.tar.gz.asc .\${LIBRESSL}.tar.gz
- if ($LastExitCode -ne 0) {
- throw "GPG signature verification failed"
+ if (-Not (Test-Path .\${LIBRESSL})) {
+ if (-Not (Test-Path .\${LIBRESSL}.tar.gz -PathType leaf)) {
+ Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz `
+ -OutFile .\${LIBRESSL}.tar.gz
+ }
+ if (-Not (Test-Path .\${LIBRESSL}.tar.gz.asc -PathType leaf)) {
+ Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz.asc `
+ -OutFile .\${LIBRESSL}.tar.gz.asc
+ }
+
+ Copy-Item "$PSScriptRoot\libressl.gpg" -Destination "${BUILD}"
+ & $GPG --list-keys
+ & $GPG --quiet --no-default-keyring --keyring ./libressl.gpg `
+ --verify .\${LIBRESSL}.tar.gz.asc .\${LIBRESSL}.tar.gz
+ if ($LastExitCode -ne 0) {
+ throw "GPG signature verification failed"
+ }
+ & $SevenZ e .\${LIBRESSL}.tar.gz
+ & $SevenZ x .\${LIBRESSL}.tar
+ Remove-Item -Force .\${LIBRESSL}.tar
}
-
- & $SevenZ e .\${LIBRESSL}.tar.gz
- & $SevenZ x .\${LIBRESSL}.tar
- Remove-Item -Force .\${LIBRESSL}.tar
-
- if(-Not (Test-Path .\${LIBCBOR})) {
- Write-Host "Cloning ${LIBCBOR}..."
- & $Git clone --branch ${LIBCBOR_BRANCH} ${LIBCBOR_GIT} `
- .\${LIBCBOR}
+ if (-Not (Test-Path .\${LIBCBOR})) {
+ GitClone "${LIBCBOR_GIT}" "${LIBCBOR_BRANCH}" ".\${LIBCBOR}"
}
-
- if(-Not (Test-Path .\${ZLIB})) {
- Write-Host "Cloning ${ZLIB}..."
- & $Git clone --branch ${ZLIB_BRANCH} ${ZLIB_GIT} `
- .\${ZLIB}
+ if (-Not (Test-Path .\${ZLIB})) {
+ GitClone "${ZLIB_GIT}" "${ZLIB_BRANCH}" ".\${ZLIB}"
}
} catch {
throw "Failed to fetch and verify dependencies"
@@ -142,131 +138,103 @@ try {
Pop-Location
}
-Function Build(${OUTPUT}, ${GENERATOR}, ${ARCH}, ${SHARED}, ${FLAGS}) {
- if (-Not (Test-Path .\${LIBRESSL})) {
- New-Item -Type Directory .\${LIBRESSL} -ErrorAction Stop
- }
-
- Push-Location .\${LIBRESSL}
- & $CMake ..\..\..\${LIBRESSL} -G "${GENERATOR}" -A "${ARCH}" `
- -DBUILD_SHARED_LIBS="${SHARED}" -DLIBRESSL_TESTS=OFF `
- -DCMAKE_C_FLAGS_RELEASE="${FLAGS} /Zi /guard:cf /sdl" `
- -DCMAKE_INSTALL_PREFIX="${OUTPUT}" "${CMAKE_SYSTEM_VERSION}"
- & $CMake --build . --config Release --verbose
- & $CMake --build . --config Release --target install --verbose
+# Build LibreSSL.
+Push-Location ${STAGE}\${LIBRESSL}
+try {
+ & $CMake ..\..\..\${LIBRESSL} -A "${Arch}" `
+ -DBUILD_SHARED_LIBS="${SHARED}" -DLIBRESSL_TESTS=OFF `
+ -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" `
+ -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" `
+ -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; `
+ ExitOnError
+ & $CMake --build . --config ${Config} --verbose; ExitOnError
+ & $CMake --build . --config ${Config} --target install --verbose; `
+ ExitOnError
+} catch {
+ throw "Failed to build LibreSSL"
+} finally {
Pop-Location
+}
- if (-Not (Test-Path .\${LIBCBOR})) {
- New-Item -Type Directory .\${LIBCBOR} -ErrorAction Stop
- }
-
- Push-Location .\${LIBCBOR}
- & $CMake ..\..\..\${LIBCBOR} -G "${GENERATOR}" -A "${ARCH}" `
- -DBUILD_SHARED_LIBS="${SHARED}" `
- -DCMAKE_C_FLAGS_RELEASE="${FLAGS} /Zi /guard:cf /sdl" `
- -DCMAKE_INSTALL_PREFIX="${OUTPUT}" "${CMAKE_SYSTEM_VERSION}"
- & $CMake --build . --config Release --verbose
- & $CMake --build . --config Release --target install --verbose
+# Build libcbor.
+Push-Location ${STAGE}\${LIBCBOR}
+try {
+ & $CMake ..\..\..\${LIBCBOR} -A "${Arch}" `
+ -DWITH_EXAMPLES=OFF `
+ -DBUILD_SHARED_LIBS="${SHARED}" `
+ -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" `
+ -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" `
+ -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; `
+ ExitOnError
+ & $CMake --build . --config ${Config} --verbose; ExitOnError
+ & $CMake --build . --config ${Config} --target install --verbose; `
+ ExitOnError
+} catch {
+ throw "Failed to build libcbor"
+} finally {
Pop-Location
+}
- if(-Not (Test-Path .\${ZLIB})) {
- New-Item -Type Directory .\${ZLIB} -ErrorAction Stop
+# Build zlib.
+Push-Location ${STAGE}\${ZLIB}
+try {
+ & $CMake ..\..\..\${ZLIB} -A "${Arch}" `
+ -DBUILD_SHARED_LIBS="${SHARED}" `
+ -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" `
+ -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" `
+ -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; `
+ ExitOnError
+ & $CMake --build . --config ${Config} --verbose; ExitOnError
+ & $CMake --build . --config ${Config} --target install --verbose; `
+ ExitOnError
+ # Patch up zlib's resulting names when built with --config Debug.
+ if ("${Config}" -eq "Debug") {
+ if ("${Type}" -eq "Dynamic") {
+ Copy-Item "${PREFIX}/lib/zlibd.lib" `
+ -Destination "${PREFIX}/lib/zlib.lib" -Force
+ Copy-Item "${PREFIX}/bin/zlibd1.dll" `
+ -Destination "${PREFIX}/bin/zlib1.dll" -Force
+ } else {
+ Copy-Item "${PREFIX}/lib/zlibstaticd.lib" `
+ -Destination "${PREFIX}/lib/zlib.lib" -Force
+ }
}
-
- Push-Location .\${ZLIB}
- & $CMake ..\..\..\${ZLIB} -G "${GENERATOR}" -A "${ARCH}" `
- -DBUILD_SHARED_LIBS="${SHARED}" `
- -DCMAKE_C_FLAGS_RELEASE="${FLAGS} /Zi /guard:cf /sdl" `
- -DCMAKE_INSTALL_PREFIX="${OUTPUT}" "${CMAKE_SYSTEM_VERSION}"
- & $CMake --build . --config Release --verbose
- & $CMake --build . --config Release --target install --verbose
+} catch {
+ throw "Failed to build zlib"
+} finally {
Pop-Location
+}
- & $CMake ..\..\.. -G "${GENERATOR}" -A "${ARCH}" `
- -DBUILD_SHARED_LIBS="${SHARED}" `
- -DCBOR_INCLUDE_DIRS="${OUTPUT}\include" `
- -DCBOR_LIBRARY_DIRS="${OUTPUT}\lib" `
- -DZLIB_INCLUDE_DIRS="${OUTPUT}\include" `
- -DZLIB_LIBRARY_DIRS="${OUTPUT}\lib" `
- -DCRYPTO_INCLUDE_DIRS="${OUTPUT}\include" `
- -DCRYPTO_LIBRARY_DIRS="${OUTPUT}\lib" `
- -DCMAKE_C_FLAGS_RELEASE="${FLAGS} /Zi /guard:cf /sdl ${Fido2Flags}" `
- -DCMAKE_INSTALL_PREFIX="${OUTPUT}" "${CMAKE_SYSTEM_VERSION}"
- & $CMake --build . --config Release --verbose
- & $CMake --build . --config Release --target install --verbose
+# Build libfido2.
+Push-Location ${STAGE}
+try {
+ & $CMake ..\..\.. -A "${Arch}" `
+ -DCMAKE_BUILD_TYPE="${Config}" `
+ -DBUILD_SHARED_LIBS="${SHARED}" `
+ -DCBOR_INCLUDE_DIRS="${PREFIX}\include" `
+ -DCBOR_LIBRARY_DIRS="${PREFIX}\lib" `
+ -DCBOR_BIN_DIRS="${PREFIX}\bin" `
+ -DZLIB_INCLUDE_DIRS="${PREFIX}\include" `
+ -DZLIB_LIBRARY_DIRS="${PREFIX}\lib" `
+ -DZLIB_BIN_DIRS="${PREFIX}\bin" `
+ -DCRYPTO_INCLUDE_DIRS="${PREFIX}\include" `
+ -DCRYPTO_LIBRARY_DIRS="${PREFIX}\lib" `
+ -DCRYPTO_BIN_DIRS="${PREFIX}\bin" `
+ -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG} ${Fido2Flags}" `
+ -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE} ${Fido2Flags}" `
+ -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; `
+ ExitOnError
+ & $CMake --build . --config ${Config} --verbose; ExitOnError
+ & $CMake --build . --config ${Config} --target install --verbose; `
+ ExitOnError
+ # Copy DLLs.
if ("${SHARED}" -eq "ON") {
- "cbor.dll", "crypto-46.dll", "zlib1.dll" | %{ Copy-Item "${OUTPUT}\bin\$_" `
- -Destination "examples\Release" }
+ "cbor.dll", "crypto-46.dll", "zlib1.dll" | `
+ %{ Copy-Item "${PREFIX}\bin\$_" `
+ -Destination "examples\${Config}" }
}
+} catch {
+ throw "Failed to build libfido2"
+} finally {
+ Pop-Location
}
-
-Function Package-Headers() {
- Copy-Item "${OUTPUT}\64\dynamic\include" -Destination "${OUTPUT}\pkg" `
- -Recurse -ErrorAction Stop
-}
-
-Function Package-Dynamic(${SRC}, ${DEST}) {
- Copy-Item "${SRC}\bin\cbor.dll" "${DEST}" -ErrorAction Stop
- Copy-Item "${SRC}\lib\cbor.lib" "${DEST}" -ErrorAction Stop
- Copy-Item "${SRC}\bin\zlib1.dll" "${DEST}" -ErrorAction Stop
- Copy-Item "${SRC}\lib\zlib.lib" "${DEST}" -ErrorAction Stop
- Copy-Item "${SRC}\bin\crypto-46.dll" "${DEST}" -ErrorAction Stop
- Copy-Item "${SRC}\lib\crypto-46.lib" "${DEST}" -ErrorAction Stop
- Copy-Item "${SRC}\bin\fido2.dll" "${DEST}" -ErrorAction Stop
- Copy-Item "${SRC}\lib\fido2.lib" "${DEST}" -ErrorAction Stop
-}
-
-Function Package-Static(${SRC}, ${DEST}) {
- Copy-Item "${SRC}/lib/cbor.lib" "${DEST}" -ErrorAction Stop
- Copy-Item "${SRC}/lib/zlib.lib" "${DEST}" -ErrorAction Stop
- Copy-Item "${SRC}/lib/crypto-46.lib" "${DEST}" -ErrorAction Stop
- Copy-Item "${SRC}/lib/fido2_static.lib" "${DEST}/fido2.lib" `
- -ErrorAction Stop
-}
-
-Function Package-PDBs(${SRC}, ${DEST}) {
- Copy-Item "${SRC}\${LIBRESSL}\crypto\crypto.dir\Release\vc142.pdb" `
- "${DEST}\crypto-46.pdb" -ErrorAction Stop
- Copy-Item "${SRC}\${LIBCBOR}\src\cbor.dir\Release\vc142.pdb" `
- "${DEST}\cbor.pdb" -ErrorAction Stop
- Copy-Item "${SRC}\${ZLIB}\zlib.dir\Release\vc142.pdb" `
- "${DEST}\zlib.pdb" -ErrorAction Stop
- Copy-Item "${SRC}\src\fido2_shared.dir\Release\vc142.pdb" `
- "${DEST}\fido2.pdb" -ErrorAction Stop
-}
-
-Function Package-Tools(${SRC}, ${DEST}) {
- Copy-Item "${SRC}\tools\Release\fido2-assert.exe" `
- "${DEST}\fido2-assert.exe" -ErrorAction stop
- Copy-Item "${SRC}\tools\Release\fido2-cred.exe" `
- "${DEST}\fido2-cred.exe" -ErrorAction stop
- Copy-Item "${SRC}\tools\Release\fido2-token.exe" `
- "${DEST}\fido2-token.exe" -ErrorAction stop
-}
-
-Push-Location ${BUILD}\64\dynamic
-Build ${OUTPUT}\64\dynamic "Visual Studio 16 2019" "x64" "ON" "/MD"
-Pop-Location
-Push-Location ${BUILD}\32\dynamic
-Build ${OUTPUT}\32\dynamic "Visual Studio 16 2019" "Win32" "ON" "/MD"
-Pop-Location
-
-Push-Location ${BUILD}\64\static
-Build ${OUTPUT}\64\static "Visual Studio 16 2019" "x64" "OFF" "/MT"
-Pop-Location
-Push-Location ${BUILD}\32\static
-Build ${OUTPUT}\32\static "Visual Studio 16 2019" "Win32" "OFF" "/MT"
-Pop-Location
-
-Package-Headers
-
-Package-Dynamic ${OUTPUT}\64\dynamic ${OUTPUT}\pkg\Win64\Release\v142\dynamic
-Package-PDBs ${BUILD}\64\dynamic ${OUTPUT}\pkg\Win64\Release\v142\dynamic
-Package-Tools ${BUILD}\64\dynamic ${OUTPUT}\pkg\Win64\Release\v142\dynamic
-
-Package-Dynamic ${OUTPUT}\32\dynamic ${OUTPUT}\pkg\Win32\Release\v142\dynamic
-Package-PDBs ${BUILD}\32\dynamic ${OUTPUT}\pkg\Win32\Release\v142\dynamic
-Package-Tools ${BUILD}\32\dynamic ${OUTPUT}\pkg\Win32\Release\v142\dynamic
-
-Package-Static ${OUTPUT}\64\static ${OUTPUT}\pkg\Win64\Release\v142\static
-Package-Static ${OUTPUT}\32\static ${OUTPUT}\pkg\Win32\Release\v142\static
diff --git a/contrib/libfido2/windows/const.ps1 b/contrib/libfido2/windows/const.ps1
new file mode 100644
index 000000000000..6d2a8189d362
--- /dev/null
+++ b/contrib/libfido2/windows/const.ps1
@@ -0,0 +1,42 @@
+# Copyright (c) 2021 Yubico AB. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# LibreSSL coordinates.
+New-Variable -Name 'LIBRESSL_URL' `
+ -Value 'https://fastly.cdn.openbsd.org/pub/OpenBSD/LibreSSL' `
+ -Option Constant
+New-Variable -Name 'LIBRESSL' -Value 'libressl-3.3.4' -Option Constant
+
+# libcbor coordinates.
+New-Variable -Name 'LIBCBOR' -Value 'libcbor-0.8.0' -Option Constant
+New-Variable -Name 'LIBCBOR_BRANCH' -Value 'v0.8.0' -Option Constant
+New-Variable -Name 'LIBCBOR_GIT' -Value 'https://github.com/pjk/libcbor' `
+ -Option Constant
+
+# zlib coordinates.
+New-Variable -Name 'ZLIB' -Value 'zlib-1.2.11' -Option Constant
+New-Variable -Name 'ZLIB_BRANCH' -Value 'v1.2.11' -Option Constant
+New-Variable -Name 'ZLIB_GIT' -Value 'https://github.com/madler/zlib' `
+ -Option Constant
+
+# Work directories.
+New-Variable -Name 'BUILD' -Value "$PSScriptRoot\..\build" -Option Constant
+New-Variable -Name 'OUTPUT' -Value "$PSScriptRoot\..\output" -Option Constant
+
+# Prefixes.
+New-Variable -Name 'STAGE' -Value "${BUILD}\${Arch}\${Type}" -Option Constant
+New-Variable -Name 'PREFIX' -Value "${OUTPUT}\${Arch}\${Type}" -Option Constant
+
+# Build flags.
+if ("${Type}" -eq "dynamic") {
+ New-Variable -Name 'RUNTIME' -Value '/MD' -Option Constant
+ New-Variable -Name 'SHARED' -Value 'ON' -Option Constant
+} else {
+ New-Variable -Name 'RUNTIME' -Value '/MT' -Option Constant
+ New-Variable -Name 'SHARED' -Value 'OFF' -Option Constant
+}
+New-Variable -Name 'CFLAGS_DEBUG' -Value "${RUNTIME}d /Zi /guard:cf /sdl" `
+ -Option Constant
+New-Variable -Name 'CFLAGS_RELEASE' -Value "${RUNTIME} /Zi /guard:cf /sdl" `
+ -Option Constant
diff --git a/contrib/libfido2/windows/release.ps1 b/contrib/libfido2/windows/release.ps1
new file mode 100644
index 000000000000..32e88e256274
--- /dev/null
+++ b/contrib/libfido2/windows/release.ps1
@@ -0,0 +1,84 @@
+# Copyright (c) 2021 Yubico AB. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+$ErrorActionPreference = "Stop"
+$Architectures = @('x64', 'Win32', 'ARM64', 'ARM')
+$InstallPrefixes = @('Win64', 'Win32', 'ARM64', 'ARM')
+$Types = @('dynamic', 'static')
+$Config = 'Release'
+$LibCrypto = '46'
+$SDK = '142'
+
+. "$PSScriptRoot\const.ps1"
+
+foreach ($Arch in $Architectures) {
+ foreach ($Type in $Types) {
+ ./build.ps1 -Arch ${Arch} -Type ${Type} -Config ${Config}
+ }
+}
+
+foreach ($InstallPrefix in $InstallPrefixes) {
+ foreach ($Type in $Types) {
+ New-Item -Type Directory `
+ "${OUTPUT}/pkg/${InstallPrefix}/${Config}/v${SDK}/${Type}"
+ }
+}
+
+Function Package-Headers() {
+ Copy-Item "${OUTPUT}\x64\dynamic\include" -Destination "${OUTPUT}\pkg" `
+ -Recurse -ErrorAction Stop
+}
+
+Function Package-Dynamic(${SRC}, ${DEST}) {
+ Copy-Item "${SRC}\bin\cbor.dll" "${DEST}"
+ Copy-Item "${SRC}\lib\cbor.lib" "${DEST}"
+ Copy-Item "${SRC}\bin\zlib1.dll" "${DEST}"
+ Copy-Item "${SRC}\lib\zlib.lib" "${DEST}"
+ Copy-Item "${SRC}\bin\crypto-${LibCrypto}.dll" "${DEST}"
+ Copy-Item "${SRC}\lib\crypto-${LibCrypto}.lib" "${DEST}"
+ Copy-Item "${SRC}\bin\fido2.dll" "${DEST}"
+ Copy-Item "${SRC}\lib\fido2.lib" "${DEST}"
+}
+
+Function Package-Static(${SRC}, ${DEST}) {
+ Copy-Item "${SRC}/lib/cbor.lib" "${DEST}"
+ Copy-Item "${SRC}/lib/zlib.lib" "${DEST}"
+ Copy-Item "${SRC}/lib/crypto-${LibCrypto}.lib" "${DEST}"
+ Copy-Item "${SRC}/lib/fido2_static.lib" "${DEST}/fido2.lib"
+}
+
+Function Package-PDBs(${SRC}, ${DEST}) {
+ Copy-Item "${SRC}\${LIBRESSL}\crypto\crypto.dir\${Config}\vc${SDK}.pdb" `
+ "${DEST}\crypto-${LibCrypto}.pdb"
+ Copy-Item "${SRC}\${LIBCBOR}\src\cbor.dir\${Config}\vc${SDK}.pdb" `
+ "${DEST}\cbor.pdb"
+ Copy-Item "${SRC}\${ZLIB}\zlib.dir\${Config}\vc${SDK}.pdb" `
+ "${DEST}\zlib.pdb"
+ Copy-Item "${SRC}\src\fido2_shared.dir\${Config}\vc${SDK}.pdb" `
+ "${DEST}\fido2.pdb"
+}
+
+Function Package-Tools(${SRC}, ${DEST}) {
+ Copy-Item "${SRC}\tools\${Config}\fido2-assert.exe" `
+ "${DEST}\fido2-assert.exe"
+ Copy-Item "${SRC}\tools\${Config}\fido2-cred.exe" `
+ "${DEST}\fido2-cred.exe"
+ Copy-Item "${SRC}\tools\${Config}\fido2-token.exe" `
+ "${DEST}\fido2-token.exe"
+}
+
+Package-Headers
+
+for ($i = 0; $i -lt $Architectures.Length; $i++) {
+ $Arch = $Architectures[$i]
+ $InstallPrefix = $InstallPrefixes[$i]
+ Package-Dynamic "${OUTPUT}\${Arch}\dynamic" `
+ "${OUTPUT}\pkg\${InstallPrefix}\${Config}\v${SDK}\dynamic"
+ Package-PDBs "${BUILD}\${Arch}\dynamic" `
+ "${OUTPUT}\pkg\${InstallPrefix}\${Config}\v${SDK}\dynamic"
+ Package-Tools "${BUILD}\${Arch}\dynamic" `
+ "${OUTPUT}\pkg\${InstallPrefix}\${Config}\v${SDK}\dynamic"
+ Package-Static "${OUTPUT}\${Arch}\static" `
+ "${OUTPUT}\pkg\${InstallPrefix}\${Config}\v${SDK}\static"
+}
diff --git a/lib/libfido2/Makefile b/lib/libfido2/Makefile
index edf737b9dafc..9a0e4a57bd9a 100644
--- a/lib/libfido2/Makefile
+++ b/lib/libfido2/Makefile
@@ -32,7 +32,11 @@ SRCS+= log.c
SRCS+= pin.c
SRCS+= random.c
SRCS+= reset.c
+SRCS+= rs1.c
SRCS+= rs256.c
+SRCS+= time.c
+SRCS+= tpm.c
+SRCS+= types.c
SRCS+= u2f.c
SRCS+= openbsd-compat/freezero.c