xref: /freebsd/contrib/libfido2/src/touch.c (revision 2ccfa855b2fc331819953e3de1b1c15ce5b95a7e)
1*2ccfa855SEd Maste /*
2*2ccfa855SEd Maste  * Copyright (c) 2018-2022 Yubico AB. All rights reserved.
3*2ccfa855SEd Maste  * Use of this source code is governed by a BSD-style
4*2ccfa855SEd Maste  * license that can be found in the LICENSE file.
5*2ccfa855SEd Maste  * SPDX-License-Identifier: BSD-2-Clause
6*2ccfa855SEd Maste  */
7*2ccfa855SEd Maste 
8*2ccfa855SEd Maste #include <openssl/sha.h>
9*2ccfa855SEd Maste #include "fido.h"
10*2ccfa855SEd Maste 
11*2ccfa855SEd Maste int
fido_dev_get_touch_begin(fido_dev_t * dev)12*2ccfa855SEd Maste fido_dev_get_touch_begin(fido_dev_t *dev)
13*2ccfa855SEd Maste {
14*2ccfa855SEd Maste 	fido_blob_t	 f;
15*2ccfa855SEd Maste 	cbor_item_t	*argv[9];
16*2ccfa855SEd Maste 	const char	*clientdata = FIDO_DUMMY_CLIENTDATA;
17*2ccfa855SEd Maste 	const uint8_t	 user_id = FIDO_DUMMY_USER_ID;
18*2ccfa855SEd Maste 	unsigned char	 cdh[SHA256_DIGEST_LENGTH];
19*2ccfa855SEd Maste 	fido_rp_t	 rp;
20*2ccfa855SEd Maste 	fido_user_t	 user;
21*2ccfa855SEd Maste 	int		 ms = dev->timeout_ms;
22*2ccfa855SEd Maste 	int		 r = FIDO_ERR_INTERNAL;
23*2ccfa855SEd Maste 
24*2ccfa855SEd Maste 	memset(&f, 0, sizeof(f));
25*2ccfa855SEd Maste 	memset(argv, 0, sizeof(argv));
26*2ccfa855SEd Maste 	memset(cdh, 0, sizeof(cdh));
27*2ccfa855SEd Maste 	memset(&rp, 0, sizeof(rp));
28*2ccfa855SEd Maste 	memset(&user, 0, sizeof(user));
29*2ccfa855SEd Maste 
30*2ccfa855SEd Maste 	if (fido_dev_is_fido2(dev) == false)
31*2ccfa855SEd Maste 		return (u2f_get_touch_begin(dev, &ms));
32*2ccfa855SEd Maste 
33*2ccfa855SEd Maste 	if (SHA256((const void *)clientdata, strlen(clientdata), cdh) != cdh) {
34*2ccfa855SEd Maste 		fido_log_debug("%s: sha256", __func__);
35*2ccfa855SEd Maste 		return (FIDO_ERR_INTERNAL);
36*2ccfa855SEd Maste 	}
37*2ccfa855SEd Maste 
38*2ccfa855SEd Maste 	if ((rp.id = strdup(FIDO_DUMMY_RP_ID)) == NULL ||
39*2ccfa855SEd Maste 	    (user.name = strdup(FIDO_DUMMY_USER_NAME)) == NULL) {
40*2ccfa855SEd Maste 		fido_log_debug("%s: strdup", __func__);
41*2ccfa855SEd Maste 		goto fail;
42*2ccfa855SEd Maste 	}
43*2ccfa855SEd Maste 
44*2ccfa855SEd Maste 	if (fido_blob_set(&user.id, &user_id, sizeof(user_id)) < 0) {
45*2ccfa855SEd Maste 		fido_log_debug("%s: fido_blob_set", __func__);
46*2ccfa855SEd Maste 		goto fail;
47*2ccfa855SEd Maste 	}
48*2ccfa855SEd Maste 
49*2ccfa855SEd Maste 	if ((argv[0] = cbor_build_bytestring(cdh, sizeof(cdh))) == NULL ||
50*2ccfa855SEd Maste 	    (argv[1] = cbor_encode_rp_entity(&rp)) == NULL ||
51*2ccfa855SEd Maste 	    (argv[2] = cbor_encode_user_entity(&user)) == NULL ||
52*2ccfa855SEd Maste 	    (argv[3] = cbor_encode_pubkey_param(COSE_ES256)) == NULL) {
53*2ccfa855SEd Maste 		fido_log_debug("%s: cbor encode", __func__);
54*2ccfa855SEd Maste 		goto fail;
55*2ccfa855SEd Maste 	}
56*2ccfa855SEd Maste 
57*2ccfa855SEd Maste 	if (fido_dev_supports_pin(dev)) {
58*2ccfa855SEd Maste 		if ((argv[7] = cbor_new_definite_bytestring()) == NULL ||
59*2ccfa855SEd Maste 		    (argv[8] = cbor_encode_pin_opt(dev)) == NULL) {
60*2ccfa855SEd Maste 			fido_log_debug("%s: cbor encode", __func__);
61*2ccfa855SEd Maste 			goto fail;
62*2ccfa855SEd Maste 		}
63*2ccfa855SEd Maste 	}
64*2ccfa855SEd Maste 
65*2ccfa855SEd Maste 	if (cbor_build_frame(CTAP_CBOR_MAKECRED, argv, nitems(argv), &f) < 0 ||
66*2ccfa855SEd Maste 	    fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, &ms) < 0) {
67*2ccfa855SEd Maste 		fido_log_debug("%s: fido_tx", __func__);
68*2ccfa855SEd Maste 		r = FIDO_ERR_TX;
69*2ccfa855SEd Maste 		goto fail;
70*2ccfa855SEd Maste 	}
71*2ccfa855SEd Maste 
72*2ccfa855SEd Maste 	r = FIDO_OK;
73*2ccfa855SEd Maste fail:
74*2ccfa855SEd Maste 	cbor_vector_free(argv, nitems(argv));
75*2ccfa855SEd Maste 	free(f.ptr);
76*2ccfa855SEd Maste 	free(rp.id);
77*2ccfa855SEd Maste 	free(user.name);
78*2ccfa855SEd Maste 	free(user.id.ptr);
79*2ccfa855SEd Maste 
80*2ccfa855SEd Maste 	return (r);
81*2ccfa855SEd Maste }
82*2ccfa855SEd Maste 
83*2ccfa855SEd Maste int
fido_dev_get_touch_status(fido_dev_t * dev,int * touched,int ms)84*2ccfa855SEd Maste fido_dev_get_touch_status(fido_dev_t *dev, int *touched, int ms)
85*2ccfa855SEd Maste {
86*2ccfa855SEd Maste 	int r;
87*2ccfa855SEd Maste 
88*2ccfa855SEd Maste 	*touched = 0;
89*2ccfa855SEd Maste 
90*2ccfa855SEd Maste 	if (fido_dev_is_fido2(dev) == false)
91*2ccfa855SEd Maste 		return (u2f_get_touch_status(dev, touched, &ms));
92*2ccfa855SEd Maste 
93*2ccfa855SEd Maste 	switch ((r = fido_rx_cbor_status(dev, &ms))) {
94*2ccfa855SEd Maste 	case FIDO_ERR_PIN_AUTH_INVALID:
95*2ccfa855SEd Maste 	case FIDO_ERR_PIN_INVALID:
96*2ccfa855SEd Maste 	case FIDO_ERR_PIN_NOT_SET:
97*2ccfa855SEd Maste 	case FIDO_ERR_SUCCESS:
98*2ccfa855SEd Maste 		*touched = 1;
99*2ccfa855SEd Maste 		break;
100*2ccfa855SEd Maste 	case FIDO_ERR_RX:
101*2ccfa855SEd Maste 		/* ignore */
102*2ccfa855SEd Maste 		break;
103*2ccfa855SEd Maste 	default:
104*2ccfa855SEd Maste 		fido_log_debug("%s: fido_rx_cbor_status", __func__);
105*2ccfa855SEd Maste 		return (r);
106*2ccfa855SEd Maste 	}
107*2ccfa855SEd Maste 
108*2ccfa855SEd Maste 	return (FIDO_OK);
109*2ccfa855SEd Maste }
110