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