sdcp-device: Use predictable keys and random numbers for testing
If FP_DEVICE_EMULATION is set, then switch to using predictable EC ephemeral key and random numbers. This should allow recording and replaying real device interactions using umockdev.
This commit is contained in:
parent
4f100956ac
commit
d6dc3403d8
2 changed files with 84 additions and 19 deletions
|
@ -23,6 +23,7 @@
|
|||
#include <sechash.h>
|
||||
#include <cert.h>
|
||||
|
||||
#include "fpi-compat.h"
|
||||
#include "fp-sdcp-device-private.h"
|
||||
#include "fpi-sdcp-device.h"
|
||||
#include "fpi-print.h"
|
||||
|
@ -156,6 +157,47 @@ fp_sdcp_device_get_instance_private (FpSdcpDevice *self)
|
|||
g_type_class_get_instance_private_offset (sdcp_class));
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_sdcp_generate_random:
|
||||
* @buffer: Buffer to place random bytes into
|
||||
* @len: Number of bytes to generate
|
||||
* @error: Error out
|
||||
*
|
||||
* Returns: #TRUE on success
|
||||
**/
|
||||
FP_GNUC_ACCESS (write_only, 1, 2)
|
||||
static gboolean
|
||||
fpi_sdcp_generate_random (guint8 *buffer, gsize len, GError **error)
|
||||
{
|
||||
/* Just use a counter in emulation mode. Not random, but all
|
||||
* we need is something predictable and not repeating immediately.
|
||||
*/
|
||||
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
|
||||
{
|
||||
static guint8 emulation_rand = 0;
|
||||
gsize i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
buffer[i] = emulation_rand;
|
||||
emulation_rand += 1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Generating random numbers is basic enough to assume it works */
|
||||
if (PK11_GenerateRandom (buffer, len) != SECSuccess)
|
||||
{
|
||||
g_propagate_error (error,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
"Error generating random numbers using NSS!"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fpi_sdcp_kdf:
|
||||
* @self: The #FpSdcpDevice
|
||||
|
@ -236,7 +278,6 @@ fpi_sdcp_kdf (FpSdcpDevice *self,
|
|||
data_param[kdf_params.ulNumberOfDataParams].ulValueLen = sizeof (length_format);
|
||||
kdf_params.ulNumberOfDataParams += 1;
|
||||
|
||||
/* TODO: support a second key out (may be discarded) */
|
||||
kdf_params.ulAdditionalDerivedKeys = 0;
|
||||
kdf_params.pAdditionalDerivedKeys = NULL;
|
||||
if (out_key_2)
|
||||
|
@ -362,6 +403,7 @@ fpi_sdcp_device_connect (FpSdcpDevice *self)
|
|||
FpSdcpDevicePrivate *priv = fp_sdcp_device_get_instance_private (self);
|
||||
PLArenaPool *arena = NULL;
|
||||
ECParams ec_parameters = { NULL };
|
||||
GError *error = NULL;
|
||||
|
||||
SECStatus r = SECSuccess;
|
||||
|
||||
|
@ -397,7 +439,30 @@ fpi_sdcp_device_connect (FpSdcpDevice *self)
|
|||
|
||||
arena = PORT_NewArena (NSS_FREEBL_DEFAULT_CHUNKSIZE);
|
||||
EC_FillParams (arena, &SDCPECParamsDER, &ec_parameters);
|
||||
|
||||
/* Just use a counter in emulation mode. Not random, but all
|
||||
* we need is something predictable and not repeating immediately.
|
||||
*/
|
||||
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
|
||||
{
|
||||
/* ECDSA Known Seed info for curves nistp256 and nistk283 */
|
||||
static const PRUint8 ecdsa_known_seed[] = {
|
||||
0x6a, 0x9b, 0xf6, 0xf7, 0xce, 0xed, 0x79, 0x11,
|
||||
0xf0, 0xc7, 0xc8, 0x9a, 0xa5, 0xd1, 0x57, 0xb1,
|
||||
0x7b, 0x5a, 0x3b, 0x76, 0x4e, 0x7b, 0x7c, 0xbc,
|
||||
0xf2, 0x76, 0x1c, 0x1c, 0x7f, 0xc5, 0x53, 0x2f
|
||||
};
|
||||
|
||||
r = EC_NewKeyFromSeed (&ec_parameters,
|
||||
&priv->host_key_private,
|
||||
ecdsa_known_seed,
|
||||
sizeof (ecdsa_known_seed));
|
||||
}
|
||||
else
|
||||
{
|
||||
r = EC_NewKey (&ec_parameters, &priv->host_key_private);
|
||||
}
|
||||
|
||||
PORT_FreeArena (arena, FALSE);
|
||||
arena = NULL;
|
||||
|
||||
|
@ -405,9 +470,13 @@ fpi_sdcp_device_connect (FpSdcpDevice *self)
|
|||
goto nss_error;
|
||||
|
||||
/* SDCP Connect: 3.ii. Generate host random */
|
||||
r = PK11_GenerateRandom (priv->host_random, sizeof (priv->host_random));
|
||||
if (r != SECSuccess)
|
||||
goto nss_error;
|
||||
if (!fpi_sdcp_generate_random (priv->host_random, sizeof (priv->host_random), &error))
|
||||
{
|
||||
fpi_sdcp_device_connect_complete (self,
|
||||
NULL, NULL, NULL,
|
||||
error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* SDCP Connect: 3.iii. Send the Connect message */
|
||||
cls->connect (self);
|
||||
|
@ -428,16 +497,13 @@ fpi_sdcp_device_reconnect (FpSdcpDevice *self)
|
|||
{
|
||||
FpSdcpDeviceClass *cls = FP_SDCP_DEVICE_GET_CLASS (self);
|
||||
FpSdcpDevicePrivate *priv = fp_sdcp_device_get_instance_private (self);
|
||||
SECStatus r;
|
||||
GError *error = NULL;
|
||||
|
||||
/* SDCP Reconnect: 2.i. Generate host random */
|
||||
r = PK11_GenerateRandom (priv->host_random, sizeof (priv->host_random));
|
||||
if (r != SECSuccess)
|
||||
if (!fpi_sdcp_generate_random (priv->host_random, sizeof (priv->host_random), &error))
|
||||
{
|
||||
fpi_sdcp_device_reconnect_complete (self,
|
||||
NULL,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
"Error calling NSS crypto routine: %d", r));
|
||||
fpi_sdcp_device_reconnect_complete (self, NULL, error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* SDCP Reconnect: 2.ii. Send the Reconnect message */
|
||||
|
@ -473,7 +539,7 @@ fpi_sdcp_device_identify (FpSdcpDevice *self)
|
|||
FpSdcpDevicePrivate *priv = fp_sdcp_device_get_instance_private (self);
|
||||
FpSdcpDeviceClass *cls = FP_SDCP_DEVICE_GET_CLASS (self);
|
||||
FpiDeviceAction action;
|
||||
SECStatus r;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_if_fail (FP_IS_SDCP_DEVICE (self));
|
||||
action = fpi_device_get_current_action (FP_DEVICE (self));
|
||||
|
@ -481,12 +547,9 @@ fpi_sdcp_device_identify (FpSdcpDevice *self)
|
|||
g_return_if_fail (action == FPI_DEVICE_ACTION_IDENTIFY || action == FPI_DEVICE_ACTION_VERIFY);
|
||||
|
||||
/* Generate a new nonce. */
|
||||
r = PK11_GenerateRandom (priv->host_random, sizeof (priv->host_random));
|
||||
if (r != SECSuccess)
|
||||
if (!fpi_sdcp_generate_random (priv->host_random, sizeof (priv->host_random), &error))
|
||||
{
|
||||
fpi_device_action_error (FP_DEVICE (self),
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
"Error calling NSS crypto routine: %d", r));
|
||||
fpi_device_action_error (FP_DEVICE (self), error);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -100,6 +100,8 @@ if get_option('introspection')
|
|||
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
|
||||
|
@ -112,7 +114,7 @@ if get_option('introspection')
|
|||
args: ut_args,
|
||||
suite: ut_suite,
|
||||
depends: libfprint_typelib,
|
||||
env: envs,
|
||||
env: sdcp_envs,
|
||||
)
|
||||
endforeach
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue