1 /* 2 * Copyright (c) 2019 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 <fido.h> 8 #include <fido/credman.h> 9 10 #include <stdbool.h> 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <string.h> 14 #ifdef HAVE_UNISTD_H 15 #include <unistd.h> 16 #endif 17 18 #include "../openbsd-compat/openbsd-compat.h" 19 #include "extern.h" 20 21 int 22 credman_get_metadata(fido_dev_t *dev, const char *path) 23 { 24 fido_credman_metadata_t *metadata = NULL; 25 char pin[1024]; 26 int r; 27 28 if ((metadata = fido_credman_metadata_new()) == NULL) 29 errx(1, "fido_credman_metadata_new"); 30 31 read_pin(path, pin, sizeof(pin)); 32 r = fido_credman_get_dev_metadata(dev, metadata, pin); 33 explicit_bzero(pin, sizeof(pin)); 34 35 if (r != FIDO_OK) 36 errx(1, "fido_credman_get_dev_metadata: %s", fido_strerr(r)); 37 38 printf("existing rk(s): %u\n", 39 (unsigned)fido_credman_rk_existing(metadata)); 40 printf("remaining rk(s): %u\n", 41 (unsigned)fido_credman_rk_remaining(metadata)); 42 43 fido_credman_metadata_free(&metadata); 44 fido_dev_close(dev); 45 fido_dev_free(&dev); 46 47 exit(0); 48 } 49 50 static void 51 print_rp(fido_credman_rp_t *rp, size_t idx) 52 { 53 char *rp_id_hash = NULL; 54 55 if (base64_encode(fido_credman_rp_id_hash_ptr(rp, idx), 56 fido_credman_rp_id_hash_len(rp, idx), &rp_id_hash) < 0) 57 errx(1, "output error"); 58 59 printf("%02u: %s %s\n", (unsigned)idx, rp_id_hash, 60 fido_credman_rp_id(rp, idx)); 61 62 free(rp_id_hash); 63 rp_id_hash = NULL; 64 } 65 66 int 67 credman_list_rp(char *path) 68 { 69 fido_dev_t *dev = NULL; 70 fido_credman_rp_t *rp = NULL; 71 char pin[1024]; 72 int r; 73 74 if (path == NULL) 75 usage(); 76 if ((rp = fido_credman_rp_new()) == NULL) 77 errx(1, "fido_credman_rp_new"); 78 79 dev = open_dev(path); 80 read_pin(path, pin, sizeof(pin)); 81 r = fido_credman_get_dev_rp(dev, rp, pin); 82 explicit_bzero(pin, sizeof(pin)); 83 84 if (r != FIDO_OK) 85 errx(1, "fido_credman_get_dev_rp: %s", fido_strerr(r)); 86 87 for (size_t i = 0; i < fido_credman_rp_count(rp); i++) 88 print_rp(rp, i); 89 90 fido_credman_rp_free(&rp); 91 fido_dev_close(dev); 92 fido_dev_free(&dev); 93 94 exit(0); 95 } 96 97 static void 98 print_rk(const fido_credman_rk_t *rk, size_t idx) 99 { 100 const fido_cred_t *cred; 101 char *id = NULL; 102 char *user_id = NULL; 103 const char *type; 104 const char *prot; 105 106 if ((cred = fido_credman_rk(rk, idx)) == NULL) 107 errx(1, "fido_credman_rk"); 108 if (base64_encode(fido_cred_id_ptr(cred), fido_cred_id_len(cred), 109 &id) < 0 || base64_encode(fido_cred_user_id_ptr(cred), 110 fido_cred_user_id_len(cred), &user_id) < 0) 111 errx(1, "output error"); 112 113 type = cose_string(fido_cred_type(cred)); 114 prot = prot_string(fido_cred_prot(cred)); 115 116 printf("%02u: %s %s %s %s %s\n", (unsigned)idx, id, 117 fido_cred_display_name(cred), user_id, type, prot); 118 119 free(user_id); 120 free(id); 121 user_id = NULL; 122 id = NULL; 123 } 124 125 int 126 credman_list_rk(char *path, const char *rp_id) 127 { 128 fido_dev_t *dev = NULL; 129 fido_credman_rk_t *rk = NULL; 130 char pin[1024]; 131 int r; 132 133 if (path == NULL) 134 usage(); 135 if ((rk = fido_credman_rk_new()) == NULL) 136 errx(1, "fido_credman_rk_new"); 137 138 dev = open_dev(path); 139 read_pin(path, pin, sizeof(pin)); 140 r = fido_credman_get_dev_rk(dev, rp_id, rk, pin); 141 explicit_bzero(pin, sizeof(pin)); 142 143 if (r != FIDO_OK) 144 errx(1, "fido_credman_get_dev_rk: %s", fido_strerr(r)); 145 for (size_t i = 0; i < fido_credman_rk_count(rk); i++) 146 print_rk(rk, i); 147 148 fido_credman_rk_free(&rk); 149 fido_dev_close(dev); 150 fido_dev_free(&dev); 151 152 exit(0); 153 } 154 155 int 156 credman_print_rk(fido_dev_t *dev, const char *path, char *rp_id, char *cred_id) 157 { 158 const fido_cred_t *cred = NULL; 159 fido_credman_rk_t *rk = NULL; 160 char pin[1024]; 161 void *cred_id_ptr = NULL; 162 size_t cred_id_len = 0; 163 int r; 164 165 if ((rk = fido_credman_rk_new()) == NULL) 166 errx(1, "fido_credman_rk_new"); 167 if (base64_decode(cred_id, &cred_id_ptr, &cred_id_len) < 0) 168 errx(1, "base64_decode"); 169 170 read_pin(path, pin, sizeof(pin)); 171 r = fido_credman_get_dev_rk(dev, rp_id, rk, pin); 172 explicit_bzero(pin, sizeof(pin)); 173 174 if (r != FIDO_OK) 175 errx(1, "fido_credman_get_dev_rk: %s", fido_strerr(r)); 176 177 for (size_t i = 0; i < fido_credman_rk_count(rk); i++) { 178 if ((cred = fido_credman_rk(rk, i)) == NULL || 179 fido_cred_id_ptr(cred) == NULL) 180 errx(1, "output error"); 181 if (cred_id_len != fido_cred_id_len(cred) || 182 memcmp(cred_id_ptr, fido_cred_id_ptr(cred), cred_id_len)) 183 continue; 184 print_cred(stdout, fido_cred_type(cred), cred); 185 goto out; 186 } 187 188 errx(1, "credential not found"); 189 190 out: 191 free(cred_id_ptr); 192 cred_id_ptr = NULL; 193 194 fido_credman_rk_free(&rk); 195 fido_dev_close(dev); 196 fido_dev_free(&dev); 197 198 exit(0); 199 } 200 201 int 202 credman_delete_rk(fido_dev_t *dev, const char *path, char *id) 203 { 204 char pin[1024]; 205 void *id_ptr = NULL; 206 size_t id_len = 0; 207 int r; 208 209 if (base64_decode(id, &id_ptr, &id_len) < 0) 210 errx(1, "base64_decode"); 211 212 read_pin(path, pin, sizeof(pin)); 213 r = fido_credman_del_dev_rk(dev, id_ptr, id_len, pin); 214 explicit_bzero(pin, sizeof(pin)); 215 216 if (r != FIDO_OK) 217 errx(1, "fido_credman_del_dev_rk: %s", fido_strerr(r)); 218 219 free(id_ptr); 220 id_ptr = NULL; 221 222 fido_dev_close(dev); 223 fido_dev_free(&dev); 224 225 exit(0); 226 } 227