Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/build-nativeshims.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,24 @@ jobs:
} else {
& ./build-windows.ps1
}
- name: Verify no VC++ Redistributable dependency
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
cd Yubico.NativeShims
set FAILED=0
for %%a in (win-x64 win-x86 win-arm64) do (
echo Checking %%a\Yubico.NativeShims.dll for CRT dependencies...
dumpbin /imports %%a\Yubico.NativeShims.dll | findstr /i "VCRUNTIME api-ms-win-crt" && (
echo FAIL: %%a\Yubico.NativeShims.dll has VC++ Redistributable dependency
set FAILED=1
) || (
echo PASS: %%a\Yubico.NativeShims.dll has no CRT dependencies
)
)
if %FAILED%==1 exit /b 1
echo All Windows builds verified: no VC++ Redistributable required
exit /b 0
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: win-x64
Expand Down
111 changes: 74 additions & 37 deletions Yubico.NativeShims/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
cmake_minimum_required(VERSION 3.13)
cmake_minimum_required(VERSION 3.15)

# Set default version if not provided via command line
#
# Project version
#
if(NOT DEFINED PROJECT_VERSION)
set(PROJECT_VERSION "1.14.0")
endif()

# Set VCPKG manifest version to match project version
set(VCPKG_MANIFEST_VERSION ${PROJECT_VERSION})

project(Yubico.NativeShims VERSION ${PROJECT_VERSION})
include(CheckCCompilerFlag)

# =============================================================================
# Platform configuration
#
# Each platform sets:
# PLATFORM_* — boolean flag for conditional logic later
# BACKEND — which smart card API to use (winscard/pcsc/macscard)
# exports file — controls which symbols are visible in the shared library
# hardening — platform-appropriate security compiler/linker flags
# =============================================================================

if (APPLE OR UNIX)

# --- macOS / Linux: platform identity and symbol exports ---

if (APPLE)
set(PLATFORM_MACOS true)
set(BACKEND "macscard")
Expand All @@ -20,23 +33,31 @@ if (APPLE OR UNIX)
find_package(PkgConfig REQUIRED)
set(PLATFORM_LINUX true)
set(BACKEND "pcsc")
# RELRO + NOW = full read-only relocations (exploit mitigation)
add_link_options("-Wl,-z,relro,-z,now,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/exports.gnu")
endif()

# --- macOS / Linux: security hardening (GCC/Clang) ---

if (CMAKE_C_COMPILER_ID STREQUAL "Clang" OR
CMAKE_C_COMPILER_ID STREQUAL "AppleClang" OR
CMAKE_C_COMPILER_ID STREQUAL "GNU")

# Warnings — treat all as errors
add_compile_options(-Wall -Wextra -Werror)
add_compile_options(-Wformat -Wformat-nonliteral -Wformat-security)
add_compile_options(-Wshadow)
add_compile_options(-Wcast-qual)
add_compile_options(-Wbad-function-cast)
add_compile_options(-Wshadow -Wcast-qual -Wbad-function-cast)
add_compile_options(-pedantic -pedantic-errors)

# Position-independent code (required for shared libraries)
add_compile_options(-fpic)
add_compile_options(-O2)
add_compile_definitions (-D_FORTIFY_SOURCE=2)
add_link_options(-fpic)

# Optimization and runtime hardening
add_compile_options(-O2)
add_compile_definitions(-D_FORTIFY_SOURCE=2) # Buffer overflow detection in libc calls

# Stack protection — prefer -all variant, fall back to basic
check_c_compiler_flag("-fstack-protector-all" HAVE_STACK_PROTECTOR_ALL)
if (HAVE_STACK_PROTECTOR_ALL)
message(STATUS "-fstack-protector-all support detected")
Expand All @@ -55,31 +76,42 @@ if (APPLE OR UNIX)
elseif()
message(WARNING "No compatible compiler found for setting additional security compiler flags.")
endif()

elseif(WIN32)

# --- Windows: platform identity ---

set(PLATFORM_WINDOWS true)
set(BACKEND "winscard")
add_link_options("/guard:cf" "/def:${CMAKE_CURRENT_SOURCE_DIR}/exports.msvc")
add_compile_options("/GS" "/Gs")
endif()

# Security hardening
add_link_options("/guard:cf") # Control Flow Guard
add_compile_options("/GS" "/Gs") # Buffer security check + stack probe

#
# Library dependencies
#
# Symbol exports
add_link_options("/def:${CMAKE_CURRENT_SOURCE_DIR}/exports.msvc")

# Static CRT to avoid VC++ Redistributable dependency (see #391)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

endif()

# =============================================================================
# Dependencies
# =============================================================================

include(${CMAKE_SOURCE_DIR}/cmake/pcscd.cmake)
find_pcscd()
find_package(OpenSSL REQUIRED)

#
# Build definition
#
# =============================================================================
# Build target
# =============================================================================

add_library(Yubico.NativeShims SHARED)

# Enable IPO/LTO (Link time optimization) if supported
# Optional IPO. Do not use IPO if it's not supported by compiler.
# Link-time optimization (cross-file inlining, dead code elimination)
include(CheckIPOSupported)

check_ipo_supported(RESULT result OUTPUT output)
if(result)
message(INFO "IPO is enabled.")
Expand All @@ -88,7 +120,7 @@ else()
message(WARNING "IPO is not supported: ${output}")
endif()

# Pre-processor
# Generate header from template (substitutes @VERSION@ etc.)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/Yubico.NativeShims.h.in
${CMAKE_CURRENT_SOURCE_DIR}/Yubico.NativeShims.h
Expand All @@ -101,33 +133,38 @@ target_include_directories(
"${PROJECT_BINARY_DIR}"
)

# Source
# =============================================================================
# Sources
# =============================================================================

target_sources(
Yubico.NativeShims
PRIVATE
pcsc.c
ssl.bignum.c
ssl.ecgroup.c
ssl.ecpoint.c
ssl.gcmevp.c
ssl.cmac.c
pcsc.c # Smart card (PC/SC) shim
ssl.bignum.c # OpenSSL BIGNUM operations
ssl.ecgroup.c # OpenSSL EC group operations
ssl.ecpoint.c # OpenSSL EC point operations
ssl.gcmevp.c # OpenSSL AES-GCM via EVP interface
ssl.cmac.c # OpenSSL CMAC operations
)

# Add Windows resource file for version info
if(WIN32)
target_sources(
Yubico.NativeShims
PRIVATE
Yubico.NativeShims.rc
Yubico.NativeShims.rc # Windows version info resource
)
endif()

# Linker
# =============================================================================
# Link libraries
# =============================================================================

target_link_libraries(
Yubico.NativeShims
${PCSC_LIBRARIES}
${PCSC_WIN_LIBS}
${PCSC_MACOSX_LIBS}
${PCSC_CUSTOM_LIBS}
OpenSSL::Crypto
${PCSC_LIBRARIES} # Linux: libpcsclite
${PCSC_WIN_LIBS} # Windows: winscard.lib
${PCSC_MACOSX_LIBS} # macOS: PCSC.framework
${PCSC_CUSTOM_LIBS} # Cross-compilation overrides
OpenSSL::Crypto # libcrypto (static via vcpkg on Windows)
)
2 changes: 2 additions & 0 deletions Yubico.NativeShims/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Yubico.NativeShims is a cross-platform C library designed to bridge the gap in n
- Install Visual Studio with C++ workload and ARM64 build tools.
- Use "x64 Native tools command prompt" to navigate and run `./build-windows.ps1`.

> **Note:** The Windows build statically links the MSVC C runtime (`/MT`) so that the resulting DLL does not require the Visual C++ Redistributable to be installed on end-user systems.

### macOS Build

- Requires XCode
Expand Down
Loading