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