1 /* 2 * Copyright (c) 2018 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 <stdbool.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #ifdef HAVE_UNISTD_H 13 #include <unistd.h> 14 #endif 15 16 #include "../openbsd-compat/openbsd-compat.h" 17 #include "extern.h" 18 19 int 20 pin_set(char *path) 21 { 22 fido_dev_t *dev = NULL; 23 char prompt[1024]; 24 char pin1[1024]; 25 char pin2[1024]; 26 int r; 27 int status = 1; 28 29 dev = open_dev(path); 30 31 r = snprintf(prompt, sizeof(prompt), "Enter new PIN for %s: ", path); 32 if (r < 0 || (size_t)r >= sizeof(prompt)) { 33 warnx("snprintf"); 34 goto out; 35 } 36 37 if (!readpassphrase(prompt, pin1, sizeof(pin1), RPP_ECHO_OFF)) { 38 warnx("readpassphrase"); 39 goto out; 40 } 41 42 r = snprintf(prompt, sizeof(prompt), "Enter the same PIN again: "); 43 if (r < 0 || (size_t)r >= sizeof(prompt)) { 44 warnx("snprintf"); 45 goto out; 46 } 47 48 if (!readpassphrase(prompt, pin2, sizeof(pin2), RPP_ECHO_OFF)) { 49 warnx("readpassphrase"); 50 goto out; 51 } 52 53 if (strcmp(pin1, pin2) != 0) { 54 fprintf(stderr, "PINs do not match. Try again.\n"); 55 goto out; 56 } 57 58 if ((r = fido_dev_set_pin(dev, pin1, NULL)) != FIDO_OK) { 59 warnx("fido_dev_set_pin: %s", fido_strerr(r)); 60 goto out; 61 } 62 63 fido_dev_close(dev); 64 fido_dev_free(&dev); 65 66 status = 0; 67 out: 68 explicit_bzero(pin1, sizeof(pin1)); 69 explicit_bzero(pin2, sizeof(pin2)); 70 71 exit(status); 72 } 73 74 int 75 pin_change(char *path) 76 { 77 fido_dev_t *dev = NULL; 78 char prompt[1024]; 79 char pin0[1024]; 80 char pin1[1024]; 81 char pin2[1024]; 82 int r; 83 int status = 1; 84 85 if (path == NULL) 86 usage(); 87 88 dev = open_dev(path); 89 90 r = snprintf(prompt, sizeof(prompt), "Enter current PIN for %s: ", path); 91 if (r < 0 || (size_t)r >= sizeof(prompt)) { 92 warnx("snprintf"); 93 goto out; 94 } 95 96 if (!readpassphrase(prompt, pin0, sizeof(pin0), RPP_ECHO_OFF)) { 97 warnx("readpassphrase"); 98 goto out; 99 } 100 101 r = snprintf(prompt, sizeof(prompt), "Enter new PIN for %s: ", path); 102 if (r < 0 || (size_t)r >= sizeof(prompt)) { 103 warnx("snprintf"); 104 goto out; 105 } 106 107 if (!readpassphrase(prompt, pin1, sizeof(pin1), RPP_ECHO_OFF)) { 108 warnx("readpassphrase"); 109 goto out; 110 } 111 112 r = snprintf(prompt, sizeof(prompt), "Enter the same PIN again: "); 113 if (r < 0 || (size_t)r >= sizeof(prompt)) { 114 warnx("snprintf"); 115 goto out; 116 } 117 118 if (!readpassphrase(prompt, pin2, sizeof(pin2), RPP_ECHO_OFF)) { 119 warnx("readpassphrase"); 120 goto out; 121 } 122 123 if (strcmp(pin1, pin2) != 0) { 124 fprintf(stderr, "PINs do not match. Try again.\n"); 125 goto out; 126 } 127 128 if ((r = fido_dev_set_pin(dev, pin1, pin0)) != FIDO_OK) { 129 warnx("fido_dev_set_pin: %s", fido_strerr(r)); 130 goto out; 131 } 132 133 fido_dev_close(dev); 134 fido_dev_free(&dev); 135 136 status = 0; 137 out: 138 explicit_bzero(pin0, sizeof(pin0)); 139 explicit_bzero(pin1, sizeof(pin1)); 140 explicit_bzero(pin2, sizeof(pin2)); 141 142 exit(status); 143 } 144