Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cred: support for enterprise attestation #824

Merged
merged 17 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ The following examples are provided:
The -T option may be used to enforce a timeout of <seconds>. If the
option -b is specified, the credential's "largeBlob" key is stored in
<blobkey>. If the option -c is specified the the generated credential
will be bound by the specified protection policy.
will be bound by the specified protection policy. If the option -a is
specified, enterprise attestation will be requested.

- assert [-t es256|es384|rs256|eddsa] [-a cred_id] [-h hmac_secret] [-P pin]
[-s hmac_salt] [-T seconds] [-b blobkey] [-puv] <pubkey> <device>
Expand Down
19 changes: 15 additions & 4 deletions examples/cred.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2023 Yubico AB. All rights reserved.
* Copyright (c) 2018-2024 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
Expand Down Expand Up @@ -36,7 +36,8 @@ static void
usage(void)
{
fprintf(stderr, "usage: cred [-t es256|es384|rs256|eddsa] [-k pubkey] "
"[-ei cred_id] [-P pin] [-T seconds] [-b blobkey] [-c cred_protect] [-hruv] "
"[-ei cred_id] [-P pin] [-T seconds] [-b blobkey] [-c cred_protect] "
"[-a mode] [-hruv] "
"<device>\n");
exit(EXIT_FAILURE);
}
Expand Down Expand Up @@ -166,11 +167,12 @@ main(int argc, char **argv)
int ch;
int r;
long long cred_protect = 0;
long long ea = 0;

if ((cred = fido_cred_new()) == NULL)
errx(1, "fido_cred_new");

while ((ch = getopt(argc, argv, "P:T:b:e:hi:k:rt:uvc:")) != -1) {
while ((ch = getopt(argc, argv, "P:T:a:b:e:hi:k:rt:uvc:")) != -1) {
switch (ch) {
case 'P':
pin = optarg;
Expand All @@ -182,6 +184,12 @@ main(int argc, char **argv)
errx(1, "-T: %s must be in (0,30]", optarg);
ms *= 1000; /* seconds to milliseconds */
break;
case 'a':
if (base10(optarg, &ea) < 0)
errx(1, "base10: %s", optarg);
if (ea <= 0 || ea > 2)
errx(1, "-a: %s must be in (0,2]", optarg);
break;
case 'b':
ext |= FIDO_EXT_LARGEBLOB_KEY;
blobkey_out = optarg;
Expand All @@ -203,7 +211,7 @@ main(int argc, char **argv)
if (base10(optarg, &cred_protect) < 0)
errx(1, "base10: %s", optarg);
if (cred_protect <= 0 || cred_protect > 3)
errx(1, "-c: %s must be in (1,3)", optarg);
errx(1, "-c: %s must be in (0,3]", optarg);
ext |= FIDO_EXT_CRED_PROTECT;
break;
case 'i':
Expand Down Expand Up @@ -293,6 +301,9 @@ main(int argc, char **argv)
if (cred_protect != 0 && (r = fido_cred_set_prot(cred,
(int)cred_protect)) != FIDO_OK)
errx(1, "fido_cred_set_prot: %s (0x%x)", fido_strerr(r), r);

if (ea != 0 && (r = fido_cred_set_entattest(cred, (int)ea)) != FIDO_OK)
errx(1, "fido_cred_set_entattest: %s (0x%x)", fido_strerr(r), r);

/* timeout */
if (ms != 0 && (r = fido_dev_set_timeout(dev, (int)ms)) != FIDO_OK)
Expand Down
2 changes: 2 additions & 0 deletions fuzz/export.gnu
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
fido_cred_clientdata_hash_len;
fido_cred_clientdata_hash_ptr;
fido_cred_display_name;
fido_cred_entattest;
fido_cred_exclude;
fido_cred_flags;
fido_cred_largeblob_key_len;
Expand Down Expand Up @@ -172,6 +173,7 @@
fido_cred_set_blob;
fido_cred_set_clientdata;
fido_cred_set_clientdata_hash;
fido_cred_set_entattest;
fido_cred_set_extensions;
fido_cred_set_fmt;
fido_cred_set_id;
Expand Down
8 changes: 7 additions & 1 deletion fuzz/fuzz_cred.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2022 Yubico AB. All rights reserved.
* Copyright (c) 2019-2024 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
Expand Down Expand Up @@ -248,6 +248,8 @@ make_cred(fido_cred_t *cred, uint8_t opt, int type, const struct blob *cdh,
fido_cred_set_uv(cred, FIDO_OPT_TRUE);
if (user_id->len)
fido_cred_set_prot(cred, user_id->body[0] & 0x03);
if (excl_cred->len)
fido_cred_set_entattest(cred, excl_cred->body[0] & 0x03);

/* repeat memory operations to trigger reallocation paths */
fido_cred_set_type(cred, type);
Expand Down Expand Up @@ -279,6 +281,7 @@ verify_cred(int type, const unsigned char *cdh_ptr, size_t cdh_len,
uint8_t flags;
uint32_t sigcount;
int r;
bool ea;

if ((cred = fido_cred_new()) == NULL)
return;
Expand Down Expand Up @@ -348,6 +351,9 @@ verify_cred(int type, const unsigned char *cdh_ptr, size_t cdh_len,
minpinlen = fido_cred_pin_minlen(cred);
consume(&minpinlen, sizeof(minpinlen));

ea = fido_cred_entattest(cred);
consume(&ea, sizeof(ea));

fido_cred_free(&cred);
}

Expand Down
2 changes: 2 additions & 0 deletions man/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ list(APPEND MAN_ALIAS
fido_cred_new fido_cred_clientdata_hash_len
fido_cred_new fido_cred_clientdata_hash_ptr
fido_cred_new fido_cred_display_name
fido_cred_new fido_cred_entattest
fido_cred_new fido_cred_flags
fido_cred_new fido_cred_fmt
fido_cred_new fido_cred_free
Expand Down Expand Up @@ -216,6 +217,7 @@ list(APPEND MAN_ALIAS
fido_cred_set_authdata fido_cred_set_blob
fido_cred_set_authdata fido_cred_set_clientdata
fido_cred_set_authdata fido_cred_set_clientdata_hash
fido_cred_set_authdata fido_cred_set_entattest
fido_cred_set_authdata fido_cred_set_extensions
fido_cred_set_authdata fido_cred_set_fmt
fido_cred_set_authdata fido_cred_set_id
Expand Down
8 changes: 7 additions & 1 deletion man/fido2-cred.1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.\" Copyright (c) 2018-2023 Yubico AB. All rights reserved.
.\" Copyright (c) 2018-2024 Yubico AB. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions are
Expand Down Expand Up @@ -35,6 +35,7 @@
.Nm
.Fl M
.Op Fl bdhqruvw
.Op Fl a Ar mode
.Op Fl c Ar cred_protect
.Op Fl i Ar input_file
.Op Fl o Ar output_file
Expand Down Expand Up @@ -120,6 +121,11 @@ to verify a credential.
Request the credential's
.Dq largeBlobKey ,
a 32-byte symmetric key associated with the generated credential.
.It Fl a Ar mode
When making a credential, request enterprise attestation.
Please refer to
.In fido/param.h
for the set of possible values.
.It Fl c Ar cred_protect
If making a credential, set the credential's protection level to
.Ar cred_protect ,
Expand Down
10 changes: 10 additions & 0 deletions man/fido_cred_new.3
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
.Nm fido_cred_x5c_list_len ,
.Nm fido_cred_x5c_len ,
.Nm fido_cred_attstmt_len ,
.Nm fido_cred_entattest ,
.Nm fido_cred_type ,
.Nm fido_cred_flags ,
.Nm fido_cred_sigcount
Expand Down Expand Up @@ -137,6 +138,8 @@
.Fn fido_cred_x5c_len "const fido_cred_t *cred"
.Ft size_t
.Fn fido_cred_attstmt_len "const fido_cred_t *cred"
.Ft bool
.Fn fido_cred_entattest "const fido_cred_t *cred"
.Ft int
.Fn fido_cred_type "const fido_cred_t *cred"
.Ft uint8_t
Expand Down Expand Up @@ -309,6 +312,13 @@ The authenticator data, x509 certificate, and signature parts of a
credential are typically passed to a FIDO2 server for verification.
.Pp
The
.Fn fido_cred_entattest
function returns
.Dv true
if an enterprise attestation was returned for
.Fa cred .
.Pp
The
.Fn fido_cred_type
function returns the COSE algorithm of
.Fa cred .
Expand Down
20 changes: 19 additions & 1 deletion man/fido_cred_set_authdata.3
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.\" Copyright (c) 2018-2022 Yubico AB. All rights reserved.
.\" Copyright (c) 2018-2024 Yubico AB. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions are
Expand Down Expand Up @@ -40,6 +40,7 @@
.Nm fido_cred_set_clientdata_hash ,
.Nm fido_cred_set_rp ,
.Nm fido_cred_set_user ,
.Nm fido_cred_set_entattest ,
.Nm fido_cred_set_extensions ,
.Nm fido_cred_set_blob ,
.Nm fido_cred_set_pin_minlen ,
Expand Down Expand Up @@ -81,6 +82,8 @@ typedef enum {
.Ft int
.Fn fido_cred_set_user "fido_cred_t *cred" "const unsigned char *user_id" "size_t user_id_len" "const char *name" "const char *display_name" "const char *icon"
.Ft int
.Fn fido_cred_set_entattest "fido_cred_t *cred" "int ea"
.Ft int
.Fn fido_cred_set_extensions "fido_cred_t *cred" "int flags"
.Ft int
.Fn fido_cred_set_blob "fido_cred_t *cred" "const unsigned char *ptr" "size_t len"
Expand Down Expand Up @@ -243,6 +246,21 @@ and
parameters may be NULL.
.Pp
The
.Fn fido_cred_set_entattest
function sets the enterprise attestation mode of
.Fa cred
to
.Fa ea .
At the moment, only the
.Dv FIDO_ENTATTEST_VENDOR
and
.Dv FIDO_ENTATTEST_PLATFORM
modes are supported.
By default, or if
.Fa ea
is zero, no enterprise attestation is requested.
.Pp
The
.Fn fido_cred_set_extensions
function sets the extensions of
.Fa cred
Expand Down
29 changes: 16 additions & 13 deletions regress/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
# Copyright (c) 2018-2022 Yubico AB. All rights reserved.
# Copyright (c) 2018-2024 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

add_custom_target(regress)

macro(add_regress_test NAME SOURCES LIB)
add_executable(${NAME} ${SOURCES})
function(add_regress_test NAME)
set(MULTIVAL_KEYWORDS "SOURCES" "LIBS")
cmake_parse_arguments(PARSE_ARGV 1 arg "" "" "${MULTIVAL_KEYWORDS}")
add_executable(${NAME} ${arg_SOURCES})
add_test(${NAME} ${NAME})
add_dependencies(regress ${NAME})
target_link_libraries(${NAME} ${LIB})
endmacro()
target_link_libraries(${NAME} ${arg_LIBS})
endfunction()

if(MSVC AND BUILD_SHARED_LIBS)
add_custom_command(TARGET regress POST_BUILD
Expand Down Expand Up @@ -40,18 +42,19 @@ else()
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
endif()

add_regress_test(regress_assert assert.c ${_FIDO2_LIBRARY})
add_regress_test(regress_cred cred.c ${_FIDO2_LIBRARY})
add_regress_test(regress_dev dev.c ${_FIDO2_LIBRARY})
add_regress_test(regress_eddsa eddsa.c ${_FIDO2_LIBRARY})
add_regress_test(regress_es256 es256.c ${_FIDO2_LIBRARY})
add_regress_test(regress_es384 es384.c ${_FIDO2_LIBRARY})
add_regress_test(regress_rs256 rs256.c ${_FIDO2_LIBRARY})
add_regress_test(regress_assert SOURCES assert.c LIBS ${_FIDO2_LIBRARY})
add_regress_test(regress_cred SOURCES cred.c mock.c LIBS ${_FIDO2_LIBRARY})
add_regress_test(regress_dev SOURCES dev.c mock.c LIBS ${_FIDO2_LIBRARY})
add_regress_test(regress_eddsa SOURCES eddsa.c LIBS ${_FIDO2_LIBRARY})
add_regress_test(regress_es256 SOURCES es256.c LIBS ${_FIDO2_LIBRARY})
add_regress_test(regress_es384 SOURCES es384.c LIBS ${_FIDO2_LIBRARY})
add_regress_test(regress_rs256 SOURCES rs256.c LIBS ${_FIDO2_LIBRARY})
if(BUILD_STATIC_LIBS)
add_regress_test(regress_compress compress.c fido2)
add_regress_test(regress_compress SOURCES compress.c LIBS fido2)
endif()

if(MINGW)
# needed for nanosleep() in mingw
target_link_libraries(regress_dev winpthread)
target_link_libraries(regress_cred winpthread)
endif()
Loading
Loading