f540a43052
Some highlights from NEWS: ** Added OpenSSL 3.0 compatibility. ** Removed OpenSSL 1.0 compatibility. ** Support for FIDO 2.1 "minPinLength" extension. ** Support for COSE_EDDSA, COSE_ES256, and COSE_RS1 attestation. ** Support for TPM 2.0 attestation. ** Support for device timeouts; see fido_dev_set_timeout(). ** New API calls: - es256_pk_from_EVP_PKEY; - fido_cred_attstmt_len; - fido_cred_attstmt_ptr; - fido_cred_pin_minlen; - fido_cred_set_attstmt; - fido_cred_set_pin_minlen; - fido_dev_set_pin_minlen_rpid; - fido_dev_set_timeout; - rs256_pk_from_EVP_PKEY. ** Reliability and portability fixes. ** Better handling of HID devices without identification strings; gh#381. Relnotes: Yes Sponsored by: The FreeBSD Foundation
198 lines
3.9 KiB
C
198 lines
3.9 KiB
C
/*
|
|
* Copyright (c) 2020 Yubico AB. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style
|
|
* license that can be found in the LICENSE file.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <fido.h>
|
|
#include <fido/config.h>
|
|
|
|
#include "../openbsd-compat/openbsd-compat.h"
|
|
#include "extern.h"
|
|
|
|
int
|
|
config_entattest(char *path)
|
|
{
|
|
fido_dev_t *dev;
|
|
char *pin = NULL;
|
|
int r, ok = 1;
|
|
|
|
dev = open_dev(path);
|
|
if ((r = fido_dev_enable_entattest(dev, NULL)) != FIDO_OK &&
|
|
should_retry_with_pin(dev, r)) {
|
|
if ((pin = get_pin(path)) == NULL)
|
|
goto out;
|
|
r = fido_dev_enable_entattest(dev, pin);
|
|
freezero(pin, PINBUF_LEN);
|
|
pin = NULL;
|
|
}
|
|
if (r != FIDO_OK) {
|
|
warnx("fido_dev_enable_entattest: %s (0x%x)",
|
|
fido_strerr(r), r);
|
|
goto out;
|
|
}
|
|
|
|
ok = 0;
|
|
out:
|
|
fido_dev_close(dev);
|
|
fido_dev_free(&dev);
|
|
|
|
exit(ok);
|
|
}
|
|
|
|
int
|
|
config_always_uv(char *path, int toggle)
|
|
{
|
|
fido_dev_t *dev;
|
|
char *pin = NULL;
|
|
int v, r, ok = 1;
|
|
|
|
dev = open_dev(path);
|
|
if (get_devopt(dev, "alwaysUv", &v) < 0) {
|
|
warnx("%s: getdevopt", __func__);
|
|
goto out;
|
|
}
|
|
if (v == -1) {
|
|
warnx("%s: option not found", __func__);
|
|
goto out;
|
|
}
|
|
if (v == toggle) {
|
|
ok = 0;
|
|
goto out;
|
|
}
|
|
if ((r = fido_dev_toggle_always_uv(dev, NULL)) != FIDO_OK &&
|
|
should_retry_with_pin(dev, r)) {
|
|
if ((pin = get_pin(path)) == NULL)
|
|
goto out;
|
|
r = fido_dev_toggle_always_uv(dev, pin);
|
|
freezero(pin, PINBUF_LEN);
|
|
pin = NULL;
|
|
}
|
|
if (r != FIDO_OK) {
|
|
warnx("fido_dev_toggle_always_uv: %s (0x%x)",
|
|
fido_strerr(r), r);
|
|
goto out;
|
|
}
|
|
|
|
ok = 0;
|
|
out:
|
|
fido_dev_close(dev);
|
|
fido_dev_free(&dev);
|
|
|
|
exit(ok);
|
|
}
|
|
|
|
int
|
|
config_pin_minlen(char *path, const char *pinlen)
|
|
{
|
|
fido_dev_t *dev;
|
|
char *pin = NULL;
|
|
int len, r, ok = 1;
|
|
|
|
dev = open_dev(path);
|
|
if ((len = base10(pinlen)) < 0 || len > 63) {
|
|
warnx("%s: len > 63", __func__);
|
|
goto out;
|
|
}
|
|
if ((r = fido_dev_set_pin_minlen(dev, (size_t)len, NULL)) != FIDO_OK &&
|
|
should_retry_with_pin(dev, r)) {
|
|
if ((pin = get_pin(path)) == NULL)
|
|
goto out;
|
|
r = fido_dev_set_pin_minlen(dev, (size_t)len, pin);
|
|
freezero(pin, PINBUF_LEN);
|
|
pin = NULL;
|
|
}
|
|
if (r != FIDO_OK) {
|
|
warnx("fido_dev_set_pin_minlen: %s (0x%x)", fido_strerr(r), r);
|
|
goto out;
|
|
}
|
|
|
|
ok = 0;
|
|
out:
|
|
fido_dev_close(dev);
|
|
fido_dev_free(&dev);
|
|
|
|
exit(ok);
|
|
}
|
|
|
|
int
|
|
config_force_pin_change(char *path)
|
|
{
|
|
fido_dev_t *dev;
|
|
char *pin = NULL;
|
|
int r, ok = 1;
|
|
|
|
dev = open_dev(path);
|
|
if ((r = fido_dev_force_pin_change(dev, NULL)) != FIDO_OK &&
|
|
should_retry_with_pin(dev, r)) {
|
|
if ((pin = get_pin(path)) == NULL)
|
|
goto out;
|
|
r = fido_dev_force_pin_change(dev, pin);
|
|
freezero(pin, PINBUF_LEN);
|
|
pin = NULL;
|
|
}
|
|
if (r != FIDO_OK) {
|
|
warnx("fido_dev_force_pin_change: %s (0x%x)", fido_strerr(r), r);
|
|
goto out;
|
|
}
|
|
|
|
ok = 0;
|
|
out:
|
|
fido_dev_close(dev);
|
|
fido_dev_free(&dev);
|
|
|
|
exit(ok);
|
|
}
|
|
|
|
int
|
|
config_pin_minlen_rpid(char *path, const char *rpids)
|
|
{
|
|
fido_dev_t *dev;
|
|
char *otmp, *tmp, *cp;
|
|
char *pin = NULL, **rpid = NULL;
|
|
int r, ok = 1;
|
|
size_t n;
|
|
|
|
if ((tmp = strdup(rpids)) == NULL)
|
|
err(1, "strdup");
|
|
otmp = tmp;
|
|
for (n = 0; (cp = strsep(&tmp, ",")) != NULL; n++) {
|
|
if (n == SIZE_MAX || (rpid = recallocarray(rpid, n, n + 1,
|
|
sizeof(*rpid))) == NULL)
|
|
err(1, "recallocarray");
|
|
if ((rpid[n] = strdup(cp)) == NULL)
|
|
err(1, "strdup");
|
|
if (*rpid[n] == '\0')
|
|
errx(1, "empty rpid");
|
|
}
|
|
free(otmp);
|
|
if (rpid == NULL || n == 0)
|
|
errx(1, "could not parse rp_id");
|
|
dev = open_dev(path);
|
|
if ((r = fido_dev_set_pin_minlen_rpid(dev, (const char * const *)rpid,
|
|
n, NULL)) != FIDO_OK && should_retry_with_pin(dev, r)) {
|
|
if ((pin = get_pin(path)) == NULL)
|
|
goto out;
|
|
r = fido_dev_set_pin_minlen_rpid(dev, (const char * const *)rpid,
|
|
n, pin);
|
|
freezero(pin, PINBUF_LEN);
|
|
pin = NULL;
|
|
}
|
|
if (r != FIDO_OK) {
|
|
warnx("fido_dev_set_pin_minlen_rpid: %s (0x%x)",
|
|
fido_strerr(r), r);
|
|
goto out;
|
|
}
|
|
|
|
ok = 0;
|
|
out:
|
|
fido_dev_close(dev);
|
|
fido_dev_free(&dev);
|
|
|
|
exit(ok);
|
|
}
|