diff --git a/0001-feature-ukey-The-UKey-device-is-adapted.patch b/0001-feature-ukey-The-UKey-device-is-adapted.patch new file mode 100644 index 0000000..5388aad --- /dev/null +++ b/0001-feature-ukey-The-UKey-device-is-adapted.patch @@ -0,0 +1,3101 @@ +From 919d46a3371e4770ca13ac25e5ce3fd996710d9e Mon Sep 17 00:00:00 2001 +From: luoqing +Date: Thu, 13 Apr 2023 15:41:16 +0800 +Subject: [PATCH] feature(ukey):The UKey device is adapted +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +- 完成UKey设备适配 +--- + data/drivers.conf | 6 +- + include/auth-enum.h | 4 +- + include/kiran-auth-device-i.h | 7 + + include/third-party-device.h | 5 +- + include/ukey-skf.h | 325 +++++++++++ + src/CMakeLists.txt | 9 +- + src/auth-device-manager.cpp | 45 +- + src/auth-device-manager.h | 24 +- + src/context/context-factory.cpp | 25 +- + src/context/context-factory.h | 11 +- + src/context/finger-vein/fv-sd-context.cpp | 1 + + src/context/ukey/ukey-ft-context.cpp | 57 ++ + src/context/ukey/ukey-ft-context.h | 27 + + src/device/auth-device.cpp | 228 ++++---- + src/device/auth-device.h | 65 +-- + src/device/bio-device.cpp | 104 ++++ + src/device/bio-device.h | 47 ++ + src/device/finger-vein/fv-sd-device.cpp | 28 +- + src/device/finger-vein/fv-sd-device.h | 10 +- + src/device/fingerprint/fp-device.cpp | 2 +- + src/device/fingerprint/fp-device.h | 4 +- + src/device/fingerprint/fp-zk-device.cpp | 22 +- + src/device/fingerprint/fp-zk-device.h | 7 +- + src/device/ukey/ukey-ft-device.cpp | 400 ++++++++++++++ + src/device/ukey/ukey-ft-device.h | 68 +++ + src/driver/ukey/ukey-skf-driver.cpp | 516 ++++++++++++++++++ + src/driver/ukey/ukey-skf-driver.h | 62 +++ + .../kiran-authentication-devices.zh_CN.ts | 82 ++- + 28 files changed, 1916 insertions(+), 275 deletions(-) + create mode 100644 include/ukey-skf.h + create mode 100644 src/context/ukey/ukey-ft-context.cpp + create mode 100644 src/context/ukey/ukey-ft-context.h + create mode 100644 src/device/bio-device.cpp + create mode 100644 src/device/bio-device.h + create mode 100644 src/device/ukey/ukey-ft-device.cpp + create mode 100644 src/device/ukey/ukey-ft-device.h + create mode 100644 src/driver/ukey/ukey-skf-driver.cpp + create mode 100644 src/driver/ukey/ukey-skf-driver.h + +diff --git a/data/drivers.conf b/data/drivers.conf +index e2be3f1..ef3f9f8 100644 +--- a/data/drivers.conf ++++ b/data/drivers.conf +@@ -8,4 +8,8 @@ Type=0 + + [sdfv] + Enable=true +-Type=2 +\ No newline at end of file ++Type=2 ++ ++[es_3000gm] ++Enable=true ++Type=5 +\ No newline at end of file +diff --git a/include/auth-enum.h b/include/auth-enum.h +index 19f98d1..a29e9b5 100644 +--- a/include/auth-enum.h ++++ b/include/auth-enum.h +@@ -93,7 +93,9 @@ enum IdentifyProcess + // 匹配 + IDENTIFY_PROCESS_MACTCH, + // 不匹配 +- IDENTIFY_PROCESS_NO_MATCH ++ IDENTIFY_PROCESS_NO_MATCH, ++ // PIN码不正确 ++ IDENTIFY_PROCESS_PIN_INCORRECT + }; + + } // namespace Kiran +\ No newline at end of file +diff --git a/include/kiran-auth-device-i.h b/include/kiran-auth-device-i.h +index 8422eaf..89e4000 100644 +--- a/include/kiran-auth-device-i.h ++++ b/include/kiran-auth-device-i.h +@@ -26,6 +26,11 @@ extern "C" + #define GENERAL_AUTH_DEVICE_DBUS_OBJECT_PATH "/com/kylinsec/Kiran/AuthDevice/Device" + #define GENERAL_AUTH_DEVICE_DBUS_INTERFACE_NAME "com.kylinsec.Kiran.AuthDevice.Device" + ++#define AUTH_DEVICE_JSON_KEY_UKEY "ukey" ++#define AUTH_DEVICE_JSON_KEY_PIN "pin" ++#define AUTH_DEVICE_JSON_KEY_REBINDING "rebinding" ++#define AUTH_DEVICE_JSON_KEY_FEATURE_IDS "feature_ids" ++ + // 录入结果 + enum EnrollResult + { +@@ -37,6 +42,8 @@ extern "C" + ENROLL_RESULT_PASS, + // 因为扫描质量或者用户扫描过程中发生的问题引起 + ENROLL_RESULT_RETRY, ++ // UKey已经存在绑定关系 ++ ENROLL_RESULT_UKEY_EXIST_BINDING + }; + + // 识别结果 +diff --git a/include/third-party-device.h b/include/third-party-device.h +index d06a4a2..2b118d3 100644 +--- a/include/third-party-device.h ++++ b/include/third-party-device.h +@@ -19,7 +19,7 @@ namespace Kiran + { + #define ZK_ID_VENDOR "1b55" + #define SD_ID_VENDOR "05e3" +- ++#define FT_ID_VENDOR "096e" + + static const struct ThirdPartyDeviceSupported + { +@@ -35,7 +35,8 @@ static const struct ThirdPartyDeviceSupported + QString description; + }ThirdPartyDeviceSupportedTable[] = { + {DEVICE_TYPE_FingerPrint,"1b55","0120","","ZK"}, +- {DEVICE_TYPE_FingerVein,"05e3","0608","","SD"} ++ {DEVICE_TYPE_FingerVein,"05e3","0608","","SD"}, ++ {DEVICE_TYPE_UKey,"096e","0309","","FT"} + }; + + } +\ No newline at end of file +diff --git a/include/ukey-skf.h b/include/ukey-skf.h +new file mode 100644 +index 0000000..d1b6a6f +--- /dev/null ++++ b/include/ukey-skf.h +@@ -0,0 +1,325 @@ ++/** ++ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd. ++ * kiran-biometrics is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ * ++ * Author: luoqing ++ */ ++ ++#pragma once ++#include ++#include ++ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif ++ ++typedef int8_t INT8; ++typedef int16_t INT16; ++typedef int32_t INT32; ++typedef unsigned char UINT8; ++typedef uint16_t UINT16; ++typedef uint32_t UINT32; ++typedef long BOOL; ++ ++typedef UINT8 BYTE; ++typedef UINT8 CHAR; ++typedef INT16 SHORT; ++typedef UINT16 USHORT; ++typedef INT32 LONG; ++typedef UINT32 ULONG; ++typedef UINT32 UINT; ++typedef UINT16 WORD; ++typedef UINT32 DWORD; ++typedef UINT32 FLAGS; ++typedef CHAR *LPSTR; ++typedef void *HANDLE; ++typedef HANDLE DEVHANDLE; ++typedef HANDLE HAPPLICATION; ++typedef HANDLE HCONTAINER; ++ ++#define MAX_RSA_MODULUS_LEN 256 ++#define MAX_RSA_EXPONENT_LEN 4 ++#define ECC_MAX_XCOORDINATE_BITS_LEN 512 ++#define ECC_MAX_YCOORDINATE_BITS_LEN 512 ++#define ECC_MAX_MODULUS_BITS_LEN 512 ++ ++#define MAX_IV_LEN 32 ++#define MAX_FILE_NAME_SIZE 32 ++#define MAX_FILE_CONTAINER_NAME_SIZE 64 ++ ++/*Permission type*/ ++#define SECURE_NEVER_ACCOUNT 0x00000000 ++#define SECURE_ADM_ACCOUNT 0x00000001 ++#define SECURE_USER_ACCOUNT 0x00000010 ++#define SECURE_ANYONE_ACCOUNT 0x000000FF ++ ++#ifndef FALSE ++#define FALSE 0x00000000 ++#endif ++ ++#ifndef TRUE ++#define TRUE 0x00000001 ++#endif ++ ++#ifndef ADMIN_TYPE ++#define ADMIN_TYPE 0 ++#endif ++ ++#ifndef USER_TYPE ++#define USER_TYPE 1 ++#endif ++ ++/* public key usage */ ++#define SGD_PK_SIGN 0x0100 ++#define SGD_PK_DH 0x0200 ++#define SGD_PK_ENC 0x0400 ++ ++/* public key types */ ++#define SGD_RSA 0x00010000 ++#define SGD_RSA_SIGN (SGD_RSA | SGD_PK_SIGN) ++#define SGD_RSA_ENC (SGD_RSA | SGD_PK_ENC) ++#define SGD_SM2 0x00020000 ++#define SGD_SM2_1 (SGD_SM2 | SGD_PK_SIGN) ++#define SGD_SM2_2 (SGD_SM2 | SGD_PK_DH) ++#define SGD_SM2_3 (SGD_SM2 | SGD_PK_ENC) ++ ++/* hash */ ++#define SGD_SM3 0x00000001 ++#define SGD_SHA1 0x00000002 ++#define SGD_SHA256 0x00000004 ++#define SGD_HASH_FROM 0x00000008 ++#define SGD_HASH_TO 0x000000FF ++ ++/* signatue schemes */ ++#define SGD_SM3_RSA (SGD_SM3|SGD_RSA) ++#define SGD_SHA1_RSA (SGD_SHA1|SGD_RSA) ++#define SGD_SHA256_RSA (SGD_SHA256|SGD_RSA) ++#define SGD_SM3_SM2 (SGD_SM3|SGD_SM2) ++#define SGD_SIG_FROM 0x00040000 ++#define SGD_SIG_TO 0x800000FF ++ ++#pragma pack(1) ++ typedef struct Struct_Version ++ { ++ BYTE major; ++ BYTE minor; ++ } VERSION; ++ ++ typedef struct Struct_DEVINFO ++ { ++ VERSION Version; ++ CHAR Manufacturer[64]; ++ CHAR Issuer[64]; ++ CHAR Label[32]; ++ CHAR SerialNumber[32]; ++ VERSION HWVersion; ++ VERSION FirmwareVersion; ++ ULONG AlgSymCap; ++ ULONG AlgAsymCap; ++ ULONG AlgHashCap; ++ ULONG DevAuthAlgId; ++ ULONG TotalSpace; ++ ULONG FreeSpace; ++ ULONG MaxECCBufferSize; ++ ULONG MaxBufferSize; ++ BYTE Reserved[64]; ++ } DEVINFO, *PDEVINFO; ++ ++ typedef struct Struct_RSAPUBLICKEYBLOB ++ { ++ ULONG AlgID; ++ ULONG BitLen; ++ BYTE Modulus[MAX_RSA_MODULUS_LEN]; ++ BYTE PublicExponent[MAX_RSA_EXPONENT_LEN]; ++ } RSAPUBLICKEYBLOB, *PRSAPUBLICKEYBLOB; ++ ++ typedef struct Struct_RSAPRIVATEKEYBLOB ++ { ++ ULONG AlgID; ++ ULONG BitLen; ++ BYTE Modulus[MAX_RSA_MODULUS_LEN]; ++ BYTE PublicExponent[MAX_RSA_EXPONENT_LEN]; ++ BYTE PrivateExponent[MAX_RSA_MODULUS_LEN]; ++ BYTE Prime1[MAX_RSA_MODULUS_LEN / 2]; ++ BYTE Prime2[MAX_RSA_MODULUS_LEN / 2]; ++ BYTE Prime1Exponent[MAX_RSA_MODULUS_LEN / 2]; ++ BYTE Prime2Exponent[MAX_RSA_MODULUS_LEN / 2]; ++ BYTE Coefficient[MAX_RSA_MODULUS_LEN / 2]; ++ } RSAPRIVATEKEYBLOB, *PRSAPRIVATEKEYBLOB; ++ ++ typedef struct Struct_ECCPUBLICKEYBLOB ++ { ++ ULONG BitLen; ++ BYTE XCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN / 8]; ++ BYTE YCoordinate[ECC_MAX_YCOORDINATE_BITS_LEN / 8]; ++ } ECCPUBLICKEYBLOB, *PECCPUBLICKEYBLOB; ++ ++ typedef struct Struct_ECCPRIVATEKEYBLOB ++ { ++ ULONG BitLen; ++ BYTE PrivateKey[ECC_MAX_MODULUS_BITS_LEN / 8]; ++ } ECCPRIVATEKEYBLOB, *PECCPRIVATEKEYBLOB; ++ ++ typedef struct Struct_ECCCIPHERBLOB ++ { ++ BYTE XCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN / 8]; ++ BYTE YCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN / 8]; ++ BYTE HASH[32]; ++ ULONG CipherLen; ++ BYTE Cipher[1]; ++ } ECCCIPHERBLOB, *PECCCIPHERBLOB; ++ ++ typedef struct Struct_ECCSIGNATUREBLOB ++ { ++ BYTE r[ECC_MAX_XCOORDINATE_BITS_LEN / 8]; ++ BYTE s[ECC_MAX_XCOORDINATE_BITS_LEN / 8]; ++ } ECCSIGNATUREBLOB, *PECCSIGNATUREBLOB; ++ ++ typedef struct Struct_BLOCKCIPHERPARAM ++ { ++ BYTE IV[MAX_IV_LEN]; ++ ULONG IVLen; ++ ULONG PaddingType; ++ ULONG FeedBitLen; ++ } BLOCKCIPHERPARAM, *PBLOCKCIPHERPARAM; ++ ++ typedef struct SKF_ENVELOPEDKEYBLOB ++ { ++ ULONG Version; ++ ULONG ulSymmAlgID; ++ ULONG ulBits; ++ BYTE cbEncryptedPriKey[64]; ++ ECCPUBLICKEYBLOB PubKey; ++ ECCCIPHERBLOB ECCCipherBlob; ++ } ENVELOPEDKEYBLOB, *PENVELOPEDKEYBLOB; ++ ++ typedef struct Struct_FILEATTRIBUTE ++ { ++ CHAR FileName[MAX_FILE_NAME_SIZE]; ++ ULONG FileSize; ++ ULONG ReadRights; ++ ULONG WriteRights; ++ } FILEATTRIBUTE, *PFILEATTRIBUTE; ++#pragma pack() ++ ++#define SAR_OK 0x00000000 ++#define SAR_FAIL 0x0A000001 ++#define SAR_UNKNOWNERR 0x0A000002 ++#define SAR_NOTSUPPORTYETERR 0x0A000003 ++#define SAR_FILEERR 0x0A000004 ++#define SAR_INVALIDHANDLEERR 0x0A000005 ++#define SAR_INVALIDPARAMERR 0x0A000006 ++#define SAR_READFILEERR 0x0A000007 ++#define SAR_WRITEFILEERR 0x0A000008 ++#define SAR_NAMELENERR 0x0A000009 ++#define SAR_KEYUSAGEERR 0x0A00000A ++#define SAR_MODULUSLENERR 0x0A00000B ++#define SAR_NOTINITIALIZEERR 0x0A00000C ++#define SAR_OBJERR 0x0A00000D ++#define SAR_MEMORYERR 0x0A00000E ++#define SAR_TIMEOUTERR 0x0A00000F ++#define SAR_INDATALENERR 0x0A000010 ++#define SAR_INDATAERR 0x0A000011 ++#define SAR_GENRANDERR 0x0A000012 ++#define SAR_HASHOBJERR 0x0A000013 ++#define SAR_HASHERR 0x0A000014 ++#define SAR_GENRSAKEYERR 0x0A000015 ++#define SAR_RSAMODULUSLENERR 0x0A000016 ++#define SAR_CSPIMPRTPUBKEYERR 0x0A000017 ++#define SAR_RSAENCERR 0x0A000018 ++#define SAR_RSADECERR 0x0A000019 ++#define SAR_HASHNOTEQUALERR 0x0A00001A ++#define SAR_KEYNOTFOUNTERR 0x0A00001B ++#define SAR_CERTNOTFOUNTERR 0x0A00001C ++#define SAR_NOTEXPORTERR 0x0A00001D ++#define SAR_DECRYPTPADERR 0x0A00001E ++#define SAR_MACLENERR 0x0A00001F ++#define SAR_BUFFER_TOO_SMALL 0x0A000020 ++#define SAR_KEYINFOTYPEERR 0x0A000021 ++#define SAR_NOT_EVENTERR 0x0A000022 ++#define SAR_DEVICE_REMOVED 0x0A000023 ++#define SAR_PIN_INCORRECT 0x0A000024 ++#define SAR_PIN_LOCKED 0x0A000025 ++#define SAR_PIN_INVALID 0x0A000026 ++#define SAR_PIN_LEN_RANGE 0x0A000027 ++#define SAR_USER_ALREADY_LOGGED_IN 0x0A000028 ++#define SAR_USER_PIN_NOT_INITIALIZED 0x0A000029 ++#define SAR_USER_TYPE_INVALID 0x0A00002A ++#define SAR_APPLICATION_NAME_INVALID 0x0A00002B ++#define SAR_APPLICATION_EXISTS 0x0A00002C ++#define SAR_USER_NOT_LOGGED_IN 0x0A00002D ++#define SAR_APPLICATION_NOT_EXISTS 0x0A00002E ++#define SAR_FILE_ALREADY_EXIST 0x0A00002F ++#define SAR_NO_ROOM 0x0A000030 ++#define SAR_FILE_NOT_EXIST 0x0A000031 ++#define SAR_REACH_MAX_CONTAINER_COUNT 0x0A000032 ++ ++typedef struct { ++ ULONG err; ++ QString reason; ++} SKF_ERR_REASON; ++ ++static SKF_ERR_REASON skf_errors[] = { ++ { SAR_OK, "success" }, ++ { SAR_FAIL, "failure" }, ++ { SAR_UNKNOWNERR, "unknown error" }, ++ { SAR_NOTSUPPORTYETERR, "operation not supported" }, ++ { SAR_FILEERR, "file error" }, ++ { SAR_INVALIDHANDLEERR, "invalid handle" }, ++ { SAR_INVALIDPARAMERR, "invalid parameter" }, ++ { SAR_READFILEERR, "read file failure" }, ++ { SAR_WRITEFILEERR, "write file failure" }, ++ { SAR_NAMELENERR, "invalid name length" }, ++ { SAR_KEYUSAGEERR, "invalid key usage" }, ++ { SAR_MODULUSLENERR, "invalid modulus length" }, ++ { SAR_NOTINITIALIZEERR, "not initialized" }, ++ { SAR_OBJERR, "invalid object" }, ++ { SAR_MEMORYERR, "memory error" }, ++ { SAR_TIMEOUTERR, "timeout" }, ++ { SAR_INDATALENERR, "invalid input length" }, ++ { SAR_INDATAERR, "invalid input value" }, ++ { SAR_GENRANDERR, "random generation failed" }, ++ { SAR_HASHOBJERR, "invalid digest handle" }, ++ { SAR_HASHERR, "digest error" }, ++ { SAR_GENRSAKEYERR, "rsa key generation failure" }, ++ { SAR_RSAMODULUSLENERR, "invalid rsa modulus length" }, ++ { SAR_CSPIMPRTPUBKEYERR, "csp import public key error" }, ++ { SAR_RSAENCERR, "rsa encryption failure" }, ++ { SAR_RSADECERR, "rsa decryption failure" }, ++ { SAR_HASHNOTEQUALERR, "hash not equal" }, ++ { SAR_KEYNOTFOUNTERR, "key not found" }, ++ { SAR_CERTNOTFOUNTERR, "certificate not found" }, ++ { SAR_NOTEXPORTERR, "export failed" }, ++ { SAR_DECRYPTPADERR, "decrypt invalid padding" }, ++ { SAR_MACLENERR, "invalid mac length" }, ++ { SAR_BUFFER_TOO_SMALL, "buffer too small" }, ++ { SAR_KEYINFOTYPEERR, "invalid key info type" }, ++ { SAR_NOT_EVENTERR, "no event" }, ++ { SAR_DEVICE_REMOVED, "device removed" }, ++ { SAR_PIN_INCORRECT, "pin incorrect" }, ++ { SAR_PIN_LOCKED, "pin locked" }, ++ { SAR_PIN_INVALID, "invalid pin" }, ++ { SAR_PIN_LEN_RANGE, "invalid pin length" }, ++ { SAR_USER_ALREADY_LOGGED_IN, "user already logged in" }, ++ { SAR_USER_PIN_NOT_INITIALIZED, "user pin not initialized" }, ++ { SAR_USER_TYPE_INVALID, "invalid user type" }, ++ { SAR_APPLICATION_NAME_INVALID, "invalid application name" }, ++ { SAR_APPLICATION_EXISTS, "application already exist" }, ++ { SAR_USER_NOT_LOGGED_IN, "user not logged in" }, ++ { SAR_APPLICATION_NOT_EXISTS, "application not exist" }, ++ { SAR_FILE_ALREADY_EXIST, "file already exist" }, ++ { SAR_NO_ROOM, "no space" }, ++ { SAR_FILE_NOT_EXIST, "file not exist" }, ++}; ++ ++#ifdef __cplusplus ++} ++#endif +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index 39c8dc5..cac6cb4 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -37,11 +37,14 @@ qt_add_dbus_adaptor( + set(DEVICE_SDK ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}-sdk) + + set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) +-set(CMAKE_INSTALL_RPATH ${DEVICE_SDK}/finger-vein/sd:${DEVICE_SDK}/fingerprint/zk) ++set(CMAKE_INSTALL_RPATH ${DEVICE_SDK}/finger-vein/sd:${DEVICE_SDK}/fingerprint/zk:${DEVICE_SDK}/ukey/ft) + + + set(TS_FILES "${PROJECT_SOURCE_DIR}/translations/${PROJECT_NAME}.zh_CN.ts") +-qt_create_translation(QM_FILES ${CMAKE_CURRENT_SOURCE_DIR} ${TS_FILES}) ++qt_create_translation(QM_FILES ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${TS_FILES} ++ ) + + add_executable(${PROJECT_NAME} + ${SRC_H_FILES} +@@ -58,7 +61,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC + ${KLOG_QT5_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ) +- ++ + target_link_libraries(${PROJECT_NAME} + ${KLOG_QT5_LIBRARIES} + ${LIBUDEV_LIBRARIES} +diff --git a/src/auth-device-manager.cpp b/src/auth-device-manager.cpp +index 984d3c1..a0ac795 100644 +--- a/src/auth-device-manager.cpp ++++ b/src/auth-device-manager.cpp +@@ -18,9 +18,9 @@ + #include + #include + #include +-#include "device/auth-device.h" + #include "auth_device_manager_adaptor.h" + #include "context/context-factory.h" ++#include "device/auth-device.h" + #include "feature-db.h" + #include "kiran-auth-device-i.h" + #include "polkit-proxy.h" +@@ -148,7 +148,7 @@ void AuthDeviceManager::onRemove(const QDBusMessage& message, const QString& fea + { + bool result = FeatureDB::getInstance()->deleteFeature(feature_id); + KLOG_DEBUG() << "deleteFeature:" << feature_id +- << "result" << result; ++ << "exec:" << result; + auto replyMessage = message.createReply(); + QDBusConnection::systemBus().send(replyMessage); + } +@@ -192,10 +192,9 @@ CHECK_AUTH_WITH_2ARGS(AuthDeviceManager, SetEnableDriver, onSetEnableDriver, AUT + + void AuthDeviceManager::init() + { +- m_dbusAdaptor = new AuthDeviceManagerAdaptor(this); +- m_contextFactory = ContextFactory::instance(); +- m_timer = new QTimer(this); +- connect(m_timer, &QTimer::timeout, this, &AuthDeviceManager::handleDeviceReCreate); ++ m_dbusAdaptor = QSharedPointer(new AuthDeviceManagerAdaptor(this)); ++ m_contextFactory = QSharedPointer(ContextFactory::instance()); ++ connect(&m_timer, &QTimer::timeout, this, &AuthDeviceManager::handleDeviceReCreate); + + QDBusConnection dbusConnection = QDBusConnection::systemBus(); + if (!dbusConnection.registerService(AUTH_DEVICE_DBUS_NAME)) +@@ -214,14 +213,14 @@ void AuthDeviceManager::init() + KLOG_ERROR() << "Can't register object:" << dbusConnection.lastError(); + } + +- m_udev = udev_new(); ++ m_udev = QSharedPointer (udev_new()); + if (!m_udev) + { + KLOG_ERROR() << "new udev error"; + } + +- initDeviceMonitor(m_udev); +- auto usbInfoList = enumerateDevices(m_udev); ++ initDeviceMonitor(m_udev.data()); ++ auto usbInfoList = enumerateDevices(m_udev.data()); + // 枚举设备后,生成设备对象 + Q_FOREACH (auto deviceInfo, usbInfoList) + { +@@ -243,16 +242,16 @@ void AuthDeviceManager::init() + void AuthDeviceManager::initDeviceMonitor(struct udev* udev) + { + // 创建一个新的monitor +- m_monitor = udev_monitor_new_from_netlink(udev, "udev"); ++ m_monitor = QSharedPointer (udev_monitor_new_from_netlink(udev, "udev")); + // 增加一个udev事件过滤器 +- udev_monitor_filter_add_match_subsystem_devtype(m_monitor, "usb", nullptr); ++ udev_monitor_filter_add_match_subsystem_devtype(m_monitor.data(), "usb", nullptr); + // 启动监控 +- udev_monitor_enable_receiving(m_monitor); ++ udev_monitor_enable_receiving(m_monitor.data()); + // 获取该监控的文件描述符,fd就代表了这个监控 +- m_fd = udev_monitor_get_fd(m_monitor); ++ m_fd = udev_monitor_get_fd(m_monitor.data()); + +- m_socketNotifierRead = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); +- connect(m_socketNotifierRead, &QSocketNotifier::activated, this, &AuthDeviceManager::handleSocketNotifierRead); ++ m_socketNotifierRead = QSharedPointer(new QSocketNotifier(m_fd, QSocketNotifier::Read, this)); ++ connect(m_socketNotifierRead.data(), &QSocketNotifier::activated, this, &AuthDeviceManager::handleSocketNotifierRead); + } + + void AuthDeviceManager::handleSocketNotifierRead(int socket) +@@ -274,7 +273,7 @@ void AuthDeviceManager::handleSocketNotifierRead(int socket) + return; + + // 获取产生事件的设备映射 +- struct udev_device* dev = udev_monitor_receive_device(m_monitor); ++ struct udev_device* dev = udev_monitor_receive_device(m_monitor.data()); + if (!dev) + return; + +@@ -317,11 +316,11 @@ void AuthDeviceManager::handleSocketNotifierRead(int socket) + QList AuthDeviceManager::enumerateDevices(struct udev* udev) + { + // 创建一个枚举器用于扫描已连接的设备 +- struct udev_enumerate* enumerate = udev_enumerate_new(udev); ++ struct udev_enumerate* enumerate = udev_enumerate_new(udev); + udev_enumerate_add_match_subsystem(enumerate, SUBSYSTEM); + udev_enumerate_scan_devices(enumerate); + // 返回一个存储了设备所有属性信息的链表 +- struct udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate); ++ struct udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate); + struct udev_list_entry* entry; + + QList usbInfoList; +@@ -329,7 +328,7 @@ QList AuthDeviceManager::enumerateDevices(struct udev* udev) + { + const char* path = udev_list_entry_get_name(entry); + // 创建一个udev设备的映射 +- struct udev_device* dev = udev_device_new_from_syspath(udev, path); ++ struct udev_device* dev = udev_device_new_from_syspath(udev, path); + DeviceInfo usbInfo; + usbInfo.idVendor = udev_device_get_sysattr_value(dev, "idVendor"); + usbInfo.idProduct = udev_device_get_sysattr_value(dev, "idProduct"); +@@ -419,16 +418,16 @@ void AuthDeviceManager::handleDeviceCreateFail(DeviceInfo deviceInfo) + m_retreyCreateDeviceMap.insert(deviceInfo, 0); + if (m_retreyCreateDeviceMap.count() != 0) + { +- if (!m_timer->isActive()) ++ if (!m_timer.isActive()) + { +- m_timer->start(1000); ++ m_timer.start(1000); + } + } + } + + void AuthDeviceManager::handleDeviceDeleted() + { +- QList newUsbInfoList = enumerateDevices(m_udev); ++ QList newUsbInfoList = enumerateDevices(m_udev.data()); + QStringList newBusList; + Q_FOREACH (auto newUsbInfo, newUsbInfoList) + { +@@ -468,7 +467,7 @@ void AuthDeviceManager::handleDeviceReCreate() + { + if (m_retreyCreateDeviceMap.count() == 0) + { +- m_timer->stop(); ++ m_timer.stop(); + } + else + { +diff --git a/src/auth-device-manager.h b/src/auth-device-manager.h +index fcf56bd..0993a55 100644 +--- a/src/auth-device-manager.h ++++ b/src/auth-device-manager.h +@@ -15,12 +15,13 @@ + #pragma once + + #include ++#include + #include + #include ++#include + #include + #include + #include "auth-enum.h" +-#include + + class AuthDeviceManagerAdaptor; + +@@ -43,7 +44,7 @@ public: + + public Q_SLOTS: + QString GetDevices(); +- QString GetDevicesByType(int device_type); ++ QString GetDevicesByType(int device_type); + QDBusObjectPath GetDevice(const QString &device_id); + QStringList GetAllFeatureIDs(); + QString GetDriversByType(int device_type); +@@ -64,8 +65,8 @@ private: + void processDevice(struct udev_device *dev); + void deviceSimpleInfo(struct udev_device *dev); + +- void onRemove(const QDBusMessage &message,const QString &feature_id); +- void onSetEnableDriver(const QDBusMessage &message,const QString &driver_name, bool enable); ++ void onRemove(const QDBusMessage &message, const QString &feature_id); ++ void onSetEnableDriver(const QDBusMessage &message, const QString &driver_name, bool enable); + + Q_SIGNALS: + void DeviceAdded(int device_type, const QString &device_id); +@@ -73,19 +74,18 @@ Q_SIGNALS: + + private: + static AuthDeviceManager *m_instance; +- struct udev *m_udev; +- struct udev_monitor *m_monitor; ++ QSharedPointer m_udev; ++ QSharedPointer m_monitor; + + int m_fd; +- AuthDeviceManagerAdaptor *m_dbusAdaptor; +- QSocketNotifier *m_socketNotifierRead; ++ QSharedPointer m_dbusAdaptor; ++ QSharedPointer m_socketNotifierRead; + // 总线 -- AuthDevice对象对应 + QMap m_deviceMap; +- ContextFactory *m_contextFactory; +- +- QTimer *m_timer; ++ QSharedPointer m_contextFactory; ++ QTimer m_timer; + + // 设备信息-重试次数 +- QMap m_retreyCreateDeviceMap; ++ QMap m_retreyCreateDeviceMap; + }; + } // namespace Kiran +diff --git a/src/context/context-factory.cpp b/src/context/context-factory.cpp +index 82c9c6b..f489d8f 100644 +--- a/src/context/context-factory.cpp ++++ b/src/context/context-factory.cpp +@@ -15,11 +15,12 @@ + #include "context-factory.h" + #include + #include ++#include "finger-vein/fv-sd-context.h" + #include "fingerprint/fp-builtin-context.h" + #include "fingerprint/fp-zk-context.h" +-#include "finger-vein/fv-sd-context.h" + #include "kiran-auth-device-i.h" + #include "third-party-device.h" ++#include "ukey/ukey-ft-context.h" + + namespace Kiran + { +@@ -47,9 +48,10 @@ ContextFactory::ContextFactory(QObject* parent) + + void ContextFactory::init() + { +- m_fpZKContext = new FPZKContext(); +- m_fpBuiltInContext = new FPBuiltInContext(); +- m_fvSDContext = new FVSDContext(); ++ m_fpZKContext = QSharedPointer(new FPZKContext()); ++ m_fpBuiltInContext = QSharedPointer(new FPBuiltInContext()); ++ m_fvSDContext = QSharedPointer(new FVSDContext()); ++ m_ukeyFTContext = QSharedPointer(new UKeyFTContext()); + } + + AuthDevice* ContextFactory::createDevice(const QString& idVendor, const QString& idProduct) +@@ -72,6 +74,9 @@ AuthDevice* ContextFactory::createDevice(const QString& idVendor, const QString& + case DEVICE_TYPE_FingerVein: + device = createFingerVeinDevice(idVendor, idProduct); + break; ++ case DEVICE_TYPE_UKey: ++ device = createUKeyDevice(idVendor, idProduct); ++ break; + default: + break; + } +@@ -120,6 +125,18 @@ AuthDevice* ContextFactory::createFingerVeinDevice(const QString& idVendor, cons + return nullptr; + } + ++AuthDevice* ContextFactory::createUKeyDevice(const QString& idVendor, const QString& idProduct) ++{ ++ if (idVendor == FT_ID_VENDOR) ++ { ++ return m_ukeyFTContext->createDevice(idVendor, idProduct); ++ } ++ else ++ { ++ return nullptr; ++ }; ++} ++ + Context* ContextFactory::CreateContext() + { + return nullptr; +diff --git a/src/context/context-factory.h b/src/context/context-factory.h +index f2d510a..5d06839 100644 +--- a/src/context/context-factory.h ++++ b/src/context/context-factory.h +@@ -15,13 +15,14 @@ + + #include + #include "context.h" +- ++#include + + namespace Kiran + { + class FPZKContext; + class FPBuiltInContext; + class FVSDContext; ++class UKeyFTContext; + + class ContextFactory : public QObject + { +@@ -43,11 +44,13 @@ private: + void init(); + AuthDevice* createFingerPrintDevice(const QString& idVendor, const QString& idProduct); + AuthDevice* createFingerVeinDevice(const QString& idVendor, const QString& idProduct); ++ AuthDevice* createUKeyDevice(const QString& idVendor, const QString& idProduct); + + private: + QStringList m_idVendorList; +- FPZKContext* m_fpZKContext; +- FPBuiltInContext* m_fpBuiltInContext; +- FVSDContext* m_fvSDContext; ++ QSharedPointer m_fpZKContext; ++ QSharedPointer m_fpBuiltInContext; ++ QSharedPointer m_fvSDContext; ++ QSharedPointer m_ukeyFTContext; + }; + } // namespace Kiran +diff --git a/src/context/finger-vein/fv-sd-context.cpp b/src/context/finger-vein/fv-sd-context.cpp +index a2e9dc7..d898564 100644 +--- a/src/context/finger-vein/fv-sd-context.cpp ++++ b/src/context/finger-vein/fv-sd-context.cpp +@@ -24,6 +24,7 @@ FVSDContext::FVSDContext(QObject* parent) + { + } + ++//TODO:createDevice 流程类似,考虑优化,减少重复代码 + // fp-zk-context 需要管理多个so,可以生成不同 so的设备 + AuthDevice* FVSDContext::createDevice(const QString& idVendor, const QString& idProduct) + { +diff --git a/src/context/ukey/ukey-ft-context.cpp b/src/context/ukey/ukey-ft-context.cpp +new file mode 100644 +index 0000000..40e9df3 +--- /dev/null ++++ b/src/context/ukey/ukey-ft-context.cpp +@@ -0,0 +1,57 @@ ++/** ++ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd. ++ * kiran-biometrics is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ * ++ * Author: luoqing ++ */ ++ ++#include "ukey-ft-context.h" ++#include ++#include "device/ukey/ukey-ft-device.h" ++#include "utils.h" ++ ++namespace Kiran ++{ ++UKeyFTContext::UKeyFTContext(QObject* parent) ++ : Context{parent} ++{ ++} ++ ++AuthDevice* UKeyFTContext::createDevice(const QString& idVendor, const QString& idProduct) ++{ ++ auto ftDevice = new UKeyFTDevice(); ++ if (!Utils::driverEnabled(ftDevice->deviceDriver())) ++ { ++ KLOG_INFO() << QString("driver %1 is disabled! device %2:%3 can't be used") ++ .arg(ftDevice->deviceDriver()) ++ .arg(idVendor) ++ .arg(idProduct); ++ return nullptr; ++ } ++ if (ftDevice->init()) ++ { ++ QString deviceName = Utils::getDeviceName(idVendor, idProduct); ++ if (deviceName.isEmpty()) ++ { ++ deviceName = "Feitian Technologies"; ++ } ++ ftDevice->setDeviceName(deviceName); ++ ftDevice->setDeviceInfo(idVendor, idProduct); ++ m_deviceMap.insert(ftDevice->deviceID(), ftDevice); ++ return ftDevice; ++ } ++ else ++ { ++ KLOG_ERROR() << QString("device %1:%2 init failed!").arg(idVendor).arg(idProduct); ++ ftDevice->deleteLater(); ++ return nullptr; ++ } ++} ++} // namespace Kiran +diff --git a/src/context/ukey/ukey-ft-context.h b/src/context/ukey/ukey-ft-context.h +new file mode 100644 +index 0000000..48bd40d +--- /dev/null ++++ b/src/context/ukey/ukey-ft-context.h +@@ -0,0 +1,27 @@ ++/** ++ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd. ++ * kiran-biometrics is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ * ++ * Author: luoqing ++ */ ++#pragma once ++#include "context/context.h" ++ ++namespace Kiran ++{ ++class AuthDevice; ++class UKeyFTContext : public Context ++{ ++public: ++ explicit UKeyFTContext(QObject *parent = nullptr); ++ AuthDevice* createDevice(const QString& idVendor, const QString& idProduct) override; ++}; ++ ++} // namespace Kiran +diff --git a/src/device/auth-device.cpp b/src/device/auth-device.cpp +index 0b890ec..d906fd1 100644 +--- a/src/device/auth-device.cpp ++++ b/src/device/auth-device.cpp +@@ -42,7 +42,7 @@ bool AuthDevice::init() + { + if (initDevice()) + { +- m_dbusAdaptor = new AuthDeviceAdaptor(this); ++ m_dbusAdaptor = QSharedPointer(new AuthDeviceAdaptor(this)); + m_deviceID = QUuid::createUuid().toString(QUuid::WithoutBraces); + m_deviceStatus = DEVICE_STATUS_IDLE; + registerDBusObject(); +@@ -71,17 +71,17 @@ void AuthDevice::registerDBusObject() + + void AuthDevice::initFutureWatcher() + { +- m_futureWatcher = new QFutureWatcher(this); +- connect(m_futureWatcher, &QFutureWatcher::finished, this, &AuthDevice::handleAcquiredFeature); ++ m_futureWatcher = QSharedPointer>(new QFutureWatcher(this)); ++ connect(m_futureWatcher.data(), &QFutureWatcher::finished, this, &AuthDevice::handleAcquiredFeature); + connect(this, &AuthDevice::retry, this, &AuthDevice::handleRetry); + } + + void AuthDevice::initServiceWatcher() + { +- m_serviceWatcher = new QDBusServiceWatcher(this); ++ m_serviceWatcher = QSharedPointer(new QDBusServiceWatcher(this)); + this->m_serviceWatcher->setConnection(QDBusConnection::systemBus()); + this->m_serviceWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration); +- connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, &AuthDevice::onNameLost); ++ connect(m_serviceWatcher.data(), &QDBusServiceWatcher::serviceUnregistered, this, &AuthDevice::onNameLost); + } + + void AuthDevice::onNameLost(const QString& serviceName) +@@ -110,6 +110,15 @@ void AuthDevice::clearWatchedServices() + } + } + ++DeviceInfo AuthDevice::deviceInfo() ++{ ++ DeviceInfo deviceInfo; ++ deviceInfo.idVendor = m_idVendor; ++ deviceInfo.idProduct = m_idProduct; ++ deviceInfo.busPath = ""; ++ return deviceInfo; ++} ++ + void AuthDevice::setDeviceType(DeviceType deviceType) + { + m_deviceType = deviceType; +@@ -153,8 +162,36 @@ void AuthDevice::onEnrollStart(const QDBusMessage& dbusMessage, const QString& e + KLOG_DEBUG() << message; + return; + } ++ QJsonValue ukeyValue = Utils::getValueFromJsonString(extraInfo, AUTH_DEVICE_JSON_KEY_UKEY); ++ if (ukeyValue.isNull()) ++ { ++ onBioEnrollStart(dbusMessage); ++ } ++ else ++ { ++ onUKeyEnrollStart(dbusMessage, ukeyValue); ++ } ++} + +- // 获取当前保存的指纹模板,判断是否达到最大指纹数目 ++void AuthDevice::onEnrollStop(const QDBusMessage& dbusMessage) ++{ ++ if (deviceStatus() == DEVICE_STATUS_DOING_ENROLL) ++ { ++ acquireFeatureStop(); ++ m_enrollTemplates.clear(); ++ setDeviceStatus(DEVICE_STATUS_IDLE); ++ clearWatchedServices(); ++ KLOG_DEBUG() << "EnrollStop"; ++ } ++ ++ auto replyMessage = dbusMessage.createReply(); ++ QDBusConnection::systemBus().send(replyMessage); ++} ++ ++void AuthDevice::onBioEnrollStart(const QDBusMessage& dbusMessage) ++{ ++ QString message; ++ // 获取当前保存的特征模板,判断是否达到最大数目 + QByteArrayList saveList = FeatureDB::getInstance()->getFeatures(m_idVendor, m_idProduct); + if (saveList.count() == TEMPLATE_MAX_NUMBER) + { +@@ -163,32 +200,35 @@ void AuthDevice::onEnrollStart(const QDBusMessage& dbusMessage, const QString& e + KLOG_ERROR() << message; + return; + } +- + setDeviceStatus(DEVICE_STATUS_DOING_ENROLL); +- m_doEnroll = true; +- + auto future = QtConcurrent::run(this, &AuthDevice::acquireFeature); + m_futureWatcher->setFuture(future); + m_serviceWatcher->addWatchedService(dbusMessage.service()); +- + auto replyMessage = dbusMessage.createReply(); + QDBusConnection::systemBus().send(replyMessage); + } + +-void AuthDevice::onEnrollStop(const QDBusMessage& dbusMessage) ++void AuthDevice::onUKeyEnrollStart(const QDBusMessage& dbusMessage, QJsonValue ukeyValue) + { +- if (deviceStatus() == DEVICE_STATUS_DOING_ENROLL) ++ QString message; ++ auto jsonObject = ukeyValue.toObject(); ++ m_pin = jsonObject.value(AUTH_DEVICE_JSON_KEY_PIN).toString(); ++ bool rebinding = jsonObject.value(AUTH_DEVICE_JSON_KEY_REBINDING).toBool(); ++ if (m_pin.isEmpty()) + { +- acquireFeatureStop(); +- m_doEnroll = false; +- m_enrollTemplates.clear(); +- setDeviceStatus(DEVICE_STATUS_IDLE); +- clearWatchedServices(); +- KLOG_DEBUG() << "EnrollStop"; ++ message = tr("The pin code cannot be empty!"); ++ Q_EMIT m_dbusAdaptor->EnrollStatus("", 0, ENROLL_RESULT_FAIL, message); ++ KLOG_ERROR() << message; ++ return; ++ } ++ else ++ { ++ setDeviceStatus(DEVICE_STATUS_DOING_ENROLL); ++ doingUKeyEnrollStart(m_pin, rebinding); ++ m_serviceWatcher->addWatchedService(dbusMessage.service()); ++ auto replyMessage = dbusMessage.createReply(); ++ QDBusConnection::systemBus().send(replyMessage); + } +- +- auto replyMessage = dbusMessage.createReply(); +- QDBusConnection::systemBus().send(replyMessage); + } + + void AuthDevice::onIdentifyStart(const QDBusMessage& dbusMessage, const QString& value) +@@ -202,10 +242,7 @@ void AuthDevice::onIdentifyStart(const QDBusMessage& dbusMessage, const QString& + return; + } + +- setDeviceStatus(DEVICE_STATUS_DOING_IDENTIFY); +- m_doIdentify = true; +- +- QJsonArray jsonArray = Utils::getValueFromJsonString(value, "feature_ids").toArray(); ++ QJsonArray jsonArray = Utils::getValueFromJsonString(value, AUTH_DEVICE_JSON_KEY_FEATURE_IDS).toArray(); + if (!jsonArray.isEmpty()) + { + QVariantList varList = jsonArray.toVariantList(); +@@ -214,12 +251,16 @@ void AuthDevice::onIdentifyStart(const QDBusMessage& dbusMessage, const QString& + m_identifyIDs << var.toString(); + } + } +- auto future = QtConcurrent::run(this, &AuthDevice::acquireFeature); +- m_futureWatcher->setFuture(future); +- m_serviceWatcher->addWatchedService(dbusMessage.service()); + +- auto replyMessage = dbusMessage.createReply(); +- QDBusConnection::systemBus().send(replyMessage); ++ QJsonValue ukeyValue = Utils::getValueFromJsonString(value, AUTH_DEVICE_JSON_KEY_UKEY); ++ if (ukeyValue.isUndefined()) ++ { ++ onBioIdentifyStart(dbusMessage); ++ } ++ else ++ { ++ onUKeyIdentifyStart(dbusMessage, ukeyValue); ++ } + } + + void AuthDevice::onIdentifyStop(const QDBusMessage& message) +@@ -227,7 +268,6 @@ void AuthDevice::onIdentifyStop(const QDBusMessage& message) + if (deviceStatus() == DEVICE_STATUS_DOING_IDENTIFY) + { + acquireFeatureStop(); +- m_doIdentify = false; + m_identifyIDs.clear(); + setDeviceStatus(DEVICE_STATUS_IDLE); + clearWatchedServices(); +@@ -237,90 +277,49 @@ void AuthDevice::onIdentifyStop(const QDBusMessage& message) + QDBusConnection::systemBus().send(replyMessage); + } + +-CHECK_AUTH_WITH_1ARGS(AuthDevice, EnrollStart, onEnrollStart, AUTH_USER_ADMIN, const QString&) +-CHECK_AUTH_WITH_1ARGS(AuthDevice, IdentifyStart, onIdentifyStart, AUTH_USER_ADMIN, const QString&) +-CHECK_AUTH(AuthDevice, EnrollStop, onEnrollStop, AUTH_USER_ADMIN) +-CHECK_AUTH(AuthDevice, IdentifyStop, onIdentifyStop, AUTH_USER_ADMIN) +- +-QStringList AuthDevice::GetFeatureIDList() ++void AuthDevice::onBioIdentifyStart(const QDBusMessage& dbusMessage) + { +- QStringList featureIDs = FeatureDB::getInstance()->getFeatureIDs(m_idVendor, m_idProduct); +- return featureIDs; ++ setDeviceStatus(DEVICE_STATUS_DOING_IDENTIFY); ++ auto future = QtConcurrent::run(this, &AuthDevice::acquireFeature); ++ m_futureWatcher->setFuture(future); ++ ++ m_serviceWatcher->addWatchedService(dbusMessage.service()); ++ auto replyMessage = dbusMessage.createReply(); ++ QDBusConnection::systemBus().send(replyMessage); + } + +-void AuthDevice::doingEnrollProcess(QByteArray feature) ++void AuthDevice::onUKeyIdentifyStart(const QDBusMessage& dbusMessage, QJsonValue ukeyValue) + { +- if (!m_doEnroll) +- { +- return; +- } + QString message; +- if (feature.isEmpty()) +- { +- acquireFeatureFail(); +- return; +- } ++ auto jsonObject = ukeyValue.toObject(); ++ m_pin = jsonObject.value(AUTH_DEVICE_JSON_KEY_PIN).toString(); + +- int templatesCount = enrollTemplatesFromCache().count(); +- if (templatesCount == 0) ++ if (m_pin.isEmpty()) + { +- // 第一个指纹模板入录时,检查该指纹是否录入过 +- QString featureID = isFeatureEnrolled(feature); +- if (featureID.isEmpty()) +- { +- saveEnrollTemplateToCache(feature); +- enrollProcessRetry(); +- } +- else +- { +- notifyEnrollProcess(ENROLL_PROCESS_REPEATED_ENROLL, featureID); +- internalStopEnroll(); +- } +- } +- else if (templatesCount < needTemplatesCountForEnroll()) +- { +- // 判断录入时是否录的是同一根手指 +- int matchResult = templateMatch(m_enrollTemplates.value(0), feature); +- if (matchResult == GENERAL_RESULT_OK) +- { +- saveEnrollTemplateToCache(feature); +- } +- else +- { +- notifyEnrollProcess(ENROLL_PROCESS_INCONSISTENT_FEATURE); +- } +- enrollProcessRetry(); +- } +- else if (enrollTemplatesFromCache().count() == needTemplatesCountForEnroll()) +- { +- enrollTemplateMerge(); +- } +-} +- +-void AuthDevice::doingIdentifyProcess(QByteArray feature) +-{ +- if (!m_doIdentify) +- { +- KLOG_DEBUG() << "device busy"; +- return; +- } +- if (feature.isEmpty()) +- { +- acquireFeatureFail(); ++ message = tr("The pin code cannot be empty!"); ++ Q_EMIT m_dbusAdaptor->IdentifyStatus("", IDENTIFY_RESULT_NOT_MATCH, message); ++ KLOG_ERROR() << message; + return; + } +- +- QString featureID = identifyFeature(feature, m_identifyIDs); +- if (!featureID.isEmpty()) +- { +- notifyIdentifyProcess(IDENTIFY_PROCESS_MACTCH,featureID); +- } + else + { +- notifyIdentifyProcess(IDENTIFY_PROCESS_NO_MATCH); ++ setDeviceStatus(DEVICE_STATUS_DOING_IDENTIFY); ++ doingUKeyIdentifyStart(m_pin); ++ m_serviceWatcher->addWatchedService(dbusMessage.service()); ++ auto replyMessage = dbusMessage.createReply(); ++ QDBusConnection::systemBus().send(replyMessage); + } ++} ++ ++CHECK_AUTH_WITH_1ARGS(AuthDevice, EnrollStart, onEnrollStart, AUTH_USER_ADMIN, const QString&) ++CHECK_AUTH_WITH_1ARGS(AuthDevice, IdentifyStart, onIdentifyStart, AUTH_USER_ADMIN, const QString&) ++CHECK_AUTH(AuthDevice, EnrollStop, onEnrollStop, AUTH_USER_ADMIN) ++CHECK_AUTH(AuthDevice, IdentifyStop, onIdentifyStop, AUTH_USER_ADMIN) + +- internalStopIdentify(); ++QStringList AuthDevice::GetFeatureIDList() ++{ ++ QStringList featureIDs = FeatureDB::getInstance()->getFeatureIDs(m_idVendor, m_idProduct); ++ return featureIDs; + } + + void AuthDevice::internalStopEnroll() +@@ -328,7 +327,6 @@ void AuthDevice::internalStopEnroll() + if (deviceStatus() == DEVICE_STATUS_DOING_ENROLL) + { + acquireFeatureStop(); +- m_doEnroll = false; + m_enrollTemplates.clear(); + setDeviceStatus(DEVICE_STATUS_IDLE); + clearWatchedServices(); +@@ -341,7 +339,6 @@ void AuthDevice::internalStopIdentify() + if (deviceStatus() == DEVICE_STATUS_DOING_IDENTIFY) + { + acquireFeatureStop(); +- m_doIdentify = false; + m_identifyIDs.clear(); + setDeviceStatus(DEVICE_STATUS_IDLE); + clearWatchedServices(); +@@ -349,28 +346,15 @@ void AuthDevice::internalStopIdentify() + } + } + +-void AuthDevice::enrollProcessRetry() +-{ +- Q_EMIT this->retry(); +-} +- +-void AuthDevice::saveEnrollTemplateToCache(QByteArray enrollTemplate) ++void AuthDevice::handleAcquiredFeature() + { +- if (!enrollTemplate.isEmpty()) ++ QByteArray feature = m_futureWatcher->result(); ++ if (feature.isEmpty()) + { +- m_enrollTemplates << enrollTemplate; +- KLOG_DEBUG() << "enroll template:" << enrollTemplate; +- notifyEnrollProcess(ENROLL_PROCESS_PASS); ++ acquireFeatureFail(); ++ return; + } +-} +- +-QByteArrayList AuthDevice::enrollTemplatesFromCache() +-{ +- return m_enrollTemplates; +-} + +-void AuthDevice::handleAcquiredFeature() +-{ + switch (deviceStatus()) + { + case DEVICE_STATUS_DOING_ENROLL: +diff --git a/src/device/auth-device.h b/src/device/auth-device.h +index 03997bc..0d9a9c8 100644 +--- a/src/device/auth-device.h ++++ b/src/device/auth-device.h +@@ -14,7 +14,6 @@ + + #pragma once + +-// #include "auth_device_adaptor.h" + #include + #include + #include +@@ -22,12 +21,13 @@ + #include + #include "auth-enum.h" + #include "kiran-auth-device-i.h" ++#include + + class AuthDeviceAdaptor; + + namespace Kiran + { +-typedef void* Handle; ++typedef void *Handle; + class BDriver; + + class AuthDevice : public QObject, protected QDBusContext +@@ -40,19 +40,21 @@ class AuthDevice : public QObject, protected QDBusContext + + public: + explicit AuthDevice(QObject *parent = nullptr); ++ + virtual ~AuthDevice(); + bool init(); + + virtual bool initDevice() = 0; + virtual BDriver *getDriver() = 0; +- QDBusObjectPath getObjectPath() { return m_objectPath; }; + ++ QDBusObjectPath getObjectPath() { return m_objectPath; }; + QString deviceID() { return m_deviceID; }; + QString deviceDriver() { return m_deviceDriver; }; + int deviceType() { return m_deviceType; }; + int deviceStatus() { return m_deviceStatus; } +- + QString deviceName() { return m_deviceName; }; ++ DeviceInfo deviceInfo(); ++ + void setDeviceType(DeviceType deviceType); + void setDeviceStatus(DeviceStatus deviceStatus); + void setDeviceName(const QString &deviceName); +@@ -71,24 +73,6 @@ protected: + virtual void acquireFeatureStop() = 0; + virtual void acquireFeatureFail() = 0; + +- virtual void doingEnrollProcess(QByteArray feature); +- virtual void doingIdentifyProcess(QByteArray feature); +- +- virtual void enrollProcessFail(const QString &featureID){}; +- virtual void enrollProcessRetry(); +- virtual void enrollTemplateMerge() = 0; +- +- virtual QString isFeatureEnrolled(QByteArray fpTemplate) = 0; +- virtual QString identifyFeature(QByteArray feature, QStringList featureIDs) = 0; +- virtual int templateMatch(QByteArray fpTemplate1, QByteArray fpTemplate2) = 0; +- +- virtual void saveEnrollTemplateToCache(QByteArray enrollTemplate); +- QByteArrayList enrollTemplatesFromCache(); +- +- virtual void notifyEnrollProcess(EnrollProcess process, const QString &featureID = QString()) = 0; +- virtual void notifyIdentifyProcess(IdentifyProcess process, const QString &featureID = QString()) = 0; +- virtual int needTemplatesCountForEnroll() = 0; +- + private Q_SLOTS: + void onNameLost(const QString &serviceName); + void handleAcquiredFeature(); +@@ -96,8 +80,8 @@ private Q_SLOTS: + + protected: + void clearWatchedServices(); +- void internalStopEnroll(); +- void internalStopIdentify(); ++ virtual void internalStopEnroll(); ++ virtual void internalStopIdentify(); + + private: + void registerDBusObject(); +@@ -106,33 +90,42 @@ private: + + void onEnrollStart(const QDBusMessage &message, const QString &extraInfo); + void onEnrollStop(const QDBusMessage &message); ++ void onBioEnrollStart(const QDBusMessage &dbusMessage); ++ void onUKeyEnrollStart(const QDBusMessage &dbusMessage, QJsonValue jsonValue); ++ + void onIdentifyStart(const QDBusMessage &message, const QString &value); + void onIdentifyStop(const QDBusMessage &message); ++ void onBioIdentifyStart(const QDBusMessage &dbusMessage); ++ void onUKeyIdentifyStart(const QDBusMessage &dbusMessage, QJsonValue jsonValue); ++ ++ virtual void doingEnrollProcess(QByteArray feature){}; ++ virtual void doingIdentifyProcess(QByteArray feature){}; ++ ++ virtual void doingUKeyEnrollStart(const QString &pin, bool rebinding = false){}; ++ virtual void doingUKeyIdentifyStart(const QString &pin){}; + + Q_SIGNALS: + void retry(); + + protected: +- QString m_deviceID; + QString m_deviceDriver; ++ QSharedPointer m_dbusAdaptor; ++ bool m_doAcquire = true; ++ QStringList m_identifyIDs; ++ QByteArrayList m_enrollTemplates; ++ QSharedPointer> m_futureWatcher; ++ QString m_pin; ++ ++private: ++ QString m_deviceID; + int m_deviceType; + int m_deviceStatus; + QString m_deviceName; + QString m_idVendor; + QString m_idProduct; + QDBusObjectPath m_objectPath; +- QDBusServiceWatcher *m_serviceWatcher; +- AuthDeviceAdaptor *m_dbusAdaptor; ++ QSharedPointer m_serviceWatcher; + +- bool m_doAcquire = true; +- bool m_doIdentify = true; +- bool m_doEnroll = true; +- QStringList m_identifyIDs; +- QByteArrayList m_enrollTemplates; +- +- QFutureWatcher *m_futureWatcher; +- +-private: + /** + * 用于注册com.kylinsec.Kiran.AuthDevice.Device服务时的编号 + * 在生成AuthDevice对象,注册dbus服务成功后,数值加1 +diff --git a/src/device/bio-device.cpp b/src/device/bio-device.cpp +new file mode 100644 +index 0000000..7342928 +--- /dev/null ++++ b/src/device/bio-device.cpp +@@ -0,0 +1,104 @@ ++/** ++ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd. ++ * kiran-biometrics is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ * ++ * Author: luoqing ++ */ ++ ++#include "bio-device.h" ++#include ++namespace Kiran ++{ ++BioDevice::BioDevice(QObject *parent) : AuthDevice{parent} ++{ ++} ++ ++BioDevice::~BioDevice() ++{ ++} ++ ++void BioDevice::doingEnrollProcess(QByteArray feature) ++{ ++ int templatesCount = enrollTemplatesFromCache().count(); ++ if (templatesCount == 0) ++ { ++ // 第一个指纹模板入录时,检查该指纹是否录入过 ++ QString featureID = isFeatureEnrolled(feature); ++ if (featureID.isEmpty()) ++ { ++ saveEnrollTemplateToCache(feature); ++ enrollProcessRetry(); ++ } ++ else ++ { ++ notifyEnrollProcess(ENROLL_PROCESS_REPEATED_ENROLL, featureID); ++ internalStopEnroll(); ++ } ++ } ++ else if (templatesCount < mergeTemplateCount()) ++ { ++ // 判断录入时是否录的是同一根手指 ++ int matchResult = templateMatch(m_enrollTemplates.value(0), feature); ++ if (matchResult == GENERAL_RESULT_OK) ++ { ++ saveEnrollTemplateToCache(feature); ++ } ++ else ++ { ++ notifyEnrollProcess(ENROLL_PROCESS_INCONSISTENT_FEATURE); ++ } ++ enrollProcessRetry(); ++ } ++ else if (enrollTemplatesFromCache().count() == mergeTemplateCount()) ++ { ++ enrollTemplateMerge(); ++ } ++} ++ ++void BioDevice::doingIdentifyProcess(QByteArray feature) ++{ ++ QString featureID = identifyFeature(feature, m_identifyIDs); ++ if (!featureID.isEmpty()) ++ { ++ notifyIdentifyProcess(IDENTIFY_PROCESS_MACTCH, featureID); ++ } ++ else ++ { ++ notifyIdentifyProcess(IDENTIFY_PROCESS_NO_MATCH); ++ } ++ ++ internalStopIdentify(); ++} ++QByteArrayList BioDevice::enrollTemplatesFromCache() ++{ ++ return m_enrollTemplates; ++} ++ ++void BioDevice::saveEnrollTemplateToCache(QByteArray enrollTemplate) ++{ ++ if (!enrollTemplate.isEmpty()) ++ { ++ m_enrollTemplates << enrollTemplate; ++ KLOG_DEBUG() << "enroll template:" << enrollTemplate; ++ notifyEnrollProcess(ENROLL_PROCESS_PASS); ++ } ++} ++ ++void BioDevice::enrollProcessRetry() ++{ ++ Q_EMIT this->retry(); ++} ++ ++QString BioDevice::isFeatureEnrolled(QByteArray fpTemplate) ++{ ++ return identifyFeature(fpTemplate, QStringList()); ++} ++ ++} // namespace Kiran +\ No newline at end of file +diff --git a/src/device/bio-device.h b/src/device/bio-device.h +new file mode 100644 +index 0000000..c55aa84 +--- /dev/null ++++ b/src/device/bio-device.h +@@ -0,0 +1,47 @@ ++/** ++ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd. ++ * kiran-biometrics is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ * ++ * Author: luoqing ++ */ ++#pragma once ++#include "auth-device.h" ++ ++namespace Kiran ++{ ++class BioDevice : public AuthDevice ++{ ++ Q_OBJECT ++public: ++ explicit BioDevice(QObject *parent = nullptr); ++ ~BioDevice(); ++ ++protected: ++ void doingEnrollProcess(QByteArray feature) override; ++ void doingIdentifyProcess(QByteArray feature) override; ++ ++ virtual void enrollProcessRetry(); ++ ++ virtual void enrollTemplateMerge() = 0; ++ virtual int templateMatch(QByteArray fpTemplate1, QByteArray fpTemplate2) = 0; ++ virtual QString identifyFeature(QByteArray feature, QStringList featureIDs) = 0; ++ ++ virtual int mergeTemplateCount() = 0; ++ virtual void notifyEnrollProcess(EnrollProcess process, const QString &featureID = QString()) = 0; ++ virtual void notifyIdentifyProcess(IdentifyProcess process, const QString &featureID = QString()) = 0; ++ ++ QByteArrayList enrollTemplatesFromCache(); ++ virtual void saveEnrollTemplateToCache(QByteArray enrollTemplate); ++ ++private: ++ virtual QString isFeatureEnrolled(QByteArray fpTemplate); ++}; ++ ++} // namespace Kiran +diff --git a/src/device/finger-vein/fv-sd-device.cpp b/src/device/finger-vein/fv-sd-device.cpp +index 43faad7..5ae6605 100644 +--- a/src/device/finger-vein/fv-sd-device.cpp ++++ b/src/device/finger-vein/fv-sd-device.cpp +@@ -111,7 +111,7 @@ struct DriverLib + TGSetDevLedFunc TGSetDevLed; + }; + +-FVSDDevice::FVSDDevice(QObject *parent) : AuthDevice{parent}, ++FVSDDevice::FVSDDevice(QObject *parent) : BioDevice{parent}, + m_driverLib(nullptr), + m_libProcessHandle(nullptr), + m_libComHandle(nullptr) +@@ -125,17 +125,10 @@ FVSDDevice::~FVSDDevice() + if (!deviceID().isEmpty()) + { + acquireFeatureStop(); +- m_futureWatcher->deleteLater(); + KLOG_DEBUG() << "TGGetDevStatus():" << m_driverLib->TGGetDevStatus(); + m_driverLib->TGCloseDev(); + } + +- if (m_driverLib) +- { +- delete m_driverLib; +- m_driverLib = nullptr; +- } +- + if (m_libComHandle) + { + dlclose(m_libComHandle); +@@ -166,7 +159,7 @@ bool FVSDDevice::loadLib() + return false; + } + +- m_driverLib = new DriverLib; ++ m_driverLib = QSharedPointer(new DriverLib); + m_driverLib->TGInitFVProcess = (TGInitFVProcessFunc)dlsym(m_libProcessHandle, "TGInitFVProcess"); + m_driverLib->TGImgExtractFeatureVerify = (TGImgExtractFeatureVerifyFunc)dlsym(m_libProcessHandle, "TGImgExtractFeatureVerify"); + m_driverLib->TGFeaturesFusionTmpl = (TGFeaturesFusionTmplFunc)dlsym(m_libProcessHandle, "TGFeaturesFusionTmpl"); +@@ -221,11 +214,11 @@ bool FVSDDevice::initDevice() + } + KLOG_DEBUG() << "Device opened successfully:" << ret; + +- ret = m_driverLib->TGGetDevFW(fw); ++ m_driverLib->TGGetDevFW(fw); + KLOG_DEBUG() << "Get firmware version:" << fw; +- ret = m_driverLib->TGGetDevSN(sn); ++ m_driverLib->TGGetDevSN(sn); + KLOG_DEBUG() << "Obtain device SN number:" << sn; +- ret = m_driverLib->TGPlayDevVoice(VOICE_VOLUME1); ++ m_driverLib->TGPlayDevVoice(VOICE_VOLUME1); + + return true; + } +@@ -291,7 +284,7 @@ QByteArray FVSDDevice::acquireFeature() + void FVSDDevice::acquireFeatureStop() + { + m_driverLib->TGCancelGetImage(); +- if (m_futureWatcher != nullptr) ++ if (m_futureWatcher.data() != nullptr) + { + m_futureWatcher->waitForFinished(); + } +@@ -357,9 +350,7 @@ void FVSDDevice::enrollTemplateMerge() + { + QString id = QCryptographicHash::hash(mergedTemplate, QCryptographicHash::Md5).toHex(); + +- DeviceInfo deviceInfo; +- deviceInfo.idVendor = m_idVendor; +- deviceInfo.idProduct = m_idProduct; ++ DeviceInfo deviceInfo = this->deviceInfo(); + bool save = FeatureDB::getInstance()->addFeature(id, mergedTemplate, deviceInfo); + if (save) + { +@@ -396,9 +387,10 @@ QString FVSDDevice::identifyFeature(QByteArray feature, QStringList featureIDs) + { + QList saveList; + QString featureID; ++ DeviceInfo deviceInfo = this->deviceInfo(); + if (featureIDs.isEmpty()) + { +- saveList = FeatureDB::getInstance()->getFeatures(m_idVendor, m_idProduct); ++ saveList = FeatureDB::getInstance()->getFeatures(deviceInfo.idVendor, deviceInfo.idProduct); + } + else + { +@@ -481,7 +473,7 @@ BDriver *FVSDDevice::getDriver() + return nullptr; + } + +-int FVSDDevice::needTemplatesCountForEnroll() ++int FVSDDevice::mergeTemplateCount() + { + return TEMPLATE_FV_NUM; + } +diff --git a/src/device/finger-vein/fv-sd-device.h b/src/device/finger-vein/fv-sd-device.h +index d1fa8c7..09b372b 100644 +--- a/src/device/finger-vein/fv-sd-device.h ++++ b/src/device/finger-vein/fv-sd-device.h +@@ -14,7 +14,8 @@ + + #pragma once + #include +-#include "device/auth-device.h" ++#include "device/bio-device.h" ++#include + + namespace Kiran + { +@@ -25,7 +26,7 @@ enum ExtractFeatureMode + }; + + struct DriverLib; +-class FVSDDevice : public AuthDevice ++class FVSDDevice : public BioDevice + { + Q_OBJECT + public: +@@ -53,13 +54,14 @@ private: + + QByteArray getFeatureFromImage(QByteArray image, ExtractFeatureMode mode); + +- int needTemplatesCountForEnroll() override; ++ int mergeTemplateCount() override; + int templateMatch(QByteArray fpTemplate1, QByteArray fpTemplate2) override; + void notifyEnrollProcess(EnrollProcess process, const QString &featureID = QString()) override; + void notifyIdentifyProcess(IdentifyProcess process, const QString &featureID = QString()) override; + + private: +- DriverLib *m_driverLib; ++ QSharedPointer m_driverLib; ++ + Handle m_libProcessHandle; + Handle m_libComHandle; + }; +diff --git a/src/device/fingerprint/fp-device.cpp b/src/device/fingerprint/fp-device.cpp +index d610844..cddaadd 100644 +--- a/src/device/fingerprint/fp-device.cpp ++++ b/src/device/fingerprint/fp-device.cpp +@@ -17,7 +17,7 @@ + namespace Kiran + { + FPDevice::FPDevice(QObject *parent) +- : AuthDevice{parent} ++ : BioDevice{parent} + { + } + +diff --git a/src/device/fingerprint/fp-device.h b/src/device/fingerprint/fp-device.h +index abbbcd1..7a792ba 100644 +--- a/src/device/fingerprint/fp-device.h ++++ b/src/device/fingerprint/fp-device.h +@@ -13,11 +13,11 @@ + */ + + #pragma once +-#include "device/auth-device.h" ++#include "device/bio-device.h" + + namespace Kiran + { +-class FPDevice : public AuthDevice ++class FPDevice : public BioDevice + { + public: + explicit FPDevice(QObject *parent = nullptr); +diff --git a/src/device/fingerprint/fp-zk-device.cpp b/src/device/fingerprint/fp-zk-device.cpp +index 1862446..8236787 100644 +--- a/src/device/fingerprint/fp-zk-device.cpp ++++ b/src/device/fingerprint/fp-zk-device.cpp +@@ -140,18 +140,15 @@ FPZKDevice::FPZKDevice(QObject* parent) + FPZKDevice::~FPZKDevice() + { + acquireFeatureStop(); +- m_futureWatcher->deleteLater(); + if (m_hDBCache) + { + m_driverLib->ZKFPM_DBFree(m_hDBCache); + m_hDBCache = NULL; + } + +- if (m_driverLib) ++ if (m_driverLib.data()) + { + m_driverLib->ZKFPM_Terminate(); // 释放资源 +- delete m_driverLib; +- m_driverLib = nullptr; + } + + if (m_libHandle) +@@ -193,7 +190,7 @@ bool FPZKDevice::loadLib() + return false; + } + +- m_driverLib = new DriverLib; ++ m_driverLib = QSharedPointer(new DriverLib); + m_driverLib->ZKFPM_Init = (T_ZKFPM_Init)dlsym(m_libHandle, "ZKFPM_Init"); + if (NULL == m_driverLib->ZKFPM_Init) + { +@@ -323,7 +320,7 @@ QByteArray FPZKDevice::acquireFeature() + void FPZKDevice::acquireFeatureStop() + { + m_doAcquire = false; +- if (m_futureWatcher != nullptr) ++ if (m_futureWatcher.data() != nullptr) + { + m_futureWatcher->waitForFinished(); + } +@@ -374,18 +371,15 @@ int FPZKDevice::templateMatch(QByteArray fpTemplate1, QByteArray fpTemplate2) + return score > 0 ? GENERAL_RESULT_OK : GENERAL_RESULT_FAIL; + } + +-QString FPZKDevice::isFeatureEnrolled(QByteArray fpTemplate) +-{ +- return identifyFeature(fpTemplate, QStringList()); +-} + + QString FPZKDevice::identifyFeature(QByteArray fpTemplate, QStringList featureIDs) + { + QList saveList; + QString featureID; ++ DeviceInfo info = this->deviceInfo(); + if (featureIDs.isEmpty()) + { +- saveList = FeatureDB::getInstance()->getFeatures(m_idVendor, m_idProduct); ++ saveList = FeatureDB::getInstance()->getFeatures(info.idVendor, info.idProduct); + } + else + { +@@ -416,9 +410,7 @@ QString FPZKDevice::identifyFeature(QByteArray fpTemplate, QStringList featureID + + bool FPZKDevice::saveFPrintTemplate(QByteArray fpTemplate, const QString& featureID) + { +- DeviceInfo deviceInfo; +- deviceInfo.idVendor = m_idVendor; +- deviceInfo.idProduct = m_idProduct; ++ DeviceInfo deviceInfo = this->deviceInfo(); + bool save = FeatureDB::getInstance()->addFeature(featureID, fpTemplate, deviceInfo); + return save; + } +@@ -469,7 +461,7 @@ void FPZKDevice::enrollTemplateMerge() + internalStopEnroll(); + } + +-int FPZKDevice::needTemplatesCountForEnroll() ++int FPZKDevice::mergeTemplateCount() + { + return FP_ZK_MEGER_TEMPLATE_COUNT; + } +diff --git a/src/device/fingerprint/fp-zk-device.h b/src/device/fingerprint/fp-zk-device.h +index 30e4e93..3379e2e 100644 +--- a/src/device/fingerprint/fp-zk-device.h ++++ b/src/device/fingerprint/fp-zk-device.h +@@ -14,6 +14,7 @@ + #pragma once + + #include ++#include + #include "auth-enum.h" + #include "fp-device.h" + +@@ -39,8 +40,8 @@ private: + void acquireFeatureStop() override; + void acquireFeatureFail() override; + void enrollTemplateMerge() override; +- int needTemplatesCountForEnroll() override; +- QString isFeatureEnrolled(QByteArray fpTemplate) override; ++ int mergeTemplateCount() override; ++ + void notifyEnrollProcess(EnrollProcess process, const QString& featureID = QString()) override; + void notifyIdentifyProcess(IdentifyProcess process, const QString& featureID = QString()) override; + +@@ -63,6 +64,6 @@ private: + private: + Handle m_libHandle; + Handle m_hDBCache; +- DriverLib* m_driverLib; ++ QSharedPointer m_driverLib; + }; + } // namespace Kiran +diff --git a/src/device/ukey/ukey-ft-device.cpp b/src/device/ukey/ukey-ft-device.cpp +new file mode 100644 +index 0000000..38017c6 +--- /dev/null ++++ b/src/device/ukey/ukey-ft-device.cpp +@@ -0,0 +1,400 @@ ++/** ++ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd. ++ * kiran-biometrics is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ * ++ * Author: luoqing ++ */ ++ ++#include "ukey-ft-device.h" ++#include ++#include ++#include ++#include "auth-enum.h" ++#include "auth_device_adaptor.h" ++#include "feature-db.h" ++ ++namespace Kiran ++{ ++#define FT_UKEY_DRIVER_LIB "libes_3000gm.so" ++#define UKEY_APP_NAME "KIRAN-AUTHENTICATION-DEVICES" ++#define UKEY_CONTAINER_NAME "1003-3001" ++ ++UKeyFTDevice::UKeyFTDevice(QObject *parent) : AuthDevice{parent}, ++ m_libHandle(nullptr), ++ m_appHandle(nullptr), ++ m_devHandle(nullptr), ++ m_containerHandle(nullptr) ++{ ++ setDeviceType(DEVICE_TYPE_UKey); ++ setDeviceDriver(FT_UKEY_DRIVER_LIB); ++} ++ ++UKeyFTDevice::~UKeyFTDevice() ++{ ++ m_driver->closeContainer(m_containerHandle); ++ m_driver->closeApplication(m_appHandle); ++ m_driver->disConnectDev(m_devHandle); ++ m_containerHandle = nullptr; ++ m_appHandle = nullptr; ++ m_devHandle = nullptr; ++} ++ ++bool UKeyFTDevice::initDevice() ++{ ++ m_driver = QSharedPointer(new UKeySKFDriver()); ++ if (!m_driver->loadLibrary(FT_UKEY_DRIVER_LIB)) ++ { ++ return false; ++ } ++ m_devHandle = m_driver->connectDev(); ++ if (!m_devHandle) ++ { ++ KLOG_DEBUG() << ""; ++ return false; ++ } ++ ++ return true; ++} ++ ++BDriver *UKeyFTDevice::getDriver() ++{ ++ return nullptr; ++} ++ ++void UKeyFTDevice::doingUKeyEnrollStart(const QString &pin, bool rebinding) ++{ ++ if (rebinding) ++ { ++ ULONG ulReval = m_driver->devAuth(m_devHandle); ++ if (ulReval == SAR_OK) ++ { ++ m_driver->deleteAllApplication(m_devHandle); ++ DeviceInfo deviceInfo = this->deviceInfo(); ++ QStringList idList = FeatureDB::getInstance()->getFeatureIDs(deviceInfo.idVendor, deviceInfo.idProduct); ++ Q_FOREACH (auto id, idList) ++ { ++ FeatureDB::getInstance()->deleteFeature(id); ++ } ++ bindingCurrentUser(); ++ } ++ else ++ { ++ KLOG_ERROR() << "rebinding failed"; ++ } ++ } ++ else ++ { ++ bindingCurrentUser(); ++ } ++ internalStopEnroll(); ++} ++ ++void UKeyFTDevice::bindingCurrentUser() ++{ ++ if (isExistPublicKey()) ++ { ++ notifyUKeyEnrollProcess(ENROLL_PROCESS_REPEATED_ENROLL); ++ return; ++ } ++ ++ ECCPUBLICKEYBLOB publicKey = genKeyPair(); ++ if (publicKey.BitLen != 0) ++ { ++ /** ++ * 存入PublicKey,生成FID,并返回FID,FID标识PublicKey ++ * 不用保存PublicKey和systemUser的关系,目前只有一个用户 ++ */ ++ QByteArray keyFeature; ++ QByteArray xCoordinateArray((char *)publicKey.XCoordinate, 64); ++ QByteArray yCoordinateArray((char *)publicKey.YCoordinate, 64); ++ keyFeature.append(publicKey.BitLen); ++ keyFeature.append(xCoordinateArray); ++ keyFeature.append(yCoordinateArray); ++ KLOG_DEBUG() << "keyFeature:" << keyFeature; ++ ++ QString featureID = QCryptographicHash::hash(keyFeature, QCryptographicHash::Md5).toHex(); ++ DeviceInfo deviceInfo = this->deviceInfo(); ++ ++ if (FeatureDB::getInstance()->addFeature(featureID, keyFeature, deviceInfo)) ++ { ++ notifyUKeyEnrollProcess(ENROLL_PROCESS_SUCCESS, SAR_OK, featureID); ++ } ++ else ++ { ++ KLOG_DEBUG() << "save feature fail"; ++ notifyUKeyEnrollProcess(ENROLL_PROCESS_SAVE_FAIL); ++ } ++ } ++ else ++ { ++ notifyUKeyEnrollProcess(ENROLL_PROCESS_SAVE_FAIL); ++ } ++} ++ ++bool UKeyFTDevice::isExistPublicKey() ++{ ++ DeviceInfo deviceInfo = this->deviceInfo(); ++ auto features = FeatureDB::getInstance()->getFeatures(deviceInfo.idVendor, deviceInfo.idProduct); ++ if (features.count() != 0) ++ { ++ return true; ++ } ++ else ++ { ++ return false; ++ } ++} ++ ++ECCPUBLICKEYBLOB UKeyFTDevice::genKeyPair() ++{ ++ ECCPUBLICKEYBLOB publicKey = {0}; ++ if (!isExistsApplication(UKEY_APP_NAME)) ++ { ++ // NOTE:必须通过设备认证后才能在设备内创建和删除应用 ++ ULONG ulReval = m_driver->devAuth(m_devHandle); ++ if (ulReval != SAR_OK) ++ { ++ KLOG_ERROR() << "Device auth failure: " << m_driver->getErrorReason(ulReval); ++ return publicKey; ++ } ++ else ++ { ++ KLOG_DEBUG() << "device auth success"; ++ } ++ m_driver->deleteAllApplication(m_devHandle); ++ KLOG_DEBUG() << "m_devHandle:" << m_devHandle; ++ KLOG_DEBUG() << "m_pin:" << m_pin; ++ m_appHandle = m_driver->createApplication(m_devHandle, m_pin, UKEY_APP_NAME); ++ m_containerHandle = m_driver->createContainer(m_appHandle, m_pin, UKEY_CONTAINER_NAME, &m_retryCount); ++ if (!m_appHandle || !m_containerHandle) ++ { ++ return publicKey; ++ } ++ } ++ ++ m_appHandle = m_driver->onOpenApplication(m_devHandle, (LPSTR)UKEY_APP_NAME); ++ m_containerHandle = m_driver->onOpenContainer(m_appHandle, m_pin, UKEY_CONTAINER_NAME, &m_retryCount); ++ if (!m_appHandle || !m_containerHandle) ++ { ++ return publicKey; ++ } ++ ++ ULONG ret = m_driver->genECCKeyPair(m_containerHandle, &publicKey); ++ if (ret == SAR_OK) ++ { ++ KLOG_DEBUG() << "gen ecc key pair success"; ++ } ++ else ++ { ++ KLOG_ERROR() << "gen ecc key pair failed:" << m_driver->getErrorReason(ret); ++ } ++ ++ return publicKey; ++} ++ ++bool UKeyFTDevice::isExistsApplication(const QString &appName) ++{ ++ QString appNames = m_driver->enumApplication(m_devHandle); ++ KLOG_DEBUG() << "enum app names:" << appNames; ++ if (appNames.contains(appName)) ++ { ++ return true; ++ } ++ return false; ++} ++ ++void UKeyFTDevice::doingUKeyIdentifyStart(const QString &pin) ++{ ++ QList saveList; ++ DeviceInfo deviceInfo = this->deviceInfo(); ++ if (m_identifyIDs.isEmpty()) ++ { ++ saveList = FeatureDB::getInstance()->getFeatures(deviceInfo.idVendor, deviceInfo.idProduct); ++ } ++ else ++ { ++ Q_FOREACH (auto id, m_identifyIDs) ++ { ++ QByteArray feature = FeatureDB::getInstance()->getFeature(id); ++ if (!feature.isEmpty()) ++ saveList << feature; ++ } ++ } ++ ++ if (saveList.count() != 0) ++ { ++ for (int j = 0; j < saveList.count(); j++) ++ { ++ auto saveTemplate = saveList.value(j); ++ identifyKeyFeature(saveTemplate); ++ } ++ } ++ else ++ { ++ KLOG_DEBUG() << "no found feature id"; ++ } ++ ++ internalStopIdentify(); ++} ++ ++void UKeyFTDevice::internalStopEnroll() ++{ ++ if (deviceStatus() == DEVICE_STATUS_DOING_ENROLL) ++ { ++ m_driver->closeContainer(m_containerHandle); ++ m_driver->closeApplication(m_appHandle); ++ acquireFeatureStop(); ++ m_enrollTemplates.clear(); ++ setDeviceStatus(DEVICE_STATUS_IDLE); ++ clearWatchedServices(); ++ KLOG_DEBUG() << "stop Enroll"; ++ } ++} ++ ++void UKeyFTDevice::internalStopIdentify() ++{ ++ if (deviceStatus() == DEVICE_STATUS_DOING_IDENTIFY) ++ { ++ m_driver->closeContainer(m_containerHandle); ++ m_driver->closeApplication(m_appHandle); ++ acquireFeatureStop(); ++ m_identifyIDs.clear(); ++ setDeviceStatus(DEVICE_STATUS_IDLE); ++ clearWatchedServices(); ++ KLOG_DEBUG() << "stopIdentify"; ++ } ++} ++ ++void UKeyFTDevice::identifyKeyFeature(QByteArray keyFeature) ++{ ++ m_appHandle = m_driver->onOpenApplication(m_devHandle, (LPSTR)UKEY_APP_NAME); ++ if (m_appHandle == nullptr) ++ { ++ notifyUKeyIdentifyProcess(IDENTIFY_PROCESS_NO_MATCH); ++ return; ++ } ++ ++ m_containerHandle = m_driver->onOpenContainer(m_appHandle, m_pin, UKEY_CONTAINER_NAME, &m_retryCount); ++ if (m_containerHandle == nullptr) ++ { ++ notifyUKeyIdentifyProcess(IDENTIFY_PROCESS_NO_MATCH); ++ return; ++ } ++ ++ ECCSIGNATUREBLOB Signature = {0}; ++ ULONG ret = m_driver->authSignData(m_containerHandle, m_devHandle, Signature); ++ if (ret != SAR_OK) ++ { ++ KLOG_DEBUG() << "auth sign data failed:" << m_driver->getErrorReason(ret); ++ notifyUKeyIdentifyProcess(IDENTIFY_PROCESS_NO_MATCH, ret); ++ return; ++ } ++ ++ ECCPUBLICKEYBLOB eccPubKey; ++ eccPubKey.BitLen = keyFeature.left(1).at(0); ++ auto xCoordinateArray = keyFeature.mid(1, sizeof(eccPubKey.XCoordinate)); ++ auto yCoordinateArray = keyFeature.mid(sizeof(eccPubKey.XCoordinate) + 1); ++ ++ memcpy(eccPubKey.XCoordinate, (unsigned char *)xCoordinateArray.data(), ECC_MAX_XCOORDINATE_BITS_LEN / 8); ++ memcpy(eccPubKey.YCoordinate, (unsigned char *)yCoordinateArray.data(), ECC_MAX_YCOORDINATE_BITS_LEN / 8); ++ ++ ret = m_driver->verifyData(m_devHandle, Signature, eccPubKey); ++ if (ret != SAR_OK) ++ { ++ KLOG_DEBUG() << "verify data failed:" << m_driver->getErrorReason(ret); ++ notifyUKeyIdentifyProcess(IDENTIFY_PROCESS_NO_MATCH, ret); ++ } ++ else ++ { ++ notifyUKeyIdentifyProcess(IDENTIFY_PROCESS_MACTCH); ++ } ++} ++ ++QByteArray UKeyFTDevice::acquireFeature() ++{ ++ return QByteArray(); ++} ++ ++void UKeyFTDevice::acquireFeatureStop() ++{ ++} ++void UKeyFTDevice::acquireFeatureFail() ++{ ++} ++ ++void UKeyFTDevice::notifyUKeyEnrollProcess(EnrollProcess process, ULONG error, const QString &featureID) ++{ ++ QString message; ++ switch (process) ++ { ++ case ENROLL_PROCESS_SUCCESS: ++ message = tr("Successed binding user"); ++ Q_EMIT m_dbusAdaptor->EnrollStatus(featureID, 100, ENROLL_RESULT_COMPLETE, message); ++ break; ++ case ENROLL_PROCESS_SAVE_FAIL: ++ message = tr("Binding user failed"); ++ Q_EMIT m_dbusAdaptor->EnrollStatus("", 0, ENROLL_RESULT_FAIL, message); ++ break; ++ case ENROLL_PROCESS_REPEATED_ENROLL: ++ message = tr("UKey has been bound"); ++ Q_EMIT m_dbusAdaptor->EnrollStatus("", 0, ENROLL_RESULT_UKEY_EXIST_BINDING, message); ++ default: ++ break; ++ } ++ if (!message.isEmpty()) ++ { ++ if (!featureID.isEmpty()) ++ { ++ KLOG_DEBUG() << QString("%1, feature id:%2").arg(message).arg(featureID); ++ } ++ else ++ { ++ KLOG_DEBUG() << message; ++ } ++ } ++} ++ ++void UKeyFTDevice::notifyUKeyIdentifyProcess(IdentifyProcess process, ULONG error, const QString &featureID) ++{ ++ QString message, reason; ++ if (error != SAR_OK) ++ { ++ reason = m_driver->getErrorReason(error); ++ KLOG_DEBUG() << "fail reason:" << reason; ++ } ++ ++ KLOG_DEBUG() << "m_retryCount:" << m_retryCount; ++ switch (process) ++ { ++ case IDENTIFY_PROCESS_NO_MATCH: ++ message = tr("identify fail!"); ++ // 目前只需要返回有关pin码的错误信息 ++ if (reason.contains("pin")) ++ { ++ message.append(reason); ++ } ++ message.append(QString(",remaining retry count: %1").arg(m_retryCount)); ++ Q_EMIT m_dbusAdaptor->IdentifyStatus("", IDENTIFY_RESULT_NOT_MATCH, message); ++ break; ++ case IDENTIFY_PROCESS_MACTCH: ++ message = tr("identify ukey success"); ++ Q_EMIT m_dbusAdaptor->IdentifyStatus(featureID, IDENTIFY_RESULT_MATCH, message); ++ break; ++ default: ++ break; ++ } ++ ++ if (!message.isEmpty()) ++ { ++ KLOG_DEBUG() << QString("%1, feature id:%2").arg(message).arg(featureID); ++ } ++} ++ ++} // namespace Kiran +diff --git a/src/device/ukey/ukey-ft-device.h b/src/device/ukey/ukey-ft-device.h +new file mode 100644 +index 0000000..901393b +--- /dev/null ++++ b/src/device/ukey/ukey-ft-device.h +@@ -0,0 +1,68 @@ ++/** ++ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd. ++ * kiran-biometrics is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ * ++ * Author: luoqing ++ */ ++ ++#pragma once ++#include ++#include "device/auth-device.h" ++#include "driver/ukey/ukey-skf-driver.h" ++#include "ukey-skf.h" ++#include ++ ++namespace Kiran ++{ ++struct DriverLib; ++ ++class UKeyFTDevice : public AuthDevice ++{ ++ Q_OBJECT ++public: ++ explicit UKeyFTDevice(QObject *parent = nullptr); ++ ~UKeyFTDevice(); ++ ++ bool initDevice() override; ++ BDriver *getDriver() override; ++ ++private: ++ void doingUKeyEnrollStart(const QString &pin, bool rebinding = false) override; ++ void doingUKeyIdentifyStart(const QString &pin) override; ++ ++ void internalStopEnroll() override; ++ void internalStopIdentify() override; ++ ++ void identifyKeyFeature(QByteArray keyFeature); ++ ++ bool isExistPublicKey(); ++ void bindingCurrentUser(); ++ ECCPUBLICKEYBLOB genKeyPair(); ++ ++ bool isExistsApplication(const QString &appName); ++ ++ void notifyUKeyEnrollProcess(EnrollProcess process, ULONG error = SAR_OK, const QString &featureID = QString()); ++ void notifyUKeyIdentifyProcess(IdentifyProcess process, ULONG error = SAR_OK, const QString &featureID = QString()); ++ ++ QByteArray acquireFeature() override; ++ void acquireFeatureStop() override; ++ void acquireFeatureFail() override; ++ ++private: ++ Handle m_libHandle; ++ DEVHANDLE m_devHandle; ++ HAPPLICATION m_appHandle; ++ HCONTAINER m_containerHandle; ++ ULONG m_retryCount = 1000000; ++ ++ QSharedPointer m_driver; ++}; ++ ++} // namespace Kiran +diff --git a/src/driver/ukey/ukey-skf-driver.cpp b/src/driver/ukey/ukey-skf-driver.cpp +new file mode 100644 +index 0000000..b81bda4 +--- /dev/null ++++ b/src/driver/ukey/ukey-skf-driver.cpp +@@ -0,0 +1,516 @@ ++/** ++ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd. ++ * kiran-biometrics is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ * ++ * Author: luoqing ++ */ ++#include "ukey-skf-driver.h" ++#include ++#include ++#include ++#include ++ ++namespace Kiran ++{ ++// 签名者ID ++#define CONF_DEFAULT_KEY_PUC_ID "PucId" ++#define CONF_DEFAULT_KEY_DEV_KEY "DevKey" ++ ++#define CONF_DEFAULT_KEY_ADMIN_PINCODE "AdminPinCode" ++#define CONF_DEFAULT_KEY_USER_PINCODE "UserPinCode" ++ ++#define SIGN_DATA "kiran-authentication-devices" ++ ++#define UKEY_DEFAULT_CONFIG "/etc/kiran-authentication-devices-sdk/ukey-skf.conf" ++#define ADMIN_PIN_RETRY_COUNT 10 ++#define USER_PIN_RETRY_COUNT 10 ++ ++extern "C" ++{ ++ typedef ULONG (*SKF_EnumDev_Func)(BOOL bPresent, LPSTR szNameList, ULONG *pulSize); ++ typedef ULONG (*SKF_ConnectDev_Func)(LPSTR szName, DEVHANDLE *phDev); ++ typedef ULONG (*SKF_DisConnectDev_Func)(DEVHANDLE hDev); ++ typedef ULONG (*SKF_GetDevState_Func)(LPSTR szDevName, ULONG *pulDevState); ++ typedef ULONG (*SKF_GetDevInfo_Func)(DEVHANDLE hDev, DEVINFO *pDevInfo); ++ typedef ULONG (*SKF_SetLabel_Func)(DEVHANDLE hDev, LPSTR szLabel); ++ typedef ULONG (*SKF_OpenApplication_Func)(DEVHANDLE hDev, LPSTR szAppName, HAPPLICATION *phApplication); ++ typedef ULONG (*SKF_VerifyPIN_Func)(HAPPLICATION hApplication, ULONG ulPINType, LPSTR szPIN, ULONG *pulRetryCount); ++ typedef ULONG (*SKF_OpenContainer_Func)(HAPPLICATION hApplication, LPSTR szContainerName, HCONTAINER *phContainer); ++ typedef ULONG (*SKF_GenECCKeyPair_Func)(HCONTAINER hContainer, ULONG ulAlgId, ECCPUBLICKEYBLOB *pBlob); ++ typedef ULONG (*SKF_CloseContainer_Func)(HCONTAINER hContainer); ++ typedef ULONG (*SKF_CloseApplication_Func)(HAPPLICATION hApplication); ++ typedef ULONG (*SKF_CreateApplication_Func)(DEVHANDLE hDev, LPSTR szAppName, LPSTR szAdminPin, ++ DWORD dwAdminPinRetryCount, LPSTR szUserPin, DWORD dwUserPinRetryCount, ++ DWORD dwCreateFileRights, HAPPLICATION *phApplication); ++ ++ typedef ULONG (*SKF_EnumApplication_Func)(DEVHANDLE hDev, LPSTR szAppName, ULONG *pulSize); ++ typedef ULONG (*SKF_ExportPublicKey_Func)(HCONTAINER hContainer, BOOL bSignFlag, BYTE *pbBlob, ULONG *pulBlobLen); ++ typedef ULONG (*SKF_Digest_Func)(HANDLE hHash, BYTE *pbData, ULONG ulDataLen, BYTE *pbHashData, ULONG *pulHashLen); ++ typedef ULONG (*SKF_DigestInit_Func)(DEVHANDLE hDev, ULONG ulAlgID, ECCPUBLICKEYBLOB *pPubKey, ++ unsigned char *pucID, ULONG ulIDLen, HANDLE *phHash); ++ typedef ULONG (*SKF_ECCSignData_Func)(HCONTAINER hContainer, BYTE *pbData, ULONG ulDataLen, PECCSIGNATUREBLOB pSignature); ++ typedef ULONG (*SKF_ECCVerify_Func)(DEVHANDLE hDev, ECCPUBLICKEYBLOB *pECCPubKeyBlob, BYTE *pbData, ++ ULONG ulDataLen, PECCSIGNATUREBLOB pSignature); ++ ++ typedef ULONG (*SKF_GenRandom_Func)(DEVHANDLE hDev, BYTE *pbRandom, ULONG ulRandomLen); ++ typedef ULONG (*SKF_SetSymmKey_Func)(DEVHANDLE hDev, BYTE *pbKey, ULONG ulAlgID, HANDLE *phKey); ++ typedef ULONG (*SKF_EncryptInit_Func)(HANDLE hKey, BLOCKCIPHERPARAM EncryptParam); ++ typedef ULONG (*SKF_Encrypt_Func)(HANDLE hKey, BYTE *pbData, ULONG ulDataLen, BYTE *pbEncryptedData, ULONG *pulEncryptedLen); ++ typedef ULONG (*SKF_DevAuth_Func)(DEVHANDLE hDev, BYTE *pbAuthData, ULONG ulLen); ++ typedef ULONG (*SKF_DeleteApplication_Func)(DEVHANDLE hDev, LPSTR szAppName); ++ typedef ULONG (*SKF_CreateContainer_Func)(HAPPLICATION hApplication, LPSTR szContainerName, HCONTAINER *phContainer); ++} ++ ++struct DriverLib ++{ ++ SKF_EnumDev_Func SKF_EnumDev; ++ SKF_ConnectDev_Func SKF_ConnectDev; ++ SKF_DisConnectDev_Func SKF_DisConnectDev; ++ SKF_GetDevState_Func SKF_GetDevState; ++ SKF_GetDevInfo_Func SKF_GetDevInfo; ++ SKF_SetLabel_Func SKF_SetLabel; ++ SKF_OpenApplication_Func SKF_OpenApplication; ++ SKF_VerifyPIN_Func SKF_VerifyPIN; ++ SKF_OpenContainer_Func SKF_OpenContainer; ++ SKF_GenECCKeyPair_Func SKF_GenECCKeyPair; ++ SKF_CloseContainer_Func SKF_CloseContainer; ++ SKF_CloseApplication_Func SKF_CloseApplication; ++ SKF_CreateApplication_Func SKF_CreateApplication; ++ SKF_EnumApplication_Func SKF_EnumApplication; ++ SKF_ExportPublicKey_Func SKF_ExportPublicKey; ++ SKF_Digest_Func SKF_Digest; ++ SKF_DigestInit_Func SKF_DigestInit; ++ SKF_ECCSignData_Func SKF_ECCSignData; ++ SKF_ECCVerify_Func SKF_ECCVerify; ++ SKF_GenRandom_Func SKF_GenRandom; ++ SKF_SetSymmKey_Func SKF_SetSymmKey; ++ SKF_EncryptInit_Func SKF_EncryptInit; ++ SKF_Encrypt_Func SKF_Encrypt; ++ SKF_DevAuth_Func SKF_DevAuth; ++ SKF_DeleteApplication_Func SKF_DeleteApplication; ++ SKF_CreateContainer_Func SKF_CreateContainer; ++}; ++ ++UKeySKFDriver::UKeySKFDriver(QObject *parent) : BDriver(parent) ++{ ++} ++ ++UKeySKFDriver::~UKeySKFDriver() ++{ ++ if (m_libHandle) ++ { ++ dlclose(m_libHandle); ++ m_libHandle = NULL; ++ } ++} ++ ++QString UKeySKFDriver::getName() ++{ ++ return QString(); ++} ++QString UKeySKFDriver::getFullName() ++{ ++ return QString(); ++} ++quint16 UKeySKFDriver::getDriverId() ++{ ++ return 0; ++} ++ ++bool UKeySKFDriver::loadLibrary(QString libPath) ++{ ++ if (!QFile::exists(UKEY_DEFAULT_CONFIG)) ++ { ++ return false; ++ } ++ ++ m_libHandle = dlopen(libPath.toStdString().c_str(), RTLD_NOW); ++ if (m_libHandle == nullptr) ++ { ++ KLOG_ERROR() << "Load ukey lib failed,error:" << dlerror(); ++ return false; ++ } ++ ++ m_driverLib = QSharedPointer(new DriverLib); ++ m_driverLib->SKF_EnumDev = (SKF_EnumDev_Func)dlsym(m_libHandle, "SKF_EnumDev"); ++ m_driverLib->SKF_ConnectDev = (SKF_ConnectDev_Func)dlsym(m_libHandle, "SKF_ConnectDev"); ++ m_driverLib->SKF_DisConnectDev = (SKF_DisConnectDev_Func)dlsym(m_libHandle, "SKF_DisConnectDev"); ++ m_driverLib->SKF_GetDevState = (SKF_GetDevState_Func)dlsym(m_libHandle, "SKF_GetDevState"); ++ m_driverLib->SKF_GetDevInfo = (SKF_GetDevInfo_Func)dlsym(m_libHandle, "SKF_GetDevInfo"); ++ m_driverLib->SKF_SetLabel = (SKF_SetLabel_Func)dlsym(m_libHandle, "SKF_SetLabel"); ++ m_driverLib->SKF_OpenApplication = (SKF_OpenApplication_Func)dlsym(m_libHandle, "SKF_OpenApplication"); ++ m_driverLib->SKF_VerifyPIN = (SKF_VerifyPIN_Func)dlsym(m_libHandle, "SKF_VerifyPIN"); ++ m_driverLib->SKF_OpenContainer = (SKF_OpenContainer_Func)dlsym(m_libHandle, "SKF_OpenContainer"); ++ m_driverLib->SKF_GenECCKeyPair = (SKF_GenECCKeyPair_Func)dlsym(m_libHandle, "SKF_GenECCKeyPair"); ++ m_driverLib->SKF_CloseContainer = (SKF_CloseContainer_Func)dlsym(m_libHandle, "SKF_CloseContainer"); ++ m_driverLib->SKF_CloseApplication = (SKF_CloseApplication_Func)dlsym(m_libHandle, "SKF_CloseApplication"); ++ m_driverLib->SKF_CreateApplication = (SKF_CreateApplication_Func)dlsym(m_libHandle, "SKF_CreateApplication"); ++ m_driverLib->SKF_EnumApplication = (SKF_EnumApplication_Func)dlsym(m_libHandle, "SKF_EnumApplication"); ++ m_driverLib->SKF_ExportPublicKey = (SKF_ExportPublicKey_Func)dlsym(m_libHandle, "SKF_ExportPublicKey"); ++ m_driverLib->SKF_Digest = (SKF_Digest_Func)dlsym(m_libHandle, "SKF_Digest"); ++ m_driverLib->SKF_DigestInit = (SKF_DigestInit_Func)dlsym(m_libHandle, "SKF_DigestInit"); ++ m_driverLib->SKF_ECCSignData = (SKF_ECCSignData_Func)dlsym(m_libHandle, "SKF_ECCSignData"); ++ m_driverLib->SKF_ECCVerify = (SKF_ECCVerify_Func)dlsym(m_libHandle, "SKF_ECCVerify"); ++ m_driverLib->SKF_GenRandom = (SKF_GenRandom_Func)dlsym(m_libHandle, "SKF_GenRandom"); ++ m_driverLib->SKF_SetSymmKey = (SKF_SetSymmKey_Func)dlsym(m_libHandle, "SKF_SetSymmKey"); ++ m_driverLib->SKF_EncryptInit = (SKF_EncryptInit_Func)dlsym(m_libHandle, "SKF_EncryptInit"); ++ m_driverLib->SKF_Encrypt = (SKF_Encrypt_Func)dlsym(m_libHandle, "SKF_Encrypt"); ++ m_driverLib->SKF_DevAuth = (SKF_DevAuth_Func)dlsym(m_libHandle, "SKF_DevAuth"); ++ m_driverLib->SKF_DeleteApplication = (SKF_DeleteApplication_Func)dlsym(m_libHandle, "SKF_DeleteApplication"); ++ m_driverLib->SKF_CreateContainer = (SKF_CreateContainer_Func)dlsym(m_libHandle, "SKF_CreateContainer"); ++ ++ return true; ++} ++ ++DEVHANDLE UKeySKFDriver::connectDev() ++{ ++ ULONG ulBufSize = 0; ++ ULONG ulReval = m_driverLib->SKF_EnumDev(TRUE, NULL, &ulBufSize); ++ ++ if (ulReval != SAR_OK) ++ { ++ KLOG_DEBUG() << "Enum Dev error:" << getErrorReason(ulReval); ++ return nullptr; ++ } ++ ++ LPSTR szNameList = (LPSTR)malloc(ulBufSize * sizeof(CHAR)); ++ memset(szNameList, '\0', ulBufSize); ++ ulReval = m_driverLib->SKF_EnumDev(TRUE, szNameList, &ulBufSize); ++ if (ulReval == SAR_OK) ++ { ++ LPSTR pszTemp = szNameList; ++ if (NULL == pszTemp) ++ { ++ KLOG_DEBUG() << "no found ukey device"; ++ return nullptr; ++ } ++ while (*pszTemp != '\0') ++ { ++ DEVHANDLE devHandle; ++ ulReval = m_driverLib->SKF_ConnectDev(pszTemp, &devHandle); ++ if (SAR_OK == ulReval) ++ { ++ return devHandle; ++ } ++ else ++ { ++ KLOG_ERROR() << "Connect Dev failed:" << getErrorReason(ulReval); ++ } ++ pszTemp += strlen((const char *)pszTemp) + 1; ++ } ++ } ++ free(szNameList); ++ return nullptr; ++} ++ ++void UKeySKFDriver::deleteAllApplication(DEVHANDLE devHandle) ++{ ++ ULONG ulReval = SAR_FAIL; ++ char szAppNames[256] = {0}; ++ ULONG ulSize = 256; ++ ++ ulReval = m_driverLib->SKF_EnumApplication(devHandle, (LPSTR)szAppNames, &ulSize); ++ if (SAR_OK == ulReval) ++ { ++ char *pszTemp = szAppNames; ++ if (*pszTemp == '\0') ++ { ++ m_driverLib->SKF_DeleteApplication(devHandle, (LPSTR)pszTemp); ++ } ++ ++ while (*pszTemp != '\0') ++ { ++ m_driverLib->SKF_DeleteApplication(devHandle, (LPSTR)pszTemp); ++ pszTemp += strlen((const char *)pszTemp) + 1; ++ } ++ } ++ KLOG_DEBUG() << "clear all application"; ++} ++ ++QString UKeySKFDriver::enumApplication(DEVHANDLE devHandle) ++{ ++ char szAppNames[256] = {0}; ++ ULONG ulSize = 256; ++ ULONG ret = m_driverLib->SKF_EnumApplication(devHandle, (LPSTR)szAppNames, &ulSize); ++ if (ret == SAR_OK) ++ { ++ QString appNames(szAppNames); ++ KLOG_DEBUG() << "enum app names:" << appNames; ++ return appNames; ++ } ++ else ++ { ++ return QString(); ++ } ++} ++ ++ULONG UKeySKFDriver::devAuth(DEVHANDLE devHandle) ++{ ++ BYTE random[16] = {0}; ++ BYTE devKey[16] = {0}; ++ BLOCKCIPHERPARAM param = {0}; ++ BYTE devkeyenc[16] = {0}; ++ ULONG dwResultLen = 16; ++ ULONG ulReval; ++ DEVINFO devInfo; ++ HANDLE hSessionKey; ++ ++ QString defaultDevKey = getDefaultValueFromConf(CONF_DEFAULT_KEY_DEV_KEY); ++ QByteArray byteArray = defaultDevKey.toLatin1(); ++ unsigned char *key = (unsigned char *)byteArray.data(); ++ ++ memcpy(devKey, key, 16); ++ ++ ulReval = m_driverLib->SKF_GenRandom(devHandle, random, 8); ++ if (SAR_OK != ulReval) ++ return ulReval; ++ ++ ulReval = m_driverLib->SKF_GetDevInfo(devHandle, &devInfo); ++ if (SAR_OK != ulReval) ++ return ulReval; ++ ++ ulReval = m_driverLib->SKF_SetSymmKey(devHandle, devKey, devInfo.DevAuthAlgId, &hSessionKey); ++ if (SAR_OK != ulReval) ++ return ulReval; ++ ++ ulReval = m_driverLib->SKF_EncryptInit(hSessionKey, param); ++ if (SAR_OK != ulReval) ++ return ulReval; ++ ++ ulReval = m_driverLib->SKF_Encrypt(hSessionKey, random, 16, devkeyenc, &dwResultLen); ++ if (SAR_OK != ulReval) ++ return ulReval; ++ ++ ulReval = m_driverLib->SKF_DevAuth(devHandle, devkeyenc, 16); ++ ++ return ulReval; ++} ++ ++HAPPLICATION UKeySKFDriver::onOpenApplication(DEVHANDLE devHandle, LPSTR szAppName) ++{ ++ HAPPLICATION phApplication = nullptr; ++ ULONG ret = m_driverLib->SKF_OpenApplication(devHandle, szAppName, &phApplication); ++ if (ret != SAR_OK) ++ { ++ KLOG_DEBUG() << "open Application failed:" << getErrorReason(ret); ++ return nullptr; ++ } ++ return phApplication; ++} ++ ++HCONTAINER UKeySKFDriver::onOpenContainer(HAPPLICATION appHandle, const QString &pin, QString containerName, ULONG *retryCount) ++{ ++ QByteArray byteArray = pin.toLatin1(); ++ unsigned char *szPIN = (unsigned char *)byteArray.data(); ++ ULONG ret = m_driverLib->SKF_VerifyPIN(appHandle, USER_TYPE, szPIN, retryCount); ++ if (ret == SAR_OK) ++ { ++ HCONTAINER containerHandle = nullptr; ++ ret = m_driverLib->SKF_OpenContainer(appHandle, (LPSTR)containerName.data(), &containerHandle); ++ if (ret == SAR_OK) ++ { ++ KLOG_DEBUG() << "open container success"; ++ return containerHandle; ++ } ++ else ++ { ++ KLOG_ERROR() << "open container failed:" << getErrorReason(ret); ++ } ++ } ++ else ++ { ++ KLOG_DEBUG() << "Verify PIN failed:" << getErrorReason(ret); ++ KLOG_DEBUG() << "Retry Count:" << retryCount; ++ } ++ return nullptr; ++} ++ ++void UKeySKFDriver::closeApplication(HAPPLICATION appHandle) ++{ ++ m_driverLib->SKF_CloseApplication(appHandle); ++} ++void UKeySKFDriver::closeContainer(HCONTAINER containerHandle) ++{ ++ m_driverLib->SKF_CloseContainer(containerHandle); ++} ++ ++void UKeySKFDriver::disConnectDev(DEVHANDLE devHandle) ++{ ++ m_driverLib->SKF_DisConnectDev(devHandle); ++} ++ ++HAPPLICATION UKeySKFDriver::createApplication(DEVHANDLE devHandle, QString pin, QString appName) ++{ ++ QByteArray pinArray = pin.toLatin1(); ++ unsigned char *userPin = (unsigned char *)pinArray.data(); ++ ++ QByteArray appNameArray = appName.toLatin1(); ++ unsigned char *szAppName = (unsigned char *)appNameArray.data(); ++ ++ QString defaultAdminPin = getDefaultValueFromConf(CONF_DEFAULT_KEY_ADMIN_PINCODE); ++ QByteArray byteArray = defaultAdminPin.toLatin1(); ++ unsigned char *adminPIn = (unsigned char *)byteArray.data(); ++ ++ HAPPLICATION appHandle = nullptr; ++ ULONG ulReval = m_driverLib->SKF_CreateApplication(devHandle, szAppName, adminPIn, ++ ADMIN_PIN_RETRY_COUNT, userPin, USER_PIN_RETRY_COUNT, ++ SECURE_USER_ACCOUNT, &appHandle); ++ ULONG retryCount; ++ if (ulReval != SAR_OK) ++ { ++ KLOG_ERROR() << "create application failed:" << getErrorReason(ulReval); ++ return nullptr; ++ } ++ ++ return appHandle; ++} ++ ++HCONTAINER UKeySKFDriver::createContainer(HAPPLICATION appHandle, QString pin, QString containerName, ULONG *retryCount) ++{ ++ QByteArray byteArray = pin.toLatin1(); ++ unsigned char *userPin = (unsigned char *)byteArray.data(); ++ ULONG ulReval = m_driverLib->SKF_VerifyPIN(appHandle, USER_TYPE, userPin, retryCount); ++ if (ulReval != SAR_OK) ++ { ++ KLOG_ERROR() << "verifyPin failed:" << getErrorReason(ulReval); ++ return nullptr; ++ } ++ ++ HCONTAINER containerHandle = nullptr; ++ ulReval = m_driverLib->SKF_CreateContainer(appHandle, (LPSTR)containerName.data(), &containerHandle); ++ if (ulReval != SAR_OK) ++ { ++ KLOG_ERROR() << "create container failed:" << getErrorReason(ulReval); ++ return nullptr; ++ } ++ KLOG_DEBUG() << "create new application and container success"; ++ return containerHandle; ++} ++ ++ULONG UKeySKFDriver::genECCKeyPair(HCONTAINER containerHandle, ECCPUBLICKEYBLOB *pBlob) ++{ ++ return m_driverLib->SKF_GenECCKeyPair(containerHandle, SGD_SM2_1, pBlob); ++} ++ ++ULONG UKeySKFDriver::authSignData(HCONTAINER containerHandle, DEVHANDLE devHandle, ECCSIGNATUREBLOB &Signature) ++{ ++ unsigned char *pPubKey = NULL; ++ ULONG ulPubKeyLen = 0; ++ ECCPUBLICKEYBLOB EccPubKey = {0}; ++ unsigned char pucId[32] = {0}; ++ ULONG ulIdLen = 16; ++ HANDLE hHash = nullptr; ++ ULONG ulHashLen = 64; ++ int signDataLen = strlen(SIGN_DATA); ++ unsigned char pbHashData[33] = {0}; ++ ++ QString defaultPucId = getDefaultValueFromConf(CONF_DEFAULT_KEY_PUC_ID); ++ QByteArray byteArray = defaultPucId.toLatin1(); ++ unsigned char *PUC_ID = (unsigned char *)byteArray.data(); ++ ++ ULONG ret = m_driverLib->SKF_ExportPublicKey(containerHandle, TRUE, pPubKey, &ulPubKeyLen); ++ if (ret != SAR_OK) ++ { ++ goto end; ++ } ++ ++ pPubKey = (unsigned char *)malloc(ulPubKeyLen); ++ if (pPubKey == NULL) ++ { ++ goto end; ++ } ++ ++ ret = m_driverLib->SKF_ExportPublicKey(containerHandle, TRUE, pPubKey, &ulPubKeyLen); ++ if (ret != SAR_OK) ++ { ++ goto end; ++ } ++ ++ if (ulPubKeyLen != sizeof(ECCPUBLICKEYBLOB)) ++ { ++ goto end; ++ } ++ ++ memcpy(&EccPubKey, pPubKey, ulPubKeyLen); ++ memcpy(pucId, PUC_ID, 16); ++ ++ ret = m_driverLib->SKF_DigestInit(devHandle, SGD_SM3, &EccPubKey, pucId, ulIdLen, &hHash); ++ if (ret != SAR_OK) ++ { ++ goto end; ++ } ++ ++ ret = m_driverLib->SKF_Digest(hHash, (BYTE *)SIGN_DATA, signDataLen, pbHashData, &ulHashLen); ++ if (ret != SAR_OK) ++ { ++ goto end; ++ } ++ ++ ret = m_driverLib->SKF_ECCSignData(containerHandle, pbHashData, ulHashLen, &Signature); ++ ++end: ++ getErrorReason(ret); ++ return ret; ++} ++ ++ULONG UKeySKFDriver::verifyData(DEVHANDLE devHandle, ECCSIGNATUREBLOB &Signature, ECCPUBLICKEYBLOB &publicKey) ++{ ++ unsigned char *pbInData = NULL, pbHashData[33] = {0}, pbOutData[256] = {0}; ++ ULONG ulInLen = 0, ulOutLen = 0, ulHashLen = 0, ulIdLen = 7; ++ unsigned char pucId[32] = {0}; ++ HANDLE hHash; ++ ULONG ulPubKeyLen = 0; ++ int signDataLen = strlen(SIGN_DATA); ++ QString defaultPucId = getDefaultValueFromConf(CONF_DEFAULT_KEY_PUC_ID); ++ QByteArray byteArray = defaultPucId.toLatin1(); ++ unsigned char *PUC_ID = (unsigned char *)byteArray.data(); ++ ++ memcpy(pucId, PUC_ID, 16); ++ ulIdLen = 16; ++ ULONG ulReval = m_driverLib->SKF_DigestInit(devHandle, SGD_SM3, &publicKey, pucId, ulIdLen, &hHash); ++ if (ulReval != SAR_OK) ++ { ++ goto end; ++ } ++ ++ ulHashLen = 64; ++ ulReval = m_driverLib->SKF_Digest(hHash, (BYTE *)SIGN_DATA, signDataLen, pbHashData, &ulHashLen); ++ if (ulReval != SAR_OK) ++ { ++ goto end; ++ } ++ ++ ulReval = m_driverLib->SKF_ECCVerify(devHandle, &publicKey, pbHashData, ulHashLen, &Signature); ++ ++end: ++ getErrorReason(ulReval); ++ return ulReval; ++} ++ ++QString UKeySKFDriver::getErrorReason(ULONG error) ++{ ++ for (int i = 0; i < sizeof(skf_errors) / sizeof(skf_errors[0]); i++) ++ { ++ if (error == skf_errors[i].err) ++ { ++ return skf_errors[i].reason; ++ } ++ } ++ return QString(); ++} ++ ++QString UKeySKFDriver::getDefaultValueFromConf(const QString &key) ++{ ++ QSettings confSettings(UKEY_DEFAULT_CONFIG, QSettings::NativeFormat); ++ QVariant value = confSettings.value(QString("default/%1").arg(key)); ++ return value.toString(); ++} ++ ++} // namespace Kiran +diff --git a/src/driver/ukey/ukey-skf-driver.h b/src/driver/ukey/ukey-skf-driver.h +new file mode 100644 +index 0000000..4952ff6 +--- /dev/null ++++ b/src/driver/ukey/ukey-skf-driver.h +@@ -0,0 +1,62 @@ ++/** ++ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd. ++ * kiran-biometrics is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ * ++ * Author: luoqing ++ */ ++#pragma once ++#include "driver/driver.h" ++#include "ukey-skf.h" ++#include ++ ++namespace Kiran ++{ ++struct DriverLib; ++ ++class UKeySKFDriver : public BDriver ++{ ++public: ++ UKeySKFDriver(QObject *parent = nullptr); ++ ~UKeySKFDriver(); ++ QString getName() override; ++ QString getFullName() override; ++ quint16 getDriverId() override; ++ ++ bool loadLibrary(QString libPath); ++ DEVHANDLE connectDev(); ++ void deleteAllApplication(DEVHANDLE devHandle); ++ QString enumApplication(DEVHANDLE devHandle); ++ ++ ULONG devAuth(DEVHANDLE devHandle); ++ HAPPLICATION onOpenApplication(DEVHANDLE hDev, LPSTR szAppName); ++ HCONTAINER onOpenContainer(HAPPLICATION appHandle,const QString &pin,QString containerName,ULONG *retryCount); ++ ++ void closeApplication(HAPPLICATION appHandle); ++ void closeContainer(HCONTAINER containerHandle); ++ void disConnectDev(DEVHANDLE devHandle); ++ ++ HAPPLICATION createApplication(DEVHANDLE devHandle,QString pin,QString appName); ++ HCONTAINER createContainer(HAPPLICATION appHandle, QString pin,QString containerName,ULONG *retryCount); ++ ++ ULONG genECCKeyPair(HCONTAINER containerHandle,ECCPUBLICKEYBLOB *pBlob); ++ ++ ULONG authSignData(HCONTAINER containerHandle,DEVHANDLE devHandle,ECCSIGNATUREBLOB &Signature); ++ ULONG verifyData(DEVHANDLE devHandle,ECCSIGNATUREBLOB &Signature, ECCPUBLICKEYBLOB &publicKey); ++ ++ QString getErrorReason(ULONG error); ++ ++ QString getDefaultValueFromConf(const QString &key); ++ ++private: ++ QSharedPointer m_driverLib; ++ HANDLE m_libHandle; ++}; ++ ++} // namespace Kiran +\ No newline at end of file +diff --git a/translations/kiran-authentication-devices.zh_CN.ts b/translations/kiran-authentication-devices.zh_CN.ts +index 40aef0a..540aadb 100644 +--- a/translations/kiran-authentication-devices.zh_CN.ts ++++ b/translations/kiran-authentication-devices.zh_CN.ts +@@ -4,63 +4,69 @@ + + Kiran::AuthDevice + +- +- ++ ++ + Device Busy + 设备忙 + + +- ++ + feature has reached the upper limit of %1 + 录入的特征已达上限 %1 + ++ ++ ++ ++ The pin code cannot be empty! ++ pin码不能为空! ++ + + + Kiran::FPZKDevice + +- +- ++ ++ + acquire fingerprint fail! + 获取指纹失败! + + +- ++ + Partial fingerprint feature entry + 录入部分指纹特征 + + +- ++ + The fingerprint has been enrolled + 指纹重复录入 + + +- ++ + Please place the same finger! + 请放置相同的手指! + + +- +- ++ ++ + Failed to enroll fingerprint, please enroll again + 录入指纹失败,请重新录入 + + +- ++ + Successed save finger + 录入指纹成功 + + +- ++ + Save Finger Failed! + 录入指纹失败! + + +- ++ + Fingerprint match + 指纹匹配 + + +- ++ + Fingerprint not match, place again + 指纹不匹配,请重试 + +@@ -68,52 +74,52 @@ + + Kiran::FVSDDevice + +- ++ + Finger vein image not obtained + 未获取到指静脉图像 + + +- ++ + Partial finger vein feature entry + 录入部分指静脉特征 + + +- ++ + The finger vein has been enrolled + 指静脉重复录入 + + +- ++ + Please place the same finger! + 请放置相同的手指! + + +- ++ + Finger vein template merged failed + 指静脉模板融合失败 + + +- ++ + Successed save feature + 录入特征成功 + + +- ++ + Save Feature Failed! + 录入特征失败! + + +- ++ + timeout, acquire finger vein fail! + 超时,获取指静脉失败! + + +- ++ + Feature Match + 特征匹配 + + +- ++ + Feature not match, place again + 特征不匹配,请重试 + +@@ -126,4 +132,32 @@ + 授权失败. + + ++ ++ Kiran::UKeyFTDevice ++ ++ ++ Successed binding user ++ 绑定用户成功 ++ ++ ++ ++ Binding user failed ++ 绑定用户失败 ++ ++ ++ ++ UKey has been bound ++ UKey已经被绑定 ++ ++ ++ ++ identify fail! ++ 认证失败! ++ ++ ++ ++ identify ukey success ++ ukey认证成功 ++ ++ + +-- +2.33.0 + diff --git a/kiran-authentication-devices.spec b/kiran-authentication-devices.spec index 4deffa0..b608b2b 100644 --- a/kiran-authentication-devices.spec +++ b/kiran-authentication-devices.spec @@ -1,12 +1,14 @@ Name: kiran-authentication-devices Version: 2.5.0 -Release: 1 +Release: 2 Summary: Kiran Authentication Devices License: MulanPSL-2.0 Source0: %{name}-%{version}.tar.gz +Patch0001: 0001-feature-ukey-The-UKey-device-is-adapted.patch + BuildRequires: cmake BuildRequires: gcc-c++ BuildRequires: qt5-qtbase-devel @@ -61,5 +63,8 @@ systemctl enable kiran-authentication-devices.service rm -rf ${buildroot} %changelog +* Wed Apr 19 2023 luoqing - 2.5.0-2 +- KYOS-F: The UKey device is adapted. + * Mon Apr 03 2023 luoqing - 2.5.0-1 - Inital build