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