xref: /freebsd/contrib/libfido2/tools/pin.c (revision 2ccfa855b2fc331819953e3de1b1c15ce5b95a7e)
10afa8e06SEd Maste /*
20afa8e06SEd Maste  * Copyright (c) 2018 Yubico AB. All rights reserved.
30afa8e06SEd Maste  * Use of this source code is governed by a BSD-style
40afa8e06SEd Maste  * license that can be found in the LICENSE file.
5*2ccfa855SEd Maste  * SPDX-License-Identifier: BSD-2-Clause
60afa8e06SEd Maste  */
70afa8e06SEd Maste 
80afa8e06SEd Maste #include <fido.h>
90afa8e06SEd Maste #include <stdbool.h>
100afa8e06SEd Maste #include <stdio.h>
110afa8e06SEd Maste #include <stdlib.h>
120afa8e06SEd Maste #include <string.h>
130afa8e06SEd Maste #ifdef HAVE_UNISTD_H
140afa8e06SEd Maste #include <unistd.h>
150afa8e06SEd Maste #endif
160afa8e06SEd Maste 
170afa8e06SEd Maste #include "../openbsd-compat/openbsd-compat.h"
180afa8e06SEd Maste #include "extern.h"
190afa8e06SEd Maste 
200afa8e06SEd Maste int
pin_set(char * path)210afa8e06SEd Maste pin_set(char *path)
220afa8e06SEd Maste {
230afa8e06SEd Maste 	fido_dev_t *dev = NULL;
240afa8e06SEd Maste 	char prompt[1024];
25*2ccfa855SEd Maste 	char pin1[128];
26*2ccfa855SEd Maste 	char pin2[128];
270afa8e06SEd Maste 	int r;
280afa8e06SEd Maste 	int status = 1;
290afa8e06SEd Maste 
300afa8e06SEd Maste 	dev = open_dev(path);
310afa8e06SEd Maste 
320afa8e06SEd Maste 	r = snprintf(prompt, sizeof(prompt), "Enter new PIN for %s: ", path);
330afa8e06SEd Maste 	if (r < 0 || (size_t)r >= sizeof(prompt)) {
340afa8e06SEd Maste 		warnx("snprintf");
350afa8e06SEd Maste 		goto out;
360afa8e06SEd Maste 	}
370afa8e06SEd Maste 
380afa8e06SEd Maste 	if (!readpassphrase(prompt, pin1, sizeof(pin1), RPP_ECHO_OFF)) {
390afa8e06SEd Maste 		warnx("readpassphrase");
400afa8e06SEd Maste 		goto out;
410afa8e06SEd Maste 	}
420afa8e06SEd Maste 
430afa8e06SEd Maste 	r = snprintf(prompt, sizeof(prompt), "Enter the same PIN again: ");
440afa8e06SEd Maste 	if (r < 0 || (size_t)r >= sizeof(prompt)) {
450afa8e06SEd Maste 		warnx("snprintf");
460afa8e06SEd Maste 		goto out;
470afa8e06SEd Maste 	}
480afa8e06SEd Maste 
490afa8e06SEd Maste 	if (!readpassphrase(prompt, pin2, sizeof(pin2), RPP_ECHO_OFF)) {
500afa8e06SEd Maste 		warnx("readpassphrase");
510afa8e06SEd Maste 		goto out;
520afa8e06SEd Maste 	}
530afa8e06SEd Maste 
540afa8e06SEd Maste 	if (strcmp(pin1, pin2) != 0) {
550afa8e06SEd Maste 		fprintf(stderr, "PINs do not match. Try again.\n");
560afa8e06SEd Maste 		goto out;
570afa8e06SEd Maste 	}
580afa8e06SEd Maste 
59*2ccfa855SEd Maste 	if (strlen(pin1) < 4 || strlen(pin1) > 63) {
60*2ccfa855SEd Maste 		fprintf(stderr, "invalid PIN length\n");
61*2ccfa855SEd Maste 		goto out;
62*2ccfa855SEd Maste 	}
63*2ccfa855SEd Maste 
640afa8e06SEd Maste 	if ((r = fido_dev_set_pin(dev, pin1, NULL)) != FIDO_OK) {
650afa8e06SEd Maste 		warnx("fido_dev_set_pin: %s", fido_strerr(r));
660afa8e06SEd Maste 		goto out;
670afa8e06SEd Maste 	}
680afa8e06SEd Maste 
690afa8e06SEd Maste 	fido_dev_close(dev);
700afa8e06SEd Maste 	fido_dev_free(&dev);
710afa8e06SEd Maste 
720afa8e06SEd Maste 	status = 0;
730afa8e06SEd Maste out:
740afa8e06SEd Maste 	explicit_bzero(pin1, sizeof(pin1));
750afa8e06SEd Maste 	explicit_bzero(pin2, sizeof(pin2));
760afa8e06SEd Maste 
770afa8e06SEd Maste 	exit(status);
780afa8e06SEd Maste }
790afa8e06SEd Maste 
800afa8e06SEd Maste int
pin_change(char * path)810afa8e06SEd Maste pin_change(char *path)
820afa8e06SEd Maste {
830afa8e06SEd Maste 	fido_dev_t *dev = NULL;
840afa8e06SEd Maste 	char prompt[1024];
85*2ccfa855SEd Maste 	char pin0[128];
86*2ccfa855SEd Maste 	char pin1[128];
87*2ccfa855SEd Maste 	char pin2[128];
880afa8e06SEd Maste 	int r;
890afa8e06SEd Maste 	int status = 1;
900afa8e06SEd Maste 
910afa8e06SEd Maste 	if (path == NULL)
920afa8e06SEd Maste 		usage();
930afa8e06SEd Maste 
940afa8e06SEd Maste 	dev = open_dev(path);
950afa8e06SEd Maste 
960afa8e06SEd Maste 	r = snprintf(prompt, sizeof(prompt), "Enter current PIN for %s: ", path);
970afa8e06SEd Maste 	if (r < 0 || (size_t)r >= sizeof(prompt)) {
980afa8e06SEd Maste 		warnx("snprintf");
990afa8e06SEd Maste 		goto out;
1000afa8e06SEd Maste 	}
1010afa8e06SEd Maste 
1020afa8e06SEd Maste 	if (!readpassphrase(prompt, pin0, sizeof(pin0), RPP_ECHO_OFF)) {
1030afa8e06SEd Maste 		warnx("readpassphrase");
1040afa8e06SEd Maste 		goto out;
1050afa8e06SEd Maste 	}
1060afa8e06SEd Maste 
107*2ccfa855SEd Maste 	if (strlen(pin0) < 4 || strlen(pin0) > 63) {
108*2ccfa855SEd Maste 		warnx("invalid PIN length");
109*2ccfa855SEd Maste 		goto out;
110*2ccfa855SEd Maste 	}
111*2ccfa855SEd Maste 
1120afa8e06SEd Maste 	r = snprintf(prompt, sizeof(prompt), "Enter new PIN for %s: ", path);
1130afa8e06SEd Maste 	if (r < 0 || (size_t)r >= sizeof(prompt)) {
1140afa8e06SEd Maste 		warnx("snprintf");
1150afa8e06SEd Maste 		goto out;
1160afa8e06SEd Maste 	}
1170afa8e06SEd Maste 
1180afa8e06SEd Maste 	if (!readpassphrase(prompt, pin1, sizeof(pin1), RPP_ECHO_OFF)) {
1190afa8e06SEd Maste 		warnx("readpassphrase");
1200afa8e06SEd Maste 		goto out;
1210afa8e06SEd Maste 	}
1220afa8e06SEd Maste 
1230afa8e06SEd Maste 	r = snprintf(prompt, sizeof(prompt), "Enter the same PIN again: ");
1240afa8e06SEd Maste 	if (r < 0 || (size_t)r >= sizeof(prompt)) {
1250afa8e06SEd Maste 		warnx("snprintf");
1260afa8e06SEd Maste 		goto out;
1270afa8e06SEd Maste 	}
1280afa8e06SEd Maste 
1290afa8e06SEd Maste 	if (!readpassphrase(prompt, pin2, sizeof(pin2), RPP_ECHO_OFF)) {
1300afa8e06SEd Maste 		warnx("readpassphrase");
1310afa8e06SEd Maste 		goto out;
1320afa8e06SEd Maste 	}
1330afa8e06SEd Maste 
1340afa8e06SEd Maste 	if (strcmp(pin1, pin2) != 0) {
1350afa8e06SEd Maste 		fprintf(stderr, "PINs do not match. Try again.\n");
1360afa8e06SEd Maste 		goto out;
1370afa8e06SEd Maste 	}
1380afa8e06SEd Maste 
139*2ccfa855SEd Maste 	if (strlen(pin1) < 4 || strlen(pin1) > 63) {
140*2ccfa855SEd Maste 		fprintf(stderr, "invalid PIN length\n");
141*2ccfa855SEd Maste 		goto out;
142*2ccfa855SEd Maste 	}
143*2ccfa855SEd Maste 
1440afa8e06SEd Maste 	if ((r = fido_dev_set_pin(dev, pin1, pin0)) != FIDO_OK) {
1450afa8e06SEd Maste 		warnx("fido_dev_set_pin: %s", fido_strerr(r));
1460afa8e06SEd Maste 		goto out;
1470afa8e06SEd Maste 	}
1480afa8e06SEd Maste 
1490afa8e06SEd Maste 	fido_dev_close(dev);
1500afa8e06SEd Maste 	fido_dev_free(&dev);
1510afa8e06SEd Maste 
1520afa8e06SEd Maste 	status = 0;
1530afa8e06SEd Maste out:
1540afa8e06SEd Maste 	explicit_bzero(pin0, sizeof(pin0));
1550afa8e06SEd Maste 	explicit_bzero(pin1, sizeof(pin1));
1560afa8e06SEd Maste 	explicit_bzero(pin2, sizeof(pin2));
1570afa8e06SEd Maste 
1580afa8e06SEd Maste 	exit(status);
1590afa8e06SEd Maste }
160