Skip to content

Commit

Permalink
Merge pull request #492 from Yubico/5.7-bio-piv_pub
Browse files Browse the repository at this point in the history
Add support for biometric verify and match policy
  • Loading branch information
aveenismail authored Jul 24, 2024
2 parents 54ee39d + aa776cb commit e8c7837
Show file tree
Hide file tree
Showing 10 changed files with 374 additions and 84 deletions.
171 changes: 168 additions & 3 deletions .github/workflows/windows_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on: [push]

jobs:

souce_build:
source_build:
name: Build dist with Linux
runs-on: ubuntu-latest
steps:
Expand All @@ -31,7 +31,7 @@ jobs:

win2019_x86:
name: Windows Server 2019 - x86
needs: souce_build
needs: source_build
runs-on: windows-2019
steps:
- name: Download source from job_1
Expand Down Expand Up @@ -107,7 +107,7 @@ jobs:
win2019_x64:
name: Windows Server 2019 - x64
needs: souce_build
needs: source_build
runs-on: windows-2019

steps:
Expand Down Expand Up @@ -181,3 +181,168 @@ jobs:
cmake --build . -v
$env:Path +=";C:/vcpkg/packages/check_x64-windows/bin;C:/vcpkg/packages/openssl_x64-windows/bin;$env:GITHUB_WORKSPACE\yubico-piv-tool-src\yubico-piv-tool-\build\lib\Debug;$env:GITHUB_WORKSPACE\yubico-piv-tool-src\yubico-piv-tool-\build\ykcs11\Debug"
ctest.exe -C Debug
build:
name: Build and Test on Windows
needs: source_build
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: windows-2019
arch: x86
arch_cmake: Win32
- os: windows-2019
arch: x64
arch_cmake: x64
- os: windows-2022
arch: x86
arch_cmake: Win32
- os: windows-2022
arch: x64
arch_cmake: x64

steps:
- name: Download source from source work
uses: actions/download-artifact@v1
with:
name: yubico-piv-tool-src

- name: Extract source
run: |
Set-PSDebug -Trace 1
cd yubico-piv-tool-src
tar xf yubico-piv-tool-.tar.gz
- name: install prerequisites
env:
ARCH: ${{ matrix.arch }}
run: |
Set-PSDebug -Trace 1
vcpkg install openssl:$env:ARCH-windows
vcpkg install getopt:$env:ARCH-windows
vcpkg install check:$env:ARCH-windows
vcpkg install zlib:$env:ARCH-windows
- name: build
env:
ARCH_CMAKE: ${{ matrix.arch_cmake }}
ARCH: ${{ matrix.arch }}
run: |
Set-PSDebug -Trace 1
$env:Path ="C:\vcpkg\packages\openssl_$env:ARCH-windows;$env:Path"
$env:include ="C:\vcpkg\packages\openssl_$env:ARCH-windows/include;$env:include"
cd yubico-piv-tool-src/yubico-piv-tool-
mkdir build; cd build
cmake -A $env:ARCH_CMAKE -DVERBOSE_CMAKE=ON -DBACKEND=winscard -DGETOPT_LIB_DIR=C:/vcpkg/packages/getopt-win32_$env:ARCH-windows/lib -DGETOPT_INCLUDE_DIR=C:/vcpkg/packages/getopt-win32_$env:ARCH-windows/include -DCHECK_PATH=C:/vcpkg/packages/check_$env:ARCH-windows ..
cmake --build . -v
$env:Path +=";C:/vcpkg/packages/check_$env:ARCH-windows/bin;C:/vcpkg/packages/openssl_$env:ARCH-windows/bin;$env:GITHUB_WORKSPACE\yubico-piv-tool-src\yubico-piv-tool-\build\lib\Debug;$env:GITHUB_WORKSPACE\yubico-piv-tool-src\yubico-piv-tool-\build\ykcs11\Debug"
ctest.exe -C Debug
- name: Build with YKCS11_DBG is set
env:
ARCH_CMAKE: ${{ matrix.arch_cmake }}
ARCH: ${{ matrix.arch }}
run: |
Set-PSDebug -Trace 1
$env:Path ="C:\vcpkg\packages\openssl_$env:ARCH-windows;$env:Path"
$env:include ="C:\vcpkg\packages\openssl_$env:ARCH-windows/include;$env:include"
cd yubico-piv-tool-src/yubico-piv-tool-
rm -r build; mkdir build; cd build
cmake -A $env:ARCH_CMAKE -DVERBOSE_CMAKE=ON -DBACKEND=winscard -DGETOPT_LIB_DIR=C:/vcpkg/packages/getopt-win32_$env:ARCH-windows/lib -DGETOPT_INCLUDE_DIR=C:/vcpkg/packages/getopt-win32_$env:ARCH-windows/include -DCHECK_PATH=C:/vcpkg/packages/check_$env:ARCH-windows -DYKCS11_DBG=3 ..
cmake --build . -v
$env:Path +=";C:/vcpkg/packages/check_$env:ARCH-windows/bin;C:/vcpkg/packages/openssl_$env:ARCH-windows/bin;$env:GITHUB_WORKSPACE\yubico-piv-tool-src\yubico-piv-tool-\build\lib\Debug;$env:GITHUB_WORKSPACE\yubico-piv-tool-src\yubico-piv-tool-\build\ykcs11\Debug"
ctest.exe -C Debug
- name: Build only library (no CLI and no ykcs11)
env:
ARCH_CMAKE: ${{ matrix.arch_cmake }}
ARCH: ${{ matrix.arch }}
run: |
Set-PSDebug -Trace 1
$env:Path ="C:\vcpkg\packages\openssl_$env:ARCH-windows;$env:Path"
$env:include ="C:\vcpkg\packages\openssl_$env:ARCH-windows/include;$env:include"
cd yubico-piv-tool-src/yubico-piv-tool-
rm -r build; mkdir build; cd build
cmake -A $env:ARCH_CMAKE -DVERBOSE_CMAKE=ON -DBACKEND=winscard -DGETOPT_LIB_DIR=C:/vcpkg/packages/getopt-win32_$env:ARCH-windows/lib -DGETOPT_INCLUDE_DIR=C:/vcpkg/packages/getopt-win32_$env:ARCH-windows/include -DCHECK_PATH=C:/vcpkg/packages/check_$env:ARCH-windows -DBUILD_ONLY_LIB=ON ..
cmake --build . -v
$env:Path +=";C:/vcpkg/packages/check_$env:ARCH-windows/bin;C:/vcpkg/packages/openssl_$env:ARCH-windows/bin;$env:GITHUB_WORKSPACE\yubico-piv-tool-src\yubico-piv-tool-\build\lib\Debug;$env:GITHUB_WORKSPACE\yubico-piv-tool-src\yubico-piv-tool-\build\ykcs11\Debug"
ctest.exe -C Debug
- name: Build only dynamic libaries
env:
ARCH_CMAKE: ${{ matrix.arch_cmake }}
ARCH: ${{ matrix.arch }}
run: |
Set-PSDebug -Trace 1
$env:Path ="C:\vcpkg\packages\openssl_$env:ARCH-windows;$env:Path"
$env:include ="C:\vcpkg\packages\openssl_$env:ARCH-windows/include;$env:include"
cd yubico-piv-tool-src/yubico-piv-tool-
rm -r build; mkdir build; cd build
cmake -A $env:ARCH_CMAKE -DVERBOSE_CMAKE=ON -DBACKEND=winscard -DGETOPT_LIB_DIR=C:/vcpkg/packages/getopt-win32_$env:ARCH-windows/lib -DGETOPT_INCLUDE_DIR=C:/vcpkg/packages/getopt-win32_$env:ARCH-windows/include -DCHECK_PATH=C:/vcpkg/packages/check_$env:ARCH-windows -DBUILD_STATIC_LIB=OFF ..
cmake --build . -v
$env:Path +=";C:/vcpkg/packages/check_$env:ARCH-windows/bin;C:/vcpkg/packages/openssl_$env:ARCH-windows/bin;$env:GITHUB_WORKSPACE\yubico-piv-tool-src\yubico-piv-tool-\build\lib\Debug;$env:GITHUB_WORKSPACE\yubico-piv-tool-src\yubico-piv-tool-\build\ykcs11\Debug"
ctest.exe -C Debug
build_no_zlib:
name: Build and Test on Windows where zlib is not installed
needs: source_build
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: windows-2019
arch: x86
arch_cmake: Win32
- os: windows-2019
arch: x64
arch_cmake: x64
- os: windows-2022
arch: x86
arch_cmake: Win32
- os: windows-2022
arch: x64
arch_cmake: x64

steps:
- name: Download source from source work
uses: actions/download-artifact@v1
with:
name: yubico-piv-tool-src

- name: Extract source
run: |
Set-PSDebug -Trace 1
cd yubico-piv-tool-src
tar xf yubico-piv-tool-.tar.gz
- name: install prerequisites
env:
ARCH: ${{ matrix.arch }}
run: |
Set-PSDebug -Trace 1
vcpkg install openssl:$env:ARCH-windows
vcpkg install getopt:$env:ARCH-windows
vcpkg install check:$env:ARCH-windows
- name: build
env:
ARCH_CMAKE: ${{ matrix.arch_cmake }}
ARCH: ${{ matrix.arch }}
run: |
Set-PSDebug -Trace 1
$env:Path ="C:\vcpkg\packages\openssl_$env:ARCH-windows;$env:Path"
$env:include ="C:\vcpkg\packages\openssl_$env:ARCH-windows/include;$env:include"
cd yubico-piv-tool-src/yubico-piv-tool-
mkdir build; cd build
cmake -A $env:ARCH_CMAKE -DVERBOSE_CMAKE=ON -DBACKEND=winscard -DENABLE_CERT_COMPRESS=OFF -DGETOPT_LIB_DIR=C:/vcpkg/packages/getopt-win32_$env:ARCH-windows/lib -DGETOPT_INCLUDE_DIR=C:/vcpkg/packages/getopt-win32_$env:ARCH-windows/include -DCHECK_PATH=C:/vcpkg/packages/check_$env:ARCH-windows ..
cmake --build . -v
$env:Path +=";C:/vcpkg/packages/check_$env:ARCH-windows/bin;C:/vcpkg/packages/openssl_$env:ARCH-windows/bin;$env:GITHUB_WORKSPACE\yubico-piv-tool-src\yubico-piv-tool-\build\lib\Debug;$env:GITHUB_WORKSPACE\yubico-piv-tool-src\yubico-piv-tool-\build\ykcs11\Debug"
ctest.exe -C Debug
4 changes: 4 additions & 0 deletions common/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,10 @@ unsigned char get_pin_policy(enum enum_pin_policy policy) {
return YKPIV_PINPOLICY_ONCE;
case pin_policy_arg_always:
return YKPIV_PINPOLICY_ALWAYS;
case pin_policy_arg_matchonce:
return YKPIV_PINPOLICY_MATCH_ONCE;
case pin_policy_arg_matchalways:
return YKPIV_PINPOLICY_MATCH_ALWAYS;
case pin_policy__NULL:
default:
return YKPIV_PINPOLICY_DEFAULT;
Expand Down
70 changes: 44 additions & 26 deletions lib/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,26 @@
#include <stdlib.h>
#include <string.h>

/*
** Definitions
*/
/*
** Definitions
*/

/* crypt defines */
/* crypt defines */

#ifdef _WIN32

#define strcasecmp _stricmp

struct _cipher_key {
BCRYPT_KEY_HANDLE hKey;
BCRYPT_ALG_HANDLE hAlg;
BCRYPT_KEY_HANDLE hKey;
};

#else

struct _cipher_key {
const EVP_CIPHER *cipher;
EVP_CIPHER_CTX *ctx;
const EVP_CIPHER* cipher;
EVP_CIPHER_CTX* ctx;
unsigned char key[EVP_MAX_KEY_LENGTH];
};

Expand All @@ -80,45 +81,54 @@ struct _cipher_key {

#define _ENV_PREFIX "YUBIKEY_PIV_"

char *_strip_ws(char *sz);
setting_bool_t _get_bool_config(const char *sz_setting);
setting_bool_t _get_bool_env(const char *sz_setting);
char* _strip_ws(char* sz);
setting_bool_t _get_bool_config(const char* sz_setting);
setting_bool_t _get_bool_env(const char* sz_setting);

/*
** Methods
*/

#ifdef _WIN32

static BCRYPT_ALG_HANDLE bcrypt_algo(unsigned char algo) {
switch (algo) {
case YKPIV_ALGO_3DES:
return BCRYPT_3DES_ECB_ALG_HANDLE;
case YKPIV_ALGO_AES128:
static LPCWSTR bcrypt_algo(unsigned char algo) {
switch (algo) {
case YKPIV_ALGO_3DES:
return BCRYPT_3DES_ALGORITHM;
case YKPIV_ALGO_AES128:
case YKPIV_ALGO_AES192:
case YKPIV_ALGO_AES256:
return BCRYPT_AES_ECB_ALG_HANDLE;
return BCRYPT_AES_ALGORITHM;
default:
return NULL;
}
}
}

cipher_rc cipher_import_key(unsigned char algo, const unsigned char *keyraw, uint32_t keyrawlen, cipher_key *key) {
cipher_rc cipher_import_key(unsigned char algo, const unsigned char* keyraw, uint32_t keyrawlen, cipher_key* key) {
*key = calloc(1, sizeof(**key));
if (!*key) {
if (!*key) {
return CIPHER_MEMORY_ERROR;
}
if(!BCRYPT_SUCCESS(BCryptGenerateSymmetricKey(bcrypt_algo(algo), &(*key)->hKey, NULL, 0, (PUCHAR)keyraw, keyrawlen, 0))) {
return CIPHER_INVALID_PARAMETER;
}
return 0;
if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&(*key)->hAlg, bcrypt_algo(algo), NULL, 0))) {
return CIPHER_INVALID_PARAMETER;
}
if (!BCRYPT_SUCCESS(BCryptSetProperty((*key)->hAlg, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0))) {
return CIPHER_INVALID_PARAMETER;
}
if (!BCRYPT_SUCCESS(BCryptGenerateSymmetricKey((*key)->hAlg, &(*key)->hKey, NULL, 0, (PUCHAR)keyraw, keyrawlen, 0))) {
return CIPHER_INVALID_PARAMETER;
}
return 0;
}

cipher_rc cipher_destroy_key(cipher_key key) {
if (key == NULL) {
if (key == NULL) {
return CIPHER_MEMORY_ERROR;
}
if(!BCRYPT_SUCCESS(BCryptDestroyKey(key->hKey))) {
if (!BCRYPT_SUCCESS(BCryptDestroyKey(key->hKey))) {
return CIPHER_INVALID_PARAMETER;
}
if (!BCRYPT_SUCCESS(BCryptCloseAlgorithmProvider(key->hAlg, 0))) {
return CIPHER_INVALID_PARAMETER;
}
free(key);
Expand Down Expand Up @@ -331,7 +341,15 @@ prng_rc _ykpiv_prng_generate(unsigned char *buffer, const size_t cb_req) {
prng_rc rc = PRNG_OK;

#ifdef _WIN32
if (!BCRYPT_SUCCESS(BCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, buffer, (ULONG)cb_req, 0))) {
BCRYPT_ALG_HANDLE hAlg = 0;

if (BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM, NULL, 0))) {
if (!BCRYPT_SUCCESS(BCryptGenRandom(hAlg, buffer, (ULONG)cb_req, 0))) {
rc = PRNG_GENERAL_ERROR;
}
BCryptCloseAlgorithmProvider(hAlg, 0);
}
else {
rc = PRNG_GENERAL_ERROR;
}
#else
Expand Down
2 changes: 2 additions & 0 deletions lib/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ ykpiv_rc _ykpiv_transfer_data(
ykpiv_rc ykpiv_auth_getchallenge(ykpiv_state *state, ykpiv_metadata *metadata, uint8_t *challenge, unsigned long *challenge_len);
ykpiv_rc ykpiv_auth_verifyresponse(ykpiv_state *state, ykpiv_metadata *metadata, uint8_t *response, unsigned long response_len);
ykpiv_rc ykpiv_auth_deauthenticate(ykpiv_state *state);
ykpiv_rc ykpiv_auth_get_verified(ykpiv_state *state);
ykpiv_rc ykpiv_auth_verify(ykpiv_state* state, uint8_t* pin, size_t* p_pin_len, int *tries, bool force_select, bool bio, bool verify_spin);

typedef enum _setting_source_t {
SETTING_SOURCE_USER,
Expand Down
Loading

0 comments on commit e8c7837

Please sign in to comment.