mirror of
https://github.com/opnsense/src.git
synced 2026-06-04 22:32:43 -04:00
Vendor import of libfido2 1.11.0
This commit is contained in:
parent
3a9b77fea2
commit
cd0b1b947d
72 changed files with 3466 additions and 990 deletions
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2018-2021 Yubico AB. All rights reserved.
|
||||
# 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.
|
||||
|
||||
|
|
@ -28,18 +28,19 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|||
set(CMAKE_COLOR_MAKEFILE OFF)
|
||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
set(FIDO_MAJOR "1")
|
||||
set(FIDO_MINOR "10")
|
||||
set(FIDO_MINOR "11")
|
||||
set(FIDO_PATCH "0")
|
||||
set(FIDO_VERSION ${FIDO_MAJOR}.${FIDO_MINOR}.${FIDO_PATCH})
|
||||
|
||||
option(BUILD_EXAMPLES "Build example programs" ON)
|
||||
option(BUILD_MANPAGES "Build man pages" ON)
|
||||
option(BUILD_SHARED_LIBS "Build the shared library" ON)
|
||||
option(BUILD_STATIC_LIBS "Build the static library" 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(LIBFUZZER "Build libfuzzer harnesses" 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)
|
||||
|
||||
|
|
@ -91,6 +92,7 @@ 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)
|
||||
|
|
@ -116,6 +118,7 @@ try_compile(HAVE_POSIX_IOCTL
|
|||
|
||||
list(APPEND CHECK_VARIABLES
|
||||
HAVE_ARC4RANDOM_BUF
|
||||
HAVE_ASPRINTF
|
||||
HAVE_CBOR_H
|
||||
HAVE_CLOCK_GETTIME
|
||||
HAVE_ENDIAN_H
|
||||
|
|
@ -166,8 +169,8 @@ if(MSVC)
|
|||
"building under msvc")
|
||||
endif()
|
||||
set(CBOR_LIBRARIES cbor)
|
||||
set(ZLIB_LIBRARIES zlib)
|
||||
set(CRYPTO_LIBRARIES crypto-47)
|
||||
set(ZLIB_LIBRARIES zlib1)
|
||||
set(CRYPTO_LIBRARIES crypto-49)
|
||||
set(MSVC_DISABLED_WARNINGS_LIST
|
||||
"C4152" # nonstandard extension used: function/data pointer
|
||||
# conversion in expression;
|
||||
|
|
@ -237,6 +240,17 @@ else()
|
|||
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)
|
||||
|
|
@ -244,7 +258,7 @@ else()
|
|||
endif()
|
||||
|
||||
if(NFC_LINUX)
|
||||
add_definitions(-DNFC_LINUX)
|
||||
add_definitions(-DUSE_NFC)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
|
|
@ -285,10 +299,6 @@ else()
|
|||
add_definitions(-DOPENSSL_API_COMPAT=0x10100000L)
|
||||
endif()
|
||||
|
||||
if(FUZZ)
|
||||
add_definitions(-DFIDO_FUZZ)
|
||||
endif()
|
||||
|
||||
if(LIBFUZZER)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=fuzzer-no-link")
|
||||
endif()
|
||||
|
|
@ -309,6 +319,10 @@ elseif(WIN32)
|
|||
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"))
|
||||
|
|
@ -345,16 +359,18 @@ else()
|
|||
" /def:\"${CMAKE_CURRENT_SOURCE_DIR}/src/export.msvc\"")
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src)
|
||||
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})
|
||||
|
||||
|
|
@ -372,9 +388,14 @@ 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}")
|
||||
|
|
@ -392,6 +413,10 @@ if(USE_HIDAPI)
|
|||
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 "LIBFUZZER: ${LIBFUZZER}")
|
||||
message(STATUS "TLS: ${TLS}")
|
||||
message(STATUS "UDEV_INCLUDE_DIRS: ${UDEV_INCLUDE_DIRS}")
|
||||
|
|
@ -400,10 +425,22 @@ 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_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()
|
||||
|
||||
enable_testing()
|
||||
|
||||
subdirs(src)
|
||||
subdirs(regress)
|
||||
if(BUILD_EXAMPLES)
|
||||
subdirs(examples)
|
||||
endif()
|
||||
|
|
@ -415,10 +452,6 @@ if(BUILD_MANPAGES)
|
|||
endif()
|
||||
|
||||
if(NOT WIN32)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT FUZZ)
|
||||
enable_testing()
|
||||
subdirs(regress)
|
||||
endif()
|
||||
if(FUZZ)
|
||||
subdirs(fuzz)
|
||||
endif()
|
||||
|
|
|
|||
11
NEWS
11
NEWS
|
|
@ -1,3 +1,14 @@
|
|||
* 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.
|
||||
|
|
|
|||
123
README.adoc
123
README.adoc
|
|
@ -7,7 +7,7 @@ image:https://github.com/yubico/libfido2/workflows/fuzzer/badge.svg["Fuzz Status
|
|||
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, and to verify attestation and
|
||||
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.
|
||||
|
|
@ -23,8 +23,6 @@ file for the full license text.
|
|||
|
||||
*libfido2* is known to work on Linux, macOS, Windows, OpenBSD, and FreeBSD.
|
||||
|
||||
NFC support is available on Linux and Windows.
|
||||
|
||||
=== Documentation
|
||||
|
||||
Documentation is available in troff and HTML formats. An
|
||||
|
|
@ -38,19 +36,29 @@ is also available.
|
|||
* 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.11.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
|
||||
|
||||
==== Releases
|
||||
==== Fedora 35 and 34
|
||||
|
||||
The current release of *libfido2* is 1.10.0. Please consult Yubico's
|
||||
https://developers.yubico.com/libfido2/Releases[release page] for source
|
||||
and binary releases.
|
||||
$ sudo dnf install libfido2 libfido2-devel fido2-tools
|
||||
|
||||
==== Ubuntu 20.04 (Focal)
|
||||
==== Ubuntu 22.04 (Jammy) and 20.04 (Focal)
|
||||
|
||||
$ sudo apt install libfido2-1
|
||||
$ sudo apt install libfido2-dev
|
||||
$ sudo apt install libfido2-doc
|
||||
$ 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.
|
||||
|
|
@ -60,33 +68,10 @@ Follow the instructions for Ubuntu 18.04 (Bionic) below.
|
|||
$ sudo apt install software-properties-common
|
||||
$ sudo apt-add-repository ppa:yubico/stable
|
||||
$ sudo apt update
|
||||
$ sudo apt install libfido2-dev
|
||||
$ sudo apt install libfido2-1 libfido2-dev libfido2-doc fido2-tools
|
||||
|
||||
==== macOS
|
||||
|
||||
$ brew install libfido2
|
||||
|
||||
Or 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.
|
||||
|
||||
*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.
|
||||
|
||||
For complete, OS-specific installation instructions, please refer to the
|
||||
`.actions/` (Linux, macOS) and `windows/` directories.
|
||||
|
||||
On Linux, you will need to add a udev rule to be able to access the FIDO
|
||||
device, or run as root. For example, the udev rule may contain the following:
|
||||
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.
|
||||
|
|
@ -94,3 +79,67 @@ device, or run as root. For example, the udev rule may contain the following:
|
|||
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
|
||||
| LIBFUZZER | Build libfuzzer harnesses | 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/.
|
||||
|
|
|
|||
|
|
@ -13,17 +13,6 @@ if(WIN32 AND BUILD_SHARED_LIBS AND NOT CYGWIN AND NOT MSYS)
|
|||
list(APPEND COMPAT_SOURCES ../openbsd-compat/posix_win.c)
|
||||
endif()
|
||||
|
||||
# set the library to link against
|
||||
if(BUILD_STATIC_LIBS)
|
||||
# drop -rdynamic
|
||||
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
|
||||
set(_FIDO2_LIBRARY fido2)
|
||||
elseif(BUILD_SHARED_LIBS)
|
||||
set(_FIDO2_LIBRARY fido2_shared)
|
||||
else()
|
||||
set(_FIDO2_LIBRARY ${CRYPTO_LIBRARIES} fido2)
|
||||
endif()
|
||||
|
||||
# enable -Wconversion -Wsign-conversion
|
||||
if(NOT MSVC)
|
||||
set_source_files_properties(assert.c cred.c info.c manifest.c reset.c
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Yubico AB. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -182,6 +182,16 @@ print_maxcredidlen(uint64_t maxcredidlen)
|
|||
printf("maxcredlen: %d\n", (int)maxcredidlen);
|
||||
}
|
||||
|
||||
/*
|
||||
* Auxiliary function to print the maximum size of an authenticator's
|
||||
* serialized largeBlob array.
|
||||
*/
|
||||
static void
|
||||
print_maxlargeblob(uint64_t maxlargeblob)
|
||||
{
|
||||
printf("maxlargeblob: %d\n", (int)maxlargeblob);
|
||||
}
|
||||
|
||||
/*
|
||||
* Auxiliary function to print an authenticator's firmware version on stdout.
|
||||
*/
|
||||
|
|
@ -264,6 +274,9 @@ getinfo(const char *path)
|
|||
/* print maximum length of a credential ID */
|
||||
print_maxcredidlen(fido_cbor_info_maxcredidlen(ci));
|
||||
|
||||
/* print maximum length of largeBlob array */
|
||||
print_maxlargeblob(fido_cbor_info_maxlargeblob(ci));
|
||||
|
||||
/* print firmware version */
|
||||
print_fwversion(fido_cbor_info_fwversion(ci));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Yubico AB. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -23,7 +23,7 @@ nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
|
|||
return (-1);
|
||||
}
|
||||
|
||||
Sleep(rqtp->tv_nsec / 1000000);
|
||||
Sleep((DWORD)(rqtp->tv_sec * 1000) + (DWORD)(rqtp->tv_nsec / 1000000));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ setpin(const char *path, const char *pin, const char *oldpin)
|
|||
errx(1, "fido_dev_open: %s (0x%x)", fido_strerr(r), r);
|
||||
|
||||
if ((r = fido_dev_set_pin(dev, pin, oldpin)) != FIDO_OK)
|
||||
errx(1, "fido_setpin: %s (0x%x)", fido_strerr(r), r);
|
||||
errx(1, "fido_dev_set_pin: %s (0x%x)", fido_strerr(r), r);
|
||||
|
||||
if ((r = fido_dev_close(dev)) != FIDO_OK)
|
||||
errx(1, "fido_dev_close: %s (0x%x)", fido_strerr(r), r);
|
||||
|
|
|
|||
|
|
@ -61,3 +61,9 @@ add_executable(fuzz_largeblob fuzz_largeblob.c ${COMMON_SOURCES} ${COMPAT_SOURCE
|
|||
target_compile_options(fuzz_largeblob PRIVATE ${FUZZ_LDFLAGS})
|
||||
set_target_properties(fuzz_largeblob PROPERTIES LINK_FLAGS ${FUZZ_LDFLAGS})
|
||||
target_link_libraries(fuzz_largeblob fido2_shared)
|
||||
|
||||
# fuzz_pcsc
|
||||
add_executable(fuzz_pcsc fuzz_pcsc.c ${COMMON_SOURCES} ${COMPAT_SOURCES})
|
||||
target_compile_options(fuzz_pcsc PRIVATE ${FUZZ_LDFLAGS})
|
||||
set_target_properties(fuzz_pcsc PROPERTIES LINK_FLAGS ${FUZZ_LDFLAGS})
|
||||
target_link_libraries(fuzz_pcsc fido2_shared)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
# Copyright (c) 2019-2021 Yubico AB. All rights reserved.
|
||||
# Copyright (c) 2019-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.
|
||||
|
||||
FROM ubuntu:focal
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV CC=clang-14
|
||||
ENV CXX=clang++-14
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y clang-12 cmake git libssl-dev libudev-dev make pkg-config
|
||||
RUN apt-get install -y zlib1g-dev
|
||||
RUN git clone --branch v0.9.0 https://github.com/PJK/libcbor
|
||||
RUN git clone https://github.com/yubico/libfido2
|
||||
RUN CC=clang-12 CXX=clang++-12 /libfido2/fuzz/build-coverage /libcbor /libfido2
|
||||
RUN apt-get install -y cmake git libssl-dev libudev-dev make pkg-config
|
||||
RUN apt-get install -y libpcsclite-dev zlib1g-dev software-properties-common
|
||||
RUN git clone --branch v0.9.0 --depth=1 https://github.com/PJK/libcbor
|
||||
RUN git clone --depth=1 https://github.com/yubico/libfido2
|
||||
WORKDIR /libfido2
|
||||
RUN ./.actions/setup_clang "${CC}"
|
||||
RUN ./fuzz/build-coverage /libcbor /libfido2
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
# Copyright (c) 2019-2021 Yubico AB. All rights reserved.
|
||||
# Copyright (c) 2019-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.
|
||||
|
||||
IMAGE := libfido2-coverage:1.10.0
|
||||
IMAGE := libfido2-coverage:1.11.2
|
||||
RUNNER := libfido2-runner
|
||||
PROFDATA := llvm-profdata-12
|
||||
COV := llvm-cov-12
|
||||
PROFDATA := llvm-profdata-14
|
||||
COV := llvm-cov-14
|
||||
TARGETS := fuzz_assert fuzz_bio fuzz_cred fuzz_credman fuzz_hid \
|
||||
fuzz_largeblob fuzz_netlink fuzz_mgmt
|
||||
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
|
||||
|
|
@ -24,7 +24,7 @@ run: build
|
|||
|
||||
sync: run
|
||||
tar Ccf .. - src fuzz | docker exec -i ${RUNNER} tar Cxf /libfido2 -
|
||||
docker exec ${RUNNER} make -C libfido2/build
|
||||
docker exec ${RUNNER} make -C /libfido2/build
|
||||
|
||||
corpus: sync
|
||||
docker exec ${RUNNER} /bin/sh -c 'cd /libfido2/fuzz && rm -rf ${TARGETS}'
|
||||
|
|
@ -45,23 +45,24 @@ corpus.tgz-: ${MINIFY}
|
|||
|
||||
profdata: run
|
||||
docker exec ${RUNNER} /bin/sh -c 'rm -f /$@ && ${PROFDATA} \
|
||||
merge -sparse profraw/* -o $@'
|
||||
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=/$< \
|
||||
--show-branch-summary=false -output-dir=/report \
|
||||
/libfido2/build/src/libfido2.so'
|
||||
-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 \
|
||||
--show-branch-summary=false /libfido2/build/src/libfido2.so \
|
||||
-instr-profile=/$< > $@
|
||||
-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 \
|
||||
-show-functions --show-branch-summary=false -instr-profile=/$< \
|
||||
-ignore-filename-regex=pcsclite.h -show-functions \
|
||||
--show-branch-summary=false -instr-profile=/$< \
|
||||
/libfido2/build/src/libfido2.so /libfido2/src/*.[ch]' > $@
|
||||
|
||||
clean: run
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Yubico AB. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -18,6 +18,8 @@ const char dummy_rp_name[] = "sweet home localhost";
|
|||
const char dummy_user_icon[] = "an icon";
|
||||
const char dummy_user_name[] = "john smith";
|
||||
const char dummy_user_nick[] = "jsmith";
|
||||
const char dummy_pcsc_list[] = "reader1\0reader2\0reader3\0\0";
|
||||
const char dummy_pcsc_path[] = "pcsc://slot7";
|
||||
const uint8_t dummy_id[] = { 0x5e, 0xd2 };
|
||||
|
||||
const uint8_t dummy_user_id[] = {
|
||||
|
|
|
|||
|
|
@ -85,10 +85,11 @@
|
|||
fido_cbor_info_extensions_len;
|
||||
fido_cbor_info_extensions_ptr;
|
||||
fido_cbor_info_free;
|
||||
fido_cbor_info_maxmsgsiz;
|
||||
fido_cbor_info_maxcredbloblen;
|
||||
fido_cbor_info_maxcredcntlst;
|
||||
fido_cbor_info_maxcredidlen;
|
||||
fido_cbor_info_maxlargeblob;
|
||||
fido_cbor_info_maxmsgsiz;
|
||||
fido_cbor_info_fwversion;
|
||||
fido_cbor_info_new;
|
||||
fido_cbor_info_options_len;
|
||||
|
|
@ -212,6 +213,7 @@
|
|||
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;
|
||||
|
|
@ -237,6 +239,13 @@
|
|||
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;
|
||||
|
|
@ -246,8 +255,11 @@
|
|||
rs256_pk_new;
|
||||
rs256_pk_to_EVP_PKEY;
|
||||
prng_init;
|
||||
prng_up;
|
||||
fuzz_clock_reset;
|
||||
set_netlink_io_functions;
|
||||
set_pcsc_parameters;
|
||||
set_pcsc_io_functions;
|
||||
set_udev_parameters;
|
||||
uniform_random;
|
||||
local:
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
File '/libfido2/src/aes256.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
aes256_cbc_enc 3 0 100.00% 4 0 100.00%
|
||||
aes256_cbc_dec 3 0 100.00% 4 0 100.00%
|
||||
aes256_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 2 92.31% 42 7 83.33%
|
||||
aes256.c:aes256_cbc 29 1 96.55% 36 3 91.67%
|
||||
aes256.c:aes256_cbc_proto1 1 0 100.00% 5 0 100.00%
|
||||
aes256.c:aes256_gcm 51 1 98.04% 60 4 93.33%
|
||||
aes256.c:aes256_gcm 52 1 98.08% 60 4 93.33%
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
TOTAL 115 4 96.52% 157 14 91.08%
|
||||
TOTAL 118 4 96.61% 157 14 91.08%
|
||||
|
||||
File '/libfido2/src/assert.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
|
|
@ -18,7 +18,7 @@ Name Regions Miss Cover Lines Miss
|
|||
fido_dev_get_assert 40 0 100.00% 35 0 100.00%
|
||||
fido_check_flags 13 0 100.00% 15 0 100.00%
|
||||
fido_get_signed_hash 36 0 100.00% 46 0 100.00%
|
||||
fido_assert_verify 48 4 91.67% 67 5 92.54%
|
||||
fido_assert_verify 48 4 91.67% 67 7 89.55%
|
||||
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%
|
||||
|
|
@ -26,7 +26,7 @@ fido_assert_set_hmac_secret 12 12 0.00% 7 7
|
|||
fido_assert_set_rp 12 0 100.00% 11 0 100.00%
|
||||
fido_assert_allow_cred 13 2 84.62% 22 3 86.36%
|
||||
fido_assert_set_extensions 14 0 100.00% 10 0 100.00%
|
||||
fido_assert_set_options 6 6 0.00% 5 5 0.00%
|
||||
fido_assert_set_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%
|
||||
|
|
@ -72,7 +72,7 @@ assert.c:check_extensions 5 0 100.00% 9 0
|
|||
assert.c:fido_assert_reset_extattr 1 0 100.00% 5 0 100.00%
|
||||
assert.c:fido_assert_clean_authdata 1 0 100.00% 5 0 100.00%
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
TOTAL 563 40 92.90% 694 40 94.24%
|
||||
TOTAL 565 42 92.57% 694 42 93.95%
|
||||
|
||||
File '/libfido2/src/authkey.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
|
|
@ -88,10 +88,10 @@ TOTAL 44 0 100.00% 59 0
|
|||
File '/libfido2/src/bio.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
fido_bio_dev_get_template_array 5 2 60.00% 6 0 100.00%
|
||||
fido_bio_dev_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 0 100.00%
|
||||
fido_bio_dev_enroll_continue 5 2 60.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%
|
||||
|
|
@ -138,7 +138,7 @@ bio.c:bio_reset_template_array 4 0 100.00% 7 0
|
|||
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 419 20 95.23% 559 21 96.24%
|
||||
TOTAL 419 20 95.23% 559 24 95.71%
|
||||
|
||||
File '/libfido2/src/blob.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
|
|
@ -187,9 +187,9 @@ cbor_encode_str_array 18 0 100.00% 19 0
|
|||
cbor_encode_cred_ext 55 0 100.00% 50 0 100.00%
|
||||
cbor_encode_cred_opt 13 0 100.00% 11 0 100.00%
|
||||
cbor_encode_assert_opt 13 0 100.00% 11 0 100.00%
|
||||
cbor_encode_pin_auth 20 1 95.00% 22 3 86.36%
|
||||
cbor_encode_pin_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 31 1 96.77% 36 3 91.67%
|
||||
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 21 1 95.24% 30 2 93.33%
|
||||
|
|
@ -200,7 +200,7 @@ cbor_decode_uint64 4 0 100.00% 8 0
|
|||
cbor_decode_cred_id 8 0 100.00% 9 0 100.00%
|
||||
cbor_decode_user 8 0 100.00% 9 0 100.00%
|
||||
cbor_decode_rp_entity 8 0 100.00% 9 0 100.00%
|
||||
cbor_build_uint 10 1 90.00% 9 2 77.78%
|
||||
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 2 88.89% 17 3 82.35%
|
||||
cbor.c:ctap_check_cbor 28 0 100.00% 26 0 100.00%
|
||||
|
|
@ -222,16 +222,18 @@ cbor.c:decode_cred_id_entry 10 0 100.00% 19 0
|
|||
cbor.c:decode_user_entry 25 0 100.00% 35 0 100.00%
|
||||
cbor.c:decode_rp_entity_entry 15 0 100.00% 25 0 100.00%
|
||||
------------------------------------------------------------------------------------------------------------------
|
||||
TOTAL 1047 23 97.80% 1237 46 96.28%
|
||||
TOTAL 1049 23 97.81% 1237 45 96.36%
|
||||
|
||||
File '/libfido2/src/compress.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
------------------------------------------------------------------------------------------------------------------
|
||||
fido_compress 1 0 100.00% 3 0 100.00%
|
||||
fido_uncompress 1 0 100.00% 3 0 100.00%
|
||||
compress.c:do_compress 32 4 87.50% 22 3 86.36%
|
||||
fido_uncompress 6 0 100.00% 5 0 100.00%
|
||||
compress.c:rfc1951_deflate 33 2 93.94% 47 3 93.62%
|
||||
compress.c:rfc1950_inflate 27 2 92.59% 22 4 81.82%
|
||||
compress.c:rfc1951_inflate 38 10 73.68% 45 17 62.22%
|
||||
------------------------------------------------------------------------------------------------------------------
|
||||
TOTAL 34 4 88.24% 28 3 89.29%
|
||||
TOTAL 105 14 86.67% 122 24 80.33%
|
||||
|
||||
File '/libfido2/src/config.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
|
|
@ -255,8 +257,8 @@ 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 56 2 96.43% 72 5 93.06%
|
||||
fido_cred_verify_self 58 4 93.10% 83 5 93.98%
|
||||
fido_cred_verify 56 2 96.43% 72 4 94.44%
|
||||
fido_cred_verify_self 58 4 93.10% 83 7 91.57%
|
||||
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_rx 1 0 100.00% 7 0 100.00%
|
||||
|
|
@ -273,13 +275,13 @@ fido_cred_set_clientdata_hash 8 0 100.00% 6
|
|||
fido_cred_set_rp 18 0 100.00% 22 0 100.00%
|
||||
fido_cred_set_user 32 0 100.00% 41 0 100.00%
|
||||
fido_cred_set_extensions 16 0 100.00% 10 0 100.00%
|
||||
fido_cred_set_options 6 6 0.00% 5 5 0.00%
|
||||
fido_cred_set_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 2 84.62% 8 1 87.50%
|
||||
fido_cred_set_fmt 20 4 80.00% 12 1 91.67%
|
||||
fido_cred_set_fmt 20 4 80.00% 12 2 83.33%
|
||||
fido_cred_set_type 17 0 100.00% 7 0 100.00%
|
||||
fido_cred_type 1 0 100.00% 3 0 100.00%
|
||||
fido_cred_flags 1 0 100.00% 3 0 100.00%
|
||||
|
|
@ -319,11 +321,11 @@ cred.c:fido_dev_make_cred_rx 29 0 100.00% 32
|
|||
cred.c:parse_makecred_reply 14 0 100.00% 27 0 100.00%
|
||||
cred.c:check_extensions 2 0 100.00% 6 0 100.00%
|
||||
cred.c:get_signed_hash_u2f 27 0 100.00% 26 0 100.00%
|
||||
cred.c:verify_attstmt 23 2 91.30% 40 5 87.50%
|
||||
cred.c:verify_attstmt 23 2 91.30% 40 6 85.00%
|
||||
cred.c:fido_cred_clean_authdata 1 0 100.00% 8 0 100.00%
|
||||
cred.c:fido_cred_clean_attstmt 1 0 100.00% 8 0 100.00%
|
||||
-------------------------------------------------------------------------------------------------------------------
|
||||
TOTAL 632 34 94.62% 830 36 95.66%
|
||||
TOTAL 634 36 94.32% 830 39 95.30%
|
||||
|
||||
File '/libfido2/src/credman.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
|
|
@ -334,15 +336,15 @@ fido_credman_del_dev_rk 1 0 100.00% 4
|
|||
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 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 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 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%
|
||||
|
|
@ -369,21 +371,17 @@ credman.c:credman_set_dev_rk_wait 11 0 100.00% 8
|
|||
credman.c:credman_reset_rk 4 0 100.00% 9 0 100.00%
|
||||
credman.c:credman_reset_rp 4 0 100.00% 12 0 100.00%
|
||||
-------------------------------------------------------------------------------------------------------------------
|
||||
TOTAL 382 10 97.38% 518 15 97.10%
|
||||
TOTAL 382 10 97.38% 518 18 96.53%
|
||||
|
||||
File '/libfido2/src/dev.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
-------------------------------------------------------------------------------------------------------------------
|
||||
fido_dev_register_manifest_func 10 2 80.00% 14 3 78.57%
|
||||
fido_dev_unregister_manifest_func 7 7 0.00% 11 11 0.00%
|
||||
fido_dev_info_manifest 22 4 81.82% 24 0 100.00%
|
||||
fido_dev_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 5 1 80.00% 19 12 36.84%
|
||||
fido_dev_close 9 2 77.78% 8 0 100.00%
|
||||
fido_dev_open 13 6 53.85% 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_get_touch_begin 50 0 100.00% 59 0 100.00%
|
||||
fido_dev_get_touch_status 17 0 100.00% 20 0 100.00%
|
||||
fido_dev_set_io_functions 18 4 77.78% 14 6 57.14%
|
||||
fido_dev_set_transport_functions 6 2 66.67% 9 3 66.67%
|
||||
fido_dev_io_handle 1 1 0.00% 3 3 0.00%
|
||||
|
|
@ -410,17 +408,17 @@ fido_dev_force_fido2 2 2 0.00% 3
|
|||
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:find_manifest_func_node 5 0 100.00% 8 0 100.00%
|
||||
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 15 73.21% 56 26 53.57%
|
||||
dev.c:set_random_report_len 11 0 100.00% 6 0 100.00%
|
||||
dev.c:fido_dev_open_rx 36 1 97.22% 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 29 0 100.00% 18 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 421 79 81.24% 491 105 78.62%
|
||||
TOTAL 332 71 78.61% 378 86 77.25%
|
||||
|
||||
File '/libfido2/src/ecdh.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
|
|
@ -438,15 +436,15 @@ Name Regions Miss Cover Lines Mis
|
|||
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 6 0 100.00% 6 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 14 0 100.00% 10 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 80 3 96.25% 106 8 92.45%
|
||||
TOTAL 88 5 94.32% 114 9 92.11%
|
||||
|
||||
File '/libfido2/src/err.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
|
|
@ -464,21 +462,21 @@ es256_sk_new 1 0 100.00% 3
|
|||
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 11 0 100.00% 10 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% 41 0 100.00%
|
||||
es256_pk_to_EVP_PKEY 42 0 100.00% 54 0 100.00%
|
||||
es256_pk_from_EC_KEY 38 0 100.00% 36 0 100.00%
|
||||
es256_pk_from_EVP_PKEY 7 2 71.43% 7 0 100.00%
|
||||
es256_sk_to_EVP_PKEY 28 0 100.00% 40 0 100.00%
|
||||
es256_derive_pk 25 0 100.00% 30 0 100.00%
|
||||
es256_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_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 306 5 98.37% 358 7 98.04%
|
||||
TOTAL 315 7 97.78% 372 12 96.77%
|
||||
|
||||
File '/libfido2/src/extern.h':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
|
|
@ -511,7 +509,7 @@ TOTAL 87 2 97.70% 145
|
|||
File '/libfido2/src/hid_linux.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
-------------------------------------------------------------------------------------------------------------------
|
||||
fido_hid_manifest 35 4 88.57% 41 1 97.56%
|
||||
fido_hid_manifest 35 4 88.57% 41 2 95.12%
|
||||
fido_hid_open 27 27 0.00% 40 40 0.00%
|
||||
fido_hid_close 3 3 0.00% 6 6 0.00%
|
||||
fido_hid_set_sigmask 2 2 0.00% 6 6 0.00%
|
||||
|
|
@ -526,15 +524,15 @@ hid_linux.c:parse_uevent 12 0 100.00% 24
|
|||
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 173 68 60.69% 250 104 58.40%
|
||||
TOTAL 173 68 60.69% 250 105 58.00%
|
||||
|
||||
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 10 9 10.00% 21 10 52.38%
|
||||
fido_hid_unix_wait 11 10 9.09% 21 12 42.86%
|
||||
-------------------------------------------------------------------------------------------------------------------
|
||||
TOTAL 28 20 28.57% 43 24 44.19%
|
||||
TOTAL 29 21 27.59% 43 26 39.53%
|
||||
|
||||
File '/libfido2/src/info.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
|
|
@ -559,6 +557,7 @@ fido_cbor_info_maxcredbloblen 1 0 100.00% 3
|
|||
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_protocols_ptr 1 0 100.00% 3 0 100.00%
|
||||
fido_cbor_info_protocols_len 1 0 100.00% 3 0 100.00%
|
||||
|
|
@ -567,7 +566,7 @@ fido_cbor_info_algorithm_type 4 0 100.00% 5
|
|||
fido_cbor_info_algorithm_cose 4 0 100.00% 5 0 100.00%
|
||||
info.c:fido_dev_get_cbor_info_tx 8 0 100.00% 9 0 100.00%
|
||||
info.c:fido_dev_get_cbor_info_rx 6 0 100.00% 14 0 100.00%
|
||||
info.c:parse_reply_element 19 0 100.00% 37 0 100.00%
|
||||
info.c:parse_reply_element 20 0 100.00% 39 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%
|
||||
|
|
@ -579,37 +578,37 @@ info.c:decode_algorithms 12 0 100.00% 17
|
|||
info.c:decode_algorithm 9 0 100.00% 17 0 100.00%
|
||||
info.c:decode_algorithm_entry 20 0 100.00% 27 0 100.00%
|
||||
-------------------------------------------------------------------------------------------------------------------
|
||||
TOTAL 184 0 100.00% 316 0 100.00%
|
||||
TOTAL 186 0 100.00% 321 0 100.00%
|
||||
|
||||
File '/libfido2/src/io.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
-------------------------------------------------------------------------------------------------------------------
|
||||
fido_tx 13 0 100.00% 11 0 100.00%
|
||||
fido_tx 14 0 100.00% 11 0 100.00%
|
||||
fido_rx 13 1 92.31% 14 3 78.57%
|
||||
fido_rx_cbor_status 8 0 100.00% 10 0 100.00%
|
||||
io.c:transport_tx 7 0 100.00% 10 0 100.00%
|
||||
io.c:tx_empty 9 0 100.00% 14 0 100.00%
|
||||
io.c:tx_pkt 7 0 100.00% 10 0 100.00%
|
||||
io.c:tx 13 0 100.00% 19 0 100.00%
|
||||
io.c:tx_preamble 16 1 93.75% 20 1 95.00%
|
||||
io.c:tx_frame 15 1 93.33% 18 1 94.44%
|
||||
io.c: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 1 98.08%
|
||||
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 182 7 96.15% 221 11 95.02%
|
||||
TOTAL 185 7 96.22% 221 12 94.57%
|
||||
|
||||
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 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 0 100.00%
|
||||
TOTAL 18 1 94.44% 38 1 97.37%
|
||||
|
||||
File '/libfido2/src/largeblob.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
|
|
@ -620,7 +619,7 @@ fido_dev_largeblob_remove 12 0 100.00% 18
|
|||
fido_dev_largeblob_get_array 15 2 86.67% 27 4 85.19%
|
||||
fido_dev_largeblob_set_array 14 0 100.00% 19 0 100.00%
|
||||
largeblob.c:largeblob_get_array 32 0 100.00% 36 0 100.00%
|
||||
largeblob.c:get_chunklen 9 1 88.89% 9 0 100.00%
|
||||
largeblob.c: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 15 0 100.00% 21 0 100.00%
|
||||
largeblob.c:parse_largeblob_reply 8 0 100.00% 9 0 100.00%
|
||||
|
|
@ -629,7 +628,7 @@ largeblob.c:largeblob_array_digest 10 0 100.00% 9
|
|||
largeblob.c:largeblob_array_load 14 2 85.71% 19 7 63.16%
|
||||
largeblob.c:largeblob_array_lookup 25 0 100.00% 33 0 100.00%
|
||||
largeblob.c:largeblob_decode 16 2 87.50% 16 6 62.50%
|
||||
largeblob.c:largeblob_do_decode 27 3 88.89% 30 5 83.33%
|
||||
largeblob.c:largeblob_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%
|
||||
|
|
@ -645,34 +644,34 @@ largeblob.c:largeblob_get_uv_token 19 0 100.00% 23
|
|||
largeblob.c:largeblob_set_tx 35 0 100.00% 36 0 100.00%
|
||||
largeblob.c:prepare_hmac 13 2 84.62% 23 7 69.57%
|
||||
-------------------------------------------------------------------------------------------------------------------
|
||||
TOTAL 513 19 96.30% 684 43 93.71%
|
||||
TOTAL 514 19 96.30% 684 46 93.27%
|
||||
|
||||
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 0 100.00%
|
||||
fido_log_xxd 16 1 93.75% 24 0 100.00%
|
||||
fido_log_error 8 2 75.00% 11 1 90.91%
|
||||
fido_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 4 93.65%
|
||||
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 1 94.44% 24 3 87.50%
|
||||
fido_nl_get_nfc_target 17 1 94.12% 31 3 90.32%
|
||||
fido_nl_free 10 2 80.00% 9 1 88.89%
|
||||
fido_nl_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 14 1 92.86% 17 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%
|
||||
|
|
@ -704,36 +703,62 @@ netlink.c:parse_mcastgrps 1 0 100.00% 3
|
|||
netlink.c:parse_mcastgrp 15 0 100.00% 24 0 100.00%
|
||||
netlink.c:nla_get_str 10 0 100.00% 11 0 100.00%
|
||||
-------------------------------------------------------------------------------------------------------------------
|
||||
TOTAL 328 14 95.73% 498 32 93.57%
|
||||
TOTAL 329 14 95.74% 498 33 93.37%
|
||||
|
||||
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%
|
||||
fido_is_nfc 3 0 100.00% 3 0 100.00%
|
||||
fido_dev_set_nfc 4 4 0.00% 18 18 0.00%
|
||||
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 142 7 95.07% 223 27 87.89%
|
||||
|
||||
File '/libfido2/src/nfc_linux.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
-------------------------------------------------------------------------------------------------------------------
|
||||
fido_nfc_tx 28 0 100.00% 43 0 100.00%
|
||||
fido_nfc_rx 8 1 87.50% 13 3 76.92%
|
||||
fido_nfc_manifest 35 5 85.71% 45 13 71.11%
|
||||
fido_nfc_open 20 3 85.00% 23 5 78.26%
|
||||
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:nfc_do_tx 20 2 90.00% 25 6 76.00%
|
||||
nfc_linux.c:tx_short_apdu 14 0 100.00% 32 0 100.00%
|
||||
nfc_linux.c:rx_init 25 6 76.00% 27 5 81.48%
|
||||
nfc_linux.c:rx_cbor 4 0 100.00% 6 0 100.00%
|
||||
nfc_linux.c:rx_msg 18 2 88.89% 23 6 73.91%
|
||||
nfc_linux.c:rx_apdu 14 1 92.86% 22 3 86.36%
|
||||
nfc_linux.c:tx_get_response 4 0 100.00% 11 0 100.00%
|
||||
nfc_linux.c:copy_info 41 9 78.05% 44 3 93.18%
|
||||
nfc_linux.c:copy_info 41 8 80.49% 47 5 89.36%
|
||||
nfc_linux.c:get_usb_attr 1 0 100.00% 3 0 100.00%
|
||||
nfc_linux.c:get_parent_attr 6 0 100.00% 9 0 100.00%
|
||||
nfc_linux.c:to_int 21 6 71.43% 14 1 92.86%
|
||||
nfc_linux.c:sysnum_from_syspath 12 0 100.00% 17 0 100.00%
|
||||
nfc_linux.c: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 327 73 77.68% 458 124 72.93%
|
||||
TOTAL 174 56 67.82% 245 103 57.96%
|
||||
|
||||
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 27 0 100.00% 37 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 201 1 99.50% 278 3 98.92%
|
||||
|
||||
File '/libfido2/src/pin.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
|
|
@ -744,7 +769,7 @@ fido_dev_set_pin 1 0 100.00% 4
|
|||
fido_dev_get_retry_count 1 0 100.00% 4 0 100.00%
|
||||
fido_dev_get_uv_retry_count 1 0 100.00% 4 0 100.00%
|
||||
cbor_add_uv_params 17 0 100.00% 23 0 100.00%
|
||||
pin.c:uv_token_wait 14 2 85.71% 12 0 100.00%
|
||||
pin.c: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%
|
||||
|
|
@ -765,7 +790,7 @@ pin.c:fido_dev_get_uv_retry_count_wait 10 0 100.00% 7
|
|||
pin.c:fido_dev_get_uv_retry_count_rx 11 0 100.00% 17 0 100.00%
|
||||
pin.c:parse_uv_retry_count 1 0 100.00% 3 0 100.00%
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
TOTAL 403 3 99.26% 495 3 99.39%
|
||||
TOTAL 403 3 99.26% 495 4 99.19%
|
||||
|
||||
File '/libfido2/src/random.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
|
|
@ -786,11 +811,11 @@ TOTAL 24 0 100.00% 23
|
|||
File '/libfido2/src/rs1.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
rs1_verify_sig 20 0 100.00% 30 0 100.00%
|
||||
rs1.c:rs1_get_EVP_MD 4 0 100.00% 6 0 100.00%
|
||||
rs1_verify_sig 20 1 95.00% 30 3 90.00%
|
||||
rs1.c:rs1_get_EVP_MD 4 1 75.00% 6 1 83.33%
|
||||
rs1.c:rs1_free_EVP_MD 1 0 100.00% 3 0 100.00%
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
TOTAL 25 0 100.00% 39 0 100.00%
|
||||
TOTAL 25 2 92.00% 39 4 89.74%
|
||||
|
||||
File '/libfido2/src/rs256.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
|
|
@ -801,7 +826,7 @@ rs256_pk_free 6 0 100.00% 7
|
|||
rs256_pk_from_ptr 6 0 100.00% 6 0 100.00%
|
||||
rs256_pk_to_EVP_PKEY 32 0 100.00% 39 0 100.00%
|
||||
rs256_pk_from_RSA 32 4 87.50% 26 6 76.92%
|
||||
rs256_pk_from_EVP_PKEY 7 2 71.43% 7 0 100.00%
|
||||
rs256_pk_from_EVP_PKEY 7 2 71.43% 7 1 85.71%
|
||||
rs256_verify_sig 20 1 95.00% 30 2 93.33%
|
||||
rs256_pk_verify_sig 7 1 85.71% 13 2 84.62%
|
||||
rs256.c:decode_rsa_pubkey 9 0 100.00% 13 0 100.00%
|
||||
|
|
@ -809,31 +834,39 @@ rs256.c:decode_bignum 8 0 100.00% 10
|
|||
rs256.c:rs256_get_EVP_MD 4 0 100.00% 6 0 100.00%
|
||||
rs256.c:rs256_free_EVP_MD 1 0 100.00% 3 0 100.00%
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
TOTAL 141 8 94.33% 172 10 94.19%
|
||||
TOTAL 141 8 94.33% 172 11 93.60%
|
||||
|
||||
File '/libfido2/src/time.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
fido_time_now 4 0 100.00% 7 0 100.00%
|
||||
fido_time_delta 23 1 95.65% 23 0 100.00%
|
||||
time.c:timespec_to_ms 16 2 87.50% 13 1 92.31%
|
||||
time.c:timespec_to_ms 16 2 87.50% 13 2 84.62%
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
TOTAL 43 3 93.02% 43 1 97.67%
|
||||
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 18 0 100.00% 30 0 100.00%
|
||||
fido_get_signed_hash_tpm 25 1 96.00% 39 3 92.31%
|
||||
tpm.c:check_es256_pubarea 19 1 94.74% 30 3 90.00%
|
||||
tpm.c:bswap_es256_pubarea 1 0 100.00% 12 0 100.00%
|
||||
tpm.c:check_rs256_pubarea 16 0 100.00% 28 0 100.00%
|
||||
tpm.c:check_rs256_pubarea 17 1 94.12% 28 3 89.29%
|
||||
tpm.c:bswap_rs256_pubarea 1 0 100.00% 10 0 100.00%
|
||||
tpm.c:check_sha1_certinfo 14 0 100.00% 38 0 100.00%
|
||||
tpm.c: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 100 0 100.00% 194 0 100.00%
|
||||
TOTAL 103 3 97.09% 194 9 95.36%
|
||||
|
||||
File '/libfido2/src/types.c':
|
||||
Name Regions Miss Cover Lines Miss Cover
|
||||
|
|
@ -869,3 +902,10 @@ u2f.c:parse_auth_reply 23 0 100.00% 23
|
|||
u2f.c:authdata_fake 12 0 100.00% 27 0 100.00%
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
TOTAL 528 4 99.24% 685 12 98.25%
|
||||
|
||||
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%
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Yubico AB. All rights reserved.
|
||||
* Copyright (c) 2019-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.
|
||||
*/
|
||||
|
|
@ -288,6 +288,9 @@ dev_get_cbor_info(const struct param *p)
|
|||
n = fido_cbor_info_maxcredidlen(ci);
|
||||
consume(&n, sizeof(n));
|
||||
|
||||
n = fido_cbor_info_maxlargeblob(ci);
|
||||
consume(&n, sizeof(n));
|
||||
|
||||
n = fido_cbor_info_fwversion(ci);
|
||||
consume(&n, sizeof(n));
|
||||
|
||||
|
|
|
|||
266
fuzz/fuzz_pcsc.c
Normal file
266
fuzz/fuzz_pcsc.c
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define _FIDO_INTERNAL
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <winscard.h>
|
||||
|
||||
#include "mutator_aux.h"
|
||||
#include "wiredata_fido2.h"
|
||||
#include "dummy.h"
|
||||
|
||||
#include "../src/extern.h"
|
||||
|
||||
struct param {
|
||||
int seed;
|
||||
char path[MAXSTR];
|
||||
struct blob pcsc_list;
|
||||
struct blob tx_apdu;
|
||||
struct blob wiredata_init;
|
||||
struct blob wiredata_msg;
|
||||
};
|
||||
|
||||
static const uint8_t dummy_tx_apdu[] = { WIREDATA_CTAP_EXTENDED_APDU };
|
||||
static const uint8_t dummy_wiredata_init[] = { WIREDATA_CTAP_NFC_INIT };
|
||||
static const uint8_t dummy_wiredata_msg[] = { WIREDATA_CTAP_NFC_MSG };
|
||||
|
||||
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) != 6 ||
|
||||
(v = cbor_array_handle(item)) == NULL)
|
||||
goto fail;
|
||||
|
||||
if (unpack_int(v[0], &p->seed) < 0 ||
|
||||
unpack_string(v[1], p->path) < 0 ||
|
||||
unpack_blob(v[2], &p->pcsc_list) < 0 ||
|
||||
unpack_blob(v[3], &p->tx_apdu) < 0 ||
|
||||
unpack_blob(v[4], &p->wiredata_init) < 0 ||
|
||||
unpack_blob(v[5], &p->wiredata_msg) < 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[6], *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(6)) == NULL ||
|
||||
(argv[0] = pack_int(p->seed)) == NULL ||
|
||||
(argv[1] = pack_string(p->path)) == NULL ||
|
||||
(argv[2] = pack_blob(&p->pcsc_list)) == NULL ||
|
||||
(argv[3] = pack_blob(&p->tx_apdu)) == NULL ||
|
||||
(argv[4] = pack_blob(&p->wiredata_init)) == NULL ||
|
||||
(argv[5] = pack_blob(&p->wiredata_msg)) == NULL)
|
||||
goto fail;
|
||||
|
||||
for (size_t i = 0; i < 6; i++)
|
||||
if (cbor_array_push(array, argv[i]) == false)
|
||||
goto fail;
|
||||
|
||||
if ((cbor_len = cbor_serialize_alloc(array, &cbor,
|
||||
&cbor_alloc_len)) > len) {
|
||||
cbor_len = 0;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
memcpy(ptr, cbor, cbor_len);
|
||||
fail:
|
||||
for (size_t i = 0; i < 6; 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[4096];
|
||||
size_t blob_len;
|
||||
|
||||
memset(&dummy, 0, sizeof(dummy));
|
||||
|
||||
strlcpy(dummy.path, dummy_pcsc_path, sizeof(dummy.path));
|
||||
|
||||
dummy.pcsc_list.len = sizeof(dummy_pcsc_list);
|
||||
memcpy(&dummy.pcsc_list.body, &dummy_pcsc_list, dummy.pcsc_list.len);
|
||||
|
||||
dummy.tx_apdu.len = sizeof(dummy_tx_apdu);
|
||||
memcpy(&dummy.tx_apdu.body, &dummy_tx_apdu, dummy.tx_apdu.len);
|
||||
|
||||
dummy.wiredata_init.len = sizeof(dummy_wiredata_init);
|
||||
memcpy(&dummy.wiredata_init.body, &dummy_wiredata_init,
|
||||
dummy.wiredata_init.len);
|
||||
|
||||
dummy.wiredata_msg.len = sizeof(dummy_wiredata_msg);
|
||||
memcpy(&dummy.wiredata_msg.body, &dummy_wiredata_msg,
|
||||
dummy.wiredata_msg.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
|
||||
test_manifest(void)
|
||||
{
|
||||
size_t ndevs, nfound;
|
||||
fido_dev_info_t *devlist = NULL;
|
||||
int16_t vendor_id, product_id;
|
||||
int r;
|
||||
|
||||
r = fido_pcsc_manifest(NULL, 0, &nfound);
|
||||
assert(r == FIDO_OK && nfound == 0);
|
||||
r = fido_pcsc_manifest(NULL, 1, &nfound);
|
||||
assert(r == FIDO_ERR_INVALID_ARGUMENT);
|
||||
|
||||
ndevs = uniform_random(64);
|
||||
if ((devlist = fido_dev_info_new(ndevs)) == NULL ||
|
||||
fido_pcsc_manifest(devlist, ndevs, &nfound) != FIDO_OK)
|
||||
goto out;
|
||||
|
||||
for (size_t i = 0; i < nfound; i++) {
|
||||
const fido_dev_info_t *di = fido_dev_info_ptr(devlist, i);
|
||||
consume_str(fido_dev_info_path(di));
|
||||
consume_str(fido_dev_info_manufacturer_string(di));
|
||||
consume_str(fido_dev_info_product_string(di));
|
||||
vendor_id = fido_dev_info_vendor(di);
|
||||
product_id = fido_dev_info_product(di);
|
||||
consume(&vendor_id, sizeof(vendor_id));
|
||||
consume(&product_id, sizeof(product_id));
|
||||
}
|
||||
|
||||
out:
|
||||
fido_dev_info_free(&devlist, ndevs);
|
||||
}
|
||||
|
||||
static void
|
||||
test_tx(const char *path, const struct blob *apdu, uint8_t cmd, u_char *rx_buf,
|
||||
size_t rx_len)
|
||||
{
|
||||
fido_dev_t dev;
|
||||
const u_char *tx_ptr = NULL;
|
||||
size_t tx_len = 0;
|
||||
int n;
|
||||
|
||||
memset(&dev, 0, sizeof(dev));
|
||||
|
||||
if (fido_dev_set_pcsc(&dev) < 0)
|
||||
return;
|
||||
if ((dev.io_handle = fido_pcsc_open(path)) == NULL)
|
||||
return;
|
||||
|
||||
if (apdu) {
|
||||
tx_ptr = apdu->body;
|
||||
tx_len = apdu->len;
|
||||
}
|
||||
|
||||
fido_pcsc_tx(&dev, cmd, tx_ptr, tx_len);
|
||||
|
||||
if ((n = fido_pcsc_rx(&dev, cmd, rx_buf, rx_len, -1)) >= 0)
|
||||
consume(rx_buf, n);
|
||||
|
||||
fido_pcsc_close(dev.io_handle);
|
||||
}
|
||||
|
||||
static void
|
||||
test_misc(void)
|
||||
{
|
||||
assert(fido_pcsc_open(NULL) == NULL);
|
||||
assert(fido_pcsc_write(NULL, NULL, INT_MAX + 1LL) == -1);
|
||||
}
|
||||
|
||||
void
|
||||
test(const struct param *p)
|
||||
{
|
||||
u_char buf[512];
|
||||
|
||||
prng_init((unsigned int)p->seed);
|
||||
fuzz_clock_reset();
|
||||
fido_init(FIDO_DEBUG);
|
||||
fido_set_log_handler(consume_str);
|
||||
|
||||
set_pcsc_parameters(&p->pcsc_list);
|
||||
set_pcsc_io_functions(nfc_read, nfc_write, consume);
|
||||
|
||||
test_manifest();
|
||||
test_misc();
|
||||
|
||||
set_wire_data(p->wiredata_init.body, p->wiredata_init.len);
|
||||
test_tx(p->path, NULL, CTAP_CMD_INIT, buf, uniform_random(20));
|
||||
|
||||
set_wire_data(p->wiredata_msg.body, p->wiredata_msg.len);
|
||||
test_tx(p->path, &p->tx_apdu, CTAP_CMD_MSG, buf, sizeof(buf));
|
||||
|
||||
set_wire_data(p->wiredata_msg.body, p->wiredata_msg.len);
|
||||
test_tx(p->path, &p->tx_apdu, CTAP_CMD_CBOR, buf, sizeof(buf));
|
||||
|
||||
set_wire_data(p->wiredata_msg.body, p->wiredata_msg.len);
|
||||
test_tx(p->path, &p->tx_apdu, CTAP_CMD_LOCK, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
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_string(p->path);
|
||||
mutate_blob(&p->pcsc_list);
|
||||
mutate_blob(&p->tx_apdu);
|
||||
}
|
||||
|
||||
if (flags & MUTATE_WIREDATA) {
|
||||
mutate_blob(&p->wiredata_init);
|
||||
mutate_blob(&p->wiredata_msg);
|
||||
}
|
||||
}
|
||||
|
|
@ -15,9 +15,6 @@
|
|||
|
||||
#include "mutator_aux.h"
|
||||
|
||||
#define HID_DEV_HANDLE 0x68696421
|
||||
#define NFC_DEV_HANDLE 0x6e666321
|
||||
|
||||
int fido_nfc_rx(fido_dev_t *, uint8_t, unsigned char *, size_t, int);
|
||||
int fido_nfc_tx(fido_dev_t *, uint8_t, const unsigned char *, size_t);
|
||||
size_t LLVMFuzzerMutate(uint8_t *, size_t, size_t);
|
||||
|
|
@ -241,16 +238,16 @@ nfc_close(void *handle)
|
|||
assert(handle == (void *)NFC_DEV_HANDLE);
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
nfc_read(void *handle, unsigned char *ptr, size_t len, int ms)
|
||||
{
|
||||
assert(handle == (void *)NFC_DEV_HANDLE);
|
||||
assert(len > 0 && len <= 256 + 2);
|
||||
assert(len > 0 && len <= 264);
|
||||
|
||||
return buf_read(ptr, len, ms);
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
nfc_write(void *handle, const unsigned char *ptr, size_t len)
|
||||
{
|
||||
assert(handle == (void *)NFC_DEV_HANDLE);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021 Yubico AB. All rights reserved.
|
||||
* Copyright (c) 2019-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.
|
||||
*/
|
||||
|
|
@ -51,6 +51,9 @@
|
|||
#define MAXSTR 1024
|
||||
#define MAXBLOB 3600
|
||||
|
||||
#define HID_DEV_HANDLE 0x68696421
|
||||
#define NFC_DEV_HANDLE 0x6e666321
|
||||
|
||||
struct blob {
|
||||
uint8_t body[MAXBLOB];
|
||||
size_t len;
|
||||
|
|
@ -85,6 +88,9 @@ void mutate_string(char *);
|
|||
ssize_t fd_read(int, void *, size_t);
|
||||
ssize_t fd_write(int, const void *, size_t);
|
||||
|
||||
int nfc_read(void *, unsigned char *, size_t, int);
|
||||
int nfc_write(void *, const unsigned char *, size_t);
|
||||
|
||||
fido_dev_t *open_dev(int);
|
||||
void set_wire_data(const uint8_t *, size_t);
|
||||
|
||||
|
|
@ -94,4 +100,8 @@ unsigned long prng_uint32(void);
|
|||
|
||||
uint32_t uniform_random(uint32_t);
|
||||
|
||||
void set_pcsc_parameters(const struct blob *);
|
||||
void set_pcsc_io_functions(int (*)(void *, u_char *, size_t, int),
|
||||
int (*)(void *, const u_char *, size_t), void (*)(const void *, size_t));
|
||||
|
||||
#endif /* !_MUTATOR_AUX_H */
|
||||
|
|
|
|||
152
fuzz/pcsc.c
Normal file
152
fuzz/pcsc.c
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <winscard.h>
|
||||
|
||||
#include "mutator_aux.h"
|
||||
|
||||
static const struct blob *reader_list;
|
||||
static int (*xread)(void *, u_char *, size_t, int);
|
||||
static int (*xwrite)(void *, const u_char *, size_t);
|
||||
static void (*xconsume)(const void *, size_t);
|
||||
|
||||
LONG __wrap_SCardEstablishContext(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT);
|
||||
LONG __wrap_SCardListReaders(SCARDCONTEXT, LPCSTR, LPSTR, LPDWORD);
|
||||
LONG __wrap_SCardReleaseContext(SCARDCONTEXT);
|
||||
LONG __wrap_SCardConnect(SCARDCONTEXT, LPCSTR, DWORD, DWORD, LPSCARDHANDLE,
|
||||
LPDWORD);
|
||||
LONG __wrap_SCardDisconnect(SCARDHANDLE, DWORD);
|
||||
LONG __wrap_SCardTransmit(SCARDHANDLE, const SCARD_IO_REQUEST *, LPCBYTE,
|
||||
DWORD, SCARD_IO_REQUEST *, LPBYTE, LPDWORD);
|
||||
|
||||
LONG
|
||||
__wrap_SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
|
||||
LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
|
||||
{
|
||||
assert(dwScope == SCARD_SCOPE_SYSTEM);
|
||||
assert(pvReserved1 == NULL);
|
||||
assert(pvReserved2 == NULL);
|
||||
|
||||
*phContext = 1;
|
||||
|
||||
if (uniform_random(400) < 1)
|
||||
return SCARD_E_NO_SERVICE;
|
||||
if (uniform_random(400) < 1)
|
||||
return SCARD_E_NO_SMARTCARD;
|
||||
if (uniform_random(400) < 1)
|
||||
return SCARD_E_NO_MEMORY;
|
||||
if (uniform_random(400) < 1)
|
||||
*phContext = 0;
|
||||
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
LONG
|
||||
__wrap_SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
|
||||
LPSTR mszReaders, LPDWORD pcchReaders)
|
||||
{
|
||||
assert(hContext == 1);
|
||||
assert(mszGroups == NULL);
|
||||
assert(mszReaders != NULL);
|
||||
assert(pcchReaders != 0);
|
||||
|
||||
if (reader_list == NULL || uniform_random(400) < 1)
|
||||
return SCARD_E_NO_READERS_AVAILABLE;
|
||||
if (uniform_random(400) < 1)
|
||||
return SCARD_E_NO_MEMORY;
|
||||
|
||||
memcpy(mszReaders, reader_list->body, reader_list->len > *pcchReaders ?
|
||||
*pcchReaders : reader_list->len);
|
||||
*pcchReaders = (DWORD)reader_list->len; /* on purpose */
|
||||
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
LONG
|
||||
__wrap_SCardReleaseContext(SCARDCONTEXT hContext)
|
||||
{
|
||||
assert(hContext == 1);
|
||||
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
LONG
|
||||
__wrap_SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
|
||||
DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
|
||||
{
|
||||
uint32_t r;
|
||||
|
||||
assert(hContext == 1);
|
||||
xconsume(szReader, strlen(szReader) + 1);
|
||||
assert(dwShareMode == SCARD_SHARE_SHARED);
|
||||
assert(dwPreferredProtocols == SCARD_PROTOCOL_ANY);
|
||||
assert(phCard != NULL);
|
||||
assert(pdwActiveProtocol != NULL);
|
||||
|
||||
if ((r = uniform_random(400)) < 1)
|
||||
return SCARD_E_UNEXPECTED;
|
||||
|
||||
*phCard = 1;
|
||||
*pdwActiveProtocol = (r & 1) ? SCARD_PROTOCOL_T0 : SCARD_PROTOCOL_T1;
|
||||
|
||||
if (uniform_random(400) < 1)
|
||||
*pdwActiveProtocol = SCARD_PROTOCOL_RAW;
|
||||
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
LONG
|
||||
__wrap_SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
|
||||
{
|
||||
assert(hCard == 1);
|
||||
assert(dwDisposition == SCARD_LEAVE_CARD);
|
||||
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
extern void consume(const void *body, size_t len);
|
||||
|
||||
LONG
|
||||
__wrap_SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
|
||||
LPCBYTE pbSendBuffer, DWORD cbSendLength, SCARD_IO_REQUEST *pioRecvPci,
|
||||
LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
|
||||
{
|
||||
void *ioh = (void *)NFC_DEV_HANDLE;
|
||||
int n;
|
||||
|
||||
assert(hCard == 1);
|
||||
xconsume(pioSendPci, sizeof(*pioSendPci));
|
||||
xwrite(ioh, pbSendBuffer, cbSendLength);
|
||||
assert(pioRecvPci == NULL);
|
||||
|
||||
if (uniform_random(400) < 1 ||
|
||||
(n = xread(ioh, pbRecvBuffer, *pcbRecvLength, -1)) == -1)
|
||||
return SCARD_E_UNEXPECTED;
|
||||
*pcbRecvLength = (DWORD)n;
|
||||
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
set_pcsc_parameters(const struct blob *reader_list_ptr)
|
||||
{
|
||||
reader_list = reader_list_ptr;
|
||||
}
|
||||
|
||||
void
|
||||
set_pcsc_io_functions(int (*read_f)(void *, u_char *, size_t, int),
|
||||
int (*write_f)(void *, const u_char *, size_t),
|
||||
void (*consume_f)(const void *, size_t))
|
||||
{
|
||||
xread = read_f;
|
||||
xwrite = write_f;
|
||||
xconsume = consume_f;
|
||||
}
|
||||
BIN
fuzz/report.tgz
BIN
fuzz/report.tgz
Binary file not shown.
|
|
@ -1,52 +1,58 @@
|
|||
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 0 100.00%
|
||||
fuzz/prng.c 31 0 100.00% 2 0 100.00% 35 0 100.00%
|
||||
fuzz/udev.c 103 1 99.03% 17 0 100.00% 126 3 97.62%
|
||||
fuzz/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 109 1 99.08% 17 0 100.00% 126 11 91.27%
|
||||
fuzz/uniform_random.c 7 1 85.71% 1 0 100.00% 12 1 91.67%
|
||||
fuzz/wrap.c 6 0 100.00% 1 0 100.00% 7 0 100.00%
|
||||
fuzz/wrap.c 17 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/strlcat.c 12 1 91.67% 1 0 100.00% 21 1 95.24%
|
||||
openbsd-compat/timingsafe_bcmp.c 4 0 100.00% 1 0 100.00% 7 0 100.00%
|
||||
src/aes256.c 115 4 96.52% 8 0 100.00% 157 14 91.08%
|
||||
src/assert.c 563 40 92.90% 56 3 94.64% 694 40 94.24%
|
||||
src/aes256.c 118 4 96.61% 8 0 100.00% 157 14 91.08%
|
||||
src/assert.c 565 42 92.57% 56 3 94.64% 694 42 93.95%
|
||||
src/authkey.c 44 0 100.00% 5 0 100.00% 59 0 100.00%
|
||||
src/bio.c 419 20 95.23% 49 2 95.92% 559 21 96.24%
|
||||
src/bio.c 419 20 95.23% 49 2 95.92% 559 24 95.71%
|
||||
src/blob.c 53 2 96.23% 10 0 100.00% 83 4 95.18%
|
||||
src/buf.c 8 1 87.50% 2 0 100.00% 16 1 93.75%
|
||||
src/cbor.c 1047 23 97.80% 54 0 100.00% 1237 46 96.28%
|
||||
src/compress.c 34 4 88.24% 3 0 100.00% 28 3 89.29%
|
||||
src/cbor.c 1049 23 97.81% 54 0 100.00% 1237 45 96.36%
|
||||
src/compress.c 105 14 86.67% 5 0 100.00% 122 24 80.33%
|
||||
src/config.c 108 0 100.00% 11 0 100.00% 151 0 100.00%
|
||||
src/cred.c 632 34 94.62% 69 2 97.10% 830 36 95.66%
|
||||
src/credman.c 382 10 97.38% 40 0 100.00% 518 15 97.10%
|
||||
src/dev.c 421 79 81.24% 45 7 84.44% 491 105 78.62%
|
||||
src/cred.c 634 36 94.32% 69 2 97.10% 830 39 95.30%
|
||||
src/credman.c 382 10 97.38% 40 0 100.00% 518 18 96.53%
|
||||
src/dev.c 332 71 78.61% 41 6 85.37% 378 86 77.25%
|
||||
src/ecdh.c 117 2 98.29% 4 0 100.00% 146 5 96.58%
|
||||
src/eddsa.c 80 3 96.25% 10 0 100.00% 106 8 92.45%
|
||||
src/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 306 5 98.37% 19 0 100.00% 358 7 98.04%
|
||||
src/es256.c 315 7 97.78% 19 0 100.00% 372 12 96.77%
|
||||
src/hid.c 87 2 97.70% 14 0 100.00% 145 3 97.93%
|
||||
src/hid_linux.c 173 68 60.69% 14 7 50.00% 250 104 58.40%
|
||||
src/hid_unix.c 28 20 28.57% 2 0 100.00% 43 24 44.19%
|
||||
src/info.c 184 0 100.00% 39 0 100.00% 316 0 100.00%
|
||||
src/io.c 182 7 96.15% 13 0 100.00% 221 11 95.02%
|
||||
src/iso7816.c 18 1 94.44% 5 0 100.00% 38 0 100.00%
|
||||
src/largeblob.c 513 19 96.30% 30 0 100.00% 684 43 93.71%
|
||||
src/log.c 39 5 87.18% 7 1 85.71% 63 4 93.65%
|
||||
src/netlink.c 328 14 95.73% 40 0 100.00% 498 32 93.57%
|
||||
src/nfc_linux.c 327 73 77.68% 23 5 78.26% 458 124 72.93%
|
||||
src/pin.c 403 3 99.26% 26 0 100.00% 495 3 99.39%
|
||||
src/hid_linux.c 173 68 60.69% 14 7 50.00% 250 105 58.00%
|
||||
src/hid_unix.c 29 21 27.59% 2 0 100.00% 43 26 39.53%
|
||||
src/info.c 186 0 100.00% 40 0 100.00% 321 0 100.00%
|
||||
src/io.c 185 7 96.22% 13 0 100.00% 221 12 94.57%
|
||||
src/iso7816.c 18 1 94.44% 5 0 100.00% 38 1 97.37%
|
||||
src/largeblob.c 514 19 96.30% 30 0 100.00% 684 46 93.27%
|
||||
src/log.c 39 5 87.18% 7 1 85.71% 63 7 88.89%
|
||||
src/netlink.c 329 14 95.74% 40 0 100.00% 498 33 93.37%
|
||||
src/nfc.c 142 7 95.07% 11 1 90.91% 223 27 87.89%
|
||||
src/nfc_linux.c 174 56 67.82% 13 5 61.54% 245 103 57.96%
|
||||
src/pcsc.c 201 1 99.50% 13 0 100.00% 278 3 98.92%
|
||||
src/pin.c 403 3 99.26% 26 0 100.00% 495 4 99.19%
|
||||
src/random.c 6 1 83.33% 1 0 100.00% 6 1 83.33%
|
||||
src/reset.c 24 0 100.00% 3 0 100.00% 23 0 100.00%
|
||||
src/rs1.c 25 0 100.00% 3 0 100.00% 39 0 100.00%
|
||||
src/rs256.c 141 8 94.33% 13 0 100.00% 172 10 94.19%
|
||||
src/time.c 43 3 93.02% 3 0 100.00% 43 1 97.67%
|
||||
src/tpm.c 100 0 100.00% 9 0 100.00% 194 0 100.00%
|
||||
src/rs1.c 25 2 92.00% 3 0 100.00% 39 4 89.74%
|
||||
src/rs256.c 141 8 94.33% 13 0 100.00% 172 11 93.60%
|
||||
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 3 97.09% 9 0 100.00% 194 9 95.36%
|
||||
src/types.c 25 0 100.00% 6 0 100.00% 46 0 100.00%
|
||||
src/u2f.c 528 4 99.24% 17 0 100.00% 685 12 98.25%
|
||||
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 -
|
||||
|
|
@ -54,4 +60,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 7861 476 93.94% 684 27 96.05% 10270 699 93.19%
|
||||
TOTAL 8227 484 94.12% 710 27 96.20% 10756 777 92.78%
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Yubico AB. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -630,4 +630,78 @@
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
|
||||
#define WIREDATA_CTAP_NFC_INIT \
|
||||
0x55, 0x32, 0x46, 0x5f, 0x56, 0x32, 0x90, 0x00
|
||||
|
||||
#define WIREDATA_CTAP_NFC_MSG \
|
||||
0x90, 0x00, 0x90, 0x00, 0x90, 0x00, 0x90, 0x00
|
||||
|
||||
#define WIREDATA_CTAP_EXTENDED_APDU \
|
||||
0x00, 0xa4, 0x04, 0x00, 0x00, 0x02, 0x00, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, \
|
||||
0x00
|
||||
|
||||
#endif /* _WIREDATA_FIDO2_H */
|
||||
|
|
|
|||
51
fuzz/wrap.c
51
fuzz/wrap.c
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021 Yubico AB. All rights reserved.
|
||||
* Copyright (c) 2019-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.
|
||||
*/
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "mutator_aux.h"
|
||||
|
||||
|
|
@ -635,3 +636,51 @@ WRAP(int,
|
|||
(sockfd, addr, addrlen),
|
||||
1
|
||||
)
|
||||
|
||||
WRAP(int,
|
||||
deflateInit2_,
|
||||
(z_streamp strm, int level, int method, int windowBits, int memLevel,
|
||||
int strategy, const char *version, int stream_size),
|
||||
Z_STREAM_ERROR,
|
||||
(strm, level, method, windowBits, memLevel, strategy, version,
|
||||
stream_size),
|
||||
1
|
||||
)
|
||||
|
||||
int __wrap_deflate(z_streamp, int);
|
||||
int __real_deflate(z_streamp, int);
|
||||
|
||||
int
|
||||
__wrap_deflate(z_streamp strm, int flush)
|
||||
{
|
||||
if (uniform_random(400) < 1) {
|
||||
return Z_BUF_ERROR;
|
||||
}
|
||||
/* should never happen, but we check for it */
|
||||
if (uniform_random(400) < 1) {
|
||||
strm->avail_out = UINT_MAX;
|
||||
return Z_STREAM_END;
|
||||
}
|
||||
|
||||
return __real_deflate(strm, flush);
|
||||
}
|
||||
|
||||
int __wrap_asprintf(char **, const char *, ...);
|
||||
|
||||
int
|
||||
__wrap_asprintf(char **strp, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int r;
|
||||
|
||||
if (uniform_random(400) < 1) {
|
||||
*strp = (void *)0xdeadbeef;
|
||||
return -1;
|
||||
}
|
||||
|
||||
va_start(ap, fmt);
|
||||
r = vasprintf(strp, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
asprintf
|
||||
bind
|
||||
BN_bin2bn
|
||||
BN_bn2bin
|
||||
|
|
@ -24,6 +25,8 @@ cbor_new_definite_bytestring
|
|||
cbor_new_definite_map
|
||||
cbor_serialize_alloc
|
||||
clock_gettime
|
||||
deflate
|
||||
deflateInit2_
|
||||
EC_KEY_get0_group
|
||||
EC_KEY_get0_private_key
|
||||
EC_KEY_new_by_curve_name
|
||||
|
|
@ -71,6 +74,12 @@ realloc
|
|||
RSA_new
|
||||
RSA_pkey_ctx_ctrl
|
||||
RSA_set0_key
|
||||
SCardConnect
|
||||
SCardDisconnect
|
||||
SCardEstablishContext
|
||||
SCardListReaders
|
||||
SCardReleaseContext
|
||||
SCardTransmit
|
||||
SHA1
|
||||
SHA256
|
||||
strdup
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2018 Yubico AB. All rights reserved.
|
||||
# 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.
|
||||
|
||||
|
|
@ -117,10 +117,11 @@ list(APPEND MAN_ALIAS
|
|||
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_maxmsgsiz
|
||||
fido_cbor_info_new fido_cbor_info_maxcredbloblen
|
||||
fido_cbor_info_new fido_cbor_info_maxcredcntlst
|
||||
fido_cbor_info_new fido_cbor_info_maxcredidlen
|
||||
fido_cbor_info_new fido_cbor_info_maxlargeblob
|
||||
fido_cbor_info_new fido_cbor_info_maxmsgsiz
|
||||
fido_cbor_info_new fido_cbor_info_fwversion
|
||||
fido_cbor_info_new fido_cbor_info_options_len
|
||||
fido_cbor_info_new fido_cbor_info_options_name_ptr
|
||||
|
|
@ -263,7 +264,7 @@ math(EXPR MAN_ALIAS_MAX "${MAN_ALIAS_LEN} - 2")
|
|||
# man_copy
|
||||
foreach(f ${MAN_SOURCES})
|
||||
add_custom_command(OUTPUT ${f}
|
||||
COMMAND cp -f ${CMAKE_SOURCE_DIR}/man/${f} .
|
||||
COMMAND cp -f ${PROJECT_SOURCE_DIR}/man/${f} .
|
||||
DEPENDS ${f})
|
||||
list(APPEND COPY_FILES ${f})
|
||||
endforeach()
|
||||
|
|
@ -289,7 +290,7 @@ endforeach()
|
|||
foreach(f ${MAN_SOURCES})
|
||||
string(REGEX REPLACE ".[13]" "" g ${f})
|
||||
add_custom_command(OUTPUT ${g}.partial
|
||||
COMMAND cat ${CMAKE_SOURCE_DIR}/man/dyc.css > ${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)
|
||||
|
|
@ -337,17 +338,17 @@ add_custom_target(man ALL)
|
|||
if(MANDOC_PATH)
|
||||
add_dependencies(man man_symlink_html)
|
||||
add_dependencies(man_gzip man_lint)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/man/style.css
|
||||
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 ${CMAKE_BINARY_DIR}/man/${f}.html
|
||||
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 ${CMAKE_BINARY_DIR}/man/${DST}.html
|
||||
install(FILES ${PROJECT_BINARY_DIR}/man/${DST}.html
|
||||
DESTINATION "${CMAKE_INSTALL_DOCDIR}/html")
|
||||
endforeach()
|
||||
endif()
|
||||
|
|
@ -358,34 +359,34 @@ if(GZIP_PATH)
|
|||
add_dependencies(man man_symlink_gzip)
|
||||
foreach(f ${MAN_SOURCES})
|
||||
if (${f} MATCHES ".1$")
|
||||
install(FILES ${CMAKE_BINARY_DIR}/man/${f}.gz
|
||||
install(FILES ${PROJECT_BINARY_DIR}/man/${f}.gz
|
||||
DESTINATION "${CMAKE_INSTALL_MANDIR}/man1")
|
||||
elseif(${f} MATCHES ".3$")
|
||||
install(FILES ${CMAKE_BINARY_DIR}/man/${f}.gz
|
||||
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 ${CMAKE_BINARY_DIR}/man/${DST}.3.gz
|
||||
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 ${CMAKE_BINARY_DIR}/man/${f}
|
||||
install(FILES ${PROJECT_BINARY_DIR}/man/${f}
|
||||
DESTINATION "${CMAKE_INSTALL_MANDIR}/man1")
|
||||
elseif(${f} MATCHES ".3$")
|
||||
install(FILES ${CMAKE_BINARY_DIR}/man/${f}
|
||||
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 ${CMAKE_BINARY_DIR}/man/${DST}.3
|
||||
install(FILES ${PROJECT_BINARY_DIR}/man/${DST}.3
|
||||
DESTINATION "${CMAKE_INSTALL_MANDIR}/man3")
|
||||
endforeach()
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
.\" Copyright (c) 2018-2021 Yubico AB. All rights reserved.
|
||||
.\" 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.
|
||||
.\"
|
||||
.Dd $Mdocdate: September 13 2019 $
|
||||
.Dd $Mdocdate: April 11 2022 $
|
||||
.Dt FIDO2-TOKEN 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
|
@ -147,7 +147,7 @@ from
|
|||
.Ar device ,
|
||||
where
|
||||
.Ar key_path
|
||||
must hold the blob's base64-encoded encryption key.
|
||||
holds the blob's base64-encoded 32-byte AES-256 GCM encryption key.
|
||||
A PIN or equivalent user-verification gesture is required.
|
||||
.It Fl D Fl b Fl n Ar rp_id Oo Fl i Ar cred_id Oc Ar device
|
||||
Deletes a
|
||||
|
|
@ -189,7 +189,7 @@ from
|
|||
.Ar device ,
|
||||
where
|
||||
.Ar key_path
|
||||
must hold the blob's base64-encoded encryption key.
|
||||
holds the blob's base64-encoded 32-byte AES-256 GCM encryption key.
|
||||
The blob is written to
|
||||
.Ar blob_path .
|
||||
A PIN or equivalent user-verification gesture is required.
|
||||
|
|
@ -267,29 +267,27 @@ The user will be prompted for the PIN.
|
|||
Enables CTAP 2.1 Enterprise Attestation on
|
||||
.Ar device .
|
||||
.It Fl S Fl b Fl k Ar key_path Ar blob_path Ar device
|
||||
Sets
|
||||
.Ar blob_path
|
||||
as a CTAP 2.1
|
||||
Sets a CTAP 2.1
|
||||
.Dq largeBlob
|
||||
encrypted with
|
||||
.Ar key_path
|
||||
on
|
||||
.Ar device ,
|
||||
where
|
||||
.Ar blob_path
|
||||
holds the blob's plaintext, and
|
||||
.Ar key_path
|
||||
the blob's base64-encoded encryption.
|
||||
holds the blob's base64-encoded 32-byte AES-256 GCM encryption key.
|
||||
The blob is read from
|
||||
.Fa blob_path .
|
||||
A PIN or equivalent user-verification gesture is required.
|
||||
.It Fl S Fl b Fl n Ar rp_id Oo Fl i Ar cred_id Oc Ar blob_path Ar device
|
||||
Sets
|
||||
.Ar blob_path
|
||||
as a CTAP 2.1
|
||||
Sets a CTAP 2.1
|
||||
.Dq largeBlob
|
||||
associated with
|
||||
.Ar rp_id
|
||||
on
|
||||
.Ar device .
|
||||
The blob is read from
|
||||
.Fa blob_path .
|
||||
If
|
||||
.Ar rp_id
|
||||
has multiple credentials enrolled on
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
.\" Copyright (c) 2018 Yubico AB. All rights reserved.
|
||||
.\" 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.
|
||||
.\"
|
||||
.Dd $Mdocdate: October 22 2019 $
|
||||
.Dd $Mdocdate: April 27 2022 $
|
||||
.Dt FIDO_ASSERT_NEW 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
|
@ -180,6 +180,8 @@ in
|
|||
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
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
.\" Copyright (c) 2018 Yubico AB. All rights reserved.
|
||||
.\" 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.
|
||||
.\"
|
||||
.Dd $Mdocdate: May 23 2018 $
|
||||
.Dd $Mdocdate: April 27 2022 $
|
||||
.Dt FIDO_ASSERT_SET_AUTHDATA 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
|
@ -182,6 +182,8 @@ 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.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
.\" Copyright (c) 2018 Yubico AB. All rights reserved.
|
||||
.\" 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.
|
||||
.\"
|
||||
.Dd $Mdocdate: May 24 2018 $
|
||||
.Dd $Mdocdate: April 22 2022 $
|
||||
.Dt FIDO_CBOR_INFO_NEW 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
|
@ -29,6 +29,7 @@
|
|||
.Nm fido_cbor_info_maxcredbloblen ,
|
||||
.Nm fido_cbor_info_maxcredcntlst ,
|
||||
.Nm fido_cbor_info_maxcredidlen ,
|
||||
.Nm fido_cbor_info_maxlargeblob ,
|
||||
.Nm fido_cbor_info_fwversion
|
||||
.Nd FIDO2 CBOR Info API
|
||||
.Sh SYNOPSIS
|
||||
|
|
@ -80,6 +81,8 @@
|
|||
.Ft uint64_t
|
||||
.Fn fido_cbor_info_maxcredidlen "const fido_cbor_info_t *ci"
|
||||
.Ft uint64_t
|
||||
.Fn fido_cbor_info_maxlargeblob "const fido_cbor_info_t *ci"
|
||||
.Ft uint64_t
|
||||
.Fn fido_cbor_info_fwversion "const fido_cbor_info_t *ci"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
|
|
@ -201,6 +204,12 @@ as reported in
|
|||
.Fa ci .
|
||||
.Pp
|
||||
The
|
||||
.Fn fido_cbor_info_maxlargeblob
|
||||
function returns the maximum length in bytes of an authenticator's
|
||||
serialized largeBlob array as reported in
|
||||
.Fa ci .
|
||||
.Pp
|
||||
The
|
||||
.Fn fido_cbor_info_fwversion
|
||||
function returns the firmware version attribute of
|
||||
.Fa ci .
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
.\" Use of this source code is governed by a BSD-style
|
||||
.\" license that can be found in the LICENSE file.
|
||||
.\"
|
||||
.Dd $Mdocdate: September 22 2020 $
|
||||
.Dd $Mdocdate: March 30 2022 $
|
||||
.Dt FIDO_DEV_ENABLE_ENTATTEST 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
|
@ -65,7 +65,7 @@ does not have a PIN set.
|
|||
.Pp
|
||||
The
|
||||
.Fn fido_dev_force_pin_change
|
||||
instructs
|
||||
function instructs
|
||||
.Fa dev
|
||||
to require a PIN change.
|
||||
Subsequent PIN authentication attempts against
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
.\" Use of this source code is governed by a BSD-style
|
||||
.\" license that can be found in the LICENSE file.
|
||||
.\"
|
||||
.Dd $Mdocdate: May 25 2018 $
|
||||
.Dd $Mdocdate: March 30 2022 $
|
||||
.Dt FIDO_DEV_INFO_MANIFEST 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
|
@ -97,7 +97,7 @@ Please note that the first slot has index 0.
|
|||
.Pp
|
||||
The
|
||||
.Fn fido_dev_info_path
|
||||
returns the filesystem path or subsystem-specific identification
|
||||
function returns the filesystem path or subsystem-specific identification
|
||||
string of
|
||||
.Fa di .
|
||||
.Pp
|
||||
|
|
|
|||
88
openbsd-compat/bsd-asprintf.c
Normal file
88
openbsd-compat/bsd-asprintf.c
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 2004 Darren Tucker.
|
||||
*
|
||||
* Based originally on asprintf.c from OpenBSD:
|
||||
* Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "openbsd-compat.h"
|
||||
|
||||
#ifndef HAVE_ASPRINTF
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h> /* for INT_MAX */
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h> /* for vsnprintf */
|
||||
#include <stdlib.h>
|
||||
|
||||
#define VA_COPY(dest, src) va_copy(dest, src)
|
||||
|
||||
#define INIT_SZ 128
|
||||
|
||||
int
|
||||
vasprintf(char **str, const char *fmt, va_list ap)
|
||||
{
|
||||
int ret;
|
||||
va_list ap2;
|
||||
char *string, *newstr;
|
||||
size_t len;
|
||||
|
||||
if ((string = malloc(INIT_SZ)) == NULL)
|
||||
goto fail;
|
||||
|
||||
VA_COPY(ap2, ap);
|
||||
ret = vsnprintf(string, INIT_SZ, fmt, ap2);
|
||||
va_end(ap2);
|
||||
if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */
|
||||
*str = string;
|
||||
} else if (ret == INT_MAX || ret < 0) { /* Bad length */
|
||||
free(string);
|
||||
goto fail;
|
||||
} else { /* bigger than initial, realloc allowing for nul */
|
||||
len = (size_t)ret + 1;
|
||||
if ((newstr = realloc(string, len)) == NULL) {
|
||||
free(string);
|
||||
goto fail;
|
||||
}
|
||||
VA_COPY(ap2, ap);
|
||||
ret = vsnprintf(newstr, len, fmt, ap2);
|
||||
va_end(ap2);
|
||||
if (ret < 0 || (size_t)ret >= len) { /* failed with realloc'ed string */
|
||||
free(newstr);
|
||||
goto fail;
|
||||
}
|
||||
*str = newstr;
|
||||
}
|
||||
return (ret);
|
||||
|
||||
fail:
|
||||
*str = NULL;
|
||||
errno = ENOMEM;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int asprintf(char **str, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
*str = NULL;
|
||||
va_start(ap, fmt);
|
||||
ret = vasprintf(str, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -115,4 +115,8 @@ ssize_t getline(char **, size_t *, FILE *);
|
|||
#define IOCTL_REQ(x) ((int)(x))
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_ASPRINTF)
|
||||
int asprintf(char **, const char *, ...);
|
||||
#endif
|
||||
|
||||
#endif /* !_OPENBSD_COMPAT_H */
|
||||
|
|
|
|||
|
|
@ -1,20 +1,45 @@
|
|||
# Copyright (c) 2018-2021 Yubico AB. All rights reserved.
|
||||
# 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.
|
||||
|
||||
add_custom_target(regress ALL)
|
||||
add_custom_target(regress)
|
||||
|
||||
macro(add_regress_test NAME SOURCES)
|
||||
add_executable(${NAME} ${SOURCES})
|
||||
target_link_libraries(${NAME} fido2_shared)
|
||||
target_link_libraries(${NAME} fido2)
|
||||
add_test(${NAME} ${NAME})
|
||||
add_dependencies(regress ${NAME})
|
||||
endmacro()
|
||||
|
||||
add_custom_command(TARGET regress POST_BUILD
|
||||
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
if(MSVC AND BUILD_SHARED_LIBS)
|
||||
add_custom_command(TARGET regress POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy
|
||||
"${CBOR_BIN_DIRS}/${CBOR_LIBRARIES}.dll"
|
||||
"${CRYPTO_BIN_DIRS}/${CRYPTO_LIBRARIES}.dll"
|
||||
"${ZLIB_BIN_DIRS}/${ZLIB_LIBRARIES}.dll"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}")
|
||||
endif()
|
||||
|
||||
if(CMAKE_CROSSCOMPILING OR (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "AMD64" AND
|
||||
CMAKE_GENERATOR_PLATFORM MATCHES "^ARM.*$"))
|
||||
add_custom_command(TARGET regress POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E echo
|
||||
"Cross-compilation detected. Skipping regress tests.")
|
||||
else()
|
||||
add_custom_command(TARGET regress POST_BUILD
|
||||
COMMAND "${CMAKE_CTEST_COMMAND}" --output-on-failure
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
endif()
|
||||
|
||||
add_regress_test(regress_cred cred.c)
|
||||
add_regress_test(regress_assert assert.c)
|
||||
add_regress_test(regress_compress compress.c)
|
||||
add_regress_test(regress_cred cred.c)
|
||||
add_regress_test(regress_dev dev.c)
|
||||
add_regress_test(regress_eddsa eddsa.c)
|
||||
add_regress_test(regress_es256 es256.c)
|
||||
add_regress_test(regress_rs256 rs256.c)
|
||||
|
||||
if(MINGW)
|
||||
# needed for nanosleep() in mingw
|
||||
target_link_libraries(regress_dev winpthread)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -4,16 +4,19 @@
|
|||
* license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#define _FIDO_INTERNAL
|
||||
#undef NDEBUG
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#define _FIDO_INTERNAL
|
||||
|
||||
#include <fido.h>
|
||||
#include <fido/es256.h>
|
||||
#include <fido/rs256.h>
|
||||
#include <fido/eddsa.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FAKE_DEV_HANDLE ((void *)0xdeadbeef)
|
||||
static int fake_dev_handle;
|
||||
|
||||
static const unsigned char es256_pk[64] = {
|
||||
0x34, 0xeb, 0x99, 0x77, 0x02, 0x9c, 0x36, 0x38,
|
||||
|
|
@ -94,13 +97,13 @@ dummy_open(const char *path)
|
|||
{
|
||||
(void)path;
|
||||
|
||||
return (FAKE_DEV_HANDLE);
|
||||
return (&fake_dev_handle);
|
||||
}
|
||||
|
||||
static void
|
||||
dummy_close(void *handle)
|
||||
{
|
||||
assert(handle == FAKE_DEV_HANDLE);
|
||||
assert(handle == &fake_dev_handle);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
|||
267
regress/compress.c
Normal file
267
regress/compress.c
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#undef NDEBUG
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#define _FIDO_INTERNAL
|
||||
|
||||
#include <fido.h>
|
||||
|
||||
/*
|
||||
* zlib compressed data (RFC1950); see https://www.ietf.org/rfc/rfc6713.txt
|
||||
*/
|
||||
static /* const */ unsigned char rfc1950_blob[694] = {
|
||||
0x78, 0x9c, 0xb5, 0x52, 0x3b, 0x6f, 0xdb, 0x30,
|
||||
0x10, 0xde, 0xf5, 0x2b, 0x0e, 0x99, 0x12, 0x40,
|
||||
0x75, 0x13, 0x4f, 0x45, 0x3b, 0xd1, 0x12, 0x6d,
|
||||
0x1d, 0x20, 0x8b, 0x2a, 0x49, 0xd9, 0xf5, 0x28,
|
||||
0x4b, 0x4c, 0x42, 0xc0, 0x12, 0x03, 0x3d, 0x12,
|
||||
0xe4, 0xdf, 0xf7, 0xc8, 0x3a, 0x88, 0xd3, 0x0c,
|
||||
0x9d, 0xea, 0xc1, 0x3e, 0xf3, 0x8e, 0xdf, 0xeb,
|
||||
0x98, 0xb8, 0xa7, 0xd7, 0xc1, 0x3e, 0x3c, 0x4e,
|
||||
0x70, 0xdd, 0xdc, 0xc0, 0xf2, 0xf6, 0xee, 0xdb,
|
||||
0x97, 0xe5, 0xed, 0x72, 0x09, 0x87, 0xf9, 0x68,
|
||||
0x1b, 0x07, 0x6c, 0xb5, 0x00, 0x76, 0x3a, 0x41,
|
||||
0x18, 0x19, 0x61, 0x30, 0xa3, 0x19, 0x9e, 0x4d,
|
||||
0xbb, 0x88, 0x22, 0x69, 0x5a, 0x3b, 0x4e, 0x83,
|
||||
0x3d, 0xce, 0x93, 0x75, 0x3d, 0xd4, 0x7d, 0x0b,
|
||||
0xf3, 0x68, 0xc0, 0xf6, 0x30, 0xba, 0x79, 0x68,
|
||||
0x4c, 0x38, 0x39, 0xda, 0xbe, 0x1e, 0x5e, 0xe1,
|
||||
0xde, 0x0d, 0xdd, 0x18, 0xc3, 0x8b, 0x9d, 0x1e,
|
||||
0xc1, 0x0d, 0xe1, 0xd7, 0xcd, 0x53, 0xd4, 0xb9,
|
||||
0xd6, 0xde, 0xdb, 0xa6, 0xf6, 0x00, 0x31, 0xd4,
|
||||
0x83, 0x81, 0x27, 0x33, 0x74, 0x76, 0x9a, 0x4c,
|
||||
0x0b, 0x4f, 0x83, 0x7b, 0xb6, 0x2d, 0x15, 0xd3,
|
||||
0x63, 0x3d, 0xd1, 0x97, 0x21, 0x90, 0xd3, 0xc9,
|
||||
0xbd, 0xd8, 0xfe, 0x01, 0x1a, 0xd7, 0xb7, 0xd6,
|
||||
0x5f, 0x1a, 0xfd, 0xa5, 0xa8, 0x33, 0xd3, 0xf7,
|
||||
0x28, 0x02, 0x80, 0xbb, 0x05, 0x7c, 0x54, 0x35,
|
||||
0x82, 0xbb, 0x7f, 0x93, 0xd3, 0xb8, 0xd6, 0x40,
|
||||
0x37, 0x8f, 0x13, 0x99, 0x98, 0x6a, 0x92, 0xe9,
|
||||
0x31, 0xeb, 0xa3, 0x7b, 0xf6, 0xad, 0x73, 0x06,
|
||||
0x1e, 0x84, 0x3e, 0xbd, 0x9b, 0x6c, 0x63, 0x62,
|
||||
0x9a, 0xb0, 0x23, 0x9c, 0x08, 0xcf, 0xc3, 0x5c,
|
||||
0x92, 0xf6, 0xed, 0x5f, 0x8a, 0x88, 0xb4, 0x39,
|
||||
0xd5, 0xb6, 0x33, 0xc3, 0xc2, 0x63, 0x2c, 0x3f,
|
||||
0x0b, 0x21, 0xc2, 0x8b, 0x30, 0xde, 0x84, 0x90,
|
||||
0xcb, 0x76, 0x26, 0x71, 0xff, 0x47, 0x0b, 0x91,
|
||||
0x9e, 0x51, 0xfc, 0x44, 0xeb, 0x9a, 0xb9, 0x33,
|
||||
0xfd, 0x54, 0xbf, 0xed, 0xeb, 0x2b, 0xad, 0xc2,
|
||||
0x51, 0x67, 0x80, 0xae, 0x9e, 0xcc, 0x60, 0xeb,
|
||||
0xd3, 0xf8, 0x1e, 0x7b, 0xd8, 0x15, 0x35, 0xcf,
|
||||
0x00, 0x97, 0x66, 0x68, 0xf9, 0x3a, 0x43, 0x05,
|
||||
0x4a, 0xac, 0xf5, 0x9e, 0x49, 0x0e, 0x54, 0x97,
|
||||
0x52, 0xec, 0x30, 0xe5, 0x29, 0xac, 0x0e, 0xa0,
|
||||
0x33, 0x0e, 0x89, 0x28, 0x0f, 0x12, 0x37, 0x99,
|
||||
0x86, 0x4c, 0xe4, 0x29, 0x97, 0x0a, 0x58, 0x91,
|
||||
0xd2, 0x69, 0xa1, 0x25, 0xae, 0x2a, 0x2d, 0xa4,
|
||||
0x8a, 0xae, 0x98, 0xa2, 0x9b, 0x57, 0xa1, 0xc1,
|
||||
0x8a, 0x03, 0xf0, 0x5f, 0xa5, 0xe4, 0x4a, 0x81,
|
||||
0x90, 0x80, 0xdb, 0x32, 0x47, 0x02, 0x23, 0x74,
|
||||
0xc9, 0x0a, 0x8d, 0x5c, 0xc5, 0x80, 0x45, 0x92,
|
||||
0x57, 0x29, 0x16, 0x9b, 0x18, 0x08, 0x00, 0x0a,
|
||||
0xa1, 0xa3, 0x1c, 0xb7, 0xa8, 0x69, 0x4c, 0x8b,
|
||||
0x38, 0x90, 0x7e, 0xbe, 0x06, 0x62, 0x0d, 0x5b,
|
||||
0x2e, 0x93, 0x8c, 0xfe, 0xb2, 0x15, 0xe6, 0xa8,
|
||||
0x0f, 0x81, 0x6f, 0x8d, 0xba, 0xf0, 0x5c, 0x6b,
|
||||
0x21, 0x23, 0x06, 0x25, 0x93, 0x1a, 0x93, 0x2a,
|
||||
0x67, 0x12, 0xca, 0x4a, 0x96, 0x42, 0x71, 0xf0,
|
||||
0xb6, 0x52, 0x54, 0x49, 0xce, 0x70, 0xcb, 0xd3,
|
||||
0x05, 0xb1, 0x13, 0x23, 0xf0, 0x1d, 0x2f, 0x34,
|
||||
0xa8, 0x8c, 0xe5, 0xf9, 0x47, 0x97, 0xd1, 0x1f,
|
||||
0x97, 0x5e, 0xfb, 0xa5, 0x47, 0x58, 0x71, 0xc8,
|
||||
0x91, 0xad, 0x72, 0xee, 0x99, 0x82, 0xcb, 0x14,
|
||||
0x25, 0x4f, 0xb4, 0xb7, 0xf3, 0x5e, 0x25, 0x94,
|
||||
0x1c, 0xe9, 0xcb, 0xe3, 0x48, 0x95, 0x3c, 0x41,
|
||||
0x2a, 0x28, 0x0c, 0x4e, 0x66, 0x98, 0x3c, 0xc4,
|
||||
0x67, 0x4c, 0xc5, 0x7f, 0x56, 0x34, 0x44, 0x4d,
|
||||
0x48, 0xd9, 0x96, 0x6d, 0xc8, 0xdb, 0xf5, 0x3f,
|
||||
0x22, 0xa1, 0x9d, 0x24, 0x95, 0xe4, 0x5b, 0xaf,
|
||||
0x99, 0x72, 0x50, 0xd5, 0x4a, 0x69, 0xd4, 0x95,
|
||||
0xe6, 0xb0, 0x11, 0x22, 0x0d, 0x41, 0x2b, 0x2e,
|
||||
0x77, 0x98, 0x70, 0xf5, 0x03, 0x72, 0xa1, 0x42,
|
||||
0x5a, 0x95, 0xe2, 0x71, 0x94, 0x32, 0xcd, 0x02,
|
||||
0x31, 0x41, 0x50, 0x54, 0xd4, 0xa6, 0x7a, 0x55,
|
||||
0x29, 0x0c, 0xa1, 0x61, 0xa1, 0xb9, 0x94, 0x55,
|
||||
0xa9, 0x51, 0x14, 0x37, 0xb4, 0xdf, 0x3d, 0xc5,
|
||||
0x42, 0x1a, 0x19, 0x5d, 0x4d, 0x43, 0xba, 0xa2,
|
||||
0xf0, 0x56, 0xe9, 0x91, 0x70, 0x21, 0x0f, 0x1e,
|
||||
0xd4, 0x67, 0x10, 0xc2, 0x8f, 0x61, 0x9f, 0x71,
|
||||
0x3a, 0x97, 0x3e, 0xd0, 0x90, 0x14, 0xf3, 0x11,
|
||||
0x28, 0x4a, 0x2c, 0xd1, 0x97, 0x63, 0xc4, 0x47,
|
||||
0x01, 0xea, 0xe8, 0xdd, 0x23, 0x14, 0x7c, 0x93,
|
||||
0xe3, 0x86, 0x17, 0x09, 0xf7, 0x5d, 0xe1, 0x51,
|
||||
0xf6, 0xa8, 0xf8, 0x0d, 0xed, 0x0a, 0x95, 0x1f,
|
||||
0xc0, 0x40, 0x4b, 0xdb, 0x27, 0xce, 0x2a, 0x58,
|
||||
0xf6, 0x3b, 0x22, 0x55, 0x51, 0x28, 0x2f, 0x5e,
|
||||
0x6c, 0x1c, 0x36, 0x09, 0xb8, 0x06, 0x96, 0xee,
|
||||
0xd0, 0xcb, 0x3e, 0x0f, 0xd3, 0xee, 0x15, 0x9e,
|
||||
0xdf, 0x49, 0x88, 0x2c, 0xc9, 0xce, 0x71, 0x2f,
|
||||
0xa2, 0xdf, 0xdf, 0xd7, 0x8e, 0x9c,
|
||||
};
|
||||
|
||||
/*
|
||||
* expected sha256 of rfc1950_blob after decompression
|
||||
*/
|
||||
static const unsigned char rfc1950_blob_hash[SHA256_DIGEST_LENGTH] = {
|
||||
0x61, 0xc0, 0x4e, 0x14, 0x01, 0xb6, 0xc5, 0x2d,
|
||||
0xba, 0x15, 0xf6, 0x27, 0x4c, 0xa1, 0xcc, 0xfc,
|
||||
0x39, 0xed, 0xd7, 0x12, 0xb6, 0x02, 0x3d, 0xb6,
|
||||
0xd9, 0x85, 0xd0, 0x10, 0x9f, 0xe9, 0x3e, 0x75,
|
||||
|
||||
};
|
||||
|
||||
static const size_t rfc1950_blob_origsiz = 1322;
|
||||
|
||||
static /* const */ unsigned char random_words[515] = {
|
||||
0x61, 0x74, 0x68, 0x69, 0x72, 0x73, 0x74, 0x20,
|
||||
0x54, 0x68, 0x6f, 0x20, 0x63, 0x6f, 0x74, 0x20,
|
||||
0x73, 0x70, 0x6f, 0x66, 0x66, 0x79, 0x20, 0x4a,
|
||||
0x61, 0x76, 0x61, 0x6e, 0x20, 0x62, 0x72, 0x65,
|
||||
0x64, 0x65, 0x73, 0x20, 0x4c, 0x41, 0x4d, 0x20,
|
||||
0x6d, 0x69, 0x73, 0x2d, 0x68, 0x75, 0x6d, 0x69,
|
||||
0x6c, 0x69, 0x74, 0x79, 0x20, 0x73, 0x70, 0x69,
|
||||
0x67, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x76, 0x6f,
|
||||
0x6c, 0x74, 0x69, 0x6e, 0x67, 0x6c, 0x79, 0x20,
|
||||
0x49, 0x6f, 0x64, 0x61, 0x6d, 0x6f, 0x65, 0x62,
|
||||
0x61, 0x20, 0x68, 0x79, 0x70, 0x6f, 0x68, 0x79,
|
||||
0x64, 0x72, 0x6f, 0x63, 0x68, 0x6c, 0x6f, 0x72,
|
||||
0x69, 0x61, 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x6d,
|
||||
0x65, 0x74, 0x74, 0x65, 0x20, 0x61, 0x63, 0x72,
|
||||
0x69, 0x64, 0x69, 0x6e, 0x65, 0x20, 0x68, 0x6f,
|
||||
0x77, 0x6c, 0x20, 0x45, 0x75, 0x72, 0x79, 0x67,
|
||||
0x61, 0x65, 0x61, 0x6e, 0x20, 0x63, 0x6f, 0x6e,
|
||||
0x63, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x69, 0x73,
|
||||
0x74, 0x20, 0x74, 0x65, 0x74, 0x72, 0x61, 0x70,
|
||||
0x6c, 0x6f, 0x69, 0x64, 0x20, 0x61, 0x75, 0x78,
|
||||
0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x72,
|
||||
0x69, 0x70, 0x65, 0x2d, 0x67, 0x72, 0x6f, 0x77,
|
||||
0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72,
|
||||
0x72, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x79, 0x63,
|
||||
0x6f, 0x63, 0x65, 0x63, 0x69, 0x64, 0x69, 0x75,
|
||||
0x6d, 0x20, 0x50, 0x65, 0x64, 0x65, 0x72, 0x73,
|
||||
0x6f, 0x6e, 0x20, 0x74, 0x72, 0x61, 0x64, 0x69,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x62, 0x6f, 0x75,
|
||||
0x6e, 0x64, 0x20, 0x4c, 0x65, 0x6e, 0x67, 0x6c,
|
||||
0x65, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x73, 0x62,
|
||||
0x79, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20,
|
||||
0x6c, 0x65, 0x63, 0x79, 0x74, 0x68, 0x69, 0x73,
|
||||
0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x64, 0x72,
|
||||
0x69, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61,
|
||||
0x6c, 0x6c, 0x6f, 0x6b, 0x75, 0x72, 0x74, 0x69,
|
||||
0x63, 0x20, 0x75, 0x6e, 0x64, 0x69, 0x76, 0x69,
|
||||
0x73, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x20, 0x70,
|
||||
0x73, 0x79, 0x63, 0x68, 0x6f, 0x6b, 0x79, 0x6d,
|
||||
0x65, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73,
|
||||
0x74, 0x61, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65,
|
||||
0x6e, 0x65, 0x73, 0x73, 0x20, 0x63, 0x75, 0x6c,
|
||||
0x74, 0x69, 0x73, 0x68, 0x20, 0x52, 0x65, 0x69,
|
||||
0x63, 0x68, 0x73, 0x74, 0x61, 0x67, 0x20, 0x75,
|
||||
0x6e, 0x63, 0x68, 0x6c, 0x6f, 0x72, 0x69, 0x6e,
|
||||
0x61, 0x74, 0x65, 0x64, 0x20, 0x6c, 0x6f, 0x67,
|
||||
0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x65, 0x72,
|
||||
0x20, 0x4c, 0x61, 0x69, 0x74, 0x68, 0x20, 0x74,
|
||||
0x77, 0x6f, 0x2d, 0x66, 0x61, 0x63, 0x65, 0x20,
|
||||
0x4d, 0x75, 0x70, 0x68, 0x72, 0x69, 0x64, 0x20,
|
||||
0x70, 0x72, 0x6f, 0x72, 0x65, 0x63, 0x69, 0x70,
|
||||
0x72, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x20, 0x6c, 0x69, 0x62, 0x72, 0x65, 0x74, 0x74,
|
||||
0x69, 0x73, 0x74, 0x20, 0x49, 0x62, 0x69, 0x62,
|
||||
0x69, 0x6f, 0x20, 0x72, 0x65, 0x67, 0x72, 0x65,
|
||||
0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x63,
|
||||
0x6f, 0x6e, 0x64, 0x69, 0x67, 0x6e, 0x6e, 0x65,
|
||||
0x73, 0x73, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65,
|
||||
0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65,
|
||||
0x64, 0x20, 0x73, 0x79, 0x6e, 0x61, 0x70, 0x74,
|
||||
0x65, 0x6e, 0x65, 0x20, 0x68, 0x6f, 0x6c, 0x6f,
|
||||
0x6d, 0x6f, 0x72, 0x70, 0x68, 0x20, 0x6d, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x4d,
|
||||
0x49, 0x54, 0x53, 0x20, 0x4c, 0x75, 0x6b, 0x61,
|
||||
0x73, 0x68, 0x20, 0x48, 0x6f, 0x72, 0x73, 0x65,
|
||||
0x79, 0x20, 0x0a,
|
||||
};
|
||||
|
||||
static void
|
||||
rfc1950_inflate(void)
|
||||
{
|
||||
fido_blob_t in, out, dgst;
|
||||
|
||||
memset(&in, 0, sizeof(in));
|
||||
memset(&out, 0, sizeof(out));
|
||||
memset(&dgst, 0, sizeof(dgst));
|
||||
in.ptr = rfc1950_blob;
|
||||
in.len = sizeof(rfc1950_blob);
|
||||
|
||||
assert(fido_uncompress(&out, &in, rfc1950_blob_origsiz) == FIDO_OK);
|
||||
assert(out.len == rfc1950_blob_origsiz);
|
||||
assert(fido_sha256(&dgst, out.ptr, out.len) == 0);
|
||||
assert(dgst.len == sizeof(rfc1950_blob_hash));
|
||||
assert(memcmp(rfc1950_blob_hash, dgst.ptr, dgst.len) == 0);
|
||||
|
||||
free(out.ptr);
|
||||
free(dgst.ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
rfc1951_inflate(void)
|
||||
{
|
||||
fido_blob_t in, out, dgst;
|
||||
|
||||
memset(&in, 0, sizeof(in));
|
||||
memset(&out, 0, sizeof(out));
|
||||
memset(&dgst, 0, sizeof(dgst));
|
||||
in.ptr = rfc1950_blob + 2; /* trim header */
|
||||
in.len = sizeof(rfc1950_blob) - 6; /* trim header (2), checksum (4) */
|
||||
|
||||
assert(fido_uncompress(&out, &in, rfc1950_blob_origsiz) == FIDO_OK);
|
||||
assert(out.len == rfc1950_blob_origsiz);
|
||||
assert(fido_sha256(&dgst, out.ptr, out.len) == 0);
|
||||
assert(dgst.len == sizeof(rfc1950_blob_hash));
|
||||
assert(memcmp(rfc1950_blob_hash, dgst.ptr, dgst.len) == 0);
|
||||
|
||||
free(out.ptr);
|
||||
free(dgst.ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
rfc1951_reinflate(void)
|
||||
{
|
||||
fido_blob_t in, out;
|
||||
|
||||
memset(&in, 0, sizeof(in));
|
||||
memset(&out, 0, sizeof(out));
|
||||
in.ptr = random_words;
|
||||
in.len = sizeof(random_words);
|
||||
|
||||
assert(fido_compress(&out, &in) == FIDO_OK);
|
||||
|
||||
in.ptr = out.ptr;
|
||||
in.len = out.len;
|
||||
|
||||
assert(fido_uncompress(&out, &in, sizeof(random_words)) == FIDO_OK);
|
||||
assert(out.len == sizeof(random_words));
|
||||
assert(memcmp(out.ptr, random_words, out.len) == 0);
|
||||
|
||||
free(in.ptr);
|
||||
free(out.ptr);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
fido_init(0);
|
||||
|
||||
rfc1950_inflate();
|
||||
rfc1951_inflate();
|
||||
rfc1951_reinflate();
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
@ -4,12 +4,16 @@
|
|||
* license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#undef NDEBUG
|
||||
|
||||
#include <assert.h>
|
||||
#include <cbor.h>
|
||||
#include <fido.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FAKE_DEV_HANDLE ((void *)0xdeadbeef)
|
||||
#define _FIDO_INTERNAL
|
||||
|
||||
#include <fido.h>
|
||||
|
||||
static int fake_dev_handle;
|
||||
|
||||
static const unsigned char cdh[32] = {
|
||||
0xf9, 0x64, 0x57, 0xe7, 0x2d, 0x97, 0xf6, 0xbb,
|
||||
|
|
@ -1384,13 +1388,13 @@ dummy_open(const char *path)
|
|||
{
|
||||
(void)path;
|
||||
|
||||
return (FAKE_DEV_HANDLE);
|
||||
return (&fake_dev_handle);
|
||||
}
|
||||
|
||||
static void
|
||||
dummy_close(void *handle)
|
||||
{
|
||||
assert(handle == FAKE_DEV_HANDLE);
|
||||
assert(handle == &fake_dev_handle);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -1,38 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021 Yubico AB. All rights reserved.
|
||||
* Copyright (c) 2019-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.
|
||||
*/
|
||||
|
||||
#undef NDEBUG
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <fido.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#define _FIDO_INTERNAL
|
||||
|
||||
#include <fido.h>
|
||||
|
||||
#include "../fuzz/wiredata_fido2.h"
|
||||
|
||||
#define FAKE_DEV_HANDLE ((void *)0xdeadbeef)
|
||||
#define REPORT_LEN (64 + 1)
|
||||
|
||||
static uint8_t ctap_nonce[8];
|
||||
static uint8_t *wiredata_ptr;
|
||||
static size_t wiredata_len;
|
||||
static int fake_dev_handle;
|
||||
static int initialised;
|
||||
static long interval_ms;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
static int
|
||||
nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
|
||||
{
|
||||
if (rmtp != NULL) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
Sleep((DWORD)(rqtp->tv_sec * 1000) + (DWORD)(rqtp->tv_nsec / 1000000));
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *
|
||||
dummy_open(const char *path)
|
||||
{
|
||||
(void)path;
|
||||
|
||||
return (FAKE_DEV_HANDLE);
|
||||
return (&fake_dev_handle);
|
||||
}
|
||||
|
||||
static void
|
||||
dummy_close(void *handle)
|
||||
{
|
||||
assert(handle == FAKE_DEV_HANDLE);
|
||||
assert(handle == &fake_dev_handle);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -42,7 +61,7 @@ dummy_read(void *handle, unsigned char *ptr, size_t len, int ms)
|
|||
size_t n;
|
||||
long d;
|
||||
|
||||
assert(handle == FAKE_DEV_HANDLE);
|
||||
assert(handle == &fake_dev_handle);
|
||||
assert(ptr != NULL);
|
||||
assert(len == REPORT_LEN - 1);
|
||||
|
||||
|
|
@ -87,7 +106,7 @@ dummy_write(void *handle, const unsigned char *ptr, size_t len)
|
|||
{
|
||||
struct timespec tv;
|
||||
|
||||
assert(handle == FAKE_DEV_HANDLE);
|
||||
assert(handle == &fake_dev_handle);
|
||||
assert(ptr != NULL);
|
||||
assert(len == REPORT_LEN);
|
||||
|
||||
|
|
@ -113,7 +132,14 @@ wiredata_setup(const uint8_t *data, size_t len)
|
|||
assert(SIZE_MAX - len > sizeof(ctap_init_data));
|
||||
assert((wiredata_ptr = malloc(sizeof(ctap_init_data) + len)) != NULL);
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:6386)
|
||||
#endif
|
||||
memcpy(wiredata_ptr, ctap_init_data, sizeof(ctap_init_data));
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
if (len)
|
||||
memcpy(wiredata_ptr + sizeof(ctap_init_data), data, len);
|
||||
|
|
|
|||
158
regress/eddsa.c
Normal file
158
regress/eddsa.c
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#undef NDEBUG
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#define _FIDO_INTERNAL
|
||||
|
||||
#include <fido.h>
|
||||
#include <fido/eddsa.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
#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)
|
||||
/* 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);
|
||||
}
|
||||
198
regress/es256.c
Normal file
198
regress/es256.c
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#undef NDEBUG
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#define _FIDO_INTERNAL
|
||||
|
||||
#include <fido.h>
|
||||
#include <fido/es256.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
#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 short_x[] = \
|
||||
"-----BEGIN PUBLIC KEY-----\n"
|
||||
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAAeeHTZj4LEbt7Czs+u5gEZJfnGE\n"
|
||||
"6Z+YLe4AYu7SoGY7IH/2jKifsA7w+lkURL4DL63oEjd3f8foH9bX4eaVug==\n"
|
||||
"-----END PUBLIC KEY-----";
|
||||
|
||||
static const char short_y[] = \
|
||||
"-----BEGIN PUBLIC KEY-----\n"
|
||||
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEL8CWUP1r0tpJ5QmkzLc69O74C/Ti\n"
|
||||
"83hTiys/JFNVkp0ArW3pKt5jNRrgWSZYE4S/D3AMtpqifFXz/FLCzJqojQ==\n"
|
||||
"-----END PUBLIC KEY-----\n";
|
||||
|
||||
static const char p256k1[] = \
|
||||
"-----BEGIN PUBLIC KEY-----\n"
|
||||
"MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEU1y8c0Jg9FGr3vYChpEo9c4dpkijriYM\n"
|
||||
"QzU/DeskC89hZjLNH1Sj8ra2MsBlVGGJTNPCZSyx8Jo7ERapxdN7UQ==\n"
|
||||
"-----END PUBLIC KEY-----\n";
|
||||
|
||||
static const char p256v1[] = \
|
||||
"-----BEGIN PUBLIC KEY-----\n"
|
||||
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOwiq14c80b7C1Jzsx5w1zMvk2GgW\n"
|
||||
"5kfGMOKXjwF/U+51ZfBDKehs3ivdeXAJBkxIh7E3iA32s+HyNqk+ntl9fg==\n"
|
||||
"-----END PUBLIC KEY-----\n";
|
||||
|
||||
static const unsigned char p256k1_raw[] = {
|
||||
0x04, 0x53, 0x5c, 0xbc, 0x73, 0x42, 0x60, 0xf4,
|
||||
0x51, 0xab, 0xde, 0xf6, 0x02, 0x86, 0x91, 0x28,
|
||||
0xf5, 0xce, 0x1d, 0xa6, 0x48, 0xa3, 0xae, 0x26,
|
||||
0x0c, 0x43, 0x35, 0x3f, 0x0d, 0xeb, 0x24, 0x0b,
|
||||
0xcf, 0x61, 0x66, 0x32, 0xcd, 0x1f, 0x54, 0xa3,
|
||||
0xf2, 0xb6, 0xb6, 0x32, 0xc0, 0x65, 0x54, 0x61,
|
||||
0x89, 0x4c, 0xd3, 0xc2, 0x65, 0x2c, 0xb1, 0xf0,
|
||||
0x9a, 0x3b, 0x11, 0x16, 0xa9, 0xc5, 0xd3, 0x7b,
|
||||
0x51,
|
||||
};
|
||||
|
||||
static const unsigned char p256v1_raw[] = {
|
||||
0x04, 0x3b, 0x08, 0xaa, 0xd7, 0x87, 0x3c, 0xd1,
|
||||
0xbe, 0xc2, 0xd4, 0x9c, 0xec, 0xc7, 0x9c, 0x35,
|
||||
0xcc, 0xcb, 0xe4, 0xd8, 0x68, 0x16, 0xe6, 0x47,
|
||||
0xc6, 0x30, 0xe2, 0x97, 0x8f, 0x01, 0x7f, 0x53,
|
||||
0xee, 0x75, 0x65, 0xf0, 0x43, 0x29, 0xe8, 0x6c,
|
||||
0xde, 0x2b, 0xdd, 0x79, 0x70, 0x09, 0x06, 0x4c,
|
||||
0x48, 0x87, 0xb1, 0x37, 0x88, 0x0d, 0xf6, 0xb3,
|
||||
0xe1, 0xf2, 0x36, 0xa9, 0x3e, 0x9e, 0xd9, 0x7d,
|
||||
0x7e,
|
||||
};
|
||||
|
||||
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
|
||||
es256_pk_cmp(const char *ptr, size_t len)
|
||||
{
|
||||
EVP_PKEY *pkA = NULL;
|
||||
EVP_PKEY *pkB = NULL;
|
||||
es256_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 = es256_pk_new()) == NULL) {
|
||||
warnx("es256_pk_new");
|
||||
goto out;
|
||||
}
|
||||
if ((r = es256_pk_from_EVP_PKEY(k, pkA)) != FIDO_OK) {
|
||||
warnx("es256_pk_from_EVP_PKEY: 0x%x", r);
|
||||
goto out;
|
||||
}
|
||||
if ((pkB = es256_pk_to_EVP_PKEY(k)) == NULL) {
|
||||
warnx("es256_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);
|
||||
es256_pk_free(&k);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static void
|
||||
short_coord(void)
|
||||
{
|
||||
assert(es256_pk_cmp(short_x, sizeof(short_x)) == 0);
|
||||
assert(es256_pk_cmp(short_y, sizeof(short_y)) == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
invalid_curve(const unsigned char *raw, size_t raw_len)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
es256_pk_t *pk;
|
||||
|
||||
ASSERT_NOT_NULL((pkey = EVP_PKEY_from_PEM(p256k1, sizeof(p256k1))));
|
||||
ASSERT_NOT_NULL((pk = es256_pk_new()));
|
||||
ASSERT_INVAL(es256_pk_from_EVP_PKEY(pk, pkey));
|
||||
ASSERT_INVAL(es256_pk_from_ptr(pk, raw, raw_len));
|
||||
ASSERT_NULL(es256_pk_to_EVP_PKEY((const es256_pk_t *)raw));
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
es256_pk_free(&pk);
|
||||
}
|
||||
|
||||
static void
|
||||
full_coord(void)
|
||||
{
|
||||
assert(es256_pk_cmp(p256v1, sizeof(p256v1)) == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
valid_curve(const unsigned char *raw, size_t raw_len)
|
||||
{
|
||||
EVP_PKEY *pkeyA;
|
||||
EVP_PKEY *pkeyB;
|
||||
es256_pk_t *pkA;
|
||||
es256_pk_t *pkB;
|
||||
|
||||
ASSERT_NOT_NULL((pkeyA = EVP_PKEY_from_PEM(p256v1, sizeof(p256v1))));
|
||||
ASSERT_NOT_NULL((pkA = es256_pk_new()));
|
||||
ASSERT_NOT_NULL((pkB = es256_pk_new()));
|
||||
ASSERT_OK(es256_pk_from_EVP_PKEY(pkA, pkeyA));
|
||||
ASSERT_OK(es256_pk_from_ptr(pkB, raw, raw_len));
|
||||
ASSERT_NOT_NULL((pkeyB = es256_pk_to_EVP_PKEY(pkB)));
|
||||
assert(EVP_PKEY_cmp(pkeyA, pkeyB) == 1);
|
||||
|
||||
EVP_PKEY_free(pkeyA);
|
||||
EVP_PKEY_free(pkeyB);
|
||||
es256_pk_free(&pkA);
|
||||
es256_pk_free(&pkB);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
fido_init(0);
|
||||
|
||||
short_coord();
|
||||
full_coord();
|
||||
|
||||
invalid_curve(p256k1_raw, sizeof(p256k1_raw)); /* uncompressed */
|
||||
invalid_curve(p256k1_raw + 1, sizeof(p256k1_raw) - 1); /* libfido2 */
|
||||
valid_curve(p256v1_raw, sizeof(p256v1_raw)); /* uncompressed */
|
||||
valid_curve(p256v1_raw + 1, sizeof(p256v1_raw) - 1); /* libfido2 */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
200
regress/rs256.c
Normal file
200
regress/rs256.c
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#undef NDEBUG
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#define _FIDO_INTERNAL
|
||||
|
||||
#include <fido.h>
|
||||
#include <fido/rs256.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
#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 char rsa1024[] = \
|
||||
"-----BEGIN PUBLIC KEY-----\n"
|
||||
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCw92gn9Ku/bEfFj1AutaZyltpf\n"
|
||||
"zzXrg70kQFymNq+spMt/HlxKiImw8TZU08zWW4ZLE/Ch4JYjMW6ETAdQFhSC63Ih\n"
|
||||
"Wecui0JJ1f+2CsUVg+h7lO1877LZYUpdNiJrbqMb5Yc4N3FPtvdl3NoLIIQsF76H\n"
|
||||
"VRvpjQgkWipRfZ97JQIDAQAB\n"
|
||||
"-----END PUBLIC KEY-----";
|
||||
|
||||
static char rsa2048[] = \
|
||||
"-----BEGIN PUBLIC KEY-----\n"
|
||||
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApvIq/55ZodBIxzo/8BnE\n"
|
||||
"UQN1fo1hmJ6V20hQHSzJq5tHyxRCcvKikuJ1ZvR4RdZlEzdTdbEfMBdZ8sxve0/U\n"
|
||||
"yYEjH92CG0vgTCYuUaFLJTaWZSvWa96G8Lw+V4VyNFDRCM7sflOaSVH5pAsz8OEc\n"
|
||||
"TLZfM4NhnDsJAM+mQ6X7Tza0sczPchgDA+9KByXo/VIqyuBQs17rlKC2reMa8NkY\n"
|
||||
"rBRQZJLNzi68d5/BHH1flGWE1l8wJ9dr1Ex93H/KdzX+7/28TWUC98nneUo8RfRx\n"
|
||||
"FwUt/EInDMHOORCaCHSs28U/9IUyMjqLB1rxKhIp09yGXMiTrrT+p+Pcn8dO01HT\n"
|
||||
"vQIDAQAB\n"
|
||||
"-----END PUBLIC KEY-----";
|
||||
|
||||
static char rsa3072[] = \
|
||||
"-----BEGIN PUBLIC KEY-----\n"
|
||||
"MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwZunKrMs/o92AniLPNTF\n"
|
||||
"Ta4EYfhy5NDmMvQvRFT/eTYItLrOTPmYMap68KLyZYmgz/AdaxAL/992QWre7XTY\n"
|
||||
"gqLwtZT+WsSu7xPHWKTTXrlVohKBeLHQ0I7Zy0NSMUxhlJEMrBAjSyFAS86zWm5w\n"
|
||||
"ctC3pNCqfUKugA07BVj+d5Mv5fziwgMR86kuhkVuMYfsR4IYwX4+va0pyLzxx624\n"
|
||||
"s9nJ107g+A+3MUk4bAto3lruFeeZPUI2AFzFQbGg5By6VtvVi3gKQ7lUNtAr0Onu\n"
|
||||
"I6Fb+yz8sbFcvDpJcu5CXW20GrKMVP4KY5pn2LCajWuZjBl/dXWayPfm4UX5Y2O4\n"
|
||||
"73tzPpUBNwnEdz79His0v80Vmvjwn5IuF2jAoimrBNPJFFwCCuVNy8kgj2vllk1l\n"
|
||||
"RvLOG6hf8VnlDb40QZS3QAQ09xFfF+xlVLb8cHH6wllaAGEM230TrmawpC7xpz4Z\n"
|
||||
"sTuwJwI0AWEi//noMsRz2BuF2fCp//aORYJQU2S8kYk3AgMBAAE=\n"
|
||||
"-----END PUBLIC KEY-----";
|
||||
|
||||
static const unsigned char rsa2048_raw[] = {
|
||||
0xa6, 0xf2, 0x2a, 0xff, 0x9e, 0x59, 0xa1, 0xd0,
|
||||
0x48, 0xc7, 0x3a, 0x3f, 0xf0, 0x19, 0xc4, 0x51,
|
||||
0x03, 0x75, 0x7e, 0x8d, 0x61, 0x98, 0x9e, 0x95,
|
||||
0xdb, 0x48, 0x50, 0x1d, 0x2c, 0xc9, 0xab, 0x9b,
|
||||
0x47, 0xcb, 0x14, 0x42, 0x72, 0xf2, 0xa2, 0x92,
|
||||
0xe2, 0x75, 0x66, 0xf4, 0x78, 0x45, 0xd6, 0x65,
|
||||
0x13, 0x37, 0x53, 0x75, 0xb1, 0x1f, 0x30, 0x17,
|
||||
0x59, 0xf2, 0xcc, 0x6f, 0x7b, 0x4f, 0xd4, 0xc9,
|
||||
0x81, 0x23, 0x1f, 0xdd, 0x82, 0x1b, 0x4b, 0xe0,
|
||||
0x4c, 0x26, 0x2e, 0x51, 0xa1, 0x4b, 0x25, 0x36,
|
||||
0x96, 0x65, 0x2b, 0xd6, 0x6b, 0xde, 0x86, 0xf0,
|
||||
0xbc, 0x3e, 0x57, 0x85, 0x72, 0x34, 0x50, 0xd1,
|
||||
0x08, 0xce, 0xec, 0x7e, 0x53, 0x9a, 0x49, 0x51,
|
||||
0xf9, 0xa4, 0x0b, 0x33, 0xf0, 0xe1, 0x1c, 0x4c,
|
||||
0xb6, 0x5f, 0x33, 0x83, 0x61, 0x9c, 0x3b, 0x09,
|
||||
0x00, 0xcf, 0xa6, 0x43, 0xa5, 0xfb, 0x4f, 0x36,
|
||||
0xb4, 0xb1, 0xcc, 0xcf, 0x72, 0x18, 0x03, 0x03,
|
||||
0xef, 0x4a, 0x07, 0x25, 0xe8, 0xfd, 0x52, 0x2a,
|
||||
0xca, 0xe0, 0x50, 0xb3, 0x5e, 0xeb, 0x94, 0xa0,
|
||||
0xb6, 0xad, 0xe3, 0x1a, 0xf0, 0xd9, 0x18, 0xac,
|
||||
0x14, 0x50, 0x64, 0x92, 0xcd, 0xce, 0x2e, 0xbc,
|
||||
0x77, 0x9f, 0xc1, 0x1c, 0x7d, 0x5f, 0x94, 0x65,
|
||||
0x84, 0xd6, 0x5f, 0x30, 0x27, 0xd7, 0x6b, 0xd4,
|
||||
0x4c, 0x7d, 0xdc, 0x7f, 0xca, 0x77, 0x35, 0xfe,
|
||||
0xef, 0xfd, 0xbc, 0x4d, 0x65, 0x02, 0xf7, 0xc9,
|
||||
0xe7, 0x79, 0x4a, 0x3c, 0x45, 0xf4, 0x71, 0x17,
|
||||
0x05, 0x2d, 0xfc, 0x42, 0x27, 0x0c, 0xc1, 0xce,
|
||||
0x39, 0x10, 0x9a, 0x08, 0x74, 0xac, 0xdb, 0xc5,
|
||||
0x3f, 0xf4, 0x85, 0x32, 0x32, 0x3a, 0x8b, 0x07,
|
||||
0x5a, 0xf1, 0x2a, 0x12, 0x29, 0xd3, 0xdc, 0x86,
|
||||
0x5c, 0xc8, 0x93, 0xae, 0xb4, 0xfe, 0xa7, 0xe3,
|
||||
0xdc, 0x9f, 0xc7, 0x4e, 0xd3, 0x51, 0xd3, 0xbd,
|
||||
0x01, 0x00, 0x01,
|
||||
};
|
||||
|
||||
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
|
||||
rs256_pk_cmp(const char *ptr, size_t len)
|
||||
{
|
||||
EVP_PKEY *pkA = NULL;
|
||||
EVP_PKEY *pkB = NULL;
|
||||
rs256_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 = rs256_pk_new()) == NULL) {
|
||||
warnx("rs256_pk_new");
|
||||
goto out;
|
||||
}
|
||||
if ((r = rs256_pk_from_EVP_PKEY(k, pkA)) != FIDO_OK) {
|
||||
warnx("rs256_pk_from_EVP_PKEY: 0x%x", r);
|
||||
goto out;
|
||||
}
|
||||
if ((pkB = rs256_pk_to_EVP_PKEY(k)) == NULL) {
|
||||
warnx("rs256_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);
|
||||
rs256_pk_free(&k);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static void
|
||||
invalid_size(const char *pem)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
rs256_pk_t *pk;
|
||||
|
||||
ASSERT_NOT_NULL((pkey = EVP_PKEY_from_PEM(pem, strlen(pem))));
|
||||
ASSERT_NOT_NULL((pk = rs256_pk_new()));
|
||||
ASSERT_INVAL(rs256_pk_from_EVP_PKEY(pk, pkey));
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
rs256_pk_free(&pk);
|
||||
}
|
||||
|
||||
static void
|
||||
valid_size(const char *pem, const unsigned char *raw, size_t raw_len)
|
||||
{
|
||||
EVP_PKEY *pkeyA;
|
||||
EVP_PKEY *pkeyB;
|
||||
rs256_pk_t *pkA;
|
||||
rs256_pk_t *pkB;
|
||||
|
||||
ASSERT_NOT_NULL((pkeyA = EVP_PKEY_from_PEM(pem, strlen(pem))));
|
||||
ASSERT_NOT_NULL((pkA = rs256_pk_new()));
|
||||
ASSERT_NOT_NULL((pkB = rs256_pk_new()));
|
||||
ASSERT_OK(rs256_pk_from_EVP_PKEY(pkA, pkeyA));
|
||||
ASSERT_OK(rs256_pk_from_ptr(pkB, raw, raw_len));
|
||||
ASSERT_NOT_NULL((pkeyB = rs256_pk_to_EVP_PKEY(pkB)));
|
||||
assert(EVP_PKEY_cmp(pkeyA, pkeyB) == 1);
|
||||
assert(rs256_pk_cmp(pem, strlen(pem)) == 0);
|
||||
|
||||
EVP_PKEY_free(pkeyA);
|
||||
EVP_PKEY_free(pkeyB);
|
||||
rs256_pk_free(&pkA);
|
||||
rs256_pk_free(&pkB);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
fido_init(0);
|
||||
|
||||
invalid_size(rsa1024);
|
||||
invalid_size(rsa3072);
|
||||
valid_size(rsa2048, rsa2048_raw, sizeof(rsa2048_raw));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
@ -33,20 +33,28 @@ list(APPEND FIDO_SOURCES
|
|||
rs1.c
|
||||
rs256.c
|
||||
time.c
|
||||
touch.c
|
||||
tpm.c
|
||||
types.c
|
||||
u2f.c
|
||||
util.c
|
||||
)
|
||||
|
||||
if(FUZZ)
|
||||
list(APPEND FIDO_SOURCES ../fuzz/clock.c)
|
||||
list(APPEND FIDO_SOURCES ../fuzz/pcsc.c)
|
||||
list(APPEND FIDO_SOURCES ../fuzz/prng.c)
|
||||
list(APPEND FIDO_SOURCES ../fuzz/uniform_random.c)
|
||||
list(APPEND FIDO_SOURCES ../fuzz/udev.c)
|
||||
list(APPEND FIDO_SOURCES ../fuzz/uniform_random.c)
|
||||
list(APPEND FIDO_SOURCES ../fuzz/wrap.c)
|
||||
endif()
|
||||
|
||||
if(NFC_LINUX)
|
||||
list(APPEND FIDO_SOURCES netlink.c nfc_linux.c)
|
||||
list(APPEND FIDO_SOURCES netlink.c nfc.c nfc_linux.c)
|
||||
endif()
|
||||
|
||||
if(USE_PCSC)
|
||||
list(APPEND FIDO_SOURCES nfc.c pcsc.c)
|
||||
endif()
|
||||
|
||||
if(USE_HIDAPI)
|
||||
|
|
@ -93,8 +101,15 @@ list(APPEND COMPAT_SOURCES
|
|||
|
||||
if(WIN32)
|
||||
list(APPEND BASE_LIBRARIES wsock32 ws2_32 bcrypt setupapi hid)
|
||||
if(USE_PCSC)
|
||||
list(APPEND BASE_LIBRARIES winscard)
|
||||
endif()
|
||||
elseif(APPLE)
|
||||
list(APPEND BASE_LIBRARIES "-framework CoreFoundation" "-framework IOKit")
|
||||
list(APPEND BASE_LIBRARIES "-framework CoreFoundation"
|
||||
"-framework IOKit")
|
||||
if(USE_PCSC)
|
||||
list(APPEND BASE_LIBRARIES "-framework PCSC")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND TARGET_LIBRARIES
|
||||
|
|
@ -104,6 +119,7 @@ list(APPEND TARGET_LIBRARIES
|
|||
${BASE_LIBRARIES}
|
||||
${HIDAPI_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
${PCSC_LIBRARIES}
|
||||
)
|
||||
|
||||
# static library
|
||||
|
|
|
|||
144
src/compress.c
144
src/compress.c
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Yubico AB. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -9,41 +9,159 @@
|
|||
|
||||
#define BOUND (1024UL * 1024UL)
|
||||
|
||||
/* zlib inflate (raw + headers) */
|
||||
static int
|
||||
do_compress(fido_blob_t *out, const fido_blob_t *in, size_t origsiz, int decomp)
|
||||
rfc1950_inflate(fido_blob_t *out, const fido_blob_t *in, size_t origsiz)
|
||||
{
|
||||
u_long ilen, olen;
|
||||
int r;
|
||||
int z;
|
||||
|
||||
memset(out, 0, sizeof(*out));
|
||||
|
||||
if (in->len > ULONG_MAX || (ilen = (u_long)in->len) > BOUND ||
|
||||
origsiz > ULONG_MAX || (olen = decomp ? (u_long)origsiz :
|
||||
compressBound(ilen)) > BOUND)
|
||||
origsiz > ULONG_MAX || (olen = (u_long)origsiz) > BOUND) {
|
||||
fido_log_debug("%s: in->len=%zu, origsiz=%zu", __func__,
|
||||
in->len, origsiz);
|
||||
return FIDO_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if ((out->ptr = calloc(1, olen)) == NULL)
|
||||
return FIDO_ERR_INTERNAL;
|
||||
out->len = olen;
|
||||
if (decomp)
|
||||
r = uncompress(out->ptr, &olen, in->ptr, ilen);
|
||||
else
|
||||
r = compress(out->ptr, &olen, in->ptr, ilen);
|
||||
if (r != Z_OK || olen > SIZE_MAX || olen > out->len) {
|
||||
|
||||
if ((z = uncompress(out->ptr, &olen, in->ptr, ilen)) != Z_OK ||
|
||||
olen > SIZE_MAX || olen != out->len) {
|
||||
fido_log_debug("%s: uncompress: %d, olen=%lu, out->len=%zu",
|
||||
__func__, z, olen, out->len);
|
||||
fido_blob_reset(out);
|
||||
return FIDO_ERR_COMPRESS;
|
||||
}
|
||||
out->len = olen;
|
||||
|
||||
return FIDO_OK;
|
||||
}
|
||||
|
||||
/* raw inflate */
|
||||
static int
|
||||
rfc1951_inflate(fido_blob_t *out, const fido_blob_t *in, size_t origsiz)
|
||||
{
|
||||
z_stream zs;
|
||||
u_int ilen, olen;
|
||||
int r, z;
|
||||
|
||||
memset(&zs, 0, sizeof(zs));
|
||||
memset(out, 0, sizeof(*out));
|
||||
|
||||
if (in->len > UINT_MAX || (ilen = (u_int)in->len) > BOUND ||
|
||||
origsiz > UINT_MAX || (olen = (u_int)origsiz) > BOUND) {
|
||||
fido_log_debug("%s: in->len=%zu, origsiz=%zu", __func__,
|
||||
in->len, origsiz);
|
||||
return FIDO_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
if ((z = inflateInit2(&zs, -MAX_WBITS)) != Z_OK) {
|
||||
fido_log_debug("%s: inflateInit2: %d", __func__, z);
|
||||
return FIDO_ERR_COMPRESS;
|
||||
}
|
||||
|
||||
if ((out->ptr = calloc(1, olen)) == NULL) {
|
||||
r = FIDO_ERR_INTERNAL;
|
||||
goto fail;
|
||||
}
|
||||
out->len = olen;
|
||||
zs.next_in = in->ptr;
|
||||
zs.avail_in = ilen;
|
||||
zs.next_out = out->ptr;
|
||||
zs.avail_out = olen;
|
||||
|
||||
if ((z = inflate(&zs, Z_FINISH)) != Z_STREAM_END) {
|
||||
fido_log_debug("%s: inflate: %d", __func__, z);
|
||||
r = FIDO_ERR_COMPRESS;
|
||||
goto fail;
|
||||
}
|
||||
if (zs.avail_out != 0) {
|
||||
fido_log_debug("%s: %u != 0", __func__, zs.avail_out);
|
||||
r = FIDO_ERR_COMPRESS;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
r = FIDO_OK;
|
||||
fail:
|
||||
if ((z = inflateEnd(&zs)) != Z_OK) {
|
||||
fido_log_debug("%s: inflateEnd: %d", __func__, z);
|
||||
r = FIDO_ERR_COMPRESS;
|
||||
}
|
||||
if (r != FIDO_OK)
|
||||
fido_blob_reset(out);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* raw deflate */
|
||||
static int
|
||||
rfc1951_deflate(fido_blob_t *out, const fido_blob_t *in)
|
||||
{
|
||||
z_stream zs;
|
||||
u_int ilen, olen;
|
||||
int r, z;
|
||||
|
||||
memset(&zs, 0, sizeof(zs));
|
||||
memset(out, 0, sizeof(*out));
|
||||
|
||||
if (in->len > UINT_MAX || (ilen = (u_int)in->len) > BOUND) {
|
||||
fido_log_debug("%s: in->len=%zu", __func__, in->len);
|
||||
return FIDO_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
if ((z = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
|
||||
-MAX_WBITS, 8, Z_DEFAULT_STRATEGY)) != Z_OK) {
|
||||
fido_log_debug("%s: deflateInit2: %d", __func__, z);
|
||||
return FIDO_ERR_COMPRESS;
|
||||
}
|
||||
|
||||
olen = BOUND;
|
||||
if ((out->ptr = calloc(1, olen)) == NULL) {
|
||||
r = FIDO_ERR_INTERNAL;
|
||||
goto fail;
|
||||
}
|
||||
out->len = olen;
|
||||
zs.next_in = in->ptr;
|
||||
zs.avail_in = ilen;
|
||||
zs.next_out = out->ptr;
|
||||
zs.avail_out = olen;
|
||||
|
||||
if ((z = deflate(&zs, Z_FINISH)) != Z_STREAM_END) {
|
||||
fido_log_debug("%s: inflate: %d", __func__, z);
|
||||
r = FIDO_ERR_COMPRESS;
|
||||
goto fail;
|
||||
}
|
||||
if (zs.avail_out >= out->len) {
|
||||
fido_log_debug("%s: %u > %zu", __func__, zs.avail_out,
|
||||
out->len);
|
||||
r = FIDO_ERR_COMPRESS;
|
||||
goto fail;
|
||||
}
|
||||
out->len -= zs.avail_out;
|
||||
|
||||
r = FIDO_OK;
|
||||
fail:
|
||||
if ((z = deflateEnd(&zs)) != Z_OK) {
|
||||
fido_log_debug("%s: deflateEnd: %d", __func__, z);
|
||||
r = FIDO_ERR_COMPRESS;
|
||||
}
|
||||
if (r != FIDO_OK)
|
||||
fido_blob_reset(out);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
fido_compress(fido_blob_t *out, const fido_blob_t *in)
|
||||
{
|
||||
return do_compress(out, in, 0, 0);
|
||||
return rfc1951_deflate(out, in);
|
||||
}
|
||||
|
||||
int
|
||||
fido_uncompress(fido_blob_t *out, const fido_blob_t *in, size_t origsiz)
|
||||
{
|
||||
return do_compress(out, in, origsiz, 1);
|
||||
if (rfc1950_inflate(out, in, origsiz) == FIDO_OK)
|
||||
return FIDO_OK; /* backwards compat with libfido2 < 1.11 */
|
||||
return rfc1951_inflate(out, in, origsiz);
|
||||
}
|
||||
|
|
|
|||
228
src/dev.c
228
src/dev.c
|
|
@ -1,37 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Yubico AB. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <openssl/sha.h>
|
||||
#include "fido.h"
|
||||
|
||||
#ifndef TLS
|
||||
#define TLS
|
||||
#endif
|
||||
|
||||
typedef struct dev_manifest_func_node {
|
||||
dev_manifest_func_t manifest_func;
|
||||
struct dev_manifest_func_node *next;
|
||||
} dev_manifest_func_node_t;
|
||||
|
||||
static TLS dev_manifest_func_node_t *manifest_funcs = NULL;
|
||||
static TLS bool disable_u2f_fallback;
|
||||
|
||||
static void
|
||||
find_manifest_func_node(dev_manifest_func_t f, dev_manifest_func_node_t **curr,
|
||||
dev_manifest_func_node_t **prev)
|
||||
{
|
||||
*prev = NULL;
|
||||
*curr = manifest_funcs;
|
||||
|
||||
while (*curr != NULL && (*curr)->manifest_func != f) {
|
||||
*prev = *curr;
|
||||
*curr = (*curr)->next;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FIDO_FUZZ
|
||||
static void
|
||||
set_random_report_len(fido_dev_t *dev)
|
||||
|
|
@ -63,13 +43,15 @@ fido_dev_set_option_flags(fido_dev_t *dev, const fido_cbor_info_t *info)
|
|||
|
||||
for (size_t i = 0; i < len; i++)
|
||||
if (strcmp(ptr[i], "clientPin") == 0) {
|
||||
dev->flags |= val[i] ? FIDO_DEV_PIN_SET : FIDO_DEV_PIN_UNSET;
|
||||
dev->flags |= val[i] ?
|
||||
FIDO_DEV_PIN_SET : FIDO_DEV_PIN_UNSET;
|
||||
} else if (strcmp(ptr[i], "credMgmt") == 0 ||
|
||||
strcmp(ptr[i], "credentialMgmtPreview") == 0) {
|
||||
if (val[i])
|
||||
dev->flags |= FIDO_DEV_CREDMAN;
|
||||
} else if (strcmp(ptr[i], "uv") == 0) {
|
||||
dev->flags |= val[i] ? FIDO_DEV_UV_SET : FIDO_DEV_UV_UNSET;
|
||||
dev->flags |= val[i] ?
|
||||
FIDO_DEV_UV_SET : FIDO_DEV_UV_UNSET;
|
||||
} else if (strcmp(ptr[i], "pinUvAuthToken") == 0) {
|
||||
if (val[i])
|
||||
dev->flags |= FIDO_DEV_TOKEN_PERMS;
|
||||
|
|
@ -257,75 +239,40 @@ fido_dev_open_wait(fido_dev_t *dev, const char *path, int *ms)
|
|||
return (FIDO_OK);
|
||||
}
|
||||
|
||||
int
|
||||
fido_dev_register_manifest_func(const dev_manifest_func_t f)
|
||||
static void
|
||||
run_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen,
|
||||
const char *type, int (*manifest)(fido_dev_info_t *, size_t, size_t *))
|
||||
{
|
||||
dev_manifest_func_node_t *prev, *curr, *n;
|
||||
size_t ndevs = 0;
|
||||
int r;
|
||||
|
||||
find_manifest_func_node(f, &curr, &prev);
|
||||
if (curr != NULL)
|
||||
return (FIDO_OK);
|
||||
|
||||
if ((n = calloc(1, sizeof(*n))) == NULL) {
|
||||
fido_log_debug("%s: calloc", __func__);
|
||||
return (FIDO_ERR_INTERNAL);
|
||||
}
|
||||
|
||||
n->manifest_func = f;
|
||||
n->next = manifest_funcs;
|
||||
manifest_funcs = n;
|
||||
|
||||
return (FIDO_OK);
|
||||
}
|
||||
|
||||
void
|
||||
fido_dev_unregister_manifest_func(const dev_manifest_func_t f)
|
||||
{
|
||||
dev_manifest_func_node_t *prev, *curr;
|
||||
|
||||
find_manifest_func_node(f, &curr, &prev);
|
||||
if (curr == NULL)
|
||||
if (*olen >= ilen) {
|
||||
fido_log_debug("%s: skipping %s", __func__, type);
|
||||
return;
|
||||
if (prev != NULL)
|
||||
prev->next = curr->next;
|
||||
else
|
||||
manifest_funcs = curr->next;
|
||||
|
||||
free(curr);
|
||||
}
|
||||
if ((r = manifest(devlist + *olen, ilen - *olen, &ndevs)) != FIDO_OK)
|
||||
fido_log_debug("%s: %s: 0x%x", __func__, type, r);
|
||||
fido_log_debug("%s: found %zu %s device%s", __func__, ndevs, type,
|
||||
ndevs == 1 ? "" : "s");
|
||||
*olen += ndevs;
|
||||
}
|
||||
|
||||
int
|
||||
fido_dev_info_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)
|
||||
{
|
||||
dev_manifest_func_node_t *curr = NULL;
|
||||
dev_manifest_func_t m_func;
|
||||
size_t curr_olen;
|
||||
int r;
|
||||
|
||||
*olen = 0;
|
||||
|
||||
if (fido_dev_register_manifest_func(fido_hid_manifest) != FIDO_OK)
|
||||
return (FIDO_ERR_INTERNAL);
|
||||
#ifdef NFC_LINUX
|
||||
if (fido_dev_register_manifest_func(fido_nfc_manifest) != FIDO_OK)
|
||||
return (FIDO_ERR_INTERNAL);
|
||||
run_manifest(devlist, ilen, olen, "hid", fido_hid_manifest);
|
||||
#ifdef USE_NFC
|
||||
run_manifest(devlist, ilen, olen, "nfc", fido_nfc_manifest);
|
||||
#endif
|
||||
#ifdef USE_PCSC
|
||||
run_manifest(devlist, ilen, olen, "pcsc", fido_pcsc_manifest);
|
||||
#endif
|
||||
#ifdef USE_WINHELLO
|
||||
if (fido_dev_register_manifest_func(fido_winhello_manifest) != FIDO_OK)
|
||||
return (FIDO_ERR_INTERNAL);
|
||||
run_manifest(devlist, ilen, olen, "winhello", fido_winhello_manifest);
|
||||
#endif
|
||||
|
||||
for (curr = manifest_funcs; curr != NULL; curr = curr->next) {
|
||||
curr_olen = 0;
|
||||
m_func = curr->manifest_func;
|
||||
r = m_func(devlist + *olen, ilen - *olen, &curr_olen);
|
||||
if (r != FIDO_OK)
|
||||
return (r);
|
||||
*olen += curr_olen;
|
||||
if (*olen == ilen)
|
||||
break;
|
||||
}
|
||||
|
||||
return (FIDO_OK);
|
||||
}
|
||||
|
||||
|
|
@ -345,19 +292,16 @@ fido_dev_open(fido_dev_t *dev, const char *path)
|
|||
{
|
||||
int ms = dev->timeout_ms;
|
||||
|
||||
#ifdef NFC_LINUX
|
||||
if (strncmp(path, FIDO_NFC_PREFIX, strlen(FIDO_NFC_PREFIX)) == 0) {
|
||||
dev->io_own = true;
|
||||
dev->io = (fido_dev_io_t) {
|
||||
fido_nfc_open,
|
||||
fido_nfc_close,
|
||||
fido_nfc_read,
|
||||
fido_nfc_write,
|
||||
};
|
||||
dev->transport = (fido_dev_transport_t) {
|
||||
fido_nfc_rx,
|
||||
fido_nfc_tx,
|
||||
};
|
||||
#ifdef USE_NFC
|
||||
if (fido_is_nfc(path) && fido_dev_set_nfc(dev) < 0) {
|
||||
fido_log_debug("%s: fido_dev_set_nfc", __func__);
|
||||
return FIDO_ERR_INTERNAL;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_PCSC
|
||||
if (fido_is_pcsc(path) && fido_dev_set_pcsc(dev) < 0) {
|
||||
fido_log_debug("%s: fido_dev_set_pcsc", __func__);
|
||||
return FIDO_ERR_INTERNAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -387,7 +331,7 @@ fido_dev_set_sigmask(fido_dev_t *dev, const fido_sigset_t *sigmask)
|
|||
if (dev->io_handle == NULL || sigmask == NULL)
|
||||
return (FIDO_ERR_INVALID_ARGUMENT);
|
||||
|
||||
#ifdef NFC_LINUX
|
||||
#ifdef USE_NFC
|
||||
if (dev->transport.rx == fido_nfc_rx && dev->io.read == fido_nfc_read)
|
||||
return (fido_nfc_set_sigmask(dev->io_handle, sigmask));
|
||||
#endif
|
||||
|
|
@ -414,106 +358,6 @@ fido_dev_cancel(fido_dev_t *dev)
|
|||
return (FIDO_OK);
|
||||
}
|
||||
|
||||
int
|
||||
fido_dev_get_touch_begin(fido_dev_t *dev)
|
||||
{
|
||||
fido_blob_t f;
|
||||
cbor_item_t *argv[9];
|
||||
const char *clientdata = FIDO_DUMMY_CLIENTDATA;
|
||||
const uint8_t user_id = FIDO_DUMMY_USER_ID;
|
||||
unsigned char cdh[SHA256_DIGEST_LENGTH];
|
||||
fido_rp_t rp;
|
||||
fido_user_t user;
|
||||
int ms = dev->timeout_ms;
|
||||
int r = FIDO_ERR_INTERNAL;
|
||||
|
||||
memset(&f, 0, sizeof(f));
|
||||
memset(argv, 0, sizeof(argv));
|
||||
memset(cdh, 0, sizeof(cdh));
|
||||
memset(&rp, 0, sizeof(rp));
|
||||
memset(&user, 0, sizeof(user));
|
||||
|
||||
if (fido_dev_is_fido2(dev) == false)
|
||||
return (u2f_get_touch_begin(dev, &ms));
|
||||
|
||||
if (SHA256((const void *)clientdata, strlen(clientdata), cdh) != cdh) {
|
||||
fido_log_debug("%s: sha256", __func__);
|
||||
return (FIDO_ERR_INTERNAL);
|
||||
}
|
||||
|
||||
if ((rp.id = strdup(FIDO_DUMMY_RP_ID)) == NULL ||
|
||||
(user.name = strdup(FIDO_DUMMY_USER_NAME)) == NULL) {
|
||||
fido_log_debug("%s: strdup", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (fido_blob_set(&user.id, &user_id, sizeof(user_id)) < 0) {
|
||||
fido_log_debug("%s: fido_blob_set", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((argv[0] = cbor_build_bytestring(cdh, sizeof(cdh))) == NULL ||
|
||||
(argv[1] = cbor_encode_rp_entity(&rp)) == NULL ||
|
||||
(argv[2] = cbor_encode_user_entity(&user)) == NULL ||
|
||||
(argv[3] = cbor_encode_pubkey_param(COSE_ES256)) == NULL) {
|
||||
fido_log_debug("%s: cbor encode", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (fido_dev_supports_pin(dev)) {
|
||||
if ((argv[7] = cbor_new_definite_bytestring()) == NULL ||
|
||||
(argv[8] = cbor_encode_pin_opt(dev)) == NULL) {
|
||||
fido_log_debug("%s: cbor encode", __func__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (cbor_build_frame(CTAP_CBOR_MAKECRED, 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);
|
||||
free(rp.id);
|
||||
free(user.name);
|
||||
free(user.id.ptr);
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
int
|
||||
fido_dev_get_touch_status(fido_dev_t *dev, int *touched, int ms)
|
||||
{
|
||||
int r;
|
||||
|
||||
*touched = 0;
|
||||
|
||||
if (fido_dev_is_fido2(dev) == false)
|
||||
return (u2f_get_touch_status(dev, touched, &ms));
|
||||
|
||||
switch ((r = fido_rx_cbor_status(dev, &ms))) {
|
||||
case FIDO_ERR_PIN_AUTH_INVALID:
|
||||
case FIDO_ERR_PIN_INVALID:
|
||||
case FIDO_ERR_PIN_NOT_SET:
|
||||
case FIDO_ERR_SUCCESS:
|
||||
*touched = 1;
|
||||
break;
|
||||
case FIDO_ERR_RX:
|
||||
/* ignore */
|
||||
break;
|
||||
default:
|
||||
fido_log_debug("%s: fido_rx_cbor_status", __func__);
|
||||
return (r);
|
||||
}
|
||||
|
||||
return (FIDO_OK);
|
||||
}
|
||||
|
||||
int
|
||||
fido_dev_set_io_functions(fido_dev_t *dev, const fido_dev_io_t *io)
|
||||
{
|
||||
|
|
|
|||
11
src/eddsa.c
11
src/eddsa.c
|
|
@ -122,11 +122,20 @@ eddsa_pk_free(eddsa_pk_t **pkp)
|
|||
int
|
||||
eddsa_pk_from_ptr(eddsa_pk_t *pk, const void *ptr, size_t len)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
if (len < sizeof(*pk))
|
||||
return (FIDO_ERR_INVALID_ARGUMENT);
|
||||
|
||||
memcpy(pk, ptr, sizeof(*pk));
|
||||
|
||||
if ((pkey = eddsa_pk_to_EVP_PKEY(pk)) == NULL) {
|
||||
fido_log_debug("%s: eddsa_pk_to_EVP_PKEY", __func__);
|
||||
return (FIDO_ERR_INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
return (FIDO_OK);
|
||||
}
|
||||
|
||||
|
|
@ -147,6 +156,8 @@ eddsa_pk_from_EVP_PKEY(eddsa_pk_t *pk, const EVP_PKEY *pkey)
|
|||
{
|
||||
size_t len = 0;
|
||||
|
||||
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_ED25519)
|
||||
return (FIDO_ERR_INVALID_ARGUMENT);
|
||||
if (EVP_PKEY_get_raw_public_key(pkey, NULL, &len) != 1 ||
|
||||
len != sizeof(pk->x))
|
||||
return (FIDO_ERR_INTERNAL);
|
||||
|
|
|
|||
65
src/es256.c
65
src/es256.c
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2021 Yubico AB. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -11,6 +11,14 @@
|
|||
#include "fido.h"
|
||||
#include "fido/es256.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000
|
||||
#define get0_EC_KEY(x) EVP_PKEY_get0_EC_KEY((x))
|
||||
#else
|
||||
#define get0_EC_KEY(x) EVP_PKEY_get0((x))
|
||||
#endif
|
||||
|
||||
static const int es256_nid = NID_X9_62_prime256v1;
|
||||
|
||||
static int
|
||||
decode_coord(const cbor_item_t *item, void *xy, size_t xy_len)
|
||||
{
|
||||
|
|
@ -170,7 +178,8 @@ es256_pk_free(es256_pk_t **pkp)
|
|||
int
|
||||
es256_pk_from_ptr(es256_pk_t *pk, const void *ptr, size_t len)
|
||||
{
|
||||
const uint8_t *p = ptr;
|
||||
const uint8_t *p = ptr;
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
if (len < sizeof(*pk))
|
||||
return (FIDO_ERR_INVALID_ARGUMENT);
|
||||
|
|
@ -180,6 +189,14 @@ es256_pk_from_ptr(es256_pk_t *pk, const void *ptr, size_t len)
|
|||
else
|
||||
memcpy(pk, ptr, sizeof(*pk)); /* libfido2 x||y format */
|
||||
|
||||
if ((pkey = es256_pk_to_EVP_PKEY(pk)) == NULL) {
|
||||
fido_log_debug("%s: es256_pk_to_EVP_PKEY", __func__);
|
||||
explicit_bzero(pk, sizeof(*pk));
|
||||
return (FIDO_ERR_INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
return (FIDO_OK);
|
||||
}
|
||||
|
||||
|
|
@ -208,13 +225,12 @@ es256_sk_create(es256_sk_t *key)
|
|||
EVP_PKEY *k = NULL;
|
||||
const EC_KEY *ec;
|
||||
const BIGNUM *d;
|
||||
const int nid = NID_X9_62_prime256v1;
|
||||
int n;
|
||||
int ok = -1;
|
||||
|
||||
if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL ||
|
||||
EVP_PKEY_paramgen_init(pctx) <= 0 ||
|
||||
EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid) <= 0 ||
|
||||
EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, es256_nid) <= 0 ||
|
||||
EVP_PKEY_paramgen(pctx, &p) <= 0) {
|
||||
fido_log_debug("%s: EVP_PKEY_paramgen", __func__);
|
||||
goto fail;
|
||||
|
|
@ -258,7 +274,6 @@ es256_pk_to_EVP_PKEY(const es256_pk_t *k)
|
|||
BIGNUM *x = NULL;
|
||||
BIGNUM *y = NULL;
|
||||
const EC_GROUP *g = NULL;
|
||||
const int nid = NID_X9_62_prime256v1;
|
||||
int ok = -1;
|
||||
|
||||
if ((bnctx = BN_CTX_new()) == NULL)
|
||||
|
|
@ -276,7 +291,7 @@ es256_pk_to_EVP_PKEY(const es256_pk_t *k)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if ((ec = EC_KEY_new_by_curve_name(nid)) == NULL ||
|
||||
if ((ec = EC_KEY_new_by_curve_name(es256_nid)) == NULL ||
|
||||
(g = EC_KEY_get0_group(ec)) == NULL) {
|
||||
fido_log_debug("%s: EC_KEY init", __func__);
|
||||
goto fail;
|
||||
|
|
@ -324,12 +339,15 @@ es256_pk_from_EC_KEY(es256_pk_t *pk, const EC_KEY *ec)
|
|||
BIGNUM *x = NULL;
|
||||
BIGNUM *y = NULL;
|
||||
const EC_POINT *q = NULL;
|
||||
const EC_GROUP *g = NULL;
|
||||
EC_GROUP *g = NULL;
|
||||
size_t dx;
|
||||
size_t dy;
|
||||
int ok = FIDO_ERR_INTERNAL;
|
||||
int n;
|
||||
int nx;
|
||||
int ny;
|
||||
|
||||
if ((q = EC_KEY_get0_public_key(ec)) == NULL ||
|
||||
(g = EC_KEY_get0_group(ec)) == NULL ||
|
||||
(g = EC_GROUP_new_by_curve_name(es256_nid)) == NULL ||
|
||||
(bnctx = BN_CTX_new()) == NULL)
|
||||
goto fail;
|
||||
|
||||
|
|
@ -339,22 +357,33 @@ es256_pk_from_EC_KEY(es256_pk_t *pk, const EC_KEY *ec)
|
|||
(y = BN_CTX_get(bnctx)) == NULL)
|
||||
goto fail;
|
||||
|
||||
if (EC_POINT_is_on_curve(g, q, bnctx) != 1) {
|
||||
fido_log_debug("%s: EC_POINT_is_on_curve", __func__);
|
||||
ok = FIDO_ERR_INVALID_ARGUMENT;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (EC_POINT_get_affine_coordinates_GFp(g, q, x, y, bnctx) == 0 ||
|
||||
(n = BN_num_bytes(x)) < 0 || (size_t)n > sizeof(pk->x) ||
|
||||
(n = BN_num_bytes(y)) < 0 || (size_t)n > sizeof(pk->y)) {
|
||||
(nx = BN_num_bytes(x)) < 0 || (size_t)nx > sizeof(pk->x) ||
|
||||
(ny = BN_num_bytes(y)) < 0 || (size_t)ny > sizeof(pk->y)) {
|
||||
fido_log_debug("%s: EC_POINT_get_affine_coordinates_GFp",
|
||||
__func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((n = BN_bn2bin(x, pk->x)) < 0 || (size_t)n > sizeof(pk->x) ||
|
||||
(n = BN_bn2bin(y, pk->y)) < 0 || (size_t)n > sizeof(pk->y)) {
|
||||
dx = sizeof(pk->x) - (size_t)nx;
|
||||
dy = sizeof(pk->y) - (size_t)ny;
|
||||
|
||||
if ((nx = BN_bn2bin(x, pk->x + dx)) < 0 || (size_t)nx > sizeof(pk->x) ||
|
||||
(ny = BN_bn2bin(y, pk->y + dy)) < 0 || (size_t)ny > sizeof(pk->y)) {
|
||||
fido_log_debug("%s: BN_bn2bin", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = FIDO_OK;
|
||||
fail:
|
||||
EC_GROUP_free(g);
|
||||
|
||||
if (bnctx != NULL) {
|
||||
BN_CTX_end(bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
|
|
@ -366,10 +395,10 @@ fail:
|
|||
int
|
||||
es256_pk_from_EVP_PKEY(es256_pk_t *pk, const EVP_PKEY *pkey)
|
||||
{
|
||||
EC_KEY *ec;
|
||||
const EC_KEY *ec;
|
||||
|
||||
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC ||
|
||||
(ec = EVP_PKEY_get0(pkey)) == NULL)
|
||||
(ec = get0_EC_KEY(pkey)) == NULL)
|
||||
return (FIDO_ERR_INVALID_ARGUMENT);
|
||||
|
||||
return (es256_pk_from_EC_KEY(pk, ec));
|
||||
|
|
@ -382,7 +411,6 @@ es256_sk_to_EVP_PKEY(const es256_sk_t *k)
|
|||
EC_KEY *ec = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
BIGNUM *d = NULL;
|
||||
const int nid = NID_X9_62_prime256v1;
|
||||
int ok = -1;
|
||||
|
||||
if ((bnctx = BN_CTX_new()) == NULL)
|
||||
|
|
@ -396,7 +424,7 @@ es256_sk_to_EVP_PKEY(const es256_sk_t *k)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if ((ec = EC_KEY_new_by_curve_name(nid)) == NULL ||
|
||||
if ((ec = EC_KEY_new_by_curve_name(es256_nid)) == NULL ||
|
||||
EC_KEY_set_private_key(ec, d) == 0) {
|
||||
fido_log_debug("%s: EC_KEY_set_private_key", __func__);
|
||||
goto fail;
|
||||
|
|
@ -435,11 +463,10 @@ es256_derive_pk(const es256_sk_t *sk, es256_pk_t *pk)
|
|||
EC_KEY *ec = NULL;
|
||||
EC_POINT *q = NULL;
|
||||
const EC_GROUP *g = NULL;
|
||||
const int nid = NID_X9_62_prime256v1;
|
||||
int ok = -1;
|
||||
|
||||
if ((d = BN_bin2bn(sk->d, (int)sizeof(sk->d), NULL)) == NULL ||
|
||||
(ec = EC_KEY_new_by_curve_name(nid)) == NULL ||
|
||||
(ec = EC_KEY_new_by_curve_name(es256_nid)) == NULL ||
|
||||
(g = EC_KEY_get0_group(ec)) == NULL ||
|
||||
(q = EC_POINT_new(g)) == NULL) {
|
||||
fido_log_debug("%s: get", __func__);
|
||||
|
|
|
|||
|
|
@ -85,10 +85,11 @@
|
|||
fido_cbor_info_extensions_len;
|
||||
fido_cbor_info_extensions_ptr;
|
||||
fido_cbor_info_free;
|
||||
fido_cbor_info_maxmsgsiz;
|
||||
fido_cbor_info_maxcredbloblen;
|
||||
fido_cbor_info_maxcredcntlst;
|
||||
fido_cbor_info_maxcredidlen;
|
||||
fido_cbor_info_maxlargeblob;
|
||||
fido_cbor_info_maxmsgsiz;
|
||||
fido_cbor_info_fwversion;
|
||||
fido_cbor_info_new;
|
||||
fido_cbor_info_options_len;
|
||||
|
|
|
|||
|
|
@ -83,10 +83,11 @@ _fido_cbor_info_algorithm_type
|
|||
_fido_cbor_info_extensions_len
|
||||
_fido_cbor_info_extensions_ptr
|
||||
_fido_cbor_info_free
|
||||
_fido_cbor_info_maxmsgsiz
|
||||
_fido_cbor_info_maxcredbloblen
|
||||
_fido_cbor_info_maxcredcntlst
|
||||
_fido_cbor_info_maxcredidlen
|
||||
_fido_cbor_info_maxlargeblob
|
||||
_fido_cbor_info_maxmsgsiz
|
||||
_fido_cbor_info_fwversion
|
||||
_fido_cbor_info_new
|
||||
_fido_cbor_info_options_len
|
||||
|
|
|
|||
|
|
@ -84,10 +84,11 @@ fido_cbor_info_algorithm_type
|
|||
fido_cbor_info_extensions_len
|
||||
fido_cbor_info_extensions_ptr
|
||||
fido_cbor_info_free
|
||||
fido_cbor_info_maxmsgsiz
|
||||
fido_cbor_info_maxcredbloblen
|
||||
fido_cbor_info_maxcredcntlst
|
||||
fido_cbor_info_maxcredidlen
|
||||
fido_cbor_info_maxlargeblob
|
||||
fido_cbor_info_maxmsgsiz
|
||||
fido_cbor_info_fwversion
|
||||
fido_cbor_info_new
|
||||
fido_cbor_info_options_len
|
||||
|
|
|
|||
22
src/extern.h
22
src/extern.h
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2021 Yubico AB. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -118,6 +118,7 @@ size_t fido_hid_report_in_len(void *);
|
|||
size_t fido_hid_report_out_len(void *);
|
||||
|
||||
/* nfc i/o */
|
||||
bool fido_is_nfc(const char *);
|
||||
void *fido_nfc_open(const char *);
|
||||
void fido_nfc_close(void *);
|
||||
int fido_nfc_read(void *, unsigned char *, size_t, int);
|
||||
|
|
@ -125,6 +126,17 @@ int fido_nfc_write(void *, const unsigned char *, size_t);
|
|||
int fido_nfc_rx(fido_dev_t *, uint8_t, unsigned char *, size_t, int);
|
||||
int fido_nfc_tx(fido_dev_t *, uint8_t, const unsigned char *, size_t);
|
||||
int fido_nfc_set_sigmask(void *, const fido_sigset_t *);
|
||||
int fido_dev_set_nfc(fido_dev_t *);
|
||||
|
||||
/* pcsc i/o */
|
||||
bool fido_is_pcsc(const char *);
|
||||
void *fido_pcsc_open(const char *);
|
||||
void fido_pcsc_close(void *);
|
||||
int fido_pcsc_read(void *, unsigned char *, size_t, int);
|
||||
int fido_pcsc_write(void *, const unsigned char *, size_t);
|
||||
int fido_pcsc_rx(fido_dev_t *, uint8_t, unsigned char *, size_t, int);
|
||||
int fido_pcsc_tx(fido_dev_t *, uint8_t, const unsigned char *, size_t);
|
||||
int fido_dev_set_pcsc(fido_dev_t *);
|
||||
|
||||
/* windows hello */
|
||||
int fido_winhello_manifest(fido_dev_info_t *, size_t, size_t *);
|
||||
|
|
@ -200,6 +212,7 @@ int fido_get_random(void *, size_t);
|
|||
int fido_sha256(fido_blob_t *, const u_char *, size_t);
|
||||
int fido_time_now(struct timespec *);
|
||||
int fido_time_delta(const struct timespec *, int *);
|
||||
int fido_to_uint64(const char *, int, uint64_t *);
|
||||
|
||||
/* crypto */
|
||||
int es256_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *);
|
||||
|
|
@ -220,11 +233,7 @@ int fido_get_signed_hash_tpm(fido_blob_t *, const fido_blob_t *,
|
|||
/* device manifest functions */
|
||||
int fido_hid_manifest(fido_dev_info_t *, size_t, size_t *);
|
||||
int fido_nfc_manifest(fido_dev_info_t *, size_t, size_t *);
|
||||
|
||||
/* device manifest registration */
|
||||
typedef int (*dev_manifest_func_t)(fido_dev_info_t *, size_t, size_t *);
|
||||
int fido_dev_register_manifest_func(const dev_manifest_func_t);
|
||||
void fido_dev_unregister_manifest_func(const dev_manifest_func_t);
|
||||
int fido_pcsc_manifest(fido_dev_info_t *, size_t, size_t *);
|
||||
|
||||
/* fuzzing instrumentation */
|
||||
#ifdef FIDO_FUZZ
|
||||
|
|
@ -250,6 +259,7 @@ uint32_t uniform_random(uint32_t);
|
|||
#define FIDO_DUMMY_USER_ID 1
|
||||
#define FIDO_WINHELLO_PATH "windows://hello"
|
||||
#define FIDO_NFC_PREFIX "nfc:"
|
||||
#define FIDO_PCSC_PREFIX "pcsc:"
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
|||
|
|
@ -144,7 +144,9 @@ int fido_cred_set_user(fido_cred_t *, const unsigned char *, size_t,
|
|||
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 *);
|
||||
|
|
@ -205,10 +207,11 @@ 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_maxmsgsiz(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_fwversion(const fido_cbor_info_t *);
|
||||
|
||||
bool fido_dev_has_pin(const fido_dev_t *);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Yubico AB. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -48,10 +48,14 @@ typedef enum {
|
|||
|
||||
typedef void fido_log_handler_t(const char *);
|
||||
|
||||
#undef _FIDO_SIGSET_DEFINED
|
||||
#define _FIDO_SIGSET_DEFINED
|
||||
#ifdef _WIN32
|
||||
typedef int fido_sigset_t;
|
||||
#else
|
||||
#elif defined(SIG_BLOCK)
|
||||
typedef sigset_t fido_sigset_t;
|
||||
#else
|
||||
#undef _FIDO_SIGSET_DEFINED
|
||||
#endif
|
||||
|
||||
#ifdef _FIDO_INTERNAL
|
||||
|
|
@ -216,18 +220,19 @@ typedef struct fido_algo_array {
|
|||
} fido_algo_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 number of credentials in list */
|
||||
uint64_t maxcredidlen; /* max credential ID length */
|
||||
uint64_t fwversion; /* firmware version */
|
||||
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 */
|
||||
} fido_cbor_info_t;
|
||||
|
||||
typedef struct fido_dev_info {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Yubico AB. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -87,8 +87,8 @@ copy_info(fido_dev_info_t *di, const char *path)
|
|||
|
||||
ok = 0;
|
||||
fail:
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
if (fd != -1 && close(fd) == -1)
|
||||
fido_log_error(errno, "%s: close %s", __func__, path);
|
||||
|
||||
if (ok < 0) {
|
||||
free(di->path);
|
||||
|
|
@ -106,8 +106,6 @@ fido_hid_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)
|
|||
char path[64];
|
||||
size_t i;
|
||||
|
||||
*olen = 0;
|
||||
|
||||
if (ilen == 0)
|
||||
return (FIDO_OK); /* nothing to do */
|
||||
|
||||
|
|
|
|||
|
|
@ -27,14 +27,58 @@ struct hid_openbsd {
|
|||
const sigset_t *sigmaskp;
|
||||
};
|
||||
|
||||
static int
|
||||
copy_info(fido_dev_info_t *di, const char *path)
|
||||
{
|
||||
int fd = -1, ok = -1;
|
||||
struct usb_device_info udi;
|
||||
|
||||
memset(di, 0, sizeof(*di));
|
||||
memset(&udi, 0, sizeof(udi));
|
||||
|
||||
if ((fd = fido_hid_unix_open(path)) == -1)
|
||||
goto fail;
|
||||
if (ioctl(fd, IOCTL_REQ(USB_GET_DEVICEINFO), &udi) == -1) {
|
||||
fido_log_error(errno, "%s: ioctl %s", __func__, path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fido_log_debug("%s: %s: bus = 0x%02x, addr = 0x%02x", __func__, path,
|
||||
udi.udi_bus, udi.udi_addr);
|
||||
fido_log_debug("%s: %s: vendor = \"%s\", product = \"%s\"", __func__,
|
||||
path, udi.udi_vendor, udi.udi_product);
|
||||
fido_log_debug("%s: %s: productNo = 0x%04x, vendorNo = 0x%04x, "
|
||||
"releaseNo = 0x%04x", __func__, path, udi.udi_productNo,
|
||||
udi.udi_vendorNo, udi.udi_releaseNo);
|
||||
|
||||
if ((di->path = strdup(path)) == NULL ||
|
||||
(di->manufacturer = strdup(udi.udi_vendor)) == NULL ||
|
||||
(di->product = strdup(udi.udi_product)) == NULL)
|
||||
goto fail;
|
||||
|
||||
di->vendor_id = (int16_t)udi.udi_vendorNo;
|
||||
di->product_id = (int16_t)udi.udi_productNo;
|
||||
|
||||
ok = 0;
|
||||
fail:
|
||||
if (fd != -1 && close(fd) == -1)
|
||||
fido_log_error(errno, "%s: close %s", __func__, path);
|
||||
|
||||
if (ok < 0) {
|
||||
free(di->path);
|
||||
free(di->manufacturer);
|
||||
free(di->product);
|
||||
explicit_bzero(di, sizeof(*di));
|
||||
}
|
||||
|
||||
return (ok);
|
||||
}
|
||||
|
||||
int
|
||||
fido_hid_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)
|
||||
{
|
||||
size_t i;
|
||||
char path[64];
|
||||
int fd;
|
||||
struct usb_device_info udi;
|
||||
fido_dev_info_t *di;
|
||||
|
||||
if (ilen == 0)
|
||||
return (FIDO_OK); /* nothing to do */
|
||||
|
|
@ -44,50 +88,18 @@ fido_hid_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)
|
|||
|
||||
for (i = *olen = 0; i < MAX_UHID && *olen < ilen; i++) {
|
||||
snprintf(path, sizeof(path), "/dev/fido/%zu", i);
|
||||
if ((fd = fido_hid_unix_open(path)) == -1)
|
||||
continue;
|
||||
memset(&udi, 0, sizeof(udi));
|
||||
if (ioctl(fd, IOCTL_REQ(USB_GET_DEVICEINFO), &udi) == -1) {
|
||||
fido_log_error(errno, "%s: get device info %s",
|
||||
__func__, path);
|
||||
if (close(fd) == -1)
|
||||
fido_log_error(errno, "%s: close", __func__);
|
||||
continue;
|
||||
if (copy_info(&devlist[*olen], path) == 0) {
|
||||
devlist[*olen].io = (fido_dev_io_t) {
|
||||
fido_hid_open,
|
||||
fido_hid_close,
|
||||
fido_hid_read,
|
||||
fido_hid_write,
|
||||
};
|
||||
++(*olen);
|
||||
}
|
||||
if (close(fd) == -1)
|
||||
fido_log_error(errno, "%s: close", __func__);
|
||||
|
||||
fido_log_debug("%s: %s: bus = 0x%02x, addr = 0x%02x",
|
||||
__func__, path, udi.udi_bus, udi.udi_addr);
|
||||
fido_log_debug("%s: %s: vendor = \"%s\", product = \"%s\"",
|
||||
__func__, path, udi.udi_vendor, udi.udi_product);
|
||||
fido_log_debug("%s: %s: productNo = 0x%04x, vendorNo = 0x%04x, "
|
||||
"releaseNo = 0x%04x", __func__, path, udi.udi_productNo,
|
||||
udi.udi_vendorNo, udi.udi_releaseNo);
|
||||
|
||||
di = &devlist[*olen];
|
||||
memset(di, 0, sizeof(*di));
|
||||
di->io = (fido_dev_io_t) {
|
||||
fido_hid_open,
|
||||
fido_hid_close,
|
||||
fido_hid_read,
|
||||
fido_hid_write,
|
||||
};
|
||||
if ((di->path = strdup(path)) == NULL ||
|
||||
(di->manufacturer = strdup(udi.udi_vendor)) == NULL ||
|
||||
(di->product = strdup(udi.udi_product)) == NULL) {
|
||||
free(di->path);
|
||||
free(di->manufacturer);
|
||||
free(di->product);
|
||||
explicit_bzero(di, sizeof(*di));
|
||||
return FIDO_ERR_INTERNAL;
|
||||
}
|
||||
di->vendor_id = (int16_t)udi.udi_vendorNo;
|
||||
di->product_id = (int16_t)udi.udi_productNo;
|
||||
(*olen)++;
|
||||
}
|
||||
|
||||
return FIDO_OK;
|
||||
return (FIDO_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021 Yubico AB. All rights reserved.
|
||||
* Copyright (c) 2019-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.
|
||||
*/
|
||||
|
|
@ -374,25 +374,6 @@ disable_sigpipe(int fd)
|
|||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
to_uint64(const char *str, uint64_t *out)
|
||||
{
|
||||
char *ep;
|
||||
unsigned long long ull;
|
||||
|
||||
errno = 0;
|
||||
ull = strtoull(str, &ep, 10);
|
||||
if (str == ep || *ep != '\0')
|
||||
return (-1);
|
||||
else if (ull == ULLONG_MAX && errno == ERANGE)
|
||||
return (-1);
|
||||
else if (ull > UINT64_MAX)
|
||||
return (-1);
|
||||
*out = (uint64_t)ull;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static io_registry_entry_t
|
||||
get_ioreg_entry(const char *path)
|
||||
{
|
||||
|
|
@ -401,8 +382,8 @@ get_ioreg_entry(const char *path)
|
|||
if (strncmp(path, IOREG, strlen(IOREG)) != 0)
|
||||
return (IORegistryEntryFromPath(kIOMainPortDefault, path));
|
||||
|
||||
if (to_uint64(path + strlen(IOREG), &id) == -1) {
|
||||
fido_log_debug("%s: to_uint64", __func__);
|
||||
if (fido_to_uint64(path + strlen(IOREG), 10, &id) == -1) {
|
||||
fido_log_debug("%s: fido_to_uint64", __func__);
|
||||
return (MACH_PORT_NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -268,6 +268,8 @@ parse_reply_element(const cbor_item_t *key, const cbor_item_t *val, void *arg)
|
|||
return (decode_string_array(val, &ci->transports));
|
||||
case 10: /* algorithms */
|
||||
return (decode_algorithms(val, &ci->algorithms));
|
||||
case 11: /* maxSerializedLargeBlobArray */
|
||||
return (cbor_decode_uint64(val, &ci->maxlargeblob));
|
||||
case 14: /* fwVersion */
|
||||
return (cbor_decode_uint64(val, &ci->fwversion));
|
||||
case 15: /* maxCredBlobLen */
|
||||
|
|
@ -461,6 +463,12 @@ fido_cbor_info_maxcredidlen(const fido_cbor_info_t *ci)
|
|||
return (ci->maxcredidlen);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
fido_cbor_info_maxlargeblob(const fido_cbor_info_t *ci)
|
||||
{
|
||||
return (ci->maxlargeblob);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
fido_cbor_info_fwversion(const fido_cbor_info_t *ci)
|
||||
{
|
||||
|
|
|
|||
320
src/nfc.c
Normal file
320
src/nfc.c
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fido.h"
|
||||
#include "fido/param.h"
|
||||
#include "iso7816.h"
|
||||
|
||||
#define TX_CHUNK_SIZE 240
|
||||
|
||||
static const uint8_t aid[] = { 0xa0, 0x00, 0x00, 0x06, 0x47, 0x2f, 0x00, 0x01 };
|
||||
static const uint8_t v_u2f[] = { 'U', '2', 'F', '_', 'V', '2' };
|
||||
static const uint8_t v_fido[] = { 'F', 'I', 'D', 'O', '_', '2', '_', '0' };
|
||||
|
||||
static int
|
||||
tx_short_apdu(fido_dev_t *d, const iso7816_header_t *h, const uint8_t *payload,
|
||||
uint8_t payload_len, uint8_t cla_flags)
|
||||
{
|
||||
uint8_t apdu[5 + UINT8_MAX + 1];
|
||||
uint8_t sw[2];
|
||||
size_t apdu_len;
|
||||
int ok = -1;
|
||||
|
||||
memset(&apdu, 0, sizeof(apdu));
|
||||
apdu[0] = h->cla | cla_flags;
|
||||
apdu[1] = h->ins;
|
||||
apdu[2] = h->p1;
|
||||
apdu[3] = h->p2;
|
||||
apdu[4] = payload_len;
|
||||
memcpy(&apdu[5], payload, payload_len);
|
||||
apdu_len = (size_t)(5 + payload_len + 1);
|
||||
|
||||
if (d->io.write(d->io_handle, apdu, apdu_len) < 0) {
|
||||
fido_log_debug("%s: write", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (cla_flags & 0x10) {
|
||||
if (d->io.read(d->io_handle, sw, sizeof(sw), -1) != 2) {
|
||||
fido_log_debug("%s: read", __func__);
|
||||
goto fail;
|
||||
}
|
||||
if ((sw[0] << 8 | sw[1]) != SW_NO_ERROR) {
|
||||
fido_log_debug("%s: unexpected sw", __func__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
ok = 0;
|
||||
fail:
|
||||
explicit_bzero(apdu, sizeof(apdu));
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int
|
||||
nfc_do_tx(fido_dev_t *d, const uint8_t *apdu_ptr, size_t apdu_len)
|
||||
{
|
||||
iso7816_header_t h;
|
||||
|
||||
if (fido_buf_read(&apdu_ptr, &apdu_len, &h, sizeof(h)) < 0) {
|
||||
fido_log_debug("%s: header", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (apdu_len < 2) {
|
||||
fido_log_debug("%s: apdu_len %zu", __func__, apdu_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
apdu_len -= 2; /* trim le1 le2 */
|
||||
|
||||
while (apdu_len > TX_CHUNK_SIZE) {
|
||||
if (tx_short_apdu(d, &h, apdu_ptr, TX_CHUNK_SIZE, 0x10) < 0) {
|
||||
fido_log_debug("%s: chain", __func__);
|
||||
return -1;
|
||||
}
|
||||
apdu_ptr += TX_CHUNK_SIZE;
|
||||
apdu_len -= TX_CHUNK_SIZE;
|
||||
}
|
||||
|
||||
if (tx_short_apdu(d, &h, apdu_ptr, (uint8_t)apdu_len, 0) < 0) {
|
||||
fido_log_debug("%s: tx_short_apdu", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fido_nfc_tx(fido_dev_t *d, uint8_t cmd, const unsigned char *buf, size_t count)
|
||||
{
|
||||
iso7816_apdu_t *apdu = NULL;
|
||||
const uint8_t *ptr;
|
||||
size_t len;
|
||||
int ok = -1;
|
||||
|
||||
switch (cmd) {
|
||||
case CTAP_CMD_INIT: /* select */
|
||||
if ((apdu = iso7816_new(0, 0xa4, 0x04, sizeof(aid))) == NULL ||
|
||||
iso7816_add(apdu, aid, sizeof(aid)) < 0) {
|
||||
fido_log_debug("%s: iso7816", __func__);
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case CTAP_CMD_CBOR: /* wrap cbor */
|
||||
if (count > UINT16_MAX || (apdu = iso7816_new(0x80, 0x10, 0x00,
|
||||
(uint16_t)count)) == NULL ||
|
||||
iso7816_add(apdu, buf, count) < 0) {
|
||||
fido_log_debug("%s: iso7816", __func__);
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case CTAP_CMD_MSG: /* already an apdu */
|
||||
break;
|
||||
default:
|
||||
fido_log_debug("%s: cmd=%02x", __func__, cmd);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (apdu != NULL) {
|
||||
ptr = iso7816_ptr(apdu);
|
||||
len = iso7816_len(apdu);
|
||||
} else {
|
||||
ptr = buf;
|
||||
len = count;
|
||||
}
|
||||
|
||||
if (nfc_do_tx(d, ptr, len) < 0) {
|
||||
fido_log_debug("%s: nfc_do_tx", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = 0;
|
||||
fail:
|
||||
iso7816_free(&apdu);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int
|
||||
rx_init(fido_dev_t *d, unsigned char *buf, size_t count, int ms)
|
||||
{
|
||||
fido_ctap_info_t *attr = (fido_ctap_info_t *)buf;
|
||||
uint8_t f[64];
|
||||
int n;
|
||||
|
||||
if (count != sizeof(*attr)) {
|
||||
fido_log_debug("%s: count=%zu", __func__, count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(attr, 0, sizeof(*attr));
|
||||
|
||||
if ((n = d->io.read(d->io_handle, f, sizeof(f), ms)) < 2 ||
|
||||
(f[n - 2] << 8 | f[n - 1]) != SW_NO_ERROR) {
|
||||
fido_log_debug("%s: read", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
n -= 2;
|
||||
|
||||
if (n == sizeof(v_u2f) && memcmp(f, v_u2f, sizeof(v_u2f)) == 0)
|
||||
attr->flags = FIDO_CAP_CBOR;
|
||||
else if (n == sizeof(v_fido) && memcmp(f, v_fido, sizeof(v_fido)) == 0)
|
||||
attr->flags = FIDO_CAP_CBOR | FIDO_CAP_NMSG;
|
||||
else {
|
||||
fido_log_debug("%s: unknown version string", __func__);
|
||||
#ifdef FIDO_FUZZ
|
||||
attr->flags = FIDO_CAP_CBOR | FIDO_CAP_NMSG;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
memcpy(&attr->nonce, &d->nonce, sizeof(attr->nonce)); /* XXX */
|
||||
|
||||
return (int)count;
|
||||
}
|
||||
|
||||
static int
|
||||
tx_get_response(fido_dev_t *d, uint8_t count)
|
||||
{
|
||||
uint8_t apdu[5];
|
||||
|
||||
memset(apdu, 0, sizeof(apdu));
|
||||
apdu[1] = 0xc0; /* GET_RESPONSE */
|
||||
apdu[4] = count;
|
||||
|
||||
if (d->io.write(d->io_handle, apdu, sizeof(apdu)) < 0) {
|
||||
fido_log_debug("%s: write", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rx_apdu(fido_dev_t *d, uint8_t sw[2], unsigned char **buf, size_t *count, int *ms)
|
||||
{
|
||||
uint8_t f[256 + 2];
|
||||
struct timespec ts;
|
||||
int n, ok = -1;
|
||||
|
||||
if (fido_time_now(&ts) != 0)
|
||||
goto fail;
|
||||
|
||||
if ((n = d->io.read(d->io_handle, f, sizeof(f), *ms)) < 2) {
|
||||
fido_log_debug("%s: read", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (fido_time_delta(&ts, ms) != 0)
|
||||
goto fail;
|
||||
|
||||
if (fido_buf_write(buf, count, f, (size_t)(n - 2)) < 0) {
|
||||
fido_log_debug("%s: fido_buf_write", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
memcpy(sw, f + n - 2, 2);
|
||||
|
||||
ok = 0;
|
||||
fail:
|
||||
explicit_bzero(f, sizeof(f));
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int
|
||||
rx_msg(fido_dev_t *d, unsigned char *buf, size_t count, int ms)
|
||||
{
|
||||
uint8_t sw[2];
|
||||
const size_t bufsiz = count;
|
||||
|
||||
if (rx_apdu(d, sw, &buf, &count, &ms) < 0) {
|
||||
fido_log_debug("%s: preamble", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (sw[0] == SW1_MORE_DATA)
|
||||
if (tx_get_response(d, sw[1]) < 0 ||
|
||||
rx_apdu(d, sw, &buf, &count, &ms) < 0) {
|
||||
fido_log_debug("%s: chain", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fido_buf_write(&buf, &count, sw, sizeof(sw)) < 0) {
|
||||
fido_log_debug("%s: sw", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bufsiz - count > INT_MAX) {
|
||||
fido_log_debug("%s: bufsiz", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int)(bufsiz - count);
|
||||
}
|
||||
|
||||
static int
|
||||
rx_cbor(fido_dev_t *d, unsigned char *buf, size_t count, int ms)
|
||||
{
|
||||
int r;
|
||||
|
||||
if ((r = rx_msg(d, buf, count, ms)) < 2)
|
||||
return -1;
|
||||
|
||||
return r - 2;
|
||||
}
|
||||
|
||||
int
|
||||
fido_nfc_rx(fido_dev_t *d, uint8_t cmd, unsigned char *buf, size_t count, int ms)
|
||||
{
|
||||
switch (cmd) {
|
||||
case CTAP_CMD_INIT:
|
||||
return rx_init(d, buf, count, ms);
|
||||
case CTAP_CMD_CBOR:
|
||||
return rx_cbor(d, buf, count, ms);
|
||||
case CTAP_CMD_MSG:
|
||||
return rx_msg(d, buf, count, ms);
|
||||
default:
|
||||
fido_log_debug("%s: cmd=%02x", __func__, cmd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_NFC
|
||||
bool
|
||||
fido_is_nfc(const char *path)
|
||||
{
|
||||
return strncmp(path, FIDO_NFC_PREFIX, strlen(FIDO_NFC_PREFIX)) == 0;
|
||||
}
|
||||
|
||||
int
|
||||
fido_dev_set_nfc(fido_dev_t *d)
|
||||
{
|
||||
if (d->io_handle != NULL) {
|
||||
fido_log_debug("%s: device open", __func__);
|
||||
return -1;
|
||||
}
|
||||
d->io_own = true;
|
||||
d->io = (fido_dev_io_t) {
|
||||
fido_nfc_open,
|
||||
fido_nfc_close,
|
||||
fido_nfc_read,
|
||||
fido_nfc_write,
|
||||
};
|
||||
d->transport = (fido_dev_transport_t) {
|
||||
fido_nfc_rx,
|
||||
fido_nfc_tx,
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* USE_NFC */
|
||||
374
src/nfc_linux.c
374
src/nfc_linux.c
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Yubico AB. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -22,12 +22,6 @@
|
|||
#include "netlink.h"
|
||||
#include "iso7816.h"
|
||||
|
||||
#define TX_CHUNK_SIZE 240
|
||||
|
||||
static const uint8_t aid[] = { 0xa0, 0x00, 0x00, 0x06, 0x47, 0x2f, 0x00, 0x01 };
|
||||
static const uint8_t v_u2f[] = { 'U', '2', 'F', '_', 'V', '2' };
|
||||
static const uint8_t v_fido[] = { 'F', 'I', 'D', 'O', '_', '2', '_', '0' };
|
||||
|
||||
struct nfc_linux {
|
||||
int fd;
|
||||
uint32_t dev;
|
||||
|
|
@ -37,278 +31,6 @@ struct nfc_linux {
|
|||
struct fido_nl *nl;
|
||||
};
|
||||
|
||||
static int
|
||||
tx_short_apdu(fido_dev_t *d, const iso7816_header_t *h, const uint8_t *payload,
|
||||
uint8_t payload_len, uint8_t cla_flags)
|
||||
{
|
||||
uint8_t apdu[5 + UINT8_MAX + 1];
|
||||
uint8_t sw[2];
|
||||
size_t apdu_len;
|
||||
int ok = -1;
|
||||
|
||||
memset(&apdu, 0, sizeof(apdu));
|
||||
apdu[0] = h->cla | cla_flags;
|
||||
apdu[1] = h->ins;
|
||||
apdu[2] = h->p1;
|
||||
apdu[3] = h->p2;
|
||||
apdu[4] = payload_len;
|
||||
memcpy(&apdu[5], payload, payload_len);
|
||||
apdu_len = (size_t)(5 + payload_len + 1);
|
||||
|
||||
if (d->io.write(d->io_handle, apdu, apdu_len) < 0) {
|
||||
fido_log_debug("%s: write", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (cla_flags & 0x10) {
|
||||
if (d->io.read(d->io_handle, sw, sizeof(sw), -1) != 2) {
|
||||
fido_log_debug("%s: read", __func__);
|
||||
goto fail;
|
||||
}
|
||||
if ((sw[0] << 8 | sw[1]) != SW_NO_ERROR) {
|
||||
fido_log_debug("%s: unexpected sw", __func__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
ok = 0;
|
||||
fail:
|
||||
explicit_bzero(apdu, sizeof(apdu));
|
||||
|
||||
return (ok);
|
||||
}
|
||||
|
||||
static int
|
||||
nfc_do_tx(fido_dev_t *d, const uint8_t *apdu_ptr, size_t apdu_len)
|
||||
{
|
||||
iso7816_header_t h;
|
||||
|
||||
if (fido_buf_read(&apdu_ptr, &apdu_len, &h, sizeof(h)) < 0) {
|
||||
fido_log_debug("%s: header", __func__);
|
||||
return (-1);
|
||||
}
|
||||
if (apdu_len < 2) {
|
||||
fido_log_debug("%s: apdu_len %zu", __func__, apdu_len);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
apdu_len -= 2; /* trim le1 le2 */
|
||||
|
||||
while (apdu_len > TX_CHUNK_SIZE) {
|
||||
if (tx_short_apdu(d, &h, apdu_ptr, TX_CHUNK_SIZE, 0x10) < 0) {
|
||||
fido_log_debug("%s: chain", __func__);
|
||||
return (-1);
|
||||
}
|
||||
apdu_ptr += TX_CHUNK_SIZE;
|
||||
apdu_len -= TX_CHUNK_SIZE;
|
||||
}
|
||||
|
||||
if (tx_short_apdu(d, &h, apdu_ptr, (uint8_t)apdu_len, 0) < 0) {
|
||||
fido_log_debug("%s: tx_short_apdu", __func__);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
fido_nfc_tx(fido_dev_t *d, uint8_t cmd, const unsigned char *buf, size_t count)
|
||||
{
|
||||
iso7816_apdu_t *apdu = NULL;
|
||||
const uint8_t *ptr;
|
||||
size_t len;
|
||||
int ok = -1;
|
||||
|
||||
switch (cmd) {
|
||||
case CTAP_CMD_INIT: /* select */
|
||||
if ((apdu = iso7816_new(0, 0xa4, 0x04, sizeof(aid))) == NULL ||
|
||||
iso7816_add(apdu, aid, sizeof(aid)) < 0) {
|
||||
fido_log_debug("%s: iso7816", __func__);
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case CTAP_CMD_CBOR: /* wrap cbor */
|
||||
if (count > UINT16_MAX || (apdu = iso7816_new(0x80, 0x10, 0x80,
|
||||
(uint16_t)count)) == NULL ||
|
||||
iso7816_add(apdu, buf, count) < 0) {
|
||||
fido_log_debug("%s: iso7816", __func__);
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case CTAP_CMD_MSG: /* already an apdu */
|
||||
break;
|
||||
default:
|
||||
fido_log_debug("%s: cmd=%02x", __func__, cmd);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (apdu != NULL) {
|
||||
ptr = iso7816_ptr(apdu);
|
||||
len = iso7816_len(apdu);
|
||||
} else {
|
||||
ptr = buf;
|
||||
len = count;
|
||||
}
|
||||
|
||||
if (nfc_do_tx(d, ptr, len) < 0) {
|
||||
fido_log_debug("%s: nfc_do_tx", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ok = 0;
|
||||
fail:
|
||||
iso7816_free(&apdu);
|
||||
|
||||
return (ok);
|
||||
}
|
||||
|
||||
static int
|
||||
rx_init(fido_dev_t *d, unsigned char *buf, size_t count, int ms)
|
||||
{
|
||||
fido_ctap_info_t *attr = (fido_ctap_info_t *)buf;
|
||||
uint8_t f[64];
|
||||
int n;
|
||||
|
||||
if (count != sizeof(*attr)) {
|
||||
fido_log_debug("%s: count=%zu", __func__, count);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
memset(attr, 0, sizeof(*attr));
|
||||
|
||||
if ((n = d->io.read(d->io_handle, f, sizeof(f), ms)) < 2 ||
|
||||
(f[n - 2] << 8 | f[n - 1]) != SW_NO_ERROR) {
|
||||
fido_log_debug("%s: read", __func__);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
n -= 2;
|
||||
|
||||
if (n == sizeof(v_u2f) && memcmp(f, v_u2f, sizeof(v_u2f)) == 0)
|
||||
attr->flags = FIDO_CAP_CBOR;
|
||||
else if (n == sizeof(v_fido) && memcmp(f, v_fido, sizeof(v_fido)) == 0)
|
||||
attr->flags = FIDO_CAP_CBOR | FIDO_CAP_NMSG;
|
||||
else {
|
||||
fido_log_debug("%s: unknown version string", __func__);
|
||||
#ifdef FIDO_FUZZ
|
||||
attr->flags = FIDO_CAP_CBOR | FIDO_CAP_NMSG;
|
||||
#else
|
||||
return (-1);
|
||||
#endif
|
||||
}
|
||||
|
||||
memcpy(&attr->nonce, &d->nonce, sizeof(attr->nonce)); /* XXX */
|
||||
|
||||
return ((int)count);
|
||||
}
|
||||
|
||||
static int
|
||||
tx_get_response(fido_dev_t *d, uint8_t count)
|
||||
{
|
||||
uint8_t apdu[5];
|
||||
|
||||
memset(apdu, 0, sizeof(apdu));
|
||||
apdu[1] = 0xc0; /* GET_RESPONSE */
|
||||
apdu[4] = count;
|
||||
|
||||
if (d->io.write(d->io_handle, apdu, sizeof(apdu)) < 0) {
|
||||
fido_log_debug("%s: write", __func__);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
rx_apdu(fido_dev_t *d, uint8_t sw[2], unsigned char **buf, size_t *count, int *ms)
|
||||
{
|
||||
uint8_t f[256 + 2];
|
||||
struct timespec ts;
|
||||
int n, ok = -1;
|
||||
|
||||
if (fido_time_now(&ts) != 0)
|
||||
goto fail;
|
||||
|
||||
if ((n = d->io.read(d->io_handle, f, sizeof(f), *ms)) < 2) {
|
||||
fido_log_debug("%s: read", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (fido_time_delta(&ts, ms) != 0)
|
||||
goto fail;
|
||||
|
||||
if (fido_buf_write(buf, count, f, (size_t)(n - 2)) < 0) {
|
||||
fido_log_debug("%s: fido_buf_write", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
memcpy(sw, f + n - 2, 2);
|
||||
|
||||
ok = 0;
|
||||
fail:
|
||||
explicit_bzero(f, sizeof(f));
|
||||
|
||||
return (ok);
|
||||
}
|
||||
|
||||
static int
|
||||
rx_msg(fido_dev_t *d, unsigned char *buf, size_t count, int ms)
|
||||
{
|
||||
uint8_t sw[2];
|
||||
const size_t bufsiz = count;
|
||||
|
||||
if (rx_apdu(d, sw, &buf, &count, &ms) < 0) {
|
||||
fido_log_debug("%s: preamble", __func__);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
while (sw[0] == SW1_MORE_DATA)
|
||||
if (tx_get_response(d, sw[1]) < 0 ||
|
||||
rx_apdu(d, sw, &buf, &count, &ms) < 0) {
|
||||
fido_log_debug("%s: chain", __func__);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (fido_buf_write(&buf, &count, sw, sizeof(sw)) < 0) {
|
||||
fido_log_debug("%s: sw", __func__);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (bufsiz - count > INT_MAX) {
|
||||
fido_log_debug("%s: bufsiz", __func__);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return ((int)(bufsiz - count));
|
||||
}
|
||||
|
||||
static int
|
||||
rx_cbor(fido_dev_t *d, unsigned char *buf, size_t count, int ms)
|
||||
{
|
||||
int r;
|
||||
|
||||
if ((r = rx_msg(d, buf, count, ms)) < 2)
|
||||
return (-1);
|
||||
|
||||
return (r - 2);
|
||||
}
|
||||
|
||||
int
|
||||
fido_nfc_rx(fido_dev_t *d, uint8_t cmd, unsigned char *buf, size_t count, int ms)
|
||||
{
|
||||
switch (cmd) {
|
||||
case CTAP_CMD_INIT:
|
||||
return (rx_init(d, buf, count, ms));
|
||||
case CTAP_CMD_CBOR:
|
||||
return (rx_cbor(d, buf, count, ms));
|
||||
case CTAP_CMD_MSG:
|
||||
return (rx_msg(d, buf, count, ms));
|
||||
default:
|
||||
fido_log_debug("%s: cmd=%02x", __func__, cmd);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
get_parent_attr(struct udev_device *dev, const char *subsystem,
|
||||
const char *devtype, const char *attr)
|
||||
|
|
@ -319,34 +41,15 @@ get_parent_attr(struct udev_device *dev, const char *subsystem,
|
|||
if ((parent = udev_device_get_parent_with_subsystem_devtype(dev,
|
||||
subsystem, devtype)) == NULL || (value =
|
||||
udev_device_get_sysattr_value(parent, attr)) == NULL)
|
||||
return (NULL);
|
||||
return NULL;
|
||||
|
||||
return (strdup(value));
|
||||
return strdup(value);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_usb_attr(struct udev_device *dev, const char *attr)
|
||||
{
|
||||
return (get_parent_attr(dev, "usb", "usb_device", attr));
|
||||
}
|
||||
|
||||
static int
|
||||
to_int(const char *str, int base)
|
||||
{
|
||||
char *ep;
|
||||
long long ll;
|
||||
|
||||
ll = strtoll(str, &ep, base);
|
||||
if (str == ep || *ep != '\0')
|
||||
return (-1);
|
||||
else if (ll == LLONG_MIN && errno == ERANGE)
|
||||
return (-1);
|
||||
else if (ll == LLONG_MAX && errno == ERANGE)
|
||||
return (-1);
|
||||
else if (ll < 0 || ll > INT_MAX)
|
||||
return (-1);
|
||||
|
||||
return ((int)ll);
|
||||
return get_parent_attr(dev, "usb", "usb_device", attr);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -357,15 +60,18 @@ copy_info(fido_dev_info_t *di, struct udev *udev,
|
|||
char *str;
|
||||
struct udev_device *dev = NULL;
|
||||
void *ctx = NULL;
|
||||
int id, ok = -1;
|
||||
uint64_t id;
|
||||
int ok = -1;
|
||||
|
||||
memset(di, 0, sizeof(*di));
|
||||
|
||||
if ((name = udev_list_entry_get_name(udev_entry)) == NULL ||
|
||||
(dev = udev_device_new_from_syspath(udev, name)) == NULL)
|
||||
goto fail;
|
||||
if (asprintf(&di->path, "%s/%s", FIDO_NFC_PREFIX, name) == -1)
|
||||
if (asprintf(&di->path, "%s/%s", FIDO_NFC_PREFIX, name) == -1) {
|
||||
di->path = NULL;
|
||||
goto fail;
|
||||
}
|
||||
if ((di->manufacturer = get_usb_attr(dev, "manufacturer")) == NULL)
|
||||
di->manufacturer = strdup("");
|
||||
if ((di->product = get_usb_attr(dev, "product")) == NULL)
|
||||
|
|
@ -374,11 +80,11 @@ copy_info(fido_dev_info_t *di, struct udev *udev,
|
|||
goto fail;
|
||||
/* XXX assumes USB for vendor/product info */
|
||||
if ((str = get_usb_attr(dev, "idVendor")) != NULL &&
|
||||
(id = to_int(str, 16)) > 0 && id <= UINT16_MAX)
|
||||
fido_to_uint64(str, 16, &id) == 0 && id <= UINT16_MAX)
|
||||
di->vendor_id = (int16_t)id;
|
||||
free(str);
|
||||
if ((str = get_usb_attr(dev, "idProduct")) != NULL &&
|
||||
(id = to_int(str, 16)) > 0 && id <= UINT16_MAX)
|
||||
fido_to_uint64(str, 16, &id) == 0 && id <= UINT16_MAX)
|
||||
di->product_id = (int16_t)id;
|
||||
free(str);
|
||||
|
||||
|
|
@ -401,7 +107,7 @@ fail:
|
|||
explicit_bzero(di, sizeof(*di));
|
||||
}
|
||||
|
||||
return (ok);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -410,21 +116,21 @@ sysnum_from_syspath(const char *path)
|
|||
struct udev *udev = NULL;
|
||||
struct udev_device *dev = NULL;
|
||||
const char *str;
|
||||
int idx;
|
||||
uint64_t idx64;
|
||||
int idx = -1;
|
||||
|
||||
if ((udev = udev_new()) == NULL ||
|
||||
(dev = udev_device_new_from_syspath(udev, path)) == NULL ||
|
||||
(str = udev_device_get_sysnum(dev)) == NULL)
|
||||
idx = -1;
|
||||
else
|
||||
idx = to_int(str, 10);
|
||||
if ((udev = udev_new()) != NULL &&
|
||||
(dev = udev_device_new_from_syspath(udev, path)) != NULL &&
|
||||
(str = udev_device_get_sysnum(dev)) != NULL &&
|
||||
fido_to_uint64(str, 10, &idx64) == 0 && idx64 < INT_MAX)
|
||||
idx = (int)idx64;
|
||||
|
||||
if (dev != NULL)
|
||||
udev_device_unref(dev);
|
||||
if (udev != NULL)
|
||||
udev_unref(udev);
|
||||
|
||||
return (idx);
|
||||
return idx;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -439,10 +145,10 @@ fido_nfc_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)
|
|||
*olen = 0;
|
||||
|
||||
if (ilen == 0)
|
||||
return (FIDO_OK);
|
||||
return FIDO_OK;
|
||||
|
||||
if (devlist == NULL)
|
||||
return (FIDO_ERR_INVALID_ARGUMENT);
|
||||
return FIDO_ERR_INVALID_ARGUMENT;
|
||||
|
||||
if ((udev = udev_new()) == NULL ||
|
||||
(udev_enum = udev_enumerate_new(udev)) == NULL)
|
||||
|
|
@ -481,7 +187,7 @@ fail:
|
|||
if (udev != NULL)
|
||||
udev_unref(udev);
|
||||
|
||||
return (r);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -498,17 +204,17 @@ nfc_target_connect(struct nfc_linux *ctx)
|
|||
if ((ctx->fd = socket(AF_NFC, SOCK_SEQPACKET | SOCK_CLOEXEC,
|
||||
NFC_SOCKPROTO_RAW)) == -1) {
|
||||
fido_log_error(errno, "%s: socket", __func__);
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
if (connect(ctx->fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
|
||||
fido_log_error(errno, "%s: connect", __func__);
|
||||
if (close(ctx->fd) == -1)
|
||||
fido_log_error(errno, "%s: close", __func__);
|
||||
ctx->fd = -1;
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -535,13 +241,13 @@ nfc_new(uint32_t dev)
|
|||
if ((ctx = calloc(1, sizeof(*ctx))) == NULL ||
|
||||
(ctx->nl = fido_nl_new()) == NULL) {
|
||||
nfc_free(&ctx);
|
||||
return (NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->fd = -1;
|
||||
ctx->dev = dev;
|
||||
|
||||
return (ctx);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void *
|
||||
|
|
@ -566,10 +272,10 @@ fido_nfc_open(const char *path)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
return (ctx);
|
||||
return ctx;
|
||||
fail:
|
||||
nfc_free(&ctx);
|
||||
return (NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -588,7 +294,7 @@ fido_nfc_set_sigmask(void *handle, const fido_sigset_t *sigmask)
|
|||
ctx->sigmask = *sigmask;
|
||||
ctx->sigmaskp = &ctx->sigmask;
|
||||
|
||||
return (FIDO_OK);
|
||||
return FIDO_OK;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -607,25 +313,25 @@ fido_nfc_read(void *handle, unsigned char *buf, size_t len, int ms)
|
|||
|
||||
if (fido_hid_unix_wait(ctx->fd, ms, ctx->sigmaskp) < 0) {
|
||||
fido_log_debug("%s: fido_hid_unix_wait", __func__);
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
if ((r = readv(ctx->fd, iov, nitems(iov))) == -1) {
|
||||
fido_log_error(errno, "%s: read", __func__);
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
if (r < 1) {
|
||||
fido_log_debug("%s: %zd < 1", __func__, r);
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
if (preamble != 0x00) {
|
||||
fido_log_debug("%s: preamble", __func__);
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
r--;
|
||||
fido_log_xxd(buf, (size_t)r, "%s", __func__);
|
||||
|
||||
return ((int)r);
|
||||
return (int)r;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -638,16 +344,16 @@ fido_nfc_write(void *handle, const unsigned char *buf, size_t len)
|
|||
|
||||
if (len > INT_MAX) {
|
||||
fido_log_debug("%s: len", __func__);
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
if ((r = write(ctx->fd, buf, len)) == -1) {
|
||||
fido_log_error(errno, "%s: write", __func__);
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
if (r < 0 || (size_t)r != len) {
|
||||
fido_log_debug("%s: %zd != %zu", __func__, r, len);
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ((int)r);
|
||||
return (int)r;
|
||||
}
|
||||
|
|
|
|||
389
src/pcsc.c
Normal file
389
src/pcsc.c
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Micro Focus or one of its affiliates.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if __APPLE__
|
||||
#include <PCSC/wintypes.h>
|
||||
#include <PCSC/winscard.h>
|
||||
#else
|
||||
#include <winscard.h>
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "fido.h"
|
||||
#include "fido/param.h"
|
||||
#include "iso7816.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
#define SCardConnect SCardConnectA
|
||||
#define SCardListReaders SCardListReadersA
|
||||
#endif
|
||||
|
||||
#ifndef SCARD_PROTOCOL_Tx
|
||||
#define SCARD_PROTOCOL_Tx SCARD_PROTOCOL_ANY
|
||||
#endif
|
||||
|
||||
#define BUFSIZE 1024 /* in bytes; passed to SCardListReaders() */
|
||||
#define APDULEN 264 /* 261 rounded up to the nearest multiple of 8 */
|
||||
#define READERS 8 /* maximum number of readers */
|
||||
|
||||
struct pcsc {
|
||||
SCARDCONTEXT ctx;
|
||||
SCARDHANDLE h;
|
||||
SCARD_IO_REQUEST req;
|
||||
uint8_t rx_buf[APDULEN];
|
||||
size_t rx_len;
|
||||
};
|
||||
|
||||
static LONG
|
||||
list_readers(SCARDCONTEXT ctx, char **buf)
|
||||
{
|
||||
LONG s;
|
||||
DWORD len;
|
||||
|
||||
len = BUFSIZE;
|
||||
if ((*buf = calloc(1, len)) == NULL)
|
||||
goto fail;
|
||||
if ((s = SCardListReaders(ctx, NULL, *buf, &len)) != SCARD_S_SUCCESS) {
|
||||
fido_log_debug("%s: SCardListReaders 0x%lx", __func__, (long)s);
|
||||
goto fail;
|
||||
}
|
||||
/* sanity check "multi-string" */
|
||||
if (len > BUFSIZE || len < 2) {
|
||||
fido_log_debug("%s: bogus len=%u", __func__, (unsigned)len);
|
||||
goto fail;
|
||||
}
|
||||
if ((*buf)[len - 1] != 0 || (*buf)[len - 2] != '\0') {
|
||||
fido_log_debug("%s: bogus buf", __func__);
|
||||
goto fail;
|
||||
}
|
||||
return (LONG)SCARD_S_SUCCESS;
|
||||
fail:
|
||||
free(*buf);
|
||||
*buf = NULL;
|
||||
|
||||
return (LONG)SCARD_E_NO_READERS_AVAILABLE;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_reader(SCARDCONTEXT ctx, const char *path)
|
||||
{
|
||||
char *reader = NULL, *buf = NULL;
|
||||
const char prefix[] = FIDO_PCSC_PREFIX "//slot";
|
||||
uint64_t n;
|
||||
|
||||
if (path == NULL)
|
||||
goto out;
|
||||
if (strncmp(path, prefix, strlen(prefix)) != 0 ||
|
||||
fido_to_uint64(path + strlen(prefix), 10, &n) < 0 ||
|
||||
n > READERS - 1) {
|
||||
fido_log_debug("%s: invalid path %s", __func__, path);
|
||||
goto out;
|
||||
}
|
||||
if (list_readers(ctx, &buf) != SCARD_S_SUCCESS) {
|
||||
fido_log_debug("%s: list_readers", __func__);
|
||||
goto out;
|
||||
}
|
||||
for (const char *name = buf; *name != 0; name += strlen(name) + 1) {
|
||||
if (n == 0) {
|
||||
reader = strdup(name);
|
||||
goto out;
|
||||
}
|
||||
n--;
|
||||
}
|
||||
fido_log_debug("%s: failed to find reader %s", __func__, path);
|
||||
out:
|
||||
free(buf);
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
static int
|
||||
prepare_io_request(DWORD prot, SCARD_IO_REQUEST *req)
|
||||
{
|
||||
switch (prot) {
|
||||
case SCARD_PROTOCOL_T0:
|
||||
req->dwProtocol = SCARD_PCI_T0->dwProtocol;
|
||||
req->cbPciLength = SCARD_PCI_T0->cbPciLength;
|
||||
break;
|
||||
case SCARD_PROTOCOL_T1:
|
||||
req->dwProtocol = SCARD_PCI_T1->dwProtocol;
|
||||
req->cbPciLength = SCARD_PCI_T1->cbPciLength;
|
||||
break;
|
||||
default:
|
||||
fido_log_debug("%s: unknown protocol %lu", __func__,
|
||||
(u_long)prot);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
copy_info(fido_dev_info_t *di, SCARDCONTEXT ctx, const char *reader, size_t idx)
|
||||
{
|
||||
SCARDHANDLE h = 0;
|
||||
SCARD_IO_REQUEST req;
|
||||
DWORD prot = 0;
|
||||
LONG s;
|
||||
int ok = -1;
|
||||
|
||||
memset(di, 0, sizeof(*di));
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
if ((s = SCardConnect(ctx, reader, SCARD_SHARE_SHARED,
|
||||
SCARD_PROTOCOL_Tx, &h, &prot)) != SCARD_S_SUCCESS) {
|
||||
fido_log_debug("%s: SCardConnect 0x%lx", __func__, (long)s);
|
||||
goto fail;
|
||||
}
|
||||
if (prepare_io_request(prot, &req) < 0) {
|
||||
fido_log_debug("%s: prepare_io_request", __func__);
|
||||
goto fail;
|
||||
}
|
||||
if (asprintf(&di->path, "%s//slot%zu", FIDO_PCSC_PREFIX, idx) == -1) {
|
||||
di->path = NULL;
|
||||
fido_log_debug("%s: asprintf", __func__);
|
||||
goto fail;
|
||||
}
|
||||
if ((di->manufacturer = strdup("PC/SC")) == NULL ||
|
||||
(di->product = strdup(reader)) == NULL)
|
||||
goto fail;
|
||||
|
||||
ok = 0;
|
||||
fail:
|
||||
if (h != 0)
|
||||
SCardDisconnect(h, SCARD_LEAVE_CARD);
|
||||
if (ok < 0) {
|
||||
free(di->path);
|
||||
free(di->manufacturer);
|
||||
free(di->product);
|
||||
explicit_bzero(di, sizeof(*di));
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
int
|
||||
fido_pcsc_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)
|
||||
{
|
||||
SCARDCONTEXT ctx = 0;
|
||||
char *buf = NULL;
|
||||
LONG s;
|
||||
size_t idx = 0;
|
||||
int r = FIDO_ERR_INTERNAL;
|
||||
|
||||
*olen = 0;
|
||||
|
||||
if (ilen == 0)
|
||||
return FIDO_OK;
|
||||
if (devlist == NULL)
|
||||
return FIDO_ERR_INVALID_ARGUMENT;
|
||||
|
||||
if ((s = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL,
|
||||
&ctx)) != SCARD_S_SUCCESS || ctx == 0) {
|
||||
fido_log_debug("%s: SCardEstablishContext 0x%lx", __func__,
|
||||
(long)s);
|
||||
if (s == (LONG)SCARD_E_NO_SERVICE ||
|
||||
s == (LONG)SCARD_E_NO_SMARTCARD)
|
||||
r = FIDO_OK; /* suppress error */
|
||||
goto out;
|
||||
}
|
||||
if ((s = list_readers(ctx, &buf)) != SCARD_S_SUCCESS) {
|
||||
fido_log_debug("%s: list_readers 0x%lx", __func__, (long)s);
|
||||
if (s == (LONG)SCARD_E_NO_READERS_AVAILABLE)
|
||||
r = FIDO_OK; /* suppress error */
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (const char *name = buf; *name != 0; name += strlen(name) + 1) {
|
||||
if (idx == READERS) {
|
||||
fido_log_debug("%s: stopping at %zu readers", __func__,
|
||||
idx);
|
||||
r = FIDO_OK;
|
||||
goto out;
|
||||
}
|
||||
if (copy_info(&devlist[*olen], ctx, name, idx++) == 0) {
|
||||
devlist[*olen].io = (fido_dev_io_t) {
|
||||
fido_pcsc_open,
|
||||
fido_pcsc_close,
|
||||
fido_pcsc_read,
|
||||
fido_pcsc_write,
|
||||
};
|
||||
devlist[*olen].transport = (fido_dev_transport_t) {
|
||||
fido_pcsc_rx,
|
||||
fido_pcsc_tx,
|
||||
};
|
||||
if (++(*olen) == ilen)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
r = FIDO_OK;
|
||||
out:
|
||||
free(buf);
|
||||
if (ctx != 0)
|
||||
SCardReleaseContext(ctx);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void *
|
||||
fido_pcsc_open(const char *path)
|
||||
{
|
||||
char *reader = NULL;
|
||||
struct pcsc *dev = NULL;
|
||||
SCARDCONTEXT ctx = 0;
|
||||
SCARDHANDLE h = 0;
|
||||
SCARD_IO_REQUEST req;
|
||||
DWORD prot = 0;
|
||||
LONG s;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
if ((s = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL,
|
||||
&ctx)) != SCARD_S_SUCCESS || ctx == 0) {
|
||||
fido_log_debug("%s: SCardEstablishContext 0x%lx", __func__,
|
||||
(long)s);
|
||||
goto fail;
|
||||
|
||||
}
|
||||
if ((reader = get_reader(ctx, path)) == NULL) {
|
||||
fido_log_debug("%s: get_reader(%s)", __func__, path);
|
||||
goto fail;
|
||||
}
|
||||
if ((s = SCardConnect(ctx, reader, SCARD_SHARE_SHARED,
|
||||
SCARD_PROTOCOL_Tx, &h, &prot)) != SCARD_S_SUCCESS) {
|
||||
fido_log_debug("%s: SCardConnect 0x%lx", __func__, (long)s);
|
||||
goto fail;
|
||||
}
|
||||
if (prepare_io_request(prot, &req) < 0) {
|
||||
fido_log_debug("%s: prepare_io_request", __func__);
|
||||
goto fail;
|
||||
}
|
||||
if ((dev = calloc(1, sizeof(*dev))) == NULL)
|
||||
goto fail;
|
||||
|
||||
dev->ctx = ctx;
|
||||
dev->h = h;
|
||||
dev->req = req;
|
||||
ctx = 0;
|
||||
h = 0;
|
||||
fail:
|
||||
if (h != 0)
|
||||
SCardDisconnect(h, SCARD_LEAVE_CARD);
|
||||
if (ctx != 0)
|
||||
SCardReleaseContext(ctx);
|
||||
free(reader);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
void
|
||||
fido_pcsc_close(void *handle)
|
||||
{
|
||||
struct pcsc *dev = handle;
|
||||
|
||||
if (dev->h != 0)
|
||||
SCardDisconnect(dev->h, SCARD_LEAVE_CARD);
|
||||
if (dev->ctx != 0)
|
||||
SCardReleaseContext(dev->ctx);
|
||||
|
||||
explicit_bzero(dev->rx_buf, sizeof(dev->rx_buf));
|
||||
free(dev);
|
||||
}
|
||||
|
||||
int
|
||||
fido_pcsc_read(void *handle, unsigned char *buf, size_t len, int ms)
|
||||
{
|
||||
struct pcsc *dev = handle;
|
||||
int r;
|
||||
|
||||
(void)ms;
|
||||
if (dev->rx_len == 0 || dev->rx_len > len ||
|
||||
dev->rx_len > sizeof(dev->rx_buf)) {
|
||||
fido_log_debug("%s: rx_len", __func__);
|
||||
return -1;
|
||||
}
|
||||
fido_log_xxd(dev->rx_buf, dev->rx_len, "%s: reading", __func__);
|
||||
memcpy(buf, dev->rx_buf, dev->rx_len);
|
||||
explicit_bzero(dev->rx_buf, sizeof(dev->rx_buf));
|
||||
r = (int)dev->rx_len;
|
||||
dev->rx_len = 0;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
fido_pcsc_write(void *handle, const unsigned char *buf, size_t len)
|
||||
{
|
||||
struct pcsc *dev = handle;
|
||||
DWORD n;
|
||||
LONG s;
|
||||
|
||||
if (len > INT_MAX) {
|
||||
fido_log_debug("%s: len", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
explicit_bzero(dev->rx_buf, sizeof(dev->rx_buf));
|
||||
dev->rx_len = 0;
|
||||
n = (DWORD)sizeof(dev->rx_buf);
|
||||
|
||||
fido_log_xxd(buf, len, "%s: writing", __func__);
|
||||
|
||||
if ((s = SCardTransmit(dev->h, &dev->req, buf, (DWORD)len, NULL,
|
||||
dev->rx_buf, &n)) != SCARD_S_SUCCESS) {
|
||||
fido_log_debug("%s: SCardTransmit 0x%lx", __func__, (long)s);
|
||||
explicit_bzero(dev->rx_buf, sizeof(dev->rx_buf));
|
||||
return -1;
|
||||
}
|
||||
dev->rx_len = (size_t)n;
|
||||
|
||||
fido_log_xxd(dev->rx_buf, dev->rx_len, "%s: read", __func__);
|
||||
|
||||
return (int)len;
|
||||
}
|
||||
|
||||
int
|
||||
fido_pcsc_tx(fido_dev_t *d, uint8_t cmd, const u_char *buf, size_t count)
|
||||
{
|
||||
return fido_nfc_tx(d, cmd, buf, count);
|
||||
}
|
||||
|
||||
int
|
||||
fido_pcsc_rx(fido_dev_t *d, uint8_t cmd, u_char *buf, size_t count, int ms)
|
||||
{
|
||||
return fido_nfc_rx(d, cmd, buf, count, ms);
|
||||
}
|
||||
|
||||
bool
|
||||
fido_is_pcsc(const char *path)
|
||||
{
|
||||
return strncmp(path, FIDO_PCSC_PREFIX, strlen(FIDO_PCSC_PREFIX)) == 0;
|
||||
}
|
||||
|
||||
int
|
||||
fido_dev_set_pcsc(fido_dev_t *d)
|
||||
{
|
||||
if (d->io_handle != NULL) {
|
||||
fido_log_debug("%s: device open", __func__);
|
||||
return -1;
|
||||
}
|
||||
d->io_own = true;
|
||||
d->io = (fido_dev_io_t) {
|
||||
fido_pcsc_open,
|
||||
fido_pcsc_close,
|
||||
fido_pcsc_read,
|
||||
fido_pcsc_write,
|
||||
};
|
||||
d->transport = (fido_dev_transport_t) {
|
||||
fido_pcsc_rx,
|
||||
fido_pcsc_tx,
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include "fido.h"
|
||||
|
||||
#if defined(LIBRESSL_VERSION_NUMBER)
|
||||
#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3050200fL
|
||||
static EVP_MD *
|
||||
rs1_get_EVP_MD(void)
|
||||
{
|
||||
|
|
|
|||
28
src/rs256.c
28
src/rs256.c
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2021 Yubico AB. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -11,7 +11,13 @@
|
|||
#include "fido.h"
|
||||
#include "fido/rs256.h"
|
||||
|
||||
#if defined(LIBRESSL_VERSION_NUMBER)
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000
|
||||
#define get0_RSA(x) EVP_PKEY_get0_RSA((x))
|
||||
#else
|
||||
#define get0_RSA(x) EVP_PKEY_get0((x))
|
||||
#endif
|
||||
|
||||
#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3050200fL
|
||||
static EVP_MD *
|
||||
rs256_get_EVP_MD(void)
|
||||
{
|
||||
|
|
@ -128,11 +134,20 @@ rs256_pk_free(rs256_pk_t **pkp)
|
|||
int
|
||||
rs256_pk_from_ptr(rs256_pk_t *pk, const void *ptr, size_t len)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
if (len < sizeof(*pk))
|
||||
return (FIDO_ERR_INVALID_ARGUMENT);
|
||||
|
||||
memcpy(pk, ptr, sizeof(*pk));
|
||||
|
||||
if ((pkey = rs256_pk_to_EVP_PKEY(pk)) == NULL) {
|
||||
fido_log_debug("%s: rs256_pk_to_EVP_PKEY", __func__);
|
||||
return (FIDO_ERR_INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
return (FIDO_OK);
|
||||
}
|
||||
|
||||
|
|
@ -163,6 +178,11 @@ rs256_pk_to_EVP_PKEY(const rs256_pk_t *k)
|
|||
n = NULL;
|
||||
e = NULL;
|
||||
|
||||
if (RSA_bits(rsa) != 2048) {
|
||||
fido_log_debug("%s: invalid key length", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((pkey = EVP_PKEY_new()) == NULL ||
|
||||
EVP_PKEY_assign_RSA(pkey, rsa) == 0) {
|
||||
fido_log_debug("%s: EVP_PKEY_assign_RSA", __func__);
|
||||
|
|
@ -225,10 +245,10 @@ rs256_pk_from_RSA(rs256_pk_t *pk, const RSA *rsa)
|
|||
int
|
||||
rs256_pk_from_EVP_PKEY(rs256_pk_t *pk, const EVP_PKEY *pkey)
|
||||
{
|
||||
RSA *rsa;
|
||||
const RSA *rsa;
|
||||
|
||||
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA ||
|
||||
(rsa = EVP_PKEY_get0(pkey)) == NULL)
|
||||
(rsa = get0_RSA(pkey)) == NULL)
|
||||
return (FIDO_ERR_INVALID_ARGUMENT);
|
||||
|
||||
return (rs256_pk_from_RSA(pk, rsa));
|
||||
|
|
|
|||
108
src/touch.c
Normal file
108
src/touch.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <openssl/sha.h>
|
||||
#include "fido.h"
|
||||
|
||||
int
|
||||
fido_dev_get_touch_begin(fido_dev_t *dev)
|
||||
{
|
||||
fido_blob_t f;
|
||||
cbor_item_t *argv[9];
|
||||
const char *clientdata = FIDO_DUMMY_CLIENTDATA;
|
||||
const uint8_t user_id = FIDO_DUMMY_USER_ID;
|
||||
unsigned char cdh[SHA256_DIGEST_LENGTH];
|
||||
fido_rp_t rp;
|
||||
fido_user_t user;
|
||||
int ms = dev->timeout_ms;
|
||||
int r = FIDO_ERR_INTERNAL;
|
||||
|
||||
memset(&f, 0, sizeof(f));
|
||||
memset(argv, 0, sizeof(argv));
|
||||
memset(cdh, 0, sizeof(cdh));
|
||||
memset(&rp, 0, sizeof(rp));
|
||||
memset(&user, 0, sizeof(user));
|
||||
|
||||
if (fido_dev_is_fido2(dev) == false)
|
||||
return (u2f_get_touch_begin(dev, &ms));
|
||||
|
||||
if (SHA256((const void *)clientdata, strlen(clientdata), cdh) != cdh) {
|
||||
fido_log_debug("%s: sha256", __func__);
|
||||
return (FIDO_ERR_INTERNAL);
|
||||
}
|
||||
|
||||
if ((rp.id = strdup(FIDO_DUMMY_RP_ID)) == NULL ||
|
||||
(user.name = strdup(FIDO_DUMMY_USER_NAME)) == NULL) {
|
||||
fido_log_debug("%s: strdup", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (fido_blob_set(&user.id, &user_id, sizeof(user_id)) < 0) {
|
||||
fido_log_debug("%s: fido_blob_set", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((argv[0] = cbor_build_bytestring(cdh, sizeof(cdh))) == NULL ||
|
||||
(argv[1] = cbor_encode_rp_entity(&rp)) == NULL ||
|
||||
(argv[2] = cbor_encode_user_entity(&user)) == NULL ||
|
||||
(argv[3] = cbor_encode_pubkey_param(COSE_ES256)) == NULL) {
|
||||
fido_log_debug("%s: cbor encode", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (fido_dev_supports_pin(dev)) {
|
||||
if ((argv[7] = cbor_new_definite_bytestring()) == NULL ||
|
||||
(argv[8] = cbor_encode_pin_opt(dev)) == NULL) {
|
||||
fido_log_debug("%s: cbor encode", __func__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (cbor_build_frame(CTAP_CBOR_MAKECRED, 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);
|
||||
free(rp.id);
|
||||
free(user.name);
|
||||
free(user.id.ptr);
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
int
|
||||
fido_dev_get_touch_status(fido_dev_t *dev, int *touched, int ms)
|
||||
{
|
||||
int r;
|
||||
|
||||
*touched = 0;
|
||||
|
||||
if (fido_dev_is_fido2(dev) == false)
|
||||
return (u2f_get_touch_status(dev, touched, &ms));
|
||||
|
||||
switch ((r = fido_rx_cbor_status(dev, &ms))) {
|
||||
case FIDO_ERR_PIN_AUTH_INVALID:
|
||||
case FIDO_ERR_PIN_INVALID:
|
||||
case FIDO_ERR_PIN_NOT_SET:
|
||||
case FIDO_ERR_SUCCESS:
|
||||
*touched = 1;
|
||||
break;
|
||||
case FIDO_ERR_RX:
|
||||
/* ignore */
|
||||
break;
|
||||
default:
|
||||
fido_log_debug("%s: fido_rx_cbor_status", __func__);
|
||||
return (r);
|
||||
}
|
||||
|
||||
return (FIDO_OK);
|
||||
}
|
||||
30
src/util.c
Normal file
30
src/util.c
Normal file
|
|
@ -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.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fido.h"
|
||||
|
||||
int
|
||||
fido_to_uint64(const char *str, int base, uint64_t *out)
|
||||
{
|
||||
char *ep;
|
||||
unsigned long long ull;
|
||||
|
||||
errno = 0;
|
||||
ull = strtoull(str, &ep, base);
|
||||
if (str == ep || *ep != '\0')
|
||||
return -1;
|
||||
else if (ull == ULLONG_MAX && errno == ERANGE)
|
||||
return -1;
|
||||
else if (ull > UINT64_MAX)
|
||||
return -1;
|
||||
*out = (uint64_t)ull;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -92,6 +92,9 @@ extern "C" {
|
|||
// - WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS : 5
|
||||
// - WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS : 6
|
||||
// - WEBAUTHN_ASSERTION : 3
|
||||
// APIs:
|
||||
// - WebAuthNGetPlatformCredentialList
|
||||
// - WebAuthNFreePlatformCredentialList
|
||||
//
|
||||
|
||||
#define WEBAUTHN_API_CURRENT_VERSION WEBAUTHN_API_VERSION_4
|
||||
|
|
@ -282,12 +285,65 @@ typedef struct _WEBAUTHN_CREDENTIAL_LIST {
|
|||
} WEBAUTHN_CREDENTIAL_LIST, *PWEBAUTHN_CREDENTIAL_LIST;
|
||||
typedef const WEBAUTHN_CREDENTIAL_LIST *PCWEBAUTHN_CREDENTIAL_LIST;
|
||||
|
||||
//+------------------------------------------------------------------------------------------
|
||||
// Credential Information for WebAuthNGetPlatformCredentialList API
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
#define WEBAUTHN_CREDENTIAL_DETAILS_VERSION_1 1
|
||||
#define WEBAUTHN_CREDENTIAL_DETAILS_CURRENT_VERSION WEBAUTHN_CREDENTIAL_DETAILS_VERSION_1
|
||||
|
||||
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;
|
||||
} 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
|
||||
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,
|
||||
// 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;
|
||||
|
|
@ -545,6 +601,12 @@ typedef const WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS *PCWEBAUTHN_AUTHENT
|
|||
#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_6 6
|
||||
#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_6
|
||||
|
||||
/*
|
||||
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;
|
||||
|
|
@ -565,7 +627,7 @@ typedef struct _WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS {
|
|||
// User Verification Requirement.
|
||||
DWORD dwUserVerificationRequirement;
|
||||
|
||||
// Reserved for future Use
|
||||
// Flags
|
||||
DWORD dwFlags;
|
||||
|
||||
//
|
||||
|
|
@ -879,6 +941,17 @@ WINAPI
|
|||
WebAuthNCancelCurrentOperation(
|
||||
_In_ const GUID* pCancellationId);
|
||||
|
||||
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);
|
||||
|
||||
//
|
||||
// Returns the following Error Names:
|
||||
// L"Success" - S_OK
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Yubico AB. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -427,6 +427,42 @@ pack_cred_ext(WEBAUTHN_EXTENSIONS *out, const fido_cred_ext_t *in)
|
|||
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
|
||||
unpack_assert_authdata(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa)
|
||||
{
|
||||
|
|
@ -499,6 +535,39 @@ unpack_user_id(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
unpack_hmac_secret(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa)
|
||||
{
|
||||
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->cbFirst > SIZE_MAX ||
|
||||
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, (size_t)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)
|
||||
|
|
@ -510,11 +579,6 @@ translate_fido_assert(struct winhello_assert *ctx, const fido_assert_t *assert,
|
|||
fido_log_debug("%s: up %d", __func__, assert->up);
|
||||
return FIDO_ERR_UNSUPPORTED_OPTION;
|
||||
}
|
||||
/* not implemented */
|
||||
if (assert->ext.mask) {
|
||||
fido_log_debug("%s: ext 0x%x", __func__, assert->ext.mask);
|
||||
return FIDO_ERR_UNSUPPORTED_EXTENSION;
|
||||
}
|
||||
if ((ctx->rp_id = to_utf16(assert->rp_id)) == NULL) {
|
||||
fido_log_debug("%s: rp_id", __func__);
|
||||
return FIDO_ERR_INTERNAL;
|
||||
|
|
@ -531,6 +595,10 @@ translate_fido_assert(struct winhello_assert *ctx, const fido_assert_t *assert,
|
|||
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__);
|
||||
|
|
@ -570,6 +638,11 @@ translate_winhello_assert(fido_assert_t *assert, const WEBAUTHN_ASSERTION *wa)
|
|||
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;
|
||||
}
|
||||
|
|
@ -742,6 +815,9 @@ winhello_assert_free(struct winhello_assert *ctx)
|
|||
|
||||
free(ctx->rp_id);
|
||||
free(ctx->opt.CredentialList.pCredentials);
|
||||
if (ctx->opt.pHmacSecretSaltValues != NULL)
|
||||
free(ctx->opt.pHmacSecretSaltValues->pGlobalHmacSalt);
|
||||
free(ctx->opt.pHmacSecretSaltValues);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
|
|
@ -883,7 +959,7 @@ 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", "plat", "clientPin" };
|
||||
const char *o[4] = { "rk", "up", "uv", "plat" };
|
||||
|
||||
(void)dev;
|
||||
|
||||
|
|
|
|||
|
|
@ -65,13 +65,6 @@ add_executable(fido2-token
|
|||
${COMPAT_SOURCES}
|
||||
)
|
||||
|
||||
# set the library to link against
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(_FIDO2_LIBRARY fido2_shared)
|
||||
else()
|
||||
set(_FIDO2_LIBRARY fido2)
|
||||
endif()
|
||||
|
||||
target_link_libraries(fido2-cred ${CRYPTO_LIBRARIES} ${_FIDO2_LIBRARY})
|
||||
target_link_libraries(fido2-assert ${CRYPTO_LIBRARIES} ${_FIDO2_LIBRARY})
|
||||
target_link_libraries(fido2-token ${CRYPTO_LIBRARIES} ${_FIDO2_LIBRARY})
|
||||
|
|
|
|||
|
|
@ -155,6 +155,12 @@ print_maxcredidlen(uint64_t maxcredidlen)
|
|||
printf("maxcredlen: %d\n", (int)maxcredidlen);
|
||||
}
|
||||
|
||||
static void
|
||||
print_maxlargeblob(uint64_t maxlargeblob)
|
||||
{
|
||||
printf("maxlargeblob: %d\n", (int)maxlargeblob);
|
||||
}
|
||||
|
||||
static void
|
||||
print_fwversion(uint64_t fwversion)
|
||||
{
|
||||
|
|
@ -259,6 +265,9 @@ token_info(int argc, char **argv, char *path)
|
|||
/* print maximum length of a credential ID */
|
||||
print_maxcredidlen(fido_cbor_info_maxcredidlen(ci));
|
||||
|
||||
/* print maximum length of serialized largeBlob array */
|
||||
print_maxlargeblob(fido_cbor_info_maxlargeblob(ci));
|
||||
|
||||
/* print firmware version */
|
||||
print_fwversion(fido_cbor_info_fwversion(ci));
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,9 @@ KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1209", ATTRS{idProduct
|
|||
# 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"
|
||||
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ 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
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2021 Yubico AB. All rights reserved.
|
||||
# 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.
|
||||
|
||||
|
|
@ -187,17 +187,15 @@ try {
|
|||
& $CMake --build . --config ${Config} --verbose; ExitOnError
|
||||
& $CMake --build . --config ${Config} --target install --verbose; `
|
||||
ExitOnError
|
||||
# Patch up zlib's resulting names when built with --config Debug.
|
||||
if ("${Config}" -eq "Debug") {
|
||||
if ("${Type}" -eq "Dynamic") {
|
||||
Copy-Item "${PREFIX}/lib/zlibd.lib" `
|
||||
-Destination "${PREFIX}/lib/zlib.lib" -Force
|
||||
Copy-Item "${PREFIX}/bin/zlibd1.dll" `
|
||||
-Destination "${PREFIX}/bin/zlib1.dll" -Force
|
||||
} else {
|
||||
Copy-Item "${PREFIX}/lib/zlibstaticd.lib" `
|
||||
-Destination "${PREFIX}/lib/zlib.lib" -Force
|
||||
}
|
||||
# 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"
|
||||
|
|
@ -225,11 +223,13 @@ try {
|
|||
-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-47.dll", "zlib1.dll" | `
|
||||
"cbor.dll", "crypto-49.dll", "zlib1.dll" | `
|
||||
%{ Copy-Item "${PREFIX}\bin\$_" `
|
||||
-Destination "examples\${Config}" }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
New-Variable -Name 'LIBRESSL_URL' `
|
||||
-Value 'https://fastly.cdn.openbsd.org/pub/OpenBSD/LibreSSL' `
|
||||
-Option Constant
|
||||
New-Variable -Name 'LIBRESSL' -Value 'libressl-3.4.2' -Option Constant
|
||||
New-Variable -Name 'LIBRESSL' -Value 'libressl-3.5.2' -Option Constant
|
||||
|
||||
# libcbor coordinates.
|
||||
New-Variable -Name 'LIBCBOR' -Value 'libcbor-0.9.0' -Option Constant
|
||||
|
|
@ -15,8 +15,8 @@ New-Variable -Name 'LIBCBOR_GIT' -Value 'https://github.com/pjk/libcbor' `
|
|||
-Option Constant
|
||||
|
||||
# zlib coordinates.
|
||||
New-Variable -Name 'ZLIB' -Value 'zlib-1.2.11' -Option Constant
|
||||
New-Variable -Name 'ZLIB_BRANCH' -Value 'v1.2.11' -Option Constant
|
||||
New-Variable -Name 'ZLIB' -Value 'zlib-1.2.12' -Option Constant
|
||||
New-Variable -Name 'ZLIB_BRANCH' -Value 'v1.2.12' -Option Constant
|
||||
New-Variable -Name 'ZLIB_GIT' -Value 'https://github.com/madler/zlib' `
|
||||
-Option Constant
|
||||
|
||||
|
|
|
|||
|
|
@ -66,3 +66,4 @@ Start-Process "${Cygwin}\${Setup}" -Wait -NoNewWindow `
|
|||
$Env:PATH = "${Root}\bin\;" + $Env:PATH
|
||||
cmake "-DCMAKE_BUILD_TYPE=${Config}" -B "build-${Config}"
|
||||
make -C "build-${Config}"
|
||||
make -C "build-${Config}" regress
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2021 Yubico AB. All rights reserved.
|
||||
# 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.
|
||||
|
||||
|
|
@ -7,7 +7,7 @@ $Architectures = @('x64', 'Win32', 'ARM64', 'ARM')
|
|||
$InstallPrefixes = @('Win64', 'Win32', 'ARM64', 'ARM')
|
||||
$Types = @('dynamic', 'static')
|
||||
$Config = 'Release'
|
||||
$LibCrypto = '47'
|
||||
$LibCrypto = '49'
|
||||
$SDK = '143'
|
||||
|
||||
. "$PSScriptRoot\const.ps1"
|
||||
|
|
@ -34,7 +34,7 @@ Function Package-Dynamic(${SRC}, ${DEST}) {
|
|||
Copy-Item "${SRC}\bin\cbor.dll" "${DEST}"
|
||||
Copy-Item "${SRC}\lib\cbor.lib" "${DEST}"
|
||||
Copy-Item "${SRC}\bin\zlib1.dll" "${DEST}"
|
||||
Copy-Item "${SRC}\lib\zlib.lib" "${DEST}"
|
||||
Copy-Item "${SRC}\lib\zlib1.lib" "${DEST}"
|
||||
Copy-Item "${SRC}\bin\crypto-${LibCrypto}.dll" "${DEST}"
|
||||
Copy-Item "${SRC}\lib\crypto-${LibCrypto}.lib" "${DEST}"
|
||||
Copy-Item "${SRC}\bin\fido2.dll" "${DEST}"
|
||||
|
|
@ -43,7 +43,7 @@ Function Package-Dynamic(${SRC}, ${DEST}) {
|
|||
|
||||
Function Package-Static(${SRC}, ${DEST}) {
|
||||
Copy-Item "${SRC}/lib/cbor.lib" "${DEST}"
|
||||
Copy-Item "${SRC}/lib/zlib.lib" "${DEST}"
|
||||
Copy-Item "${SRC}/lib/zlib1.lib" "${DEST}"
|
||||
Copy-Item "${SRC}/lib/crypto-${LibCrypto}.lib" "${DEST}"
|
||||
Copy-Item "${SRC}/lib/fido2_static.lib" "${DEST}/fido2.lib"
|
||||
}
|
||||
|
|
@ -54,19 +54,19 @@ Function Package-PDBs(${SRC}, ${DEST}) {
|
|||
Copy-Item "${SRC}\${LIBCBOR}\src\cbor.dir\${Config}\vc${SDK}.pdb" `
|
||||
"${DEST}\cbor.pdb"
|
||||
Copy-Item "${SRC}\${ZLIB}\zlib.dir\${Config}\vc${SDK}.pdb" `
|
||||
"${DEST}\zlib.pdb"
|
||||
"${DEST}\zlib1.pdb"
|
||||
Copy-Item "${SRC}\src\fido2_shared.dir\${Config}\vc${SDK}.pdb" `
|
||||
"${DEST}\fido2.pdb"
|
||||
}
|
||||
|
||||
Function Package-StaticPDBs(${SRC}, ${DEST}) {
|
||||
Copy-Item "${SRC}\${LIBRESSL}\crypto\Release\crypto-${LibCrypto}.pdb" `
|
||||
Copy-Item "${SRC}\${LIBRESSL}\crypto\crypto_obj.dir\${Config}\crypto_obj.pdb" `
|
||||
"${DEST}\crypto-${LibCrypto}.pdb"
|
||||
Copy-Item "${SRC}\${LIBCBOR}\src\Release\cbor.pdb" `
|
||||
Copy-Item "${SRC}\${LIBCBOR}\src\${Config}\cbor.pdb" `
|
||||
"${DEST}\cbor.pdb"
|
||||
Copy-Item "${SRC}\${ZLIB}\Release\zlibstatic.pdb" `
|
||||
"${DEST}\zlib.pdb"
|
||||
Copy-Item "${SRC}\src\Release\fido2_static.pdb" `
|
||||
Copy-Item "${SRC}\${ZLIB}\${Config}\zlibstatic.pdb" `
|
||||
"${DEST}\zlib1.pdb"
|
||||
Copy-Item "${SRC}\src\${Config}\fido2_static.pdb" `
|
||||
"${DEST}\fido2.pdb"
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue