From 0b0d3a5df1371acb3c5059a2c5834ec8c9c5843a Mon Sep 17 00:00:00 2001 From: luoqing Date: Fri, 2 Jun 2023 16:58:45 +0800 Subject: [PATCH] fix(ukey):Fix the issue where only one ukey can be bound to a device;Fix some self-test bugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复一台设备只能绑一个ukey的问题 修复一些自测缺陷 Closes #I78P3F --- ...-issue-where-only-one-ukey-can-be-bo.patch | 1430 +++++++++++++++++ kiran-authentication-devices.spec | 6 +- 2 files changed, 1435 insertions(+), 1 deletion(-) create mode 100644 0001-fix-ukey-Fix-the-issue-where-only-one-ukey-can-be-bo.patch diff --git a/0001-fix-ukey-Fix-the-issue-where-only-one-ukey-can-be-bo.patch b/0001-fix-ukey-Fix-the-issue-where-only-one-ukey-can-be-bo.patch new file mode 100644 index 0000000..bcc3cad --- /dev/null +++ b/0001-fix-ukey-Fix-the-issue-where-only-one-ukey-can-be-bo.patch @@ -0,0 +1,1430 @@ +From 80f7c120db60ba057a6d3ba673fc3daafe3f2a8b Mon Sep 17 00:00:00 2001 +From: luoqing +Date: Fri, 26 May 2023 16:01:55 +0800 +Subject: [PATCH] fix(ukey):Fix the issue where only one ukey can be bound to a + device;Fix some self-test bugs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +- 修复一台设备只能绑一个ukey的问题 + 修复一些自测缺陷 + + Closes #I78P3F +--- + CMakeLists.txt | 18 +- + data/com.kylinsec.Kiran.AuthDevice.Device.xml | 4 +- + src/auth-device-manager.cpp | 116 ++++--- + src/context/context.h | 4 - + src/context/finger-vein/fv-sd-context.cpp | 1 - + src/context/fingerprint/fp-zk-context.cpp | 1 - + src/context/multi-function-context.cpp | 2 - + src/context/ukey/ukey-ft-context.cpp | 1 - + src/device/auth-device.cpp | 2 +- + src/device/auth-device.h | 3 + + src/device/bio-device.cpp | 2 +- + src/device/finger-vein/fv-sd-device.cpp | 2 +- + src/device/fingerprint/fp-zk-device.cpp | 2 +- + src/device/ukey/ukey-ft-device.cpp | 321 ++++++++++-------- + src/device/ukey/ukey-ft-device.h | 30 +- + .../multi-function/mf-iristar-driver.cpp | 2 +- + src/driver/ukey/ukey-skf-driver.cpp | 149 ++++++-- + src/driver/ukey/ukey-skf-driver.h | 10 +- + src/feature-db.cpp | 38 ++- + src/feature-db.h | 24 +- + ukey-manager/ukey-manager.cpp | 26 +- + 21 files changed, 460 insertions(+), 298 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index e198c84..122d4be 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,11 +1,3 @@ +-set(CMAKE_INCLUDE_CURRENT_DIR ON) +- +-set(CMAKE_AUTOUIC ON) +-set(CMAKE_AUTOMOC ON) +-set(CMAKE_AUTORCC ON) +- +-set(CMAKE_CXX_STANDARD 11) +-set(CMAKE_CXX_STANDARD_REQUIRED ON) + + cmake_minimum_required(VERSION 3.2) + +@@ -17,10 +9,18 @@ find_package(PkgConfig REQUIRED) + find_package(Qt5 REQUIRED COMPONENTS Core DBus Sql Concurrent LinguistTools) + pkg_search_module(KLOG_QT5 REQUIRED klog-qt5) + ++set(CMAKE_INCLUDE_CURRENT_DIR ON) ++ ++set(CMAKE_AUTOUIC ON) ++set(CMAKE_AUTOMOC ON) ++set(CMAKE_AUTORCC ON) ++ ++set(CMAKE_CXX_STANDARD 11) ++set(CMAKE_CXX_STANDARD_REQUIRED ON) ++ + set(TRANSLATION_INSTALL_DIR ${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/translations) + configure_file(${CMAKE_SOURCE_DIR}/data/config.h.in ${CMAKE_BINARY_DIR}/config.h) + +- + add_subdirectory(src) + add_subdirectory(data) + add_subdirectory(ukey-manager) +diff --git a/data/com.kylinsec.Kiran.AuthDevice.Device.xml b/data/com.kylinsec.Kiran.AuthDevice.Device.xml +index ad41a33..9b22600 100644 +--- a/data/com.kylinsec.Kiran.AuthDevice.Device.xml ++++ b/data/com.kylinsec.Kiran.AuthDevice.Device.xml +@@ -55,7 +55,7 @@ + A number between 0 and 100 to describe the progress of enrolling fingerprint. 0 is failed + + +- Represent the status of the enrollment. Refer to enum DeviceType in file kiran-auth-device-i.h ++ Represent the status of the enrollment. Refer to enum EnrollStatus in file kiran-auth-device-i.h + + + Status description information. +@@ -67,7 +67,7 @@ + Feature ID. + + +- Represent the status of the identification. Refer to enum DeviceType in file kiran-auth-device-i.h. ++ Represent the status of the identification. Refer to enum IdentifyStatus in file kiran-auth-device-i.h. + + + Status description information. +diff --git a/src/auth-device-manager.cpp b/src/auth-device-manager.cpp +index ab9a0df..5c7577b 100644 +--- a/src/auth-device-manager.cpp ++++ b/src/auth-device-manager.cpp +@@ -25,6 +25,7 @@ + #include "kiran-auth-device-i.h" + #include "polkit-proxy.h" + #include "utils.h" ++#include "device/ukey/ukey-ft-device.h" + + namespace Kiran + { +@@ -147,11 +148,30 @@ QString AuthDeviceManager::GetDriversByType(int device_type) + + void AuthDeviceManager::onRemove(const QDBusMessage& message, const QString& feature_id) + { ++ FeatureInfo featureInfo = FeatureDB::getInstance()->getFeatureInfo(feature_id); + bool result = FeatureDB::getInstance()->deleteFeature(feature_id); + KLOG_DEBUG() << "deleteFeature:" << feature_id + << "exec:" << result; + auto replyMessage = message.createReply(); + QDBusConnection::systemBus().send(replyMessage); ++ ++ if (featureInfo.deviceType == DEVICE_TYPE_UKey) ++ { ++ AuthDeviceList deviceList = m_deviceMap.values(); ++ for (auto device : deviceList) ++ { ++ if (device->deviceType() != DEVICE_TYPE_UKey) ++ { ++ continue; ++ } ++ auto ukeyDevice = qobject_cast(device); ++ if (ukeyDevice->deviceSerialNumber() != featureInfo.deviceSerialNumber) ++ { ++ continue; ++ } ++ ukeyDevice->resetUkey(); ++ } ++ } + } + + // TODO:是否需要监听配置文件的改变 +@@ -297,27 +317,30 @@ void AuthDeviceManager::handleDeviceDeleted() + int deviceType; + Q_FOREACH (auto busPath, oldBusList) + { +- if (!newBusList.contains(busPath)) ++ if (newBusList.contains(busPath)) + { +- AuthDevicePtr oldAuthDevice = m_deviceMap.value(busPath); +- deviceID = oldAuthDevice->deviceID(); +- deviceType = oldAuthDevice->deviceType(); +- m_deviceMap.remove(busPath); ++ continue; ++ } ++ ++ AuthDevicePtr oldAuthDevice = m_deviceMap.value(busPath); ++ deviceID = oldAuthDevice->deviceID(); ++ deviceType = oldAuthDevice->deviceType(); ++ int removeCount = m_deviceMap.remove(busPath); ++ oldAuthDevice.clear(); ++ Q_EMIT m_dbusAdaptor->DeviceDeleted(deviceType, deviceID); + +- QMapIterator i(m_retreyCreateDeviceMap); +- while (i.hasNext()) ++ QMapIterator i(m_retreyCreateDeviceMap); ++ while (i.hasNext()) ++ { ++ i.next(); ++ if (i.key().busPath == busPath) + { +- i.next(); +- if (i.key().busPath == busPath) +- { +- m_retreyCreateDeviceMap.remove(i.key()); +- } ++ m_retreyCreateDeviceMap.remove(i.key()); + } +- KLOG_DEBUG() << "device delete: " << busPath; +- break; + } ++ KLOG_DEBUG() << "device delete: " << busPath; ++ break; + } +- Q_EMIT m_dbusAdaptor->DeviceDeleted(deviceType, deviceID); + } + + void AuthDeviceManager::handleDeviceReCreate() +@@ -325,43 +348,40 @@ void AuthDeviceManager::handleDeviceReCreate() + if (m_retreyCreateDeviceMap.count() == 0) + { + m_timer.stop(); ++ return; + } +- else ++ ++ QMapIterator i(m_retreyCreateDeviceMap); ++ while (i.hasNext()) + { +- QMapIterator i(m_retreyCreateDeviceMap); +- while (i.hasNext()) ++ i.next(); ++ if (i.value() >= 2) + { +- i.next(); +- if (i.value() >= 2) +- { +- m_retreyCreateDeviceMap.remove(i.key()); +- } +- else +- { +- auto deviceInfo = i.key(); +- AuthDeviceList deviceList = m_contextFactory->createDevices(deviceInfo.idVendor, deviceInfo.idProduct); +- if (deviceList.count() != 0) +- { +- Q_FOREACH (auto device, deviceList) +- { +- m_deviceMap.insert(deviceInfo.busPath, device); +- Q_EMIT this->DeviceAdded(device->deviceType(), device->deviceID()); +- Q_EMIT m_dbusAdaptor->DeviceAdded(device->deviceType(), device->deviceID()); +- +- KLOG_DEBUG() << "device added" +- << "idVendor:" << deviceInfo.idVendor +- << "idProduct:" << deviceInfo.idProduct +- << "bus:" << deviceInfo.busPath; +- } +- +- m_retreyCreateDeviceMap.remove(i.key()); +- } +- else +- { +- m_retreyCreateDeviceMap.insert(i.key(), i.value() + 1); +- } +- } ++ m_retreyCreateDeviceMap.remove(i.key()); ++ continue; ++ } ++ ++ auto deviceInfo = i.key(); ++ AuthDeviceList deviceList = m_contextFactory->createDevices(deviceInfo.idVendor, deviceInfo.idProduct); ++ if (deviceList.count() == 0) ++ { ++ m_retreyCreateDeviceMap.insert(i.key(), i.value() + 1); ++ continue; + } ++ ++ Q_FOREACH (auto device, deviceList) ++ { ++ m_deviceMap.insert(deviceInfo.busPath, device); ++ Q_EMIT this->DeviceAdded(device->deviceType(), device->deviceID()); ++ Q_EMIT m_dbusAdaptor->DeviceAdded(device->deviceType(), device->deviceID()); ++ ++ KLOG_DEBUG() << "device added" ++ << "idVendor:" << deviceInfo.idVendor ++ << "idProduct:" << deviceInfo.idProduct ++ << "bus:" << deviceInfo.busPath; ++ } ++ ++ m_retreyCreateDeviceMap.remove(i.key()); + } + } + } // namespace Kiran +diff --git a/src/context/context.h b/src/context/context.h +index 2043f82..fd6a3ff 100644 +--- a/src/context/context.h ++++ b/src/context/context.h +@@ -29,11 +29,7 @@ class Context : public QObject + public: + explicit Context(QObject *parent = nullptr); + virtual AuthDevicePtr createDevice(const QString &idVendor, const QString &idProduct) = 0; +- virtual AuthDeviceList getDevices() { return m_deviceMap.values(); }; + +-protected: +- QMap m_deviceMap; +- AuthDevicePtr m_device; + }; + + } // namespace Kiran +diff --git a/src/context/finger-vein/fv-sd-context.cpp b/src/context/finger-vein/fv-sd-context.cpp +index c417745..6265ba4 100644 +--- a/src/context/finger-vein/fv-sd-context.cpp ++++ b/src/context/finger-vein/fv-sd-context.cpp +@@ -59,7 +59,6 @@ AuthDevicePtr FVSDContext::createDevice(const QString& idVendor, const QString& + } + sdDevice->setDeviceName(deviceName); + sdDevice->setDeviceInfo(idVendor, idProduct); +- m_deviceMap.insert(sdDevice->deviceID(), sdDevice); + return sdDevice; + } + } // namespace Kiran +diff --git a/src/context/fingerprint/fp-zk-context.cpp b/src/context/fingerprint/fp-zk-context.cpp +index bde2b02..82bc74a 100644 +--- a/src/context/fingerprint/fp-zk-context.cpp ++++ b/src/context/fingerprint/fp-zk-context.cpp +@@ -63,7 +63,6 @@ AuthDevicePtr FPZKContext::createDevice(const QString& idVendor, const QString& + } + zkDevice->setDeviceName(deviceName); + zkDevice->setDeviceInfo(idVendor, idProduct); +- m_deviceMap.insert(zkDevice->deviceID(), zkDevice); + return zkDevice; + } + } // namespace Kiran +diff --git a/src/context/multi-function-context.cpp b/src/context/multi-function-context.cpp +index 750689a..f3b7670 100644 +--- a/src/context/multi-function-context.cpp ++++ b/src/context/multi-function-context.cpp +@@ -81,8 +81,6 @@ AuthDevicePtr MultiFunctionContext::createIriStarDevice(const QString& idVendor, + iriStarDevice->setDeviceName(deviceName); + iriStarDevice->setDeviceInfo(idVendor, idProduct); + +- m_deviceMap.insert(iriStarDevice->deviceID(), iriStarDevice); +- + return iriStarDevice; + } + +diff --git a/src/context/ukey/ukey-ft-context.cpp b/src/context/ukey/ukey-ft-context.cpp +index e363fc1..3b1b859 100644 +--- a/src/context/ukey/ukey-ft-context.cpp ++++ b/src/context/ukey/ukey-ft-context.cpp +@@ -58,7 +58,6 @@ AuthDevicePtr UKeyFTContext::createDevice(const QString& idVendor, const QString + } + ftDevice->setDeviceName(deviceName); + ftDevice->setDeviceInfo(idVendor, idProduct); +- m_deviceMap.insert(ftDevice->deviceID(), ftDevice); + return ftDevice; + } + } // namespace Kiran +diff --git a/src/device/auth-device.cpp b/src/device/auth-device.cpp +index 0595fb1..a321723 100644 +--- a/src/device/auth-device.cpp ++++ b/src/device/auth-device.cpp +@@ -194,7 +194,7 @@ CHECK_AUTH(AuthDevice, IdentifyStop, onIdentifyStop, AUTH_USER_ADMIN) + + QStringList AuthDevice::GetFeatureIDList() + { +- QStringList featureIDs = FeatureDB::getInstance()->getFeatureIDs(m_idVendor, m_idProduct,deviceType()); ++ QStringList featureIDs = FeatureDB::getInstance()->getFeatureIDs(m_idVendor, m_idProduct,deviceType(),deviceSerialNumber()); + return featureIDs; + } + +diff --git a/src/device/auth-device.h b/src/device/auth-device.h +index b943189..8b522d0 100644 +--- a/src/device/auth-device.h ++++ b/src/device/auth-device.h +@@ -52,12 +52,14 @@ public: + DeviceStatus deviceStatus() { return m_deviceStatus; }; + QString deviceName() { return m_deviceName; }; + DeviceInfo deviceInfo(); ++ QString deviceSerialNumber() { return m_serialNumber; }; + + void setDeviceType(DeviceType deviceType) { m_deviceType = deviceType; }; + void setDeviceStatus(DeviceStatus deviceStatus) { m_deviceStatus = deviceStatus; }; + void setDeviceName(const QString &deviceName) { m_deviceName = deviceName; }; + void setDeviceInfo(const QString &idVendor, const QString &idProduct); + void setDeviceDriver(const QString &deviceDriver); ++ void setDeviceSerialNumber(const QString &serialNumber) {m_serialNumber = serialNumber;}; + + public Q_SLOTS: + virtual void EnrollStart(const QString &extraInfo); +@@ -104,6 +106,7 @@ private: + QString m_deviceName; + QString m_idVendor; + QString m_idProduct; ++ QString m_serialNumber; + QDBusObjectPath m_objectPath; + QSharedPointer m_serviceWatcher; + +diff --git a/src/device/bio-device.cpp b/src/device/bio-device.cpp +index 0b06bae..dd14f0e 100644 +--- a/src/device/bio-device.cpp ++++ b/src/device/bio-device.cpp +@@ -36,7 +36,7 @@ void BioDevice::doingEnrollStart(const QString &extraInfo) + { + KLOG_DEBUG() << "biological information enroll start"; + // 获取当前保存的特征模板,判断是否达到最大数目 +- QByteArrayList saveList = FeatureDB::getInstance()->getFeatures(deviceInfo().idVendor, deviceInfo().idProduct, deviceType()); ++ QByteArrayList saveList = FeatureDB::getInstance()->getFeatures(deviceInfo().idVendor, deviceInfo().idProduct, deviceType(),deviceSerialNumber()); + if (saveList.count() == TEMPLATE_MAX_NUMBER) + { + QString message = tr("feature has reached the upper limit of %1").arg(TEMPLATE_MAX_NUMBER); +diff --git a/src/device/finger-vein/fv-sd-device.cpp b/src/device/finger-vein/fv-sd-device.cpp +index 55e49c0..6581cf9 100644 +--- a/src/device/finger-vein/fv-sd-device.cpp ++++ b/src/device/finger-vein/fv-sd-device.cpp +@@ -399,7 +399,7 @@ QString FVSDDevice::identifyFeature(QByteArray feature, QStringList featureIDs) + DeviceInfo deviceInfo = this->deviceInfo(); + if (featureIDs.isEmpty()) + { +- saveList = FeatureDB::getInstance()->getFeatures(deviceInfo.idVendor, deviceInfo.idProduct, deviceType()); ++ saveList = FeatureDB::getInstance()->getFeatures(deviceInfo.idVendor, deviceInfo.idProduct, deviceType(),deviceSerialNumber()); + } + else + { +diff --git a/src/device/fingerprint/fp-zk-device.cpp b/src/device/fingerprint/fp-zk-device.cpp +index 92ff10d..4d8abc0 100644 +--- a/src/device/fingerprint/fp-zk-device.cpp ++++ b/src/device/fingerprint/fp-zk-device.cpp +@@ -384,7 +384,7 @@ QString FPZKDevice::identifyFeature(QByteArray fpTemplate, QStringList featureID + DeviceInfo info = this->deviceInfo(); + if (featureIDs.isEmpty()) + { +- saveList = FeatureDB::getInstance()->getFeatures(info.idVendor, info.idProduct,deviceType()); ++ saveList = FeatureDB::getInstance()->getFeatures(info.idVendor, info.idProduct,deviceType(),deviceSerialNumber()); + } + else + { +diff --git a/src/device/ukey/ukey-ft-device.cpp b/src/device/ukey/ukey-ft-device.cpp +index a6e1dfc..e8f5070 100644 +--- a/src/device/ukey/ukey-ft-device.cpp ++++ b/src/device/ukey/ukey-ft-device.cpp +@@ -23,28 +23,61 @@ + + namespace Kiran + { +-UKeyFTDevice::UKeyFTDevice(QObject *parent) : AuthDevice{parent}, +- m_appHandle(nullptr), +- m_devHandle(nullptr), +- m_containerHandle(nullptr) ++QStringList UKeyFTDevice::m_existingSerialNumber; ++ ++UKeyFTDevice::UKeyFTDevice(QObject *parent) : AuthDevice{parent} + { + setDeviceType(DEVICE_TYPE_UKey); + setDeviceDriver(FT_UKEY_DRIVER_LIB); +- m_driver = QSharedPointer(new UKeySKFDriver()); ++ /** ++ * NOTE: ++ * UKey设备插入时,设备可能处在未准备好的状态,无法获取到serialNumber ++ * 如果初始化时,未获取到serialNumber,则开启定时器再次获取 ++ */ ++ if (!initSerialNumber()) ++ { ++ m_reInitSerialNumberTimer.start(1000); ++ } ++ connect(&m_reInitSerialNumberTimer, &QTimer::timeout, this, &UKeyFTDevice::initSerialNumber); + } + + UKeyFTDevice::~UKeyFTDevice() + { ++ int index = m_existingSerialNumber.indexOf(deviceSerialNumber()); ++ m_existingSerialNumber.removeAt(index); ++ KLOG_DEBUG() << "destory device, serialNumber:" << deviceSerialNumber(); + } + + bool UKeyFTDevice::initDriver() + { +- if (!m_driver->loadLibrary(FT_UKEY_DRIVER_LIB)) ++ return true; ++} ++ ++bool UKeyFTDevice::initSerialNumber() ++{ ++ UKeySKFDriver driver; ++ driver.loadLibrary(FT_UKEY_DRIVER_LIB); ++ QStringList serialNumberList = driver.enumDevSerialNumber(); ++ for (auto serialNumber : serialNumberList) ++ { ++ if (m_existingSerialNumber.contains(serialNumber)) ++ { ++ continue; ++ } ++ setDeviceSerialNumber(serialNumber); ++ m_existingSerialNumber << serialNumber; ++ break; ++ } ++ KLOG_DEBUG() << "init serial number:" << deviceSerialNumber(); ++ if (deviceSerialNumber().isEmpty()) + { + return false; + } +- +- return true; ++ else ++ { ++ m_reInitSerialNumberTimer.stop(); ++ return true; ++ } + } + + void UKeyFTDevice::doingEnrollStart(const QString &extraInfo) +@@ -52,66 +85,71 @@ void UKeyFTDevice::doingEnrollStart(const QString &extraInfo) + KLOG_DEBUG() << "ukey enroll start"; + QJsonValue ukeyValue = Utils::getValueFromJsonString(extraInfo, AUTH_DEVICE_JSON_KEY_UKEY); + 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()) ++ QString pin = jsonObject.value(AUTH_DEVICE_JSON_KEY_PIN).toString(); ++ HANDLE devHandle = nullptr; ++ ++ KLOG_DEBUG() << "device serial number:" << deviceSerialNumber(); ++ if (pin.isEmpty()) + { + QString message = tr("The pin code cannot be empty!"); + Q_EMIT m_dbusAdaptor->EnrollStatus("", 0, ENROLL_STATUS_FAIL, message); + KLOG_ERROR() << "The pin code cannot be empty!"; +- internalStopEnroll(); +- return; ++ goto end; + } + +- m_devHandle = m_driver->connectDev(); +- if (!m_devHandle) ++ if (isExistBinding()) + { +- KLOG_ERROR() << "Connect Dev failed"; +- notifyUKeyEnrollProcess(ENROLL_PROCESS_FAIL); +- internalStopEnroll(); +- return; ++ notifyUKeyEnrollProcess(ENROLL_PROCESS_REPEATED_ENROLL); ++ goto end; + } + +- if (rebinding) ++ m_driver = new UKeySKFDriver(); ++ if (!m_driver->loadLibrary(FT_UKEY_DRIVER_LIB)) + { +- 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, deviceType()); +- Q_FOREACH (auto id, idList) +- { +- FeatureDB::getInstance()->deleteFeature(id); +- } +- bindingUKey(); +- } +- else +- { +- KLOG_ERROR() << "rebinding failed"; +- } ++ KLOG_ERROR() << "load library failed"; ++ notifyUKeyEnrollProcess(ENROLL_PROCESS_FAIL); ++ goto end; + } +- else ++ ++ devHandle = m_driver->connectDev(deviceSerialNumber()); ++ KLOG_DEBUG() << "devHandle:" << devHandle; ++ if (!devHandle) + { +- bindingUKey(); ++ KLOG_ERROR() << "Connect Dev failed"; ++ notifyUKeyEnrollProcess(ENROLL_PROCESS_FAIL); ++ goto end; + } ++ bindingUKey(devHandle,pin); ++ m_driver->disConnectDev(devHandle); ++ ++end: + internalStopEnroll(); ++ return; + } + +-void UKeyFTDevice::bindingUKey() ++void UKeyFTDevice::bindingUKey(DEVHANDLE devHandle, const QString &pin) + { +- if (isExistPublicKey()) ++ HCONTAINER containerHandle; ++ HAPPLICATION appHandle; ++ ULONG ret = createContainer(pin, devHandle, &appHandle, &containerHandle); ++ if (ret != SAR_OK) + { +- notifyUKeyEnrollProcess(ENROLL_PROCESS_REPEATED_ENROLL); ++ KLOG_ERROR() << "create container failed:" << m_driver->getErrorReason(ret); ++ notifyUKeyEnrollProcess(ENROLL_PROCESS_FAIL, ret); ++ m_driver->closeContainer(containerHandle); ++ m_driver->closeApplication(appHandle); + return; + } +- ECCPUBLICKEYBLOB publicKey = {0}; +- ULONG ret = genKeyPair(&publicKey); ++ KLOG_DEBUG() << "create container success"; + ++ ECCPUBLICKEYBLOB publicKey = {0}; ++ ret = m_driver->genECCKeyPair(containerHandle, &publicKey); + if (ret != SAR_OK) + { + KLOG_ERROR() << "gen ecc key pair failed:" << m_driver->getErrorReason(ret); + notifyUKeyEnrollProcess(ENROLL_PROCESS_FAIL, ret); ++ m_driver->closeContainer(containerHandle); ++ m_driver->closeApplication(appHandle); + return; + } + KLOG_DEBUG() << "gen ecc key pair success"; +@@ -131,87 +169,62 @@ void UKeyFTDevice::bindingUKey() + QString featureID = QCryptographicHash::hash(keyFeature, QCryptographicHash::Md5).toHex(); + DeviceInfo deviceInfo = this->deviceInfo(); + +- if (FeatureDB::getInstance()->addFeature(featureID, keyFeature, deviceInfo, deviceType())) ++ if (FeatureDB::getInstance()->addFeature(featureID, keyFeature, deviceInfo, deviceType(), deviceSerialNumber())) + { + notifyUKeyEnrollProcess(ENROLL_PROCESS_SUCCESS, SAR_OK, featureID); + } + else + { +- KLOG_DEBUG() << "save feature fail"; ++ KLOG_ERROR() << "save feature fail"; + notifyUKeyEnrollProcess(ENROLL_PROCESS_FAIL); + } +-} + +-bool UKeyFTDevice::isExistPublicKey() +-{ +- DeviceInfo deviceInfo = this->deviceInfo(); +- auto features = FeatureDB::getInstance()->getFeatures(deviceInfo.idVendor, deviceInfo.idProduct, deviceType()); +- if (features.count() != 0) +- { +- return true; +- } +- else +- { +- return false; +- } ++ m_driver->closeContainer(containerHandle); ++ m_driver->closeApplication(appHandle); + } + +-ULONG UKeyFTDevice::genKeyPair(ECCPUBLICKEYBLOB *publicKey) ++ULONG UKeyFTDevice::createContainer(const QString &pin, DEVHANDLE devHandle, HAPPLICATION *appHandle, HCONTAINER *containerHandle) + { +- ULONG ulReval; +- if (!isExistsApplication(UKEY_APP_NAME)) +- { +- // NOTE:必须通过设备认证后才能在设备内创建和删除应用 +- ulReval = m_driver->devAuth(m_devHandle); +- if (ulReval != SAR_OK) +- { +- KLOG_ERROR() << "Device auth failure: " << m_driver->getErrorReason(ulReval); +- return ulReval; +- } +- else +- { +- KLOG_DEBUG() << "device auth success"; +- } +- m_driver->deleteAllApplication(m_devHandle); +- ulReval = m_driver->createApplication(m_devHandle, m_pin, UKEY_APP_NAME, &m_appHandle); +- if (ulReval != SAR_OK) +- { +- KLOG_ERROR() << "create application failed:" << m_driver->getErrorReason(ulReval); +- return ulReval; +- } +- KLOG_DEBUG() << "create application suceess"; +- ulReval = m_driver->createContainer(m_appHandle, m_pin, UKEY_CONTAINER_NAME, &m_retryCount, &m_containerHandle); +- if (ulReval != SAR_OK) +- { +- KLOG_ERROR() << "create container failed:" << m_driver->getErrorReason(ulReval); +- return ulReval; +- } +- KLOG_DEBUG() << "create new container success"; +- } +- ulReval = m_driver->onOpenApplication(m_devHandle, (LPSTR)UKEY_APP_NAME, &m_appHandle); ++ // NOTE:必须通过设备认证后才能在设备内创建和删除应用 ++ ULONG ulReval = m_driver->devAuth(devHandle); + if (ulReval != SAR_OK) + { +- KLOG_DEBUG() << "open Application failed:" << m_driver->getErrorReason(ulReval); ++ KLOG_ERROR() << "Device auth failure: " << m_driver->getErrorReason(ulReval); + return ulReval; + } +- KLOG_DEBUG() << "open Application success"; ++ KLOG_DEBUG() << "device auth success"; ++ m_driver->deleteAllApplication(devHandle); + +- ulReval = m_driver->onOpenContainer(m_appHandle, m_pin, UKEY_CONTAINER_NAME, &m_retryCount, &m_containerHandle); ++ ulReval = m_driver->createApplication(devHandle, pin, UKEY_APP_NAME, appHandle); + if (ulReval != SAR_OK) + { +- KLOG_ERROR() << "open container failed:" << m_driver->getErrorReason(ulReval); ++ KLOG_ERROR() << "create application failed:" << m_driver->getErrorReason(ulReval) ++ << " device serial number:" << deviceSerialNumber(); + return ulReval; + } +- KLOG_DEBUG() << "open container success"; +- +- ulReval = m_driver->genECCKeyPair(m_containerHandle, publicKey); +- ++ KLOG_DEBUG() << "create application suceess"; ++ ulReval = m_driver->createContainer(*appHandle, pin, UKEY_CONTAINER_NAME, &m_retryCount, containerHandle); + return ulReval; + } + +-bool UKeyFTDevice::isExistsApplication(const QString &appName) ++bool UKeyFTDevice::isExistBinding() + { +- QString appNames = m_driver->enumApplication(m_devHandle); ++ QStringList featureIDs = FeatureDB::getInstance()->getFeatureIDs(deviceInfo().idVendor, deviceInfo().idProduct, deviceType(), deviceSerialNumber()); ++ for (auto id : featureIDs) ++ { ++ FeatureInfo info = FeatureDB::getInstance()->getFeatureInfo(id); ++ if (info.deviceSerialNumber == deviceSerialNumber()) ++ { ++ KLOG_DEBUG() << QString("Exist Binding: feature id:%1, device serial number: %2").arg(id).arg(deviceSerialNumber()); ++ return true; ++ } ++ } ++ return false; ++} ++ ++bool UKeyFTDevice::isExistsApplication(DEVHANDLE devHandle, const QString &appName) ++{ ++ QString appNames = m_driver->enumApplication(devHandle); + KLOG_DEBUG() << "enum app names:" << appNames; + if (appNames.contains(appName)) + { +@@ -225,8 +238,8 @@ void UKeyFTDevice::doingIdentifyStart(const QString &value) + KLOG_DEBUG() << "ukey identify start"; + QJsonValue ukeyValue = Utils::getValueFromJsonString(value, AUTH_DEVICE_JSON_KEY_UKEY); + auto jsonObject = ukeyValue.toObject(); +- m_pin = jsonObject.value(AUTH_DEVICE_JSON_KEY_PIN).toString(); +- if (m_pin.isEmpty()) ++ QString pin = jsonObject.value(AUTH_DEVICE_JSON_KEY_PIN).toString(); ++ if (pin.isEmpty()) + { + QString message = tr("The pin code cannot be empty!"); + Q_EMIT m_dbusAdaptor->IdentifyStatus("", IDENTIFY_STATUS_NOT_MATCH, message); +@@ -239,29 +252,38 @@ void UKeyFTDevice::doingIdentifyStart(const QString &value) + DeviceInfo deviceInfo = this->deviceInfo(); + if (m_identifyIDs.isEmpty()) + { +- saveList = FeatureDB::getInstance()->getFeatures(deviceInfo.idVendor, deviceInfo.idProduct, deviceType()); ++ saveList = FeatureDB::getInstance()->getFeatures(deviceInfo.idVendor, deviceInfo.idProduct, deviceType(), deviceSerialNumber()); + } + else + { + Q_FOREACH (auto id, m_identifyIDs) + { + QByteArray feature = FeatureDB::getInstance()->getFeature(id); +- if (!feature.isEmpty()) +- saveList << feature; ++ saveList << feature; + } + } + +- if (saveList.count() != 0) ++ if (saveList.count() == 0) + { +- for (int j = 0; j < saveList.count(); j++) +- { +- auto saveTemplate = saveList.value(j); +- identifyKeyFeature(saveTemplate); +- } ++ KLOG_DEBUG() << "no found feature id"; ++ notifyUKeyIdentifyProcess(IDENTIFY_PROCESS_NO_MATCH); ++ internalStopIdentify(); ++ return; + } +- else ++ ++ m_driver = new UKeySKFDriver(); ++ if (!m_driver->loadLibrary(FT_UKEY_DRIVER_LIB)) + { +- KLOG_DEBUG() << "no found feature id"; ++ KLOG_ERROR() << "load library failed"; ++ notifyUKeyEnrollProcess(ENROLL_PROCESS_FAIL); ++ internalStopIdentify(); ++ return; ++ } ++ ++ for (int j = 0; j < saveList.count(); j++) ++ { ++ auto savedKey = saveList.value(j); ++ identifyKeyFeature(pin,savedKey); + } + + internalStopIdentify(); +@@ -271,10 +293,14 @@ void UKeyFTDevice::internalStopEnroll() + { + if (deviceStatus() == DEVICE_STATUS_DOING_ENROLL) + { +- closeUkey(); +- m_pin.clear(); + setDeviceStatus(DEVICE_STATUS_IDLE); + clearWatchedServices(); ++ if (m_driver) ++ { ++ KLOG_DEBUG() << "delete m_driver"; ++ delete m_driver; ++ m_driver = nullptr; ++ } + KLOG_DEBUG() << "stop Enroll"; + } + } +@@ -283,58 +309,48 @@ void UKeyFTDevice::internalStopIdentify() + { + if (deviceStatus() == DEVICE_STATUS_DOING_IDENTIFY) + { +- closeUkey(); + m_identifyIDs.clear(); +- m_pin.clear(); + setDeviceStatus(DEVICE_STATUS_IDLE); + clearWatchedServices(); ++ if (m_driver) ++ { ++ delete m_driver; ++ m_driver = nullptr; ++ } + KLOG_DEBUG() << "stopIdentify"; + } + } + +-void UKeyFTDevice::closeUkey() ++void UKeyFTDevice::resetUkey() + { +- if (!m_driver->isLoaded()) +- { +- return; +- } +- if (m_containerHandle) +- { +- m_driver->closeContainer(m_containerHandle); +- m_containerHandle = nullptr; +- } +- +- if (m_appHandle) +- { +- m_driver->closeApplication(m_appHandle); +- m_appHandle = nullptr; +- } +- +- if (m_devHandle) +- { +- m_driver->disConnectDev(m_devHandle); +- m_devHandle = nullptr; +- } ++ UKeySKFDriver driver; ++ driver.loadLibrary(FT_UKEY_DRIVER_LIB); ++ DEVHANDLE devHandle = driver.connectDev(deviceSerialNumber()); ++ driver.resetUkey(devHandle); ++ KLOG_DEBUG() << "resetUkey"; + } + +-void UKeyFTDevice::identifyKeyFeature(QByteArray keyFeature) ++void UKeyFTDevice::identifyKeyFeature(const QString &pin, QByteArray keyFeature) + { +- DEVHANDLE m_devHandle = m_driver->connectDev(); +- if (!m_devHandle) ++ DEVHANDLE devHandle = m_driver->connectDev(deviceSerialNumber()); ++ if (!devHandle) + { + notifyUKeyIdentifyProcess(IDENTIFY_PROCESS_NO_MATCH); + return; + } + + ULONG ret; +- ret = m_driver->onOpenApplication(m_devHandle, (LPSTR)UKEY_APP_NAME, &m_appHandle); ++ HAPPLICATION appHandle; ++ HCONTAINER containerHandle; ++ ++ ret = m_driver->onOpenApplication(devHandle, (LPSTR)UKEY_APP_NAME, &appHandle); + if (ret != SAR_OK) + { + notifyUKeyIdentifyProcess(IDENTIFY_PROCESS_NO_MATCH, ret); + return; + } + +- ret = m_driver->onOpenContainer(m_appHandle, m_pin, UKEY_CONTAINER_NAME, &m_retryCount, &m_containerHandle); ++ ret = m_driver->onOpenContainer(appHandle, pin, UKEY_CONTAINER_NAME, &m_retryCount, &containerHandle); + if (ret != SAR_OK) + { + notifyUKeyIdentifyProcess(IDENTIFY_PROCESS_NO_MATCH, ret); +@@ -342,7 +358,7 @@ void UKeyFTDevice::identifyKeyFeature(QByteArray keyFeature) + } + + ECCSIGNATUREBLOB Signature = {0}; +- ret = m_driver->authSignData(m_containerHandle, m_devHandle, Signature); ++ ret = m_driver->authSignData(containerHandle, devHandle, Signature); + if (ret != SAR_OK) + { + KLOG_DEBUG() << "auth sign data failed:" << m_driver->getErrorReason(ret); +@@ -358,7 +374,7 @@ void UKeyFTDevice::identifyKeyFeature(QByteArray keyFeature) + 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); ++ ret = m_driver->verifyData(devHandle, Signature, eccPubKey); + if (ret != SAR_OK) + { + KLOG_DEBUG() << "verify data failed:" << m_driver->getErrorReason(ret); +@@ -373,10 +389,15 @@ void UKeyFTDevice::identifyKeyFeature(QByteArray keyFeature) + + void UKeyFTDevice::notifyUKeyEnrollProcess(EnrollProcess process, ULONG error, const QString &featureID) + { +- QString message, reason; ++ QString reason; + // 目前只需要返回有关pin码的错误信息 + reason = getPinErrorReson(error); ++ if (error != SAR_OK) ++ { ++ KLOG_DEBUG() << "Ukey Error Reason:" << m_driver->getErrorReason(error); ++ } + ++ QString message = tr("Binding user failed!"); + switch (process) + { + case ENROLL_PROCESS_SUCCESS: +@@ -384,18 +405,16 @@ void UKeyFTDevice::notifyUKeyEnrollProcess(EnrollProcess process, ULONG error, c + Q_EMIT m_dbusAdaptor->EnrollStatus(featureID, 100, ENROLL_STATUS_COMPLETE, message); + break; + case ENROLL_PROCESS_FAIL: +- message = tr("Binding user failed!"); + if (!reason.isEmpty()) + { + message.append(reason); + } + Q_EMIT m_dbusAdaptor->EnrollStatus("", 0, ENROLL_STATUS_FAIL, message); +- KLOG_DEBUG() << "Ukey Error Reason:" << m_driver->getErrorReason(error); + break; + case ENROLL_PROCESS_REPEATED_ENROLL: +- message = tr("UKey has been bound"); +- Q_EMIT m_dbusAdaptor->EnrollStatus("", 0, ENROLL_STATUS_REPEATED, message); ++ message.append(tr("UKey has been bound")); + Q_EMIT m_dbusAdaptor->EnrollStatus("", 0, ENROLL_STATUS_FAIL, message); ++ break; + default: + break; + } +diff --git a/src/device/ukey/ukey-ft-device.h b/src/device/ukey/ukey-ft-device.h +index b74a24e..87d8c45 100644 +--- a/src/device/ukey/ukey-ft-device.h ++++ b/src/device/ukey/ukey-ft-device.h +@@ -14,10 +14,11 @@ + + #pragma once + #include ++#include ++#include + #include "device/auth-device.h" + #include "driver/ukey/ukey-skf-driver.h" + #include "ukey-skf.h" +-#include + + namespace Kiran + { +@@ -30,33 +31,34 @@ public: + + bool initDriver() override; + ++ void resetUkey(); ++ ++private Q_SLOTS: ++ bool initSerialNumber(); ++ + private: + void doingEnrollStart(const QString &extraInfo) override; + void doingIdentifyStart(const QString &value) override; +- ++ + void internalStopEnroll() override; + void internalStopIdentify() override; + +- void identifyKeyFeature(QByteArray keyFeature); +- +- void bindingUKey(); +- ULONG genKeyPair(ECCPUBLICKEYBLOB *publicKey); +- bool isExistPublicKey(); +- bool isExistsApplication(const QString &appName); ++ void identifyKeyFeature(const QString &pin, QByteArray keyFeature); + ++ void bindingUKey(DEVHANDLE devHandle, const QString &pin); ++ ULONG createContainer(const QString &pin, DEVHANDLE devHandle, HAPPLICATION *appHandle, HCONTAINER *containerHandle); ++ bool isExistsApplication(DEVHANDLE devHandle, const QString &appName); ++ bool isExistBinding(); + void notifyUKeyEnrollProcess(EnrollProcess process, ULONG error = SAR_OK, const QString &featureID = QString()); + void notifyUKeyIdentifyProcess(IdentifyProcess process, ULONG error = SAR_OK, const QString &featureID = QString()); + + QString getPinErrorReson(ULONG error); + +- void closeUkey(); + private: +- DEVHANDLE m_devHandle; +- HAPPLICATION m_appHandle; +- HCONTAINER m_containerHandle; + ULONG m_retryCount = 1000000; +- QString m_pin; +- QSharedPointer m_driver; ++ UKeySKFDriver *m_driver = nullptr; ++ static QStringList m_existingSerialNumber; ++ QTimer m_reInitSerialNumberTimer; + }; + + } // namespace Kiran +diff --git a/src/driver/multi-function/mf-iristar-driver.cpp b/src/driver/multi-function/mf-iristar-driver.cpp +index 298a0e8..ae8a389 100644 +--- a/src/driver/multi-function/mf-iristar-driver.cpp ++++ b/src/driver/multi-function/mf-iristar-driver.cpp +@@ -376,7 +376,7 @@ int MFIriStarDriver::startIdentify(QStringList featureIDs) + + if (featureIDs.isEmpty()) + { +- saveList = FeatureDB::getInstance()->getFeatures(m_idVendor, m_idProduct, (DeviceType)m_currentDeviceType); ++ saveList = FeatureDB::getInstance()->getFeatures(m_idVendor, m_idProduct, (DeviceType)m_currentDeviceType,QString()); + } + else + { +diff --git a/src/driver/ukey/ukey-skf-driver.cpp b/src/driver/ukey/ukey-skf-driver.cpp +index dd74772..e1e89d7 100644 +--- a/src/driver/ukey/ukey-skf-driver.cpp ++++ b/src/driver/ukey/ukey-skf-driver.cpp +@@ -180,46 +180,123 @@ bool UKeySKFDriver::isLoaded() + return m_driverLib->isLoaded; + } + +-DEVHANDLE UKeySKFDriver::connectDev() ++QStringList UKeySKFDriver::enumDevName() + { + 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; ++ return QStringList(); + } + + LPSTR szNameList = (LPSTR)malloc(ulBufSize * sizeof(CHAR)); + memset(szNameList, '\0', ulBufSize); + ulReval = m_driverLib->SKF_EnumDev(TRUE, szNameList, &ulBufSize); +- if (ulReval == SAR_OK) ++ if ((ulReval != SAR_OK)) ++ { ++ KLOG_DEBUG() << "Enum Dev error:" << getErrorReason(ulReval); ++ free(szNameList); ++ return QStringList(); ++ } ++ ++ LPSTR pszTemp = szNameList; ++ if (NULL == pszTemp) ++ { ++ KLOG_DEBUG() << "no found ukey device"; ++ free(szNameList); ++ return QStringList(); ++ } ++ ++ QStringList nameList; ++ while ((*pszTemp != '\0') && (*(pszTemp + 1) != '\0')) + { +- LPSTR pszTemp = szNameList; +- if (NULL == pszTemp) ++ nameList << QString::fromLatin1((const char *)pszTemp, strlen((const char *)pszTemp)); ++ pszTemp += strlen((const char *)pszTemp) + 1; ++ } ++ KLOG_DEBUG() << "device name list:" << nameList; ++ ++ free(szNameList); ++ return nameList; ++} ++ ++QStringList UKeySKFDriver::enumDevSerialNumber() ++{ ++ QStringList devNameList = enumDevName(); ++ QStringList serialNumberList; ++ for (auto devName : devNameList) ++ { ++ DEVHANDLE devHandle; ++ ULONG pulDevState; ++ QByteArray devNameArray = devName.toLatin1(); ++ unsigned char *szDevName = (unsigned char *)devNameArray.data(); ++ ULONG ulReval = m_driverLib->SKF_ConnectDev(szDevName, &devHandle); ++ if (SAR_OK != ulReval) + { +- KLOG_DEBUG() << "no found ukey device"; +- return nullptr; ++ continue; + } +- while (*pszTemp != '\0') ++ DEVINFO devInfo; ++ m_driverLib->SKF_GetDevInfo(devHandle, &devInfo); ++ serialNumberList << QString((const char *)devInfo.SerialNumber); ++ m_driverLib->SKF_DisConnectDev(devHandle); ++ } ++ KLOG_DEBUG() << "dev serial number list:" << serialNumberList; ++ return serialNumberList; ++} ++ ++DEVHANDLE UKeySKFDriver::connectDev() ++{ ++ QStringList devNameList = enumDevName(); ++ for (auto devName : devNameList) ++ { ++ DEVHANDLE devHandle; ++ ULONG pulDevState; ++ QByteArray devNameArray = devName.toLatin1(); ++ unsigned char *szDevName = (unsigned char *)devNameArray.data(); ++ ULONG ulReval = m_driverLib->SKF_ConnectDev(szDevName, &devHandle); ++ if (SAR_OK == ulReval) + { +- 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; ++ KLOG_DEBUG() << "connect dev success"; ++ return devHandle; ++ } ++ else ++ { ++ KLOG_ERROR() << "Connect Dev failed:" << getErrorReason(ulReval); + } + } +- free(szNameList); ++ + return nullptr; + } + ++DEVHANDLE UKeySKFDriver::connectDev(const QString &serialNumber) ++{ ++ QStringList devNameList = enumDevName(); ++ for (auto devName : devNameList) ++ { ++ DEVHANDLE devHandle; ++ QByteArray devNameArray = devName.toLatin1(); ++ unsigned char *szDevName = (unsigned char *)devNameArray.data(); ++ ULONG ulReval = m_driverLib->SKF_ConnectDev(szDevName, &devHandle); ++ if (ulReval != SAR_OK) ++ { ++ KLOG_ERROR() << QString("Connect Dev %1 failed:").arg(devName) << getErrorReason(ulReval); ++ continue; ++ } ++ ++ DEVINFO devInfo; ++ m_driverLib->SKF_GetDevInfo(devHandle, &devInfo); ++ if (serialNumber == QString((const char *)devInfo.SerialNumber)) ++ { ++ KLOG_DEBUG() << QString("Connect Dev %1 success, SerialNumber: %2").arg(devName).arg(serialNumber); ++ return devHandle; ++ } ++ else ++ { ++ m_driverLib->SKF_DisConnectDev(devHandle); ++ } ++ } ++ return nullptr; ++} + + void UKeySKFDriver::deleteAllApplication(DEVHANDLE devHandle) + { +@@ -262,6 +339,23 @@ QString UKeySKFDriver::enumApplication(DEVHANDLE devHandle) + } + } + ++bool UKeySKFDriver::isExistPublicKey(HCONTAINER containerHandle) ++{ ++ unsigned char *pPubKey = NULL; ++ ULONG ulPubKeyLen = 0; ++ ULONG ret = m_driverLib->SKF_ExportPublicKey(containerHandle, TRUE, pPubKey, &ulPubKeyLen); ++ pPubKey = (unsigned char *)malloc(ulPubKeyLen); ++ ret = m_driverLib->SKF_ExportPublicKey(containerHandle, TRUE, pPubKey, &ulPubKeyLen); ++ if (ret == SAR_OK) ++ { ++ return true; ++ } ++ else ++ { ++ return false; ++ } ++} ++ + ULONG UKeySKFDriver::devAuth(DEVHANDLE devHandle) + { + BYTE random[16] = {0}; +@@ -340,7 +434,8 @@ void UKeySKFDriver::closeContainer(HCONTAINER containerHandle) + + void UKeySKFDriver::disConnectDev(DEVHANDLE devHandle) + { +- m_driverLib->SKF_DisConnectDev(devHandle); ++ ULONG ret = m_driverLib->SKF_DisConnectDev(devHandle); ++ KLOG_DEBUG() << "getErrorReason(ret):" << getErrorReason(ret); + } + + ULONG UKeySKFDriver::createApplication(DEVHANDLE devHandle, QString pin, QString appName, HAPPLICATION *appHandle) +@@ -527,6 +622,18 @@ ULONG UKeySKFDriver::unblockPin(DEVHANDLE devHandle, const QString &adminPin, co + return ulReval; + } + ++ULONG UKeySKFDriver::resetUkey(DEVHANDLE devHandle) ++{ ++ ULONG ulReval = devAuth(devHandle); ++ if (ulReval != SAR_OK) ++ { ++ KLOG_ERROR() << "Device authentication failed"; ++ return ulReval; ++ } ++ deleteAllApplication(devHandle); ++ return ulReval; ++} ++ + QString UKeySKFDriver::getErrorReason(ULONG error) + { + for (int i = 0; i < sizeof(skf_errors) / sizeof(skf_errors[0]); i++) +diff --git a/src/driver/ukey/ukey-skf-driver.h b/src/driver/ukey/ukey-skf-driver.h +index 0d45c7a..058dc63 100644 +--- a/src/driver/ukey/ukey-skf-driver.h ++++ b/src/driver/ukey/ukey-skf-driver.h +@@ -29,10 +29,15 @@ public: + bool isLoaded(); + bool loadLibrary(QString libPath); + ++ QStringList enumDevName(); ++ QStringList enumDevSerialNumber(); + DEVHANDLE connectDev(); + ++ DEVHANDLE connectDev(const QString &serialNumber); ++ + void deleteAllApplication(DEVHANDLE devHandle); + QString enumApplication(DEVHANDLE devHandle); ++ bool isExistPublicKey(HCONTAINER containerHandle); + + ULONG devAuth(DEVHANDLE devHandle); + ULONG onOpenApplication(DEVHANDLE hDev, LPSTR szAppName, HAPPLICATION *appHandle); +@@ -52,14 +57,15 @@ public: + + ULONG changePin(DEVHANDLE devHandle, int userType, const QString ¤tPin, const QString &newPin, ULONG *retryCount); + +- +- + ULONG unblockPin(DEVHANDLE devHandle, const QString &adminPin, const QString &newUserPin, ULONG *retryCount); + ++ ULONG resetUkey(DEVHANDLE devHandle); ++ + QString getErrorReason(ULONG error); + + QString getDefaultValueFromConf(const QString &key); + ++ + private: + QSharedPointer m_driverLib; + HANDLE m_libHandle; +diff --git a/src/feature-db.cpp b/src/feature-db.cpp +index 10d23ca..ee0a4bd 100644 +--- a/src/feature-db.cpp ++++ b/src/feature-db.cpp +@@ -72,7 +72,8 @@ bool FeatureDB::createDBConnection() + "feature BLOB NOT NULL," + "idVendor TEXT," + "idProduct TEXT," +- "deviceType INT);"); ++ "deviceType INT," ++ "deviceSerialNumber TEXT);"); + + if (!query.exec(createTable)) + { +@@ -82,15 +83,16 @@ bool FeatureDB::createDBConnection() + return true; + } + +-bool FeatureDB::addFeature(const QString &featureID, QByteArray feature, DeviceInfo deviceInfo, DeviceType deviceType) ++bool FeatureDB::addFeature(const QString &featureID, QByteArray feature, DeviceInfo deviceInfo, DeviceType deviceType, const QString &deviceSerialNumber) + { + QSqlQuery query(m_database); +- query.prepare("INSERT into feature(featureID, feature, idVendor, idProduct, deviceType) VALUES(:featureID, :feature,:idVendor, :idProduct, :deviceType) ;"); ++ query.prepare("INSERT into feature(featureID, feature, idVendor, idProduct, deviceType, deviceSerialNumber) VALUES(:featureID, :feature,:idVendor, :idProduct, :deviceType, :deviceSerialNumber) ;"); + query.bindValue(":featureID", featureID); + query.bindValue(":feature", feature); + query.bindValue(":idVendor", deviceInfo.idVendor); + query.bindValue(":idProduct", deviceInfo.idProduct); + query.bindValue(":deviceType", (int)deviceType); ++ query.bindValue(":deviceSerialNumber", deviceSerialNumber); + return query.exec(); + } + +@@ -116,13 +118,14 @@ QByteArray FeatureDB::getFeature(const QString &featureID) + return QByteArray(); + } + +-QList FeatureDB::getFeatures(const QString &idVendor, const QString &idProduct, DeviceType deviceType) ++QList FeatureDB::getFeatures(const QString &idVendor, const QString &idProduct, DeviceType deviceType, const QString &deviceSerialNumber) + { + QSqlQuery query(m_database); +- query.prepare("SELECT feature FROM feature WHERE idVendor = :Vid AND idProduct = :Pid AND deviceType = :devType"); ++ query.prepare("SELECT feature FROM feature WHERE idVendor = :Vid AND idProduct = :Pid AND deviceType = :devType AND deviceSerialNumber = :serialNumber"); + query.bindValue(":Vid", idVendor); + query.bindValue(":Pid", idProduct); + query.bindValue(":devType", (int)deviceType); ++ query.bindValue(":serialNumber", deviceSerialNumber); + query.exec(); + QByteArrayList featuresList; + while (query.next()) +@@ -147,13 +150,14 @@ QList FeatureDB::getAllFeatures() + return featuresList; + } + +-QStringList FeatureDB::getFeatureIDs(const QString &idVendor, const QString &idProduct, DeviceType deviceType) ++QStringList FeatureDB::getFeatureIDs(const QString &idVendor, const QString &idProduct, DeviceType deviceType, const QString &deviceSerialNumber) + { + QSqlQuery query(m_database); +- query.prepare("SELECT featureID FROM feature WHERE idVendor = :Vid AND idProduct = :Pid AND deviceType = :devType"); ++ query.prepare("SELECT featureID FROM feature WHERE idVendor = :Vid AND idProduct = :Pid AND deviceType = :devType AND deviceSerialNumber = :serialNumber"); + query.bindValue(":Vid", idVendor); + query.bindValue(":Pid", idProduct); + query.bindValue(":devType", (int)deviceType); ++ query.bindValue(":serialNumber", deviceSerialNumber); + query.exec(); + QStringList featureIDs; + while (query.next()) +@@ -192,6 +196,24 @@ QStringList FeatureDB::getAllFeatureIDs() + return featureIDs; + } + ++FeatureInfo FeatureDB::getFeatureInfo(const QString &featureID) ++{ ++ QSqlQuery query(m_database); ++ query.prepare("SELECT idVendor, idProduct, deviceType, deviceSerialNumber FROM feature WHERE featureID = :id"); ++ query.bindValue(":id", featureID); ++ query.exec(); ++ FeatureInfo featureInfo; ++ if (query.next()) ++ { ++ featureInfo.id = featureID; ++ featureInfo.idVendor = query.value("idVendor").toString(); ++ featureInfo.idProduct = query.value("idProduct").toString(); ++ featureInfo.deviceType = query.value("deviceType").toInt(); ++ featureInfo.deviceSerialNumber = query.value("deviceSerialNumber").toString(); ++ } ++ return featureInfo; ++} ++ + bool FeatureDB::updateFeature(const QString &featureID, QByteArray newFeature) + { + QSqlQuery query(m_database); +@@ -212,7 +234,9 @@ bool FeatureDB::contains(const QString &featureID) + return true; + } + else ++ { + return false; ++ } + } + + } // namespace Kiran +diff --git a/src/feature-db.h b/src/feature-db.h +index 8acad2e..2f2623e 100644 +--- a/src/feature-db.h ++++ b/src/feature-db.h +@@ -20,26 +20,38 @@ + + namespace Kiran + { ++struct FeatureInfo ++{ ++ QString id; ++ QString idVendor; ++ QString idProduct; ++ int deviceType; ++ QString deviceSerialNumber; ++}; ++ + class FeatureDB + { + public: + explicit FeatureDB(); + ~FeatureDB(); + +- static FeatureDB *getInstance() {return m_instance;}; ++ static FeatureDB *getInstance() { return m_instance; }; + static void globalInit(); +- static void globalDeinit() {delete m_instance;}; +- ++ static void globalDeinit() { delete m_instance; }; ++ + bool createDBConnection(); +- bool addFeature(const QString &featureID, QByteArray feature, DeviceInfo deviceInfo, DeviceType deviceType); ++ bool addFeature(const QString &featureID, QByteArray feature, ++ DeviceInfo deviceInfo, DeviceType deviceType, ++ const QString &deviceSerialNumber = QString()); + bool deleteFeature(const QString &featureID); + + QByteArray getFeature(const QString &featureID); +- QList getFeatures(const QString &idVendor,const QString &idProduct, DeviceType deviceType); ++ QList getFeatures(const QString &idVendor, const QString &idProduct, DeviceType deviceType, const QString &deviceSerialNumber); + QList getAllFeatures(); +- QStringList getFeatureIDs(const QString &idVendor,const QString &idProduct, DeviceType deviceType); ++ QStringList getFeatureIDs(const QString &idVendor, const QString &idProduct, DeviceType deviceType, const QString &deviceSerialNumber); + QString getFeatureID(QByteArray feature); + QStringList getAllFeatureIDs(); ++ FeatureInfo getFeatureInfo(const QString &featureID); + + bool updateFeature(const QString &featureID, QByteArray newFeature); + +diff --git a/ukey-manager/ukey-manager.cpp b/ukey-manager/ukey-manager.cpp +index 125374f..cb7a0eb 100644 +--- a/ukey-manager/ukey-manager.cpp ++++ b/ukey-manager/ukey-manager.cpp +@@ -59,29 +59,8 @@ bool UkeyManager::initDriver() + + ULONG UkeyManager::resetUkey() + { +- ULONG ulReval = m_driver->devAuth(m_devHandle); +- if (ulReval != SAR_OK) +- { +- KLOG_ERROR() << "Device authentication failed"; +- return ulReval; +- } +- m_driver->deleteAllApplication(m_devHandle); +- +- ulReval = m_driver->createApplication(m_devHandle, DEFAULT_USER_PINCODE, UKEY_APP_NAME, &m_appHandle); +- if (ulReval != SAR_OK) +- { +- KLOG_ERROR() << "create application failed:" << m_driver->getErrorReason(ulReval); +- return ulReval; +- } +- KLOG_DEBUG() << "create application suceess"; +- ulReval = m_driver->createContainer(m_appHandle, DEFAULT_USER_PINCODE, UKEY_CONTAINER_NAME, &m_retryCount, &m_containerHandle); +- if (ulReval != SAR_OK) +- { +- KLOG_ERROR() << "create container failed:" << m_driver->getErrorReason(ulReval); +- return ulReval; +- } +- KLOG_DEBUG() << "create new container success"; +- ++ ULONG ulReval = m_driver->resetUkey(m_devHandle); ++ m_driver->disConnectDev(m_devHandle); + return ulReval; + } + +@@ -102,7 +81,6 @@ ULONG UkeyManager::changePin(const QString &userType, const QString ¤tPin, + std::cout << "invalid user type" << std::endl; + return SAR_FAIL; + } +- KLOG_DEBUG() << "m_appHandle:" << m_appHandle; + KLOG_DEBUG() << "type:" << type; + ULONG ret = m_driver->changePin(m_devHandle, type, currentPin, newPin, retryCount); + return ret; +-- +2.33.0 + diff --git a/kiran-authentication-devices.spec b/kiran-authentication-devices.spec index cb6de71..bd24bba 100644 --- a/kiran-authentication-devices.spec +++ b/kiran-authentication-devices.spec @@ -1,13 +1,14 @@ Name: kiran-authentication-devices Version: 2.5.1 -Release: 2 +Release: 3 Summary: Kiran Authentication Devices License: MulanPSL-2.0 Source0: %{name}-%{version}.tar.gz Patch0001: 0001-fix-mf-iristar-driver-Fix-compilation-issues-with-st.patch +Patch0002: 0001-fix-ukey-Fix-the-issue-where-only-one-ukey-can-be-bo.patch BuildRequires: cmake BuildRequires: gcc-c++ @@ -65,6 +66,9 @@ systemctl enable kiran-authentication-devices.service rm -rf ${buildroot} %changelog +* Fri Jun 2 2023 luoqing - 2.5.1-3 +- KYOS-F: Fix the issue where only one ukey can be bound to a device, some self-test bugs.(#I78P3F) + * Wed May 24 2023 luoqing - 2.5.1-2 - KYOS-F: fix compilation issues with std:: function in lower versions. -- Gitee