mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2025-11-15 07:38:12 +00:00
sdcp-v2: Move SDCP support from using NSS to OpenSSL 3.0 and implement for egismoc
This commit is contained in:
Binary file not shown.
@@ -1,17 +1,21 @@
|
||||
P: /devices/pci0000:00/0000:00:14.0/usb3/3-5
|
||||
N: bus/usb/003/012=12010002FF0000407A1C820581110102030109022700010100A0320904000003FF000000070581020002000705020200020007058303400005
|
||||
N: bus/usb/003/002=12010002FF0000407A1C820581110102030109022700010100A0320904000003FF000000070581020002000705020200020007058303400005
|
||||
E: BUSNUM=003
|
||||
E: CURRENT_TAGS=:snap_cups_ippeveprinter:snap_cups_cupsd:
|
||||
E: DEVNAME=/dev/bus/usb/003/012
|
||||
E: DEVNUM=012
|
||||
E: CURRENT_TAGS=:snap_cups_ippeveprinter:snap_android-platform-tools_fastboot:snap_android-platform-tools_adb:snap_cups_cupsd:
|
||||
E: DEVNAME=/dev/bus/usb/003/002
|
||||
E: DEVNUM=002
|
||||
E: DEVTYPE=usb_device
|
||||
E: DRIVER=usb
|
||||
E: ID_AUTOSUSPEND=1
|
||||
E: ID_BUS=usb
|
||||
E: ID_MODEL=ETU905A80-E
|
||||
E: ID_MODEL_ENC=ETU905A80-E
|
||||
E: ID_MODEL_ID=0582
|
||||
E: ID_PATH=pci-0000:00:14.0-usb-0:5
|
||||
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_5
|
||||
E: ID_PATH_WITH_USB_REVISION=pci-0000:00:14.0-usbv2-0:5
|
||||
E: ID_PERSIST=0
|
||||
E: ID_PROCESSING=1
|
||||
E: ID_REVISION=1181
|
||||
E: ID_SERIAL=EGIS_ETU905A80-E_0E7828PBS393
|
||||
E: ID_SERIAL_SHORT=0E7828PBS393
|
||||
@@ -30,10 +34,10 @@ E: ID_VENDOR_ENC=EGIS
|
||||
E: ID_VENDOR_FROM_DATABASE=LighTuning Technology Inc.
|
||||
E: ID_VENDOR_ID=1c7a
|
||||
E: MAJOR=189
|
||||
E: MINOR=267
|
||||
E: MINOR=257
|
||||
E: PRODUCT=1c7a/582/1181
|
||||
E: SUBSYSTEM=usb
|
||||
E: TAGS=:snap_cups_ippeveprinter:snap_cups_cupsd:
|
||||
E: TAGS=:snap_cups_ippeveprinter:snap_android-platform-tools_fastboot:snap_cups_cupsd:snap_android-platform-tools_adb:
|
||||
E: TYPE=255/0/0
|
||||
A: authorized=1\n
|
||||
A: avoid_reset_quirk=0\n
|
||||
@@ -50,8 +54,8 @@ A: bmAttributes=a0\n
|
||||
A: busnum=3\n
|
||||
A: configuration=
|
||||
H: descriptors=12010002FF0000407A1C820581110102030109022700010100A0320904000003FF000000070581020002000705020200020007058303400005
|
||||
A: dev=189:267\n
|
||||
A: devnum=12\n
|
||||
A: dev=189:257\n
|
||||
A: devnum=2\n
|
||||
A: devpath=5\n
|
||||
L: driver=../../../../../bus/usb/drivers/usb
|
||||
L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:51/device:52/device:57
|
||||
@@ -66,20 +70,20 @@ A: physical_location/lid=no\n
|
||||
A: physical_location/panel=unknown\n
|
||||
A: physical_location/vertical_position=center\n
|
||||
L: port=../3-0:1.0/usb3-port5
|
||||
A: power/active_duration=1425996\n
|
||||
A: power/active_duration=2329204\n
|
||||
A: power/async=enabled\n
|
||||
A: power/autosuspend=2\n
|
||||
A: power/autosuspend_delay_ms=2000\n
|
||||
A: power/connected_duration=1426656\n
|
||||
A: power/control=on\n
|
||||
A: power/level=on\n
|
||||
A: power/persist=0\n
|
||||
A: power/connected_duration=96447632\n
|
||||
A: power/control=auto\n
|
||||
A: power/level=auto\n
|
||||
A: power/persist=1\n
|
||||
A: power/runtime_active_kids=0\n
|
||||
A: power/runtime_active_time=1426124\n
|
||||
A: power/runtime_enabled=forbidden\n
|
||||
A: power/runtime_active_time=2345067\n
|
||||
A: power/runtime_enabled=enabled\n
|
||||
A: power/runtime_status=active\n
|
||||
A: power/runtime_suspended_time=0\n
|
||||
A: power/runtime_usage=1\n
|
||||
A: power/runtime_suspended_time=94056717\n
|
||||
A: power/runtime_usage=0\n
|
||||
A: power/wakeup=disabled\n
|
||||
A: power/wakeup_abort_count=\n
|
||||
A: power/wakeup_active=\n
|
||||
@@ -96,13 +100,13 @@ A: rx_lanes=1\n
|
||||
A: serial=0E7828PBS393\n
|
||||
A: speed=480\n
|
||||
A: tx_lanes=1\n
|
||||
A: urbnum=2803\n
|
||||
A: urbnum=10257\n
|
||||
A: version= 2.00\n
|
||||
|
||||
P: /devices/pci0000:00/0000:00:14.0/usb3
|
||||
N: bus/usb/003/001=12010002090001406B1D020002060302010109021900010100E0000904000001090000000705810304000C
|
||||
N: bus/usb/003/001=12010002090001406B1D020015060302010109021900010100E0000904000001090000000705810304000C
|
||||
E: BUSNUM=003
|
||||
E: CURRENT_TAGS=:seat:snap_cups_cupsd:snap_cups_ippeveprinter:
|
||||
E: CURRENT_TAGS=:snap_cups_ippeveprinter:seat:snap_android-platform-tools_fastboot:snap_cups_cupsd:snap_android-platform-tools_adb:
|
||||
E: DEVNAME=/dev/bus/usb/003/001
|
||||
E: DEVNUM=001
|
||||
E: DEVTYPE=usb_device
|
||||
@@ -116,28 +120,28 @@ E: ID_MODEL_FROM_DATABASE=2.0 root hub
|
||||
E: ID_MODEL_ID=0002
|
||||
E: ID_PATH=pci-0000:00:14.0
|
||||
E: ID_PATH_TAG=pci-0000_00_14_0
|
||||
E: ID_REVISION=0602
|
||||
E: ID_SERIAL=Linux_6.2.0-34-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
|
||||
E: ID_REVISION=0615
|
||||
E: ID_SERIAL=Linux_6.15.1_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
|
||||
E: ID_SERIAL_SHORT=0000:00:14.0
|
||||
E: ID_USB_INTERFACES=:090000:
|
||||
E: ID_USB_MODEL=xHCI_Host_Controller
|
||||
E: ID_USB_MODEL_ENC=xHCI\x20Host\x20Controller
|
||||
E: ID_USB_MODEL_ID=0002
|
||||
E: ID_USB_REVISION=0602
|
||||
E: ID_USB_SERIAL=Linux_6.2.0-34-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
|
||||
E: ID_USB_REVISION=0615
|
||||
E: ID_USB_SERIAL=Linux_6.15.1_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
|
||||
E: ID_USB_SERIAL_SHORT=0000:00:14.0
|
||||
E: ID_USB_VENDOR=Linux_6.2.0-34-generic_xhci-hcd
|
||||
E: ID_USB_VENDOR_ENC=Linux\x206.2.0-34-generic\x20xhci-hcd
|
||||
E: ID_USB_VENDOR=Linux_6.15.1_xhci-hcd
|
||||
E: ID_USB_VENDOR_ENC=Linux\x206.15.1\x20xhci-hcd
|
||||
E: ID_USB_VENDOR_ID=1d6b
|
||||
E: ID_VENDOR=Linux_6.2.0-34-generic_xhci-hcd
|
||||
E: ID_VENDOR_ENC=Linux\x206.2.0-34-generic\x20xhci-hcd
|
||||
E: ID_VENDOR=Linux_6.15.1_xhci-hcd
|
||||
E: ID_VENDOR_ENC=Linux\x206.15.1\x20xhci-hcd
|
||||
E: ID_VENDOR_FROM_DATABASE=Linux Foundation
|
||||
E: ID_VENDOR_ID=1d6b
|
||||
E: MAJOR=189
|
||||
E: MINOR=256
|
||||
E: PRODUCT=1d6b/2/602
|
||||
E: PRODUCT=1d6b/2/615
|
||||
E: SUBSYSTEM=usb
|
||||
E: TAGS=:snap_cups_cupsd:seat:snap_cups_ippeveprinter:
|
||||
E: TAGS=:snap_cups_ippeveprinter:seat:snap_android-platform-tools_fastboot:snap_cups_cupsd:snap_android-platform-tools_adb:
|
||||
E: TYPE=9/0/1
|
||||
A: authorized=1\n
|
||||
A: authorized_default=1\n
|
||||
@@ -150,11 +154,11 @@ A: bMaxPacketSize0=64\n
|
||||
A: bMaxPower=0mA\n
|
||||
A: bNumConfigurations=1\n
|
||||
A: bNumInterfaces= 1\n
|
||||
A: bcdDevice=0602\n
|
||||
A: bcdDevice=0615\n
|
||||
A: bmAttributes=e0\n
|
||||
A: busnum=3\n
|
||||
A: configuration=
|
||||
H: descriptors=12010002090001406B1D020002060302010109021900010100E0000904000001090000000705810304000C
|
||||
H: descriptors=12010002090001406B1D020015060302010109021900010100E0000904000001090000000705810304000C
|
||||
A: dev=189:256\n
|
||||
A: devnum=1\n
|
||||
A: devpath=0\n
|
||||
@@ -164,20 +168,20 @@ A: idProduct=0002\n
|
||||
A: idVendor=1d6b\n
|
||||
A: interface_authorized_default=1\n
|
||||
A: ltm_capable=no\n
|
||||
A: manufacturer=Linux 6.2.0-34-generic xhci-hcd\n
|
||||
A: manufacturer=Linux 6.15.1 xhci-hcd\n
|
||||
A: maxchild=12\n
|
||||
A: power/active_duration=337953872\n
|
||||
A: power/active_duration=2362684\n
|
||||
A: power/async=enabled\n
|
||||
A: power/autosuspend=0\n
|
||||
A: power/autosuspend_delay_ms=0\n
|
||||
A: power/connected_duration=337978524\n
|
||||
A: power/connected_duration=96447784\n
|
||||
A: power/control=auto\n
|
||||
A: power/level=auto\n
|
||||
A: power/runtime_active_kids=1\n
|
||||
A: power/runtime_active_time=337962424\n
|
||||
A: power/runtime_active_time=2368910\n
|
||||
A: power/runtime_enabled=enabled\n
|
||||
A: power/runtime_status=active\n
|
||||
A: power/runtime_suspended_time=616\n
|
||||
A: power/runtime_suspended_time=94033284\n
|
||||
A: power/runtime_usage=0\n
|
||||
A: power/wakeup=disabled\n
|
||||
A: power/wakeup_abort_count=\n
|
||||
@@ -195,12 +199,15 @@ A: rx_lanes=1\n
|
||||
A: serial=0000:00:14.0\n
|
||||
A: speed=480\n
|
||||
A: tx_lanes=1\n
|
||||
A: urbnum=4969\n
|
||||
A: urbnum=7078\n
|
||||
A: version= 2.00\n
|
||||
|
||||
P: /devices/pci0000:00/0000:00:14.0
|
||||
E: DRIVER=xhci_hcd
|
||||
E: ID_AUTOSUSPEND=1
|
||||
E: ID_MODEL_FROM_DATABASE=Alder Lake PCH USB 3.2 xHCI Host Controller
|
||||
E: ID_PATH=pci-0000:00:14.0
|
||||
E: ID_PATH_TAG=pci-0000_00_14_0
|
||||
E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
|
||||
E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI
|
||||
E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
|
||||
@@ -214,10 +221,15 @@ E: SUBSYSTEM=pci
|
||||
A: ari_enabled=0\n
|
||||
A: broken_parity_status=0\n
|
||||
A: class=0x0c0330\n
|
||||
H: config=8680ED51060490020130030C000080000400161D6000000000000000000000000000000000000000000000004D1470C8000000007000000000000000FF010000FD0134A089C27F8000000000000000003F6DD80F000000000000000000000000316000000000000000000000000000000180C2C1080000000000000000000000059087007805E0FE000000000000000009B014F01000400100000000C10A080000080E00001800008F50020000010000090000018680C00009001014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B50F010112000000
|
||||
H: config=8680ED51060490020130030C000080000400161D6000000000000000000000000000000000000000000000004D1470C8000000007000000000000000FF010000FD0134A089C27F8000000000000000003F6DD80F000000000000000000000000316000000000000000000000000000000180C2C10800000000000000000000000590B7001804E0FE000000000000000009B014F01000400100000000C10A080000080E00001800008F50020000010000090000018680C00009001014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B50F010112000000
|
||||
A: consistent_dma_mask_bits=64\n
|
||||
A: d3cold_allowed=1\n
|
||||
A: dbc=disabled\n
|
||||
A: dbc_bInterfaceProtocol=01\n
|
||||
A: dbc_bcdDevice=0010\n
|
||||
A: dbc_idProduct=0010\n
|
||||
A: dbc_idVendor=1d6b\n
|
||||
A: dbc_poll_interval_ms=64\n
|
||||
A: device=0x51ed\n
|
||||
A: dma_mask_bits=64\n
|
||||
L: driver=../../../bus/pci/drivers/xhci_hcd
|
||||
@@ -227,32 +239,39 @@ L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:51
|
||||
A: index=7\n
|
||||
L: iommu=../../virtual/iommu/dmar1
|
||||
L: iommu_group=../../../kernel/iommu_groups/8
|
||||
A: irq=145\n
|
||||
A: irq=133\n
|
||||
A: label=Onboard - Other\n
|
||||
A: local_cpulist=0-15\n
|
||||
A: local_cpus=ffff\n
|
||||
A: modalias=pci:v00008086d000051EDsv0000144Dsd0000C870bc0Csc03i30\n
|
||||
A: msi_bus=1\n
|
||||
A: msi_irqs/145=msi\n
|
||||
A: msi_irqs/133=msi\n
|
||||
A: msi_irqs/134=msi\n
|
||||
A: msi_irqs/135=msi\n
|
||||
A: msi_irqs/136=msi\n
|
||||
A: msi_irqs/137=msi\n
|
||||
A: msi_irqs/138=msi\n
|
||||
A: msi_irqs/139=msi\n
|
||||
A: msi_irqs/140=msi\n
|
||||
A: numa_node=-1\n
|
||||
A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 6 9 2112 9\nxHCI ring segments 26 34 4096 34\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 32 128 1\nbuffer-32 0 0 32 0\n
|
||||
A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 6 7 2112 7\nxHCI ring segments 27 27 4096 27\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\n
|
||||
A: power/async=enabled\n
|
||||
A: power/control=auto\n
|
||||
A: power/runtime_active_kids=1\n
|
||||
A: power/runtime_active_time=337964621\n
|
||||
A: power/runtime_active_time=2376480\n
|
||||
A: power/runtime_enabled=enabled\n
|
||||
A: power/runtime_status=active\n
|
||||
A: power/runtime_suspended_time=438\n
|
||||
A: power/runtime_suspended_time=94028360\n
|
||||
A: power/runtime_usage=0\n
|
||||
A: power/wakeup=enabled\n
|
||||
A: power/wakeup_abort_count=0\n
|
||||
A: power/wakeup_active=0\n
|
||||
A: power/wakeup_active_count=7\n
|
||||
A: power/wakeup_active_count=1\n
|
||||
A: power/wakeup_count=0\n
|
||||
A: power/wakeup_expire_count=7\n
|
||||
A: power/wakeup_last_time_ms=336554844\n
|
||||
A: power/wakeup_max_time_ms=105\n
|
||||
A: power/wakeup_total_time_ms=721\n
|
||||
A: power/wakeup_expire_count=1\n
|
||||
A: power/wakeup_last_time_ms=41666464\n
|
||||
A: power/wakeup_max_time_ms=101\n
|
||||
A: power/wakeup_total_time_ms=101\n
|
||||
A: power_state=D0\n
|
||||
A: resource=0x000000601d160000 0x000000601d16ffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n
|
||||
A: revision=0x01\n
|
||||
|
||||
@@ -14,9 +14,6 @@ envs.prepend('LD_LIBRARY_PATH', meson.project_build_root() / 'libfprint')
|
||||
# random numbers rather than proper ones)
|
||||
envs.set('FP_DEVICE_EMULATION', '1')
|
||||
|
||||
# Path to SDCP virtual device binary, only used for virtual-sdcp test
|
||||
envs.set('SDCP_VIRT_BINARY', get_option('sdcp_virt_binary'))
|
||||
|
||||
# Set a colon-separated list of native drivers we enable in tests
|
||||
envs.set('FP_DRIVERS_ALLOWLIST', ':'.join([
|
||||
'virtual_image',
|
||||
@@ -55,9 +52,9 @@ drivers_tests = [
|
||||
'nb1010',
|
||||
'egis0570',
|
||||
'egismoc',
|
||||
'egismoc-05a1',
|
||||
'egismoc-0586',
|
||||
'egismoc-0587',
|
||||
# 'egismoc-05a1', # commented out until new capture with SDCP support can be provided
|
||||
# 'egismoc-0586', # commented out until new capture with SDCP support can be provided
|
||||
# 'egismoc-0587', # commented out until new capture with SDCP support can be provided
|
||||
'fpcmoc',
|
||||
'realtek',
|
||||
'realtek-5816',
|
||||
@@ -249,13 +246,10 @@ else
|
||||
endforeach
|
||||
endif
|
||||
|
||||
test_utils = static_library('fprint-test-utils',
|
||||
sources: [
|
||||
'test-utils.c',
|
||||
'test-device-fake.c',
|
||||
],
|
||||
dependencies: libfprint_private_dep,
|
||||
install: false)
|
||||
test_util_sources = [
|
||||
'test-utils.c',
|
||||
'test-device-fake.c',
|
||||
]
|
||||
|
||||
unit_tests = [
|
||||
'fpi-device',
|
||||
@@ -270,6 +264,22 @@ if 'virtual_image' in drivers
|
||||
]
|
||||
endif
|
||||
|
||||
if 'sdcp' in driver_helpers
|
||||
test_util_sources += [
|
||||
'test-sdcp-device-fake.c',
|
||||
'test-sdcp-utils.c',
|
||||
]
|
||||
unit_tests += [
|
||||
'fp-sdcp-device',
|
||||
'fpi-sdcp',
|
||||
]
|
||||
endif
|
||||
|
||||
test_utils = static_library('fprint-test-utils',
|
||||
sources: test_util_sources,
|
||||
dependencies: libfprint_private_dep,
|
||||
install: false)
|
||||
|
||||
unit_tests_deps = { 'fpi-assembling' : [cairo_dep] }
|
||||
|
||||
foreach test_name: unit_tests
|
||||
|
||||
Binary file not shown.
Binary file not shown.
143
tests/test-fp-sdcp-device.c
Normal file
143
tests/test-fp-sdcp-device.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* FpSdcpDevice Unit tests
|
||||
* Copyright (C) 2025 Joshua Grisham <josh@joshuagrisham.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <libfprint/fprint.h>
|
||||
|
||||
#include "test-sdcp-device-fake.h"
|
||||
#include "test-sdcp-utils.h"
|
||||
|
||||
static void
|
||||
test_set_get_print_id (void)
|
||||
{
|
||||
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_SDCP_DEVICE_FAKE, NULL);
|
||||
g_autoptr(FpPrint) print = fp_print_new (device);
|
||||
g_autoptr(GBytes) id1 = NULL;
|
||||
g_autoptr(GBytes) id2 = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
id1 = fpi_sdcp_generate_random (&error);
|
||||
|
||||
g_assert_nonnull (id1);
|
||||
g_assert_no_error (error);
|
||||
|
||||
fpi_sdcp_device_set_print_id (print, id1);
|
||||
fpi_sdcp_device_get_print_id (print, &id2);
|
||||
|
||||
g_assert_nonnull (id2);
|
||||
g_assert_true (g_bytes_equal (id1, id2));
|
||||
}
|
||||
|
||||
static void
|
||||
test_identify (void)
|
||||
{
|
||||
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_SDCP_DEVICE_FAKE, NULL);
|
||||
g_autoptr(GPtrArray) match_prints = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
g_autoptr(FpPrint) template_print = fp_print_new (device);
|
||||
g_autoptr(FpPrint) print = NULL;
|
||||
g_autoptr(FpPrint) matched_print = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
g_assert_true (fp_device_open_sync (device, NULL, &error));
|
||||
|
||||
print = fp_device_enroll_sync (device, template_print, NULL, NULL, NULL, &error);
|
||||
g_ptr_array_add (match_prints, g_object_ref_sink (print));
|
||||
|
||||
g_assert_true (fp_device_identify_sync (device, match_prints, NULL, NULL, NULL,
|
||||
&matched_print, &print, &error));
|
||||
|
||||
g_assert_true (fp_device_close_sync (device, NULL, &error));
|
||||
}
|
||||
|
||||
static void
|
||||
test_enroll (void)
|
||||
{
|
||||
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_SDCP_DEVICE_FAKE, NULL);
|
||||
g_autoptr(FpPrint) template_print = fp_print_new (device);
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
g_assert_true (fp_device_open_sync (device, NULL, &error));
|
||||
|
||||
g_assert_nonnull (fp_device_enroll_sync (device, template_print, NULL, NULL, NULL, &error));
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_assert_true (fp_device_close_sync (device, NULL, &error));
|
||||
}
|
||||
|
||||
static void
|
||||
test_list (void)
|
||||
{
|
||||
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_SDCP_DEVICE_FAKE, NULL);
|
||||
g_autoptr(GPtrArray) prints = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
g_assert_true (fp_device_open_sync (device, NULL, &error));
|
||||
|
||||
prints = fp_device_list_prints_sync (device, NULL, &error);
|
||||
|
||||
g_assert_nonnull (prints);
|
||||
g_assert_true (prints->len == 1);
|
||||
|
||||
/* TODO: Should we also check the print's "fpi-data" for the expected ID? */
|
||||
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_assert_true (fp_device_close_sync (device, NULL, &error));
|
||||
}
|
||||
|
||||
static void
|
||||
test_reconnect (void)
|
||||
{
|
||||
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_SDCP_DEVICE_FAKE, NULL);
|
||||
FpiSdcpDeviceFake *fake_device = FPI_SDCP_DEVICE_FAKE (device);
|
||||
|
||||
g_assert_true (fp_device_open_sync (device, NULL, NULL));
|
||||
g_assert (fake_device->reconnect_called == FALSE);
|
||||
|
||||
g_assert_true (fp_device_close_sync (device, NULL, NULL));
|
||||
|
||||
/* open a second time to reconnect */
|
||||
g_assert_true (fp_device_open_sync (device, NULL, NULL));
|
||||
g_assert (fake_device->reconnect_called == TRUE);
|
||||
|
||||
g_assert_true (fp_device_close_sync (device, NULL, NULL));
|
||||
}
|
||||
|
||||
static void
|
||||
test_open (void)
|
||||
{
|
||||
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_SDCP_DEVICE_FAKE, NULL);
|
||||
|
||||
g_assert_true (fp_device_open_sync (device, NULL, NULL));
|
||||
g_assert_true (fp_device_close_sync (device, NULL, NULL));
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/sdcp_device/open", test_open);
|
||||
g_test_add_func ("/sdcp_device/reconnect", test_reconnect);
|
||||
g_test_add_func ("/sdcp_device/list", test_list);
|
||||
g_test_add_func ("/sdcp_device/enroll", test_enroll);
|
||||
g_test_add_func ("/sdcp_device/identify", test_identify);
|
||||
g_test_add_func ("/sdcp_device/set_get_print_id", test_set_get_print_id);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
162
tests/test-fpi-sdcp.c
Normal file
162
tests/test-fpi-sdcp.c
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Secure Device Connection Protocol (SDCP) support unit tests
|
||||
* Copyright (C) 2025 Joshua Grisham <josh@joshuagrisham.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#define FP_COMPONENT "test_fpi_sdcp"
|
||||
#include "fpi-log.h"
|
||||
|
||||
#include "test-sdcp-utils.h"
|
||||
|
||||
static void
|
||||
test_generate_enrollment_id (void)
|
||||
{
|
||||
g_autoptr(GBytes) id = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GBytes) application_secret = g_bytes_from_hex (application_secret_hex);
|
||||
g_autoptr(GBytes) nonce = g_bytes_from_hex (enrollment_nonce_hex);
|
||||
g_autoptr(GBytes) expected_id = g_bytes_from_hex (enrollment_enrollment_id_hex);
|
||||
|
||||
id = fpi_sdcp_generate_enrollment_id (application_secret, nonce, &error);
|
||||
|
||||
fp_dbg ("id:");
|
||||
fp_dbg_hex_dump_gbytes (id);
|
||||
|
||||
fp_dbg ("expected:");
|
||||
fp_dbg_hex_dump_gbytes (expected_id);
|
||||
|
||||
g_assert (g_bytes_equal (expected_id, id));
|
||||
g_assert_null (error);
|
||||
}
|
||||
|
||||
static void
|
||||
test_verify_identify (void)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GBytes) application_secret = g_bytes_from_hex (application_secret_hex);
|
||||
g_autoptr(GBytes) nonce = g_bytes_from_hex (identify_nonce_hex);
|
||||
g_autoptr(GBytes) id = g_bytes_from_hex (identify_enrollment_id_hex);
|
||||
g_autoptr(GBytes) mac = g_bytes_from_hex (identify_mac_hex);
|
||||
|
||||
g_assert_true (fpi_sdcp_verify_identify (application_secret, nonce, id, mac, &error));
|
||||
g_assert_null (error);
|
||||
}
|
||||
|
||||
static void
|
||||
test_verify_reconnect (void)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GBytes) application_secret = g_bytes_from_hex (application_secret_hex);
|
||||
g_autoptr(GBytes) random = g_bytes_from_hex (reconnect_random_hex);
|
||||
g_autoptr(GBytes) mac = g_bytes_from_hex (reconnect_mac_hex);
|
||||
|
||||
g_assert_true (fpi_sdcp_verify_reconnect (application_secret, random, mac, &error));
|
||||
g_assert_null (error);
|
||||
}
|
||||
|
||||
static void
|
||||
test_verify_connect (void)
|
||||
{
|
||||
g_autoptr(GBytes) application_secret = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
g_autoptr(GBytes) host_private_key = g_bytes_from_hex (host_private_key_hex);
|
||||
g_autoptr(GBytes) host_random = g_bytes_from_hex (host_random_hex);
|
||||
g_autoptr(GBytes) device_random = g_bytes_from_hex (device_random_hex);
|
||||
g_autoptr(GBytes) connect_mac = g_bytes_from_hex (connect_mac_hex);
|
||||
FpiSdcpClaim *claim = sdcp_test_claim ();
|
||||
|
||||
g_autoptr(GBytes) expected_application_secret = g_bytes_from_hex (application_secret_hex);
|
||||
|
||||
g_assert_true (fpi_sdcp_verify_connect (host_private_key,
|
||||
host_random,
|
||||
device_random,
|
||||
claim,
|
||||
connect_mac,
|
||||
TRUE,
|
||||
TRUE,
|
||||
&application_secret,
|
||||
&error));
|
||||
|
||||
g_assert_null (error);
|
||||
g_assert (g_bytes_get_size (application_secret) == SDCP_APPLICATION_SECRET_SIZE);
|
||||
|
||||
fp_dbg ("application_secret:");
|
||||
fp_dbg_hex_dump_gbytes (application_secret);
|
||||
|
||||
fp_dbg ("expected:");
|
||||
fp_dbg_hex_dump_gbytes (expected_application_secret);
|
||||
|
||||
g_assert_true (g_bytes_equal (expected_application_secret, application_secret));
|
||||
|
||||
fpi_sdcp_claim_free (claim);
|
||||
}
|
||||
|
||||
static void
|
||||
test_generate_random (void)
|
||||
{
|
||||
g_autoptr(GBytes) random = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
random = fpi_sdcp_generate_random (&error);
|
||||
|
||||
g_assert_null (error);
|
||||
g_assert (g_bytes_get_size (random) == SDCP_RANDOM_SIZE);
|
||||
|
||||
fp_dbg ("random:");
|
||||
fp_dbg_hex_dump_gbytes (random);
|
||||
}
|
||||
|
||||
static void
|
||||
test_generate_host_key (void)
|
||||
{
|
||||
g_autoptr(GBytes) private_key = NULL;
|
||||
g_autoptr(GBytes) public_key = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
gsize len = 0;
|
||||
|
||||
fpi_sdcp_generate_host_key (&private_key, &public_key, &error);
|
||||
|
||||
g_assert_null (error);
|
||||
|
||||
g_bytes_get_data (private_key, &len);
|
||||
g_assert (len == 32);
|
||||
|
||||
fp_dbg ("private_key:");
|
||||
fp_dbg_hex_dump_gbytes (private_key);
|
||||
|
||||
g_bytes_get_data (public_key, &len);
|
||||
g_assert (len == SDCP_PUBLIC_KEY_SIZE);
|
||||
|
||||
fp_dbg ("public_key:");
|
||||
fp_dbg_hex_dump_gbytes (public_key);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/sdcp/generate_host_key", test_generate_host_key);
|
||||
g_test_add_func ("/sdcp/generate_random", test_generate_random);
|
||||
g_test_add_func ("/sdcp/verify_connect", test_verify_connect);
|
||||
g_test_add_func ("/sdcp/verify_reconnect", test_verify_reconnect);
|
||||
g_test_add_func ("/sdcp/verify_identify", test_verify_identify);
|
||||
g_test_add_func ("/sdcp/generate_enrollment_id", test_generate_enrollment_id);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
196
tests/test-sdcp-device-fake.c
Normal file
196
tests/test-sdcp-device-fake.c
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Virtual driver for SDCP unit testing
|
||||
* Completes actions using example values from Microsoft's SDCP documentation
|
||||
* Copyright (C) 2025 Joshua Grisham <josh@joshuagrisham.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#define FP_COMPONENT "fake_test_sdcp_dev"
|
||||
#include "fpi-log.h"
|
||||
|
||||
#include "test-sdcp-device-fake.h"
|
||||
|
||||
G_DEFINE_TYPE (FpiSdcpDeviceFake, fpi_sdcp_device_fake, FP_TYPE_SDCP_DEVICE)
|
||||
|
||||
static const FpIdEntry driver_ids[] = {
|
||||
{ .virtual_envvar = "FP_VIRTUAL_FAKE_SDCP_DEVICE" },
|
||||
{ .virtual_envvar = NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
fpi_sdcp_device_fake_identify (FpSdcpDevice *sdcp_device)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GBytes) nonce = NULL;
|
||||
g_autoptr(GBytes) identify_enrollment_id = g_bytes_from_hex (identify_enrollment_id_hex);
|
||||
g_autoptr(GBytes) identify_mac = g_bytes_from_hex (identify_mac_hex);
|
||||
|
||||
/*
|
||||
* Normally, a driver would fetch the identify data and then send it to the
|
||||
* device's Identify command. In this fake device, we will just fetch and
|
||||
* verify the nonce was generated but do nothing with it
|
||||
*/
|
||||
|
||||
fpi_sdcp_device_get_identify_data (sdcp_device, &nonce);
|
||||
|
||||
g_assert (nonce);
|
||||
g_assert (g_bytes_get_size (nonce) == SDCP_NONCE_SIZE);
|
||||
|
||||
/*
|
||||
* In emulation mode (FP_DEVICE_EMULATION=1), a different hard-coded nonce is
|
||||
* set in fpi-sdcp-device, which was the same nonce used to generate both the
|
||||
* identify_enrollment_id and identify_mac values provided here
|
||||
*/
|
||||
|
||||
fpi_sdcp_device_identify_complete (sdcp_device, identify_enrollment_id, identify_mac, error);
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_sdcp_device_fake_enroll_commit (FpSdcpDevice *sdcp_device, GBytes *id)
|
||||
{
|
||||
fpi_sdcp_device_enroll_commit_complete (sdcp_device, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_sdcp_device_fake_enroll (FpSdcpDevice *sdcp_device)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
GBytes *enrollment_nonce = g_bytes_from_hex (enrollment_nonce_hex);
|
||||
|
||||
fpi_sdcp_device_enroll_commit (sdcp_device, enrollment_nonce, error);
|
||||
|
||||
g_bytes_unref (enrollment_nonce);
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_sdcp_device_fake_list (FpSdcpDevice *sdcp_device)
|
||||
{
|
||||
g_autoptr(GBytes) identify_enrollment_id = g_bytes_from_hex (identify_enrollment_id_hex);
|
||||
GPtrArray *enrollment_ids = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref);
|
||||
|
||||
g_ptr_array_add (enrollment_ids, g_steal_pointer (&identify_enrollment_id));
|
||||
|
||||
for (gint i = 0; i < enrollment_ids->len; i++)
|
||||
{
|
||||
fp_dbg ("print %d:", i);
|
||||
fp_dbg_hex_dump_gbytes (g_ptr_array_index (enrollment_ids, i));
|
||||
}
|
||||
|
||||
fpi_sdcp_device_list_complete (sdcp_device, g_steal_pointer (&enrollment_ids), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_sdcp_device_fake_reconnect (FpSdcpDevice *sdcp_device)
|
||||
{
|
||||
FpiSdcpDeviceFake *fake_device = FPI_SDCP_DEVICE_FAKE (sdcp_device);
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GBytes) random = NULL;
|
||||
g_autoptr(GBytes) reconnect_mac = g_bytes_from_hex (reconnect_mac_hex);
|
||||
|
||||
/*
|
||||
* Normally, a driver would fetch the reconnect data and then send it to the
|
||||
* device's Reconnect command. In this fake device, we will just fetch and
|
||||
* verify the random was generated but do nothing with it
|
||||
*/
|
||||
|
||||
fpi_sdcp_device_get_reconnect_data (sdcp_device, &random);
|
||||
|
||||
g_assert (random);
|
||||
g_assert (g_bytes_get_size (random) == SDCP_RANDOM_SIZE);
|
||||
|
||||
/*
|
||||
* In emulation mode (FP_DEVICE_EMULATION=1), a different hard-coded random is
|
||||
* set in fpi-sdcp-device, which was the same random used to generate the
|
||||
* reconnect_mac value provided here
|
||||
*/
|
||||
|
||||
fpi_sdcp_device_reconnect_complete (sdcp_device, reconnect_mac, error);
|
||||
|
||||
fake_device->reconnect_called = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_sdcp_device_fake_connect (FpSdcpDevice *sdcp_device)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GBytes) host_random = NULL;
|
||||
g_autoptr(GBytes) host_public_key = NULL;
|
||||
g_autoptr(GBytes) device_random = g_bytes_from_hex (device_random_hex);
|
||||
g_autoptr(GBytes) connect_mac = g_bytes_from_hex (connect_mac_hex);
|
||||
FpiSdcpClaim *claim = sdcp_test_claim ();
|
||||
|
||||
fp_device_open_sync (FP_DEVICE (sdcp_device), NULL, NULL);
|
||||
|
||||
fpi_sdcp_device_get_connect_data (sdcp_device, &host_random, &host_public_key);
|
||||
|
||||
g_assert (host_random);
|
||||
g_assert (g_bytes_get_size (host_random) == SDCP_RANDOM_SIZE);
|
||||
|
||||
g_assert (host_public_key);
|
||||
g_assert (g_bytes_get_size (host_public_key) == SDCP_PUBLIC_KEY_SIZE);
|
||||
|
||||
fpi_sdcp_device_connect_complete (sdcp_device, device_random, claim, connect_mac, error);
|
||||
|
||||
fpi_sdcp_claim_free (claim);
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_sdcp_device_fake_close (FpDevice *device)
|
||||
{
|
||||
fpi_device_close_complete (device, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_sdcp_device_fake_open (FpSdcpDevice *sdcp_device)
|
||||
{
|
||||
fpi_sdcp_device_open_complete (sdcp_device, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_sdcp_device_fake_init (FpiSdcpDeviceFake *self)
|
||||
{
|
||||
G_DEBUG_HERE ();
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_sdcp_device_fake_class_init (FpiSdcpDeviceFakeClass *klass)
|
||||
{
|
||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||
FpSdcpDeviceClass *sdcp_dev_class = FP_SDCP_DEVICE_CLASS (klass);
|
||||
|
||||
dev_class->id = FP_COMPONENT;
|
||||
dev_class->full_name = "Virtual SDCP test device";
|
||||
dev_class->type = FP_DEVICE_TYPE_VIRTUAL;
|
||||
dev_class->id_table = driver_ids;
|
||||
dev_class->nr_enroll_stages = 5;
|
||||
dev_class->scan_type = FP_SCAN_TYPE_PRESS;
|
||||
|
||||
sdcp_dev_class->ignore_device_certificate = FALSE;
|
||||
sdcp_dev_class->ignore_device_signatures = FALSE;
|
||||
|
||||
sdcp_dev_class->open = fpi_sdcp_device_fake_open;
|
||||
sdcp_dev_class->connect = fpi_sdcp_device_fake_connect;
|
||||
sdcp_dev_class->reconnect = fpi_sdcp_device_fake_reconnect;
|
||||
sdcp_dev_class->list = fpi_sdcp_device_fake_list;
|
||||
sdcp_dev_class->enroll = fpi_sdcp_device_fake_enroll;
|
||||
sdcp_dev_class->enroll_commit = fpi_sdcp_device_fake_enroll_commit;
|
||||
sdcp_dev_class->identify = fpi_sdcp_device_fake_identify;
|
||||
|
||||
dev_class->close = fpi_sdcp_device_fake_close;
|
||||
|
||||
fpi_device_class_auto_initialize_features (dev_class);
|
||||
dev_class->features |= FP_DEVICE_FEATURE_STORAGE;
|
||||
}
|
||||
33
tests/test-sdcp-device-fake.h
Normal file
33
tests/test-sdcp-device-fake.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Virtual driver for SDCP unit testing
|
||||
* Copyright (C) 2025 Joshua Grisham <josh@joshuagrisham.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fpi-sdcp-device.h"
|
||||
|
||||
#include "test-sdcp-utils.h"
|
||||
|
||||
#define FPI_TYPE_SDCP_DEVICE_FAKE (fpi_sdcp_device_fake_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (FpiSdcpDeviceFake, fpi_sdcp_device_fake, FPI, SDCP_DEVICE_FAKE, FpSdcpDevice)
|
||||
|
||||
struct _FpiSdcpDeviceFake
|
||||
{
|
||||
FpDevice parent;
|
||||
gboolean reconnect_called;
|
||||
};
|
||||
60
tests/test-sdcp-utils.c
Normal file
60
tests/test-sdcp-utils.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Secure Device Connection Protocol (SDCP) support test utils
|
||||
* Copyright (C) 2025 Joshua Grisham <josh@joshuagrisham.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "test-sdcp-utils.h"
|
||||
|
||||
static const guint8 from_hex_map[] =
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 01234567
|
||||
0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 89:;<=>?
|
||||
0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, // @abcdef
|
||||
};
|
||||
|
||||
GBytes *
|
||||
g_bytes_from_hex (const gchar *hex)
|
||||
{
|
||||
g_autoptr(GBytes) res = NULL;
|
||||
guint8 b0, b1;
|
||||
gsize bytes_len = strlen (hex) / 2;
|
||||
guint8 *bytes = g_malloc0 (bytes_len);
|
||||
|
||||
for (int i = 0; i < strlen (hex) - 1; i += 2)
|
||||
{
|
||||
b0 = ((guint8)hex[i+0] & 0x1F) ^ 0x10;
|
||||
b1 = ((guint8)hex[i+1] & 0x1F) ^ 0x10;
|
||||
bytes[i/2] = (guint8)(from_hex_map[b0] << 4) | from_hex_map[b1];
|
||||
}
|
||||
|
||||
res = g_bytes_new_take (bytes, bytes_len);
|
||||
|
||||
return g_steal_pointer (&res);
|
||||
}
|
||||
|
||||
FpiSdcpClaim *
|
||||
sdcp_test_claim (void)
|
||||
{
|
||||
FpiSdcpClaim *claim = g_new0 (FpiSdcpClaim, 1);
|
||||
claim->model_certificate = g_bytes_from_hex (model_certificate_hex);
|
||||
claim->device_public_key = g_bytes_from_hex (device_public_key_hex);
|
||||
claim->firmware_public_key = g_bytes_from_hex (firmware_public_key_hex);
|
||||
claim->firmware_hash = g_bytes_from_hex (firmware_hash_hex);
|
||||
claim->model_signature = g_bytes_from_hex (model_signature_hex);
|
||||
claim->device_signature = g_bytes_from_hex (device_signature_hex);
|
||||
return g_steal_pointer (&claim);
|
||||
}
|
||||
102
tests/test-sdcp-utils.h
Normal file
102
tests/test-sdcp-utils.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Secure Device Connection Protocol (SDCP) support test utils
|
||||
* Copyright (C) 2025 Joshua Grisham <josh@joshuagrisham.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fpi-log.h"
|
||||
#include "fpi-sdcp.h"
|
||||
#include "fpi-sdcp-device.h"
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* host keys */
|
||||
|
||||
static const gchar host_private_key_hex[] = "8400ed14579cdf11586477e836e8cb52708441c1c2a447c218c5bbc2d118fbc7";
|
||||
static const gchar host_public_key_hex[] = "0452f056ffb9c6728654771a3629b770767b19a2106a4916fb81ba06ef6797c4"
|
||||
"a3df672ade0e9116d1abe278a8223abde4958d62d4ff6882159f0617c6f8ce10"
|
||||
"bf";
|
||||
static const gchar host_random_hex[] = "d877403abe82f4d97e1448c5052d83a532a45e56ef049cbbf981137520e713bf";
|
||||
|
||||
/* device keys */
|
||||
|
||||
static const gchar device_random_hex[] = "6e2f6c1abef2a1973fb1315a17e209fdb0c78520f1fd6a85d294d7aeb40a04a7";
|
||||
static const gchar model_certificate_hex[] = "30820323308202caa00302010202133300000004c45d661d6eed040d00000000"
|
||||
"0004300a06082a8648ce3d0403023056310b3009060355040613025553311e30"
|
||||
"1c060355040a13154d6963726f736f667420436f72706f726174696f6e312730"
|
||||
"250603550403131e57696e646f77732048656c6c6f2032303936414443432043"
|
||||
"412032303231301e170d3232303130343231303033355a170d32333034303432"
|
||||
"31303033355a301c311a3018060355040313115365637572652042494f205365"
|
||||
"6e736f723059301306072a8648ce3d020106082a8648ce3d0301070342000414"
|
||||
"cfc287f872a2b7d3339e0b31390e3ca688e61165eaa6687c959270e07666b1fa"
|
||||
"19e3efaf1750d134a886d494424fe471970c4b06838408a18d1f5d57735dd7a3"
|
||||
"8201af308201ab30750603551d11046e306ca46a30683132303006082b060104"
|
||||
"82376402132436423045413344382d383339372d343444332d383043392d3930"
|
||||
"324130414346344343303132303006082b060104823764011324413944423730"
|
||||
"32362d433646462d344341462d423134382d393133454641333730423933301d"
|
||||
"0603551d0e04160414db6d66d642b7236d5e6bb2ec2186decda98067b6301f06"
|
||||
"03551d23041830168014bf3748e34a632de953a3ba890298c069472a99b9305f"
|
||||
"0603551d1f045830563054a052a050864e687474703a2f2f7777772e6d696372"
|
||||
"6f736f66742e636f6d2f706b696f70732f63726c2f57696e646f777325323048"
|
||||
"656c6c6f25323032303936414443432532304341253230323032312e63726c30"
|
||||
"6c06082b060105050701010460305e305c06082b060105050730028650687474"
|
||||
"703a2f2f7777772e6d6963726f736f66742e636f6d2f706b696f70732f636572"
|
||||
"74732f57696e646f777325323048656c6c6f2532303230393641444343253230"
|
||||
"4341253230323032312e637274300c0603551d130101ff040230003015060355"
|
||||
"1d25040e300c060a2b0601040182374c2b01300a06082a8648ce3d0403020347"
|
||||
"003044022077553ef520f732e03cd740c8cf807e6366e12918bc581f75bfe0f1"
|
||||
"95b7b1fd4f0220324e25b93b9da7538b797a624272b21b7cc0e96ea487924250"
|
||||
"4677600450f283";
|
||||
static const gchar device_public_key_hex[] = "04e2787890a684f95b96b9a2316ca8d3d33d4d79ff4c89dc6f9e888e973990d1"
|
||||
"d3154133dcc8bd33b99af9dbf0673390d404d092498a3f214cd93f9b9f28fb5f"
|
||||
"66";
|
||||
static const gchar firmware_public_key_hex[] = "04f06a84ab51a3a6e8ff46868f91dd720e4cdad21f2e090d11e8f9bfc2ea19ee"
|
||||
"1b5eac850b4532968a9399f76cd779e7723e8c2ca73b597c0df5f73b94a36f2b"
|
||||
"6c";
|
||||
static const gchar firmware_hash_hex[] = "c3bf47ea1f4a4a605470313cacb3a44f4a461f68c6faeab07e737610cb5ac835";
|
||||
static const gchar model_signature_hex[] = "febe6ba3107813e185f05189e69ae79d9f7a40802582d94324459844c8b97ec6"
|
||||
"c5daed5462276cb8a193c33e350424b0305d63d79a93a9188dcfc0cb5595f6c1";
|
||||
static const gchar device_signature_hex[] = "10cc57dd8dafb463510a7327a5fca49b698e999b36448e2023eaf0dff0b0d4a3"
|
||||
"4f1caf4e872b77364a0a00d7476554d0324c4cc931937e232a0315837d696c06";
|
||||
static const gchar connect_mac_hex[] = "422bc475a78f972bae842a28e5ad721207457fcbd9a1a3aaf71587c07b84d247";
|
||||
|
||||
/* expected application_secret based on above */
|
||||
|
||||
static const gchar application_secret_hex[] = "13330ba3135ecf5dc71cede01a886540771efab35c8ba053902b2c1ee7de6efe";
|
||||
|
||||
/* test verify_reconnect values */
|
||||
|
||||
static const gchar reconnect_random_hex[] = "8a7451c1d3a8dca1c1330ca50d73454b351a49f46c8e9dcee15c964d295c31c9";
|
||||
static const gchar reconnect_mac_hex[] = "bf3f3bb3bd6ecb2784c160f526f7bc3b3ca8faf5557194c48e0024a0493903c7";
|
||||
|
||||
/* test verify_identify values */
|
||||
|
||||
static const gchar identify_nonce_hex[] = "3a1b506f5bec089059acefb9b44dfbdea7a599ee9aa267e5252664d60b798053";
|
||||
static const gchar identify_enrollment_id_hex[] = "ef2055244e49c39beabdac49fdf4ee418605d195da23b202ba219a13831ae621";
|
||||
static const gchar identify_mac_hex[] = "f0a5c5f261c2fe937d8b113857bc629cd07ca88edf991f69ca6fae5c332390f6";
|
||||
|
||||
/* test enrollment_id values */
|
||||
|
||||
static const gchar enrollment_nonce_hex[] = "c2101c44c9a667bba397e81f48b143398603e2c9335a68b409e1dbe71e005ca2";
|
||||
static const gchar enrollment_enrollment_id_hex[] = "67109dc70a216331f1580ddac601915929c1ff6c9bcba6544ba572c660c3d91e";
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
GBytes *g_bytes_from_hex (const gchar *hex);
|
||||
|
||||
FpiSdcpClaim *sdcp_test_claim (void);
|
||||
@@ -1,144 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
try:
|
||||
import gi
|
||||
import os
|
||||
|
||||
from gi.repository import GLib, Gio
|
||||
|
||||
import unittest
|
||||
import subprocess
|
||||
import shutil
|
||||
import tempfile
|
||||
except Exception as e:
|
||||
print("Missing dependencies: %s" % str(e))
|
||||
sys.exit(77)
|
||||
|
||||
FPrint = None
|
||||
|
||||
# Re-run the test with the passed wrapper if set
|
||||
wrapper = os.getenv('LIBFPRINT_TEST_WRAPPER')
|
||||
if wrapper:
|
||||
wrap_cmd = wrapper.split(' ') + [sys.executable, os.path.abspath(__file__)] + \
|
||||
sys.argv[1:]
|
||||
os.unsetenv('LIBFPRINT_TEST_WRAPPER')
|
||||
sys.exit(subprocess.check_call(wrap_cmd))
|
||||
|
||||
# Only permit loading virtual_sdcp driver for tests in this file
|
||||
os.environ['FP_DRIVERS_WHITELIST'] = 'virtual_sdcp'
|
||||
|
||||
if hasattr(os.environ, 'MESON_SOURCE_ROOT'):
|
||||
root = os.environ['MESON_SOURCE_ROOT']
|
||||
else:
|
||||
root = os.path.join(os.path.dirname(__file__), '..')
|
||||
|
||||
ctx = GLib.main_context_default()
|
||||
|
||||
class VirtualSDCP(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
os.environ['FP_VIRTUAL_SDCP'] = os.environ['SDCP_VIRT_BINARY']
|
||||
|
||||
cls.ctx = FPrint.Context()
|
||||
|
||||
cls.dev = None
|
||||
for dev in cls.ctx.get_devices():
|
||||
cls.dev = dev
|
||||
break
|
||||
|
||||
assert cls.dev is not None, "You need to compile with virtual_sdcp for testing"
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
del cls.dev
|
||||
del cls.ctx
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def enroll(self, progress_cb=None):
|
||||
# Enroll another print
|
||||
template = FPrint.Print.new(self.dev)
|
||||
template.props.finger = FPrint.Finger.LEFT_THUMB
|
||||
template.props.username = "testuser"
|
||||
template.props.description = "test print"
|
||||
datetime = GLib.DateTime.new_now_local()
|
||||
date = GLib.Date()
|
||||
date.set_dmy(*datetime.get_ymd()[::-1])
|
||||
template.props.enroll_date = date
|
||||
return self.dev.enroll_sync(template, None, progress_cb, None)
|
||||
|
||||
def test_connect(self):
|
||||
self.dev.open_sync()
|
||||
self.dev.close_sync()
|
||||
|
||||
def test_reconnect(self):
|
||||
# Ensure device was opened once before, this may be a reconnect if
|
||||
# it is the same process as another test.
|
||||
self.dev.open_sync()
|
||||
self.dev.close_sync()
|
||||
|
||||
# Check that a reconnect happens on next open. To know about this, we
|
||||
# need to parse check log messages for that.
|
||||
success = [False]
|
||||
def log_func(domain, level, msg):
|
||||
print("log: '%s', '%s', '%s'" % (str(domain), str(level), msg))
|
||||
if msg == 'Reconnect succeeded':
|
||||
success[0] = True
|
||||
|
||||
# Call default handler
|
||||
GLib.log_default_handler(domain, level, msg)
|
||||
|
||||
handler_id = GLib.log_set_handler('libfprint-sdcp_device', GLib.LogLevelFlags.LEVEL_DEBUG, log_func)
|
||||
self.dev.open_sync()
|
||||
self.dev.close_sync()
|
||||
GLib.log_remove_handler('libfprint-sdcp_device', handler_id)
|
||||
assert success[0]
|
||||
|
||||
def test_enroll(self):
|
||||
self.dev.open_sync()
|
||||
|
||||
# Must return a print
|
||||
assert isinstance(self.enroll(), FPrint.Print)
|
||||
|
||||
self.dev.close_sync()
|
||||
|
||||
|
||||
def test_verify(self):
|
||||
self.dev.open_sync()
|
||||
|
||||
# Enroll a new print (will be the last), check that it verifies
|
||||
p = self.enroll()
|
||||
match, dev_print = self.dev.verify_sync(p)
|
||||
assert match
|
||||
|
||||
# The returned "device" print is identical
|
||||
assert p.equal(dev_print)
|
||||
|
||||
# We can do the same with it
|
||||
match, dev_print2 = self.dev.verify_sync(dev_print)
|
||||
assert match
|
||||
|
||||
# Now, enroll a new print, causing the old one to not match anymore
|
||||
# (the device always claims to see the last enrolled print).
|
||||
self.enroll()
|
||||
match, dev_print = self.dev.verify_sync(p)
|
||||
assert match is False
|
||||
|
||||
self.dev.close_sync()
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
gi.require_version('FPrint', '2.0')
|
||||
from gi.repository import FPrint
|
||||
except Exception as e:
|
||||
print("Missing dependencies: %s" % str(e))
|
||||
sys.exit(77)
|
||||
|
||||
# avoid writing to stderr
|
||||
unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2))
|
||||
Reference in New Issue
Block a user