diff --git a/.actions/build-linux-i686-w64-mingw32-gcc b/.actions/build-linux-i686-w64-mingw32-gcc index 7d7d4e34..a89578da 100755 --- a/.actions/build-linux-i686-w64-mingw32-gcc +++ b/.actions/build-linux-i686-w64-mingw32-gcc @@ -32,8 +32,8 @@ make -j"$(nproc)" -C build sudo make -C build install cd .. -# Build and install OpenSSL 1.1.1t. -git clone --depth=1 https://github.com/openssl/openssl -b OpenSSL_1_1_1t +# 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- @@ -42,7 +42,7 @@ sudo make install_sw cd .. # Build and install zlib. -git clone --depth=1 https://github.com/madler/zlib -b v1.2.13 +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 \ diff --git a/.actions/build-linux-openssl3-clang b/.actions/build-linux-openssl3-clang index e61eeec8..2383e51a 100755 --- a/.actions/build-linux-openssl3-clang +++ b/.actions/build-linux-openssl3-clang @@ -12,8 +12,8 @@ FAKEROOT="$(mktemp -d)" # Check exports. (cd src && ./diff_exports.sh) -# Build and install OpenSSL 3.0.8. -git clone --branch openssl-3.0.8 \ +# 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}" \ diff --git a/.actions/build-linux-openssl3-gcc b/.actions/build-linux-openssl3-gcc index ac237494..344fc12b 100755 --- a/.actions/build-linux-openssl3-gcc +++ b/.actions/build-linux-openssl3-gcc @@ -8,8 +8,8 @@ ${CC} --version FAKEROOT="$(mktemp -d)" -# Build and install OpenSSL 3.0.8. -git clone --branch openssl-3.0.8 \ +# 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}" \ diff --git a/.actions/build-linux-openssl3-i686-w64-mingw32-gcc b/.actions/build-linux-openssl3-i686-w64-mingw32-gcc index b88d4f50..3bbb141d 100755 --- a/.actions/build-linux-openssl3-i686-w64-mingw32-gcc +++ b/.actions/build-linux-openssl3-i686-w64-mingw32-gcc @@ -32,8 +32,8 @@ make -j"$(nproc)" -C build sudo make -C build install cd .. -# Build and install OpenSSL 3.0.8. -git clone --branch openssl-3.0.8 \ +# 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 \ @@ -43,7 +43,7 @@ sudo make install_sw cd .. # Build and install zlib. -git clone --depth=1 https://github.com/madler/zlib -b v1.2.13 +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 \ diff --git a/.actions/build-osx-clang b/.actions/build-osx-clang index 1815a60a..b4beea22 100755 --- a/.actions/build-osx-clang +++ b/.actions/build-osx-clang @@ -5,7 +5,7 @@ # license that can be found in the LICENSE file. # SPDX-License-Identifier: BSD-2-Clause -export PKG_CONFIG_PATH="$(brew --prefix openssl@1.1)/lib/pkgconfig" +export PKG_CONFIG_PATH="$(brew --prefix openssl@3.0)/lib/pkgconfig" SCAN="$(brew --prefix llvm)/bin/scan-build" # Build, analyze, and install libfido2. diff --git a/.actions/fuzz-linux b/.actions/fuzz-linux index 17d033e6..3f57ac40 100755 --- a/.actions/fuzz-linux +++ b/.actions/fuzz-linux @@ -6,13 +6,13 @@ # SPDX-License-Identifier: BSD-2-Clause LIBCBOR_URL="https://github.com/pjk/libcbor" -LIBCBOR_TAG="v0.10.1" +LIBCBOR_TAG="v0.10.2" LIBCBOR_ASAN="address alignment bounds" LIBCBOR_MSAN="memory" OPENSSL_URL="https://github.com/openssl/openssl" -OPENSSL_TAG="OpenSSL_1_1_1t" +OPENSSL_TAG="openssl-3.0.12" ZLIB_URL="https://github.com/madler/zlib" -ZLIB_TAG="v1.2.13" +ZLIB_TAG="v1.3" ZLIB_ASAN="address alignment bounds undefined" ZLIB_MSAN="memory" FIDO2_ASAN="address bounds fuzzer-no-link implicit-conversion leak" @@ -62,7 +62,7 @@ cd - git clone --depth=1 "${OPENSSL_URL}" -b "${OPENSSL_TAG}" cd openssl ./Configure linux-x86_64-clang "enable-$1" --prefix="${FAKEROOT}" \ - --openssldir="${FAKEROOT}/openssl" + --openssldir="${FAKEROOT}/openssl" --libdir=lib make install_sw cd - diff --git a/.github/workflows/alpine_builds.yml b/.github/workflows/alpine_builds.yml index ece6ba5f..c6d826f3 100644 --- a/.github/workflows/alpine_builds.yml +++ b/.github/workflows/alpine_builds.yml @@ -32,7 +32,7 @@ jobs: - name: fix permissions on workdir run: chown root:wheel "${GITHUB_WORKSPACE}" - name: checkout libfido2 - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: build libfido2 env: CC: ${{ matrix.cc }} diff --git a/.github/workflows/bsd_builds.yml b/.github/workflows/bsd_builds.yml index fdace071..366ea214 100644 --- a/.github/workflows/bsd_builds.yml +++ b/.github/workflows/bsd_builds.yml @@ -20,7 +20,7 @@ jobs: matrix: image: [freebsd/13.x, openbsd/7.2] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: dependencies run: | sudo apt -q update diff --git a/.github/workflows/cifuzz_oss.yml b/.github/workflows/cifuzz_oss.yml index 42e4a6a3..556d5ad3 100644 --- a/.github/workflows/cifuzz_oss.yml +++ b/.github/workflows/cifuzz_oss.yml @@ -39,7 +39,7 @@ jobs: fuzz-seconds: 600 dry-run: false - name: upload crash - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v3 if: failure() with: name: ${{ matrix.sanitizer }}-artifacts diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index de381e9b..a3a8d54d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -16,13 +16,16 @@ on: 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@v2 + uses: actions/checkout@v4 with: fetch-depth: 2 - name: init codeql diff --git a/.github/workflows/cygwin_builds.yml b/.github/workflows/cygwin_builds.yml index 7178d2e4..d8146c54 100644 --- a/.github/workflows/cygwin_builds.yml +++ b/.github/workflows/cygwin_builds.yml @@ -24,7 +24,7 @@ jobs: arch: [ x64 ] config: [ "Debug", "Release" ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: build run: | .\windows\cygwin.ps1 -Config ${{ matrix.config }} diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 64bbfd2a..ec911cb9 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -26,14 +26,14 @@ jobs: - { os: ubuntu-22.04, cc: gcc-10 } - { os: ubuntu-22.04, cc: gcc-11 } - { os: ubuntu-22.04, cc: gcc-12 } - - { os: ubuntu-20.04, cc: clang-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@v2 + - uses: actions/checkout@v4 - name: dependencies run: | sudo apt -q update diff --git a/.github/workflows/linux_fuzz.yml b/.github/workflows/linux_fuzz.yml index aa383539..296c0d9f 100644 --- a/.github/workflows/linux_fuzz.yml +++ b/.github/workflows/linux_fuzz.yml @@ -21,10 +21,10 @@ jobs: fail-fast: false matrix: os: [ ubuntu-22.04 ] - cc: [ clang-15 ] + cc: [ clang-16 ] sanitizer: [ asan, msan ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: dependencies run: | sudo apt -q update diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml index 0fe5bf07..7d84a750 100644 --- a/.github/workflows/macos_builds.yml +++ b/.github/workflows/macos_builds.yml @@ -20,12 +20,12 @@ jobs: strategy: fail-fast: false matrix: - os: [ macos-12, macos-11 ] + os: [ macos-13, macos-12 ] cc: [ clang ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: dependencies - run: brew install libcbor llvm mandoc pkg-config zlib + run: brew install libcbor llvm mandoc openssl@3.0 pkg-config zlib - name: build env: CC: ${{ matrix.cc }} diff --git a/.github/workflows/openssl3.yml b/.github/workflows/openssl3.yml index 4e2a7122..ee70c087 100644 --- a/.github/workflows/openssl3.yml +++ b/.github/workflows/openssl3.yml @@ -24,11 +24,11 @@ jobs: - os: ubuntu-22.04 cc: gcc-11 - os: ubuntu-22.04 - cc: clang-15 + cc: clang-16 - os: ubuntu-22.04 cc: i686-w64-mingw32-gcc-10 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: dependencies env: CC: ${{ matrix.cc }} diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml index 1316ea7c..bfc1eb3c 100644 --- a/.github/workflows/windows_builds.yml +++ b/.github/workflows/windows_builds.yml @@ -25,7 +25,7 @@ jobs: type: [ dynamic, static ] config: [ "Release" ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: build run: | .\windows\build.ps1 -Fido2Flags '/analyze' -Arch ${{ matrix.arch }} ` diff --git a/CMakeLists.txt b/CMakeLists.txt index 256dacbe..d385fa5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,12 +2,12 @@ # 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) @@ -29,7 +29,7 @@ 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}) diff --git a/NEWS b/NEWS index bf648aab..58387ffd 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,13 @@ +* 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: diff --git a/README.adoc b/README.adoc index 44d55989..fb6f3d3e 100644 --- a/README.adoc +++ b/README.adoc @@ -38,7 +38,7 @@ is also available. === 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]. diff --git a/examples/README.adoc b/examples/README.adoc index d44218c2..6151b70b 100644 --- a/examples/README.adoc +++ b/examples/README.adoc @@ -48,7 +48,7 @@ The following examples are 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 @@ -63,7 +63,8 @@ The following examples are provided: 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] diff --git a/examples/cred.c b/examples/cred.c index 576900d9..5a2a27fd 100644 --- a/examples/cred.c +++ b/examples/cred.c @@ -1,5 +1,5 @@ /* - * 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 @@ -36,7 +36,7 @@ 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); } @@ -44,7 +44,8 @@ usage(void) 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; @@ -85,6 +86,11 @@ verify_cred(int type, const char *fmt, const unsigned char *authdata_ptr, 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) @@ -159,11 +165,12 @@ main(int argc, char **argv) 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; @@ -192,6 +199,13 @@ main(int argc, char **argv) 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; @@ -275,6 +289,11 @@ main(int argc, char **argv) if (uv && (r = fido_cred_set_uv(cred, FIDO_OPT_TRUE)) != FIDO_OK) errx(1, "fido_cred_set_uv: %s (0x%x)", fido_strerr(r), r); + /* 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); @@ -296,7 +315,8 @@ main(int argc, char **argv) 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 */ diff --git a/fuzz/Dockerfile b/fuzz/Dockerfile index 9cda3758..7b26e6ec 100644 --- a/fuzz/Dockerfile +++ b/fuzz/Dockerfile @@ -10,7 +10,7 @@ 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/fuzz/Makefile b/fuzz/Makefile index 0e6756f0..55a506bc 100644 --- a/fuzz/Makefile +++ b/fuzz/Makefile @@ -3,7 +3,7 @@ # 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 diff --git a/fuzz/export.gnu b/fuzz/export.gnu index f0fb840d..bc25dd66 100644 --- a/fuzz/export.gnu +++ b/fuzz/export.gnu @@ -20,6 +20,8 @@ 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; diff --git a/fuzz/functions.txt b/fuzz/functions.txt index da7f058d..4ad5a0c8 100644 --- a/fuzz/functions.txt +++ b/fuzz/functions.txt @@ -24,7 +24,9 @@ fido_assert_set_clientdata_hash 8 0 100.00% 6 0 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% @@ -32,8 +34,8 @@ fido_assert_set_uv 2 0 100.00% 4 0 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% @@ -41,6 +43,8 @@ fido_assert_flags 4 0 100.00% 5 0 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% @@ -56,15 +60,15 @@ fido_assert_largeblob_key_ptr 4 0 100.00% 5 0 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% @@ -73,9 +77,9 @@ assert.c:get_es384_hash 16 0 100.00% 17 0 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 @@ -197,7 +201,7 @@ cbor_encode_assert_ext 33 0 100.00% 32 0 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% @@ -213,11 +217,11 @@ cbor.c:cbor_add_arg 13 0 100.00% 21 0 cbor.c:cbor_add_uint8 14 0 100.00% 21 0 100.00% cbor.c:cbor_encode_largeblob_key_ext 6 0 100.00% 6 0 100.00% cbor.c:cbor_encode_hmac_secret_param 59 4 93.22% 66 8 87.88% -cbor.c:get_cose_alg 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% @@ -226,7 +230,7 @@ cbor.c:decode_cred_id_entry 10 0 100.00% 19 0 cbor.c:decode_user_entry 25 0 100.00% 35 0 100.00% cbor.c:decode_rp_entity_entry 15 0 100.00% 25 0 100.00% ------------------------------------------------------------------------------------------------------------------ -TOTAL 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 @@ -248,13 +252,13 @@ fido_dev_set_pin_minlen 1 0 100.00% 4 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 @@ -262,9 +266,9 @@ Name Regions Miss Cover Lines Mis 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% @@ -274,6 +278,7 @@ fido_cred_set_x509 6 0 100.00% 5 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% @@ -329,7 +334,7 @@ cred.c:verify_attstmt 25 2 92.00% 43 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 @@ -472,7 +477,7 @@ es256_pk_set_y 1 0 100.00% 4 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% @@ -480,7 +485,7 @@ es256_pk_verify_sig 7 1 85.71% 13 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 @@ -491,13 +496,13 @@ es384_pk_free 6 0 100.00% 7 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 @@ -848,11 +853,11 @@ TOTAL 24 0 100.00% 23 File '/libfido2/src/rs1.c': Name Regions Miss Cover Lines Miss Cover --------------------------------------------------------------------------------------------------------------------- -rs1_verify_sig 20 1 95.00% 30 3 90.00% -rs1.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 @@ -863,15 +868,15 @@ rs256_pk_free 6 0 100.00% 7 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 diff --git a/fuzz/fuzz_assert.c b/fuzz/fuzz_assert.c index 9f39f3d6..03cb51cb 100644 --- a/fuzz/fuzz_assert.c +++ b/fuzz/fuzz_assert.c @@ -1,5 +1,5 @@ /* - * 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 @@ -467,6 +467,8 @@ test(const struct param *p) 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), diff --git a/fuzz/report.tgz b/fuzz/report.tgz index e984ee9d..9c012635 100644 Binary files a/fuzz/report.tgz and b/fuzz/report.tgz differ diff --git a/fuzz/summary.txt b/fuzz/summary.txt index 0f79600f..adda3acc 100644 --- a/fuzz/summary.txt +++ b/fuzz/summary.txt @@ -11,22 +11,22 @@ openbsd-compat/freezero.c 4 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% @@ -42,8 +42,8 @@ src/pcsc.c 204 1 99.51% 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% @@ -61,4 +61,4 @@ src/fido.h 0 0 - src/fido/err.h 0 0 - 0 0 - 0 0 - src/fido/param.h 0 0 - 0 0 - 0 0 - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -TOTAL 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/man/CMakeLists.txt b/man/CMakeLists.txt index a47767fb..6616e4ea 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -62,6 +62,8 @@ list(APPEND MAN_ALIAS 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 @@ -95,6 +97,7 @@ list(APPEND MAN_ALIAS 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 diff --git a/man/fido2-assert.1 b/man/fido2-assert.1 index 0ee6e094..882b7ab1 100644 --- a/man/fido2-assert.1 +++ b/man/fido2-assert.1 @@ -1,4 +1,4 @@ -.\" 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 @@ -25,7 +25,7 @@ .\" .\" SPDX-License-Identifier: BSD-2-Clause .\" -.Dd $Mdocdate: November 5 2019 $ +.Dd $Mdocdate: July 3 2023 $ .Dt FIDO2-ASSERT 1 .Os .Sh NAME @@ -34,7 +34,7 @@ .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 @@ -175,6 +175,13 @@ 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 diff --git a/man/fido2-cred.1 b/man/fido2-cred.1 index bd82499a..3f181db6 100644 --- a/man/fido2-cred.1 +++ b/man/fido2-cred.1 @@ -1,4 +1,4 @@ -.\" 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 @@ -25,7 +25,7 @@ .\" .\" SPDX-License-Identifier: BSD-2-Clause .\" -.Dd $Mdocdate: November 5 2019 $ +.Dd $Mdocdate: July 3 2023 $ .Dt FIDO2-CRED 1 .Os .Sh NAME @@ -34,7 +34,7 @@ .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 @@ -177,6 +177,13 @@ U2F otherwise. 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 diff --git a/man/fido_assert_new.3 b/man/fido_assert_new.3 index 192625e3..fdc74a90 100644 --- a/man/fido_assert_new.3 +++ b/man/fido_assert_new.3 @@ -1,4 +1,4 @@ -.\" 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 @@ -25,7 +25,7 @@ .\" .\" SPDX-License-Identifier: BSD-2-Clause .\" -.Dd $Mdocdate: April 27 2022 $ +.Dd $Mdocdate: June 19 2023 $ .Dt FIDO_ASSERT_NEW 3 .Os .Sh NAME @@ -37,6 +37,7 @@ .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 , @@ -45,6 +46,7 @@ .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 , @@ -74,6 +76,8 @@ .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" @@ -90,6 +94,8 @@ .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" @@ -184,6 +190,7 @@ 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 , @@ -191,7 +198,7 @@ The .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 @@ -231,6 +238,7 @@ 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 , diff --git a/man/fido_assert_set_authdata.3 b/man/fido_assert_set_authdata.3 index f3a307fd..503e2bfb 100644 --- a/man/fido_assert_set_authdata.3 +++ b/man/fido_assert_set_authdata.3 @@ -25,7 +25,7 @@ .\" .\" 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 @@ -40,7 +40,8 @@ .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 @@ -75,6 +76,8 @@ typedef enum { .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 @@ -226,6 +229,55 @@ 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: @@ -258,4 +310,5 @@ set of functions are defined in .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/regress/assert.c b/regress/assert.c index 98609257..ad31903c 100644 --- a/regress/assert.c +++ b/regress/assert.c @@ -1,5 +1,5 @@ /* - * 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 @@ -230,6 +230,8 @@ empty_assert(fido_dev_t *d, fido_assert_t *a, size_t idx) 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); @@ -496,6 +498,10 @@ junk_authdata(void) 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); } @@ -613,6 +619,47 @@ es256_PKEY(void) 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) { @@ -632,6 +679,7 @@ main(void) bad_cbor_serialize(); rs256_PKEY(); es256_PKEY(); + raw_authdata(); exit(0); } diff --git a/regress/cred.c b/regress/cred.c index e4dc76ac..61e603d1 100644 --- a/regress/cred.c +++ b/regress/cred.c @@ -9,6 +9,8 @@ #include #include +#include +#include #define _FIDO_INTERNAL @@ -2094,7 +2096,7 @@ fmt_none(void) } static void -valid_tpm_rs256_cred(void) +valid_tpm_rs256_cred(bool xfail) { fido_cred_t *c; @@ -2107,7 +2109,8 @@ valid_tpm_rs256_cred(void) 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); @@ -2119,7 +2122,7 @@ valid_tpm_rs256_cred(void) } static void -valid_tpm_es256_cred(void) +valid_tpm_es256_cred(bool xfail) { fido_cred_t *c; @@ -2132,7 +2135,8 @@ valid_tpm_es256_cred(void) 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); @@ -2146,6 +2150,8 @@ valid_tpm_es256_cred(void) int main(void) { + bool xfail = getenv("FIDO_REGRESS_RS1_XFAIL") != NULL; + fido_init(0); empty_cred(); @@ -2172,8 +2178,8 @@ main(void) 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/regress/eddsa.c b/regress/eddsa.c index 06236987..f97f97ce 100644 --- a/regress/eddsa.c +++ b/regress/eddsa.c @@ -123,7 +123,7 @@ valid_key(void) 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())); diff --git a/src/assert.c b/src/assert.c index dabe8b9f..39d63bc9 100644 --- a/src/assert.c +++ b/src/assert.c @@ -1,5 +1,5 @@ /* - * 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 @@ -63,6 +63,10 @@ parse_assert_reply(const cbor_item_t *key, const cbor_item_t *val, void *arg) 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 */ @@ -643,6 +647,34 @@ fido_assert_set_rp(fido_assert_t *assert, const char *id) 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) @@ -745,12 +777,14 @@ 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; } @@ -774,6 +808,7 @@ fido_assert_reset_rx(fido_assert_t *assert) 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); @@ -846,6 +881,24 @@ fido_assert_authdata_len(const fido_assert_t *assert, size_t idx) 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) { @@ -985,6 +1038,7 @@ 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)); } @@ -1010,6 +1064,12 @@ fido_assert_set_authdata(fido_assert_t *assert, size_t idx, 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__); @@ -1042,6 +1102,12 @@ fido_assert_set_authdata_raw(fido_assert_t *assert, size_t idx, 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; diff --git a/src/export.gnu b/src/export.gnu index 604741ed..ea6ca7d3 100644 --- a/src/export.gnu +++ b/src/export.gnu @@ -20,6 +20,8 @@ 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; @@ -49,6 +51,7 @@ 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; diff --git a/src/export.llvm b/src/export.llvm index 0be82953..2a923814 100644 --- a/src/export.llvm +++ b/src/export.llvm @@ -18,6 +18,8 @@ _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 @@ -47,6 +49,7 @@ _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 diff --git a/src/export.msvc b/src/export.msvc index 10f8bd14..c5b2edc0 100644 --- a/src/export.msvc +++ b/src/export.msvc @@ -19,6 +19,8 @@ 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 @@ -48,6 +50,7 @@ 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 diff --git a/src/fido.h b/src/fido.h index 607c44fc..914e3776 100644 --- a/src/fido.h +++ b/src/fido.h @@ -80,6 +80,8 @@ 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); @@ -142,6 +144,7 @@ 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 *); @@ -194,6 +197,7 @@ 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); diff --git a/src/fido/types.h b/src/fido/types.h index cfb4c7a7..01d68200 100644 --- a/src/fido/types.h +++ b/src/fido/types.h @@ -199,6 +199,7 @@ typedef struct _fido_assert_stmt { 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 */ @@ -211,6 +212,7 @@ typedef struct fido_assert_ext { 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 */ diff --git a/src/webauthn.h b/src/webauthn.h index e64236a0..153609b1 100644 --- a/src/webauthn.h +++ b/src/webauthn.h @@ -67,6 +67,11 @@ extern "C" { // - 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 @@ -92,12 +97,39 @@ extern "C" { // - 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 @@ -252,7 +284,8 @@ typedef const WEBAUTHN_CREDENTIALS *PCWEBAUTHN_CREDENTIALS; #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 @@ -285,12 +318,53 @@ typedef struct _WEBAUTHN_CREDENTIAL_LIST { } 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. @@ -306,6 +380,16 @@ typedef struct _WEBAUTHN_CREDENTIAL_DETAILS { // 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; @@ -323,7 +407,7 @@ 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. @@ -340,7 +424,7 @@ typedef const WEBAUTHN_GET_CREDENTIALS_OPTIONS *PCWEBAUTHN_GET_CREDENTIALS_OPTIO // 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. @@ -516,7 +600,9 @@ typedef const WEBAUTHN_EXTENSIONS *PCWEBAUTHN_EXTENSIONS; #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. @@ -585,6 +671,24 @@ typedef struct _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS { // 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; @@ -599,7 +703,8 @@ typedef const WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS *PCWEBAUTHN_AUTHENT #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. @@ -676,6 +781,20 @@ typedef struct _WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS { // 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; @@ -752,7 +871,9 @@ typedef const WEBAUTHN_COMMON_ATTESTATION *PCWEBAUTHN_COMMON_ATTESTATION; #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. @@ -815,6 +936,19 @@ typedef struct _WEBAUTHN_CREDENTIAL_ATTESTATION { 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; @@ -837,7 +971,9 @@ typedef const WEBAUTHN_CREDENTIAL_ATTESTATION *PCWEBAUTHN_CREDENTIAL_ATTESTATION #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. @@ -883,6 +1019,21 @@ typedef struct _WEBAUTHN_ASSERTION { 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; @@ -941,6 +1092,7 @@ WINAPI WebAuthNCancelCurrentOperation( _In_ const GUID* pCancellationId); +// Returns NTE_NOT_FOUND when credentials are not found. HRESULT WINAPI WebAuthNGetPlatformCredentialList( @@ -952,6 +1104,13 @@ 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 diff --git a/src/winhello.c b/src/winhello.c index efc7dc22..ff969a4f 100644 --- a/src/winhello.c +++ b/src/winhello.c @@ -22,6 +22,9 @@ #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 @@ -34,6 +37,7 @@ struct winhello_assert { WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS opt; WEBAUTHN_ASSERTION *assert; wchar_t *rp_id; + wchar_t *appid; }; struct winhello_cred { @@ -194,6 +198,9 @@ to_fido(HRESULT hr) 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; @@ -401,6 +408,10 @@ pack_cred_ext(WEBAUTHN_EXTENSIONS *out, const fido_cred_ext_t *in) } 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; @@ -467,6 +478,43 @@ pack_assert_ext(WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS *out, 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) { @@ -526,7 +574,7 @@ unpack_user_id(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) 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 */ @@ -578,6 +626,10 @@ translate_fido_assert(struct winhello_assert *ctx, const fido_assert_t *assert, 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; @@ -596,8 +648,11 @@ translate_fido_assert(struct winhello_assert *ctx, const fido_assert_t *assert, } 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) { @@ -609,6 +664,7 @@ translate_winhello_assert(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa) 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; @@ -800,6 +856,7 @@ winhello_assert_free(struct winhello_assert *ctx) 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); @@ -928,7 +985,7 @@ fido_winhello_get_assert(fido_dev_t *dev, fido_assert_t *assert, 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; } diff --git a/tools/assert_get.c b/tools/assert_get.c index 8260fb83..32d40b1e 100644 --- a/tools/assert_get.c +++ b/tools/assert_get.c @@ -1,5 +1,5 @@ /* - * 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 @@ -99,7 +99,8 @@ prepare_assert(FILE *in_f, int flags, const struct toggle *opt) 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) { @@ -114,9 +115,12 @@ prepare_assert(FILE *in_f, int flags, const struct toggle *opt) 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)); @@ -222,7 +226,7 @@ assert_get(int argc, char **argv) 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; @@ -256,6 +260,9 @@ assert_get(int argc, char **argv) opt.pin = FIDO_OPT_TRUE; opt.uv = FIDO_OPT_TRUE; break; + case 'w': + flags |= FLAG_CD; + break; default: usage(); } diff --git a/tools/cred_make.c b/tools/cred_make.c index a6239ec2..66c8b52d 100644 --- a/tools/cred_make.c +++ b/tools/cred_make.c @@ -1,5 +1,5 @@ /* - * 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 @@ -37,7 +37,8 @@ prepare_cred(FILE *in_f, int type, int flags) 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); @@ -48,9 +49,13 @@ prepare_cred(FILE *in_f, int type, int flags) 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) @@ -149,7 +154,7 @@ cred_make(int argc, char **argv) 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; @@ -182,6 +187,9 @@ cred_make(int argc, char **argv) case 'v': flags |= FLAG_UV; break; + case 'w': + flags |= FLAG_CD; + break; default: usage(); } diff --git a/tools/extern.h b/tools/extern.h index ed4b348c..b806ddd6 100644 --- a/tools/extern.h +++ b/tools/extern.h @@ -1,5 +1,5 @@ /* - * 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 @@ -23,14 +23,15 @@ struct blob { #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 diff --git a/tools/fido2-assert.c b/tools/fido2-assert.c index d05c5416..351ed4fd 100644 --- a/tools/fido2-assert.c +++ b/tools/fido2-assert.c @@ -1,5 +1,5 @@ /* - * 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 @@ -29,7 +29,7 @@ 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" ); diff --git a/tools/fido2-cred.c b/tools/fido2-cred.c index 965dbf9e..76081c68 100644 --- a/tools/fido2-cred.c +++ b/tools/fido2-cred.c @@ -1,5 +1,5 @@ /* - * 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 @@ -27,7 +27,7 @@ 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" ); diff --git a/udev/70-u2f.rules b/udev/70-u2f.rules index c443f752..6df852b9 100644 --- a/udev/70-u2f.rules +++ b/udev/70-u2f.rules @@ -198,18 +198,42 @@ KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2c97", ATTRS{idProduct # 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" diff --git a/udev/fidodevs b/udev/fidodevs index 196e92f0..ba626965 100644 --- a/udev/fidodevs +++ b/udev/fidodevs @@ -107,10 +107,18 @@ 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 diff --git a/windows/build.ps1 b/windows/build.ps1 index 52a1d669..ff43d8b8 100644 --- a/windows/build.ps1 +++ b/windows/build.ps1 @@ -183,6 +183,7 @@ try { -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 diff --git a/windows/const.ps1 b/windows/const.ps1 index f657846d..7fac21e9 100644 --- a/windows/const.ps1 +++ b/windows/const.ps1 @@ -5,20 +5,20 @@ # 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 @@ -34,9 +34,13 @@ New-Variable -Name 'PREFIX' -Value "${OUTPUT}\${Arch}\${Type}" -Option Constant 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