You've already forked fido2-manage
mirror of
https://github.com/token2/fido2-manage.git
synced 2026-06-22 14:42:51 -07:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
# Copyright (c) 2018-2022 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.
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
list(APPEND COMPAT_SOURCES
|
||||
../openbsd-compat/bsd-getpagesize.c
|
||||
../openbsd-compat/explicit_bzero.c
|
||||
../openbsd-compat/freezero.c
|
||||
../openbsd-compat/recallocarray.c
|
||||
../openbsd-compat/strlcat.c
|
||||
../openbsd-compat/strlcpy.c
|
||||
../openbsd-compat/strsep.c
|
||||
)
|
||||
|
||||
if(WIN32 AND NOT CYGWIN AND NOT MSYS)
|
||||
list(APPEND COMPAT_SOURCES
|
||||
../openbsd-compat/bsd-getline.c
|
||||
../openbsd-compat/endian_win32.c
|
||||
../openbsd-compat/explicit_bzero_win32.c
|
||||
../openbsd-compat/getopt_long.c
|
||||
../openbsd-compat/readpassphrase_win32.c
|
||||
)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
list(APPEND COMPAT_SOURCES ../openbsd-compat/posix_win.c)
|
||||
endif()
|
||||
else()
|
||||
list(APPEND COMPAT_SOURCES ../openbsd-compat/readpassphrase.c)
|
||||
endif()
|
||||
|
||||
if(NOT MSVC)
|
||||
set_source_files_properties(assert_get.c assert_verify.c base64.c bio.c
|
||||
config.c cred_make.c cred_verify.c credman.c
|
||||
fido2-token.c pin.c token.c util.c
|
||||
PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
|
||||
endif()
|
||||
|
||||
|
||||
add_executable(fido2-token
|
||||
fido2-token.c
|
||||
base64.c
|
||||
bio.c
|
||||
config.c
|
||||
credman.c
|
||||
largeblob.c
|
||||
pin.c
|
||||
token.c
|
||||
util.c
|
||||
${COMPAT_SOURCES}
|
||||
)
|
||||
|
||||
target_link_libraries(fido2-token ${CRYPTO_LIBRARIES} ${_FIDO2_LIBRARY})
|
||||
|
||||
install(TARGETS fido2-token
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2023 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.
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <fido.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../openbsd-compat/openbsd-compat.h"
|
||||
#include "extern.h"
|
||||
|
||||
struct toggle {
|
||||
fido_opt_t up;
|
||||
fido_opt_t uv;
|
||||
fido_opt_t pin;
|
||||
};
|
||||
|
||||
static const char *
|
||||
opt2str(fido_opt_t v)
|
||||
{
|
||||
switch (v) {
|
||||
case FIDO_OPT_OMIT:
|
||||
return "omit";
|
||||
case FIDO_OPT_TRUE:
|
||||
return "true";
|
||||
case FIDO_OPT_FALSE:
|
||||
return "false";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parse_toggle(const char *str, struct toggle *opt)
|
||||
{
|
||||
fido_opt_t *k;
|
||||
fido_opt_t v;
|
||||
char *assignment;
|
||||
char *key;
|
||||
char *val;
|
||||
|
||||
if ((assignment = strdup(str)) == NULL)
|
||||
err(1, "strdup");
|
||||
if ((val = strchr(assignment, '=')) == NULL)
|
||||
errx(1, "invalid assignment '%s'", assignment);
|
||||
|
||||
key = assignment;
|
||||
*val++ = '\0';
|
||||
|
||||
if (!strcmp(val, "true"))
|
||||
v = FIDO_OPT_TRUE;
|
||||
else if (!strcmp(val, "false"))
|
||||
v = FIDO_OPT_FALSE;
|
||||
else
|
||||
errx(1, "unknown value '%s'", val);
|
||||
|
||||
if (!strcmp(key, "up"))
|
||||
k = &opt->up;
|
||||
else if (!strcmp(key, "uv"))
|
||||
k = &opt->uv;
|
||||
else if (!strcmp(key, "pin"))
|
||||
k = &opt->pin;
|
||||
else
|
||||
errx(1, "unknown key '%s'", key);
|
||||
|
||||
free(assignment);
|
||||
|
||||
*k = v;
|
||||
}
|
||||
|
||||
static fido_assert_t *
|
||||
prepare_assert(FILE *in_f, int flags, const struct toggle *opt)
|
||||
{
|
||||
fido_assert_t *assert = NULL;
|
||||
struct blob cdh;
|
||||
struct blob id;
|
||||
struct blob hmac_salt;
|
||||
char *rpid = NULL;
|
||||
int r;
|
||||
|
||||
memset(&cdh, 0, sizeof(cdh));
|
||||
memset(&id, 0, sizeof(id));
|
||||
memset(&hmac_salt, 0, sizeof(hmac_salt));
|
||||
|
||||
r = base64_read(in_f, &cdh);
|
||||
r |= string_read(in_f, &rpid);
|
||||
if ((flags & FLAG_RK) == 0)
|
||||
r |= base64_read(in_f, &id);
|
||||
if (flags & FLAG_HMAC)
|
||||
r |= base64_read(in_f, &hmac_salt);
|
||||
if (r < 0)
|
||||
errx(1, "input error");
|
||||
|
||||
if (flags & FLAG_DEBUG) {
|
||||
fprintf(stderr, "client data%s:\n",
|
||||
flags & FLAG_CD ? "" : " hash");
|
||||
xxd(cdh.ptr, cdh.len);
|
||||
fprintf(stderr, "relying party id: %s\n", rpid);
|
||||
if ((flags & FLAG_RK) == 0) {
|
||||
fprintf(stderr, "credential id:\n");
|
||||
xxd(id.ptr, id.len);
|
||||
}
|
||||
fprintf(stderr, "up=%s\n", opt2str(opt->up));
|
||||
fprintf(stderr, "uv=%s\n", opt2str(opt->uv));
|
||||
fprintf(stderr, "pin=%s\n", opt2str(opt->pin));
|
||||
}
|
||||
|
||||
if ((assert = fido_assert_new()) == NULL)
|
||||
errx(1, "fido_assert_new");
|
||||
|
||||
if (flags & FLAG_CD)
|
||||
r = fido_assert_set_clientdata(assert, cdh.ptr, cdh.len);
|
||||
else
|
||||
r = fido_assert_set_clientdata_hash(assert, cdh.ptr, cdh.len);
|
||||
|
||||
if (r != FIDO_OK || (r = fido_assert_set_rp(assert, rpid)) != FIDO_OK)
|
||||
errx(1, "fido_assert_set: %s", fido_strerr(r));
|
||||
if ((r = fido_assert_set_up(assert, opt->up)) != FIDO_OK)
|
||||
errx(1, "fido_assert_set_up: %s", fido_strerr(r));
|
||||
if ((r = fido_assert_set_uv(assert, opt->uv)) != FIDO_OK)
|
||||
errx(1, "fido_assert_set_uv: %s", fido_strerr(r));
|
||||
|
||||
if (flags & FLAG_HMAC) {
|
||||
if ((r = fido_assert_set_extensions(assert,
|
||||
FIDO_EXT_HMAC_SECRET)) != FIDO_OK)
|
||||
errx(1, "fido_assert_set_extensions: %s",
|
||||
fido_strerr(r));
|
||||
if ((r = fido_assert_set_hmac_salt(assert, hmac_salt.ptr,
|
||||
hmac_salt.len)) != FIDO_OK)
|
||||
errx(1, "fido_assert_set_hmac_salt: %s",
|
||||
fido_strerr(r));
|
||||
}
|
||||
if (flags & FLAG_LARGEBLOB) {
|
||||
if ((r = fido_assert_set_extensions(assert,
|
||||
FIDO_EXT_LARGEBLOB_KEY)) != FIDO_OK)
|
||||
errx(1, "fido_assert_set_extensions: %s", fido_strerr(r));
|
||||
}
|
||||
if ((flags & FLAG_RK) == 0) {
|
||||
if ((r = fido_assert_allow_cred(assert, id.ptr,
|
||||
id.len)) != FIDO_OK)
|
||||
errx(1, "fido_assert_allow_cred: %s", fido_strerr(r));
|
||||
}
|
||||
|
||||
free(hmac_salt.ptr);
|
||||
free(cdh.ptr);
|
||||
free(id.ptr);
|
||||
free(rpid);
|
||||
|
||||
return (assert);
|
||||
}
|
||||
|
||||
static void
|
||||
print_assert(FILE *out_f, const fido_assert_t *assert, size_t idx, int flags)
|
||||
{
|
||||
char *cdh = NULL;
|
||||
char *authdata = NULL;
|
||||
char *sig = NULL;
|
||||
char *user_id = NULL;
|
||||
char *hmac_secret = NULL;
|
||||
char *key = NULL;
|
||||
int r;
|
||||
|
||||
r = base64_encode(fido_assert_clientdata_hash_ptr(assert),
|
||||
fido_assert_clientdata_hash_len(assert), &cdh);
|
||||
r |= base64_encode(fido_assert_authdata_ptr(assert, idx),
|
||||
fido_assert_authdata_len(assert, 0), &authdata);
|
||||
r |= base64_encode(fido_assert_sig_ptr(assert, idx),
|
||||
fido_assert_sig_len(assert, idx), &sig);
|
||||
if (flags & FLAG_RK)
|
||||
r |= base64_encode(fido_assert_user_id_ptr(assert, idx),
|
||||
fido_assert_user_id_len(assert, idx), &user_id);
|
||||
if (flags & FLAG_HMAC)
|
||||
r |= base64_encode(fido_assert_hmac_secret_ptr(assert, idx),
|
||||
fido_assert_hmac_secret_len(assert, idx), &hmac_secret);
|
||||
if (flags & FLAG_LARGEBLOB)
|
||||
r |= base64_encode(fido_assert_largeblob_key_ptr(assert, idx),
|
||||
fido_assert_largeblob_key_len(assert, idx), &key);
|
||||
if (r < 0)
|
||||
errx(1, "output error");
|
||||
|
||||
fprintf(out_f, "%s\n", cdh);
|
||||
fprintf(out_f, "%s\n", fido_assert_rp_id(assert));
|
||||
fprintf(out_f, "%s\n", authdata);
|
||||
fprintf(out_f, "%s\n", sig);
|
||||
if (flags & FLAG_RK)
|
||||
fprintf(out_f, "%s\n", user_id);
|
||||
if (hmac_secret) {
|
||||
fprintf(out_f, "%s\n", hmac_secret);
|
||||
explicit_bzero(hmac_secret, strlen(hmac_secret));
|
||||
}
|
||||
if (key) {
|
||||
fprintf(out_f, "%s\n", key);
|
||||
explicit_bzero(key, strlen(key));
|
||||
}
|
||||
|
||||
free(key);
|
||||
free(hmac_secret);
|
||||
free(cdh);
|
||||
free(authdata);
|
||||
free(sig);
|
||||
free(user_id);
|
||||
}
|
||||
|
||||
int
|
||||
assert_get(int argc, char **argv)
|
||||
{
|
||||
fido_dev_t *dev = NULL;
|
||||
fido_assert_t *assert = NULL;
|
||||
struct toggle opt;
|
||||
char prompt[1024];
|
||||
char pin[128];
|
||||
char *in_path = NULL;
|
||||
char *out_path = NULL;
|
||||
FILE *in_f = NULL;
|
||||
FILE *out_f = NULL;
|
||||
int flags = 0;
|
||||
int ch;
|
||||
int r;
|
||||
|
||||
opt.up = opt.uv = opt.pin = FIDO_OPT_OMIT;
|
||||
|
||||
while ((ch = getopt(argc, argv, "bdhi:o:prt:uvw")) != -1) {
|
||||
switch (ch) {
|
||||
case 'b':
|
||||
flags |= FLAG_LARGEBLOB;
|
||||
break;
|
||||
case 'd':
|
||||
flags |= FLAG_DEBUG;
|
||||
break;
|
||||
case 'h':
|
||||
flags |= FLAG_HMAC;
|
||||
break;
|
||||
case 'i':
|
||||
in_path = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
out_path = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
opt.up = FIDO_OPT_TRUE;
|
||||
break;
|
||||
case 'r':
|
||||
flags |= FLAG_RK;
|
||||
break;
|
||||
case 't' :
|
||||
parse_toggle(optarg, &opt);
|
||||
break;
|
||||
case 'u':
|
||||
flags |= FLAG_U2F;
|
||||
break;
|
||||
case 'v':
|
||||
/* -v implies both pin and uv for historical reasons */
|
||||
opt.pin = FIDO_OPT_TRUE;
|
||||
opt.uv = FIDO_OPT_TRUE;
|
||||
break;
|
||||
case 'w':
|
||||
flags |= FLAG_CD;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1)
|
||||
usage();
|
||||
|
||||
in_f = open_read(in_path);
|
||||
out_f = open_write(out_path);
|
||||
|
||||
fido_init((flags & FLAG_DEBUG) ? FIDO_DEBUG : 0);
|
||||
|
||||
assert = prepare_assert(in_f, flags, &opt);
|
||||
|
||||
dev = open_dev(argv[0]);
|
||||
if (flags & FLAG_U2F)
|
||||
fido_dev_force_u2f(dev);
|
||||
|
||||
if (opt.pin == FIDO_OPT_TRUE) {
|
||||
r = snprintf(prompt, sizeof(prompt), "Enter PIN for %s: ",
|
||||
argv[0]);
|
||||
if (r < 0 || (size_t)r >= sizeof(prompt))
|
||||
errx(1, "snprintf");
|
||||
if (!readpassphrase(prompt, pin, sizeof(pin), RPP_ECHO_OFF))
|
||||
errx(1, "readpassphrase");
|
||||
if (strlen(pin) < 4 || strlen(pin) > 63) {
|
||||
explicit_bzero(pin, sizeof(pin));
|
||||
errx(1, "invalid PIN length");
|
||||
}
|
||||
r = fido_dev_get_assert(dev, assert, pin);
|
||||
} else
|
||||
r = fido_dev_get_assert(dev, assert, NULL);
|
||||
|
||||
explicit_bzero(pin, sizeof(pin));
|
||||
|
||||
if (r != FIDO_OK)
|
||||
errx(1, "fido_dev_get_assert: %s", fido_strerr(r));
|
||||
|
||||
if (flags & FLAG_RK) {
|
||||
for (size_t idx = 0; idx < fido_assert_count(assert); idx++)
|
||||
print_assert(out_f, assert, idx, flags);
|
||||
} else {
|
||||
if (fido_assert_count(assert) != 1)
|
||||
errx(1, "fido_assert_count: %zu",
|
||||
fido_assert_count(assert));
|
||||
print_assert(out_f, assert, 0, flags);
|
||||
}
|
||||
|
||||
fido_dev_close(dev);
|
||||
fido_dev_free(&dev);
|
||||
fido_assert_free(&assert);
|
||||
|
||||
fclose(in_f);
|
||||
fclose(out_f);
|
||||
in_f = NULL;
|
||||
out_f = NULL;
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2022 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.
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <fido.h>
|
||||
#include <fido/es256.h>
|
||||
#include <fido/es384.h>
|
||||
#include <fido/rs256.h>
|
||||
#include <fido/eddsa.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../openbsd-compat/openbsd-compat.h"
|
||||
#include "extern.h"
|
||||
|
||||
static fido_assert_t *
|
||||
prepare_assert(FILE *in_f, int flags)
|
||||
{
|
||||
fido_assert_t *assert = NULL;
|
||||
struct blob cdh;
|
||||
struct blob authdata;
|
||||
struct blob sig;
|
||||
char *rpid = NULL;
|
||||
int r;
|
||||
|
||||
memset(&cdh, 0, sizeof(cdh));
|
||||
memset(&authdata, 0, sizeof(authdata));
|
||||
memset(&sig, 0, sizeof(sig));
|
||||
|
||||
r = base64_read(in_f, &cdh);
|
||||
r |= string_read(in_f, &rpid);
|
||||
r |= base64_read(in_f, &authdata);
|
||||
r |= base64_read(in_f, &sig);
|
||||
if (r < 0)
|
||||
errx(1, "input error");
|
||||
|
||||
if (flags & FLAG_DEBUG) {
|
||||
fprintf(stderr, "client data hash:\n");
|
||||
xxd(cdh.ptr, cdh.len);
|
||||
fprintf(stderr, "relying party id: %s\n", rpid);
|
||||
fprintf(stderr, "authenticator data:\n");
|
||||
xxd(authdata.ptr, authdata.len);
|
||||
fprintf(stderr, "signature:\n");
|
||||
xxd(sig.ptr, sig.len);
|
||||
}
|
||||
|
||||
if ((assert = fido_assert_new()) == NULL)
|
||||
errx(1, "fido_assert_new");
|
||||
if ((r = fido_assert_set_count(assert, 1)) != FIDO_OK)
|
||||
errx(1, "fido_assert_count: %s", fido_strerr(r));
|
||||
|
||||
if ((r = fido_assert_set_clientdata_hash(assert, cdh.ptr,
|
||||
cdh.len)) != FIDO_OK ||
|
||||
(r = fido_assert_set_rp(assert, rpid)) != FIDO_OK ||
|
||||
(r = fido_assert_set_authdata(assert, 0, authdata.ptr,
|
||||
authdata.len)) != FIDO_OK ||
|
||||
(r = fido_assert_set_sig(assert, 0, sig.ptr, sig.len)) != FIDO_OK)
|
||||
errx(1, "fido_assert_set: %s", fido_strerr(r));
|
||||
|
||||
if (flags & FLAG_UP) {
|
||||
if ((r = fido_assert_set_up(assert, FIDO_OPT_TRUE)) != FIDO_OK)
|
||||
errx(1, "fido_assert_set_up: %s", fido_strerr(r));
|
||||
}
|
||||
if (flags & FLAG_UV) {
|
||||
if ((r = fido_assert_set_uv(assert, FIDO_OPT_TRUE)) != FIDO_OK)
|
||||
errx(1, "fido_assert_set_uv: %s", fido_strerr(r));
|
||||
}
|
||||
if (flags & FLAG_HMAC) {
|
||||
if ((r = fido_assert_set_extensions(assert,
|
||||
FIDO_EXT_HMAC_SECRET)) != FIDO_OK)
|
||||
errx(1, "fido_assert_set_extensions: %s",
|
||||
fido_strerr(r));
|
||||
}
|
||||
|
||||
free(cdh.ptr);
|
||||
free(authdata.ptr);
|
||||
free(sig.ptr);
|
||||
free(rpid);
|
||||
|
||||
return (assert);
|
||||
}
|
||||
|
||||
static void *
|
||||
load_pubkey(int type, const char *file)
|
||||
{
|
||||
EC_KEY *ec = NULL;
|
||||
RSA *rsa = NULL;
|
||||
EVP_PKEY *eddsa = NULL;
|
||||
es256_pk_t *es256_pk = NULL;
|
||||
es384_pk_t *es384_pk = NULL;
|
||||
rs256_pk_t *rs256_pk = NULL;
|
||||
eddsa_pk_t *eddsa_pk = NULL;
|
||||
void *pk = NULL;
|
||||
|
||||
switch (type) {
|
||||
case COSE_ES256:
|
||||
if ((ec = read_ec_pubkey(file)) == NULL)
|
||||
errx(1, "read_ec_pubkey");
|
||||
if ((es256_pk = es256_pk_new()) == NULL)
|
||||
errx(1, "es256_pk_new");
|
||||
if (es256_pk_from_EC_KEY(es256_pk, ec) != FIDO_OK)
|
||||
errx(1, "es256_pk_from_EC_KEY");
|
||||
pk = es256_pk;
|
||||
EC_KEY_free(ec);
|
||||
break;
|
||||
case COSE_ES384:
|
||||
if ((ec = read_ec_pubkey(file)) == NULL)
|
||||
errx(1, "read_ec_pubkey");
|
||||
if ((es384_pk = es384_pk_new()) == NULL)
|
||||
errx(1, "es384_pk_new");
|
||||
if (es384_pk_from_EC_KEY(es384_pk, ec) != FIDO_OK)
|
||||
errx(1, "es384_pk_from_EC_KEY");
|
||||
pk = es384_pk;
|
||||
EC_KEY_free(ec);
|
||||
break;
|
||||
case COSE_RS256:
|
||||
if ((rsa = read_rsa_pubkey(file)) == NULL)
|
||||
errx(1, "read_rsa_pubkey");
|
||||
if ((rs256_pk = rs256_pk_new()) == NULL)
|
||||
errx(1, "rs256_pk_new");
|
||||
if (rs256_pk_from_RSA(rs256_pk, rsa) != FIDO_OK)
|
||||
errx(1, "rs256_pk_from_RSA");
|
||||
pk = rs256_pk;
|
||||
RSA_free(rsa);
|
||||
break;
|
||||
case COSE_EDDSA:
|
||||
if ((eddsa = read_eddsa_pubkey(file)) == NULL)
|
||||
errx(1, "read_eddsa_pubkey");
|
||||
if ((eddsa_pk = eddsa_pk_new()) == NULL)
|
||||
errx(1, "eddsa_pk_new");
|
||||
if (eddsa_pk_from_EVP_PKEY(eddsa_pk, eddsa) != FIDO_OK)
|
||||
errx(1, "eddsa_pk_from_EVP_PKEY");
|
||||
pk = eddsa_pk;
|
||||
EVP_PKEY_free(eddsa);
|
||||
break;
|
||||
default:
|
||||
errx(1, "invalid type %d", type);
|
||||
}
|
||||
|
||||
return (pk);
|
||||
}
|
||||
|
||||
int
|
||||
assert_verify(int argc, char **argv)
|
||||
{
|
||||
fido_assert_t *assert = NULL;
|
||||
void *pk = NULL;
|
||||
char *in_path = NULL;
|
||||
FILE *in_f = NULL;
|
||||
int type = COSE_ES256;
|
||||
int flags = 0;
|
||||
int ch;
|
||||
int r;
|
||||
|
||||
while ((ch = getopt(argc, argv, "dhi:pv")) != -1) {
|
||||
switch (ch) {
|
||||
case 'd':
|
||||
flags |= FLAG_DEBUG;
|
||||
break;
|
||||
case 'h':
|
||||
flags |= FLAG_HMAC;
|
||||
break;
|
||||
case 'i':
|
||||
in_path = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
flags |= FLAG_UP;
|
||||
break;
|
||||
case 'v':
|
||||
flags |= FLAG_UV;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1 || argc > 2)
|
||||
usage();
|
||||
|
||||
in_f = open_read(in_path);
|
||||
|
||||
if (argc > 1 && cose_type(argv[1], &type) < 0)
|
||||
errx(1, "unknown type %s", argv[1]);
|
||||
|
||||
fido_init((flags & FLAG_DEBUG) ? FIDO_DEBUG : 0);
|
||||
|
||||
pk = load_pubkey(type, argv[0]);
|
||||
assert = prepare_assert(in_f, flags);
|
||||
if ((r = fido_assert_verify(assert, 0, type, pk)) != FIDO_OK)
|
||||
errx(1, "fido_assert_verify: %s", fido_strerr(r));
|
||||
fido_assert_free(&assert);
|
||||
|
||||
fclose(in_f);
|
||||
in_f = NULL;
|
||||
|
||||
exit(0);
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../openbsd-compat/openbsd-compat.h"
|
||||
#include "extern.h"
|
||||
|
||||
int
|
||||
base64_encode(const void *ptr, size_t len, char **out)
|
||||
{
|
||||
BIO *bio_b64 = NULL;
|
||||
BIO *bio_mem = NULL;
|
||||
char *b64_ptr = NULL;
|
||||
long b64_len;
|
||||
int n;
|
||||
int ok = -1;
|
||||
|
||||
if (ptr == NULL || out == NULL || len > INT_MAX)
|
||||
return (-1);
|
||||
|
||||
*out = NULL;
|
||||
|
||||
if ((bio_b64 = BIO_new(BIO_f_base64())) == NULL)
|
||||
goto fail;
|
||||
if ((bio_mem = BIO_new(BIO_s_mem())) == NULL)
|
||||
goto fail;
|
||||
|
||||
BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
|
||||
BIO_push(bio_b64, bio_mem);
|
||||
|
||||
n = BIO_write(bio_b64, ptr, (int)len);
|
||||
if (n < 0 || (size_t)n != len)
|
||||
goto fail;
|
||||
|
||||
if (BIO_flush(bio_b64) < 0)
|
||||
goto fail;
|
||||
|
||||
b64_len = BIO_get_mem_data(bio_b64, &b64_ptr);
|
||||
if (b64_len < 0 || (size_t)b64_len == SIZE_MAX || b64_ptr == NULL)
|
||||
goto fail;
|
||||
if ((*out = calloc(1, (size_t)b64_len + 1)) == NULL)
|
||||
goto fail;
|
||||
|
||||
memcpy(*out, b64_ptr, (size_t)b64_len);
|
||||
ok = 0;
|
||||
|
||||
fail:
|
||||
BIO_free(bio_b64);
|
||||
BIO_free(bio_mem);
|
||||
|
||||
return (ok);
|
||||
}
|
||||
|
||||
int
|
||||
base64_decode(const char *in, void **ptr, size_t *len)
|
||||
{
|
||||
BIO *bio_mem = NULL;
|
||||
BIO *bio_b64 = NULL;
|
||||
size_t alloc_len;
|
||||
int n;
|
||||
int ok = -1;
|
||||
|
||||
if (in == NULL || ptr == NULL || len == NULL || strlen(in) > INT_MAX)
|
||||
return (-1);
|
||||
|
||||
*ptr = NULL;
|
||||
*len = 0;
|
||||
|
||||
if ((bio_b64 = BIO_new(BIO_f_base64())) == NULL)
|
||||
goto fail;
|
||||
if ((bio_mem = BIO_new_mem_buf((const void *)in, -1)) == NULL)
|
||||
goto fail;
|
||||
|
||||
BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
|
||||
BIO_push(bio_b64, bio_mem);
|
||||
|
||||
alloc_len = strlen(in);
|
||||
if ((*ptr = calloc(1, alloc_len)) == NULL)
|
||||
goto fail;
|
||||
|
||||
n = BIO_read(bio_b64, *ptr, (int)alloc_len);
|
||||
if (n <= 0 || BIO_eof(bio_b64) == 0)
|
||||
goto fail;
|
||||
|
||||
*len = (size_t)n;
|
||||
ok = 0;
|
||||
|
||||
fail:
|
||||
BIO_free(bio_b64);
|
||||
BIO_free(bio_mem);
|
||||
|
||||
if (ok < 0) {
|
||||
free(*ptr);
|
||||
*ptr = NULL;
|
||||
*len = 0;
|
||||
}
|
||||
|
||||
return (ok);
|
||||
}
|
||||
|
||||
int
|
||||
base64_read(FILE *f, struct blob *out)
|
||||
{
|
||||
char *line = NULL;
|
||||
size_t linesize = 0;
|
||||
ssize_t n;
|
||||
|
||||
out->ptr = NULL;
|
||||
out->len = 0;
|
||||
|
||||
if ((n = getline(&line, &linesize, f)) <= 0 ||
|
||||
(size_t)n != strlen(line)) {
|
||||
free(line); /* XXX should be free'd _even_ if getline() fails */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (base64_decode(line, (void **)&out->ptr, &out->len) < 0) {
|
||||
free(line);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
free(line);
|
||||
|
||||
return (0);
|
||||
}
|
||||
+278
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright (c) 2019 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.
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <fido.h>
|
||||
#include <fido/bio.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../openbsd-compat/openbsd-compat.h"
|
||||
#include "extern.h"
|
||||
|
||||
static int
|
||||
print_template(const fido_bio_template_array_t *ta, size_t idx)
|
||||
{
|
||||
const fido_bio_template_t *t = NULL;
|
||||
char *id = NULL;
|
||||
|
||||
if ((t = fido_bio_template(ta, idx)) == NULL) {
|
||||
warnx("fido_bio_template");
|
||||
return -1;
|
||||
}
|
||||
if (base64_encode(fido_bio_template_id_ptr(t),
|
||||
fido_bio_template_id_len(t), &id) < 0) {
|
||||
warnx("output error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%02u: %s %s\n", (unsigned)idx, id, fido_bio_template_name(t));
|
||||
free(id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bio_list(const char *path)
|
||||
{
|
||||
fido_bio_template_array_t *ta = NULL;
|
||||
fido_dev_t *dev = NULL;
|
||||
char *pin = NULL;
|
||||
int r, ok = 1;
|
||||
|
||||
if ((ta = fido_bio_template_array_new()) == NULL)
|
||||
errx(1, "fido_bio_template_array_new");
|
||||
dev = open_dev(path);
|
||||
if ((pin = get_pin(path)) == NULL)
|
||||
goto out;
|
||||
r = fido_bio_dev_get_template_array(dev, ta, pin);
|
||||
freezero(pin, PINBUF_LEN);
|
||||
pin = NULL;
|
||||
if (r != FIDO_OK) {
|
||||
warnx("fido_bio_dev_get_template_array: %s", fido_strerr(r));
|
||||
goto out;
|
||||
}
|
||||
for (size_t i = 0; i < fido_bio_template_array_count(ta); i++)
|
||||
if (print_template(ta, i) < 0)
|
||||
goto out;
|
||||
|
||||
ok = 0;
|
||||
out:
|
||||
fido_bio_template_array_free(&ta);
|
||||
fido_dev_close(dev);
|
||||
fido_dev_free(&dev);
|
||||
|
||||
exit(ok);
|
||||
}
|
||||
|
||||
int
|
||||
bio_set_name(const char *path, const char *id, const char *name)
|
||||
{
|
||||
fido_bio_template_t *t = NULL;
|
||||
fido_dev_t *dev = NULL;
|
||||
char *pin = NULL;
|
||||
void *id_blob_ptr = NULL;
|
||||
size_t id_blob_len = 0;
|
||||
int r, ok = 1;
|
||||
|
||||
if ((t = fido_bio_template_new()) == NULL)
|
||||
errx(1, "fido_bio_template_new");
|
||||
if (base64_decode(id, &id_blob_ptr, &id_blob_len) < 0)
|
||||
errx(1, "base64_decode");
|
||||
if ((r = fido_bio_template_set_name(t, name)) != FIDO_OK)
|
||||
errx(1, "fido_bio_template_set_name: %s", fido_strerr(r));
|
||||
if ((r = fido_bio_template_set_id(t, id_blob_ptr,
|
||||
id_blob_len)) != FIDO_OK)
|
||||
errx(1, "fido_bio_template_set_id: %s", fido_strerr(r));
|
||||
|
||||
dev = open_dev(path);
|
||||
if ((pin = get_pin(path)) == NULL)
|
||||
goto out;
|
||||
r = fido_bio_dev_set_template_name(dev, t, pin);
|
||||
freezero(pin, PINBUF_LEN);
|
||||
pin = NULL;
|
||||
if (r != FIDO_OK) {
|
||||
warnx("fido_bio_dev_set_template_name: %s", fido_strerr(r));
|
||||
goto out;
|
||||
}
|
||||
|
||||
ok = 0;
|
||||
out:
|
||||
free(id_blob_ptr);
|
||||
fido_bio_template_free(&t);
|
||||
fido_dev_close(dev);
|
||||
fido_dev_free(&dev);
|
||||
|
||||
exit(ok);
|
||||
}
|
||||
|
||||
static const char *
|
||||
enroll_strerr(uint8_t n)
|
||||
{
|
||||
switch (n) {
|
||||
case FIDO_BIO_ENROLL_FP_GOOD:
|
||||
return "Sample ok";
|
||||
case FIDO_BIO_ENROLL_FP_TOO_HIGH:
|
||||
return "Sample too high";
|
||||
case FIDO_BIO_ENROLL_FP_TOO_LOW:
|
||||
return "Sample too low";
|
||||
case FIDO_BIO_ENROLL_FP_TOO_LEFT:
|
||||
return "Sample too left";
|
||||
case FIDO_BIO_ENROLL_FP_TOO_RIGHT:
|
||||
return "Sample too right";
|
||||
case FIDO_BIO_ENROLL_FP_TOO_FAST:
|
||||
return "Sample too fast";
|
||||
case FIDO_BIO_ENROLL_FP_TOO_SLOW:
|
||||
return "Sample too slow";
|
||||
case FIDO_BIO_ENROLL_FP_POOR_QUALITY:
|
||||
return "Poor quality sample";
|
||||
case FIDO_BIO_ENROLL_FP_TOO_SKEWED:
|
||||
return "Sample too skewed";
|
||||
case FIDO_BIO_ENROLL_FP_TOO_SHORT:
|
||||
return "Sample too short";
|
||||
case FIDO_BIO_ENROLL_FP_MERGE_FAILURE:
|
||||
return "Sample merge failure";
|
||||
case FIDO_BIO_ENROLL_FP_EXISTS:
|
||||
return "Sample exists";
|
||||
case FIDO_BIO_ENROLL_FP_DATABASE_FULL:
|
||||
return "Fingerprint database full";
|
||||
case FIDO_BIO_ENROLL_NO_USER_ACTIVITY:
|
||||
return "No user activity";
|
||||
case FIDO_BIO_ENROLL_NO_USER_PRESENCE_TRANSITION:
|
||||
return "No user presence transition";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
bio_enroll(const char *path)
|
||||
{
|
||||
fido_bio_template_t *t = NULL;
|
||||
fido_bio_enroll_t *e = NULL;
|
||||
fido_dev_t *dev = NULL;
|
||||
char *pin = NULL;
|
||||
int r, ok = 1;
|
||||
|
||||
if ((t = fido_bio_template_new()) == NULL)
|
||||
errx(1, "fido_bio_template_new");
|
||||
if ((e = fido_bio_enroll_new()) == NULL)
|
||||
errx(1, "fido_bio_enroll_new");
|
||||
|
||||
dev = open_dev(path);
|
||||
if ((pin = get_pin(path)) == NULL)
|
||||
goto out;
|
||||
printf("Touch your security key.\n");
|
||||
r = fido_bio_dev_enroll_begin(dev, t, e, 10000, pin);
|
||||
freezero(pin, PINBUF_LEN);
|
||||
pin = NULL;
|
||||
if (r != FIDO_OK) {
|
||||
warnx("fido_bio_dev_enroll_begin: %s", fido_strerr(r));
|
||||
goto out;
|
||||
}
|
||||
printf("%s.\n", enroll_strerr(fido_bio_enroll_last_status(e)));
|
||||
|
||||
while (fido_bio_enroll_remaining_samples(e) > 0) {
|
||||
printf("Touch your security key (%u sample%s left).\n",
|
||||
(unsigned)fido_bio_enroll_remaining_samples(e),
|
||||
plural(fido_bio_enroll_remaining_samples(e)));
|
||||
if ((r = fido_bio_dev_enroll_continue(dev, t, e,
|
||||
10000)) != FIDO_OK) {
|
||||
fido_dev_cancel(dev);
|
||||
warnx("fido_bio_dev_enroll_continue: %s",
|
||||
fido_strerr(r));
|
||||
goto out;
|
||||
}
|
||||
printf("%s.\n", enroll_strerr(fido_bio_enroll_last_status(e)));
|
||||
}
|
||||
|
||||
ok = 0;
|
||||
out:
|
||||
fido_bio_template_free(&t);
|
||||
fido_bio_enroll_free(&e);
|
||||
fido_dev_close(dev);
|
||||
fido_dev_free(&dev);
|
||||
|
||||
exit(ok);
|
||||
}
|
||||
|
||||
int
|
||||
bio_delete(const char *path, const char *id)
|
||||
{
|
||||
fido_bio_template_t *t = NULL;
|
||||
fido_dev_t *dev = NULL;
|
||||
char *pin = NULL;
|
||||
void *id_blob_ptr = NULL;
|
||||
size_t id_blob_len = 0;
|
||||
int r, ok = 1;
|
||||
|
||||
if ((t = fido_bio_template_new()) == NULL)
|
||||
errx(1, "fido_bio_template_new");
|
||||
if (base64_decode(id, &id_blob_ptr, &id_blob_len) < 0)
|
||||
errx(1, "base64_decode");
|
||||
if ((r = fido_bio_template_set_id(t, id_blob_ptr,
|
||||
id_blob_len)) != FIDO_OK)
|
||||
errx(1, "fido_bio_template_set_id: %s", fido_strerr(r));
|
||||
|
||||
dev = open_dev(path);
|
||||
if ((pin = get_pin(path)) == NULL)
|
||||
goto out;
|
||||
r = fido_bio_dev_enroll_remove(dev, t, pin);
|
||||
freezero(pin, PINBUF_LEN);
|
||||
pin = NULL;
|
||||
if (r != FIDO_OK) {
|
||||
warnx("fido_bio_dev_enroll_remove: %s", fido_strerr(r));
|
||||
goto out;
|
||||
}
|
||||
|
||||
ok = 0;
|
||||
out:
|
||||
free(id_blob_ptr);
|
||||
fido_bio_template_free(&t);
|
||||
fido_dev_close(dev);
|
||||
fido_dev_free(&dev);
|
||||
|
||||
exit(ok);
|
||||
}
|
||||
|
||||
static const char *
|
||||
type_str(uint8_t t)
|
||||
{
|
||||
switch (t) {
|
||||
case 1:
|
||||
return "touch";
|
||||
case 2:
|
||||
return "swipe";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bio_info(fido_dev_t *dev)
|
||||
{
|
||||
fido_bio_info_t *i = NULL;
|
||||
|
||||
if ((i = fido_bio_info_new()) == NULL) {
|
||||
warnx("fido_bio_info_new");
|
||||
return;
|
||||
}
|
||||
if (fido_bio_dev_get_info(dev, i) != FIDO_OK) {
|
||||
fido_bio_info_free(&i);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("sensor type: %u (%s)\n", (unsigned)fido_bio_info_type(i),
|
||||
type_str(fido_bio_info_type(i)));
|
||||
printf("max samples: %u\n", (unsigned)fido_bio_info_max_samples(i));
|
||||
|
||||
fido_bio_info_free(&i);
|
||||
}
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* 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.
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#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);
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2023 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.
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <fido.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../openbsd-compat/openbsd-compat.h"
|
||||
#include "extern.h"
|
||||
|
||||
static fido_cred_t *
|
||||
prepare_cred(FILE *in_f, int type, int flags)
|
||||
{
|
||||
fido_cred_t *cred = NULL;
|
||||
struct blob cdh;
|
||||
struct blob uid;
|
||||
char *rpid = NULL;
|
||||
char *uname = NULL;
|
||||
int r;
|
||||
|
||||
memset(&cdh, 0, sizeof(cdh));
|
||||
memset(&uid, 0, sizeof(uid));
|
||||
|
||||
r = base64_read(in_f, &cdh);
|
||||
r |= string_read(in_f, &rpid);
|
||||
r |= string_read(in_f, &uname);
|
||||
r |= base64_read(in_f, &uid);
|
||||
if (r < 0)
|
||||
errx(1, "input error");
|
||||
|
||||
if (flags & FLAG_DEBUG) {
|
||||
fprintf(stderr, "client data%s:\n",
|
||||
flags & FLAG_CD ? "" : " hash");
|
||||
xxd(cdh.ptr, cdh.len);
|
||||
fprintf(stderr, "relying party id: %s\n", rpid);
|
||||
fprintf(stderr, "user name: %s\n", uname);
|
||||
fprintf(stderr, "user id:\n");
|
||||
xxd(uid.ptr, uid.len);
|
||||
}
|
||||
|
||||
if ((cred = fido_cred_new()) == NULL)
|
||||
errx(1, "fido_cred_new");
|
||||
|
||||
|
||||
if (flags & FLAG_CD)
|
||||
r = fido_cred_set_clientdata(cred, cdh.ptr, cdh.len);
|
||||
else
|
||||
r = fido_cred_set_clientdata_hash(cred, cdh.ptr, cdh.len);
|
||||
|
||||
if (r != FIDO_OK || (r = fido_cred_set_type(cred, type)) != FIDO_OK ||
|
||||
(r = fido_cred_set_rp(cred, rpid, NULL)) != FIDO_OK ||
|
||||
(r = fido_cred_set_user(cred, uid.ptr, uid.len, uname, NULL,
|
||||
NULL)) != FIDO_OK)
|
||||
errx(1, "fido_cred_set: %s", fido_strerr(r));
|
||||
|
||||
if (flags & FLAG_RK) {
|
||||
if ((r = fido_cred_set_rk(cred, FIDO_OPT_TRUE)) != FIDO_OK)
|
||||
errx(1, "fido_cred_set_rk: %s", fido_strerr(r));
|
||||
}
|
||||
if (flags & FLAG_UV) {
|
||||
if ((r = fido_cred_set_uv(cred, FIDO_OPT_TRUE)) != FIDO_OK)
|
||||
errx(1, "fido_cred_set_uv: %s", fido_strerr(r));
|
||||
}
|
||||
if (flags & FLAG_HMAC) {
|
||||
if ((r = fido_cred_set_extensions(cred,
|
||||
FIDO_EXT_HMAC_SECRET)) != FIDO_OK)
|
||||
errx(1, "fido_cred_set_extensions: %s", fido_strerr(r));
|
||||
}
|
||||
if (flags & FLAG_LARGEBLOB) {
|
||||
if ((r = fido_cred_set_extensions(cred,
|
||||
FIDO_EXT_LARGEBLOB_KEY)) != FIDO_OK)
|
||||
errx(1, "fido_cred_set_extensions: %s", fido_strerr(r));
|
||||
}
|
||||
|
||||
free(cdh.ptr);
|
||||
free(uid.ptr);
|
||||
free(rpid);
|
||||
free(uname);
|
||||
|
||||
return (cred);
|
||||
}
|
||||
|
||||
static void
|
||||
print_attcred(FILE *out_f, const fido_cred_t *cred)
|
||||
{
|
||||
char *cdh = NULL;
|
||||
char *authdata = NULL;
|
||||
char *id = NULL;
|
||||
char *sig = NULL;
|
||||
char *x5c = NULL;
|
||||
char *key = NULL;
|
||||
int r;
|
||||
|
||||
r = base64_encode(fido_cred_clientdata_hash_ptr(cred),
|
||||
fido_cred_clientdata_hash_len(cred), &cdh);
|
||||
r |= base64_encode(fido_cred_authdata_ptr(cred),
|
||||
fido_cred_authdata_len(cred), &authdata);
|
||||
r |= base64_encode(fido_cred_id_ptr(cred), fido_cred_id_len(cred),
|
||||
&id);
|
||||
r |= base64_encode(fido_cred_sig_ptr(cred), fido_cred_sig_len(cred),
|
||||
&sig);
|
||||
if (fido_cred_x5c_ptr(cred) != NULL)
|
||||
r |= base64_encode(fido_cred_x5c_ptr(cred),
|
||||
fido_cred_x5c_len(cred), &x5c);
|
||||
if (fido_cred_largeblob_key_ptr(cred) != NULL)
|
||||
r |= base64_encode(fido_cred_largeblob_key_ptr(cred),
|
||||
fido_cred_largeblob_key_len(cred), &key);
|
||||
if (r < 0)
|
||||
errx(1, "output error");
|
||||
|
||||
fprintf(out_f, "%s\n", cdh);
|
||||
fprintf(out_f, "%s\n", fido_cred_rp_id(cred));
|
||||
fprintf(out_f, "%s\n", fido_cred_fmt(cred));
|
||||
fprintf(out_f, "%s\n", authdata);
|
||||
fprintf(out_f, "%s\n", id);
|
||||
fprintf(out_f, "%s\n", sig);
|
||||
if (x5c != NULL)
|
||||
fprintf(out_f, "%s\n", x5c);
|
||||
if (key != NULL) {
|
||||
fprintf(out_f, "%s\n", key);
|
||||
explicit_bzero(key, strlen(key));
|
||||
}
|
||||
|
||||
free(cdh);
|
||||
free(authdata);
|
||||
free(id);
|
||||
free(sig);
|
||||
free(x5c);
|
||||
free(key);
|
||||
}
|
||||
|
||||
int
|
||||
cred_make(int argc, char **argv)
|
||||
{
|
||||
fido_dev_t *dev = NULL;
|
||||
fido_cred_t *cred = NULL;
|
||||
char prompt[1024];
|
||||
char pin[128];
|
||||
char *in_path = NULL;
|
||||
char *out_path = NULL;
|
||||
FILE *in_f = NULL;
|
||||
FILE *out_f = NULL;
|
||||
int type = COSE_ES256;
|
||||
int flags = 0;
|
||||
int cred_protect = -1;
|
||||
int ch;
|
||||
int r;
|
||||
|
||||
while ((ch = getopt(argc, argv, "bc:dhi:o:qruvw")) != -1) {
|
||||
switch (ch) {
|
||||
case 'b':
|
||||
flags |= FLAG_LARGEBLOB;
|
||||
break;
|
||||
case 'c':
|
||||
if ((cred_protect = base10(optarg)) < 0)
|
||||
errx(1, "-c: invalid argument '%s'", optarg);
|
||||
break;
|
||||
case 'd':
|
||||
flags |= FLAG_DEBUG;
|
||||
break;
|
||||
case 'h':
|
||||
flags |= FLAG_HMAC;
|
||||
break;
|
||||
case 'i':
|
||||
in_path = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
out_path = optarg;
|
||||
break;
|
||||
case 'q':
|
||||
flags |= FLAG_QUIET;
|
||||
break;
|
||||
case 'r':
|
||||
flags |= FLAG_RK;
|
||||
break;
|
||||
case 'u':
|
||||
flags |= FLAG_U2F;
|
||||
break;
|
||||
case 'v':
|
||||
flags |= FLAG_UV;
|
||||
break;
|
||||
case 'w':
|
||||
flags |= FLAG_CD;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1 || argc > 2)
|
||||
usage();
|
||||
|
||||
in_f = open_read(in_path);
|
||||
out_f = open_write(out_path);
|
||||
|
||||
if (argc > 1 && cose_type(argv[1], &type) < 0)
|
||||
errx(1, "unknown type %s", argv[1]);
|
||||
|
||||
fido_init((flags & FLAG_DEBUG) ? FIDO_DEBUG : 0);
|
||||
|
||||
cred = prepare_cred(in_f, type, flags);
|
||||
|
||||
dev = open_dev(argv[0]);
|
||||
if (flags & FLAG_U2F)
|
||||
fido_dev_force_u2f(dev);
|
||||
|
||||
if (cred_protect > 0) {
|
||||
r = fido_cred_set_prot(cred, cred_protect);
|
||||
if (r != FIDO_OK) {
|
||||
errx(1, "fido_cred_set_prot: %s", fido_strerr(r));
|
||||
}
|
||||
}
|
||||
|
||||
r = fido_dev_make_cred(dev, cred, NULL);
|
||||
if (r == FIDO_ERR_PIN_REQUIRED && !(flags & FLAG_QUIET)) {
|
||||
r = snprintf(prompt, sizeof(prompt), "Enter PIN for %s: ",
|
||||
argv[0]);
|
||||
if (r < 0 || (size_t)r >= sizeof(prompt))
|
||||
errx(1, "snprintf");
|
||||
if (!readpassphrase(prompt, pin, sizeof(pin), RPP_ECHO_OFF))
|
||||
errx(1, "readpassphrase");
|
||||
if (strlen(pin) < 4 || strlen(pin) > 63) {
|
||||
explicit_bzero(pin, sizeof(pin));
|
||||
errx(1, "invalid PIN length");
|
||||
}
|
||||
r = fido_dev_make_cred(dev, cred, pin);
|
||||
}
|
||||
|
||||
explicit_bzero(pin, sizeof(pin));
|
||||
if (r != FIDO_OK)
|
||||
errx(1, "fido_dev_make_cred: %s", fido_strerr(r));
|
||||
print_attcred(out_f, cred);
|
||||
|
||||
fido_dev_close(dev);
|
||||
fido_dev_free(&dev);
|
||||
fido_cred_free(&cred);
|
||||
|
||||
fclose(in_f);
|
||||
fclose(out_f);
|
||||
in_f = NULL;
|
||||
out_f = NULL;
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <fido.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../openbsd-compat/openbsd-compat.h"
|
||||
#include "extern.h"
|
||||
|
||||
static fido_cred_t *
|
||||
prepare_cred(FILE *in_f, int type, int flags)
|
||||
{
|
||||
fido_cred_t *cred = NULL;
|
||||
struct blob cdh;
|
||||
struct blob authdata;
|
||||
struct blob id;
|
||||
struct blob sig;
|
||||
struct blob x5c;
|
||||
char *rpid = NULL;
|
||||
char *fmt = NULL;
|
||||
int r;
|
||||
|
||||
memset(&cdh, 0, sizeof(cdh));
|
||||
memset(&authdata, 0, sizeof(authdata));
|
||||
memset(&id, 0, sizeof(id));
|
||||
memset(&sig, 0, sizeof(sig));
|
||||
memset(&x5c, 0, sizeof(x5c));
|
||||
|
||||
r = base64_read(in_f, &cdh);
|
||||
r |= string_read(in_f, &rpid);
|
||||
r |= string_read(in_f, &fmt);
|
||||
r |= base64_read(in_f, &authdata);
|
||||
r |= base64_read(in_f, &id);
|
||||
r |= base64_read(in_f, &sig);
|
||||
if (r < 0)
|
||||
errx(1, "input error");
|
||||
|
||||
(void)base64_read(in_f, &x5c);
|
||||
|
||||
if (flags & FLAG_DEBUG) {
|
||||
fprintf(stderr, "client data hash:\n");
|
||||
xxd(cdh.ptr, cdh.len);
|
||||
fprintf(stderr, "relying party id: %s\n", rpid);
|
||||
fprintf(stderr, "format: %s\n", fmt);
|
||||
fprintf(stderr, "authenticator data:\n");
|
||||
xxd(authdata.ptr, authdata.len);
|
||||
fprintf(stderr, "credential id:\n");
|
||||
xxd(id.ptr, id.len);
|
||||
fprintf(stderr, "signature:\n");
|
||||
xxd(sig.ptr, sig.len);
|
||||
fprintf(stderr, "x509:\n");
|
||||
xxd(x5c.ptr, x5c.len);
|
||||
}
|
||||
|
||||
if ((cred = fido_cred_new()) == NULL)
|
||||
errx(1, "fido_cred_new");
|
||||
|
||||
if ((r = fido_cred_set_type(cred, type)) != FIDO_OK ||
|
||||
(r = fido_cred_set_clientdata_hash(cred, cdh.ptr,
|
||||
cdh.len)) != FIDO_OK ||
|
||||
(r = fido_cred_set_rp(cred, rpid, NULL)) != FIDO_OK ||
|
||||
(r = fido_cred_set_authdata(cred, authdata.ptr,
|
||||
authdata.len)) != FIDO_OK ||
|
||||
(r = fido_cred_set_sig(cred, sig.ptr, sig.len)) != FIDO_OK ||
|
||||
(r = fido_cred_set_fmt(cred, fmt)) != FIDO_OK)
|
||||
errx(1, "fido_cred_set: %s", fido_strerr(r));
|
||||
|
||||
if (x5c.ptr != NULL) {
|
||||
if ((r = fido_cred_set_x509(cred, x5c.ptr, x5c.len)) != FIDO_OK)
|
||||
errx(1, "fido_cred_set_x509: %s", fido_strerr(r));
|
||||
}
|
||||
|
||||
if (flags & FLAG_UV) {
|
||||
if ((r = fido_cred_set_uv(cred, FIDO_OPT_TRUE)) != FIDO_OK)
|
||||
errx(1, "fido_cred_set_uv: %s", fido_strerr(r));
|
||||
}
|
||||
if (flags & FLAG_HMAC) {
|
||||
if ((r = fido_cred_set_extensions(cred,
|
||||
FIDO_EXT_HMAC_SECRET)) != FIDO_OK)
|
||||
errx(1, "fido_cred_set_extensions: %s", fido_strerr(r));
|
||||
}
|
||||
|
||||
free(cdh.ptr);
|
||||
free(authdata.ptr);
|
||||
free(id.ptr);
|
||||
free(sig.ptr);
|
||||
free(x5c.ptr);
|
||||
free(rpid);
|
||||
free(fmt);
|
||||
|
||||
return (cred);
|
||||
}
|
||||
|
||||
int
|
||||
cred_verify(int argc, char **argv)
|
||||
{
|
||||
fido_cred_t *cred = NULL;
|
||||
char *in_path = NULL;
|
||||
char *out_path = NULL;
|
||||
FILE *in_f = NULL;
|
||||
FILE *out_f = NULL;
|
||||
int type = COSE_ES256;
|
||||
int flags = 0;
|
||||
int cred_prot = -1;
|
||||
int ch;
|
||||
int r;
|
||||
|
||||
while ((ch = getopt(argc, argv, "c:dhi:o:v")) != -1) {
|
||||
switch (ch) {
|
||||
case 'c':
|
||||
if ((cred_prot = base10(optarg)) < 0)
|
||||
errx(1, "-c: invalid argument '%s'", optarg);
|
||||
break;
|
||||
case 'd':
|
||||
flags |= FLAG_DEBUG;
|
||||
break;
|
||||
case 'h':
|
||||
flags |= FLAG_HMAC;
|
||||
break;
|
||||
case 'i':
|
||||
in_path = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
out_path = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
flags |= FLAG_UV;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc > 1)
|
||||
usage();
|
||||
|
||||
in_f = open_read(in_path);
|
||||
out_f = open_write(out_path);
|
||||
|
||||
if (argc > 0 && cose_type(argv[0], &type) < 0)
|
||||
errx(1, "unknown type %s", argv[0]);
|
||||
|
||||
fido_init((flags & FLAG_DEBUG) ? FIDO_DEBUG : 0);
|
||||
cred = prepare_cred(in_f, type, flags);
|
||||
|
||||
if (cred_prot > 0) {
|
||||
r = fido_cred_set_prot(cred, cred_prot);
|
||||
if (r != FIDO_OK) {
|
||||
errx(1, "fido_cred_set_prot: %s", fido_strerr(r));
|
||||
}
|
||||
}
|
||||
|
||||
if (fido_cred_x5c_ptr(cred) == NULL) {
|
||||
if ((r = fido_cred_verify_self(cred)) != FIDO_OK)
|
||||
errx(1, "fido_cred_verify_self: %s", fido_strerr(r));
|
||||
} else {
|
||||
if ((r = fido_cred_verify(cred)) != FIDO_OK)
|
||||
errx(1, "fido_cred_verify: %s", fido_strerr(r));
|
||||
}
|
||||
|
||||
print_cred(out_f, type, cred);
|
||||
fido_cred_free(&cred);
|
||||
|
||||
fclose(in_f);
|
||||
fclose(out_f);
|
||||
in_f = NULL;
|
||||
out_f = NULL;
|
||||
|
||||
exit(0);
|
||||
}
|
||||
+330
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright (c) 2019 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.
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <fido.h>
|
||||
#include <fido/credman.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../openbsd-compat/openbsd-compat.h"
|
||||
#include "extern.h"
|
||||
|
||||
int
|
||||
credman_get_metadata(fido_dev_t *dev, const char *path)
|
||||
{
|
||||
fido_credman_metadata_t *metadata = NULL;
|
||||
char *pin = NULL;
|
||||
int r, ok = 1;
|
||||
|
||||
if ((metadata = fido_credman_metadata_new()) == NULL) {
|
||||
warnx("fido_credman_metadata_new");
|
||||
goto out;
|
||||
}
|
||||
if ((r = fido_credman_get_dev_metadata(dev, metadata,
|
||||
NULL)) != FIDO_OK && should_retry_with_pin(dev, r)) {
|
||||
if ((pin = get_pin(path)) == NULL)
|
||||
goto out;
|
||||
r = fido_credman_get_dev_metadata(dev, metadata, pin);
|
||||
freezero(pin, PINBUF_LEN);
|
||||
pin = NULL;
|
||||
}
|
||||
if (r != FIDO_OK) {
|
||||
warnx("fido_credman_get_dev_metadata: %s", fido_strerr(r));
|
||||
goto out;
|
||||
}
|
||||
|
||||
printf("existing rk(s): %u\n",
|
||||
(unsigned)fido_credman_rk_existing(metadata));
|
||||
printf("remaining rk(s): %u\n",
|
||||
(unsigned)fido_credman_rk_remaining(metadata));
|
||||
|
||||
ok = 0;
|
||||
out:
|
||||
fido_credman_metadata_free(&metadata);
|
||||
fido_dev_close(dev);
|
||||
fido_dev_free(&dev);
|
||||
|
||||
exit(ok);
|
||||
}
|
||||
|
||||
static int
|
||||
print_rp(fido_credman_rp_t *rp, size_t idx)
|
||||
{
|
||||
char *rp_id_hash = NULL;
|
||||
|
||||
if (base64_encode(fido_credman_rp_id_hash_ptr(rp, idx),
|
||||
fido_credman_rp_id_hash_len(rp, idx), &rp_id_hash) < 0) {
|
||||
warnx("output error");
|
||||
return -1;
|
||||
}
|
||||
printf("%02u: %s %s\n", (unsigned)idx, rp_id_hash,
|
||||
fido_credman_rp_id(rp, idx));
|
||||
free(rp_id_hash);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
credman_list_rp(const char *path)
|
||||
{
|
||||
fido_credman_rp_t *rp = NULL;
|
||||
fido_dev_t *dev = NULL;
|
||||
char *pin = NULL;
|
||||
int r, ok = 1;
|
||||
|
||||
dev = open_dev(path);
|
||||
if ((rp = fido_credman_rp_new()) == NULL) {
|
||||
warnx("fido_credman_rp_new");
|
||||
goto out;
|
||||
}
|
||||
if ((r = fido_credman_get_dev_rp(dev, rp, NULL)) != FIDO_OK &&
|
||||
should_retry_with_pin(dev, r)) {
|
||||
if ((pin = get_pin(path)) == NULL)
|
||||
goto out;
|
||||
r = fido_credman_get_dev_rp(dev, rp, pin);
|
||||
freezero(pin, PINBUF_LEN);
|
||||
pin = NULL;
|
||||
}
|
||||
if (r != FIDO_OK) {
|
||||
warnx("fido_credman_get_dev_rp: %s", fido_strerr(r));
|
||||
goto out;
|
||||
}
|
||||
for (size_t i = 0; i < fido_credman_rp_count(rp); i++)
|
||||
if (print_rp(rp, i) < 0)
|
||||
goto out;
|
||||
|
||||
ok = 0;
|
||||
out:
|
||||
fido_credman_rp_free(&rp);
|
||||
fido_dev_close(dev);
|
||||
fido_dev_free(&dev);
|
||||
|
||||
exit(ok);
|
||||
}
|
||||
|
||||
static int
|
||||
print_rk(const fido_credman_rk_t *rk, size_t idx)
|
||||
{
|
||||
const fido_cred_t *cred;
|
||||
char *id = NULL;
|
||||
char *user_id = NULL;
|
||||
const char *type;
|
||||
const char *prot;
|
||||
|
||||
if ((cred = fido_credman_rk(rk, idx)) == NULL) {
|
||||
warnx("fido_credman_rk");
|
||||
return -1;
|
||||
}
|
||||
if (base64_encode(fido_cred_id_ptr(cred), fido_cred_id_len(cred),
|
||||
&id) < 0 || base64_encode(fido_cred_user_id_ptr(cred),
|
||||
fido_cred_user_id_len(cred), &user_id) < 0) {
|
||||
warnx("output error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
type = cose_string(fido_cred_type(cred));
|
||||
prot = prot_string(fido_cred_prot(cred));
|
||||
|
||||
printf("%02u: %s %s %s %s %s\n", (unsigned)idx, id,
|
||||
fido_cred_display_name(cred), user_id, type, prot);
|
||||
|
||||
free(user_id);
|
||||
free(id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
credman_list_rk(const char *path, const char *rp_id)
|
||||
{
|
||||
fido_dev_t *dev = NULL;
|
||||
fido_credman_rk_t *rk = NULL;
|
||||
char *pin = NULL;
|
||||
int r, ok = 1;
|
||||
|
||||
dev = open_dev(path);
|
||||
if ((rk = fido_credman_rk_new()) == NULL) {
|
||||
warnx("fido_credman_rk_new");
|
||||
goto out;
|
||||
}
|
||||
if ((r = fido_credman_get_dev_rk(dev, rp_id, rk, NULL)) != FIDO_OK &&
|
||||
should_retry_with_pin(dev, r)) {
|
||||
if ((pin = get_pin(path)) == NULL)
|
||||
goto out;
|
||||
r = fido_credman_get_dev_rk(dev, rp_id, rk, pin);
|
||||
freezero(pin, PINBUF_LEN);
|
||||
pin = NULL;
|
||||
}
|
||||
if (r != FIDO_OK) {
|
||||
warnx("fido_credman_get_dev_rk: %s", fido_strerr(r));
|
||||
goto out;
|
||||
}
|
||||
for (size_t i = 0; i < fido_credman_rk_count(rk); i++)
|
||||
if (print_rk(rk, i) < 0)
|
||||
goto out;
|
||||
|
||||
ok = 0;
|
||||
out:
|
||||
fido_credman_rk_free(&rk);
|
||||
fido_dev_close(dev);
|
||||
fido_dev_free(&dev);
|
||||
|
||||
exit(ok);
|
||||
}
|
||||
|
||||
int
|
||||
credman_print_rk(fido_dev_t *dev, const char *path, const char *rp_id,
|
||||
const char *cred_id)
|
||||
{
|
||||
fido_credman_rk_t *rk = NULL;
|
||||
const fido_cred_t *cred = NULL;
|
||||
char *pin = NULL;
|
||||
void *cred_id_ptr = NULL;
|
||||
size_t cred_id_len = 0;
|
||||
int r, ok = 1;
|
||||
|
||||
if ((rk = fido_credman_rk_new()) == NULL) {
|
||||
warnx("fido_credman_rk_new");
|
||||
goto out;
|
||||
}
|
||||
if (base64_decode(cred_id, &cred_id_ptr, &cred_id_len) < 0) {
|
||||
warnx("base64_decode");
|
||||
goto out;
|
||||
}
|
||||
if ((r = fido_credman_get_dev_rk(dev, rp_id, rk, NULL)) != FIDO_OK &&
|
||||
should_retry_with_pin(dev, r)) {
|
||||
if ((pin = get_pin(path)) == NULL)
|
||||
goto out;
|
||||
r = fido_credman_get_dev_rk(dev, rp_id, rk, pin);
|
||||
freezero(pin, PINBUF_LEN);
|
||||
pin = NULL;
|
||||
}
|
||||
if (r != FIDO_OK) {
|
||||
warnx("fido_credman_get_dev_rk: %s", fido_strerr(r));
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < fido_credman_rk_count(rk); i++) {
|
||||
if ((cred = fido_credman_rk(rk, i)) == NULL ||
|
||||
fido_cred_id_ptr(cred) == NULL) {
|
||||
warnx("output error");
|
||||
goto out;
|
||||
}
|
||||
if (cred_id_len != fido_cred_id_len(cred) ||
|
||||
memcmp(cred_id_ptr, fido_cred_id_ptr(cred), cred_id_len))
|
||||
continue;
|
||||
print_cred(stdout, fido_cred_type(cred), cred);
|
||||
ok = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
warnx("credential not found");
|
||||
out:
|
||||
free(cred_id_ptr);
|
||||
fido_credman_rk_free(&rk);
|
||||
fido_dev_close(dev);
|
||||
fido_dev_free(&dev);
|
||||
|
||||
exit(ok);
|
||||
}
|
||||
|
||||
int
|
||||
credman_delete_rk(const char *path, const char *id)
|
||||
{
|
||||
fido_dev_t *dev = NULL;
|
||||
char *pin = NULL;
|
||||
void *id_ptr = NULL;
|
||||
size_t id_len = 0;
|
||||
int r, ok = 1;
|
||||
|
||||
dev = open_dev(path);
|
||||
if (base64_decode(id, &id_ptr, &id_len) < 0) {
|
||||
warnx("base64_decode");
|
||||
goto out;
|
||||
}
|
||||
if ((r = fido_credman_del_dev_rk(dev, id_ptr, id_len,
|
||||
NULL)) != FIDO_OK && should_retry_with_pin(dev, r)) {
|
||||
if ((pin = get_pin(path)) == NULL)
|
||||
goto out;
|
||||
r = fido_credman_del_dev_rk(dev, id_ptr, id_len, pin);
|
||||
freezero(pin, PINBUF_LEN);
|
||||
pin = NULL;
|
||||
}
|
||||
if (r != FIDO_OK) {
|
||||
warnx("fido_credman_del_dev_rk: %s", fido_strerr(r));
|
||||
goto out;
|
||||
}
|
||||
|
||||
ok = 0;
|
||||
out:
|
||||
free(id_ptr);
|
||||
fido_dev_close(dev);
|
||||
fido_dev_free(&dev);
|
||||
|
||||
exit(ok);
|
||||
}
|
||||
|
||||
int
|
||||
credman_update_rk(const char *path, const char *user_id, const char *cred_id,
|
||||
const char *name, const char *display_name)
|
||||
{
|
||||
fido_dev_t *dev = NULL;
|
||||
fido_cred_t *cred = NULL;
|
||||
char *pin = NULL;
|
||||
void *user_id_ptr = NULL;
|
||||
void *cred_id_ptr = NULL;
|
||||
size_t user_id_len = 0;
|
||||
size_t cred_id_len = 0;
|
||||
int r, ok = 1;
|
||||
|
||||
dev = open_dev(path);
|
||||
if (base64_decode(user_id, &user_id_ptr, &user_id_len) < 0 ||
|
||||
base64_decode(cred_id, &cred_id_ptr, &cred_id_len) < 0) {
|
||||
warnx("base64_decode");
|
||||
goto out;
|
||||
}
|
||||
if ((cred = fido_cred_new()) == NULL) {
|
||||
warnx("fido_cred_new");
|
||||
goto out;
|
||||
}
|
||||
if ((r = fido_cred_set_id(cred, cred_id_ptr, cred_id_len)) != FIDO_OK) {
|
||||
warnx("fido_cred_set_id: %s", fido_strerr(r));
|
||||
goto out;
|
||||
}
|
||||
if ((r = fido_cred_set_user(cred, user_id_ptr, user_id_len, name,
|
||||
display_name, NULL)) != FIDO_OK) {
|
||||
warnx("fido_cred_set_user: %s", fido_strerr(r));
|
||||
goto out;
|
||||
}
|
||||
if ((r = fido_credman_set_dev_rk(dev, cred, NULL)) != FIDO_OK &&
|
||||
should_retry_with_pin(dev, r)) {
|
||||
if ((pin = get_pin(path)) == NULL)
|
||||
goto out;
|
||||
r = fido_credman_set_dev_rk(dev, cred, pin);
|
||||
freezero(pin, PINBUF_LEN);
|
||||
pin = NULL;
|
||||
}
|
||||
if (r != FIDO_OK) {
|
||||
warnx("fido_credman_set_dev_rk: %s", fido_strerr(r));
|
||||
goto out;
|
||||
}
|
||||
|
||||
ok = 0;
|
||||
out:
|
||||
free(user_id_ptr);
|
||||
free(cred_id_ptr);
|
||||
fido_dev_close(dev);
|
||||
fido_dev_free(&dev);
|
||||
fido_cred_free(&cred);
|
||||
|
||||
exit(ok);
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2023 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.
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#ifndef _EXTERN_H_
|
||||
#define _EXTERN_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/ec.h>
|
||||
|
||||
#include <fido.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct blob {
|
||||
unsigned char *ptr;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
#define TOKEN_OPT "CDGILPRSVabcdefi:k:l:m:n:p:w:ru"
|
||||
|
||||
#define FLAG_DEBUG 0x001
|
||||
#define FLAG_QUIET 0x002
|
||||
#define FLAG_RK 0x004
|
||||
#define FLAG_UV 0x008
|
||||
#define FLAG_U2F 0x010
|
||||
#define FLAG_HMAC 0x020
|
||||
#define FLAG_UP 0x040
|
||||
#define FLAG_LARGEBLOB 0x080
|
||||
#define FLAG_CD 0x100
|
||||
extern char* global_pin;
|
||||
#define PINBUF_LEN 256
|
||||
|
||||
EC_KEY *read_ec_pubkey(const char *);
|
||||
fido_dev_t *open_dev(const char *);
|
||||
FILE *open_read(const char *);
|
||||
FILE *open_write(const char *);
|
||||
char *get_pin(const char *);
|
||||
const char *plural(size_t);
|
||||
const char *cose_string(int);
|
||||
const char *prot_string(int);
|
||||
int assert_get(int, char **);
|
||||
int assert_verify(int, char **);
|
||||
int base64_decode(const char *, void **, size_t *);
|
||||
int base64_encode(const void *, size_t, char **);
|
||||
int base64_read(FILE *, struct blob *);
|
||||
int bio_delete(const char *, const char *);
|
||||
int bio_enroll(const char *);
|
||||
void bio_info(fido_dev_t *);
|
||||
int bio_list(const char *);
|
||||
int bio_set_name(const char *, const char *, const char *);
|
||||
int blob_clean(const char *);
|
||||
int blob_list(const char *);
|
||||
int blob_delete(const char *, const char *, const char *, const char *);
|
||||
int blob_get(const char *, const char *, const char *, const char *,
|
||||
const char *);
|
||||
int blob_set(const char *, const char *, const char *, const char *,
|
||||
const char *);
|
||||
int config_always_uv(char *, int);
|
||||
int config_entattest(char *);
|
||||
int config_force_pin_change(char *);
|
||||
int config_pin_minlen(char *, const char *);
|
||||
int config_pin_minlen_rpid(char *, const char *);
|
||||
int cose_type(const char *, int *);
|
||||
int cred_make(int, char **);
|
||||
int cred_verify(int, char **);
|
||||
int credman_delete_rk(const char *, const char *);
|
||||
int credman_update_rk(const char *, const char *, const char *, const char *,
|
||||
const char *);
|
||||
int credman_get_metadata(fido_dev_t *, const char *);
|
||||
int credman_list_rk(const char *, const char *);
|
||||
int credman_list_rp(const char *);
|
||||
int credman_print_rk(fido_dev_t *, const char *, const char *, const char *);
|
||||
int get_devopt(fido_dev_t *, const char *, int *);
|
||||
int pin_change(char *);
|
||||
int pin_set(char *);
|
||||
int should_retry_with_pin(const fido_dev_t *, int);
|
||||
int string_read(FILE *, char **);
|
||||
int token_config(int, char **, char *);
|
||||
int token_delete(int, char **, char *);
|
||||
int token_get(int, char **, char *);
|
||||
int token_info(int, char **, char *);
|
||||
int token_list(int, char **, char *);
|
||||
int token_reset(char *);
|
||||
int token_set(int, char **, char *);
|
||||
int write_es256_pubkey(FILE *, const void *, size_t);
|
||||
int write_es384_pubkey(FILE *, const void *, size_t);
|
||||
int write_rsa_pubkey(FILE *, const void *, size_t);
|
||||
int read_file(const char *, u_char **, size_t *);
|
||||
int write_file(const char *, const u_char *, size_t);
|
||||
RSA *read_rsa_pubkey(const char *);
|
||||
EVP_PKEY *read_eddsa_pubkey(const char *);
|
||||
int write_eddsa_pubkey(FILE *, const void *, size_t);
|
||||
void print_cred(FILE *, int, const fido_cred_t *);
|
||||
void usage(void);
|
||||
void xxd(const void *, size_t);
|
||||
int base10(const char *);
|
||||
|
||||
#endif /* _EXTERN_H_ */
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
# 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.
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
DEV=""
|
||||
|
||||
while [ -z "${DEV}" ]; do
|
||||
sleep .5
|
||||
DEV="$(fido2-token -L | sed 's/^\(.*\): .*$/\1/;q')"
|
||||
done
|
||||
|
||||
printf '%s\n' "${DEV}"
|
||||
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
# 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.
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
DEV="$(fido2-token -L | sed 's/^\(.*\): .*$/\1/;q')"
|
||||
|
||||
while [ -n "${DEV}" ]; do
|
||||
sleep .5
|
||||
DEV="$(fido2-token -L | sed 's/^\(.*\): .*$/\1/;q')"
|
||||
done
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <fido.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../openbsd-compat/openbsd-compat.h"
|
||||
#include "extern.h"
|
||||
|
||||
static int action;
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: fido2-token -C [-d] device\n"
|
||||
" fido2-token -Db [-k key_path] [-i cred_id -n rp_id] device\n"
|
||||
" fido2-token -Dei template_id device\n"
|
||||
" fido2-token -Du device\n"
|
||||
" fido2-token -Gb [-k key_path] [-i cred_id -n rp_id] blob_path device\n"
|
||||
" fido2-token -I [-cd] [-k rp_id -i cred_id] device\n"
|
||||
" fido2-token -L [-bder] [-k rp_id] [device]\n"
|
||||
" fido2-token -R [-d] device\n"
|
||||
" fido2-token -S [-adefu] [-l pin_length] [-i template_id -n template_name] device\n"
|
||||
" fido2-token -Sb [-k key_path] [-i cred_id -n rp_id] blob_path device\n"
|
||||
" fido2-token -Sc -i cred_id -k user_id -n name -p display_name device\n"
|
||||
" fido2-token -Sm rp_id device\n"
|
||||
" fido2-token -V\n"
|
||||
);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char* global_pin = NULL;
|
||||
|
||||
static void
|
||||
setaction(int ch)
|
||||
{
|
||||
if (action)
|
||||
usage();
|
||||
action = ch;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ch;
|
||||
int flags = 0;
|
||||
char *device;
|
||||
|
||||
|
||||
// Parse command line arguments
|
||||
for (int i = 1; i < argc - 1; i++) {
|
||||
if (strcmp(argv[i], "-w") == 0) {
|
||||
// Set global_pin from command line argument
|
||||
global_pin = strdup(argv[i + 1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while ((ch = getopt(argc, argv, TOKEN_OPT)) != -1) {
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'e':
|
||||
case 'f':
|
||||
case 'i':
|
||||
case 'k':
|
||||
case 'l':
|
||||
case 'm':
|
||||
case 'n':
|
||||
case 'w':
|
||||
case 'p':
|
||||
case 'r':
|
||||
case 'u':
|
||||
break; /* ignore */
|
||||
case 'd':
|
||||
flags = FIDO_DEBUG;
|
||||
break;
|
||||
default:
|
||||
setaction(ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc - optind < 1)
|
||||
device = NULL;
|
||||
else
|
||||
device = argv[argc - 1];
|
||||
|
||||
fido_init(flags);
|
||||
|
||||
switch (action) {
|
||||
case 'C':
|
||||
return (pin_change(device));
|
||||
case 'D':
|
||||
return (token_delete(argc, argv, device));
|
||||
case 'G':
|
||||
return (token_get(argc, argv, device));
|
||||
case 'I':
|
||||
return (token_info(argc, argv, device));
|
||||
case 'L':
|
||||
return (token_list(argc, argv, device));
|
||||
case 'R':
|
||||
return (token_reset(device));
|
||||
case 'S':
|
||||
return (token_set(argc, argv, device));
|
||||
case 'V':
|
||||
fprintf(stderr, "%d.%d.%d\n", _FIDO_MAJOR, _FIDO_MINOR,
|
||||
_FIDO_PATCH);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
usage();
|
||||
|
||||
/* NOTREACHED */
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2020 Fabian Henneke.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
|
||||
if [ $(uname) != "Linux" ] ; then
|
||||
echo "Can only run on Linux"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TOKEN_VERSION=$(${FIDO_TOOLS_PREFIX}fido2-token -V 2>&1)
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "Please install libfido2 1.5.0 or higher"
|
||||
exit
|
||||
fi
|
||||
|
||||
TOKEN_VERSION_MAJOR=$(echo "$TOKEN_VERSION" | cut -d. -f1)
|
||||
TOKEN_VERSION_MINOR=$(echo "$TOKEN_VERSION" | cut -d. -f2)
|
||||
if [ $TOKEN_VERSION_MAJOR -eq 0 -o $TOKEN_VERSION_MAJOR -eq 1 -a $TOKEN_VERSION_MINOR -lt 5 ] ; then
|
||||
echo "Please install libfido2 1.5.0 or higher (current version: $TOKEN_VERSION)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
TOKEN_OUTPUT=$(${FIDO_TOOLS_PREFIX}fido2-token -L)
|
||||
DEV_PATH_NAMES=$(echo "$TOKEN_OUTPUT" | sed -r 's/^(.*): .*\((.*)\)$/\1 \2/g')
|
||||
DEV_COUNT=$(echo "$DEV_PATH_NAMES" | wc -l)
|
||||
|
||||
for i in $(seq 1 $DEV_COUNT)
|
||||
do
|
||||
DEV_PATH_NAME=$(echo "$DEV_PATH_NAMES" | sed "${i}q;d")
|
||||
DEV_PATH=$(echo "$DEV_PATH_NAME" | cut -d' ' -f1)
|
||||
DEV_NAME=$(echo "$DEV_PATH_NAME" | cut -d' ' -f1 --complement)
|
||||
DEV_PRETTY=$(echo "$DEV_NAME (at '$DEV_PATH')")
|
||||
if expr match "$(${FIDO_TOOLS_PREFIX}fido2-token -I $DEV_PATH)" ".* credMgmt.* clientPin.*\|.* clientPin.* credMgmt.*" > /dev/null ; then
|
||||
printf "Enter PIN for $DEV_PRETTY once (ignore further prompts): "
|
||||
stty -echo
|
||||
read PIN
|
||||
stty echo
|
||||
printf "\n"
|
||||
RESIDENT_RPS=$(echo "${PIN}\n" | setsid -w ${FIDO_TOOLS_PREFIX}fido2-token -L -r $DEV_PATH | cut -d' ' -f3)
|
||||
printf "\n"
|
||||
RESIDENT_RPS_COUNT=$(echo "$RESIDENT_RPS" | wc -l)
|
||||
FOUND=0
|
||||
for j in $(seq 1 $DEV_RESIDENT_RPS_COUNT)
|
||||
do
|
||||
RESIDENT_RP=$(echo "$RESIDENT_RPS" | sed "${j}q;d")
|
||||
UNPROT_CREDS=$(echo "${PIN}\n" | setsid -w ${FIDO_TOOLS_PREFIX}fido2-token -L -k $RESIDENT_RP $DEV_PATH | grep ' uvopt$' | cut -d' ' -f2,3,4)
|
||||
printf "\n"
|
||||
UNPROT_CREDS_COUNT=$(echo "$UNPROT_CREDS" | wc -l)
|
||||
if [ $UNPROT_CREDS_COUNT -gt 0 ] ; then
|
||||
FOUND=1
|
||||
echo "Unprotected credentials on $DEV_PRETTY for '$RESIDENT_RP':"
|
||||
echo "$UNPROT_CREDS"
|
||||
fi
|
||||
done
|
||||
if [ $FOUND -eq 0 ] ; then
|
||||
echo "No unprotected credentials on $DEV_PRETTY"
|
||||
fi
|
||||
else
|
||||
echo "$DEV_PRETTY cannot enumerate credentials"
|
||||
echo "Discovering unprotected SSH credentials only..."
|
||||
STUB_HASH=$(echo -n "" | openssl sha256 -binary | base64)
|
||||
printf "$STUB_HASH\nssh:\n" | ${FIDO_TOOLS_PREFIX}fido2-assert -G -r -t up=false $DEV_PATH 2> /dev/null || ASSERT_EXIT_CODE=$?
|
||||
if [ $ASSERT_EXIT_CODE -eq 0 ] ; then
|
||||
echo "Found an unprotected SSH credential on $DEV_PRETTY!"
|
||||
else
|
||||
echo "No unprotected SSH credentials (default settings) on $DEV_PRETTY"
|
||||
fi
|
||||
fi
|
||||
printf "\n"
|
||||
done
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2019 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.
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
check() {
|
||||
for f in $(find $1 -maxdepth 1 -name '*.h'); do
|
||||
echo "#include \"$f\"" | \
|
||||
cc $CFLAGS -Isrc -xc -c - -o /dev/null 2>&1
|
||||
echo "$f $CFLAGS $?"
|
||||
done
|
||||
}
|
||||
|
||||
check examples
|
||||
check fuzz
|
||||
check openbsd-compat
|
||||
CFLAGS="${CFLAGS} -D_FIDO_INTERNAL" check src
|
||||
check src/fido.h
|
||||
check src/fido
|
||||
check tools
|
||||
File diff suppressed because it is too large
Load Diff
+159
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <fido.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../openbsd-compat/openbsd-compat.h"
|
||||
#include "extern.h"
|
||||
|
||||
int
|
||||
pin_set(char *path)
|
||||
{
|
||||
fido_dev_t *dev = NULL;
|
||||
char prompt[1024];
|
||||
char pin1[128];
|
||||
char pin2[128];
|
||||
int r;
|
||||
int status = 1;
|
||||
|
||||
dev = open_dev(path);
|
||||
|
||||
r = snprintf(prompt, sizeof(prompt), "Enter new PIN for %s: ", path);
|
||||
if (r < 0 || (size_t)r >= sizeof(prompt)) {
|
||||
warnx("snprintf");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!readpassphrase(prompt, pin1, sizeof(pin1), RPP_ECHO_OFF)) {
|
||||
warnx("readpassphrase");
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = snprintf(prompt, sizeof(prompt), "Enter the same PIN again: ");
|
||||
if (r < 0 || (size_t)r >= sizeof(prompt)) {
|
||||
warnx("snprintf");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!readpassphrase(prompt, pin2, sizeof(pin2), RPP_ECHO_OFF)) {
|
||||
warnx("readpassphrase");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strcmp(pin1, pin2) != 0) {
|
||||
fprintf(stderr, "PINs do not match. Try again.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strlen(pin1) < 4 || strlen(pin1) > 63) {
|
||||
fprintf(stderr, "invalid PIN length\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((r = fido_dev_set_pin(dev, pin1, NULL)) != FIDO_OK) {
|
||||
warnx("fido_dev_set_pin: %s", fido_strerr(r));
|
||||
goto out;
|
||||
}
|
||||
|
||||
fido_dev_close(dev);
|
||||
fido_dev_free(&dev);
|
||||
|
||||
status = 0;
|
||||
out:
|
||||
explicit_bzero(pin1, sizeof(pin1));
|
||||
explicit_bzero(pin2, sizeof(pin2));
|
||||
|
||||
exit(status);
|
||||
}
|
||||
|
||||
int
|
||||
pin_change(char *path)
|
||||
{
|
||||
fido_dev_t *dev = NULL;
|
||||
char prompt[1024];
|
||||
char pin0[128];
|
||||
char pin1[128];
|
||||
char pin2[128];
|
||||
int r;
|
||||
int status = 1;
|
||||
|
||||
if (path == NULL)
|
||||
usage();
|
||||
|
||||
dev = open_dev(path);
|
||||
|
||||
r = snprintf(prompt, sizeof(prompt), "Enter current PIN for %s: ", path);
|
||||
if (r < 0 || (size_t)r >= sizeof(prompt)) {
|
||||
warnx("snprintf");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!readpassphrase(prompt, pin0, sizeof(pin0), RPP_ECHO_OFF)) {
|
||||
warnx("readpassphrase");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strlen(pin0) < 4 || strlen(pin0) > 63) {
|
||||
warnx("invalid PIN length");
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = snprintf(prompt, sizeof(prompt), "Enter new PIN for %s: ", path);
|
||||
if (r < 0 || (size_t)r >= sizeof(prompt)) {
|
||||
warnx("snprintf");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!readpassphrase(prompt, pin1, sizeof(pin1), RPP_ECHO_OFF)) {
|
||||
warnx("readpassphrase");
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = snprintf(prompt, sizeof(prompt), "Enter the same PIN again: ");
|
||||
if (r < 0 || (size_t)r >= sizeof(prompt)) {
|
||||
warnx("snprintf");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!readpassphrase(prompt, pin2, sizeof(pin2), RPP_ECHO_OFF)) {
|
||||
warnx("readpassphrase");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strcmp(pin1, pin2) != 0) {
|
||||
fprintf(stderr, "PINs do not match. Try again.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strlen(pin1) < 4 || strlen(pin1) > 63) {
|
||||
fprintf(stderr, "invalid PIN length\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((r = fido_dev_set_pin(dev, pin1, pin0)) != FIDO_OK) {
|
||||
warnx("fido_dev_set_pin: %s", fido_strerr(r));
|
||||
goto out;
|
||||
}
|
||||
|
||||
fido_dev_close(dev);
|
||||
fido_dev_free(&dev);
|
||||
|
||||
status = 0;
|
||||
out:
|
||||
explicit_bzero(pin0, sizeof(pin0));
|
||||
explicit_bzero(pin1, sizeof(pin1));
|
||||
explicit_bzero(pin2, sizeof(pin2));
|
||||
|
||||
exit(status);
|
||||
}
|
||||
+304
@@ -0,0 +1,304 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
# Copyright (c) 2021-2022 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.
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
# usage: ./test.sh "$(mktemp -d fido2test-XXXXXXXX)" device
|
||||
|
||||
# Please note that this test script:
|
||||
# - is incomplete;
|
||||
# - assumes CTAP 2.1-like hmac-secret;
|
||||
# - should pass as-is on a YubiKey with a PIN set;
|
||||
# - may otherwise require set +e above;
|
||||
# - can be executed with UV=1 to run additional UV tests;
|
||||
# - was last tested on 2022-01-11 with firmware 5.4.3.
|
||||
|
||||
cd "$1"
|
||||
DEV="$2"
|
||||
TYPE="es256"
|
||||
#TYPE="es384"
|
||||
#TYPE="eddsa"
|
||||
|
||||
make_cred() {
|
||||
sed /^$/d > cred_param << EOF
|
||||
$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64)
|
||||
$1
|
||||
some user name
|
||||
$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64)
|
||||
EOF
|
||||
fido2-cred -M $2 "${DEV}" "${TYPE}" > "$3" < cred_param
|
||||
}
|
||||
|
||||
verify_cred() {
|
||||
fido2-cred -V $1 "${TYPE}" > cred_out < "$2"
|
||||
head -1 cred_out > "$3"
|
||||
tail -n +2 cred_out > "$4"
|
||||
}
|
||||
|
||||
get_assert() {
|
||||
sed /^$/d > assert_param << EOF
|
||||
$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64)
|
||||
$1
|
||||
$(cat $3)
|
||||
$(cat $4)
|
||||
EOF
|
||||
fido2-assert -G $2 "${DEV}" > "$5" < assert_param
|
||||
}
|
||||
|
||||
verify_assert() {
|
||||
fido2-assert -V $1 "$2" "${TYPE}" < "$3"
|
||||
}
|
||||
|
||||
dd if=/dev/urandom bs=32 count=1 | base64 > hmac-salt
|
||||
|
||||
# u2f
|
||||
if [ "x${TYPE}" = "xes256" ]; then
|
||||
make_cred no.tld "-u" u2f
|
||||
! make_cred no.tld "-ru" /dev/null
|
||||
! make_cred no.tld "-uc1" /dev/null
|
||||
! make_cred no.tld "-uc2" /dev/null
|
||||
verify_cred "--" u2f u2f-cred u2f-pubkey
|
||||
! verify_cred "-h" u2f /dev/null /dev/null
|
||||
! verify_cred "-v" u2f /dev/null /dev/null
|
||||
verify_cred "-c0" u2f /dev/null /dev/null
|
||||
! verify_cred "-c1" u2f /dev/null /dev/null
|
||||
! verify_cred "-c2" u2f /dev/null /dev/null
|
||||
! verify_cred "-c3" u2f /dev/null /dev/null
|
||||
fi
|
||||
|
||||
# wrap (non-resident)
|
||||
make_cred no.tld "--" wrap
|
||||
verify_cred "--" wrap wrap-cred wrap-pubkey
|
||||
! verify_cred "-h" wrap /dev/null /dev/null
|
||||
! verify_cred "-v" wrap /dev/null /dev/null
|
||||
verify_cred "-c0" wrap /dev/null /dev/null
|
||||
! verify_cred "-c1" wrap /dev/null /dev/null
|
||||
! verify_cred "-c2" wrap /dev/null /dev/null
|
||||
! verify_cred "-c3" wrap /dev/null /dev/null
|
||||
|
||||
# wrap (non-resident) + hmac-secret
|
||||
make_cred no.tld "-h" wrap-hs
|
||||
! verify_cred "--" wrap-hs /dev/null /dev/null
|
||||
verify_cred "-h" wrap-hs wrap-hs-cred wrap-hs-pubkey
|
||||
! verify_cred "-v" wrap-hs /dev/null /dev/null
|
||||
verify_cred "-hc0" wrap-hs /dev/null /dev/null
|
||||
! verify_cred "-c0" wrap-hs /dev/null /dev/null
|
||||
! verify_cred "-c1" wrap-hs /dev/null /dev/null
|
||||
! verify_cred "-c2" wrap-hs /dev/null /dev/null
|
||||
! verify_cred "-c3" wrap-hs /dev/null /dev/null
|
||||
|
||||
# resident
|
||||
make_cred no.tld "-r" rk
|
||||
verify_cred "--" rk rk-cred rk-pubkey
|
||||
! verify_cred "-h" rk /dev/null /dev/null
|
||||
! verify_cred "-v" rk /dev/null /dev/null
|
||||
verify_cred "-c0" rk /dev/null /dev/null
|
||||
! verify_cred "-c1" rk /dev/null /dev/null
|
||||
! verify_cred "-c2" rk /dev/null /dev/null
|
||||
! verify_cred "-c3" rk /dev/null /dev/null
|
||||
|
||||
# resident + hmac-secret
|
||||
make_cred no.tld "-hr" rk-hs
|
||||
! verify_cred "--" rk-hs rk-hs-cred rk-hs-pubkey
|
||||
verify_cred "-h" rk-hs /dev/null /dev/null
|
||||
! verify_cred "-v" rk-hs /dev/null /dev/null
|
||||
verify_cred "-hc0" rk-hs /dev/null /dev/null
|
||||
! verify_cred "-c0" rk-hs /dev/null /dev/null
|
||||
! verify_cred "-c1" rk-hs /dev/null /dev/null
|
||||
! verify_cred "-c2" rk-hs /dev/null /dev/null
|
||||
! verify_cred "-c3" rk-hs /dev/null /dev/null
|
||||
|
||||
# u2f
|
||||
if [ "x${TYPE}" = "xes256" ]; then
|
||||
get_assert no.tld "-u" u2f-cred /dev/null u2f-assert
|
||||
! get_assert no.tld "-u -t up=false" u2f-cred /dev/null /dev/null
|
||||
verify_assert "--" u2f-pubkey u2f-assert
|
||||
verify_assert "-p" u2f-pubkey u2f-assert
|
||||
fi
|
||||
|
||||
# wrap (non-resident)
|
||||
get_assert no.tld "--" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "--" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t pin=true" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "--" wrap-pubkey wrap-assert
|
||||
verify_assert "-v" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t pin=false" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "--" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=true" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "-p" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=true -t pin=true" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "--" wrap-pubkey wrap-assert
|
||||
verify_assert "-p" wrap-pubkey wrap-assert
|
||||
verify_assert "-v" wrap-pubkey wrap-assert
|
||||
verify_assert "-pv" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=true -t pin=false" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "--" wrap-pubkey wrap-assert
|
||||
verify_assert "-p" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=false" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "--" wrap-pubkey wrap-assert
|
||||
! verify_assert "-p" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=false -t pin=true" wrap-cred /dev/null wrap-assert
|
||||
! verify_assert "-p" wrap-pubkey wrap-assert
|
||||
verify_assert "-v" wrap-pubkey wrap-assert
|
||||
! verify_assert "-pv" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=false -t pin=false" wrap-cred /dev/null wrap-assert
|
||||
! verify_assert "-p" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h" wrap-cred hmac-salt wrap-assert
|
||||
! verify_assert "--" wrap-pubkey wrap-assert
|
||||
verify_assert "-h" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t pin=true" wrap-cred hmac-salt wrap-assert
|
||||
! verify_assert "--" wrap-pubkey wrap-assert
|
||||
verify_assert "-h" wrap-pubkey wrap-assert
|
||||
verify_assert "-hv" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t pin=false" wrap-cred hmac-salt wrap-assert
|
||||
! verify_assert "--" wrap-pubkey wrap-assert
|
||||
verify_assert "-h" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t up=true" wrap-cred hmac-salt wrap-assert
|
||||
! verify_assert "--" wrap-pubkey wrap-assert
|
||||
verify_assert "-h" wrap-pubkey wrap-assert
|
||||
verify_assert "-hp" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t up=true -t pin=true" wrap-cred hmac-salt wrap-assert
|
||||
! verify_assert "--" wrap-pubkey wrap-assert
|
||||
verify_assert "-h" wrap-pubkey wrap-assert
|
||||
verify_assert "-hp" wrap-pubkey wrap-assert
|
||||
verify_assert "-hv" wrap-pubkey wrap-assert
|
||||
verify_assert "-hpv" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t up=true -t pin=false" wrap-cred hmac-salt wrap-assert
|
||||
! verify_assert "--" wrap-pubkey wrap-assert
|
||||
verify_assert "-h" wrap-pubkey wrap-assert
|
||||
verify_assert "-hp" wrap-pubkey wrap-assert
|
||||
! get_assert no.tld "-h -t up=false" wrap-cred hmac-salt wrap-assert
|
||||
! get_assert no.tld "-h -t up=false -t pin=true" wrap-cred hmac-salt wrap-assert
|
||||
! get_assert no.tld "-h -t up=false -t pin=false" wrap-cred hmac-salt wrap-assert
|
||||
|
||||
if [ "x${UV}" != "x" ]; then
|
||||
get_assert no.tld "-t uv=true" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "-v" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t uv=true -t pin=true" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "-v" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t uv=true -t pin=false" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "-v" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t uv=false" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "--" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t uv=false -t pin=true" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "-v" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t uv=false -t pin=false" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "--" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=true -t uv=true" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "-pv" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=true -t uv=true -t pin=true" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "-pv" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=true -t uv=true -t pin=false" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "-pv" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=true -t uv=false" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "-p" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=true -t uv=false -t pin=true" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "-pv" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=true -t uv=false -t pin=false" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "-p" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=false -t uv=true" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "-v" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=false -t uv=true -t pin=true" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "-v" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=false -t uv=true -t pin=false" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "-v" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=false -t uv=false" wrap-cred /dev/null wrap-assert
|
||||
! verify_assert "--" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=false -t uv=false -t pin=true" wrap-cred /dev/null wrap-assert
|
||||
verify_assert "-v" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-t up=false -t uv=false -t pin=false" wrap-cred /dev/null wrap-assert
|
||||
! verify_assert "--" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t uv=true" wrap-cred hmac-salt wrap-assert
|
||||
verify_assert "-hv" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t uv=true -t pin=true" wrap-cred hmac-salt wrap-assert
|
||||
verify_assert "-hv" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t uv=true -t pin=false" wrap-cred hmac-salt wrap-assert
|
||||
verify_assert "-hv" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t uv=false" wrap-cred hmac-salt wrap-assert
|
||||
verify_assert "-h" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t uv=false -t pin=true" wrap-cred hmac-salt wrap-assert
|
||||
verify_assert "-hv" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t uv=false -t pin=false" wrap-cred hmac-salt wrap-assert
|
||||
verify_assert "-h" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t up=true -t uv=true" wrap-cred hmac-salt wrap-assert
|
||||
verify_assert "-hpv" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t up=true -t uv=true -t pin=true" wrap-cred hmac-salt wrap-assert
|
||||
verify_assert "-hpv" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t up=true -t uv=true -t pin=false" wrap-cred hmac-salt wrap-assert
|
||||
verify_assert "-hpv" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t up=true -t uv=false" wrap-cred hmac-salt wrap-assert
|
||||
verify_assert "-hp" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t up=true -t uv=false -t pin=true" wrap-cred hmac-salt wrap-assert
|
||||
verify_assert "-hpv" wrap-pubkey wrap-assert
|
||||
get_assert no.tld "-h -t up=true -t uv=false -t pin=false" wrap-cred hmac-salt wrap-assert
|
||||
verify_assert "-hp" wrap-pubkey wrap-assert
|
||||
! get_assert no.tld "-h -t up=false -t uv=true" wrap-cred hmac-salt wrap-assert
|
||||
! get_assert no.tld "-h -t up=false -t uv=true -t pin=true" wrap-cred hmac-salt wrap-assert
|
||||
! get_assert no.tld "-h -t up=false -t uv=true -t pin=false" wrap-cred hmac-salt wrap-assert
|
||||
! get_assert no.tld "-h -t up=false -t uv=false" wrap-cred hmac-salt wrap-assert
|
||||
! get_assert no.tld "-h -t up=false -t uv=false -t pin=true" wrap-cred hmac-salt wrap-assert
|
||||
! get_assert no.tld "-h -t up=false -t uv=false -t pin=false" wrap-cred hmac-salt wrap-assert
|
||||
fi
|
||||
|
||||
# resident
|
||||
get_assert no.tld "-r" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t pin=true" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t pin=false" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=true" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=true -t pin=true" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=true -t pin=false" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=false" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=false -t pin=true" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=false -t pin=false" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -h" /dev/null hmac-salt wrap-assert
|
||||
get_assert no.tld "-r -h -t pin=true" /dev/null hmac-salt wrap-assert
|
||||
get_assert no.tld "-r -h -t pin=false" /dev/null hmac-salt wrap-assert
|
||||
get_assert no.tld "-r -h -t up=true" /dev/null hmac-salt wrap-assert
|
||||
get_assert no.tld "-r -h -t up=true -t pin=true" /dev/null hmac-salt wrap-assert
|
||||
get_assert no.tld "-r -h -t up=true -t pin=false" /dev/null hmac-salt wrap-assert
|
||||
! get_assert no.tld "-r -h -t up=false" /dev/null hmac-salt wrap-assert
|
||||
! get_assert no.tld "-r -h -t up=false -t pin=true" /dev/null hmac-salt wrap-assert
|
||||
! get_assert no.tld "-r -h -t up=false -t pin=false" /dev/null hmac-salt wrap-assert
|
||||
|
||||
if [ "x${UV}" != "x" ]; then
|
||||
get_assert no.tld "-r -t uv=true" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t uv=true -t pin=true" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t uv=true -t pin=false" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t uv=false" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t uv=false -t pin=true" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t uv=false -t pin=false" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=true -t uv=true" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=true -t uv=true -t pin=true" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=true -t uv=true -t pin=false" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=true -t uv=false" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=true -t uv=false -t pin=true" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=true -t uv=false -t pin=false" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=false -t uv=true" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=false -t uv=true -t pin=true" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=false -t uv=true -t pin=false" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=false -t uv=false" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=false -t uv=false -t pin=true" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -t up=false -t uv=false -t pin=false" /dev/null /dev/null wrap-assert
|
||||
get_assert no.tld "-r -h -t uv=true" /dev/null hmac-salt wrap-assert
|
||||
get_assert no.tld "-r -h -t uv=true -t pin=true" /dev/null hmac-salt wrap-assert
|
||||
get_assert no.tld "-r -h -t uv=true -t pin=false" /dev/null hmac-salt wrap-assert
|
||||
get_assert no.tld "-r -h -t uv=false" /dev/null hmac-salt wrap-assert
|
||||
get_assert no.tld "-r -h -t uv=false -t pin=true" /dev/null hmac-salt wrap-assert
|
||||
get_assert no.tld "-r -h -t uv=false -t pin=false" /dev/null hmac-salt wrap-assert
|
||||
get_assert no.tld "-r -h -t up=true -t uv=true" /dev/null hmac-salt wrap-assert
|
||||
get_assert no.tld "-r -h -t up=true -t uv=true -t pin=true" /dev/null hmac-salt wrap-assert
|
||||
get_assert no.tld "-r -h -t up=true -t uv=true -t pin=false" /dev/null hmac-salt wrap-assert
|
||||
get_assert no.tld "-r -h -t up=true -t uv=false" /dev/null hmac-salt wrap-assert
|
||||
get_assert no.tld "-r -h -t up=true -t uv=false -t pin=true" /dev/null hmac-salt wrap-assert
|
||||
get_assert no.tld "-r -h -t up=true -t uv=false -t pin=false" /dev/null hmac-salt wrap-assert
|
||||
! get_assert no.tld "-r -h -t up=false -t uv=true" /dev/null hmac-salt wrap-assert
|
||||
! get_assert no.tld "-r -h -t up=false -t uv=true -t pin=true" /dev/null hmac-salt wrap-assert
|
||||
! get_assert no.tld "-r -h -t up=false -t uv=true -t pin=false" /dev/null hmac-salt wrap-assert
|
||||
! get_assert no.tld "-r -h -t up=false -t uv=false" /dev/null hmac-salt wrap-assert
|
||||
! get_assert no.tld "-r -h -t up=false -t uv=false -t pin=true" /dev/null hmac-salt wrap-assert
|
||||
! get_assert no.tld "-r -h -t up=false -t uv=false -t pin=false" /dev/null hmac-salt wrap-assert
|
||||
fi
|
||||
|
||||
exit 0
|
||||
+738
File diff suppressed because it is too large
Load Diff
+655
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user