libfido2: update to 1.10.0

Some highlights from NEWS:

 ** bio: fix CTAP2 canonical CBOR encoding in fido_bio_dev_enroll_*();
    gh#480.
 ** New API calls:
  - fido_dev_info_set;
  - fido_dev_io_handle;
  - fido_dev_new_with_info;
  - fido_dev_open_with_info.
 ** Documentation and reliability fixes.
 ** Support for TPM 2.0 attestation of COSE_ES256 credentials.

Relnotes:       Yes
Sponsored by:   The FreeBSD Foundation
This commit is contained in:
Ed Maste 2023-05-05 19:57:34 -04:00
commit 3e696dfb70
71 changed files with 1653 additions and 388 deletions

View File

@ -9,7 +9,7 @@ project(libfido2 C)
cmake_minimum_required(VERSION 3.0)
# Set PIE flags for POSITION_INDEPENDENT_CODE targets, added in CMake 3.14.
if(POLICY CMP0083)
cmake_policy(SET CMP0083 NEW)
cmake_policy(SET CMP0083 NEW)
endif()
include(CheckCCompilerFlag)
@ -21,14 +21,14 @@ include(CheckTypeSize)
include(GNUInstallDirs)
include(CheckPIESupported OPTIONAL RESULT_VARIABLE CHECK_PIE_SUPPORTED)
if(CHECK_PIE_SUPPORTED)
check_pie_supported(LANGUAGES C)
check_pie_supported(LANGUAGES C)
endif()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_COLOR_MAKEFILE OFF)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(FIDO_MAJOR "1")
set(FIDO_MINOR "9")
set(FIDO_MINOR "10")
set(FIDO_PATCH "0")
set(FIDO_VERSION ${FIDO_MAJOR}.${FIDO_MINOR}.${FIDO_PATCH})
@ -40,16 +40,15 @@ option(BUILD_TOOLS "Build tool programs" ON)
option(FUZZ "Enable fuzzing instrumentation" OFF)
option(LIBFUZZER "Build libfuzzer harnesses" OFF)
option(USE_HIDAPI "Use hidapi as the HID backend" OFF)
option(USE_WINHELLO "Abstract Windows Hello as a FIDO device" OFF)
option(NFC_LINUX "Experimental NFC support on Linux" OFF)
option(USE_WINHELLO "Abstract Windows Hello as a FIDO device" ON)
option(NFC_LINUX "Enable NFC support on Linux" ON)
add_definitions(-D_FIDO_MAJOR=${FIDO_MAJOR})
add_definitions(-D_FIDO_MINOR=${FIDO_MINOR})
add_definitions(-D_FIDO_PATCH=${FIDO_PATCH})
if(CYGWIN OR MSYS)
if(CYGWIN OR MSYS OR MINGW)
set(WIN32 1)
add_definitions(-DWINVER=0x0a00)
endif()
if(WIN32)
@ -68,12 +67,13 @@ if(NOT MSVC)
set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_DARWIN_C_SOURCE")
set(FIDO_CFLAGS "${FIDO_CFLAGS} -D__STDC_WANT_LIB_EXT1__=1")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(NFC_LINUX ON)
set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_GNU_SOURCE")
set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_DEFAULT_SOURCE")
elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
CMAKE_SYSTEM_NAME STREQUAL "MidnightBSD")
set(FIDO_CFLAGS "${FIDO_CFLAGS} -D__BSD_VISIBLE=1")
elseif(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_NETBSD_SOURCE")
endif()
set(FIDO_CFLAGS "${FIDO_CFLAGS} -std=c99")
set(CMAKE_C_FLAGS "${FIDO_CFLAGS} ${CMAKE_C_FLAGS}")
@ -167,12 +167,13 @@ if(MSVC)
endif()
set(CBOR_LIBRARIES cbor)
set(ZLIB_LIBRARIES zlib)
set(CRYPTO_LIBRARIES crypto-46)
set(CRYPTO_LIBRARIES crypto-47)
set(MSVC_DISABLED_WARNINGS_LIST
"C4152" # nonstandard extension used: function/data pointer
# conversion in expression;
"C4200" # nonstandard extension used: zero-sized array in
# struct/union;
"C4201" # nonstandard extension used: nameless struct/union;
"C4204" # nonstandard extension used: non-constant aggregate
# initializer;
"C4706" # assignment within conditional expression;
@ -188,8 +189,10 @@ if(MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -MP -W4 -WX ${MSVC_DISABLED_WARNINGS_STR}")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Od /Z7 /guard:cf /sdl /RTCcsu")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Zi /guard:cf /sdl")
add_definitions(-DUSE_WINHELLO)
set(USE_WINHELLO ON)
if(USE_WINHELLO)
add_definitions(-DUSE_WINHELLO)
endif()
set(NFC_LINUX OFF)
else()
include(FindPkgConfig)
pkg_search_module(CBOR libcbor)
@ -223,6 +226,8 @@ else()
set(BASE_LIBRARIES ${BASE_LIBRARIES} rt)
endif()
endif()
else()
set(NFC_LINUX OFF)
endif()
if(MINGW)
@ -238,14 +243,18 @@ else()
set(HIDAPI_LIBRARIES hidapi${HIDAPI_SUFFIX})
endif()
if(FUZZ)
set(NFC_LINUX ON)
endif()
if(NFC_LINUX)
add_definitions(-DNFC_LINUX)
endif()
if(WIN32)
if(USE_WINHELLO)
add_definitions(-DUSE_WINHELLO)
endif()
else()
set(USE_WINHELLO OFF)
endif()
add_compile_options(-Wall)
add_compile_options(-Wextra)
add_compile_options(-Werror)
@ -257,6 +266,10 @@ else()
add_compile_options(-pedantic)
add_compile_options(-pedantic-errors)
if(WIN32)
add_compile_options(-Wno-type-limits)
add_compile_options(-Wno-cast-function-type)
endif()
if(HAVE_SHORTEN_64_TO_32)
add_compile_options(-Wshorten-64-to-32)
endif()
@ -306,10 +319,10 @@ elseif(NOT MSVC)
# clang/gcc + gnu ld
if(FUZZ)
string(CONCAT CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS}
" -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/fuzz/export.gnu")
" -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/fuzz/export.gnu")
else()
string(CONCAT CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS}
" -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/export.gnu")
" -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/export.gnu")
endif()
if(NOT WIN32)
string(CONCAT CMAKE_SHARED_LINKER_FLAGS

View File

@ -1,4 +1,4 @@
Copyright (c) 2018-2021 Yubico AB. All rights reserved.
Copyright (c) 2018-2022 Yubico AB. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are

View File

@ -1,3 +1,17 @@
* Version 1.10.0 (2022-01-17)
** hid_osx: handle devices with paths > 511 bytes; gh#462.
** bio: fix CTAP2 canonical CBOR encoding in fido_bio_dev_enroll_*(); gh#480.
** winhello: fallback to GetTopWindow() if GetForegroundWindow() fails.
** winhello: fallback to hid_win.c if webauthn.dll isn't available.
** New API calls:
- fido_dev_info_set;
- fido_dev_io_handle;
- fido_dev_new_with_info;
- fido_dev_open_with_info.
** Cygwin and NetBSD build fixes.
** Documentation and reliability fixes.
** Support for TPM 2.0 attestation of COSE_ES256 credentials.
* Version 1.9.0 (2021-10-27)
** Enabled NFC support on Linux.
** Added OpenSSL 3.0 compatibility.

View File

@ -10,7 +10,7 @@ image:https://oss-fuzz-build-logs.storage.googleapis.com/badges/libfido2.svg["Fu
communicate with a FIDO device over USB, and to verify attestation and
assertion signatures.
*libfido2* supports the FIDO U2F (CTAP 1) and FIDO 2.0 (CTAP 2) protocols.
*libfido2* supports the FIDO U2F (CTAP 1) and FIDO2 (CTAP 2) protocols.
For usage, see the `examples/` directory.
@ -42,7 +42,7 @@ is also available.
==== Releases
The current release of *libfido2* is 1.9.0. Please consult Yubico's
The current release of *libfido2* is 1.10.0. Please consult Yubico's
https://developers.yubico.com/libfido2/Releases[release page] for source
and binary releases.

View File

@ -0,0 +1,5 @@
# Reporting libfido2 Security Issues
To report security issues in libfido2, please contact security@yubico.com.
A PGP public key can be found at
https://www.yubico.com/support/security-advisories/issue-rating-system/.

View File

@ -25,7 +25,7 @@ The following definitions are used in the description below:
- <blobkey>
A credential's associated FIDO 2.1 "largeBlob" symmetric key.
A credential's associated CTAP 2.1 "largeBlob" symmetric key.
=== Description

View File

@ -7,6 +7,6 @@ ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get install -y clang-12 cmake git libssl-dev libudev-dev make pkg-config
RUN apt-get install -y zlib1g-dev
RUN git clone --branch v0.8.0 https://github.com/PJK/libcbor
RUN git clone --branch v0.9.0 https://github.com/PJK/libcbor
RUN git clone https://github.com/yubico/libfido2
RUN CC=clang-12 CXX=clang++-12 /libfido2/fuzz/build-coverage /libcbor /libfido2

View File

@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
IMAGE := libfido2-coverage:1.9.1
IMAGE := libfido2-coverage:1.10.0
RUNNER := libfido2-runner
PROFDATA := llvm-profdata-12
COV := llvm-cov-12

View File

@ -201,6 +201,7 @@
fido_dev_info_product;
fido_dev_info_product_string;
fido_dev_info_ptr;
fido_dev_info_set;
fido_dev_info_vendor;
fido_dev_is_fido2;
fido_dev_major;

View File

@ -172,7 +172,7 @@ cbor_array_iter 12 0 100.00% 16 0
cbor_parse_reply 27 0 100.00% 36 0 100.00%
cbor_vector_free 6 0 100.00% 5 0 100.00%
cbor_bytestring_copy 14 0 100.00% 18 0 100.00%
cbor_string_copy 14 1 92.86% 18 3 83.33%
cbor_string_copy 14 0 100.00% 18 0 100.00%
cbor_add_bytestring 14 0 100.00% 21 0 100.00%
cbor_add_string 14 0 100.00% 21 0 100.00%
cbor_add_bool 14 0 100.00% 21 0 100.00%
@ -200,7 +200,7 @@ cbor_decode_uint64 4 0 100.00% 8 0
cbor_decode_cred_id 8 0 100.00% 9 0 100.00%
cbor_decode_user 8 0 100.00% 9 0 100.00%
cbor_decode_rp_entity 8 0 100.00% 9 0 100.00%
cbor_build_uint 10 4 60.00% 9 4 55.56%
cbor_build_uint 10 1 90.00% 9 2 77.78%
cbor_array_append 17 0 100.00% 21 0 100.00%
cbor_array_drop 18 2 88.89% 17 3 82.35%
cbor.c:ctap_check_cbor 28 0 100.00% 26 0 100.00%
@ -209,7 +209,7 @@ cbor.c:cbor_add_arg 13 0 100.00% 21 0
cbor.c:cbor_add_uint8 14 0 100.00% 21 0 100.00%
cbor.c:cbor_encode_largeblob_key_ext 6 0 100.00% 6 0 100.00%
cbor.c:cbor_encode_hmac_secret_param 59 4 93.22% 66 8 87.88%
cbor.c:get_cose_alg 36 1 97.22% 38 3 92.11%
cbor.c:get_cose_alg 36 0 100.00% 38 0 100.00%
cbor.c:find_cose_alg 35 0 100.00% 33 0 100.00%
cbor.c:decode_attcred 25 0 100.00% 44 0 100.00%
cbor.c:decode_cred_extensions 14 0 100.00% 24 0 100.00%
@ -222,7 +222,7 @@ cbor.c:decode_cred_id_entry 10 0 100.00% 19 0
cbor.c:decode_user_entry 25 0 100.00% 35 0 100.00%
cbor.c:decode_rp_entity_entry 15 0 100.00% 25 0 100.00%
------------------------------------------------------------------------------------------------------------------
TOTAL 1047 28 97.33% 1237 54 95.63%
TOTAL 1047 23 97.80% 1237 46 96.28%
File '/libfido2/src/compress.c':
Name Regions Miss Cover Lines Miss Cover
@ -386,6 +386,7 @@ fido_dev_get_touch_begin 50 0 100.00% 59
fido_dev_get_touch_status 17 0 100.00% 20 0 100.00%
fido_dev_set_io_functions 18 4 77.78% 14 6 57.14%
fido_dev_set_transport_functions 6 2 66.67% 9 3 66.67%
fido_dev_io_handle 1 1 0.00% 3 3 0.00%
fido_init 8 1 87.50% 5 0 100.00%
fido_dev_new 5 0 100.00% 14 0 100.00%
fido_dev_new_with_info 10 10 0.00% 16 16 0.00%
@ -419,7 +420,7 @@ dev.c:fido_dev_set_extension_flags 7 0 100.00% 7
dev.c:fido_dev_set_option_flags 29 0 100.00% 18 0 100.00%
dev.c:fido_dev_set_protocol_flags 11 0 100.00% 17 0 100.00%
-------------------------------------------------------------------------------------------------------------------
TOTAL 420 78 81.43% 488 102 79.10%
TOTAL 421 79 81.24% 491 105 78.62%
File '/libfido2/src/ecdh.c':
Name Regions Miss Cover Lines Miss Cover
@ -493,8 +494,9 @@ Name Regions Miss Cover Lines Mis
fido_hid_get_usage 13 0 100.00% 22 0 100.00%
fido_hid_get_report_len 19 0 100.00% 27 0 100.00%
fido_dev_info_new 1 0 100.00% 3 0 100.00%
fido_dev_info_free 9 0 100.00% 14 0 100.00%
fido_dev_info_free 9 0 100.00% 9 0 100.00%
fido_dev_info_ptr 1 0 100.00% 3 0 100.00%
fido_dev_info_set 26 2 92.31% 30 3 90.00%
fido_dev_info_path 1 0 100.00% 3 0 100.00%
fido_dev_info_vendor 1 0 100.00% 3 0 100.00%
fido_dev_info_product 1 0 100.00% 3 0 100.00%
@ -502,8 +504,9 @@ fido_dev_info_manufacturer_string 1 0 100.00% 3
fido_dev_info_product_string 1 0 100.00% 3 0 100.00%
hid.c:get_key_len 6 0 100.00% 12 0 100.00%
hid.c:get_key_val 6 0 100.00% 18 0 100.00%
hid.c:fido_dev_info_reset 1 0 100.00% 6 0 100.00%
-------------------------------------------------------------------------------------------------------------------
TOTAL 60 0 100.00% 114 0 100.00%
TOTAL 87 2 97.70% 145 3 97.93%
File '/libfido2/src/hid_linux.c':
Name Regions Miss Cover Lines Miss Cover
@ -612,7 +615,7 @@ File '/libfido2/src/largeblob.c':
Name Regions Miss Cover Lines Miss Cover
-------------------------------------------------------------------------------------------------------------------
fido_dev_largeblob_get 26 2 92.31% 38 4 89.47%
fido_dev_largeblob_set 27 2 92.59% 36 4 88.89%
fido_dev_largeblob_set 27 0 100.00% 36 0 100.00%
fido_dev_largeblob_remove 12 0 100.00% 18 0 100.00%
fido_dev_largeblob_get_array 15 2 86.67% 27 4 85.19%
fido_dev_largeblob_set_array 14 0 100.00% 19 0 100.00%
@ -642,7 +645,7 @@ largeblob.c:largeblob_get_uv_token 19 0 100.00% 23
largeblob.c:largeblob_set_tx 35 0 100.00% 36 0 100.00%
largeblob.c:prepare_hmac 13 2 84.62% 23 7 69.57%
-------------------------------------------------------------------------------------------------------------------
TOTAL 513 21 95.91% 684 47 93.13%
TOTAL 513 19 96.30% 684 43 93.71%
File '/libfido2/src/log.c':
Name Regions Miss Cover Lines Miss Cover
@ -783,11 +786,11 @@ TOTAL 24 0 100.00% 23
File '/libfido2/src/rs1.c':
Name Regions Miss Cover Lines Miss Cover
---------------------------------------------------------------------------------------------------------------------
rs1_verify_sig 20 1 95.00% 30 3 90.00%
rs1_verify_sig 20 0 100.00% 30 0 100.00%
rs1.c:rs1_get_EVP_MD 4 0 100.00% 6 0 100.00%
rs1.c:rs1_free_EVP_MD 1 0 100.00% 3 0 100.00%
---------------------------------------------------------------------------------------------------------------------
TOTAL 25 1 96.00% 39 3 92.31%
TOTAL 25 0 100.00% 39 0 100.00%
File '/libfido2/src/rs256.c':
Name Regions Miss Cover Lines Miss Cover
@ -820,15 +823,17 @@ TOTAL 43 3 93.02% 43
File '/libfido2/src/tpm.c':
Name Regions Miss Cover Lines Miss Cover
---------------------------------------------------------------------------------------------------------------------
fido_get_signed_hash_tpm 20 0 100.00% 25 0 100.00%
tpm.c:check_rsa2048_pubarea 16 0 100.00% 28 0 100.00%
tpm.c:bswap_rsa2048_pubarea 1 0 100.00% 10 0 100.00%
fido_get_signed_hash_tpm 25 0 100.00% 39 0 100.00%
tpm.c:check_es256_pubarea 18 0 100.00% 30 0 100.00%
tpm.c:bswap_es256_pubarea 1 0 100.00% 12 0 100.00%
tpm.c:check_rs256_pubarea 16 0 100.00% 28 0 100.00%
tpm.c:bswap_rs256_pubarea 1 0 100.00% 10 0 100.00%
tpm.c:check_sha1_certinfo 14 0 100.00% 38 0 100.00%
tpm.c:get_signed_sha1 17 0 100.00% 19 0 100.00%
tpm.c:get_signed_name 7 0 100.00% 10 0 100.00%
tpm.c:bswap_sha1_certinfo 1 0 100.00% 8 0 100.00%
---------------------------------------------------------------------------------------------------------------------
TOTAL 76 0 100.00% 138 0 100.00%
TOTAL 100 0 100.00% 194 0 100.00%
File '/libfido2/src/types.c':
Name Regions Miss Cover Lines Miss Cover

View File

@ -175,15 +175,20 @@ static void
manifest(const struct param *p)
{
size_t ndevs, nfound;
fido_dev_info_t *devlist;
fido_dev_info_t *devlist = NULL, *devlist_set = NULL;
int16_t vendor_id, product_id;
fido_dev_io_t io;
fido_dev_transport_t t;
memset(&io, 0, sizeof(io));
memset(&t, 0, sizeof(t));
set_netlink_io_functions(fd_read, fd_write);
set_wire_data(p->netlink_wiredata.body, p->netlink_wiredata.len);
set_udev_parameters(p->uevent, &p->report_descriptor);
ndevs = uniform_random(64);
if ((devlist = fido_dev_info_new(ndevs)) == NULL ||
(devlist_set = fido_dev_info_new(1)) == NULL ||
fido_dev_info_manifest(devlist, ndevs, &nfound) != FIDO_OK)
goto out;
for (size_t i = 0; i < nfound; i++) {
@ -195,9 +200,13 @@ manifest(const struct param *p)
product_id = fido_dev_info_product(di);
consume(&vendor_id, sizeof(vendor_id));
consume(&product_id, sizeof(product_id));
fido_dev_info_set(devlist_set, 0, fido_dev_info_path(di),
fido_dev_info_manufacturer_string(di),
fido_dev_info_product_string(di), &io, &t);
}
out:
fido_dev_info_free(&devlist, ndevs);
fido_dev_info_free(&devlist_set, 1);
}
void

Binary file not shown.

View File

@ -16,33 +16,33 @@ src/authkey.c 44 0 100.00%
src/bio.c 419 20 95.23% 49 2 95.92% 559 21 96.24%
src/blob.c 53 2 96.23% 10 0 100.00% 83 4 95.18%
src/buf.c 8 1 87.50% 2 0 100.00% 16 1 93.75%
src/cbor.c 1047 28 97.33% 54 0 100.00% 1237 54 95.63%
src/cbor.c 1047 23 97.80% 54 0 100.00% 1237 46 96.28%
src/compress.c 34 4 88.24% 3 0 100.00% 28 3 89.29%
src/config.c 108 0 100.00% 11 0 100.00% 151 0 100.00%
src/cred.c 632 34 94.62% 69 2 97.10% 830 36 95.66%
src/credman.c 382 10 97.38% 40 0 100.00% 518 15 97.10%
src/dev.c 420 78 81.43% 44 6 86.36% 488 102 79.10%
src/dev.c 421 79 81.24% 45 7 84.44% 491 105 78.62%
src/ecdh.c 117 2 98.29% 4 0 100.00% 146 5 96.58%
src/eddsa.c 80 3 96.25% 10 0 100.00% 106 8 92.45%
src/err.c 122 10 91.80% 1 0 100.00% 126 10 92.06%
src/es256.c 306 5 98.37% 19 0 100.00% 358 7 98.04%
src/hid.c 60 0 100.00% 12 0 100.00% 114 0 100.00%
src/hid.c 87 2 97.70% 14 0 100.00% 145 3 97.93%
src/hid_linux.c 173 68 60.69% 14 7 50.00% 250 104 58.40%
src/hid_unix.c 28 20 28.57% 2 0 100.00% 43 24 44.19%
src/info.c 184 0 100.00% 39 0 100.00% 316 0 100.00%
src/io.c 182 7 96.15% 13 0 100.00% 221 11 95.02%
src/iso7816.c 18 1 94.44% 5 0 100.00% 38 0 100.00%
src/largeblob.c 513 21 95.91% 30 0 100.00% 684 47 93.13%
src/largeblob.c 513 19 96.30% 30 0 100.00% 684 43 93.71%
src/log.c 39 5 87.18% 7 1 85.71% 63 4 93.65%
src/netlink.c 328 14 95.73% 40 0 100.00% 498 32 93.57%
src/nfc_linux.c 327 73 77.68% 23 5 78.26% 458 124 72.93%
src/pin.c 403 3 99.26% 26 0 100.00% 495 3 99.39%
src/random.c 6 1 83.33% 1 0 100.00% 6 1 83.33%
src/reset.c 24 0 100.00% 3 0 100.00% 23 0 100.00%
src/rs1.c 25 1 96.00% 3 0 100.00% 39 3 92.31%
src/rs1.c 25 0 100.00% 3 0 100.00% 39 0 100.00%
src/rs256.c 141 8 94.33% 13 0 100.00% 172 10 94.19%
src/time.c 43 3 93.02% 3 0 100.00% 43 1 97.67%
src/tpm.c 76 0 100.00% 7 0 100.00% 138 0 100.00%
src/tpm.c 100 0 100.00% 9 0 100.00% 194 0 100.00%
src/types.c 25 0 100.00% 6 0 100.00% 46 0 100.00%
src/u2f.c 528 4 99.24% 17 0 100.00% 685 12 98.25%
@ -54,4 +54,4 @@ src/fido.h 0 0 -
src/fido/err.h 0 0 - 0 0 - 0 0 -
src/fido/param.h 0 0 - 0 0 - 0 0 -
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TOTAL 7809 481 93.84% 679 26 96.17% 10180 708 93.05%
TOTAL 7861 476 93.94% 684 27 96.05% 10270 699 93.19%

View File

@ -44,6 +44,7 @@ list(APPEND MAN_SOURCES
list(APPEND MAN_ALIAS
eddsa_pk_new eddsa_pk_free
eddsa_pk_new eddsa_pk_from_EVP_PKEY
eddsa_pk_new eddsa_pk_from_ptr
eddsa_pk_new eddsa_pk_to_EVP_PKEY
es256_pk_new es256_pk_free
@ -75,6 +76,7 @@ list(APPEND MAN_ALIAS
fido_assert_new fido_assert_user_id_len
fido_assert_new fido_assert_user_id_ptr
fido_assert_new fido_assert_user_name
fido_assert_set_authdata fido_assert_set_authdata_raw
fido_assert_set_authdata fido_assert_set_clientdata
fido_assert_set_authdata fido_assert_set_clientdata_hash
fido_assert_set_authdata fido_assert_set_count
@ -117,8 +119,8 @@ list(APPEND MAN_ALIAS
fido_cbor_info_new fido_cbor_info_free
fido_cbor_info_new fido_cbor_info_maxmsgsiz
fido_cbor_info_new fido_cbor_info_maxcredbloblen
fido_cbor_info_new fido_cbor_info_maxcredcntlst;
fido_cbor_info_new fido_cbor_info_maxcredidlen;
fido_cbor_info_new fido_cbor_info_maxcredcntlst
fido_cbor_info_new fido_cbor_info_maxcredidlen
fido_cbor_info_new fido_cbor_info_fwversion
fido_cbor_info_new fido_cbor_info_options_len
fido_cbor_info_new fido_cbor_info_options_name_ptr
@ -163,6 +165,7 @@ list(APPEND MAN_ALIAS
fido_cred_new fido_cred_user_name
fido_cred_new fido_cred_x5c_len
fido_cred_new fido_cred_x5c_ptr
fido_cred_verify fido_cred_verify_self
fido_credman_metadata_new fido_credman_del_dev_rk
fido_credman_metadata_new fido_credman_get_dev_metadata
fido_credman_metadata_new fido_credman_get_dev_rk
@ -211,6 +214,7 @@ list(APPEND MAN_ALIAS
fido_dev_info_manifest fido_dev_info_product
fido_dev_info_manifest fido_dev_info_product_string
fido_dev_info_manifest fido_dev_info_ptr
fido_dev_info_manifest fido_dev_info_set
fido_dev_info_manifest fido_dev_info_vendor
fido_dev_open fido_dev_build
fido_dev_open fido_dev_cancel
@ -219,26 +223,33 @@ list(APPEND MAN_ALIAS
fido_dev_open fido_dev_force_fido2
fido_dev_open fido_dev_force_u2f
fido_dev_open fido_dev_free
fido_dev_open fido_dev_has_pin
fido_dev_open fido_dev_has_uv
fido_dev_open fido_dev_is_fido2
fido_dev_open fido_dev_is_winhello
fido_dev_open fido_dev_major
fido_dev_open fido_dev_minor
fido_dev_open fido_dev_new
fido_dev_open fido_dev_new_with_info
fido_dev_open fido_dev_open_with_info
fido_dev_open fido_dev_protocol
fido_dev_open fido_dev_supports_cred_prot
fido_dev_open fido_dev_supports_credman
fido_dev_open fido_dev_supports_permissions
fido_dev_open fido_dev_supports_pin
fido_dev_open fido_dev_supports_uv
fido_dev_open fido_dev_has_uv
fido_dev_set_pin fido_dev_get_retry_count
fido_dev_set_pin fido_dev_get_uv_retry_count
fido_dev_set_pin fido_dev_reset
fido_dev_set_io_functions fido_dev_io_handle
fido_dev_set_io_functions fido_dev_set_sigmask
fido_dev_set_io_functions fido_dev_set_timeout
fido_dev_set_io_functions fido_dev_set_transport_functions
fido_dev_largeblob_get fido_dev_largeblob_set
fido_dev_largeblob_get fido_dev_largeblob_remove
fido_dev_largeblob_get fido_dev_largeblob_get_array
fido_dev_largeblob_get fido_dev_largeblob_set_array
fido_init fido_set_log_handler
rs256_pk_new rs256_pk_free
rs256_pk_new rs256_pk_from_ptr
rs256_pk_new rs256_pk_from_EVP_PKEY

42
contrib/libfido2/man/check.sh Executable file
View File

@ -0,0 +1,42 @@
#!/bin/sh -u
# Copyright (c) 2022 Yubico AB. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
T=$(mktemp -d) || exit 1
find . -maxdepth 1 -type f -name '*.3' -print0 > "$T/files"
xargs -0 awk '/^.Sh NAME/,/^.Nd/' < "$T/files" | \
awk '/^.Nm/ { print $2 }' | sort -u > "$T/Nm"
xargs -0 awk '/^.Fn/ { print $2 }' < "$T/files" | sort -u > "$T/Fn"
(cd "$T" && diff -u Nm Fn)
cut -c2- ../src/export.llvm | sort > "$T/exports"
(cd "$T" && diff -u Nm exports)
awk '/^list\(APPEND MAN_SOURCES/,/^\)/' CMakeLists.txt | \
awk '/.3$/ { print $1 }' | sort > "$T/listed_sources"
xargs -0 -n1 basename < "$T/files" | sort > "$T/actual_sources"
(cd "$T" && diff -u listed_sources actual_sources)
awk '/^list\(APPEND MAN_ALIAS/,/^\)/' CMakeLists.txt | \
sed '1d;$d' | awk '{ print $1, $2 }' | sort > "$T/listed_aliases"
xargs -0 grep -o "^.Fn [A-Za-z0-9_]* \"" < "$T/files" | \
cut -c3- | sed 's/\.3:\.Fn//;s/ "//' | awk '$1 != $2' | \
sort > "$T/actual_aliases"
(cd "$T" && diff -u listed_aliases actual_aliases)
xargs -0 grep -hB1 "^.Fn [A-Za-z0-9_]* \"" < "$T/files" | \
sed -E 's/^.F[tn] //;s/\*[^"\*]+"/\*"/g;s/ [^" \*]+"/"/g;/^--$/d' | \
paste -d " " - - | sed 's/\* /\*/' | sort > "$T/documented_prototypes"
while read -r f; do
awk "/\/\*/ { next } /$f\(/,/;/" ../src/fido.h ../src/fido/*.h | \
sed -E 's/^[ ]+//;s/[ ]+/ /' | tr '\n' ' ' | \
sed 's/(/ "/;s/, /" "/g;s/);/"/;s/ $/\n/'
done < "$T/exports" | sort > "$T/actual_prototypes"
(cd "$T" && diff -u documented_prototypes actual_prototypes)
(cd "$T" && rm files Nm Fn exports listed_sources actual_sources \
listed_aliases actual_aliases documented_prototypes actual_prototypes)
rmdir -- "$T"

View File

@ -11,7 +11,7 @@
.Nm eddsa_pk_from_EVP_PKEY ,
.Nm eddsa_pk_from_ptr ,
.Nm eddsa_pk_to_EVP_PKEY
.Nd FIDO 2 COSE EDDSA API
.Nd FIDO2 COSE EDDSA API
.Sh SYNOPSIS
.In openssl/evp.h
.In fido/eddsa.h
@ -106,7 +106,7 @@ If an error occurs,
returns NULL.
.Sh RETURN VALUES
The
.Fn eddsa_pk_from_EC_KEY
.Fn eddsa_pk_from_EVP_PKEY
and
.Fn eddsa_pk_from_ptr
functions return

View File

@ -9,10 +9,10 @@
.Nm es256_pk_new ,
.Nm es256_pk_free ,
.Nm es256_pk_from_EC_KEY ,
.Nm es256_pk_from_EVP_KEY ,
.Nm es256_pk_from_EVP_PKEY ,
.Nm es256_pk_from_ptr ,
.Nm es256_pk_to_EVP_PKEY
.Nd FIDO 2 COSE ES256 API
.Nd FIDO2 COSE ES256 API
.Sh SYNOPSIS
.In openssl/ec.h
.In fido/es256.h
@ -82,7 +82,7 @@ No references to
are kept.
.Pp
The
.Fn es256_pk_from_EVP_KEY
.Fn es256_pk_from_EVP_PKEY
function fills
.Fa pk
with the contents of
@ -124,7 +124,7 @@ returns NULL.
.Sh RETURN VALUES
The
.Fn es256_pk_from_EC_KEY ,
.Fn es256_pk_from_EVP_KEY ,
.Fn es256_pk_from_EVP_PKEY ,
and
.Fn es256_pk_from_ptr
functions return

View File

@ -7,7 +7,7 @@
.Os
.Sh NAME
.Nm fido2-assert
.Nd get/verify a FIDO 2 assertion
.Nd get/verify a FIDO2 assertion
.Sh SYNOPSIS
.Nm
.Fl G
@ -24,7 +24,7 @@
.Op Ar type
.Sh DESCRIPTION
.Nm
gets or verifies a FIDO 2 assertion.
gets or verifies a FIDO2 assertion.
.Pp
The input of
.Nm
@ -117,7 +117,7 @@ will not expect a credential id in its input, and may output
multiple assertions.
Resident credentials are called
.Dq discoverable credentials
in FIDO 2.1.
in CTAP 2.1.
.It Fl t Ar option
Toggles a key/value
.Ar option ,

View File

@ -7,7 +7,7 @@
.Os
.Sh NAME
.Nm fido2-cred
.Nd make/verify a FIDO 2 credential
.Nd make/verify a FIDO2 credential
.Sh SYNOPSIS
.Nm
.Fl M
@ -26,7 +26,7 @@
.Op Ar type
.Sh DESCRIPTION
.Nm
makes or verifies a FIDO 2 credential.
makes or verifies a FIDO2 credential.
.Pp
A credential
.Ar type
@ -143,7 +143,7 @@ will fail.
Create a resident credential.
Resident credentials are called
.Dq discoverable credentials
in FIDO 2.1.
in CTAP 2.1.
.It Fl u
Create a U2F credential.
By default,

View File

@ -7,7 +7,7 @@
.Os
.Sh NAME
.Nm fido2-token
.Nd find and manage a FIDO 2 authenticator
.Nd find and manage a FIDO2 authenticator
.Sh SYNOPSIS
.Nm
.Fl C
@ -121,7 +121,7 @@
.Fl V
.Sh DESCRIPTION
.Nm
manages a FIDO 2 authenticator.
manages a FIDO2 authenticator.
.Pp
The options are as follows:
.Bl -tag -width Ds
@ -176,12 +176,12 @@ where
is the enrollment's template base64-encoded id.
The user will be prompted for the PIN.
.It Fl D Fl u Ar device
Disables the FIDO 2.1
Disables the CTAP 2.1
.Dq user verification always
feature on
.Ar device .
.It Fl G Fl b Fl k Ar key_path Ar blob_path Ar device
Gets a FIDO 2.1
Gets a CTAP 2.1
.Dq largeBlob
encrypted with
.Ar key_path
@ -194,7 +194,7 @@ The blob is written to
.Ar blob_path .
A PIN or equivalent user-verification gesture is required.
.It Fl G Fl b Fl n Ar rp_id Oo Fl i Ar cred_id Oc Ar blob_path Ar device
Gets a FIDO 2.1
Gets a CTAP 2.1
.Dq largeBlob
associated with
.Ar rp_id
@ -234,7 +234,7 @@ The user will be prompted for the PIN.
.It Fl L
Produces a list of authenticators found by the operating system.
.It Fl L Fl b Ar device
Produces a list of FIDO 2.1
Produces a list of CTAP 2.1
.Dq largeBlobs
on
.Ar device .
@ -264,12 +264,12 @@ Sets the PIN of
.Ar device .
The user will be prompted for the PIN.
.It Fl S Fl a Ar device
Enables FIDO 2.1 Enterprise Attestation on
Enables CTAP 2.1 Enterprise Attestation on
.Ar device .
.It Fl S Fl b Fl k Ar key_path Ar blob_path Ar device
Sets
.Ar blob_path
as a FIDO 2.1
as a CTAP 2.1
.Dq largeBlob
encrypted with
.Ar key_path
@ -284,7 +284,7 @@ A PIN or equivalent user-verification gesture is required.
.It Fl S Fl b Fl n Ar rp_id Oo Fl i Ar cred_id Oc Ar blob_path Ar device
Sets
.Ar blob_path
as a FIDO 2.1
as a CTAP 2.1
.Dq largeBlob
associated with
.Ar rp_id
@ -353,7 +353,7 @@ the minimum PIN length of
Multiple IDs may be specified, separated by commas.
The user will be prompted for the PIN.
.It Fl S Fl u Ar device
Enables the FIDO 2.1
Enables the CTAP 2.1
.Dq user verification always
feature on
.Ar device .
@ -392,9 +392,9 @@ An authenticator's path may contain spaces.
.Pp
Resident credentials are called
.Dq discoverable credentials
in FIDO 2.1.
in CTAP 2.1.
.Pp
Whether the FIDO 2.1
Whether the CTAP 2.1
.Dq user verification always
feature is activated or deactivated after an authenticator reset
is vendor-specific.

View File

@ -7,7 +7,7 @@
.Os
.Sh NAME
.Nm fido_assert_allow_cred
.Nd appends a credential ID to the list of credentials allowed in an assertion
.Nd allow a credential in a FIDO2 assertion
.Sh SYNOPSIS
.In fido.h
.Ft int
@ -31,7 +31,7 @@ If
.Fn fido_assert_allow_cred
fails, the existing list of allowed credentials is preserved.
.Pp
For the format of a FIDO 2 credential ID, please refer to the
For the format of a FIDO2 credential ID, please refer to the
Web Authentication (webauthn) standard.
.Sh RETURN VALUES
The error codes returned by

View File

@ -31,7 +31,7 @@
.Nm fido_assert_id_len ,
.Nm fido_assert_sigcount ,
.Nm fido_assert_flags
.Nd FIDO 2 assertion API
.Nd FIDO2 assertion API
.Sh SYNOPSIS
.In fido.h
.Ft fido_assert_t *
@ -85,9 +85,12 @@
.Ft uint8_t
.Fn fido_assert_flags "const fido_assert_t *assert" "size_t idx"
.Sh DESCRIPTION
FIDO 2 assertions are abstracted in
.Em libfido2
by the
A FIDO2 assertion is a collection of statements, each statement a
map between a challenge, a credential, a signature, and ancillary
attributes.
In
.Em libfido2 ,
a FIDO2 assertion is abstracted by the
.Vt fido_assert_t
type.
The functions described in this page allow a
@ -153,48 +156,62 @@ If not NULL, the values returned by these functions point to
NUL-terminated UTF-8 strings.
.Pp
The
.Fn fido_assert_user_id_ptr ,
.Fn fido_assert_authdata_ptr ,
.Fn fido_assert_blob_ptr ,
.Fn fido_assert_hmac_secret_ptr ,
.Fn fido_assert_largeblob_key_ptr ,
.Fn fido_assert_clientdata_hash_ptr ,
.Fn fido_assert_id_ptr ,
.Fn fido_assert_user_id_ptr ,
.Fn fido_assert_sig_ptr ,
.Fn fido_assert_sigcount ,
and
.Fn fido_assert_id_ptr
functions return pointers to the user ID, CBOR-encoded
authenticator data, cred blob, hmac-secret,
.Dq largeBlobKey ,
signature, and credential ID attributes of statement
.Fa idx
in
.Fa assert .
.Pp
The
.Fn fido_assert_user_id_len ,
.Fn fido_assert_authdata_len ,
.Fn fido_assert_blob_len ,
.Fn fido_assert_hmac_secret_len ,
.Fn fido_assert_largeblob_key_len ,
.Fn fido_assert_sig_len ,
and
.Fn fido_assert_id_len
functions can be used to retrieve the corresponding length of a
specific attribute.
.Pp
The
.Fn fido_assert_sigcount
function can be used to obtain the signature counter of statement
.Fa idx
in
.Fa assert .
.Pp
The
.Fn fido_assert_flags
function returns the authenticator data flags of statement
functions return pointers to the CBOR-encoded authenticator data,
client data hash, credential ID, user ID, signature, signature
count, and authenticator data flags of statement
.Fa idx
in
.Fa assert .
.Pp
The
.Fn fido_assert_hmac_secret_ptr
function returns a pointer to the hmac-secret attribute of statement
.Fa idx
in
.Fa assert .
The HMAC Secret Extension
.Pq hmac-secret
is a CTAP 2.0 extension.
.Pp
The
.Fn fido_assert_blob_ptr
and
.Fn fido_assert_largeblob_key_ptr
functions return pointers to the
.Dq credBlob
and
.Dq largeBlobKey
attributes of statement
.Fa idx
in
.Fa assert .
Credential Blob
.Pq credBlob
and
Large Blob Key
.Pq largeBlobKey
are CTAP 2.1 extensions.
.Pp
The
.Fn fido_assert_authdata_len ,
.Fn fido_assert_clientdata_hash_len ,
.Fn fido_assert_id_len ,
.Fn fido_assert_user_id_len ,
.Fn fido_assert_sig_len ,
.Fn fido_assert_hmac_secret_len ,
.Fn fido_assert_blob_len ,
and
.Fn fido_assert_largeblob_key_len
functions return the length of a given attribute.
.Pp
Please note that the first statement in
.Fa assert
has an
@ -202,31 +219,27 @@ has an
(index) value of 0.
.Pp
The authenticator data and signature parts of an assertion
statement are typically passed to a FIDO 2 server for verification.
.Pp
The
.Fn fido_assert_clientdata_hash_ptr
function returns a pointer to the client data hash of
.Fa assert .
The corresponding length can be obtained by
.Fn fido_assert_clientdata_hash_len .
statement are typically passed to a FIDO2 server for verification.
.Sh RETURN VALUES
The authenticator data returned by
.Fn fido_assert_authdata_ptr
is a CBOR-encoded byte string, as obtained from the authenticator.
.Pp
The
.Fn fido_assert_rp_id ,
.Fn fido_assert_user_display_name ,
.Fn fido_assert_user_icon ,
.Fn fido_assert_user_name ,
.Fn fido_assert_authdata_ptr ,
.Fn fido_assert_clientdata_hash_ptr ,
.Fn fido_assert_hmac_secret_ptr ,
.Fn fido_assert_largeblob_key_ptr ,
.Fn fido_assert_id_ptr ,
.Fn fido_assert_user_id_ptr ,
.Fn fido_assert_sig_ptr ,
.Fn fido_assert_hmac_secret_ptr ,
.Fn fido_assert_blob_ptr ,
and
.Fn fido_assert_sig_ptr
functions return NULL if the respective field in
.Fn fido_assert_largeblob_key_ptr
functions may return NULL if the respective field in
.Fa assert
is not set.
If not NULL, returned pointers are guaranteed to exist until any API

View File

@ -18,7 +18,7 @@
.Nm fido_assert_set_uv ,
.Nm fido_assert_set_rp ,
.Nm fido_assert_set_sig
.Nd set parameters of a FIDO 2 assertion
.Nd set parameters of a FIDO2 assertion
.Sh SYNOPSIS
.In fido.h
.Bd -literal
@ -29,9 +29,9 @@ typedef enum {
} fido_opt_t;
.Ed
.Ft int
.Fn fido_assert_set_authdata "fido_assert_t *assert" " size_t idx" "const unsigned char *ptr" "size_t len"
.Fn fido_assert_set_authdata "fido_assert_t *assert" "size_t idx" "const unsigned char *ptr" "size_t len"
.Ft int
.Fn fido_assert_set_authdata_raw "fido_assert_t *assert" " size_t idx" "const unsigned char *ptr" "size_t len"
.Fn fido_assert_set_authdata_raw "fido_assert_t *assert" "size_t idx" "const unsigned char *ptr" "size_t len"
.Ft int
.Fn fido_assert_set_clientdata "fido_assert_t *assert" "const unsigned char *ptr" "size_t len"
.Ft int
@ -43,7 +43,7 @@ typedef enum {
.Ft int
.Fn fido_assert_set_hmac_salt "fido_assert_t *assert" "const unsigned char *ptr" "size_t len"
.Ft int
.Fn fido_assert_set_hmac_secret "fido_assert_t *assert" "const unsigned char *ptr" "size_t len"
.Fn fido_assert_set_hmac_secret "fido_assert_t *assert" "size_t idx" "const unsigned char *ptr" "size_t len"
.Ft int
.Fn fido_assert_set_up "fido_assert_t *assert" "fido_opt_t up"
.Ft int
@ -55,14 +55,14 @@ typedef enum {
.Sh DESCRIPTION
The
.Nm
set of functions define the various parameters of a FIDO 2
set of functions define the various parameters of a FIDO2
assertion, allowing a
.Fa fido_assert_t
type to be prepared for a subsequent call to
.Xr fido_dev_get_assert 3
or
.Xr fido_assert_verify 3 .
For the complete specification of a FIDO 2 assertion and the format
For the complete specification of a FIDO2 assertion and the format
of its constituent parts, please refer to the Web Authentication
(webauthn) standard.
.Pp
@ -106,11 +106,8 @@ Alternatively, a raw binary blob may be passed to
.Fn fido_assert_set_authdata_raw .
.Pp
The
.Fn fido_assert_set_clientdata_hash ,
.Fn fido_assert_set_hmac_salt ,
and
.Fn fido_assert_set_hmac_secret
functions set the client data hash and hmac-salt parts of
.Fn fido_assert_set_clientdata_hash
function sets the client data hash of
.Fa assert
to
.Fa ptr ,
@ -167,6 +164,29 @@ is zero, the extensions of
are cleared.
.Pp
The
.Fn fido_assert_set_hmac_salt
and
.Fn fido_assert_set_hmac_secret
functions set the hmac-salt and hmac-secret parts of
.Fa assert
to
.Fa ptr ,
where
.Fa ptr
points to
.Fa len
bytes.
A copy of
.Fa ptr
is made, and no references to the passed pointer are kept.
The HMAC Secret
.Pq hmac-secret
Extension is a CTAP 2.0 extension.
The
.Fn fido_assert_set_hmac_secret
function is normally only useful when writing tests.
.Pp
The
.Fn fido_assert_set_up
and
.Fn fido_assert_set_uv
@ -184,27 +204,22 @@ by default, allowing the authenticator to use its default settings.
Use of the
.Nm
set of functions may happen in two distinct situations:
when asking a FIDO device to produce a series of assertion
when asking a FIDO2 device to produce a series of assertion
statements, prior to
.Xr fido_dev_get_assert 3
(i.e, in the context of a FIDO client), or when verifying assertion
(i.e, in the context of a FIDO2 client), or when verifying assertion
statements using
.Xr fido_assert_verify 3
(i.e, in the context of a FIDO server).
(i.e, in the context of a FIDO2 server).
.Pp
For a complete description of the generation of a FIDO 2 assertion
and its verification, please refer to the FIDO 2 specification.
For a complete description of the generation of a FIDO2 assertion
and its verification, please refer to the FIDO2 specification.
An example of how to use the
.Nm
set of functions can be found in the
.Pa examples/assert.c
file shipped with
.Em libfido2 .
.Pp
.Fn fido_assert_set_hmac_secret
is not normally useful in a FIDO client or server \(em it is provided
to enable testing other functionality that relies on retrieving the
HMAC secret from an assertion obtained from an authenticator.
.Sh RETURN VALUES
The
.Nm

View File

@ -7,11 +7,11 @@
.Os
.Sh NAME
.Nm fido_assert_verify
.Nd verifies the signature of a FIDO 2 assertion statement
.Nd verifies the signature of a FIDO2 assertion statement
.Sh SYNOPSIS
.In fido.h
.Ft int
.Fn fido_assert_verify "fido_assert_t *assert" "size_t idx" "int cose_alg" "const void *pk"
.Fn fido_assert_verify "const fido_assert_t *assert" "size_t idx" "int cose_alg" "const void *pk"
.Sh DESCRIPTION
The
.Fn fido_assert_verify
@ -23,7 +23,7 @@ matches the parameters of the assertion.
Before using
.Fn fido_assert_verify
in a sensitive context, the reader is strongly encouraged to make
herself familiar with the FIDO 2 assertion statement process
herself familiar with the FIDO2 assertion statement process
as defined in the Web Authentication (webauthn) standard.
.Pp
A brief description follows:

View File

@ -13,7 +13,7 @@
.Nm fido_bio_dev_enroll_remove ,
.Nm fido_bio_dev_get_template_array ,
.Nm fido_bio_dev_set_template_name
.Nd FIDO 2 biometric authenticator API
.Nd FIDO2 biometric authenticator API
.Sh SYNOPSIS
.In fido.h
.In fido/bio.h

View File

@ -10,7 +10,7 @@
.Nm fido_bio_enroll_free ,
.Nm fido_bio_enroll_last_status ,
.Nm fido_bio_enroll_remaining_samples
.Nd FIDO 2 biometric enrollment API
.Nd FIDO2 biometric enrollment API
.Sh SYNOPSIS
.In fido.h
.In fido/bio.h
@ -40,7 +40,7 @@
.Ft uint8_t
.Fn fido_bio_enroll_remaining_samples "const fido_bio_enroll_t *enroll"
.Sh DESCRIPTION
Ongoing FIDO 2 biometric enrollments are abstracted in
Ongoing FIDO2 biometric enrollments are abstracted in
.Em libfido2
by the
.Vt fido_bio_enroll_t

View File

@ -10,7 +10,7 @@
.Nm fido_bio_info_free ,
.Nm fido_bio_info_type ,
.Nm fido_bio_info_max_samples
.Nd FIDO 2 biometric sensor information API
.Nd FIDO2 biometric sensor information API
.Sh SYNOPSIS
.In fido.h
.In fido/bio.h

View File

@ -17,7 +17,7 @@
.Nm fido_bio_template_new ,
.Nm fido_bio_template_set_id ,
.Nm fido_bio_template_set_name
.Nd FIDO 2 biometric template API
.Nd FIDO2 biometric template API
.Sh SYNOPSIS
.In fido.h
.In fido/bio.h
@ -44,7 +44,7 @@
.Ft const fido_bio_template_t *
.Fn fido_bio_template "const fido_bio_template_array_t *array" "size_t idx"
.Sh DESCRIPTION
Existing FIDO 2 biometric enrollments are abstracted in
Existing FIDO2 biometric enrollments are abstracted in
.Em libfido2
by the
.Vt fido_bio_template_t

View File

@ -26,10 +26,11 @@
.Nm fido_cbor_info_versions_len ,
.Nm fido_cbor_info_options_len ,
.Nm fido_cbor_info_maxmsgsiz ,
.Nm fido_cbor_info_maxcredbloblen ,
.Nm fido_cbor_info_maxcredcntlst ,
.Nm fido_cbor_info_maxcredidlen ,
.Nm fido_cbor_info_fwversion
.Nd FIDO 2 CBOR Info API
.Nd FIDO2 CBOR Info API
.Sh SYNOPSIS
.In fido.h
.Ft fido_cbor_info_t *

View File

@ -44,7 +44,7 @@ then
.Xr fido_dev_make_cred 3
will fail.
.Pp
For the format of a FIDO 2 credential ID, please refer to the
For the format of a FIDO2 credential ID, please refer to the
Web Authentication (webauthn) standard.
.Sh RETURN VALUES
The error codes returned by

View File

@ -40,7 +40,7 @@
.Nm fido_cred_type ,
.Nm fido_cred_flags ,
.Nm fido_cred_sigcount
.Nd FIDO 2 credential API
.Nd FIDO2 credential API
.Sh SYNOPSIS
.In fido.h
.Ft fido_cred_t *
@ -112,7 +112,7 @@
.Ft uint32_t
.Fn fido_cred_sigcount "const fido_cred_t *cred"
.Sh DESCRIPTION
FIDO 2 credentials are abstracted in
FIDO2 credentials are abstracted in
.Em libfido2
by the
.Vt fido_cred_t
@ -155,7 +155,7 @@ may be NULL, in which case
.Fn fido_cred_free
is a NOP.
.Pp
If the FIDO 2.1
If the CTAP 2.1
.Dv FIDO_EXT_MINPINLEN
extension is enabled on
.Fa cred ,
@ -170,7 +170,7 @@ See
.Xr fido_cred_set_pin_minlen 3
on how to enable this extension.
.Pp
If the FIDO 2.1
If the CTAP 2.1
.Dv FIDO_EXT_CRED_PROTECT
extension is enabled on
.Fa cred ,
@ -243,7 +243,7 @@ and
.Fn fido_cred_attstmt_len .
.Pp
The authenticator data, x509 certificate, and signature parts of a
credential are typically passed to a FIDO 2 server for verification.
credential are typically passed to a FIDO2 server for verification.
.Pp
The
.Fn fido_cred_type

View File

@ -24,7 +24,7 @@
.Nm fido_cred_set_uv ,
.Nm fido_cred_set_fmt ,
.Nm fido_cred_set_type
.Nd set parameters of a FIDO 2 credential
.Nd set parameters of a FIDO2 credential
.Sh SYNOPSIS
.In fido.h
.Bd -literal
@ -73,14 +73,14 @@ typedef enum {
.Sh DESCRIPTION
The
.Nm
set of functions define the various parameters of a FIDO 2
set of functions define the various parameters of a FIDO2
credential, allowing a
.Fa fido_cred_t
type to be prepared for a subsequent call to
.Xr fido_dev_make_cred 3
or
.Xr fido_cred_verify 3 .
For the complete specification of a FIDO 2 credential and the format
For the complete specification of a FIDO2 credential and the format
of its constituent parts, please refer to the Web Authentication
(webauthn) standard.
.Pp
@ -229,7 +229,7 @@ bytes long.
.Pp
The
.Fn fido_cred_set_pin_minlen
function enables the FIDO 2.1
function enables the CTAP 2.1
.Dv FIDO_EXT_MINPINLEN
extension on
.Fa cred
@ -249,7 +249,7 @@ extension is disabled on
.Pp
The
.Fn fido_cred_set_prot
function enables the FIDO 2.1
function enables the CTAP 2.1
.Dv FIDO_EXT_CRED_PROTECT
extension on
.Fa cred
@ -325,15 +325,15 @@ Note that not all authenticators support COSE_RS256 or COSE_EDDSA.
Use of the
.Nm
set of functions may happen in two distinct situations:
when generating a new credential on a FIDO device, prior to
when generating a new credential on a FIDO2 device, prior to
.Xr fido_dev_make_cred 3
(i.e, in the context of a FIDO client), or when validating
(i.e, in the context of a FIDO2 client), or when validating
a generated credential using
.Xr fido_cred_verify 3
(i.e, in the context of a FIDO server).
(i.e, in the context of a FIDO2 server).
.Pp
For a complete description of the generation of a FIDO 2 credential
and its verification, please refer to the FIDO 2 specification.
For a complete description of the generation of a FIDO2 credential
and its verification, please refer to the FIDO2 specification.
A concrete utilisation example of the
.Nm
set of functions can be found in the

View File

@ -6,26 +6,31 @@
.Dt FIDO_CRED_VERIFY 3
.Os
.Sh NAME
.Nm fido_cred_verify
.Nd verifies the attestation signature of a FIDO 2 credential
.Nm fido_cred_verify ,
.Nm fido_cred_verify_self
.Nd verify the attestation signature of a FIDO2 credential
.Sh SYNOPSIS
.In fido.h
.Ft int
.Fn fido_cred_verify "const fido_cred_t *cred"
.Ft int
.Fn fido_cred_verify_self "const fido_cred_t *cred"
.Sh DESCRIPTION
The
.Fn fido_cred_verify
function verifies whether the attestation signature contained in
and
.Fn fido_cred_verify_self
functions verify whether the attestation signature contained in
.Fa cred
matches the attributes of the credential.
Before using
.Fn fido_cred_verify
or
.Fn fido_cred_verify_self
in a sensitive context, the reader is strongly encouraged to make
herself familiar with the FIDO 2 credential attestation process
herself familiar with the FIDO2 credential attestation process
as defined in the Web Authentication (webauthn) standard.
.Pp
A brief description follows:
.Pp
The
.Fn fido_cred_verify
function verifies whether the client data hash, relying party ID,
@ -48,19 +53,36 @@ The attestation type implemented by
.Fn fido_cred_verify
is
.Em Basic Attestation .
.Pp
The
.Fn fido_cred_verify_self
function verifies whether the client data hash, relying party ID,
credential ID, type, protection policy, minimum PIN length, and
resident/discoverable key and user verification attributes of
.Fa cred
have been attested by the holder of the credential's private key.
.Pp
The attestation statement formats supported by
.Fn fido_cred_verify_self
are
.Em packed
and
.Em fido-u2f .
The attestation type implemented by
.Fn fido_cred_verify_self
is
.Em Self Attestation .
.Pp
Other attestation formats and types are not supported.
.Sh RETURN VALUES
The error codes returned by
.Fn fido_cred_verify
and
.Fn fido_cred_verify_self
are defined in
.In fido/err.h .
If
.Fa cred
does not contain attestation data, then
.Dv FIDO_ERR_INVALID_ARGUMENT
is returned.
If
.Fa cred
passes verification, then
.Dv FIDO_OK
is returned.

View File

@ -26,7 +26,7 @@
.Nm fido_credman_set_dev_rk ,
.Nm fido_credman_del_dev_rk ,
.Nm fido_credman_get_dev_rp
.Nd FIDO 2 credential management API
.Nd FIDO2 credential management API
.Sh SYNOPSIS
.In fido.h
.In fido/credman.h
@ -307,7 +307,7 @@ The
.Fn fido_credman_set_dev_rk ,
.Fn fido_credman_del_dev_rk ,
and
.Fn fido_credman_get_dev_rp
.Fn fido_credman_get_dev_rp
functions return
.Dv FIDO_OK
on success.
@ -323,4 +323,4 @@ should have their return values checked for NULL.
.Sh CAVEATS
Resident credentials are called
.Dq discoverable credentials
in FIDO 2.1.
in CTAP 2.1.

View File

@ -11,7 +11,7 @@
.Nm fido_dev_force_pin_change ,
.Nm fido_dev_set_pin_minlen ,
.Nm fido_dev_set_pin_minlen_rpid
.Nd FIDO 2.1 configuration authenticator API
.Nd CTAP 2.1 configuration authenticator API
.Sh SYNOPSIS
.In fido.h
.In fido/config.h
@ -27,7 +27,7 @@
.Fn fido_dev_set_pin_minlen_rpid "fido_dev_t *dev" "const char * const *rpid" "size_t n" "const char *pin"
.Sh DESCRIPTION
The functions described in this page allow configuration of a
FIDO 2.1 authenticator.
CTAP 2.1 authenticator.
.Pp
The
.Fn fido_dev_enable_entattest
@ -86,7 +86,7 @@ function sets the list of relying party identifiers
.Pq RP IDs
that are allowed to obtain the minimum PIN length of
.Fa dev
through the FIDO 2.1
through the CTAP 2.1
.Dv FIDO_EXT_MINPINLEN
extension.
The list of RP identifiers is denoted by

View File

@ -7,15 +7,15 @@
.Os
.Sh NAME
.Nm fido_dev_get_assert
.Nd obtains an assertion from a FIDO device
.Nd obtains an assertion from a FIDO2 device
.Sh SYNOPSIS
.In fido.h
.Ft int
.Fn fido_dev_get_assert "fido_dev_t *dev" " fido_assert_t *assert" "const char *pin"
.Fn fido_dev_get_assert "fido_dev_t *dev" "fido_assert_t *assert" "const char *pin"
.Sh DESCRIPTION
The
.Fn fido_dev_get_assert
function asks the FIDO device represented by
function asks the FIDO2 device represented by
.Fa dev
for an assertion according to the following parameters defined in
.Fa assert :

View File

@ -8,7 +8,7 @@
.Sh NAME
.Nm fido_dev_get_touch_begin ,
.Nm fido_dev_get_touch_status
.Nd asynchronously wait for touch on a FIDO 2 authenticator
.Nd asynchronously wait for touch on a FIDO2 authenticator
.Sh SYNOPSIS
.In fido.h
.Ft int
@ -17,7 +17,7 @@
.Fn fido_dev_get_touch_status "fido_dev_t *dev" "int *touched" "int ms"
.Sh DESCRIPTION
The functions described in this page allow an application to
asynchronously wait for touch on a FIDO authenticator.
asynchronously wait for touch on a FIDO2 authenticator.
This is useful when multiple authenticators are present and
the application needs to know which one to use.
.Pp

View File

@ -14,8 +14,9 @@
.Nm fido_dev_info_product ,
.Nm fido_dev_info_vendor ,
.Nm fido_dev_info_manufacturer_string ,
.Nm fido_dev_info_product_string
.Nd FIDO 2 device discovery functions
.Nm fido_dev_info_product_string ,
.Nm fido_dev_info_set
.Nd FIDO2 device discovery functions
.Sh SYNOPSIS
.In fido.h
.Ft int
@ -36,6 +37,8 @@
.Fn fido_dev_info_manufacturer_string "const fido_dev_info_t *di"
.Ft const char *
.Fn fido_dev_info_product_string "const fido_dev_info_t *di"
.Ft int
.Fn fido_dev_info_set "fido_dev_info_t *devlist" "size_t i" "const char *path" "const char *manufacturer" "const char *product" "const fido_dev_io_t *io" "const fido_dev_transport_t *transport"
.Sh DESCRIPTION
The
.Fn fido_dev_info_manifest
@ -43,7 +46,7 @@ function fills
.Fa devlist
with up to
.Fa ilen
FIDO devices found by the underlying operating system.
FIDO2 devices found by the underlying operating system.
Currently only USB HID devices are supported.
The number of discovered devices is returned in
.Fa olen ,
@ -133,6 +136,30 @@ can be found in the
.Pa examples/manifest.c
file shipped with
.Em libfido2 .
.Pp
The
.Fn fido_dev_info_set
function initializes an entry in a device list allocated by
.Fn fido_dev_info_new
with the specified path, manufacturer, and product strings, and with
the specified I/O handlers and, optionally, transport functions, as
described in
.Xr fido_dev_set_io_functions 3 .
The
.Fa io
argument must be specified; the
.Fa transport
argument may be
.Dv NULL .
The path, I/O handlers, and transport functions will be used
automatically by
.Xr fido_dev_new_with_info 3
and
.Xr fido_dev_open_with_info 3 .
An application can use this, for example, to substitute mock FIDO2
devices in testing for the real ones that
.Fn fido_dev_info_manifest
would discover.
.Sh RETURN VALUES
The
.Fn fido_dev_info_manifest
@ -142,6 +169,14 @@ If a discovery error occurs, the
.Fa olen
pointer is set to 0.
.Pp
On success, the
.Fn fido_dev_info_set
function returns
.Dv FIDO_OK .
On error, a different error code defined in
.In fido/err.h
is returned.
.Pp
The pointers returned by
.Fn fido_dev_info_ptr ,
.Fn fido_dev_info_path ,

View File

@ -11,7 +11,7 @@
.Nm fido_dev_largeblob_remove ,
.Nm fido_dev_largeblob_get_array ,
.Nm fido_dev_largeblob_set_array
.Nd FIDO 2 large blob API
.Nd FIDO2 large blob API
.Sh SYNOPSIS
.In fido.h
.Ft int
@ -29,10 +29,10 @@ The
.Dq largeBlobs
API of
.Em libfido2
allows binary blobs residing on a FIDO 2.1 authenticator to be
allows binary blobs residing on a CTAP 2.1 authenticator to be
read, written, and inspected.
.Dq largeBlobs
is a FIDO 2.1 extension.
is a CTAP 2.1 extension.
.Pp
.Dq largeBlobs
are stored as elements of a CBOR array.
@ -58,9 +58,9 @@ The
.Dq largeBlobs
CBOR array is opaque to the authenticator.
Management of the array is left at the discretion of FIDO2 clients.
For further details on FIDO 2.1's
For further details on CTAP 2.1's
.Dq largeBlobs
extension, please refer to the FIDO 2.1 spec.
extension, please refer to the CTAP 2.1 spec.
.Pp
The
.Fn fido_dev_largeblob_get

View File

@ -7,15 +7,15 @@
.Os
.Sh NAME
.Nm fido_dev_make_cred
.Nd generates a new credential on a FIDO device
.Nd generates a new credential on a FIDO2 device
.Sh SYNOPSIS
.In fido.h
.Ft int
.Fn fido_dev_make_cred "fido_dev_t *dev" " fido_cred_t *cred" "const char *pin"
.Fn fido_dev_make_cred "fido_dev_t *dev" "fido_cred_t *cred" "const char *pin"
.Sh DESCRIPTION
The
.Fn fido_dev_make_cred
function asks the FIDO device represented by
function asks the FIDO2 device represented by
.Fa dev
to generate a new credential according to the following parameters
defined in

View File

@ -7,9 +7,11 @@
.Os
.Sh NAME
.Nm fido_dev_open ,
.Nm fido_dev_open_with_info ,
.Nm fido_dev_close ,
.Nm fido_dev_cancel ,
.Nm fido_dev_new ,
.Nm fido_dev_new_with_info ,
.Nm fido_dev_free ,
.Nm fido_dev_force_fido2 ,
.Nm fido_dev_force_u2f ,
@ -17,26 +19,31 @@
.Nm fido_dev_is_winhello ,
.Nm fido_dev_supports_credman ,
.Nm fido_dev_supports_cred_prot ,
.Nm fido_dev_supports_permissions ,
.Nm fido_dev_supports_pin ,
.Nm fido_dev_has_pin ,
.Nm fido_dev_supports_uv ,
.Nm fido_dev_has_pin ,
.Nm fido_dev_has_uv ,
.Nm fido_dev_protocol ,
.Nm fido_dev_build ,
.Nm fido_dev_flags ,
.Nm fido_dev_major ,
.Nm fido_dev_minor
.Nd FIDO 2 device open/close and related functions
.Nd FIDO2 device open/close and related functions
.Sh SYNOPSIS
.In fido.h
.Ft int
.Fn fido_dev_open "fido_dev_t *dev" "const char *path"
.Ft int
.Fn fido_dev_open_with_info "fido_dev_t *dev"
.Ft int
.Fn fido_dev_close "fido_dev_t *dev"
.Ft int
.Fn fido_dev_cancel "fido_dev_t *dev"
.Ft fido_dev_t *
.Fn fido_dev_new "void"
.Ft fido_dev_t *
.Fn fido_dev_new_with_info "const fido_dev_info_t *"
.Ft void
.Fn fido_dev_free "fido_dev_t **dev_p"
.Ft void
@ -52,12 +59,14 @@
.Ft bool
.Fn fido_dev_supports_cred_prot "const fido_dev_t *dev"
.Ft bool
.Fn fido_dev_supports_permissions "const fido_dev_t *dev"
.Ft bool
.Fn fido_dev_supports_pin "const fido_dev_t *dev"
.Ft bool
.Fn fido_dev_has_pin "const fido_dev_t *dev"
.Ft bool
.Fn fido_dev_supports_uv "const fido_dev_t *dev"
.Ft bool
.Fn fido_dev_has_pin "const fido_dev_t *dev"
.Ft bool
.Fn fido_dev_has_uv "const fido_dev_t *dev"
.Ft uint8_t
.Fn fido_dev_protocol "const fido_dev_t *dev"
@ -92,6 +101,13 @@ flag was set in
.Xr fido_init 3 .
.Pp
The
.Fn fido_dev_open_with_info
function opens
.Fa dev
as previously allocated using
.Fn fido_dev_new_with_info .
.Pp
The
.Fn fido_dev_close
function closes the device represented by
.Fa dev .
@ -113,6 +129,18 @@ function returns a pointer to a newly allocated, empty
If memory cannot be allocated, NULL is returned.
.Pp
The
.Fn fido_dev_new_with_info
function returns a pointer to a newly allocated
.Vt fido_dev_t
with
.Vt fido_dev_info_t
parameters, for use with
.Xr fido_dev_info_manifest 3
and
.Fn fido_dev_open_with_info .
If memory cannot be allocated, NULL is returned.
.Pp
The
.Fn fido_dev_free
function releases the memory backing
.Fa *dev_p ,
@ -134,12 +162,18 @@ is a NOP.
The
.Fn fido_dev_force_fido2
function can be used to force CTAP2 communication with
.Fa dev .
.Fa dev ,
where
.Fa dev
is an open device.
.Pp
The
.Fn fido_dev_force_u2f
function can be used to force CTAP1 (U2F) communication with
.Fa dev .
.Fa dev ,
where
.Fa dev
is an open device.
.Pp
The
.Fn fido_dev_is_fido2
@ -147,7 +181,7 @@ function returns
.Dv true
if
.Fa dev
is a FIDO 2 device.
is a FIDO2 device.
.Pp
The
.Fn fido_dev_is_winhello
@ -163,7 +197,7 @@ function returns
.Dv true
if
.Fa dev
supports FIDO 2.1 Credential Management.
supports CTAP 2.1 Credential Management.
.Pp
The
.Fn fido_dev_supports_cred_prot
@ -171,7 +205,15 @@ function returns
.Dv true
if
.Fa dev
supports FIDO 2.1 Credential Protection.
supports CTAP 2.1 Credential Protection.
.Pp
The
.Fn fido_dev_supports_permissions
function returns
.Dv true
if
.Fa dev
supports CTAP 2.1 UV token permissions.
.Pp
The
.Fn fido_dev_supports_pin
@ -179,15 +221,7 @@ function returns
.Dv true
if
.Fa dev
supports FIDO 2.0 Client PINs.
.Pp
The
.Fn fido_dev_has_pin
function returns
.Dv true
if
.Fa dev
has a FIDO 2.0 Client PIN set.
supports CTAP 2.0 Client PINs.
.Pp
The
.Fn fido_dev_supports_uv
@ -198,6 +232,14 @@ if
supports a built-in user verification method.
.Pp
The
.Fn fido_dev_has_pin
function returns
.Dv true
if
.Fa dev
has a CTAP 2.0 Client PIN set.
.Pp
The
.Fn fido_dev_has_uv
function returns
.Dv true
@ -236,7 +278,8 @@ functions above, please refer to the FIDO Client to Authenticator
Protocol (CTAP) specification.
.Sh RETURN VALUES
On success,
.Fn fido_dev_open
.Fn fido_dev_open ,
.Fn fido_dev_open_with_info ,
and
.Fn fido_dev_close
return

View File

@ -8,8 +8,10 @@
.Sh NAME
.Nm fido_dev_set_io_functions ,
.Nm fido_dev_set_sigmask ,
.Nm fido_dev_set_timeout
.Nd FIDO 2 device I/O interface
.Nm fido_dev_set_timeout ,
.Nm fido_dev_set_transport_functions ,
.Nm fido_dev_io_handle
.Nd FIDO2 device I/O interface
.Sh SYNOPSIS
.In fido.h
.Bd -literal
@ -30,13 +32,28 @@ typedef int fido_sigset_t;
#else
typedef sigset_t fido_sigset_t;
#endif
typedef int fido_dev_rx_t(struct fido_dev *,
uint8_t, unsigned char *, size_t, int);
typedef int fido_dev_tx_t(struct fido_dev *,
uint8_t, const unsigned char *, size_t);
typedef struct fido_dev_transport {
fido_dev_rx_t *rx;
fido_dev_tx_t *tx;
} fido_dev_transport_t;
.Ed
.Pp
.Ft int
.Fn fido_dev_set_io_functions "fido_dev_t *dev" "const fido_dev_io_t *io"
.Ft int
.Fn fido_dev_set_sigmask "fido_dev_t *dev" "const fido_sigset_t *sigmask"
.Ft int
.Fn fido_dev_set_timeout "fido_dev_t *dev" "int ms"
.Ft int
.Fn fido_dev_set_transport_functions "fido_dev_t *dev" "const fido_dev_transport_t *t"
.Ft void *
.Fn fido_dev_io_handle "const fido_dev_t *dev"
.Sh DESCRIPTION
The
.Fn fido_dev_set_io_functions
@ -148,9 +165,59 @@ This is the default behaviour.
When using the Windows Hello backend,
.Fa ms
is used as a guidance and may be overwritten by the platform.
.Pp
The
.Fn fido_dev_set_transport_functions
function sets the transport functions used by
.Em libfido2
to talk to
.Fa dev .
While the I/O handlers are responsible for sending and receiving
transmission units of initialization and continuation packets already
formatted by
.Em libfido2 ,
the transport handlers are responsible for sending and receiving
the CTAPHID commands and data directly, as defined in the FIDO Client
to Authenticator Protocol (CTAP) standard.
They are defined as follows:
.Bl -tag -width Ds
.It Vt fido_dev_tx_t
Receives a device, a CTAPHID command to transmit, a data buffer to
transmit, and the length of the data buffer.
On success, 0 is returned.
On error, -1 is returned.
.It Vt fido_dev_rx_t
Receives a device, a CTAPHID command whose response the caller expects
to receive, a data buffer to receive into, the size of the data buffer
determining the maximum length of a response, and the maximum number of
milliseconds to wait for a response.
On success, the number of bytes read into the data buffer is returned.
On error, -1 is returned.
.El
.Pp
When transport functions are specified,
.Em libfido2
will use them instead of the
.Dv read
and
.Dv write
functions of the I/O handlers.
However, the I/O handlers must still be specified to open and close the
device.
.Pp
The
.Fn fido_dev_io_handle
function returns the opaque pointer returned by the
.Dv open
function of the I/O handlers.
This is useful mainly for the transport functions, which unlike the I/O
handlers are passed the
.Vt fido_dev_t
pointer instead of the opaque I/O handle.
.Sh RETURN VALUES
On success,
.Fn fido_dev_set_io_functions ,
.Fn fido_dev_set_transport_functions ,
.Fn fido_dev_set_sigmask ,
and
.Fn fido_dev_set_timeout
@ -159,3 +226,13 @@ return
On error, a different error code defined in
.In fido/err.h
is returned.
.Sh SEE ALSO
.Xr fido_dev_info_manifest 3 ,
.Xr fido_dev_open 3
.Rs
.%D 2021-06-15
.%O Proposed Standard, Version 2.1
.%Q FIDO Alliance
.%R Client to Authenticator Protocol (CTAP)
.%U https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html
.Re

View File

@ -10,7 +10,7 @@
.Nm fido_dev_get_retry_count ,
.Nm fido_dev_get_uv_retry_count ,
.Nm fido_dev_reset
.Nd FIDO 2 device management functions
.Nd FIDO2 device management functions
.Sh SYNOPSIS
.In fido.h
.Ft int

View File

@ -6,12 +6,19 @@
.Dt FIDO_INIT 3
.Os
.Sh NAME
.Nm fido_init
.Nd initialise the FIDO 2 library
.Nm fido_init ,
.Nm fido_set_log_handler
.Nd initialise the FIDO2 library
.Sh SYNOPSIS
.In fido.h
.Bd -literal
typedef void fido_log_handler_t(const char *);
.Ed
.Pp
.Ft void
.Fn fido_init "int flags"
.Ft void
.Fn fido_set_log_handler "fido_log_handler_t *handler"
.Sh DESCRIPTION
The
.Fn fido_init
@ -43,8 +50,21 @@ then
.Em libfido2
will not fallback to U2F in
.Xr fido_dev_open 3
if a device claims to be FIDO2 but fails to respond to a
FIDO2 command.
if a device claims to support FIDO2 but fails to respond to
a CTAP 2.0 greeting.
.Pp
The
.Fn fido_set_log_handler
function causes
.Fa handler
to be called for each log line generated in the context of the
executing thread.
Lines passed to
.Fa handler
include a trailing newline character and are not printed by
.Em libfido2
on
.Em stderr .
.Sh SEE ALSO
.Xr fido_assert_new 3 ,
.Xr fido_cred_new 3 ,

View File

@ -7,7 +7,7 @@
.Os
.Sh NAME
.Nm fido_strerr
.Nd FIDO 2 error codes
.Nd FIDO2 error codes
.Sh SYNOPSIS
.In fido.h
.Ft const char *

View File

@ -8,11 +8,11 @@
.Sh NAME
.Nm rs256_pk_new ,
.Nm rs256_pk_free ,
.Nm rs256_pk_from_EVP_PKEY ,
.Nm rs256_pk_from_RSA ,
.Nm rs256_pk_from_EVP_PKEY ,
.Nm rs256_pk_from_ptr ,
.Nm rs256_pk_to_EVP_PKEY
.Nd FIDO 2 COSE RS256 API
.Nd FIDO2 COSE RS256 API
.Sh SYNOPSIS
.In openssl/rsa.h
.In fido/rs256.h

View File

@ -102,7 +102,7 @@ static const unsigned char authdata_unsorted_keys[198] = {
0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2,
};
const unsigned char authdata_tpm[362] = {
const unsigned char authdata_tpm_rs256[362] = {
0x59, 0x01, 0x67, 0x49, 0x96, 0x0d, 0xe5, 0x88,
0x0e, 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64,
0x76, 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2,
@ -151,6 +151,30 @@ const unsigned char authdata_tpm[362] = {
0x00, 0x01
};
static const unsigned char authdata_tpm_es256[166] = {
0x58, 0xa4, 0x49, 0x96, 0x0d, 0xe5, 0x88, 0x0e,
0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64, 0x76,
0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2, 0x86,
0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, 0x83, 0x1d,
0x97, 0x63, 0x45, 0x00, 0x00, 0x00, 0x00, 0x08,
0x98, 0x70, 0x58, 0xca, 0xdc, 0x4b, 0x81, 0xb6,
0xe1, 0x30, 0xde, 0x50, 0xdc, 0xbe, 0x96, 0x00,
0x20, 0xa8, 0xdf, 0x03, 0xf7, 0xbf, 0x39, 0x51,
0x94, 0x95, 0x8f, 0xa4, 0x84, 0x97, 0x30, 0xbc,
0x3c, 0x7e, 0x1c, 0x99, 0x91, 0x4d, 0xae, 0x6d,
0xfb, 0xdf, 0x53, 0xb5, 0xb6, 0x1f, 0x3a, 0x4e,
0x6a, 0xa5, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01,
0x21, 0x58, 0x20, 0xfb, 0xd6, 0xba, 0x74, 0xe6,
0x6e, 0x5c, 0x87, 0xef, 0x89, 0xa2, 0xe8, 0x3d,
0x0b, 0xe9, 0x69, 0x2c, 0x07, 0x07, 0x7a, 0x8a,
0x1e, 0xce, 0x12, 0xea, 0x3b, 0xb3, 0xf1, 0xf3,
0xd9, 0xc3, 0xe6, 0x22, 0x58, 0x20, 0x3c, 0x68,
0x51, 0x94, 0x54, 0x8d, 0xeb, 0x9f, 0xb2, 0x2c,
0x66, 0x75, 0xb6, 0xb7, 0x55, 0x22, 0x0d, 0x87,
0x59, 0xc4, 0x39, 0x91, 0x62, 0x17, 0xc2, 0xc3,
0x53, 0xa5, 0x26, 0x97, 0x4f, 0x2d
};
static const unsigned char x509[742] = {
0x30, 0x82, 0x02, 0xe2, 0x30, 0x81, 0xcb, 0x02,
0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
@ -270,7 +294,7 @@ const unsigned char pubkey[64] = {
0xfe, 0x5d, 0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2,
};
const unsigned char pubkey_tpm[259] = {
const unsigned char pubkey_tpm_rs256[259] = {
0xc5, 0xb6, 0x9c, 0x06, 0x1d, 0xcf, 0xb9, 0xf2,
0x5e, 0x99, 0x7d, 0x6d, 0x73, 0xd8, 0x36, 0xc1,
0x4a, 0x90, 0x05, 0x4d, 0x82, 0x57, 0xc1, 0xb6,
@ -306,6 +330,17 @@ const unsigned char pubkey_tpm[259] = {
0x01, 0x00, 0x01,
};
const unsigned char pubkey_tpm_es256[64] = {
0xfb, 0xd6, 0xba, 0x74, 0xe6, 0x6e, 0x5c, 0x87,
0xef, 0x89, 0xa2, 0xe8, 0x3d, 0x0b, 0xe9, 0x69,
0x2c, 0x07, 0x07, 0x7a, 0x8a, 0x1e, 0xce, 0x12,
0xea, 0x3b, 0xb3, 0xf1, 0xf3, 0xd9, 0xc3, 0xe6,
0x3c, 0x68, 0x51, 0x94, 0x54, 0x8d, 0xeb, 0x9f,
0xb2, 0x2c, 0x66, 0x75, 0xb6, 0xb7, 0x55, 0x22,
0x0d, 0x87, 0x59, 0xc4, 0x39, 0x91, 0x62, 0x17,
0xc2, 0xc3, 0x53, 0xa5, 0x26, 0x97, 0x4f, 0x2d
};
const unsigned char id[64] = {
0x53, 0xfb, 0xdf, 0xaa, 0xce, 0x63, 0xde, 0xc5,
0xfe, 0x47, 0xe6, 0x52, 0xeb, 0xf3, 0x5d, 0x53,
@ -317,14 +352,21 @@ const unsigned char id[64] = {
0x34, 0xe3, 0x83, 0xe7, 0xd1, 0xbd, 0x9f, 0x25,
};
const unsigned char id_tpm[32] = {
const unsigned char id_tpm_rs256[32] = {
0x89, 0x99, 0x6d, 0x5a, 0x00, 0x29, 0xe5, 0x3e,
0x6a, 0x1c, 0x72, 0x6d, 0x71, 0x4a, 0x4f, 0x03,
0x9b, 0x68, 0x17, 0xdb, 0x29, 0x1a, 0x6b, 0x02,
0x6c, 0x26, 0xf9, 0xbd, 0xc3, 0x0e, 0x38, 0x1a
};
const unsigned char attstmt_tpm[4034] = {
const unsigned char id_tpm_es256[32] = {
0xa8, 0xdf, 0x03, 0xf7, 0xbf, 0x39, 0x51, 0x94,
0x95, 0x8f, 0xa4, 0x84, 0x97, 0x30, 0xbc, 0x3c,
0x7e, 0x1c, 0x99, 0x91, 0x4d, 0xae, 0x6d, 0xfb,
0xdf, 0x53, 0xb5, 0xb6, 0x1f, 0x3a, 0x4e, 0x6a
};
const unsigned char attstmt_tpm_rs256[4034] = {
0xa6, 0x63, 0x61, 0x6c, 0x67, 0x39, 0xff, 0xfe,
0x63, 0x73, 0x69, 0x67, 0x59, 0x01, 0x00, 0x1c,
0x09, 0x0d, 0x35, 0x97, 0x22, 0xfc, 0xfe, 0xc0,
@ -832,6 +874,490 @@ const unsigned char attstmt_tpm[4034] = {
0x3e, 0x91
};
const unsigned char attstmt_tpm_es256[3841] = {
0xa6, 0x63, 0x61, 0x6c, 0x67, 0x39, 0xff, 0xfe,
0x63, 0x73, 0x69, 0x67, 0x59, 0x01, 0x00, 0x6d,
0x11, 0x61, 0x1f, 0x45, 0xb9, 0x7f, 0x65, 0x6f,
0x97, 0x46, 0xfe, 0xbb, 0x8a, 0x98, 0x07, 0xa3,
0xbc, 0x67, 0x5c, 0xd7, 0x65, 0xa4, 0xf4, 0x6c,
0x5b, 0x37, 0x75, 0xa4, 0x7f, 0x08, 0x52, 0xeb,
0x1e, 0x12, 0xe2, 0x78, 0x8c, 0x7d, 0x94, 0xab,
0x7b, 0xed, 0x05, 0x17, 0x67, 0x7e, 0xaa, 0x02,
0x89, 0x6d, 0xe8, 0x6d, 0x43, 0x30, 0x99, 0xc6,
0xf9, 0x59, 0xe5, 0x82, 0x3c, 0x56, 0x4e, 0x77,
0x11, 0x25, 0xe4, 0x43, 0x6a, 0xae, 0x92, 0x4f,
0x60, 0x92, 0x50, 0xf9, 0x65, 0x0e, 0x44, 0x38,
0x3d, 0xf7, 0xaf, 0x66, 0x89, 0xc7, 0xe6, 0xe6,
0x01, 0x07, 0x9e, 0x90, 0xfd, 0x6d, 0xaa, 0x35,
0x51, 0x51, 0xbf, 0x54, 0x13, 0x95, 0xc2, 0x17,
0xfa, 0x32, 0x0f, 0xa7, 0x82, 0x17, 0x58, 0x6c,
0x3d, 0xea, 0x88, 0xd8, 0x64, 0xc7, 0xf8, 0xc2,
0xd6, 0x1c, 0xbb, 0xea, 0x1e, 0xb3, 0xd9, 0x4c,
0xa7, 0xce, 0x18, 0x1e, 0xcb, 0x42, 0x5f, 0xbf,
0x44, 0xe7, 0xf1, 0x22, 0xe0, 0x5b, 0xeb, 0xff,
0xb6, 0x1e, 0x6f, 0x60, 0x12, 0x16, 0x63, 0xfe,
0xab, 0x5e, 0x31, 0x13, 0xdb, 0x72, 0xc6, 0x9a,
0xf8, 0x8f, 0x19, 0x6b, 0x2e, 0xaf, 0x7d, 0xca,
0x9f, 0xbc, 0x6b, 0x1a, 0x8b, 0x5e, 0xe3, 0x9e,
0xaa, 0x8c, 0x79, 0x9c, 0x4e, 0xed, 0xe4, 0xff,
0x3d, 0x12, 0x79, 0x90, 0x09, 0x61, 0x97, 0x67,
0xbf, 0x04, 0xac, 0x37, 0xea, 0xa9, 0x1f, 0x9f,
0x52, 0x64, 0x0b, 0xeb, 0xc3, 0x61, 0xd4, 0x13,
0xb0, 0x84, 0xf1, 0x3c, 0x74, 0x83, 0xcc, 0xa8,
0x1c, 0x14, 0xe6, 0x9d, 0xfe, 0xec, 0xee, 0xa1,
0xd2, 0xc2, 0x0a, 0xa6, 0x36, 0x08, 0xbb, 0x17,
0xa5, 0x7b, 0x53, 0x34, 0x0e, 0xc9, 0x09, 0xe5,
0x10, 0xa6, 0x85, 0x01, 0x71, 0x66, 0xff, 0xd0,
0x6d, 0x4b, 0x93, 0xdb, 0x81, 0x25, 0x01, 0x63,
0x76, 0x65, 0x72, 0x63, 0x32, 0x2e, 0x30, 0x63,
0x78, 0x35, 0x63, 0x82, 0x59, 0x05, 0xc4, 0x30,
0x82, 0x05, 0xc0, 0x30, 0x82, 0x03, 0xa8, 0xa0,
0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x30, 0xcd,
0xf2, 0x7e, 0x81, 0xc0, 0x43, 0x85, 0xa2, 0xd7,
0x29, 0xef, 0xf7, 0x9f, 0xa5, 0x2b, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x41, 0x31,
0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04, 0x03,
0x13, 0x36, 0x45, 0x55, 0x53, 0x2d, 0x53, 0x54,
0x4d, 0x2d, 0x4b, 0x45, 0x59, 0x49, 0x44, 0x2d,
0x31, 0x41, 0x44, 0x42, 0x39, 0x39, 0x34, 0x41,
0x42, 0x35, 0x38, 0x42, 0x45, 0x35, 0x37, 0x41,
0x30, 0x43, 0x43, 0x39, 0x42, 0x39, 0x30, 0x30,
0x45, 0x37, 0x38, 0x35, 0x31, 0x45, 0x31, 0x41,
0x34, 0x33, 0x43, 0x30, 0x38, 0x36, 0x36, 0x30,
0x30, 0x1e, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31,
0x30, 0x32, 0x31, 0x35, 0x30, 0x36, 0x35, 0x33,
0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x36, 0x30,
0x33, 0x31, 0x39, 0x34, 0x30, 0x31, 0x36, 0x5a,
0x30, 0x00, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
0x01, 0x01, 0x00, 0xdb, 0xd5, 0x9a, 0xfc, 0x09,
0xa7, 0xc4, 0xa5, 0x5f, 0xbe, 0x5f, 0xa2, 0xeb,
0xd6, 0x8e, 0xed, 0xc5, 0x67, 0xa6, 0xa7, 0xd9,
0xb2, 0x46, 0xc6, 0xe0, 0xae, 0x0c, 0x02, 0x25,
0x0a, 0xf2, 0xc5, 0x96, 0xdc, 0xb7, 0x0e, 0xb9,
0x86, 0xd3, 0x51, 0xbb, 0x63, 0xf0, 0x4f, 0x8a,
0x5e, 0xd7, 0xf7, 0xff, 0xbb, 0x29, 0xbd, 0x58,
0xcf, 0x75, 0x02, 0x39, 0xcb, 0x80, 0xf1, 0xd4,
0xb6, 0x75, 0x67, 0x2f, 0x27, 0x4d, 0x0c, 0xcc,
0x18, 0x59, 0x87, 0xfa, 0x51, 0xd1, 0x80, 0xb5,
0x1a, 0xac, 0xac, 0x29, 0x51, 0xcf, 0x27, 0xaa,
0x74, 0xac, 0x3e, 0x59, 0x56, 0x67, 0xe4, 0x42,
0xe8, 0x30, 0x35, 0xb2, 0xf6, 0x27, 0x91, 0x62,
0x60, 0x42, 0x42, 0x12, 0xde, 0xfe, 0xdd, 0xee,
0xe8, 0xa8, 0x82, 0xf9, 0xb1, 0x08, 0xd5, 0x8d,
0x57, 0x9a, 0x29, 0xb9, 0xb4, 0xe9, 0x19, 0x1e,
0x33, 0x7d, 0x37, 0xa0, 0xce, 0x2e, 0x53, 0x13,
0x39, 0xb6, 0x12, 0x61, 0x63, 0xbf, 0xd3, 0x42,
0xeb, 0x6f, 0xed, 0xc1, 0x8e, 0x26, 0xba, 0x7d,
0x8b, 0x37, 0x7c, 0xbb, 0x42, 0x1e, 0x56, 0x76,
0xda, 0xdb, 0x35, 0x6b, 0x80, 0xe1, 0x8e, 0x00,
0xac, 0xd2, 0xfc, 0x22, 0x96, 0x14, 0x0c, 0xf4,
0xe4, 0xc5, 0xad, 0x14, 0xb7, 0x4d, 0x46, 0x63,
0x30, 0x79, 0x3a, 0x7c, 0x33, 0xb5, 0xe5, 0x2e,
0xbb, 0x5f, 0xca, 0xf2, 0x75, 0xe3, 0x4e, 0x99,
0x64, 0x1b, 0x26, 0x99, 0x60, 0x1a, 0x79, 0xcc,
0x30, 0x2c, 0xb3, 0x4c, 0x59, 0xf7, 0x77, 0x59,
0xd5, 0x90, 0x70, 0x21, 0x79, 0x8c, 0x1f, 0x79,
0x0a, 0x12, 0x8b, 0x3b, 0x37, 0x2d, 0x97, 0x39,
0x89, 0x92, 0x0c, 0x44, 0x7c, 0xe9, 0x9f, 0xce,
0x6d, 0xad, 0xc5, 0xae, 0xea, 0x8e, 0x50, 0x22,
0x37, 0xe0, 0xd1, 0x9e, 0xd6, 0xe6, 0xa8, 0xcc,
0x21, 0xfb, 0xff, 0x02, 0x03, 0x01, 0x00, 0x01,
0xa3, 0x82, 0x01, 0xf3, 0x30, 0x82, 0x01, 0xef,
0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80,
0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x6d,
0x06, 0x03, 0x55, 0x1d, 0x20, 0x01, 0x01, 0xff,
0x04, 0x63, 0x30, 0x61, 0x30, 0x5f, 0x06, 0x09,
0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15,
0x1f, 0x30, 0x52, 0x30, 0x50, 0x06, 0x08, 0x2b,
0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30,
0x44, 0x1e, 0x42, 0x00, 0x54, 0x00, 0x43, 0x00,
0x50, 0x00, 0x41, 0x00, 0x20, 0x00, 0x20, 0x00,
0x54, 0x00, 0x72, 0x00, 0x75, 0x00, 0x73, 0x00,
0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00,
0x20, 0x00, 0x50, 0x00, 0x6c, 0x00, 0x61, 0x00,
0x74, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00,
0x6d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x49, 0x00,
0x64, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00,
0x69, 0x00, 0x74, 0x00, 0x79, 0x30, 0x10, 0x06,
0x03, 0x55, 0x1d, 0x25, 0x04, 0x09, 0x30, 0x07,
0x06, 0x05, 0x67, 0x81, 0x05, 0x08, 0x03, 0x30,
0x59, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x01, 0x01,
0xff, 0x04, 0x4f, 0x30, 0x4d, 0xa4, 0x4b, 0x30,
0x49, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67,
0x81, 0x05, 0x02, 0x01, 0x0c, 0x0b, 0x69, 0x64,
0x3a, 0x35, 0x33, 0x35, 0x34, 0x34, 0x44, 0x32,
0x30, 0x31, 0x17, 0x30, 0x15, 0x06, 0x05, 0x67,
0x81, 0x05, 0x02, 0x02, 0x0c, 0x0c, 0x53, 0x54,
0x33, 0x33, 0x48, 0x54, 0x50, 0x48, 0x41, 0x48,
0x42, 0x34, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05,
0x67, 0x81, 0x05, 0x02, 0x03, 0x0c, 0x0b, 0x69,
0x64, 0x3a, 0x30, 0x30, 0x34, 0x39, 0x30, 0x30,
0x30, 0x34, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x45,
0x1a, 0xec, 0xfc, 0x91, 0x70, 0xf8, 0x83, 0x8b,
0x9c, 0x47, 0x2f, 0x0b, 0x9f, 0x07, 0xf3, 0x2f,
0x7c, 0xa2, 0x8a, 0x30, 0x1d, 0x06, 0x03, 0x55,
0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x55, 0xa6,
0xee, 0xe3, 0x28, 0xdd, 0x40, 0x7f, 0x21, 0xd2,
0x7b, 0x8c, 0x69, 0x2f, 0x8c, 0x08, 0x29, 0xbc,
0x95, 0xb8, 0x30, 0x81, 0xb2, 0x06, 0x08, 0x2b,
0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
0x81, 0xa5, 0x30, 0x81, 0xa2, 0x30, 0x81, 0x9f,
0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
0x30, 0x02, 0x86, 0x81, 0x92, 0x68, 0x74, 0x74,
0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x7a, 0x63, 0x73,
0x70, 0x72, 0x6f, 0x64, 0x65, 0x75, 0x73, 0x61,
0x69, 0x6b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73,
0x68, 0x2e, 0x62, 0x6c, 0x6f, 0x62, 0x2e, 0x63,
0x6f, 0x72, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64,
0x6f, 0x77, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x2f,
0x65, 0x75, 0x73, 0x2d, 0x73, 0x74, 0x6d, 0x2d,
0x6b, 0x65, 0x79, 0x69, 0x64, 0x2d, 0x31, 0x61,
0x64, 0x62, 0x39, 0x39, 0x34, 0x61, 0x62, 0x35,
0x38, 0x62, 0x65, 0x35, 0x37, 0x61, 0x30, 0x63,
0x63, 0x39, 0x62, 0x39, 0x30, 0x30, 0x65, 0x37,
0x38, 0x35, 0x31, 0x65, 0x31, 0x61, 0x34, 0x33,
0x63, 0x30, 0x38, 0x36, 0x36, 0x30, 0x2f, 0x62,
0x36, 0x63, 0x30, 0x64, 0x39, 0x38, 0x64, 0x2d,
0x35, 0x37, 0x38, 0x61, 0x2d, 0x34, 0x62, 0x66,
0x62, 0x2d, 0x61, 0x32, 0x64, 0x33, 0x2d, 0x65,
0x64, 0x66, 0x65, 0x35, 0x66, 0x38, 0x32, 0x30,
0x36, 0x30, 0x31, 0x2e, 0x63, 0x65, 0x72, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
0x02, 0x01, 0x00, 0x2a, 0x08, 0x30, 0x1f, 0xfd,
0x8f, 0x80, 0x9b, 0x4b, 0x37, 0x82, 0x61, 0x86,
0x36, 0x57, 0x90, 0xb5, 0x1d, 0x1f, 0xa3, 0xae,
0x68, 0xac, 0xa7, 0x96, 0x6a, 0x25, 0x5e, 0xc5,
0x82, 0x7c, 0x36, 0x64, 0x58, 0x11, 0xcb, 0xa5,
0xee, 0xbf, 0xc4, 0xdb, 0xa0, 0xc7, 0x82, 0x3b,
0xa3, 0x85, 0x9b, 0xc4, 0xee, 0x07, 0x36, 0xd7,
0xc7, 0xb6, 0x23, 0xed, 0xc2, 0x73, 0xab, 0xbe,
0xbe, 0xee, 0x63, 0x17, 0xf9, 0xd7, 0x7a, 0x23,
0x7b, 0xf8, 0x09, 0x7a, 0xaa, 0x7f, 0x67, 0xc3,
0x04, 0x84, 0x71, 0x9b, 0x06, 0x9c, 0x07, 0x42,
0x4b, 0x65, 0x41, 0x56, 0x58, 0x14, 0x92, 0xb0,
0xb9, 0xaf, 0xa1, 0x39, 0xd4, 0x08, 0x2d, 0x71,
0xd5, 0x6c, 0x56, 0xb9, 0x2b, 0x1e, 0xf3, 0x93,
0xa5, 0xe9, 0xb2, 0x9b, 0x4d, 0x05, 0x2b, 0xbc,
0xd2, 0x20, 0x57, 0x3b, 0xa4, 0x01, 0x68, 0x8c,
0x23, 0x20, 0x7d, 0xbb, 0x71, 0xe4, 0x2a, 0x24,
0xba, 0x75, 0x0c, 0x89, 0x54, 0x22, 0xeb, 0x0e,
0xb2, 0xf4, 0xc2, 0x1f, 0x02, 0xb7, 0xe3, 0x06,
0x41, 0x15, 0x6b, 0xf3, 0xc8, 0x2d, 0x5b, 0xc2,
0x21, 0x82, 0x3e, 0xe8, 0x95, 0x40, 0x39, 0x9e,
0x91, 0x68, 0x33, 0x0c, 0x3d, 0x45, 0xef, 0x99,
0x79, 0xe6, 0x32, 0xc9, 0x00, 0x84, 0x36, 0xfb,
0x0a, 0x8d, 0x41, 0x1c, 0x32, 0x64, 0x06, 0x9e,
0x0f, 0xb5, 0x04, 0xcc, 0x08, 0xb1, 0xb6, 0x2b,
0xcf, 0x36, 0x0f, 0x73, 0x14, 0x8e, 0x25, 0x44,
0xb3, 0x0c, 0x34, 0x14, 0x96, 0x0c, 0x8a, 0x65,
0xa1, 0xde, 0x8e, 0xc8, 0x9d, 0xbe, 0x66, 0xdf,
0x06, 0x91, 0xca, 0x15, 0x0f, 0x92, 0xd5, 0x2a,
0x0b, 0xdc, 0x4c, 0x6a, 0xf3, 0x16, 0x4a, 0x3e,
0xb9, 0x76, 0xbc, 0xfe, 0x62, 0xd4, 0xa8, 0xcd,
0x94, 0x78, 0x0d, 0xdd, 0x94, 0xfd, 0x5e, 0x63,
0x57, 0x27, 0x05, 0x9c, 0xd0, 0x80, 0x91, 0x91,
0x79, 0xe8, 0x5e, 0x18, 0x64, 0x22, 0xe4, 0x2c,
0x13, 0x65, 0xa4, 0x51, 0x5a, 0x1e, 0x3b, 0x71,
0x2e, 0x70, 0x9f, 0xc4, 0xa5, 0x20, 0xcd, 0xef,
0xd8, 0x3f, 0xa4, 0xf5, 0x89, 0x8a, 0xa5, 0x4f,
0x76, 0x2d, 0x49, 0x56, 0x00, 0x8d, 0xde, 0x40,
0xba, 0x24, 0x46, 0x51, 0x38, 0xad, 0xdb, 0xc4,
0x04, 0xf4, 0x6e, 0xc0, 0x29, 0x48, 0x07, 0x6a,
0x1b, 0x26, 0x32, 0x0a, 0xfb, 0xea, 0x71, 0x2a,
0x11, 0xfc, 0x98, 0x7c, 0x44, 0x87, 0xbc, 0x06,
0x3a, 0x4d, 0xbd, 0x91, 0x63, 0x4f, 0x26, 0x48,
0x54, 0x47, 0x1b, 0xbd, 0xf0, 0xf1, 0x56, 0x05,
0xc5, 0x0f, 0x8f, 0x20, 0xa5, 0xcc, 0xfb, 0x76,
0xb0, 0xbd, 0x83, 0xde, 0x7f, 0x39, 0x4f, 0xcf,
0x61, 0x74, 0x52, 0xa7, 0x1d, 0xf6, 0xb5, 0x5e,
0x4a, 0x82, 0x20, 0xc1, 0x94, 0xaa, 0x2c, 0x33,
0xd6, 0x0a, 0xf9, 0x8f, 0x92, 0xc6, 0x29, 0x80,
0xf5, 0xa2, 0xb1, 0xff, 0xb6, 0x2b, 0xaa, 0x04,
0x00, 0x72, 0xb4, 0x12, 0xbb, 0xb1, 0xf1, 0x3c,
0x88, 0xa3, 0xab, 0x49, 0x17, 0x90, 0x80, 0x59,
0xa2, 0x96, 0x41, 0x69, 0x74, 0x33, 0x8a, 0x28,
0x33, 0x7e, 0xb3, 0x19, 0x92, 0x28, 0xc1, 0xf0,
0xd1, 0x82, 0xd5, 0x42, 0xff, 0xe7, 0xa5, 0x3f,
0x1e, 0xb6, 0x4a, 0x23, 0xcc, 0x6a, 0x7f, 0x15,
0x15, 0x52, 0x25, 0xb1, 0xca, 0x21, 0x95, 0x11,
0x53, 0x3e, 0x1f, 0x50, 0x33, 0x12, 0x7a, 0x62,
0xce, 0xcc, 0x71, 0xc2, 0x5f, 0x34, 0x47, 0xc6,
0x7c, 0x71, 0xfa, 0xa0, 0x54, 0x00, 0xb2, 0xdf,
0xc5, 0x54, 0xac, 0x6c, 0x53, 0xef, 0x64, 0x6b,
0x08, 0x82, 0xd8, 0x16, 0x1e, 0xca, 0x40, 0xf3,
0x1f, 0xdf, 0x56, 0x63, 0x10, 0xbc, 0xd7, 0xa0,
0xeb, 0xee, 0xd1, 0x95, 0xe5, 0xef, 0xf1, 0x6a,
0x83, 0x2d, 0x5a, 0x59, 0x06, 0xef, 0x30, 0x82,
0x06, 0xeb, 0x30, 0x82, 0x04, 0xd3, 0xa0, 0x03,
0x02, 0x01, 0x02, 0x02, 0x13, 0x33, 0x00, 0x00,
0x05, 0x23, 0xbf, 0xe8, 0xa1, 0x1a, 0x2a, 0x68,
0xbd, 0x09, 0x00, 0x00, 0x00, 0x00, 0x05, 0x23,
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
0x81, 0x8c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e,
0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e,
0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52,
0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e,
0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f,
0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x36,
0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
0x2d, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f,
0x66, 0x74, 0x20, 0x54, 0x50, 0x4d, 0x20, 0x52,
0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74,
0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20,
0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
0x79, 0x20, 0x32, 0x30, 0x31, 0x34, 0x30, 0x1e,
0x17, 0x0d, 0x32, 0x31, 0x30, 0x36, 0x30, 0x33,
0x31, 0x39, 0x34, 0x30, 0x31, 0x36, 0x5a, 0x17,
0x0d, 0x32, 0x37, 0x30, 0x36, 0x30, 0x33, 0x31,
0x39, 0x34, 0x30, 0x31, 0x36, 0x5a, 0x30, 0x41,
0x31, 0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04,
0x03, 0x13, 0x36, 0x45, 0x55, 0x53, 0x2d, 0x53,
0x54, 0x4d, 0x2d, 0x4b, 0x45, 0x59, 0x49, 0x44,
0x2d, 0x31, 0x41, 0x44, 0x42, 0x39, 0x39, 0x34,
0x41, 0x42, 0x35, 0x38, 0x42, 0x45, 0x35, 0x37,
0x41, 0x30, 0x43, 0x43, 0x39, 0x42, 0x39, 0x30,
0x30, 0x45, 0x37, 0x38, 0x35, 0x31, 0x45, 0x31,
0x41, 0x34, 0x33, 0x43, 0x30, 0x38, 0x36, 0x36,
0x30, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f,
0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02,
0x01, 0x00, 0xdb, 0x03, 0x34, 0x82, 0xfa, 0x81,
0x1c, 0x84, 0x0b, 0xa0, 0x0e, 0x60, 0xd8, 0x9d,
0x84, 0xf4, 0x81, 0xc4, 0xe9, 0xff, 0xcf, 0xe9,
0xa3, 0x57, 0x53, 0x60, 0xa8, 0x19, 0xce, 0xbe,
0xe1, 0x97, 0xee, 0x5d, 0x8c, 0x9f, 0xe4, 0xbd,
0xef, 0xbd, 0x94, 0x14, 0xe4, 0x74, 0x41, 0x02,
0xe9, 0x03, 0x19, 0x9f, 0xdd, 0x48, 0x2d, 0xbd,
0xca, 0x26, 0x47, 0x2c, 0x01, 0x31, 0x5f, 0x34,
0xef, 0x59, 0x35, 0x48, 0x36, 0x3d, 0x1e, 0xdf,
0xd8, 0x13, 0xf0, 0xd0, 0x67, 0xc1, 0xb0, 0x47,
0x67, 0xa2, 0xd6, 0x62, 0xc8, 0xe1, 0x00, 0x36,
0x8b, 0x45, 0xf6, 0x3b, 0x96, 0x60, 0xa0, 0x45,
0x26, 0xcb, 0xc7, 0x0b, 0x5b, 0x97, 0xd1, 0xaf,
0x54, 0x25, 0x7a, 0x67, 0xe4, 0x2a, 0xd8, 0x9d,
0x53, 0x05, 0xbd, 0x12, 0xac, 0xa2, 0x8e, 0x95,
0xb4, 0x2a, 0xca, 0x89, 0x93, 0x64, 0x97, 0x25,
0xdc, 0x1f, 0xa9, 0xe0, 0x55, 0x07, 0x38, 0x1d,
0xee, 0x02, 0x90, 0x22, 0xf5, 0xad, 0x4e, 0x5c,
0xf8, 0xc5, 0x1f, 0x9e, 0x84, 0x7e, 0x13, 0x47,
0x52, 0xa2, 0x36, 0xf9, 0xf6, 0xbf, 0x76, 0x9e,
0x0f, 0xdd, 0x14, 0x99, 0xb9, 0xd8, 0x5a, 0x42,
0x3d, 0xd8, 0xbf, 0xdd, 0xb4, 0x9b, 0xbf, 0x6a,
0x9f, 0x89, 0x13, 0x75, 0xaf, 0x96, 0xd2, 0x72,
0xdf, 0xb3, 0x80, 0x6f, 0x84, 0x1a, 0x9d, 0x06,
0x55, 0x09, 0x29, 0xea, 0xa7, 0x05, 0x31, 0xec,
0x47, 0x3a, 0xcf, 0x3f, 0x9c, 0x2c, 0xbd, 0xd0,
0x7d, 0xe4, 0x75, 0x5b, 0x33, 0xbe, 0x12, 0x86,
0x09, 0xcf, 0x66, 0x9a, 0xeb, 0xf8, 0xf8, 0x72,
0x91, 0x88, 0x4a, 0x5e, 0x89, 0x62, 0x6a, 0x94,
0xdc, 0x48, 0x37, 0x13, 0xd8, 0x91, 0x02, 0xe3,
0x42, 0x41, 0x7c, 0x2f, 0xe3, 0xb6, 0x0f, 0xb4,
0x96, 0x06, 0x80, 0xca, 0x28, 0x01, 0x6f, 0x4b,
0xcd, 0x28, 0xd4, 0x2c, 0x94, 0x7e, 0x40, 0x7e,
0xdf, 0x01, 0xe5, 0xf2, 0x33, 0xd4, 0xda, 0xf4,
0x1a, 0x17, 0xf7, 0x5d, 0xcb, 0x66, 0x2c, 0x2a,
0xeb, 0xe1, 0xb1, 0x4a, 0xc3, 0x85, 0x63, 0xb2,
0xac, 0xd0, 0x3f, 0x1a, 0x8d, 0xa5, 0x0c, 0xee,
0x4f, 0xde, 0x74, 0x9c, 0xe0, 0x5a, 0x10, 0xc7,
0xb8, 0xe4, 0xec, 0xe7, 0x73, 0xa6, 0x41, 0x42,
0x37, 0xe1, 0xdf, 0xb9, 0xc7, 0xb5, 0x14, 0xa8,
0x80, 0x95, 0xa0, 0x12, 0x67, 0x99, 0xf5, 0xba,
0x25, 0x0a, 0x74, 0x86, 0x71, 0x9c, 0x7f, 0x59,
0x97, 0xd2, 0x3f, 0x10, 0xfe, 0x6a, 0xb9, 0xe4,
0x47, 0x36, 0xfb, 0x0f, 0x50, 0xee, 0xfc, 0x87,
0x99, 0x7e, 0x36, 0x64, 0x1b, 0xc7, 0x13, 0xb3,
0x33, 0x18, 0x71, 0xa4, 0xc3, 0xb0, 0xfc, 0x45,
0x37, 0x11, 0x40, 0xb3, 0xde, 0x2c, 0x9f, 0x0a,
0xcd, 0xaf, 0x5e, 0xfb, 0xd5, 0x9c, 0xea, 0xd7,
0x24, 0x19, 0x3a, 0x92, 0x80, 0xa5, 0x63, 0xc5,
0x3e, 0xdd, 0x51, 0xd0, 0x9f, 0xb8, 0x5e, 0xd5,
0xf1, 0xfe, 0xa5, 0x93, 0xfb, 0x7f, 0xd9, 0xb8,
0xb7, 0x0e, 0x0d, 0x12, 0x71, 0xf0, 0x52, 0x9d,
0xe9, 0xd0, 0xd2, 0x8b, 0x38, 0x8b, 0x85, 0x83,
0x98, 0x24, 0x88, 0xe8, 0x42, 0x30, 0x83, 0x12,
0xef, 0x09, 0x96, 0x2f, 0x21, 0x81, 0x05, 0x30,
0x0c, 0xbb, 0xba, 0x21, 0x39, 0x16, 0x12, 0xe8,
0x4b, 0x7b, 0x7a, 0x66, 0xb8, 0x22, 0x2c, 0x71,
0xaf, 0x59, 0xa1, 0xfc, 0x61, 0xf1, 0xb4, 0x5e,
0xfc, 0x43, 0x19, 0x45, 0x6e, 0xa3, 0x45, 0xe4,
0xcb, 0x66, 0x5f, 0xe0, 0x57, 0xf6, 0x0a, 0x30,
0xa3, 0xd6, 0x51, 0x24, 0xc9, 0x07, 0x55, 0x82,
0x4a, 0x66, 0x0e, 0x9d, 0xb2, 0x2f, 0x84, 0x56,
0x6c, 0x3e, 0x71, 0xef, 0x9b, 0x35, 0x4d, 0x72,
0xdc, 0x46, 0x2a, 0xe3, 0x7b, 0x13, 0x20, 0xbf,
0xab, 0x77, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
0x82, 0x01, 0x8e, 0x30, 0x82, 0x01, 0x8a, 0x30,
0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x84, 0x30,
0x1b, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x14,
0x30, 0x12, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04,
0x01, 0x82, 0x37, 0x15, 0x24, 0x06, 0x05, 0x67,
0x81, 0x05, 0x08, 0x03, 0x30, 0x16, 0x06, 0x03,
0x55, 0x1d, 0x20, 0x04, 0x0f, 0x30, 0x0d, 0x30,
0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01,
0x82, 0x37, 0x15, 0x1f, 0x30, 0x12, 0x06, 0x03,
0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08,
0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00,
0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
0x16, 0x04, 0x14, 0x45, 0x1a, 0xec, 0xfc, 0x91,
0x70, 0xf8, 0x83, 0x8b, 0x9c, 0x47, 0x2f, 0x0b,
0x9f, 0x07, 0xf3, 0x2f, 0x7c, 0xa2, 0x8a, 0x30,
0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
0x30, 0x16, 0x80, 0x14, 0x7a, 0x8c, 0x0a, 0xce,
0x2f, 0x48, 0x62, 0x17, 0xe2, 0x94, 0xd1, 0xae,
0x55, 0xc1, 0x52, 0xec, 0x71, 0x74, 0xa4, 0x56,
0x30, 0x70, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04,
0x69, 0x30, 0x67, 0x30, 0x65, 0xa0, 0x63, 0xa0,
0x61, 0x86, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x3a,
0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69,
0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e,
0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x6f,
0x70, 0x73, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x4d,
0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
0x25, 0x32, 0x30, 0x54, 0x50, 0x4d, 0x25, 0x32,
0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30,
0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75,
0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x25,
0x32, 0x30, 0x32, 0x30, 0x31, 0x34, 0x2e, 0x63,
0x72, 0x6c, 0x30, 0x7d, 0x06, 0x08, 0x2b, 0x06,
0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x71,
0x30, 0x6f, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06,
0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x61,
0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f,
0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
0x2f, 0x70, 0x6b, 0x69, 0x6f, 0x70, 0x73, 0x2f,
0x63, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x4d, 0x69,
0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x25,
0x32, 0x30, 0x54, 0x50, 0x4d, 0x25, 0x32, 0x30,
0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43,
0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74,
0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x25, 0x32,
0x30, 0x32, 0x30, 0x31, 0x34, 0x2e, 0x63, 0x72,
0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
0x03, 0x82, 0x02, 0x01, 0x00, 0x48, 0x24, 0x32,
0xe8, 0xd6, 0x38, 0xda, 0x65, 0xec, 0x1b, 0x18,
0x8e, 0x37, 0x07, 0xd5, 0x18, 0x5a, 0xc8, 0xb9,
0xbb, 0x24, 0x8a, 0x4d, 0xa1, 0x3c, 0x9e, 0x46,
0x76, 0xcf, 0xa5, 0xdf, 0xd7, 0x61, 0xba, 0x05,
0x89, 0x3c, 0x13, 0xc2, 0x1f, 0x71, 0xe3, 0xec,
0x5d, 0x54, 0x9e, 0xd9, 0x01, 0x5a, 0x10, 0x3b,
0x17, 0x75, 0xde, 0xa1, 0x45, 0xbf, 0x1d, 0x1b,
0x41, 0x21, 0x42, 0x68, 0x22, 0x6b, 0xbb, 0xcb,
0x11, 0x04, 0xd2, 0xae, 0x86, 0xcf, 0x73, 0x5a,
0xf2, 0x80, 0x18, 0x00, 0xf0, 0xd6, 0x6c, 0x5a,
0x1e, 0xb3, 0x4d, 0x30, 0x02, 0x4a, 0x6a, 0x03,
0x36, 0x42, 0xde, 0xb2, 0x52, 0x55, 0xff, 0x71,
0xeb, 0x7b, 0x8b, 0x55, 0x6c, 0xdf, 0x05, 0x35,
0x47, 0x70, 0x53, 0xfb, 0x6c, 0xba, 0x06, 0xb2,
0x61, 0x86, 0xdc, 0x2a, 0x64, 0x81, 0x24, 0x79,
0x46, 0x73, 0x04, 0x55, 0x59, 0xed, 0xd6, 0x06,
0x61, 0x15, 0xf9, 0x8d, 0x78, 0x39, 0x7b, 0x84,
0x7a, 0x40, 0x45, 0x13, 0x1a, 0x91, 0x71, 0x8f,
0xd1, 0x4f, 0x78, 0x10, 0x68, 0x9b, 0x15, 0x79,
0x3f, 0x79, 0x2d, 0x9b, 0xc7, 0x5d, 0xa3, 0xcf,
0xa9, 0x14, 0xb0, 0xc4, 0xdb, 0xa9, 0x45, 0x6a,
0x6e, 0x60, 0x45, 0x0b, 0x14, 0x25, 0xc7, 0x74,
0xd0, 0x36, 0xaf, 0xc5, 0xbd, 0x4f, 0x7b, 0xc0,
0x04, 0x43, 0x85, 0xbb, 0x06, 0x36, 0x77, 0x26,
0x02, 0x23, 0x0b, 0xf8, 0x57, 0x8f, 0x1f, 0x27,
0x30, 0x95, 0xff, 0x83, 0x23, 0x2b, 0x49, 0x33,
0x43, 0x62, 0x87, 0x5d, 0x27, 0x12, 0x1a, 0x68,
0x7b, 0xba, 0x2d, 0xf6, 0xed, 0x2c, 0x26, 0xb5,
0xbb, 0xe2, 0x6f, 0xc2, 0x61, 0x17, 0xfc, 0x72,
0x14, 0x57, 0x2c, 0x2c, 0x5a, 0x92, 0x13, 0x41,
0xc4, 0x7e, 0xb5, 0x64, 0x5b, 0x86, 0x57, 0x13,
0x14, 0xff, 0xf5, 0x04, 0xb9, 0x3d, 0x2d, 0xc3,
0xe9, 0x75, 0x1f, 0x68, 0x0b, 0xb5, 0x76, 0xe1,
0x7d, 0xe3, 0xb0, 0x14, 0xa8, 0x45, 0x05, 0x98,
0x81, 0x32, 0xc1, 0xf5, 0x49, 0x4d, 0x58, 0xa4,
0xee, 0xd8, 0x84, 0xba, 0x65, 0x07, 0x8d, 0xf7,
0x9a, 0xff, 0x7d, 0xa5, 0xbc, 0x9a, 0xed, 0x4a,
0x5d, 0xa4, 0x97, 0x4b, 0x4d, 0x31, 0x90, 0xb5,
0x7d, 0x28, 0x77, 0x25, 0x88, 0x1c, 0xbf, 0x78,
0x22, 0xb2, 0xb5, 0x5c, 0x9a, 0xc9, 0x63, 0x17,
0x96, 0xe9, 0xc2, 0x52, 0x30, 0xb8, 0x9b, 0x37,
0x69, 0x1a, 0x6a, 0x66, 0x76, 0x18, 0xac, 0xc0,
0x48, 0xee, 0x46, 0x5b, 0xbe, 0x6a, 0xd5, 0x72,
0x07, 0xdc, 0x7d, 0x05, 0xbe, 0x76, 0x7d, 0xa5,
0x5e, 0x53, 0xb5, 0x47, 0x80, 0x58, 0xf0, 0xaf,
0x6f, 0x4e, 0xc0, 0xf1, 0x1e, 0x37, 0x64, 0x15,
0x42, 0x96, 0x18, 0x3a, 0x89, 0xc8, 0x14, 0x48,
0x89, 0x5c, 0x12, 0x88, 0x98, 0x0b, 0x7b, 0x4e,
0xce, 0x1c, 0xda, 0xd5, 0xa4, 0xd3, 0x32, 0x32,
0x74, 0x5b, 0xcc, 0xfd, 0x2b, 0x02, 0xfb, 0xae,
0xd0, 0x5a, 0x4c, 0xc9, 0xc1, 0x35, 0x19, 0x90,
0x5f, 0xca, 0x14, 0xeb, 0x4c, 0x17, 0xd7, 0xe3,
0xe2, 0x5d, 0xb4, 0x49, 0xaa, 0xf0, 0x50, 0x87,
0xc3, 0x20, 0x00, 0xda, 0xe9, 0x04, 0x80, 0x64,
0xac, 0x9f, 0xcd, 0x26, 0x41, 0x48, 0xe8, 0x4c,
0x46, 0xcc, 0x5b, 0xd7, 0xca, 0x4c, 0x1b, 0x43,
0x43, 0x1e, 0xbd, 0x94, 0xe7, 0xa7, 0xa6, 0x86,
0xe5, 0xd1, 0x78, 0x29, 0xa2, 0x40, 0xc5, 0xc5,
0x47, 0xb6, 0x6d, 0x53, 0xde, 0xac, 0x97, 0x74,
0x24, 0x57, 0xcc, 0x05, 0x93, 0xfd, 0x52, 0x35,
0x29, 0xd5, 0xe0, 0xfa, 0x23, 0x0d, 0xd7, 0xaa,
0x8b, 0x07, 0x4b, 0xf6, 0x64, 0xc7, 0xad, 0x3c,
0xa1, 0xb5, 0xc5, 0x70, 0xaf, 0x46, 0xfe, 0x9a,
0x82, 0x4d, 0x75, 0xb8, 0x6d, 0x67, 0x70, 0x75,
0x62, 0x41, 0x72, 0x65, 0x61, 0x58, 0x76, 0x00,
0x23, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x72, 0x00,
0x20, 0x9d, 0xff, 0xcb, 0xf3, 0x6c, 0x38, 0x3a,
0xe6, 0x99, 0xfb, 0x98, 0x68, 0xdc, 0x6d, 0xcb,
0x89, 0xd7, 0x15, 0x38, 0x84, 0xbe, 0x28, 0x03,
0x92, 0x2c, 0x12, 0x41, 0x58, 0xbf, 0xad, 0x22,
0xae, 0x00, 0x10, 0x00, 0x10, 0x00, 0x03, 0x00,
0x10, 0x00, 0x20, 0xfb, 0xd6, 0xba, 0x74, 0xe6,
0x6e, 0x5c, 0x87, 0xef, 0x89, 0xa2, 0xe8, 0x3d,
0x0b, 0xe9, 0x69, 0x2c, 0x07, 0x07, 0x7a, 0x8a,
0x1e, 0xce, 0x12, 0xea, 0x3b, 0xb3, 0xf1, 0xf3,
0xd9, 0xc3, 0xe6, 0x00, 0x20, 0x3c, 0x68, 0x51,
0x94, 0x54, 0x8d, 0xeb, 0x9f, 0xb2, 0x2c, 0x66,
0x75, 0xb6, 0xb7, 0x55, 0x22, 0x0d, 0x87, 0x59,
0xc4, 0x39, 0x91, 0x62, 0x17, 0xc2, 0xc3, 0x53,
0xa5, 0x26, 0x97, 0x4f, 0x2d, 0x68, 0x63, 0x65,
0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x58, 0xa1,
0xff, 0x54, 0x43, 0x47, 0x80, 0x17, 0x00, 0x22,
0x00, 0x0b, 0x73, 0xbe, 0xb7, 0x40, 0x82, 0xc0,
0x49, 0x9a, 0xf7, 0xf2, 0xd0, 0x79, 0x6c, 0x88,
0xf3, 0x56, 0x7b, 0x7a, 0x7d, 0xcd, 0x70, 0xd1,
0xbc, 0x41, 0x88, 0x48, 0x51, 0x03, 0xf3, 0x58,
0x3e, 0xb8, 0x00, 0x14, 0x9f, 0x57, 0x39, 0x67,
0xa8, 0x7b, 0xd8, 0xf6, 0x9e, 0x75, 0xc9, 0x85,
0xab, 0xe3, 0x55, 0xc7, 0x9c, 0xf6, 0xd8, 0x4f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x1c, 0x12,
0xfd, 0xc6, 0x05, 0xc6, 0x2b, 0xf5, 0xe9, 0x88,
0x01, 0x1f, 0x70, 0x8d, 0x98, 0x2a, 0x04, 0x21,
0x30, 0x00, 0x22, 0x00, 0x0b, 0xf4, 0xfd, 0x9a,
0x33, 0x55, 0x21, 0x08, 0x27, 0x48, 0x55, 0x01,
0x56, 0xf9, 0x0b, 0x4e, 0x47, 0x55, 0x08, 0x2e,
0x3c, 0x91, 0x3d, 0x6e, 0x53, 0xcf, 0x08, 0xe9,
0x0a, 0x4b, 0xc9, 0x7e, 0x99, 0x00, 0x22, 0x00,
0x0b, 0x51, 0xd3, 0x38, 0xfe, 0xaa, 0xda, 0xc6,
0x68, 0x84, 0x39, 0xe7, 0xb1, 0x03, 0x22, 0x5e,
0xc4, 0xd3, 0xf1, 0x0c, 0xec, 0x35, 0x5d, 0x50,
0xa3, 0x9d, 0xab, 0xa1, 0x7b, 0x61, 0x51, 0x8f,
0x4e
};
/*
* Security Key By Yubico
* 5.1.X
@ -1563,7 +2089,7 @@ fmt_none(void)
}
static void
valid_tpm_cred(void)
valid_tpm_rs256_cred(void)
{
fido_cred_t *c;
@ -1571,17 +2097,42 @@ valid_tpm_cred(void)
assert(fido_cred_set_type(c, COSE_RS256) == FIDO_OK);
assert(fido_cred_set_clientdata(c, cdh, sizeof(cdh)) == FIDO_OK);
assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK);
assert(fido_cred_set_authdata(c, authdata_tpm, sizeof(authdata_tpm)) == FIDO_OK);
assert(fido_cred_set_authdata(c, authdata_tpm_rs256, sizeof(authdata_tpm_rs256)) == FIDO_OK);
assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_cred_set_uv(c, FIDO_OPT_TRUE) == FIDO_OK);
assert(fido_cred_set_fmt(c, "tpm") == FIDO_OK);
assert(fido_cred_set_attstmt(c, attstmt_tpm, sizeof(attstmt_tpm)) == FIDO_OK);
assert(fido_cred_set_attstmt(c, attstmt_tpm_rs256, sizeof(attstmt_tpm_rs256)) == FIDO_OK);
assert(fido_cred_verify(c) == FIDO_OK);
assert(fido_cred_prot(c) == 0);
assert(fido_cred_pubkey_len(c) == sizeof(pubkey_tpm));
assert(memcmp(fido_cred_pubkey_ptr(c), pubkey_tpm, sizeof(pubkey_tpm)) == 0);
assert(fido_cred_id_len(c) == sizeof(id_tpm));
assert(memcmp(fido_cred_id_ptr(c), id_tpm, sizeof(id_tpm)) == 0);
assert(fido_cred_pubkey_len(c) == sizeof(pubkey_tpm_rs256));
assert(memcmp(fido_cred_pubkey_ptr(c), pubkey_tpm_rs256, sizeof(pubkey_tpm_rs256)) == 0);
assert(fido_cred_id_len(c) == sizeof(id_tpm_rs256));
assert(memcmp(fido_cred_id_ptr(c), id_tpm_rs256, sizeof(id_tpm_rs256)) == 0);
assert(fido_cred_aaguid_len(c) == sizeof(aaguid_tpm));
assert(memcmp(fido_cred_aaguid_ptr(c), aaguid_tpm, sizeof(aaguid_tpm)) == 0);
free_cred(c);
}
static void
valid_tpm_es256_cred(void)
{
fido_cred_t *c;
c = alloc_cred();
assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK);
assert(fido_cred_set_clientdata(c, cdh, sizeof(cdh)) == FIDO_OK);
assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK);
assert(fido_cred_set_authdata(c, authdata_tpm_es256, sizeof(authdata_tpm_es256)) == FIDO_OK);
assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_cred_set_uv(c, FIDO_OPT_TRUE) == FIDO_OK);
assert(fido_cred_set_fmt(c, "tpm") == FIDO_OK);
assert(fido_cred_set_attstmt(c, attstmt_tpm_es256, sizeof(attstmt_tpm_es256)) == FIDO_OK);
assert(fido_cred_verify(c) == FIDO_OK);
assert(fido_cred_prot(c) == 0);
assert(fido_cred_pubkey_len(c) == sizeof(pubkey_tpm_es256));
assert(memcmp(fido_cred_pubkey_ptr(c), pubkey_tpm_es256, sizeof(pubkey_tpm_es256)) == 0);
assert(fido_cred_id_len(c) == sizeof(id_tpm_es256));
assert(memcmp(fido_cred_id_ptr(c), id_tpm_es256, sizeof(id_tpm_es256)) == 0);
assert(fido_cred_aaguid_len(c) == sizeof(aaguid_tpm));
assert(memcmp(fido_cred_aaguid_ptr(c), aaguid_tpm, sizeof(aaguid_tpm)) == 0);
free_cred(c);
@ -1616,7 +2167,8 @@ main(void)
wrong_credprot();
raw_authdata();
fmt_none();
valid_tpm_cred();
valid_tpm_rs256_cred();
valid_tpm_es256_cred();
exit(0);
}

View File

@ -132,7 +132,7 @@ endif()
install(FILES fido.h DESTINATION include)
install(DIRECTORY fido DESTINATION include)
if(NOT WIN32)
if(NOT MSVC)
configure_file(libfido2.pc.in libfido2.pc @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libfido2.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")

View File

@ -424,7 +424,7 @@ bio_enroll_begin_wait(fido_dev_t *dev, fido_bio_template_t *t,
memset(&argv, 0, sizeof(argv));
if ((argv[2] = cbor_build_uint32(timo_ms)) == NULL) {
if ((argv[2] = cbor_build_uint(timo_ms)) == NULL) {
fido_log_debug("%s: cbor encode", __func__);
goto fail;
}
@ -520,7 +520,7 @@ bio_enroll_continue_wait(fido_dev_t *dev, const fido_bio_template_t *t,
memset(&argv, 0, sizeof(argv));
if ((argv[0] = fido_blob_encode(&t->id)) == NULL ||
(argv[2] = cbor_build_uint32(timo_ms)) == NULL) {
(argv[2] = cbor_build_uint(timo_ms)) == NULL) {
fido_log_debug("%s: cbor encode", __func__);
goto fail;
}

View File

@ -696,7 +696,6 @@ cbor_encode_pin_auth(const fido_dev_t *dev, const fido_blob_t *secret,
uint8_t prot;
fido_blob_t key;
key.ptr = secret->ptr;
key.len = secret->len;

View File

@ -548,6 +548,13 @@ fido_dev_set_transport_functions(fido_dev_t *dev, const fido_dev_transport_t *t)
return (FIDO_OK);
}
void *
fido_dev_io_handle(const fido_dev_t *dev)
{
return (dev->io_handle);
}
void
fido_init(int flags)
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 Yubico AB. All rights reserved.
* Copyright (c) 2019-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@ -37,7 +37,9 @@ EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
return (0);
}
#endif /* LIBRESSL_VERSION_NUMBER */
#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3040000f
int
EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen,
const unsigned char *tbs, size_t tbslen)
@ -52,7 +54,7 @@ EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen,
return (0);
}
#endif /* LIBRESSL_VERSION_NUMBER */
#endif /* LIBRESSL_VERSION_NUMBER < 0x3040000f */
static int
decode_coord(const cbor_item_t *item, void *xy, size_t xy_len)

View File

@ -201,14 +201,18 @@
fido_dev_info_product;
fido_dev_info_product_string;
fido_dev_info_ptr;
fido_dev_info_set;
fido_dev_info_vendor;
fido_dev_io_handle;
fido_dev_is_fido2;
fido_dev_is_winhello;
fido_dev_major;
fido_dev_make_cred;
fido_dev_minor;
fido_dev_new;
fido_dev_new_with_info;
fido_dev_open;
fido_dev_open_with_info;
fido_dev_protocol;
fido_dev_reset;
fido_dev_set_io_functions;

View File

@ -199,14 +199,18 @@ _fido_dev_info_path
_fido_dev_info_product
_fido_dev_info_product_string
_fido_dev_info_ptr
_fido_dev_info_set
_fido_dev_info_vendor
_fido_dev_io_handle
_fido_dev_is_fido2
_fido_dev_is_winhello
_fido_dev_major
_fido_dev_make_cred
_fido_dev_minor
_fido_dev_new
_fido_dev_new_with_info
_fido_dev_open
_fido_dev_open_with_info
_fido_dev_protocol
_fido_dev_reset
_fido_dev_set_io_functions

View File

@ -200,14 +200,18 @@ fido_dev_info_path
fido_dev_info_product
fido_dev_info_product_string
fido_dev_info_ptr
fido_dev_info_set
fido_dev_info_vendor
fido_dev_io_handle
fido_dev_is_fido2
fido_dev_is_winhello
fido_dev_major
fido_dev_make_cred
fido_dev_minor
fido_dev_new
fido_dev_new_with_info
fido_dev_open
fido_dev_open_with_info
fido_dev_protocol
fido_dev_reset
fido_dev_set_io_functions

View File

@ -178,7 +178,6 @@ int fido_dev_get_uv_token(fido_dev_t *, uint8_t, const char *,
int *);
uint64_t fido_dev_maxmsgsize(const fido_dev_t *);
int fido_do_ecdh(fido_dev_t *, es256_pk_t **, fido_blob_t **, int *);
bool fido_dev_supports_permissions(const fido_dev_t *);
/* types */
void fido_algo_array_free(fido_algo_array_t *);

View File

@ -40,6 +40,7 @@ fido_dev_t *fido_dev_new(void);
fido_dev_t *fido_dev_new_with_info(const fido_dev_info_t *);
fido_dev_info_t *fido_dev_info_new(size_t);
fido_cbor_info_t *fido_cbor_info_new(void);
void *fido_dev_io_handle(const fido_dev_t *);
void fido_assert_free(fido_assert_t **);
void fido_cbor_info_free(fido_cbor_info_t **);
@ -153,6 +154,8 @@ int fido_dev_get_uv_retry_count(fido_dev_t *, int *);
int fido_dev_get_touch_begin(fido_dev_t *);
int fido_dev_get_touch_status(fido_dev_t *, int *, int);
int fido_dev_info_manifest(fido_dev_info_t *, size_t, size_t *);
int fido_dev_info_set(fido_dev_info_t *, size_t, const char *, const char *,
const char *, const fido_dev_io_t *, const fido_dev_transport_t *);
int fido_dev_make_cred(fido_dev_t *, fido_cred_t *, const char *);
int fido_dev_open_with_info(fido_dev_t *);
int fido_dev_open(fido_dev_t *, const char *);
@ -212,9 +215,10 @@ bool fido_dev_has_pin(const fido_dev_t *);
bool fido_dev_has_uv(const fido_dev_t *);
bool fido_dev_is_fido2(const fido_dev_t *);
bool fido_dev_is_winhello(const fido_dev_t *);
bool fido_dev_supports_pin(const fido_dev_t *);
bool fido_dev_supports_cred_prot(const fido_dev_t *);
bool fido_dev_supports_credman(const fido_dev_t *);
bool fido_dev_supports_cred_prot(const fido_dev_t *);
bool fido_dev_supports_permissions(const fido_dev_t *);
bool fido_dev_supports_pin(const fido_dev_t *);
bool fido_dev_supports_uv(const fido_dev_t *);
int fido_dev_largeblob_get(fido_dev_t *, const unsigned char *, size_t,

View File

@ -151,13 +151,13 @@ typedef struct fido_cred {
fido_attcred_t attcred; /* returned credential (key + id) */
fido_attstmt_t attstmt; /* attestation statement (x509 + sig) */
fido_blob_t largeblob_key; /* decoded large blob key */
fido_blob_t blob; /* FIDO 2.1 credBlob */
fido_blob_t blob; /* CTAP 2.1 credBlob */
} fido_cred_t;
typedef struct fido_assert_extattr {
int mask; /* decoded extensions */
fido_blob_t hmac_secret_enc; /* hmac secret, encrypted */
fido_blob_t blob; /* decoded FIDO 2.1 credBlob */
fido_blob_t blob; /* decoded CTAP 2.1 credBlob */
} fido_assert_extattr_t;
typedef struct _fido_assert_stmt {

View File

@ -121,6 +121,15 @@ fido_dev_info_new(size_t n)
return (calloc(n, sizeof(fido_dev_info_t)));
}
static void
fido_dev_info_reset(fido_dev_info_t *di)
{
free(di->path);
free(di->manufacturer);
free(di->product);
memset(di, 0, sizeof(*di));
}
void
fido_dev_info_free(fido_dev_info_t **devlist_p, size_t n)
{
@ -129,13 +138,8 @@ fido_dev_info_free(fido_dev_info_t **devlist_p, size_t n)
if (devlist_p == NULL || (devlist = *devlist_p) == NULL)
return;
for (size_t i = 0; i < n; i++) {
const fido_dev_info_t *di;
di = &devlist[i];
free(di->path);
free(di->manufacturer);
free(di->product);
}
for (size_t i = 0; i < n; i++)
fido_dev_info_reset(&devlist[i]);
free(devlist);
@ -148,6 +152,44 @@ fido_dev_info_ptr(const fido_dev_info_t *devlist, size_t i)
return (&devlist[i]);
}
int
fido_dev_info_set(fido_dev_info_t *devlist, size_t i,
const char *path, const char *manufacturer, const char *product,
const fido_dev_io_t *io, const fido_dev_transport_t *transport)
{
char *path_copy = NULL, *manu_copy = NULL, *prod_copy = NULL;
int r;
if (path == NULL || manufacturer == NULL || product == NULL ||
io == NULL) {
r = FIDO_ERR_INVALID_ARGUMENT;
goto out;
}
if ((path_copy = strdup(path)) == NULL ||
(manu_copy = strdup(manufacturer)) == NULL ||
(prod_copy = strdup(product)) == NULL) {
r = FIDO_ERR_INTERNAL;
goto out;
}
fido_dev_info_reset(&devlist[i]);
devlist[i].path = path_copy;
devlist[i].manufacturer = manu_copy;
devlist[i].product = prod_copy;
devlist[i].io = *io;
if (transport)
devlist[i].transport = *transport;
r = FIDO_OK;
out:
if (r != FIDO_OK) {
free(prod_copy);
free(manu_copy);
free(path_copy);
}
return (r);
}
const char *
fido_dev_info_path(const fido_dev_info_t *di)
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 Yubico AB. All rights reserved.
* Copyright (c) 2019-2021 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
@ -23,6 +23,8 @@
#define kIOMainPortDefault kIOMasterPortDefault
#endif
#define IOREG "ioreg://"
struct hid_osx {
IOHIDDeviceRef ref;
CFStringRef loop_id;
@ -166,20 +168,27 @@ get_str(IOHIDDeviceRef dev, char **manufacturer, char **product)
static char *
get_path(IOHIDDeviceRef dev)
{
io_service_t s;
io_string_t path;
io_service_t s;
uint64_t id;
char *path;
if ((s = IOHIDDeviceGetService(dev)) == MACH_PORT_NULL) {
fido_log_debug("%s: IOHIDDeviceGetService", __func__);
return (NULL);
}
if (IORegistryEntryGetPath(s, kIOServicePlane, path) != KERN_SUCCESS) {
fido_log_debug("%s: IORegistryEntryGetPath", __func__);
if (IORegistryEntryGetRegistryEntryID(s, &id) != KERN_SUCCESS) {
fido_log_debug("%s: IORegistryEntryGetRegistryEntryID",
__func__);
return (NULL);
}
return (strdup(path));
if (asprintf(&path, "%s%llu", IOREG, (unsigned long long)id) == -1) {
fido_log_error(errno, "%s: asprintf", __func__);
return (NULL);
}
return (path);
}
static bool
@ -365,6 +374,42 @@ disable_sigpipe(int fd)
return (0);
}
static int
to_uint64(const char *str, uint64_t *out)
{
char *ep;
unsigned long long ull;
errno = 0;
ull = strtoull(str, &ep, 10);
if (str == ep || *ep != '\0')
return (-1);
else if (ull == ULLONG_MAX && errno == ERANGE)
return (-1);
else if (ull > UINT64_MAX)
return (-1);
*out = (uint64_t)ull;
return (0);
}
static io_registry_entry_t
get_ioreg_entry(const char *path)
{
uint64_t id;
if (strncmp(path, IOREG, strlen(IOREG)) != 0)
return (IORegistryEntryFromPath(kIOMainPortDefault, path));
if (to_uint64(path + strlen(IOREG), &id) == -1) {
fido_log_debug("%s: to_uint64", __func__);
return (MACH_PORT_NULL);
}
return (IOServiceGetMatchingService(kIOMainPortDefault,
IORegistryEntryIDMatching(id)));
}
void *
fido_hid_open(const char *path)
{
@ -398,9 +443,8 @@ fido_hid_open(const char *path)
goto fail;
}
if ((entry = IORegistryEntryFromPath(kIOMainPortDefault,
path)) == MACH_PORT_NULL) {
fido_log_debug("%s: IORegistryEntryFromPath", __func__);
if ((entry = get_ioreg_entry(path)) == MACH_PORT_NULL) {
fido_log_debug("%s: get_ioreg_entry: %s", __func__, path);
goto fail;
}

View File

@ -454,7 +454,7 @@ fido_hid_close(void *handle)
fido_log_debug("%s: report_pending", __func__);
if (CancelIoEx(ctx->dev, &ctx->overlap) == 0)
fido_log_debug("%s CancelIoEx: 0x%lx",
__func__, GetLastError());
__func__, (u_long)GetLastError());
}
CloseHandle(ctx->overlap.hEvent);
}

View File

@ -21,6 +21,10 @@
#define TPM_ALG_RSA 0x0001
#define TPM_ALG_SHA256 0x000b
#define TPM_ALG_NULL 0x0010
#define TPM_ALG_ECC 0x0023
/* Part 2, 6.4: TPM_ECC_CURVE */
#define TPM_ECC_P256 0x0003
/* Part 2, 6.9: TPM_ST_ATTEST_CERTIFY */
#define TPM_ST_CERTIFY 0x8017
@ -31,7 +35,7 @@
#define TPMA_CLEAR 0x00000004 /* object persists */
#define TPMA_FIXED_P 0x00000010 /* object has fixed parent */
#define TPMA_SENSITIVE 0x00000020 /* data originates within tpm */
#define TPMA_SIGN 0x00020000 /* object may sign */
#define TPMA_SIGN 0x00040000 /* object may sign */
/* Part 2, 10.4.2: TPM2B_DIGEST */
PACKED_TYPE(tpm_sha256_digest_t,
@ -73,35 +77,69 @@ struct tpm_sha1_attest {
tpm_sha1_data_t data; /* signed sha1 */
tpm_clock_info_t clock;
uint64_t fwversion; /* obfuscated by tpm */
tpm_sha256_name_t name; /* sha256 of tpm_rsa2048_pubarea_t */
tpm_sha256_name_t name; /* sha256 of tpm_rs256_pubarea_t */
tpm_sha256_name_t qual_name; /* full tpm path of attested key */
})
/* Part 2, 11.2.4.5: TPM2B_PUBLIC_KEY_RSA */
PACKED_TYPE(tpm_rsa2048_key_t,
struct tpm_rsa2048_key {
PACKED_TYPE(tpm_rs256_key_t,
struct tpm_rs256_key {
uint16_t size; /* sizeof(body) */
uint8_t body[256];
})
/* Part 2, 11.2.5.1: TPM2B_ECC_PARAMETER */
PACKED_TYPE(tpm_es256_coord_t,
struct tpm_es256_coord {
uint16_t size; /* sizeof(body) */
uint8_t body[32];
})
/* Part 2, 11.2.5.2: TPMS_ECC_POINT */
PACKED_TYPE(tpm_es256_point_t,
struct tpm_es256_point {
tpm_es256_coord_t x;
tpm_es256_coord_t y;
})
/* Part 2, 12.2.3.5: TPMS_RSA_PARMS */
PACKED_TYPE(tpm_rsa2048_param_t,
struct tpm_rsa2048_param {
PACKED_TYPE(tpm_rs256_param_t,
struct tpm_rs256_param {
uint16_t symmetric; /* TPM_ALG_NULL */
uint16_t scheme; /* TPM_ALG_NULL */
uint16_t keybits; /* 2048 */
uint32_t exponent; /* zero (meaning 2^16 + 1) */
})
/* Part 2, 12.2.3.6: TPMS_ECC_PARMS */
PACKED_TYPE(tpm_es256_param_t,
struct tpm_es256_param {
uint16_t symmetric; /* TPM_ALG_NULL */
uint16_t scheme; /* TPM_ALG_NULL */
uint16_t curve_id; /* TPM_ECC_P256 */
uint16_t kdf; /* TPM_ALG_NULL */
})
/* Part 2, 12.2.4: TPMT_PUBLIC */
PACKED_TYPE(tpm_rsa2048_pubarea_t,
struct tpm_rsa2048_pubarea {
PACKED_TYPE(tpm_rs256_pubarea_t,
struct tpm_rs256_pubarea {
uint16_t alg; /* TPM_ALG_RSA */
uint16_t hash; /* TPM_ALG_SHA256 */
uint32_t attr;
tpm_sha256_digest_t policy; /* must be present? */
tpm_rsa2048_param_t param;
tpm_rsa2048_key_t key;
tpm_rs256_param_t param;
tpm_rs256_key_t key;
})
/* Part 2, 12.2.4: TPMT_PUBLIC */
PACKED_TYPE(tpm_es256_pubarea_t,
struct tpm_es256_pubarea {
uint16_t alg; /* TPM_ALG_ECC */
uint16_t hash; /* TPM_ALG_SHA256 */
uint32_t attr;
tpm_sha256_digest_t policy; /* must be present? */
tpm_es256_param_t param;
tpm_es256_point_t point;
})
static int
@ -145,7 +183,7 @@ get_signed_name(tpm_sha256_name_t *name, const fido_blob_t *pubarea)
}
static void
bswap_rsa2048_pubarea(tpm_rsa2048_pubarea_t *x)
bswap_rs256_pubarea(tpm_rs256_pubarea_t *x)
{
x->alg = htobe16(x->alg);
x->hash = htobe16(x->hash);
@ -157,6 +195,21 @@ bswap_rsa2048_pubarea(tpm_rsa2048_pubarea_t *x)
x->key.size = htobe16(x->key.size);
}
static void
bswap_es256_pubarea(tpm_es256_pubarea_t *x)
{
x->alg = htobe16(x->alg);
x->hash = htobe16(x->hash);
x->attr = htobe32(x->attr);
x->policy.size = htobe16(x->policy.size);
x->param.symmetric = htobe16(x->param.symmetric);
x->param.scheme = htobe16(x->param.scheme);
x->param.curve_id = htobe16(x->param.curve_id);
x->param.kdf = htobe16(x->param.kdf);
x->point.x.size = htobe16(x->point.x.size);
x->point.y.size = htobe16(x->point.y.size);
}
static void
bswap_sha1_certinfo(tpm_sha1_attest_t *x)
{
@ -169,10 +222,10 @@ bswap_sha1_certinfo(tpm_sha1_attest_t *x)
}
static int
check_rsa2048_pubarea(const fido_blob_t *buf, const rs256_pk_t *pk)
check_rs256_pubarea(const fido_blob_t *buf, const rs256_pk_t *pk)
{
const tpm_rsa2048_pubarea_t *actual;
tpm_rsa2048_pubarea_t expected;
const tpm_rs256_pubarea_t *actual;
tpm_rs256_pubarea_t expected;
int ok;
if (buf->len != sizeof(*actual)) {
@ -195,7 +248,44 @@ check_rsa2048_pubarea(const fido_blob_t *buf, const rs256_pk_t *pk)
expected.param.exponent = 0; /* meaning 2^16+1 */
expected.key.size = sizeof(expected.key.body);
memcpy(&expected.key.body, &pk->n, sizeof(expected.key.body));
bswap_rsa2048_pubarea(&expected);
bswap_rs256_pubarea(&expected);
ok = timingsafe_bcmp(&expected, actual, sizeof(expected));
explicit_bzero(&expected, sizeof(expected));
return ok != 0 ? -1 : 0;
}
static int
check_es256_pubarea(const fido_blob_t *buf, const es256_pk_t *pk)
{
const tpm_es256_pubarea_t *actual;
tpm_es256_pubarea_t expected;
int ok;
if (buf->len != sizeof(*actual)) {
fido_log_debug("%s: buf->len=%zu", __func__, buf->len);
return -1;
}
actual = (const void *)buf->ptr;
memset(&expected, 0, sizeof(expected));
expected.alg = TPM_ALG_ECC;
expected.hash = TPM_ALG_SHA256;
expected.attr = be32toh(actual->attr);
expected.attr &= ~(TPMA_RESERVED|TPMA_CLEAR);
expected.attr |= (TPMA_FIXED|TPMA_FIXED_P|TPMA_SENSITIVE|TPMA_SIGN);
expected.policy = actual->policy;
expected.policy.size = sizeof(expected.policy.body);
expected.param.symmetric = TPM_ALG_NULL;
expected.param.scheme = TPM_ALG_NULL; /* TCG Alg. Registry, 5.2.4 */
expected.param.curve_id = TPM_ECC_P256;
expected.param.kdf = TPM_ALG_NULL;
expected.point.x.size = sizeof(expected.point.x.body);
expected.point.y.size = sizeof(expected.point.y.body);
memcpy(&expected.point.x.body, &pk->x, sizeof(expected.point.x.body));
memcpy(&expected.point.y.body, &pk->y, sizeof(expected.point.y.body));
bswap_es256_pubarea(&expected);
ok = timingsafe_bcmp(&expected, actual, sizeof(expected));
explicit_bzero(&expected, sizeof(expected));
@ -258,14 +348,28 @@ fido_get_signed_hash_tpm(fido_blob_t *dgst, const fido_blob_t *clientdata_hash,
const fido_blob_t *pubarea = &attstmt->pubarea;
const fido_blob_t *certinfo = &attstmt->certinfo;
if (attstmt->alg != COSE_RS1 || attcred->type != COSE_RS256) {
fido_log_debug("%s: unsupported alg %d, type %d", __func__,
attstmt->alg, attcred->type);
if (attstmt->alg != COSE_RS1) {
fido_log_debug("%s: unsupported alg %d", __func__,
attstmt->alg);
return -1;
}
if (check_rsa2048_pubarea(pubarea, &attcred->pubkey.rs256) < 0) {
fido_log_debug("%s: check_rsa2048_pubarea", __func__);
switch (attcred->type) {
case COSE_ES256:
if (check_es256_pubarea(pubarea, &attcred->pubkey.es256) < 0) {
fido_log_debug("%s: check_es256_pubarea", __func__);
return -1;
}
break;
case COSE_RS256:
if (check_rs256_pubarea(pubarea, &attcred->pubkey.rs256) < 0) {
fido_log_debug("%s: check_rs256_pubarea", __func__);
return -1;
}
break;
default:
fido_log_debug("%s: unsupported type %d", __func__,
attcred->type);
return -1;
}

View File

@ -8,7 +8,9 @@
#include <winapifamily.h>
#ifdef _MSC_VER
#pragma region Desktop Family or OneCore Family
#endif
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)
#ifdef __cplusplus
@ -84,7 +86,15 @@ extern "C" {
// - WEBAUTHN_EXTENSIONS_IDENTIFIER_MIN_PIN_LENGTH
//
#define WEBAUTHN_API_CURRENT_VERSION WEBAUTHN_API_VERSION_3
#define WEBAUTHN_API_VERSION_4 4
// WEBAUTHN_API_VERSION_4 : Delta From WEBAUTHN_API_VERSION_3
// Data Structures and their sub versions:
// - WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS : 5
// - WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS : 6
// - WEBAUTHN_ASSERTION : 3
//
#define WEBAUTHN_API_CURRENT_VERSION WEBAUTHN_API_VERSION_4
//+------------------------------------------------------------------------------------------
// Information about an RP Entity
@ -272,6 +282,45 @@ typedef struct _WEBAUTHN_CREDENTIAL_LIST {
} WEBAUTHN_CREDENTIAL_LIST, *PWEBAUTHN_CREDENTIAL_LIST;
typedef const WEBAUTHN_CREDENTIAL_LIST *PCWEBAUTHN_CREDENTIAL_LIST;
//+------------------------------------------------------------------------------------------
// PRF values.
//-------------------------------------------------------------------------------------------
#define WEBAUTHN_CTAP_ONE_HMAC_SECRET_LENGTH 32
typedef struct _WEBAUTHN_HMAC_SECRET_SALT {
// Size of pbFirst.
DWORD cbFirst;
_Field_size_bytes_(cbFirst)
PBYTE pbFirst; // Required
// Size of pbSecond.
DWORD cbSecond;
_Field_size_bytes_(cbSecond)
PBYTE pbSecond;
} WEBAUTHN_HMAC_SECRET_SALT, *PWEBAUTHN_HMAC_SECRET_SALT;
typedef const WEBAUTHN_HMAC_SECRET_SALT *PCWEBAUTHN_HMAC_SECRET_SALT;
typedef struct _WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT {
// Size of pbCredID.
DWORD cbCredID;
_Field_size_bytes_(cbCredID)
PBYTE pbCredID; // Required
// PRF Values for above credential
PWEBAUTHN_HMAC_SECRET_SALT pHmacSecretSalt; // Required
} WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT, *PWEBAUTHN_CRED_WITH_HMAC_SECRET_SALT;
typedef const WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT *PCWEBAUTHN_CRED_WITH_HMAC_SECRET_SALT;
typedef struct _WEBAUTHN_HMAC_SECRET_SALT_VALUES {
PWEBAUTHN_HMAC_SECRET_SALT pGlobalHmacSalt;
DWORD cCredWithHmacSecretSaltList;
_Field_size_(cCredWithHmacSecretSaltList)
PWEBAUTHN_CRED_WITH_HMAC_SECRET_SALT pCredWithHmacSecretSaltList;
} WEBAUTHN_HMAC_SECRET_SALT_VALUES, *PWEBAUTHN_HMAC_SECRET_SALT_VALUES;
typedef const WEBAUTHN_HMAC_SECRET_SALT_VALUES *PCWEBAUTHN_HMAC_SECRET_SALT_VALUES;
//+------------------------------------------------------------------------------------------
// Hmac-Secret extension
//-------------------------------------------------------------------------------------------
@ -410,7 +459,8 @@ typedef const WEBAUTHN_EXTENSIONS *PCWEBAUTHN_EXTENSIONS;
#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_2 2
#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_3 3
#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_4 4
#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_4
#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_5 5
#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_5
typedef struct _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS {
// Version of this structure, to allow for modifications in the future.
@ -465,13 +515,20 @@ typedef struct _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS {
// Large Blob Support: none, required or preferred
//
// NTE_INVALID_PARAMETER when large blob required or preferred and
// both bRequireResidentKey and bPreferResidentKey are set to FALSE.
// bRequireResidentKey isn't set to TRUE
DWORD dwLargeBlobSupport;
// Optional. Prefer key to be resident. Defaulting to FALSE. When TRUE,
// overrides the above bRequireResidentKey.
BOOL bPreferResidentKey;
//
// The following fields have been added in WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_5
//
// Optional. BrowserInPrivate Mode. Defaulting to FALSE.
BOOL bBrowserInPrivateMode;
} WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS, *PWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS;
typedef const WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS *PCWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS;
@ -485,7 +542,8 @@ typedef const WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS *PCWEBAUTHN_AUTHENT
#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_3 3
#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_4 4
#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_5 5
#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_5
#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_6 6
#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_6
typedef struct _WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS {
// Version of this structure, to allow for modifications in the future.
@ -545,6 +603,17 @@ typedef struct _WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS {
DWORD cbCredLargeBlob;
_Field_size_bytes_(cbCredLargeBlob)
PBYTE pbCredLargeBlob;
//
// The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_6
//
// PRF values which will be converted into HMAC-SECRET values according to WebAuthn Spec.
PWEBAUTHN_HMAC_SECRET_SALT_VALUES pHmacSecretSaltValues;
// Optional. BrowserInPrivate Mode. Defaulting to FALSE.
BOOL bBrowserInPrivateMode;
} WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS, *PWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS;
typedef const WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS *PCWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS;
@ -705,7 +774,8 @@ typedef const WEBAUTHN_CREDENTIAL_ATTESTATION *PCWEBAUTHN_CREDENTIAL_ATTESTATION
#define WEBAUTHN_ASSERTION_VERSION_1 1
#define WEBAUTHN_ASSERTION_VERSION_2 2
#define WEBAUTHN_ASSERTION_CURRENT_VERSION WEBAUTHN_ASSERTION_VERSION_2
#define WEBAUTHN_ASSERTION_VERSION_3 3
#define WEBAUTHN_ASSERTION_CURRENT_VERSION WEBAUTHN_ASSERTION_VERSION_3
typedef struct _WEBAUTHN_ASSERTION {
// Version of this structure, to allow for modifications in the future.
@ -745,6 +815,12 @@ typedef struct _WEBAUTHN_ASSERTION {
DWORD dwCredLargeBlobStatus;
//
// Following fields have been added in WEBAUTHN_ASSERTION_VERSION_3
//
PWEBAUTHN_HMAC_SECRET_SALT pHmacSecret;
} WEBAUTHN_ASSERTION, *PWEBAUTHN_ASSERTION;
typedef const WEBAUTHN_ASSERTION *PCWEBAUTHN_ASSERTION;
@ -834,6 +910,8 @@ WebAuthNGetW3CExceptionDOMError(
#endif
#endif // WINAPI_FAMILY_PARTITION
#ifdef _MSC_VER
#pragma endregion
#endif
#endif // __WEBAUTHN_H_

View File

@ -12,6 +12,16 @@
#include "fido.h"
#include "webauthn.h"
#ifndef NTE_INVALID_PARAMETER
#define NTE_INVALID_PARAMETER _HRESULT_TYPEDEF_(0x80090027)
#endif
#ifndef NTE_NOT_SUPPORTED
#define NTE_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x80090029)
#endif
#ifndef NTE_DEVICE_NOT_FOUND
#define NTE_DEVICE_NOT_FOUND _HRESULT_TYPEDEF_(0x80090035)
#endif
#define MAXCHARS 128
#define MAXCREDS 128
#define MAXMSEC 6000 * 1000
@ -40,27 +50,36 @@ struct winhello_cred {
wchar_t *display_name;
};
static TLS BOOL webauthn_loaded;
static TLS HMODULE webauthn_handle;
static TLS DWORD (*webauthn_get_api_version)(void);
static TLS PCWSTR (*webauthn_strerr)(HRESULT);
static TLS HRESULT (*webauthn_get_assert)(HWND, LPCWSTR,
typedef DWORD WINAPI webauthn_get_api_version_t(void);
typedef PCWSTR WINAPI webauthn_strerr_t(HRESULT);
typedef HRESULT WINAPI webauthn_get_assert_t(HWND, LPCWSTR,
PCWEBAUTHN_CLIENT_DATA,
PCWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS,
PWEBAUTHN_ASSERTION *);
static TLS HRESULT (*webauthn_make_cred)(HWND,
typedef HRESULT WINAPI webauthn_make_cred_t(HWND,
PCWEBAUTHN_RP_ENTITY_INFORMATION,
PCWEBAUTHN_USER_ENTITY_INFORMATION,
PCWEBAUTHN_COSE_CREDENTIAL_PARAMETERS,
PCWEBAUTHN_CLIENT_DATA,
PCWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS,
PWEBAUTHN_CREDENTIAL_ATTESTATION *);
static TLS void (*webauthn_free_assert)(PWEBAUTHN_ASSERTION);
static TLS void (*webauthn_free_attest)(PWEBAUTHN_CREDENTIAL_ATTESTATION);
typedef void WINAPI webauthn_free_assert_t(PWEBAUTHN_ASSERTION);
typedef void WINAPI webauthn_free_attest_t(PWEBAUTHN_CREDENTIAL_ATTESTATION);
static TLS BOOL webauthn_loaded;
static TLS HMODULE webauthn_handle;
static TLS webauthn_get_api_version_t *webauthn_get_api_version;
static TLS webauthn_strerr_t *webauthn_strerr;
static TLS webauthn_get_assert_t *webauthn_get_assert;
static TLS webauthn_make_cred_t *webauthn_make_cred;
static TLS webauthn_free_assert_t *webauthn_free_assert;
static TLS webauthn_free_attest_t *webauthn_free_attest;
static int
webauthn_load(void)
{
DWORD n = 1;
if (webauthn_loaded || webauthn_handle != NULL) {
fido_log_debug("%s: already loaded", __func__);
return -1;
@ -70,34 +89,46 @@ webauthn_load(void)
return -1;
}
if ((webauthn_get_api_version = (void *)GetProcAddress(webauthn_handle,
if ((webauthn_get_api_version =
(webauthn_get_api_version_t *)GetProcAddress(webauthn_handle,
"WebAuthNGetApiVersionNumber")) == NULL) {
fido_log_debug("%s: WebAuthNGetApiVersionNumber", __func__);
/* WebAuthNGetApiVersionNumber might not exist */
}
if (webauthn_get_api_version != NULL &&
(n = webauthn_get_api_version()) < 1) {
fido_log_debug("%s: unsupported api %lu", __func__, (u_long)n);
goto fail;
}
if ((webauthn_strerr = (void *)GetProcAddress(webauthn_handle,
fido_log_debug("%s: api version %lu", __func__, (u_long)n);
if ((webauthn_strerr =
(webauthn_strerr_t *)GetProcAddress(webauthn_handle,
"WebAuthNGetErrorName")) == NULL) {
fido_log_debug("%s: WebAuthNGetErrorName", __func__);
goto fail;
}
if ((webauthn_get_assert = (void *)GetProcAddress(webauthn_handle,
if ((webauthn_get_assert =
(webauthn_get_assert_t *)GetProcAddress(webauthn_handle,
"WebAuthNAuthenticatorGetAssertion")) == NULL) {
fido_log_debug("%s: WebAuthNAuthenticatorGetAssertion",
__func__);
goto fail;
}
if ((webauthn_make_cred = (void *)GetProcAddress(webauthn_handle,
if ((webauthn_make_cred =
(webauthn_make_cred_t *)GetProcAddress(webauthn_handle,
"WebAuthNAuthenticatorMakeCredential")) == NULL) {
fido_log_debug("%s: WebAuthNAuthenticatorMakeCredential",
__func__);
goto fail;
}
if ((webauthn_free_assert = (void *)GetProcAddress(webauthn_handle,
if ((webauthn_free_assert =
(webauthn_free_assert_t *)GetProcAddress(webauthn_handle,
"WebAuthNFreeAssertion")) == NULL) {
fido_log_debug("%s: WebAuthNFreeAssertion", __func__);
goto fail;
}
if ((webauthn_free_attest = (void *)GetProcAddress(webauthn_handle,
if ((webauthn_free_attest =
(webauthn_free_attest_t *)GetProcAddress(webauthn_handle,
"WebAuthNFreeCredentialAttestation")) == NULL) {
fido_log_debug("%s: WebAuthNFreeCredentialAttestation",
__func__);
@ -149,35 +180,6 @@ to_utf16(const char *utf8)
return utf16;
}
static char *
to_utf8(const wchar_t *utf16)
{
int nch;
char *utf8;
if (utf16 == NULL) {
fido_log_debug("%s: NULL", __func__);
return NULL;
}
if ((nch = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, utf16,
-1, NULL, 0, NULL, NULL)) < 1 || (size_t)nch > MAXCHARS) {
fido_log_debug("%s: WideCharToMultiByte %d", __func__);
return NULL;
}
if ((utf8 = calloc((size_t)nch, sizeof(*utf8))) == NULL) {
fido_log_debug("%s: calloc", __func__);
return NULL;
}
if (WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, utf16, -1,
utf8, nch, NULL, NULL) != nch) {
fido_log_debug("%s: WideCharToMultiByte", __func__);
free(utf8);
return NULL;
}
return utf8;
}
static int
to_fido(HRESULT hr)
{
@ -192,7 +194,7 @@ to_fido(HRESULT hr)
case NTE_NOT_FOUND:
return FIDO_ERR_NOT_ALLOWED;
default:
fido_log_debug("%s: hr=0x%x", __func__, hr);
fido_log_debug("%s: hr=0x%lx", __func__, (u_long)hr);
return FIDO_ERR_INTERNAL;
}
}
@ -249,7 +251,7 @@ pack_credlist(WEBAUTHN_CREDENTIALS *out, const fido_blob_array_t *in)
}
static int
set_uv(DWORD *out, fido_opt_t uv, const char *pin)
set_cred_uv(DWORD *out, fido_opt_t uv, const char *pin)
{
if (pin) {
*out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED;
@ -258,7 +260,28 @@ set_uv(DWORD *out, fido_opt_t uv, const char *pin)
switch (uv) {
case FIDO_OPT_OMIT:
*out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_ANY;
case FIDO_OPT_FALSE:
*out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_DISCOURAGED;
break;
case FIDO_OPT_TRUE:
*out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED;
break;
}
return 0;
}
static int
set_assert_uv(DWORD *out, fido_opt_t uv, const char *pin)
{
if (pin) {
*out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED;
return 0;
}
switch (uv) {
case FIDO_OPT_OMIT:
*out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_PREFERRED;
break;
case FIDO_OPT_FALSE:
*out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_DISCOURAGED;
@ -361,7 +384,7 @@ pack_cred_ext(WEBAUTHN_EXTENSIONS *out, const fido_cred_ext_t *in)
return 0; /* nothing to do */
}
if (in->mask & ~(FIDO_EXT_HMAC_SECRET | FIDO_EXT_CRED_PROTECT)) {
fido_log_debug("%s: mask 0x%x", in->mask);
fido_log_debug("%s: mask 0x%x", __func__, in->mask);
return -1;
}
if (in->mask & FIDO_EXT_HMAC_SECRET)
@ -508,8 +531,9 @@ translate_fido_assert(struct winhello_assert *ctx, const fido_assert_t *assert,
fido_log_debug("%s: pack_credlist", __func__);
return FIDO_ERR_INTERNAL;
}
if (set_uv(&opt->dwUserVerificationRequirement, assert->uv, pin) < 0) {
fido_log_debug("%s: set_uv", __func__);
if (set_assert_uv(&opt->dwUserVerificationRequirement, assert->uv,
pin) < 0) {
fido_log_debug("%s: set_assert_uv", __func__);
return FIDO_ERR_INTERNAL;
}
@ -587,9 +611,9 @@ translate_fido_cred(struct winhello_cred *ctx, const fido_cred_t *cred,
fido_log_debug("%s: pack_cred_ext", __func__);
return FIDO_ERR_UNSUPPORTED_EXTENSION;
}
if (set_uv(&opt->dwUserVerificationRequirement, (cred->ext.mask &
if (set_cred_uv(&opt->dwUserVerificationRequirement, (cred->ext.mask &
FIDO_EXT_CRED_PROTECT) ? FIDO_OPT_TRUE : cred->uv, pin) < 0) {
fido_log_debug("%s: set_uv", __func__);
fido_log_debug("%s: set_cred_uv", __func__);
return FIDO_ERR_INTERNAL;
}
if (cred->rk == FIDO_OPT_TRUE) {
@ -623,6 +647,10 @@ decode_attobj(const cbor_item_t *key, const cbor_item_t *val, void *arg)
goto fail;
}
} else if (!strcmp(name, "authData")) {
if (fido_blob_decode(val, &cred->authdata_raw) < 0) {
fido_log_debug("%s: fido_blob_decode", __func__);
goto fail;
}
if (cbor_decode_cred_authdata(val, cred->type,
&cred->authdata_cbor, &cred->authdata, &cred->attcred,
&cred->authdata_ext) < 0) {
@ -640,9 +668,9 @@ decode_attobj(const cbor_item_t *key, const cbor_item_t *val, void *arg)
}
static int
translate_winhello_cred(fido_cred_t *cred, const WEBAUTHN_CREDENTIAL_ATTESTATION *att)
translate_winhello_cred(fido_cred_t *cred,
const WEBAUTHN_CREDENTIAL_ATTESTATION *att)
{
cbor_item_t *item = NULL;
struct cbor_load_result cbor;
int r = FIDO_ERR_INTERNAL;
@ -672,24 +700,6 @@ translate_winhello_cred(fido_cred_t *cred, const WEBAUTHN_CREDENTIAL_ATTESTATION
return r;
}
static int
winhello_manifest(void)
{
DWORD n;
if (!webauthn_loaded && webauthn_load() < 0) {
fido_log_debug("%s: webauthn_load", __func__);
return FIDO_ERR_INTERNAL;
}
if ((n = webauthn_get_api_version()) < 1) {
fido_log_debug("%s: unsupported api %u", __func__, n);
return FIDO_ERR_INTERNAL;
}
fido_log_debug("%s: api version %u", __func__, n);
return FIDO_OK;
}
static int
winhello_get_assert(HWND w, struct winhello_assert *ctx)
{
@ -761,7 +771,6 @@ winhello_cred_free(struct winhello_cred *ctx)
int
fido_winhello_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)
{
int r;
fido_dev_info_t *di;
if (ilen == 0) {
@ -770,9 +779,9 @@ fido_winhello_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)
if (devlist == NULL) {
return FIDO_ERR_INVALID_ARGUMENT;
}
if ((r = winhello_manifest()) != FIDO_OK) {
fido_log_debug("%s: winhello_manifest", __func__);
return r;
if (!webauthn_loaded && webauthn_load() < 0) {
fido_log_debug("%s: webauthn_load", __func__);
return FIDO_OK; /* not an error */
}
di = &devlist[*olen];
@ -844,13 +853,16 @@ fido_winhello_get_assert(fido_dev_t *dev, fido_assert_t *assert,
}
if ((w = GetForegroundWindow()) == NULL) {
fido_log_debug("%s: GetForegroundWindow", __func__);
goto fail;
if ((w = GetTopWindow(NULL)) == NULL) {
fido_log_debug("%s: GetTopWindow", __func__);
goto fail;
}
}
if ((r = translate_fido_assert(ctx, assert, pin, ms)) != FIDO_OK) {
fido_log_debug("%s: translate_fido_assert", __func__);
goto fail;
}
if ((r = winhello_get_assert(w, ctx)) != S_OK) {
if ((r = winhello_get_assert(w, ctx)) != FIDO_OK) {
fido_log_debug("%s: winhello_get_assert", __func__);
goto fail;
}
@ -918,7 +930,10 @@ fido_winhello_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin,
}
if ((w = GetForegroundWindow()) == NULL) {
fido_log_debug("%s: GetForegroundWindow", __func__);
goto fail;
if ((w = GetTopWindow(NULL)) == NULL) {
fido_log_debug("%s: GetTopWindow", __func__);
goto fail;
}
}
if ((r = translate_fido_cred(ctx, cred, pin, ms)) != FIDO_OK) {
fido_log_debug("%s: translate_fido_cred", __func__);

View File

@ -12,13 +12,13 @@
# - should pass as-is on a YubiKey with a PIN set;
# - may otherwise require set +e above;
# - can be executed with UV=1 to run additional UV tests;
# - was last tested on 2021-07-21 with firmware 5.2.7.
# - was last tested on 2022-01-11 with firmware 5.4.3.
cd "$1"
DEV="$2"
make_cred() {
cat > cred_param << EOF
sed /^$/d > cred_param << EOF
$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64)
$1
some user name
@ -34,7 +34,7 @@ verify_cred() {
}
get_assert() {
cat > assert_param << EOF
sed /^$/d > assert_param << EOF
$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64)
$1
$(cat $3)

View File

@ -229,7 +229,7 @@ try {
ExitOnError
# Copy DLLs.
if ("${SHARED}" -eq "ON") {
"cbor.dll", "crypto-46.dll", "zlib1.dll" | `
"cbor.dll", "crypto-47.dll", "zlib1.dll" | `
%{ Copy-Item "${PREFIX}\bin\$_" `
-Destination "examples\${Config}" }
}

View File

@ -6,11 +6,11 @@
New-Variable -Name 'LIBRESSL_URL' `
-Value 'https://fastly.cdn.openbsd.org/pub/OpenBSD/LibreSSL' `
-Option Constant
New-Variable -Name 'LIBRESSL' -Value 'libressl-3.3.4' -Option Constant
New-Variable -Name 'LIBRESSL' -Value 'libressl-3.4.2' -Option Constant
# libcbor coordinates.
New-Variable -Name 'LIBCBOR' -Value 'libcbor-0.8.0' -Option Constant
New-Variable -Name 'LIBCBOR_BRANCH' -Value 'v0.8.0' -Option Constant
New-Variable -Name 'LIBCBOR' -Value 'libcbor-0.9.0' -Option Constant
New-Variable -Name 'LIBCBOR_BRANCH' -Value 'v0.9.0' -Option Constant
New-Variable -Name 'LIBCBOR_GIT' -Value 'https://github.com/pjk/libcbor' `
-Option Constant

Binary file not shown.

View File

@ -0,0 +1,68 @@
# Copyright (c) 2021 Yubico AB. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
param(
[string]$GPGPath = "C:\Program Files (x86)\GnuPG\bin\gpg.exe",
[string]$Config = "Release"
)
$ErrorActionPreference = "Stop"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Cygwin coordinates.
$URL = 'https://www.cygwin.com'
$Setup = 'setup-x86_64.exe'
$Mirror = 'https://mirrors.kernel.org/sourceware/cygwin/'
$Packages = 'gcc-core,pkg-config,cmake,make,libcbor-devel,libssl-devel,zlib-devel'
# Work directories.
$Cygwin = "$PSScriptRoot\..\cygwin"
$Root = "${Cygwin}\root"
# Find GPG.
$GPG = $(Get-Command gpg -ErrorAction Ignore | `
Select-Object -ExpandProperty Source)
if ([string]::IsNullOrEmpty($GPG)) {
$GPG = $GPGPath
}
if (-Not (Test-Path $GPG)) {
throw "Unable to find GPG at $GPG"
}
Write-Host "Config: $Config"
Write-Host "GPG: $GPG"
# Create work directories.
New-Item -Type Directory "${Cygwin}" -Force
New-Item -Type Directory "${Root}" -Force
# Fetch and verify Cygwin.
try {
if (-Not (Test-Path ${Cygwin}\${Setup} -PathType leaf)) {
Invoke-WebRequest ${URL}/${Setup} `
-OutFile ${Cygwin}\${Setup}
}
if (-Not (Test-Path ${Cygwin}\${Setup}.sig -PathType leaf)) {
Invoke-WebRequest ${URL}/${Setup}.sig `
-OutFile ${Cygwin}\${Setup}.sig
}
& $GPG --list-keys
& $GPG --quiet --no-default-keyring `
--keyring ${PSScriptRoot}/cygwin.gpg `
--verify ${Cygwin}\${Setup}.sig ${Cygwin}\${Setup}
if ($LastExitCode -ne 0) {
throw "GPG signature verification failed"
}
} catch {
throw "Failed to fetch and verify Cygwin"
}
# Bootstrap Cygwin.
Start-Process "${Cygwin}\${Setup}" -Wait -NoNewWindow `
-ArgumentList "-dnNOqW -s ${Mirror} -R ${Root} -P ${Packages}"
# Build libfido2.
$Env:PATH = "${Root}\bin\;" + $Env:PATH
cmake "-DCMAKE_BUILD_TYPE=${Config}" -B "build-${Config}"
make -C "build-${Config}"

View File

@ -7,8 +7,8 @@ $Architectures = @('x64', 'Win32', 'ARM64', 'ARM')
$InstallPrefixes = @('Win64', 'Win32', 'ARM64', 'ARM')
$Types = @('dynamic', 'static')
$Config = 'Release'
$LibCrypto = '46'
$SDK = '142'
$LibCrypto = '47'
$SDK = '143'
. "$PSScriptRoot\const.ps1"
@ -49,7 +49,7 @@ Function Package-Static(${SRC}, ${DEST}) {
}
Function Package-PDBs(${SRC}, ${DEST}) {
Copy-Item "${SRC}\${LIBRESSL}\crypto\crypto.dir\${Config}\vc${SDK}.pdb" `
Copy-Item "${SRC}\${LIBRESSL}\crypto\crypto_obj.dir\${Config}\crypto_obj.pdb" `
"${DEST}\crypto-${LibCrypto}.pdb"
Copy-Item "${SRC}\${LIBCBOR}\src\cbor.dir\${Config}\vc${SDK}.pdb" `
"${DEST}\cbor.pdb"
@ -59,6 +59,17 @@ Function Package-PDBs(${SRC}, ${DEST}) {
"${DEST}\fido2.pdb"
}
Function Package-StaticPDBs(${SRC}, ${DEST}) {
Copy-Item "${SRC}\${LIBRESSL}\crypto\Release\crypto-${LibCrypto}.pdb" `
"${DEST}\crypto-${LibCrypto}.pdb"
Copy-Item "${SRC}\${LIBCBOR}\src\Release\cbor.pdb" `
"${DEST}\cbor.pdb"
Copy-Item "${SRC}\${ZLIB}\Release\zlibstatic.pdb" `
"${DEST}\zlib.pdb"
Copy-Item "${SRC}\src\Release\fido2_static.pdb" `
"${DEST}\fido2.pdb"
}
Function Package-Tools(${SRC}, ${DEST}) {
Copy-Item "${SRC}\tools\${Config}\fido2-assert.exe" `
"${DEST}\fido2-assert.exe"
@ -81,4 +92,6 @@ for ($i = 0; $i -lt $Architectures.Length; $i++) {
"${OUTPUT}\pkg\${InstallPrefix}\${Config}\v${SDK}\dynamic"
Package-Static "${OUTPUT}\${Arch}\static" `
"${OUTPUT}\pkg\${InstallPrefix}\${Config}\v${SDK}\static"
Package-StaticPDBs "${BUILD}\${Arch}\static" `
"${OUTPUT}\pkg\${InstallPrefix}\${Config}\v${SDK}\static"
}

View File

@ -66,7 +66,7 @@ CFLAGS+= -DHAVE_TIMINGSAFE_BCMP
CFLAGS+= -DHAVE_UNISTD_H
CFLAGS+= -DTLS=__thread
CFLAGS+= -D_FIDO_MAJOR=1
CFLAGS+= -D_FIDO_MINOR=9
CFLAGS+= -D_FIDO_MINOR=10
CFLAGS+= -D_FIDO_PATCH=0
LIBADD= crypto z