1ba9bdd8bSchristos /*
2ba9bdd8bSchristos * Copyright (c) 2018 Yubico AB. All rights reserved.
3ba9bdd8bSchristos * Use of this source code is governed by a BSD-style
4ba9bdd8bSchristos * license that can be found in the LICENSE file.
5*2d40c451Schristos * SPDX-License-Identifier: BSD-2-Clause
6ba9bdd8bSchristos */
7ba9bdd8bSchristos
8ba9bdd8bSchristos #include <fido.h>
9ba9bdd8bSchristos #include <stdbool.h>
10ba9bdd8bSchristos #include <stdio.h>
11ba9bdd8bSchristos #include <stdlib.h>
12ba9bdd8bSchristos #include <string.h>
13ba9bdd8bSchristos #ifdef HAVE_UNISTD_H
14ba9bdd8bSchristos #include <unistd.h>
15ba9bdd8bSchristos #endif
16ba9bdd8bSchristos
17ba9bdd8bSchristos #include "../openbsd-compat/openbsd-compat.h"
18ba9bdd8bSchristos #include "extern.h"
19ba9bdd8bSchristos
20ba9bdd8bSchristos int
pin_set(char * path)21ba9bdd8bSchristos pin_set(char *path)
22ba9bdd8bSchristos {
23ba9bdd8bSchristos fido_dev_t *dev = NULL;
24ba9bdd8bSchristos char prompt[1024];
25*2d40c451Schristos char pin1[128];
26*2d40c451Schristos char pin2[128];
27ba9bdd8bSchristos int r;
28ba9bdd8bSchristos int status = 1;
29ba9bdd8bSchristos
30ba9bdd8bSchristos dev = open_dev(path);
31ba9bdd8bSchristos
32ba9bdd8bSchristos r = snprintf(prompt, sizeof(prompt), "Enter new PIN for %s: ", path);
33ba9bdd8bSchristos if (r < 0 || (size_t)r >= sizeof(prompt)) {
34ba9bdd8bSchristos warnx("snprintf");
35ba9bdd8bSchristos goto out;
36ba9bdd8bSchristos }
37ba9bdd8bSchristos
38ba9bdd8bSchristos if (!readpassphrase(prompt, pin1, sizeof(pin1), RPP_ECHO_OFF)) {
39ba9bdd8bSchristos warnx("readpassphrase");
40ba9bdd8bSchristos goto out;
41ba9bdd8bSchristos }
42ba9bdd8bSchristos
43ba9bdd8bSchristos r = snprintf(prompt, sizeof(prompt), "Enter the same PIN again: ");
44ba9bdd8bSchristos if (r < 0 || (size_t)r >= sizeof(prompt)) {
45ba9bdd8bSchristos warnx("snprintf");
46ba9bdd8bSchristos goto out;
47ba9bdd8bSchristos }
48ba9bdd8bSchristos
49ba9bdd8bSchristos if (!readpassphrase(prompt, pin2, sizeof(pin2), RPP_ECHO_OFF)) {
50ba9bdd8bSchristos warnx("readpassphrase");
51ba9bdd8bSchristos goto out;
52ba9bdd8bSchristos }
53ba9bdd8bSchristos
54ba9bdd8bSchristos if (strcmp(pin1, pin2) != 0) {
55ba9bdd8bSchristos fprintf(stderr, "PINs do not match. Try again.\n");
56ba9bdd8bSchristos goto out;
57ba9bdd8bSchristos }
58ba9bdd8bSchristos
59*2d40c451Schristos if (strlen(pin1) < 4 || strlen(pin1) > 63) {
60*2d40c451Schristos fprintf(stderr, "invalid PIN length\n");
61*2d40c451Schristos goto out;
62*2d40c451Schristos }
63*2d40c451Schristos
64ba9bdd8bSchristos if ((r = fido_dev_set_pin(dev, pin1, NULL)) != FIDO_OK) {
65ba9bdd8bSchristos warnx("fido_dev_set_pin: %s", fido_strerr(r));
66ba9bdd8bSchristos goto out;
67ba9bdd8bSchristos }
68ba9bdd8bSchristos
69ba9bdd8bSchristos fido_dev_close(dev);
70ba9bdd8bSchristos fido_dev_free(&dev);
71ba9bdd8bSchristos
72ba9bdd8bSchristos status = 0;
73ba9bdd8bSchristos out:
74ba9bdd8bSchristos explicit_bzero(pin1, sizeof(pin1));
75ba9bdd8bSchristos explicit_bzero(pin2, sizeof(pin2));
76ba9bdd8bSchristos
77ba9bdd8bSchristos exit(status);
78ba9bdd8bSchristos }
79ba9bdd8bSchristos
80ba9bdd8bSchristos int
pin_change(char * path)81ba9bdd8bSchristos pin_change(char *path)
82ba9bdd8bSchristos {
83ba9bdd8bSchristos fido_dev_t *dev = NULL;
84ba9bdd8bSchristos char prompt[1024];
85*2d40c451Schristos char pin0[128];
86*2d40c451Schristos char pin1[128];
87*2d40c451Schristos char pin2[128];
88ba9bdd8bSchristos int r;
89ba9bdd8bSchristos int status = 1;
90ba9bdd8bSchristos
91ba9bdd8bSchristos if (path == NULL)
92ba9bdd8bSchristos usage();
93ba9bdd8bSchristos
94ba9bdd8bSchristos dev = open_dev(path);
95ba9bdd8bSchristos
96ba9bdd8bSchristos r = snprintf(prompt, sizeof(prompt), "Enter current PIN for %s: ", path);
97ba9bdd8bSchristos if (r < 0 || (size_t)r >= sizeof(prompt)) {
98ba9bdd8bSchristos warnx("snprintf");
99ba9bdd8bSchristos goto out;
100ba9bdd8bSchristos }
101ba9bdd8bSchristos
102ba9bdd8bSchristos if (!readpassphrase(prompt, pin0, sizeof(pin0), RPP_ECHO_OFF)) {
103ba9bdd8bSchristos warnx("readpassphrase");
104ba9bdd8bSchristos goto out;
105ba9bdd8bSchristos }
106ba9bdd8bSchristos
107*2d40c451Schristos if (strlen(pin0) < 4 || strlen(pin0) > 63) {
108*2d40c451Schristos warnx("invalid PIN length");
109*2d40c451Schristos goto out;
110*2d40c451Schristos }
111*2d40c451Schristos
112ba9bdd8bSchristos r = snprintf(prompt, sizeof(prompt), "Enter new PIN for %s: ", path);
113ba9bdd8bSchristos if (r < 0 || (size_t)r >= sizeof(prompt)) {
114ba9bdd8bSchristos warnx("snprintf");
115ba9bdd8bSchristos goto out;
116ba9bdd8bSchristos }
117ba9bdd8bSchristos
118ba9bdd8bSchristos if (!readpassphrase(prompt, pin1, sizeof(pin1), RPP_ECHO_OFF)) {
119ba9bdd8bSchristos warnx("readpassphrase");
120ba9bdd8bSchristos goto out;
121ba9bdd8bSchristos }
122ba9bdd8bSchristos
123ba9bdd8bSchristos r = snprintf(prompt, sizeof(prompt), "Enter the same PIN again: ");
124ba9bdd8bSchristos if (r < 0 || (size_t)r >= sizeof(prompt)) {
125ba9bdd8bSchristos warnx("snprintf");
126ba9bdd8bSchristos goto out;
127ba9bdd8bSchristos }
128ba9bdd8bSchristos
129ba9bdd8bSchristos if (!readpassphrase(prompt, pin2, sizeof(pin2), RPP_ECHO_OFF)) {
130ba9bdd8bSchristos warnx("readpassphrase");
131ba9bdd8bSchristos goto out;
132ba9bdd8bSchristos }
133ba9bdd8bSchristos
134ba9bdd8bSchristos if (strcmp(pin1, pin2) != 0) {
135ba9bdd8bSchristos fprintf(stderr, "PINs do not match. Try again.\n");
136ba9bdd8bSchristos goto out;
137ba9bdd8bSchristos }
138ba9bdd8bSchristos
139*2d40c451Schristos if (strlen(pin1) < 4 || strlen(pin1) > 63) {
140*2d40c451Schristos fprintf(stderr, "invalid PIN length\n");
141*2d40c451Schristos goto out;
142*2d40c451Schristos }
143*2d40c451Schristos
144ba9bdd8bSchristos if ((r = fido_dev_set_pin(dev, pin1, pin0)) != FIDO_OK) {
145ba9bdd8bSchristos warnx("fido_dev_set_pin: %s", fido_strerr(r));
146ba9bdd8bSchristos goto out;
147ba9bdd8bSchristos }
148ba9bdd8bSchristos
149ba9bdd8bSchristos fido_dev_close(dev);
150ba9bdd8bSchristos fido_dev_free(&dev);
151ba9bdd8bSchristos
152ba9bdd8bSchristos status = 0;
153ba9bdd8bSchristos out:
154ba9bdd8bSchristos explicit_bzero(pin0, sizeof(pin0));
155ba9bdd8bSchristos explicit_bzero(pin1, sizeof(pin1));
156ba9bdd8bSchristos explicit_bzero(pin2, sizeof(pin2));
157ba9bdd8bSchristos
158ba9bdd8bSchristos exit(status);
159ba9bdd8bSchristos }
160