Compare commits
16 commits
master
...
feature/sd
Author | SHA1 | Date | |
---|---|---|---|
|
64bbdc81a2 | ||
|
d6dc3403d8 | ||
|
4f100956ac | ||
|
ac5736a90f | ||
|
bf6df9e889 | ||
|
a5a4415003 | ||
|
40c9669e78 | ||
|
8767796562 | ||
|
aa1981e280 | ||
|
9d12a4edb6 | ||
|
d81e46b7a0 | ||
|
ffd30bd3d0 | ||
|
2d7f2c67bf | ||
|
4a8ab83a13 | ||
|
6c291aeb7a | ||
|
13d2a6a69b |
21 changed files with 2938 additions and 182 deletions
|
@ -62,7 +62,7 @@ test:
|
||||||
variables:
|
variables:
|
||||||
- $CI_PIPELINE_SOURCE == "schedule"
|
- $CI_PIPELINE_SOURCE == "schedule"
|
||||||
script:
|
script:
|
||||||
- meson --werror -Ddrivers=all -Db_coverage=true . _build
|
- meson --werror -Ddrivers=all -Db_coverage=true -Dsdcp_virt_binary=/usr/local/bin/sdcp_virt_device . _build
|
||||||
- ninja -C _build
|
- ninja -C _build
|
||||||
- meson test -C _build --print-errorlogs --no-stdsplit --timeout-multiplier 3
|
- meson test -C _build --print-errorlogs --no-stdsplit --timeout-multiplier 3
|
||||||
- ninja -C _build coverage
|
- ninja -C _build coverage
|
||||||
|
@ -81,7 +81,7 @@ test_valgrind:
|
||||||
variables:
|
variables:
|
||||||
- $CI_PIPELINE_SOURCE == "schedule"
|
- $CI_PIPELINE_SOURCE == "schedule"
|
||||||
script:
|
script:
|
||||||
- meson -Ddrivers=all . _build
|
- meson -Ddrivers=all -Dsdcp_virt_binary=/usr/local/bin/sdcp_virt_device . _build
|
||||||
- ninja -C _build
|
- ninja -C _build
|
||||||
- meson test -C _build --print-errorlogs --no-stdsplit --setup=valgrind
|
- meson test -C _build --print-errorlogs --no-stdsplit --setup=valgrind
|
||||||
artifacts:
|
artifacts:
|
||||||
|
@ -163,8 +163,20 @@ container_fedora_build:
|
||||||
vala
|
vala
|
||||||
libpcap-devel
|
libpcap-devel
|
||||||
libudev-devel
|
libudev-devel
|
||||||
|
mbedtls-devel
|
||||||
FDO_DISTRIBUTION_EXEC: |
|
FDO_DISTRIBUTION_EXEC: |
|
||||||
git clone https://github.com/martinpitt/umockdev.git && \
|
git clone https://github.com/martinpitt/umockdev.git && \
|
||||||
cd umockdev && \
|
cd umockdev && \
|
||||||
meson _build --prefix=/usr && \
|
meson _build --prefix=/usr && \
|
||||||
ninja -C _build && ninja -C _build install
|
ninja -C _build && ninja -C _build install
|
||||||
|
cd /tmp
|
||||||
|
mkdir -p /usr/local/bin
|
||||||
|
git clone https://github.com/benzea/SecureDeviceConnectionProtocol.git
|
||||||
|
# Don't bother with cmake
|
||||||
|
gcc -l mbedcrypto -I SecureDeviceConnectionProtocol/src/include \
|
||||||
|
SecureDeviceConnectionProtocol/src/test/virt_device.c \
|
||||||
|
SecureDeviceConnectionProtocol/src/client/client.c \
|
||||||
|
SecureDeviceConnectionProtocol/src/test/helpers.c \
|
||||||
|
SecureDeviceConnectionProtocol/src/test/testkeys.c \
|
||||||
|
-o /usr/local/bin/sdcp_virt_device
|
||||||
|
rm -rf SecureDeviceConnectionProtocol
|
||||||
|
|
|
@ -94,6 +94,12 @@ FP_TYPE_IMAGE_DEVICE
|
||||||
FpImageDevice
|
FpImageDevice
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<FILE>fp-sdcp-device</FILE>
|
||||||
|
FP_TYPE_SDCP_DEVICE
|
||||||
|
FpSdcpDevice
|
||||||
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>fp-print</FILE>
|
<FILE>fp-print</FILE>
|
||||||
FP_TYPE_PRINT
|
FP_TYPE_PRINT
|
||||||
|
@ -204,6 +210,26 @@ fpi_image_device_retry_scan
|
||||||
fpi_image_device_set_bz3_threshold
|
fpi_image_device_set_bz3_threshold
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<FILE>fpi-sdcp-device</FILE>
|
||||||
|
<TITLE>Internal FpSdcpDevice</TITLE>
|
||||||
|
FpiSdcpClaim
|
||||||
|
FpSdcpDeviceClass
|
||||||
|
fpi_sdcp_claim_copy
|
||||||
|
fpi_sdcp_claim_free
|
||||||
|
fpi_sdcp_claim_get_type
|
||||||
|
fpi_sdcp_claim_new
|
||||||
|
fpi_sdcp_device_connect_complete
|
||||||
|
fpi_sdcp_device_get_connect_data
|
||||||
|
fpi_sdcp_device_get_reconnect_data
|
||||||
|
fpi_sdcp_device_reconnect_complete
|
||||||
|
fpi_sdcp_device_enroll_commit_complete
|
||||||
|
fpi_sdcp_device_enroll_ready
|
||||||
|
fpi_sdcp_device_enroll_set_nonce
|
||||||
|
fpi_sdcp_device_identify_retry
|
||||||
|
fpi_sdcp_device_identify_complete
|
||||||
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>fpi-log</FILE>
|
<FILE>fpi-log</FILE>
|
||||||
fp_dbg
|
fp_dbg
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
<xi:include href="xml/fp-context.xml"/>
|
<xi:include href="xml/fp-context.xml"/>
|
||||||
<xi:include href="xml/fp-device.xml"/>
|
<xi:include href="xml/fp-device.xml"/>
|
||||||
<xi:include href="xml/fp-image-device.xml"/>
|
<xi:include href="xml/fp-image-device.xml"/>
|
||||||
|
<xi:include href="xml/fp-sdcp-device.xml"/>
|
||||||
<xi:include href="xml/fp-print.xml"/>
|
<xi:include href="xml/fp-print.xml"/>
|
||||||
<xi:include href="xml/fp-image.xml"/>
|
<xi:include href="xml/fp-image.xml"/>
|
||||||
</part>
|
</part>
|
||||||
|
@ -38,6 +39,7 @@
|
||||||
<title>Device methods for drivers</title>
|
<title>Device methods for drivers</title>
|
||||||
<xi:include href="xml/fpi-device.xml"/>
|
<xi:include href="xml/fpi-device.xml"/>
|
||||||
<xi:include href="xml/fpi-image-device.xml"/>
|
<xi:include href="xml/fpi-image-device.xml"/>
|
||||||
|
<xi:include href="xml/fpi-sdcp-device.xml"/>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
<chapter id="driver-helpers">
|
<chapter id="driver-helpers">
|
||||||
|
|
676
libfprint/drivers/virtual-sdcp.c
Normal file
676
libfprint/drivers/virtual-sdcp.c
Normal file
|
@ -0,0 +1,676 @@
|
||||||
|
/*
|
||||||
|
* Virtual driver for SDCP device debugging
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a virtual test driver to test the basic SDCP functionality.
|
||||||
|
* It uses the test binaries from Microsoft, which were extended to allow
|
||||||
|
* a simple chat with the device.
|
||||||
|
* The environment variable contains the to be executed binary including
|
||||||
|
* arguments. This binary should be compiled from the code in
|
||||||
|
* https://github.com/Microsoft/SecureDeviceConnectionProtocol
|
||||||
|
* or, until it is merged upstream
|
||||||
|
* https://github.com/benzea/SecureDeviceConnectionProtocol
|
||||||
|
*
|
||||||
|
* Note that using this as an external executable has the advantage that we
|
||||||
|
* do not need to link against mbedtls or any other crypto library.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FP_COMPONENT "virtual_sdcp"
|
||||||
|
|
||||||
|
#include "fpi-log.h"
|
||||||
|
#include "fpi-ssm.h"
|
||||||
|
|
||||||
|
#include "../fpi-sdcp-device.h"
|
||||||
|
|
||||||
|
#include <glib/gstdio.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
struct _FpDeviceVirtualSdcp
|
||||||
|
{
|
||||||
|
FpSdcpDevice parent;
|
||||||
|
|
||||||
|
GSubprocess *proc;
|
||||||
|
GOutputStream *proc_stdin;
|
||||||
|
GInputStream *proc_stdout;
|
||||||
|
|
||||||
|
/* Only valid while a read/write is pending */
|
||||||
|
GByteArray *msg_out;
|
||||||
|
GByteArray *msg_in;
|
||||||
|
|
||||||
|
GByteArray *connect_msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (FpDeviceVirtualSdcp, fpi_device_virtual_sdcp, FPI, DEVICE_VIRTUAL_SDCP, FpSdcpDevice)
|
||||||
|
G_DEFINE_TYPE (FpDeviceVirtualSdcp, fpi_device_virtual_sdcp, FP_TYPE_SDCP_DEVICE)
|
||||||
|
|
||||||
|
guint8 ca_1[] = {
|
||||||
|
0x30, 0x82, 0x03, 0xFD, 0x30, 0x82, 0x03, 0x82, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x13, 0x33,
|
||||||
|
0x00, 0x00, 0x00, 0x07, 0xE8, 0x9D, 0x61, 0x62, 0x4D, 0x46, 0x0F, 0x95, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x07, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x30, 0x81,
|
||||||
|
0x84, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
|
||||||
|
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67,
|
||||||
|
0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65,
|
||||||
|
0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15,
|
||||||
|
0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72,
|
||||||
|
0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25,
|
||||||
|
0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x53, 0x65,
|
||||||
|
0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x50, 0x43, 0x41,
|
||||||
|
0x20, 0x32, 0x30, 0x31, 0x38, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x31, 0x33, 0x31, 0x31,
|
||||||
|
0x39, 0x35, 0x34, 0x35, 0x33, 0x5A, 0x17, 0x0D, 0x32, 0x38, 0x30, 0x31, 0x33, 0x31, 0x32, 0x30,
|
||||||
|
0x30, 0x34, 0x35, 0x33, 0x5A, 0x30, 0x7D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
|
||||||
|
0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57,
|
||||||
|
0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55,
|
||||||
|
0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06,
|
||||||
|
0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20,
|
||||||
|
0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x27, 0x30, 0x25, 0x06,
|
||||||
|
0x03, 0x55, 0x04, 0x03, 0x13, 0x1E, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x48, 0x65,
|
||||||
|
0x6C, 0x6C, 0x6F, 0x20, 0x31, 0x39, 0x42, 0x39, 0x32, 0x39, 0x36, 0x35, 0x20, 0x43, 0x41, 0x20,
|
||||||
|
0x32, 0x30, 0x31, 0x38, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02,
|
||||||
|
0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xBE,
|
||||||
|
0x4B, 0x90, 0x6E, 0x24, 0xFC, 0xA1, 0x53, 0xC8, 0xA7, 0x3C, 0x70, 0xE8, 0x97, 0xCD, 0x1B, 0x31,
|
||||||
|
0xE4, 0x95, 0x91, 0x7A, 0x58, 0xA2, 0x86, 0xA8, 0x70, 0xF6, 0x09, 0x30, 0x77, 0x99, 0x3D, 0x10,
|
||||||
|
0xDF, 0xF7, 0x95, 0x0F, 0x68, 0x83, 0xE6, 0xA4, 0x11, 0x7C, 0xDA, 0x82, 0xE7, 0x0B, 0x8B, 0xF2,
|
||||||
|
0x9D, 0x6B, 0x5B, 0xF5, 0x3E, 0x77, 0xB4, 0xC1, 0x0E, 0x49, 0x00, 0x83, 0xBA, 0x94, 0xF8, 0xA3,
|
||||||
|
0x82, 0x01, 0xD7, 0x30, 0x82, 0x01, 0xD3, 0x30, 0x10, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01,
|
||||||
|
0x82, 0x37, 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E,
|
||||||
|
0x04, 0x16, 0x04, 0x14, 0x13, 0x93, 0xC8, 0xCD, 0xF2, 0x23, 0x9A, 0x2D, 0xC6, 0x9B, 0x2A, 0xEB,
|
||||||
|
0x9A, 0xAB, 0x99, 0x0B, 0x56, 0x04, 0x5E, 0x7C, 0x30, 0x65, 0x06, 0x03, 0x55, 0x1D, 0x20, 0x04,
|
||||||
|
0x5E, 0x30, 0x5C, 0x30, 0x06, 0x06, 0x04, 0x55, 0x1D, 0x20, 0x00, 0x30, 0x52, 0x06, 0x0C, 0x2B,
|
||||||
|
0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x4C, 0x83, 0x7D, 0x01, 0x01, 0x30, 0x42, 0x30, 0x40, 0x06,
|
||||||
|
0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x3A,
|
||||||
|
0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E,
|
||||||
|
0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x44, 0x6F, 0x63, 0x73, 0x2F,
|
||||||
|
0x52, 0x65, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x6F, 0x72, 0x79, 0x2E, 0x68, 0x74, 0x6D, 0x00, 0x30,
|
||||||
|
0x19, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x0C, 0x1E, 0x0A,
|
||||||
|
0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x1D,
|
||||||
|
0x0F, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01,
|
||||||
|
0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04,
|
||||||
|
0x18, 0x30, 0x16, 0x80, 0x14, 0xDA, 0xCA, 0x4B, 0xD0, 0x4C, 0x56, 0x03, 0x27, 0x5F, 0x97, 0xEB,
|
||||||
|
0x75, 0xA3, 0x02, 0xC3, 0xBF, 0x45, 0x9C, 0xF8, 0xB1, 0x30, 0x68, 0x06, 0x03, 0x55, 0x1D, 0x1F,
|
||||||
|
0x04, 0x61, 0x30, 0x5F, 0x30, 0x5D, 0xA0, 0x5B, 0xA0, 0x59, 0x86, 0x57, 0x68, 0x74, 0x74, 0x70,
|
||||||
|
0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74,
|
||||||
|
0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x63, 0x72, 0x6C, 0x2F,
|
||||||
|
0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x25, 0x32, 0x30, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x25,
|
||||||
|
0x32, 0x30, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x25, 0x32, 0x30, 0x44, 0x65, 0x76, 0x69, 0x63,
|
||||||
|
0x65, 0x73, 0x25, 0x32, 0x30, 0x50, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x38, 0x2E,
|
||||||
|
0x63, 0x72, 0x6C, 0x30, 0x75, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
|
||||||
|
0x69, 0x30, 0x67, 0x30, 0x65, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86,
|
||||||
|
0x59, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72,
|
||||||
|
0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73,
|
||||||
|
0x2F, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2F, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x25, 0x32,
|
||||||
|
0x30, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x25, 0x32, 0x30, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x25,
|
||||||
|
0x32, 0x30, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 0x32, 0x30, 0x50, 0x43, 0x41, 0x25,
|
||||||
|
0x32, 0x30, 0x32, 0x30, 0x31, 0x38, 0x2E, 0x63, 0x72, 0x74, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86,
|
||||||
|
0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x69, 0x00, 0x30, 0x66, 0x02, 0x31, 0x00, 0x87, 0xB6,
|
||||||
|
0x82, 0xF3, 0xDA, 0xBE, 0xB1, 0x7B, 0x98, 0x7D, 0x3D, 0x0A, 0x90, 0xA8, 0xF5, 0xBF, 0x15, 0xC3,
|
||||||
|
0xEE, 0x8A, 0x4E, 0xC0, 0x7B, 0x10, 0x1D, 0xA9, 0xE3, 0x0B, 0xEC, 0x2C, 0x53, 0x4E, 0xA7, 0xBD,
|
||||||
|
0xF1, 0x6C, 0xAD, 0x18, 0x55, 0xBA, 0x25, 0x73, 0x55, 0xB7, 0x5B, 0x12, 0x24, 0xF4, 0x02, 0x31,
|
||||||
|
0x00, 0xAF, 0x02, 0x9C, 0x4B, 0x92, 0xD0, 0x72, 0xA5, 0x80, 0xCA, 0x69, 0x2B, 0x38, 0x50, 0x64,
|
||||||
|
0xD8, 0x58, 0x9E, 0xEA, 0xD6, 0x35, 0xCF, 0x68, 0x98, 0x92, 0x81, 0x09, 0x61, 0xC2, 0xBD, 0xB1,
|
||||||
|
0x4C, 0x7F, 0xAE, 0x55, 0x7B, 0xFC, 0x22, 0xDD, 0xD6, 0xB7, 0x7C, 0xB5, 0xA8, 0x18, 0x5D, 0x33,
|
||||||
|
0x04
|
||||||
|
};
|
||||||
|
guint8 ca_2[] = {
|
||||||
|
0x30, 0x82, 0x04, 0x56, 0x30, 0x82, 0x03, 0xDC, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x13, 0x33,
|
||||||
|
0x00, 0x00, 0x00, 0x03, 0x6C, 0xCF, 0xED, 0xE2, 0x44, 0x70, 0x19, 0xBF, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x03, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03, 0x30, 0x81,
|
||||||
|
0x94, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
|
||||||
|
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67,
|
||||||
|
0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65,
|
||||||
|
0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15,
|
||||||
|
0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72,
|
||||||
|
0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x3E, 0x30, 0x3C, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x35,
|
||||||
|
0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x20, 0x45, 0x43, 0x43, 0x20, 0x44, 0x65,
|
||||||
|
0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
|
||||||
|
0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79,
|
||||||
|
0x20, 0x32, 0x30, 0x31, 0x37, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x38, 0x30, 0x31, 0x32, 0x35, 0x31,
|
||||||
|
0x39, 0x34, 0x39, 0x33, 0x38, 0x5A, 0x17, 0x0D, 0x33, 0x33, 0x30, 0x31, 0x32, 0x35, 0x31, 0x39,
|
||||||
|
0x35, 0x39, 0x33, 0x38, 0x5A, 0x30, 0x81, 0x84, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
|
||||||
|
0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A,
|
||||||
|
0x57, 0x61, 0x73, 0x68, 0x69, 0x6E, 0x67, 0x74, 0x6F, 0x6E, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03,
|
||||||
|
0x55, 0x04, 0x07, 0x13, 0x07, 0x52, 0x65, 0x64, 0x6D, 0x6F, 0x6E, 0x64, 0x31, 0x1E, 0x30, 0x1C,
|
||||||
|
0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x15, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74,
|
||||||
|
0x20, 0x43, 0x6F, 0x72, 0x70, 0x6F, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x31, 0x2E, 0x30, 0x2C,
|
||||||
|
0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x20, 0x48,
|
||||||
|
0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x65, 0x76, 0x69,
|
||||||
|
0x63, 0x65, 0x73, 0x20, 0x50, 0x43, 0x41, 0x20, 0x32, 0x30, 0x31, 0x38, 0x30, 0x76, 0x30, 0x10,
|
||||||
|
0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22,
|
||||||
|
0x03, 0x62, 0x00, 0x04, 0x1D, 0xDD, 0x08, 0x02, 0x03, 0x25, 0x75, 0x20, 0xE2, 0x71, 0x8B, 0xAD,
|
||||||
|
0x28, 0x09, 0x82, 0xE9, 0x06, 0xEE, 0x83, 0xC5, 0x3A, 0x6C, 0x4B, 0x71, 0x92, 0x50, 0x4E, 0x20,
|
||||||
|
0xE9, 0x72, 0xB4, 0xFC, 0x53, 0x2A, 0xEF, 0x5D, 0xCC, 0x9A, 0xB4, 0xCD, 0x76, 0xB8, 0x94, 0x97,
|
||||||
|
0x44, 0xB2, 0x71, 0x0E, 0xC9, 0xB1, 0x16, 0x03, 0xA1, 0x65, 0x2B, 0xB9, 0xE8, 0x5D, 0x5F, 0xF2,
|
||||||
|
0x30, 0x2E, 0xDD, 0xB1, 0x2B, 0x20, 0xFC, 0xBE, 0x00, 0x88, 0xEA, 0x1F, 0xA7, 0x7F, 0x99, 0x84,
|
||||||
|
0x98, 0x7C, 0x71, 0x3E, 0x4D, 0x34, 0x83, 0x69, 0x9B, 0x08, 0xCB, 0x78, 0xB2, 0x4B, 0xBD, 0xD7,
|
||||||
|
0x3E, 0xBE, 0x67, 0xA0, 0xA3, 0x82, 0x01, 0xFC, 0x30, 0x82, 0x01, 0xF8, 0x30, 0x10, 0x06, 0x09,
|
||||||
|
0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x1D,
|
||||||
|
0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xDA, 0xCA, 0x4B, 0xD0, 0x4C, 0x56, 0x03,
|
||||||
|
0x27, 0x5F, 0x97, 0xEB, 0x75, 0xA3, 0x02, 0xC3, 0xBF, 0x45, 0x9C, 0xF8, 0xB1, 0x30, 0x65, 0x06,
|
||||||
|
0x03, 0x55, 0x1D, 0x20, 0x04, 0x5E, 0x30, 0x5C, 0x30, 0x06, 0x06, 0x04, 0x55, 0x1D, 0x20, 0x00,
|
||||||
|
0x30, 0x52, 0x06, 0x0C, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x4C, 0x83, 0x7D, 0x01, 0x01,
|
||||||
|
0x30, 0x42, 0x30, 0x40, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x34,
|
||||||
|
0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F,
|
||||||
|
0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F,
|
||||||
|
0x44, 0x6F, 0x63, 0x73, 0x2F, 0x52, 0x65, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x6F, 0x72, 0x79, 0x2E,
|
||||||
|
0x68, 0x74, 0x6D, 0x00, 0x30, 0x19, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14,
|
||||||
|
0x02, 0x04, 0x0C, 0x1E, 0x0A, 0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30,
|
||||||
|
0x0B, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0F, 0x06, 0x03,
|
||||||
|
0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x1F, 0x06,
|
||||||
|
0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x14, 0xDA, 0x5B, 0xF1, 0x0E, 0x66,
|
||||||
|
0x47, 0xD1, 0x5D, 0x13, 0x5F, 0x5B, 0x7A, 0xEB, 0xEB, 0x5F, 0x01, 0x08, 0xB5, 0x49, 0x30, 0x7A,
|
||||||
|
0x06, 0x03, 0x55, 0x1D, 0x1F, 0x04, 0x73, 0x30, 0x71, 0x30, 0x6F, 0xA0, 0x6D, 0xA0, 0x6B, 0x86,
|
||||||
|
0x69, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72,
|
||||||
|
0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73,
|
||||||
|
0x2F, 0x63, 0x72, 0x6C, 0x2F, 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x25, 0x32,
|
||||||
|
0x30, 0x45, 0x43, 0x43, 0x25, 0x32, 0x30, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 0x32,
|
||||||
|
0x30, 0x52, 0x6F, 0x6F, 0x74, 0x25, 0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
|
||||||
|
0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x25,
|
||||||
|
0x32, 0x30, 0x32, 0x30, 0x31, 0x37, 0x2E, 0x63, 0x72, 0x6C, 0x30, 0x81, 0x87, 0x06, 0x08, 0x2B,
|
||||||
|
0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x7B, 0x30, 0x79, 0x30, 0x77, 0x06, 0x08, 0x2B,
|
||||||
|
0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x6B, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F,
|
||||||
|
0x77, 0x77, 0x77, 0x2E, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x2E, 0x63, 0x6F,
|
||||||
|
0x6D, 0x2F, 0x70, 0x6B, 0x69, 0x6F, 0x70, 0x73, 0x2F, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2F, 0x4D,
|
||||||
|
0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, 0x74, 0x25, 0x32, 0x30, 0x45, 0x43, 0x43, 0x25, 0x32,
|
||||||
|
0x30, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x25, 0x32, 0x30, 0x52, 0x6F, 0x6F, 0x74, 0x25,
|
||||||
|
0x32, 0x30, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x25, 0x32, 0x30,
|
||||||
|
0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x25, 0x32, 0x30, 0x32, 0x30, 0x31, 0x37,
|
||||||
|
0x2E, 0x63, 0x72, 0x74, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03,
|
||||||
|
0x03, 0x68, 0x00, 0x30, 0x65, 0x02, 0x30, 0x56, 0x2A, 0xAD, 0x72, 0x4C, 0xB9, 0x8C, 0xB3, 0x23,
|
||||||
|
0x80, 0xF5, 0x5F, 0xF8, 0x21, 0x94, 0x66, 0x0F, 0x76, 0x77, 0xE2, 0x7B, 0x03, 0xDD, 0x30, 0x5E,
|
||||||
|
0xCB, 0x90, 0xCA, 0x78, 0xE6, 0x0B, 0x2D, 0x12, 0xE5, 0xF7, 0x67, 0x31, 0x58, 0x71, 0xE6, 0xF3,
|
||||||
|
0x64, 0xC1, 0x04, 0xB3, 0x8B, 0xE9, 0xE2, 0x02, 0x31, 0x00, 0xB9, 0x20, 0x61, 0xB9, 0xD0, 0x5E,
|
||||||
|
0x3A, 0xA4, 0xA2, 0x8A, 0xFE, 0x1D, 0xFC, 0x27, 0x61, 0x0B, 0x98, 0x16, 0x8C, 0x02, 0x9C, 0x20,
|
||||||
|
0x7F, 0xEE, 0xF3, 0xCB, 0x1F, 0x0A, 0x37, 0x62, 0xB1, 0x8E, 0xCE, 0xD9, 0x9A, 0x9E, 0xAC, 0xE6,
|
||||||
|
0x1A, 0xD4, 0xB8, 0xF1, 0xA8, 0x2B, 0xB1, 0xB4, 0x40, 0x9B
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
msg_written_cb (GObject *source_object,
|
||||||
|
GAsyncResult *res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
GOutputStream *stream = G_OUTPUT_STREAM (source_object);
|
||||||
|
FpiSsm *ssm = user_data;
|
||||||
|
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (fpi_ssm_get_device (ssm));
|
||||||
|
|
||||||
|
g_clear_pointer (&self->msg_out, g_byte_array_unref);
|
||||||
|
g_assert (self->msg_out == NULL);
|
||||||
|
|
||||||
|
if (!g_output_stream_write_all_finish (stream, res, NULL, &error))
|
||||||
|
{
|
||||||
|
fpi_ssm_mark_failed (ssm, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fpi_ssm_next_state (ssm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
msg_received_cb (GObject *source_object,
|
||||||
|
GAsyncResult *res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
GInputStream *stream = G_INPUT_STREAM (source_object);
|
||||||
|
FpiSsm *ssm = user_data;
|
||||||
|
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (fpi_ssm_get_device (ssm));
|
||||||
|
gsize read;
|
||||||
|
|
||||||
|
g_assert (self->msg_out == NULL);
|
||||||
|
|
||||||
|
if (!g_input_stream_read_all_finish (stream, res, &read, &error) ||
|
||||||
|
read != self->msg_in->len)
|
||||||
|
{
|
||||||
|
g_clear_pointer (&self->msg_in, g_byte_array_unref);
|
||||||
|
|
||||||
|
if (!error)
|
||||||
|
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||||
|
"Received EOF while reading from test binary.");
|
||||||
|
|
||||||
|
fpi_ssm_mark_failed (ssm, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fpi_ssm_next_state (ssm);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SEND_MESSAGE,
|
||||||
|
RECV_MESSAGE,
|
||||||
|
SEND_RECV_STATES
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_recv_ssm (FpiSsm *ssm, FpDevice *dev)
|
||||||
|
{
|
||||||
|
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||||
|
|
||||||
|
switch (fpi_ssm_get_cur_state (ssm))
|
||||||
|
{
|
||||||
|
case SEND_MESSAGE:
|
||||||
|
g_output_stream_write_all_async (self->proc_stdin,
|
||||||
|
self->msg_out->data,
|
||||||
|
self->msg_out->len,
|
||||||
|
G_PRIORITY_DEFAULT,
|
||||||
|
fpi_device_get_cancellable (FP_DEVICE (dev)),
|
||||||
|
msg_written_cb,
|
||||||
|
ssm);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECV_MESSAGE:
|
||||||
|
g_input_stream_read_all_async (self->proc_stdout,
|
||||||
|
self->msg_in->data,
|
||||||
|
self->msg_in->len,
|
||||||
|
G_PRIORITY_DEFAULT,
|
||||||
|
fpi_device_get_cancellable (FP_DEVICE (dev)),
|
||||||
|
msg_received_cb,
|
||||||
|
ssm);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect_2_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||||
|
{
|
||||||
|
g_autoptr(GBytes) recv_data = NULL;
|
||||||
|
g_autoptr(GBytes) r_d = NULL;
|
||||||
|
g_autoptr(FpiSdcpClaim) claim = NULL;
|
||||||
|
g_autoptr(GBytes) mac = NULL;
|
||||||
|
g_autoptr(GBytes) ca_1_bytes = NULL, ca_2_bytes = NULL;
|
||||||
|
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||||
|
guint16 cert_size;
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
fpi_sdcp_device_connect_complete (FP_SDCP_DEVICE (dev), NULL, NULL, NULL, error);
|
||||||
|
g_clear_pointer (&self->connect_msg, g_byte_array_unref);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (&cert_size, self->connect_msg->data + 32, 2);
|
||||||
|
g_byte_array_append (self->connect_msg, self->msg_in->data, self->msg_in->len);
|
||||||
|
g_clear_pointer (&self->msg_in, g_byte_array_unref);
|
||||||
|
/* Double check that the size is correct. */
|
||||||
|
g_assert (self->connect_msg->len == 32 + (2 + cert_size + 65 + 65 + 32 + 64 + 64) + 32);
|
||||||
|
recv_data = g_byte_array_free_to_bytes (g_steal_pointer (&self->connect_msg));
|
||||||
|
|
||||||
|
claim = fpi_sdcp_claim_new ();
|
||||||
|
r_d = g_bytes_new_from_bytes (recv_data, 0, 32);
|
||||||
|
claim->cert_m = g_bytes_new_from_bytes (recv_data, 34, cert_size);
|
||||||
|
claim->pk_d = g_bytes_new_from_bytes (recv_data, 34 + cert_size, 65);
|
||||||
|
claim->pk_f = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65, 65);
|
||||||
|
claim->h_f = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65 + 65, 32);
|
||||||
|
claim->s_m = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65 + 65 + 32, 64);
|
||||||
|
claim->s_d = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65 + 65 + 32 + 64, 64);
|
||||||
|
mac = g_bytes_new_from_bytes (recv_data, 34 + cert_size + 65 + 65 + 32 + 64 + 64, 32);
|
||||||
|
|
||||||
|
ca_1_bytes = g_bytes_new_static (ca_1, G_N_ELEMENTS (ca_1));
|
||||||
|
ca_2_bytes = g_bytes_new_static (ca_2, G_N_ELEMENTS (ca_2));
|
||||||
|
|
||||||
|
fpi_sdcp_device_set_intermediat_cas (FP_SDCP_DEVICE (dev),
|
||||||
|
ca_1_bytes,
|
||||||
|
ca_2_bytes);
|
||||||
|
|
||||||
|
fpi_sdcp_device_connect_complete (FP_SDCP_DEVICE (dev), r_d, claim, mac, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect_1_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||||
|
{
|
||||||
|
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||||
|
guint16 cert_size;
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
fpi_sdcp_device_connect_complete (FP_SDCP_DEVICE (dev), NULL, NULL, NULL, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_pointer (&self->connect_msg, g_byte_array_unref);
|
||||||
|
self->connect_msg = g_steal_pointer (&self->msg_in);
|
||||||
|
|
||||||
|
memcpy (&cert_size, self->connect_msg->data + 32, 2);
|
||||||
|
|
||||||
|
/* Nothing to send and the rest to receive. */
|
||||||
|
self->msg_out = g_byte_array_new ();
|
||||||
|
self->msg_in = g_byte_array_new ();
|
||||||
|
g_byte_array_set_size (self->msg_in, 32 + (2 + cert_size + 65 + 65 + 32 + 64 + 64) + 32 - self->connect_msg->len);
|
||||||
|
|
||||||
|
/* New SSM */
|
||||||
|
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, SEND_RECV_STATES, "connect 2");
|
||||||
|
fpi_ssm_start (ssm, connect_2_cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect (FpSdcpDevice *dev)
|
||||||
|
{
|
||||||
|
g_autoptr(GBytes) r_h = NULL;
|
||||||
|
g_autoptr(GBytes) pk_h = NULL;
|
||||||
|
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||||
|
FpiSsm *ssm;
|
||||||
|
|
||||||
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
|
g_assert (self->proc);
|
||||||
|
g_assert (self->connect_msg == NULL);
|
||||||
|
|
||||||
|
fpi_sdcp_device_get_connect_data (dev, &r_h, &pk_h);
|
||||||
|
|
||||||
|
self->msg_out = g_byte_array_new ();
|
||||||
|
g_byte_array_append (self->msg_out, (const guint8 *) "C", 1);
|
||||||
|
g_byte_array_append (self->msg_out,
|
||||||
|
g_bytes_get_data (r_h, NULL),
|
||||||
|
g_bytes_get_size (r_h));
|
||||||
|
g_byte_array_append (self->msg_out,
|
||||||
|
g_bytes_get_data (pk_h, NULL),
|
||||||
|
g_bytes_get_size (pk_h));
|
||||||
|
|
||||||
|
self->msg_in = g_byte_array_new ();
|
||||||
|
g_byte_array_set_size (self->msg_in, 34);
|
||||||
|
|
||||||
|
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, SEND_RECV_STATES, "connect");
|
||||||
|
fpi_ssm_start (ssm, connect_1_cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
reconnect_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||||
|
{
|
||||||
|
g_autoptr(GBytes) mac = NULL;
|
||||||
|
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
fpi_sdcp_device_reconnect_complete (FP_SDCP_DEVICE (dev), mac, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mac = g_byte_array_free_to_bytes (g_steal_pointer (&self->msg_in));
|
||||||
|
|
||||||
|
fpi_sdcp_device_reconnect_complete (FP_SDCP_DEVICE (dev), mac, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
reconnect (FpSdcpDevice *dev)
|
||||||
|
{
|
||||||
|
g_autoptr(GBytes) r_h = NULL;
|
||||||
|
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||||
|
FpiSsm *ssm;
|
||||||
|
|
||||||
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
|
g_assert (self->proc);
|
||||||
|
|
||||||
|
fpi_sdcp_device_get_reconnect_data (dev, &r_h);
|
||||||
|
|
||||||
|
self->msg_out = g_byte_array_new ();
|
||||||
|
g_byte_array_append (self->msg_out, (const guint8 *) "R", 1);
|
||||||
|
g_byte_array_append (self->msg_out,
|
||||||
|
g_bytes_get_data (r_h, NULL),
|
||||||
|
g_bytes_get_size (r_h));
|
||||||
|
|
||||||
|
self->msg_in = g_byte_array_new ();
|
||||||
|
g_byte_array_set_size (self->msg_in, 32);
|
||||||
|
|
||||||
|
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, SEND_RECV_STATES, "connect 2");
|
||||||
|
fpi_ssm_start (ssm, reconnect_cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
enroll_begin_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||||
|
{
|
||||||
|
g_autoptr(GBytes) nonce = NULL;
|
||||||
|
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
fpi_sdcp_device_enroll_ready (FP_SDCP_DEVICE (dev), error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nonce = g_byte_array_free_to_bytes (g_steal_pointer (&self->msg_in));
|
||||||
|
|
||||||
|
fpi_sdcp_device_enroll_set_nonce (FP_SDCP_DEVICE (dev), nonce);
|
||||||
|
|
||||||
|
/* Claim that we completed one enroll step. */
|
||||||
|
fpi_device_enroll_progress (dev, 1, NULL, NULL);
|
||||||
|
|
||||||
|
/* And signal that we are ready to commit. */
|
||||||
|
fpi_sdcp_device_enroll_ready (FP_SDCP_DEVICE (dev), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
enroll_begin (FpSdcpDevice *dev)
|
||||||
|
{
|
||||||
|
g_autoptr(GBytes) r_h = NULL;
|
||||||
|
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||||
|
FpiSsm *ssm;
|
||||||
|
|
||||||
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
|
g_assert (self->proc);
|
||||||
|
|
||||||
|
fpi_sdcp_device_get_reconnect_data (dev, &r_h);
|
||||||
|
|
||||||
|
self->msg_out = g_byte_array_new ();
|
||||||
|
g_byte_array_append (self->msg_out, (const guint8 *) "E", 1);
|
||||||
|
|
||||||
|
/* Expect 32 byte nonce */
|
||||||
|
self->msg_in = g_byte_array_new ();
|
||||||
|
g_byte_array_set_size (self->msg_in, 32);
|
||||||
|
|
||||||
|
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, SEND_RECV_STATES, "enroll_begin");
|
||||||
|
fpi_ssm_start (ssm, enroll_begin_cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
enroll_commit_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||||
|
{
|
||||||
|
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||||
|
|
||||||
|
g_clear_pointer (&self->msg_in, g_byte_array_unref);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
fpi_sdcp_device_enroll_ready (FP_SDCP_DEVICE (dev), error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Signal that we have committed. We don't expect a response
|
||||||
|
* from the virtual device (even though that is kind of broken).
|
||||||
|
*/
|
||||||
|
fpi_sdcp_device_enroll_commit_complete (FP_SDCP_DEVICE (dev), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
enroll_commit (FpSdcpDevice *dev, GBytes *id_in)
|
||||||
|
{
|
||||||
|
g_autoptr(GBytes) r_h = NULL;
|
||||||
|
g_autoptr(GBytes) id = id_in;
|
||||||
|
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||||
|
FpiSsm *ssm;
|
||||||
|
|
||||||
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
|
g_assert (self->proc);
|
||||||
|
|
||||||
|
fpi_sdcp_device_get_reconnect_data (dev, &r_h);
|
||||||
|
|
||||||
|
self->msg_out = g_byte_array_new ();
|
||||||
|
self->msg_in = g_byte_array_new ();
|
||||||
|
if (id)
|
||||||
|
{
|
||||||
|
g_byte_array_append (self->msg_out, (const guint8 *) "F", 1);
|
||||||
|
g_byte_array_append (self->msg_out,
|
||||||
|
g_bytes_get_data (id, NULL),
|
||||||
|
g_bytes_get_size (id));
|
||||||
|
|
||||||
|
/* NOTE: No response from device, assume commit works. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Cancel enroll (does not receive a reply) */
|
||||||
|
g_byte_array_append (self->msg_out, (const guint8 *) "G", 1);
|
||||||
|
|
||||||
|
/* NOTE: No response from device, assume cancellation works. */
|
||||||
|
}
|
||||||
|
|
||||||
|
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, SEND_RECV_STATES, "enroll_commit");
|
||||||
|
fpi_ssm_start (ssm, enroll_commit_cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
identify_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||||
|
{
|
||||||
|
g_autoptr(GBytes) reply = NULL;
|
||||||
|
g_autoptr(GBytes) id = NULL;
|
||||||
|
g_autoptr(GBytes) mac = NULL;
|
||||||
|
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
fpi_sdcp_device_identify_complete (FP_SDCP_DEVICE (dev), NULL, NULL, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reply = g_byte_array_free_to_bytes (g_steal_pointer (&self->msg_in));
|
||||||
|
id = g_bytes_new_from_bytes (reply, 0, 32);
|
||||||
|
mac = g_bytes_new_from_bytes (reply, 32, 32);
|
||||||
|
|
||||||
|
fpi_sdcp_device_identify_complete (FP_SDCP_DEVICE (self), id, mac, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
identify (FpSdcpDevice *dev)
|
||||||
|
{
|
||||||
|
g_autoptr(GBytes) nonce = NULL;
|
||||||
|
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||||
|
FpiSsm *ssm;
|
||||||
|
|
||||||
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
|
g_assert (self->proc);
|
||||||
|
|
||||||
|
fpi_sdcp_device_get_identify_data (dev, &nonce);
|
||||||
|
|
||||||
|
self->msg_out = g_byte_array_new ();
|
||||||
|
g_byte_array_append (self->msg_out, (const guint8 *) "I", 1);
|
||||||
|
g_byte_array_append (self->msg_out, g_bytes_get_data (nonce, NULL), g_bytes_get_size (nonce));
|
||||||
|
|
||||||
|
/* Expect 64 byte nonce */
|
||||||
|
self->msg_in = g_byte_array_new ();
|
||||||
|
g_byte_array_set_size (self->msg_in, 64);
|
||||||
|
|
||||||
|
ssm = fpi_ssm_new_full (FP_DEVICE (dev), send_recv_ssm, SEND_RECV_STATES, SEND_RECV_STATES, "identify");
|
||||||
|
fpi_ssm_start (ssm, identify_cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
probe (FpDevice *dev)
|
||||||
|
{
|
||||||
|
g_auto(GStrv) argv = NULL;
|
||||||
|
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (dev);
|
||||||
|
GError *error = NULL;
|
||||||
|
const char *env;
|
||||||
|
|
||||||
|
/* We launch the test binary alread at probe time and quit only when
|
||||||
|
* the object is finalized. This allows testing reconnect properly.
|
||||||
|
*
|
||||||
|
* Also, we'll fail probe if something goes wrong executing it.
|
||||||
|
*/
|
||||||
|
env = fpi_device_get_virtual_env (FP_DEVICE (self));
|
||||||
|
|
||||||
|
if (!g_shell_parse_argv (env, NULL, &argv, &error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
self->proc = g_subprocess_newv ((const char * const *) argv,
|
||||||
|
G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE,
|
||||||
|
&error);
|
||||||
|
if (!self->proc)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
self->proc_stdin = g_object_ref (g_subprocess_get_stdin_pipe (self->proc));
|
||||||
|
self->proc_stdout = g_object_ref (g_subprocess_get_stdout_pipe (self->proc));
|
||||||
|
|
||||||
|
|
||||||
|
out:
|
||||||
|
fpi_device_probe_complete (dev, "virtual-sdcp", NULL, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dev_close (FpDevice *dev)
|
||||||
|
{
|
||||||
|
/* No-op, needs to be defined. */
|
||||||
|
fpi_device_close_complete (dev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_device_virtual_sdcp_init (FpDeviceVirtualSdcp *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_device_virtual_sdcp_finalize (GObject *obj)
|
||||||
|
{
|
||||||
|
FpDeviceVirtualSdcp *self = FPI_DEVICE_VIRTUAL_SDCP (obj);
|
||||||
|
|
||||||
|
/* Just kill the subprocess, no need to be graceful here. */
|
||||||
|
if (self->proc)
|
||||||
|
g_subprocess_force_exit (self->proc);
|
||||||
|
|
||||||
|
g_clear_object (&self->proc);
|
||||||
|
g_clear_object (&self->proc_stdin);
|
||||||
|
g_clear_object (&self->proc_stdout);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (fpi_device_virtual_sdcp_parent_class)->finalize (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const FpIdEntry driver_ids[] = {
|
||||||
|
{ .virtual_envvar = "FP_VIRTUAL_SDCP" },
|
||||||
|
{ .virtual_envvar = NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_device_virtual_sdcp_class_init (FpDeviceVirtualSdcpClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *obj_class = G_OBJECT_CLASS (klass);
|
||||||
|
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||||
|
FpSdcpDeviceClass *sdcp_class = FP_SDCP_DEVICE_CLASS (klass);
|
||||||
|
|
||||||
|
obj_class->finalize = fpi_device_virtual_sdcp_finalize;
|
||||||
|
|
||||||
|
dev_class->id = FP_COMPONENT;
|
||||||
|
dev_class->full_name = "Virtual SDCP device talking to MS test code";
|
||||||
|
dev_class->type = FP_DEVICE_TYPE_VIRTUAL;
|
||||||
|
dev_class->id_table = driver_ids;
|
||||||
|
dev_class->nr_enroll_stages = 1;
|
||||||
|
|
||||||
|
/* The SDCP base class may need to override this in the long run */
|
||||||
|
dev_class->probe = probe;
|
||||||
|
dev_class->close = dev_close;
|
||||||
|
|
||||||
|
sdcp_class->connect = connect;
|
||||||
|
sdcp_class->reconnect = reconnect;
|
||||||
|
|
||||||
|
sdcp_class->enroll_begin = enroll_begin;
|
||||||
|
sdcp_class->enroll_commit = enroll_commit;
|
||||||
|
|
||||||
|
sdcp_class->identify = identify;
|
||||||
|
}
|
|
@ -118,6 +118,7 @@ typedef enum {
|
||||||
* @FP_DEVICE_ERROR_DATA_FULL: No space on device available for operation
|
* @FP_DEVICE_ERROR_DATA_FULL: No space on device available for operation
|
||||||
* @FP_DEVICE_ERROR_DATA_DUPLICATE: Enrolling template duplicates storaged templates
|
* @FP_DEVICE_ERROR_DATA_DUPLICATE: Enrolling template duplicates storaged templates
|
||||||
* @FP_DEVICE_ERROR_REMOVED: The device has been removed.
|
* @FP_DEVICE_ERROR_REMOVED: The device has been removed.
|
||||||
|
* @FP_DEVICE_ERROR_UNTRUSTED: Device cannot be trusted
|
||||||
*
|
*
|
||||||
* Error codes for device operations. More specific errors from other domains
|
* Error codes for device operations. More specific errors from other domains
|
||||||
* such as #G_IO_ERROR or #G_USB_DEVICE_ERROR may also be reported.
|
* such as #G_IO_ERROR or #G_USB_DEVICE_ERROR may also be reported.
|
||||||
|
@ -135,6 +136,7 @@ typedef enum {
|
||||||
FP_DEVICE_ERROR_DATA_DUPLICATE,
|
FP_DEVICE_ERROR_DATA_DUPLICATE,
|
||||||
/* Leave some room to add more DATA related errors */
|
/* Leave some room to add more DATA related errors */
|
||||||
FP_DEVICE_ERROR_REMOVED = 0x100,
|
FP_DEVICE_ERROR_REMOVED = 0x100,
|
||||||
|
FP_DEVICE_ERROR_UNTRUSTED,
|
||||||
} FpDeviceError;
|
} FpDeviceError;
|
||||||
|
|
||||||
GQuark fp_device_retry_quark (void);
|
GQuark fp_device_retry_quark (void);
|
||||||
|
|
|
@ -281,7 +281,7 @@ fp_print_class_init (FpPrintClass *klass)
|
||||||
"Type",
|
"Type",
|
||||||
"Private: The type of the print data",
|
"Private: The type of the print data",
|
||||||
FPI_TYPE_PRINT_TYPE,
|
FPI_TYPE_PRINT_TYPE,
|
||||||
FPI_PRINT_RAW,
|
FPI_PRINT_UNDEFINED,
|
||||||
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -582,7 +582,7 @@ fp_print_equal (FpPrint *self, FpPrint *other)
|
||||||
if (g_strcmp0 (self->device_id, other->device_id))
|
if (g_strcmp0 (self->device_id, other->device_id))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (self->type == FPI_PRINT_RAW)
|
if (self->type == FPI_PRINT_RAW || self->type == FPI_PRINT_SDCP)
|
||||||
{
|
{
|
||||||
return g_variant_equal (self->data, other->data);
|
return g_variant_equal (self->data, other->data);
|
||||||
}
|
}
|
||||||
|
@ -847,7 +847,7 @@ fp_print_deserialize (const guchar *data,
|
||||||
g_ptr_array_add (result->prints, g_steal_pointer (&xyt));
|
g_ptr_array_add (result->prints, g_steal_pointer (&xyt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == FPI_PRINT_RAW)
|
else if (type == FPI_PRINT_RAW || type == FPI_PRINT_SDCP)
|
||||||
{
|
{
|
||||||
g_autoptr(GVariant) fp_data = g_variant_get_child_value (print_data, 0);
|
g_autoptr(GVariant) fp_data = g_variant_get_child_value (print_data, 0);
|
||||||
|
|
||||||
|
|
58
libfprint/fp-sdcp-device-private.h
Normal file
58
libfprint/fp-sdcp-device-private.h
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* FpSdcpDevice - A base class for SDCP enabled devices
|
||||||
|
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.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 <nss.h>
|
||||||
|
#include <keyhi.h>
|
||||||
|
#include <keythi.h>
|
||||||
|
#include <pk11pub.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GError *enroll_pre_commit_error;
|
||||||
|
|
||||||
|
/* XXX: Do we want a separate SDCP session object?
|
||||||
|
*/
|
||||||
|
|
||||||
|
GPtrArray *intermediate_cas;
|
||||||
|
|
||||||
|
/* Host random for the connection */
|
||||||
|
guint8 host_random[32];
|
||||||
|
|
||||||
|
NSSInitContext *nss_init_context;
|
||||||
|
PK11SlotInfo *slot;
|
||||||
|
SECKEYPrivateKey *host_key_private;
|
||||||
|
SECKEYPublicKey *host_key_public;
|
||||||
|
|
||||||
|
/* Master secret is required for reconnects.
|
||||||
|
* TODO: We probably want to serialize this to disk so it can survive
|
||||||
|
* fprintd idle shutdown. */
|
||||||
|
PK11SymKey *master_secret;
|
||||||
|
PK11SymKey *mac_secret;
|
||||||
|
|
||||||
|
} FpSdcpDevicePrivate;
|
||||||
|
|
||||||
|
void fpi_sdcp_device_connect (FpSdcpDevice *self);
|
||||||
|
void fpi_sdcp_device_reconnect (FpSdcpDevice *self);
|
||||||
|
|
||||||
|
void fpi_sdcp_device_enroll (FpSdcpDevice *self);
|
||||||
|
void fpi_sdcp_device_identify (FpSdcpDevice *self);
|
141
libfprint/fp-sdcp-device.c
Normal file
141
libfprint/fp-sdcp-device.c
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
* FpSdcpDevice - A base class for SDCP enabled devices
|
||||||
|
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.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 "sdcp_device"
|
||||||
|
#include "fpi-log.h"
|
||||||
|
|
||||||
|
#include "fp-sdcp-device-private.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION: fp-sdcp-device
|
||||||
|
* @title: FpSdcpDevice
|
||||||
|
* @short_description: SDCP device subclass
|
||||||
|
*
|
||||||
|
* This is a base class for devices implementing the SDCP security protocol.
|
||||||
|
*/
|
||||||
|
|
||||||
|
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (FpSdcpDevice, fp_sdcp_device, FP_TYPE_DEVICE)
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* XXX: We'll very likely want/need some properties on this class. */
|
||||||
|
enum {
|
||||||
|
PROP_0,
|
||||||
|
N_PROPS
|
||||||
|
};
|
||||||
|
|
||||||
|
static GParamSpec *properties[N_PROPS];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*******************************************************/
|
||||||
|
|
||||||
|
/* Callbacks/vfuncs */
|
||||||
|
static void
|
||||||
|
fp_sdcp_device_open (FpDevice *device)
|
||||||
|
{
|
||||||
|
FpSdcpDevice *self = FP_SDCP_DEVICE (device);
|
||||||
|
FpSdcpDevicePrivate *priv = fp_sdcp_device_get_instance_private (self);
|
||||||
|
|
||||||
|
/* Try a reconnect if we still have the mac secret. */
|
||||||
|
if (priv->mac_secret)
|
||||||
|
fpi_sdcp_device_reconnect (self);
|
||||||
|
else
|
||||||
|
fpi_sdcp_device_connect (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fp_sdcp_device_enroll (FpDevice *device)
|
||||||
|
{
|
||||||
|
FpSdcpDevice *self = FP_SDCP_DEVICE (device);
|
||||||
|
|
||||||
|
fpi_sdcp_device_enroll (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fp_sdcp_device_identify (FpDevice *device)
|
||||||
|
{
|
||||||
|
FpSdcpDevice *self = FP_SDCP_DEVICE (device);
|
||||||
|
|
||||||
|
fpi_sdcp_device_identify (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
fp_sdcp_device_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
FpSdcpDevice *self = (FpSdcpDevice *) object;
|
||||||
|
FpSdcpDevicePrivate *priv = fp_sdcp_device_get_instance_private (self);
|
||||||
|
|
||||||
|
g_clear_pointer (&priv->intermediate_cas, g_ptr_array_unref);
|
||||||
|
g_clear_pointer (&priv->slot, PK11_FreeSlot);
|
||||||
|
g_clear_pointer (&priv->host_key_private, SECKEY_DestroyPrivateKey);
|
||||||
|
g_clear_pointer (&priv->host_key_public, SECKEY_DestroyPublicKey);
|
||||||
|
g_clear_pointer (&priv->master_secret, PK11_FreeSymKey);
|
||||||
|
g_clear_pointer (&priv->mac_secret, PK11_FreeSymKey);
|
||||||
|
g_clear_pointer (&priv->nss_init_context, NSS_ShutdownContext);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (fp_sdcp_device_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fp_sdcp_device_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fp_sdcp_device_constructed (GObject *obj)
|
||||||
|
{
|
||||||
|
G_OBJECT_CLASS (fp_sdcp_device_parent_class)->constructed (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fp_sdcp_device_class_init (FpSdcpDeviceClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
FpDeviceClass *fp_device_class = FP_DEVICE_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->finalize = fp_sdcp_device_finalize;
|
||||||
|
object_class->get_property = fp_sdcp_device_get_property;
|
||||||
|
object_class->constructed = fp_sdcp_device_constructed;
|
||||||
|
|
||||||
|
fp_device_class->open = fp_sdcp_device_open;
|
||||||
|
fp_device_class->enroll = fp_sdcp_device_enroll;
|
||||||
|
fp_device_class->verify = fp_sdcp_device_identify;
|
||||||
|
fp_device_class->identify = fp_sdcp_device_identify;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fp_sdcp_device_init (FpSdcpDevice *self)
|
||||||
|
{
|
||||||
|
FpSdcpDevicePrivate *priv = fp_sdcp_device_get_instance_private (self);
|
||||||
|
|
||||||
|
priv->intermediate_cas = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref);
|
||||||
|
}
|
29
libfprint/fp-sdcp-device.h
Normal file
29
libfprint/fp-sdcp-device.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* FpSdcpDevice - A base class for SDCP enabled devices
|
||||||
|
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.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 <fp-device.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define FP_TYPE_SDCP_DEVICE (fp_sdcp_device_get_type ())
|
||||||
|
G_DECLARE_DERIVABLE_TYPE (FpSdcpDevice, fp_sdcp_device, FP, SDCP_DEVICE, FpDevice)
|
||||||
|
|
||||||
|
G_END_DECLS
|
|
@ -177,6 +177,10 @@ fpi_device_error_new (FpDeviceError error)
|
||||||
msg = "This device has been removed from the system.";
|
msg = "This device has been removed from the system.";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FP_DEVICE_ERROR_UNTRUSTED:
|
||||||
|
msg = "Could not verify integrity of the device, it cannot be trusted!";
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_warning ("Unsupported error, returning general error instead!");
|
g_warning ("Unsupported error, returning general error instead!");
|
||||||
error = FP_DEVICE_ERROR_GENERAL;
|
error = FP_DEVICE_ERROR_GENERAL;
|
||||||
|
|
|
@ -11,11 +11,13 @@ G_BEGIN_DECLS
|
||||||
* @FPI_PRINT_UNDEFINED: Undefined type, this happens prior to enrollment
|
* @FPI_PRINT_UNDEFINED: Undefined type, this happens prior to enrollment
|
||||||
* @FPI_PRINT_RAW: A raw print where the data is directly compared
|
* @FPI_PRINT_RAW: A raw print where the data is directly compared
|
||||||
* @FPI_PRINT_NBIS: NBIS minutiae comparison
|
* @FPI_PRINT_NBIS: NBIS minutiae comparison
|
||||||
|
* @FPI_PRINT_SDCP: Print from an SDCP conforming device
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FPI_PRINT_UNDEFINED = 0,
|
FPI_PRINT_UNDEFINED = 0,
|
||||||
FPI_PRINT_RAW,
|
FPI_PRINT_RAW,
|
||||||
FPI_PRINT_NBIS,
|
FPI_PRINT_NBIS,
|
||||||
|
FPI_PRINT_SDCP,
|
||||||
} FpiPrintType;
|
} FpiPrintType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
1469
libfprint/fpi-sdcp-device.c
Normal file
1469
libfprint/fpi-sdcp-device.c
Normal file
File diff suppressed because it is too large
Load diff
142
libfprint/fpi-sdcp-device.h
Normal file
142
libfprint/fpi-sdcp-device.h
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
/*
|
||||||
|
* FpSdcpDevice - A base class for SDCP enabled devices
|
||||||
|
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.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 <glib-2.0/glib.h>
|
||||||
|
#include "fpi-device.h"
|
||||||
|
#include "fp-sdcp-device.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FpiSdcpClaim:
|
||||||
|
* @cert_m: The per-model ECDSA certificate (x509 ASN.1 DER encoded)
|
||||||
|
* @pk_d: The device public key (65 bytes)
|
||||||
|
* @pk_f: The firmware public key (65 bytes)
|
||||||
|
* @h_f: The firmware hash
|
||||||
|
* @s_m: Signature over @pk_d using the per-model private key (64 bytes)
|
||||||
|
* @s_d: Signature over h_f and pk_f using the device private key (64 bytes)
|
||||||
|
*
|
||||||
|
* Structure to hold the claim as produced by the device during a secure
|
||||||
|
* connect. See the SDCP specification for more details.
|
||||||
|
*
|
||||||
|
* Note all of these may simply be memory views into a larger #GBytes created
|
||||||
|
* using g_bytes_new_from_bytes().
|
||||||
|
*/
|
||||||
|
struct _FpiSdcpClaim
|
||||||
|
{
|
||||||
|
/*< public >*/
|
||||||
|
GBytes *cert_m;
|
||||||
|
GBytes *pk_d;
|
||||||
|
GBytes *pk_f;
|
||||||
|
GBytes *h_f;
|
||||||
|
GBytes *s_m;
|
||||||
|
GBytes *s_d;
|
||||||
|
};
|
||||||
|
typedef struct _FpiSdcpClaim FpiSdcpClaim;
|
||||||
|
|
||||||
|
GType fpi_sdcp_claim_get_type (void) G_GNUC_CONST;
|
||||||
|
FpiSdcpClaim *fpi_sdcp_claim_new (void);
|
||||||
|
FpiSdcpClaim *fpi_sdcp_claim_copy (FpiSdcpClaim *other);
|
||||||
|
void fpi_sdcp_claim_free (FpiSdcpClaim *claim);
|
||||||
|
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpiSdcpClaim, fpi_sdcp_claim_free)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FpSdcpDeviceClass:
|
||||||
|
* @connect: Establish SDCP connection. Similar to open in #FpDeviceClass
|
||||||
|
* but called connect to mirror the SDCP specification.
|
||||||
|
* @reconnect: Perform a faster reconnect. Drivers do not need to provide this
|
||||||
|
* function. If reconnect fails, then a normal connect will be tried.
|
||||||
|
* @enroll_begin: Start the enrollment procedure. In the absence of an error,
|
||||||
|
* the driver must call fpi_sdcp_device_enroll_set_nonce() at any point. It
|
||||||
|
* also must report enrollment progress using fpi_device_enroll_progress().
|
||||||
|
* It should also store available metadata about the print in device memory.
|
||||||
|
* The operation is completed with fpi_sdcp_device_enroll_ready().
|
||||||
|
* @enroll_commit: Complete the enrollment procedure. This commits the newly
|
||||||
|
* enrolled print to the device memory. Will only be called if enroll_begin
|
||||||
|
* succeeded. The passed id may be %NULL, in that case the driver must
|
||||||
|
* abort the enrollment process. id is owned by the base class and remains
|
||||||
|
* valid throughout the operation.
|
||||||
|
* @identify: Start identification process. On completion, the driver must call
|
||||||
|
* fpi_sdcp_device_identify_complete(). To request the user to retry the
|
||||||
|
* fpi_sdcp_device_identify_retry() function is used.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* These are the main entry points for drivers implementing SDCP.
|
||||||
|
*
|
||||||
|
* Drivers *must* eventually call the corresponding function to finish the
|
||||||
|
* operation.
|
||||||
|
*
|
||||||
|
* XXX: Is the use of fpi_device_action_error() acceptable?
|
||||||
|
*
|
||||||
|
* Drivers *must* also handle cancellation properly for any long running
|
||||||
|
* operation (i.e. any operation that requires capturing). It is entirely fine
|
||||||
|
* to ignore cancellation requests for short operations (e.g. open/close).
|
||||||
|
*
|
||||||
|
* This API is solely intended for drivers. It is purely internal and neither
|
||||||
|
* API nor ABI stable.
|
||||||
|
*/
|
||||||
|
struct _FpSdcpDeviceClass
|
||||||
|
{
|
||||||
|
FpDeviceClass parent_class;
|
||||||
|
|
||||||
|
void (*connect) (FpSdcpDevice *dev);
|
||||||
|
void (*reconnect) (FpSdcpDevice *dev);
|
||||||
|
void (*close) (FpSdcpDevice *dev);
|
||||||
|
void (*enroll_begin) (FpSdcpDevice *dev);
|
||||||
|
void (*enroll_commit) (FpSdcpDevice *dev,
|
||||||
|
GBytes *id);
|
||||||
|
void (*identify) (FpSdcpDevice *dev);
|
||||||
|
};
|
||||||
|
|
||||||
|
void fpi_sdcp_device_set_intermediat_cas (FpSdcpDevice *self,
|
||||||
|
GBytes *ca_1,
|
||||||
|
GBytes *ca_2);
|
||||||
|
|
||||||
|
void fpi_sdcp_device_get_connect_data (FpSdcpDevice *self,
|
||||||
|
GBytes **r_h,
|
||||||
|
GBytes **pk_h);
|
||||||
|
void fpi_sdcp_device_connect_complete (FpSdcpDevice *self,
|
||||||
|
GBytes *r_d,
|
||||||
|
FpiSdcpClaim *claim,
|
||||||
|
GBytes *mac,
|
||||||
|
GError *error);
|
||||||
|
|
||||||
|
void fpi_sdcp_device_get_reconnect_data (FpSdcpDevice *self,
|
||||||
|
GBytes **r_h);
|
||||||
|
void fpi_sdcp_device_reconnect_complete (FpSdcpDevice *self,
|
||||||
|
GBytes *mac,
|
||||||
|
GError *error);
|
||||||
|
|
||||||
|
void fpi_sdcp_device_enroll_set_nonce (FpSdcpDevice *self,
|
||||||
|
GBytes *nonce);
|
||||||
|
void fpi_sdcp_device_enroll_ready (FpSdcpDevice *self,
|
||||||
|
GError *error);
|
||||||
|
void fpi_sdcp_device_enroll_commit_complete (FpSdcpDevice *self,
|
||||||
|
GError *error);
|
||||||
|
|
||||||
|
void fpi_sdcp_device_get_identify_data (FpSdcpDevice *self,
|
||||||
|
GBytes **nonce);
|
||||||
|
void fpi_sdcp_device_identify_retry (FpSdcpDevice *self,
|
||||||
|
GError *error);
|
||||||
|
void fpi_sdcp_device_identify_complete (FpSdcpDevice *self,
|
||||||
|
GBytes *id,
|
||||||
|
GBytes *mac,
|
||||||
|
GError *error);
|
|
@ -80,128 +80,91 @@ nbis_sources = [
|
||||||
'nbis/mindtct/xytreps.c',
|
'nbis/mindtct/xytreps.c',
|
||||||
]
|
]
|
||||||
|
|
||||||
aeslib = false
|
driver_sources = {
|
||||||
aesx660 = false
|
'upekts' :
|
||||||
aes3k = false
|
[ 'drivers/upekts.c', 'drivers/upek_proto.c' ],
|
||||||
|
'upektc' :
|
||||||
|
[ 'drivers/upektc.c' ],
|
||||||
|
'upeksonly' :
|
||||||
|
[ 'drivers/upeksonly.c' ],
|
||||||
|
'uru4000' :
|
||||||
|
[ 'drivers/uru4000.c' ],
|
||||||
|
'aes1610' :
|
||||||
|
[ 'drivers/aes1610.c' ],
|
||||||
|
'aes1660' :
|
||||||
|
[ 'drivers/aes1660.c' ],
|
||||||
|
'aes2501' :
|
||||||
|
[ 'drivers/aes2501.c' ],
|
||||||
|
'aes2550' :
|
||||||
|
[ 'drivers/aes2550.c' ],
|
||||||
|
'aes2660' :
|
||||||
|
[ 'drivers/aes2660.c' ],
|
||||||
|
'aes3500' :
|
||||||
|
[ 'drivers/aes3500.c' ],
|
||||||
|
'aes4000' :
|
||||||
|
[ 'drivers/aes4000.c' ],
|
||||||
|
'vcom5s' :
|
||||||
|
[ 'drivers/vcom5s.c' ],
|
||||||
|
'vfs101' :
|
||||||
|
[ 'drivers/vfs101.c' ],
|
||||||
|
'vfs301' :
|
||||||
|
[ 'drivers/vfs301.c', 'drivers/vfs301_proto.c' ],
|
||||||
|
'vfs5011' :
|
||||||
|
[ 'drivers/vfs5011.c' ],
|
||||||
|
'vfs7552' :
|
||||||
|
[ 'drivers/vfs7552.c' ],
|
||||||
|
'upektc_img' :
|
||||||
|
[ 'drivers/upektc_img.c', 'drivers/upek_proto.c' ],
|
||||||
|
'etes603' :
|
||||||
|
[ 'drivers/etes603.c' ],
|
||||||
|
'vfs0050' :
|
||||||
|
[ 'drivers/vfs0050.c' ],
|
||||||
|
'elan' :
|
||||||
|
[ 'drivers/elan.c' ],
|
||||||
|
'elanspi' :
|
||||||
|
[ 'drivers/elanspi.c' ],
|
||||||
|
'nb1010' :
|
||||||
|
[ 'drivers/nb1010.c' ],
|
||||||
|
'virtual_image' :
|
||||||
|
[ 'drivers/virtual-image.c' ],
|
||||||
|
'virtual_device' :
|
||||||
|
[ 'drivers/virtual-device.c' ],
|
||||||
|
'virtual_device_storage' :
|
||||||
|
[ 'drivers/virtual-device-storage.c' ],
|
||||||
|
'virtual_sdcp' :
|
||||||
|
[ 'drivers/virtual-sdcp.c' ],
|
||||||
|
'synaptics' :
|
||||||
|
[ 'drivers/synaptics/synaptics.c', 'drivers/synaptics/bmkt_message.c' ],
|
||||||
|
'goodixmoc' :
|
||||||
|
[ 'drivers/goodixmoc/goodix.c', 'drivers/goodixmoc/goodix_proto.c' ],
|
||||||
|
}
|
||||||
|
|
||||||
|
helper_sources = {
|
||||||
|
'sdcp' :
|
||||||
|
[ 'fp-sdcp-device.c', 'fpi-sdcp-device.c' ],
|
||||||
|
'aeslib' :
|
||||||
|
[ 'drivers/aeslib.c' ],
|
||||||
|
'aesx660' :
|
||||||
|
[ 'drivers/aesx660.c' ],
|
||||||
|
'aes3k' :
|
||||||
|
[ 'drivers/aes3k.c' ],
|
||||||
|
'nss' :
|
||||||
|
[ ],
|
||||||
|
'udev' :
|
||||||
|
[ ],
|
||||||
|
'virtual' :
|
||||||
|
[ 'drivers/virtual-device-listener.c' ],
|
||||||
|
}
|
||||||
|
|
||||||
drivers_sources = []
|
drivers_sources = []
|
||||||
drivers_cflags = []
|
drivers_cflags = []
|
||||||
foreach driver: drivers
|
foreach driver: drivers
|
||||||
if driver == 'upekts'
|
drivers_sources += driver_sources[driver]
|
||||||
drivers_sources += [ 'drivers/upekts.c', 'drivers/upek_proto.c' ]
|
endforeach
|
||||||
endif
|
foreach helper : driver_helpers
|
||||||
if driver == 'upektc'
|
drivers_sources += helper_sources[helper]
|
||||||
drivers_sources += [ 'drivers/upektc.c' ]
|
|
||||||
endif
|
|
||||||
if driver == 'upeksonly'
|
|
||||||
drivers_sources += [ 'drivers/upeksonly.c' ]
|
|
||||||
endif
|
|
||||||
if driver == 'uru4000'
|
|
||||||
drivers_sources += [ 'drivers/uru4000.c' ]
|
|
||||||
endif
|
|
||||||
if driver == 'aes1610'
|
|
||||||
drivers_sources += [ 'drivers/aes1610.c' ]
|
|
||||||
aeslib = true
|
|
||||||
endif
|
|
||||||
if driver == 'aes1660'
|
|
||||||
drivers_sources += [ 'drivers/aes1660.c' ]
|
|
||||||
aeslib = true
|
|
||||||
aesx660 = true
|
|
||||||
endif
|
|
||||||
if driver == 'aes2501'
|
|
||||||
drivers_sources += [ 'drivers/aes2501.c' ]
|
|
||||||
aeslib = true
|
|
||||||
endif
|
|
||||||
if driver == 'aes2550'
|
|
||||||
drivers_sources += [ 'drivers/aes2550.c' ]
|
|
||||||
aeslib = true
|
|
||||||
endif
|
|
||||||
if driver == 'aes2660'
|
|
||||||
drivers_sources += [ 'drivers/aes2660.c' ]
|
|
||||||
aeslib = true
|
|
||||||
aesx660 = true
|
|
||||||
endif
|
|
||||||
if driver == 'aes3500'
|
|
||||||
drivers_sources += [ 'drivers/aes3500.c' ]
|
|
||||||
aeslib = true
|
|
||||||
aes3k = true
|
|
||||||
endif
|
|
||||||
if driver == 'aes4000'
|
|
||||||
drivers_sources += [ 'drivers/aes4000.c' ]
|
|
||||||
aeslib = true
|
|
||||||
aes3k = true
|
|
||||||
endif
|
|
||||||
if driver == 'vcom5s'
|
|
||||||
drivers_sources += [ 'drivers/vcom5s.c' ]
|
|
||||||
endif
|
|
||||||
if driver == 'vfs101'
|
|
||||||
drivers_sources += [ 'drivers/vfs101.c' ]
|
|
||||||
endif
|
|
||||||
if driver == 'vfs301'
|
|
||||||
drivers_sources += [ 'drivers/vfs301.c', 'drivers/vfs301_proto.c' ]
|
|
||||||
endif
|
|
||||||
if driver == 'vfs5011'
|
|
||||||
drivers_sources += [ 'drivers/vfs5011.c' ]
|
|
||||||
endif
|
|
||||||
if driver == 'vfs7552'
|
|
||||||
drivers_sources += [ 'drivers/vfs7552.c' ]
|
|
||||||
endif
|
|
||||||
if driver == 'upektc_img'
|
|
||||||
drivers_sources += [ 'drivers/upektc_img.c', 'drivers/upek_proto.c' ]
|
|
||||||
endif
|
|
||||||
if driver == 'etes603'
|
|
||||||
drivers_sources += [ 'drivers/etes603.c' ]
|
|
||||||
endif
|
|
||||||
if driver == 'vfs0050'
|
|
||||||
drivers_sources += [ 'drivers/vfs0050.c' ]
|
|
||||||
endif
|
|
||||||
if driver == 'elan'
|
|
||||||
drivers_sources += [ 'drivers/elan.c' ]
|
|
||||||
endif
|
|
||||||
if driver == 'elanspi'
|
|
||||||
drivers_sources += [ 'drivers/elanspi.c' ]
|
|
||||||
endif
|
|
||||||
if driver == 'virtual_image'
|
|
||||||
drivers_sources += [ 'drivers/virtual-image.c' ]
|
|
||||||
endif
|
|
||||||
if driver == 'virtual_device'
|
|
||||||
drivers_sources += [ 'drivers/virtual-device.c' ]
|
|
||||||
endif
|
|
||||||
if driver == 'virtual_device_storage'
|
|
||||||
drivers_sources += [ 'drivers/virtual-device-storage.c' ]
|
|
||||||
endif
|
|
||||||
if driver.startswith('virtual_')
|
|
||||||
drivers_sources += [ 'drivers/virtual-device-listener.c' ]
|
|
||||||
endif
|
|
||||||
if driver == 'synaptics'
|
|
||||||
drivers_sources += [
|
|
||||||
'drivers/synaptics/synaptics.c',
|
|
||||||
'drivers/synaptics/bmkt_message.c',
|
|
||||||
]
|
|
||||||
endif
|
|
||||||
if driver == 'goodixmoc'
|
|
||||||
drivers_sources += [
|
|
||||||
'drivers/goodixmoc/goodix.c',
|
|
||||||
'drivers/goodixmoc/goodix_proto.c',
|
|
||||||
]
|
|
||||||
endif
|
|
||||||
if driver == 'nb1010'
|
|
||||||
drivers_sources += [
|
|
||||||
'drivers/nb1010.c',
|
|
||||||
]
|
|
||||||
endif
|
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
if aeslib
|
|
||||||
drivers_sources += [ 'drivers/aeslib.c' ]
|
|
||||||
endif
|
|
||||||
if aesx660
|
|
||||||
drivers_sources += ['drivers/aesx660.c' ]
|
|
||||||
endif
|
|
||||||
if aes3k
|
|
||||||
drivers_sources += ['drivers/aes3k.c' ]
|
|
||||||
endif
|
|
||||||
|
|
||||||
other_sources = []
|
|
||||||
|
|
||||||
fp_enums = gnome.mkenums_simple('fp-enums',
|
fp_enums = gnome.mkenums_simple('fp-enums',
|
||||||
sources: libfprint_public_headers,
|
sources: libfprint_public_headers,
|
||||||
|
@ -220,6 +183,28 @@ enums_dep = declare_dependency(
|
||||||
sources: [ fp_enums_h, fpi_enums_h ]
|
sources: [ fp_enums_h, fpi_enums_h ]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Export the drivers' types to the core code
|
||||||
|
drivers_type_list = []
|
||||||
|
drivers_type_func = []
|
||||||
|
drivers_type_list += '#include <glib-object.h>'
|
||||||
|
drivers_type_list += '#include "fpi-context.h"'
|
||||||
|
drivers_type_list += ''
|
||||||
|
drivers_type_func += 'GArray *'
|
||||||
|
drivers_type_func += 'fpi_get_driver_types (void)'
|
||||||
|
drivers_type_func += '{'
|
||||||
|
drivers_type_func += ' GArray *drivers = g_array_new (TRUE, FALSE, sizeof (GType));'
|
||||||
|
drivers_type_func += ' GType t;'
|
||||||
|
drivers_type_func += ''
|
||||||
|
foreach driver: supported_drivers
|
||||||
|
drivers_type_list += 'extern GType (fpi_device_' + driver + '_get_type) (void);'
|
||||||
|
drivers_type_func += ' t = fpi_device_' + driver + '_get_type ();'
|
||||||
|
drivers_type_func += ' g_array_append_val (drivers, t);'
|
||||||
|
drivers_type_func += ''
|
||||||
|
endforeach
|
||||||
|
drivers_type_list += ''
|
||||||
|
drivers_type_func += ' return drivers;'
|
||||||
|
drivers_type_func += '}'
|
||||||
|
|
||||||
drivers_sources += configure_file(input: 'empty_file',
|
drivers_sources += configure_file(input: 'empty_file',
|
||||||
output: 'fpi-drivers.c',
|
output: 'fpi-drivers.c',
|
||||||
capture: true,
|
capture: true,
|
||||||
|
@ -234,11 +219,8 @@ deps = [
|
||||||
glib_dep,
|
glib_dep,
|
||||||
gobject_dep,
|
gobject_dep,
|
||||||
gusb_dep,
|
gusb_dep,
|
||||||
gudev_dep,
|
|
||||||
imaging_dep,
|
|
||||||
mathlib_dep,
|
mathlib_dep,
|
||||||
nss_dep,
|
] + optional_deps
|
||||||
]
|
|
||||||
|
|
||||||
# These are empty and only exist so that the include directories are created
|
# These are empty and only exist so that the include directories are created
|
||||||
# in the build tree. This silences a build time warning.
|
# in the build tree. This silences a build time warning.
|
||||||
|
@ -285,7 +267,6 @@ libfprint = shared_library(versioned_libname.split('lib')[1],
|
||||||
sources: [
|
sources: [
|
||||||
fp_enums,
|
fp_enums,
|
||||||
libfprint_sources,
|
libfprint_sources,
|
||||||
other_sources,
|
|
||||||
],
|
],
|
||||||
soversion: soversion,
|
soversion: soversion,
|
||||||
version: libversion,
|
version: libversion,
|
||||||
|
|
121
meson.build
121
meson.build
|
@ -96,8 +96,8 @@ virtual_drivers = [
|
||||||
'virtual_image',
|
'virtual_image',
|
||||||
'virtual_device',
|
'virtual_device',
|
||||||
'virtual_device_storage',
|
'virtual_device_storage',
|
||||||
|
'virtual_sdcp',
|
||||||
]
|
]
|
||||||
|
|
||||||
default_drivers = [
|
default_drivers = [
|
||||||
'upektc_img',
|
'upektc_img',
|
||||||
'vfs5011',
|
'vfs5011',
|
||||||
|
@ -144,10 +144,33 @@ if drivers == [ 'default' ]
|
||||||
drivers = default_drivers
|
drivers = default_drivers
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# For detection whether udev is needed
|
driver_helper_mapping = {
|
||||||
udev_drivers = [
|
'aes1610' : [ 'aeslib' ],
|
||||||
'elanspi'
|
'aes1660' : [ 'aeslib', 'aesx660' ],
|
||||||
]
|
'aes2501' : [ 'aeslib' ],
|
||||||
|
'aes2550' : [ 'aeslib' ],
|
||||||
|
'aes2660' : [ 'aeslib', 'aesx660' ],
|
||||||
|
'aes3500' : [ 'aeslib', 'aes3k' ],
|
||||||
|
'aes4000' : [ 'aeslib', 'aes3k' ],
|
||||||
|
'uru4000' : [ 'nss' ],
|
||||||
|
'elanspi' : [ 'udev' ],
|
||||||
|
'virtual_image' : [ 'virtual' ],
|
||||||
|
'virtual_device' : [ 'virtual' ],
|
||||||
|
'virtual_device_storage' : [ 'virtual' ],
|
||||||
|
'virtual_sdcp' : [ 'sdcp' ],
|
||||||
|
}
|
||||||
|
|
||||||
|
driver_helpers = []
|
||||||
|
foreach driver : drivers
|
||||||
|
if driver in driver_helper_mapping
|
||||||
|
foreach helper : driver_helper_mapping[driver]
|
||||||
|
if helper not in driver_helpers
|
||||||
|
driver_helpers += helper
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
|
||||||
if drivers.length() == 0 or drivers[0] == ''
|
if drivers.length() == 0 or drivers[0] == ''
|
||||||
error('Cannot build libfprint without drivers, please specify a valid value for the drivers option')
|
error('Cannot build libfprint without drivers, please specify a valid value for the drivers option')
|
||||||
|
@ -165,41 +188,53 @@ else
|
||||||
endforeach
|
endforeach
|
||||||
endif
|
endif
|
||||||
|
|
||||||
nss_dep = dependency('', required: false)
|
|
||||||
imaging_dep = dependency('', required: false)
|
|
||||||
gudev_dep = dependency('', required: false)
|
|
||||||
libfprint_conf.set10('HAVE_PIXMAN', false)
|
|
||||||
|
|
||||||
udev_rules = get_option('udev_rules')
|
udev_rules = get_option('udev_rules')
|
||||||
install_udev_rules = udev_rules.enabled()
|
install_udev_rules = udev_rules.enabled()
|
||||||
|
|
||||||
foreach driver: drivers
|
optional_deps = []
|
||||||
if driver == 'uru4000'
|
|
||||||
nss_dep = dependency('nss', required: false)
|
# Resolve extra dependencies
|
||||||
if not nss_dep.found()
|
foreach i : driver_helpers
|
||||||
error('NSS is required for the URU4000/URU4500 driver')
|
foreach d, helpers : driver_helper_mapping
|
||||||
|
if i in helpers
|
||||||
|
driver = d
|
||||||
|
break
|
||||||
endif
|
endif
|
||||||
endif
|
endforeach
|
||||||
if driver == 'aes3500' or driver == 'aes4000' or driver == 'elanspi'
|
|
||||||
|
if i == 'aes3k'
|
||||||
imaging_dep = dependency('pixman-1', required: false)
|
imaging_dep = dependency('pixman-1', required: false)
|
||||||
if not imaging_dep.found()
|
if not imaging_dep.found()
|
||||||
error('pixman is required for imaging support')
|
error('pixman is required for @0@ and possibly others'.format(driver))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libfprint_conf.set10('HAVE_PIXMAN', true)
|
libfprint_conf.set10('HAVE_PIXMAN', true)
|
||||||
endif
|
optional_deps += imaging_dep
|
||||||
if udev_drivers.contains(driver)
|
elif i == 'nss'
|
||||||
install_udev_rules = true
|
nss_dep = dependency('nss', required: false)
|
||||||
|
if not nss_dep.found()
|
||||||
gudev_dep = dependency('gudev-1.0', required: false)
|
error('nss is required for @0@ and possibly others'.format(driver))
|
||||||
if not gudev_dep.found()
|
|
||||||
error('udev is required for SPI support')
|
|
||||||
endif
|
|
||||||
|
|
||||||
libfprint_conf.set10('HAVE_UDEV', true)
|
|
||||||
endif
|
endif
|
||||||
if not all_drivers.contains(driver)
|
|
||||||
error('Invalid driver \'' + driver + '\'')
|
optional_deps += nss_dep
|
||||||
|
elif i == 'sdcp'
|
||||||
|
nss_dep = dependency('nss', version: '>=3.55', required: false)
|
||||||
|
if not nss_dep.found()
|
||||||
|
error('nss >=3.55 is required for SDCP support (@0@ and possibly others)'.format(driver))
|
||||||
|
endif
|
||||||
|
|
||||||
|
optional_deps += nss_dep
|
||||||
|
elif i == 'udev'
|
||||||
|
install_udev_rules = true
|
||||||
|
|
||||||
|
gudev_dep = dependency('gudev-1.0', required: false)
|
||||||
|
if not gudev_dep.found()
|
||||||
|
error('udev is required for SPI support')
|
||||||
|
endif
|
||||||
|
|
||||||
|
libfprint_conf.set10('HAVE_UDEV', true)
|
||||||
|
|
||||||
|
optional_deps += gudev_dep
|
||||||
endif
|
endif
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
|
@ -229,28 +264,6 @@ if default_drivers_are_enabled and supported_drivers != drivers
|
||||||
default_drivers_are_enabled = false
|
default_drivers_are_enabled = false
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Export the drivers' types to the core code
|
|
||||||
drivers_type_list = []
|
|
||||||
drivers_type_func = []
|
|
||||||
drivers_type_list += '#include <glib-object.h>'
|
|
||||||
drivers_type_list += '#include "fpi-context.h"'
|
|
||||||
drivers_type_list += ''
|
|
||||||
drivers_type_func += 'GArray *'
|
|
||||||
drivers_type_func += 'fpi_get_driver_types (void)'
|
|
||||||
drivers_type_func += '{'
|
|
||||||
drivers_type_func += ' GArray *drivers = g_array_new (TRUE, FALSE, sizeof (GType));'
|
|
||||||
drivers_type_func += ' GType t;'
|
|
||||||
drivers_type_func += ''
|
|
||||||
foreach driver: supported_drivers
|
|
||||||
drivers_type_list += 'extern GType (fpi_device_' + driver + '_get_type) (void);'
|
|
||||||
drivers_type_func += ' t = fpi_device_' + driver + '_get_type ();'
|
|
||||||
drivers_type_func += ' g_array_append_val (drivers, t);'
|
|
||||||
drivers_type_func += ''
|
|
||||||
endforeach
|
|
||||||
drivers_type_list += ''
|
|
||||||
drivers_type_func += ' return drivers;'
|
|
||||||
drivers_type_func += '}'
|
|
||||||
|
|
||||||
root_inc = include_directories('.')
|
root_inc = include_directories('.')
|
||||||
|
|
||||||
udev_hwdb = get_option('udev_hwdb')
|
udev_hwdb = get_option('udev_hwdb')
|
||||||
|
@ -285,9 +298,11 @@ if get_option('gtk-examples')
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Some dependency resolving happens inside here
|
||||||
|
subdir('libfprint')
|
||||||
|
|
||||||
configure_file(output: 'config.h', configuration: libfprint_conf)
|
configure_file(output: 'config.h', configuration: libfprint_conf)
|
||||||
|
|
||||||
subdir('libfprint')
|
|
||||||
subdir('examples')
|
subdir('examples')
|
||||||
if get_option('doc')
|
if get_option('doc')
|
||||||
gnome = import('gnome')
|
gnome = import('gnome')
|
||||||
|
|
|
@ -30,3 +30,8 @@ option('doc',
|
||||||
description: 'Whether to build the API documentation',
|
description: 'Whether to build the API documentation',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
value: true)
|
value: true)
|
||||||
|
|
||||||
|
option('sdcp_virt_binary',
|
||||||
|
description: 'Path to virtual SDCP test binary, please refer to CI for more details.',
|
||||||
|
type: 'string',
|
||||||
|
value: '')
|
||||||
|
|
|
@ -12,8 +12,11 @@ case "$1" in
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
ARGS=4
|
||||||
|
JOBS=4
|
||||||
|
|
||||||
pushd "$SRCROOT"
|
pushd "$SRCROOT"
|
||||||
uncrustify -c "$CFG" $OPTS `git ls-tree --name-only -r HEAD | grep -E '.*\.[ch]$' | grep -v nbis | grep -v fpi-byte | grep -v build/`
|
git ls-tree --name-only -r HEAD | grep -E '.*\.[ch]$' | grep -v nbis | grep -v fpi-byte | grep -v build/ | xargs -n$ARGS -P $JOBS uncrustify -c "$CFG" $OPTS
|
||||||
RES=$?
|
RES=$?
|
||||||
popd
|
popd
|
||||||
exit $RES
|
exit $RES
|
||||||
|
|
|
@ -12,6 +12,9 @@ envs.prepend('LD_LIBRARY_PATH', join_paths(meson.build_root(), 'libfprint'))
|
||||||
# random numbers rather than proper ones)
|
# random numbers rather than proper ones)
|
||||||
envs.set('FP_DEVICE_EMULATION', '1')
|
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
|
# Set a colon-separated list of native drivers we enable in tests
|
||||||
envs.set('FP_DRIVERS_WHITELIST', ':'.join([
|
envs.set('FP_DRIVERS_WHITELIST', ':'.join([
|
||||||
'virtual_image',
|
'virtual_image',
|
||||||
|
@ -72,6 +75,7 @@ if get_option('introspection')
|
||||||
suite: ut_suite,
|
suite: ut_suite,
|
||||||
depends: libfprint_typelib,
|
depends: libfprint_typelib,
|
||||||
env: envs,
|
env: envs,
|
||||||
|
workdir: meson.current_source_dir(),
|
||||||
)
|
)
|
||||||
endforeach
|
endforeach
|
||||||
else
|
else
|
||||||
|
@ -82,6 +86,46 @@ if get_option('introspection')
|
||||||
endif
|
endif
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
|
if 'virtual_sdcp' in drivers and get_option('sdcp_virt_binary') != ''
|
||||||
|
python3 = find_program('python3')
|
||||||
|
unittest_inspector = find_program('unittest_inspector.py')
|
||||||
|
base_args = files('virtual-sdcp.py')
|
||||||
|
suite = []
|
||||||
|
|
||||||
|
r = run_command(unittest_inspector, files('virtual-sdcp.py'))
|
||||||
|
unit_tests = r.stdout().strip().split('\n')
|
||||||
|
|
||||||
|
if r.returncode() == 0 and unit_tests.length() > 0
|
||||||
|
suite += 'virtual-sdcp'
|
||||||
|
else
|
||||||
|
unit_tests = ['virtual-sdcp']
|
||||||
|
endif
|
||||||
|
|
||||||
|
sdcp_envs = envs
|
||||||
|
sdcp_envs.set('FP_DEVICE_EMULATION', '0')
|
||||||
|
foreach ut: unit_tests
|
||||||
|
ut_suite = suite
|
||||||
|
ut_args = base_args
|
||||||
|
if unit_tests.length() > 1
|
||||||
|
ut_args += ut
|
||||||
|
ut_suite += ut.split('.')[0]
|
||||||
|
endif
|
||||||
|
test(ut,
|
||||||
|
python3,
|
||||||
|
args: ut_args,
|
||||||
|
suite: ut_suite,
|
||||||
|
depends: libfprint_typelib,
|
||||||
|
env: sdcp_envs,
|
||||||
|
workdir: meson.current_source_dir(),
|
||||||
|
)
|
||||||
|
endforeach
|
||||||
|
else
|
||||||
|
test('virtual-sdcp',
|
||||||
|
find_program('sh'),
|
||||||
|
args: ['-c', 'exit 77']
|
||||||
|
)
|
||||||
|
endif
|
||||||
|
|
||||||
foreach driver_test: drivers_tests
|
foreach driver_test: drivers_tests
|
||||||
if driver_test.contains('-')
|
if driver_test.contains('-')
|
||||||
driver_name = driver_test.split('-')[0]
|
driver_name = driver_test.split('-')[0]
|
||||||
|
@ -97,6 +141,7 @@ if get_option('introspection')
|
||||||
find_program('umockdev-test.py'),
|
find_program('umockdev-test.py'),
|
||||||
args: join_paths(meson.current_source_dir(), driver_test),
|
args: join_paths(meson.current_source_dir(), driver_test),
|
||||||
env: driver_envs,
|
env: driver_envs,
|
||||||
|
workdir: meson.current_source_dir(),
|
||||||
suite: ['drivers'],
|
suite: ['drivers'],
|
||||||
timeout: 15,
|
timeout: 15,
|
||||||
depends: libfprint_typelib,
|
depends: libfprint_typelib,
|
||||||
|
|
BIN
tests/sdcp-key-db/cert9.db
Normal file
BIN
tests/sdcp-key-db/cert9.db
Normal file
Binary file not shown.
BIN
tests/sdcp-key-db/key4.db
Normal file
BIN
tests/sdcp-key-db/key4.db
Normal file
Binary file not shown.
144
tests/virtual-sdcp.py
Normal file
144
tests/virtual-sdcp.py
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
#!/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))
|
Loading…
Reference in a new issue