xref: /freebsd/contrib/libfido2/regress/dev.c (revision f540a43052c12c76d3453ead881248d5467a1ab0)
10afa8e06SEd Maste /*
2*f540a430SEd Maste  * Copyright (c) 2019-2021 Yubico AB. All rights reserved.
30afa8e06SEd Maste  * Use of this source code is governed by a BSD-style
40afa8e06SEd Maste  * license that can be found in the LICENSE file.
50afa8e06SEd Maste  */
60afa8e06SEd Maste 
70afa8e06SEd Maste #include <assert.h>
8*f540a430SEd Maste #include <err.h>
90afa8e06SEd Maste #include <fido.h>
100afa8e06SEd Maste #include <string.h>
11*f540a430SEd Maste #include <time.h>
120afa8e06SEd Maste 
130afa8e06SEd Maste #include "../fuzz/wiredata_fido2.h"
140afa8e06SEd Maste 
150afa8e06SEd Maste #define FAKE_DEV_HANDLE	((void *)0xdeadbeef)
160afa8e06SEd Maste #define REPORT_LEN	(64 + 1)
170afa8e06SEd Maste 
180afa8e06SEd Maste static uint8_t	 ctap_nonce[8];
190afa8e06SEd Maste static uint8_t	*wiredata_ptr;
200afa8e06SEd Maste static size_t	 wiredata_len;
210afa8e06SEd Maste static int	 initialised;
22*f540a430SEd Maste static long	 interval_ms;
230afa8e06SEd Maste 
240afa8e06SEd Maste static void *
250afa8e06SEd Maste dummy_open(const char *path)
260afa8e06SEd Maste {
270afa8e06SEd Maste 	(void)path;
280afa8e06SEd Maste 
290afa8e06SEd Maste 	return (FAKE_DEV_HANDLE);
300afa8e06SEd Maste }
310afa8e06SEd Maste 
320afa8e06SEd Maste static void
330afa8e06SEd Maste dummy_close(void *handle)
340afa8e06SEd Maste {
350afa8e06SEd Maste 	assert(handle == FAKE_DEV_HANDLE);
360afa8e06SEd Maste }
370afa8e06SEd Maste 
380afa8e06SEd Maste static int
390afa8e06SEd Maste dummy_read(void *handle, unsigned char *ptr, size_t len, int ms)
400afa8e06SEd Maste {
41*f540a430SEd Maste 	struct timespec tv;
420afa8e06SEd Maste 	size_t		n;
43*f540a430SEd Maste 	long		d;
440afa8e06SEd Maste 
450afa8e06SEd Maste 	assert(handle == FAKE_DEV_HANDLE);
460afa8e06SEd Maste 	assert(ptr != NULL);
470afa8e06SEd Maste 	assert(len == REPORT_LEN - 1);
480afa8e06SEd Maste 
490afa8e06SEd Maste 	if (wiredata_ptr == NULL)
500afa8e06SEd Maste 		return (-1);
510afa8e06SEd Maste 
520afa8e06SEd Maste 	if (!initialised) {
530afa8e06SEd Maste 		assert(wiredata_len >= REPORT_LEN - 1);
540afa8e06SEd Maste 		memcpy(&wiredata_ptr[7], &ctap_nonce, sizeof(ctap_nonce));
550afa8e06SEd Maste 		initialised = 1;
560afa8e06SEd Maste 	}
570afa8e06SEd Maste 
58*f540a430SEd Maste 	if (ms >= 0 && ms < interval_ms)
59*f540a430SEd Maste 		d = ms;
60*f540a430SEd Maste 	else
61*f540a430SEd Maste 		d = interval_ms;
62*f540a430SEd Maste 
63*f540a430SEd Maste 	if (d) {
64*f540a430SEd Maste 		tv.tv_sec = d / 1000;
65*f540a430SEd Maste 		tv.tv_nsec = (d % 1000) * 1000000;
66*f540a430SEd Maste 		if (nanosleep(&tv, NULL) == -1)
67*f540a430SEd Maste 			err(1, "nanosleep");
68*f540a430SEd Maste 	}
69*f540a430SEd Maste 
70*f540a430SEd Maste 	if (d != interval_ms)
71*f540a430SEd Maste 		return (-1); /* timeout */
72*f540a430SEd Maste 
730afa8e06SEd Maste 	if (wiredata_len < len)
740afa8e06SEd Maste 		n = wiredata_len;
750afa8e06SEd Maste 	else
760afa8e06SEd Maste 		n = len;
770afa8e06SEd Maste 
780afa8e06SEd Maste 	memcpy(ptr, wiredata_ptr, n);
790afa8e06SEd Maste 	wiredata_ptr += n;
800afa8e06SEd Maste 	wiredata_len -= n;
810afa8e06SEd Maste 
820afa8e06SEd Maste 	return ((int)n);
830afa8e06SEd Maste }
840afa8e06SEd Maste 
850afa8e06SEd Maste static int
860afa8e06SEd Maste dummy_write(void *handle, const unsigned char *ptr, size_t len)
870afa8e06SEd Maste {
88*f540a430SEd Maste 	struct timespec tv;
89*f540a430SEd Maste 
900afa8e06SEd Maste 	assert(handle == FAKE_DEV_HANDLE);
910afa8e06SEd Maste 	assert(ptr != NULL);
920afa8e06SEd Maste 	assert(len == REPORT_LEN);
930afa8e06SEd Maste 
940afa8e06SEd Maste 	if (!initialised)
950afa8e06SEd Maste 		memcpy(&ctap_nonce, &ptr[8], sizeof(ctap_nonce));
960afa8e06SEd Maste 
97*f540a430SEd Maste 	if (interval_ms) {
98*f540a430SEd Maste 		tv.tv_sec = interval_ms / 1000;
99*f540a430SEd Maste 		tv.tv_nsec = (interval_ms % 1000) * 1000000;
100*f540a430SEd Maste 		if (nanosleep(&tv, NULL) == -1)
101*f540a430SEd Maste 			err(1, "nanosleep");
102*f540a430SEd Maste 	}
103*f540a430SEd Maste 
1040afa8e06SEd Maste 	return ((int)len);
1050afa8e06SEd Maste }
1060afa8e06SEd Maste 
1070afa8e06SEd Maste static uint8_t *
1080afa8e06SEd Maste wiredata_setup(const uint8_t *data, size_t len)
1090afa8e06SEd Maste {
1100afa8e06SEd Maste 	const uint8_t ctap_init_data[] = { WIREDATA_CTAP_INIT };
1110afa8e06SEd Maste 
1120afa8e06SEd Maste 	assert(wiredata_ptr == NULL);
1130afa8e06SEd Maste 	assert(SIZE_MAX - len > sizeof(ctap_init_data));
1140afa8e06SEd Maste 	assert((wiredata_ptr = malloc(sizeof(ctap_init_data) + len)) != NULL);
1150afa8e06SEd Maste 
1160afa8e06SEd Maste 	memcpy(wiredata_ptr, ctap_init_data, sizeof(ctap_init_data));
1170afa8e06SEd Maste 
1180afa8e06SEd Maste 	if (len)
1190afa8e06SEd Maste 		memcpy(wiredata_ptr + sizeof(ctap_init_data), data, len);
1200afa8e06SEd Maste 
1210afa8e06SEd Maste 	wiredata_len = sizeof(ctap_init_data) + len;
1220afa8e06SEd Maste 
1230afa8e06SEd Maste 	return (wiredata_ptr);
1240afa8e06SEd Maste }
1250afa8e06SEd Maste 
1260afa8e06SEd Maste static void
1270afa8e06SEd Maste wiredata_clear(uint8_t **wiredata)
1280afa8e06SEd Maste {
1290afa8e06SEd Maste 	free(*wiredata);
1300afa8e06SEd Maste 	*wiredata = NULL;
1310afa8e06SEd Maste 	wiredata_ptr = NULL;
1320afa8e06SEd Maste 	wiredata_len = 0;
1330afa8e06SEd Maste 	initialised = 0;
1340afa8e06SEd Maste }
1350afa8e06SEd Maste 
1360afa8e06SEd Maste /* gh#56 */
1370afa8e06SEd Maste static void
1380afa8e06SEd Maste open_iff_ok(void)
1390afa8e06SEd Maste {
1400afa8e06SEd Maste 	fido_dev_t	*dev = NULL;
1410afa8e06SEd Maste 	fido_dev_io_t	 io;
1420afa8e06SEd Maste 
1430afa8e06SEd Maste 	memset(&io, 0, sizeof(io));
1440afa8e06SEd Maste 
1450afa8e06SEd Maste 	io.open = dummy_open;
1460afa8e06SEd Maste 	io.close = dummy_close;
1470afa8e06SEd Maste 	io.read = dummy_read;
1480afa8e06SEd Maste 	io.write = dummy_write;
1490afa8e06SEd Maste 
1500afa8e06SEd Maste 	assert((dev = fido_dev_new()) != NULL);
1510afa8e06SEd Maste 	assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK);
1520afa8e06SEd Maste 	assert(fido_dev_open(dev, "dummy") == FIDO_ERR_RX);
1530afa8e06SEd Maste 	assert(fido_dev_close(dev) == FIDO_ERR_INVALID_ARGUMENT);
1540afa8e06SEd Maste 
1550afa8e06SEd Maste 	fido_dev_free(&dev);
1560afa8e06SEd Maste }
1570afa8e06SEd Maste 
1580afa8e06SEd Maste static void
1590afa8e06SEd Maste reopen(void)
1600afa8e06SEd Maste {
1610afa8e06SEd Maste 	const uint8_t	 cbor_info_data[] = { WIREDATA_CTAP_CBOR_INFO };
1620afa8e06SEd Maste 	uint8_t		*wiredata;
1630afa8e06SEd Maste 	fido_dev_t	*dev = NULL;
1640afa8e06SEd Maste 	fido_dev_io_t	 io;
1650afa8e06SEd Maste 
1660afa8e06SEd Maste 	memset(&io, 0, sizeof(io));
1670afa8e06SEd Maste 
1680afa8e06SEd Maste 	io.open = dummy_open;
1690afa8e06SEd Maste 	io.close = dummy_close;
1700afa8e06SEd Maste 	io.read = dummy_read;
1710afa8e06SEd Maste 	io.write = dummy_write;
1720afa8e06SEd Maste 
1730afa8e06SEd Maste 	wiredata = wiredata_setup(cbor_info_data, sizeof(cbor_info_data));
1740afa8e06SEd Maste 	assert((dev = fido_dev_new()) != NULL);
1750afa8e06SEd Maste 	assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK);
1760afa8e06SEd Maste 	assert(fido_dev_open(dev, "dummy") == FIDO_OK);
1770afa8e06SEd Maste 	assert(fido_dev_close(dev) == FIDO_OK);
1780afa8e06SEd Maste 	wiredata_clear(&wiredata);
1790afa8e06SEd Maste 
1800afa8e06SEd Maste 	wiredata = wiredata_setup(cbor_info_data, sizeof(cbor_info_data));
1810afa8e06SEd Maste 	assert(fido_dev_open(dev, "dummy") == FIDO_OK);
1820afa8e06SEd Maste 	assert(fido_dev_close(dev) == FIDO_OK);
183*f540a430SEd Maste 	fido_dev_free(&dev);
1840afa8e06SEd Maste 	wiredata_clear(&wiredata);
1850afa8e06SEd Maste }
1860afa8e06SEd Maste 
1870afa8e06SEd Maste static void
1880afa8e06SEd Maste double_open(void)
1890afa8e06SEd Maste {
1900afa8e06SEd Maste 	const uint8_t	 cbor_info_data[] = { WIREDATA_CTAP_CBOR_INFO };
1910afa8e06SEd Maste 	uint8_t		*wiredata;
1920afa8e06SEd Maste 	fido_dev_t	*dev = NULL;
1930afa8e06SEd Maste 	fido_dev_io_t	 io;
1940afa8e06SEd Maste 
1950afa8e06SEd Maste 	memset(&io, 0, sizeof(io));
1960afa8e06SEd Maste 
1970afa8e06SEd Maste 	io.open = dummy_open;
1980afa8e06SEd Maste 	io.close = dummy_close;
1990afa8e06SEd Maste 	io.read = dummy_read;
2000afa8e06SEd Maste 	io.write = dummy_write;
2010afa8e06SEd Maste 
2020afa8e06SEd Maste 	wiredata = wiredata_setup(cbor_info_data, sizeof(cbor_info_data));
2030afa8e06SEd Maste 	assert((dev = fido_dev_new()) != NULL);
2040afa8e06SEd Maste 	assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK);
2050afa8e06SEd Maste 	assert(fido_dev_open(dev, "dummy") == FIDO_OK);
2060afa8e06SEd Maste 	assert(fido_dev_open(dev, "dummy") == FIDO_ERR_INVALID_ARGUMENT);
2070afa8e06SEd Maste 	assert(fido_dev_close(dev) == FIDO_OK);
208*f540a430SEd Maste 	fido_dev_free(&dev);
209*f540a430SEd Maste 	wiredata_clear(&wiredata);
210*f540a430SEd Maste }
211*f540a430SEd Maste 
212*f540a430SEd Maste static void
213*f540a430SEd Maste double_close(void)
214*f540a430SEd Maste {
215*f540a430SEd Maste 	const uint8_t	 cbor_info_data[] = { WIREDATA_CTAP_CBOR_INFO };
216*f540a430SEd Maste 	uint8_t		*wiredata;
217*f540a430SEd Maste 	fido_dev_t	*dev = NULL;
218*f540a430SEd Maste 	fido_dev_io_t	 io;
219*f540a430SEd Maste 
220*f540a430SEd Maste 	memset(&io, 0, sizeof(io));
221*f540a430SEd Maste 
222*f540a430SEd Maste 	io.open = dummy_open;
223*f540a430SEd Maste 	io.close = dummy_close;
224*f540a430SEd Maste 	io.read = dummy_read;
225*f540a430SEd Maste 	io.write = dummy_write;
226*f540a430SEd Maste 
227*f540a430SEd Maste 	wiredata = wiredata_setup(cbor_info_data, sizeof(cbor_info_data));
228*f540a430SEd Maste 	assert((dev = fido_dev_new()) != NULL);
229*f540a430SEd Maste 	assert(fido_dev_close(dev) == FIDO_ERR_INVALID_ARGUMENT);
230*f540a430SEd Maste 	assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK);
231*f540a430SEd Maste 	assert(fido_dev_close(dev) == FIDO_ERR_INVALID_ARGUMENT);
232*f540a430SEd Maste 	assert(fido_dev_open(dev, "dummy") == FIDO_OK);
233*f540a430SEd Maste 	assert(fido_dev_close(dev) == FIDO_OK);
234*f540a430SEd Maste 	assert(fido_dev_close(dev) == FIDO_ERR_INVALID_ARGUMENT);
235*f540a430SEd Maste 	fido_dev_free(&dev);
2360afa8e06SEd Maste 	wiredata_clear(&wiredata);
2370afa8e06SEd Maste }
2380afa8e06SEd Maste 
2390afa8e06SEd Maste static void
2400afa8e06SEd Maste is_fido2(void)
2410afa8e06SEd Maste {
2420afa8e06SEd Maste 	const uint8_t	 cbor_info_data[] = { WIREDATA_CTAP_CBOR_INFO };
2430afa8e06SEd Maste 	uint8_t		*wiredata;
2440afa8e06SEd Maste 	fido_dev_t	*dev = NULL;
2450afa8e06SEd Maste 	fido_dev_io_t	 io;
2460afa8e06SEd Maste 
2470afa8e06SEd Maste 	memset(&io, 0, sizeof(io));
2480afa8e06SEd Maste 
2490afa8e06SEd Maste 	io.open = dummy_open;
2500afa8e06SEd Maste 	io.close = dummy_close;
2510afa8e06SEd Maste 	io.read = dummy_read;
2520afa8e06SEd Maste 	io.write = dummy_write;
2530afa8e06SEd Maste 
2540afa8e06SEd Maste 	wiredata = wiredata_setup(cbor_info_data, sizeof(cbor_info_data));
2550afa8e06SEd Maste 	assert((dev = fido_dev_new()) != NULL);
2560afa8e06SEd Maste 	assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK);
2570afa8e06SEd Maste 	assert(fido_dev_open(dev, "dummy") == FIDO_OK);
2580afa8e06SEd Maste 	assert(fido_dev_is_fido2(dev) == true);
2590afa8e06SEd Maste 	assert(fido_dev_supports_pin(dev) == true);
2600afa8e06SEd Maste 	fido_dev_force_u2f(dev);
2610afa8e06SEd Maste 	assert(fido_dev_is_fido2(dev) == false);
2620afa8e06SEd Maste 	assert(fido_dev_supports_pin(dev) == false);
2630afa8e06SEd Maste 	assert(fido_dev_close(dev) == FIDO_OK);
2640afa8e06SEd Maste 	wiredata_clear(&wiredata);
2650afa8e06SEd Maste 
2660afa8e06SEd Maste 	wiredata = wiredata_setup(NULL, 0);
2670afa8e06SEd Maste 	assert(fido_dev_open(dev, "dummy") == FIDO_OK);
2680afa8e06SEd Maste 	assert(fido_dev_is_fido2(dev) == false);
2690afa8e06SEd Maste 	assert(fido_dev_supports_pin(dev) == false);
2700afa8e06SEd Maste 	fido_dev_force_fido2(dev);
2710afa8e06SEd Maste 	assert(fido_dev_is_fido2(dev) == true);
2720afa8e06SEd Maste 	assert(fido_dev_supports_pin(dev) == false);
2730afa8e06SEd Maste 	assert(fido_dev_close(dev) == FIDO_OK);
274*f540a430SEd Maste 	fido_dev_free(&dev);
2750afa8e06SEd Maste 	wiredata_clear(&wiredata);
2760afa8e06SEd Maste }
2770afa8e06SEd Maste 
2780afa8e06SEd Maste static void
2790afa8e06SEd Maste has_pin(void)
2800afa8e06SEd Maste {
2810afa8e06SEd Maste 	const uint8_t	 set_pin_data[] = {
2820afa8e06SEd Maste 			    WIREDATA_CTAP_CBOR_INFO,
2830afa8e06SEd Maste 			    WIREDATA_CTAP_CBOR_AUTHKEY,
2840afa8e06SEd Maste 			    WIREDATA_CTAP_CBOR_STATUS,
2850afa8e06SEd Maste 			    WIREDATA_CTAP_CBOR_STATUS
2860afa8e06SEd Maste 			 };
2870afa8e06SEd Maste 	uint8_t		*wiredata;
2880afa8e06SEd Maste 	fido_dev_t	*dev = NULL;
2890afa8e06SEd Maste 	fido_dev_io_t	 io;
2900afa8e06SEd Maste 
2910afa8e06SEd Maste 	memset(&io, 0, sizeof(io));
2920afa8e06SEd Maste 
2930afa8e06SEd Maste 	io.open = dummy_open;
2940afa8e06SEd Maste 	io.close = dummy_close;
2950afa8e06SEd Maste 	io.read = dummy_read;
2960afa8e06SEd Maste 	io.write = dummy_write;
2970afa8e06SEd Maste 
2980afa8e06SEd Maste 	wiredata = wiredata_setup(set_pin_data, sizeof(set_pin_data));
2990afa8e06SEd Maste 	assert((dev = fido_dev_new()) != NULL);
3000afa8e06SEd Maste 	assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK);
3010afa8e06SEd Maste 	assert(fido_dev_open(dev, "dummy") == FIDO_OK);
3020afa8e06SEd Maste 	assert(fido_dev_has_pin(dev) == false);
3030afa8e06SEd Maste 	assert(fido_dev_set_pin(dev, "top secret", NULL) == FIDO_OK);
3040afa8e06SEd Maste 	assert(fido_dev_has_pin(dev) == true);
3050afa8e06SEd Maste 	assert(fido_dev_reset(dev) == FIDO_OK);
3060afa8e06SEd Maste 	assert(fido_dev_has_pin(dev) == false);
3070afa8e06SEd Maste 	assert(fido_dev_close(dev) == FIDO_OK);
308*f540a430SEd Maste 	fido_dev_free(&dev);
3090afa8e06SEd Maste 	wiredata_clear(&wiredata);
3100afa8e06SEd Maste }
3110afa8e06SEd Maste 
312*f540a430SEd Maste static void
313*f540a430SEd Maste timeout_rx(void)
314*f540a430SEd Maste {
315*f540a430SEd Maste 	const uint8_t	 timeout_rx_data[] = {
316*f540a430SEd Maste 			    WIREDATA_CTAP_CBOR_INFO,
317*f540a430SEd Maste 			    WIREDATA_CTAP_KEEPALIVE,
318*f540a430SEd Maste 			    WIREDATA_CTAP_KEEPALIVE,
319*f540a430SEd Maste 			    WIREDATA_CTAP_KEEPALIVE,
320*f540a430SEd Maste 			    WIREDATA_CTAP_KEEPALIVE,
321*f540a430SEd Maste 			    WIREDATA_CTAP_KEEPALIVE,
322*f540a430SEd Maste 			    WIREDATA_CTAP_CBOR_STATUS
323*f540a430SEd Maste 			 };
324*f540a430SEd Maste 	uint8_t		*wiredata;
325*f540a430SEd Maste 	fido_dev_t	*dev = NULL;
326*f540a430SEd Maste 	fido_dev_io_t	 io;
327*f540a430SEd Maste 
328*f540a430SEd Maste 	memset(&io, 0, sizeof(io));
329*f540a430SEd Maste 
330*f540a430SEd Maste 	io.open = dummy_open;
331*f540a430SEd Maste 	io.close = dummy_close;
332*f540a430SEd Maste 	io.read = dummy_read;
333*f540a430SEd Maste 	io.write = dummy_write;
334*f540a430SEd Maste 
335*f540a430SEd Maste 	wiredata = wiredata_setup(timeout_rx_data, sizeof(timeout_rx_data));
336*f540a430SEd Maste 	assert((dev = fido_dev_new()) != NULL);
337*f540a430SEd Maste 	assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK);
338*f540a430SEd Maste 	assert(fido_dev_open(dev, "dummy") == FIDO_OK);
339*f540a430SEd Maste 	assert(fido_dev_set_timeout(dev, 3 * 1000) == FIDO_OK);
340*f540a430SEd Maste 	interval_ms = 1000;
341*f540a430SEd Maste 	assert(fido_dev_reset(dev) == FIDO_ERR_RX);
342*f540a430SEd Maste 	assert(fido_dev_close(dev) == FIDO_OK);
343*f540a430SEd Maste 	fido_dev_free(&dev);
344*f540a430SEd Maste 	wiredata_clear(&wiredata);
345*f540a430SEd Maste 	interval_ms = 0;
346*f540a430SEd Maste }
347*f540a430SEd Maste 
348*f540a430SEd Maste static void
349*f540a430SEd Maste timeout_ok(void)
350*f540a430SEd Maste {
351*f540a430SEd Maste 	const uint8_t	 timeout_ok_data[] = {
352*f540a430SEd Maste 			    WIREDATA_CTAP_CBOR_INFO,
353*f540a430SEd Maste 			    WIREDATA_CTAP_KEEPALIVE,
354*f540a430SEd Maste 			    WIREDATA_CTAP_KEEPALIVE,
355*f540a430SEd Maste 			    WIREDATA_CTAP_KEEPALIVE,
356*f540a430SEd Maste 			    WIREDATA_CTAP_KEEPALIVE,
357*f540a430SEd Maste 			    WIREDATA_CTAP_KEEPALIVE,
358*f540a430SEd Maste 			    WIREDATA_CTAP_CBOR_STATUS
359*f540a430SEd Maste 			 };
360*f540a430SEd Maste 	uint8_t		*wiredata;
361*f540a430SEd Maste 	fido_dev_t	*dev = NULL;
362*f540a430SEd Maste 	fido_dev_io_t	 io;
363*f540a430SEd Maste 
364*f540a430SEd Maste 	memset(&io, 0, sizeof(io));
365*f540a430SEd Maste 
366*f540a430SEd Maste 	io.open = dummy_open;
367*f540a430SEd Maste 	io.close = dummy_close;
368*f540a430SEd Maste 	io.read = dummy_read;
369*f540a430SEd Maste 	io.write = dummy_write;
370*f540a430SEd Maste 
371*f540a430SEd Maste 	wiredata = wiredata_setup(timeout_ok_data, sizeof(timeout_ok_data));
372*f540a430SEd Maste 	assert((dev = fido_dev_new()) != NULL);
373*f540a430SEd Maste 	assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK);
374*f540a430SEd Maste 	assert(fido_dev_open(dev, "dummy") == FIDO_OK);
375*f540a430SEd Maste 	assert(fido_dev_set_timeout(dev, 30 * 1000) == FIDO_OK);
376*f540a430SEd Maste 	interval_ms = 1000;
377*f540a430SEd Maste 	assert(fido_dev_reset(dev) == FIDO_OK);
378*f540a430SEd Maste 	assert(fido_dev_close(dev) == FIDO_OK);
379*f540a430SEd Maste 	fido_dev_free(&dev);
380*f540a430SEd Maste 	wiredata_clear(&wiredata);
381*f540a430SEd Maste 	interval_ms = 0;
382*f540a430SEd Maste }
383*f540a430SEd Maste 
384*f540a430SEd Maste static void
385*f540a430SEd Maste timeout_misc(void)
386*f540a430SEd Maste {
387*f540a430SEd Maste 	fido_dev_t *dev;
388*f540a430SEd Maste 
389*f540a430SEd Maste 	assert((dev = fido_dev_new()) != NULL);
390*f540a430SEd Maste 	assert(fido_dev_set_timeout(dev, -2) == FIDO_ERR_INVALID_ARGUMENT);
391*f540a430SEd Maste 	assert(fido_dev_set_timeout(dev, 3 * 1000) == FIDO_OK);
392*f540a430SEd Maste 	assert(fido_dev_set_timeout(dev, -1) == FIDO_OK);
393*f540a430SEd Maste 	fido_dev_free(&dev);
394*f540a430SEd Maste }
395*f540a430SEd Maste 
3960afa8e06SEd Maste int
3970afa8e06SEd Maste main(void)
3980afa8e06SEd Maste {
3990afa8e06SEd Maste 	fido_init(0);
4000afa8e06SEd Maste 
4010afa8e06SEd Maste 	open_iff_ok();
4020afa8e06SEd Maste 	reopen();
4030afa8e06SEd Maste 	double_open();
404*f540a430SEd Maste 	double_close();
4050afa8e06SEd Maste 	is_fido2();
4060afa8e06SEd Maste 	has_pin();
407*f540a430SEd Maste 	timeout_rx();
408*f540a430SEd Maste 	timeout_ok();
409*f540a430SEd Maste 	timeout_misc();
4100afa8e06SEd Maste 
4110afa8e06SEd Maste 	exit(0);
4120afa8e06SEd Maste }
413