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