Skip to content

Commit

Permalink
experimental support for PC/SC
Browse files Browse the repository at this point in the history
allows communication with PC/SC NFC readers on Windows, macOS, and
Linux. disabled by default; enable with cmake -DUSE_PCSC=ON. based
on code contribution from Micro Focus in issue #481; thanks!
fixes #481 and #249.
  • Loading branch information
martelletto committed Feb 24, 2022
1 parent 278f7cc commit 5db60f2
Show file tree
Hide file tree
Showing 6 changed files with 405 additions and 1 deletion.
18 changes: 18 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ 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)

Expand Down Expand Up @@ -237,6 +238,12 @@ else()
add_compile_options(-Wno-unused-parameter)
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)
Expand Down Expand Up @@ -309,6 +316,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"))
Expand Down Expand Up @@ -349,12 +360,14 @@ 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})

Expand Down Expand Up @@ -392,6 +405,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}")
Expand All @@ -400,6 +417,7 @@ 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}")

Expand Down
13 changes: 12 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ endif()
if(NFC_LINUX)
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)
list(APPEND FIDO_SOURCES hid_hidapi.c)
Expand Down Expand Up @@ -93,8 +96,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
Expand All @@ -104,6 +114,7 @@ list(APPEND TARGET_LIBRARIES
${BASE_LIBRARIES}
${HIDAPI_LIBRARIES}
${ZLIB_LIBRARIES}
${PCSC_LIBRARIES}
)

# static library
Expand Down
10 changes: 10 additions & 0 deletions src/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,10 @@ fido_dev_info_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)
if (fido_dev_register_manifest_func(fido_winhello_manifest) != FIDO_OK)
return (FIDO_ERR_INTERNAL);
#endif
#ifdef USE_PCSC
if (fido_dev_register_manifest_func(fido_pcsc_manifest) != FIDO_OK)
return (FIDO_ERR_INTERNAL);
#endif

for (curr = manifest_funcs; curr != NULL; curr = curr->next) {
curr_olen = 0;
Expand Down Expand Up @@ -351,6 +355,12 @@ fido_dev_open(fido_dev_t *dev, const char *path)
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

return (fido_dev_open_wait(dev, path, &ms));
}
Expand Down
12 changes: 12 additions & 0 deletions src/extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,16 @@ 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 *);
int fido_winhello_open(fido_dev_t *);
Expand Down Expand Up @@ -222,6 +232,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 *);
int fido_pcsc_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 *);
Expand Down Expand Up @@ -252,6 +263,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" */
Expand Down
2 changes: 2 additions & 0 deletions src/nfc.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ fido_nfc_rx(fido_dev_t *d, uint8_t cmd, unsigned char *buf, size_t count, int ms
}
}

#ifdef USE_NFC
bool
fido_is_nfc(const char *path)
{
Expand Down Expand Up @@ -316,3 +317,4 @@ fido_dev_set_nfc(fido_dev_t *d)

return 0;
}
#endif /* USE_NFC */
Loading

0 comments on commit 5db60f2

Please sign in to comment.