diff --git a/contrib/libfido2/.actions/build-bsd b/contrib/libfido2/.actions/build-bsd new file mode 100755 index 000000000000..66fc4e3ba281 --- /dev/null +++ b/contrib/libfido2/.actions/build-bsd @@ -0,0 +1,97 @@ +#!/bin/sh -eux + +# 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. +# SPDX-License-Identifier: BSD-2-Clause + +BASE_URL="https://builds.sr.ht" +MANIFEST="$(mktemp)" +LOGFILE="$(mktemp)" +trap '[ -f "${LOGFILE}" ] && cat -- "${LOGFILE}"' EXIT + +# construct the sourcehut build manifest +cat > "${MANIFEST}" <<- EOF +image: ${IMAGE} +packages: + - cmake + - llvm + - pcsc-lite +EOF + +case "${IMAGE}" in + freebsd*) +cat >> "${MANIFEST}" <<- EOF + - libcbor + - pkgconf +EOF + ;; +esac + +cat >> "${MANIFEST}" <<- EOF +sources: + - ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}#$(git rev-parse HEAD) +tasks: + - build: | + if [ "\$(uname)" = "OpenBSD" ]; then + SUDO="doas -u root" + else + SUDO=sudo + fi + SCAN="/usr/local/bin/scan-build --use-cc=/usr/bin/cc --status-bugs" + cd libfido2 + for T in Debug Release; do + mkdir build-\$T + (cd build-\$T && \${SCAN} cmake -DCMAKE_BUILD_TYPE=\$T ..) + \${SCAN} make -j"\$(sysctl -n hw.ncpu)" -C build-\$T + make -C build-\$T regress + \${SUDO} make -C build-\$T install + done +EOF + +q() { + curl \ + --silent \ + --oauth2-bearer "${SOURCEHUT_TOKEN}" \ + --header "Content-Type: application/json" \ + --data @- -- \ + "${BASE_URL}/query" \ + | tee -a -- "${LOGFILE}" +} + +submit_job() { + local manifest="$1" + jq \ + --compact-output --null-input \ + '{ query: $body, variables: { var: $var } }' \ + --arg body 'mutation($var: String!) { submit(manifest: $var) { id } }' \ + --rawfile var "${manifest}" \ + | q \ + | jq --exit-status --raw-output '.data.submit.id' +} + +job_status() { + local id="$1" + jq \ + --compact-output --null-input \ + '{ query: $body, variables: { var: $var } }' \ + --arg body 'query($var: Int!) { job(id: $var) { status } }' \ + --argjson var "${id}" \ + | q \ + | jq --exit-status --raw-output '.data.job.status' +} + +JOB_ID="$(submit_job "${MANIFEST}")" || exit 1 +[ -z "${JOB_ID}" ] && exit 1 +echo "Job '${JOB_ID}' running at ${BASE_URL}/~yubico-libfido2/job/${JOB_ID}" + +while true; do + JOB_STATUS="$(job_status "${JOB_ID}")" || exit 1 + case "${JOB_STATUS}" in + SUCCESS) exit 0;; + FAILED) exit 1;; + PENDING|QUEUED|RUNNING) ;; + *) exit 1;; + esac + sleep 60 +done diff --git a/contrib/libfido2/.actions/build-linux-clang b/contrib/libfido2/.actions/build-linux-clang new file mode 100755 index 000000000000..ba20f1279ec9 --- /dev/null +++ b/contrib/libfido2/.actions/build-linux-clang @@ -0,0 +1,21 @@ +#!/bin/sh -eux + +# 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. +# SPDX-License-Identifier: BSD-2-Clause + +${CC} --version +SCAN=scan-build${CC#clang} + +# Check exports. +(cd src && ./diff_exports.sh) + +# Build, analyze, and install libfido2. +for T in Debug Release; do + mkdir build-$T + (cd build-$T && ${SCAN} --use-cc="${CC}" cmake -DCMAKE_BUILD_TYPE=$T ..) + ${SCAN} --use-cc="${CC}" --status-bugs make -j"$(nproc)" -C build-$T + make -C build-$T regress + sudo make -C build-$T install +done diff --git a/contrib/libfido2/.actions/build-linux-gcc b/contrib/libfido2/.actions/build-linux-gcc new file mode 100755 index 000000000000..cd42b5eb7bed --- /dev/null +++ b/contrib/libfido2/.actions/build-linux-gcc @@ -0,0 +1,23 @@ +#!/bin/sh -eux + +# 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. +# SPDX-License-Identifier: BSD-2-Clause + +${CC} --version + +# Build and install libfido2. +for T in Debug Release; do + mkdir build-$T + (cd build-$T && cmake -DCMAKE_BUILD_TYPE=$T ..) + make -j"$(nproc)" -C build-$T + make -C build-$T regress + sudo make -C build-$T install +done + +# Check udev/fidodevs. +[ -x "$(which update-alternatives)" ] && { + sudo update-alternatives --set awk "$(which original-awk)" +} +udev/check.sh udev/fidodevs diff --git a/contrib/libfido2/.actions/build-linux-i686-w64-mingw32-gcc b/contrib/libfido2/.actions/build-linux-i686-w64-mingw32-gcc new file mode 100755 index 000000000000..a89578da0886 --- /dev/null +++ b/contrib/libfido2/.actions/build-linux-i686-w64-mingw32-gcc @@ -0,0 +1,58 @@ +#!/bin/sh -eux + +# Copyright (c) 2022-2023 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. +# SPDX-License-Identifier: BSD-2-Clause + +# XXX defining CC and cross-compiling confuses OpenSSL's build. +unset CC + +sudo mkdir /fakeroot +sudo chmod 755 /fakeroot + +cat << EOF > /tmp/mingw.cmake +SET(CMAKE_SYSTEM_NAME Windows) +SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc) +SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++) +SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres) +SET(CMAKE_FIND_ROOT_PATH /fakeroot) +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +EOF + +# Build and install libcbor. +git clone --depth=1 https://github.com/pjk/libcbor -b v0.10.1 +cd libcbor +mkdir build +(cd build && cmake -DCMAKE_TOOLCHAIN_FILE=/tmp/mingw.cmake \ + -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=/fakeroot ..) +make -j"$(nproc)" -C build +sudo make -C build install +cd .. + +# Build and install OpenSSL 1.1.1w. +git clone --depth=1 https://github.com/openssl/openssl -b OpenSSL_1_1_1w +cd openssl +./Configure mingw --prefix=/fakeroot --openssldir=/fakeroot/openssl \ + --cross-compile-prefix=i686-w64-mingw32- +make -j"$(nproc)" +sudo make install_sw +cd .. + +# Build and install zlib. +git clone --depth=1 https://github.com/madler/zlib -b v1.3 +cd zlib +make -fwin32/Makefile.gcc PREFIX=i686-w64-mingw32- +sudo make -fwin32/Makefile.gcc PREFIX=i686-w64-mingw32- DESTDIR=/fakeroot \ + INCLUDE_PATH=/include LIBRARY_PATH=/lib BINARY_PATH=/bin install +cd .. + +# Build and install libfido2. +export PKG_CONFIG_PATH=/fakeroot/lib/pkgconfig +mkdir build +(cd build && cmake -DCMAKE_TOOLCHAIN_FILE=/tmp/mingw.cmake \ + -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/fakeroot ..) +make -j"$(nproc)" -C build +sudo make -C build install diff --git a/contrib/libfido2/.actions/build-linux-openssl3-clang b/contrib/libfido2/.actions/build-linux-openssl3-clang new file mode 100755 index 000000000000..2383e51ad8f5 --- /dev/null +++ b/contrib/libfido2/.actions/build-linux-openssl3-clang @@ -0,0 +1,33 @@ +#!/bin/sh -eux + +# 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. +# SPDX-License-Identifier: BSD-2-Clause + +${CC} --version +SCAN=scan-build${CC#clang} +FAKEROOT="$(mktemp -d)" + +# Check exports. +(cd src && ./diff_exports.sh) + +# Build and install OpenSSL 3.0.12. +git clone --branch openssl-3.0.12 \ + --depth=1 https://github.com/openssl/openssl +cd openssl +./Configure linux-x86_64-clang --prefix="${FAKEROOT}" \ + --openssldir="${FAKEROOT}/openssl" --libdir=lib +make install_sw +cd .. + +# Build, analyze, and install libfido2. +for T in Debug Release; do + mkdir build-$T + export PKG_CONFIG_PATH="${FAKEROOT}/lib/pkgconfig" + (cd build-$T && ${SCAN} --use-cc="${CC}" \ + cmake -DCMAKE_BUILD_TYPE=$T ..) + ${SCAN} --use-cc="${CC}" --status-bugs make -C build-$T + make -C build-$T regress + sudo make -C build-$T install +done diff --git a/contrib/libfido2/.actions/build-linux-openssl3-gcc b/contrib/libfido2/.actions/build-linux-openssl3-gcc new file mode 100755 index 000000000000..344fc12bce8c --- /dev/null +++ b/contrib/libfido2/.actions/build-linux-openssl3-gcc @@ -0,0 +1,28 @@ +#!/bin/sh -eux + +# 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. +# SPDX-License-Identifier: BSD-2-Clause + +${CC} --version +FAKEROOT="$(mktemp -d)" + +# Build and install OpenSSL 3.0.12. +git clone --branch openssl-3.0.12 \ + --depth=1 https://github.com/openssl/openssl +cd openssl +./Configure linux-x86_64 --prefix="${FAKEROOT}" \ + --openssldir="${FAKEROOT}/openssl" --libdir=lib +make install_sw +cd .. + +# Build and install libfido2. +for T in Debug Release; do + mkdir build-$T + export PKG_CONFIG_PATH="${FAKEROOT}/lib/pkgconfig" + (cd build-$T && cmake -DCMAKE_BUILD_TYPE=$T ..) + make -j"$(nproc)" -C build-$T + make -C build-$T regress + sudo make -C build-$T install +done diff --git a/contrib/libfido2/.actions/build-linux-openssl3-i686-w64-mingw32-gcc b/contrib/libfido2/.actions/build-linux-openssl3-i686-w64-mingw32-gcc new file mode 100755 index 000000000000..3bbb141dad0d --- /dev/null +++ b/contrib/libfido2/.actions/build-linux-openssl3-i686-w64-mingw32-gcc @@ -0,0 +1,59 @@ +#!/bin/sh -eux + +# Copyright (c) 2022-2023 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. +# SPDX-License-Identifier: BSD-2-Clause + +# XXX defining CC and cross-compiling confuses OpenSSL's build. +unset CC + +sudo mkdir /fakeroot +sudo chmod 755 /fakeroot + +cat << EOF > /tmp/mingw.cmake +SET(CMAKE_SYSTEM_NAME Windows) +SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc) +SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++) +SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres) +SET(CMAKE_FIND_ROOT_PATH /fakeroot) +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +EOF + +# Build and install libcbor. +git clone --depth=1 https://github.com/pjk/libcbor -b v0.10.1 +cd libcbor +mkdir build +(cd build && cmake -DCMAKE_TOOLCHAIN_FILE=/tmp/mingw.cmake \ + -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=/fakeroot ..) +make -j"$(nproc)" -C build +sudo make -C build install +cd .. + +# Build and install OpenSSL 3.0.11. +git clone --branch openssl-3.0.12 \ + --depth=1 https://github.com/openssl/openssl +cd openssl +./Configure mingw --prefix=/fakeroot --openssldir=/fakeroot/openssl \ + --cross-compile-prefix=i686-w64-mingw32- --libdir=lib +make -j"$(nproc)" +sudo make install_sw +cd .. + +# Build and install zlib. +git clone --depth=1 https://github.com/madler/zlib -b v1.3 +cd zlib +make -fwin32/Makefile.gcc PREFIX=i686-w64-mingw32- +sudo make -fwin32/Makefile.gcc PREFIX=i686-w64-mingw32- DESTDIR=/fakeroot \ + INCLUDE_PATH=/include LIBRARY_PATH=/lib BINARY_PATH=/bin install +cd .. + +# Build and install libfido2. +export PKG_CONFIG_PATH=/fakeroot/lib/pkgconfig +mkdir build +(cd build && cmake -DCMAKE_TOOLCHAIN_FILE=/tmp/mingw.cmake \ + -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/fakeroot ..) +make -C build 2>&1 +sudo make -C build install diff --git a/contrib/libfido2/.actions/build-osx-clang b/contrib/libfido2/.actions/build-osx-clang new file mode 100755 index 000000000000..b4beea221315 --- /dev/null +++ b/contrib/libfido2/.actions/build-osx-clang @@ -0,0 +1,19 @@ +#!/bin/sh -eux + +# 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. +# SPDX-License-Identifier: BSD-2-Clause + +export PKG_CONFIG_PATH="$(brew --prefix openssl@3.0)/lib/pkgconfig" +SCAN="$(brew --prefix llvm)/bin/scan-build" + +# Build, analyze, and install libfido2. +for T in Debug Release; do + mkdir build-$T + (cd build-$T && ${SCAN} cmake -DCMAKE_BUILD_TYPE=$T ..) + ${SCAN} --status-bugs make -j"$(sysctl -n hw.ncpu)" -C build-$T + make -C build-$T man_symlink_html + make -C build-$T regress + sudo make -C build-$T install +done diff --git a/contrib/libfido2/.actions/fuzz-linux b/contrib/libfido2/.actions/fuzz-linux new file mode 100755 index 000000000000..3f57ac40ff4b --- /dev/null +++ b/contrib/libfido2/.actions/fuzz-linux @@ -0,0 +1,93 @@ +#!/bin/sh -eux + +# Copyright (c) 2020-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. +# SPDX-License-Identifier: BSD-2-Clause + +LIBCBOR_URL="https://github.com/pjk/libcbor" +LIBCBOR_TAG="v0.10.2" +LIBCBOR_ASAN="address alignment bounds" +LIBCBOR_MSAN="memory" +OPENSSL_URL="https://github.com/openssl/openssl" +OPENSSL_TAG="openssl-3.0.12" +ZLIB_URL="https://github.com/madler/zlib" +ZLIB_TAG="v1.3" +ZLIB_ASAN="address alignment bounds undefined" +ZLIB_MSAN="memory" +FIDO2_ASAN="address bounds fuzzer-no-link implicit-conversion leak" +FIDO2_ASAN="${FIDO2_ASAN} pointer-compare pointer-subtract undefined" +FIDO2_MSAN="fuzzer-no-link memory" +COMMON_CFLAGS="-g2 -fno-omit-frame-pointer" +COMMON_CFLAGS="${COMMON_CFLAGS} -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" +UBSAN_OPTIONS="halt_on_error=1:print_stacktrace=1:strict_string_checks=1" +ASAN_OPTIONS="${UBSAN_OPTIONS}:detect_invalid_pointer_pairs=2:detect_leaks=1" +MSAN_OPTIONS="${UBSAN_OPTIONS}" + +case "$1" in +asan) + LIBCBOR_CFLAGS="-fsanitize=$(echo "${LIBCBOR_ASAN}" | tr ' ' ',')" + ZLIB_CFLAGS="-fsanitize=$(echo "${ZLIB_ASAN}" | tr ' ' ',')" + FIDO2_CFLAGS="-fsanitize=$(echo "${FIDO2_ASAN}" | tr ' ' ',')" + FIDO2_CFLAGS="${FIDO2_CFLAGS} -fsanitize-address-use-after-scope" + ;; +msan) + LIBCBOR_CFLAGS="-fsanitize=$(echo "${LIBCBOR_MSAN}" | tr ' ' ',')" + ZLIB_CFLAGS="-fsanitize=$(echo "${ZLIB_MSAN}" | tr ' ' ',')" + FIDO2_CFLAGS="-fsanitize=$(echo "${FIDO2_MSAN}" | tr ' ' ',')" + FIDO2_CFLAGS="${FIDO2_CFLAGS} -fsanitize-memory-track-origins" + ;; +*) + echo "unknown sanitiser \"$1\"" 1>&2 && exit 1 +esac + +${CC} --version +WORKDIR="${WORKDIR:-$(pwd)}" +FAKEROOT="${FAKEROOT:-$(mktemp -d)}" +cd "${FAKEROOT}" + +# libcbor +git clone --depth=1 "${LIBCBOR_URL}" -b "${LIBCBOR_TAG}" +cd libcbor +patch -p0 -s < "${WORKDIR}/fuzz/README" +mkdir build +(cd build && cmake -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_C_FLAGS_DEBUG="${LIBCBOR_CFLAGS} ${COMMON_CFLAGS}" \ + -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_INSTALL_PREFIX="${FAKEROOT}" \ + -DSANITIZE=OFF ..) +make VERBOSE=1 -j"$(nproc)" -C build all install +cd - + +# openssl +git clone --depth=1 "${OPENSSL_URL}" -b "${OPENSSL_TAG}" +cd openssl +./Configure linux-x86_64-clang "enable-$1" --prefix="${FAKEROOT}" \ + --openssldir="${FAKEROOT}/openssl" --libdir=lib +make install_sw +cd - + +# zlib +git clone --depth=1 "${ZLIB_URL}" -b "${ZLIB_TAG}" +cd zlib +CFLAGS="${ZLIB_CFLAGS}" LDFLAGS="${ZLIB_CFLAGS}" ./configure \ + --prefix="${FAKEROOT}" +make install +cd - + +# libfido2 +mkdir build +export PKG_CONFIG_PATH="${FAKEROOT}/lib/pkgconfig" +(cd build && cmake -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_C_FLAGS_DEBUG="${FIDO2_CFLAGS} ${COMMON_CFLAGS}" -DFUZZ=ON \ + -DFUZZ_LDFLAGS="-fsanitize=fuzzer" "${WORKDIR}") +make -j"$(nproc)" -C build + +# fuzz +mkdir corpus +curl -s https://storage.googleapis.com/yubico-libfido2/corpus.tgz | + tar -C corpus -zxf - +export UBSAN_OPTIONS ASAN_OPTIONS MSAN_OPTIONS +for f in assert bio cred credman hid largeblob mgmt netlink pcsc; do + build/fuzz/fuzz_${f} -use_value_profile=1 -reload=30 -print_pcs=1 \ + -print_funcs=30 -timeout=10 -runs=1 corpus/fuzz_${f} +done diff --git a/contrib/libfido2/.actions/llvm.gpg b/contrib/libfido2/.actions/llvm.gpg new file mode 100644 index 000000000000..aa6b105aa3d7 --- /dev/null +++ b/contrib/libfido2/.actions/llvm.gpg @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.12 (GNU/Linux) + +mQINBFE9lCwBEADi0WUAApM/mgHJRU8lVkkw0CHsZNpqaQDNaHefD6Rw3S4LxNmM +EZaOTkhP200XZM8lVdbfUW9xSjA3oPldc1HG26NjbqqCmWpdo2fb+r7VmU2dq3NM +R18ZlKixiLDE6OUfaXWKamZsXb6ITTYmgTO6orQWYrnW6ckYHSeaAkW0wkDAryl2 +B5v8aoFnQ1rFiVEMo4NGzw4UX+MelF7rxaaregmKVTPiqCOSPJ1McC1dHFN533FY +Wh/RVLKWo6npu+owtwYFQW+zyQhKzSIMvNujFRzhIxzxR9Gn87MoLAyfgKEzrbbT +DhqqNXTxS4UMUKCQaO93TzetX/EBrRpJj+vP640yio80h4Dr5pAd7+LnKwgpTDk1 +G88bBXJAcPZnTSKu9I2c6KY4iRNbvRz4i+ZdwwZtdW4nSdl2792L7Sl7Nc44uLL/ +ZqkKDXEBF6lsX5XpABwyK89S/SbHOytXv9o4puv+65Ac5/UShspQTMSKGZgvDauU +cs8kE1U9dPOqVNCYq9Nfwinkf6RxV1k1+gwtclxQuY7UpKXP0hNAXjAiA5KS5Crq +7aaJg9q2F4bub0mNU6n7UI6vXguF2n4SEtzPRk6RP+4TiT3bZUsmr+1ktogyOJCc +Ha8G5VdL+NBIYQthOcieYCBnTeIH7D3Sp6FYQTYtVbKFzmMK+36ERreL/wARAQAB +tD1TeWx2ZXN0cmUgTGVkcnUgLSBEZWJpYW4gTExWTSBwYWNrYWdlcyA8c3lsdmVz +dHJlQGRlYmlhbi5vcmc+iQI4BBMBAgAiBQJRPZQsAhsDBgsJCAcDAgYVCAIJCgsE +FgIDAQIeAQIXgAAKCRAVz00Yr090Ibx+EADArS/hvkDF8juWMXxh17CgR0WZlHCC +9CTBWkg5a0bNN/3bb97cPQt/vIKWjQtkQpav6/5JTVCSx2riL4FHYhH0iuo4iAPR +udC7Cvg8g7bSPrKO6tenQZNvQm+tUmBHgFiMBJi92AjZ/Qn1Shg7p9ITivFxpLyX +wpmnF1OKyI2Kof2rm4BFwfSWuf8Fvh7kDMRLHv+MlnK/7j/BNpKdozXxLcwoFBmn +l0WjpAH3OFF7Pvm1LJdf1DjWKH0Dc3sc6zxtmBR/KHHg6kK4BGQNnFKujcP7TVdv +gMYv84kun14pnwjZcqOtN3UJtcx22880DOQzinoMs3Q4w4o05oIF+sSgHViFpc3W +R0v+RllnH05vKZo+LDzc83DQVrdwliV12eHxrMQ8UYg88zCbF/cHHnlzZWAJgftg +hB08v1BKPgYRUzwJ6VdVqXYcZWEaUJmQAPuAALyZESw94hSo28FAn0/gzEc5uOYx +K+xG/lFwgAGYNb3uGM5m0P6LVTfdg6vDwwOeTNIExVk3KVFXeSQef2ZMkhwA7wya +KJptkb62wBHFE+o9TUdtMCY6qONxMMdwioRE5BYNwAsS1PnRD2+jtlI0DzvKHt7B +MWd8hnoUKhMeZ9TNmo+8CpsAtXZcBho0zPGz/R8NlJhAWpdAZ1CmcPo83EW86Yq7 +BxQUKnNHcwj2ebkCDQRRPZQsARAA4jxYmbTHwmMjqSizlMJYNuGOpIidEdx9zQ5g +zOr431/VfWq4S+VhMDhs15j9lyml0y4ok215VRFwrAREDg6UPMr7ajLmBQGau0Fc +bvZJ90l4NjXp5p0NEE/qOb9UEHT7EGkEhaZ1ekkWFTWCgsy7rRXfZLxB6sk7pzLC +DshyW3zjIakWAnpQ5j5obiDy708pReAuGB94NSyb1HoW/xGsGgvvCw4r0w3xPStw +F1PhmScE6NTBIfLliea3pl8vhKPlCh54Hk7I8QGjo1ETlRP4Qll1ZxHJ8u25f/ta +RES2Aw8Hi7j0EVcZ6MT9JWTI83yUcnUlZPZS2HyeWcUj+8nUC8W4N8An+aNps9l/ +21inIl2TbGo3Yn1JQLnA1YCoGwC34g8QZTJhElEQBN0X29ayWW6OdFx8MDvllbBV +ymmKq2lK1U55mQTfDli7S3vfGz9Gp/oQwZ8bQpOeUkc5hbZszYwP4RX+68xDPfn+ +M9udl+qW9wu+LyePbW6HX90LmkhNkkY2ZzUPRPDHZANU5btaPXc2H7edX4y4maQa +xenqD0lGh9LGz/mps4HEZtCI5CY8o0uCMF3lT0XfXhuLksr7Pxv57yue8LLTItOJ +d9Hmzp9G97SRYYeqU+8lyNXtU2PdrLLq7QHkzrsloG78lCpQcalHGACJzrlUWVP/ +fN3Ht3kAEQEAAYkCHwQYAQIACQUCUT2ULAIbDAAKCRAVz00Yr090IbhWEADbr50X +OEXMIMGRLe+YMjeMX9NG4jxs0jZaWHc/WrGR+CCSUb9r6aPXeLo+45949uEfdSsB +pbaEdNWxF5Vr1CSjuO5siIlgDjmT655voXo67xVpEN4HhMrxugDJfCa6z97P0+ML +PdDxim57uNqkam9XIq9hKQaurxMAECDPmlEXI4QT3eu5qw5/knMzDMZj4Vi6hovL +wvvAeLHO/jsyfIdNmhBGU2RWCEZ9uo/MeerPHtRPfg74g+9PPfP6nyHD2Wes6yGd +oVQwtPNAQD6Cj7EaA2xdZYLJ7/jW6yiPu98FFWP74FN2dlyEA2uVziLsfBrgpS4l +tVOlrO2YzkkqUGrybzbLpj6eeHx+Cd7wcjI8CalsqtL6cG8cUEjtWQUHyTbQWAgG +5VPEgIAVhJ6RTZ26i/G+4J8neKyRs4vz+57UGwY6zI4AB1ZcWGEE3Bf+CDEDgmnP +LSwbnHefK9IljT9XU98PelSryUO/5UPw7leE0akXKB4DtekToO226px1VnGp3Bov +1GBGvpHvL2WizEwdk+nfk8LtrLzej+9FtIcq3uIrYnsac47Pf7p0otcFeTJTjSq3 +krCaoG4Hx0zGQG2ZFpHrSrZTVy6lxvIdfi0beMgY6h78p6M9eYZHQHc02DjFkQXN +bXb5c6gCHESH5PXwPU4jQEE7Ib9J6sbk7ZT2Mw== +=j+4q +-----END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/libfido2/.actions/setup_clang b/contrib/libfido2/.actions/setup_clang new file mode 100755 index 000000000000..be06709c88b6 --- /dev/null +++ b/contrib/libfido2/.actions/setup_clang @@ -0,0 +1,17 @@ +#!/bin/sh -eu + +# 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. +# SPDX-License-Identifier: BSD-2-Clause + +CC="$1" +APT="http://apt.llvm.org" +CODENAME="$(lsb_release -cs)" +VERSION="${CC#*-}" +apt-get install -q -y software-properties-common +apt-key add ./.actions/llvm.gpg +add-apt-repository \ + "deb ${APT}/${CODENAME}/ llvm-toolchain-${CODENAME}-${VERSION} main" +apt-get update -q +apt-get install -q -y "${CC}" "clang-tools-${VERSION}" diff --git a/contrib/libfido2/.gitattributes b/contrib/libfido2/.gitattributes new file mode 100644 index 000000000000..998f601da4d0 --- /dev/null +++ b/contrib/libfido2/.gitattributes @@ -0,0 +1 @@ +.* export-ignore diff --git a/contrib/libfido2/.github/ISSUE_TEMPLATE/bug_report.md b/contrib/libfido2/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000000..6e88c1ff8006 --- /dev/null +++ b/contrib/libfido2/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,80 @@ +--- +name: Bug report +labels: 'bug report' +about: Report a bug in libfido2 + +--- + + + +**What version of libfido2 are you using?** + +**What operating system are you running?** + +**What application are you using in conjunction with libfido2?** + +**How does the problem manifest itself?** + +**Is the problem reproducible?** + +**What are the steps that lead to the problem?** + +**Does the problem happen with different authenticators?** + + + +**Please include the output of `fido2-token -L`.** + +
+fido2-token -L +
+
+$ fido2-token -L
+
+
+
+ +**Please include the output of `fido2-token -I`.** + +
+fido2-token -I +
+
+$ fido2-token -I <device>
+
+
+
+ + + +**Please include the output of `FIDO_DEBUG=1`.** + +
+FIDO_DEBUG=1 +
+
+$ export FIDO_DEBUG=1
+$ <command1>
+$ <command2>
+(...)
+$ <commandn>
+
+
+
diff --git a/contrib/libfido2/.github/ISSUE_TEMPLATE/config.yml b/contrib/libfido2/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000000..3ecb227ffeb0 --- /dev/null +++ b/contrib/libfido2/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Feature Request + url: https://github.com/Yubico/libfido2/discussions/new + about: Share ideas for new features + - name: Ask a question about libfido2 + url: https://github.com/Yubico/libfido2/discussions/new + about: Ask the community for help diff --git a/contrib/libfido2/.github/workflows/alpine_builds.yml b/contrib/libfido2/.github/workflows/alpine_builds.yml new file mode 100644 index 000000000000..c6d826f39835 --- /dev/null +++ b/contrib/libfido2/.github/workflows/alpine_builds.yml @@ -0,0 +1,39 @@ +# Copyright (c) 2022-2023 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. +# SPDX-License-Identifier: BSD-2-Clause + +name: alpine + +on: + pull_request: + branches: + - main + push: + branches: + - main + - '*-ci' + +jobs: + build: + runs-on: ubuntu-20.04 + container: alpine:latest + strategy: + fail-fast: false + matrix: + cc: [ gcc, clang ] + steps: + - name: dependencies + run: | + apk -q update + apk add build-base clang clang-analyzer cmake coreutils eudev-dev + apk add git linux-headers openssl-dev sudo zlib-dev pcsc-lite-dev \ + libcbor-dev + - name: fix permissions on workdir + run: chown root:wheel "${GITHUB_WORKSPACE}" + - name: checkout libfido2 + uses: actions/checkout@v4 + - name: build libfido2 + env: + CC: ${{ matrix.cc }} + run: ./.actions/build-linux-${CC} diff --git a/contrib/libfido2/.github/workflows/bsd_builds.yml b/contrib/libfido2/.github/workflows/bsd_builds.yml new file mode 100644 index 000000000000..366ea2141aca --- /dev/null +++ b/contrib/libfido2/.github/workflows/bsd_builds.yml @@ -0,0 +1,32 @@ +# 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. +# SPDX-License-Identifier: BSD-2-Clause + +name: bsd + +on: + push: + branches: + - main + - '*-ci' + +jobs: + build: + if: github.repository == 'Yubico/libfido2' + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + image: [freebsd/13.x, openbsd/7.2] + steps: + - uses: actions/checkout@v4 + - name: dependencies + run: | + sudo apt -q update + sudo apt install -q -y curl jq + - name: build + env: + IMAGE: ${{ matrix.image }} + SOURCEHUT_TOKEN: ${{ secrets.SOURCEHUT_TOKEN }} + run: ./.actions/build-bsd diff --git a/contrib/libfido2/.github/workflows/cifuzz_oss.yml b/contrib/libfido2/.github/workflows/cifuzz_oss.yml new file mode 100644 index 000000000000..556d5ad36f7c --- /dev/null +++ b/contrib/libfido2/.github/workflows/cifuzz_oss.yml @@ -0,0 +1,46 @@ +# 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. +# SPDX-License-Identifier: BSD-2-Clause + +name: cifuzz + +on: + pull_request: + branches: + - main + push: + branches: + - main + - '*-ci' + +jobs: + fuzzing: + if: github.repository == 'Yubico/libfido2' + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + sanitizer: [address, undefined, memory] + steps: + - name: build fuzzers (${{ matrix.sanitizer }}) + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'libfido2' + language: c + sanitizer: ${{ matrix.sanitizer }} + dry-run: false + - name: run fuzzers (${{ matrix.sanitizer }}) + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'libfido2' + language: c + sanitizer: ${{ matrix.sanitizer }} + fuzz-seconds: 600 + dry-run: false + - name: upload crash + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.sanitizer }}-artifacts + path: ./out/artifacts diff --git a/contrib/libfido2/.github/workflows/codeql-analysis.yml b/contrib/libfido2/.github/workflows/codeql-analysis.yml new file mode 100644 index 000000000000..a3a8d54d2daa --- /dev/null +++ b/contrib/libfido2/.github/workflows/codeql-analysis.yml @@ -0,0 +1,42 @@ +# 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. +# SPDX-License-Identifier: BSD-2-Clause + +name: "codeql" + +on: + pull_request: + branches: + - main + push: + branches: + - main + - '*-ci' + schedule: + - cron: '0 0 * * 0' + +permissions: + security-events: write + +jobs: + codeql-build: + if: github.repository == 'Yubico/libfido2' + runs-on: ubuntu-22.04 + steps: + - name: checkout + uses: actions/checkout@v4 + with: + fetch-depth: 2 + - name: init codeql + uses: github/codeql-action/init@v2 + - name: build + env: + CC: gcc + run: | + sudo apt -q update + sudo apt install -q -y libcbor-dev libudev-dev libz-dev original-awk \ + libpcsclite-dev + ./.actions/build-linux-gcc + - name: perform codeql analysis + uses: github/codeql-action/analyze@v2 diff --git a/contrib/libfido2/.github/workflows/cygwin_builds.yml b/contrib/libfido2/.github/workflows/cygwin_builds.yml new file mode 100644 index 000000000000..d8146c54904e --- /dev/null +++ b/contrib/libfido2/.github/workflows/cygwin_builds.yml @@ -0,0 +1,30 @@ +# 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. +# SPDX-License-Identifier: BSD-2-Clause + +name: cygwin + +on: + pull_request: + branches: + - main + push: + branches: + - main + - '*-ci' + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ windows-2022 ] + arch: [ x64 ] + config: [ "Debug", "Release" ] + steps: + - uses: actions/checkout@v4 + - name: build + run: | + .\windows\cygwin.ps1 -Config ${{ matrix.config }} diff --git a/contrib/libfido2/.github/workflows/linux_builds.yml b/contrib/libfido2/.github/workflows/linux_builds.yml new file mode 100644 index 000000000000..ec911cb92d92 --- /dev/null +++ b/contrib/libfido2/.github/workflows/linux_builds.yml @@ -0,0 +1,57 @@ +# 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. +# SPDX-License-Identifier: BSD-2-Clause + +name: linux + +on: + pull_request: + branches: + - main + push: + branches: + - main + - '*-ci' + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - { os: ubuntu-20.04, cc: gcc-8 } + - { os: ubuntu-22.04, cc: gcc-9 } + - { os: ubuntu-22.04, cc: gcc-10 } + - { os: ubuntu-22.04, cc: gcc-11 } + - { os: ubuntu-22.04, cc: gcc-12 } + - { os: ubuntu-22.04, cc: clang-13 } + - { os: ubuntu-22.04, cc: clang-14 } + - { os: ubuntu-22.04, cc: clang-15 } + - { os: ubuntu-22.04, cc: clang-16 } + - { os: ubuntu-20.04, cc: i686-w64-mingw32-gcc-9 } + - { os: ubuntu-22.04, cc: i686-w64-mingw32-gcc-10 } + steps: + - uses: actions/checkout@v4 + - name: dependencies + run: | + sudo apt -q update + sudo apt install -q -y libcbor-dev libudev-dev libz-dev \ + original-awk mandoc libpcsclite-dev + - name: compiler + env: + CC: ${{ matrix.cc }} + run: | + if [ "${CC%-*}" == "clang" ]; then + sudo ./.actions/setup_clang "${CC}" + elif [ "${CC%-*}" == "i686-w64-mingw32-gcc" ]; then + sudo apt install -q -y binutils-mingw-w64-i686 gcc-mingw-w64 \ + g++-mingw-w64 mingw-w64-i686-dev + else + sudo apt install -q -y "${CC}" + fi + - name: build + env: + CC: ${{ matrix.cc }} + run: ./.actions/build-linux-${CC%-*} diff --git a/contrib/libfido2/.github/workflows/linux_fuzz.yml b/contrib/libfido2/.github/workflows/linux_fuzz.yml new file mode 100644 index 000000000000..296c0d9fab23 --- /dev/null +++ b/contrib/libfido2/.github/workflows/linux_fuzz.yml @@ -0,0 +1,41 @@ +# 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. +# SPDX-License-Identifier: BSD-2-Clause + +name: fuzzer + +on: + pull_request: + branches: + - main + push: + branches: + - main + - '*-ci' + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ ubuntu-22.04 ] + cc: [ clang-16 ] + sanitizer: [ asan, msan ] + steps: + - uses: actions/checkout@v4 + - name: dependencies + run: | + sudo apt -q update + sudo apt install -q -y libudev-dev libpcsclite-dev + - name: compiler + env: + CC: ${{ matrix.cc }} + run: | + sudo ./.actions/setup_clang "${CC}" + - name: fuzz + env: + CC: ${{ matrix.cc }} + SANITIZER: ${{ matrix.sanitizer }} + run: ./.actions/fuzz-linux "${SANITIZER}" diff --git a/contrib/libfido2/.github/workflows/macos_builds.yml b/contrib/libfido2/.github/workflows/macos_builds.yml new file mode 100644 index 000000000000..7d84a750ac37 --- /dev/null +++ b/contrib/libfido2/.github/workflows/macos_builds.yml @@ -0,0 +1,32 @@ +# 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. +# SPDX-License-Identifier: BSD-2-Clause + +name: macos + +on: + pull_request: + branches: + - main + push: + branches: + - main + - '*-ci' + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ macos-13, macos-12 ] + cc: [ clang ] + steps: + - uses: actions/checkout@v4 + - name: dependencies + run: brew install libcbor llvm mandoc openssl@3.0 pkg-config zlib + - name: build + env: + CC: ${{ matrix.cc }} + run: ./.actions/build-osx-clang diff --git a/contrib/libfido2/.github/workflows/openssl3.yml b/contrib/libfido2/.github/workflows/openssl3.yml new file mode 100644 index 000000000000..ee70c087d285 --- /dev/null +++ b/contrib/libfido2/.github/workflows/openssl3.yml @@ -0,0 +1,51 @@ +# 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. +# SPDX-License-Identifier: BSD-2-Clause + +name: openssl3 + +on: + pull_request: + branches: + - main + push: + branches: + - main + - '*-ci' + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-22.04 + cc: gcc-11 + - os: ubuntu-22.04 + cc: clang-16 + - os: ubuntu-22.04 + cc: i686-w64-mingw32-gcc-10 + steps: + - uses: actions/checkout@v4 + - name: dependencies + env: + CC: ${{ matrix.cc }} + run: | + sudo apt -q update + sudo apt install -q -y libcbor-dev libudev-dev libz-dev \ + original-awk mandoc libpcsclite-dev + sudo apt remove -y libssl-dev + if [ "${CC%-*}" == "clang" ]; then + sudo ./.actions/setup_clang "${CC}" + elif [ "${CC%-*}" == "i686-w64-mingw32-gcc" ]; then + sudo apt install -q -y binutils-mingw-w64-i686 gcc-mingw-w64 \ + g++-mingw-w64 mingw-w64-i686-dev + else + sudo apt install -q -y "${CC}" + fi + - name: build + env: + CC: ${{ matrix.cc }} + run: ./.actions/build-linux-openssl3-${CC%-*} diff --git a/contrib/libfido2/.github/workflows/windows_builds.yml b/contrib/libfido2/.github/workflows/windows_builds.yml new file mode 100644 index 000000000000..bfc1eb3c1deb --- /dev/null +++ b/contrib/libfido2/.github/workflows/windows_builds.yml @@ -0,0 +1,32 @@ +# 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. +# SPDX-License-Identifier: BSD-2-Clause + +name: windows + +on: + pull_request: + branches: + - main + push: + branches: + - main + - '*-ci' + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ windows-2022 ] + arch: [ x64, Win32, ARM64, ARM ] + type: [ dynamic, static ] + config: [ "Release" ] + steps: + - uses: actions/checkout@v4 + - name: build + run: | + .\windows\build.ps1 -Fido2Flags '/analyze' -Arch ${{ matrix.arch }} ` + -Type ${{ matrix.type }} -Config ${{ matrix.config }} diff --git a/contrib/libfido2/.gitignore b/contrib/libfido2/.gitignore new file mode 100644 index 000000000000..0915625a059c --- /dev/null +++ b/contrib/libfido2/.gitignore @@ -0,0 +1,9 @@ +build/ +cscope.out +fuzz/build/ +fuzz/corpus.tgz- +fuzz/fuzz_*/ +fuzz/obj/ +fuzz/report +fuzz/*.so +output/ diff --git a/contrib/libfido2/CMakeLists.txt b/contrib/libfido2/CMakeLists.txt index 6fa341a01cc6..c4f7b1b7b51e 100644 --- a/contrib/libfido2/CMakeLists.txt +++ b/contrib/libfido2/CMakeLists.txt @@ -1,498 +1,498 @@ # Copyright (c) 2018-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. # SPDX-License-Identifier: BSD-2-Clause +cmake_minimum_required(VERSION 3.7) # detect AppleClang; needs to come before project() cmake_policy(SET CMP0025 NEW) project(libfido2 C) -cmake_minimum_required(VERSION 3.0) # Set PIE flags for POSITION_INDEPENDENT_CODE targets, added in CMake 3.14. if(POLICY CMP0083) cmake_policy(SET CMP0083 NEW) endif() include(CheckCCompilerFlag) include(CheckFunctionExists) include(CheckLibraryExists) include(CheckSymbolExists) include(CheckIncludeFiles) include(CheckTypeSize) include(GNUInstallDirs) include(CheckPIESupported OPTIONAL RESULT_VARIABLE CHECK_PIE_SUPPORTED) if(CHECK_PIE_SUPPORTED) check_pie_supported(LANGUAGES C) endif() set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_COLOR_MAKEFILE OFF) set(CMAKE_VERBOSE_MAKEFILE ON) set(FIDO_MAJOR "1") -set(FIDO_MINOR "13") +set(FIDO_MINOR "14") set(FIDO_PATCH "0") set(FIDO_VERSION ${FIDO_MAJOR}.${FIDO_MINOR}.${FIDO_PATCH}) option(BUILD_TESTS "Build the regress tests" ON) option(BUILD_EXAMPLES "Build example programs" ON) option(BUILD_MANPAGES "Build man pages" ON) option(BUILD_SHARED_LIBS "Build a shared library" ON) option(BUILD_STATIC_LIBS "Build a static library" ON) option(BUILD_TOOLS "Build tool programs" ON) option(FUZZ "Enable fuzzing instrumentation" OFF) option(USE_HIDAPI "Use hidapi as the HID backend" OFF) option(USE_PCSC "Enable experimental PCSC support" 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(BUILD_SHARED_LIBS) set(_FIDO2_LIBRARY fido2_shared) elseif(BUILD_STATIC_LIBS) set(_FIDO2_LIBRARY fido2) else() message(FATAL_ERROR "Nothing to build (BUILD_*_LIBS=OFF)") endif() if(CYGWIN OR MSYS OR MINGW) set(WIN32 1) endif() if(WIN32) add_definitions(-DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=0x0600) endif() if(APPLE) set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") endif() if(NOT MSVC) set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_POSIX_C_SOURCE=200809L") set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_BSD_SOURCE") if(APPLE) set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_DARWIN_C_SOURCE") set(FIDO_CFLAGS "${FIDO_CFLAGS} -D__STDC_WANT_LIB_EXT1__=1") elseif((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR MINGW OR CYGWIN) set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_GNU_SOURCE") set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_DEFAULT_SOURCE") elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "MidnightBSD") set(FIDO_CFLAGS "${FIDO_CFLAGS} -D__BSD_VISIBLE=1") elseif(CMAKE_SYSTEM_NAME STREQUAL "NetBSD") set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_NETBSD_SOURCE") endif() set(FIDO_CFLAGS "${FIDO_CFLAGS} -std=c99") set(CMAKE_C_FLAGS "${FIDO_CFLAGS} ${CMAKE_C_FLAGS}") endif() check_c_compiler_flag("-Wshorten-64-to-32" HAVE_SHORTEN_64_TO_32) check_c_compiler_flag("-Werror -fstack-protector-all" HAVE_STACK_PROTECTOR_ALL) check_include_files(cbor.h HAVE_CBOR_H) check_include_files(endian.h HAVE_ENDIAN_H) check_include_files(err.h HAVE_ERR_H) check_include_files(openssl/opensslv.h HAVE_OPENSSLV_H) check_include_files(signal.h HAVE_SIGNAL_H) check_include_files(sys/random.h HAVE_SYS_RANDOM_H) check_include_files(unistd.h HAVE_UNISTD_H) check_symbol_exists(arc4random_buf stdlib.h HAVE_ARC4RANDOM_BUF) check_symbol_exists(asprintf stdio.h HAVE_ASPRINTF) check_symbol_exists(clock_gettime time.h HAVE_CLOCK_GETTIME) check_symbol_exists(explicit_bzero string.h HAVE_EXPLICIT_BZERO) check_symbol_exists(freezero stdlib.h HAVE_FREEZERO) check_symbol_exists(getline stdio.h HAVE_GETLINE) check_symbol_exists(getopt unistd.h HAVE_GETOPT) check_symbol_exists(getpagesize unistd.h HAVE_GETPAGESIZE) check_symbol_exists(getrandom sys/random.h HAVE_GETRANDOM) check_symbol_exists(memset_s string.h HAVE_MEMSET_S) check_symbol_exists(readpassphrase readpassphrase.h HAVE_READPASSPHRASE) check_symbol_exists(recallocarray stdlib.h HAVE_RECALLOCARRAY) check_symbol_exists(strlcat string.h HAVE_STRLCAT) check_symbol_exists(strlcpy string.h HAVE_STRLCPY) check_symbol_exists(strsep string.h HAVE_STRSEP) check_symbol_exists(sysconf unistd.h HAVE_SYSCONF) check_symbol_exists(timespecsub sys/time.h HAVE_TIMESPECSUB) check_symbol_exists(timingsafe_bcmp string.h HAVE_TIMINGSAFE_BCMP) set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) try_compile(HAVE_POSIX_IOCTL "${CMAKE_CURRENT_BINARY_DIR}/posix_ioctl_check.o" "${CMAKE_CURRENT_SOURCE_DIR}/openbsd-compat/posix_ioctl_check.c" COMPILE_DEFINITIONS "-Werror -Woverflow -Wsign-conversion") list(APPEND CHECK_VARIABLES HAVE_ARC4RANDOM_BUF HAVE_ASPRINTF HAVE_CBOR_H HAVE_CLOCK_GETTIME HAVE_ENDIAN_H HAVE_ERR_H HAVE_FREEZERO HAVE_GETLINE HAVE_GETOPT HAVE_GETPAGESIZE HAVE_GETRANDOM HAVE_MEMSET_S HAVE_OPENSSLV_H HAVE_POSIX_IOCTL HAVE_READPASSPHRASE HAVE_RECALLOCARRAY HAVE_SIGNAL_H HAVE_STRLCAT HAVE_STRLCPY HAVE_STRSEP HAVE_SYSCONF HAVE_SYS_RANDOM_H HAVE_TIMESPECSUB HAVE_TIMINGSAFE_BCMP HAVE_UNISTD_H ) foreach(v ${CHECK_VARIABLES}) if (${v}) add_definitions(-D${v}) endif() endforeach() if(HAVE_EXPLICIT_BZERO AND NOT FUZZ) add_definitions(-DHAVE_EXPLICIT_BZERO) endif() if(UNIX) add_definitions(-DHAVE_DEV_URANDOM) endif() if(MSVC) if((NOT CBOR_INCLUDE_DIRS) OR (NOT CBOR_LIBRARY_DIRS) OR (NOT CRYPTO_INCLUDE_DIRS) OR (NOT CRYPTO_LIBRARY_DIRS) OR (NOT ZLIB_INCLUDE_DIRS) OR (NOT ZLIB_LIBRARY_DIRS)) message(FATAL_ERROR "please define " "{CBOR,CRYPTO,ZLIB}_{INCLUDE,LIBRARY}_DIRS when " "building under msvc") endif() if(BUILD_TESTS AND BUILD_SHARED_LIBS AND ((NOT CBOR_BIN_DIRS) OR (NOT ZLIB_BIN_DIRS) OR (NOT CRYPTO_BIN_DIRS))) message(FATAL_ERROR "please define {CBOR,CRYPTO,ZLIB}_BIN_DIRS " "when building tests") endif() if(NOT CBOR_LIBRARIES) set(CBOR_LIBRARIES cbor) endif() if(NOT ZLIB_LIBRARIES) set(ZLIB_LIBRARIES zlib1) endif() if(NOT CRYPTO_LIBRARIES) set(CRYPTO_LIBRARIES crypto) endif() set(MSVC_DISABLED_WARNINGS_LIST "C4152" # nonstandard extension used: function/data pointer # conversion in expression; "C4200" # nonstandard extension used: zero-sized array in # struct/union; "C4201" # nonstandard extension used: nameless struct/union; "C4204" # nonstandard extension used: non-constant aggregate # initializer; "C4706" # assignment within conditional expression; "C4996" # The POSIX name for this item is deprecated. Instead, # use the ISO C and C++ conformant name; "C6287" # redundant code: the left and right subexpressions are identical ) # The construction in the following 3 lines was taken from LibreSSL's # CMakeLists.txt. string(REPLACE "C" " -wd" MSVC_DISABLED_WARNINGS_STR ${MSVC_DISABLED_WARNINGS_LIST}) string(REGEX REPLACE "[/-]W[1234][ ]?" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -MP -W4 -WX ${MSVC_DISABLED_WARNINGS_STR}") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Od /Z7 /guard:cf /sdl /RTCcsu") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Zi /guard:cf /sdl") if(USE_WINHELLO) add_definitions(-DUSE_WINHELLO) endif() set(NFC_LINUX OFF) else() include(FindPkgConfig) pkg_search_module(CBOR libcbor) pkg_search_module(CRYPTO libcrypto) pkg_search_module(ZLIB zlib) if(NOT CBOR_FOUND AND NOT HAVE_CBOR_H) message(FATAL_ERROR "could not find libcbor") endif() if(NOT CRYPTO_FOUND AND NOT HAVE_OPENSSLV_H) message(FATAL_ERROR "could not find libcrypto") endif() if(NOT ZLIB_FOUND) message(FATAL_ERROR "could not find zlib") endif() if(NOT CBOR_LIBRARIES) set(CBOR_LIBRARIES "cbor") endif() if(NOT CRYPTO_LIBRARIES) set(CRYPTO_LIBRARIES "crypto") endif() if(CMAKE_SYSTEM_NAME STREQUAL "Linux") pkg_search_module(UDEV libudev REQUIRED) set(UDEV_NAME "udev") # If using hidapi, use hidapi-hidraw. set(HIDAPI_SUFFIX -hidraw) if(NOT HAVE_CLOCK_GETTIME) # Look for clock_gettime in librt. check_library_exists(rt clock_gettime "time.h" HAVE_CLOCK_GETTIME) if (HAVE_CLOCK_GETTIME) add_definitions(-DHAVE_CLOCK_GETTIME) set(BASE_LIBRARIES ${BASE_LIBRARIES} rt) endif() endif() else() set(NFC_LINUX OFF) endif() if(MINGW) # MinGW is stuck with a flavour of C89. add_definitions(-DFIDO_NO_DIAGNOSTIC) add_definitions(-DWC_ERR_INVALID_CHARS=0x80) add_compile_options(-Wno-unused-parameter) endif() if(FUZZ) set(USE_PCSC ON) add_definitions(-DFIDO_FUZZ) endif() # If building with PCSC, look for pcsc-lite. if(USE_PCSC AND NOT (APPLE OR CYGWIN OR MSYS OR MINGW)) pkg_search_module(PCSC libpcsclite REQUIRED) set(PCSC_LIBRARIES pcsclite) endif() if(USE_HIDAPI) add_definitions(-DUSE_HIDAPI) pkg_search_module(HIDAPI hidapi${HIDAPI_SUFFIX} REQUIRED) set(HIDAPI_LIBRARIES hidapi${HIDAPI_SUFFIX}) endif() if(NFC_LINUX) add_definitions(-DUSE_NFC) endif() if(WIN32) if(USE_WINHELLO) add_definitions(-DUSE_WINHELLO) endif() else() set(USE_WINHELLO OFF) endif() add_compile_options(-Wall) add_compile_options(-Wextra) add_compile_options(-Werror) add_compile_options(-Wshadow) add_compile_options(-Wcast-qual) add_compile_options(-Wwrite-strings) add_compile_options(-Wmissing-prototypes) add_compile_options(-Wbad-function-cast) add_compile_options(-Wimplicit-fallthrough) add_compile_options(-pedantic) add_compile_options(-pedantic-errors) set(EXTRA_CFLAGS "-Wconversion -Wsign-conversion") if(WIN32) add_compile_options(-Wno-type-limits) add_compile_options(-Wno-cast-function-type) endif() if(HAVE_SHORTEN_64_TO_32) add_compile_options(-Wshorten-64-to-32) endif() if(HAVE_STACK_PROTECTOR_ALL) add_compile_options(-fstack-protector-all) endif() set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g2") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -D_FORTIFY_SOURCE=2") if(CRYPTO_VERSION VERSION_GREATER_EQUAL 3.0) add_definitions(-DOPENSSL_API_COMPAT=0x10100000L) endif() if(NOT FUZZ) set(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wframe-larger-than=2047") endif() endif() # Avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 if(CMAKE_COMPILER_IS_GNUCC) add_compile_options(-Wno-unused-result) endif() # Decide which keyword to use for thread-local storage. if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang") set(TLS "__thread") elseif(WIN32) set(TLS "__declspec(thread)") endif() add_definitions(-DTLS=${TLS}) if(USE_PCSC) add_definitions(-DUSE_PCSC) endif() # export list if(APPLE AND (CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")) # clang + lld string(CONCAT CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} " -exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/src/export.llvm") elseif(NOT MSVC) # clang/gcc + gnu ld if(FUZZ) string(CONCAT CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} " -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/fuzz/export.gnu") else() string(CONCAT CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} " -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/export.gnu") endif() if(NOT WIN32) string(CONCAT CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} " -Wl,-z,noexecstack -Wl,-z,relro,-z,now") string(CONCAT CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} " -Wl,-z,noexecstack -Wl,-z,relro,-z,now") if(FUZZ) file(STRINGS fuzz/wrapped.sym WRAPPED_SYMBOLS) foreach(s ${WRAPPED_SYMBOLS}) string(CONCAT CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} " -Wl,--wrap=${s}") endforeach() endif() endif() else() string(CONCAT CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} " /def:\"${CMAKE_CURRENT_SOURCE_DIR}/src/export.msvc\"") endif() include_directories(${PROJECT_SOURCE_DIR}/src) include_directories(${CBOR_INCLUDE_DIRS}) include_directories(${CRYPTO_INCLUDE_DIRS}) include_directories(${HIDAPI_INCLUDE_DIRS}) include_directories(${PCSC_INCLUDE_DIRS}) include_directories(${UDEV_INCLUDE_DIRS}) include_directories(${ZLIB_INCLUDE_DIRS}) link_directories(${CBOR_LIBRARY_DIRS}) link_directories(${CRYPTO_LIBRARY_DIRS}) link_directories(${HIDAPI_LIBRARY_DIRS}) link_directories(${PCSC_LIBRARY_DIRS}) link_directories(${UDEV_LIBRARY_DIRS}) link_directories(${ZLIB_LIBRARY_DIRS}) message(STATUS "BASE_LIBRARIES: ${BASE_LIBRARIES}") message(STATUS "BUILD_EXAMPLES: ${BUILD_EXAMPLES}") message(STATUS "BUILD_MANPAGES: ${BUILD_MANPAGES}") message(STATUS "BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}") message(STATUS "BUILD_STATIC_LIBS: ${BUILD_STATIC_LIBS}") message(STATUS "BUILD_TOOLS: ${BUILD_TOOLS}") message(STATUS "CBOR_INCLUDE_DIRS: ${CBOR_INCLUDE_DIRS}") message(STATUS "CBOR_LIBRARIES: ${CBOR_LIBRARIES}") message(STATUS "CBOR_LIBRARY_DIRS: ${CBOR_LIBRARY_DIRS}") if(BUILD_TESTS) message(STATUS "CBOR_BIN_DIRS: ${CBOR_BIN_DIRS}") endif() message(STATUS "CBOR_VERSION: ${CBOR_VERSION}") message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}") message(STATUS "CMAKE_C_COMPILER_ID: ${CMAKE_C_COMPILER_ID}") message(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") message(STATUS "CMAKE_CROSSCOMPILING: ${CMAKE_CROSSCOMPILING}") message(STATUS "CMAKE_GENERATOR_PLATFORM: ${CMAKE_GENERATOR_PLATFORM}") message(STATUS "CMAKE_HOST_SYSTEM_NAME: ${CMAKE_HOST_SYSTEM_NAME}") message(STATUS "CMAKE_HOST_SYSTEM_PROCESSOR: ${CMAKE_HOST_SYSTEM_PROCESSOR}") message(STATUS "CMAKE_INSTALL_LIBDIR: ${CMAKE_INSTALL_LIBDIR}") message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") message(STATUS "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}") message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") message(STATUS "CMAKE_SYSTEM_VERSION: ${CMAKE_SYSTEM_VERSION}") message(STATUS "CRYPTO_INCLUDE_DIRS: ${CRYPTO_INCLUDE_DIRS}") message(STATUS "CRYPTO_LIBRARIES: ${CRYPTO_LIBRARIES}") message(STATUS "CRYPTO_LIBRARY_DIRS: ${CRYPTO_LIBRARY_DIRS}") if(BUILD_TESTS) message(STATUS "CRYPTO_BIN_DIRS: ${CRYPTO_BIN_DIRS}") endif() message(STATUS "CRYPTO_VERSION: ${CRYPTO_VERSION}") message(STATUS "FIDO_VERSION: ${FIDO_VERSION}") message(STATUS "FUZZ: ${FUZZ}") if(FUZZ) message(STATUS "FUZZ_LDFLAGS: ${FUZZ_LDFLAGS}") endif() message(STATUS "ZLIB_INCLUDE_DIRS: ${ZLIB_INCLUDE_DIRS}") message(STATUS "ZLIB_LIBRARIES: ${ZLIB_LIBRARIES}") message(STATUS "ZLIB_LIBRARY_DIRS: ${ZLIB_LIBRARY_DIRS}") if(BUILD_TESTS) message(STATUS "ZLIB_BIN_DIRS: ${ZLIB_BIN_DIRS}") endif() message(STATUS "ZLIB_VERSION: ${ZLIB_VERSION}") if(USE_HIDAPI) message(STATUS "HIDAPI_INCLUDE_DIRS: ${HIDAPI_INCLUDE_DIRS}") message(STATUS "HIDAPI_LIBRARIES: ${HIDAPI_LIBRARIES}") message(STATUS "HIDAPI_LIBRARY_DIRS: ${HIDAPI_LIBRARY_DIRS}") message(STATUS "HIDAPI_VERSION: ${HIDAPI_VERSION}") endif() message(STATUS "PCSC_INCLUDE_DIRS: ${PCSC_INCLUDE_DIRS}") message(STATUS "PCSC_LIBRARIES: ${PCSC_LIBRARIES}") message(STATUS "PCSC_LIBRARY_DIRS: ${PCSC_LIBRARY_DIRS}") message(STATUS "PCSC_VERSION: ${PCSC_VERSION}") message(STATUS "TLS: ${TLS}") message(STATUS "UDEV_INCLUDE_DIRS: ${UDEV_INCLUDE_DIRS}") message(STATUS "UDEV_LIBRARIES: ${UDEV_LIBRARIES}") message(STATUS "UDEV_LIBRARY_DIRS: ${UDEV_LIBRARY_DIRS}") message(STATUS "UDEV_RULES_DIR: ${UDEV_RULES_DIR}") message(STATUS "UDEV_VERSION: ${UDEV_VERSION}") message(STATUS "USE_HIDAPI: ${USE_HIDAPI}") message(STATUS "USE_PCSC: ${USE_PCSC}") message(STATUS "USE_WINHELLO: ${USE_WINHELLO}") message(STATUS "NFC_LINUX: ${NFC_LINUX}") if(BUILD_TESTS) enable_testing() endif() add_subdirectory(src) if(BUILD_TESTS) add_subdirectory(regress) endif() if(BUILD_EXAMPLES) add_subdirectory(examples) endif() if(BUILD_TOOLS) add_subdirectory(tools) endif() if(BUILD_MANPAGES) add_subdirectory(man) endif() if(NOT WIN32) if(FUZZ) add_subdirectory(fuzz) endif() if(CMAKE_SYSTEM_NAME STREQUAL "Linux") add_subdirectory(udev) endif() endif() diff --git a/contrib/libfido2/NEWS b/contrib/libfido2/NEWS index bf648aabfd92..58387ffd72bf 100644 --- a/contrib/libfido2/NEWS +++ b/contrib/libfido2/NEWS @@ -1,256 +1,266 @@ +* Version 1.14.0 (2023-11-13) + ** fido2-cred -M, fido2-token -G: support raw client data via -w flag. + ** winhello: support U2F AppID extension for assertions. + ** winhello: fix restrictive parsing of the hmac-secret on assertions. + ** winhello: translate NTE_USER_CANCELLED to FIDO_ERR_OPERATION_DENIED; gh#685. + ** New API calls: + ** fido_assert_authdata_raw_len; + ** fido_assert_authdata_raw_ptr; + ** fido_assert_set_winhello_appid. + * Version 1.13.0 (2023-02-20) ** Support for linking against OpenSSL on Windows; gh#668. ** New API calls: - fido_assert_empty_allow_list; - fido_cred_empty_exclude_list. ** fido2-token: fix issue when listing large blobs. ** Improved support for different fuzzing engines. * Version 1.12.0 (2022-09-22) ** Support for COSE_ES384. ** Support for hidraw(4) on FreeBSD; gh#597. ** Improved support for FIDO 2.1 authenticators. ** New API calls: - es384_pk_free; - es384_pk_from_EC_KEY; - es384_pk_from_EVP_PKEY; - es384_pk_from_ptr; - es384_pk_new; - es384_pk_to_EVP_PKEY; - fido_cbor_info_certs_len; - fido_cbor_info_certs_name_ptr; - fido_cbor_info_certs_value_ptr; - fido_cbor_info_maxrpid_minpinlen; - fido_cbor_info_minpinlen; - fido_cbor_info_new_pin_required; - fido_cbor_info_rk_remaining; - fido_cbor_info_uv_attempts; - fido_cbor_info_uv_modality. ** Documentation and reliability fixes. * Version 1.11.0 (2022-05-03) ** Experimental PCSC support; enable with -DUSE_PCSC. ** Improved OpenSSL 3.0 compatibility. ** Use RFC1951 raw deflate to compress CTAP 2.1 largeBlobs. ** winhello: advertise "uv" instead of "clientPin". ** winhello: support hmac-secret in fido_dev_get_assert(). ** New API calls: - fido_cbor_info_maxlargeblob. ** Documentation and reliability fixes. ** Separate build and regress targets. * Version 1.10.0 (2022-01-17) ** hid_osx: handle devices with paths > 511 bytes; gh#462. ** bio: fix CTAP2 canonical CBOR encoding in fido_bio_dev_enroll_*(); gh#480. ** winhello: fallback to GetTopWindow() if GetForegroundWindow() fails. ** winhello: fallback to hid_win.c if webauthn.dll isn't available. ** New API calls: - fido_dev_info_set; - fido_dev_io_handle; - fido_dev_new_with_info; - fido_dev_open_with_info. ** Cygwin and NetBSD build fixes. ** Documentation and reliability fixes. ** Support for TPM 2.0 attestation of COSE_ES256 credentials. * Version 1.9.0 (2021-10-27) ** Enabled NFC support on Linux. ** Added OpenSSL 3.0 compatibility. ** Removed OpenSSL 1.0 compatibility. ** Support for FIDO 2.1 "minPinLength" extension. ** Support for COSE_EDDSA, COSE_ES256, and COSE_RS1 attestation. ** Support for TPM 2.0 attestation. ** Support for device timeouts; see fido_dev_set_timeout(). ** New API calls: - es256_pk_from_EVP_PKEY; - fido_cred_attstmt_len; - fido_cred_attstmt_ptr; - fido_cred_pin_minlen; - fido_cred_set_attstmt; - fido_cred_set_pin_minlen; - fido_dev_set_pin_minlen_rpid; - fido_dev_set_timeout; - rs256_pk_from_EVP_PKEY. ** Reliability and portability fixes. ** Better handling of HID devices without identification strings; gh#381. ** Fixed detection of Windows's native webauthn API; gh#382. * Version 1.8.0 (2021-07-22) ** Dropped 'Requires.private' entry from pkg-config file. ** Better support for FIDO 2.1 authenticators. ** Support for Windows's native webauthn API. ** Support for attestation format 'none'. ** New API calls: - fido_assert_set_clientdata; - fido_cbor_info_algorithm_cose; - fido_cbor_info_algorithm_count; - fido_cbor_info_algorithm_type; - fido_cbor_info_transports_len; - fido_cbor_info_transports_ptr; - fido_cred_set_clientdata; - fido_cred_set_id; - fido_credman_set_dev_rk; - fido_dev_is_winhello. ** fido2-token: new -Sc option to update a resident credential. ** Documentation and reliability fixes. ** HID access serialisation on Linux. * Version 1.7.0 (2021-03-29) ** New dependency on zlib. ** Fixed musl build; gh#259. ** hid_win: detect devices with vendor or product IDs > 0x7fff; gh#264. ** Support for FIDO 2.1 authenticator configuration. ** Support for FIDO 2.1 UV token permissions. ** Support for FIDO 2.1 "credBlobs" and "largeBlobs" extensions. ** New API calls: - fido_assert_blob_len; - fido_assert_blob_ptr; - fido_assert_largeblob_key_len; - fido_assert_largeblob_key_ptr; - fido_assert_set_hmac_secret; - fido_cbor_info_maxcredbloblen; - fido_cred_largeblob_key_len; - fido_cred_largeblob_key_ptr; - fido_cred_set_blob; - fido_dev_enable_entattest; - fido_dev_force_pin_change; - fido_dev_has_uv; - fido_dev_largeblob_get; - fido_dev_largeblob_get_array; - fido_dev_largeblob_remove; - fido_dev_largeblob_set; - fido_dev_largeblob_set_array; - fido_dev_set_pin_minlen; - fido_dev_set_sigmask; - fido_dev_supports_credman; - fido_dev_supports_permissions; - fido_dev_supports_uv; - fido_dev_toggle_always_uv. ** New fido_init flag to disable fido_dev_open's U2F fallback; gh#282. ** Experimental NFC support on Linux; enable with -DNFC_LINUX. * Version 1.6.0 (2020-12-22) ** Fix OpenSSL 1.0 and Cygwin builds. ** hid_linux: fix build on 32-bit systems. ** hid_osx: allow reads from spawned threads. ** Documentation and reliability fixes. ** New API calls: - fido_cred_authdata_raw_len; - fido_cred_authdata_raw_ptr; - fido_cred_sigcount; - fido_dev_get_uv_retry_count; - fido_dev_supports_credman. ** Hardened Windows build. ** Native FreeBSD and NetBSD support. ** Use CTAP2 canonical CBOR when combining hmac-secret and credProtect. * Version 1.5.0 (2020-09-01) ** hid_linux: return FIDO_OK if no devices are found. ** hid_osx: - repair communication with U2F tokens, gh#166; - reliability fixes. ** fido2-{assert,cred}: new options to explicitly toggle UP, UV. ** Support for configurable report lengths. ** New API calls: - fido_cbor_info_maxcredcntlst; - fido_cbor_info_maxcredidlen; - fido_cred_aaguid_len; - fido_cred_aaguid_ptr; - fido_dev_get_touch_begin; - fido_dev_get_touch_status. ** Use COSE_ECDH_ES256 with CTAP_CBOR_CLIENT_PIN; gh#154. ** Allow CTAP messages up to 2048 bytes; gh#171. ** Ensure we only list USB devices by default. * Version 1.4.0 (2020-04-15) ** hid_hidapi: hidapi backend; enable with -DUSE_HIDAPI=1. ** Fall back to U2F if the key claims to, but does not support FIDO2. ** FIDO2 credential protection (credprot) support. ** New API calls: - fido_cbor_info_fwversion; - fido_cred_prot; - fido_cred_set_prot; - fido_dev_set_transport_functions; - fido_set_log_handler. ** Support for FreeBSD. ** Support for C++. ** Support for MSYS. ** Fixed EdDSA and RSA self-attestation. * Version 1.3.1 (2020-02-19) ** fix zero-ing of le1 and le2 when talking to a U2F device. ** dropping sk-libfido2 middleware, please find it in the openssh tree. * Version 1.3.0 (2019-11-28) ** assert/hmac: encode public key as per spec, gh#60. ** fido2-cred: fix creation of resident keys. ** fido2-{assert,cred}: support for hmac-secret extension. ** hid_osx: detect device removal, gh#56. ** hid_osx: fix device detection in MacOS Catalina. ** New API calls: - fido_assert_set_authdata_raw; - fido_assert_sigcount; - fido_cred_set_authdata_raw; - fido_dev_cancel. ** Middleware library for use by OpenSSH. ** Support for biometric enrollment. ** Support for OpenBSD. ** Support for self-attestation. * Version 1.2.0 (released 2019-07-26) ** Credential management support. ** New API reflecting FIDO's 3-state booleans (true, false, absent): - fido_assert_set_up; - fido_assert_set_uv; - fido_cred_set_rk; - fido_cred_set_uv. ** Command-line tools for Windows. ** Documentation and reliability fixes. ** fido_{assert,cred}_set_options() are now marked as deprecated. * Version 1.1.0 (released 2019-05-08) ** MacOS: fix IOKit crash on HID read. ** Windows: fix contents of release file. ** EdDSA (Ed25519) support. ** fido_dev_make_cred: fix order of CBOR map keys. ** fido_dev_get_assert: plug memory leak when operating on U2F devices. * Version 1.0.0 (released 2019-03-21) ** Native HID support on Linux, MacOS, and Windows. ** fido2-{assert,cred}: new -u option to force U2F on dual authenticators. ** fido2-assert: support for multiple resident keys with the same RP. ** Strict checks for CTAP2 compliance on received CBOR payloads. ** Better fuzzing harnesses. ** Documentation and reliability fixes. * Version 0.4.0 (released 2019-01-07) ** fido2-assert: print the user id for resident credentials. ** Fix encoding of COSE algorithms when making a credential. ** Rework purpose of fido_cred_set_type; no ABI change. ** Minor documentation and code fixes. * Version 0.3.0 (released 2018-09-11) ** Various reliability fixes. ** Merged fuzzing instrumentation. ** Added regress tests. ** Added support for FIDO 2's hmac-secret extension. ** New API calls: - fido_assert_hmac_secret_len; - fido_assert_hmac_secret_ptr; - fido_assert_set_extensions; - fido_assert_set_hmac_salt; - fido_cred_set_extensions; - fido_dev_force_fido2. ** Support for native builds with Microsoft Visual Studio 17. * Version 0.2.0 (released 2018-06-20) ** Added command-line tools. ** Added a couple of missing get functions. * Version 0.1.1 (released 2018-06-05) ** Added documentation. ** Added OpenSSL 1.0 support. ** Minor fixes. * Version 0.1.0 (released 2018-05-18) ** First beta release. diff --git a/contrib/libfido2/README.adoc b/contrib/libfido2/README.adoc index 44d559894dac..fb6f3d3eb004 100644 --- a/contrib/libfido2/README.adoc +++ b/contrib/libfido2/README.adoc @@ -1,144 +1,144 @@ == libfido2 image:https://github.com/yubico/libfido2/workflows/linux/badge.svg["Linux Build Status (github actions)", link="https://github.com/Yubico/libfido2/actions"] image:https://github.com/yubico/libfido2/workflows/macos/badge.svg["macOS Build Status (github actions)", link="https://github.com/Yubico/libfido2/actions"] image:https://github.com/yubico/libfido2/workflows/windows/badge.svg["Windows Build Status (github actions)", link="https://github.com/Yubico/libfido2/actions"] image:https://github.com/yubico/libfido2/workflows/fuzzer/badge.svg["Fuzz Status (github actions)", link="https://github.com/Yubico/libfido2/actions"] image:https://oss-fuzz-build-logs.storage.googleapis.com/badges/libfido2.svg["Fuzz Status (oss-fuzz)", link="https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:libfido2"] *libfido2* provides library functionality and command-line tools to communicate with a FIDO device over USB or NFC, and to verify attestation and assertion signatures. *libfido2* supports the FIDO U2F (CTAP 1) and FIDO2 (CTAP 2) protocols. For usage, see the `examples/` directory. === License *libfido2* is licensed under the BSD 2-clause license. See the LICENSE file for the full license text. === Supported Platforms *libfido2* is known to work on Linux, macOS, Windows, OpenBSD, and FreeBSD. === Documentation Documentation is available in troff and HTML formats. An https://developers.yubico.com/libfido2/Manuals/[online mirror of *libfido2*'s documentation] is also available. === Bindings * .NET: https://github.com/borrrden/Fido2Net[Fido2Net] * Go: https://github.com/keys-pub/go-libfido2[go-libfido2] * Perl: https://github.com/jacquesg/p5-FIDO-Raw[p5-FIDO-Raw] * Rust: https://github.com/PvdBerg1998/libfido2[libfido2] === Releases -The current release of *libfido2* is 1.13.0. Signed release tarballs are +The current release of *libfido2* is 1.14.0. Signed release tarballs are available at Yubico's https://developers.yubico.com/libfido2/Releases[release page]. === Dependencies *libfido2* depends on https://github.com/pjk/libcbor[libcbor], https://www.openssl.org[OpenSSL] 1.1 or newer, and https://zlib.net[zlib]. On Linux, libudev (part of https://www.freedesktop.org/wiki/Software/systemd[systemd]) is also required. === Installation ==== Fedora 35 and 34 $ sudo dnf install libfido2 libfido2-devel fido2-tools ==== Ubuntu 22.04 (Jammy) and 20.04 (Focal) $ sudo apt install libfido2-1 libfido2-dev libfido2-doc fido2-tools Alternatively, newer versions of *libfido2* are available in Yubico's PPA. Follow the instructions for Ubuntu 18.04 (Bionic) below. ==== Ubuntu 18.04 (Bionic) $ sudo apt install software-properties-common $ sudo apt-add-repository ppa:yubico/stable $ sudo apt update $ sudo apt install libfido2-1 libfido2-dev libfido2-doc fido2-tools On Linux, you may need to add a udev rule to be able to access the FIDO device. For example, the udev rule may contain the following: ---- #udev rule for allowing HID access to Yubico devices for FIDO support. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", \ MODE="0664", GROUP="plugdev", ATTRS{idVendor}=="1050" ---- ==== macOS $ brew install libfido2 ==== Windows Please consult Yubico's https://developers.yubico.com/libfido2/Releases[release page] for ARM, ARM64, Win32, and Win64 artefacts. === Building from source On UNIX-like systems: $ cmake -B build $ make -C build $ sudo make -C build install Depending on the platform, https://www.freedesktop.org/wiki/Software/pkg-config/[pkg-config] may need to be installed, or the PKG_CONFIG_PATH environment variable set. For complete, OS-specific build instructions, please refer to the `.actions/` (Linux, macOS, BSD) and `windows/` directories. === Build-time Customisation *libfido2* supports a number of CMake options. Some of the options require additional dependencies. Options that are disabled by default are not officially supported. [%autowidth.stretch] |=== |*Option* |*Description* |*Default* | BUILD_EXAMPLES | Build example programs | ON | BUILD_MANPAGES | Build man pages | ON | BUILD_SHARED_LIBS | Build a shared library | ON | BUILD_STATIC_LIBS | Build a static library | ON | BUILD_TOOLS | Build auxiliary tools | ON | FUZZ | Enable fuzzing instrumentation | OFF | NFC_LINUX | Enable netlink NFC support on Linux | ON | USE_HIDAPI | Use hidapi as the HID backend | OFF | USE_PCSC | Enable experimental PCSC support | OFF | USE_WINHELLO | Abstract Windows Hello as a FIDO device | ON |=== The USE_HIDAPI option requires https://github.com/libusb/hidapi[hidapi]. The USE_PCSC option requires https://github.com/LudovicRousseau/PCSC[pcsc-lite] on Linux. === Development Please use https://github.com/Yubico/libfido2/discussions[GitHub Discussions] to ask questions and suggest features, and https://github.com/Yubico/libfido2/pulls[GitHub pull-requests] for code contributions. === Reporting bugs Please use https://github.com/Yubico/libfido2/issues[GitHub Issues] to report bugs. To report security issues, please contact security@yubico.com. A PGP public key can be found at https://www.yubico.com/support/security-advisories/issue-rating-system/. diff --git a/contrib/libfido2/examples/README.adoc b/contrib/libfido2/examples/README.adoc index d44218c2cf87..6151b70bd91e 100644 --- a/contrib/libfido2/examples/README.adoc +++ b/contrib/libfido2/examples/README.adoc @@ -1,99 +1,100 @@ = Examples === Definitions The following definitions are used in the description below: - The file system path or subsystem-specific identification string of a FIDO device. - , [oldpin] Strings passed directly in the executed command's argument vector. - The file system path of a file containing a FIDO credential ID in binary representation. - The file system path of a file containing a public key in PEM format. - A credential's associated CTAP 2.1 "largeBlob" symmetric key. === Description The following examples are provided: - manifest Prints a list of configured FIDO devices. - info Prints information about . - reset Performs a factory reset on . - setpin [oldpin] Configures as the new PIN of . If [oldpin] is provided, the device's PIN is changed from [oldpin] to . - cred [-t es256|es384|rs256|eddsa] [-k pubkey] [-ei cred_id] [-P pin] - [-T seconds] [-b blobkey] [-hruv] + [-T seconds] [-b blobkey] [-hruv] [-c cred_protect] Creates a new credential on and verify that the credential was signed by the authenticator. The device's attestation certificate is not verified. If option -k is specified, the credential's public key is stored in . If option -i is specified, the credential ID is stored in . The -e option may be used to add to the list of excluded credentials. If option -h is specified, the hmac-secret FIDO2 extension is enabled on the generated credential. If option -r is specified, the generated credential will involve a resident key. User verification may be requested through the -v option. If option -u is specified, the credential is generated using U2F (CTAP1) instead of FIDO2 (CTAP2) commands. The -T option may be used to enforce a timeout of . If the option -b is specified, the credential's "largeBlob" key is stored in - . + . If the option -c is specified the the generated credential + will be bound by the specified protection policy. - assert [-t es256|es384|rs256|eddsa] [-a cred_id] [-h hmac_secret] [-P pin] [-s hmac_salt] [-T seconds] [-b blobkey] [-puv] Asks for a FIDO2 assertion corresponding to [cred_id], which may be omitted for resident keys. The obtained assertion is verified using . The -p option requests that the user be present and checks whether the user presence bit was signed by the authenticator. The -v option requests user verification and checks whether the user verification bit was signed by the authenticator. If option -u is specified, the assertion is generated using U2F (CTAP1) instead of FIDO2 (CTAP2) commands. If option -s is specified, a FIDO2 hmac-secret is requested from the authenticator, and the contents of are used as the salt. If option -h is specified, the resulting hmac-secret is stored in . The -T option may be used to enforce a timeout of . If the option -b specified, the credential's "largeBlob" key is stored in . - retries Get the number of PIN attempts left on before lockout. - select Enumerates available FIDO devices and, if more than one is present, simultaneously requests touch on all of them, printing information about the device touched. Debugging is possible through the use of the FIDO_DEBUG environment variable. If set, libfido2 will produce a log of its transactions with the authenticator. Additionally, an example of a WebAuthn client using libfido2 is available at https://github.com/martelletto/fido2-webauthn-client. diff --git a/contrib/libfido2/examples/cred.c b/contrib/libfido2/examples/cred.c index 576900d97786..5a2a27fd7771 100644 --- a/contrib/libfido2/examples/cred.c +++ b/contrib/libfido2/examples/cred.c @@ -1,311 +1,331 @@ /* - * Copyright (c) 2018-2022 Yubico AB. All rights reserved. + * Copyright (c) 2018-2023 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. * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include "../openbsd-compat/openbsd-compat.h" #include "extern.h" static const unsigned char cd[32] = { 0xf9, 0x64, 0x57, 0xe7, 0x2d, 0x97, 0xf6, 0xbb, 0xdd, 0xd7, 0xfb, 0x06, 0x37, 0x62, 0xea, 0x26, 0x20, 0x44, 0x8e, 0x69, 0x7c, 0x03, 0xf2, 0x31, 0x2f, 0x99, 0xdc, 0xaf, 0x3e, 0x8a, 0x91, 0x6b, }; static const unsigned char user_id[32] = { 0x78, 0x1c, 0x78, 0x60, 0xad, 0x88, 0xd2, 0x63, 0x32, 0x62, 0x2a, 0xf1, 0x74, 0x5d, 0xed, 0xb2, 0xe7, 0xa4, 0x2b, 0x44, 0x89, 0x29, 0x39, 0xc5, 0x56, 0x64, 0x01, 0x27, 0x0d, 0xbb, 0xc4, 0x49, }; static void usage(void) { fprintf(stderr, "usage: cred [-t es256|es384|rs256|eddsa] [-k pubkey] " - "[-ei cred_id] [-P pin] [-T seconds] [-b blobkey] [-hruv] " + "[-ei cred_id] [-P pin] [-T seconds] [-b blobkey] [-c cred_protect] [-hruv] " "\n"); exit(EXIT_FAILURE); } static void verify_cred(int type, const char *fmt, const unsigned char *authdata_ptr, size_t authdata_len, const unsigned char *attstmt_ptr, size_t attstmt_len, - bool rk, bool uv, int ext, const char *key_out, const char *id_out) + bool rk, bool uv, int ext, int cred_protect, const char *key_out, + const char *id_out) { fido_cred_t *cred; int r; if ((cred = fido_cred_new()) == NULL) errx(1, "fido_cred_new"); /* type */ r = fido_cred_set_type(cred, type); if (r != FIDO_OK) errx(1, "fido_cred_set_type: %s (0x%x)", fido_strerr(r), r); /* client data */ r = fido_cred_set_clientdata(cred, cd, sizeof(cd)); if (r != FIDO_OK) errx(1, "fido_cred_set_clientdata: %s (0x%x)", fido_strerr(r), r); /* relying party */ r = fido_cred_set_rp(cred, "localhost", "sweet home localhost"); if (r != FIDO_OK) errx(1, "fido_cred_set_rp: %s (0x%x)", fido_strerr(r), r); /* authdata */ r = fido_cred_set_authdata(cred, authdata_ptr, authdata_len); if (r != FIDO_OK) errx(1, "fido_cred_set_authdata: %s (0x%x)", fido_strerr(r), r); /* extensions */ r = fido_cred_set_extensions(cred, ext); if (r != FIDO_OK) errx(1, "fido_cred_set_extensions: %s (0x%x)", fido_strerr(r), r); /* resident key */ if (rk && (r = fido_cred_set_rk(cred, FIDO_OPT_TRUE)) != FIDO_OK) errx(1, "fido_cred_set_rk: %s (0x%x)", fido_strerr(r), r); /* user verification */ if (uv && (r = fido_cred_set_uv(cred, FIDO_OPT_TRUE)) != FIDO_OK) errx(1, "fido_cred_set_uv: %s (0x%x)", fido_strerr(r), r); + /* credProt */ + if (cred_protect != 0 && (r = fido_cred_set_prot(cred, + cred_protect)) != FIDO_OK) + errx(1, "fido_cred_set_prot: %s (0x%x)", fido_strerr(r), r); + /* fmt */ r = fido_cred_set_fmt(cred, fmt); if (r != FIDO_OK) errx(1, "fido_cred_set_fmt: %s (0x%x)", fido_strerr(r), r); if (!strcmp(fido_cred_fmt(cred), "none")) { warnx("no attestation data, skipping credential verification"); goto out; } /* attestation statement */ r = fido_cred_set_attstmt(cred, attstmt_ptr, attstmt_len); if (r != FIDO_OK) errx(1, "fido_cred_set_attstmt: %s (0x%x)", fido_strerr(r), r); r = fido_cred_verify(cred); if (r != FIDO_OK) errx(1, "fido_cred_verify: %s (0x%x)", fido_strerr(r), r); out: if (key_out != NULL) { /* extract the credential pubkey */ if (type == COSE_ES256) { if (write_es256_pubkey(key_out, fido_cred_pubkey_ptr(cred), fido_cred_pubkey_len(cred)) < 0) errx(1, "write_es256_pubkey"); } else if (type == COSE_ES384) { if (write_es384_pubkey(key_out, fido_cred_pubkey_ptr(cred), fido_cred_pubkey_len(cred)) < 0) errx(1, "write_es384_pubkey"); } else if (type == COSE_RS256) { if (write_rs256_pubkey(key_out, fido_cred_pubkey_ptr(cred), fido_cred_pubkey_len(cred)) < 0) errx(1, "write_rs256_pubkey"); } else if (type == COSE_EDDSA) { if (write_eddsa_pubkey(key_out, fido_cred_pubkey_ptr(cred), fido_cred_pubkey_len(cred)) < 0) errx(1, "write_eddsa_pubkey"); } } if (id_out != NULL) { /* extract the credential id */ if (write_blob(id_out, fido_cred_id_ptr(cred), fido_cred_id_len(cred)) < 0) errx(1, "write_blob"); } fido_cred_free(&cred); } int main(int argc, char **argv) { bool rk = false; bool uv = false; bool u2f = false; fido_dev_t *dev; fido_cred_t *cred = NULL; const char *pin = NULL; const char *blobkey_out = NULL; const char *key_out = NULL; const char *id_out = NULL; unsigned char *body = NULL; long long ms = 0; size_t len; int type = COSE_ES256; int ext = 0; int ch; int r; + long long cred_protect = 0; if ((cred = fido_cred_new()) == NULL) errx(1, "fido_cred_new"); - while ((ch = getopt(argc, argv, "P:T:b:e:hi:k:rt:uv")) != -1) { + while ((ch = getopt(argc, argv, "P:T:b:e:hi:k:rt:uvc:")) != -1) { switch (ch) { case 'P': pin = optarg; break; case 'T': if (base10(optarg, &ms) < 0) errx(1, "base10: %s", optarg); if (ms <= 0 || ms > 30) errx(1, "-T: %s must be in (0,30]", optarg); ms *= 1000; /* seconds to milliseconds */ break; case 'b': ext |= FIDO_EXT_LARGEBLOB_KEY; blobkey_out = optarg; break; case 'e': if (read_blob(optarg, &body, &len) < 0) errx(1, "read_blob: %s", optarg); r = fido_cred_exclude(cred, body, len); if (r != FIDO_OK) errx(1, "fido_cred_exclude: %s (0x%x)", fido_strerr(r), r); free(body); body = NULL; break; case 'h': ext |= FIDO_EXT_HMAC_SECRET; break; + case 'c': + if (base10(optarg, &cred_protect) < 0) + errx(1, "base10: %s", optarg); + if (cred_protect <= 0 || cred_protect > 3) + errx(1, "-c: %s must be in (1,3)", optarg); + ext |= FIDO_EXT_CRED_PROTECT; + break; case 'i': id_out = optarg; break; case 'k': key_out = optarg; break; case 'r': rk = true; break; case 't': if (strcmp(optarg, "es256") == 0) type = COSE_ES256; else if (strcmp(optarg, "es384") == 0) type = COSE_ES384; else if (strcmp(optarg, "rs256") == 0) type = COSE_RS256; else if (strcmp(optarg, "eddsa") == 0) type = COSE_EDDSA; else errx(1, "unknown type %s", optarg); break; case 'u': u2f = true; break; case 'v': uv = true; break; default: usage(); } } argc -= optind; argv += optind; if (argc != 1) usage(); fido_init(0); if ((dev = fido_dev_new()) == NULL) errx(1, "fido_dev_new"); r = fido_dev_open(dev, argv[0]); if (r != FIDO_OK) errx(1, "fido_dev_open: %s (0x%x)", fido_strerr(r), r); if (u2f) fido_dev_force_u2f(dev); /* type */ r = fido_cred_set_type(cred, type); if (r != FIDO_OK) errx(1, "fido_cred_set_type: %s (0x%x)", fido_strerr(r), r); /* client data */ r = fido_cred_set_clientdata(cred, cd, sizeof(cd)); if (r != FIDO_OK) errx(1, "fido_cred_set_clientdata: %s (0x%x)", fido_strerr(r), r); /* relying party */ r = fido_cred_set_rp(cred, "localhost", "sweet home localhost"); if (r != FIDO_OK) errx(1, "fido_cred_set_rp: %s (0x%x)", fido_strerr(r), r); /* user */ r = fido_cred_set_user(cred, user_id, sizeof(user_id), "john smith", "jsmith", NULL); if (r != FIDO_OK) errx(1, "fido_cred_set_user: %s (0x%x)", fido_strerr(r), r); /* extensions */ r = fido_cred_set_extensions(cred, ext); if (r != FIDO_OK) errx(1, "fido_cred_set_extensions: %s (0x%x)", fido_strerr(r), r); /* resident key */ if (rk && (r = fido_cred_set_rk(cred, FIDO_OPT_TRUE)) != FIDO_OK) errx(1, "fido_cred_set_rk: %s (0x%x)", fido_strerr(r), r); /* user verification */ if (uv && (r = fido_cred_set_uv(cred, FIDO_OPT_TRUE)) != FIDO_OK) errx(1, "fido_cred_set_uv: %s (0x%x)", fido_strerr(r), r); + /* credProt */ + if (cred_protect != 0 && (r = fido_cred_set_prot(cred, + (int)cred_protect)) != FIDO_OK) + errx(1, "fido_cred_set_prot: %s (0x%x)", fido_strerr(r), r); + /* timeout */ if (ms != 0 && (r = fido_dev_set_timeout(dev, (int)ms)) != FIDO_OK) errx(1, "fido_dev_set_timeout: %s (0x%x)", fido_strerr(r), r); if ((r = fido_dev_make_cred(dev, cred, pin)) != FIDO_OK) { fido_dev_cancel(dev); errx(1, "fido_makecred: %s (0x%x)", fido_strerr(r), r); } r = fido_dev_close(dev); if (r != FIDO_OK) errx(1, "fido_dev_close: %s (0x%x)", fido_strerr(r), r); fido_dev_free(&dev); /* when verifying, pin implies uv */ if (pin) uv = true; verify_cred(type, fido_cred_fmt(cred), fido_cred_authdata_ptr(cred), fido_cred_authdata_len(cred), fido_cred_attstmt_ptr(cred), - fido_cred_attstmt_len(cred), rk, uv, ext, key_out, id_out); + fido_cred_attstmt_len(cred), rk, uv, ext, fido_cred_prot(cred), + key_out, id_out); if (blobkey_out != NULL) { /* extract the "largeBlob" key */ if (write_blob(blobkey_out, fido_cred_largeblob_key_ptr(cred), fido_cred_largeblob_key_len(cred)) < 0) errx(1, "write_blob"); } fido_cred_free(&cred); exit(0); } diff --git a/contrib/libfido2/fuzz/Dockerfile b/contrib/libfido2/fuzz/Dockerfile index 9cda37589b44..7b26e6ec3b19 100644 --- a/contrib/libfido2/fuzz/Dockerfile +++ b/contrib/libfido2/fuzz/Dockerfile @@ -1,16 +1,16 @@ # Copyright (c) 2019-2023 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. # SPDX-License-Identifier: BSD-2-Clause FROM alpine:latest ENV CC=clang ENV CXX=clang++ RUN apk -q update RUN apk add build-base clang clang-analyzer cmake compiler-rt coreutils RUN apk add eudev-dev git linux-headers llvm openssl-dev pcsc-lite-dev RUN apk add sudo tar zlib-dev -RUN git clone --branch v0.10.1 --depth=1 https://github.com/PJK/libcbor +RUN git clone --branch v0.10.2 --depth=1 https://github.com/PJK/libcbor RUN git clone --depth=1 https://github.com/yubico/libfido2 WORKDIR /libfido2 RUN ./fuzz/build-coverage /libcbor /libfido2 diff --git a/contrib/libfido2/fuzz/Makefile b/contrib/libfido2/fuzz/Makefile index 0e6756f0ada1..55a506bc8312 100644 --- a/contrib/libfido2/fuzz/Makefile +++ b/contrib/libfido2/fuzz/Makefile @@ -1,90 +1,90 @@ # Copyright (c) 2019-2023 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. # SPDX-License-Identifier: BSD-2-Clause -IMAGE := libfido2-coverage:1.13.1 +IMAGE := libfido2-coverage:1.14.0 RUNNER := libfido2-runner PROFDATA := llvm-profdata COV := llvm-cov TARGETS := fuzz_assert fuzz_bio fuzz_cred fuzz_credman fuzz_hid \ fuzz_largeblob fuzz_netlink fuzz_mgmt fuzz_pcsc CORPORA := $(foreach f,${TARGETS},${f}/corpus) MINIFY := $(foreach f,${TARGETS},/minify/${f}/corpus) REMOTE := gs://libfido2-corpus.clusterfuzz-external.appspot.com .DEFAULT_GOAL := all all: ${TARGETS} build: docker build -t ${IMAGE} - < Dockerfile run: build -docker run -it -d --name ${RUNNER} ${IMAGE} docker start ${RUNNER} sync: run tar Ccf .. - src fuzz | docker exec -i ${RUNNER} tar Cxf /libfido2 - docker exec ${RUNNER} make -C /libfido2/build corpus: sync docker exec ${RUNNER} /bin/sh -c 'cd /libfido2/fuzz && rm -rf ${TARGETS}' docker exec ${RUNNER} tar Czxf /libfido2/fuzz /libfido2/fuzz/corpus.tgz ${TARGETS}: corpus sync docker exec -e LLVM_PROFILE_FILE=/profraw/$@ ${RUNNER} \ /bin/sh -c 'rm -f /profraw/$@ && /libfido2/build/fuzz/$@ \ -runs=1 /libfido2/fuzz/$@' ${MINIFY}: /minify/%/corpus: % docker exec ${RUNNER} /bin/sh -c 'rm -rf $@ && mkdir -p $@ && \ /libfido2/build/fuzz/$< -use_value_profile=1 -merge=1 $@ \ /libfido2/fuzz/$ $@ profdata: run docker exec ${RUNNER} /bin/sh -c 'rm -f /$@ && ${PROFDATA} \ merge -sparse /profraw/* -o /$@' report.tgz: profdata docker exec ${RUNNER} /bin/sh -c 'rm -rf /report && mkdir /report && \ ${COV} show -format=html -tab-size=8 -instr-profile=/$< \ -ignore-filename-regex=pcsclite.h --show-branch-summary=false \ -output-dir=/report /libfido2/build/src/libfido2.so' docker exec -i ${RUNNER} tar Czcf / - report > $@ summary.txt: profdata docker exec ${RUNNER} ${COV} report -use-color=false \ -ignore-filename-regex=pcsclite.h --show-branch-summary=false \ /libfido2/build/src/libfido2.so -instr-profile=/$< > $@ functions.txt: profdata docker exec ${RUNNER} /bin/sh -c '${COV} report -use-color=false \ -ignore-filename-regex=pcsclite.h -show-functions \ --show-branch-summary=false -instr-profile=/$< \ /libfido2/build/src/libfido2.so /libfido2/src/*.[ch]' > $@ clean: run docker exec ${RUNNER} /bin/sh -c 'rm -rf /profraw /profdata && \ make -C /libfido2/build clean' -docker stop ${RUNNER} rm -rf ${TARGETS} ${CORPORA}: -mkdir -p $@ gsutil -q -m rsync -d -r ${REMOTE}/libFuzzer/libfido2_$(@:/corpus=) $@ fetch-oss-fuzz: ${CORPORA} find ${TARGETS} -type f -size +8192c -print0 | xargs -0 rm fetch-franz: ssh franz tar -C corpus -cf- . | tar -xf- corpus.tgz: tar zcf $@ ${TARGETS} .PHONY: build run sync corpus ${TARGETS} ${CORPORA} .PHONY: report.tgz summary.txt functions.txt .PHONY: fetch-oss-fuzz fetch-franz corpus.tgz diff --git a/contrib/libfido2/fuzz/export.gnu b/contrib/libfido2/fuzz/export.gnu index f0fb840dd686..bc25dd66cba7 100644 --- a/contrib/libfido2/fuzz/export.gnu +++ b/contrib/libfido2/fuzz/export.gnu @@ -1,283 +1,285 @@ { global: eddsa_pk_free; eddsa_pk_from_EVP_PKEY; eddsa_pk_from_ptr; eddsa_pk_new; eddsa_pk_to_EVP_PKEY; es256_pk_free; es256_pk_from_EC_KEY; es256_pk_from_EVP_PKEY; es256_pk_from_ptr; es256_pk_new; es256_pk_to_EVP_PKEY; es384_pk_free; es384_pk_from_EC_KEY; es384_pk_from_EVP_PKEY; es384_pk_from_ptr; es384_pk_new; es384_pk_to_EVP_PKEY; fido_assert_allow_cred; fido_assert_authdata_len; fido_assert_authdata_ptr; + fido_assert_authdata_raw_len; + fido_assert_authdata_raw_ptr; fido_assert_blob_len; fido_assert_blob_ptr; fido_assert_clientdata_hash_len; fido_assert_clientdata_hash_ptr; fido_assert_count; fido_assert_flags; fido_assert_free; fido_assert_hmac_secret_len; fido_assert_hmac_secret_ptr; fido_assert_id_len; fido_assert_id_ptr; fido_assert_largeblob_key_len; fido_assert_largeblob_key_ptr; fido_assert_new; fido_assert_rp_id; fido_assert_set_authdata; fido_assert_set_authdata_raw; fido_assert_set_clientdata; fido_assert_set_clientdata_hash; fido_assert_set_count; fido_assert_set_extensions; fido_assert_set_hmac_salt; fido_assert_set_hmac_secret; fido_assert_set_options; fido_assert_set_rp; fido_assert_set_sig; fido_assert_set_up; fido_assert_set_uv; fido_assert_sigcount; fido_assert_sig_len; fido_assert_sig_ptr; fido_assert_user_display_name; fido_assert_user_icon; fido_assert_user_id_len; fido_assert_user_id_ptr; fido_assert_user_name; fido_assert_verify; fido_bio_dev_enroll_begin; fido_bio_dev_enroll_cancel; fido_bio_dev_enroll_continue; fido_bio_dev_enroll_remove; fido_bio_dev_get_info; fido_bio_dev_get_template_array; fido_bio_dev_set_template_name; fido_bio_enroll_free; fido_bio_enroll_last_status; fido_bio_enroll_new; fido_bio_enroll_remaining_samples; fido_bio_info_free; fido_bio_info_max_samples; fido_bio_info_new; fido_bio_info_type; fido_bio_template; fido_bio_template_array_count; fido_bio_template_array_free; fido_bio_template_array_new; fido_bio_template_free; fido_bio_template_id_len; fido_bio_template_id_ptr; fido_bio_template_name; fido_bio_template_new; fido_bio_template_set_id; fido_bio_template_set_name; fido_cbor_info_aaguid_len; fido_cbor_info_aaguid_ptr; fido_cbor_info_algorithm_cose; fido_cbor_info_algorithm_count; fido_cbor_info_algorithm_type; fido_cbor_info_certs_len; fido_cbor_info_certs_name_ptr; fido_cbor_info_certs_value_ptr; fido_cbor_info_extensions_len; fido_cbor_info_extensions_ptr; fido_cbor_info_free; fido_cbor_info_fwversion; fido_cbor_info_maxcredbloblen; fido_cbor_info_maxcredcntlst; fido_cbor_info_maxcredidlen; fido_cbor_info_maxlargeblob; fido_cbor_info_maxmsgsiz; fido_cbor_info_maxrpid_minpinlen; fido_cbor_info_minpinlen; fido_cbor_info_new; fido_cbor_info_new_pin_required; fido_cbor_info_options_len; fido_cbor_info_options_name_ptr; fido_cbor_info_options_value_ptr; fido_cbor_info_protocols_len; fido_cbor_info_protocols_ptr; fido_cbor_info_rk_remaining; fido_cbor_info_transports_len; fido_cbor_info_transports_ptr; fido_cbor_info_uv_attempts; fido_cbor_info_uv_modality; fido_cbor_info_versions_len; fido_cbor_info_versions_ptr; fido_cred_attstmt_len; fido_cred_attstmt_ptr; fido_cred_authdata_len; fido_cred_authdata_ptr; fido_cred_authdata_raw_len; fido_cred_authdata_raw_ptr; fido_cred_clientdata_hash_len; fido_cred_clientdata_hash_ptr; fido_cred_display_name; fido_cred_exclude; fido_cred_flags; fido_cred_largeblob_key_len; fido_cred_largeblob_key_ptr; fido_cred_sigcount; fido_cred_fmt; fido_cred_free; fido_cred_id_len; fido_cred_id_ptr; fido_cred_aaguid_len; fido_cred_aaguid_ptr; fido_credman_del_dev_rk; fido_credman_get_dev_metadata; fido_credman_get_dev_rk; fido_credman_get_dev_rp; fido_credman_metadata_free; fido_credman_metadata_new; fido_credman_rk; fido_credman_rk_count; fido_credman_rk_existing; fido_credman_rk_free; fido_credman_rk_new; fido_credman_rk_remaining; fido_credman_rp_count; fido_credman_rp_free; fido_credman_rp_id; fido_credman_rp_id_hash_len; fido_credman_rp_id_hash_ptr; fido_credman_rp_name; fido_credman_rp_new; fido_credman_set_dev_rk; fido_cred_new; fido_cred_pin_minlen; fido_cred_prot; fido_cred_pubkey_len; fido_cred_pubkey_ptr; fido_cred_rp_id; fido_cred_rp_name; fido_cred_set_attstmt; fido_cred_set_authdata; fido_cred_set_authdata_raw; fido_cred_set_blob; fido_cred_set_clientdata; fido_cred_set_clientdata_hash; fido_cred_set_extensions; fido_cred_set_fmt; fido_cred_set_id; fido_cred_set_options; fido_cred_set_pin_minlen; fido_cred_set_prot; fido_cred_set_rk; fido_cred_set_rp; fido_cred_set_sig; fido_cred_set_type; fido_cred_set_user; fido_cred_set_uv; fido_cred_set_x509; fido_cred_sig_len; fido_cred_sig_ptr; fido_cred_type; fido_cred_user_id_len; fido_cred_user_id_ptr; fido_cred_user_name; fido_cred_verify; fido_cred_verify_self; fido_cred_x5c_len; fido_cred_x5c_ptr; fido_dev_build; fido_dev_cancel; fido_dev_close; fido_dev_enable_entattest; fido_dev_flags; fido_dev_force_fido2; fido_dev_force_pin_change; fido_dev_force_u2f; fido_dev_free; fido_dev_get_assert; fido_dev_get_cbor_info; fido_dev_get_retry_count; fido_dev_get_uv_retry_count; fido_dev_get_touch_begin; fido_dev_get_touch_status; fido_dev_has_pin; fido_dev_has_uv; fido_dev_info_free; fido_dev_info_manifest; fido_dev_info_manufacturer_string; fido_dev_info_new; fido_dev_info_path; fido_dev_info_product; fido_dev_info_product_string; fido_dev_info_ptr; fido_dev_info_set; fido_dev_info_vendor; fido_dev_is_fido2; fido_dev_major; fido_dev_make_cred; fido_dev_minor; fido_dev_new; fido_dev_open; fido_dev_protocol; fido_dev_reset; fido_dev_set_io_functions; fido_dev_set_pcsc; fido_dev_set_pin; fido_dev_set_pin_minlen; fido_dev_set_pin_minlen_rpid; fido_dev_set_timeout; fido_dev_set_transport_functions; fido_dev_supports_cred_prot; fido_dev_supports_credman; fido_dev_supports_permissions; fido_dev_supports_pin; fido_dev_supports_uv; fido_dev_toggle_always_uv; fido_dev_largeblob_get; fido_dev_largeblob_get_array; fido_dev_largeblob_remove; fido_dev_largeblob_set; fido_dev_largeblob_set_array; fido_hid_get_report_len; fido_hid_get_usage; fido_init; fido_nfc_rx; fido_nfc_tx; fido_nl_free; fido_nl_get_nfc_target; fido_nl_new; fido_nl_power_nfc; fido_pcsc_close; fido_pcsc_manifest; fido_pcsc_open; fido_pcsc_read; fido_pcsc_rx; fido_pcsc_tx; fido_pcsc_write; fido_set_log_handler; fido_strerr; rs256_pk_free; rs256_pk_from_ptr; rs256_pk_from_EVP_PKEY; rs256_pk_from_RSA; rs256_pk_new; rs256_pk_to_EVP_PKEY; prng_init; prng_up; fuzz_clock_reset; fuzz_save_corpus; set_netlink_io_functions; set_pcsc_parameters; set_pcsc_io_functions; set_udev_parameters; uniform_random; local: *; }; diff --git a/contrib/libfido2/fuzz/functions.txt b/contrib/libfido2/fuzz/functions.txt index da7f058d6c00..4ad5a0c83f5c 100644 --- a/contrib/libfido2/fuzz/functions.txt +++ b/contrib/libfido2/fuzz/functions.txt @@ -1,949 +1,954 @@ File '/libfido2/src/aes256.c': Name Regions Miss Cover Lines Miss Cover -------------------------------------------------------------------------------------------------------- aes256_cbc_enc 4 0 100.00% 4 0 100.00% aes256_cbc_dec 4 0 100.00% 4 0 100.00% aes256_gcm_enc 1 0 100.00% 3 0 100.00% aes256_gcm_dec 1 0 100.00% 3 0 100.00% aes256.c:aes256_cbc_fips 26 1 96.15% 42 4 90.48% aes256.c:aes256_cbc 29 1 96.55% 36 3 91.67% aes256.c:aes256_cbc_proto1 1 0 100.00% 5 0 100.00% aes256.c:aes256_gcm 52 1 98.08% 60 4 93.33% -------------------------------------------------------------------------------------------------------- TOTAL 118 3 97.46% 157 11 92.99% File '/libfido2/src/assert.c': Name Regions Miss Cover Lines Miss Cover ----------------------------------------------------------------------------------------------------------------- fido_dev_get_assert 40 0 100.00% 35 0 100.00% fido_check_flags 13 0 100.00% 15 0 100.00% fido_get_signed_hash 20 1 95.00% 34 3 91.18% fido_assert_verify 50 4 92.00% 70 7 90.00% fido_assert_set_clientdata 12 12 0.00% 11 11 0.00% fido_assert_set_clientdata_hash 8 0 100.00% 6 0 100.00% fido_assert_set_hmac_salt 10 0 100.00% 6 0 100.00% fido_assert_set_hmac_secret 12 12 0.00% 7 7 0.00% fido_assert_set_rp 12 0 100.00% 11 0 100.00% +fido_assert_set_winhello_appid 2 2 0.00% 5 5 0.00% fido_assert_allow_cred 13 2 84.62% 22 3 86.36% +fido_assert_empty_allow_list 2 0 100.00% 5 0 100.00% fido_assert_set_extensions 14 0 100.00% 10 0 100.00% fido_assert_set_options 8 8 0.00% 5 5 0.00% fido_assert_set_up 2 0 100.00% 4 0 100.00% fido_assert_set_uv 2 0 100.00% 4 0 100.00% fido_assert_clientdata_hash_ptr 1 0 100.00% 3 0 100.00% fido_assert_clientdata_hash_len 1 0 100.00% 3 0 100.00% fido_assert_new 1 0 100.00% 3 0 100.00% -fido_assert_reset_tx 1 0 100.00% 12 0 100.00% -fido_assert_reset_rx 4 0 100.00% 19 0 100.00% +fido_assert_reset_tx 1 0 100.00% 13 0 100.00% +fido_assert_reset_rx 4 0 100.00% 20 0 100.00% fido_assert_free 6 0 100.00% 9 0 100.00% fido_assert_count 1 0 100.00% 3 0 100.00% fido_assert_rp_id 1 0 100.00% 3 0 100.00% fido_assert_flags 4 0 100.00% 5 0 100.00% fido_assert_sigcount 4 0 100.00% 5 0 100.00% fido_assert_authdata_ptr 4 0 100.00% 5 0 100.00% fido_assert_authdata_len 4 0 100.00% 5 0 100.00% +fido_assert_authdata_raw_ptr 4 0 100.00% 5 0 100.00% +fido_assert_authdata_raw_len 4 0 100.00% 5 0 100.00% fido_assert_sig_ptr 4 0 100.00% 5 0 100.00% fido_assert_sig_len 4 0 100.00% 5 0 100.00% fido_assert_id_ptr 4 0 100.00% 5 0 100.00% fido_assert_id_len 4 0 100.00% 5 0 100.00% fido_assert_user_id_ptr 4 0 100.00% 5 0 100.00% fido_assert_user_id_len 4 0 100.00% 5 0 100.00% fido_assert_user_icon 4 0 100.00% 5 0 100.00% fido_assert_user_name 4 0 100.00% 5 0 100.00% fido_assert_user_display_name 4 0 100.00% 5 0 100.00% fido_assert_hmac_secret_ptr 4 0 100.00% 5 0 100.00% fido_assert_hmac_secret_len 4 0 100.00% 5 0 100.00% fido_assert_largeblob_key_ptr 4 0 100.00% 5 0 100.00% fido_assert_largeblob_key_len 4 0 100.00% 5 0 100.00% fido_assert_blob_ptr 4 0 100.00% 5 0 100.00% fido_assert_blob_len 4 0 100.00% 5 0 100.00% -fido_assert_set_authdata 24 0 100.00% 28 0 100.00% -fido_assert_set_authdata_raw 24 0 100.00% 27 0 100.00% +fido_assert_set_authdata 28 0 100.00% 33 0 100.00% +fido_assert_set_authdata_raw 28 0 100.00% 32 0 100.00% fido_assert_set_sig 14 0 100.00% 7 0 100.00% fido_assert_set_count 10 0 100.00% 17 0 100.00% assert.c:fido_dev_get_assert_wait 21 0 100.00% 14 0 100.00% assert.c:fido_dev_get_assert_tx 56 2 96.43% 62 5 91.94% assert.c:fido_dev_get_assert_rx 27 0 100.00% 36 0 100.00% assert.c:adjust_assert_count 24 0 100.00% 26 0 100.00% -assert.c:parse_assert_reply 12 0 100.00% 24 0 100.00% +assert.c:parse_assert_reply 15 0 100.00% 28 0 100.00% assert.c:fido_get_next_assert_tx 8 0 100.00% 8 0 100.00% assert.c:fido_get_next_assert_rx 23 2 91.30% 29 5 82.76% assert.c:decrypt_hmac_secrets 9 0 100.00% 15 0 100.00% assert.c:get_es256_hash 16 0 100.00% 17 0 100.00% assert.c:get_es384_hash 16 0 100.00% 17 0 100.00% assert.c:get_eddsa_hash 6 0 100.00% 9 0 100.00% assert.c:check_extensions 5 0 100.00% 9 0 100.00% assert.c:fido_assert_reset_extattr 1 0 100.00% 5 0 100.00% -assert.c:fido_assert_clean_authdata 1 0 100.00% 5 0 100.00% +assert.c:fido_assert_clean_authdata 1 0 100.00% 6 0 100.00% ----------------------------------------------------------------------------------------------------------------- -TOTAL 605 43 92.89% 745 46 93.83% +TOTAL 628 45 92.83% 782 51 93.48% File '/libfido2/src/authkey.c': Name Regions Miss Cover Lines Miss Cover ----------------------------------------------------------------------------------------------------------------- fido_dev_authkey 1 0 100.00% 3 0 100.00% authkey.c:fido_dev_authkey_wait 10 0 100.00% 7 0 100.00% authkey.c:fido_dev_authkey_tx 19 0 100.00% 25 0 100.00% authkey.c:fido_dev_authkey_rx 14 0 100.00% 21 0 100.00% authkey.c:parse_authkey 8 0 100.00% 10 0 100.00% ----------------------------------------------------------------------------------------------------------------- TOTAL 52 0 100.00% 66 0 100.00% File '/libfido2/src/bio.c': Name Regions Miss Cover Lines Miss Cover ----------------------------------------------------------------------------------------------------------------- fido_bio_dev_get_template_array 5 2 60.00% 6 1 83.33% fido_bio_dev_set_template_name 7 0 100.00% 6 0 100.00% fido_bio_dev_enroll_begin 25 2 92.00% 31 1 96.77% fido_bio_dev_enroll_continue 5 2 60.00% 6 1 83.33% fido_bio_dev_enroll_cancel 1 1 0.00% 4 4 0.00% fido_bio_dev_enroll_remove 1 0 100.00% 4 0 100.00% fido_bio_dev_get_info 1 0 100.00% 4 0 100.00% fido_bio_template_name 1 0 100.00% 3 0 100.00% fido_bio_template_id_ptr 1 0 100.00% 3 0 100.00% fido_bio_template_id_len 1 0 100.00% 3 0 100.00% fido_bio_template_array_count 1 0 100.00% 3 0 100.00% fido_bio_template_array_new 1 0 100.00% 3 0 100.00% fido_bio_template_new 1 0 100.00% 3 0 100.00% fido_bio_template_array_free 6 0 100.00% 8 0 100.00% fido_bio_template_free 6 0 100.00% 8 0 100.00% fido_bio_template_set_name 8 0 100.00% 7 0 100.00% fido_bio_template_set_id 8 0 100.00% 6 0 100.00% fido_bio_template 4 0 100.00% 5 0 100.00% fido_bio_enroll_new 1 0 100.00% 3 0 100.00% fido_bio_info_new 1 0 100.00% 3 0 100.00% fido_bio_info_type 1 0 100.00% 3 0 100.00% fido_bio_info_max_samples 1 0 100.00% 3 0 100.00% fido_bio_enroll_free 6 0 100.00% 8 0 100.00% fido_bio_info_free 6 0 100.00% 7 0 100.00% fido_bio_enroll_remaining_samples 1 0 100.00% 3 0 100.00% fido_bio_enroll_last_status 1 0 100.00% 3 0 100.00% bio.c:bio_get_template_array_wait 11 0 100.00% 7 0 100.00% bio.c:bio_tx 43 0 100.00% 55 0 100.00% bio.c:bio_prepare_hmac 18 0 100.00% 29 0 100.00% bio.c:bio_rx_template_array 19 0 100.00% 24 0 100.00% bio.c:bio_parse_template_array 26 1 96.15% 27 4 85.19% bio.c:decode_template_array 12 1 91.67% 18 3 83.33% bio.c:decode_template 9 0 100.00% 15 0 100.00% bio.c:bio_set_template_name_wait 19 0 100.00% 20 0 100.00% bio.c:bio_enroll_begin_wait 17 0 100.00% 19 0 100.00% bio.c:bio_rx_enroll_begin 23 0 100.00% 31 0 100.00% bio.c:bio_parse_enroll_status 20 0 100.00% 28 0 100.00% bio.c:bio_parse_template_id 8 0 100.00% 10 0 100.00% bio.c:bio_enroll_continue_wait 19 0 100.00% 20 0 100.00% bio.c:bio_rx_enroll_continue 19 0 100.00% 25 0 100.00% bio.c:bio_enroll_cancel_wait 11 11 0.00% 10 10 0.00% bio.c:bio_enroll_remove_wait 17 0 100.00% 19 0 100.00% bio.c:bio_get_info_wait 11 0 100.00% 10 0 100.00% bio.c:bio_rx_info 19 0 100.00% 24 0 100.00% bio.c:bio_reset_info 1 0 100.00% 4 0 100.00% bio.c:bio_parse_info 20 0 100.00% 28 0 100.00% bio.c:bio_reset_template_array 4 0 100.00% 7 0 100.00% bio.c:bio_reset_template 1 0 100.00% 5 0 100.00% bio.c:bio_reset_enroll 3 0 100.00% 6 0 100.00% ----------------------------------------------------------------------------------------------------------------- TOTAL 451 20 95.57% 587 24 95.91% File '/libfido2/src/blob.c': Name Regions Miss Cover Lines Miss Cover ----------------------------------------------------------------------------------------------------------------- fido_blob_new 1 0 100.00% 3 0 100.00% fido_blob_reset 1 0 100.00% 4 0 100.00% fido_blob_set 9 0 100.00% 15 0 100.00% fido_blob_append 12 1 91.67% 20 3 85.00% fido_blob_free 6 0 100.00% 8 0 100.00% fido_free_blob_array 7 0 100.00% 12 0 100.00% fido_blob_encode 6 0 100.00% 5 0 100.00% fido_blob_decode 1 0 100.00% 3 0 100.00% fido_blob_is_empty 3 0 100.00% 3 0 100.00% fido_blob_serialise 7 1 85.71% 10 1 90.00% ----------------------------------------------------------------------------------------------------------------- TOTAL 53 2 96.23% 83 4 95.18% File '/libfido2/src/buf.c': Name Regions Miss Cover Lines Miss Cover ----------------------------------------------------------------------------------------------------------------- fido_buf_read 4 0 100.00% 8 0 100.00% fido_buf_write 4 1 75.00% 8 1 87.50% ----------------------------------------------------------------------------------------------------------------- TOTAL 8 1 87.50% 16 1 93.75% File '/libfido2/src/cbor.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------ cbor_map_iter 20 1 95.00% 26 4 84.62% cbor_array_iter 12 0 100.00% 16 0 100.00% cbor_parse_reply 27 0 100.00% 36 0 100.00% cbor_vector_free 6 0 100.00% 5 0 100.00% cbor_bytestring_copy 14 0 100.00% 18 0 100.00% cbor_string_copy 14 0 100.00% 18 0 100.00% cbor_add_bytestring 14 0 100.00% 21 0 100.00% cbor_add_string 14 0 100.00% 21 0 100.00% cbor_add_bool 14 0 100.00% 21 0 100.00% cbor_flatten_vector 14 1 92.86% 16 1 93.75% cbor_build_frame 15 0 100.00% 25 0 100.00% cbor_encode_rp_entity 13 0 100.00% 11 0 100.00% cbor_encode_user_entity 21 0 100.00% 15 0 100.00% cbor_encode_pubkey_param 36 0 100.00% 39 0 100.00% cbor_encode_pubkey 10 0 100.00% 11 0 100.00% cbor_encode_pubkey_list 18 0 100.00% 19 0 100.00% cbor_encode_str_array 18 0 100.00% 19 0 100.00% cbor_encode_cred_ext 55 0 100.00% 50 0 100.00% cbor_encode_cred_opt 13 0 100.00% 11 0 100.00% cbor_encode_assert_opt 13 0 100.00% 11 0 100.00% cbor_encode_pin_auth 21 1 95.24% 22 3 86.36% cbor_encode_pin_opt 4 0 100.00% 8 0 100.00% cbor_encode_change_pin_auth 32 1 96.88% 36 3 91.67% cbor_encode_assert_ext 33 0 100.00% 32 0 100.00% cbor_decode_fmt 13 0 100.00% 15 0 100.00% cbor_decode_pubkey 26 1 96.15% 36 2 94.44% cbor_decode_cred_authdata 31 1 96.77% 35 3 91.43% -cbor_decode_assert_authdata 21 0 100.00% 32 0 100.00% +cbor_decode_assert_authdata 21 1 95.24% 32 3 90.62% cbor_decode_attstmt 13 0 100.00% 16 0 100.00% cbor_decode_uint64 4 0 100.00% 8 0 100.00% cbor_decode_cred_id 8 0 100.00% 9 0 100.00% cbor_decode_user 8 0 100.00% 9 0 100.00% cbor_decode_rp_entity 8 0 100.00% 9 0 100.00% cbor_decode_bool 10 0 100.00% 11 0 100.00% cbor_build_uint 10 1 90.00% 9 1 88.89% cbor_array_append 17 0 100.00% 21 0 100.00% cbor_array_drop 18 0 100.00% 17 0 100.00% cbor.c:ctap_check_cbor 28 0 100.00% 26 0 100.00% cbor.c:check_key_type 8 0 100.00% 7 0 100.00% cbor.c:cbor_add_arg 13 0 100.00% 21 0 100.00% cbor.c:cbor_add_uint8 14 0 100.00% 21 0 100.00% cbor.c:cbor_encode_largeblob_key_ext 6 0 100.00% 6 0 100.00% cbor.c:cbor_encode_hmac_secret_param 59 4 93.22% 66 8 87.88% -cbor.c:get_cose_alg 46 1 97.83% 45 3 93.33% +cbor.c:get_cose_alg 46 0 100.00% 45 0 100.00% cbor.c:find_cose_alg 35 0 100.00% 33 0 100.00% cbor.c:decode_attcred 25 0 100.00% 44 0 100.00% cbor.c:decode_cred_extensions 14 0 100.00% 24 0 100.00% -cbor.c:decode_cred_extension 41 1 97.56% 45 3 93.33% +cbor.c:decode_cred_extension 41 0 100.00% 45 0 100.00% cbor.c:decode_assert_extensions 14 0 100.00% 23 0 100.00% cbor.c:decode_assert_extension 19 0 100.00% 27 0 100.00% cbor.c:decode_attstmt_entry 56 0 100.00% 51 0 100.00% cbor.c:decode_x5c 4 0 100.00% 6 0 100.00% cbor.c:decode_cred_id_entry 10 0 100.00% 19 0 100.00% cbor.c:decode_user_entry 25 0 100.00% 35 0 100.00% cbor.c:decode_rp_entity_entry 15 0 100.00% 25 0 100.00% ------------------------------------------------------------------------------------------------------------------ -TOTAL 1070 13 98.79% 1258 31 97.54% +TOTAL 1070 12 98.88% 1258 28 97.77% File '/libfido2/src/compress.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------ fido_compress 1 0 100.00% 3 0 100.00% fido_uncompress 6 0 100.00% 5 0 100.00% compress.c:rfc1951_deflate 33 4 87.88% 47 6 87.23% compress.c:rfc1950_inflate 27 2 92.59% 22 4 81.82% compress.c:rfc1951_inflate 38 8 78.95% 45 14 68.89% ------------------------------------------------------------------------------------------------------------------ TOTAL 105 14 86.67% 122 24 80.33% File '/libfido2/src/config.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- fido_dev_enable_entattest 1 0 100.00% 4 0 100.00% fido_dev_toggle_always_uv 1 0 100.00% 4 0 100.00% fido_dev_set_pin_minlen 1 0 100.00% 4 0 100.00% fido_dev_force_pin_change 1 0 100.00% 4 0 100.00% fido_dev_set_pin_minlen_rpid 6 0 100.00% 15 0 100.00% config.c:config_enable_entattest_wait 6 0 100.00% 7 0 100.00% -config.c:config_tx 41 0 100.00% 49 0 100.00% -config.c:config_prepare_hmac 8 0 100.00% 19 0 100.00% +config.c:config_tx 39 0 100.00% 49 0 100.00% +config.c:config_prepare_hmac 10 0 100.00% 21 0 100.00% config.c:config_toggle_always_uv_wait 6 0 100.00% 7 0 100.00% config.c:config_pin_minlen 5 0 100.00% 7 0 100.00% config.c:config_pin_minlen_tx 36 0 100.00% 32 0 100.00% ------------------------------------------------------------------------------------------------------------------- -TOTAL 112 0 100.00% 152 0 100.00% +TOTAL 112 0 100.00% 154 0 100.00% File '/libfido2/src/cred.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- fido_dev_make_cred 12 0 100.00% 10 0 100.00% fido_check_rp_id 4 0 100.00% 11 0 100.00% fido_cred_verify 59 2 96.61% 75 4 94.67% -fido_cred_verify_self 60 6 90.00% 87 11 87.36% +fido_cred_verify_self 60 4 93.33% 87 7 91.95% fido_cred_new 1 0 100.00% 3 0 100.00% -fido_cred_reset_tx 1 0 100.00% 19 0 100.00% +fido_cred_reset_tx 1 0 100.00% 18 0 100.00% fido_cred_reset_rx 1 0 100.00% 7 0 100.00% fido_cred_free 6 0 100.00% 9 0 100.00% fido_cred_set_authdata 23 0 100.00% 28 0 100.00% fido_cred_set_authdata_raw 25 0 100.00% 29 0 100.00% fido_cred_set_id 6 0 100.00% 5 0 100.00% fido_cred_set_x509 6 0 100.00% 5 0 100.00% fido_cred_set_sig 6 0 100.00% 5 0 100.00% fido_cred_set_attstmt 20 0 100.00% 23 0 100.00% fido_cred_exclude 14 2 85.71% 19 3 84.21% +fido_cred_empty_exclude_list 2 0 100.00% 5 0 100.00% fido_cred_set_clientdata 12 12 0.00% 11 11 0.00% fido_cred_set_clientdata_hash 8 0 100.00% 6 0 100.00% fido_cred_set_rp 18 0 100.00% 22 0 100.00% fido_cred_set_user 32 0 100.00% 41 0 100.00% fido_cred_set_extensions 16 0 100.00% 10 0 100.00% fido_cred_set_options 8 8 0.00% 5 5 0.00% fido_cred_set_rk 2 0 100.00% 4 0 100.00% fido_cred_set_uv 2 0 100.00% 4 0 100.00% fido_cred_set_prot 21 0 100.00% 14 0 100.00% fido_cred_set_pin_minlen 7 0 100.00% 8 0 100.00% fido_cred_set_blob 13 0 100.00% 8 0 100.00% fido_cred_set_fmt 20 4 80.00% 12 2 83.33% fido_cred_set_type 23 2 91.30% 9 1 88.89% fido_cred_type 1 0 100.00% 3 0 100.00% fido_cred_flags 1 0 100.00% 3 0 100.00% fido_cred_sigcount 1 0 100.00% 3 0 100.00% fido_cred_clientdata_hash_ptr 1 0 100.00% 3 0 100.00% fido_cred_clientdata_hash_len 1 0 100.00% 3 0 100.00% fido_cred_x5c_ptr 1 0 100.00% 3 0 100.00% fido_cred_x5c_len 1 0 100.00% 3 0 100.00% fido_cred_sig_ptr 1 0 100.00% 3 0 100.00% fido_cred_sig_len 1 0 100.00% 3 0 100.00% fido_cred_authdata_ptr 1 0 100.00% 3 0 100.00% fido_cred_authdata_len 1 0 100.00% 3 0 100.00% fido_cred_authdata_raw_ptr 1 0 100.00% 3 0 100.00% fido_cred_authdata_raw_len 1 0 100.00% 3 0 100.00% fido_cred_attstmt_ptr 1 0 100.00% 3 0 100.00% fido_cred_attstmt_len 1 0 100.00% 3 0 100.00% fido_cred_pubkey_ptr 11 0 100.00% 21 0 100.00% fido_cred_pubkey_len 11 0 100.00% 21 0 100.00% fido_cred_id_ptr 1 0 100.00% 3 0 100.00% fido_cred_id_len 1 0 100.00% 3 0 100.00% fido_cred_aaguid_ptr 1 0 100.00% 3 0 100.00% fido_cred_aaguid_len 1 0 100.00% 3 0 100.00% fido_cred_prot 1 0 100.00% 3 0 100.00% fido_cred_pin_minlen 1 0 100.00% 3 0 100.00% fido_cred_fmt 1 0 100.00% 3 0 100.00% fido_cred_rp_id 1 0 100.00% 3 0 100.00% fido_cred_rp_name 1 0 100.00% 3 0 100.00% fido_cred_user_name 1 0 100.00% 3 0 100.00% fido_cred_display_name 1 0 100.00% 3 0 100.00% fido_cred_user_id_ptr 1 0 100.00% 3 0 100.00% fido_cred_user_id_len 1 0 100.00% 3 0 100.00% fido_cred_largeblob_key_ptr 1 0 100.00% 3 0 100.00% fido_cred_largeblob_key_len 1 0 100.00% 3 0 100.00% cred.c:fido_dev_make_cred_wait 10 0 100.00% 7 0 100.00% cred.c:fido_dev_make_cred_tx 64 0 100.00% 70 0 100.00% cred.c:fido_dev_make_cred_rx 29 0 100.00% 32 0 100.00% cred.c:parse_makecred_reply 14 0 100.00% 27 0 100.00% cred.c:check_extensions 2 0 100.00% 6 0 100.00% cred.c:get_signed_hash_u2f 27 0 100.00% 27 0 100.00% cred.c:verify_attstmt 25 2 92.00% 43 6 86.05% cred.c:fido_cred_clean_authdata 1 0 100.00% 8 0 100.00% cred.c:fido_cred_clean_attstmt 1 0 100.00% 8 0 100.00% ------------------------------------------------------------------------------------------------------------------- -TOTAL 651 38 94.16% 849 43 94.94% +TOTAL 653 36 94.49% 853 39 95.43% File '/libfido2/src/credman.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- fido_credman_get_dev_metadata 1 0 100.00% 4 0 100.00% fido_credman_get_dev_rk 1 0 100.00% 4 0 100.00% fido_credman_del_dev_rk 1 0 100.00% 4 0 100.00% fido_credman_get_dev_rp 1 0 100.00% 4 0 100.00% fido_credman_set_dev_rk 1 0 100.00% 4 0 100.00% fido_credman_rk_new 1 0 100.00% 3 0 100.00% fido_credman_rk_free 6 1 83.33% 8 1 87.50% fido_credman_rk_count 1 0 100.00% 3 0 100.00% fido_credman_rk 4 0 100.00% 5 0 100.00% fido_credman_metadata_new 1 0 100.00% 3 0 100.00% fido_credman_metadata_free 6 1 83.33% 7 1 85.71% fido_credman_rk_existing 1 0 100.00% 3 0 100.00% fido_credman_rk_remaining 1 0 100.00% 3 0 100.00% fido_credman_rp_new 1 0 100.00% 3 0 100.00% fido_credman_rp_free 6 1 83.33% 8 1 87.50% fido_credman_rp_count 1 0 100.00% 3 0 100.00% fido_credman_rp_id 4 0 100.00% 5 0 100.00% fido_credman_rp_name 4 0 100.00% 5 0 100.00% fido_credman_rp_id_hash_len 4 0 100.00% 5 0 100.00% fido_credman_rp_id_hash_ptr 4 0 100.00% 5 0 100.00% credman.c:credman_get_metadata_wait 11 0 100.00% 8 0 100.00% credman.c:credman_tx 36 0 100.00% 50 0 100.00% credman.c:credman_prepare_hmac 31 1 96.77% 50 2 96.00% credman.c:credman_rx_metadata 19 0 100.00% 24 0 100.00% credman.c:credman_parse_metadata 9 0 100.00% 17 0 100.00% credman.c:credman_get_rk_wait 27 0 100.00% 23 0 100.00% credman.c:credman_rx_rk 27 0 100.00% 35 0 100.00% credman.c:credman_parse_rk_count 16 0 100.00% 20 0 100.00% credman.c:credman_grow_array 17 2 88.24% 21 5 76.19% credman.c:credman_parse_rk 23 0 100.00% 31 0 100.00% credman.c:credman_rx_next_rk 23 2 91.30% 29 5 82.76% credman.c:credman_del_rk_wait 16 0 100.00% 15 0 100.00% credman.c:credman_get_rp_wait 23 0 100.00% 15 0 100.00% credman.c:credman_rx_rp 27 0 100.00% 35 0 100.00% credman.c:credman_parse_rp_count 16 0 100.00% 20 0 100.00% credman.c:credman_parse_rp 9 0 100.00% 17 0 100.00% credman.c:credman_rx_next_rp 23 2 91.30% 29 5 82.76% credman.c:credman_set_dev_rk_wait 11 0 100.00% 8 0 100.00% credman.c:credman_reset_rk 4 0 100.00% 9 0 100.00% credman.c:credman_reset_rp 4 0 100.00% 12 0 100.00% ------------------------------------------------------------------------------------------------------------------- TOTAL 422 10 97.63% 557 20 96.41% File '/libfido2/src/dev.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- fido_dev_info_manifest 2 0 100.00% 11 0 100.00% fido_dev_open_with_info 5 5 0.00% 6 6 0.00% fido_dev_open 13 4 69.23% 16 6 62.50% fido_dev_close 9 2 77.78% 8 1 87.50% fido_dev_set_sigmask 18 18 0.00% 11 11 0.00% fido_dev_cancel 11 0 100.00% 8 0 100.00% fido_dev_set_io_functions 18 4 77.78% 14 6 57.14% fido_dev_set_transport_functions 6 2 66.67% 9 3 66.67% fido_dev_io_handle 1 1 0.00% 3 3 0.00% fido_init 8 1 87.50% 5 0 100.00% fido_dev_new 5 0 100.00% 14 0 100.00% fido_dev_new_with_info 10 10 0.00% 16 16 0.00% fido_dev_free 6 0 100.00% 8 0 100.00% fido_dev_protocol 1 0 100.00% 3 0 100.00% fido_dev_major 1 0 100.00% 3 0 100.00% fido_dev_minor 1 0 100.00% 3 0 100.00% fido_dev_build 1 0 100.00% 3 0 100.00% fido_dev_flags 1 0 100.00% 3 0 100.00% fido_dev_is_fido2 2 0 100.00% 3 0 100.00% fido_dev_is_winhello 2 2 0.00% 3 3 0.00% fido_dev_supports_pin 3 0 100.00% 3 0 100.00% fido_dev_has_pin 2 0 100.00% 3 0 100.00% fido_dev_supports_cred_prot 2 0 100.00% 3 0 100.00% fido_dev_supports_credman 2 0 100.00% 3 0 100.00% fido_dev_supports_uv 3 0 100.00% 3 0 100.00% fido_dev_has_uv 2 0 100.00% 3 0 100.00% fido_dev_supports_permissions 2 0 100.00% 3 0 100.00% fido_dev_force_u2f 2 0 100.00% 4 0 100.00% fido_dev_force_fido2 2 2 0.00% 3 3 0.00% fido_dev_get_pin_protocol 11 0 100.00% 7 0 100.00% fido_dev_maxmsgsize 1 0 100.00% 3 0 100.00% fido_dev_set_timeout 6 2 66.67% 6 1 83.33% dev.c:run_manifest 10 0 100.00% 13 0 100.00% dev.c:fido_dev_open_wait 10 0 100.00% 7 0 100.00% dev.c:fido_dev_open_tx 56 11 80.36% 56 20 64.29% dev.c:set_random_report_len 11 0 100.00% 6 0 100.00% dev.c:fido_dev_open_rx 36 1 97.22% 53 1 98.11% dev.c:fido_dev_set_flags 1 0 100.00% 5 0 100.00% dev.c:fido_dev_set_extension_flags 7 0 100.00% 7 0 100.00% dev.c:fido_dev_set_option_flags 31 0 100.00% 20 0 100.00% dev.c:fido_dev_set_protocol_flags 11 0 100.00% 17 0 100.00% ------------------------------------------------------------------------------------------------------------------- TOTAL 332 65 80.42% 378 80 78.84% File '/libfido2/src/ecdh.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- fido_do_ecdh 29 0 100.00% 36 0 100.00% ecdh.c:do_ecdh 37 0 100.00% 44 0 100.00% ecdh.c:kdf 19 1 94.74% 28 2 92.86% ecdh.c:hkdf_sha256 32 1 96.88% 38 3 92.11% ------------------------------------------------------------------------------------------------------------------- TOTAL 117 2 98.29% 146 5 96.58% File '/libfido2/src/eddsa.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- eddsa_pk_decode 8 0 100.00% 9 0 100.00% eddsa_pk_new 1 0 100.00% 3 0 100.00% eddsa_pk_free 6 0 100.00% 7 0 100.00% eddsa_pk_from_ptr 10 0 100.00% 12 0 100.00% eddsa_pk_to_EVP_PKEY 3 0 100.00% 7 0 100.00% eddsa_pk_from_EVP_PKEY 18 2 88.89% 12 1 91.67% eddsa_verify_sig 19 2 89.47% 30 6 80.00% eddsa_pk_verify_sig 7 1 85.71% 13 2 84.62% eddsa.c:decode_pubkey_point 8 0 100.00% 11 0 100.00% eddsa.c:decode_coord 8 0 100.00% 10 0 100.00% ------------------------------------------------------------------------------------------------------------------- TOTAL 88 5 94.32% 114 9 92.11% File '/libfido2/src/err.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- fido_strerr 122 10 91.80% 126 10 92.06% ------------------------------------------------------------------------------------------------------------------- TOTAL 122 10 91.80% 126 10 92.06% File '/libfido2/src/es256.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- es256_pk_decode 8 0 100.00% 9 0 100.00% es256_pk_encode 56 0 100.00% 48 0 100.00% es256_sk_new 1 0 100.00% 3 0 100.00% es256_sk_free 6 0 100.00% 7 0 100.00% es256_pk_new 1 0 100.00% 3 0 100.00% es256_pk_free 6 0 100.00% 7 0 100.00% es256_pk_from_ptr 15 0 100.00% 17 0 100.00% es256_pk_set_x 1 0 100.00% 4 0 100.00% es256_pk_set_y 1 0 100.00% 4 0 100.00% es256_sk_create 39 0 100.00% 40 0 100.00% es256_pk_to_EVP_PKEY 42 0 100.00% 53 0 100.00% es256_pk_from_EC_KEY 42 2 95.24% 47 4 91.49% -es256_pk_from_EVP_PKEY 8 2 75.00% 7 1 85.71% +es256_pk_from_EVP_PKEY 8 0 100.00% 7 0 100.00% es256_sk_to_EVP_PKEY 28 0 100.00% 39 0 100.00% es256_derive_pk 25 0 100.00% 29 0 100.00% es256_verify_sig 12 2 83.33% 19 5 73.68% es256_pk_verify_sig 7 1 85.71% 13 2 84.62% es256.c:decode_pubkey_point 9 0 100.00% 13 0 100.00% es256.c:decode_coord 8 0 100.00% 10 0 100.00% ------------------------------------------------------------------------------------------------------------------- -TOTAL 315 7 97.78% 372 12 96.77% +TOTAL 315 5 98.41% 372 11 97.04% File '/libfido2/src/es384.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- es384_pk_decode 8 0 100.00% 9 0 100.00% es384_pk_new 1 0 100.00% 3 0 100.00% es384_pk_free 6 0 100.00% 7 0 100.00% es384_pk_from_ptr 15 0 100.00% 17 0 100.00% es384_pk_to_EVP_PKEY 42 0 100.00% 53 0 100.00% es384_pk_from_EC_KEY 42 2 95.24% 47 4 91.49% -es384_pk_from_EVP_PKEY 8 2 75.00% 7 1 85.71% +es384_pk_from_EVP_PKEY 8 0 100.00% 7 0 100.00% es384_verify_sig 12 2 83.33% 19 5 73.68% es384_pk_verify_sig 7 1 85.71% 13 2 84.62% es384.c:decode_pubkey_point 9 0 100.00% 13 0 100.00% -es384.c:decode_coord 8 1 87.50% 10 3 70.00% +es384.c:decode_coord 8 0 100.00% 10 0 100.00% ------------------------------------------------------------------------------------------------------------------- -TOTAL 158 8 94.94% 198 15 92.42% +TOTAL 158 5 96.84% 198 11 94.44% File '/libfido2/src/extern.h': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- File '/libfido2/src/fallthrough.h': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- File '/libfido2/src/fido.h': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- File '/libfido2/src/hid.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- fido_hid_get_usage 13 0 100.00% 22 0 100.00% fido_hid_get_report_len 19 0 100.00% 27 0 100.00% fido_dev_info_new 1 0 100.00% 3 0 100.00% fido_dev_info_free 9 0 100.00% 9 0 100.00% fido_dev_info_ptr 1 0 100.00% 3 0 100.00% fido_dev_info_set 26 2 92.31% 30 3 90.00% fido_dev_info_path 1 0 100.00% 3 0 100.00% fido_dev_info_vendor 1 0 100.00% 3 0 100.00% fido_dev_info_product 1 0 100.00% 3 0 100.00% fido_dev_info_manufacturer_string 1 0 100.00% 3 0 100.00% fido_dev_info_product_string 1 0 100.00% 3 0 100.00% hid.c:get_key_len 6 0 100.00% 12 0 100.00% hid.c:get_key_val 6 0 100.00% 18 0 100.00% hid.c:fido_dev_info_reset 1 0 100.00% 6 0 100.00% ------------------------------------------------------------------------------------------------------------------- TOTAL 87 2 97.70% 145 3 97.93% File '/libfido2/src/hid_linux.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- fido_hid_manifest 35 4 88.57% 41 2 95.12% fido_hid_open 33 33 0.00% 51 51 0.00% fido_hid_close 3 3 0.00% 6 6 0.00% fido_hid_set_sigmask 2 2 0.00% 6 6 0.00% fido_hid_read 15 15 0.00% 21 21 0.00% fido_hid_write 12 12 0.00% 17 17 0.00% fido_hid_report_in_len 1 1 0.00% 4 4 0.00% fido_hid_report_out_len 1 1 0.00% 4 4 0.00% hid_linux.c:copy_info 34 0 100.00% 44 0 100.00% hid_linux.c:is_fido 15 1 93.33% 16 1 93.75% hid_linux.c:get_parent_attr 6 0 100.00% 9 0 100.00% hid_linux.c:parse_uevent 12 0 100.00% 24 0 100.00% hid_linux.c:get_usb_attr 1 0 100.00% 3 0 100.00% hid_linux.c:get_report_descriptor 14 1 92.86% 17 3 82.35% ------------------------------------------------------------------------------------------------------------------- TOTAL 184 73 60.33% 263 115 56.27% File '/libfido2/src/hid_unix.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- fido_hid_unix_open 18 11 38.89% 22 14 36.36% fido_hid_unix_wait 11 10 9.09% 21 12 42.86% ------------------------------------------------------------------------------------------------------------------- TOTAL 29 21 27.59% 43 26 39.53% File '/libfido2/src/info.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- fido_dev_get_cbor_info_wait 10 0 100.00% 7 0 100.00% fido_dev_get_cbor_info 1 0 100.00% 4 0 100.00% fido_cbor_info_new 4 0 100.00% 7 0 100.00% fido_cbor_info_reset 1 0 100.00% 10 0 100.00% fido_cbor_info_free 6 0 100.00% 8 0 100.00% fido_cbor_info_versions_ptr 1 0 100.00% 3 0 100.00% fido_cbor_info_versions_len 1 0 100.00% 3 0 100.00% fido_cbor_info_extensions_ptr 1 0 100.00% 3 0 100.00% fido_cbor_info_extensions_len 1 0 100.00% 3 0 100.00% fido_cbor_info_transports_ptr 1 0 100.00% 3 0 100.00% fido_cbor_info_transports_len 1 0 100.00% 3 0 100.00% fido_cbor_info_aaguid_ptr 1 0 100.00% 3 0 100.00% fido_cbor_info_aaguid_len 1 0 100.00% 3 0 100.00% fido_cbor_info_options_name_ptr 1 0 100.00% 3 0 100.00% fido_cbor_info_options_value_ptr 1 0 100.00% 3 0 100.00% fido_cbor_info_options_len 1 0 100.00% 3 0 100.00% fido_cbor_info_maxcredbloblen 1 0 100.00% 3 0 100.00% fido_cbor_info_maxmsgsiz 1 0 100.00% 3 0 100.00% fido_cbor_info_maxcredcntlst 1 0 100.00% 3 0 100.00% fido_cbor_info_maxcredidlen 1 0 100.00% 3 0 100.00% fido_cbor_info_maxlargeblob 1 0 100.00% 3 0 100.00% fido_cbor_info_fwversion 1 0 100.00% 3 0 100.00% fido_cbor_info_minpinlen 1 0 100.00% 3 0 100.00% fido_cbor_info_maxrpid_minpinlen 1 0 100.00% 3 0 100.00% fido_cbor_info_uv_attempts 1 0 100.00% 3 0 100.00% fido_cbor_info_uv_modality 1 0 100.00% 3 0 100.00% fido_cbor_info_rk_remaining 1 0 100.00% 3 0 100.00% fido_cbor_info_protocols_ptr 1 0 100.00% 3 0 100.00% fido_cbor_info_protocols_len 1 0 100.00% 3 0 100.00% fido_cbor_info_algorithm_count 1 0 100.00% 3 0 100.00% fido_cbor_info_algorithm_type 4 0 100.00% 5 0 100.00% fido_cbor_info_algorithm_cose 4 0 100.00% 5 0 100.00% fido_cbor_info_new_pin_required 1 0 100.00% 3 0 100.00% fido_cbor_info_certs_name_ptr 1 0 100.00% 3 0 100.00% fido_cbor_info_certs_value_ptr 1 0 100.00% 3 0 100.00% fido_cbor_info_certs_len 1 0 100.00% 3 0 100.00% info.c:fido_dev_get_cbor_info_tx 8 0 100.00% 9 0 100.00% info.c:fido_dev_get_cbor_info_rx 14 0 100.00% 21 0 100.00% info.c:parse_reply_element 32 0 100.00% 59 0 100.00% info.c:decode_string_array 12 0 100.00% 17 0 100.00% info.c:decode_string 4 0 100.00% 10 0 100.00% info.c:decode_aaguid 8 0 100.00% 10 0 100.00% info.c:decode_options 11 0 100.00% 15 0 100.00% info.c:decode_option 7 0 100.00% 15 0 100.00% info.c:decode_protocols 12 0 100.00% 17 0 100.00% info.c:decode_protocol 6 0 100.00% 12 0 100.00% info.c:decode_algorithms 12 0 100.00% 17 0 100.00% info.c:decode_algorithm 9 0 100.00% 17 0 100.00% info.c:decode_algorithm_entry 20 0 100.00% 27 0 100.00% info.c:decode_certs 11 0 100.00% 15 0 100.00% info.c:decode_cert 7 0 100.00% 15 0 100.00% ------------------------------------------------------------------------------------------------------------------- TOTAL 232 0 100.00% 409 0 100.00% File '/libfido2/src/io.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- fido_tx 14 0 100.00% 11 0 100.00% fido_rx 13 1 92.31% 14 3 78.57% fido_rx_cbor_status 16 0 100.00% 19 0 100.00% io.c:transport_tx 7 0 100.00% 10 0 100.00% io.c:tx_empty 9 0 100.00% 14 0 100.00% io.c:tx_pkt 7 0 100.00% 10 0 100.00% io.c:tx 13 0 100.00% 19 0 100.00% io.c:tx_preamble 17 1 94.12% 20 1 95.00% io.c:tx_frame 16 1 93.75% 18 1 94.44% io.c:transport_rx 7 0 100.00% 10 0 100.00% io.c:rx 40 2 95.00% 52 2 96.15% io.c:rx_preamble 23 2 91.30% 22 5 77.27% io.c:rx_frame 11 0 100.00% 11 0 100.00% ------------------------------------------------------------------------------------------------------------------- TOTAL 193 7 96.37% 230 12 94.78% File '/libfido2/src/iso7816.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- iso7816_new 4 0 100.00% 16 0 100.00% iso7816_free 6 0 100.00% 7 0 100.00% iso7816_add 6 1 83.33% 8 1 87.50% iso7816_ptr 1 0 100.00% 3 0 100.00% iso7816_len 1 0 100.00% 4 0 100.00% ------------------------------------------------------------------------------------------------------------------- TOTAL 18 1 94.44% 38 1 97.37% 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 0 100.00% 36 0 100.00% fido_dev_largeblob_remove 12 0 100.00% 18 0 100.00% fido_dev_largeblob_get_array 15 2 86.67% 27 4 85.19% fido_dev_largeblob_set_array 14 0 100.00% 19 0 100.00% largeblob.c:largeblob_get_array 32 0 100.00% 36 0 100.00% largeblob.c:get_chunklen 10 1 90.00% 9 1 88.89% largeblob.c:largeblob_get_tx 19 0 100.00% 24 0 100.00% largeblob.c:largeblob_get_rx 26 0 100.00% 30 0 100.00% largeblob.c:parse_largeblob_reply 8 0 100.00% 9 0 100.00% largeblob.c:largeblob_array_check 7 0 100.00% 16 0 100.00% largeblob.c:largeblob_array_digest 10 0 100.00% 9 0 100.00% largeblob.c:largeblob_array_load 14 2 85.71% 19 7 63.16% largeblob.c:largeblob_array_lookup 25 0 100.00% 33 0 100.00% largeblob.c:largeblob_decode 16 2 87.50% 16 6 62.50% largeblob.c:largeblob_do_decode 27 3 88.89% 30 7 76.67% largeblob.c:largeblob_decrypt 15 0 100.00% 24 0 100.00% largeblob.c:largeblob_aad 1 0 100.00% 10 0 100.00% largeblob.c:largeblob_reset 1 0 100.00% 5 0 100.00% largeblob.c:largeblob_encode 16 0 100.00% 21 0 100.00% largeblob.c:largeblob_new 1 0 100.00% 3 0 100.00% largeblob.c:largeblob_seal 20 0 100.00% 32 0 100.00% largeblob.c:largeblob_get_nonce 8 0 100.00% 16 0 100.00% largeblob.c:largeblob_free 6 0 100.00% 8 0 100.00% largeblob.c:largeblob_add 27 2 92.59% 35 3 91.43% largeblob.c:largeblob_drop 21 0 100.00% 27 0 100.00% largeblob.c:largeblob_set_array 54 2 96.30% 61 4 93.44% largeblob.c:largeblob_get_uv_token 19 0 100.00% 23 0 100.00% largeblob.c:largeblob_set_tx 35 0 100.00% 36 0 100.00% largeblob.c:prepare_hmac 13 2 84.62% 23 7 69.57% ------------------------------------------------------------------------------------------------------------------- TOTAL 525 18 96.57% 693 43 93.80% File '/libfido2/src/log.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- fido_log_init 1 0 100.00% 4 0 100.00% fido_log_debug 6 1 83.33% 8 1 87.50% fido_log_xxd 16 1 93.75% 24 1 95.83% fido_log_error 8 2 75.00% 11 2 81.82% fido_set_log_handler 3 0 100.00% 4 0 100.00% log.c:log_on_stderr 1 1 0.00% 3 3 0.00% log.c:do_log 4 0 100.00% 9 0 100.00% ------------------------------------------------------------------------------------------------------------------- TOTAL 39 5 87.18% 63 7 88.89% File '/libfido2/src/netlink.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- fido_nl_power_nfc 18 0 100.00% 24 0 100.00% fido_nl_get_nfc_target 17 0 100.00% 31 0 100.00% fido_nl_free 10 2 80.00% 9 2 77.78% fido_nl_new 16 1 93.75% 26 3 88.46% set_netlink_io_functions 1 0 100.00% 4 0 100.00% netlink.c:nlmsg_new 8 0 100.00% 15 0 100.00% netlink.c:nlmsg_set_genl 1 0 100.00% 7 0 100.00% netlink.c:nlmsg_write 6 1 83.33% 7 1 85.71% netlink.c:nlmsg_set_u32 1 0 100.00% 3 0 100.00% netlink.c:nlmsg_setattr 15 1 93.33% 17 0 100.00% netlink.c:nlmsg_tx 10 1 90.00% 13 3 76.92% netlink.c:nlmsg_ptr 1 0 100.00% 3 0 100.00% netlink.c:nlmsg_len 1 0 100.00% 3 0 100.00% netlink.c:nlmsg_rx 11 2 81.82% 17 6 64.71% netlink.c:nl_parse_reply 20 0 100.00% 28 0 100.00% netlink.c:nlmsg_from_buf 15 0 100.00% 17 0 100.00% netlink.c:nlmsg_type 1 0 100.00% 3 0 100.00% netlink.c:nlmsg_get_status 8 0 100.00% 8 0 100.00% netlink.c:nlmsg_read 6 0 100.00% 7 0 100.00% netlink.c:nlmsg_get_genl 6 0 100.00% 7 0 100.00% netlink.c:nlmsg_iter 6 0 100.00% 13 0 100.00% netlink.c:nlmsg_getattr 1 0 100.00% 3 0 100.00% netlink.c:nla_from_buf 17 0 100.00% 21 0 100.00% netlink.c:nl_nfc_poll 18 0 100.00% 25 0 100.00% netlink.c:parse_nfc_event 10 0 100.00% 17 0 100.00% netlink.c:nla_type 1 0 100.00% 3 0 100.00% netlink.c:nla_get_u32 1 0 100.00% 3 0 100.00% netlink.c:nla_read 6 0 100.00% 7 0 100.00% netlink.c:nl_dump_nfc_target 19 0 100.00% 31 0 100.00% netlink.c:parse_target 9 0 100.00% 13 0 100.00% netlink.c:nl_get_nfc_family 23 0 100.00% 33 0 100.00% netlink.c:nlmsg_set_u16 1 0 100.00% 3 0 100.00% netlink.c:nlmsg_set_str 1 0 100.00% 3 0 100.00% netlink.c:parse_family 10 0 100.00% 17 0 100.00% netlink.c:nla_get_u16 1 0 100.00% 3 0 100.00% netlink.c:nla_iter 6 0 100.00% 13 0 100.00% netlink.c:nla_getattr 1 0 100.00% 3 0 100.00% netlink.c:parse_mcastgrps 1 0 100.00% 3 0 100.00% netlink.c:parse_mcastgrp 15 0 100.00% 24 0 100.00% netlink.c:nla_get_str 10 0 100.00% 11 0 100.00% ------------------------------------------------------------------------------------------------------------------- TOTAL 329 8 97.57% 498 15 96.99% File '/libfido2/src/nfc.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- fido_nfc_tx 28 0 100.00% 43 0 100.00% fido_nfc_rx 8 0 100.00% 13 0 100.00% nfc_is_fido 13 1 92.31% 21 3 85.71% fido_is_nfc 3 0 100.00% 3 0 100.00% fido_dev_set_nfc 4 1 75.00% 18 3 83.33% nfc.c:nfc_do_tx 20 0 100.00% 25 0 100.00% nfc.c:tx_short_apdu 14 0 100.00% 32 0 100.00% nfc.c:rx_init 25 0 100.00% 27 0 100.00% nfc.c:rx_cbor 4 0 100.00% 6 0 100.00% nfc.c:rx_msg 18 2 88.89% 23 6 73.91% nfc.c:rx_apdu 14 1 92.86% 22 3 86.36% nfc.c:tx_get_response 4 0 100.00% 11 0 100.00% ------------------------------------------------------------------------------------------------------------------- TOTAL 155 5 96.77% 244 15 93.85% File '/libfido2/src/nfc_linux.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- fido_nfc_manifest 35 7 80.00% 45 15 66.67% fido_nfc_open 20 3 85.00% 23 4 82.61% fido_nfc_close 1 1 0.00% 4 4 0.00% fido_nfc_set_sigmask 2 2 0.00% 6 6 0.00% fido_nfc_read 14 14 0.00% 30 30 0.00% fido_nfc_write 12 12 0.00% 18 18 0.00% nfc_linux.c:copy_info 39 22 43.59% 44 16 63.64% nfc_linux.c:get_usb_attr 1 1 0.00% 3 3 0.00% nfc_linux.c:get_parent_attr 6 6 0.00% 9 9 0.00% nfc_linux.c:sysnum_from_syspath 15 0 100.00% 17 0 100.00% nfc_linux.c:nfc_new 6 0 100.00% 11 0 100.00% nfc_linux.c:nfc_target_connect 9 9 0.00% 21 21 0.00% nfc_linux.c:nfc_free 12 0 100.00% 11 0 100.00% ------------------------------------------------------------------------------------------------------------------- TOTAL 172 77 55.23% 242 126 47.93% File '/libfido2/src/pcsc.c': Name Regions Miss Cover Lines Miss Cover ------------------------------------------------------------------------------------------------------------------- fido_pcsc_manifest 51 0 100.00% 55 0 100.00% fido_pcsc_open 32 0 100.00% 43 0 100.00% fido_pcsc_close 6 0 100.00% 9 0 100.00% fido_pcsc_read 8 0 100.00% 16 0 100.00% fido_pcsc_write 8 0 100.00% 22 0 100.00% fido_pcsc_tx 1 0 100.00% 3 0 100.00% fido_pcsc_rx 1 0 100.00% 3 0 100.00% fido_is_pcsc 3 0 100.00% 3 0 100.00% fido_dev_set_pcsc 4 1 75.00% 18 3 83.33% pcsc.c:list_readers 24 0 100.00% 24 0 100.00% pcsc.c:copy_info 30 0 100.00% 41 0 100.00% pcsc.c:get_reader 25 0 100.00% 28 0 100.00% pcsc.c:prepare_io_request 11 0 100.00% 17 0 100.00% ------------------------------------------------------------------------------------------------------------------- TOTAL 204 1 99.51% 282 3 98.94% File '/libfido2/src/pin.c': Name Regions Miss Cover Lines Miss Cover --------------------------------------------------------------------------------------------------------------------- fido_sha256 7 0 100.00% 10 0 100.00% fido_dev_get_uv_token 1 0 100.00% 3 0 100.00% fido_dev_set_pin 1 0 100.00% 4 0 100.00% fido_dev_get_retry_count 1 0 100.00% 4 0 100.00% fido_dev_get_uv_retry_count 1 0 100.00% 4 0 100.00% cbor_add_uv_params 17 0 100.00% 23 0 100.00% pin.c:uv_token_wait 14 2 85.71% 12 1 91.67% pin.c:ctap21_uv_token_tx 49 0 100.00% 53 0 100.00% pin.c:pin_sha256_enc 19 0 100.00% 24 0 100.00% pin.c:encode_uv_permission 20 1 95.00% 19 3 84.21% pin.c:ctap20_uv_token_tx 37 0 100.00% 45 0 100.00% pin.c:uv_token_rx 27 0 100.00% 34 0 100.00% pin.c:parse_uv_token 8 0 100.00% 10 0 100.00% pin.c:fido_dev_set_pin_wait 21 0 100.00% 24 0 100.00% pin.c:fido_dev_change_pin_tx 45 0 100.00% 56 0 100.00% pin.c:pin_pad64_enc 15 0 100.00% 21 0 100.00% pin.c:pad64 18 0 100.00% 20 0 100.00% pin.c:fido_dev_set_pin_tx 33 0 100.00% 41 0 100.00% pin.c:fido_dev_get_pin_retry_count_wait 10 0 100.00% 7 0 100.00% pin.c:fido_dev_get_retry_count_tx 19 0 100.00% 23 0 100.00% pin.c:fido_dev_get_pin_retry_count_rx 19 0 100.00% 24 0 100.00% pin.c:parse_pin_retry_count 1 0 100.00% 3 0 100.00% pin.c:parse_retry_count 13 0 100.00% 16 0 100.00% pin.c:fido_dev_get_uv_retry_count_wait 10 0 100.00% 7 0 100.00% pin.c:fido_dev_get_uv_retry_count_rx 19 0 100.00% 24 0 100.00% pin.c:parse_uv_retry_count 1 0 100.00% 3 0 100.00% --------------------------------------------------------------------------------------------------------------------- TOTAL 426 3 99.30% 514 4 99.22% File '/libfido2/src/random.c': Name Regions Miss Cover Lines Miss Cover --------------------------------------------------------------------------------------------------------------------- fido_get_random 6 0 100.00% 6 0 100.00% --------------------------------------------------------------------------------------------------------------------- TOTAL 6 0 100.00% 6 0 100.00% File '/libfido2/src/reset.c': Name Regions Miss Cover Lines Miss Cover --------------------------------------------------------------------------------------------------------------------- fido_dev_reset 1 0 100.00% 4 0 100.00% reset.c:fido_dev_reset_wait 15 0 100.00% 11 0 100.00% reset.c:fido_dev_reset_tx 8 0 100.00% 8 0 100.00% --------------------------------------------------------------------------------------------------------------------- TOTAL 24 0 100.00% 23 0 100.00% File '/libfido2/src/rs1.c': Name Regions Miss Cover Lines Miss Cover --------------------------------------------------------------------------------------------------------------------- -rs1_verify_sig 20 1 95.00% 30 3 90.00% -rs1.c:rs1_get_EVP_MD 4 0 100.00% 6 0 100.00% +rs1_verify_sig 20 2 90.00% 30 6 80.00% +rs1.c:rs1_get_EVP_MD 1 0 100.00% 3 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 22 2 90.91% 36 6 83.33% File '/libfido2/src/rs256.c': Name Regions Miss Cover Lines Miss Cover --------------------------------------------------------------------------------------------------------------------- rs256_pk_decode 8 0 100.00% 9 0 100.00% rs256_pk_new 1 0 100.00% 3 0 100.00% rs256_pk_free 6 0 100.00% 7 0 100.00% rs256_pk_from_ptr 10 0 100.00% 12 0 100.00% rs256_pk_to_EVP_PKEY 35 0 100.00% 43 0 100.00% rs256_pk_from_RSA 32 6 81.25% 26 9 65.38% -rs256_pk_from_EVP_PKEY 8 2 75.00% 7 1 85.71% -rs256_verify_sig 20 1 95.00% 30 2 93.33% +rs256_pk_from_EVP_PKEY 8 0 100.00% 7 0 100.00% +rs256_verify_sig 20 2 90.00% 30 5 83.33% rs256_pk_verify_sig 7 1 85.71% 13 2 84.62% rs256.c:decode_rsa_pubkey 9 0 100.00% 13 0 100.00% rs256.c:decode_bignum 8 0 100.00% 10 0 100.00% -rs256.c:rs256_get_EVP_MD 4 0 100.00% 6 0 100.00% +rs256.c:rs256_get_EVP_MD 1 0 100.00% 3 0 100.00% rs256.c:rs256_free_EVP_MD 1 0 100.00% 3 0 100.00% --------------------------------------------------------------------------------------------------------------------- -TOTAL 149 10 93.29% 182 14 92.31% +TOTAL 146 9 93.84% 179 16 91.06% File '/libfido2/src/time.c': Name Regions Miss Cover Lines Miss Cover --------------------------------------------------------------------------------------------------------------------- fido_time_now 4 0 100.00% 7 0 100.00% fido_time_delta 23 1 95.65% 23 0 100.00% time.c:timespec_to_ms 16 2 87.50% 13 2 84.62% --------------------------------------------------------------------------------------------------------------------- TOTAL 43 3 93.02% 43 2 95.35% File '/libfido2/src/touch.c': Name Regions Miss Cover Lines Miss Cover --------------------------------------------------------------------------------------------------------------------- fido_dev_get_touch_begin 50 0 100.00% 59 0 100.00% fido_dev_get_touch_status 17 0 100.00% 20 0 100.00% --------------------------------------------------------------------------------------------------------------------- TOTAL 67 0 100.00% 79 0 100.00% File '/libfido2/src/tpm.c': Name Regions Miss Cover Lines Miss Cover --------------------------------------------------------------------------------------------------------------------- fido_get_signed_hash_tpm 25 0 100.00% 39 0 100.00% tpm.c:check_es256_pubarea 19 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 17 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 15 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 103 0 100.00% 194 0 100.00% File '/libfido2/src/types.c': Name Regions Miss Cover Lines Miss Cover --------------------------------------------------------------------------------------------------------------------- fido_str_array_free 4 0 100.00% 7 0 100.00% fido_opt_array_free 4 0 100.00% 9 0 100.00% fido_byte_array_free 1 0 100.00% 5 0 100.00% fido_algo_free 1 0 100.00% 5 0 100.00% fido_algo_array_free 4 0 100.00% 7 0 100.00% fido_cert_array_free 4 0 100.00% 9 0 100.00% fido_str_array_pack 11 0 100.00% 14 0 100.00% --------------------------------------------------------------------------------------------------------------------- TOTAL 29 0 100.00% 56 0 100.00% File '/libfido2/src/u2f.c': Name Regions Miss Cover Lines Miss Cover --------------------------------------------------------------------------------------------------------------------- u2f_register 76 0 100.00% 81 0 100.00% u2f_authenticate 33 0 100.00% 37 0 100.00% u2f_get_touch_begin 37 0 100.00% 45 0 100.00% u2f_get_touch_status 26 0 100.00% 36 0 100.00% u2f.c:key_lookup 51 0 100.00% 65 0 100.00% u2f.c:send_dummy_register 37 0 100.00% 45 0 100.00% u2f.c:delay_ms 13 1 92.31% 15 3 80.00% u2f.c:parse_register_reply 49 0 100.00% 62 0 100.00% u2f.c:x5c_get 21 1 95.24% 26 3 88.46% u2f.c:sig_get 6 0 100.00% 10 0 100.00% u2f.c:encode_cred_attstmt 45 0 100.00% 52 0 100.00% u2f.c:encode_cred_authdata 33 2 93.94% 61 6 90.16% u2f.c:cbor_blob_from_ec_point 22 0 100.00% 31 0 100.00% u2f.c:u2f_authenticate_single 32 0 100.00% 43 0 100.00% u2f.c:do_auth 56 0 100.00% 67 0 100.00% u2f.c:parse_auth_reply 23 0 100.00% 23 0 100.00% u2f.c:authdata_fake 12 0 100.00% 27 0 100.00% --------------------------------------------------------------------------------------------------------------------- TOTAL 572 4 99.30% 726 12 98.35% File '/libfido2/src/util.c': Name Regions Miss Cover Lines Miss Cover --------------------------------------------------------------------------------------------------------------------- fido_to_uint64 14 1 92.86% 14 1 92.86% --------------------------------------------------------------------------------------------------------------------- TOTAL 14 1 92.86% 14 1 92.86% diff --git a/contrib/libfido2/fuzz/fuzz_assert.c b/contrib/libfido2/fuzz/fuzz_assert.c index 9f39f3d6ecb7..03cb51cb4f74 100644 --- a/contrib/libfido2/fuzz/fuzz_assert.c +++ b/contrib/libfido2/fuzz/fuzz_assert.c @@ -1,532 +1,534 @@ /* - * Copyright (c) 2019-2022 Yubico AB. All rights reserved. + * Copyright (c) 2019-2023 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. * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include #include "mutator_aux.h" #include "wiredata_fido2.h" #include "wiredata_u2f.h" #include "dummy.h" #include "../openbsd-compat/openbsd-compat.h" /* Parameter set defining a FIDO2 get assertion operation. */ struct param { char pin[MAXSTR]; char rp_id[MAXSTR]; int ext; int seed; struct blob cdh; struct blob cred; struct blob es256; struct blob rs256; struct blob eddsa; struct blob wire_data; uint8_t cred_count; uint8_t type; uint8_t opt; uint8_t up; uint8_t uv; }; /* * Collection of HID reports from an authenticator issued with a FIDO2 * get assertion using the example parameters above. */ static const uint8_t dummy_wire_data_fido[] = { WIREDATA_CTAP_INIT, WIREDATA_CTAP_CBOR_INFO, WIREDATA_CTAP_CBOR_AUTHKEY, WIREDATA_CTAP_CBOR_PINTOKEN, WIREDATA_CTAP_CBOR_ASSERT, }; /* * Collection of HID reports from an authenticator issued with a U2F * authentication using the example parameters above. */ static const uint8_t dummy_wire_data_u2f[] = { WIREDATA_CTAP_INIT, WIREDATA_CTAP_U2F_6985, WIREDATA_CTAP_U2F_6985, WIREDATA_CTAP_U2F_6985, WIREDATA_CTAP_U2F_6985, WIREDATA_CTAP_U2F_AUTH, }; struct param * unpack(const uint8_t *ptr, size_t len) { cbor_item_t *item = NULL, **v; struct cbor_load_result cbor; struct param *p; int ok = -1; if ((p = calloc(1, sizeof(*p))) == NULL || (item = cbor_load(ptr, len, &cbor)) == NULL || cbor.read != len || cbor_isa_array(item) == false || cbor_array_is_definite(item) == false || cbor_array_size(item) != 15 || (v = cbor_array_handle(item)) == NULL) goto fail; if (unpack_byte(v[0], &p->uv) < 0 || unpack_byte(v[1], &p->up) < 0 || unpack_byte(v[2], &p->opt) < 0 || unpack_byte(v[3], &p->type) < 0 || unpack_byte(v[4], &p->cred_count) < 0 || unpack_int(v[5], &p->ext) < 0 || unpack_int(v[6], &p->seed) < 0 || unpack_string(v[7], p->rp_id) < 0 || unpack_string(v[8], p->pin) < 0 || unpack_blob(v[9], &p->wire_data) < 0 || unpack_blob(v[10], &p->rs256) < 0 || unpack_blob(v[11], &p->es256) < 0 || unpack_blob(v[12], &p->eddsa) < 0 || unpack_blob(v[13], &p->cred) < 0 || unpack_blob(v[14], &p->cdh) < 0) goto fail; ok = 0; fail: if (ok < 0) { free(p); p = NULL; } if (item) cbor_decref(&item); return p; } size_t pack(uint8_t *ptr, size_t len, const struct param *p) { cbor_item_t *argv[15], *array = NULL; size_t cbor_alloc_len, cbor_len = 0; unsigned char *cbor = NULL; memset(argv, 0, sizeof(argv)); if ((array = cbor_new_definite_array(15)) == NULL || (argv[0] = pack_byte(p->uv)) == NULL || (argv[1] = pack_byte(p->up)) == NULL || (argv[2] = pack_byte(p->opt)) == NULL || (argv[3] = pack_byte(p->type)) == NULL || (argv[4] = pack_byte(p->cred_count)) == NULL || (argv[5] = pack_int(p->ext)) == NULL || (argv[6] = pack_int(p->seed)) == NULL || (argv[7] = pack_string(p->rp_id)) == NULL || (argv[8] = pack_string(p->pin)) == NULL || (argv[9] = pack_blob(&p->wire_data)) == NULL || (argv[10] = pack_blob(&p->rs256)) == NULL || (argv[11] = pack_blob(&p->es256)) == NULL || (argv[12] = pack_blob(&p->eddsa)) == NULL || (argv[13] = pack_blob(&p->cred)) == NULL || (argv[14] = pack_blob(&p->cdh)) == NULL) goto fail; for (size_t i = 0; i < 15; i++) if (cbor_array_push(array, argv[i]) == false) goto fail; if ((cbor_len = cbor_serialize_alloc(array, &cbor, &cbor_alloc_len)) == 0 || cbor_len > len) { cbor_len = 0; goto fail; } memcpy(ptr, cbor, cbor_len); fail: for (size_t i = 0; i < 15; i++) if (argv[i]) cbor_decref(&argv[i]); if (array) cbor_decref(&array); free(cbor); return cbor_len; } size_t pack_dummy(uint8_t *ptr, size_t len) { struct param dummy; uint8_t blob[MAXCORPUS]; size_t blob_len; memset(&dummy, 0, sizeof(dummy)); dummy.type = 1; /* rsa */ dummy.ext = FIDO_EXT_HMAC_SECRET; strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin)); strlcpy(dummy.rp_id, dummy_rp_id, sizeof(dummy.rp_id)); dummy.cred.len = sizeof(dummy_cdh); /* XXX */ dummy.cdh.len = sizeof(dummy_cdh); dummy.es256.len = sizeof(dummy_es256); dummy.rs256.len = sizeof(dummy_rs256); dummy.eddsa.len = sizeof(dummy_eddsa); dummy.wire_data.len = sizeof(dummy_wire_data_fido); memcpy(&dummy.cred.body, &dummy_cdh, dummy.cred.len); /* XXX */ memcpy(&dummy.cdh.body, &dummy_cdh, dummy.cdh.len); memcpy(&dummy.wire_data.body, &dummy_wire_data_fido, dummy.wire_data.len); memcpy(&dummy.es256.body, &dummy_es256, dummy.es256.len); memcpy(&dummy.rs256.body, &dummy_rs256, dummy.rs256.len); memcpy(&dummy.eddsa.body, &dummy_eddsa, dummy.eddsa.len); assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); if (blob_len > len) { memcpy(ptr, blob, len); return len; } memcpy(ptr, blob, blob_len); return blob_len; } static void get_assert(fido_assert_t *assert, uint8_t opt, const struct blob *cdh, const char *rp_id, int ext, uint8_t up, uint8_t uv, const char *pin, uint8_t cred_count, const struct blob *cred) { fido_dev_t *dev; if ((dev = open_dev(opt & 2)) == NULL) return; if (opt & 1) fido_dev_force_u2f(dev); if (ext & FIDO_EXT_HMAC_SECRET) fido_assert_set_extensions(assert, FIDO_EXT_HMAC_SECRET); if (ext & FIDO_EXT_CRED_BLOB) fido_assert_set_extensions(assert, FIDO_EXT_CRED_BLOB); if (ext & FIDO_EXT_LARGEBLOB_KEY) fido_assert_set_extensions(assert, FIDO_EXT_LARGEBLOB_KEY); if (up & 1) fido_assert_set_up(assert, FIDO_OPT_TRUE); else if (opt & 1) fido_assert_set_up(assert, FIDO_OPT_FALSE); if (uv & 1) fido_assert_set_uv(assert, FIDO_OPT_TRUE); for (uint8_t i = 0; i < cred_count; i++) fido_assert_allow_cred(assert, cred->body, cred->len); fido_assert_set_clientdata_hash(assert, cdh->body, cdh->len); fido_assert_set_rp(assert, rp_id); /* XXX reuse cred as hmac salt */ fido_assert_set_hmac_salt(assert, cred->body, cred->len); /* repeat memory operations to trigger reallocation paths */ fido_assert_set_clientdata_hash(assert, cdh->body, cdh->len); fido_assert_set_rp(assert, rp_id); fido_assert_set_hmac_salt(assert, cred->body, cred->len); if (strlen(pin) == 0) pin = NULL; fido_dev_get_assert(dev, assert, (opt & 1) ? NULL : pin); fido_dev_cancel(dev); fido_dev_close(dev); fido_dev_free(&dev); } static void verify_assert(int type, const unsigned char *cdh_ptr, size_t cdh_len, const char *rp_id, const unsigned char *authdata_ptr, size_t authdata_len, const unsigned char *sig_ptr, size_t sig_len, uint8_t up, uint8_t uv, int ext, void *pk) { fido_assert_t *assert = NULL; int r; if ((assert = fido_assert_new()) == NULL) return; fido_assert_set_clientdata_hash(assert, cdh_ptr, cdh_len); fido_assert_set_rp(assert, rp_id); fido_assert_set_count(assert, 1); if (fido_assert_set_authdata(assert, 0, authdata_ptr, authdata_len) != FIDO_OK) { fido_assert_set_authdata_raw(assert, 0, authdata_ptr, authdata_len); } if (up & 1) fido_assert_set_up(assert, FIDO_OPT_TRUE); if (uv & 1) fido_assert_set_uv(assert, FIDO_OPT_TRUE); fido_assert_set_extensions(assert, ext); fido_assert_set_sig(assert, 0, sig_ptr, sig_len); /* repeat memory operations to trigger reallocation paths */ if (fido_assert_set_authdata(assert, 0, authdata_ptr, authdata_len) != FIDO_OK) { fido_assert_set_authdata_raw(assert, 0, authdata_ptr, authdata_len); } fido_assert_set_sig(assert, 0, sig_ptr, sig_len); r = fido_assert_verify(assert, 0, type, pk); consume(&r, sizeof(r)); fido_assert_free(&assert); } /* * Do a dummy conversion to exercise es256_pk_from_EVP_PKEY(). */ static void es256_convert(const es256_pk_t *k) { EVP_PKEY *pkey = NULL; es256_pk_t *pk = NULL; int r; if ((pkey = es256_pk_to_EVP_PKEY(k)) == NULL || (pk = es256_pk_new()) == NULL) goto out; r = es256_pk_from_EVP_PKEY(pk, pkey); consume(&r, sizeof(r)); out: es256_pk_free(&pk); EVP_PKEY_free(pkey); } /* * Do a dummy conversion to exercise es384_pk_from_EVP_PKEY(). */ static void es384_convert(const es384_pk_t *k) { EVP_PKEY *pkey = NULL; es384_pk_t *pk = NULL; int r; if ((pkey = es384_pk_to_EVP_PKEY(k)) == NULL || (pk = es384_pk_new()) == NULL) goto out; r = es384_pk_from_EVP_PKEY(pk, pkey); consume(&r, sizeof(r)); out: es384_pk_free(&pk); EVP_PKEY_free(pkey); } /* * Do a dummy conversion to exercise rs256_pk_from_EVP_PKEY(). */ static void rs256_convert(const rs256_pk_t *k) { EVP_PKEY *pkey = NULL; rs256_pk_t *pk = NULL; int r; if ((pkey = rs256_pk_to_EVP_PKEY(k)) == NULL || (pk = rs256_pk_new()) == NULL) goto out; r = rs256_pk_from_EVP_PKEY(pk, pkey); consume(&r, sizeof(r)); out: rs256_pk_free(&pk); EVP_PKEY_free(pkey); } /* * Do a dummy conversion to exercise eddsa_pk_from_EVP_PKEY(). */ static void eddsa_convert(const eddsa_pk_t *k) { EVP_PKEY *pkey = NULL; eddsa_pk_t *pk = NULL; int r; if ((pkey = eddsa_pk_to_EVP_PKEY(k)) == NULL || (pk = eddsa_pk_new()) == NULL) goto out; r = eddsa_pk_from_EVP_PKEY(pk, pkey); consume(&r, sizeof(r)); out: if (pk) eddsa_pk_free(&pk); if (pkey) EVP_PKEY_free(pkey); } void test(const struct param *p) { fido_assert_t *assert = NULL; es256_pk_t *es256_pk = NULL; es384_pk_t *es384_pk = NULL; rs256_pk_t *rs256_pk = NULL; eddsa_pk_t *eddsa_pk = NULL; uint8_t flags; uint32_t sigcount; int cose_alg = 0; void *pk; prng_init((unsigned int)p->seed); fuzz_clock_reset(); fido_init(FIDO_DEBUG); fido_set_log_handler(consume_str); switch (p->type & 3) { case 0: cose_alg = COSE_ES256; if ((es256_pk = es256_pk_new()) == NULL) return; es256_pk_from_ptr(es256_pk, p->es256.body, p->es256.len); pk = es256_pk; es256_convert(pk); break; case 1: cose_alg = COSE_RS256; if ((rs256_pk = rs256_pk_new()) == NULL) return; rs256_pk_from_ptr(rs256_pk, p->rs256.body, p->rs256.len); pk = rs256_pk; rs256_convert(pk); break; case 2: cose_alg = COSE_ES384; if ((es384_pk = es384_pk_new()) == NULL) return; /* XXX reuse p->es256 as es384 */ es384_pk_from_ptr(es384_pk, p->es256.body, p->es256.len); pk = es384_pk; es384_convert(pk); break; default: cose_alg = COSE_EDDSA; if ((eddsa_pk = eddsa_pk_new()) == NULL) return; eddsa_pk_from_ptr(eddsa_pk, p->eddsa.body, p->eddsa.len); pk = eddsa_pk; eddsa_convert(pk); break; } if ((assert = fido_assert_new()) == NULL) goto out; set_wire_data(p->wire_data.body, p->wire_data.len); get_assert(assert, p->opt, &p->cdh, p->rp_id, p->ext, p->up, p->uv, p->pin, p->cred_count, &p->cred); /* XXX +1 on purpose */ for (size_t i = 0; i <= fido_assert_count(assert); i++) { verify_assert(cose_alg, fido_assert_clientdata_hash_ptr(assert), fido_assert_clientdata_hash_len(assert), fido_assert_rp_id(assert), fido_assert_authdata_ptr(assert, i), fido_assert_authdata_len(assert, i), fido_assert_sig_ptr(assert, i), fido_assert_sig_len(assert, i), p->up, p->uv, p->ext, pk); + consume(fido_assert_authdata_raw_ptr(assert, i), + fido_assert_authdata_raw_len(assert, i)); consume(fido_assert_id_ptr(assert, i), fido_assert_id_len(assert, i)); consume(fido_assert_user_id_ptr(assert, i), fido_assert_user_id_len(assert, i)); consume(fido_assert_hmac_secret_ptr(assert, i), fido_assert_hmac_secret_len(assert, i)); consume_str(fido_assert_user_icon(assert, i)); consume_str(fido_assert_user_name(assert, i)); consume_str(fido_assert_user_display_name(assert, i)); consume(fido_assert_blob_ptr(assert, i), fido_assert_blob_len(assert, i)); consume(fido_assert_largeblob_key_ptr(assert, i), fido_assert_largeblob_key_len(assert, i)); flags = fido_assert_flags(assert, i); consume(&flags, sizeof(flags)); sigcount = fido_assert_sigcount(assert, i); consume(&sigcount, sizeof(sigcount)); } out: es256_pk_free(&es256_pk); es384_pk_free(&es384_pk); rs256_pk_free(&rs256_pk); eddsa_pk_free(&eddsa_pk); fido_assert_free(&assert); } void mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN { if (flags & MUTATE_SEED) p->seed = (int)seed; if (flags & MUTATE_PARAM) { mutate_byte(&p->uv); mutate_byte(&p->up); mutate_byte(&p->opt); mutate_byte(&p->type); mutate_byte(&p->cred_count); mutate_int(&p->ext); mutate_blob(&p->rs256); mutate_blob(&p->es256); mutate_blob(&p->eddsa); mutate_blob(&p->cred); mutate_blob(&p->cdh); mutate_string(p->rp_id); mutate_string(p->pin); } if (flags & MUTATE_WIREDATA) { if (p->opt & 1) { p->wire_data.len = sizeof(dummy_wire_data_u2f); memcpy(&p->wire_data.body, &dummy_wire_data_u2f, p->wire_data.len); } else { p->wire_data.len = sizeof(dummy_wire_data_fido); memcpy(&p->wire_data.body, &dummy_wire_data_fido, p->wire_data.len); } mutate_blob(&p->wire_data); } } diff --git a/contrib/libfido2/fuzz/report.tgz b/contrib/libfido2/fuzz/report.tgz index e984ee9dc765..9c01263576f1 100644 Binary files a/contrib/libfido2/fuzz/report.tgz and b/contrib/libfido2/fuzz/report.tgz differ diff --git a/contrib/libfido2/fuzz/summary.txt b/contrib/libfido2/fuzz/summary.txt index 0f79600f801d..adda3acc0761 100644 --- a/contrib/libfido2/fuzz/summary.txt +++ b/contrib/libfido2/fuzz/summary.txt @@ -1,64 +1,64 @@ Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ fuzz/clock.c 24 1 95.83% 4 0 100.00% 35 1 97.14% fuzz/pcsc.c 59 0 100.00% 8 0 100.00% 75 12 84.00% fuzz/prng.c 31 0 100.00% 2 0 100.00% 35 1 97.14% fuzz/udev.c 110 2 98.18% 17 0 100.00% 126 12 90.48% fuzz/uniform_random.c 7 1 85.71% 1 0 100.00% 12 1 91.67% fuzz/wrap.c 23 0 100.00% 3 0 100.00% 29 0 100.00% openbsd-compat/explicit_bzero.c 4 0 100.00% 1 0 100.00% 7 0 100.00% openbsd-compat/freezero.c 4 0 100.00% 1 0 100.00% 6 0 100.00% openbsd-compat/recallocarray.c 41 7 82.93% 1 0 100.00% 36 7 80.56% openbsd-compat/timingsafe_bcmp.c 4 0 100.00% 1 0 100.00% 7 0 100.00% src/aes256.c 118 3 97.46% 8 0 100.00% 157 11 92.99% -src/assert.c 605 43 92.89% 59 3 94.92% 745 46 93.83% +src/assert.c 628 45 92.83% 63 4 93.65% 782 51 93.48% src/authkey.c 52 0 100.00% 5 0 100.00% 66 0 100.00% src/bio.c 451 20 95.57% 49 2 95.92% 587 24 95.91% 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 1070 13 98.79% 55 0 100.00% 1258 31 97.54% +src/cbor.c 1070 12 98.88% 55 0 100.00% 1258 28 97.77% src/compress.c 105 14 86.67% 5 0 100.00% 122 24 80.33% -src/config.c 112 0 100.00% 11 0 100.00% 152 0 100.00% -src/cred.c 651 38 94.16% 69 2 97.10% 849 43 94.94% +src/config.c 112 0 100.00% 11 0 100.00% 154 0 100.00% +src/cred.c 653 36 94.49% 70 2 97.14% 853 39 95.43% src/credman.c 422 10 97.63% 40 0 100.00% 557 20 96.41% src/dev.c 332 65 80.42% 41 6 85.37% 378 80 78.84% src/ecdh.c 117 2 98.29% 4 0 100.00% 146 5 96.58% src/eddsa.c 88 5 94.32% 10 0 100.00% 114 9 92.11% src/err.c 122 10 91.80% 1 0 100.00% 126 10 92.06% -src/es256.c 315 7 97.78% 19 0 100.00% 372 12 96.77% -src/es384.c 158 8 94.94% 11 0 100.00% 198 15 92.42% +src/es256.c 315 5 98.41% 19 0 100.00% 372 11 97.04% +src/es384.c 158 5 96.84% 11 0 100.00% 198 11 94.44% src/hid.c 87 2 97.70% 14 0 100.00% 145 3 97.93% src/hid_linux.c 184 73 60.33% 14 7 50.00% 263 115 56.27% src/hid_unix.c 29 21 27.59% 2 0 100.00% 43 26 39.53% src/info.c 232 0 100.00% 51 0 100.00% 409 0 100.00% src/io.c 193 7 96.37% 13 0 100.00% 230 12 94.78% src/iso7816.c 18 1 94.44% 5 0 100.00% 38 1 97.37% src/largeblob.c 525 18 96.57% 30 0 100.00% 693 43 93.80% src/log.c 39 5 87.18% 7 1 85.71% 63 7 88.89% src/netlink.c 329 8 97.57% 40 0 100.00% 498 15 96.99% src/nfc.c 155 5 96.77% 12 0 100.00% 244 15 93.85% src/nfc_linux.c 172 77 55.23% 13 7 46.15% 242 126 47.93% src/pcsc.c 204 1 99.51% 13 0 100.00% 282 3 98.94% src/pin.c 426 3 99.30% 26 0 100.00% 514 4 99.22% src/random.c 6 0 100.00% 1 0 100.00% 6 0 100.00% src/reset.c 24 0 100.00% 3 0 100.00% 23 0 100.00% -src/rs1.c 25 1 96.00% 3 0 100.00% 39 3 92.31% -src/rs256.c 149 10 93.29% 13 0 100.00% 182 14 92.31% +src/rs1.c 22 2 90.91% 3 0 100.00% 36 6 83.33% +src/rs256.c 146 9 93.84% 13 0 100.00% 179 16 91.06% src/time.c 43 3 93.02% 3 0 100.00% 43 2 95.35% src/touch.c 67 0 100.00% 2 0 100.00% 79 0 100.00% src/tpm.c 103 0 100.00% 9 0 100.00% 194 0 100.00% src/types.c 29 0 100.00% 7 0 100.00% 56 0 100.00% src/u2f.c 572 4 99.30% 17 0 100.00% 726 12 98.35% src/util.c 14 1 92.86% 1 0 100.00% 14 1 92.86% Files which contain no functions: fuzz/mutator_aux.h 0 0 - 0 0 - 0 0 - openbsd-compat/openbsd-compat.h 0 0 - 0 0 - 0 0 - openbsd-compat/time.h 0 0 - 0 0 - 0 0 - src/extern.h 0 0 - 0 0 - 0 0 - src/fallthrough.h 0 0 - 0 0 - 0 0 - src/fido.h 0 0 - 0 0 - 0 0 - src/fido/err.h 0 0 - 0 0 - 0 0 - src/fido/param.h 0 0 - 0 0 - 0 0 - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -TOTAL 8711 492 94.35% 737 28 96.20% 11320 771 93.19% +TOTAL 8730 486 94.43% 742 29 96.09% 11357 769 93.23% diff --git a/contrib/libfido2/man/CMakeLists.txt b/contrib/libfido2/man/CMakeLists.txt index a47767fb6d4b..6616e4ea9a04 100644 --- a/contrib/libfido2/man/CMakeLists.txt +++ b/contrib/libfido2/man/CMakeLists.txt @@ -1,410 +1,413 @@ # Copyright (c) 2018-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. # SPDX-License-Identifier: BSD-2-Clause find_program(MANDOC_PATH mandoc) find_program(GZIP_PATH gzip) message(STATUS "MANDOC_PATH: ${MANDOC_PATH}") message(STATUS "GZIP_PATH: ${GZIP_PATH}") list(APPEND MAN_SOURCES eddsa_pk_new.3 es256_pk_new.3 es384_pk_new.3 fido2-assert.1 fido2-cred.1 fido2-token.1 fido_init.3 fido_assert_new.3 fido_assert_allow_cred.3 fido_assert_set_authdata.3 fido_assert_verify.3 fido_bio_dev_get_info.3 fido_bio_enroll_new.3 fido_bio_info_new.3 fido_bio_template.3 fido_cbor_info_new.3 fido_cred_new.3 fido_cred_exclude.3 fido_credman_metadata_new.3 fido_cred_set_authdata.3 fido_cred_verify.3 fido_dev_enable_entattest.3 fido_dev_get_assert.3 fido_dev_get_touch_begin.3 fido_dev_info_manifest.3 fido_dev_largeblob_get.3 fido_dev_make_cred.3 fido_dev_open.3 fido_dev_set_io_functions.3 fido_dev_set_pin.3 fido_strerr.3 rs256_pk_new.3 ) list(APPEND MAN_ALIAS eddsa_pk_new eddsa_pk_free eddsa_pk_new eddsa_pk_from_EVP_PKEY eddsa_pk_new eddsa_pk_from_ptr eddsa_pk_new eddsa_pk_to_EVP_PKEY es256_pk_new es256_pk_free es256_pk_new es256_pk_from_EC_KEY es256_pk_new es256_pk_from_EVP_PKEY es256_pk_new es256_pk_from_ptr es256_pk_new es256_pk_to_EVP_PKEY es384_pk_new es384_pk_free es384_pk_new es384_pk_from_EC_KEY es384_pk_new es384_pk_from_EVP_PKEY es384_pk_new es384_pk_from_ptr es384_pk_new es384_pk_to_EVP_PKEY fido_assert_allow_cred fido_assert_empty_allow_list fido_assert_new fido_assert_authdata_len fido_assert_new fido_assert_authdata_ptr + fido_assert_new fido_assert_authdata_raw_len + fido_assert_new fido_assert_authdata_raw_ptr fido_assert_new fido_assert_blob_len fido_assert_new fido_assert_blob_ptr fido_assert_new fido_assert_clientdata_hash_len fido_assert_new fido_assert_clientdata_hash_ptr fido_assert_new fido_assert_count fido_assert_new fido_assert_flags fido_assert_new fido_assert_free fido_assert_new fido_assert_hmac_secret_len fido_assert_new fido_assert_hmac_secret_ptr fido_assert_new fido_assert_id_len fido_assert_new fido_assert_id_ptr fido_assert_new fido_assert_largeblob_key_len fido_assert_new fido_assert_largeblob_key_ptr fido_assert_new fido_assert_rp_id fido_assert_new fido_assert_sigcount fido_assert_new fido_assert_sig_len fido_assert_new fido_assert_sig_ptr fido_assert_new fido_assert_user_display_name fido_assert_new fido_assert_user_icon fido_assert_new fido_assert_user_id_len fido_assert_new fido_assert_user_id_ptr fido_assert_new fido_assert_user_name fido_assert_set_authdata fido_assert_set_authdata_raw fido_assert_set_authdata fido_assert_set_clientdata fido_assert_set_authdata fido_assert_set_clientdata_hash fido_assert_set_authdata fido_assert_set_count fido_assert_set_authdata fido_assert_set_extensions fido_assert_set_authdata fido_assert_set_hmac_salt fido_assert_set_authdata fido_assert_set_hmac_secret fido_assert_set_authdata fido_assert_set_rp fido_assert_set_authdata fido_assert_set_sig fido_assert_set_authdata fido_assert_set_up fido_assert_set_authdata fido_assert_set_uv + fido_assert_set_authdata fido_assert_set_winhello_appid fido_bio_dev_get_info fido_bio_dev_enroll_begin fido_bio_dev_get_info fido_bio_dev_enroll_cancel fido_bio_dev_get_info fido_bio_dev_enroll_continue fido_bio_dev_get_info fido_bio_dev_enroll_remove fido_bio_dev_get_info fido_bio_dev_get_template_array fido_bio_dev_get_info fido_bio_dev_set_template_name fido_bio_enroll_new fido_bio_enroll_free fido_bio_enroll_new fido_bio_enroll_last_status fido_bio_enroll_new fido_bio_enroll_remaining_samples fido_bio_info_new fido_bio_info_free fido_bio_info_new fido_bio_info_max_samples fido_bio_info_new fido_bio_info_type fido_bio_template fido_bio_template_array_count fido_bio_template fido_bio_template_array_free fido_bio_template fido_bio_template_array_new fido_bio_template fido_bio_template_free fido_bio_template fido_bio_template_id_len fido_bio_template fido_bio_template_id_ptr fido_bio_template fido_bio_template_name fido_bio_template fido_bio_template_new fido_bio_template fido_bio_template_set_id fido_bio_template fido_bio_template_set_name fido_cbor_info_new fido_cbor_info_aaguid_len fido_cbor_info_new fido_cbor_info_aaguid_ptr fido_cbor_info_new fido_cbor_info_algorithm_cose fido_cbor_info_new fido_cbor_info_algorithm_count fido_cbor_info_new fido_cbor_info_algorithm_type fido_cbor_info_new fido_cbor_info_certs_len fido_cbor_info_new fido_cbor_info_certs_name_ptr fido_cbor_info_new fido_cbor_info_certs_value_ptr fido_cbor_info_new fido_cbor_info_extensions_len fido_cbor_info_new fido_cbor_info_extensions_ptr fido_cbor_info_new fido_cbor_info_free fido_cbor_info_new fido_cbor_info_fwversion 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_maxlargeblob fido_cbor_info_new fido_cbor_info_maxmsgsiz fido_cbor_info_new fido_cbor_info_maxrpid_minpinlen fido_cbor_info_new fido_cbor_info_minpinlen fido_cbor_info_new fido_cbor_info_new_pin_required fido_cbor_info_new fido_cbor_info_options_len fido_cbor_info_new fido_cbor_info_options_name_ptr fido_cbor_info_new fido_cbor_info_options_value_ptr fido_cbor_info_new fido_cbor_info_protocols_len fido_cbor_info_new fido_cbor_info_protocols_ptr fido_cbor_info_new fido_cbor_info_rk_remaining fido_cbor_info_new fido_cbor_info_transports_len fido_cbor_info_new fido_cbor_info_transports_ptr fido_cbor_info_new fido_cbor_info_uv_attempts fido_cbor_info_new fido_cbor_info_uv_modality fido_cbor_info_new fido_cbor_info_versions_len fido_cbor_info_new fido_cbor_info_versions_ptr fido_cbor_info_new fido_dev_get_cbor_info fido_cred_exclude fido_cred_empty_exclude_list fido_cred_new fido_cred_aaguid_len fido_cred_new fido_cred_aaguid_ptr fido_cred_new fido_cred_attstmt_len fido_cred_new fido_cred_attstmt_ptr fido_cred_new fido_cred_authdata_len fido_cred_new fido_cred_authdata_ptr fido_cred_new fido_cred_authdata_raw_len fido_cred_new fido_cred_authdata_raw_ptr fido_cred_new fido_cred_clientdata_hash_len fido_cred_new fido_cred_clientdata_hash_ptr fido_cred_new fido_cred_display_name fido_cred_new fido_cred_flags fido_cred_new fido_cred_fmt fido_cred_new fido_cred_free fido_cred_new fido_cred_id_len fido_cred_new fido_cred_id_ptr fido_cred_new fido_cred_largeblob_key_len fido_cred_new fido_cred_largeblob_key_ptr fido_cred_new fido_cred_pin_minlen fido_cred_new fido_cred_prot fido_cred_new fido_cred_pubkey_len fido_cred_new fido_cred_pubkey_ptr fido_cred_new fido_cred_rp_id fido_cred_new fido_cred_rp_name fido_cred_new fido_cred_sigcount fido_cred_new fido_cred_sig_len fido_cred_new fido_cred_sig_ptr fido_cred_new fido_cred_type fido_cred_new fido_cred_user_id_len fido_cred_new fido_cred_user_id_ptr fido_cred_new fido_cred_user_name fido_cred_new fido_cred_x5c_len fido_cred_new fido_cred_x5c_ptr fido_cred_verify fido_cred_verify_self fido_credman_metadata_new fido_credman_del_dev_rk fido_credman_metadata_new fido_credman_get_dev_metadata fido_credman_metadata_new fido_credman_get_dev_rk fido_credman_metadata_new fido_credman_get_dev_rp fido_credman_metadata_new fido_credman_metadata_free fido_credman_metadata_new fido_credman_rk fido_credman_metadata_new fido_credman_rk_count fido_credman_metadata_new fido_credman_rk_existing fido_credman_metadata_new fido_credman_rk_free fido_credman_metadata_new fido_credman_rk_new fido_credman_metadata_new fido_credman_rk_remaining fido_credman_metadata_new fido_credman_rp_count fido_credman_metadata_new fido_credman_rp_free fido_credman_metadata_new fido_credman_rp_id fido_credman_metadata_new fido_credman_rp_id_hash_len fido_credman_metadata_new fido_credman_rp_id_hash_ptr fido_credman_metadata_new fido_credman_rp_name fido_credman_metadata_new fido_credman_rp_new fido_credman_metadata_new fido_credman_set_dev_rk fido_cred_set_authdata fido_cred_set_attstmt fido_cred_set_authdata fido_cred_set_authdata_raw fido_cred_set_authdata fido_cred_set_blob fido_cred_set_authdata fido_cred_set_clientdata fido_cred_set_authdata fido_cred_set_clientdata_hash fido_cred_set_authdata fido_cred_set_extensions fido_cred_set_authdata fido_cred_set_fmt fido_cred_set_authdata fido_cred_set_id fido_cred_set_authdata fido_cred_set_pin_minlen fido_cred_set_authdata fido_cred_set_prot fido_cred_set_authdata fido_cred_set_rk fido_cred_set_authdata fido_cred_set_rp fido_cred_set_authdata fido_cred_set_sig fido_cred_set_authdata fido_cred_set_type fido_cred_set_authdata fido_cred_set_user fido_cred_set_authdata fido_cred_set_uv fido_cred_set_authdata fido_cred_set_x509 fido_dev_enable_entattest fido_dev_toggle_always_uv fido_dev_enable_entattest fido_dev_force_pin_change fido_dev_enable_entattest fido_dev_set_pin_minlen fido_dev_enable_entattest fido_dev_set_pin_minlen_rpid fido_dev_get_touch_begin fido_dev_get_touch_status fido_dev_info_manifest fido_dev_info_free fido_dev_info_manifest fido_dev_info_manufacturer_string fido_dev_info_manifest fido_dev_info_new fido_dev_info_manifest fido_dev_info_path fido_dev_info_manifest fido_dev_info_product fido_dev_info_manifest fido_dev_info_product_string fido_dev_info_manifest fido_dev_info_ptr fido_dev_info_manifest fido_dev_info_set fido_dev_info_manifest fido_dev_info_vendor fido_dev_open fido_dev_build fido_dev_open fido_dev_cancel fido_dev_open fido_dev_close fido_dev_open fido_dev_flags fido_dev_open fido_dev_force_fido2 fido_dev_open fido_dev_force_u2f fido_dev_open fido_dev_free fido_dev_open fido_dev_has_pin fido_dev_open fido_dev_has_uv fido_dev_open fido_dev_is_fido2 fido_dev_open fido_dev_is_winhello fido_dev_open fido_dev_major fido_dev_open fido_dev_minor fido_dev_open fido_dev_new fido_dev_open fido_dev_new_with_info fido_dev_open fido_dev_open_with_info fido_dev_open fido_dev_protocol fido_dev_open fido_dev_supports_cred_prot fido_dev_open fido_dev_supports_credman fido_dev_open fido_dev_supports_permissions fido_dev_open fido_dev_supports_pin fido_dev_open fido_dev_supports_uv fido_dev_set_pin fido_dev_get_retry_count fido_dev_set_pin fido_dev_get_uv_retry_count fido_dev_set_pin fido_dev_reset fido_dev_set_io_functions fido_dev_io_handle fido_dev_set_io_functions fido_dev_set_sigmask fido_dev_set_io_functions fido_dev_set_timeout fido_dev_set_io_functions fido_dev_set_transport_functions fido_dev_largeblob_get fido_dev_largeblob_set fido_dev_largeblob_get fido_dev_largeblob_remove fido_dev_largeblob_get fido_dev_largeblob_get_array fido_dev_largeblob_get fido_dev_largeblob_set_array fido_init fido_set_log_handler rs256_pk_new rs256_pk_free rs256_pk_new rs256_pk_from_ptr rs256_pk_new rs256_pk_from_EVP_PKEY rs256_pk_new rs256_pk_from_RSA rs256_pk_new rs256_pk_to_EVP_PKEY ) list(LENGTH MAN_ALIAS MAN_ALIAS_LEN) math(EXPR MAN_ALIAS_MAX "${MAN_ALIAS_LEN} - 2") # man_copy foreach(f ${MAN_SOURCES}) add_custom_command(OUTPUT ${f} COMMAND cp -f ${PROJECT_SOURCE_DIR}/man/${f} . DEPENDS ${f}) list(APPEND COPY_FILES ${f}) endforeach() # man_lint foreach(f ${MAN_SOURCES}) add_custom_command(OUTPUT ${f}.lint COMMAND mandoc -T lint -W warning ${f} > ${f}.lint DEPENDS ${f}) list(APPEND LINT_FILES ${f}.lint) endforeach() # man_html foreach(f ${MAN_SOURCES}) string(REGEX REPLACE "\\.[13]$" "" g ${f}) add_custom_command(OUTPUT ${g}.html COMMAND mandoc -T html -O man="%N.html",style=style.css -I os="Yubico AB" ${f} > ${g}.html DEPENDS ${f}) list(APPEND HTML_FILES ${g}.html) endforeach() # man_html_partial foreach(f ${MAN_SOURCES}) string(REGEX REPLACE "\\.[13]$" "" g ${f}) add_custom_command(OUTPUT ${g}.partial COMMAND cat ${PROJECT_SOURCE_DIR}/man/dyc.css > ${g}.partial COMMAND mandoc -T html -O man="%N.html",fragment ${f} >> ${g}.partial DEPENDS ${f}) list(APPEND HTML_PARTIAL_FILES ${g}.partial) endforeach() # man_gzip foreach(f ${MAN_SOURCES}) add_custom_command(OUTPUT ${f}.gz COMMAND gzip -cn ${f} > ${f}.gz DEPENDS ${f}) list(APPEND GZ_FILES ${f}.gz) endforeach() macro(define_symlink_target NAME EXT) foreach(i RANGE 0 ${MAN_ALIAS_MAX} 2) math(EXPR j "${i} + 1") list(GET MAN_ALIAS ${i} SRC) list(GET MAN_ALIAS ${j} DST) add_custom_command(OUTPUT ${DST}.${EXT} COMMAND ln -sf ${SRC}.${EXT} ${DST}.${EXT}) list(APPEND ${NAME}_LINK_FILES ${DST}.${EXT}) endforeach() add_custom_target(${NAME} DEPENDS ${${NAME}_LINK_FILES}) endmacro() add_custom_target(man_copy DEPENDS ${COPY_FILES}) add_custom_target(man_lint DEPENDS ${LINT_FILES}) add_custom_target(man_html DEPENDS ${HTML_FILES}) add_custom_target(man_html_partial DEPENDS ${HTML_PARTIAL_FILES}) add_custom_target(man_gzip DEPENDS ${GZ_FILES}) define_symlink_target(man_symlink 3) define_symlink_target(man_symlink_html html) define_symlink_target(man_symlink_html_partial partial) define_symlink_target(man_symlink_gzip 3.gz) add_dependencies(man_symlink man_copy) add_dependencies(man_lint man_symlink) add_dependencies(man_html man_lint) add_dependencies(man_symlink_html man_html) add_dependencies(man_html_partial man_lint) add_dependencies(man_symlink_html_partial man_html_partial) add_custom_target(man ALL) if(MANDOC_PATH) add_dependencies(man man_symlink_html) add_dependencies(man_gzip man_lint) install(FILES ${PROJECT_SOURCE_DIR}/man/style.css DESTINATION "${CMAKE_INSTALL_DOCDIR}/html") foreach(f ${MAN_SOURCES}) string(REGEX REPLACE "\\.[13]$" "" f ${f}) install(FILES ${PROJECT_BINARY_DIR}/man/${f}.html DESTINATION "${CMAKE_INSTALL_DOCDIR}/html") endforeach() foreach(i RANGE 0 ${MAN_ALIAS_MAX} 2) math(EXPR j "${i} + 1") list(GET MAN_ALIAS ${j} DST) install(FILES ${PROJECT_BINARY_DIR}/man/${DST}.html DESTINATION "${CMAKE_INSTALL_DOCDIR}/html") endforeach() endif() if(GZIP_PATH) add_dependencies(man_gzip man_copy) add_dependencies(man_symlink_gzip man_gzip) add_dependencies(man man_symlink_gzip) foreach(f ${MAN_SOURCES}) if (${f} MATCHES ".1$") install(FILES ${PROJECT_BINARY_DIR}/man/${f}.gz DESTINATION "${CMAKE_INSTALL_MANDIR}/man1") elseif(${f} MATCHES ".3$") install(FILES ${PROJECT_BINARY_DIR}/man/${f}.gz DESTINATION "${CMAKE_INSTALL_MANDIR}/man3") endif() endforeach() foreach(i RANGE 0 ${MAN_ALIAS_MAX} 2) math(EXPR j "${i} + 1") list(GET MAN_ALIAS ${j} DST) install(FILES ${PROJECT_BINARY_DIR}/man/${DST}.3.gz DESTINATION "${CMAKE_INSTALL_MANDIR}/man3") endforeach() elseif(NOT MSVC) add_dependencies(man man_symlink) foreach(f ${MAN_SOURCES}) if (${f} MATCHES ".1$") install(FILES ${PROJECT_BINARY_DIR}/man/${f} DESTINATION "${CMAKE_INSTALL_MANDIR}/man1") elseif(${f} MATCHES ".3$") install(FILES ${PROJECT_BINARY_DIR}/man/${f} DESTINATION "${CMAKE_INSTALL_MANDIR}/man3") endif() endforeach() foreach(i RANGE 0 ${MAN_ALIAS_MAX} 2) math(EXPR j "${i} + 1") list(GET MAN_ALIAS ${j} DST) install(FILES ${PROJECT_BINARY_DIR}/man/${DST}.3 DESTINATION "${CMAKE_INSTALL_MANDIR}/man3") endforeach() endif() diff --git a/contrib/libfido2/man/fido2-assert.1 b/contrib/libfido2/man/fido2-assert.1 index 0ee6e0942ba2..882b7ab1feaa 100644 --- a/contrib/libfido2/man/fido2-assert.1 +++ b/contrib/libfido2/man/fido2-assert.1 @@ -1,279 +1,286 @@ -.\" Copyright (c) 2018 Yubico AB. All rights reserved. +.\" Copyright (c) 2018-2023 Yubico AB. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions are .\" met: .\" .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in .\" the documentation and/or other materials provided with the .\" distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS .\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR .\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT .\" HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE .\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" SPDX-License-Identifier: BSD-2-Clause .\" -.Dd $Mdocdate: November 5 2019 $ +.Dd $Mdocdate: July 3 2023 $ .Dt FIDO2-ASSERT 1 .Os .Sh NAME .Nm fido2-assert .Nd get/verify a FIDO2 assertion .Sh SYNOPSIS .Nm .Fl G -.Op Fl bdhpruv +.Op Fl bdhpruvw .Op Fl t Ar option .Op Fl i Ar input_file .Op Fl o Ar output_file .Ar device .Nm .Fl V .Op Fl dhpv .Op Fl i Ar input_file .Ar key_file .Op Ar type .Sh DESCRIPTION .Nm gets or verifies a FIDO2 assertion. .Pp The input of .Nm is defined by the parameters of the assertion to be obtained/verified. See the .Sx INPUT FORMAT section for details. .Pp The output of .Nm is defined by the result of the selected operation. See the .Sx OUTPUT FORMAT section for details. .Pp If an assertion is successfully obtained or verified, .Nm exits 0. Otherwise, .Nm exits 1. .Pp The options are as follows: .Bl -tag -width Ds .It Fl G Tells .Nm to obtain a new assertion from .Ar device . .It Fl V Tells .Nm to verify an assertion using the PEM-encoded public key in .Ar key_file of type .Ar type , where .Ar type may be .Em es256 (denoting ECDSA over NIST P-256 with SHA-256), .Em rs256 (denoting 2048-bit RSA with PKCS#1.5 padding and SHA-256), or .Em eddsa (denoting EDDSA over Curve25519 with SHA-512). If .Ar type is not specified, .Em es256 is assumed. .It Fl b Request the credential's .Dq largeBlobKey , a 32-byte symmetric key associated with the asserted credential. .It Fl h If obtaining an assertion, enable the FIDO2 hmac-secret extension. If verifying an assertion, check whether the extension data bit was signed by the authenticator. .It Fl d Causes .Nm to emit debugging output on .Em stderr . .It Fl i Ar input_file Tells .Nm to read the parameters of the assertion from .Ar input_file instead of .Em stdin . .It Fl o Ar output_file Tells .Nm to write output on .Ar output_file instead of .Em stdout . .It Fl p If obtaining an assertion, request user presence. If verifying an assertion, check whether the user presence bit was signed by the authenticator. .It Fl r Obtain an assertion using a resident credential. If .Fl r is specified, .Nm will not expect a credential id in its input, and may output multiple assertions. Resident credentials are called .Dq discoverable credentials in CTAP 2.1. .It Fl t Ar option Toggles a key/value .Ar option , where .Ar option is a string of the form .Dq key=value . The options supported at present are: .Bl -tag -width Ds .It Cm up Ns = Ns Ar true|false Asks the authenticator for user presence to be enabled or disabled. .It Cm uv Ns = Ns Ar true|false Asks the authenticator for user verification to be enabled or disabled. .It Cm pin Ns = Ns Ar true|false Tells .Nm whether to prompt for a PIN and request user verification. .El .Pp The .Fl t option may be specified multiple times. .It Fl u Obtain an assertion using U2F. By default, .Nm will use FIDO2 if supported by the authenticator, and fallback to U2F otherwise. .It Fl v If obtaining an assertion, prompt the user for a PIN and request user verification from the authenticator. If verifying an assertion, check whether the user verification bit was signed by the authenticator. +.It Fl w +Tells +.Nm +that the first line of input when obtaining an assertion shall be +interpreted as unhashed client data. +This is required by Windows Hello, which calculates the client data hash +internally. .El .Pp If a .Em tty is available, .Nm will use it to obtain the PIN. Otherwise, .Em stdin is used. .Sh INPUT FORMAT The input of .Nm consists of base64 blobs and UTF-8 strings separated by newline characters ('\\n'). .Pp When obtaining an assertion, .Nm expects its input to consist of: .Pp .Bl -enum -offset indent -compact .It client data hash (base64 blob); .It relying party id (UTF-8 string); .It credential id, if credential not resident (base64 blob); .It hmac salt, if the FIDO2 hmac-secret extension is enabled (base64 blob); .El .Pp When verifying an assertion, .Nm expects its input to consist of: .Pp .Bl -enum -offset indent -compact .It client data hash (base64 blob); .It relying party id (UTF-8 string); .It authenticator data (base64 blob); .It assertion signature (base64 blob); .El .Pp UTF-8 strings passed to .Nm must not contain embedded newline or NUL characters. .Sh OUTPUT FORMAT The output of .Nm consists of base64 blobs and UTF-8 strings separated by newline characters ('\\n'). .Pp For each generated assertion, .Nm outputs: .Pp .Bl -enum -offset indent -compact .It client data hash (base64 blob); .It relying party id (UTF-8 string); .It authenticator data (base64 blob); .It assertion signature (base64 blob); .It user id, if credential resident (base64 blob); .It hmac secret, if the FIDO2 hmac-secret extension is enabled (base64 blob); .It the credential's associated 32-byte symmetric key .Pq Dq largeBlobKey , if requested (base64 blob). .El .Pp When verifying an assertion, .Nm produces no output. .Sh EXAMPLES Assuming .Pa cred contains a .Em es256 credential created according to the steps outlined in .Xr fido2-cred 1 , obtain an assertion from an authenticator at .Pa /dev/hidraw5 and verify it: .Pp .Dl $ echo assertion challenge | openssl sha256 -binary | base64 > assert_param .Dl $ echo relying party >> assert_param .Dl $ head -1 cred >> assert_param .Dl $ tail -n +2 cred > pubkey .Dl $ fido2-assert -G -i assert_param /dev/hidraw5 | fido2-assert -V pubkey es256 .Sh SEE ALSO .Xr fido2-cred 1 , .Xr fido2-token 1 diff --git a/contrib/libfido2/man/fido2-cred.1 b/contrib/libfido2/man/fido2-cred.1 index bd82499acac4..3f181db6d135 100644 --- a/contrib/libfido2/man/fido2-cred.1 +++ b/contrib/libfido2/man/fido2-cred.1 @@ -1,290 +1,297 @@ -.\" Copyright (c) 2018 Yubico AB. All rights reserved. +.\" Copyright (c) 2018-2023 Yubico AB. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions are .\" met: .\" .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in .\" the documentation and/or other materials provided with the .\" distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS .\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR .\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT .\" HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE .\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" SPDX-License-Identifier: BSD-2-Clause .\" -.Dd $Mdocdate: November 5 2019 $ +.Dd $Mdocdate: July 3 2023 $ .Dt FIDO2-CRED 1 .Os .Sh NAME .Nm fido2-cred .Nd make/verify a FIDO2 credential .Sh SYNOPSIS .Nm .Fl M -.Op Fl bdhqruv +.Op Fl bdhqruvw .Op Fl c Ar cred_protect .Op Fl i Ar input_file .Op Fl o Ar output_file .Ar device .Op Ar type .Nm .Fl V .Op Fl dhv .Op Fl c Ar cred_protect .Op Fl i Ar input_file .Op Fl o Ar output_file .Op Ar type .Sh DESCRIPTION .Nm makes or verifies a FIDO2 credential. .Pp A credential .Ar type may be .Em es256 (denoting ECDSA over NIST P-256 with SHA-256), .Em rs256 (denoting 2048-bit RSA with PKCS#1.5 padding and SHA-256), or .Em eddsa (denoting EDDSA over Curve25519 with SHA-512). If .Ar type is not specified, .Em es256 is assumed. .Pp When making a credential, the authenticator may require the user to authenticate with a PIN. If the .Fl q option is not specified, .Nm will prompt the user for the PIN. If a .Em tty is available, .Nm will use it to obtain the PIN. Otherwise, .Em stdin is used. .Pp The input of .Nm is defined by the parameters of the credential to be made/verified. See the .Sx INPUT FORMAT section for details. .Pp The output of .Nm is defined by the result of the selected operation. See the .Sx OUTPUT FORMAT section for details. .Pp If a credential is successfully created or verified, .Nm exits 0. Otherwise, .Nm exits 1. .Pp The options are as follows: .Bl -tag -width Ds .It Fl M Tells .Nm to make a new credential on .Ar device . .It Fl V Tells .Nm to verify a credential. .It Fl b Request the credential's .Dq largeBlobKey , a 32-byte symmetric key associated with the generated credential. .It Fl c Ar cred_protect If making a credential, set the credential's protection level to .Ar cred_protect , where .Ar cred_protect is the credential's protection level in decimal notation. Please refer to .In fido/param.h for the set of possible values. If verifying a credential, check whether the credential's protection level was signed by the authenticator as .Ar cred_protect . .It Fl d Causes .Nm to emit debugging output on .Em stderr . .It Fl h If making a credential, enable the FIDO2 hmac-secret extension. If verifying a credential, check whether the extension data bit was signed by the authenticator. .It Fl i Ar input_file Tells .Nm to read the parameters of the credential from .Ar input_file instead of .Em stdin . .It Fl o Ar output_file Tells .Nm to write output on .Ar output_file instead of .Em stdout . .It Fl q Tells .Nm to be quiet. If a PIN is required and .Fl q is specified, .Nm will fail. .It Fl r Create a resident credential. Resident credentials are called .Dq discoverable credentials in CTAP 2.1. .It Fl u Create a U2F credential. By default, .Nm will use FIDO2 if supported by the authenticator, and fallback to U2F otherwise. .It Fl v If making a credential, request user verification. If verifying a credential, check whether the user verification bit was signed by the authenticator. +.It Fl w +Tells +.Nm +that the first line of input when making a credential shall be +interpreted as unhashed client data. +This is required by Windows Hello, which calculates the client data hash +internally. .El .Sh INPUT FORMAT The input of .Nm consists of base64 blobs and UTF-8 strings separated by newline characters ('\\n'). .Pp When making a credential, .Nm expects its input to consist of: .Pp .Bl -enum -offset indent -compact .It client data hash (base64 blob); .It relying party id (UTF-8 string); .It user name (UTF-8 string); .It user id (base64 blob). .El .Pp When verifying a credential, .Nm expects its input to consist of: .Pp .Bl -enum -offset indent -compact .It client data hash (base64 blob); .It relying party id (UTF-8 string); .It credential format (UTF-8 string); .It authenticator data (base64 blob); .It credential id (base64 blob); .It attestation signature (base64 blob); .It attestation certificate (optional, base64 blob). .El .Pp UTF-8 strings passed to .Nm must not contain embedded newline or NUL characters. .Sh OUTPUT FORMAT The output of .Nm consists of base64 blobs, UTF-8 strings, and PEM-encoded public keys separated by newline characters ('\\n'). .Pp Upon the successful generation of a credential, .Nm outputs: .Pp .Bl -enum -offset indent -compact .It client data hash (base64 blob); .It relying party id (UTF-8 string); .It credential format (UTF-8 string); .It authenticator data (base64 blob); .It credential id (base64 blob); .It attestation signature (base64 blob); .It attestation certificate, if present (base64 blob). .It the credential's associated 32-byte symmetric key .Pq Dq largeBlobKey , if present (base64 blob). .El .Pp Upon the successful verification of a credential, .Nm outputs: .Pp .Bl -enum -offset indent -compact .It credential id (base64 blob); .It PEM-encoded credential key. .El .Sh EXAMPLES Create a new .Em es256 credential on .Pa /dev/hidraw5 , verify it, and save the id and the public key of the credential in .Em cred : .Pp .Dl $ echo credential challenge | openssl sha256 -binary | base64 > cred_param .Dl $ echo relying party >> cred_param .Dl $ echo user name >> cred_param .Dl $ dd if=/dev/urandom bs=1 count=32 | base64 >> cred_param .Dl $ fido2-cred -M -i cred_param /dev/hidraw5 | fido2-cred -V -o cred .Sh SEE ALSO .Xr fido2-assert 1 , .Xr fido2-token 1 .Sh CAVEATS Please note that .Nm handles Basic Attestation and Self Attestation transparently. In the case of Basic Attestation, the validity of the authenticator's attestation certificate is .Em not verified. diff --git a/contrib/libfido2/man/fido_assert_new.3 b/contrib/libfido2/man/fido_assert_new.3 index 192625e32630..fdc74a90892c 100644 --- a/contrib/libfido2/man/fido_assert_new.3 +++ b/contrib/libfido2/man/fido_assert_new.3 @@ -1,285 +1,293 @@ -.\" Copyright (c) 2018-2022 Yubico AB. All rights reserved. +.\" Copyright (c) 2018-2023 Yubico AB. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions are .\" met: .\" .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in .\" the documentation and/or other materials provided with the .\" distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS .\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR .\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT .\" HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE .\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" SPDX-License-Identifier: BSD-2-Clause .\" -.Dd $Mdocdate: April 27 2022 $ +.Dd $Mdocdate: June 19 2023 $ .Dt FIDO_ASSERT_NEW 3 .Os .Sh NAME .Nm fido_assert_new , .Nm fido_assert_free , .Nm fido_assert_count , .Nm fido_assert_rp_id , .Nm fido_assert_user_display_name , .Nm fido_assert_user_icon , .Nm fido_assert_user_name , .Nm fido_assert_authdata_ptr , +.Nm fido_assert_authdata_raw_ptr , .Nm fido_assert_blob_ptr , .Nm fido_assert_clientdata_hash_ptr , .Nm fido_assert_hmac_secret_ptr , .Nm fido_assert_largeblob_key_ptr , .Nm fido_assert_user_id_ptr , .Nm fido_assert_sig_ptr , .Nm fido_assert_id_ptr , .Nm fido_assert_authdata_len , +.Nm fido_assert_authdata_raw_len , .Nm fido_assert_blob_len , .Nm fido_assert_clientdata_hash_len , .Nm fido_assert_hmac_secret_len , .Nm fido_assert_largeblob_key_len , .Nm fido_assert_user_id_len , .Nm fido_assert_sig_len , .Nm fido_assert_id_len , .Nm fido_assert_sigcount , .Nm fido_assert_flags .Nd FIDO2 assertion API .Sh SYNOPSIS .In fido.h .Ft fido_assert_t * .Fn fido_assert_new "void" .Ft void .Fn fido_assert_free "fido_assert_t **assert_p" .Ft size_t .Fn fido_assert_count "const fido_assert_t *assert" .Ft const char * .Fn fido_assert_rp_id "const fido_assert_t *assert" .Ft const char * .Fn fido_assert_user_display_name "const fido_assert_t *assert" "size_t idx" .Ft const char * .Fn fido_assert_user_icon "const fido_assert_t *assert" "size_t idx" .Ft const char * .Fn fido_assert_user_name "const fido_assert_t *assert" "size_t idx" .Ft const unsigned char * .Fn fido_assert_authdata_ptr "const fido_assert_t *assert" "size_t idx" .Ft const unsigned char * +.Fn fido_assert_authdata_raw_ptr "const fido_assert_t *assert" "size_t idx" +.Ft const unsigned char * .Fn fido_assert_clientdata_hash_ptr "const fido_assert_t *assert" .Ft const unsigned char * .Fn fido_assert_blob_ptr "const fido_assert_t *assert" "size_t idx" .Ft const unsigned char * .Fn fido_assert_hmac_secret_ptr "const fido_assert_t *assert" "size_t idx" .Ft const unsigned char * .Fn fido_assert_largeblob_key_ptr "const fido_assert_t *assert" "size_t idx" .Ft const unsigned char * .Fn fido_assert_user_id_ptr "const fido_assert_t *assert" "size_t idx" .Ft const unsigned char * .Fn fido_assert_sig_ptr "const fido_assert_t *assert" "size_t idx" .Ft const unsigned char * .Fn fido_assert_id_ptr "const fido_assert_t *assert" "size_t idx" .Ft size_t .Fn fido_assert_authdata_len "const fido_assert_t *assert" "size_t idx" .Ft size_t +.Fn fido_assert_authdata_raw_len "const fido_assert_t *assert" "size_t idx" +.Ft size_t .Fn fido_assert_clientdata_hash_len "const fido_assert_t *assert" .Ft size_t .Fn fido_assert_blob_len "const fido_assert_t *assert" "size_t idx" .Ft size_t .Fn fido_assert_hmac_secret_len "const fido_assert_t *assert" "size_t idx" .Ft size_t .Fn fido_assert_largeblob_key_len "const fido_assert_t *assert" "size_t idx" .Ft size_t .Fn fido_assert_user_id_len "const fido_assert_t *assert" "size_t idx" .Ft size_t .Fn fido_assert_sig_len "const fido_assert_t *assert" "size_t idx" .Ft size_t .Fn fido_assert_id_len "const fido_assert_t *assert" "size_t idx" .Ft uint32_t .Fn fido_assert_sigcount "const fido_assert_t *assert" "size_t idx" .Ft uint8_t .Fn fido_assert_flags "const fido_assert_t *assert" "size_t idx" .Sh DESCRIPTION A FIDO2 assertion is a collection of statements, each statement a map between a challenge, a credential, a signature, and ancillary attributes. In .Em libfido2 , a FIDO2 assertion is abstracted by the .Vt fido_assert_t type. The functions described in this page allow a .Vt fido_assert_t type to be allocated, deallocated, and inspected. For other operations on .Vt fido_assert_t , please refer to .Xr fido_assert_set_authdata 3 , .Xr fido_assert_allow_cred 3 , .Xr fido_assert_verify 3 , and .Xr fido_dev_get_assert 3 . .Pp The .Fn fido_assert_new function returns a pointer to a newly allocated, empty .Vt fido_assert_t type. If memory cannot be allocated, NULL is returned. .Pp The .Fn fido_assert_free function releases the memory backing .Fa *assert_p , where .Fa *assert_p must have been previously allocated by .Fn fido_assert_new . On return, .Fa *assert_p is set to NULL. Either .Fa assert_p or .Fa *assert_p may be NULL, in which case .Fn fido_assert_free is a NOP. .Pp The .Fn fido_assert_count function returns the number of statements in .Fa assert . .Pp The .Fn fido_assert_rp_id function returns a pointer to a NUL-terminated string holding the relying party ID of .Fa assert . .Pp The .Fn fido_assert_user_display_name , .Fn fido_assert_user_icon , and .Fn fido_assert_user_name , functions return pointers to the user display name, icon, and name attributes of statement .Fa idx in .Fa assert . If not NULL, the values returned by these functions point to NUL-terminated UTF-8 strings. The user display name, icon, and name attributes will typically only be returned by the authenticator if user verification was performed by the authenticator and multiple resident/discoverable credentials were involved in the assertion. .Pp The .Fn fido_assert_authdata_ptr , +.Fn fido_assert_authdata_raw_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_flags -functions return pointers to the CBOR-encoded authenticator data, +functions return pointers to the CBOR-encoded and raw 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. Note that the resulting hmac-secret varies according to whether user verification was performed by the authenticator. .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_authdata_raw_len , .Fn fido_assert_clientdata_hash_len , .Fn fido_assert_id_len , .Fn fido_assert_user_id_len , .Fn fido_assert_sig_len , .Fn fido_assert_hmac_secret_len , .Fn fido_assert_blob_len , and .Fn fido_assert_largeblob_key_len functions return the length of a given attribute. .Pp Please note that the first statement in .Fa assert has an .Fa idx (index) value of 0. .Pp The authenticator data and signature parts of an assertion statement are typically passed to a 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_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_largeblob_key_ptr functions may return NULL if the respective field in .Fa assert is not set. If not NULL, returned pointers are guaranteed to exist until any API function that takes .Fa assert without the .Em const qualifier is invoked. .Sh SEE ALSO .Xr fido_assert_allow_cred 3 , .Xr fido_assert_set_authdata 3 , .Xr fido_assert_verify 3 , .Xr fido_dev_get_assert 3 , .Xr fido_dev_largeblob_get 3 diff --git a/contrib/libfido2/man/fido_assert_set_authdata.3 b/contrib/libfido2/man/fido_assert_set_authdata.3 index f3a307fd05b8..503e2bfbc763 100644 --- a/contrib/libfido2/man/fido_assert_set_authdata.3 +++ b/contrib/libfido2/man/fido_assert_set_authdata.3 @@ -1,261 +1,314 @@ .\" Copyright (c) 2018-2022 Yubico AB. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions are .\" met: .\" .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in .\" the documentation and/or other materials provided with the .\" distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS .\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR .\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT .\" HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT .\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE .\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" SPDX-License-Identifier: BSD-2-Clause .\" -.Dd $Mdocdate: April 27 2022 $ +.Dd $Mdocdate: April 8 2023 $ .Dt FIDO_ASSERT_SET_AUTHDATA 3 .Os .Sh NAME .Nm fido_assert_set_authdata , .Nm fido_assert_set_authdata_raw , .Nm fido_assert_set_clientdata , .Nm fido_assert_set_clientdata_hash , .Nm fido_assert_set_count , .Nm fido_assert_set_extensions , .Nm fido_assert_set_hmac_salt , .Nm fido_assert_set_hmac_secret , .Nm fido_assert_set_up , .Nm fido_assert_set_uv , .Nm fido_assert_set_rp , -.Nm fido_assert_set_sig +.Nm fido_assert_set_sig , +.Nm fido_assert_set_winhello_appid .Nd set parameters of a FIDO2 assertion .Sh SYNOPSIS .In fido.h .Bd -literal typedef enum { FIDO_OPT_OMIT = 0, /* use authenticator's default */ FIDO_OPT_FALSE, /* explicitly set option to false */ FIDO_OPT_TRUE, /* explicitly set option to true */ } fido_opt_t; .Ed .Ft int .Fn fido_assert_set_authdata "fido_assert_t *assert" "size_t idx" "const unsigned char *ptr" "size_t len" .Ft int .Fn fido_assert_set_authdata_raw "fido_assert_t *assert" "size_t idx" "const unsigned char *ptr" "size_t len" .Ft int .Fn fido_assert_set_clientdata "fido_assert_t *assert" "const unsigned char *ptr" "size_t len" .Ft int .Fn fido_assert_set_clientdata_hash "fido_assert_t *assert" "const unsigned char *ptr" "size_t len" .Ft int .Fn fido_assert_set_count "fido_assert_t *assert" "size_t n" .Ft int .Fn fido_assert_set_extensions "fido_assert_t *assert" "int flags" .Ft int .Fn fido_assert_set_hmac_salt "fido_assert_t *assert" "const unsigned char *ptr" "size_t len" .Ft int .Fn fido_assert_set_hmac_secret "fido_assert_t *assert" "size_t idx" "const unsigned char *ptr" "size_t len" .Ft int .Fn fido_assert_set_up "fido_assert_t *assert" "fido_opt_t up" .Ft int .Fn fido_assert_set_uv "fido_assert_t *assert" "fido_opt_t uv" .Ft int .Fn fido_assert_set_rp "fido_assert_t *assert" "const char *id" .Ft int .Fn fido_assert_set_sig "fido_assert_t *assert" "size_t idx" "const unsigned char *ptr" "size_t len" +.Ft int +.Fn fido_assert_set_winhello_appid "fido_assert_t *assert" "const char *id" .Sh DESCRIPTION The .Nm 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 FIDO2 assertion and the format of its constituent parts, please refer to the Web Authentication (webauthn) standard. .Pp The .Fn fido_assert_set_count function sets the number of assertion statements in .Fa assert to .Fa n . .Pp The .Fn fido_assert_set_authdata and .Fn fido_assert_set_sig functions set the authenticator data and signature parts of the statement with index .Fa idx of .Fa assert to .Fa ptr , where .Fa ptr points to .Fa len bytes. A copy of .Fa ptr is made, and no references to the passed pointer are kept. Please note that the first assertion statement of .Fa assert has an .Fa idx of .Em 0 . The authenticator data passed to .Fn fido_assert_set_authdata must be a CBOR-encoded byte string, as obtained from .Fn fido_assert_authdata_ptr . Alternatively, a raw binary blob may be passed to .Fn fido_assert_set_authdata_raw . .Pp The .Fn fido_assert_set_clientdata_hash function sets the client data hash of .Fa assert to .Fa ptr , where .Fa ptr points to .Fa len bytes. A copy of .Fa ptr is made, and no references to the passed pointer are kept. .Pp The .Fn fido_assert_set_clientdata function allows an application to set the client data hash of .Fa assert by specifying the assertion's unhashed client data. This is required by Windows Hello, which calculates the client data hash internally. For compatibility with Windows Hello, applications should use .Fn fido_assert_set_clientdata instead of .Fn fido_assert_set_clientdata_hash . .Pp The .Fn fido_assert_set_rp function sets the relying party .Fa id of .Fa assert , where .Fa id is a NUL-terminated UTF-8 string. The content of .Fa id is copied, and no references to the passed pointer are kept. .Pp The .Fn fido_assert_set_extensions function sets the extensions of .Fa assert to the bitmask .Fa flags . At the moment, only the .Dv FIDO_EXT_CRED_BLOB , .Dv FIDO_EXT_HMAC_SECRET , and .Dv FIDO_EXT_LARGEBLOB_KEY extensions are supported. If .Fa flags is zero, the extensions of .Fa assert are cleared. .Pp The .Fn fido_assert_set_hmac_salt and .Fn fido_assert_set_hmac_secret functions set the hmac-salt and hmac-secret parts of .Fa assert to .Fa ptr , where .Fa ptr points to .Fa len bytes. A copy of .Fa ptr is made, and no references to the passed pointer are kept. The HMAC Secret .Pq hmac-secret Extension is a CTAP 2.0 extension. Note that the resulting hmac-secret varies according to whether user verification was performed by the authenticator. The .Fn fido_assert_set_hmac_secret function is normally only useful when writing tests. .Pp The .Fn fido_assert_set_up and .Fn fido_assert_set_uv functions set the .Fa up (user presence) and .Fa uv (user verification) attributes of .Fa assert . Both are .Dv FIDO_OPT_OMIT by default, allowing the authenticator to use its default settings. .Pp +The +.Fn fido_assert_set_winhello_appid +function sets the U2F application +.Fa id +.Pq Dq U2F AppID +of +.Fa assert , +where +.Fa id +is a NUL-terminated UTF-8 string. +The content of +.Fa id +is copied, and no references to the passed pointer are kept. +The +.Fn fido_assert_set_winhello_appid +function is a no-op unless +.Fa assert +is passed to +.Xr fido_dev_get_assert 3 +with a device +.Fa dev +on which +.Xr fido_dev_is_winhello 3 +holds true. +In this case, +.Em libfido2 +will instruct Windows Hello to try the assertion twice, +first with the +.Fa id +passed to +.Fn fido_assert_set_rp , +and a second time with the +.Fa id +passed to +.Fn fido_assert_set_winhello_appid . +If the second assertion succeeds, +.Xr fido_assert_rp_id 3 +will point to the U2F AppID once +.Xr fido_dev_get_assert 3 +completes. +This mechanism exists in Windows Hello to ensure U2F backwards +compatibility without the application inadvertently prompting the +user twice. +Note that +.Fn fido_assert_set_winhello_appid +is not needed on platforms offering CTAP primitives, since the +authenticator can be silently probed for the existence of U2F +credentials. +.Pp Use of the .Nm set of functions may happen in two distinct situations: 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 FIDO2 client), or when verifying assertion statements using .Xr fido_assert_verify 3 (i.e, in the context of a FIDO2 server). .Pp 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 . .Sh RETURN VALUES The .Nm functions return .Dv FIDO_OK on success. The error codes returned by the .Nm set of functions are defined in .In fido/err.h . .Sh SEE ALSO .Xr fido_assert_allow_cred 3 , .Xr fido_assert_verify 3 , -.Xr fido_dev_get_assert 3 +.Xr fido_dev_get_assert 3 , +.Xr fido_dev_is_winhello 3 diff --git a/contrib/libfido2/regress/assert.c b/contrib/libfido2/regress/assert.c index 98609257b8b5..ad31903cb1e2 100644 --- a/contrib/libfido2/regress/assert.c +++ b/contrib/libfido2/regress/assert.c @@ -1,637 +1,685 @@ /* - * Copyright (c) 2018-2021 Yubico AB. All rights reserved. + * Copyright (c) 2018-2023 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. * SPDX-License-Identifier: BSD-2-Clause */ #undef NDEBUG #include #include #define _FIDO_INTERNAL #include #include #include #include static int fake_dev_handle; static const unsigned char es256_pk[64] = { 0x34, 0xeb, 0x99, 0x77, 0x02, 0x9c, 0x36, 0x38, 0xbb, 0xc2, 0xae, 0xa0, 0xa0, 0x18, 0xc6, 0x64, 0xfc, 0xe8, 0x49, 0x92, 0xd7, 0x74, 0x9e, 0x0c, 0x46, 0x8c, 0x9d, 0xa6, 0xdf, 0x46, 0xf7, 0x84, 0x60, 0x1e, 0x0f, 0x8b, 0x23, 0x85, 0x4a, 0x9a, 0xec, 0xc1, 0x08, 0x9f, 0x30, 0xd0, 0x0d, 0xd7, 0x76, 0x7b, 0x55, 0x48, 0x91, 0x7c, 0x4f, 0x0f, 0x64, 0x1a, 0x1d, 0xf8, 0xbe, 0x14, 0x90, 0x8a, }; static const unsigned char rs256_pk[259] = { 0x9e, 0x54, 0x78, 0xb2, 0x51, 0xbe, 0x19, 0x7c, 0xcb, 0x1a, 0x9a, 0xc3, 0x49, 0x2a, 0x2f, 0xfd, 0x99, 0x64, 0x76, 0xc6, 0xdb, 0xca, 0x38, 0x3f, 0xb0, 0x6a, 0xc9, 0xc0, 0x07, 0x9f, 0x5c, 0x4d, 0xfc, 0xd1, 0x01, 0x7f, 0x69, 0x65, 0xab, 0x9c, 0x2a, 0xc2, 0x95, 0xd9, 0x44, 0xf3, 0xea, 0x94, 0x6b, 0x25, 0x66, 0x54, 0x81, 0xee, 0x24, 0x1d, 0xe1, 0x7d, 0x7f, 0xbe, 0xea, 0x76, 0x90, 0x5c, 0xbf, 0x59, 0x22, 0xd3, 0xa0, 0x68, 0x1a, 0x65, 0x8b, 0x2f, 0xb6, 0xa8, 0x30, 0x2d, 0x26, 0x81, 0xfa, 0x9e, 0x59, 0xec, 0x2f, 0xee, 0x59, 0x39, 0xe2, 0x79, 0x19, 0x54, 0x54, 0xdf, 0x24, 0x83, 0xee, 0x61, 0x5a, 0x66, 0x24, 0x2b, 0x7b, 0xfb, 0x82, 0x66, 0xe4, 0x85, 0x18, 0x20, 0x76, 0xe5, 0x4a, 0xb6, 0xcb, 0xec, 0x43, 0xbe, 0xfd, 0xb0, 0x8f, 0xfd, 0x2f, 0x69, 0xda, 0x06, 0x9c, 0x09, 0x68, 0x7a, 0x94, 0x6c, 0xb7, 0x51, 0x6d, 0x4c, 0xf7, 0x13, 0xe8, 0xd5, 0x22, 0x6b, 0x1e, 0xba, 0xb9, 0x85, 0xe8, 0x5f, 0xa1, 0x66, 0xe3, 0x20, 0x75, 0x30, 0x11, 0xb5, 0xa3, 0xc3, 0xb0, 0x72, 0x08, 0xff, 0xa3, 0xbb, 0xf1, 0x32, 0x0b, 0x06, 0xc4, 0x12, 0xa3, 0x49, 0x30, 0x19, 0xb9, 0xfe, 0x69, 0x0c, 0xd6, 0xe1, 0x58, 0x36, 0xe6, 0x41, 0x22, 0x41, 0xbf, 0x96, 0x50, 0x35, 0x56, 0x0d, 0x92, 0x8c, 0x34, 0xea, 0x28, 0x91, 0x88, 0x9e, 0x8a, 0xaa, 0x36, 0xd0, 0x0f, 0xbe, 0x16, 0xde, 0x9d, 0x5f, 0x7b, 0xda, 0x52, 0xf7, 0xf1, 0xb6, 0x28, 0x10, 0x05, 0x8f, 0xb9, 0x19, 0x7a, 0xcf, 0x18, 0x9b, 0x40, 0xcd, 0xff, 0x78, 0xea, 0x61, 0x24, 0x3b, 0x80, 0x68, 0x04, 0x9b, 0x40, 0x07, 0x98, 0xd4, 0x94, 0xd1, 0x18, 0x44, 0xa5, 0xed, 0xee, 0x18, 0xc2, 0x25, 0x52, 0x66, 0x42, 0xdf, 0x01, 0x00, 0x01, }; static const unsigned char cdh[32] = { 0xec, 0x8d, 0x8f, 0x78, 0x42, 0x4a, 0x2b, 0xb7, 0x82, 0x34, 0xaa, 0xca, 0x07, 0xa1, 0xf6, 0x56, 0x42, 0x1c, 0xb6, 0xf6, 0xb3, 0x00, 0x86, 0x52, 0x35, 0x2d, 0xa2, 0x62, 0x4a, 0xbe, 0x89, 0x76, }; static const unsigned char authdata[39] = { 0x58, 0x25, 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, 0x00, 0x00, 0x00, 0x00, 0x03, }; static const unsigned char sig[72] = { 0x30, 0x46, 0x02, 0x21, 0x00, 0xf6, 0xd1, 0xa3, 0xd5, 0x24, 0x2b, 0xde, 0xee, 0xa0, 0x90, 0x89, 0xcd, 0xf8, 0x9e, 0xbd, 0x6b, 0x4d, 0x55, 0x79, 0xe4, 0xc1, 0x42, 0x27, 0xb7, 0x9b, 0x9b, 0xa4, 0x0a, 0xe2, 0x47, 0x64, 0x0e, 0x02, 0x21, 0x00, 0xe5, 0xc9, 0xc2, 0x83, 0x47, 0x31, 0xc7, 0x26, 0xe5, 0x25, 0xb2, 0xb4, 0x39, 0xa7, 0xfc, 0x3d, 0x70, 0xbe, 0xe9, 0x81, 0x0d, 0x4a, 0x62, 0xa9, 0xab, 0x4a, 0x91, 0xc0, 0x7d, 0x2d, 0x23, 0x1e, }; static void * dummy_open(const char *path) { (void)path; return (&fake_dev_handle); } static void dummy_close(void *handle) { assert(handle == &fake_dev_handle); } static int dummy_read(void *handle, unsigned char *buf, size_t len, int ms) { (void)handle; (void)buf; (void)len; (void)ms; abort(); /* NOTREACHED */ } static int dummy_write(void *handle, const unsigned char *buf, size_t len) { (void)handle; (void)buf; (void)len; abort(); /* NOTREACHED */ } static fido_assert_t * alloc_assert(void) { fido_assert_t *a; a = fido_assert_new(); assert(a != NULL); return (a); } static void free_assert(fido_assert_t *a) { fido_assert_free(&a); assert(a == NULL); } static fido_dev_t * alloc_dev(void) { fido_dev_t *d; d = fido_dev_new(); assert(d != NULL); return (d); } static void free_dev(fido_dev_t *d) { fido_dev_free(&d); assert(d == NULL); } static es256_pk_t * alloc_es256_pk(void) { es256_pk_t *pk; pk = es256_pk_new(); assert(pk != NULL); return (pk); } static void free_es256_pk(es256_pk_t *pk) { es256_pk_free(&pk); assert(pk == NULL); } static rs256_pk_t * alloc_rs256_pk(void) { rs256_pk_t *pk; pk = rs256_pk_new(); assert(pk != NULL); return (pk); } static void free_rs256_pk(rs256_pk_t *pk) { rs256_pk_free(&pk); assert(pk == NULL); } static eddsa_pk_t * alloc_eddsa_pk(void) { eddsa_pk_t *pk; pk = eddsa_pk_new(); assert(pk != NULL); return (pk); } static void free_eddsa_pk(eddsa_pk_t *pk) { eddsa_pk_free(&pk); assert(pk == NULL); } static void empty_assert(fido_dev_t *d, fido_assert_t *a, size_t idx) { es256_pk_t *es256; rs256_pk_t *rs256; eddsa_pk_t *eddsa; assert(fido_assert_flags(a, idx) == 0); assert(fido_assert_authdata_len(a, idx) == 0); assert(fido_assert_authdata_ptr(a, idx) == NULL); + assert(fido_assert_authdata_raw_len(a, idx) == 0); + assert(fido_assert_authdata_raw_ptr(a, idx) == NULL); assert(fido_assert_clientdata_hash_len(a) == 0); assert(fido_assert_clientdata_hash_ptr(a) == NULL); assert(fido_assert_id_len(a, idx) == 0); assert(fido_assert_id_ptr(a, idx) == NULL); assert(fido_assert_rp_id(a) == NULL); assert(fido_assert_sig_len(a, idx) == 0); assert(fido_assert_sig_ptr(a, idx) == NULL); assert(fido_assert_user_display_name(a, idx) == NULL); assert(fido_assert_user_icon(a, idx) == NULL); assert(fido_assert_user_id_len(a, idx) == 0); assert(fido_assert_user_id_ptr(a, idx) == NULL); assert(fido_assert_user_name(a, idx) == NULL); es256 = alloc_es256_pk(); rs256 = alloc_rs256_pk(); eddsa = alloc_eddsa_pk(); fido_dev_force_u2f(d); assert(fido_dev_get_assert(d, a, NULL) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_dev_get_assert(d, a, "") == FIDO_ERR_INVALID_ARGUMENT); assert(fido_assert_verify(a, idx, COSE_ES256, NULL) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_assert_verify(a, idx, COSE_ES256, es256) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_assert_verify(a, idx, -1, es256) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_assert_verify(a, idx, COSE_RS256, rs256) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_assert_verify(a, idx, COSE_EDDSA, eddsa) == FIDO_ERR_INVALID_ARGUMENT); fido_dev_force_fido2(d); assert(fido_dev_get_assert(d, a, NULL) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_dev_get_assert(d, a, "") == FIDO_ERR_INVALID_ARGUMENT); assert(fido_assert_verify(a, idx, COSE_ES256, NULL) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_assert_verify(a, idx, COSE_ES256, es256) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_assert_verify(a, idx, -1, es256) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_assert_verify(a, idx, COSE_RS256, rs256) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_assert_verify(a, idx, COSE_EDDSA, eddsa) == FIDO_ERR_INVALID_ARGUMENT); free_es256_pk(es256); free_rs256_pk(rs256); free_eddsa_pk(eddsa); } static void empty_assert_tests(void) { fido_assert_t *a; fido_dev_t *d; fido_dev_io_t io_f; size_t i; memset(&io_f, 0, sizeof(io_f)); a = alloc_assert(); d = alloc_dev(); io_f.open = dummy_open; io_f.close = dummy_close; io_f.read = dummy_read; io_f.write = dummy_write; assert(fido_dev_set_io_functions(d, &io_f) == FIDO_OK); empty_assert(d, a, 0); assert(fido_assert_count(a) == 0); assert(fido_assert_set_count(a, 4) == FIDO_OK); assert(fido_assert_count(a) == 4); for (i = 0; i < 4; i++) { empty_assert(d, a, i); } empty_assert(d, a, 10); free_assert(a); free_dev(d); } static void valid_assert(void) { fido_assert_t *a; es256_pk_t *es256; rs256_pk_t *rs256; eddsa_pk_t *eddsa; a = alloc_assert(); es256 = alloc_es256_pk(); rs256 = alloc_rs256_pk(); eddsa = alloc_eddsa_pk(); assert(es256_pk_from_ptr(es256, es256_pk, sizeof(es256_pk)) == FIDO_OK); assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); assert(fido_assert_set_count(a, 1) == FIDO_OK); assert(fido_assert_set_authdata(a, 0, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); assert(fido_assert_verify(a, 0, COSE_ES256, es256) == FIDO_OK); assert(fido_assert_verify(a, 0, COSE_RS256, rs256) == FIDO_ERR_INVALID_SIG); assert(fido_assert_verify(a, 0, COSE_EDDSA, eddsa) == FIDO_ERR_INVALID_SIG); free_assert(a); free_es256_pk(es256); free_rs256_pk(rs256); free_eddsa_pk(eddsa); } static void no_cdh(void) { fido_assert_t *a; es256_pk_t *pk; a = alloc_assert(); pk = alloc_es256_pk(); assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); assert(fido_assert_set_count(a, 1) == FIDO_OK); assert(fido_assert_set_authdata(a, 0, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_ERR_INVALID_ARGUMENT); free_assert(a); free_es256_pk(pk); } static void no_rp(void) { fido_assert_t *a; es256_pk_t *pk; a = alloc_assert(); pk = alloc_es256_pk(); assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_assert_set_count(a, 1) == FIDO_OK); assert(fido_assert_set_authdata(a, 0, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_ERR_INVALID_ARGUMENT); free_assert(a); free_es256_pk(pk); } static void no_authdata(void) { fido_assert_t *a; es256_pk_t *pk; a = alloc_assert(); pk = alloc_es256_pk(); assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); assert(fido_assert_set_count(a, 1) == FIDO_OK); assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_ERR_INVALID_ARGUMENT); free_assert(a); free_es256_pk(pk); } static void no_sig(void) { fido_assert_t *a; es256_pk_t *pk; a = alloc_assert(); pk = alloc_es256_pk(); assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); assert(fido_assert_set_count(a, 1) == FIDO_OK); assert(fido_assert_set_authdata(a, 0, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_ERR_INVALID_ARGUMENT); free_assert(a); free_es256_pk(pk); } static void junk_cdh(void) { fido_assert_t *a; es256_pk_t *pk; unsigned char *junk; junk = malloc(sizeof(cdh)); assert(junk != NULL); memcpy(junk, cdh, sizeof(cdh)); junk[0] = (unsigned char)~junk[0]; a = alloc_assert(); pk = alloc_es256_pk(); assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); assert(fido_assert_set_clientdata_hash(a, junk, sizeof(cdh)) == FIDO_OK); assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); assert(fido_assert_set_count(a, 1) == FIDO_OK); assert(fido_assert_set_authdata(a, 0, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_ERR_INVALID_SIG); free_assert(a); free_es256_pk(pk); free(junk); } static void junk_rp(void) { fido_assert_t *a; es256_pk_t *pk; a = alloc_assert(); pk = alloc_es256_pk(); assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_assert_set_rp(a, "potato") == FIDO_OK); assert(fido_assert_set_count(a, 1) == FIDO_OK); assert(fido_assert_set_authdata(a, 0, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_ERR_INVALID_PARAM); free_assert(a); free_es256_pk(pk); } static void junk_authdata(void) { fido_assert_t *a; unsigned char *junk; junk = malloc(sizeof(authdata)); assert(junk != NULL); memcpy(junk, authdata, sizeof(authdata)); junk[0] = (unsigned char)~junk[0]; a = alloc_assert(); assert(fido_assert_set_count(a, 1) == FIDO_OK); assert(fido_assert_set_authdata(a, 0, junk, sizeof(authdata)) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_assert_authdata_ptr(a, 0) == NULL); + assert(fido_assert_authdata_len(a, 0) == 0); + assert(fido_assert_authdata_raw_ptr(a, 0) == NULL); + assert(fido_assert_authdata_raw_len(a, 0) == 0); free_assert(a); free(junk); } static void junk_sig(void) { fido_assert_t *a; es256_pk_t *pk; unsigned char *junk; junk = malloc(sizeof(sig)); assert(junk != NULL); memcpy(junk, sig, sizeof(sig)); junk[0] = (unsigned char)~junk[0]; a = alloc_assert(); pk = alloc_es256_pk(); assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); assert(fido_assert_set_count(a, 1) == FIDO_OK); assert(fido_assert_set_authdata(a, 0, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_sig(a, 0, junk, sizeof(sig)) == FIDO_OK); assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_ERR_INVALID_SIG); free_assert(a); free_es256_pk(pk); free(junk); } static void wrong_options(void) { fido_assert_t *a; es256_pk_t *pk; a = alloc_assert(); pk = alloc_es256_pk(); assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); assert(fido_assert_set_count(a, 1) == FIDO_OK); assert(fido_assert_set_authdata(a, 0, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_assert_set_up(a, FIDO_OPT_TRUE) == FIDO_OK); assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_ERR_INVALID_PARAM); assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_uv(a, FIDO_OPT_TRUE) == FIDO_OK); assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_ERR_INVALID_PARAM); assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_OK); free_assert(a); free_es256_pk(pk); } /* cbor_serialize_alloc misuse */ static void bad_cbor_serialize(void) { fido_assert_t *a; a = alloc_assert(); assert(fido_assert_set_count(a, 1) == FIDO_OK); assert(fido_assert_set_authdata(a, 0, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_assert_authdata_len(a, 0) == sizeof(authdata)); free_assert(a); } /* rs256 <-> EVP_PKEY transformations */ static void rs256_PKEY(void) { rs256_pk_t *pk1, *pk2; EVP_PKEY *pkey; pk1 = alloc_rs256_pk(); pk2 = alloc_rs256_pk(); assert(rs256_pk_from_ptr(pk1, rs256_pk, sizeof(rs256_pk)) == FIDO_OK); assert((pkey = rs256_pk_to_EVP_PKEY(pk1)) != NULL); assert(rs256_pk_from_EVP_PKEY(pk2, pkey) == FIDO_OK); assert(memcmp(pk1, pk2, sizeof(*pk1)) == 0); free_rs256_pk(pk1); free_rs256_pk(pk2); EVP_PKEY_free(pkey); } /* es256 <-> EVP_PKEY transformations */ static void es256_PKEY(void) { es256_pk_t *pk1, *pk2; EVP_PKEY *pkey; pk1 = alloc_es256_pk(); pk2 = alloc_es256_pk(); assert(es256_pk_from_ptr(pk1, es256_pk, sizeof(es256_pk)) == FIDO_OK); assert((pkey = es256_pk_to_EVP_PKEY(pk1)) != NULL); assert(es256_pk_from_EVP_PKEY(pk2, pkey) == FIDO_OK); assert(memcmp(pk1, pk2, sizeof(*pk1)) == 0); free_es256_pk(pk1); free_es256_pk(pk2); EVP_PKEY_free(pkey); } +static void +raw_authdata(void) +{ + fido_assert_t *a; + cbor_item_t *item; + struct cbor_load_result cbor_result; + const unsigned char *ptr; + unsigned char *cbor; + size_t len; + size_t cbor_len; + size_t alloclen; + + a = alloc_assert(); + assert(fido_assert_set_count(a, 1) == FIDO_OK); + assert(fido_assert_set_authdata(a, 0, authdata, + sizeof(authdata)) == FIDO_OK); + assert((ptr = fido_assert_authdata_ptr(a, 0)) != NULL); + assert((len = fido_assert_authdata_len(a, 0)) != 0); + assert((item = cbor_load(ptr, len, &cbor_result)) != NULL); + assert(cbor_result.read == len); + assert(cbor_isa_bytestring(item)); + assert((ptr = fido_assert_authdata_raw_ptr(a, 0)) != NULL); + assert((len = fido_assert_authdata_raw_len(a, 0)) != 0); + assert(cbor_bytestring_length(item) == len); + assert(memcmp(ptr, cbor_bytestring_handle(item), len) == 0); + assert((len = fido_assert_authdata_len(a, 0)) != 0); + assert((cbor_len = cbor_serialize_alloc(item, &cbor, &alloclen)) == len); + assert((ptr = cbor_bytestring_handle(item)) != NULL); + assert((len = cbor_bytestring_length(item)) != 0); + assert(fido_assert_set_authdata_raw(a, 0, ptr, len) == FIDO_OK); + assert((ptr = fido_assert_authdata_ptr(a, 0)) != NULL); + assert((len = fido_assert_authdata_len(a, 0)) != 0); + assert(len == cbor_len); + assert(memcmp(cbor, ptr, len) == 0); + assert(cbor_len == sizeof(authdata)); + assert(memcmp(cbor, authdata, cbor_len) == 0); + cbor_decref(&item); + free(cbor); + free_assert(a); +} + int main(void) { fido_init(0); empty_assert_tests(); valid_assert(); no_cdh(); no_rp(); no_authdata(); no_sig(); junk_cdh(); junk_rp(); junk_authdata(); junk_sig(); wrong_options(); bad_cbor_serialize(); rs256_PKEY(); es256_PKEY(); + raw_authdata(); exit(0); } diff --git a/contrib/libfido2/regress/cred.c b/contrib/libfido2/regress/cred.c index e4dc76ac1f0d..61e603d1db1a 100644 --- a/contrib/libfido2/regress/cred.c +++ b/contrib/libfido2/regress/cred.c @@ -1,2179 +1,2185 @@ /* * Copyright (c) 2018-2021 Yubico AB. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. * SPDX-License-Identifier: BSD-2-Clause */ #undef NDEBUG #include #include +#include +#include #define _FIDO_INTERNAL #include static int fake_dev_handle; static const unsigned char cdh[32] = { 0xf9, 0x64, 0x57, 0xe7, 0x2d, 0x97, 0xf6, 0xbb, 0xdd, 0xd7, 0xfb, 0x06, 0x37, 0x62, 0xea, 0x26, 0x20, 0x44, 0x8e, 0x69, 0x7c, 0x03, 0xf2, 0x31, 0x2f, 0x99, 0xdc, 0xaf, 0x3e, 0x8a, 0x91, 0x6b, }; static const unsigned char authdata[198] = { 0x58, 0xc4, 0x49, 0x96, 0x0d, 0xe5, 0x88, 0x0e, 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64, 0x76, 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2, 0x86, 0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, 0x83, 0x1d, 0x97, 0x63, 0x41, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa0, 0x11, 0xf3, 0x8c, 0x0a, 0x4d, 0x15, 0x80, 0x06, 0x17, 0x11, 0x1f, 0x9e, 0xdc, 0x7d, 0x00, 0x40, 0x53, 0xfb, 0xdf, 0xaa, 0xce, 0x63, 0xde, 0xc5, 0xfe, 0x47, 0xe6, 0x52, 0xeb, 0xf3, 0x5d, 0x53, 0xa8, 0xbf, 0x9d, 0xd6, 0x09, 0x6b, 0x5e, 0x7f, 0xe0, 0x0d, 0x51, 0x30, 0x85, 0x6a, 0xda, 0x68, 0x70, 0x85, 0xb0, 0xdb, 0x08, 0x0b, 0x83, 0x2c, 0xef, 0x44, 0xe2, 0x36, 0x88, 0xee, 0x76, 0x90, 0x6e, 0x7b, 0x50, 0x3e, 0x9a, 0xa0, 0xd6, 0x3c, 0x34, 0xe3, 0x83, 0xe7, 0xd1, 0xbd, 0x9f, 0x25, 0xa5, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, 0x17, 0x5b, 0x27, 0xa6, 0x56, 0xb2, 0x26, 0x0c, 0x26, 0x0c, 0x55, 0x42, 0x78, 0x17, 0x5d, 0x4c, 0xf8, 0xa2, 0xfd, 0x1b, 0xb9, 0x54, 0xdf, 0xd5, 0xeb, 0xbf, 0x22, 0x64, 0xf5, 0x21, 0x9a, 0xc6, 0x22, 0x58, 0x20, 0x87, 0x5f, 0x90, 0xe6, 0xfd, 0x71, 0x27, 0x9f, 0xeb, 0xe3, 0x03, 0x44, 0xbc, 0x8d, 0x49, 0xc6, 0x1c, 0x31, 0x3b, 0x72, 0xae, 0xd4, 0x53, 0xb1, 0xfe, 0x5d, 0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2, }; static const unsigned char authdata_dupkeys[200] = { 0x58, 0xc6, 0x49, 0x96, 0x0d, 0xe5, 0x88, 0x0e, 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64, 0x76, 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2, 0x86, 0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, 0x83, 0x1d, 0x97, 0x63, 0x41, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa0, 0x11, 0xf3, 0x8c, 0x0a, 0x4d, 0x15, 0x80, 0x06, 0x17, 0x11, 0x1f, 0x9e, 0xdc, 0x7d, 0x00, 0x40, 0x53, 0xfb, 0xdf, 0xaa, 0xce, 0x63, 0xde, 0xc5, 0xfe, 0x47, 0xe6, 0x52, 0xeb, 0xf3, 0x5d, 0x53, 0xa8, 0xbf, 0x9d, 0xd6, 0x09, 0x6b, 0x5e, 0x7f, 0xe0, 0x0d, 0x51, 0x30, 0x85, 0x6a, 0xda, 0x68, 0x70, 0x85, 0xb0, 0xdb, 0x08, 0x0b, 0x83, 0x2c, 0xef, 0x44, 0xe2, 0x36, 0x88, 0xee, 0x76, 0x90, 0x6e, 0x7b, 0x50, 0x3e, 0x9a, 0xa0, 0xd6, 0x3c, 0x34, 0xe3, 0x83, 0xe7, 0xd1, 0xbd, 0x9f, 0x25, 0xa6, 0x01, 0x02, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, 0x17, 0x5b, 0x27, 0xa6, 0x56, 0xb2, 0x26, 0x0c, 0x26, 0x0c, 0x55, 0x42, 0x78, 0x17, 0x5d, 0x4c, 0xf8, 0xa2, 0xfd, 0x1b, 0xb9, 0x54, 0xdf, 0xd5, 0xeb, 0xbf, 0x22, 0x64, 0xf5, 0x21, 0x9a, 0xc6, 0x22, 0x58, 0x20, 0x87, 0x5f, 0x90, 0xe6, 0xfd, 0x71, 0x27, 0x9f, 0xeb, 0xe3, 0x03, 0x44, 0xbc, 0x8d, 0x49, 0xc6, 0x1c, 0x31, 0x3b, 0x72, 0xae, 0xd4, 0x53, 0xb1, 0xfe, 0x5d, 0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2, }; static const unsigned char authdata_unsorted_keys[198] = { 0x58, 0xc4, 0x49, 0x96, 0x0d, 0xe5, 0x88, 0x0e, 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64, 0x76, 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2, 0x86, 0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, 0x83, 0x1d, 0x97, 0x63, 0x41, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa0, 0x11, 0xf3, 0x8c, 0x0a, 0x4d, 0x15, 0x80, 0x06, 0x17, 0x11, 0x1f, 0x9e, 0xdc, 0x7d, 0x00, 0x40, 0x53, 0xfb, 0xdf, 0xaa, 0xce, 0x63, 0xde, 0xc5, 0xfe, 0x47, 0xe6, 0x52, 0xeb, 0xf3, 0x5d, 0x53, 0xa8, 0xbf, 0x9d, 0xd6, 0x09, 0x6b, 0x5e, 0x7f, 0xe0, 0x0d, 0x51, 0x30, 0x85, 0x6a, 0xda, 0x68, 0x70, 0x85, 0xb0, 0xdb, 0x08, 0x0b, 0x83, 0x2c, 0xef, 0x44, 0xe2, 0x36, 0x88, 0xee, 0x76, 0x90, 0x6e, 0x7b, 0x50, 0x3e, 0x9a, 0xa0, 0xd6, 0x3c, 0x34, 0xe3, 0x83, 0xe7, 0xd1, 0xbd, 0x9f, 0x25, 0xa5, 0x03, 0x26, 0x01, 0x02, 0x20, 0x01, 0x21, 0x58, 0x20, 0x17, 0x5b, 0x27, 0xa6, 0x56, 0xb2, 0x26, 0x0c, 0x26, 0x0c, 0x55, 0x42, 0x78, 0x17, 0x5d, 0x4c, 0xf8, 0xa2, 0xfd, 0x1b, 0xb9, 0x54, 0xdf, 0xd5, 0xeb, 0xbf, 0x22, 0x64, 0xf5, 0x21, 0x9a, 0xc6, 0x22, 0x58, 0x20, 0x87, 0x5f, 0x90, 0xe6, 0xfd, 0x71, 0x27, 0x9f, 0xeb, 0xe3, 0x03, 0x44, 0xbc, 0x8d, 0x49, 0xc6, 0x1c, 0x31, 0x3b, 0x72, 0xae, 0xd4, 0x53, 0xb1, 0xfe, 0x5d, 0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2, }; const unsigned char authdata_tpm_rs256[362] = { 0x59, 0x01, 0x67, 0x49, 0x96, 0x0d, 0xe5, 0x88, 0x0e, 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64, 0x76, 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2, 0x86, 0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, 0x83, 0x1d, 0x97, 0x63, 0x45, 0x00, 0x00, 0x00, 0x00, 0x08, 0x98, 0x70, 0x58, 0xca, 0xdc, 0x4b, 0x81, 0xb6, 0xe1, 0x30, 0xde, 0x50, 0xdc, 0xbe, 0x96, 0x00, 0x20, 0x89, 0x99, 0x6d, 0x5a, 0x00, 0x29, 0xe5, 0x3e, 0x6a, 0x1c, 0x72, 0x6d, 0x71, 0x4a, 0x4f, 0x03, 0x9b, 0x68, 0x17, 0xdb, 0x29, 0x1a, 0x6b, 0x02, 0x6c, 0x26, 0xf9, 0xbd, 0xc3, 0x0e, 0x38, 0x1a, 0xa4, 0x01, 0x03, 0x03, 0x39, 0x01, 0x00, 0x20, 0x59, 0x01, 0x00, 0xc5, 0xb6, 0x9c, 0x06, 0x1d, 0xcf, 0xb9, 0xf2, 0x5e, 0x99, 0x7d, 0x6d, 0x73, 0xd8, 0x36, 0xc1, 0x4a, 0x90, 0x05, 0x4d, 0x82, 0x57, 0xc1, 0xb6, 0x6a, 0xd1, 0x43, 0x03, 0x85, 0xf8, 0x52, 0x4f, 0xd2, 0x27, 0x91, 0x0b, 0xb5, 0x93, 0xa0, 0x68, 0xf8, 0x80, 0x1b, 0xaa, 0x65, 0x97, 0x45, 0x11, 0x86, 0x34, 0xd6, 0x67, 0xf8, 0xd5, 0x12, 0x79, 0x84, 0xee, 0x70, 0x99, 0x00, 0x63, 0xa8, 0xb4, 0x43, 0x0b, 0x4c, 0x57, 0x4a, 0xd6, 0x9b, 0x75, 0x63, 0x8a, 0x46, 0x57, 0xdb, 0x14, 0xc8, 0x71, 0xd1, 0xb3, 0x07, 0x68, 0x58, 0xbc, 0x55, 0x84, 0x80, 0x2a, 0xd2, 0x36, 0x9f, 0xc1, 0x64, 0xa0, 0x11, 0x4b, 0xc9, 0x32, 0x31, 0x3a, 0xd6, 0x87, 0x26, 0x1a, 0x3a, 0x78, 0x3d, 0x89, 0xdb, 0x00, 0x28, 0x3b, 0xae, 0x2b, 0x1b, 0x56, 0xe2, 0x8c, 0x4c, 0x63, 0xac, 0x6e, 0x6c, 0xf7, 0xb5, 0x7d, 0x4d, 0x0b, 0x9f, 0x06, 0xa0, 0x10, 0x35, 0x38, 0x20, 0x4d, 0xcc, 0x07, 0xd7, 0x00, 0x4e, 0x86, 0xba, 0xfe, 0x8b, 0xe4, 0x3f, 0x4a, 0xd6, 0xca, 0xbf, 0x67, 0x40, 0x1a, 0xa4, 0xda, 0x82, 0x52, 0x15, 0xb8, 0x14, 0x3a, 0x7c, 0xa9, 0x02, 0xc1, 0x01, 0x69, 0xc6, 0x51, 0xd4, 0xbc, 0x1f, 0x95, 0xb2, 0xee, 0x1f, 0xdd, 0xb5, 0x73, 0x16, 0x5e, 0x29, 0x3f, 0x47, 0xac, 0x65, 0xfb, 0x63, 0x5c, 0xb9, 0xc8, 0x13, 0x2d, 0xec, 0x85, 0xde, 0x71, 0x0d, 0x84, 0x93, 0x74, 0x76, 0x91, 0xdd, 0x1d, 0x6d, 0x3d, 0xc7, 0x36, 0x19, 0x19, 0x86, 0xde, 0x7c, 0xca, 0xd6, 0xc6, 0x65, 0x7e, 0x4b, 0x24, 0x9c, 0xce, 0x92, 0x6b, 0x1c, 0xe0, 0xa0, 0xa9, 0x6c, 0xc3, 0xed, 0x4f, 0x2a, 0x54, 0x07, 0x00, 0x32, 0x5e, 0x1b, 0x94, 0x37, 0xcd, 0xe2, 0x32, 0xa8, 0xd5, 0x2c, 0xfb, 0x03, 0x9d, 0x79, 0xdf, 0x21, 0x43, 0x01, 0x00, 0x01 }; static const unsigned char authdata_tpm_es256[166] = { 0x58, 0xa4, 0x49, 0x96, 0x0d, 0xe5, 0x88, 0x0e, 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64, 0x76, 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2, 0x86, 0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, 0x83, 0x1d, 0x97, 0x63, 0x45, 0x00, 0x00, 0x00, 0x00, 0x08, 0x98, 0x70, 0x58, 0xca, 0xdc, 0x4b, 0x81, 0xb6, 0xe1, 0x30, 0xde, 0x50, 0xdc, 0xbe, 0x96, 0x00, 0x20, 0xa8, 0xdf, 0x03, 0xf7, 0xbf, 0x39, 0x51, 0x94, 0x95, 0x8f, 0xa4, 0x84, 0x97, 0x30, 0xbc, 0x3c, 0x7e, 0x1c, 0x99, 0x91, 0x4d, 0xae, 0x6d, 0xfb, 0xdf, 0x53, 0xb5, 0xb6, 0x1f, 0x3a, 0x4e, 0x6a, 0xa5, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, 0xfb, 0xd6, 0xba, 0x74, 0xe6, 0x6e, 0x5c, 0x87, 0xef, 0x89, 0xa2, 0xe8, 0x3d, 0x0b, 0xe9, 0x69, 0x2c, 0x07, 0x07, 0x7a, 0x8a, 0x1e, 0xce, 0x12, 0xea, 0x3b, 0xb3, 0xf1, 0xf3, 0xd9, 0xc3, 0xe6, 0x22, 0x58, 0x20, 0x3c, 0x68, 0x51, 0x94, 0x54, 0x8d, 0xeb, 0x9f, 0xb2, 0x2c, 0x66, 0x75, 0xb6, 0xb7, 0x55, 0x22, 0x0d, 0x87, 0x59, 0xc4, 0x39, 0x91, 0x62, 0x17, 0xc2, 0xc3, 0x53, 0xa5, 0x26, 0x97, 0x4f, 0x2d }; static const unsigned char x509[742] = { 0x30, 0x82, 0x02, 0xe2, 0x30, 0x81, 0xcb, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x59, 0x75, 0x62, 0x69, 0x63, 0x6f, 0x20, 0x55, 0x32, 0x46, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x35, 0x31, 0x35, 0x31, 0x32, 0x35, 0x38, 0x35, 0x34, 0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x36, 0x31, 0x34, 0x31, 0x32, 0x35, 0x38, 0x35, 0x34, 0x5a, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x59, 0x75, 0x62, 0x69, 0x63, 0x6f, 0x20, 0x55, 0x32, 0x46, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x45, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xdb, 0x0a, 0xdb, 0xf5, 0x21, 0xc7, 0x5c, 0xce, 0x63, 0xdc, 0xa6, 0xe1, 0xe8, 0x25, 0x06, 0x0d, 0x94, 0xe6, 0x27, 0x54, 0x19, 0x4f, 0x9d, 0x24, 0xaf, 0x26, 0x1a, 0xbe, 0xad, 0x99, 0x44, 0x1f, 0x95, 0xa3, 0x71, 0x91, 0x0a, 0x3a, 0x20, 0xe7, 0x3e, 0x91, 0x5e, 0x13, 0xe8, 0xbe, 0x38, 0x05, 0x7a, 0xd5, 0x7a, 0xa3, 0x7e, 0x76, 0x90, 0x8f, 0xaf, 0xe2, 0x8a, 0x94, 0xb6, 0x30, 0xeb, 0x9d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x95, 0x40, 0x6b, 0x50, 0x61, 0x7d, 0xad, 0x84, 0xa3, 0xb4, 0xeb, 0x88, 0x0f, 0xe3, 0x30, 0x0f, 0x2d, 0xa2, 0x0a, 0x00, 0xd9, 0x25, 0x04, 0xee, 0x72, 0xfa, 0x67, 0xdf, 0x58, 0x51, 0x0f, 0x0b, 0x47, 0x02, 0x9c, 0x3e, 0x41, 0x29, 0x4a, 0x93, 0xac, 0x29, 0x85, 0x89, 0x2d, 0xa4, 0x7a, 0x81, 0x32, 0x28, 0x57, 0x71, 0x01, 0xef, 0xa8, 0x42, 0x88, 0x16, 0x96, 0x37, 0x91, 0xd5, 0xdf, 0xe0, 0x8f, 0xc9, 0x3c, 0x8d, 0xb0, 0xcd, 0x89, 0x70, 0x82, 0xec, 0x79, 0xd3, 0xc6, 0x78, 0x73, 0x29, 0x32, 0xe5, 0xab, 0x6c, 0xbd, 0x56, 0x9f, 0xd5, 0x45, 0x91, 0xce, 0xc1, 0xdd, 0x8d, 0x64, 0xdc, 0xe9, 0x9c, 0x1f, 0x5e, 0x3c, 0xd2, 0xaf, 0x51, 0xa5, 0x82, 0x18, 0xaf, 0xe0, 0x37, 0xe7, 0x32, 0x9e, 0x76, 0x05, 0x77, 0x02, 0x7b, 0xe6, 0x24, 0xa0, 0x31, 0x56, 0x1b, 0xfd, 0x19, 0xc5, 0x71, 0xd3, 0xf0, 0x9e, 0xc0, 0x73, 0x05, 0x4e, 0xbc, 0x85, 0xb8, 0x53, 0x9e, 0xef, 0xc5, 0xbc, 0x9c, 0x56, 0xa3, 0xba, 0xd9, 0x27, 0x6a, 0xbb, 0xa9, 0x7a, 0x40, 0xd7, 0x47, 0x8b, 0x55, 0x72, 0x6b, 0xe3, 0xfe, 0x28, 0x49, 0x71, 0x24, 0xf4, 0x8f, 0xf4, 0x20, 0x81, 0xea, 0x38, 0xff, 0x7c, 0x0a, 0x4f, 0xdf, 0x02, 0x82, 0x39, 0x81, 0x82, 0x3b, 0xca, 0x09, 0xdd, 0xca, 0xaa, 0x0f, 0x27, 0xf5, 0xa4, 0x83, 0x55, 0x6c, 0x9a, 0x39, 0x9b, 0x15, 0x3a, 0x16, 0x63, 0xdc, 0x5b, 0xf9, 0xac, 0x5b, 0xbc, 0xf7, 0x9f, 0xbe, 0x0f, 0x8a, 0xa2, 0x3c, 0x31, 0x13, 0xa3, 0x32, 0x48, 0xca, 0x58, 0x87, 0xf8, 0x7b, 0xa0, 0xa1, 0x0a, 0x6a, 0x60, 0x96, 0x93, 0x5f, 0x5d, 0x26, 0x9e, 0x63, 0x1d, 0x09, 0xae, 0x9a, 0x41, 0xe5, 0xbd, 0x08, 0x47, 0xfe, 0xe5, 0x09, 0x9b, 0x20, 0xfd, 0x12, 0xe2, 0xe6, 0x40, 0x7f, 0xba, 0x4a, 0x61, 0x33, 0x66, 0x0d, 0x0e, 0x73, 0xdb, 0xb0, 0xd5, 0xa2, 0x9a, 0x9a, 0x17, 0x0d, 0x34, 0x30, 0x85, 0x6a, 0x42, 0x46, 0x9e, 0xff, 0x34, 0x8f, 0x5f, 0x87, 0x6c, 0x35, 0xe7, 0xa8, 0x4d, 0x35, 0xeb, 0xc1, 0x41, 0xaa, 0x8a, 0xd2, 0xda, 0x19, 0xaa, 0x79, 0xa2, 0x5f, 0x35, 0x2c, 0xa0, 0xfd, 0x25, 0xd3, 0xf7, 0x9d, 0x25, 0x18, 0x2d, 0xfa, 0xb4, 0xbc, 0xbb, 0x07, 0x34, 0x3c, 0x8d, 0x81, 0xbd, 0xf4, 0xe9, 0x37, 0xdb, 0x39, 0xe9, 0xd1, 0x45, 0x5b, 0x20, 0x41, 0x2f, 0x2d, 0x27, 0x22, 0xdc, 0x92, 0x74, 0x8a, 0x92, 0xd5, 0x83, 0xfd, 0x09, 0xfb, 0x13, 0x9b, 0xe3, 0x39, 0x7a, 0x6b, 0x5c, 0xfa, 0xe6, 0x76, 0x9e, 0xe0, 0xe4, 0xe3, 0xef, 0xad, 0xbc, 0xfd, 0x42, 0x45, 0x9a, 0xd4, 0x94, 0xd1, 0x7e, 0x8d, 0xa7, 0xd8, 0x05, 0xd5, 0xd3, 0x62, 0xcf, 0x15, 0xcf, 0x94, 0x7d, 0x1f, 0x5b, 0x58, 0x20, 0x44, 0x20, 0x90, 0x71, 0xbe, 0x66, 0xe9, 0x9a, 0xab, 0x74, 0x32, 0x70, 0x53, 0x1d, 0x69, 0xed, 0x87, 0x66, 0xf4, 0x09, 0x4f, 0xca, 0x25, 0x30, 0xc2, 0x63, 0x79, 0x00, 0x3c, 0xb1, 0x9b, 0x39, 0x3f, 0x00, 0xe0, 0xa8, 0x88, 0xef, 0x7a, 0x51, 0x5b, 0xe7, 0xbd, 0x49, 0x64, 0xda, 0x41, 0x7b, 0x24, 0xc3, 0x71, 0x22, 0xfd, 0xd1, 0xd1, 0x20, 0xb3, 0x3f, 0x97, 0xd3, 0x97, 0xb2, 0xaa, 0x18, 0x1c, 0x9e, 0x03, 0x77, 0x7b, 0x5b, 0x7e, 0xf9, 0xa3, 0xa0, 0xd6, 0x20, 0x81, 0x2c, 0x38, 0x8f, 0x9d, 0x25, 0xde, 0xe9, 0xc8, 0xf5, 0xdd, 0x6a, 0x47, 0x9c, 0x65, 0x04, 0x5a, 0x56, 0xe6, 0xc2, 0xeb, 0xf2, 0x02, 0x97, 0xe1, 0xb9, 0xd8, 0xe1, 0x24, 0x76, 0x9f, 0x23, 0x62, 0x39, 0x03, 0x4b, 0xc8, 0xf7, 0x34, 0x07, 0x49, 0xd6, 0xe7, 0x4d, 0x9a, }; const unsigned char sig[70] = { 0x30, 0x44, 0x02, 0x20, 0x54, 0x92, 0x28, 0x3b, 0x83, 0x33, 0x47, 0x56, 0x68, 0x79, 0xb2, 0x0c, 0x84, 0x80, 0xcc, 0x67, 0x27, 0x8b, 0xfa, 0x48, 0x43, 0x0d, 0x3c, 0xb4, 0x02, 0x36, 0x87, 0x97, 0x3e, 0xdf, 0x2f, 0x65, 0x02, 0x20, 0x1b, 0x56, 0x17, 0x06, 0xe2, 0x26, 0x0f, 0x6a, 0xe9, 0xa9, 0x70, 0x99, 0x62, 0xeb, 0x3a, 0x04, 0x1a, 0xc4, 0xa7, 0x03, 0x28, 0x56, 0x7c, 0xed, 0x47, 0x08, 0x68, 0x73, 0x6a, 0xb6, 0x89, 0x0d, }; const unsigned char pubkey[64] = { 0x17, 0x5b, 0x27, 0xa6, 0x56, 0xb2, 0x26, 0x0c, 0x26, 0x0c, 0x55, 0x42, 0x78, 0x17, 0x5d, 0x4c, 0xf8, 0xa2, 0xfd, 0x1b, 0xb9, 0x54, 0xdf, 0xd5, 0xeb, 0xbf, 0x22, 0x64, 0xf5, 0x21, 0x9a, 0xc6, 0x87, 0x5f, 0x90, 0xe6, 0xfd, 0x71, 0x27, 0x9f, 0xeb, 0xe3, 0x03, 0x44, 0xbc, 0x8d, 0x49, 0xc6, 0x1c, 0x31, 0x3b, 0x72, 0xae, 0xd4, 0x53, 0xb1, 0xfe, 0x5d, 0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2, }; const unsigned char pubkey_tpm_rs256[259] = { 0xc5, 0xb6, 0x9c, 0x06, 0x1d, 0xcf, 0xb9, 0xf2, 0x5e, 0x99, 0x7d, 0x6d, 0x73, 0xd8, 0x36, 0xc1, 0x4a, 0x90, 0x05, 0x4d, 0x82, 0x57, 0xc1, 0xb6, 0x6a, 0xd1, 0x43, 0x03, 0x85, 0xf8, 0x52, 0x4f, 0xd2, 0x27, 0x91, 0x0b, 0xb5, 0x93, 0xa0, 0x68, 0xf8, 0x80, 0x1b, 0xaa, 0x65, 0x97, 0x45, 0x11, 0x86, 0x34, 0xd6, 0x67, 0xf8, 0xd5, 0x12, 0x79, 0x84, 0xee, 0x70, 0x99, 0x00, 0x63, 0xa8, 0xb4, 0x43, 0x0b, 0x4c, 0x57, 0x4a, 0xd6, 0x9b, 0x75, 0x63, 0x8a, 0x46, 0x57, 0xdb, 0x14, 0xc8, 0x71, 0xd1, 0xb3, 0x07, 0x68, 0x58, 0xbc, 0x55, 0x84, 0x80, 0x2a, 0xd2, 0x36, 0x9f, 0xc1, 0x64, 0xa0, 0x11, 0x4b, 0xc9, 0x32, 0x31, 0x3a, 0xd6, 0x87, 0x26, 0x1a, 0x3a, 0x78, 0x3d, 0x89, 0xdb, 0x00, 0x28, 0x3b, 0xae, 0x2b, 0x1b, 0x56, 0xe2, 0x8c, 0x4c, 0x63, 0xac, 0x6e, 0x6c, 0xf7, 0xb5, 0x7d, 0x4d, 0x0b, 0x9f, 0x06, 0xa0, 0x10, 0x35, 0x38, 0x20, 0x4d, 0xcc, 0x07, 0xd7, 0x00, 0x4e, 0x86, 0xba, 0xfe, 0x8b, 0xe4, 0x3f, 0x4a, 0xd6, 0xca, 0xbf, 0x67, 0x40, 0x1a, 0xa4, 0xda, 0x82, 0x52, 0x15, 0xb8, 0x14, 0x3a, 0x7c, 0xa9, 0x02, 0xc1, 0x01, 0x69, 0xc6, 0x51, 0xd4, 0xbc, 0x1f, 0x95, 0xb2, 0xee, 0x1f, 0xdd, 0xb5, 0x73, 0x16, 0x5e, 0x29, 0x3f, 0x47, 0xac, 0x65, 0xfb, 0x63, 0x5c, 0xb9, 0xc8, 0x13, 0x2d, 0xec, 0x85, 0xde, 0x71, 0x0d, 0x84, 0x93, 0x74, 0x76, 0x91, 0xdd, 0x1d, 0x6d, 0x3d, 0xc7, 0x36, 0x19, 0x19, 0x86, 0xde, 0x7c, 0xca, 0xd6, 0xc6, 0x65, 0x7e, 0x4b, 0x24, 0x9c, 0xce, 0x92, 0x6b, 0x1c, 0xe0, 0xa0, 0xa9, 0x6c, 0xc3, 0xed, 0x4f, 0x2a, 0x54, 0x07, 0x00, 0x32, 0x5e, 0x1b, 0x94, 0x37, 0xcd, 0xe2, 0x32, 0xa8, 0xd5, 0x2c, 0xfb, 0x03, 0x9d, 0x79, 0xdf, 0x01, 0x00, 0x01, }; const unsigned char pubkey_tpm_es256[64] = { 0xfb, 0xd6, 0xba, 0x74, 0xe6, 0x6e, 0x5c, 0x87, 0xef, 0x89, 0xa2, 0xe8, 0x3d, 0x0b, 0xe9, 0x69, 0x2c, 0x07, 0x07, 0x7a, 0x8a, 0x1e, 0xce, 0x12, 0xea, 0x3b, 0xb3, 0xf1, 0xf3, 0xd9, 0xc3, 0xe6, 0x3c, 0x68, 0x51, 0x94, 0x54, 0x8d, 0xeb, 0x9f, 0xb2, 0x2c, 0x66, 0x75, 0xb6, 0xb7, 0x55, 0x22, 0x0d, 0x87, 0x59, 0xc4, 0x39, 0x91, 0x62, 0x17, 0xc2, 0xc3, 0x53, 0xa5, 0x26, 0x97, 0x4f, 0x2d }; const unsigned char id[64] = { 0x53, 0xfb, 0xdf, 0xaa, 0xce, 0x63, 0xde, 0xc5, 0xfe, 0x47, 0xe6, 0x52, 0xeb, 0xf3, 0x5d, 0x53, 0xa8, 0xbf, 0x9d, 0xd6, 0x09, 0x6b, 0x5e, 0x7f, 0xe0, 0x0d, 0x51, 0x30, 0x85, 0x6a, 0xda, 0x68, 0x70, 0x85, 0xb0, 0xdb, 0x08, 0x0b, 0x83, 0x2c, 0xef, 0x44, 0xe2, 0x36, 0x88, 0xee, 0x76, 0x90, 0x6e, 0x7b, 0x50, 0x3e, 0x9a, 0xa0, 0xd6, 0x3c, 0x34, 0xe3, 0x83, 0xe7, 0xd1, 0xbd, 0x9f, 0x25, }; const unsigned char id_tpm_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 id_tpm_es256[32] = { 0xa8, 0xdf, 0x03, 0xf7, 0xbf, 0x39, 0x51, 0x94, 0x95, 0x8f, 0xa4, 0x84, 0x97, 0x30, 0xbc, 0x3c, 0x7e, 0x1c, 0x99, 0x91, 0x4d, 0xae, 0x6d, 0xfb, 0xdf, 0x53, 0xb5, 0xb6, 0x1f, 0x3a, 0x4e, 0x6a }; const unsigned char attstmt_tpm_rs256[4034] = { 0xa6, 0x63, 0x61, 0x6c, 0x67, 0x39, 0xff, 0xfe, 0x63, 0x73, 0x69, 0x67, 0x59, 0x01, 0x00, 0x1c, 0x09, 0x0d, 0x35, 0x97, 0x22, 0xfc, 0xfe, 0xc0, 0x58, 0x49, 0x9e, 0xd4, 0x7e, 0x6a, 0x7d, 0xdb, 0x6d, 0x20, 0x95, 0x5c, 0x0b, 0xd0, 0xd5, 0x72, 0x4f, 0x15, 0x22, 0x38, 0x97, 0xb2, 0x4b, 0xd0, 0xef, 0x31, 0x7c, 0xf2, 0x42, 0x19, 0x41, 0xa1, 0xe2, 0xc5, 0xca, 0xc6, 0x74, 0x95, 0xcf, 0xf9, 0x41, 0x75, 0x0b, 0x56, 0x39, 0x82, 0x78, 0xf6, 0x59, 0xf1, 0x09, 0x96, 0x9e, 0x38, 0x7f, 0x14, 0x9b, 0xf5, 0x36, 0xbb, 0x92, 0x32, 0xc4, 0x64, 0xe8, 0xff, 0xb4, 0xc7, 0xcf, 0xcd, 0x17, 0x48, 0x0f, 0x83, 0xd9, 0x44, 0x03, 0x35, 0x26, 0xad, 0x01, 0xb7, 0x57, 0x06, 0xb3, 0x9c, 0xa0, 0x6e, 0x2f, 0x58, 0xcb, 0x5c, 0xaa, 0x7c, 0xea, 0x7e, 0x3f, 0xbc, 0x76, 0xc9, 0x0e, 0x52, 0x39, 0x81, 0xa9, 0x9e, 0x37, 0x14, 0x1f, 0x50, 0x6a, 0x4f, 0xd7, 0xfc, 0xd4, 0xfa, 0xf2, 0x18, 0x60, 0xd5, 0xc3, 0x57, 0x7d, 0x6d, 0x05, 0x28, 0x25, 0xc3, 0xde, 0x86, 0x85, 0x06, 0x71, 0xfb, 0x84, 0xa2, 0x07, 0xb6, 0x77, 0xc9, 0x68, 0x41, 0x53, 0x32, 0x4c, 0xa8, 0x4b, 0xf7, 0x08, 0x84, 0x62, 0x6c, 0x8a, 0xb6, 0xcf, 0xc1, 0xde, 0x6b, 0x61, 0xc8, 0xdd, 0xc0, 0x13, 0x70, 0x22, 0x28, 0xe1, 0x0f, 0x46, 0x02, 0xc6, 0xb1, 0xfa, 0x30, 0xcb, 0xec, 0xd1, 0x82, 0xfa, 0x51, 0xcb, 0x71, 0x5e, 0x1f, 0x1b, 0x5f, 0xe0, 0xb0, 0x02, 0x8a, 0x7c, 0x78, 0xd1, 0xb7, 0x4d, 0x56, 0xb0, 0x92, 0x3e, 0xda, 0xc7, 0xb1, 0x74, 0xcf, 0x6a, 0x40, 0xeb, 0x98, 0x1c, 0x2e, 0xf2, 0x86, 0x76, 0xf8, 0x2e, 0x6a, 0x9f, 0x77, 0x51, 0x64, 0xce, 0xdc, 0x12, 0x85, 0x84, 0x6b, 0x01, 0xc8, 0xeb, 0xbc, 0x57, 0x6c, 0x32, 0x26, 0xcb, 0xb2, 0x84, 0x02, 0x2a, 0x33, 0x15, 0xd9, 0xe3, 0x15, 0xfc, 0x3a, 0x24, 0x63, 0x76, 0x65, 0x72, 0x63, 0x32, 0x2e, 0x30, 0x63, 0x78, 0x35, 0x63, 0x82, 0x59, 0x05, 0xc4, 0x30, 0x82, 0x05, 0xc0, 0x30, 0x82, 0x03, 0xa8, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x78, 0xd9, 0xa8, 0xb2, 0x64, 0xf9, 0x4d, 0x28, 0x82, 0xc0, 0xd3, 0x1b, 0x40, 0x3c, 0xc8, 0xd9, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x41, 0x31, 0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x36, 0x45, 0x55, 0x53, 0x2d, 0x53, 0x54, 0x4d, 0x2d, 0x4b, 0x45, 0x59, 0x49, 0x44, 0x2d, 0x31, 0x41, 0x44, 0x42, 0x39, 0x39, 0x34, 0x41, 0x42, 0x35, 0x38, 0x42, 0x45, 0x35, 0x37, 0x41, 0x30, 0x43, 0x43, 0x39, 0x42, 0x39, 0x30, 0x30, 0x45, 0x37, 0x38, 0x35, 0x31, 0x45, 0x31, 0x41, 0x34, 0x33, 0x43, 0x30, 0x38, 0x36, 0x36, 0x30, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x37, 0x31, 0x35, 0x31, 0x31, 0x31, 0x32, 0x31, 0x33, 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x33, 0x32, 0x31, 0x32, 0x30, 0x32, 0x39, 0x31, 0x35, 0x5a, 0x30, 0x00, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xca, 0xbe, 0x77, 0x9f, 0x45, 0x97, 0x17, 0x8d, 0x01, 0xe1, 0x18, 0xcc, 0xf0, 0xb5, 0xed, 0x9a, 0xb7, 0x36, 0xac, 0x05, 0x26, 0xbe, 0x35, 0xd9, 0x5c, 0x00, 0x5c, 0x5d, 0x8b, 0x6f, 0x2a, 0xb8, 0xf6, 0x02, 0x4f, 0x33, 0xfe, 0x84, 0x45, 0x4c, 0x4f, 0x7a, 0xdb, 0xa9, 0x6a, 0x62, 0x0f, 0x19, 0x35, 0x5d, 0xd2, 0x34, 0x1a, 0x9d, 0x73, 0x55, 0xe5, 0x3e, 0x04, 0xa2, 0xd6, 0xbe, 0xe7, 0x5a, 0xb9, 0x16, 0x6c, 0x55, 0x18, 0xa8, 0x4b, 0xb2, 0x37, 0xb9, 0xa3, 0x87, 0xfc, 0x76, 0xa8, 0x55, 0xc9, 0xe7, 0x30, 0xe5, 0x0e, 0x3c, 0x7b, 0x74, 0xd2, 0x1e, 0xa8, 0x05, 0xd5, 0xe2, 0xe3, 0xcb, 0xaf, 0x63, 0x33, 0x12, 0xaa, 0xfd, 0x31, 0x32, 0x71, 0x4f, 0x41, 0x96, 0x05, 0xb5, 0x69, 0x73, 0x45, 0xbe, 0x6f, 0x90, 0xd9, 0x10, 0x36, 0xaf, 0x7a, 0x1c, 0xf1, 0x6d, 0x14, 0xb0, 0x1e, 0xbb, 0xae, 0x1c, 0x35, 0xec, 0x1c, 0xb5, 0x0e, 0xf6, 0x33, 0x98, 0x13, 0x4e, 0x44, 0x7b, 0x5c, 0x97, 0x47, 0xed, 0x4f, 0xfe, 0xbd, 0x08, 0xd2, 0xa9, 0xc6, 0xbe, 0x8c, 0x04, 0x9e, 0xdc, 0x3d, 0xbe, 0x98, 0xe9, 0x2a, 0xb1, 0xf4, 0xfa, 0x45, 0xf9, 0xc8, 0x9a, 0x55, 0x85, 0x26, 0xfc, 0x5f, 0xad, 0x00, 0x8b, 0xc8, 0x41, 0xf2, 0x86, 0x4e, 0xba, 0x55, 0x1c, 0xb2, 0x89, 0xe8, 0x85, 0x6e, 0x1e, 0x02, 0x9f, 0x55, 0x70, 0xbe, 0xfd, 0xe7, 0x9f, 0xba, 0x59, 0xa0, 0x2e, 0x9a, 0x74, 0x11, 0xe7, 0xad, 0xa9, 0xc7, 0x7b, 0x58, 0xc4, 0x16, 0xd3, 0x35, 0xcb, 0x61, 0x00, 0xec, 0x36, 0x4a, 0xa3, 0x51, 0xa3, 0xdd, 0x61, 0xb6, 0xd6, 0x29, 0xcb, 0x76, 0xe1, 0xab, 0x51, 0x3a, 0xe8, 0xbf, 0xdb, 0x09, 0x4a, 0x39, 0x96, 0xd9, 0xac, 0x8f, 0x6c, 0x62, 0xe0, 0x03, 0x23, 0x24, 0xbe, 0xd4, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xf3, 0x30, 0x82, 0x01, 0xef, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x6d, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x01, 0x01, 0xff, 0x04, 0x63, 0x30, 0x61, 0x30, 0x5f, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x1f, 0x30, 0x52, 0x30, 0x50, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x44, 0x1e, 0x42, 0x00, 0x54, 0x00, 0x43, 0x00, 0x50, 0x00, 0x41, 0x00, 0x20, 0x00, 0x20, 0x00, 0x54, 0x00, 0x72, 0x00, 0x75, 0x00, 0x73, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x20, 0x00, 0x50, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x74, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x49, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x69, 0x00, 0x74, 0x00, 0x79, 0x30, 0x10, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x09, 0x30, 0x07, 0x06, 0x05, 0x67, 0x81, 0x05, 0x08, 0x03, 0x30, 0x59, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x01, 0x01, 0xff, 0x04, 0x4f, 0x30, 0x4d, 0xa4, 0x4b, 0x30, 0x49, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67, 0x81, 0x05, 0x02, 0x01, 0x0c, 0x0b, 0x69, 0x64, 0x3a, 0x35, 0x33, 0x35, 0x34, 0x34, 0x44, 0x32, 0x30, 0x31, 0x17, 0x30, 0x15, 0x06, 0x05, 0x67, 0x81, 0x05, 0x02, 0x02, 0x0c, 0x0c, 0x53, 0x54, 0x33, 0x33, 0x48, 0x54, 0x50, 0x48, 0x41, 0x48, 0x42, 0x34, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67, 0x81, 0x05, 0x02, 0x03, 0x0c, 0x0b, 0x69, 0x64, 0x3a, 0x30, 0x30, 0x34, 0x39, 0x30, 0x30, 0x30, 0x34, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb8, 0x5f, 0xd5, 0x67, 0xca, 0x92, 0xc4, 0x0e, 0xcf, 0x0c, 0xd8, 0x1f, 0x6d, 0x3f, 0x03, 0x55, 0x6f, 0x38, 0xa6, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd4, 0x04, 0x64, 0xfc, 0x6e, 0x50, 0x0a, 0x56, 0x48, 0x0f, 0x05, 0xa9, 0x00, 0xb7, 0x1d, 0x5e, 0x57, 0x08, 0xd5, 0xdc, 0x30, 0x81, 0xb2, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xa5, 0x30, 0x81, 0xa2, 0x30, 0x81, 0x9f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0x92, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x7a, 0x63, 0x73, 0x70, 0x72, 0x6f, 0x64, 0x65, 0x75, 0x73, 0x61, 0x69, 0x6b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x2e, 0x62, 0x6c, 0x6f, 0x62, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x65, 0x75, 0x73, 0x2d, 0x73, 0x74, 0x6d, 0x2d, 0x6b, 0x65, 0x79, 0x69, 0x64, 0x2d, 0x31, 0x61, 0x64, 0x62, 0x39, 0x39, 0x34, 0x61, 0x62, 0x35, 0x38, 0x62, 0x65, 0x35, 0x37, 0x61, 0x30, 0x63, 0x63, 0x39, 0x62, 0x39, 0x30, 0x30, 0x65, 0x37, 0x38, 0x35, 0x31, 0x65, 0x31, 0x61, 0x34, 0x33, 0x63, 0x30, 0x38, 0x36, 0x36, 0x30, 0x2f, 0x61, 0x62, 0x64, 0x36, 0x31, 0x35, 0x66, 0x32, 0x2d, 0x31, 0x35, 0x38, 0x61, 0x2d, 0x34, 0x35, 0x38, 0x65, 0x2d, 0x61, 0x31, 0x35, 0x35, 0x2d, 0x37, 0x63, 0x34, 0x63, 0x38, 0x63, 0x62, 0x31, 0x33, 0x63, 0x36, 0x35, 0x2e, 0x63, 0x65, 0x72, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0xa2, 0x10, 0xc5, 0xbf, 0x41, 0xa6, 0xba, 0x8c, 0x72, 0xca, 0x0f, 0x3e, 0x5e, 0x7f, 0xe2, 0xcb, 0x60, 0xb8, 0x3f, 0xfb, 0xde, 0x03, 0xe2, 0xfe, 0x20, 0x29, 0xdf, 0x11, 0xf5, 0xb0, 0x50, 0x6d, 0x32, 0xe8, 0x1b, 0x05, 0xad, 0x6b, 0x60, 0xb5, 0xed, 0xf3, 0xa4, 0x4a, 0xea, 0x09, 0xe5, 0x65, 0x7e, 0xe0, 0xd5, 0x3a, 0x6a, 0xdb, 0x64, 0xb7, 0x07, 0x8f, 0xa1, 0x63, 0xb3, 0x89, 0x8a, 0xac, 0x49, 0x97, 0xa0, 0x9a, 0xa3, 0xd3, 0x3a, 0xc2, 0x13, 0xb2, 0xbb, 0xab, 0x0d, 0xf2, 0x35, 0xc5, 0x03, 0xde, 0x1c, 0xad, 0x6a, 0x03, 0x0a, 0x4c, 0xe1, 0x37, 0x8f, 0xbc, 0x13, 0xc0, 0x9a, 0x17, 0xd4, 0x2e, 0x36, 0x17, 0x51, 0x12, 0xb0, 0x79, 0xbf, 0x9b, 0xb3, 0xb0, 0x74, 0x25, 0x81, 0x7e, 0x21, 0x31, 0xb7, 0xc2, 0x5e, 0xfb, 0x36, 0xab, 0xf3, 0x7a, 0x5f, 0xa4, 0x5e, 0x8f, 0x0c, 0xbd, 0xcf, 0xf5, 0x50, 0xe7, 0x0c, 0x51, 0x55, 0x48, 0xe6, 0x15, 0xb6, 0xd4, 0xaf, 0x95, 0x72, 0x56, 0x94, 0xf7, 0x0e, 0xd6, 0x90, 0xe3, 0xd3, 0x5d, 0xbd, 0x93, 0xa1, 0xbd, 0x6c, 0xe4, 0xf2, 0x39, 0x4d, 0x54, 0x74, 0xcf, 0xf5, 0xeb, 0x70, 0xdb, 0x4f, 0x52, 0xcd, 0x39, 0x8f, 0x11, 0x54, 0x28, 0x06, 0x29, 0x8f, 0x23, 0xde, 0x9e, 0x2f, 0x7b, 0xb6, 0x5f, 0xa3, 0x89, 0x04, 0x99, 0x0a, 0xf1, 0x2d, 0xf9, 0x66, 0xd3, 0x13, 0x45, 0xbd, 0x6c, 0x22, 0x57, 0xf5, 0xb1, 0xb9, 0xdf, 0x5b, 0x7b, 0x1a, 0x3a, 0xdd, 0x6b, 0xc7, 0x35, 0x88, 0xed, 0xc4, 0x09, 0x70, 0x4e, 0x5f, 0xb5, 0x3e, 0xd1, 0x0b, 0xd0, 0xca, 0xef, 0x0b, 0xe9, 0x8b, 0x6f, 0xc3, 0x16, 0xc3, 0x3d, 0x79, 0x06, 0xef, 0x81, 0xf0, 0x60, 0x0b, 0x32, 0xe3, 0x86, 0x6b, 0x92, 0x38, 0x90, 0x62, 0xed, 0x84, 0x3a, 0xb7, 0x45, 0x43, 0x2e, 0xd0, 0x3a, 0x71, 0x9e, 0x80, 0xcc, 0x9c, 0xac, 0x27, 0x10, 0x91, 0xb7, 0xb2, 0xbd, 0x41, 0x40, 0xa7, 0xb7, 0xcf, 0xe7, 0x38, 0xca, 0x68, 0xdd, 0x62, 0x09, 0xff, 0x68, 0xce, 0xba, 0xe2, 0x07, 0x49, 0x09, 0xe7, 0x1f, 0xdf, 0xe6, 0x26, 0xe5, 0x0f, 0xa9, 0xbf, 0x2a, 0x5b, 0x67, 0x92, 0xa1, 0x10, 0x53, 0xb2, 0x7a, 0x07, 0x29, 0x9d, 0xfd, 0x6d, 0xb6, 0x3b, 0x45, 0xc1, 0x94, 0xcb, 0x1c, 0xc3, 0xce, 0xf6, 0x8a, 0x1a, 0x81, 0x66, 0xb0, 0xa5, 0x14, 0xc7, 0x9e, 0x1f, 0x6e, 0xb6, 0xff, 0x8b, 0x90, 0x87, 0x3a, 0x3f, 0xa8, 0xc2, 0x2d, 0x8f, 0x6f, 0xdb, 0xb4, 0xc4, 0x14, 0x3c, 0x1d, 0x12, 0x1d, 0x6d, 0xcf, 0xa6, 0x04, 0x6a, 0xa8, 0x13, 0x5e, 0xf2, 0x5e, 0x77, 0x80, 0x6b, 0x85, 0x83, 0xfe, 0xbb, 0xeb, 0x70, 0xcb, 0x5f, 0xe4, 0x95, 0xaa, 0x0f, 0x61, 0x36, 0x7c, 0xbb, 0x22, 0x1e, 0xba, 0x98, 0x43, 0x52, 0x33, 0xae, 0xed, 0x5d, 0x10, 0x2c, 0xb3, 0xa9, 0x31, 0x8e, 0x60, 0x54, 0xaf, 0x40, 0x6d, 0x2e, 0x18, 0xc2, 0x6a, 0xf4, 0x7b, 0x9a, 0x73, 0x0f, 0x58, 0x69, 0x23, 0xbb, 0xc4, 0x84, 0x53, 0x30, 0xe2, 0xd6, 0x1e, 0x10, 0xc1, 0xec, 0x82, 0x13, 0xab, 0x53, 0x86, 0xa2, 0xb9, 0xda, 0xbb, 0x3a, 0xa2, 0xbe, 0xb0, 0x10, 0x99, 0x0e, 0xe5, 0x9c, 0xc9, 0xf1, 0xce, 0x76, 0x46, 0xea, 0x86, 0xaa, 0x36, 0x83, 0x99, 0x09, 0x9b, 0x30, 0xd3, 0x26, 0xc7, 0xdf, 0x66, 0xc7, 0xf0, 0xdd, 0x08, 0x09, 0x15, 0x15, 0x21, 0x49, 0x46, 0xd8, 0x8a, 0x66, 0xca, 0x62, 0x9c, 0x79, 0x1d, 0x81, 0xea, 0x5d, 0x82, 0xb0, 0xa6, 0x6b, 0x5c, 0xf5, 0xb8, 0x8c, 0xf6, 0x16, 0x01, 0x2c, 0xf8, 0x27, 0xf8, 0xcf, 0x88, 0xfe, 0xf3, 0xa4, 0xfc, 0x17, 0x97, 0xe7, 0x07, 0x59, 0x06, 0xef, 0x30, 0x82, 0x06, 0xeb, 0x30, 0x82, 0x04, 0xd3, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x13, 0x33, 0x00, 0x00, 0x02, 0x39, 0xf9, 0xbb, 0x6a, 0x1d, 0x49, 0x64, 0x47, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x8c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x54, 0x50, 0x4d, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x34, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x33, 0x32, 0x31, 0x32, 0x30, 0x32, 0x39, 0x31, 0x35, 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x33, 0x32, 0x31, 0x32, 0x30, 0x32, 0x39, 0x31, 0x35, 0x5a, 0x30, 0x41, 0x31, 0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x36, 0x45, 0x55, 0x53, 0x2d, 0x53, 0x54, 0x4d, 0x2d, 0x4b, 0x45, 0x59, 0x49, 0x44, 0x2d, 0x31, 0x41, 0x44, 0x42, 0x39, 0x39, 0x34, 0x41, 0x42, 0x35, 0x38, 0x42, 0x45, 0x35, 0x37, 0x41, 0x30, 0x43, 0x43, 0x39, 0x42, 0x39, 0x30, 0x30, 0x45, 0x37, 0x38, 0x35, 0x31, 0x45, 0x31, 0x41, 0x34, 0x33, 0x43, 0x30, 0x38, 0x36, 0x36, 0x30, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xdb, 0xe2, 0x23, 0xf9, 0x86, 0x8f, 0xa9, 0x71, 0x9f, 0x8b, 0xf9, 0x7c, 0xe9, 0x45, 0x2d, 0x59, 0x56, 0x5e, 0x96, 0xf4, 0xdd, 0x9a, 0x12, 0xcd, 0x90, 0x1a, 0x0c, 0xb5, 0x03, 0xbf, 0x09, 0xbe, 0xbf, 0xf7, 0x55, 0x52, 0xe8, 0x39, 0x4c, 0xbe, 0x2a, 0x28, 0x88, 0x78, 0x39, 0xa7, 0xcb, 0xf9, 0x4c, 0x55, 0xd2, 0x31, 0x96, 0x3b, 0x48, 0xa2, 0xf3, 0xf6, 0xd3, 0x1a, 0x81, 0x7f, 0x90, 0x62, 0xab, 0xec, 0x5a, 0xc7, 0xa0, 0x7f, 0x81, 0x32, 0x27, 0x9b, 0x29, 0x75, 0x7d, 0x1e, 0x96, 0xc5, 0xfa, 0x0e, 0x7c, 0xe0, 0x60, 0x96, 0x7a, 0xca, 0x94, 0xba, 0xe6, 0xb2, 0x69, 0xdd, 0xc4, 0x7d, 0xbb, 0xd3, 0xc4, 0xb4, 0x6e, 0x00, 0x86, 0x1f, 0x9d, 0x25, 0xe8, 0xae, 0xc7, 0x10, 0x84, 0xdc, 0xc0, 0x34, 0x24, 0x6e, 0xf7, 0xfc, 0xdd, 0x3d, 0x32, 0x7a, 0x43, 0x96, 0xd6, 0xc8, 0x7b, 0xf4, 0x9b, 0x3d, 0xa7, 0x1e, 0xba, 0x4d, 0xd0, 0x3b, 0x3d, 0x84, 0x9a, 0xd1, 0x25, 0x22, 0x5d, 0x00, 0x44, 0xb0, 0x59, 0xb7, 0x40, 0xc5, 0xa3, 0x53, 0x53, 0xaf, 0x8f, 0x9e, 0xfd, 0x8f, 0x1e, 0x02, 0xd3, 0x4f, 0xf7, 0x09, 0xce, 0xc5, 0xc6, 0x71, 0x5c, 0xe9, 0xe8, 0x7a, 0xb5, 0x6b, 0xa4, 0xbf, 0x0b, 0xd9, 0xb6, 0xfa, 0x24, 0xb0, 0xcd, 0x52, 0x22, 0x1d, 0x7e, 0xe8, 0x15, 0x2f, 0x1e, 0x5e, 0xa2, 0xec, 0xd3, 0xa8, 0x02, 0x77, 0xb9, 0x55, 0x9a, 0xcf, 0xcc, 0xd7, 0x08, 0x20, 0xa5, 0xda, 0x39, 0x9a, 0x30, 0x76, 0x90, 0x37, 0xa7, 0x60, 0xdf, 0x18, 0x12, 0x65, 0x17, 0xaa, 0xdd, 0x48, 0xd5, 0x12, 0x1d, 0x4c, 0x83, 0x5d, 0x81, 0x07, 0x1d, 0x18, 0x81, 0x40, 0x55, 0x60, 0x8f, 0xa3, 0x6b, 0x34, 0x1e, 0xd5, 0xe6, 0xcf, 0x52, 0x73, 0x77, 0x4a, 0x50, 0x4f, 0x1b, 0x0f, 0x39, 0xc3, 0x0d, 0x16, 0xf9, 0xbb, 0x4c, 0x77, 0xf6, 0x4e, 0xac, 0x9c, 0xfe, 0xe8, 0xbb, 0x52, 0xa5, 0x0a, 0x0e, 0x9b, 0xf0, 0x0d, 0xef, 0xfb, 0x6f, 0x89, 0x34, 0x7d, 0x47, 0xec, 0x14, 0x6a, 0xf4, 0x0a, 0xe1, 0x60, 0x44, 0x73, 0x7b, 0xa0, 0xab, 0x5b, 0x8c, 0x43, 0xa6, 0x05, 0x42, 0x61, 0x46, 0xaa, 0x1c, 0xf5, 0xec, 0x2c, 0x86, 0x85, 0x21, 0x99, 0xdf, 0x45, 0x8e, 0xf4, 0xd1, 0x1e, 0xfb, 0xcd, 0x9b, 0x94, 0x32, 0xe0, 0xa0, 0xcc, 0x4f, 0xad, 0xae, 0x44, 0x8b, 0x86, 0x27, 0x91, 0xfe, 0x60, 0x9f, 0xf2, 0x63, 0x30, 0x6c, 0x5d, 0x8d, 0xbc, 0xab, 0xd4, 0xf5, 0xa2, 0xb2, 0x74, 0xe8, 0xd4, 0x95, 0xf2, 0xd6, 0x03, 0x8b, 0xc9, 0xa3, 0x52, 0xe7, 0x63, 0x05, 0x64, 0x50, 0xe5, 0x0a, 0x6a, 0xa0, 0x6c, 0x50, 0xcd, 0x37, 0x98, 0xa8, 0x87, 0x02, 0x38, 0x5b, 0x6c, 0x02, 0x69, 0x3d, 0x1f, 0x95, 0x74, 0x4d, 0x46, 0x76, 0x2a, 0x9d, 0x62, 0xd4, 0xc7, 0x1b, 0xf9, 0x31, 0xa6, 0x51, 0xee, 0x7b, 0xc8, 0xe4, 0x6e, 0x3a, 0xcf, 0x4f, 0x4f, 0x49, 0x8a, 0xf5, 0x4f, 0x25, 0x93, 0x23, 0x02, 0xef, 0x79, 0xa6, 0x27, 0xbe, 0x5a, 0xe7, 0x74, 0xb7, 0xd7, 0xa8, 0xc1, 0xae, 0x55, 0x88, 0xa4, 0xc7, 0x4d, 0xb7, 0x62, 0xf0, 0xf9, 0x5b, 0xbf, 0x47, 0x5b, 0xfe, 0xcc, 0x0b, 0x89, 0x19, 0x65, 0x4b, 0x6f, 0xdf, 0x4f, 0x7d, 0x4d, 0x96, 0x42, 0x0d, 0x2a, 0xa1, 0xbd, 0x3e, 0x70, 0x92, 0xba, 0xc8, 0x59, 0xd5, 0x1d, 0x3a, 0x98, 0x53, 0x75, 0xa6, 0x32, 0xc8, 0x72, 0x03, 0x46, 0x5f, 0x5c, 0x13, 0xa4, 0xdb, 0xc7, 0x55, 0x35, 0x22, 0x0d, 0xc6, 0x17, 0x85, 0xbd, 0x46, 0x4b, 0xfa, 0x1e, 0x49, 0xc2, 0xfe, 0x1e, 0xf9, 0x62, 0x89, 0x56, 0x84, 0xdf, 0xa0, 0xfb, 0xfd, 0x93, 0xa4, 0x25, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x8e, 0x30, 0x82, 0x01, 0x8a, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x84, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x14, 0x30, 0x12, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x24, 0x06, 0x05, 0x67, 0x81, 0x05, 0x08, 0x03, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0f, 0x30, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x1f, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb8, 0x5f, 0xd5, 0x67, 0xca, 0x92, 0xc4, 0x0e, 0xcf, 0x0c, 0xd8, 0x1f, 0x6d, 0x3f, 0x03, 0x55, 0x6f, 0x38, 0xa6, 0x51, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7a, 0x8c, 0x0a, 0xce, 0x2f, 0x48, 0x62, 0x17, 0xe2, 0x94, 0xd1, 0xae, 0x55, 0xc1, 0x52, 0xec, 0x71, 0x74, 0xa4, 0x56, 0x30, 0x70, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x69, 0x30, 0x67, 0x30, 0x65, 0xa0, 0x63, 0xa0, 0x61, 0x86, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x6f, 0x70, 0x73, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x25, 0x32, 0x30, 0x54, 0x50, 0x4d, 0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x34, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x7d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x71, 0x30, 0x6f, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x61, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x6f, 0x70, 0x73, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x25, 0x32, 0x30, 0x54, 0x50, 0x4d, 0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x34, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x41, 0xaa, 0xfe, 0x28, 0x6c, 0xf7, 0x6b, 0x53, 0xde, 0x77, 0xc0, 0x80, 0x50, 0x94, 0xd9, 0xdb, 0x46, 0x8e, 0x6a, 0x93, 0xa9, 0x10, 0x37, 0x27, 0x1f, 0xf5, 0x70, 0xf1, 0xa8, 0xcf, 0xa1, 0x45, 0x86, 0x2a, 0xdd, 0x8f, 0xb8, 0xb5, 0xc1, 0xe6, 0xcf, 0x8a, 0xfa, 0x32, 0xa1, 0x4b, 0xb7, 0xa4, 0xbf, 0x0a, 0x48, 0xcb, 0x42, 0x63, 0x71, 0xc1, 0x96, 0xb9, 0x3a, 0x37, 0x84, 0x0e, 0x24, 0x39, 0xeb, 0x58, 0xce, 0x3d, 0xb7, 0xa9, 0x44, 0x92, 0x59, 0xb9, 0xff, 0xdb, 0x18, 0xbe, 0x6a, 0x5e, 0xe7, 0xce, 0xef, 0xb8, 0x40, 0x53, 0xaf, 0xc1, 0x9b, 0xfb, 0x42, 0x99, 0x7e, 0x9d, 0x05, 0x2b, 0x71, 0x0a, 0x7a, 0x7a, 0x44, 0xd1, 0x31, 0xca, 0xf0, 0x5f, 0x74, 0x85, 0xa9, 0xe2, 0xbc, 0xc8, 0x0c, 0xad, 0x57, 0xd1, 0xe9, 0x48, 0x90, 0x88, 0x57, 0x86, 0xd7, 0xc5, 0xc9, 0xe6, 0xb2, 0x5e, 0x5f, 0x13, 0xdc, 0x10, 0x7f, 0xdf, 0x63, 0x8a, 0xd5, 0x9e, 0x90, 0xc2, 0x75, 0x53, 0x1e, 0x68, 0x17, 0x2b, 0x03, 0x29, 0x15, 0x03, 0xc5, 0x8c, 0x66, 0x3e, 0xae, 0xbd, 0x4a, 0x32, 0x7e, 0x59, 0x89, 0x0b, 0x84, 0xc2, 0xd9, 0x90, 0xfa, 0x02, 0x22, 0x90, 0x8d, 0x9c, 0xb6, 0x0c, 0x4d, 0xe1, 0x28, 0x76, 0xd7, 0x82, 0xc3, 0x36, 0xc2, 0xa3, 0x2a, 0x52, 0xe5, 0xfe, 0x3c, 0x8f, 0xe3, 0x4b, 0xda, 0x6a, 0xdb, 0xc0, 0x7a, 0x3c, 0x57, 0xfa, 0x85, 0x8f, 0xfb, 0x62, 0xc3, 0xa1, 0x38, 0xce, 0x84, 0xf2, 0xba, 0x12, 0xf4, 0x30, 0x2a, 0x4a, 0x94, 0xa9, 0x35, 0x2c, 0x7d, 0x11, 0xc7, 0x68, 0x1f, 0x47, 0xaa, 0x57, 0x43, 0x06, 0x70, 0x79, 0x8c, 0xb6, 0x3b, 0x5d, 0x57, 0xf3, 0xf3, 0xc0, 0x2c, 0xc5, 0xde, 0x41, 0x99, 0xf6, 0xdd, 0x55, 0x8a, 0xe4, 0x13, 0xca, 0xc9, 0xec, 0x69, 0x93, 0x13, 0x48, 0xf0, 0x5f, 0xda, 0x2e, 0xfd, 0xfb, 0xa9, 0x1b, 0x92, 0xde, 0x49, 0x71, 0x37, 0x8c, 0x3f, 0xc2, 0x08, 0x0a, 0x83, 0x25, 0xf1, 0x6e, 0x0a, 0xe3, 0x55, 0x85, 0x96, 0x9a, 0x2d, 0xa2, 0xc0, 0xa1, 0xee, 0xfe, 0x23, 0x3b, 0x69, 0x22, 0x03, 0xfd, 0xcc, 0x8a, 0xdd, 0xb4, 0x53, 0x8d, 0x84, 0xa6, 0xac, 0xe0, 0x1e, 0x07, 0xe5, 0xd7, 0xf9, 0xcb, 0xb9, 0xe3, 0x9a, 0xb7, 0x84, 0x70, 0xa1, 0x93, 0xd6, 0x02, 0x1e, 0xfe, 0xdb, 0x28, 0x7c, 0xf7, 0xd4, 0x62, 0x6f, 0x80, 0x75, 0xc8, 0xd8, 0x35, 0x26, 0x0c, 0xcb, 0x84, 0xed, 0xbb, 0x95, 0xdf, 0x7f, 0xd5, 0xbb, 0x00, 0x96, 0x97, 0x32, 0xe7, 0xba, 0xe8, 0x29, 0xb5, 0x1a, 0x51, 0x81, 0xbb, 0x04, 0xd1, 0x21, 0x76, 0x34, 0x6d, 0x1e, 0x93, 0x96, 0x1f, 0x96, 0x53, 0x5f, 0x5c, 0x9e, 0xf3, 0x9d, 0x82, 0x1c, 0x39, 0x36, 0x59, 0xae, 0xc9, 0x3c, 0x53, 0x4a, 0x67, 0x65, 0x6e, 0xbf, 0xa6, 0xac, 0x3e, 0xda, 0xb2, 0xa7, 0x63, 0x07, 0x17, 0xe1, 0x5b, 0xda, 0x6a, 0x31, 0x9f, 0xfb, 0xb4, 0xea, 0xa1, 0x97, 0x08, 0x6e, 0xb2, 0x68, 0xf3, 0x72, 0x76, 0x99, 0xe8, 0x00, 0x46, 0x88, 0x26, 0xe1, 0x3c, 0x07, 0x2b, 0x78, 0x49, 0xda, 0x79, 0x3a, 0xbd, 0x6f, 0xca, 0x5c, 0xa0, 0xa8, 0xed, 0x34, 0xcc, 0xdb, 0x13, 0xe2, 0x51, 0x9b, 0x3d, 0x03, 0xac, 0xc7, 0xf6, 0x32, 0xe1, 0x11, 0x5d, 0xe1, 0xc5, 0xfd, 0x9e, 0x7a, 0xcd, 0x06, 0xb9, 0xe6, 0xfc, 0xe0, 0x03, 0x31, 0xf4, 0x4a, 0xa9, 0x3b, 0x79, 0x01, 0xb0, 0x64, 0x68, 0x9f, 0x6e, 0x76, 0xa1, 0xcc, 0xec, 0x17, 0x41, 0x9d, 0xd4, 0x5b, 0x4e, 0x9d, 0xe5, 0x46, 0xd4, 0x6b, 0x60, 0x2a, 0x23, 0xb5, 0x7a, 0x89, 0x7c, 0x27, 0x96, 0x65, 0x97, 0x56, 0xec, 0x98, 0xe3, 0x67, 0x70, 0x75, 0x62, 0x41, 0x72, 0x65, 0x61, 0x59, 0x01, 0x36, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x06, 0x04, 0x72, 0x00, 0x20, 0x9d, 0xff, 0xcb, 0xf3, 0x6c, 0x38, 0x3a, 0xe6, 0x99, 0xfb, 0x98, 0x68, 0xdc, 0x6d, 0xcb, 0x89, 0xd7, 0x15, 0x38, 0x84, 0xbe, 0x28, 0x03, 0x92, 0x2c, 0x12, 0x41, 0x58, 0xbf, 0xad, 0x22, 0xae, 0x00, 0x10, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc5, 0xb6, 0x9c, 0x06, 0x1d, 0xcf, 0xb9, 0xf2, 0x5e, 0x99, 0x7d, 0x6d, 0x73, 0xd8, 0x36, 0xc1, 0x4a, 0x90, 0x05, 0x4d, 0x82, 0x57, 0xc1, 0xb6, 0x6a, 0xd1, 0x43, 0x03, 0x85, 0xf8, 0x52, 0x4f, 0xd2, 0x27, 0x91, 0x0b, 0xb5, 0x93, 0xa0, 0x68, 0xf8, 0x80, 0x1b, 0xaa, 0x65, 0x97, 0x45, 0x11, 0x86, 0x34, 0xd6, 0x67, 0xf8, 0xd5, 0x12, 0x79, 0x84, 0xee, 0x70, 0x99, 0x00, 0x63, 0xa8, 0xb4, 0x43, 0x0b, 0x4c, 0x57, 0x4a, 0xd6, 0x9b, 0x75, 0x63, 0x8a, 0x46, 0x57, 0xdb, 0x14, 0xc8, 0x71, 0xd1, 0xb3, 0x07, 0x68, 0x58, 0xbc, 0x55, 0x84, 0x80, 0x2a, 0xd2, 0x36, 0x9f, 0xc1, 0x64, 0xa0, 0x11, 0x4b, 0xc9, 0x32, 0x31, 0x3a, 0xd6, 0x87, 0x26, 0x1a, 0x3a, 0x78, 0x3d, 0x89, 0xdb, 0x00, 0x28, 0x3b, 0xae, 0x2b, 0x1b, 0x56, 0xe2, 0x8c, 0x4c, 0x63, 0xac, 0x6e, 0x6c, 0xf7, 0xb5, 0x7d, 0x4d, 0x0b, 0x9f, 0x06, 0xa0, 0x10, 0x35, 0x38, 0x20, 0x4d, 0xcc, 0x07, 0xd7, 0x00, 0x4e, 0x86, 0xba, 0xfe, 0x8b, 0xe4, 0x3f, 0x4a, 0xd6, 0xca, 0xbf, 0x67, 0x40, 0x1a, 0xa4, 0xda, 0x82, 0x52, 0x15, 0xb8, 0x14, 0x3a, 0x7c, 0xa9, 0x02, 0xc1, 0x01, 0x69, 0xc6, 0x51, 0xd4, 0xbc, 0x1f, 0x95, 0xb2, 0xee, 0x1f, 0xdd, 0xb5, 0x73, 0x16, 0x5e, 0x29, 0x3f, 0x47, 0xac, 0x65, 0xfb, 0x63, 0x5c, 0xb9, 0xc8, 0x13, 0x2d, 0xec, 0x85, 0xde, 0x71, 0x0d, 0x84, 0x93, 0x74, 0x76, 0x91, 0xdd, 0x1d, 0x6d, 0x3d, 0xc7, 0x36, 0x19, 0x19, 0x86, 0xde, 0x7c, 0xca, 0xd6, 0xc6, 0x65, 0x7e, 0x4b, 0x24, 0x9c, 0xce, 0x92, 0x6b, 0x1c, 0xe0, 0xa0, 0xa9, 0x6c, 0xc3, 0xed, 0x4f, 0x2a, 0x54, 0x07, 0x00, 0x32, 0x5e, 0x1b, 0x94, 0x37, 0xcd, 0xe2, 0x32, 0xa8, 0xd5, 0x2c, 0xfb, 0x03, 0x9d, 0x79, 0xdf, 0x68, 0x63, 0x65, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x58, 0xa1, 0xff, 0x54, 0x43, 0x47, 0x80, 0x17, 0x00, 0x22, 0x00, 0x0b, 0xdb, 0x1f, 0x74, 0x21, 0x4f, 0xa9, 0x0d, 0x90, 0x64, 0xa2, 0x33, 0xbe, 0x3f, 0xf1, 0x95, 0xb0, 0x4e, 0x3f, 0x02, 0xdc, 0xad, 0xb0, 0x05, 0x13, 0xe6, 0x32, 0x5f, 0xed, 0x90, 0x2c, 0xad, 0xc0, 0x00, 0x14, 0x58, 0x52, 0x07, 0x5d, 0x64, 0x6c, 0x1f, 0xd1, 0x13, 0x7f, 0xc3, 0x74, 0xf6, 0x4b, 0xe3, 0xa0, 0x2e, 0xb7, 0x71, 0xda, 0x00, 0x00, 0x00, 0x00, 0x29, 0x3c, 0x64, 0xdf, 0x95, 0x38, 0xba, 0x73, 0xe3, 0x57, 0x61, 0xa0, 0x01, 0x24, 0x01, 0x08, 0xc9, 0xd6, 0xea, 0x60, 0xe4, 0x00, 0x22, 0x00, 0x0b, 0xe1, 0x86, 0xbb, 0x79, 0x27, 0xe5, 0x01, 0x19, 0x90, 0xb3, 0xe9, 0x08, 0xb0, 0xee, 0xfa, 0x3a, 0x67, 0xa9, 0xf3, 0xc8, 0x9e, 0x03, 0x41, 0x07, 0x75, 0x60, 0xbc, 0x94, 0x0c, 0x2a, 0xb7, 0xad, 0x00, 0x22, 0x00, 0x0b, 0x35, 0xb1, 0x72, 0xd6, 0x3c, 0xe9, 0x85, 0xe8, 0x66, 0xed, 0x10, 0x7a, 0x5c, 0xa3, 0xe6, 0xd9, 0x4d, 0xf0, 0x52, 0x69, 0x26, 0x14, 0xb4, 0x36, 0x7e, 0xad, 0x76, 0x9e, 0x58, 0x68, 0x3e, 0x91 }; const unsigned char attstmt_tpm_es256[3841] = { 0xa6, 0x63, 0x61, 0x6c, 0x67, 0x39, 0xff, 0xfe, 0x63, 0x73, 0x69, 0x67, 0x59, 0x01, 0x00, 0x6d, 0x11, 0x61, 0x1f, 0x45, 0xb9, 0x7f, 0x65, 0x6f, 0x97, 0x46, 0xfe, 0xbb, 0x8a, 0x98, 0x07, 0xa3, 0xbc, 0x67, 0x5c, 0xd7, 0x65, 0xa4, 0xf4, 0x6c, 0x5b, 0x37, 0x75, 0xa4, 0x7f, 0x08, 0x52, 0xeb, 0x1e, 0x12, 0xe2, 0x78, 0x8c, 0x7d, 0x94, 0xab, 0x7b, 0xed, 0x05, 0x17, 0x67, 0x7e, 0xaa, 0x02, 0x89, 0x6d, 0xe8, 0x6d, 0x43, 0x30, 0x99, 0xc6, 0xf9, 0x59, 0xe5, 0x82, 0x3c, 0x56, 0x4e, 0x77, 0x11, 0x25, 0xe4, 0x43, 0x6a, 0xae, 0x92, 0x4f, 0x60, 0x92, 0x50, 0xf9, 0x65, 0x0e, 0x44, 0x38, 0x3d, 0xf7, 0xaf, 0x66, 0x89, 0xc7, 0xe6, 0xe6, 0x01, 0x07, 0x9e, 0x90, 0xfd, 0x6d, 0xaa, 0x35, 0x51, 0x51, 0xbf, 0x54, 0x13, 0x95, 0xc2, 0x17, 0xfa, 0x32, 0x0f, 0xa7, 0x82, 0x17, 0x58, 0x6c, 0x3d, 0xea, 0x88, 0xd8, 0x64, 0xc7, 0xf8, 0xc2, 0xd6, 0x1c, 0xbb, 0xea, 0x1e, 0xb3, 0xd9, 0x4c, 0xa7, 0xce, 0x18, 0x1e, 0xcb, 0x42, 0x5f, 0xbf, 0x44, 0xe7, 0xf1, 0x22, 0xe0, 0x5b, 0xeb, 0xff, 0xb6, 0x1e, 0x6f, 0x60, 0x12, 0x16, 0x63, 0xfe, 0xab, 0x5e, 0x31, 0x13, 0xdb, 0x72, 0xc6, 0x9a, 0xf8, 0x8f, 0x19, 0x6b, 0x2e, 0xaf, 0x7d, 0xca, 0x9f, 0xbc, 0x6b, 0x1a, 0x8b, 0x5e, 0xe3, 0x9e, 0xaa, 0x8c, 0x79, 0x9c, 0x4e, 0xed, 0xe4, 0xff, 0x3d, 0x12, 0x79, 0x90, 0x09, 0x61, 0x97, 0x67, 0xbf, 0x04, 0xac, 0x37, 0xea, 0xa9, 0x1f, 0x9f, 0x52, 0x64, 0x0b, 0xeb, 0xc3, 0x61, 0xd4, 0x13, 0xb0, 0x84, 0xf1, 0x3c, 0x74, 0x83, 0xcc, 0xa8, 0x1c, 0x14, 0xe6, 0x9d, 0xfe, 0xec, 0xee, 0xa1, 0xd2, 0xc2, 0x0a, 0xa6, 0x36, 0x08, 0xbb, 0x17, 0xa5, 0x7b, 0x53, 0x34, 0x0e, 0xc9, 0x09, 0xe5, 0x10, 0xa6, 0x85, 0x01, 0x71, 0x66, 0xff, 0xd0, 0x6d, 0x4b, 0x93, 0xdb, 0x81, 0x25, 0x01, 0x63, 0x76, 0x65, 0x72, 0x63, 0x32, 0x2e, 0x30, 0x63, 0x78, 0x35, 0x63, 0x82, 0x59, 0x05, 0xc4, 0x30, 0x82, 0x05, 0xc0, 0x30, 0x82, 0x03, 0xa8, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x30, 0xcd, 0xf2, 0x7e, 0x81, 0xc0, 0x43, 0x85, 0xa2, 0xd7, 0x29, 0xef, 0xf7, 0x9f, 0xa5, 0x2b, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x41, 0x31, 0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x36, 0x45, 0x55, 0x53, 0x2d, 0x53, 0x54, 0x4d, 0x2d, 0x4b, 0x45, 0x59, 0x49, 0x44, 0x2d, 0x31, 0x41, 0x44, 0x42, 0x39, 0x39, 0x34, 0x41, 0x42, 0x35, 0x38, 0x42, 0x45, 0x35, 0x37, 0x41, 0x30, 0x43, 0x43, 0x39, 0x42, 0x39, 0x30, 0x30, 0x45, 0x37, 0x38, 0x35, 0x31, 0x45, 0x31, 0x41, 0x34, 0x33, 0x43, 0x30, 0x38, 0x36, 0x36, 0x30, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x30, 0x32, 0x31, 0x35, 0x30, 0x36, 0x35, 0x33, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x36, 0x30, 0x33, 0x31, 0x39, 0x34, 0x30, 0x31, 0x36, 0x5a, 0x30, 0x00, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xdb, 0xd5, 0x9a, 0xfc, 0x09, 0xa7, 0xc4, 0xa5, 0x5f, 0xbe, 0x5f, 0xa2, 0xeb, 0xd6, 0x8e, 0xed, 0xc5, 0x67, 0xa6, 0xa7, 0xd9, 0xb2, 0x46, 0xc6, 0xe0, 0xae, 0x0c, 0x02, 0x25, 0x0a, 0xf2, 0xc5, 0x96, 0xdc, 0xb7, 0x0e, 0xb9, 0x86, 0xd3, 0x51, 0xbb, 0x63, 0xf0, 0x4f, 0x8a, 0x5e, 0xd7, 0xf7, 0xff, 0xbb, 0x29, 0xbd, 0x58, 0xcf, 0x75, 0x02, 0x39, 0xcb, 0x80, 0xf1, 0xd4, 0xb6, 0x75, 0x67, 0x2f, 0x27, 0x4d, 0x0c, 0xcc, 0x18, 0x59, 0x87, 0xfa, 0x51, 0xd1, 0x80, 0xb5, 0x1a, 0xac, 0xac, 0x29, 0x51, 0xcf, 0x27, 0xaa, 0x74, 0xac, 0x3e, 0x59, 0x56, 0x67, 0xe4, 0x42, 0xe8, 0x30, 0x35, 0xb2, 0xf6, 0x27, 0x91, 0x62, 0x60, 0x42, 0x42, 0x12, 0xde, 0xfe, 0xdd, 0xee, 0xe8, 0xa8, 0x82, 0xf9, 0xb1, 0x08, 0xd5, 0x8d, 0x57, 0x9a, 0x29, 0xb9, 0xb4, 0xe9, 0x19, 0x1e, 0x33, 0x7d, 0x37, 0xa0, 0xce, 0x2e, 0x53, 0x13, 0x39, 0xb6, 0x12, 0x61, 0x63, 0xbf, 0xd3, 0x42, 0xeb, 0x6f, 0xed, 0xc1, 0x8e, 0x26, 0xba, 0x7d, 0x8b, 0x37, 0x7c, 0xbb, 0x42, 0x1e, 0x56, 0x76, 0xda, 0xdb, 0x35, 0x6b, 0x80, 0xe1, 0x8e, 0x00, 0xac, 0xd2, 0xfc, 0x22, 0x96, 0x14, 0x0c, 0xf4, 0xe4, 0xc5, 0xad, 0x14, 0xb7, 0x4d, 0x46, 0x63, 0x30, 0x79, 0x3a, 0x7c, 0x33, 0xb5, 0xe5, 0x2e, 0xbb, 0x5f, 0xca, 0xf2, 0x75, 0xe3, 0x4e, 0x99, 0x64, 0x1b, 0x26, 0x99, 0x60, 0x1a, 0x79, 0xcc, 0x30, 0x2c, 0xb3, 0x4c, 0x59, 0xf7, 0x77, 0x59, 0xd5, 0x90, 0x70, 0x21, 0x79, 0x8c, 0x1f, 0x79, 0x0a, 0x12, 0x8b, 0x3b, 0x37, 0x2d, 0x97, 0x39, 0x89, 0x92, 0x0c, 0x44, 0x7c, 0xe9, 0x9f, 0xce, 0x6d, 0xad, 0xc5, 0xae, 0xea, 0x8e, 0x50, 0x22, 0x37, 0xe0, 0xd1, 0x9e, 0xd6, 0xe6, 0xa8, 0xcc, 0x21, 0xfb, 0xff, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xf3, 0x30, 0x82, 0x01, 0xef, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x6d, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x01, 0x01, 0xff, 0x04, 0x63, 0x30, 0x61, 0x30, 0x5f, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x1f, 0x30, 0x52, 0x30, 0x50, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x44, 0x1e, 0x42, 0x00, 0x54, 0x00, 0x43, 0x00, 0x50, 0x00, 0x41, 0x00, 0x20, 0x00, 0x20, 0x00, 0x54, 0x00, 0x72, 0x00, 0x75, 0x00, 0x73, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x20, 0x00, 0x50, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x74, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x49, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x69, 0x00, 0x74, 0x00, 0x79, 0x30, 0x10, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x09, 0x30, 0x07, 0x06, 0x05, 0x67, 0x81, 0x05, 0x08, 0x03, 0x30, 0x59, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x01, 0x01, 0xff, 0x04, 0x4f, 0x30, 0x4d, 0xa4, 0x4b, 0x30, 0x49, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67, 0x81, 0x05, 0x02, 0x01, 0x0c, 0x0b, 0x69, 0x64, 0x3a, 0x35, 0x33, 0x35, 0x34, 0x34, 0x44, 0x32, 0x30, 0x31, 0x17, 0x30, 0x15, 0x06, 0x05, 0x67, 0x81, 0x05, 0x02, 0x02, 0x0c, 0x0c, 0x53, 0x54, 0x33, 0x33, 0x48, 0x54, 0x50, 0x48, 0x41, 0x48, 0x42, 0x34, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67, 0x81, 0x05, 0x02, 0x03, 0x0c, 0x0b, 0x69, 0x64, 0x3a, 0x30, 0x30, 0x34, 0x39, 0x30, 0x30, 0x30, 0x34, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x45, 0x1a, 0xec, 0xfc, 0x91, 0x70, 0xf8, 0x83, 0x8b, 0x9c, 0x47, 0x2f, 0x0b, 0x9f, 0x07, 0xf3, 0x2f, 0x7c, 0xa2, 0x8a, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x55, 0xa6, 0xee, 0xe3, 0x28, 0xdd, 0x40, 0x7f, 0x21, 0xd2, 0x7b, 0x8c, 0x69, 0x2f, 0x8c, 0x08, 0x29, 0xbc, 0x95, 0xb8, 0x30, 0x81, 0xb2, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xa5, 0x30, 0x81, 0xa2, 0x30, 0x81, 0x9f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0x92, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x7a, 0x63, 0x73, 0x70, 0x72, 0x6f, 0x64, 0x65, 0x75, 0x73, 0x61, 0x69, 0x6b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x2e, 0x62, 0x6c, 0x6f, 0x62, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x65, 0x75, 0x73, 0x2d, 0x73, 0x74, 0x6d, 0x2d, 0x6b, 0x65, 0x79, 0x69, 0x64, 0x2d, 0x31, 0x61, 0x64, 0x62, 0x39, 0x39, 0x34, 0x61, 0x62, 0x35, 0x38, 0x62, 0x65, 0x35, 0x37, 0x61, 0x30, 0x63, 0x63, 0x39, 0x62, 0x39, 0x30, 0x30, 0x65, 0x37, 0x38, 0x35, 0x31, 0x65, 0x31, 0x61, 0x34, 0x33, 0x63, 0x30, 0x38, 0x36, 0x36, 0x30, 0x2f, 0x62, 0x36, 0x63, 0x30, 0x64, 0x39, 0x38, 0x64, 0x2d, 0x35, 0x37, 0x38, 0x61, 0x2d, 0x34, 0x62, 0x66, 0x62, 0x2d, 0x61, 0x32, 0x64, 0x33, 0x2d, 0x65, 0x64, 0x66, 0x65, 0x35, 0x66, 0x38, 0x32, 0x30, 0x36, 0x30, 0x31, 0x2e, 0x63, 0x65, 0x72, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x2a, 0x08, 0x30, 0x1f, 0xfd, 0x8f, 0x80, 0x9b, 0x4b, 0x37, 0x82, 0x61, 0x86, 0x36, 0x57, 0x90, 0xb5, 0x1d, 0x1f, 0xa3, 0xae, 0x68, 0xac, 0xa7, 0x96, 0x6a, 0x25, 0x5e, 0xc5, 0x82, 0x7c, 0x36, 0x64, 0x58, 0x11, 0xcb, 0xa5, 0xee, 0xbf, 0xc4, 0xdb, 0xa0, 0xc7, 0x82, 0x3b, 0xa3, 0x85, 0x9b, 0xc4, 0xee, 0x07, 0x36, 0xd7, 0xc7, 0xb6, 0x23, 0xed, 0xc2, 0x73, 0xab, 0xbe, 0xbe, 0xee, 0x63, 0x17, 0xf9, 0xd7, 0x7a, 0x23, 0x7b, 0xf8, 0x09, 0x7a, 0xaa, 0x7f, 0x67, 0xc3, 0x04, 0x84, 0x71, 0x9b, 0x06, 0x9c, 0x07, 0x42, 0x4b, 0x65, 0x41, 0x56, 0x58, 0x14, 0x92, 0xb0, 0xb9, 0xaf, 0xa1, 0x39, 0xd4, 0x08, 0x2d, 0x71, 0xd5, 0x6c, 0x56, 0xb9, 0x2b, 0x1e, 0xf3, 0x93, 0xa5, 0xe9, 0xb2, 0x9b, 0x4d, 0x05, 0x2b, 0xbc, 0xd2, 0x20, 0x57, 0x3b, 0xa4, 0x01, 0x68, 0x8c, 0x23, 0x20, 0x7d, 0xbb, 0x71, 0xe4, 0x2a, 0x24, 0xba, 0x75, 0x0c, 0x89, 0x54, 0x22, 0xeb, 0x0e, 0xb2, 0xf4, 0xc2, 0x1f, 0x02, 0xb7, 0xe3, 0x06, 0x41, 0x15, 0x6b, 0xf3, 0xc8, 0x2d, 0x5b, 0xc2, 0x21, 0x82, 0x3e, 0xe8, 0x95, 0x40, 0x39, 0x9e, 0x91, 0x68, 0x33, 0x0c, 0x3d, 0x45, 0xef, 0x99, 0x79, 0xe6, 0x32, 0xc9, 0x00, 0x84, 0x36, 0xfb, 0x0a, 0x8d, 0x41, 0x1c, 0x32, 0x64, 0x06, 0x9e, 0x0f, 0xb5, 0x04, 0xcc, 0x08, 0xb1, 0xb6, 0x2b, 0xcf, 0x36, 0x0f, 0x73, 0x14, 0x8e, 0x25, 0x44, 0xb3, 0x0c, 0x34, 0x14, 0x96, 0x0c, 0x8a, 0x65, 0xa1, 0xde, 0x8e, 0xc8, 0x9d, 0xbe, 0x66, 0xdf, 0x06, 0x91, 0xca, 0x15, 0x0f, 0x92, 0xd5, 0x2a, 0x0b, 0xdc, 0x4c, 0x6a, 0xf3, 0x16, 0x4a, 0x3e, 0xb9, 0x76, 0xbc, 0xfe, 0x62, 0xd4, 0xa8, 0xcd, 0x94, 0x78, 0x0d, 0xdd, 0x94, 0xfd, 0x5e, 0x63, 0x57, 0x27, 0x05, 0x9c, 0xd0, 0x80, 0x91, 0x91, 0x79, 0xe8, 0x5e, 0x18, 0x64, 0x22, 0xe4, 0x2c, 0x13, 0x65, 0xa4, 0x51, 0x5a, 0x1e, 0x3b, 0x71, 0x2e, 0x70, 0x9f, 0xc4, 0xa5, 0x20, 0xcd, 0xef, 0xd8, 0x3f, 0xa4, 0xf5, 0x89, 0x8a, 0xa5, 0x4f, 0x76, 0x2d, 0x49, 0x56, 0x00, 0x8d, 0xde, 0x40, 0xba, 0x24, 0x46, 0x51, 0x38, 0xad, 0xdb, 0xc4, 0x04, 0xf4, 0x6e, 0xc0, 0x29, 0x48, 0x07, 0x6a, 0x1b, 0x26, 0x32, 0x0a, 0xfb, 0xea, 0x71, 0x2a, 0x11, 0xfc, 0x98, 0x7c, 0x44, 0x87, 0xbc, 0x06, 0x3a, 0x4d, 0xbd, 0x91, 0x63, 0x4f, 0x26, 0x48, 0x54, 0x47, 0x1b, 0xbd, 0xf0, 0xf1, 0x56, 0x05, 0xc5, 0x0f, 0x8f, 0x20, 0xa5, 0xcc, 0xfb, 0x76, 0xb0, 0xbd, 0x83, 0xde, 0x7f, 0x39, 0x4f, 0xcf, 0x61, 0x74, 0x52, 0xa7, 0x1d, 0xf6, 0xb5, 0x5e, 0x4a, 0x82, 0x20, 0xc1, 0x94, 0xaa, 0x2c, 0x33, 0xd6, 0x0a, 0xf9, 0x8f, 0x92, 0xc6, 0x29, 0x80, 0xf5, 0xa2, 0xb1, 0xff, 0xb6, 0x2b, 0xaa, 0x04, 0x00, 0x72, 0xb4, 0x12, 0xbb, 0xb1, 0xf1, 0x3c, 0x88, 0xa3, 0xab, 0x49, 0x17, 0x90, 0x80, 0x59, 0xa2, 0x96, 0x41, 0x69, 0x74, 0x33, 0x8a, 0x28, 0x33, 0x7e, 0xb3, 0x19, 0x92, 0x28, 0xc1, 0xf0, 0xd1, 0x82, 0xd5, 0x42, 0xff, 0xe7, 0xa5, 0x3f, 0x1e, 0xb6, 0x4a, 0x23, 0xcc, 0x6a, 0x7f, 0x15, 0x15, 0x52, 0x25, 0xb1, 0xca, 0x21, 0x95, 0x11, 0x53, 0x3e, 0x1f, 0x50, 0x33, 0x12, 0x7a, 0x62, 0xce, 0xcc, 0x71, 0xc2, 0x5f, 0x34, 0x47, 0xc6, 0x7c, 0x71, 0xfa, 0xa0, 0x54, 0x00, 0xb2, 0xdf, 0xc5, 0x54, 0xac, 0x6c, 0x53, 0xef, 0x64, 0x6b, 0x08, 0x82, 0xd8, 0x16, 0x1e, 0xca, 0x40, 0xf3, 0x1f, 0xdf, 0x56, 0x63, 0x10, 0xbc, 0xd7, 0xa0, 0xeb, 0xee, 0xd1, 0x95, 0xe5, 0xef, 0xf1, 0x6a, 0x83, 0x2d, 0x5a, 0x59, 0x06, 0xef, 0x30, 0x82, 0x06, 0xeb, 0x30, 0x82, 0x04, 0xd3, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x13, 0x33, 0x00, 0x00, 0x05, 0x23, 0xbf, 0xe8, 0xa1, 0x1a, 0x2a, 0x68, 0xbd, 0x09, 0x00, 0x00, 0x00, 0x00, 0x05, 0x23, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x8c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x54, 0x50, 0x4d, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x32, 0x30, 0x31, 0x34, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x36, 0x30, 0x33, 0x31, 0x39, 0x34, 0x30, 0x31, 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x36, 0x30, 0x33, 0x31, 0x39, 0x34, 0x30, 0x31, 0x36, 0x5a, 0x30, 0x41, 0x31, 0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x36, 0x45, 0x55, 0x53, 0x2d, 0x53, 0x54, 0x4d, 0x2d, 0x4b, 0x45, 0x59, 0x49, 0x44, 0x2d, 0x31, 0x41, 0x44, 0x42, 0x39, 0x39, 0x34, 0x41, 0x42, 0x35, 0x38, 0x42, 0x45, 0x35, 0x37, 0x41, 0x30, 0x43, 0x43, 0x39, 0x42, 0x39, 0x30, 0x30, 0x45, 0x37, 0x38, 0x35, 0x31, 0x45, 0x31, 0x41, 0x34, 0x33, 0x43, 0x30, 0x38, 0x36, 0x36, 0x30, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xdb, 0x03, 0x34, 0x82, 0xfa, 0x81, 0x1c, 0x84, 0x0b, 0xa0, 0x0e, 0x60, 0xd8, 0x9d, 0x84, 0xf4, 0x81, 0xc4, 0xe9, 0xff, 0xcf, 0xe9, 0xa3, 0x57, 0x53, 0x60, 0xa8, 0x19, 0xce, 0xbe, 0xe1, 0x97, 0xee, 0x5d, 0x8c, 0x9f, 0xe4, 0xbd, 0xef, 0xbd, 0x94, 0x14, 0xe4, 0x74, 0x41, 0x02, 0xe9, 0x03, 0x19, 0x9f, 0xdd, 0x48, 0x2d, 0xbd, 0xca, 0x26, 0x47, 0x2c, 0x01, 0x31, 0x5f, 0x34, 0xef, 0x59, 0x35, 0x48, 0x36, 0x3d, 0x1e, 0xdf, 0xd8, 0x13, 0xf0, 0xd0, 0x67, 0xc1, 0xb0, 0x47, 0x67, 0xa2, 0xd6, 0x62, 0xc8, 0xe1, 0x00, 0x36, 0x8b, 0x45, 0xf6, 0x3b, 0x96, 0x60, 0xa0, 0x45, 0x26, 0xcb, 0xc7, 0x0b, 0x5b, 0x97, 0xd1, 0xaf, 0x54, 0x25, 0x7a, 0x67, 0xe4, 0x2a, 0xd8, 0x9d, 0x53, 0x05, 0xbd, 0x12, 0xac, 0xa2, 0x8e, 0x95, 0xb4, 0x2a, 0xca, 0x89, 0x93, 0x64, 0x97, 0x25, 0xdc, 0x1f, 0xa9, 0xe0, 0x55, 0x07, 0x38, 0x1d, 0xee, 0x02, 0x90, 0x22, 0xf5, 0xad, 0x4e, 0x5c, 0xf8, 0xc5, 0x1f, 0x9e, 0x84, 0x7e, 0x13, 0x47, 0x52, 0xa2, 0x36, 0xf9, 0xf6, 0xbf, 0x76, 0x9e, 0x0f, 0xdd, 0x14, 0x99, 0xb9, 0xd8, 0x5a, 0x42, 0x3d, 0xd8, 0xbf, 0xdd, 0xb4, 0x9b, 0xbf, 0x6a, 0x9f, 0x89, 0x13, 0x75, 0xaf, 0x96, 0xd2, 0x72, 0xdf, 0xb3, 0x80, 0x6f, 0x84, 0x1a, 0x9d, 0x06, 0x55, 0x09, 0x29, 0xea, 0xa7, 0x05, 0x31, 0xec, 0x47, 0x3a, 0xcf, 0x3f, 0x9c, 0x2c, 0xbd, 0xd0, 0x7d, 0xe4, 0x75, 0x5b, 0x33, 0xbe, 0x12, 0x86, 0x09, 0xcf, 0x66, 0x9a, 0xeb, 0xf8, 0xf8, 0x72, 0x91, 0x88, 0x4a, 0x5e, 0x89, 0x62, 0x6a, 0x94, 0xdc, 0x48, 0x37, 0x13, 0xd8, 0x91, 0x02, 0xe3, 0x42, 0x41, 0x7c, 0x2f, 0xe3, 0xb6, 0x0f, 0xb4, 0x96, 0x06, 0x80, 0xca, 0x28, 0x01, 0x6f, 0x4b, 0xcd, 0x28, 0xd4, 0x2c, 0x94, 0x7e, 0x40, 0x7e, 0xdf, 0x01, 0xe5, 0xf2, 0x33, 0xd4, 0xda, 0xf4, 0x1a, 0x17, 0xf7, 0x5d, 0xcb, 0x66, 0x2c, 0x2a, 0xeb, 0xe1, 0xb1, 0x4a, 0xc3, 0x85, 0x63, 0xb2, 0xac, 0xd0, 0x3f, 0x1a, 0x8d, 0xa5, 0x0c, 0xee, 0x4f, 0xde, 0x74, 0x9c, 0xe0, 0x5a, 0x10, 0xc7, 0xb8, 0xe4, 0xec, 0xe7, 0x73, 0xa6, 0x41, 0x42, 0x37, 0xe1, 0xdf, 0xb9, 0xc7, 0xb5, 0x14, 0xa8, 0x80, 0x95, 0xa0, 0x12, 0x67, 0x99, 0xf5, 0xba, 0x25, 0x0a, 0x74, 0x86, 0x71, 0x9c, 0x7f, 0x59, 0x97, 0xd2, 0x3f, 0x10, 0xfe, 0x6a, 0xb9, 0xe4, 0x47, 0x36, 0xfb, 0x0f, 0x50, 0xee, 0xfc, 0x87, 0x99, 0x7e, 0x36, 0x64, 0x1b, 0xc7, 0x13, 0xb3, 0x33, 0x18, 0x71, 0xa4, 0xc3, 0xb0, 0xfc, 0x45, 0x37, 0x11, 0x40, 0xb3, 0xde, 0x2c, 0x9f, 0x0a, 0xcd, 0xaf, 0x5e, 0xfb, 0xd5, 0x9c, 0xea, 0xd7, 0x24, 0x19, 0x3a, 0x92, 0x80, 0xa5, 0x63, 0xc5, 0x3e, 0xdd, 0x51, 0xd0, 0x9f, 0xb8, 0x5e, 0xd5, 0xf1, 0xfe, 0xa5, 0x93, 0xfb, 0x7f, 0xd9, 0xb8, 0xb7, 0x0e, 0x0d, 0x12, 0x71, 0xf0, 0x52, 0x9d, 0xe9, 0xd0, 0xd2, 0x8b, 0x38, 0x8b, 0x85, 0x83, 0x98, 0x24, 0x88, 0xe8, 0x42, 0x30, 0x83, 0x12, 0xef, 0x09, 0x96, 0x2f, 0x21, 0x81, 0x05, 0x30, 0x0c, 0xbb, 0xba, 0x21, 0x39, 0x16, 0x12, 0xe8, 0x4b, 0x7b, 0x7a, 0x66, 0xb8, 0x22, 0x2c, 0x71, 0xaf, 0x59, 0xa1, 0xfc, 0x61, 0xf1, 0xb4, 0x5e, 0xfc, 0x43, 0x19, 0x45, 0x6e, 0xa3, 0x45, 0xe4, 0xcb, 0x66, 0x5f, 0xe0, 0x57, 0xf6, 0x0a, 0x30, 0xa3, 0xd6, 0x51, 0x24, 0xc9, 0x07, 0x55, 0x82, 0x4a, 0x66, 0x0e, 0x9d, 0xb2, 0x2f, 0x84, 0x56, 0x6c, 0x3e, 0x71, 0xef, 0x9b, 0x35, 0x4d, 0x72, 0xdc, 0x46, 0x2a, 0xe3, 0x7b, 0x13, 0x20, 0xbf, 0xab, 0x77, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x8e, 0x30, 0x82, 0x01, 0x8a, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x84, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x14, 0x30, 0x12, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x24, 0x06, 0x05, 0x67, 0x81, 0x05, 0x08, 0x03, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0f, 0x30, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x1f, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x45, 0x1a, 0xec, 0xfc, 0x91, 0x70, 0xf8, 0x83, 0x8b, 0x9c, 0x47, 0x2f, 0x0b, 0x9f, 0x07, 0xf3, 0x2f, 0x7c, 0xa2, 0x8a, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7a, 0x8c, 0x0a, 0xce, 0x2f, 0x48, 0x62, 0x17, 0xe2, 0x94, 0xd1, 0xae, 0x55, 0xc1, 0x52, 0xec, 0x71, 0x74, 0xa4, 0x56, 0x30, 0x70, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x69, 0x30, 0x67, 0x30, 0x65, 0xa0, 0x63, 0xa0, 0x61, 0x86, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x6f, 0x70, 0x73, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x25, 0x32, 0x30, 0x54, 0x50, 0x4d, 0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x34, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x7d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x71, 0x30, 0x6f, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x61, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x6f, 0x70, 0x73, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x25, 0x32, 0x30, 0x54, 0x50, 0x4d, 0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x34, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x48, 0x24, 0x32, 0xe8, 0xd6, 0x38, 0xda, 0x65, 0xec, 0x1b, 0x18, 0x8e, 0x37, 0x07, 0xd5, 0x18, 0x5a, 0xc8, 0xb9, 0xbb, 0x24, 0x8a, 0x4d, 0xa1, 0x3c, 0x9e, 0x46, 0x76, 0xcf, 0xa5, 0xdf, 0xd7, 0x61, 0xba, 0x05, 0x89, 0x3c, 0x13, 0xc2, 0x1f, 0x71, 0xe3, 0xec, 0x5d, 0x54, 0x9e, 0xd9, 0x01, 0x5a, 0x10, 0x3b, 0x17, 0x75, 0xde, 0xa1, 0x45, 0xbf, 0x1d, 0x1b, 0x41, 0x21, 0x42, 0x68, 0x22, 0x6b, 0xbb, 0xcb, 0x11, 0x04, 0xd2, 0xae, 0x86, 0xcf, 0x73, 0x5a, 0xf2, 0x80, 0x18, 0x00, 0xf0, 0xd6, 0x6c, 0x5a, 0x1e, 0xb3, 0x4d, 0x30, 0x02, 0x4a, 0x6a, 0x03, 0x36, 0x42, 0xde, 0xb2, 0x52, 0x55, 0xff, 0x71, 0xeb, 0x7b, 0x8b, 0x55, 0x6c, 0xdf, 0x05, 0x35, 0x47, 0x70, 0x53, 0xfb, 0x6c, 0xba, 0x06, 0xb2, 0x61, 0x86, 0xdc, 0x2a, 0x64, 0x81, 0x24, 0x79, 0x46, 0x73, 0x04, 0x55, 0x59, 0xed, 0xd6, 0x06, 0x61, 0x15, 0xf9, 0x8d, 0x78, 0x39, 0x7b, 0x84, 0x7a, 0x40, 0x45, 0x13, 0x1a, 0x91, 0x71, 0x8f, 0xd1, 0x4f, 0x78, 0x10, 0x68, 0x9b, 0x15, 0x79, 0x3f, 0x79, 0x2d, 0x9b, 0xc7, 0x5d, 0xa3, 0xcf, 0xa9, 0x14, 0xb0, 0xc4, 0xdb, 0xa9, 0x45, 0x6a, 0x6e, 0x60, 0x45, 0x0b, 0x14, 0x25, 0xc7, 0x74, 0xd0, 0x36, 0xaf, 0xc5, 0xbd, 0x4f, 0x7b, 0xc0, 0x04, 0x43, 0x85, 0xbb, 0x06, 0x36, 0x77, 0x26, 0x02, 0x23, 0x0b, 0xf8, 0x57, 0x8f, 0x1f, 0x27, 0x30, 0x95, 0xff, 0x83, 0x23, 0x2b, 0x49, 0x33, 0x43, 0x62, 0x87, 0x5d, 0x27, 0x12, 0x1a, 0x68, 0x7b, 0xba, 0x2d, 0xf6, 0xed, 0x2c, 0x26, 0xb5, 0xbb, 0xe2, 0x6f, 0xc2, 0x61, 0x17, 0xfc, 0x72, 0x14, 0x57, 0x2c, 0x2c, 0x5a, 0x92, 0x13, 0x41, 0xc4, 0x7e, 0xb5, 0x64, 0x5b, 0x86, 0x57, 0x13, 0x14, 0xff, 0xf5, 0x04, 0xb9, 0x3d, 0x2d, 0xc3, 0xe9, 0x75, 0x1f, 0x68, 0x0b, 0xb5, 0x76, 0xe1, 0x7d, 0xe3, 0xb0, 0x14, 0xa8, 0x45, 0x05, 0x98, 0x81, 0x32, 0xc1, 0xf5, 0x49, 0x4d, 0x58, 0xa4, 0xee, 0xd8, 0x84, 0xba, 0x65, 0x07, 0x8d, 0xf7, 0x9a, 0xff, 0x7d, 0xa5, 0xbc, 0x9a, 0xed, 0x4a, 0x5d, 0xa4, 0x97, 0x4b, 0x4d, 0x31, 0x90, 0xb5, 0x7d, 0x28, 0x77, 0x25, 0x88, 0x1c, 0xbf, 0x78, 0x22, 0xb2, 0xb5, 0x5c, 0x9a, 0xc9, 0x63, 0x17, 0x96, 0xe9, 0xc2, 0x52, 0x30, 0xb8, 0x9b, 0x37, 0x69, 0x1a, 0x6a, 0x66, 0x76, 0x18, 0xac, 0xc0, 0x48, 0xee, 0x46, 0x5b, 0xbe, 0x6a, 0xd5, 0x72, 0x07, 0xdc, 0x7d, 0x05, 0xbe, 0x76, 0x7d, 0xa5, 0x5e, 0x53, 0xb5, 0x47, 0x80, 0x58, 0xf0, 0xaf, 0x6f, 0x4e, 0xc0, 0xf1, 0x1e, 0x37, 0x64, 0x15, 0x42, 0x96, 0x18, 0x3a, 0x89, 0xc8, 0x14, 0x48, 0x89, 0x5c, 0x12, 0x88, 0x98, 0x0b, 0x7b, 0x4e, 0xce, 0x1c, 0xda, 0xd5, 0xa4, 0xd3, 0x32, 0x32, 0x74, 0x5b, 0xcc, 0xfd, 0x2b, 0x02, 0xfb, 0xae, 0xd0, 0x5a, 0x4c, 0xc9, 0xc1, 0x35, 0x19, 0x90, 0x5f, 0xca, 0x14, 0xeb, 0x4c, 0x17, 0xd7, 0xe3, 0xe2, 0x5d, 0xb4, 0x49, 0xaa, 0xf0, 0x50, 0x87, 0xc3, 0x20, 0x00, 0xda, 0xe9, 0x04, 0x80, 0x64, 0xac, 0x9f, 0xcd, 0x26, 0x41, 0x48, 0xe8, 0x4c, 0x46, 0xcc, 0x5b, 0xd7, 0xca, 0x4c, 0x1b, 0x43, 0x43, 0x1e, 0xbd, 0x94, 0xe7, 0xa7, 0xa6, 0x86, 0xe5, 0xd1, 0x78, 0x29, 0xa2, 0x40, 0xc5, 0xc5, 0x47, 0xb6, 0x6d, 0x53, 0xde, 0xac, 0x97, 0x74, 0x24, 0x57, 0xcc, 0x05, 0x93, 0xfd, 0x52, 0x35, 0x29, 0xd5, 0xe0, 0xfa, 0x23, 0x0d, 0xd7, 0xaa, 0x8b, 0x07, 0x4b, 0xf6, 0x64, 0xc7, 0xad, 0x3c, 0xa1, 0xb5, 0xc5, 0x70, 0xaf, 0x46, 0xfe, 0x9a, 0x82, 0x4d, 0x75, 0xb8, 0x6d, 0x67, 0x70, 0x75, 0x62, 0x41, 0x72, 0x65, 0x61, 0x58, 0x76, 0x00, 0x23, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x72, 0x00, 0x20, 0x9d, 0xff, 0xcb, 0xf3, 0x6c, 0x38, 0x3a, 0xe6, 0x99, 0xfb, 0x98, 0x68, 0xdc, 0x6d, 0xcb, 0x89, 0xd7, 0x15, 0x38, 0x84, 0xbe, 0x28, 0x03, 0x92, 0x2c, 0x12, 0x41, 0x58, 0xbf, 0xad, 0x22, 0xae, 0x00, 0x10, 0x00, 0x10, 0x00, 0x03, 0x00, 0x10, 0x00, 0x20, 0xfb, 0xd6, 0xba, 0x74, 0xe6, 0x6e, 0x5c, 0x87, 0xef, 0x89, 0xa2, 0xe8, 0x3d, 0x0b, 0xe9, 0x69, 0x2c, 0x07, 0x07, 0x7a, 0x8a, 0x1e, 0xce, 0x12, 0xea, 0x3b, 0xb3, 0xf1, 0xf3, 0xd9, 0xc3, 0xe6, 0x00, 0x20, 0x3c, 0x68, 0x51, 0x94, 0x54, 0x8d, 0xeb, 0x9f, 0xb2, 0x2c, 0x66, 0x75, 0xb6, 0xb7, 0x55, 0x22, 0x0d, 0x87, 0x59, 0xc4, 0x39, 0x91, 0x62, 0x17, 0xc2, 0xc3, 0x53, 0xa5, 0x26, 0x97, 0x4f, 0x2d, 0x68, 0x63, 0x65, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x58, 0xa1, 0xff, 0x54, 0x43, 0x47, 0x80, 0x17, 0x00, 0x22, 0x00, 0x0b, 0x73, 0xbe, 0xb7, 0x40, 0x82, 0xc0, 0x49, 0x9a, 0xf7, 0xf2, 0xd0, 0x79, 0x6c, 0x88, 0xf3, 0x56, 0x7b, 0x7a, 0x7d, 0xcd, 0x70, 0xd1, 0xbc, 0x41, 0x88, 0x48, 0x51, 0x03, 0xf3, 0x58, 0x3e, 0xb8, 0x00, 0x14, 0x9f, 0x57, 0x39, 0x67, 0xa8, 0x7b, 0xd8, 0xf6, 0x9e, 0x75, 0xc9, 0x85, 0xab, 0xe3, 0x55, 0xc7, 0x9c, 0xf6, 0xd8, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x1c, 0x12, 0xfd, 0xc6, 0x05, 0xc6, 0x2b, 0xf5, 0xe9, 0x88, 0x01, 0x1f, 0x70, 0x8d, 0x98, 0x2a, 0x04, 0x21, 0x30, 0x00, 0x22, 0x00, 0x0b, 0xf4, 0xfd, 0x9a, 0x33, 0x55, 0x21, 0x08, 0x27, 0x48, 0x55, 0x01, 0x56, 0xf9, 0x0b, 0x4e, 0x47, 0x55, 0x08, 0x2e, 0x3c, 0x91, 0x3d, 0x6e, 0x53, 0xcf, 0x08, 0xe9, 0x0a, 0x4b, 0xc9, 0x7e, 0x99, 0x00, 0x22, 0x00, 0x0b, 0x51, 0xd3, 0x38, 0xfe, 0xaa, 0xda, 0xc6, 0x68, 0x84, 0x39, 0xe7, 0xb1, 0x03, 0x22, 0x5e, 0xc4, 0xd3, 0xf1, 0x0c, 0xec, 0x35, 0x5d, 0x50, 0xa3, 0x9d, 0xab, 0xa1, 0x7b, 0x61, 0x51, 0x8f, 0x4e }; /* * Security Key By Yubico * 5.1.X * f8a011f3-8c0a-4d15-8006-17111f9edc7d */ const unsigned char aaguid[16] = { 0xf8, 0xa0, 0x11, 0xf3, 0x8c, 0x0a, 0x4d, 0x15, 0x80, 0x06, 0x17, 0x11, 0x1f, 0x9e, 0xdc, 0x7d, }; /* * Windows Hello by Microsoft */ const unsigned char aaguid_tpm[16] = { 0x08, 0x98, 0x70, 0x58, 0xca, 0xdc, 0x4b, 0x81, 0xb6, 0xe1, 0x30, 0xde, 0x50, 0xdc, 0xbe, 0x96, }; const char rp_id[] = "localhost"; const char rp_name[] = "sweet home localhost"; static void * dummy_open(const char *path) { (void)path; return (&fake_dev_handle); } static void dummy_close(void *handle) { assert(handle == &fake_dev_handle); } static int dummy_read(void *handle, unsigned char *buf, size_t len, int ms) { (void)handle; (void)buf; (void)len; (void)ms; abort(); /* NOTREACHED */ } static int dummy_write(void *handle, const unsigned char *buf, size_t len) { (void)handle; (void)buf; (void)len; abort(); /* NOTREACHED */ } static fido_cred_t * alloc_cred(void) { fido_cred_t *c; c = fido_cred_new(); assert(c != NULL); return (c); } static void free_cred(fido_cred_t *c) { fido_cred_free(&c); assert(c == NULL); } static fido_dev_t * alloc_dev(void) { fido_dev_t *d; d = fido_dev_new(); assert(d != NULL); return (d); } static void free_dev(fido_dev_t *d) { fido_dev_free(&d); assert(d == NULL); } static void empty_cred(void) { fido_cred_t *c; fido_dev_t *d; fido_dev_io_t io_f; c = alloc_cred(); assert(fido_cred_authdata_len(c) == 0); assert(fido_cred_authdata_ptr(c) == NULL); assert(fido_cred_authdata_raw_len(c) == 0); assert(fido_cred_authdata_raw_ptr(c) == NULL); assert(fido_cred_clientdata_hash_len(c) == 0); assert(fido_cred_clientdata_hash_ptr(c) == NULL); assert(fido_cred_flags(c) == 0); assert(fido_cred_fmt(c) == NULL); assert(fido_cred_id_len(c) == 0); assert(fido_cred_id_ptr(c) == NULL); assert(fido_cred_prot(c) == 0); assert(fido_cred_pubkey_len(c) == 0); assert(fido_cred_pubkey_ptr(c) == NULL); assert(fido_cred_rp_id(c) == NULL); assert(fido_cred_rp_name(c) == NULL); assert(fido_cred_sig_len(c) == 0); assert(fido_cred_sig_ptr(c) == NULL); assert(fido_cred_x5c_len(c) == 0); assert(fido_cred_x5c_ptr(c) == NULL); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); memset(&io_f, 0, sizeof(io_f)); io_f.open = dummy_open; io_f.close = dummy_close; io_f.read = dummy_read; io_f.write = dummy_write; d = alloc_dev(); fido_dev_force_u2f(d); assert(fido_dev_set_io_functions(d, &io_f) == FIDO_OK); assert(fido_dev_make_cred(d, c, NULL) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_dev_make_cred(d, c, "") == FIDO_ERR_UNSUPPORTED_OPTION); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); fido_dev_force_fido2(d); assert(fido_dev_set_io_functions(d, &io_f) == FIDO_OK); assert(fido_dev_make_cred(d, c, NULL) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_dev_make_cred(d, c, "") == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); free_cred(c); free_dev(d); } static void valid_cred(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_OK); assert(fido_cred_prot(c) == 0); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void no_cdh(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void no_rp_id(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void no_rp_name(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, NULL) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_OK); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void no_authdata(void) { fido_cred_t *c; unsigned char *unset; unset = calloc(1, sizeof(aaguid)); assert(unset != NULL); c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_pubkey_len(c) == 0); assert(fido_cred_pubkey_ptr(c) == NULL); assert(fido_cred_id_len(c) == 0); assert(fido_cred_id_ptr(c) == NULL); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), unset, sizeof(aaguid)) == 0); free_cred(c); free(unset); } static void no_x509(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void no_sig(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void no_fmt(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void wrong_options(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_TRUE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_PARAM); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void junk_cdh(void) { fido_cred_t *c; unsigned char *junk; junk = malloc(sizeof(cdh)); assert(junk != NULL); memcpy(junk, cdh, sizeof(cdh)); junk[0] = (unsigned char)~junk[0]; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, junk, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_SIG); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); free(junk); } static void junk_fmt(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "junk") == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); free_cred(c); } static void junk_rp_id(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, "potato", rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_PARAM); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void junk_rp_name(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, "potato") == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_OK); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void junk_authdata(void) { fido_cred_t *c; unsigned char *junk; unsigned char *unset; junk = malloc(sizeof(authdata)); assert(junk != NULL); memcpy(junk, authdata, sizeof(authdata)); junk[0] = (unsigned char)~junk[0]; unset = calloc(1, sizeof(aaguid)); assert(unset != NULL); c = alloc_cred(); assert(fido_cred_set_authdata(c, junk, sizeof(authdata)) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_authdata_len(c) == 0); assert(fido_cred_authdata_ptr(c) == NULL); assert(fido_cred_authdata_raw_len(c) == 0); assert(fido_cred_authdata_raw_ptr(c) == NULL); assert(fido_cred_flags(c) == 0); assert(fido_cred_fmt(c) == NULL); assert(fido_cred_id_len(c) == 0); assert(fido_cred_id_ptr(c) == NULL); assert(fido_cred_pubkey_len(c) == 0); assert(fido_cred_pubkey_ptr(c) == NULL); assert(fido_cred_rp_id(c) == NULL); assert(fido_cred_rp_name(c) == NULL); assert(fido_cred_sig_len(c) == 0); assert(fido_cred_sig_ptr(c) == NULL); assert(fido_cred_x5c_len(c) == 0); assert(fido_cred_x5c_ptr(c) == NULL); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), unset, sizeof(aaguid)) == 0); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); free_cred(c); free(junk); free(unset); } static void junk_sig(void) { fido_cred_t *c; unsigned char *junk; junk = malloc(sizeof(sig)); assert(junk != NULL); memcpy(junk, sig, sizeof(sig)); junk[0] = (unsigned char)~junk[0]; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, junk, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_SIG); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); free(junk); } static void junk_x509(void) { fido_cred_t *c; unsigned char *junk; junk = malloc(sizeof(x509)); assert(junk != NULL); memcpy(junk, x509, sizeof(x509)); junk[0] = (unsigned char)~junk[0]; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, junk, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_SIG); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); free(junk); } /* github issue #6 */ static void invalid_type(void) { fido_cred_t *c; unsigned char *unset; unset = calloc(1, sizeof(aaguid)); assert(unset != NULL); c = alloc_cred(); assert(fido_cred_set_type(c, COSE_RS256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_pubkey_len(c) == 0); assert(fido_cred_pubkey_ptr(c) == NULL); assert(fido_cred_id_len(c) == 0); assert(fido_cred_id_ptr(c) == NULL); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), unset, sizeof(aaguid)) == 0); free_cred(c); free(unset); } /* cbor_serialize_alloc misuse */ static void bad_cbor_serialize(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_authdata_len(c) == sizeof(authdata)); free_cred(c); } static void duplicate_keys(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata_dupkeys, sizeof(authdata_dupkeys)) == FIDO_ERR_INVALID_ARGUMENT); free_cred(c); } static void unsorted_keys(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata_unsorted_keys, sizeof(authdata_unsorted_keys)) == FIDO_ERR_INVALID_ARGUMENT); free_cred(c); } static void wrong_credprot(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); assert(fido_cred_set_prot(c, FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_PARAM); free_cred(c); } static void raw_authdata(void) { fido_cred_t *c; cbor_item_t *item; struct cbor_load_result cbor_result; const unsigned char *ptr; unsigned char *cbor; size_t len; size_t cbor_len; size_t alloclen; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert((ptr = fido_cred_authdata_ptr(c)) != NULL); assert((len = fido_cred_authdata_len(c)) != 0); assert((item = cbor_load(ptr, len, &cbor_result)) != NULL); assert(cbor_result.read == len); assert(cbor_isa_bytestring(item)); assert((ptr = fido_cred_authdata_raw_ptr(c)) != NULL); assert((len = fido_cred_authdata_raw_len(c)) != 0); assert(cbor_bytestring_length(item) == len); assert(memcmp(ptr, cbor_bytestring_handle(item), len) == 0); assert((len = fido_cred_authdata_len(c)) != 0); assert((cbor_len = cbor_serialize_alloc(item, &cbor, &alloclen)) == len); assert((ptr = cbor_bytestring_handle(item)) != NULL); assert((len = cbor_bytestring_length(item)) != 0); assert(fido_cred_set_authdata_raw(c, ptr, len) == FIDO_OK); assert((ptr = fido_cred_authdata_ptr(c)) != NULL); assert((len = fido_cred_authdata_len(c)) != 0); assert(len == cbor_len); assert(memcmp(cbor, ptr, len) == 0); assert(cbor_len == sizeof(authdata)); assert(memcmp(cbor, authdata, cbor_len) == 0); cbor_decref(&item); free(cbor); free_cred(c); } static void fmt_none(void) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_fmt(c, "none") == FIDO_OK); assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); assert(fido_cred_prot(c) == 0); assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); assert(fido_cred_id_len(c) == sizeof(id)); assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); free_cred(c); } static void -valid_tpm_rs256_cred(void) +valid_tpm_rs256_cred(bool xfail) { fido_cred_t *c; c = alloc_cred(); assert(fido_cred_set_type(c, COSE_RS256) == FIDO_OK); assert(fido_cred_set_clientdata(c, cdh, sizeof(cdh)) == FIDO_OK); assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); assert(fido_cred_set_authdata(c, authdata_tpm_rs256, sizeof(authdata_tpm_rs256)) == FIDO_OK); assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); assert(fido_cred_set_uv(c, FIDO_OPT_TRUE) == FIDO_OK); assert(fido_cred_set_fmt(c, "tpm") == FIDO_OK); assert(fido_cred_set_attstmt(c, attstmt_tpm_rs256, sizeof(attstmt_tpm_rs256)) == FIDO_OK); - assert(fido_cred_verify(c) == FIDO_OK); + // XXX: RHEL9 has deprecated SHA-1 for signing. + assert(fido_cred_verify(c) == (xfail ? FIDO_ERR_INVALID_SIG : FIDO_OK)); assert(fido_cred_prot(c) == 0); assert(fido_cred_pubkey_len(c) == sizeof(pubkey_tpm_rs256)); assert(memcmp(fido_cred_pubkey_ptr(c), pubkey_tpm_rs256, sizeof(pubkey_tpm_rs256)) == 0); assert(fido_cred_id_len(c) == sizeof(id_tpm_rs256)); assert(memcmp(fido_cred_id_ptr(c), id_tpm_rs256, sizeof(id_tpm_rs256)) == 0); assert(fido_cred_aaguid_len(c) == sizeof(aaguid_tpm)); assert(memcmp(fido_cred_aaguid_ptr(c), aaguid_tpm, sizeof(aaguid_tpm)) == 0); free_cred(c); } static void -valid_tpm_es256_cred(void) +valid_tpm_es256_cred(bool xfail) { 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); + // XXX: RHEL9 has deprecated SHA-1 for signing. + assert(fido_cred_verify(c) == (xfail ? FIDO_ERR_INVALID_SIG : 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); } int main(void) { + bool xfail = getenv("FIDO_REGRESS_RS1_XFAIL") != NULL; + fido_init(0); empty_cred(); valid_cred(); no_cdh(); no_rp_id(); no_rp_name(); no_authdata(); no_x509(); no_sig(); no_fmt(); junk_cdh(); junk_fmt(); junk_rp_id(); junk_rp_name(); junk_authdata(); junk_x509(); junk_sig(); wrong_options(); invalid_type(); bad_cbor_serialize(); duplicate_keys(); unsorted_keys(); wrong_credprot(); raw_authdata(); fmt_none(); - valid_tpm_rs256_cred(); - valid_tpm_es256_cred(); + valid_tpm_rs256_cred(xfail); + valid_tpm_es256_cred(xfail); exit(0); } diff --git a/contrib/libfido2/regress/eddsa.c b/contrib/libfido2/regress/eddsa.c index 06236987ed17..f97f97ce16e5 100644 --- a/contrib/libfido2/regress/eddsa.c +++ b/contrib/libfido2/regress/eddsa.c @@ -1,159 +1,159 @@ /* * 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. * SPDX-License-Identifier: BSD-2-Clause */ #undef NDEBUG #include #include #define _FIDO_INTERNAL #include #include #include #include #define ASSERT_NOT_NULL(e) assert((e) != NULL) #define ASSERT_NULL(e) assert((e) == NULL) #define ASSERT_INVAL(e) assert((e) == FIDO_ERR_INVALID_ARGUMENT) #define ASSERT_OK(e) assert((e) == FIDO_OK) static const char ecdsa[] = \ "-----BEGIN PUBLIC KEY-----\n" "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOwiq14c80b7C1Jzsx5w1zMvk2GgW\n" "5kfGMOKXjwF/U+51ZfBDKehs3ivdeXAJBkxIh7E3iA32s+HyNqk+ntl9fg==\n" "-----END PUBLIC KEY-----\n"; static const char eddsa[] = \ "-----BEGIN PUBLIC KEY-----\n" "MCowBQYDK2VwAyEADt/RHErAxAHxH9FUmsjOhQ2ALl6Y8nE0m3zQxkEE2iM=\n" "-----END PUBLIC KEY-----\n"; static const unsigned char eddsa_raw[] = { 0x0e, 0xdf, 0xd1, 0x1c, 0x4a, 0xc0, 0xc4, 0x01, 0xf1, 0x1f, 0xd1, 0x54, 0x9a, 0xc8, 0xce, 0x85, 0x0d, 0x80, 0x2e, 0x5e, 0x98, 0xf2, 0x71, 0x34, 0x9b, 0x7c, 0xd0, 0xc6, 0x41, 0x04, 0xda, 0x23, }; static EVP_PKEY * EVP_PKEY_from_PEM(const char *ptr, size_t len) { BIO *bio = NULL; EVP_PKEY *pkey = NULL; if ((bio = BIO_new(BIO_s_mem())) == NULL) { warnx("BIO_new"); goto out; } if (len > INT_MAX || BIO_write(bio, ptr, (int)len) != (int)len) { warnx("BIO_write"); goto out; } if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)) == NULL) warnx("PEM_read_bio_PUBKEY"); out: BIO_free(bio); return pkey; } static int eddsa_pk_cmp(const char *ptr, size_t len) { EVP_PKEY *pkA = NULL; EVP_PKEY *pkB = NULL; eddsa_pk_t *k = NULL; int r, ok = -1; if ((pkA = EVP_PKEY_from_PEM(ptr, len)) == NULL) { warnx("EVP_PKEY_from_PEM"); goto out; } if ((k = eddsa_pk_new()) == NULL) { warnx("eddsa_pk_new"); goto out; } if ((r = eddsa_pk_from_EVP_PKEY(k, pkA)) != FIDO_OK) { warnx("eddsa_pk_from_EVP_PKEY: 0x%x", r); goto out; } if ((pkB = eddsa_pk_to_EVP_PKEY(k)) == NULL) { warnx("eddsa_pk_to_EVP_PKEY"); goto out; } if ((r = EVP_PKEY_cmp(pkA, pkB)) != 1) { warnx("EVP_PKEY_cmp: %d", r); goto out; } ok = 0; out: EVP_PKEY_free(pkA); EVP_PKEY_free(pkB); eddsa_pk_free(&k); return ok; } static void invalid_key(void) { EVP_PKEY *pkey; eddsa_pk_t *pk; ASSERT_NOT_NULL((pkey = EVP_PKEY_from_PEM(ecdsa, sizeof(ecdsa)))); ASSERT_NOT_NULL((pk = eddsa_pk_new())); ASSERT_INVAL(eddsa_pk_from_EVP_PKEY(pk, pkey)); EVP_PKEY_free(pkey); eddsa_pk_free(&pk); } static void valid_key(void) { EVP_PKEY *pkeyA = NULL; EVP_PKEY *pkeyB = NULL; eddsa_pk_t *pkA = NULL; eddsa_pk_t *pkB = NULL; -#if defined(LIBRESSL_VERSION_NUMBER) +#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3070000f /* incomplete support; test what we can */ ASSERT_NULL(EVP_PKEY_from_PEM(eddsa, sizeof(eddsa))); ASSERT_NOT_NULL((pkB = eddsa_pk_new())); ASSERT_INVAL(eddsa_pk_from_ptr(pkB, eddsa_raw, sizeof(eddsa_raw))); ASSERT_NULL(eddsa_pk_to_EVP_PKEY((const eddsa_pk_t *)eddsa_raw)); assert(eddsa_pk_cmp(eddsa, sizeof(eddsa)) < 0); #else ASSERT_NOT_NULL((pkeyA = EVP_PKEY_from_PEM(eddsa, sizeof(eddsa)))); ASSERT_NOT_NULL((pkA = eddsa_pk_new())); ASSERT_NOT_NULL((pkB = eddsa_pk_new())); ASSERT_OK(eddsa_pk_from_EVP_PKEY(pkA, pkeyA)); ASSERT_OK(eddsa_pk_from_ptr(pkB, eddsa_raw, sizeof(eddsa_raw))); ASSERT_NOT_NULL((pkeyB = eddsa_pk_to_EVP_PKEY((const eddsa_pk_t *)eddsa_raw))); assert(EVP_PKEY_cmp(pkeyA, pkeyB) == 1); assert(eddsa_pk_cmp(eddsa, sizeof(eddsa)) == 0); #endif EVP_PKEY_free(pkeyA); EVP_PKEY_free(pkeyB); eddsa_pk_free(&pkA); eddsa_pk_free(&pkB); } int main(void) { fido_init(0); invalid_key(); valid_key(); exit(0); } diff --git a/contrib/libfido2/src/assert.c b/contrib/libfido2/src/assert.c index dabe8b9fdcf7..39d63bc9a174 100644 --- a/contrib/libfido2/src/assert.c +++ b/contrib/libfido2/src/assert.c @@ -1,1104 +1,1170 @@ /* - * Copyright (c) 2018-2022 Yubico AB. All rights reserved. + * Copyright (c) 2018-2023 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. * SPDX-License-Identifier: BSD-2-Clause */ #include #include "fido.h" #include "fido/es256.h" #include "fido/rs256.h" #include "fido/eddsa.h" static int adjust_assert_count(const cbor_item_t *key, const cbor_item_t *val, void *arg) { fido_assert_t *assert = arg; uint64_t n; /* numberOfCredentials; see section 6.2 */ if (cbor_isa_uint(key) == false || cbor_int_get_width(key) != CBOR_INT_8 || cbor_get_uint8(key) != 5) { fido_log_debug("%s: cbor_type", __func__); return (0); /* ignore */ } if (cbor_decode_uint64(val, &n) < 0 || n > SIZE_MAX) { fido_log_debug("%s: cbor_decode_uint64", __func__); return (-1); } if (assert->stmt_len != 0 || assert->stmt_cnt != 1 || (size_t)n < assert->stmt_cnt) { fido_log_debug("%s: stmt_len=%zu, stmt_cnt=%zu, n=%zu", __func__, assert->stmt_len, assert->stmt_cnt, (size_t)n); return (-1); } if (fido_assert_set_count(assert, (size_t)n) != FIDO_OK) { fido_log_debug("%s: fido_assert_set_count", __func__); return (-1); } assert->stmt_len = 0; /* XXX */ return (0); } static int parse_assert_reply(const cbor_item_t *key, const cbor_item_t *val, void *arg) { fido_assert_stmt *stmt = arg; if (cbor_isa_uint(key) == false || cbor_int_get_width(key) != CBOR_INT_8) { fido_log_debug("%s: cbor type", __func__); return (0); /* ignore */ } switch (cbor_get_uint8(key)) { case 1: /* credential id */ return (cbor_decode_cred_id(val, &stmt->id)); case 2: /* authdata */ + if (fido_blob_decode(val, &stmt->authdata_raw) < 0) { + fido_log_debug("%s: fido_blob_decode", __func__); + return (-1); + } return (cbor_decode_assert_authdata(val, &stmt->authdata_cbor, &stmt->authdata, &stmt->authdata_ext)); case 3: /* signature */ return (fido_blob_decode(val, &stmt->sig)); case 4: /* user attributes */ return (cbor_decode_user(val, &stmt->user)); case 7: /* large blob key */ return (fido_blob_decode(val, &stmt->largeblob_key)); default: /* ignore */ fido_log_debug("%s: cbor type", __func__); return (0); } } static int fido_dev_get_assert_tx(fido_dev_t *dev, fido_assert_t *assert, const es256_pk_t *pk, const fido_blob_t *ecdh, const char *pin, int *ms) { fido_blob_t f; fido_opt_t uv = assert->uv; cbor_item_t *argv[7]; const uint8_t cmd = CTAP_CBOR_ASSERT; int r; memset(argv, 0, sizeof(argv)); memset(&f, 0, sizeof(f)); /* do we have everything we need? */ if (assert->rp_id == NULL || assert->cdh.ptr == NULL) { fido_log_debug("%s: rp_id=%p, cdh.ptr=%p", __func__, (void *)assert->rp_id, (void *)assert->cdh.ptr); r = FIDO_ERR_INVALID_ARGUMENT; goto fail; } if ((argv[0] = cbor_build_string(assert->rp_id)) == NULL || (argv[1] = fido_blob_encode(&assert->cdh)) == NULL) { fido_log_debug("%s: cbor encode", __func__); r = FIDO_ERR_INTERNAL; goto fail; } /* allowed credentials */ if (assert->allow_list.len) { const fido_blob_array_t *cl = &assert->allow_list; if ((argv[2] = cbor_encode_pubkey_list(cl)) == NULL) { fido_log_debug("%s: cbor_encode_pubkey_list", __func__); r = FIDO_ERR_INTERNAL; goto fail; } } if (assert->ext.mask) if ((argv[3] = cbor_encode_assert_ext(dev, &assert->ext, ecdh, pk)) == NULL) { fido_log_debug("%s: cbor_encode_assert_ext", __func__); r = FIDO_ERR_INTERNAL; goto fail; } /* user verification */ if (pin != NULL || (uv == FIDO_OPT_TRUE && fido_dev_supports_permissions(dev))) { if ((r = cbor_add_uv_params(dev, cmd, &assert->cdh, pk, ecdh, pin, assert->rp_id, &argv[5], &argv[6], ms)) != FIDO_OK) { fido_log_debug("%s: cbor_add_uv_params", __func__); goto fail; } uv = FIDO_OPT_OMIT; } /* options */ if (assert->up != FIDO_OPT_OMIT || uv != FIDO_OPT_OMIT) if ((argv[4] = cbor_encode_assert_opt(assert->up, uv)) == NULL) { fido_log_debug("%s: cbor_encode_assert_opt", __func__); r = FIDO_ERR_INTERNAL; goto fail; } /* frame and transmit */ if (cbor_build_frame(cmd, argv, nitems(argv), &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; } r = FIDO_OK; fail: cbor_vector_free(argv, nitems(argv)); free(f.ptr); return (r); } static int fido_dev_get_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int *ms) { unsigned char *msg; int msglen; int r; fido_assert_reset_rx(assert); if ((msg = malloc(FIDO_MAXMSG)) == NULL) { r = FIDO_ERR_INTERNAL; goto out; } if ((msglen = fido_rx(dev, CTAP_CMD_CBOR, msg, FIDO_MAXMSG, ms)) < 0) { fido_log_debug("%s: fido_rx", __func__); r = FIDO_ERR_RX; goto out; } /* start with room for a single assertion */ if ((assert->stmt = calloc(1, sizeof(fido_assert_stmt))) == NULL) { r = FIDO_ERR_INTERNAL; goto out; } assert->stmt_len = 0; assert->stmt_cnt = 1; /* adjust as needed */ if ((r = cbor_parse_reply(msg, (size_t)msglen, assert, adjust_assert_count)) != FIDO_OK) { fido_log_debug("%s: adjust_assert_count", __func__); goto out; } /* parse the first assertion */ if ((r = cbor_parse_reply(msg, (size_t)msglen, &assert->stmt[0], parse_assert_reply)) != FIDO_OK) { fido_log_debug("%s: parse_assert_reply", __func__); goto out; } assert->stmt_len = 1; r = FIDO_OK; out: freezero(msg, FIDO_MAXMSG); return (r); } static int fido_get_next_assert_tx(fido_dev_t *dev, int *ms) { const unsigned char cbor[] = { CTAP_CBOR_NEXT_ASSERT }; if (fido_tx(dev, CTAP_CMD_CBOR, cbor, sizeof(cbor), ms) < 0) { fido_log_debug("%s: fido_tx", __func__); return (FIDO_ERR_TX); } return (FIDO_OK); } static int fido_get_next_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int *ms) { unsigned char *msg; int msglen; int r; if ((msg = malloc(FIDO_MAXMSG)) == NULL) { r = FIDO_ERR_INTERNAL; goto out; } if ((msglen = fido_rx(dev, CTAP_CMD_CBOR, msg, FIDO_MAXMSG, ms)) < 0) { fido_log_debug("%s: fido_rx", __func__); r = FIDO_ERR_RX; goto out; } /* sanity check */ if (assert->stmt_len >= assert->stmt_cnt) { fido_log_debug("%s: stmt_len=%zu, stmt_cnt=%zu", __func__, assert->stmt_len, assert->stmt_cnt); r = FIDO_ERR_INTERNAL; goto out; } if ((r = cbor_parse_reply(msg, (size_t)msglen, &assert->stmt[assert->stmt_len], parse_assert_reply)) != FIDO_OK) { fido_log_debug("%s: parse_assert_reply", __func__); goto out; } r = FIDO_OK; out: freezero(msg, FIDO_MAXMSG); return (r); } static int fido_dev_get_assert_wait(fido_dev_t *dev, fido_assert_t *assert, const es256_pk_t *pk, const fido_blob_t *ecdh, const char *pin, int *ms) { int r; if ((r = fido_dev_get_assert_tx(dev, assert, pk, ecdh, pin, ms)) != FIDO_OK || (r = fido_dev_get_assert_rx(dev, assert, ms)) != FIDO_OK) return (r); while (assert->stmt_len < assert->stmt_cnt) { if ((r = fido_get_next_assert_tx(dev, ms)) != FIDO_OK || (r = fido_get_next_assert_rx(dev, assert, ms)) != FIDO_OK) return (r); assert->stmt_len++; } return (FIDO_OK); } static int decrypt_hmac_secrets(const fido_dev_t *dev, fido_assert_t *assert, const fido_blob_t *key) { for (size_t i = 0; i < assert->stmt_cnt; i++) { fido_assert_stmt *stmt = &assert->stmt[i]; if (stmt->authdata_ext.hmac_secret_enc.ptr != NULL) { if (aes256_cbc_dec(dev, key, &stmt->authdata_ext.hmac_secret_enc, &stmt->hmac_secret) < 0) { fido_log_debug("%s: aes256_cbc_dec %zu", __func__, i); return (-1); } } } return (0); } int fido_dev_get_assert(fido_dev_t *dev, fido_assert_t *assert, const char *pin) { fido_blob_t *ecdh = NULL; es256_pk_t *pk = NULL; int ms = dev->timeout_ms; int r; #ifdef USE_WINHELLO if (dev->flags & FIDO_DEV_WINHELLO) return (fido_winhello_get_assert(dev, assert, pin, ms)); #endif if (assert->rp_id == NULL || assert->cdh.ptr == NULL) { fido_log_debug("%s: rp_id=%p, cdh.ptr=%p", __func__, (void *)assert->rp_id, (void *)assert->cdh.ptr); return (FIDO_ERR_INVALID_ARGUMENT); } if (fido_dev_is_fido2(dev) == false) { if (pin != NULL || assert->ext.mask != 0) return (FIDO_ERR_UNSUPPORTED_OPTION); return (u2f_authenticate(dev, assert, &ms)); } if (pin != NULL || (assert->uv == FIDO_OPT_TRUE && fido_dev_supports_permissions(dev)) || (assert->ext.mask & FIDO_EXT_HMAC_SECRET)) { if ((r = fido_do_ecdh(dev, &pk, &ecdh, &ms)) != FIDO_OK) { fido_log_debug("%s: fido_do_ecdh", __func__); goto fail; } } r = fido_dev_get_assert_wait(dev, assert, pk, ecdh, pin, &ms); if (r == FIDO_OK && (assert->ext.mask & FIDO_EXT_HMAC_SECRET)) if (decrypt_hmac_secrets(dev, assert, ecdh) < 0) { fido_log_debug("%s: decrypt_hmac_secrets", __func__); r = FIDO_ERR_INTERNAL; goto fail; } fail: es256_pk_free(&pk); fido_blob_free(&ecdh); return (r); } int fido_check_flags(uint8_t flags, fido_opt_t up, fido_opt_t uv) { fido_log_debug("%s: flags=%02x", __func__, flags); fido_log_debug("%s: up=%d, uv=%d", __func__, up, uv); if (up == FIDO_OPT_TRUE && (flags & CTAP_AUTHDATA_USER_PRESENT) == 0) { fido_log_debug("%s: CTAP_AUTHDATA_USER_PRESENT", __func__); return (-1); /* user not present */ } if (uv == FIDO_OPT_TRUE && (flags & CTAP_AUTHDATA_USER_VERIFIED) == 0) { fido_log_debug("%s: CTAP_AUTHDATA_USER_VERIFIED", __func__); return (-1); /* user not verified */ } return (0); } static int check_extensions(int authdata_ext, int ext) { /* XXX: largeBlobKey is not part of extensions map */ ext &= ~FIDO_EXT_LARGEBLOB_KEY; if (authdata_ext != ext) { fido_log_debug("%s: authdata_ext=0x%x != ext=0x%x", __func__, authdata_ext, ext); return (-1); } return (0); } static int get_es256_hash(fido_blob_t *dgst, const fido_blob_t *clientdata, const fido_blob_t *authdata) { const EVP_MD *md; EVP_MD_CTX *ctx = NULL; if (dgst->len < SHA256_DIGEST_LENGTH || (md = EVP_sha256()) == NULL || (ctx = EVP_MD_CTX_new()) == NULL || EVP_DigestInit_ex(ctx, md, NULL) != 1 || EVP_DigestUpdate(ctx, authdata->ptr, authdata->len) != 1 || EVP_DigestUpdate(ctx, clientdata->ptr, clientdata->len) != 1 || EVP_DigestFinal_ex(ctx, dgst->ptr, NULL) != 1) { EVP_MD_CTX_free(ctx); return (-1); } dgst->len = SHA256_DIGEST_LENGTH; EVP_MD_CTX_free(ctx); return (0); } static int get_es384_hash(fido_blob_t *dgst, const fido_blob_t *clientdata, const fido_blob_t *authdata) { const EVP_MD *md; EVP_MD_CTX *ctx = NULL; if (dgst->len < SHA384_DIGEST_LENGTH || (md = EVP_sha384()) == NULL || (ctx = EVP_MD_CTX_new()) == NULL || EVP_DigestInit_ex(ctx, md, NULL) != 1 || EVP_DigestUpdate(ctx, authdata->ptr, authdata->len) != 1 || EVP_DigestUpdate(ctx, clientdata->ptr, clientdata->len) != 1 || EVP_DigestFinal_ex(ctx, dgst->ptr, NULL) != 1) { EVP_MD_CTX_free(ctx); return (-1); } dgst->len = SHA384_DIGEST_LENGTH; EVP_MD_CTX_free(ctx); return (0); } static int get_eddsa_hash(fido_blob_t *dgst, const fido_blob_t *clientdata, const fido_blob_t *authdata) { if (SIZE_MAX - authdata->len < clientdata->len || dgst->len < authdata->len + clientdata->len) return (-1); memcpy(dgst->ptr, authdata->ptr, authdata->len); memcpy(dgst->ptr + authdata->len, clientdata->ptr, clientdata->len); dgst->len = authdata->len + clientdata->len; return (0); } int fido_get_signed_hash(int cose_alg, fido_blob_t *dgst, const fido_blob_t *clientdata, const fido_blob_t *authdata_cbor) { cbor_item_t *item = NULL; fido_blob_t authdata; struct cbor_load_result cbor; int ok = -1; fido_log_debug("%s: cose_alg=%d", __func__, cose_alg); if ((item = cbor_load(authdata_cbor->ptr, authdata_cbor->len, &cbor)) == NULL || cbor_isa_bytestring(item) == false || cbor_bytestring_is_definite(item) == false) { fido_log_debug("%s: authdata", __func__); goto fail; } authdata.ptr = cbor_bytestring_handle(item); authdata.len = cbor_bytestring_length(item); switch (cose_alg) { case COSE_ES256: case COSE_RS256: ok = get_es256_hash(dgst, clientdata, &authdata); break; case COSE_ES384: ok = get_es384_hash(dgst, clientdata, &authdata); break; case COSE_EDDSA: ok = get_eddsa_hash(dgst, clientdata, &authdata); break; default: fido_log_debug("%s: unknown cose_alg", __func__); break; } fail: if (item != NULL) cbor_decref(&item); return (ok); } int fido_assert_verify(const fido_assert_t *assert, size_t idx, int cose_alg, const void *pk) { unsigned char buf[1024]; /* XXX */ fido_blob_t dgst; const fido_assert_stmt *stmt = NULL; int ok = -1; int r; dgst.ptr = buf; dgst.len = sizeof(buf); if (idx >= assert->stmt_len || pk == NULL) { r = FIDO_ERR_INVALID_ARGUMENT; goto out; } stmt = &assert->stmt[idx]; /* do we have everything we need? */ if (assert->cdh.ptr == NULL || assert->rp_id == NULL || stmt->authdata_cbor.ptr == NULL || stmt->sig.ptr == NULL) { fido_log_debug("%s: cdh=%p, rp_id=%s, authdata=%p, sig=%p", __func__, (void *)assert->cdh.ptr, assert->rp_id, (void *)stmt->authdata_cbor.ptr, (void *)stmt->sig.ptr); r = FIDO_ERR_INVALID_ARGUMENT; goto out; } if (fido_check_flags(stmt->authdata.flags, assert->up, assert->uv) < 0) { fido_log_debug("%s: fido_check_flags", __func__); r = FIDO_ERR_INVALID_PARAM; goto out; } if (check_extensions(stmt->authdata_ext.mask, assert->ext.mask) < 0) { fido_log_debug("%s: check_extensions", __func__); r = FIDO_ERR_INVALID_PARAM; goto out; } if (fido_check_rp_id(assert->rp_id, stmt->authdata.rp_id_hash) != 0) { fido_log_debug("%s: fido_check_rp_id", __func__); r = FIDO_ERR_INVALID_PARAM; goto out; } if (fido_get_signed_hash(cose_alg, &dgst, &assert->cdh, &stmt->authdata_cbor) < 0) { fido_log_debug("%s: fido_get_signed_hash", __func__); r = FIDO_ERR_INTERNAL; goto out; } switch (cose_alg) { case COSE_ES256: ok = es256_pk_verify_sig(&dgst, pk, &stmt->sig); break; case COSE_ES384: ok = es384_pk_verify_sig(&dgst, pk, &stmt->sig); break; case COSE_RS256: ok = rs256_pk_verify_sig(&dgst, pk, &stmt->sig); break; case COSE_EDDSA: ok = eddsa_pk_verify_sig(&dgst, pk, &stmt->sig); break; default: fido_log_debug("%s: unsupported cose_alg %d", __func__, cose_alg); r = FIDO_ERR_UNSUPPORTED_OPTION; goto out; } if (ok < 0) r = FIDO_ERR_INVALID_SIG; else r = FIDO_OK; out: explicit_bzero(buf, sizeof(buf)); return (r); } int fido_assert_set_clientdata(fido_assert_t *assert, const unsigned char *data, size_t data_len) { if (!fido_blob_is_empty(&assert->cdh) || fido_blob_set(&assert->cd, data, data_len) < 0) { return (FIDO_ERR_INVALID_ARGUMENT); } if (fido_sha256(&assert->cdh, data, data_len) < 0) { fido_blob_reset(&assert->cd); return (FIDO_ERR_INTERNAL); } return (FIDO_OK); } int fido_assert_set_clientdata_hash(fido_assert_t *assert, const unsigned char *hash, size_t hash_len) { if (!fido_blob_is_empty(&assert->cd) || fido_blob_set(&assert->cdh, hash, hash_len) < 0) return (FIDO_ERR_INVALID_ARGUMENT); return (FIDO_OK); } int fido_assert_set_hmac_salt(fido_assert_t *assert, const unsigned char *salt, size_t salt_len) { if ((salt_len != 32 && salt_len != 64) || fido_blob_set(&assert->ext.hmac_salt, salt, salt_len) < 0) return (FIDO_ERR_INVALID_ARGUMENT); return (FIDO_OK); } int fido_assert_set_hmac_secret(fido_assert_t *assert, size_t idx, const unsigned char *secret, size_t secret_len) { if (idx >= assert->stmt_len || (secret_len != 32 && secret_len != 64) || fido_blob_set(&assert->stmt[idx].hmac_secret, secret, secret_len) < 0) return (FIDO_ERR_INVALID_ARGUMENT); return (FIDO_OK); } int fido_assert_set_rp(fido_assert_t *assert, const char *id) { if (assert->rp_id != NULL) { free(assert->rp_id); assert->rp_id = NULL; } if (id == NULL) return (FIDO_ERR_INVALID_ARGUMENT); if ((assert->rp_id = strdup(id)) == NULL) return (FIDO_ERR_INTERNAL); return (FIDO_OK); } +#ifdef USE_WINHELLO +int +fido_assert_set_winhello_appid(fido_assert_t *assert, const char *id) +{ + if (assert->appid != NULL) { + free(assert->appid); + assert->appid = NULL; + } + + if (id == NULL) + return (FIDO_ERR_INVALID_ARGUMENT); + + if ((assert->appid = strdup(id)) == NULL) + return (FIDO_ERR_INTERNAL); + + return (FIDO_OK); +} +#else +int +fido_assert_set_winhello_appid(fido_assert_t *assert, const char *id) +{ + (void)assert; + (void)id; + + return (FIDO_ERR_UNSUPPORTED_EXTENSION); +} +#endif /* USE_WINHELLO */ + int fido_assert_allow_cred(fido_assert_t *assert, const unsigned char *ptr, size_t len) { fido_blob_t id; fido_blob_t *list_ptr; int r; memset(&id, 0, sizeof(id)); if (assert->allow_list.len == SIZE_MAX) { r = FIDO_ERR_INVALID_ARGUMENT; goto fail; } if (fido_blob_set(&id, ptr, len) < 0 || (list_ptr = recallocarray(assert->allow_list.ptr, assert->allow_list.len, assert->allow_list.len + 1, sizeof(fido_blob_t))) == NULL) { r = FIDO_ERR_INVALID_ARGUMENT; goto fail; } list_ptr[assert->allow_list.len++] = id; assert->allow_list.ptr = list_ptr; return (FIDO_OK); fail: free(id.ptr); return (r); } int fido_assert_empty_allow_list(fido_assert_t *assert) { fido_free_blob_array(&assert->allow_list); memset(&assert->allow_list, 0, sizeof(assert->allow_list)); return (FIDO_OK); } int fido_assert_set_extensions(fido_assert_t *assert, int ext) { if (ext == 0) assert->ext.mask = 0; else { if ((ext & FIDO_EXT_ASSERT_MASK) != ext) return (FIDO_ERR_INVALID_ARGUMENT); assert->ext.mask |= ext; } return (FIDO_OK); } int fido_assert_set_options(fido_assert_t *assert, bool up, bool uv) { assert->up = up ? FIDO_OPT_TRUE : FIDO_OPT_FALSE; assert->uv = uv ? FIDO_OPT_TRUE : FIDO_OPT_FALSE; return (FIDO_OK); } int fido_assert_set_up(fido_assert_t *assert, fido_opt_t up) { assert->up = up; return (FIDO_OK); } int fido_assert_set_uv(fido_assert_t *assert, fido_opt_t uv) { assert->uv = uv; return (FIDO_OK); } const unsigned char * fido_assert_clientdata_hash_ptr(const fido_assert_t *assert) { return (assert->cdh.ptr); } size_t fido_assert_clientdata_hash_len(const fido_assert_t *assert) { return (assert->cdh.len); } fido_assert_t * fido_assert_new(void) { return (calloc(1, sizeof(fido_assert_t))); } void fido_assert_reset_tx(fido_assert_t *assert) { free(assert->rp_id); + free(assert->appid); fido_blob_reset(&assert->cd); fido_blob_reset(&assert->cdh); fido_blob_reset(&assert->ext.hmac_salt); fido_assert_empty_allow_list(assert); memset(&assert->ext, 0, sizeof(assert->ext)); assert->rp_id = NULL; + assert->appid = NULL; assert->up = FIDO_OPT_OMIT; assert->uv = FIDO_OPT_OMIT; } static void fido_assert_reset_extattr(fido_assert_extattr_t *ext) { fido_blob_reset(&ext->hmac_secret_enc); fido_blob_reset(&ext->blob); memset(ext, 0, sizeof(*ext)); } void fido_assert_reset_rx(fido_assert_t *assert) { for (size_t i = 0; i < assert->stmt_cnt; i++) { free(assert->stmt[i].user.icon); free(assert->stmt[i].user.name); free(assert->stmt[i].user.display_name); fido_blob_reset(&assert->stmt[i].user.id); fido_blob_reset(&assert->stmt[i].id); fido_blob_reset(&assert->stmt[i].hmac_secret); fido_blob_reset(&assert->stmt[i].authdata_cbor); + fido_blob_reset(&assert->stmt[i].authdata_raw); fido_blob_reset(&assert->stmt[i].largeblob_key); fido_blob_reset(&assert->stmt[i].sig); fido_assert_reset_extattr(&assert->stmt[i].authdata_ext); memset(&assert->stmt[i], 0, sizeof(assert->stmt[i])); } free(assert->stmt); assert->stmt = NULL; assert->stmt_len = 0; assert->stmt_cnt = 0; } void fido_assert_free(fido_assert_t **assert_p) { fido_assert_t *assert; if (assert_p == NULL || (assert = *assert_p) == NULL) return; fido_assert_reset_tx(assert); fido_assert_reset_rx(assert); free(assert); *assert_p = NULL; } size_t fido_assert_count(const fido_assert_t *assert) { return (assert->stmt_len); } const char * fido_assert_rp_id(const fido_assert_t *assert) { return (assert->rp_id); } uint8_t fido_assert_flags(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (0); return (assert->stmt[idx].authdata.flags); } uint32_t fido_assert_sigcount(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (0); return (assert->stmt[idx].authdata.sigcount); } const unsigned char * fido_assert_authdata_ptr(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (NULL); return (assert->stmt[idx].authdata_cbor.ptr); } size_t fido_assert_authdata_len(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (0); return (assert->stmt[idx].authdata_cbor.len); } +const unsigned char * +fido_assert_authdata_raw_ptr(const fido_assert_t *assert, size_t idx) +{ + if (idx >= assert->stmt_len) + return (NULL); + + return (assert->stmt[idx].authdata_raw.ptr); +} + +size_t +fido_assert_authdata_raw_len(const fido_assert_t *assert, size_t idx) +{ + if (idx >= assert->stmt_len) + return (0); + + return (assert->stmt[idx].authdata_raw.len); +} + const unsigned char * fido_assert_sig_ptr(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (NULL); return (assert->stmt[idx].sig.ptr); } size_t fido_assert_sig_len(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (0); return (assert->stmt[idx].sig.len); } const unsigned char * fido_assert_id_ptr(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (NULL); return (assert->stmt[idx].id.ptr); } size_t fido_assert_id_len(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (0); return (assert->stmt[idx].id.len); } const unsigned char * fido_assert_user_id_ptr(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (NULL); return (assert->stmt[idx].user.id.ptr); } size_t fido_assert_user_id_len(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (0); return (assert->stmt[idx].user.id.len); } const char * fido_assert_user_icon(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (NULL); return (assert->stmt[idx].user.icon); } const char * fido_assert_user_name(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (NULL); return (assert->stmt[idx].user.name); } const char * fido_assert_user_display_name(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (NULL); return (assert->stmt[idx].user.display_name); } const unsigned char * fido_assert_hmac_secret_ptr(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (NULL); return (assert->stmt[idx].hmac_secret.ptr); } size_t fido_assert_hmac_secret_len(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (0); return (assert->stmt[idx].hmac_secret.len); } const unsigned char * fido_assert_largeblob_key_ptr(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (NULL); return (assert->stmt[idx].largeblob_key.ptr); } size_t fido_assert_largeblob_key_len(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (0); return (assert->stmt[idx].largeblob_key.len); } const unsigned char * fido_assert_blob_ptr(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (NULL); return (assert->stmt[idx].authdata_ext.blob.ptr); } size_t fido_assert_blob_len(const fido_assert_t *assert, size_t idx) { if (idx >= assert->stmt_len) return (0); return (assert->stmt[idx].authdata_ext.blob.len); } static void fido_assert_clean_authdata(fido_assert_stmt *stmt) { fido_blob_reset(&stmt->authdata_cbor); + fido_blob_reset(&stmt->authdata_raw); fido_assert_reset_extattr(&stmt->authdata_ext); memset(&stmt->authdata, 0, sizeof(stmt->authdata)); } int fido_assert_set_authdata(fido_assert_t *assert, size_t idx, const unsigned char *ptr, size_t len) { cbor_item_t *item = NULL; fido_assert_stmt *stmt = NULL; struct cbor_load_result cbor; int r; if (idx >= assert->stmt_len || ptr == NULL || len == 0) return (FIDO_ERR_INVALID_ARGUMENT); stmt = &assert->stmt[idx]; fido_assert_clean_authdata(stmt); if ((item = cbor_load(ptr, len, &cbor)) == NULL) { fido_log_debug("%s: cbor_load", __func__); r = FIDO_ERR_INVALID_ARGUMENT; goto fail; } + if (fido_blob_decode(item, &stmt->authdata_raw) < 0) { + fido_log_debug("%s: fido_blob_decode", __func__); + r = FIDO_ERR_INTERNAL; + goto fail; + } + if (cbor_decode_assert_authdata(item, &stmt->authdata_cbor, &stmt->authdata, &stmt->authdata_ext) < 0) { fido_log_debug("%s: cbor_decode_assert_authdata", __func__); r = FIDO_ERR_INVALID_ARGUMENT; goto fail; } r = FIDO_OK; fail: if (item != NULL) cbor_decref(&item); if (r != FIDO_OK) fido_assert_clean_authdata(stmt); return (r); } int fido_assert_set_authdata_raw(fido_assert_t *assert, size_t idx, const unsigned char *ptr, size_t len) { cbor_item_t *item = NULL; fido_assert_stmt *stmt = NULL; int r; if (idx >= assert->stmt_len || ptr == NULL || len == 0) return (FIDO_ERR_INVALID_ARGUMENT); stmt = &assert->stmt[idx]; fido_assert_clean_authdata(stmt); + if (fido_blob_set(&stmt->authdata_raw, ptr, len) < 0) { + fido_log_debug("%s: fido_blob_set", __func__); + r = FIDO_ERR_INTERNAL; + goto fail; + } + if ((item = cbor_build_bytestring(ptr, len)) == NULL) { fido_log_debug("%s: cbor_build_bytestring", __func__); r = FIDO_ERR_INTERNAL; goto fail; } if (cbor_decode_assert_authdata(item, &stmt->authdata_cbor, &stmt->authdata, &stmt->authdata_ext) < 0) { fido_log_debug("%s: cbor_decode_assert_authdata", __func__); r = FIDO_ERR_INVALID_ARGUMENT; goto fail; } r = FIDO_OK; fail: if (item != NULL) cbor_decref(&item); if (r != FIDO_OK) fido_assert_clean_authdata(stmt); return (r); } int fido_assert_set_sig(fido_assert_t *a, size_t idx, const unsigned char *ptr, size_t len) { if (idx >= a->stmt_len || ptr == NULL || len == 0) return (FIDO_ERR_INVALID_ARGUMENT); if (fido_blob_set(&a->stmt[idx].sig, ptr, len) < 0) return (FIDO_ERR_INTERNAL); return (FIDO_OK); } /* XXX shrinking leaks memory; fortunately that shouldn't happen */ int fido_assert_set_count(fido_assert_t *assert, size_t n) { void *new_stmt; #ifdef FIDO_FUZZ if (n > UINT8_MAX) { fido_log_debug("%s: n > UINT8_MAX", __func__); return (FIDO_ERR_INTERNAL); } #endif new_stmt = recallocarray(assert->stmt, assert->stmt_cnt, n, sizeof(fido_assert_stmt)); if (new_stmt == NULL) return (FIDO_ERR_INTERNAL); assert->stmt = new_stmt; assert->stmt_cnt = n; assert->stmt_len = n; return (FIDO_OK); } diff --git a/contrib/libfido2/src/export.gnu b/contrib/libfido2/src/export.gnu index 604741ed7d92..ea6ca7d373ef 100644 --- a/contrib/libfido2/src/export.gnu +++ b/contrib/libfido2/src/export.gnu @@ -1,265 +1,268 @@ { global: eddsa_pk_free; eddsa_pk_from_EVP_PKEY; eddsa_pk_from_ptr; eddsa_pk_new; eddsa_pk_to_EVP_PKEY; es256_pk_free; es256_pk_from_EC_KEY; es256_pk_from_EVP_PKEY; es256_pk_from_ptr; es256_pk_new; es256_pk_to_EVP_PKEY; es384_pk_free; es384_pk_from_EC_KEY; es384_pk_from_EVP_PKEY; es384_pk_from_ptr; es384_pk_new; es384_pk_to_EVP_PKEY; fido_assert_allow_cred; fido_assert_authdata_len; fido_assert_authdata_ptr; + fido_assert_authdata_raw_len; + fido_assert_authdata_raw_ptr; fido_assert_blob_len; fido_assert_blob_ptr; fido_assert_clientdata_hash_len; fido_assert_clientdata_hash_ptr; fido_assert_count; fido_assert_empty_allow_list; fido_assert_flags; fido_assert_free; fido_assert_hmac_secret_len; fido_assert_hmac_secret_ptr; fido_assert_id_len; fido_assert_id_ptr; fido_assert_largeblob_key_len; fido_assert_largeblob_key_ptr; fido_assert_new; fido_assert_rp_id; fido_assert_set_authdata; fido_assert_set_authdata_raw; fido_assert_set_clientdata; fido_assert_set_clientdata_hash; fido_assert_set_count; fido_assert_set_extensions; fido_assert_set_hmac_salt; fido_assert_set_hmac_secret; fido_assert_set_options; fido_assert_set_rp; fido_assert_set_sig; fido_assert_set_up; fido_assert_set_uv; + fido_assert_set_winhello_appid; fido_assert_sigcount; fido_assert_sig_len; fido_assert_sig_ptr; fido_assert_user_display_name; fido_assert_user_icon; fido_assert_user_id_len; fido_assert_user_id_ptr; fido_assert_user_name; fido_assert_verify; fido_bio_dev_enroll_begin; fido_bio_dev_enroll_cancel; fido_bio_dev_enroll_continue; fido_bio_dev_enroll_remove; fido_bio_dev_get_info; fido_bio_dev_get_template_array; fido_bio_dev_set_template_name; fido_bio_enroll_free; fido_bio_enroll_last_status; fido_bio_enroll_new; fido_bio_enroll_remaining_samples; fido_bio_info_free; fido_bio_info_max_samples; fido_bio_info_new; fido_bio_info_type; fido_bio_template; fido_bio_template_array_count; fido_bio_template_array_free; fido_bio_template_array_new; fido_bio_template_free; fido_bio_template_id_len; fido_bio_template_id_ptr; fido_bio_template_name; fido_bio_template_new; fido_bio_template_set_id; fido_bio_template_set_name; fido_cbor_info_aaguid_len; fido_cbor_info_aaguid_ptr; fido_cbor_info_algorithm_cose; fido_cbor_info_algorithm_count; fido_cbor_info_algorithm_type; fido_cbor_info_certs_len; fido_cbor_info_certs_name_ptr; fido_cbor_info_certs_value_ptr; fido_cbor_info_extensions_len; fido_cbor_info_extensions_ptr; fido_cbor_info_free; fido_cbor_info_fwversion; fido_cbor_info_maxcredbloblen; fido_cbor_info_maxcredcntlst; fido_cbor_info_maxcredidlen; fido_cbor_info_maxlargeblob; fido_cbor_info_maxmsgsiz; fido_cbor_info_maxrpid_minpinlen; fido_cbor_info_minpinlen; fido_cbor_info_new; fido_cbor_info_new_pin_required; fido_cbor_info_options_len; fido_cbor_info_options_name_ptr; fido_cbor_info_options_value_ptr; fido_cbor_info_protocols_len; fido_cbor_info_protocols_ptr; fido_cbor_info_rk_remaining; fido_cbor_info_transports_len; fido_cbor_info_transports_ptr; fido_cbor_info_uv_attempts; fido_cbor_info_uv_modality; fido_cbor_info_versions_len; fido_cbor_info_versions_ptr; fido_cred_attstmt_len; fido_cred_attstmt_ptr; fido_cred_authdata_len; fido_cred_authdata_ptr; fido_cred_authdata_raw_len; fido_cred_authdata_raw_ptr; fido_cred_clientdata_hash_len; fido_cred_clientdata_hash_ptr; fido_cred_display_name; fido_cred_empty_exclude_list; fido_cred_exclude; fido_cred_flags; fido_cred_largeblob_key_len; fido_cred_largeblob_key_ptr; fido_cred_sigcount; fido_cred_fmt; fido_cred_free; fido_cred_id_len; fido_cred_id_ptr; fido_cred_aaguid_len; fido_cred_aaguid_ptr; fido_credman_del_dev_rk; fido_credman_get_dev_metadata; fido_credman_get_dev_rk; fido_credman_get_dev_rp; fido_credman_metadata_free; fido_credman_metadata_new; fido_credman_rk; fido_credman_rk_count; fido_credman_rk_existing; fido_credman_rk_free; fido_credman_rk_new; fido_credman_rk_remaining; fido_credman_rp_count; fido_credman_rp_free; fido_credman_rp_id; fido_credman_rp_id_hash_len; fido_credman_rp_id_hash_ptr; fido_credman_rp_name; fido_credman_rp_new; fido_credman_set_dev_rk; fido_cred_new; fido_cred_pin_minlen; fido_cred_prot; fido_cred_pubkey_len; fido_cred_pubkey_ptr; fido_cred_rp_id; fido_cred_rp_name; fido_cred_set_attstmt; fido_cred_set_authdata; fido_cred_set_authdata_raw; fido_cred_set_blob; fido_cred_set_clientdata; fido_cred_set_clientdata_hash; fido_cred_set_extensions; fido_cred_set_fmt; fido_cred_set_id; fido_cred_set_options; fido_cred_set_pin_minlen; fido_cred_set_prot; fido_cred_set_rk; fido_cred_set_rp; fido_cred_set_sig; fido_cred_set_type; fido_cred_set_user; fido_cred_set_uv; fido_cred_set_x509; fido_cred_sig_len; fido_cred_sig_ptr; fido_cred_type; fido_cred_user_id_len; fido_cred_user_id_ptr; fido_cred_user_name; fido_cred_verify; fido_cred_verify_self; fido_cred_x5c_len; fido_cred_x5c_ptr; fido_dev_build; fido_dev_cancel; fido_dev_close; fido_dev_enable_entattest; fido_dev_flags; fido_dev_force_fido2; fido_dev_force_pin_change; fido_dev_force_u2f; fido_dev_free; fido_dev_get_assert; fido_dev_get_cbor_info; fido_dev_get_retry_count; fido_dev_get_uv_retry_count; fido_dev_get_touch_begin; fido_dev_get_touch_status; fido_dev_has_pin; fido_dev_has_uv; fido_dev_info_free; fido_dev_info_manifest; fido_dev_info_manufacturer_string; fido_dev_info_new; fido_dev_info_path; fido_dev_info_product; fido_dev_info_product_string; fido_dev_info_ptr; fido_dev_info_set; fido_dev_info_vendor; fido_dev_io_handle; fido_dev_is_fido2; fido_dev_is_winhello; fido_dev_major; fido_dev_make_cred; fido_dev_minor; fido_dev_new; fido_dev_new_with_info; fido_dev_open; fido_dev_open_with_info; fido_dev_protocol; fido_dev_reset; fido_dev_set_io_functions; fido_dev_set_pin; fido_dev_set_pin_minlen; fido_dev_set_pin_minlen_rpid; fido_dev_set_sigmask; fido_dev_set_timeout; fido_dev_set_transport_functions; fido_dev_supports_cred_prot; fido_dev_supports_credman; fido_dev_supports_permissions; fido_dev_supports_pin; fido_dev_supports_uv; fido_dev_toggle_always_uv; fido_dev_largeblob_get; fido_dev_largeblob_get_array; fido_dev_largeblob_remove; fido_dev_largeblob_set; fido_dev_largeblob_set_array; fido_init; fido_set_log_handler; fido_strerr; rs256_pk_free; rs256_pk_from_ptr; rs256_pk_from_EVP_PKEY; rs256_pk_from_RSA; rs256_pk_new; rs256_pk_to_EVP_PKEY; local: *; }; diff --git a/contrib/libfido2/src/export.llvm b/contrib/libfido2/src/export.llvm index 0be829538d7b..2a9238141937 100644 --- a/contrib/libfido2/src/export.llvm +++ b/contrib/libfido2/src/export.llvm @@ -1,260 +1,263 @@ _eddsa_pk_free _eddsa_pk_from_EVP_PKEY _eddsa_pk_from_ptr _eddsa_pk_new _eddsa_pk_to_EVP_PKEY _es256_pk_free _es256_pk_from_EC_KEY _es256_pk_from_EVP_PKEY _es256_pk_from_ptr _es256_pk_new _es256_pk_to_EVP_PKEY _es384_pk_free _es384_pk_from_EC_KEY _es384_pk_from_EVP_PKEY _es384_pk_from_ptr _es384_pk_new _es384_pk_to_EVP_PKEY _fido_assert_allow_cred _fido_assert_authdata_len _fido_assert_authdata_ptr +_fido_assert_authdata_raw_len +_fido_assert_authdata_raw_ptr _fido_assert_blob_len _fido_assert_blob_ptr _fido_assert_clientdata_hash_len _fido_assert_clientdata_hash_ptr _fido_assert_count _fido_assert_empty_allow_list _fido_assert_flags _fido_assert_free _fido_assert_hmac_secret_len _fido_assert_hmac_secret_ptr _fido_assert_id_len _fido_assert_id_ptr _fido_assert_largeblob_key_len _fido_assert_largeblob_key_ptr _fido_assert_new _fido_assert_rp_id _fido_assert_set_authdata _fido_assert_set_authdata_raw _fido_assert_set_clientdata _fido_assert_set_clientdata_hash _fido_assert_set_count _fido_assert_set_extensions _fido_assert_set_hmac_salt _fido_assert_set_hmac_secret _fido_assert_set_options _fido_assert_set_rp _fido_assert_set_sig _fido_assert_set_up _fido_assert_set_uv +_fido_assert_set_winhello_appid _fido_assert_sigcount _fido_assert_sig_len _fido_assert_sig_ptr _fido_assert_user_display_name _fido_assert_user_icon _fido_assert_user_id_len _fido_assert_user_id_ptr _fido_assert_user_name _fido_assert_verify _fido_bio_dev_enroll_begin _fido_bio_dev_enroll_cancel _fido_bio_dev_enroll_continue _fido_bio_dev_enroll_remove _fido_bio_dev_get_info _fido_bio_dev_get_template_array _fido_bio_dev_set_template_name _fido_bio_enroll_free _fido_bio_enroll_last_status _fido_bio_enroll_new _fido_bio_enroll_remaining_samples _fido_bio_info_free _fido_bio_info_max_samples _fido_bio_info_new _fido_bio_info_type _fido_bio_template _fido_bio_template_array_count _fido_bio_template_array_free _fido_bio_template_array_new _fido_bio_template_free _fido_bio_template_id_len _fido_bio_template_id_ptr _fido_bio_template_name _fido_bio_template_new _fido_bio_template_set_id _fido_bio_template_set_name _fido_cbor_info_aaguid_len _fido_cbor_info_aaguid_ptr _fido_cbor_info_algorithm_cose _fido_cbor_info_algorithm_count _fido_cbor_info_algorithm_type _fido_cbor_info_certs_len _fido_cbor_info_certs_name_ptr _fido_cbor_info_certs_value_ptr _fido_cbor_info_extensions_len _fido_cbor_info_extensions_ptr _fido_cbor_info_free _fido_cbor_info_fwversion _fido_cbor_info_maxcredbloblen _fido_cbor_info_maxcredcntlst _fido_cbor_info_maxcredidlen _fido_cbor_info_maxlargeblob _fido_cbor_info_maxmsgsiz _fido_cbor_info_maxrpid_minpinlen _fido_cbor_info_minpinlen _fido_cbor_info_new _fido_cbor_info_new_pin_required _fido_cbor_info_options_len _fido_cbor_info_options_name_ptr _fido_cbor_info_options_value_ptr _fido_cbor_info_protocols_len _fido_cbor_info_protocols_ptr _fido_cbor_info_rk_remaining _fido_cbor_info_transports_len _fido_cbor_info_transports_ptr _fido_cbor_info_uv_attempts _fido_cbor_info_uv_modality _fido_cbor_info_versions_len _fido_cbor_info_versions_ptr _fido_cred_attstmt_len _fido_cred_attstmt_ptr _fido_cred_authdata_len _fido_cred_authdata_ptr _fido_cred_authdata_raw_len _fido_cred_authdata_raw_ptr _fido_cred_clientdata_hash_len _fido_cred_clientdata_hash_ptr _fido_cred_display_name _fido_cred_empty_exclude_list _fido_cred_exclude _fido_cred_flags _fido_cred_largeblob_key_len _fido_cred_largeblob_key_ptr _fido_cred_sigcount _fido_cred_fmt _fido_cred_free _fido_cred_id_len _fido_cred_id_ptr _fido_cred_aaguid_len _fido_cred_aaguid_ptr _fido_credman_del_dev_rk _fido_credman_get_dev_metadata _fido_credman_get_dev_rk _fido_credman_get_dev_rp _fido_credman_metadata_free _fido_credman_metadata_new _fido_credman_rk _fido_credman_rk_count _fido_credman_rk_existing _fido_credman_rk_free _fido_credman_rk_new _fido_credman_rk_remaining _fido_credman_rp_count _fido_credman_rp_free _fido_credman_rp_id _fido_credman_rp_id_hash_len _fido_credman_rp_id_hash_ptr _fido_credman_rp_name _fido_credman_rp_new _fido_credman_set_dev_rk _fido_cred_new _fido_cred_pin_minlen _fido_cred_prot _fido_cred_pubkey_len _fido_cred_pubkey_ptr _fido_cred_rp_id _fido_cred_rp_name _fido_cred_set_attstmt _fido_cred_set_authdata _fido_cred_set_authdata_raw _fido_cred_set_blob _fido_cred_set_clientdata _fido_cred_set_clientdata_hash _fido_cred_set_extensions _fido_cred_set_fmt _fido_cred_set_id _fido_cred_set_options _fido_cred_set_pin_minlen _fido_cred_set_prot _fido_cred_set_rk _fido_cred_set_rp _fido_cred_set_sig _fido_cred_set_type _fido_cred_set_user _fido_cred_set_uv _fido_cred_set_x509 _fido_cred_sig_len _fido_cred_sig_ptr _fido_cred_type _fido_cred_user_id_len _fido_cred_user_id_ptr _fido_cred_user_name _fido_cred_verify _fido_cred_verify_self _fido_cred_x5c_len _fido_cred_x5c_ptr _fido_dev_build _fido_dev_cancel _fido_dev_close _fido_dev_enable_entattest _fido_dev_flags _fido_dev_force_fido2 _fido_dev_force_pin_change _fido_dev_force_u2f _fido_dev_free _fido_dev_get_assert _fido_dev_get_cbor_info _fido_dev_get_retry_count _fido_dev_get_uv_retry_count _fido_dev_get_touch_begin _fido_dev_get_touch_status _fido_dev_has_pin _fido_dev_has_uv _fido_dev_info_free _fido_dev_info_manifest _fido_dev_info_manufacturer_string _fido_dev_info_new _fido_dev_info_path _fido_dev_info_product _fido_dev_info_product_string _fido_dev_info_ptr _fido_dev_info_set _fido_dev_info_vendor _fido_dev_io_handle _fido_dev_is_fido2 _fido_dev_is_winhello _fido_dev_major _fido_dev_make_cred _fido_dev_minor _fido_dev_new _fido_dev_new_with_info _fido_dev_open _fido_dev_open_with_info _fido_dev_protocol _fido_dev_reset _fido_dev_set_io_functions _fido_dev_set_pin _fido_dev_set_pin_minlen _fido_dev_set_pin_minlen_rpid _fido_dev_set_sigmask _fido_dev_set_timeout _fido_dev_set_transport_functions _fido_dev_supports_cred_prot _fido_dev_supports_credman _fido_dev_supports_permissions _fido_dev_supports_pin _fido_dev_supports_uv _fido_dev_toggle_always_uv _fido_dev_largeblob_get _fido_dev_largeblob_get_array _fido_dev_largeblob_remove _fido_dev_largeblob_set _fido_dev_largeblob_set_array _fido_init _fido_set_log_handler _fido_strerr _rs256_pk_free _rs256_pk_from_ptr _rs256_pk_from_EVP_PKEY _rs256_pk_from_RSA _rs256_pk_new _rs256_pk_to_EVP_PKEY diff --git a/contrib/libfido2/src/export.msvc b/contrib/libfido2/src/export.msvc index 10f8bd14497d..c5b2edc0b5c8 100644 --- a/contrib/libfido2/src/export.msvc +++ b/contrib/libfido2/src/export.msvc @@ -1,261 +1,264 @@ EXPORTS eddsa_pk_free eddsa_pk_from_EVP_PKEY eddsa_pk_from_ptr eddsa_pk_new eddsa_pk_to_EVP_PKEY es256_pk_free es256_pk_from_EC_KEY es256_pk_from_EVP_PKEY es256_pk_from_ptr es256_pk_new es256_pk_to_EVP_PKEY es384_pk_free es384_pk_from_EC_KEY es384_pk_from_EVP_PKEY es384_pk_from_ptr es384_pk_new es384_pk_to_EVP_PKEY fido_assert_allow_cred fido_assert_authdata_len fido_assert_authdata_ptr +fido_assert_authdata_raw_len +fido_assert_authdata_raw_ptr fido_assert_blob_len fido_assert_blob_ptr fido_assert_clientdata_hash_len fido_assert_clientdata_hash_ptr fido_assert_count fido_assert_empty_allow_list fido_assert_flags fido_assert_free fido_assert_hmac_secret_len fido_assert_hmac_secret_ptr fido_assert_id_len fido_assert_id_ptr fido_assert_largeblob_key_len fido_assert_largeblob_key_ptr fido_assert_new fido_assert_rp_id fido_assert_set_authdata fido_assert_set_authdata_raw fido_assert_set_clientdata fido_assert_set_clientdata_hash fido_assert_set_count fido_assert_set_extensions fido_assert_set_hmac_salt fido_assert_set_hmac_secret fido_assert_set_options fido_assert_set_rp fido_assert_set_sig fido_assert_set_up fido_assert_set_uv +fido_assert_set_winhello_appid fido_assert_sigcount fido_assert_sig_len fido_assert_sig_ptr fido_assert_user_display_name fido_assert_user_icon fido_assert_user_id_len fido_assert_user_id_ptr fido_assert_user_name fido_assert_verify fido_bio_dev_enroll_begin fido_bio_dev_enroll_cancel fido_bio_dev_enroll_continue fido_bio_dev_enroll_remove fido_bio_dev_get_info fido_bio_dev_get_template_array fido_bio_dev_set_template_name fido_bio_enroll_free fido_bio_enroll_last_status fido_bio_enroll_new fido_bio_enroll_remaining_samples fido_bio_info_free fido_bio_info_max_samples fido_bio_info_new fido_bio_info_type fido_bio_template fido_bio_template_array_count fido_bio_template_array_free fido_bio_template_array_new fido_bio_template_free fido_bio_template_id_len fido_bio_template_id_ptr fido_bio_template_name fido_bio_template_new fido_bio_template_set_id fido_bio_template_set_name fido_cbor_info_aaguid_len fido_cbor_info_aaguid_ptr fido_cbor_info_algorithm_cose fido_cbor_info_algorithm_count fido_cbor_info_algorithm_type fido_cbor_info_certs_len fido_cbor_info_certs_name_ptr fido_cbor_info_certs_value_ptr fido_cbor_info_extensions_len fido_cbor_info_extensions_ptr fido_cbor_info_free fido_cbor_info_fwversion fido_cbor_info_maxcredbloblen fido_cbor_info_maxcredcntlst fido_cbor_info_maxcredidlen fido_cbor_info_maxlargeblob fido_cbor_info_maxmsgsiz fido_cbor_info_maxrpid_minpinlen fido_cbor_info_minpinlen fido_cbor_info_new fido_cbor_info_new_pin_required fido_cbor_info_options_len fido_cbor_info_options_name_ptr fido_cbor_info_options_value_ptr fido_cbor_info_protocols_len fido_cbor_info_protocols_ptr fido_cbor_info_rk_remaining fido_cbor_info_transports_len fido_cbor_info_transports_ptr fido_cbor_info_uv_attempts fido_cbor_info_uv_modality fido_cbor_info_versions_len fido_cbor_info_versions_ptr fido_cred_attstmt_len fido_cred_attstmt_ptr fido_cred_authdata_len fido_cred_authdata_ptr fido_cred_authdata_raw_len fido_cred_authdata_raw_ptr fido_cred_clientdata_hash_len fido_cred_clientdata_hash_ptr fido_cred_display_name fido_cred_empty_exclude_list fido_cred_exclude fido_cred_flags fido_cred_largeblob_key_len fido_cred_largeblob_key_ptr fido_cred_sigcount fido_cred_fmt fido_cred_free fido_cred_id_len fido_cred_id_ptr fido_cred_aaguid_len fido_cred_aaguid_ptr fido_credman_del_dev_rk fido_credman_get_dev_metadata fido_credman_get_dev_rk fido_credman_get_dev_rp fido_credman_metadata_free fido_credman_metadata_new fido_credman_rk fido_credman_rk_count fido_credman_rk_existing fido_credman_rk_free fido_credman_rk_new fido_credman_rk_remaining fido_credman_rp_count fido_credman_rp_free fido_credman_rp_id fido_credman_rp_id_hash_len fido_credman_rp_id_hash_ptr fido_credman_rp_name fido_credman_rp_new fido_credman_set_dev_rk fido_cred_new fido_cred_pin_minlen fido_cred_prot fido_cred_pubkey_len fido_cred_pubkey_ptr fido_cred_rp_id fido_cred_rp_name fido_cred_set_attstmt fido_cred_set_authdata fido_cred_set_authdata_raw fido_cred_set_blob fido_cred_set_clientdata fido_cred_set_clientdata_hash fido_cred_set_extensions fido_cred_set_fmt fido_cred_set_id fido_cred_set_options fido_cred_set_pin_minlen fido_cred_set_prot fido_cred_set_rk fido_cred_set_rp fido_cred_set_sig fido_cred_set_type fido_cred_set_user fido_cred_set_uv fido_cred_set_x509 fido_cred_sig_len fido_cred_sig_ptr fido_cred_type fido_cred_user_id_len fido_cred_user_id_ptr fido_cred_user_name fido_cred_verify fido_cred_verify_self fido_cred_x5c_len fido_cred_x5c_ptr fido_dev_build fido_dev_cancel fido_dev_close fido_dev_enable_entattest fido_dev_flags fido_dev_force_fido2 fido_dev_force_pin_change fido_dev_force_u2f fido_dev_free fido_dev_get_assert fido_dev_get_cbor_info fido_dev_get_retry_count fido_dev_get_uv_retry_count fido_dev_get_touch_begin fido_dev_get_touch_status fido_dev_has_pin fido_dev_has_uv fido_dev_info_free fido_dev_info_manifest fido_dev_info_manufacturer_string fido_dev_info_new fido_dev_info_path fido_dev_info_product fido_dev_info_product_string fido_dev_info_ptr fido_dev_info_set fido_dev_info_vendor fido_dev_io_handle fido_dev_is_fido2 fido_dev_is_winhello fido_dev_major fido_dev_make_cred fido_dev_minor fido_dev_new fido_dev_new_with_info fido_dev_open fido_dev_open_with_info fido_dev_protocol fido_dev_reset fido_dev_set_io_functions fido_dev_set_pin fido_dev_set_pin_minlen fido_dev_set_pin_minlen_rpid fido_dev_set_sigmask fido_dev_set_timeout fido_dev_set_transport_functions fido_dev_supports_cred_prot fido_dev_supports_credman fido_dev_supports_permissions fido_dev_supports_pin fido_dev_supports_uv fido_dev_toggle_always_uv fido_dev_largeblob_get fido_dev_largeblob_get_array fido_dev_largeblob_remove fido_dev_largeblob_set fido_dev_largeblob_set_array fido_init fido_set_log_handler fido_strerr rs256_pk_free rs256_pk_from_ptr rs256_pk_from_EVP_PKEY rs256_pk_from_RSA rs256_pk_new rs256_pk_to_EVP_PKEY diff --git a/contrib/libfido2/src/fido.h b/contrib/libfido2/src/fido.h index 607c44fcfd91..914e37762870 100644 --- a/contrib/libfido2/src/fido.h +++ b/contrib/libfido2/src/fido.h @@ -1,274 +1,278 @@ /* * Copyright (c) 2018-2022 Yubico AB. All rights reserved. * SPDX-License-Identifier: BSD-2-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _FIDO_H #define _FIDO_H #include #include #include #include #include #ifdef _FIDO_INTERNAL #include #include #include #include "../openbsd-compat/openbsd-compat.h" #include "blob.h" #include "iso7816.h" #include "extern.h" #endif #include "fido/err.h" #include "fido/param.h" #include "fido/types.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ fido_assert_t *fido_assert_new(void); fido_cred_t *fido_cred_new(void); fido_dev_t *fido_dev_new(void); fido_dev_t *fido_dev_new_with_info(const fido_dev_info_t *); fido_dev_info_t *fido_dev_info_new(size_t); fido_cbor_info_t *fido_cbor_info_new(void); void *fido_dev_io_handle(const fido_dev_t *); void fido_assert_free(fido_assert_t **); void fido_cbor_info_free(fido_cbor_info_t **); void fido_cred_free(fido_cred_t **); void fido_dev_force_fido2(fido_dev_t *); void fido_dev_force_u2f(fido_dev_t *); void fido_dev_free(fido_dev_t **); void fido_dev_info_free(fido_dev_info_t **, size_t); /* fido_init() flags. */ #define FIDO_DEBUG 0x01 #define FIDO_DISABLE_U2F_FALLBACK 0x02 void fido_init(int); void fido_set_log_handler(fido_log_handler_t *); const unsigned char *fido_assert_authdata_ptr(const fido_assert_t *, size_t); +const unsigned char *fido_assert_authdata_raw_ptr(const fido_assert_t *, + size_t); const unsigned char *fido_assert_clientdata_hash_ptr(const fido_assert_t *); const unsigned char *fido_assert_hmac_secret_ptr(const fido_assert_t *, size_t); const unsigned char *fido_assert_id_ptr(const fido_assert_t *, size_t); const unsigned char *fido_assert_largeblob_key_ptr(const fido_assert_t *, size_t); const unsigned char *fido_assert_sig_ptr(const fido_assert_t *, size_t); const unsigned char *fido_assert_user_id_ptr(const fido_assert_t *, size_t); const unsigned char *fido_assert_blob_ptr(const fido_assert_t *, size_t); char **fido_cbor_info_certs_name_ptr(const fido_cbor_info_t *); char **fido_cbor_info_extensions_ptr(const fido_cbor_info_t *); char **fido_cbor_info_options_name_ptr(const fido_cbor_info_t *); char **fido_cbor_info_transports_ptr(const fido_cbor_info_t *); char **fido_cbor_info_versions_ptr(const fido_cbor_info_t *); const bool *fido_cbor_info_options_value_ptr(const fido_cbor_info_t *); const char *fido_assert_rp_id(const fido_assert_t *); const char *fido_assert_user_display_name(const fido_assert_t *, size_t); const char *fido_assert_user_icon(const fido_assert_t *, size_t); const char *fido_assert_user_name(const fido_assert_t *, size_t); const char *fido_cbor_info_algorithm_type(const fido_cbor_info_t *, size_t); const char *fido_cred_display_name(const fido_cred_t *); const char *fido_cred_fmt(const fido_cred_t *); const char *fido_cred_rp_id(const fido_cred_t *); const char *fido_cred_rp_name(const fido_cred_t *); const char *fido_cred_user_name(const fido_cred_t *); const char *fido_dev_info_manufacturer_string(const fido_dev_info_t *); const char *fido_dev_info_path(const fido_dev_info_t *); const char *fido_dev_info_product_string(const fido_dev_info_t *); const fido_dev_info_t *fido_dev_info_ptr(const fido_dev_info_t *, size_t); const uint8_t *fido_cbor_info_protocols_ptr(const fido_cbor_info_t *); const uint64_t *fido_cbor_info_certs_value_ptr(const fido_cbor_info_t *); const unsigned char *fido_cbor_info_aaguid_ptr(const fido_cbor_info_t *); const unsigned char *fido_cred_aaguid_ptr(const fido_cred_t *); const unsigned char *fido_cred_attstmt_ptr(const fido_cred_t *); const unsigned char *fido_cred_authdata_ptr(const fido_cred_t *); const unsigned char *fido_cred_authdata_raw_ptr(const fido_cred_t *); const unsigned char *fido_cred_clientdata_hash_ptr(const fido_cred_t *); const unsigned char *fido_cred_id_ptr(const fido_cred_t *); const unsigned char *fido_cred_largeblob_key_ptr(const fido_cred_t *); const unsigned char *fido_cred_pubkey_ptr(const fido_cred_t *); const unsigned char *fido_cred_sig_ptr(const fido_cred_t *); const unsigned char *fido_cred_user_id_ptr(const fido_cred_t *); const unsigned char *fido_cred_x5c_ptr(const fido_cred_t *); int fido_assert_allow_cred(fido_assert_t *, const unsigned char *, size_t); int fido_assert_empty_allow_list(fido_assert_t *); int fido_assert_set_authdata(fido_assert_t *, size_t, const unsigned char *, size_t); int fido_assert_set_authdata_raw(fido_assert_t *, size_t, const unsigned char *, size_t); int fido_assert_set_clientdata(fido_assert_t *, const unsigned char *, size_t); int fido_assert_set_clientdata_hash(fido_assert_t *, const unsigned char *, size_t); int fido_assert_set_count(fido_assert_t *, size_t); int fido_assert_set_extensions(fido_assert_t *, int); int fido_assert_set_hmac_salt(fido_assert_t *, const unsigned char *, size_t); int fido_assert_set_hmac_secret(fido_assert_t *, size_t, const unsigned char *, size_t); int fido_assert_set_options(fido_assert_t *, bool, bool); int fido_assert_set_rp(fido_assert_t *, const char *); int fido_assert_set_up(fido_assert_t *, fido_opt_t); int fido_assert_set_uv(fido_assert_t *, fido_opt_t); int fido_assert_set_sig(fido_assert_t *, size_t, const unsigned char *, size_t); +int fido_assert_set_winhello_appid(fido_assert_t *, const char *); int fido_assert_verify(const fido_assert_t *, size_t, int, const void *); int fido_cbor_info_algorithm_cose(const fido_cbor_info_t *, size_t); int fido_cred_empty_exclude_list(fido_cred_t *); int fido_cred_exclude(fido_cred_t *, const unsigned char *, size_t); int fido_cred_prot(const fido_cred_t *); int fido_cred_set_attstmt(fido_cred_t *, const unsigned char *, size_t); int fido_cred_set_authdata(fido_cred_t *, const unsigned char *, size_t); int fido_cred_set_authdata_raw(fido_cred_t *, const unsigned char *, size_t); int fido_cred_set_blob(fido_cred_t *, const unsigned char *, size_t); int fido_cred_set_clientdata(fido_cred_t *, const unsigned char *, size_t); int fido_cred_set_clientdata_hash(fido_cred_t *, const unsigned char *, size_t); int fido_cred_set_extensions(fido_cred_t *, int); int fido_cred_set_fmt(fido_cred_t *, const char *); int fido_cred_set_id(fido_cred_t *, const unsigned char *, size_t); int fido_cred_set_options(fido_cred_t *, bool, bool); int fido_cred_set_pin_minlen(fido_cred_t *, size_t); int fido_cred_set_prot(fido_cred_t *, int); int fido_cred_set_rk(fido_cred_t *, fido_opt_t); int fido_cred_set_rp(fido_cred_t *, const char *, const char *); int fido_cred_set_sig(fido_cred_t *, const unsigned char *, size_t); int fido_cred_set_type(fido_cred_t *, int); int fido_cred_set_uv(fido_cred_t *, fido_opt_t); int fido_cred_type(const fido_cred_t *); int fido_cred_set_user(fido_cred_t *, const unsigned char *, size_t, const char *, const char *, const char *); int fido_cred_set_x509(fido_cred_t *, const unsigned char *, size_t); int fido_cred_verify(const fido_cred_t *); int fido_cred_verify_self(const fido_cred_t *); #ifdef _FIDO_SIGSET_DEFINED int fido_dev_set_sigmask(fido_dev_t *, const fido_sigset_t *); #endif int fido_dev_cancel(fido_dev_t *); int fido_dev_close(fido_dev_t *); int fido_dev_get_assert(fido_dev_t *, fido_assert_t *, const char *); int fido_dev_get_cbor_info(fido_dev_t *, fido_cbor_info_t *); int fido_dev_get_retry_count(fido_dev_t *, int *); int fido_dev_get_uv_retry_count(fido_dev_t *, int *); int fido_dev_get_touch_begin(fido_dev_t *); int fido_dev_get_touch_status(fido_dev_t *, int *, int); int fido_dev_info_manifest(fido_dev_info_t *, size_t, size_t *); int fido_dev_info_set(fido_dev_info_t *, size_t, const char *, const char *, const char *, const fido_dev_io_t *, const fido_dev_transport_t *); int fido_dev_make_cred(fido_dev_t *, fido_cred_t *, const char *); int fido_dev_open_with_info(fido_dev_t *); int fido_dev_open(fido_dev_t *, const char *); int fido_dev_reset(fido_dev_t *); int fido_dev_set_io_functions(fido_dev_t *, const fido_dev_io_t *); int fido_dev_set_pin(fido_dev_t *, const char *, const char *); int fido_dev_set_transport_functions(fido_dev_t *, const fido_dev_transport_t *); int fido_dev_set_timeout(fido_dev_t *, int); size_t fido_assert_authdata_len(const fido_assert_t *, size_t); +size_t fido_assert_authdata_raw_len(const fido_assert_t *, size_t); size_t fido_assert_clientdata_hash_len(const fido_assert_t *); size_t fido_assert_count(const fido_assert_t *); size_t fido_assert_hmac_secret_len(const fido_assert_t *, size_t); size_t fido_assert_id_len(const fido_assert_t *, size_t); size_t fido_assert_largeblob_key_len(const fido_assert_t *, size_t); size_t fido_assert_sig_len(const fido_assert_t *, size_t); size_t fido_assert_user_id_len(const fido_assert_t *, size_t); size_t fido_assert_blob_len(const fido_assert_t *, size_t); size_t fido_cbor_info_aaguid_len(const fido_cbor_info_t *); size_t fido_cbor_info_algorithm_count(const fido_cbor_info_t *); size_t fido_cbor_info_certs_len(const fido_cbor_info_t *); size_t fido_cbor_info_extensions_len(const fido_cbor_info_t *); size_t fido_cbor_info_options_len(const fido_cbor_info_t *); size_t fido_cbor_info_protocols_len(const fido_cbor_info_t *); size_t fido_cbor_info_transports_len(const fido_cbor_info_t *); size_t fido_cbor_info_versions_len(const fido_cbor_info_t *); size_t fido_cred_aaguid_len(const fido_cred_t *); size_t fido_cred_attstmt_len(const fido_cred_t *); size_t fido_cred_authdata_len(const fido_cred_t *); size_t fido_cred_authdata_raw_len(const fido_cred_t *); size_t fido_cred_clientdata_hash_len(const fido_cred_t *); size_t fido_cred_id_len(const fido_cred_t *); size_t fido_cred_largeblob_key_len(const fido_cred_t *); size_t fido_cred_pin_minlen(const fido_cred_t *); size_t fido_cred_pubkey_len(const fido_cred_t *); size_t fido_cred_sig_len(const fido_cred_t *); size_t fido_cred_user_id_len(const fido_cred_t *); size_t fido_cred_x5c_len(const fido_cred_t *); uint8_t fido_assert_flags(const fido_assert_t *, size_t); uint32_t fido_assert_sigcount(const fido_assert_t *, size_t); uint8_t fido_cred_flags(const fido_cred_t *); uint32_t fido_cred_sigcount(const fido_cred_t *); uint8_t fido_dev_protocol(const fido_dev_t *); uint8_t fido_dev_major(const fido_dev_t *); uint8_t fido_dev_minor(const fido_dev_t *); uint8_t fido_dev_build(const fido_dev_t *); uint8_t fido_dev_flags(const fido_dev_t *); int16_t fido_dev_info_vendor(const fido_dev_info_t *); int16_t fido_dev_info_product(const fido_dev_info_t *); uint64_t fido_cbor_info_fwversion(const fido_cbor_info_t *); uint64_t fido_cbor_info_maxcredbloblen(const fido_cbor_info_t *); uint64_t fido_cbor_info_maxcredcntlst(const fido_cbor_info_t *); uint64_t fido_cbor_info_maxcredidlen(const fido_cbor_info_t *); uint64_t fido_cbor_info_maxlargeblob(const fido_cbor_info_t *); uint64_t fido_cbor_info_maxmsgsiz(const fido_cbor_info_t *); uint64_t fido_cbor_info_maxrpid_minpinlen(const fido_cbor_info_t *); uint64_t fido_cbor_info_minpinlen(const fido_cbor_info_t *); uint64_t fido_cbor_info_uv_attempts(const fido_cbor_info_t *); uint64_t fido_cbor_info_uv_modality(const fido_cbor_info_t *); int64_t fido_cbor_info_rk_remaining(const fido_cbor_info_t *); bool fido_dev_has_pin(const fido_dev_t *); bool fido_dev_has_uv(const fido_dev_t *); bool fido_dev_is_fido2(const fido_dev_t *); bool fido_dev_is_winhello(const fido_dev_t *); bool fido_dev_supports_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 *); bool fido_cbor_info_new_pin_required(const fido_cbor_info_t *); int fido_dev_largeblob_get(fido_dev_t *, const unsigned char *, size_t, unsigned char **, size_t *); int fido_dev_largeblob_set(fido_dev_t *, const unsigned char *, size_t, const unsigned char *, size_t, const char *); int fido_dev_largeblob_remove(fido_dev_t *, const unsigned char *, size_t, const char *); int fido_dev_largeblob_get_array(fido_dev_t *, unsigned char **, size_t *); int fido_dev_largeblob_set_array(fido_dev_t *, const unsigned char *, size_t, const char *); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* !_FIDO_H */ diff --git a/contrib/libfido2/src/fido/types.h b/contrib/libfido2/src/fido/types.h index cfb4c7a75315..01d68200c19c 100644 --- a/contrib/libfido2/src/fido/types.h +++ b/contrib/libfido2/src/fido/types.h @@ -1,335 +1,337 @@ /* * Copyright (c) 2018-2022 Yubico AB. All rights reserved. * SPDX-License-Identifier: BSD-2-Clause * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _FIDO_TYPES_H #define _FIDO_TYPES_H #ifdef __MINGW32__ #include #endif #include #include #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct fido_dev; typedef void *fido_dev_io_open_t(const char *); typedef void fido_dev_io_close_t(void *); typedef int fido_dev_io_read_t(void *, unsigned char *, size_t, int); typedef int fido_dev_io_write_t(void *, const unsigned char *, size_t); typedef int fido_dev_rx_t(struct fido_dev *, uint8_t, unsigned char *, size_t, int); typedef int fido_dev_tx_t(struct fido_dev *, uint8_t, const unsigned char *, size_t); typedef struct fido_dev_io { fido_dev_io_open_t *open; fido_dev_io_close_t *close; fido_dev_io_read_t *read; fido_dev_io_write_t *write; } fido_dev_io_t; typedef struct fido_dev_transport { fido_dev_rx_t *rx; fido_dev_tx_t *tx; } fido_dev_transport_t; typedef enum { FIDO_OPT_OMIT = 0, /* use authenticator's default */ FIDO_OPT_FALSE, /* explicitly set option to false */ FIDO_OPT_TRUE, /* explicitly set option to true */ } fido_opt_t; typedef void fido_log_handler_t(const char *); #undef _FIDO_SIGSET_DEFINED #define _FIDO_SIGSET_DEFINED #ifdef _WIN32 typedef int fido_sigset_t; #elif defined(SIG_BLOCK) typedef sigset_t fido_sigset_t; #else #undef _FIDO_SIGSET_DEFINED #endif #ifdef _FIDO_INTERNAL #include "packed.h" #include "blob.h" /* COSE ES256 (ECDSA over P-256 with SHA-256) public key */ typedef struct es256_pk { unsigned char x[32]; unsigned char y[32]; } es256_pk_t; /* COSE ES256 (ECDSA over P-256 with SHA-256) (secret) key */ typedef struct es256_sk { unsigned char d[32]; } es256_sk_t; /* COSE ES384 (ECDSA over P-384 with SHA-384) public key */ typedef struct es384_pk { unsigned char x[48]; unsigned char y[48]; } es384_pk_t; /* COSE RS256 (2048-bit RSA with PKCS1 padding and SHA-256) public key */ typedef struct rs256_pk { unsigned char n[256]; unsigned char e[3]; } rs256_pk_t; /* COSE EDDSA (ED25519) */ typedef struct eddsa_pk { unsigned char x[32]; } eddsa_pk_t; PACKED_TYPE(fido_authdata_t, struct fido_authdata { unsigned char rp_id_hash[32]; /* sha256 of fido_rp.id */ uint8_t flags; /* user present/verified */ uint32_t sigcount; /* signature counter */ /* actually longer */ }) PACKED_TYPE(fido_attcred_raw_t, struct fido_attcred_raw { unsigned char aaguid[16]; /* credential's aaguid */ uint16_t id_len; /* credential id length */ uint8_t body[]; /* credential id + pubkey */ }) typedef struct fido_attcred { unsigned char aaguid[16]; /* credential's aaguid */ fido_blob_t id; /* credential id */ int type; /* credential's cose algorithm */ union { /* credential's public key */ es256_pk_t es256; es384_pk_t es384; rs256_pk_t rs256; eddsa_pk_t eddsa; } pubkey; } fido_attcred_t; typedef struct fido_attstmt { fido_blob_t certinfo; /* tpm attestation TPMS_ATTEST structure */ fido_blob_t pubarea; /* tpm attestation TPMT_PUBLIC structure */ fido_blob_t cbor; /* cbor-encoded attestation statement */ fido_blob_t x5c; /* attestation certificate */ fido_blob_t sig; /* attestation signature */ int alg; /* attestation algorithm (cose) */ } fido_attstmt_t; typedef struct fido_rp { char *id; /* relying party id */ char *name; /* relying party name */ } fido_rp_t; typedef struct fido_user { fido_blob_t id; /* required */ char *icon; /* optional */ char *name; /* optional */ char *display_name; /* required */ } fido_user_t; typedef struct fido_cred_ext { int mask; /* enabled extensions */ int prot; /* protection policy */ size_t minpinlen; /* minimum pin length */ } fido_cred_ext_t; typedef struct fido_cred { fido_blob_t cd; /* client data */ fido_blob_t cdh; /* client data hash */ fido_rp_t rp; /* relying party */ fido_user_t user; /* user entity */ fido_blob_array_t excl; /* list of credential ids to exclude */ fido_opt_t rk; /* resident key */ fido_opt_t uv; /* user verification */ fido_cred_ext_t ext; /* extensions */ int type; /* cose algorithm */ char *fmt; /* credential format */ fido_cred_ext_t authdata_ext; /* decoded extensions */ fido_blob_t authdata_cbor; /* cbor-encoded payload */ fido_blob_t authdata_raw; /* cbor-decoded payload */ fido_authdata_t authdata; /* decoded authdata payload */ fido_attcred_t attcred; /* returned credential (key + id) */ fido_attstmt_t attstmt; /* attestation statement (x509 + sig) */ fido_blob_t largeblob_key; /* decoded large blob key */ fido_blob_t blob; /* 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 CTAP 2.1 credBlob */ } fido_assert_extattr_t; typedef struct _fido_assert_stmt { fido_blob_t id; /* credential id */ fido_user_t user; /* user attributes */ fido_blob_t hmac_secret; /* hmac secret */ fido_assert_extattr_t authdata_ext; /* decoded extensions */ fido_blob_t authdata_cbor; /* raw cbor payload */ + fido_blob_t authdata_raw; /* raw authdata */ fido_authdata_t authdata; /* decoded authdata payload */ fido_blob_t sig; /* signature of cdh + authdata */ fido_blob_t largeblob_key; /* decoded large blob key */ } fido_assert_stmt; typedef struct fido_assert_ext { int mask; /* enabled extensions */ fido_blob_t hmac_salt; /* optional hmac-secret salt */ } fido_assert_ext_t; typedef struct fido_assert { char *rp_id; /* relying party id */ + char *appid; /* winhello u2f appid */ fido_blob_t cd; /* client data */ fido_blob_t cdh; /* client data hash */ fido_blob_array_t allow_list; /* list of allowed credentials */ fido_opt_t up; /* user presence */ fido_opt_t uv; /* user verification */ fido_assert_ext_t ext; /* enabled extensions */ fido_assert_stmt *stmt; /* array of expected assertions */ size_t stmt_cnt; /* number of allocated assertions */ size_t stmt_len; /* number of received assertions */ } fido_assert_t; typedef struct fido_opt_array { char **name; bool *value; size_t len; } fido_opt_array_t; typedef struct fido_str_array { char **ptr; size_t len; } fido_str_array_t; typedef struct fido_byte_array { uint8_t *ptr; size_t len; } fido_byte_array_t; typedef struct fido_algo { char *type; int cose; } fido_algo_t; typedef struct fido_algo_array { fido_algo_t *ptr; size_t len; } fido_algo_array_t; typedef struct fido_cert_array { char **name; uint64_t *value; size_t len; } fido_cert_array_t; typedef struct fido_cbor_info { fido_str_array_t versions; /* supported versions: fido2|u2f */ fido_str_array_t extensions; /* list of supported extensions */ fido_str_array_t transports; /* list of supported transports */ unsigned char aaguid[16]; /* aaguid */ fido_opt_array_t options; /* list of supported options */ uint64_t maxmsgsiz; /* maximum message size */ fido_byte_array_t protocols; /* supported pin protocols */ fido_algo_array_t algorithms; /* list of supported algorithms */ uint64_t maxcredcntlst; /* max credentials in list */ uint64_t maxcredidlen; /* max credential ID length */ uint64_t fwversion; /* firmware version */ uint64_t maxcredbloblen; /* max credBlob length */ uint64_t maxlargeblob; /* max largeBlob array length */ uint64_t maxrpid_minlen; /* max rpid in set_pin_minlen_rpid */ uint64_t minpinlen; /* min pin len enforced */ uint64_t uv_attempts; /* platform uv attempts */ uint64_t uv_modality; /* bitmask of supported uv types */ int64_t rk_remaining; /* remaining resident credentials */ bool new_pin_reqd; /* new pin required */ fido_cert_array_t certs; /* associated certifications */ } fido_cbor_info_t; typedef struct fido_dev_info { char *path; /* device path */ int16_t vendor_id; /* 2-byte vendor id */ int16_t product_id; /* 2-byte product id */ char *manufacturer; /* manufacturer string */ char *product; /* product string */ fido_dev_io_t io; /* i/o functions */ fido_dev_transport_t transport; /* transport functions */ } fido_dev_info_t; PACKED_TYPE(fido_ctap_info_t, /* defined in section 8.1.9.1.3 (CTAPHID_INIT) of the fido2 ctap spec */ struct fido_ctap_info { uint64_t nonce; /* echoed nonce */ uint32_t cid; /* channel id */ uint8_t protocol; /* ctaphid protocol id */ uint8_t major; /* major version number */ uint8_t minor; /* minor version number */ uint8_t build; /* build version number */ uint8_t flags; /* capabilities flags; see FIDO_CAP_* */ }) typedef struct fido_dev { uint64_t nonce; /* issued nonce */ fido_ctap_info_t attr; /* device attributes */ uint32_t cid; /* assigned channel id */ char *path; /* device path */ void *io_handle; /* abstract i/o handle */ fido_dev_io_t io; /* i/o functions */ bool io_own; /* device has own io/transport */ size_t rx_len; /* length of HID input reports */ size_t tx_len; /* length of HID output reports */ int flags; /* internal flags; see FIDO_DEV_* */ fido_dev_transport_t transport; /* transport functions */ uint64_t maxmsgsize; /* max message size */ int timeout_ms; /* read timeout in ms */ } fido_dev_t; #else typedef struct fido_assert fido_assert_t; typedef struct fido_cbor_info fido_cbor_info_t; typedef struct fido_cred fido_cred_t; typedef struct fido_dev fido_dev_t; typedef struct fido_dev_info fido_dev_info_t; typedef struct es256_pk es256_pk_t; typedef struct es256_sk es256_sk_t; typedef struct es384_pk es384_pk_t; typedef struct rs256_pk rs256_pk_t; typedef struct eddsa_pk eddsa_pk_t; #endif /* _FIDO_INTERNAL */ #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* !_FIDO_TYPES_H */ diff --git a/contrib/libfido2/src/webauthn.h b/contrib/libfido2/src/webauthn.h index e64236a0f6fe..153609b10d29 100644 --- a/contrib/libfido2/src/webauthn.h +++ b/contrib/libfido2/src/webauthn.h @@ -1,990 +1,1149 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #ifndef __WEBAUTHN_H_ #define __WEBAUTHN_H_ #pragma once #include #ifdef _MSC_VER #pragma region Desktop Family or OneCore Family #endif #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM) #ifdef __cplusplus extern "C" { #endif #ifndef WINAPI #define WINAPI __stdcall #endif #ifndef INITGUID #define INITGUID #include #undef INITGUID #else #include #endif //+------------------------------------------------------------------------------------------ // API Version Information. // Caller should check for WebAuthNGetApiVersionNumber to check the presence of relevant APIs // and features for their usage. //------------------------------------------------------------------------------------------- #define WEBAUTHN_API_VERSION_1 1 // WEBAUTHN_API_VERSION_1 : Baseline Version // Data Structures and their sub versions: // - WEBAUTHN_RP_ENTITY_INFORMATION : 1 // - WEBAUTHN_USER_ENTITY_INFORMATION : 1 // - WEBAUTHN_CLIENT_DATA : 1 // - WEBAUTHN_COSE_CREDENTIAL_PARAMETER : 1 // - WEBAUTHN_COSE_CREDENTIAL_PARAMETERS : Not Applicable // - WEBAUTHN_CREDENTIAL : 1 // - WEBAUTHN_CREDENTIALS : Not Applicable // - WEBAUTHN_CREDENTIAL_EX : 1 // - WEBAUTHN_CREDENTIAL_LIST : Not Applicable // - WEBAUTHN_EXTENSION : Not Applicable // - WEBAUTHN_EXTENSIONS : Not Applicable // - WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS : 3 // - WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS : 4 // - WEBAUTHN_COMMON_ATTESTATION : 1 // - WEBAUTHN_CREDENTIAL_ATTESTATION : 3 // - WEBAUTHN_ASSERTION : 1 // Extensions: // - WEBAUTHN_EXTENSIONS_IDENTIFIER_HMAC_SECRET // APIs: // - WebAuthNGetApiVersionNumber // - WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable // - WebAuthNAuthenticatorMakeCredential // - WebAuthNAuthenticatorGetAssertion // - WebAuthNFreeCredentialAttestation // - WebAuthNFreeAssertion // - WebAuthNGetCancellationId // - WebAuthNCancelCurrentOperation // - WebAuthNGetErrorName // - WebAuthNGetW3CExceptionDOMError +// Transports: +// - WEBAUTHN_CTAP_TRANSPORT_USB +// - WEBAUTHN_CTAP_TRANSPORT_NFC +// - WEBAUTHN_CTAP_TRANSPORT_BLE +// - WEBAUTHN_CTAP_TRANSPORT_INTERNAL #define WEBAUTHN_API_VERSION_2 2 // WEBAUTHN_API_VERSION_2 : Delta From WEBAUTHN_API_VERSION_1 // Added Extensions: // - WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT // #define WEBAUTHN_API_VERSION_3 3 // WEBAUTHN_API_VERSION_3 : Delta From WEBAUTHN_API_VERSION_2 // Data Structures and their sub versions: // - WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS : 4 // - WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS : 5 // - WEBAUTHN_CREDENTIAL_ATTESTATION : 4 // - WEBAUTHN_ASSERTION : 2 // Added Extensions: // - WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_BLOB // - WEBAUTHN_EXTENSIONS_IDENTIFIER_MIN_PIN_LENGTH // #define WEBAUTHN_API_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 +// - WEBAUTHN_CREDENTIAL_DETAILS : 1 // APIs: // - WebAuthNGetPlatformCredentialList // - WebAuthNFreePlatformCredentialList +// - WebAuthNDeletePlatformCredential // -#define WEBAUTHN_API_CURRENT_VERSION WEBAUTHN_API_VERSION_4 +#define WEBAUTHN_API_VERSION_5 5 +// WEBAUTHN_API_VERSION_5 : Delta From WEBAUTHN_API_VERSION_4 +// Data Structures and their sub versions: +// - WEBAUTHN_CREDENTIAL_DETAILS : 2 +// Extension Changes: +// - Enabled LARGE_BLOB Support +// + +#define WEBAUTHN_API_VERSION_6 6 +// WEBAUTHN_API_VERSION_6 : Delta From WEBAUTHN_API_VERSION_5 +// Data Structures and their sub versions: +// - WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS : 6 +// - WEBAUTHN_CREDENTIAL_ATTESTATION : 5 +// - WEBAUTHN_ASSERTION : 4 +// Transports: +// - WEBAUTHN_CTAP_TRANSPORT_HYBRID + +#define WEBAUTHN_API_VERSION_7 7 +// WEBAUTHN_API_VERSION_7 : Delta From WEBAUTHN_API_VERSION_6 +// Data Structures and their sub versions: +// - WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS : 7 +// - WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS : 7 +// - WEBAUTHN_CREDENTIAL_ATTESTATION : 6 +// - WEBAUTHN_ASSERTION : 5 + +#define WEBAUTHN_API_CURRENT_VERSION WEBAUTHN_API_VERSION_7 //+------------------------------------------------------------------------------------------ // Information about an RP Entity //------------------------------------------------------------------------------------------- #define WEBAUTHN_RP_ENTITY_INFORMATION_CURRENT_VERSION 1 typedef struct _WEBAUTHN_RP_ENTITY_INFORMATION { // Version of this structure, to allow for modifications in the future. // This field is required and should be set to CURRENT_VERSION above. DWORD dwVersion; // Identifier for the RP. This field is required. PCWSTR pwszId; // Contains the friendly name of the Relying Party, such as "Acme Corporation", "Widgets Inc" or "Awesome Site". // This field is required. PCWSTR pwszName; // Optional URL pointing to RP's logo. PCWSTR pwszIcon; } WEBAUTHN_RP_ENTITY_INFORMATION, *PWEBAUTHN_RP_ENTITY_INFORMATION; typedef const WEBAUTHN_RP_ENTITY_INFORMATION *PCWEBAUTHN_RP_ENTITY_INFORMATION; //+------------------------------------------------------------------------------------------ // Information about an User Entity //------------------------------------------------------------------------------------------- #define WEBAUTHN_MAX_USER_ID_LENGTH 64 #define WEBAUTHN_USER_ENTITY_INFORMATION_CURRENT_VERSION 1 typedef struct _WEBAUTHN_USER_ENTITY_INFORMATION { // Version of this structure, to allow for modifications in the future. // This field is required and should be set to CURRENT_VERSION above. DWORD dwVersion; // Identifier for the User. This field is required. DWORD cbId; _Field_size_bytes_(cbId) PBYTE pbId; // Contains a detailed name for this account, such as "john.p.smith@example.com". PCWSTR pwszName; // Optional URL that can be used to retrieve an image containing the user's current avatar, // or a data URI that contains the image data. PCWSTR pwszIcon; // For User: Contains the friendly name associated with the user account by the Relying Party, such as "John P. Smith". PCWSTR pwszDisplayName; } WEBAUTHN_USER_ENTITY_INFORMATION, *PWEBAUTHN_USER_ENTITY_INFORMATION; typedef const WEBAUTHN_USER_ENTITY_INFORMATION *PCWEBAUTHN_USER_ENTITY_INFORMATION; //+------------------------------------------------------------------------------------------ // Information about client data. //------------------------------------------------------------------------------------------- #define WEBAUTHN_HASH_ALGORITHM_SHA_256 L"SHA-256" #define WEBAUTHN_HASH_ALGORITHM_SHA_384 L"SHA-384" #define WEBAUTHN_HASH_ALGORITHM_SHA_512 L"SHA-512" #define WEBAUTHN_CLIENT_DATA_CURRENT_VERSION 1 typedef struct _WEBAUTHN_CLIENT_DATA { // Version of this structure, to allow for modifications in the future. // This field is required and should be set to CURRENT_VERSION above. DWORD dwVersion; // Size of the pbClientDataJSON field. DWORD cbClientDataJSON; // UTF-8 encoded JSON serialization of the client data. _Field_size_bytes_(cbClientDataJSON) PBYTE pbClientDataJSON; // Hash algorithm ID used to hash the pbClientDataJSON field. LPCWSTR pwszHashAlgId; } WEBAUTHN_CLIENT_DATA, *PWEBAUTHN_CLIENT_DATA; typedef const WEBAUTHN_CLIENT_DATA *PCWEBAUTHN_CLIENT_DATA; //+------------------------------------------------------------------------------------------ // Information about credential parameters. //------------------------------------------------------------------------------------------- #define WEBAUTHN_CREDENTIAL_TYPE_PUBLIC_KEY L"public-key" #define WEBAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256 -7 #define WEBAUTHN_COSE_ALGORITHM_ECDSA_P384_WITH_SHA384 -35 #define WEBAUTHN_COSE_ALGORITHM_ECDSA_P521_WITH_SHA512 -36 #define WEBAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA256 -257 #define WEBAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA384 -258 #define WEBAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA512 -259 #define WEBAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA256 -37 #define WEBAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA384 -38 #define WEBAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA512 -39 #define WEBAUTHN_COSE_CREDENTIAL_PARAMETER_CURRENT_VERSION 1 typedef struct _WEBAUTHN_COSE_CREDENTIAL_PARAMETER { // Version of this structure, to allow for modifications in the future. DWORD dwVersion; // Well-known credential type specifying a credential to create. LPCWSTR pwszCredentialType; // Well-known COSE algorithm specifying the algorithm to use for the credential. LONG lAlg; } WEBAUTHN_COSE_CREDENTIAL_PARAMETER, *PWEBAUTHN_COSE_CREDENTIAL_PARAMETER; typedef const WEBAUTHN_COSE_CREDENTIAL_PARAMETER *PCWEBAUTHN_COSE_CREDENTIAL_PARAMETER; typedef struct _WEBAUTHN_COSE_CREDENTIAL_PARAMETERS { DWORD cCredentialParameters; _Field_size_(cCredentialParameters) PWEBAUTHN_COSE_CREDENTIAL_PARAMETER pCredentialParameters; } WEBAUTHN_COSE_CREDENTIAL_PARAMETERS, *PWEBAUTHN_COSE_CREDENTIAL_PARAMETERS; typedef const WEBAUTHN_COSE_CREDENTIAL_PARAMETERS *PCWEBAUTHN_COSE_CREDENTIAL_PARAMETERS; //+------------------------------------------------------------------------------------------ // Information about credential. //------------------------------------------------------------------------------------------- #define WEBAUTHN_CREDENTIAL_CURRENT_VERSION 1 typedef struct _WEBAUTHN_CREDENTIAL { // Version of this structure, to allow for modifications in the future. DWORD dwVersion; // Size of pbID. DWORD cbId; // Unique ID for this particular credential. _Field_size_bytes_(cbId) PBYTE pbId; // Well-known credential type specifying what this particular credential is. LPCWSTR pwszCredentialType; } WEBAUTHN_CREDENTIAL, *PWEBAUTHN_CREDENTIAL; typedef const WEBAUTHN_CREDENTIAL *PCWEBAUTHN_CREDENTIAL; typedef struct _WEBAUTHN_CREDENTIALS { DWORD cCredentials; _Field_size_(cCredentials) PWEBAUTHN_CREDENTIAL pCredentials; } WEBAUTHN_CREDENTIALS, *PWEBAUTHN_CREDENTIALS; typedef const WEBAUTHN_CREDENTIALS *PCWEBAUTHN_CREDENTIALS; //+------------------------------------------------------------------------------------------ // Information about credential with extra information, such as, dwTransports //------------------------------------------------------------------------------------------- #define WEBAUTHN_CTAP_TRANSPORT_USB 0x00000001 #define WEBAUTHN_CTAP_TRANSPORT_NFC 0x00000002 #define WEBAUTHN_CTAP_TRANSPORT_BLE 0x00000004 #define WEBAUTHN_CTAP_TRANSPORT_TEST 0x00000008 #define WEBAUTHN_CTAP_TRANSPORT_INTERNAL 0x00000010 -#define WEBAUTHN_CTAP_TRANSPORT_FLAGS_MASK 0x0000001F +#define WEBAUTHN_CTAP_TRANSPORT_HYBRID 0x00000020 +#define WEBAUTHN_CTAP_TRANSPORT_FLAGS_MASK 0x0000003F #define WEBAUTHN_CREDENTIAL_EX_CURRENT_VERSION 1 typedef struct _WEBAUTHN_CREDENTIAL_EX { // Version of this structure, to allow for modifications in the future. DWORD dwVersion; // Size of pbID. DWORD cbId; // Unique ID for this particular credential. _Field_size_bytes_(cbId) PBYTE pbId; // Well-known credential type specifying what this particular credential is. LPCWSTR pwszCredentialType; // Transports. 0 implies no transport restrictions. DWORD dwTransports; } WEBAUTHN_CREDENTIAL_EX, *PWEBAUTHN_CREDENTIAL_EX; typedef const WEBAUTHN_CREDENTIAL_EX *PCWEBAUTHN_CREDENTIAL_EX; //+------------------------------------------------------------------------------------------ // Information about credential list with extra information //------------------------------------------------------------------------------------------- typedef struct _WEBAUTHN_CREDENTIAL_LIST { DWORD cCredentials; _Field_size_(cCredentials) PWEBAUTHN_CREDENTIAL_EX *ppCredentials; } WEBAUTHN_CREDENTIAL_LIST, *PWEBAUTHN_CREDENTIAL_LIST; typedef const WEBAUTHN_CREDENTIAL_LIST *PCWEBAUTHN_CREDENTIAL_LIST; +//+------------------------------------------------------------------------------------------ +// Information about linked devices +//------------------------------------------------------------------------------------------- + +#define CTAPCBOR_HYBRID_STORAGE_LINKED_DATA_VERSION_1 1 +#define CTAPCBOR_HYBRID_STORAGE_LINKED_DATA_CURRENT_VERSION CTAPCBOR_HYBRID_STORAGE_LINKED_DATA_VERSION_1 + +typedef struct _CTAPCBOR_HYBRID_STORAGE_LINKED_DATA +{ + // Version + DWORD dwVersion; + + // Contact Id + DWORD cbContactId; + _Field_size_bytes_(cbContactId) + PBYTE pbContactId; + + // Link Id + DWORD cbLinkId; + _Field_size_bytes_(cbLinkId) + PBYTE pbLinkId; + + // Link secret + DWORD cbLinkSecret; + _Field_size_bytes_(cbLinkSecret) + PBYTE pbLinkSecret; + + // Authenticator Public Key + DWORD cbPublicKey; + _Field_size_bytes_(cbPublicKey) + PBYTE pbPublicKey; + + // Authenticator Name + PCWSTR pwszAuthenticatorName; + + // Tunnel server domain + WORD wEncodedTunnelServerDomain; +} CTAPCBOR_HYBRID_STORAGE_LINKED_DATA, *PCTAPCBOR_HYBRID_STORAGE_LINKED_DATA; +typedef const CTAPCBOR_HYBRID_STORAGE_LINKED_DATA *PCCTAPCBOR_HYBRID_STORAGE_LINKED_DATA; + //+------------------------------------------------------------------------------------------ // Credential Information for WebAuthNGetPlatformCredentialList API //------------------------------------------------------------------------------------------- #define WEBAUTHN_CREDENTIAL_DETAILS_VERSION_1 1 -#define WEBAUTHN_CREDENTIAL_DETAILS_CURRENT_VERSION WEBAUTHN_CREDENTIAL_DETAILS_VERSION_1 +#define WEBAUTHN_CREDENTIAL_DETAILS_VERSION_2 2 +#define WEBAUTHN_CREDENTIAL_DETAILS_CURRENT_VERSION WEBAUTHN_CREDENTIAL_DETAILS_VERSION_2 typedef struct _WEBAUTHN_CREDENTIAL_DETAILS { // Version of this structure, to allow for modifications in the future. DWORD dwVersion; // Size of pbCredentialID. DWORD cbCredentialID; _Field_size_bytes_(cbCredentialID) PBYTE pbCredentialID; // RP Info PWEBAUTHN_RP_ENTITY_INFORMATION pRpInformation; // User Info PWEBAUTHN_USER_ENTITY_INFORMATION pUserInformation; + + // Removable or not. + BOOL bRemovable; + + // + // The following fields have been added in WEBAUTHN_CREDENTIAL_DETAILS_VERSION_2 + // + + // Backed Up or not. + BOOL bBackedUp; } WEBAUTHN_CREDENTIAL_DETAILS, *PWEBAUTHN_CREDENTIAL_DETAILS; typedef const WEBAUTHN_CREDENTIAL_DETAILS *PCWEBAUTHN_CREDENTIAL_DETAILS; typedef struct _WEBAUTHN_CREDENTIAL_DETAILS_LIST { DWORD cCredentialDetails; _Field_size_(cCredentialDetails) PWEBAUTHN_CREDENTIAL_DETAILS *ppCredentialDetails; } WEBAUTHN_CREDENTIAL_DETAILS_LIST, *PWEBAUTHN_CREDENTIAL_DETAILS_LIST; typedef const WEBAUTHN_CREDENTIAL_DETAILS_LIST *PCWEBAUTHN_CREDENTIAL_DETAILS_LIST; #define WEBAUTHN_GET_CREDENTIALS_OPTIONS_VERSION_1 1 #define WEBAUTHN_GET_CREDENTIALS_OPTIONS_CURRENT_VERSION WEBAUTHN_GET_CREDENTIALS_OPTIONS_VERSION_1 typedef struct _WEBAUTHN_GET_CREDENTIALS_OPTIONS { // Version of this structure, to allow for modifications in the future. DWORD dwVersion; - // RPID + // Optional. LPCWSTR pwszRpId; // Optional. BrowserInPrivate Mode. Defaulting to FALSE. BOOL bBrowserInPrivateMode; } WEBAUTHN_GET_CREDENTIALS_OPTIONS, *PWEBAUTHN_GET_CREDENTIALS_OPTIONS; typedef const WEBAUTHN_GET_CREDENTIALS_OPTIONS *PCWEBAUTHN_GET_CREDENTIALS_OPTIONS; //+------------------------------------------------------------------------------------------ // PRF values. //------------------------------------------------------------------------------------------- #define WEBAUTHN_CTAP_ONE_HMAC_SECRET_LENGTH 32 // SALT values below by default are converted into RAW Hmac-Secret values as per PRF extension. // - SHA-256(UTF8Encode("WebAuthn PRF") || 0x00 || Value) // -// Set WEBAUTHN_CTAP_HMAC_SECRET_VALUES_FLAG in dwFlags in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS, +// Set WEBAUTHN_AUTHENTICATOR_HMAC_SECRET_VALUES_FLAG in dwFlags in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS, // if caller wants to provide RAW Hmac-Secret SALT values directly. In that case, // values if provided MUST be of WEBAUTHN_CTAP_ONE_HMAC_SECRET_LENGTH size. typedef struct _WEBAUTHN_HMAC_SECRET_SALT { // Size of pbFirst. DWORD cbFirst; _Field_size_bytes_(cbFirst) PBYTE pbFirst; // Required // Size of pbSecond. DWORD cbSecond; _Field_size_bytes_(cbSecond) PBYTE pbSecond; } WEBAUTHN_HMAC_SECRET_SALT, *PWEBAUTHN_HMAC_SECRET_SALT; typedef const WEBAUTHN_HMAC_SECRET_SALT *PCWEBAUTHN_HMAC_SECRET_SALT; typedef struct _WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT { // Size of pbCredID. DWORD cbCredID; _Field_size_bytes_(cbCredID) PBYTE pbCredID; // Required // PRF Values for above credential PWEBAUTHN_HMAC_SECRET_SALT pHmacSecretSalt; // Required } WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT, *PWEBAUTHN_CRED_WITH_HMAC_SECRET_SALT; typedef const WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT *PCWEBAUTHN_CRED_WITH_HMAC_SECRET_SALT; typedef struct _WEBAUTHN_HMAC_SECRET_SALT_VALUES { PWEBAUTHN_HMAC_SECRET_SALT pGlobalHmacSalt; DWORD cCredWithHmacSecretSaltList; _Field_size_(cCredWithHmacSecretSaltList) PWEBAUTHN_CRED_WITH_HMAC_SECRET_SALT pCredWithHmacSecretSaltList; } WEBAUTHN_HMAC_SECRET_SALT_VALUES, *PWEBAUTHN_HMAC_SECRET_SALT_VALUES; typedef const WEBAUTHN_HMAC_SECRET_SALT_VALUES *PCWEBAUTHN_HMAC_SECRET_SALT_VALUES; //+------------------------------------------------------------------------------------------ // Hmac-Secret extension //------------------------------------------------------------------------------------------- #define WEBAUTHN_EXTENSIONS_IDENTIFIER_HMAC_SECRET L"hmac-secret" // Below type definitions is for WEBAUTHN_EXTENSIONS_IDENTIFIER_HMAC_SECRET // MakeCredential Input Type: BOOL. // - pvExtension must point to a BOOL with the value TRUE. // - cbExtension must contain the sizeof(BOOL). // MakeCredential Output Type: BOOL. // - pvExtension will point to a BOOL with the value TRUE if credential // was successfully created with HMAC_SECRET. // - cbExtension will contain the sizeof(BOOL). // GetAssertion Input Type: Not Supported // GetAssertion Output Type: Not Supported //+------------------------------------------------------------------------------------------ // credProtect extension //------------------------------------------------------------------------------------------- #define WEBAUTHN_USER_VERIFICATION_ANY 0 #define WEBAUTHN_USER_VERIFICATION_OPTIONAL 1 #define WEBAUTHN_USER_VERIFICATION_OPTIONAL_WITH_CREDENTIAL_ID_LIST 2 #define WEBAUTHN_USER_VERIFICATION_REQUIRED 3 typedef struct _WEBAUTHN_CRED_PROTECT_EXTENSION_IN { // One of the above WEBAUTHN_USER_VERIFICATION_* values DWORD dwCredProtect; // Set the following to TRUE to require authenticator support for the credProtect extension BOOL bRequireCredProtect; } WEBAUTHN_CRED_PROTECT_EXTENSION_IN, *PWEBAUTHN_CRED_PROTECT_EXTENSION_IN; typedef const WEBAUTHN_CRED_PROTECT_EXTENSION_IN *PCWEBAUTHN_CRED_PROTECT_EXTENSION_IN; #define WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT L"credProtect" // Below type definitions is for WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT // MakeCredential Input Type: WEBAUTHN_CRED_PROTECT_EXTENSION_IN. // - pvExtension must point to a WEBAUTHN_CRED_PROTECT_EXTENSION_IN struct // - cbExtension will contain the sizeof(WEBAUTHN_CRED_PROTECT_EXTENSION_IN). // MakeCredential Output Type: DWORD. // - pvExtension will point to a DWORD with one of the above WEBAUTHN_USER_VERIFICATION_* values // if credential was successfully created with CRED_PROTECT. // - cbExtension will contain the sizeof(DWORD). // GetAssertion Input Type: Not Supported // GetAssertion Output Type: Not Supported //+------------------------------------------------------------------------------------------ // credBlob extension //------------------------------------------------------------------------------------------- typedef struct _WEBAUTHN_CRED_BLOB_EXTENSION { // Size of pbCredBlob. DWORD cbCredBlob; _Field_size_bytes_(cbCredBlob) PBYTE pbCredBlob; } WEBAUTHN_CRED_BLOB_EXTENSION, *PWEBAUTHN_CRED_BLOB_EXTENSION; typedef const WEBAUTHN_CRED_BLOB_EXTENSION *PCWEBAUTHN_CRED_BLOB_EXTENSION; #define WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_BLOB L"credBlob" // Below type definitions is for WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_BLOB // MakeCredential Input Type: WEBAUTHN_CRED_BLOB_EXTENSION. // - pvExtension must point to a WEBAUTHN_CRED_BLOB_EXTENSION struct // - cbExtension must contain the sizeof(WEBAUTHN_CRED_BLOB_EXTENSION). // MakeCredential Output Type: BOOL. // - pvExtension will point to a BOOL with the value TRUE if credBlob was successfully created // - cbExtension will contain the sizeof(BOOL). // GetAssertion Input Type: BOOL. // - pvExtension must point to a BOOL with the value TRUE to request the credBlob. // - cbExtension must contain the sizeof(BOOL). // GetAssertion Output Type: WEBAUTHN_CRED_BLOB_EXTENSION. // - pvExtension will point to a WEBAUTHN_CRED_BLOB_EXTENSION struct if the authenticator // returns the credBlob in the signed extensions // - cbExtension will contain the sizeof(WEBAUTHN_CRED_BLOB_EXTENSION). //+------------------------------------------------------------------------------------------ // minPinLength extension //------------------------------------------------------------------------------------------- #define WEBAUTHN_EXTENSIONS_IDENTIFIER_MIN_PIN_LENGTH L"minPinLength" // Below type definitions is for WEBAUTHN_EXTENSIONS_IDENTIFIER_MIN_PIN_LENGTH // MakeCredential Input Type: BOOL. // - pvExtension must point to a BOOL with the value TRUE to request the minPinLength. // - cbExtension must contain the sizeof(BOOL). // MakeCredential Output Type: DWORD. // - pvExtension will point to a DWORD with the minimum pin length if returned by the authenticator // - cbExtension will contain the sizeof(DWORD). // GetAssertion Input Type: Not Supported // GetAssertion Output Type: Not Supported //+------------------------------------------------------------------------------------------ // Information about Extensions. //------------------------------------------------------------------------------------------- typedef struct _WEBAUTHN_EXTENSION { LPCWSTR pwszExtensionIdentifier; DWORD cbExtension; PVOID pvExtension; } WEBAUTHN_EXTENSION, *PWEBAUTHN_EXTENSION; typedef const WEBAUTHN_EXTENSION *PCWEBAUTHN_EXTENSION; typedef struct _WEBAUTHN_EXTENSIONS { DWORD cExtensions; _Field_size_(cExtensions) PWEBAUTHN_EXTENSION pExtensions; } WEBAUTHN_EXTENSIONS, *PWEBAUTHN_EXTENSIONS; typedef const WEBAUTHN_EXTENSIONS *PCWEBAUTHN_EXTENSIONS; //+------------------------------------------------------------------------------------------ // Options. //------------------------------------------------------------------------------------------- #define WEBAUTHN_AUTHENTICATOR_ATTACHMENT_ANY 0 #define WEBAUTHN_AUTHENTICATOR_ATTACHMENT_PLATFORM 1 #define WEBAUTHN_AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM 2 #define WEBAUTHN_AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM_U2F_V2 3 #define WEBAUTHN_USER_VERIFICATION_REQUIREMENT_ANY 0 #define WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED 1 #define WEBAUTHN_USER_VERIFICATION_REQUIREMENT_PREFERRED 2 #define WEBAUTHN_USER_VERIFICATION_REQUIREMENT_DISCOURAGED 3 #define WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_ANY 0 #define WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_NONE 1 #define WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_INDIRECT 2 #define WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_DIRECT 3 #define WEBAUTHN_ENTERPRISE_ATTESTATION_NONE 0 #define WEBAUTHN_ENTERPRISE_ATTESTATION_VENDOR_FACILITATED 1 #define WEBAUTHN_ENTERPRISE_ATTESTATION_PLATFORM_MANAGED 2 #define WEBAUTHN_LARGE_BLOB_SUPPORT_NONE 0 #define WEBAUTHN_LARGE_BLOB_SUPPORT_REQUIRED 1 #define WEBAUTHN_LARGE_BLOB_SUPPORT_PREFERRED 2 #define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_1 1 #define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_2 2 #define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_3 3 #define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_4 4 #define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_5 5 -#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_5 +#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_6 6 +#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_7 7 +#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_7 typedef struct _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS { // Version of this structure, to allow for modifications in the future. DWORD dwVersion; // Time that the operation is expected to complete within. // This is used as guidance, and can be overridden by the platform. DWORD dwTimeoutMilliseconds; // Credentials used for exclusion. WEBAUTHN_CREDENTIALS CredentialList; // Optional extensions to parse when performing the operation. WEBAUTHN_EXTENSIONS Extensions; // Optional. Platform vs Cross-Platform Authenticators. DWORD dwAuthenticatorAttachment; // Optional. Require key to be resident or not. Defaulting to FALSE. BOOL bRequireResidentKey; // User Verification Requirement. DWORD dwUserVerificationRequirement; // Attestation Conveyance Preference. DWORD dwAttestationConveyancePreference; // Reserved for future Use DWORD dwFlags; // // The following fields have been added in WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_2 // // Cancellation Id - Optional - See WebAuthNGetCancellationId GUID *pCancellationId; // // The following fields have been added in WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_3 // // Exclude Credential List. If present, "CredentialList" will be ignored. PWEBAUTHN_CREDENTIAL_LIST pExcludeCredentialList; // // The following fields have been added in WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_4 // // Enterprise Attestation DWORD dwEnterpriseAttestation; // Large Blob Support: none, required or preferred // // NTE_INVALID_PARAMETER when large blob required or preferred and // 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; + // + // The following fields have been added in WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_6 + // + + // Enable PRF + BOOL bEnablePrf; + + // + // The following fields have been added in WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_7 + // + + // Optional. Linked Device Connection Info. + PCTAPCBOR_HYBRID_STORAGE_LINKED_DATA pLinkedDevice; + + // Size of pbJsonExt + DWORD cbJsonExt; + _Field_size_bytes_(cbJsonExt) + PBYTE pbJsonExt; } WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS, *PWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS; typedef const WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS *PCWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS; #define WEBAUTHN_CRED_LARGE_BLOB_OPERATION_NONE 0 #define WEBAUTHN_CRED_LARGE_BLOB_OPERATION_GET 1 #define WEBAUTHN_CRED_LARGE_BLOB_OPERATION_SET 2 #define WEBAUTHN_CRED_LARGE_BLOB_OPERATION_DELETE 3 #define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_1 1 #define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_2 2 #define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_3 3 #define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_4 4 #define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_5 5 #define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_6 6 -#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_6 +#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_7 7 +#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_7 /* Information about flags. */ #define WEBAUTHN_AUTHENTICATOR_HMAC_SECRET_VALUES_FLAG 0x00100000 typedef struct _WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS { // Version of this structure, to allow for modifications in the future. DWORD dwVersion; // Time that the operation is expected to complete within. // This is used as guidance, and can be overridden by the platform. DWORD dwTimeoutMilliseconds; // Allowed Credentials List. WEBAUTHN_CREDENTIALS CredentialList; // Optional extensions to parse when performing the operation. WEBAUTHN_EXTENSIONS Extensions; // Optional. Platform vs Cross-Platform Authenticators. DWORD dwAuthenticatorAttachment; // User Verification Requirement. DWORD dwUserVerificationRequirement; // Flags DWORD dwFlags; // // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_2 // // Optional identifier for the U2F AppId. Converted to UTF8 before being hashed. Not lower cased. PCWSTR pwszU2fAppId; // If the following is non-NULL, then, set to TRUE if the above pwszU2fAppid was used instead of // PCWSTR pwszRpId; BOOL *pbU2fAppId; // // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_3 // // Cancellation Id - Optional - See WebAuthNGetCancellationId GUID *pCancellationId; // // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_4 // // Allow Credential List. If present, "CredentialList" will be ignored. PWEBAUTHN_CREDENTIAL_LIST pAllowCredentialList; // // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_5 // DWORD dwCredLargeBlobOperation; // Size of pbCredLargeBlob DWORD cbCredLargeBlob; _Field_size_bytes_(cbCredLargeBlob) PBYTE pbCredLargeBlob; // // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_6 // // PRF values which will be converted into HMAC-SECRET values according to WebAuthn Spec. PWEBAUTHN_HMAC_SECRET_SALT_VALUES pHmacSecretSaltValues; // Optional. BrowserInPrivate Mode. Defaulting to FALSE. BOOL bBrowserInPrivateMode; + // + // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_7 + // + + // Optional. Linked Device Connection Info. + PCTAPCBOR_HYBRID_STORAGE_LINKED_DATA pLinkedDevice; + + // Optional. Allowlist MUST contain 1 credential applicable for Hybrid transport. + BOOL bAutoFill; + + // Size of pbJsonExt + DWORD cbJsonExt; + _Field_size_bytes_(cbJsonExt) + PBYTE pbJsonExt; } WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS, *PWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS; typedef const WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS *PCWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS; //+------------------------------------------------------------------------------------------ // Attestation Info. // //------------------------------------------------------------------------------------------- #define WEBAUTHN_ATTESTATION_DECODE_NONE 0 #define WEBAUTHN_ATTESTATION_DECODE_COMMON 1 // WEBAUTHN_ATTESTATION_DECODE_COMMON supports format types // L"packed" // L"fido-u2f" #define WEBAUTHN_ATTESTATION_VER_TPM_2_0 L"2.0" typedef struct _WEBAUTHN_X5C { // Length of X.509 encoded certificate DWORD cbData; // X.509 encoded certificate bytes _Field_size_bytes_(cbData) PBYTE pbData; } WEBAUTHN_X5C, *PWEBAUTHN_X5C; // Supports either Self or Full Basic Attestation // Note, new fields will be added to the following data structure to // support additional attestation format types, such as, TPM. // When fields are added, the dwVersion will be incremented. // // Therefore, your code must make the following check: // "if (dwVersion >= WEBAUTHN_COMMON_ATTESTATION_CURRENT_VERSION)" #define WEBAUTHN_COMMON_ATTESTATION_CURRENT_VERSION 1 typedef struct _WEBAUTHN_COMMON_ATTESTATION { // Version of this structure, to allow for modifications in the future. DWORD dwVersion; // Hash and Padding Algorithm // // The following won't be set for "fido-u2f" which assumes "ES256". PCWSTR pwszAlg; LONG lAlg; // COSE algorithm // Signature that was generated for this attestation. DWORD cbSignature; _Field_size_bytes_(cbSignature) PBYTE pbSignature; // Following is set for Full Basic Attestation. If not, set then, this is Self Attestation. // Array of X.509 DER encoded certificates. The first certificate is the signer, leaf certificate. DWORD cX5c; _Field_size_(cX5c) PWEBAUTHN_X5C pX5c; // Following are also set for tpm PCWSTR pwszVer; // L"2.0" DWORD cbCertInfo; _Field_size_bytes_(cbCertInfo) PBYTE pbCertInfo; DWORD cbPubArea; _Field_size_bytes_(cbPubArea) PBYTE pbPubArea; } WEBAUTHN_COMMON_ATTESTATION, *PWEBAUTHN_COMMON_ATTESTATION; typedef const WEBAUTHN_COMMON_ATTESTATION *PCWEBAUTHN_COMMON_ATTESTATION; #define WEBAUTHN_ATTESTATION_TYPE_PACKED L"packed" #define WEBAUTHN_ATTESTATION_TYPE_U2F L"fido-u2f" #define WEBAUTHN_ATTESTATION_TYPE_TPM L"tpm" #define WEBAUTHN_ATTESTATION_TYPE_NONE L"none" #define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_1 1 #define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_2 2 #define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_3 3 #define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_4 4 -#define WEBAUTHN_CREDENTIAL_ATTESTATION_CURRENT_VERSION WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_4 +#define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_5 5 +#define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_6 6 +#define WEBAUTHN_CREDENTIAL_ATTESTATION_CURRENT_VERSION WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_6 typedef struct _WEBAUTHN_CREDENTIAL_ATTESTATION { // Version of this structure, to allow for modifications in the future. DWORD dwVersion; // Attestation format type PCWSTR pwszFormatType; // Size of cbAuthenticatorData. DWORD cbAuthenticatorData; // Authenticator data that was created for this credential. _Field_size_bytes_(cbAuthenticatorData) PBYTE pbAuthenticatorData; // Size of CBOR encoded attestation information //0 => encoded as CBOR null value. DWORD cbAttestation; //Encoded CBOR attestation information _Field_size_bytes_(cbAttestation) PBYTE pbAttestation; DWORD dwAttestationDecodeType; // Following depends on the dwAttestationDecodeType // WEBAUTHN_ATTESTATION_DECODE_NONE // NULL - not able to decode the CBOR attestation information // WEBAUTHN_ATTESTATION_DECODE_COMMON // PWEBAUTHN_COMMON_ATTESTATION; PVOID pvAttestationDecode; // The CBOR encoded Attestation Object to be returned to the RP. DWORD cbAttestationObject; _Field_size_bytes_(cbAttestationObject) PBYTE pbAttestationObject; // The CredentialId bytes extracted from the Authenticator Data. // Used by Edge to return to the RP. DWORD cbCredentialId; _Field_size_bytes_(cbCredentialId) PBYTE pbCredentialId; // // Following fields have been added in WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_2 // WEBAUTHN_EXTENSIONS Extensions; // // Following fields have been added in WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_3 // // One of the WEBAUTHN_CTAP_TRANSPORT_* bits will be set corresponding to // the transport that was used. DWORD dwUsedTransport; // // Following fields have been added in WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_4 // BOOL bEpAtt; BOOL bLargeBlobSupported; BOOL bResidentKey; + // + // Following fields have been added in WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_5 + // + + BOOL bPrfEnabled; + + // + // Following fields have been added in WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_6 + // + + DWORD cbUnsignedExtensionOutputs; + _Field_size_bytes_(cbUnsignedExtensionOutputs) + PBYTE pbUnsignedExtensionOutputs; } WEBAUTHN_CREDENTIAL_ATTESTATION, *PWEBAUTHN_CREDENTIAL_ATTESTATION; typedef const WEBAUTHN_CREDENTIAL_ATTESTATION *PCWEBAUTHN_CREDENTIAL_ATTESTATION; //+------------------------------------------------------------------------------------------ // authenticatorGetAssertion output. //------------------------------------------------------------------------------------------- #define WEBAUTHN_CRED_LARGE_BLOB_STATUS_NONE 0 #define WEBAUTHN_CRED_LARGE_BLOB_STATUS_SUCCESS 1 #define WEBAUTHN_CRED_LARGE_BLOB_STATUS_NOT_SUPPORTED 2 #define WEBAUTHN_CRED_LARGE_BLOB_STATUS_INVALID_DATA 3 #define WEBAUTHN_CRED_LARGE_BLOB_STATUS_INVALID_PARAMETER 4 #define WEBAUTHN_CRED_LARGE_BLOB_STATUS_NOT_FOUND 5 #define WEBAUTHN_CRED_LARGE_BLOB_STATUS_MULTIPLE_CREDENTIALS 6 #define WEBAUTHN_CRED_LARGE_BLOB_STATUS_LACK_OF_SPACE 7 #define WEBAUTHN_CRED_LARGE_BLOB_STATUS_PLATFORM_ERROR 8 #define WEBAUTHN_CRED_LARGE_BLOB_STATUS_AUTHENTICATOR_ERROR 9 #define WEBAUTHN_ASSERTION_VERSION_1 1 #define WEBAUTHN_ASSERTION_VERSION_2 2 #define WEBAUTHN_ASSERTION_VERSION_3 3 -#define WEBAUTHN_ASSERTION_CURRENT_VERSION WEBAUTHN_ASSERTION_VERSION_3 +#define WEBAUTHN_ASSERTION_VERSION_4 4 +#define WEBAUTHN_ASSERTION_VERSION_5 5 +#define WEBAUTHN_ASSERTION_CURRENT_VERSION WEBAUTHN_ASSERTION_VERSION_5 typedef struct _WEBAUTHN_ASSERTION { // Version of this structure, to allow for modifications in the future. DWORD dwVersion; // Size of cbAuthenticatorData. DWORD cbAuthenticatorData; // Authenticator data that was created for this assertion. _Field_size_bytes_(cbAuthenticatorData) PBYTE pbAuthenticatorData; // Size of pbSignature. DWORD cbSignature; // Signature that was generated for this assertion. _Field_size_bytes_(cbSignature) PBYTE pbSignature; // Credential that was used for this assertion. WEBAUTHN_CREDENTIAL Credential; // Size of User Id DWORD cbUserId; // UserId _Field_size_bytes_(cbUserId) PBYTE pbUserId; // // Following fields have been added in WEBAUTHN_ASSERTION_VERSION_2 // WEBAUTHN_EXTENSIONS Extensions; // Size of pbCredLargeBlob DWORD cbCredLargeBlob; _Field_size_bytes_(cbCredLargeBlob) PBYTE pbCredLargeBlob; DWORD dwCredLargeBlobStatus; // // Following fields have been added in WEBAUTHN_ASSERTION_VERSION_3 // PWEBAUTHN_HMAC_SECRET_SALT pHmacSecret; + // + // Following fields have been added in WEBAUTHN_ASSERTION_VERSION_4 + // + + // One of the WEBAUTHN_CTAP_TRANSPORT_* bits will be set corresponding to + // the transport that was used. + DWORD dwUsedTransport; + + // + // Following fields have been added in WEBAUTHN_ASSERTION_VERSION_5 + // + + DWORD cbUnsignedExtensionOutputs; + _Field_size_bytes_(cbUnsignedExtensionOutputs) + PBYTE pbUnsignedExtensionOutputs; } WEBAUTHN_ASSERTION, *PWEBAUTHN_ASSERTION; typedef const WEBAUTHN_ASSERTION *PCWEBAUTHN_ASSERTION; //+------------------------------------------------------------------------------------------ // APIs. //------------------------------------------------------------------------------------------- DWORD WINAPI WebAuthNGetApiVersionNumber(); HRESULT WINAPI WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable( _Out_ BOOL *pbIsUserVerifyingPlatformAuthenticatorAvailable); HRESULT WINAPI WebAuthNAuthenticatorMakeCredential( _In_ HWND hWnd, _In_ PCWEBAUTHN_RP_ENTITY_INFORMATION pRpInformation, _In_ PCWEBAUTHN_USER_ENTITY_INFORMATION pUserInformation, _In_ PCWEBAUTHN_COSE_CREDENTIAL_PARAMETERS pPubKeyCredParams, _In_ PCWEBAUTHN_CLIENT_DATA pWebAuthNClientData, _In_opt_ PCWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS pWebAuthNMakeCredentialOptions, _Outptr_result_maybenull_ PWEBAUTHN_CREDENTIAL_ATTESTATION *ppWebAuthNCredentialAttestation); HRESULT WINAPI WebAuthNAuthenticatorGetAssertion( _In_ HWND hWnd, _In_ LPCWSTR pwszRpId, _In_ PCWEBAUTHN_CLIENT_DATA pWebAuthNClientData, _In_opt_ PCWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS pWebAuthNGetAssertionOptions, _Outptr_result_maybenull_ PWEBAUTHN_ASSERTION *ppWebAuthNAssertion); void WINAPI WebAuthNFreeCredentialAttestation( _In_opt_ PWEBAUTHN_CREDENTIAL_ATTESTATION pWebAuthNCredentialAttestation); void WINAPI WebAuthNFreeAssertion( _In_ PWEBAUTHN_ASSERTION pWebAuthNAssertion); HRESULT WINAPI WebAuthNGetCancellationId( _Out_ GUID* pCancellationId); HRESULT WINAPI WebAuthNCancelCurrentOperation( _In_ const GUID* pCancellationId); +// Returns NTE_NOT_FOUND when credentials are not found. HRESULT WINAPI WebAuthNGetPlatformCredentialList( _In_ PCWEBAUTHN_GET_CREDENTIALS_OPTIONS pGetCredentialsOptions, _Outptr_result_maybenull_ PWEBAUTHN_CREDENTIAL_DETAILS_LIST *ppCredentialDetailsList); void WINAPI WebAuthNFreePlatformCredentialList( _In_ PWEBAUTHN_CREDENTIAL_DETAILS_LIST pCredentialDetailsList); +HRESULT +WINAPI +WebAuthNDeletePlatformCredential( + _In_ DWORD cbCredentialId, + _In_reads_bytes_(cbCredentialId) const BYTE *pbCredentialId + ); + // // Returns the following Error Names: // L"Success" - S_OK // L"InvalidStateError" - NTE_EXISTS // L"ConstraintError" - HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), // NTE_NOT_SUPPORTED, // NTE_TOKEN_KEYSET_STORAGE_FULL // L"NotSupportedError" - NTE_INVALID_PARAMETER // L"NotAllowedError" - NTE_DEVICE_NOT_FOUND, // NTE_NOT_FOUND, // HRESULT_FROM_WIN32(ERROR_CANCELLED), // NTE_USER_CANCELLED, // HRESULT_FROM_WIN32(ERROR_TIMEOUT) // L"UnknownError" - All other hr values // PCWSTR WINAPI WebAuthNGetErrorName( _In_ HRESULT hr); HRESULT WINAPI WebAuthNGetW3CExceptionDOMError( _In_ HRESULT hr); #ifdef __cplusplus } // Balance extern "C" above #endif #endif // WINAPI_FAMILY_PARTITION #ifdef _MSC_VER #pragma endregion #endif #endif // __WEBAUTHN_H_ diff --git a/contrib/libfido2/src/winhello.c b/contrib/libfido2/src/winhello.c index efc7dc22f851..ff969a4f6f73 100644 --- a/contrib/libfido2/src/winhello.c +++ b/contrib/libfido2/src/winhello.c @@ -1,1018 +1,1075 @@ /* * Copyright (c) 2021-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. * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include "fido.h" #include "webauthn.h" #ifndef NTE_INVALID_PARAMETER #define NTE_INVALID_PARAMETER _HRESULT_TYPEDEF_(0x80090027) #endif #ifndef NTE_NOT_SUPPORTED #define NTE_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x80090029) #endif #ifndef NTE_DEVICE_NOT_FOUND #define NTE_DEVICE_NOT_FOUND _HRESULT_TYPEDEF_(0x80090035) #endif +#ifndef NTE_USER_CANCELLED +#define NTE_USER_CANCELLED _HRESULT_TYPEDEF_(0x80090036L) +#endif #define MAXCHARS 128 #define MAXCREDS 128 #define MAXMSEC 6000 * 1000 #define VENDORID 0x045e #define PRODID 0x0001 struct winhello_assert { WEBAUTHN_CLIENT_DATA cd; WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS opt; WEBAUTHN_ASSERTION *assert; wchar_t *rp_id; + wchar_t *appid; }; struct winhello_cred { WEBAUTHN_RP_ENTITY_INFORMATION rp; WEBAUTHN_USER_ENTITY_INFORMATION user; WEBAUTHN_COSE_CREDENTIAL_PARAMETER alg; WEBAUTHN_COSE_CREDENTIAL_PARAMETERS cose; WEBAUTHN_CLIENT_DATA cd; WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS opt; WEBAUTHN_CREDENTIAL_ATTESTATION *att; wchar_t *rp_id; wchar_t *rp_name; wchar_t *user_name; wchar_t *user_icon; wchar_t *display_name; }; 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 *); 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 *); typedef void WINAPI webauthn_free_assert_t(PWEBAUTHN_ASSERTION); typedef void WINAPI webauthn_free_attest_t(PWEBAUTHN_CREDENTIAL_ATTESTATION); static TLS BOOL webauthn_loaded; static TLS HMODULE webauthn_handle; static TLS webauthn_get_api_version_t *webauthn_get_api_version; static TLS webauthn_strerr_t *webauthn_strerr; static TLS webauthn_get_assert_t *webauthn_get_assert; static TLS webauthn_make_cred_t *webauthn_make_cred; static TLS webauthn_free_assert_t *webauthn_free_assert; static TLS webauthn_free_attest_t *webauthn_free_attest; static int webauthn_load(void) { DWORD n = 1; if (webauthn_loaded || webauthn_handle != NULL) { fido_log_debug("%s: already loaded", __func__); return -1; } if ((webauthn_handle = LoadLibrary(TEXT("webauthn.dll"))) == NULL) { fido_log_debug("%s: LoadLibrary", __func__); return -1; } 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; } 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 = (webauthn_get_assert_t *)GetProcAddress(webauthn_handle, "WebAuthNAuthenticatorGetAssertion")) == NULL) { fido_log_debug("%s: WebAuthNAuthenticatorGetAssertion", __func__); goto fail; } 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 = (webauthn_free_assert_t *)GetProcAddress(webauthn_handle, "WebAuthNFreeAssertion")) == NULL) { fido_log_debug("%s: WebAuthNFreeAssertion", __func__); goto fail; } if ((webauthn_free_attest = (webauthn_free_attest_t *)GetProcAddress(webauthn_handle, "WebAuthNFreeCredentialAttestation")) == NULL) { fido_log_debug("%s: WebAuthNFreeCredentialAttestation", __func__); goto fail; } webauthn_loaded = true; return 0; fail: fido_log_debug("%s: GetProcAddress", __func__); webauthn_get_api_version = NULL; webauthn_strerr = NULL; webauthn_get_assert = NULL; webauthn_make_cred = NULL; webauthn_free_assert = NULL; webauthn_free_attest = NULL; FreeLibrary(webauthn_handle); webauthn_handle = NULL; return -1; } static wchar_t * to_utf16(const char *utf8) { int nch; wchar_t *utf16; if (utf8 == NULL) { fido_log_debug("%s: NULL", __func__); return NULL; } if ((nch = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0)) < 1 || (size_t)nch > MAXCHARS) { fido_log_debug("%s: MultiByteToWideChar %d", __func__, nch); return NULL; } if ((utf16 = calloc((size_t)nch, sizeof(*utf16))) == NULL) { fido_log_debug("%s: calloc", __func__); return NULL; } if (MultiByteToWideChar(CP_UTF8, 0, utf8, -1, utf16, nch) != nch) { fido_log_debug("%s: MultiByteToWideChar", __func__); free(utf16); return NULL; } return utf16; } static int to_fido(HRESULT hr) { switch (hr) { case NTE_NOT_SUPPORTED: return FIDO_ERR_UNSUPPORTED_OPTION; case NTE_INVALID_PARAMETER: return FIDO_ERR_INVALID_PARAMETER; case NTE_TOKEN_KEYSET_STORAGE_FULL: return FIDO_ERR_KEY_STORE_FULL; case NTE_DEVICE_NOT_FOUND: case NTE_NOT_FOUND: return FIDO_ERR_NOT_ALLOWED; + case __HRESULT_FROM_WIN32(ERROR_CANCELLED): + case NTE_USER_CANCELLED: + return FIDO_ERR_OPERATION_DENIED; default: fido_log_debug("%s: hr=0x%lx", __func__, (u_long)hr); return FIDO_ERR_INTERNAL; } } static int pack_cd(WEBAUTHN_CLIENT_DATA *out, const fido_blob_t *in) { if (in->ptr == NULL) { fido_log_debug("%s: NULL", __func__); return -1; } if (in->len > ULONG_MAX) { fido_log_debug("%s: in->len=%zu", __func__, in->len); return -1; } out->dwVersion = WEBAUTHN_CLIENT_DATA_CURRENT_VERSION; out->cbClientDataJSON = (DWORD)in->len; out->pbClientDataJSON = in->ptr; out->pwszHashAlgId = WEBAUTHN_HASH_ALGORITHM_SHA_256; return 0; } static int pack_credlist(WEBAUTHN_CREDENTIALS *out, const fido_blob_array_t *in) { WEBAUTHN_CREDENTIAL *c; if (in->len == 0) { return 0; /* nothing to do */ } if (in->len > MAXCREDS) { fido_log_debug("%s: in->len=%zu", __func__, in->len); return -1; } if ((out->pCredentials = calloc(in->len, sizeof(*c))) == NULL) { fido_log_debug("%s: calloc", __func__); return -1; } out->cCredentials = (DWORD)in->len; for (size_t i = 0; i < in->len; i++) { if (in->ptr[i].len > ULONG_MAX) { fido_log_debug("%s: %zu", __func__, in->ptr[i].len); return -1; } c = &out->pCredentials[i]; c->dwVersion = WEBAUTHN_CREDENTIAL_CURRENT_VERSION; c->cbId = (DWORD)in->ptr[i].len; c->pbId = in->ptr[i].ptr; c->pwszCredentialType = WEBAUTHN_CREDENTIAL_TYPE_PUBLIC_KEY; } return 0; } static int set_cred_uv(DWORD *out, fido_opt_t uv, const char *pin) { if (pin) { *out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED; return 0; } switch (uv) { case FIDO_OPT_OMIT: case FIDO_OPT_FALSE: *out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_DISCOURAGED; break; case FIDO_OPT_TRUE: *out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED; break; } return 0; } static int set_assert_uv(DWORD *out, fido_opt_t uv, const char *pin) { if (pin) { *out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED; return 0; } switch (uv) { case FIDO_OPT_OMIT: *out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_PREFERRED; break; case FIDO_OPT_FALSE: *out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_DISCOURAGED; break; case FIDO_OPT_TRUE: *out = WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED; break; } return 0; } static int pack_rp(wchar_t **id, wchar_t **name, WEBAUTHN_RP_ENTITY_INFORMATION *out, const fido_rp_t *in) { /* keep non-const copies of pwsz* for free() */ out->dwVersion = WEBAUTHN_RP_ENTITY_INFORMATION_CURRENT_VERSION; if ((out->pwszId = *id = to_utf16(in->id)) == NULL) { fido_log_debug("%s: id", __func__); return -1; } if (in->name && (out->pwszName = *name = to_utf16(in->name)) == NULL) { fido_log_debug("%s: name", __func__); return -1; } return 0; } static int pack_user(wchar_t **name, wchar_t **icon, wchar_t **display_name, WEBAUTHN_USER_ENTITY_INFORMATION *out, const fido_user_t *in) { if (in->id.ptr == NULL || in->id.len > ULONG_MAX) { fido_log_debug("%s: id", __func__); return -1; } out->dwVersion = WEBAUTHN_USER_ENTITY_INFORMATION_CURRENT_VERSION; out->cbId = (DWORD)in->id.len; out->pbId = in->id.ptr; /* keep non-const copies of pwsz* for free() */ if (in->name != NULL) { if ((out->pwszName = *name = to_utf16(in->name)) == NULL) { fido_log_debug("%s: name", __func__); return -1; } } if (in->icon != NULL) { if ((out->pwszIcon = *icon = to_utf16(in->icon)) == NULL) { fido_log_debug("%s: icon", __func__); return -1; } } if (in->display_name != NULL) { if ((out->pwszDisplayName = *display_name = to_utf16(in->display_name)) == NULL) { fido_log_debug("%s: display_name", __func__); return -1; } } return 0; } static int pack_cose(WEBAUTHN_COSE_CREDENTIAL_PARAMETER *alg, WEBAUTHN_COSE_CREDENTIAL_PARAMETERS *cose, int type) { switch (type) { case COSE_ES256: alg->lAlg = WEBAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256; break; case COSE_ES384: alg->lAlg = WEBAUTHN_COSE_ALGORITHM_ECDSA_P384_WITH_SHA384; break; case COSE_EDDSA: alg->lAlg = -8; /* XXX */; break; case COSE_RS256: alg->lAlg = WEBAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA256; break; default: fido_log_debug("%s: type %d", __func__, type); return -1; } alg->dwVersion = WEBAUTHN_COSE_CREDENTIAL_PARAMETER_CURRENT_VERSION; alg->pwszCredentialType = WEBAUTHN_CREDENTIAL_TYPE_PUBLIC_KEY; cose->cCredentialParameters = 1; cose->pCredentialParameters = alg; return 0; } static int pack_cred_ext(WEBAUTHN_EXTENSIONS *out, const fido_cred_ext_t *in) { WEBAUTHN_EXTENSION *e; WEBAUTHN_CRED_PROTECT_EXTENSION_IN *p; BOOL *b; size_t n = 0, i = 0; if (in->mask == 0) { return 0; /* nothing to do */ } if (in->mask & ~(FIDO_EXT_HMAC_SECRET | FIDO_EXT_CRED_PROTECT)) { fido_log_debug("%s: mask 0x%x", __func__, in->mask); return -1; } if (in->mask & FIDO_EXT_HMAC_SECRET) n++; if (in->mask & FIDO_EXT_CRED_PROTECT) n++; if ((out->pExtensions = calloc(n, sizeof(*e))) == NULL) { fido_log_debug("%s: calloc", __func__); return -1; } out->cExtensions = (DWORD)n; if (in->mask & FIDO_EXT_HMAC_SECRET) { + /* + * NOTE: webauthn.dll ignores requests to enable hmac-secret + * unless a discoverable credential is also requested. + */ if ((b = calloc(1, sizeof(*b))) == NULL) { fido_log_debug("%s: calloc", __func__); return -1; } *b = true; e = &out->pExtensions[i]; e->pwszExtensionIdentifier = WEBAUTHN_EXTENSIONS_IDENTIFIER_HMAC_SECRET; e->pvExtension = b; e->cbExtension = sizeof(*b); i++; } if (in->mask & FIDO_EXT_CRED_PROTECT) { if ((p = calloc(1, sizeof(*p))) == NULL) { fido_log_debug("%s: calloc", __func__); return -1; } p->dwCredProtect = (DWORD)in->prot; p->bRequireCredProtect = true; e = &out->pExtensions[i]; e->pwszExtensionIdentifier = WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT; e->pvExtension = p; e->cbExtension = sizeof(*p); i++; } return 0; } static int pack_assert_ext(WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS *out, const fido_assert_ext_t *in) { WEBAUTHN_HMAC_SECRET_SALT_VALUES *v; WEBAUTHN_HMAC_SECRET_SALT *s; if (in->mask == 0) { return 0; /* nothing to do */ } if (in->mask != FIDO_EXT_HMAC_SECRET) { fido_log_debug("%s: mask 0x%x", __func__, in->mask); return -1; } if (in->hmac_salt.ptr == NULL || in->hmac_salt.len != WEBAUTHN_CTAP_ONE_HMAC_SECRET_LENGTH) { fido_log_debug("%s: salt %p/%zu", __func__, (const void *)in->hmac_salt.ptr, in->hmac_salt.len); return -1; } if ((v = calloc(1, sizeof(*v))) == NULL || (s = calloc(1, sizeof(*s))) == NULL) { free(v); fido_log_debug("%s: calloc", __func__); return -1; } s->cbFirst = (DWORD)in->hmac_salt.len; s->pbFirst = in->hmac_salt.ptr; v->pGlobalHmacSalt = s; out->pHmacSecretSaltValues = v; out->dwFlags |= WEBAUTHN_AUTHENTICATOR_HMAC_SECRET_VALUES_FLAG; out->dwVersion = WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_6; return 0; } +static int +pack_appid(WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS *opt, const char *id, + wchar_t **appid) +{ + if (id == NULL) + return 0; /* nothing to do */ + if ((opt->pbU2fAppId = calloc(1, sizeof(*opt->pbU2fAppId))) == NULL) { + fido_log_debug("%s: calloc", __func__); + return -1; + } + if ((*appid = to_utf16(id)) == NULL) { + fido_log_debug("%s: to_utf16", __func__); + return -1; + } + fido_log_debug("%s: using %s", __func__, id); + opt->pwszU2fAppId = *appid; + opt->dwVersion = WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_2; + + return 0; +} + +static void +unpack_appid(fido_assert_t *assert, + const WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS *opt) +{ + if (assert->appid == NULL || opt->pbU2fAppId == NULL) + return; /* nothing to do */ + if (*opt->pbU2fAppId == false) { + fido_log_debug("%s: not used", __func__); + return; + } + fido_log_debug("%s: %s -> %s", __func__, assert->rp_id, assert->appid); + free(assert->rp_id); + assert->rp_id = assert->appid; + assert->appid = NULL; +} + static int unpack_assert_authdata(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) { int r; if ((r = fido_assert_set_authdata_raw(assert, 0, wa->pbAuthenticatorData, wa->cbAuthenticatorData)) != FIDO_OK) { fido_log_debug("%s: fido_assert_set_authdata_raw: %s", __func__, fido_strerr(r)); return -1; } return 0; } static int unpack_assert_sig(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) { int r; if ((r = fido_assert_set_sig(assert, 0, wa->pbSignature, wa->cbSignature)) != FIDO_OK) { fido_log_debug("%s: fido_assert_set_sig: %s", __func__, fido_strerr(r)); return -1; } return 0; } static int unpack_cred_id(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) { if (fido_blob_set(&assert->stmt[0].id, wa->Credential.pbId, wa->Credential.cbId) < 0) { fido_log_debug("%s: fido_blob_set", __func__); return -1; } return 0; } static int unpack_user_id(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) { if (wa->cbUserId == 0) return 0; /* user id absent */ if (fido_blob_set(&assert->stmt[0].user.id, wa->pbUserId, wa->cbUserId) < 0) { fido_log_debug("%s: fido_blob_set", __func__); return -1; } return 0; } static int unpack_hmac_secret(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) { - if (wa->dwVersion != WEBAUTHN_ASSERTION_VERSION_3) { + if (wa->dwVersion < WEBAUTHN_ASSERTION_VERSION_3) { fido_log_debug("%s: dwVersion %u", __func__, (unsigned)wa->dwVersion); return 0; /* proceed without hmac-secret */ } if (wa->pHmacSecret == NULL || wa->pHmacSecret->cbFirst == 0 || wa->pHmacSecret->pbFirst == NULL) { fido_log_debug("%s: hmac-secret absent", __func__); return 0; /* proceed without hmac-secret */ } if (wa->pHmacSecret->cbSecond != 0 || wa->pHmacSecret->pbSecond != NULL) { fido_log_debug("%s: 64-byte hmac-secret", __func__); return 0; /* proceed without hmac-secret */ } if (!fido_blob_is_empty(&assert->stmt[0].hmac_secret)) { fido_log_debug("%s: fido_blob_is_empty", __func__); return -1; } if (fido_blob_set(&assert->stmt[0].hmac_secret, wa->pHmacSecret->pbFirst, wa->pHmacSecret->cbFirst) < 0) { fido_log_debug("%s: fido_blob_set", __func__); return -1; } return 0; } static int translate_fido_assert(struct winhello_assert *ctx, const fido_assert_t *assert, const char *pin, int ms) { WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS *opt; /* not supported by webauthn.h */ if (assert->up == FIDO_OPT_FALSE) { fido_log_debug("%s: up %d", __func__, assert->up); return FIDO_ERR_UNSUPPORTED_OPTION; } if ((ctx->rp_id = to_utf16(assert->rp_id)) == NULL) { fido_log_debug("%s: rp_id", __func__); return FIDO_ERR_INTERNAL; } if (pack_cd(&ctx->cd, &assert->cd) < 0) { fido_log_debug("%s: pack_cd", __func__); return FIDO_ERR_INTERNAL; } /* options */ opt = &ctx->opt; opt->dwVersion = WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_1; opt->dwTimeoutMilliseconds = ms < 0 ? MAXMSEC : (DWORD)ms; + if (pack_appid(opt, assert->appid, &ctx->appid) < 0) { + fido_log_debug("%s: pack_appid" , __func__); + return FIDO_ERR_INTERNAL; + } if (pack_credlist(&opt->CredentialList, &assert->allow_list) < 0) { fido_log_debug("%s: pack_credlist", __func__); return FIDO_ERR_INTERNAL; } if (pack_assert_ext(opt, &assert->ext) < 0) { fido_log_debug("%s: pack_assert_ext", __func__); return FIDO_ERR_UNSUPPORTED_EXTENSION; } if (set_assert_uv(&opt->dwUserVerificationRequirement, assert->uv, pin) < 0) { fido_log_debug("%s: set_assert_uv", __func__); return FIDO_ERR_INTERNAL; } return FIDO_OK; } static int -translate_winhello_assert(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) +translate_winhello_assert(fido_assert_t *assert, + const struct winhello_assert *ctx) { + const WEBAUTHN_ASSERTION *wa = ctx->assert; + const WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS *opt = &ctx->opt; int r; if (assert->stmt_len > 0) { fido_log_debug("%s: stmt_len=%zu", __func__, assert->stmt_len); return FIDO_ERR_INTERNAL; } if ((r = fido_assert_set_count(assert, 1)) != FIDO_OK) { fido_log_debug("%s: fido_assert_set_count: %s", __func__, fido_strerr(r)); return FIDO_ERR_INTERNAL; } + unpack_appid(assert, opt); if (unpack_assert_authdata(assert, wa) < 0) { fido_log_debug("%s: unpack_assert_authdata", __func__); return FIDO_ERR_INTERNAL; } if (unpack_assert_sig(assert, wa) < 0) { fido_log_debug("%s: unpack_assert_sig", __func__); return FIDO_ERR_INTERNAL; } if (unpack_cred_id(assert, wa) < 0) { fido_log_debug("%s: unpack_cred_id", __func__); return FIDO_ERR_INTERNAL; } if (unpack_user_id(assert, wa) < 0) { fido_log_debug("%s: unpack_user_id", __func__); return FIDO_ERR_INTERNAL; } if (assert->ext.mask & FIDO_EXT_HMAC_SECRET && unpack_hmac_secret(assert, wa) < 0) { fido_log_debug("%s: unpack_hmac_secret", __func__); return FIDO_ERR_INTERNAL; } return FIDO_OK; } static int translate_fido_cred(struct winhello_cred *ctx, const fido_cred_t *cred, const char *pin, int ms) { WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS *opt; if (pack_rp(&ctx->rp_id, &ctx->rp_name, &ctx->rp, &cred->rp) < 0) { fido_log_debug("%s: pack_rp", __func__); return FIDO_ERR_INTERNAL; } if (pack_user(&ctx->user_name, &ctx->user_icon, &ctx->display_name, &ctx->user, &cred->user) < 0) { fido_log_debug("%s: pack_user", __func__); return FIDO_ERR_INTERNAL; } if (pack_cose(&ctx->alg, &ctx->cose, cred->type) < 0) { fido_log_debug("%s: pack_cose", __func__); return FIDO_ERR_INTERNAL; } if (pack_cd(&ctx->cd, &cred->cd) < 0) { fido_log_debug("%s: pack_cd", __func__); return FIDO_ERR_INTERNAL; } /* options */ opt = &ctx->opt; opt->dwVersion = WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_1; opt->dwTimeoutMilliseconds = ms < 0 ? MAXMSEC : (DWORD)ms; opt->dwAttestationConveyancePreference = WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_DIRECT; if (pack_credlist(&opt->CredentialList, &cred->excl) < 0) { fido_log_debug("%s: pack_credlist", __func__); return FIDO_ERR_INTERNAL; } if (pack_cred_ext(&opt->Extensions, &cred->ext) < 0) { fido_log_debug("%s: pack_cred_ext", __func__); return FIDO_ERR_UNSUPPORTED_EXTENSION; } if (set_cred_uv(&opt->dwUserVerificationRequirement, (cred->ext.mask & FIDO_EXT_CRED_PROTECT) ? FIDO_OPT_TRUE : cred->uv, pin) < 0) { fido_log_debug("%s: set_cred_uv", __func__); return FIDO_ERR_INTERNAL; } if (cred->rk == FIDO_OPT_TRUE) { opt->bRequireResidentKey = true; } return FIDO_OK; } static int decode_attobj(const cbor_item_t *key, const cbor_item_t *val, void *arg) { fido_cred_t *cred = arg; char *name = NULL; int ok = -1; if (cbor_string_copy(key, &name) < 0) { fido_log_debug("%s: cbor type", __func__); ok = 0; /* ignore */ goto fail; } if (!strcmp(name, "fmt")) { if (cbor_decode_fmt(val, &cred->fmt) < 0) { fido_log_debug("%s: cbor_decode_fmt", __func__); goto fail; } } else if (!strcmp(name, "attStmt")) { if (cbor_decode_attstmt(val, &cred->attstmt) < 0) { fido_log_debug("%s: cbor_decode_attstmt", __func__); goto fail; } } else if (!strcmp(name, "authData")) { if (fido_blob_decode(val, &cred->authdata_raw) < 0) { fido_log_debug("%s: fido_blob_decode", __func__); goto fail; } if (cbor_decode_cred_authdata(val, cred->type, &cred->authdata_cbor, &cred->authdata, &cred->attcred, &cred->authdata_ext) < 0) { fido_log_debug("%s: cbor_decode_cred_authdata", __func__); goto fail; } } ok = 0; fail: free(name); return (ok); } static int translate_winhello_cred(fido_cred_t *cred, const WEBAUTHN_CREDENTIAL_ATTESTATION *att) { cbor_item_t *item = NULL; struct cbor_load_result cbor; int r = FIDO_ERR_INTERNAL; if (att->pbAttestationObject == NULL) { fido_log_debug("%s: pbAttestationObject", __func__); goto fail; } if ((item = cbor_load(att->pbAttestationObject, att->cbAttestationObject, &cbor)) == NULL) { fido_log_debug("%s: cbor_load", __func__); goto fail; } if (cbor_isa_map(item) == false || cbor_map_is_definite(item) == false || cbor_map_iter(item, cred, decode_attobj) < 0) { fido_log_debug("%s: cbor type", __func__); goto fail; } r = FIDO_OK; fail: if (item != NULL) cbor_decref(&item); return r; } static int winhello_get_assert(HWND w, struct winhello_assert *ctx) { HRESULT hr; int r = FIDO_OK; if ((hr = webauthn_get_assert(w, ctx->rp_id, &ctx->cd, &ctx->opt, &ctx->assert)) != S_OK) { r = to_fido(hr); fido_log_debug("%s: %ls -> %s", __func__, webauthn_strerr(hr), fido_strerr(r)); } return r; } static int winhello_make_cred(HWND w, struct winhello_cred *ctx) { HRESULT hr; int r = FIDO_OK; if ((hr = webauthn_make_cred(w, &ctx->rp, &ctx->user, &ctx->cose, &ctx->cd, &ctx->opt, &ctx->att)) != S_OK) { r = to_fido(hr); fido_log_debug("%s: %ls -> %s", __func__, webauthn_strerr(hr), fido_strerr(r)); } return r; } static void winhello_assert_free(struct winhello_assert *ctx) { if (ctx == NULL) return; if (ctx->assert != NULL) webauthn_free_assert(ctx->assert); free(ctx->rp_id); + free(ctx->appid); free(ctx->opt.CredentialList.pCredentials); if (ctx->opt.pHmacSecretSaltValues != NULL) free(ctx->opt.pHmacSecretSaltValues->pGlobalHmacSalt); free(ctx->opt.pHmacSecretSaltValues); free(ctx); } static void winhello_cred_free(struct winhello_cred *ctx) { if (ctx == NULL) return; if (ctx->att != NULL) webauthn_free_attest(ctx->att); free(ctx->rp_id); free(ctx->rp_name); free(ctx->user_name); free(ctx->user_icon); free(ctx->display_name); free(ctx->opt.CredentialList.pCredentials); for (size_t i = 0; i < ctx->opt.Extensions.cExtensions; i++) { WEBAUTHN_EXTENSION *e; e = &ctx->opt.Extensions.pExtensions[i]; free(e->pvExtension); } free(ctx->opt.Extensions.pExtensions); free(ctx); } int fido_winhello_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen) { fido_dev_info_t *di; if (ilen == 0) { return FIDO_OK; } if (devlist == NULL) { return FIDO_ERR_INVALID_ARGUMENT; } if (!webauthn_loaded && webauthn_load() < 0) { fido_log_debug("%s: webauthn_load", __func__); return FIDO_OK; /* not an error */ } di = &devlist[*olen]; memset(di, 0, sizeof(*di)); di->path = strdup(FIDO_WINHELLO_PATH); di->manufacturer = strdup("Microsoft Corporation"); di->product = strdup("Windows Hello"); di->vendor_id = VENDORID; di->product_id = PRODID; if (di->path == NULL || di->manufacturer == NULL || di->product == NULL) { free(di->path); free(di->manufacturer); free(di->product); explicit_bzero(di, sizeof(*di)); return FIDO_ERR_INTERNAL; } ++(*olen); return FIDO_OK; } int fido_winhello_open(fido_dev_t *dev) { if (!webauthn_loaded && webauthn_load() < 0) { fido_log_debug("%s: webauthn_load", __func__); return FIDO_ERR_INTERNAL; } if (dev->flags != 0) return FIDO_ERR_INVALID_ARGUMENT; dev->attr.flags = FIDO_CAP_CBOR | FIDO_CAP_WINK; dev->flags = FIDO_DEV_WINHELLO | FIDO_DEV_CRED_PROT | FIDO_DEV_PIN_SET; return FIDO_OK; } int fido_winhello_close(fido_dev_t *dev) { memset(dev, 0, sizeof(*dev)); return FIDO_OK; } int fido_winhello_cancel(fido_dev_t *dev) { (void)dev; return FIDO_ERR_INTERNAL; } int fido_winhello_get_assert(fido_dev_t *dev, fido_assert_t *assert, const char *pin, int ms) { HWND w; struct winhello_assert *ctx; int r = FIDO_ERR_INTERNAL; (void)dev; fido_assert_reset_rx(assert); if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { fido_log_debug("%s: calloc", __func__); goto fail; } if ((w = GetForegroundWindow()) == NULL) { fido_log_debug("%s: GetForegroundWindow", __func__); 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)) != FIDO_OK) { fido_log_debug("%s: winhello_get_assert", __func__); goto fail; } - if ((r = translate_winhello_assert(assert, ctx->assert)) != FIDO_OK) { + if ((r = translate_winhello_assert(assert, ctx)) != FIDO_OK) { fido_log_debug("%s: translate_winhello_assert", __func__); goto fail; } fail: winhello_assert_free(ctx); return r; } int fido_winhello_get_cbor_info(fido_dev_t *dev, fido_cbor_info_t *ci) { const char *v[3] = { "U2F_V2", "FIDO_2_0", "FIDO_2_1_PRE" }; const char *e[2] = { "credProtect", "hmac-secret" }; const char *t[2] = { "nfc", "usb" }; const char *o[4] = { "rk", "up", "uv", "plat" }; (void)dev; fido_cbor_info_reset(ci); if (fido_str_array_pack(&ci->versions, v, nitems(v)) < 0 || fido_str_array_pack(&ci->extensions, e, nitems(e)) < 0 || fido_str_array_pack(&ci->transports, t, nitems(t)) < 0) { fido_log_debug("%s: fido_str_array_pack", __func__); return FIDO_ERR_INTERNAL; } if ((ci->options.name = calloc(nitems(o), sizeof(char *))) == NULL || (ci->options.value = calloc(nitems(o), sizeof(bool))) == NULL) { fido_log_debug("%s: calloc", __func__); return FIDO_ERR_INTERNAL; } for (size_t i = 0; i < nitems(o); i++) { if ((ci->options.name[i] = strdup(o[i])) == NULL) { fido_log_debug("%s: strdup", __func__); return FIDO_ERR_INTERNAL; } ci->options.value[i] = true; ci->options.len++; } return FIDO_OK; } int fido_winhello_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin, int ms) { HWND w; struct winhello_cred *ctx; int r = FIDO_ERR_INTERNAL; (void)dev; fido_cred_reset_rx(cred); if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { fido_log_debug("%s: calloc", __func__); goto fail; } if ((w = GetForegroundWindow()) == NULL) { fido_log_debug("%s: GetForegroundWindow", __func__); if ((w = GetTopWindow(NULL)) == NULL) { fido_log_debug("%s: GetTopWindow", __func__); goto fail; } } if ((r = translate_fido_cred(ctx, cred, pin, ms)) != FIDO_OK) { fido_log_debug("%s: translate_fido_cred", __func__); goto fail; } if ((r = winhello_make_cred(w, ctx)) != FIDO_OK) { fido_log_debug("%s: winhello_make_cred", __func__); goto fail; } if ((r = translate_winhello_cred(cred, ctx->att)) != FIDO_OK) { fido_log_debug("%s: translate_winhello_cred", __func__); goto fail; } r = FIDO_OK; fail: winhello_cred_free(ctx); return r; } diff --git a/contrib/libfido2/tools/assert_get.c b/contrib/libfido2/tools/assert_get.c index 8260fb8359f5..32d40b1ee88f 100644 --- a/contrib/libfido2/tools/assert_get.c +++ b/contrib/libfido2/tools/assert_get.c @@ -1,321 +1,328 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2023 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. * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include "../openbsd-compat/openbsd-compat.h" #include "extern.h" struct toggle { fido_opt_t up; fido_opt_t uv; fido_opt_t pin; }; static const char * opt2str(fido_opt_t v) { switch (v) { case FIDO_OPT_OMIT: return "omit"; case FIDO_OPT_TRUE: return "true"; case FIDO_OPT_FALSE: return "false"; default: return "unknown"; } } static void parse_toggle(const char *str, struct toggle *opt) { fido_opt_t *k; fido_opt_t v; char *assignment; char *key; char *val; if ((assignment = strdup(str)) == NULL) err(1, "strdup"); if ((val = strchr(assignment, '=')) == NULL) errx(1, "invalid assignment '%s'", assignment); key = assignment; *val++ = '\0'; if (!strcmp(val, "true")) v = FIDO_OPT_TRUE; else if (!strcmp(val, "false")) v = FIDO_OPT_FALSE; else errx(1, "unknown value '%s'", val); if (!strcmp(key, "up")) k = &opt->up; else if (!strcmp(key, "uv")) k = &opt->uv; else if (!strcmp(key, "pin")) k = &opt->pin; else errx(1, "unknown key '%s'", key); free(assignment); *k = v; } static fido_assert_t * prepare_assert(FILE *in_f, int flags, const struct toggle *opt) { fido_assert_t *assert = NULL; struct blob cdh; struct blob id; struct blob hmac_salt; char *rpid = NULL; int r; memset(&cdh, 0, sizeof(cdh)); memset(&id, 0, sizeof(id)); memset(&hmac_salt, 0, sizeof(hmac_salt)); r = base64_read(in_f, &cdh); r |= string_read(in_f, &rpid); if ((flags & FLAG_RK) == 0) r |= base64_read(in_f, &id); if (flags & FLAG_HMAC) r |= base64_read(in_f, &hmac_salt); if (r < 0) errx(1, "input error"); if (flags & FLAG_DEBUG) { - fprintf(stderr, "client data hash:\n"); + fprintf(stderr, "client data%s:\n", + flags & FLAG_CD ? "" : " hash"); xxd(cdh.ptr, cdh.len); fprintf(stderr, "relying party id: %s\n", rpid); if ((flags & FLAG_RK) == 0) { fprintf(stderr, "credential id:\n"); xxd(id.ptr, id.len); } fprintf(stderr, "up=%s\n", opt2str(opt->up)); fprintf(stderr, "uv=%s\n", opt2str(opt->uv)); fprintf(stderr, "pin=%s\n", opt2str(opt->pin)); } if ((assert = fido_assert_new()) == NULL) errx(1, "fido_assert_new"); - if ((r = fido_assert_set_clientdata_hash(assert, cdh.ptr, - cdh.len)) != FIDO_OK || - (r = fido_assert_set_rp(assert, rpid)) != FIDO_OK) + if (flags & FLAG_CD) + r = fido_assert_set_clientdata(assert, cdh.ptr, cdh.len); + else + r = fido_assert_set_clientdata_hash(assert, cdh.ptr, cdh.len); + + if (r != FIDO_OK || (r = fido_assert_set_rp(assert, rpid)) != FIDO_OK) errx(1, "fido_assert_set: %s", fido_strerr(r)); if ((r = fido_assert_set_up(assert, opt->up)) != FIDO_OK) errx(1, "fido_assert_set_up: %s", fido_strerr(r)); if ((r = fido_assert_set_uv(assert, opt->uv)) != FIDO_OK) errx(1, "fido_assert_set_uv: %s", fido_strerr(r)); if (flags & FLAG_HMAC) { if ((r = fido_assert_set_extensions(assert, FIDO_EXT_HMAC_SECRET)) != FIDO_OK) errx(1, "fido_assert_set_extensions: %s", fido_strerr(r)); if ((r = fido_assert_set_hmac_salt(assert, hmac_salt.ptr, hmac_salt.len)) != FIDO_OK) errx(1, "fido_assert_set_hmac_salt: %s", fido_strerr(r)); } if (flags & FLAG_LARGEBLOB) { if ((r = fido_assert_set_extensions(assert, FIDO_EXT_LARGEBLOB_KEY)) != FIDO_OK) errx(1, "fido_assert_set_extensions: %s", fido_strerr(r)); } if ((flags & FLAG_RK) == 0) { if ((r = fido_assert_allow_cred(assert, id.ptr, id.len)) != FIDO_OK) errx(1, "fido_assert_allow_cred: %s", fido_strerr(r)); } free(hmac_salt.ptr); free(cdh.ptr); free(id.ptr); free(rpid); return (assert); } static void print_assert(FILE *out_f, const fido_assert_t *assert, size_t idx, int flags) { char *cdh = NULL; char *authdata = NULL; char *sig = NULL; char *user_id = NULL; char *hmac_secret = NULL; char *key = NULL; int r; r = base64_encode(fido_assert_clientdata_hash_ptr(assert), fido_assert_clientdata_hash_len(assert), &cdh); r |= base64_encode(fido_assert_authdata_ptr(assert, idx), fido_assert_authdata_len(assert, 0), &authdata); r |= base64_encode(fido_assert_sig_ptr(assert, idx), fido_assert_sig_len(assert, idx), &sig); if (flags & FLAG_RK) r |= base64_encode(fido_assert_user_id_ptr(assert, idx), fido_assert_user_id_len(assert, idx), &user_id); if (flags & FLAG_HMAC) r |= base64_encode(fido_assert_hmac_secret_ptr(assert, idx), fido_assert_hmac_secret_len(assert, idx), &hmac_secret); if (flags & FLAG_LARGEBLOB) r |= base64_encode(fido_assert_largeblob_key_ptr(assert, idx), fido_assert_largeblob_key_len(assert, idx), &key); if (r < 0) errx(1, "output error"); fprintf(out_f, "%s\n", cdh); fprintf(out_f, "%s\n", fido_assert_rp_id(assert)); fprintf(out_f, "%s\n", authdata); fprintf(out_f, "%s\n", sig); if (flags & FLAG_RK) fprintf(out_f, "%s\n", user_id); if (hmac_secret) { fprintf(out_f, "%s\n", hmac_secret); explicit_bzero(hmac_secret, strlen(hmac_secret)); } if (key) { fprintf(out_f, "%s\n", key); explicit_bzero(key, strlen(key)); } free(key); free(hmac_secret); free(cdh); free(authdata); free(sig); free(user_id); } int assert_get(int argc, char **argv) { fido_dev_t *dev = NULL; fido_assert_t *assert = NULL; struct toggle opt; char prompt[1024]; char pin[128]; char *in_path = NULL; char *out_path = NULL; FILE *in_f = NULL; FILE *out_f = NULL; int flags = 0; int ch; int r; opt.up = opt.uv = opt.pin = FIDO_OPT_OMIT; - while ((ch = getopt(argc, argv, "bdhi:o:prt:uv")) != -1) { + while ((ch = getopt(argc, argv, "bdhi:o:prt:uvw")) != -1) { switch (ch) { case 'b': flags |= FLAG_LARGEBLOB; break; case 'd': flags |= FLAG_DEBUG; break; case 'h': flags |= FLAG_HMAC; break; case 'i': in_path = optarg; break; case 'o': out_path = optarg; break; case 'p': opt.up = FIDO_OPT_TRUE; break; case 'r': flags |= FLAG_RK; break; case 't' : parse_toggle(optarg, &opt); break; case 'u': flags |= FLAG_U2F; break; case 'v': /* -v implies both pin and uv for historical reasons */ opt.pin = FIDO_OPT_TRUE; opt.uv = FIDO_OPT_TRUE; break; + case 'w': + flags |= FLAG_CD; + break; default: usage(); } } argc -= optind; argv += optind; if (argc < 1) usage(); in_f = open_read(in_path); out_f = open_write(out_path); fido_init((flags & FLAG_DEBUG) ? FIDO_DEBUG : 0); assert = prepare_assert(in_f, flags, &opt); dev = open_dev(argv[0]); if (flags & FLAG_U2F) fido_dev_force_u2f(dev); if (opt.pin == FIDO_OPT_TRUE) { r = snprintf(prompt, sizeof(prompt), "Enter PIN for %s: ", argv[0]); if (r < 0 || (size_t)r >= sizeof(prompt)) errx(1, "snprintf"); if (!readpassphrase(prompt, pin, sizeof(pin), RPP_ECHO_OFF)) errx(1, "readpassphrase"); if (strlen(pin) < 4 || strlen(pin) > 63) { explicit_bzero(pin, sizeof(pin)); errx(1, "invalid PIN length"); } r = fido_dev_get_assert(dev, assert, pin); } else r = fido_dev_get_assert(dev, assert, NULL); explicit_bzero(pin, sizeof(pin)); if (r != FIDO_OK) errx(1, "fido_dev_get_assert: %s", fido_strerr(r)); if (flags & FLAG_RK) { for (size_t idx = 0; idx < fido_assert_count(assert); idx++) print_assert(out_f, assert, idx, flags); } else { if (fido_assert_count(assert) != 1) errx(1, "fido_assert_count: %zu", fido_assert_count(assert)); print_assert(out_f, assert, 0, flags); } fido_dev_close(dev); fido_dev_free(&dev); fido_assert_free(&assert); fclose(in_f); fclose(out_f); in_f = NULL; out_f = NULL; exit(0); } diff --git a/contrib/libfido2/tools/cred_make.c b/contrib/libfido2/tools/cred_make.c index a6239ec27aec..66c8b52d8e38 100644 --- a/contrib/libfido2/tools/cred_make.c +++ b/contrib/libfido2/tools/cred_make.c @@ -1,247 +1,255 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2023 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. * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include "../openbsd-compat/openbsd-compat.h" #include "extern.h" static fido_cred_t * prepare_cred(FILE *in_f, int type, int flags) { fido_cred_t *cred = NULL; struct blob cdh; struct blob uid; char *rpid = NULL; char *uname = NULL; int r; memset(&cdh, 0, sizeof(cdh)); memset(&uid, 0, sizeof(uid)); r = base64_read(in_f, &cdh); r |= string_read(in_f, &rpid); r |= string_read(in_f, &uname); r |= base64_read(in_f, &uid); if (r < 0) errx(1, "input error"); if (flags & FLAG_DEBUG) { - fprintf(stderr, "client data hash:\n"); + fprintf(stderr, "client data%s:\n", + flags & FLAG_CD ? "" : " hash"); xxd(cdh.ptr, cdh.len); fprintf(stderr, "relying party id: %s\n", rpid); fprintf(stderr, "user name: %s\n", uname); fprintf(stderr, "user id:\n"); xxd(uid.ptr, uid.len); } if ((cred = fido_cred_new()) == NULL) errx(1, "fido_cred_new"); - if ((r = fido_cred_set_type(cred, type)) != FIDO_OK || - (r = fido_cred_set_clientdata_hash(cred, cdh.ptr, - cdh.len)) != FIDO_OK || + + if (flags & FLAG_CD) + r = fido_cred_set_clientdata(cred, cdh.ptr, cdh.len); + else + r = fido_cred_set_clientdata_hash(cred, cdh.ptr, cdh.len); + + if (r != FIDO_OK || (r = fido_cred_set_type(cred, type)) != FIDO_OK || (r = fido_cred_set_rp(cred, rpid, NULL)) != FIDO_OK || (r = fido_cred_set_user(cred, uid.ptr, uid.len, uname, NULL, NULL)) != FIDO_OK) errx(1, "fido_cred_set: %s", fido_strerr(r)); if (flags & FLAG_RK) { if ((r = fido_cred_set_rk(cred, FIDO_OPT_TRUE)) != FIDO_OK) errx(1, "fido_cred_set_rk: %s", fido_strerr(r)); } if (flags & FLAG_UV) { if ((r = fido_cred_set_uv(cred, FIDO_OPT_TRUE)) != FIDO_OK) errx(1, "fido_cred_set_uv: %s", fido_strerr(r)); } if (flags & FLAG_HMAC) { if ((r = fido_cred_set_extensions(cred, FIDO_EXT_HMAC_SECRET)) != FIDO_OK) errx(1, "fido_cred_set_extensions: %s", fido_strerr(r)); } if (flags & FLAG_LARGEBLOB) { if ((r = fido_cred_set_extensions(cred, FIDO_EXT_LARGEBLOB_KEY)) != FIDO_OK) errx(1, "fido_cred_set_extensions: %s", fido_strerr(r)); } free(cdh.ptr); free(uid.ptr); free(rpid); free(uname); return (cred); } static void print_attcred(FILE *out_f, const fido_cred_t *cred) { char *cdh = NULL; char *authdata = NULL; char *id = NULL; char *sig = NULL; char *x5c = NULL; char *key = NULL; int r; r = base64_encode(fido_cred_clientdata_hash_ptr(cred), fido_cred_clientdata_hash_len(cred), &cdh); r |= base64_encode(fido_cred_authdata_ptr(cred), fido_cred_authdata_len(cred), &authdata); r |= base64_encode(fido_cred_id_ptr(cred), fido_cred_id_len(cred), &id); r |= base64_encode(fido_cred_sig_ptr(cred), fido_cred_sig_len(cred), &sig); if (fido_cred_x5c_ptr(cred) != NULL) r |= base64_encode(fido_cred_x5c_ptr(cred), fido_cred_x5c_len(cred), &x5c); if (fido_cred_largeblob_key_ptr(cred) != NULL) r |= base64_encode(fido_cred_largeblob_key_ptr(cred), fido_cred_largeblob_key_len(cred), &key); if (r < 0) errx(1, "output error"); fprintf(out_f, "%s\n", cdh); fprintf(out_f, "%s\n", fido_cred_rp_id(cred)); fprintf(out_f, "%s\n", fido_cred_fmt(cred)); fprintf(out_f, "%s\n", authdata); fprintf(out_f, "%s\n", id); fprintf(out_f, "%s\n", sig); if (x5c != NULL) fprintf(out_f, "%s\n", x5c); if (key != NULL) { fprintf(out_f, "%s\n", key); explicit_bzero(key, strlen(key)); } free(cdh); free(authdata); free(id); free(sig); free(x5c); free(key); } int cred_make(int argc, char **argv) { fido_dev_t *dev = NULL; fido_cred_t *cred = NULL; char prompt[1024]; char pin[128]; char *in_path = NULL; char *out_path = NULL; FILE *in_f = NULL; FILE *out_f = NULL; int type = COSE_ES256; int flags = 0; int cred_protect = -1; int ch; int r; - while ((ch = getopt(argc, argv, "bc:dhi:o:qruv")) != -1) { + while ((ch = getopt(argc, argv, "bc:dhi:o:qruvw")) != -1) { switch (ch) { case 'b': flags |= FLAG_LARGEBLOB; break; case 'c': if ((cred_protect = base10(optarg)) < 0) errx(1, "-c: invalid argument '%s'", optarg); break; case 'd': flags |= FLAG_DEBUG; break; case 'h': flags |= FLAG_HMAC; break; case 'i': in_path = optarg; break; case 'o': out_path = optarg; break; case 'q': flags |= FLAG_QUIET; break; case 'r': flags |= FLAG_RK; break; case 'u': flags |= FLAG_U2F; break; case 'v': flags |= FLAG_UV; break; + case 'w': + flags |= FLAG_CD; + break; default: usage(); } } argc -= optind; argv += optind; if (argc < 1 || argc > 2) usage(); in_f = open_read(in_path); out_f = open_write(out_path); if (argc > 1 && cose_type(argv[1], &type) < 0) errx(1, "unknown type %s", argv[1]); fido_init((flags & FLAG_DEBUG) ? FIDO_DEBUG : 0); cred = prepare_cred(in_f, type, flags); dev = open_dev(argv[0]); if (flags & FLAG_U2F) fido_dev_force_u2f(dev); if (cred_protect > 0) { r = fido_cred_set_prot(cred, cred_protect); if (r != FIDO_OK) { errx(1, "fido_cred_set_prot: %s", fido_strerr(r)); } } r = fido_dev_make_cred(dev, cred, NULL); if (r == FIDO_ERR_PIN_REQUIRED && !(flags & FLAG_QUIET)) { r = snprintf(prompt, sizeof(prompt), "Enter PIN for %s: ", argv[0]); if (r < 0 || (size_t)r >= sizeof(prompt)) errx(1, "snprintf"); if (!readpassphrase(prompt, pin, sizeof(pin), RPP_ECHO_OFF)) errx(1, "readpassphrase"); if (strlen(pin) < 4 || strlen(pin) > 63) { explicit_bzero(pin, sizeof(pin)); errx(1, "invalid PIN length"); } r = fido_dev_make_cred(dev, cred, pin); } explicit_bzero(pin, sizeof(pin)); if (r != FIDO_OK) errx(1, "fido_dev_make_cred: %s", fido_strerr(r)); print_attcred(out_f, cred); fido_dev_close(dev); fido_dev_free(&dev); fido_cred_free(&cred); fclose(in_f); fclose(out_f); in_f = NULL; out_f = NULL; exit(0); } diff --git a/contrib/libfido2/tools/extern.h b/contrib/libfido2/tools/extern.h index ed4b348cfe46..b806ddd646fb 100644 --- a/contrib/libfido2/tools/extern.h +++ b/contrib/libfido2/tools/extern.h @@ -1,102 +1,103 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2023 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. * SPDX-License-Identifier: BSD-2-Clause */ #ifndef _EXTERN_H_ #define _EXTERN_H_ #include #include #include #include #include struct blob { unsigned char *ptr; size_t len; }; #define TOKEN_OPT "CDGILPRSVabcdefi:k:l:m:n:p:ru" -#define FLAG_DEBUG 0x01 -#define FLAG_QUIET 0x02 -#define FLAG_RK 0x04 -#define FLAG_UV 0x08 -#define FLAG_U2F 0x10 -#define FLAG_HMAC 0x20 -#define FLAG_UP 0x40 -#define FLAG_LARGEBLOB 0x80 +#define FLAG_DEBUG 0x001 +#define FLAG_QUIET 0x002 +#define FLAG_RK 0x004 +#define FLAG_UV 0x008 +#define FLAG_U2F 0x010 +#define FLAG_HMAC 0x020 +#define FLAG_UP 0x040 +#define FLAG_LARGEBLOB 0x080 +#define FLAG_CD 0x100 #define PINBUF_LEN 256 EC_KEY *read_ec_pubkey(const char *); fido_dev_t *open_dev(const char *); FILE *open_read(const char *); FILE *open_write(const char *); char *get_pin(const char *); const char *plural(size_t); const char *cose_string(int); const char *prot_string(int); int assert_get(int, char **); int assert_verify(int, char **); int base64_decode(const char *, void **, size_t *); int base64_encode(const void *, size_t, char **); int base64_read(FILE *, struct blob *); int bio_delete(const char *, const char *); int bio_enroll(const char *); void bio_info(fido_dev_t *); int bio_list(const char *); int bio_set_name(const char *, const char *, const char *); int blob_clean(const char *); int blob_list(const char *); int blob_delete(const char *, const char *, const char *, const char *); int blob_get(const char *, const char *, const char *, const char *, const char *); int blob_set(const char *, const char *, const char *, const char *, const char *); int config_always_uv(char *, int); int config_entattest(char *); int config_force_pin_change(char *); int config_pin_minlen(char *, const char *); int config_pin_minlen_rpid(char *, const char *); int cose_type(const char *, int *); int cred_make(int, char **); int cred_verify(int, char **); int credman_delete_rk(const char *, const char *); int credman_update_rk(const char *, const char *, const char *, const char *, const char *); int credman_get_metadata(fido_dev_t *, const char *); int credman_list_rk(const char *, const char *); int credman_list_rp(const char *); int credman_print_rk(fido_dev_t *, const char *, const char *, const char *); int get_devopt(fido_dev_t *, const char *, int *); int pin_change(char *); int pin_set(char *); int should_retry_with_pin(const fido_dev_t *, int); int string_read(FILE *, char **); int token_config(int, char **, char *); int token_delete(int, char **, char *); int token_get(int, char **, char *); int token_info(int, char **, char *); int token_list(int, char **, char *); int token_reset(char *); int token_set(int, char **, char *); int write_es256_pubkey(FILE *, const void *, size_t); int write_es384_pubkey(FILE *, const void *, size_t); int write_rsa_pubkey(FILE *, const void *, size_t); int read_file(const char *, u_char **, size_t *); int write_file(const char *, const u_char *, size_t); RSA *read_rsa_pubkey(const char *); EVP_PKEY *read_eddsa_pubkey(const char *); int write_eddsa_pubkey(FILE *, const void *, size_t); void print_cred(FILE *, int, const fido_cred_t *); void usage(void); void xxd(const void *, size_t); int base10(const char *); #endif /* _EXTERN_H_ */ diff --git a/contrib/libfido2/tools/fido2-assert.c b/contrib/libfido2/tools/fido2-assert.c index d05c541651cb..351ed4fd387d 100644 --- a/contrib/libfido2/tools/fido2-assert.c +++ b/contrib/libfido2/tools/fido2-assert.c @@ -1,55 +1,55 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2023 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. * SPDX-License-Identifier: BSD-2-Clause */ /* * Example usage: * * $ echo assertion challenge | openssl sha256 -binary | base64 > assert_param * $ echo relying party >> assert_param * $ head -1 cred >> assert_param # credential id * $ tail -n +2 cred > pubkey # credential pubkey * $ fido2-assert -G -i assert_param /dev/hidraw5 | fido2-assert -V pubkey rs256 * * See blurb in fido2-cred.c on how to obtain cred. */ #include #include #include #include #include "../openbsd-compat/openbsd-compat.h" #include "extern.h" void usage(void) { fprintf(stderr, -"usage: fido2-assert -G [-bdhpruv] [-t option] [-i input_file] [-o output_file] device\n" +"usage: fido2-assert -G [-bdhpruvw] [-t option] [-i input_file] [-o output_file] device\n" " fido2-assert -V [-dhpv] [-i input_file] key_file [type]\n" ); exit(1); } int main(int argc, char **argv) { if (argc < 2 || strlen(argv[1]) != 2 || argv[1][0] != '-') usage(); switch (argv[1][1]) { case 'G': return (assert_get(--argc, ++argv)); case 'V': return (assert_verify(--argc, ++argv)); } usage(); /* NOTREACHED */ } diff --git a/contrib/libfido2/tools/fido2-cred.c b/contrib/libfido2/tools/fido2-cred.c index 965dbf9ef1ad..76081c6856e9 100644 --- a/contrib/libfido2/tools/fido2-cred.c +++ b/contrib/libfido2/tools/fido2-cred.c @@ -1,53 +1,53 @@ /* - * Copyright (c) 2018 Yubico AB. All rights reserved. + * Copyright (c) 2018-2023 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. * SPDX-License-Identifier: BSD-2-Clause */ /* * Example usage: * * $ echo credential challenge | openssl sha256 -binary | base64 > cred_param * $ echo relying party >> cred_param * $ echo user name >> cred_param * $ dd if=/dev/urandom bs=1 count=32 | base64 >> cred_param * $ fido2-cred -M -i cred_param /dev/hidraw5 | fido2-cred -V -o cred */ #include #include #include #include #include "../openbsd-compat/openbsd-compat.h" #include "extern.h" void usage(void) { fprintf(stderr, -"usage: fido2-cred -M [-bdhqruv] [-c cred_protect] [-i input_file] [-o output_file] device [type]\n" +"usage: fido2-cred -M [-bdhqruvw] [-c cred_protect] [-i input_file] [-o output_file] device [type]\n" " fido2-cred -V [-dhv] [-c cred_protect] [-i input_file] [-o output_file] [type]\n" ); exit(1); } int main(int argc, char **argv) { if (argc < 2 || strlen(argv[1]) != 2 || argv[1][0] != '-') usage(); switch (argv[1][1]) { case 'M': return (cred_make(--argc, ++argv)); case 'V': return (cred_verify(--argc, ++argv)); } usage(); /* NOTREACHED */ } diff --git a/contrib/libfido2/udev/70-u2f.rules b/contrib/libfido2/udev/70-u2f.rules index c443f7524a08..6df852b9de99 100644 --- a/contrib/libfido2/udev/70-u2f.rules +++ b/contrib/libfido2/udev/70-u2f.rules @@ -1,246 +1,270 @@ # Copyright (c) 2020 Yubico AB. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # SPDX-License-Identifier: BSD-2-Clause # This file is automatically generated, and should be used with udev 188 # or newer. ACTION!="add|change", GOTO="fido_end" # ellipticSecure MIRKey by STMicroelectronics KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ac", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Unknown product by STMicroelectronics KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Unknown product by STMicroelectronics KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="cdab", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Infineon FIDO by Infineon Technologies KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="058b", ATTRS{idProduct}=="022d", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Kensington VeriMark by Synaptics Inc. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="06cb", ATTRS{idProduct}=="0088", TAG+="uaccess", GROUP="plugdev", MODE="0660" # FS ePass FIDO by Feitian Technologies Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e", ATTRS{idProduct}=="0850", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Unknown product by Feitian Technologies Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e", ATTRS{idProduct}=="0852", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Unknown product by Feitian Technologies Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e", ATTRS{idProduct}=="0853", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Unknown product by Feitian Technologies Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e", ATTRS{idProduct}=="0854", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Unknown product by Feitian Technologies Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e", ATTRS{idProduct}=="0856", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Unknown product by Feitian Technologies Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e", ATTRS{idProduct}=="0858", TAG+="uaccess", GROUP="plugdev", MODE="0660" # FS MultiPass FIDO U2F by Feitian Technologies Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e", ATTRS{idProduct}=="085a", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Unknown product by Feitian Technologies Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e", ATTRS{idProduct}=="085b", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Unknown product by Feitian Technologies Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e", ATTRS{idProduct}=="085d", TAG+="uaccess", GROUP="plugdev", MODE="0660" # BioPass FIDO2 K33 by Feitian Technologies Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e", ATTRS{idProduct}=="0866", TAG+="uaccess", GROUP="plugdev", MODE="0660" # BioPass FIDO2 K43 by Feitian Technologies Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e", ATTRS{idProduct}=="0867", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Hypersecu HyperFIDO by Feitian Technologies Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="096e", ATTRS{idProduct}=="0880", TAG+="uaccess", GROUP="plugdev", MODE="0660" # YubiKey NEO FIDO by Yubico AB KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0113", TAG+="uaccess", GROUP="plugdev", MODE="0660" # YubiKey NEO OTP+FIDO by Yubico AB KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0114", TAG+="uaccess", GROUP="plugdev", MODE="0660" # YubiKey NEO FIDO+CCID by Yubico AB KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0115", TAG+="uaccess", GROUP="plugdev", MODE="0660" # YubiKey NEO OTP+FIDO+CCID by Yubico AB KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0116", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Security Key by Yubico by Yubico AB KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0120", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Unknown product by Yubico AB KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0121", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Gnubby U2F by Yubico AB KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0200", TAG+="uaccess", GROUP="plugdev", MODE="0660" # YubiKey 4 FIDO by Yubico AB KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0402", TAG+="uaccess", GROUP="plugdev", MODE="0660" # YubiKey 4 OTP+FIDO by Yubico AB KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0403", TAG+="uaccess", GROUP="plugdev", MODE="0660" # YubiKey 4 FIDO+CCID by Yubico AB KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0406", TAG+="uaccess", GROUP="plugdev", MODE="0660" # YubiKey 4 OTP+FIDO+CCID by Yubico AB KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0407", TAG+="uaccess", GROUP="plugdev", MODE="0660" # YubiKey Plus by Yubico AB KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0410", TAG+="uaccess", GROUP="plugdev", MODE="0660" # U2F Zero by Silicon Laboratories, Inc. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="8acf", TAG+="uaccess", GROUP="plugdev", MODE="0660" # SoloKeys SoloHacker by pid.codes KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="5070", TAG+="uaccess", GROUP="plugdev", MODE="0660" # SoloKeys SoloBoot by pid.codes KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="50b0", TAG+="uaccess", GROUP="plugdev", MODE="0660" # SatoshiLabs TREZOR by pid.codes KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="53c1", TAG+="uaccess", GROUP="plugdev", MODE="0660" # SoloKeys v2 by pid.codes KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="beee", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Google Titan U2F by Google Inc. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="5026", TAG+="uaccess", GROUP="plugdev", MODE="0660" # VASCO SecureClick by VASCO Data Security NV KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1a44", ATTRS{idProduct}=="00bb", TAG+="uaccess", GROUP="plugdev", MODE="0660" # OnlyKey (FIDO2/U2F) by OpenMoko, Inc. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="60fc", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Neowave Keydo AES by NEOWAVE KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1e0d", ATTRS{idProduct}=="f1ae", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Neowave Keydo by NEOWAVE KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1e0d", ATTRS{idProduct}=="f1d0", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Thethis Key by Shenzhen Excelsecu Data Technology Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1ea8", ATTRS{idProduct}=="f025", TAG+="uaccess", GROUP="plugdev", MODE="0660" # ExcelSecu FIDO2 Security Key by Shenzhen Excelsecu Data Technology Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1ea8", ATTRS{idProduct}=="fc25", TAG+="uaccess", GROUP="plugdev", MODE="0660" # GoTrust Idem Key by NXP Semiconductors KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="f143", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Nitrokey FIDO U2F by Clay Logic KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="4287", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Nitrokey FIDO2 by Clay Logic KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="42b1", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Nitrokey 3C NFC by Clay Logic KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="42b2", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Safetech SafeKey by Clay Logic KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="42b3", TAG+="uaccess", GROUP="plugdev", MODE="0660" # CanoKey by Clay Logic KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="42d4", TAG+="uaccess", GROUP="plugdev", MODE="0660" # JaCarta U2F by Aladdin Software Security R.D. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="24dc", ATTRS{idProduct}=="0101", TAG+="uaccess", GROUP="plugdev", MODE="0660" # JaCarta U2F by Aladdin Software Security R.D. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="24dc", ATTRS{idProduct}=="0501", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Happlink Security Key by Plug‐up KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2581", ATTRS{idProduct}=="f1d0", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Bluink Key by Bluink Ltd KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2abe", ATTRS{idProduct}=="1002", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Ledger Blue by LEDGER KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0000", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Ledger Nano S Old firmware by LEDGER KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0001", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Ledger Nano X Old firmware by LEDGER KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0004", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Ledger Blue by LEDGER KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0011", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Ledger Blue Legacy by LEDGER KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0015", TAG+="uaccess", GROUP="plugdev", MODE="0660" -# Ledger Nano S by LEDGER +# Ledger Nano S HID+U2F by LEDGER +KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="1005", TAG+="uaccess", GROUP="plugdev", MODE="0660" + +# Ledger Nano S HID+WEBUSB by LEDGER KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="1011", TAG+="uaccess", GROUP="plugdev", MODE="0660" -# Ledger Nano S Legacy by LEDGER +# Ledger Nano S HID+U2F+WEBUSB by LEDGER KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="1015", TAG+="uaccess", GROUP="plugdev", MODE="0660" -# Ledger Nano X by LEDGER +# Ledger Nano X HID+U2F by LEDGER +KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="4005", TAG+="uaccess", GROUP="plugdev", MODE="0660" + +# Ledger Nano X HID+WEBUSB by LEDGER KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="4011", TAG+="uaccess", GROUP="plugdev", MODE="0660" -# Ledger Nano X Legacy by LEDGER +# Ledger Nano X HID+U2F+WEBUSB by LEDGER KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="4015", TAG+="uaccess", GROUP="plugdev", MODE="0660" +# Ledger Nano S+ HID+U2F by LEDGER +KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="5005", TAG+="uaccess", GROUP="plugdev", MODE="0660" + +# Ledger Nano S+ HID+WEBUSB by LEDGER +KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="5011", TAG+="uaccess", GROUP="plugdev", MODE="0660" + +# Ledger Nano S+ HID+U2F+WEBUSB by LEDGER +KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="5015", TAG+="uaccess", GROUP="plugdev", MODE="0660" + +# Ledger Stax HID+U2F by LEDGER +KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="6005", TAG+="uaccess", GROUP="plugdev", MODE="0660" + +# Ledger Stax HID+WEBUSB by LEDGER +KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="6011", TAG+="uaccess", GROUP="plugdev", MODE="0660" + +# Ledger stax HID+U2F+WEBUSB by LEDGER +KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="6015", TAG+="uaccess", GROUP="plugdev", MODE="0660" + # Hypersecu HyperFIDO by Hypersecu Information Systems, Inc. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2ccf", ATTRS{idProduct}=="0880", TAG+="uaccess", GROUP="plugdev", MODE="0660" # TrustKey Solutions FIDO2 G310 by eWBM Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="311f", ATTRS{idProduct}=="4a1a", TAG+="uaccess", GROUP="plugdev", MODE="0660" # TrustKey Solutions FIDO2 G310H/G320H by eWBM Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="311f", ATTRS{idProduct}=="4a2a", TAG+="uaccess", GROUP="plugdev", MODE="0660" # TrustKey Solutions FIDO2 G320 by eWBM Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="311f", ATTRS{idProduct}=="4c2a", TAG+="uaccess", GROUP="plugdev", MODE="0660" # eWBM FIDO2 Goldengate G500 by eWBM Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="311f", ATTRS{idProduct}=="5c2f", TAG+="uaccess", GROUP="plugdev", MODE="0660" # TrustKey Solutions FIDO2 T120 by eWBM Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="311f", ATTRS{idProduct}=="a6e9", TAG+="uaccess", GROUP="plugdev", MODE="0660" # TrustKey Solutions FIDO2 T110 by eWBM Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="311f", ATTRS{idProduct}=="a7f9", TAG+="uaccess", GROUP="plugdev", MODE="0660" # eWBM FIDO2 Goldengate G450 by eWBM Co., Ltd. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="311f", ATTRS{idProduct}=="f47c", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Idem Key by GoTrustID Inc. KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="32a3", ATTRS{idProduct}=="3201", TAG+="uaccess", GROUP="plugdev", MODE="0660" # Longmai mFIDO by Unknown vendor KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="4c4d", ATTRS{idProduct}=="f703", TAG+="uaccess", GROUP="plugdev", MODE="0660" # SatoshiLabs TREZOR by SatoshiLabs KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="534c", ATTRS{idProduct}=="0001", TAG+="uaccess", GROUP="plugdev", MODE="0660" LABEL="fido_end" diff --git a/contrib/libfido2/udev/fidodevs b/contrib/libfido2/udev/fidodevs index 196e92f0b100..ba626965fa67 100644 --- a/contrib/libfido2/udev/fidodevs +++ b/contrib/libfido2/udev/fidodevs @@ -1,129 +1,137 @@ # Copyright (c) 2020 Yubico AB. All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. # SPDX-License-Identifier: BSD-2-Clause # After modifying this file, regenerate 70-u2f.rules: # ./genrules.awk fidodevs > 70-u2f.rules # List of known vendors. Sorted by vendor ID. vendor STMICRO 0x0483 STMicroelectronics vendor INFINEON 0x058b Infineon Technologies vendor SYNAPTICS 0x06cb Synaptics Inc. vendor FEITIAN 0x096e Feitian Technologies Co., Ltd. vendor YUBICO 0x1050 Yubico AB vendor SILICON 0x10c4 Silicon Laboratories, Inc. vendor PIDCODES 0x1209 pid.codes vendor GOOGLE 0x18d1 Google Inc. vendor VASCO 0x1a44 VASCO Data Security NV vendor OPENMOKO 0x1d50 OpenMoko, Inc. vendor NEOWAVE 0x1e0d NEOWAVE vendor EXCELSECU 0x1ea8 Shenzhen Excelsecu Data Technology Co., Ltd. vendor NXP 0x1fc9 NXP Semiconductors vendor CLAYLOGIC 0x20a0 Clay Logic vendor ALLADIN 0x24dc Aladdin Software Security R.D. vendor PLUGUP 0x2581 Plug‐up vendor BLUINK 0x2abe Bluink Ltd vendor LEDGER 0x2c97 LEDGER vendor HYPERSECU 0x2ccf Hypersecu Information Systems, Inc. vendor EWBM 0x311f eWBM Co., Ltd. vendor GOTRUST 0x32a3 GoTrustID Inc. vendor UNKNOWN1 0x4c4d Unknown vendor vendor SATOSHI 0x534c SatoshiLabs # List of known products. Grouped by vendor; sorted by product ID. product STMICRO 0xa2ac ellipticSecure MIRKey product STMICRO 0xa2ca Unknown product product STMICRO 0xcdab Unknown product product INFINEON 0x022d Infineon FIDO product SYNAPTICS 0x0088 Kensington VeriMark product FEITIAN 0x0850 FS ePass FIDO product FEITIAN 0x0852 Unknown product product FEITIAN 0x0853 Unknown product product FEITIAN 0x0854 Unknown product product FEITIAN 0x0856 Unknown product product FEITIAN 0x0858 Unknown product product FEITIAN 0x085a FS MultiPass FIDO U2F product FEITIAN 0x085b Unknown product product FEITIAN 0x085d Unknown product product FEITIAN 0x0866 BioPass FIDO2 K33 product FEITIAN 0x0867 BioPass FIDO2 K43 product FEITIAN 0x0880 Hypersecu HyperFIDO product YUBICO 0x0113 YubiKey NEO FIDO product YUBICO 0x0114 YubiKey NEO OTP+FIDO product YUBICO 0x0115 YubiKey NEO FIDO+CCID product YUBICO 0x0116 YubiKey NEO OTP+FIDO+CCID product YUBICO 0x0120 Security Key by Yubico product YUBICO 0x0121 Unknown product product YUBICO 0x0200 Gnubby U2F product YUBICO 0x0402 YubiKey 4 FIDO product YUBICO 0x0403 YubiKey 4 OTP+FIDO product YUBICO 0x0406 YubiKey 4 FIDO+CCID product YUBICO 0x0407 YubiKey 4 OTP+FIDO+CCID product YUBICO 0x0410 YubiKey Plus product SILICON 0x8acf U2F Zero product PIDCODES 0x5070 SoloKeys SoloHacker product PIDCODES 0x50b0 SoloKeys SoloBoot product PIDCODES 0x53c1 SatoshiLabs TREZOR product PIDCODES 0xbeee SoloKeys v2 product GOOGLE 0x5026 Google Titan U2F product VASCO 0x00bb VASCO SecureClick product OPENMOKO 0x60fc OnlyKey (FIDO2/U2F) product NEOWAVE 0xf1ae Neowave Keydo AES product NEOWAVE 0xf1d0 Neowave Keydo product EXCELSECU 0xf025 Thethis Key product EXCELSECU 0xfc25 ExcelSecu FIDO2 Security Key product NXP 0xf143 GoTrust Idem Key product CLAYLOGIC 0x4287 Nitrokey FIDO U2F product CLAYLOGIC 0x42b1 Nitrokey FIDO2 product CLAYLOGIC 0x42b2 Nitrokey 3C NFC product CLAYLOGIC 0x42b3 Safetech SafeKey product CLAYLOGIC 0x42d4 CanoKey product ALLADIN 0x0101 JaCarta U2F product ALLADIN 0x0501 JaCarta U2F product PLUGUP 0xf1d0 Happlink Security Key product BLUINK 0x1002 Bluink Key product LEDGER 0x0000 Ledger Blue product LEDGER 0x0001 Ledger Nano S Old firmware product LEDGER 0x0004 Ledger Nano X Old firmware product LEDGER 0x0011 Ledger Blue product LEDGER 0x0015 Ledger Blue Legacy -product LEDGER 0x1011 Ledger Nano S -product LEDGER 0x1015 Ledger Nano S Legacy -product LEDGER 0x4011 Ledger Nano X -product LEDGER 0x4015 Ledger Nano X Legacy +product LEDGER 0x1005 Ledger Nano S HID+U2F +product LEDGER 0x1011 Ledger Nano S HID+WEBUSB +product LEDGER 0x1015 Ledger Nano S HID+U2F+WEBUSB +product LEDGER 0x4005 Ledger Nano X HID+U2F +product LEDGER 0x4011 Ledger Nano X HID+WEBUSB +product LEDGER 0x4015 Ledger Nano X HID+U2F+WEBUSB +product LEDGER 0x5005 Ledger Nano S+ HID+U2F +product LEDGER 0x5011 Ledger Nano S+ HID+WEBUSB +product LEDGER 0x5015 Ledger Nano S+ HID+U2F+WEBUSB +product LEDGER 0x6005 Ledger Stax HID+U2F +product LEDGER 0x6011 Ledger Stax HID+WEBUSB +product LEDGER 0x6015 Ledger stax HID+U2F+WEBUSB product HYPERSECU 0x0880 Hypersecu HyperFIDO product EWBM 0x4a1a TrustKey Solutions FIDO2 G310 product EWBM 0x4a2a TrustKey Solutions FIDO2 G310H/G320H product EWBM 0x4c2a TrustKey Solutions FIDO2 G320 product EWBM 0x5c2f eWBM FIDO2 Goldengate G500 product EWBM 0xa6e9 TrustKey Solutions FIDO2 T120 product EWBM 0xa7f9 TrustKey Solutions FIDO2 T110 product EWBM 0xf47c eWBM FIDO2 Goldengate G450 product GOTRUST 0x3201 Idem Key product UNKNOWN1 0xf703 Longmai mFIDO product SATOSHI 0x0001 SatoshiLabs TREZOR diff --git a/contrib/libfido2/windows/build.ps1 b/contrib/libfido2/windows/build.ps1 index 52a1d6692de4..ff43d8b8962f 100644 --- a/contrib/libfido2/windows/build.ps1 +++ b/contrib/libfido2/windows/build.ps1 @@ -1,242 +1,243 @@ # Copyright (c) 2021-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. # SPDX-License-Identifier: BSD-2-Clause param( [string]$CMakePath = "C:\Program Files\CMake\bin\cmake.exe", [string]$GitPath = "C:\Program Files\Git\bin\git.exe", [string]$SevenZPath = "C:\Program Files\7-Zip\7z.exe", [string]$GPGPath = "C:\Program Files (x86)\GnuPG\bin\gpg.exe", [string]$WinSDK = "", [string]$Config = "Release", [string]$Arch = "x64", [string]$Type = "dynamic", [string]$Fido2Flags = "" ) $ErrorActionPreference = "Stop" [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 . "$PSScriptRoot\const.ps1" Function ExitOnError() { if ($LastExitCode -ne 0) { throw "A command exited with status $LastExitCode" } } Function GitClone(${REPO}, ${BRANCH}, ${DIR}) { Write-Host "Cloning ${REPO}..." & $Git -c advice.detachedHead=false clone --quiet --depth=1 ` --branch "${BRANCH}" "${REPO}" "${DIR}" Write-Host "${REPO}'s ${BRANCH} HEAD is:" & $Git -C "${DIR}" show -s HEAD } # Find Git. $Git = $(Get-Command git -ErrorAction Ignore | ` Select-Object -ExpandProperty Source) if ([string]::IsNullOrEmpty($Git)) { $Git = $GitPath } if (-Not (Test-Path $Git)) { throw "Unable to find Git at $Git" } # Find CMake. $CMake = $(Get-Command cmake -ErrorAction Ignore | ` Select-Object -ExpandProperty Source) if ([string]::IsNullOrEmpty($CMake)) { $CMake = $CMakePath } if (-Not (Test-Path $CMake)) { throw "Unable to find CMake at $CMake" } # Find 7z. $SevenZ = $(Get-Command 7z -ErrorAction Ignore | ` Select-Object -ExpandProperty Source) if ([string]::IsNullOrEmpty($SevenZ)) { $SevenZ = $SevenZPath } if (-Not (Test-Path $SevenZ)) { throw "Unable to find 7z at $SevenZ" } # Find GPG. $GPG = $(Get-Command gpg -ErrorAction Ignore | ` Select-Object -ExpandProperty Source) if ([string]::IsNullOrEmpty($GPG)) { $GPG = $GPGPath } if (-Not (Test-Path $GPG)) { throw "Unable to find GPG at $GPG" } # Override CMAKE_SYSTEM_VERSION if $WinSDK is set. if (-Not ([string]::IsNullOrEmpty($WinSDK))) { $CMAKE_SYSTEM_VERSION = "-DCMAKE_SYSTEM_VERSION='$WinSDK'" } else { $CMAKE_SYSTEM_VERSION = '' } Write-Host "WinSDK: $WinSDK" Write-Host "Config: $Config" Write-Host "Arch: $Arch" Write-Host "Type: $Type" Write-Host "Git: $Git" Write-Host "CMake: $CMake" Write-Host "7z: $SevenZ" Write-Host "GPG: $GPG" # Create build directories. New-Item -Type Directory "${BUILD}" -Force New-Item -Type Directory "${BUILD}\${Arch}" -Force New-Item -Type Directory "${BUILD}\${Arch}\${Type}" -Force New-Item -Type Directory "${STAGE}\${LIBRESSL}" -Force New-Item -Type Directory "${STAGE}\${LIBCBOR}" -Force New-Item -Type Directory "${STAGE}\${ZLIB}" -Force # Create output directories. New-Item -Type Directory "${OUTPUT}" -Force New-Item -Type Directory "${OUTPUT}\${Arch}" -Force New-Item -Type Directory "${OUTPUT}\${Arch}\${Type}" -force # Fetch and verify dependencies. Push-Location ${BUILD} try { if (-Not (Test-Path .\${LIBRESSL})) { if (-Not (Test-Path .\${LIBRESSL}.tar.gz -PathType leaf)) { Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz ` -OutFile .\${LIBRESSL}.tar.gz } if (-Not (Test-Path .\${LIBRESSL}.tar.gz.asc -PathType leaf)) { Invoke-WebRequest ${LIBRESSL_URL}/${LIBRESSL}.tar.gz.asc ` -OutFile .\${LIBRESSL}.tar.gz.asc } Copy-Item "$PSScriptRoot\libressl.gpg" -Destination "${BUILD}" & $GPG --list-keys & $GPG --quiet --no-default-keyring --keyring ./libressl.gpg ` --verify .\${LIBRESSL}.tar.gz.asc .\${LIBRESSL}.tar.gz if ($LastExitCode -ne 0) { throw "GPG signature verification failed" } & $SevenZ e .\${LIBRESSL}.tar.gz & $SevenZ x .\${LIBRESSL}.tar Remove-Item -Force .\${LIBRESSL}.tar } if (-Not (Test-Path .\${LIBCBOR})) { GitClone "${LIBCBOR_GIT}" "${LIBCBOR_BRANCH}" ".\${LIBCBOR}" } if (-Not (Test-Path .\${ZLIB})) { GitClone "${ZLIB_GIT}" "${ZLIB_BRANCH}" ".\${ZLIB}" } } catch { throw "Failed to fetch and verify dependencies" } finally { Pop-Location } # Build LibreSSL. Push-Location ${STAGE}\${LIBRESSL} try { & $CMake ..\..\..\${LIBRESSL} -A "${Arch}" ` -DBUILD_SHARED_LIBS="${SHARED}" -DLIBRESSL_TESTS=OFF ` -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" ` -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" ` -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; ` ExitOnError & $CMake --build . --config ${Config} --verbose; ExitOnError & $CMake --build . --config ${Config} --target install --verbose; ` ExitOnError } catch { throw "Failed to build LibreSSL" } finally { Pop-Location } # Build libcbor. Push-Location ${STAGE}\${LIBCBOR} try { & $CMake ..\..\..\${LIBCBOR} -A "${Arch}" ` -DWITH_EXAMPLES=OFF ` -DBUILD_SHARED_LIBS="${SHARED}" ` -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG} /wd4703" ` -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE} /wd4703" ` -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; ` ExitOnError & $CMake --build . --config ${Config} --verbose; ExitOnError & $CMake --build . --config ${Config} --target install --verbose; ` ExitOnError } catch { throw "Failed to build libcbor" } finally { Pop-Location } # Build zlib. Push-Location ${STAGE}\${ZLIB} try { & $CMake ..\..\..\${ZLIB} -A "${Arch}" ` -DBUILD_SHARED_LIBS="${SHARED}" ` -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG}" ` -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE}" ` + -DCMAKE_MSVC_RUNTIME_LIBRARY="${CMAKE_MSVC_RUNTIME_LIBRARY}" ` -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; ` ExitOnError & $CMake --build . --config ${Config} --verbose; ExitOnError & $CMake --build . --config ${Config} --target install --verbose; ` ExitOnError # Patch up zlib's various names. if ("${Type}" -eq "Dynamic") { ((Get-ChildItem -Path "${PREFIX}/lib") -Match "zlib[d]?.lib") | Copy-Item -Destination "${PREFIX}/lib/zlib1.lib" -Force ((Get-ChildItem -Path "${PREFIX}/bin") -Match "zlibd1.dll") | Copy-Item -Destination "${PREFIX}/bin/zlib1.dll" -Force } else { ((Get-ChildItem -Path "${PREFIX}/lib") -Match "zlibstatic[d]?.lib") | Copy-item -Destination "${PREFIX}/lib/zlib1.lib" -Force } } catch { throw "Failed to build zlib" } finally { Pop-Location } # Build libfido2. Push-Location ${STAGE} try { & $CMake ..\..\.. -A "${Arch}" ` -DCMAKE_BUILD_TYPE="${Config}" ` -DBUILD_SHARED_LIBS="${SHARED}" ` -DCBOR_INCLUDE_DIRS="${PREFIX}\include" ` -DCBOR_LIBRARY_DIRS="${PREFIX}\lib" ` -DCBOR_BIN_DIRS="${PREFIX}\bin" ` -DZLIB_INCLUDE_DIRS="${PREFIX}\include" ` -DZLIB_LIBRARY_DIRS="${PREFIX}\lib" ` -DZLIB_BIN_DIRS="${PREFIX}\bin" ` -DCRYPTO_INCLUDE_DIRS="${PREFIX}\include" ` -DCRYPTO_LIBRARY_DIRS="${PREFIX}\lib" ` -DCRYPTO_BIN_DIRS="${PREFIX}\bin" ` -DCRYPTO_LIBRARIES="${CRYPTO_LIBRARIES}" ` -DCMAKE_C_FLAGS_DEBUG="${CFLAGS_DEBUG} ${Fido2Flags}" ` -DCMAKE_C_FLAGS_RELEASE="${CFLAGS_RELEASE} ${Fido2Flags}" ` -DCMAKE_INSTALL_PREFIX="${PREFIX}" "${CMAKE_SYSTEM_VERSION}"; ` ExitOnError & $CMake --build . --config ${Config} --verbose; ExitOnError & $CMake --build . --config ${Config} --target regress --verbose; ` ExitOnError & $CMake --build . --config ${Config} --target install --verbose; ` ExitOnError # Copy DLLs. if ("${SHARED}" -eq "ON") { "cbor.dll", "${CRYPTO_LIBRARIES}.dll", "zlib1.dll" | ` %{ Copy-Item "${PREFIX}\bin\$_" ` -Destination "examples\${Config}" } } } catch { throw "Failed to build libfido2" } finally { Pop-Location } diff --git a/contrib/libfido2/windows/const.ps1 b/contrib/libfido2/windows/const.ps1 index f657846def5e..7fac21e93df0 100644 --- a/contrib/libfido2/windows/const.ps1 +++ b/contrib/libfido2/windows/const.ps1 @@ -1,44 +1,48 @@ # Copyright (c) 2021-2023 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. # SPDX-License-Identifier: BSD-2-Clause # LibreSSL coordinates. New-Variable -Name 'LIBRESSL_URL' ` - -Value 'https://fastly.cdn.openbsd.org/pub/OpenBSD/LibreSSL' ` + -Value 'https://cloudflare.cdn.openbsd.org/pub/OpenBSD/LibreSSL' ` -Option Constant -New-Variable -Name 'LIBRESSL' -Value 'libressl-3.6.2' -Option Constant +New-Variable -Name 'LIBRESSL' -Value 'libressl-3.7.3' -Option Constant New-Variable -Name 'CRYPTO_LIBRARIES' -Value 'crypto-50' -Option Constant # libcbor coordinates. -New-Variable -Name 'LIBCBOR' -Value 'libcbor-0.10.1' -Option Constant -New-Variable -Name 'LIBCBOR_BRANCH' -Value 'v0.10.1' -Option Constant +New-Variable -Name 'LIBCBOR' -Value 'libcbor-0.10.2' -Option Constant +New-Variable -Name 'LIBCBOR_BRANCH' -Value 'v0.10.2' -Option Constant New-Variable -Name 'LIBCBOR_GIT' -Value 'https://github.com/pjk/libcbor' ` -Option Constant # zlib coordinates. -New-Variable -Name 'ZLIB' -Value 'zlib-1.2.13' -Option Constant -New-Variable -Name 'ZLIB_BRANCH' -Value 'v1.2.13' -Option Constant +New-Variable -Name 'ZLIB' -Value 'zlib-1.3' -Option Constant +New-Variable -Name 'ZLIB_BRANCH' -Value 'v1.3' -Option Constant New-Variable -Name 'ZLIB_GIT' -Value 'https://github.com/madler/zlib' ` -Option Constant # Work directories. New-Variable -Name 'BUILD' -Value "$PSScriptRoot\..\build" -Option Constant New-Variable -Name 'OUTPUT' -Value "$PSScriptRoot\..\output" -Option Constant # Prefixes. New-Variable -Name 'STAGE' -Value "${BUILD}\${Arch}\${Type}" -Option Constant New-Variable -Name 'PREFIX' -Value "${OUTPUT}\${Arch}\${Type}" -Option Constant # Build flags. if ("${Type}" -eq "dynamic") { New-Variable -Name 'RUNTIME' -Value '/MD' -Option Constant New-Variable -Name 'SHARED' -Value 'ON' -Option Constant + New-Variable -Name 'CMAKE_MSVC_RUNTIME_LIBRARY' -Option Constant ` + -Value 'MultiThreaded$<$:Debug>DLL' } else { New-Variable -Name 'RUNTIME' -Value '/MT' -Option Constant New-Variable -Name 'SHARED' -Value 'OFF' -Option Constant + New-Variable -Name 'CMAKE_MSVC_RUNTIME_LIBRARY' -Option Constant ` + -Value 'MultiThreaded$<$:Debug>' } New-Variable -Name 'CFLAGS_DEBUG' -Value "${RUNTIME}d /Zi /guard:cf /sdl" ` -Option Constant New-Variable -Name 'CFLAGS_RELEASE' -Value "${RUNTIME} /Zi /guard:cf /sdl" ` -Option Constant diff --git a/lib/libfido2/Makefile b/lib/libfido2/Makefile index dc985e2797ed..10c008967e3d 100644 --- a/lib/libfido2/Makefile +++ b/lib/libfido2/Makefile @@ -1,82 +1,82 @@ PACKAGE=ssh LIB= fido2 PRIVATELIB= DIST= ${SRCTOP}/contrib/libfido2 .PATH: ${DIST}/src ${DIST} SRCS+= aes256.c SRCS+= assert.c SRCS+= authkey.c SRCS+= bio.c SRCS+= blob.c SRCS+= buf.c SRCS+= cbor.c SRCS+= compress.c SRCS+= config.c SRCS+= cred.c SRCS+= credman.c SRCS+= dev.c SRCS+= ecdh.c SRCS+= eddsa.c SRCS+= err.c SRCS+= es256.c SRCS+= es384.c SRCS+= hid_freebsd.c SRCS+= hid_unix.c SRCS+= hid.c SRCS+= info.c SRCS+= io.c SRCS+= iso7816.c SRCS+= largeblob.c SRCS+= log.c SRCS+= pin.c SRCS+= random.c SRCS+= reset.c SRCS+= rs1.c SRCS+= rs256.c SRCS+= time.c SRCS+= touch.c SRCS+= tpm.c SRCS+= types.c SRCS+= u2f.c SRCS+= util.c SRCS+= openbsd-compat/freezero.c SRCS+= openbsd-compat/recallocarray.c CFLAGS+= -I ${DIST}/src -I${SRCTOP}/contrib/libcbor/src -I${.CURDIR}/../libcbor CFLAGS+= -D_FIDO_INTERNAL CFLAGS+= -DHAVE_ARC4RANDOM_BUF CFLAGS+= -DHAVE_ASPRINTF CFLAGS+= -DHAVE_CLOCK_GETTIME CFLAGS+= -DHAVE_DEV_URANDOM CFLAGS+= -DHAVE_ERR_H CFLAGS+= -DHAVE_EXPLICIT_BZERO CFLAGS+= -DHAVE_GETLINE CFLAGS+= -DHAVE_GETOPT CFLAGS+= -DHAVE_GETPAGESIZE CFLAGS+= -DHAVE_GETRANDOM CFLAGS+= -DHAVE_OPENSSLV_H CFLAGS+= -DHAVE_READPASSPHRASE CFLAGS+= -DHAVE_SIGNAL_H CFLAGS+= -DHAVE_STRLCAT CFLAGS+= -DHAVE_STRLCPY CFLAGS+= -DHAVE_STRSEP CFLAGS+= -DHAVE_SYSCONF CFLAGS+= -DHAVE_SYS_RANDOM_H CFLAGS+= -DHAVE_TIMESPECSUB CFLAGS+= -DHAVE_TIMINGSAFE_BCMP CFLAGS+= -DHAVE_UNISTD_H CFLAGS+= -DOPENSSL_API_COMPAT=0x10100000L CFLAGS+= -DTLS=__thread CFLAGS+= -D_FIDO_MAJOR=1 -CFLAGS+= -D_FIDO_MINOR=13 +CFLAGS+= -D_FIDO_MINOR=14 CFLAGS+= -D_FIDO_PATCH=0 LIBADD= crypto z WARNS=2 MAN= .include