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

Set attestation object containing CBOR encoded authData, fmt and attStmt #782

Merged
merged 6 commits into from
Mar 20, 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
2 changes: 1 addition & 1 deletion .actions/fuzz-linux
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ mkdir corpus
curl -s https://storage.googleapis.com/yubico-libfido2/corpus.tgz |
tar -C corpus -zxf -
export UBSAN_OPTIONS ASAN_OPTIONS MSAN_OPTIONS
for f in assert bio cred credman hid largeblob mgmt netlink pcsc; do
for f in assert attobj bio cred credman hid largeblob mgmt netlink pcsc; do
build/fuzz/fuzz_${f} -use_value_profile=1 -reload=30 -print_pcs=1 \
-print_funcs=30 -timeout=10 -runs=1 corpus/fuzz_${f}
done
9 changes: 8 additions & 1 deletion fuzz/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2019-2023 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 @@ -80,3 +80,10 @@ set_target_properties(fuzz_pcsc PROPERTIES
LINK_FLAGS ${FUZZ_LDFLAGS}
LINKER_LANGUAGE ${FUZZ_LINKER_LANGUAGE})
target_link_libraries(fuzz_pcsc fido2_shared)

# fuzz_attobj
add_executable(fuzz_attobj fuzz_attobj.c ${COMMON_SOURCES} ${COMPAT_SOURCES})
set_target_properties(fuzz_attobj PROPERTIES
LINK_FLAGS ${FUZZ_LDFLAGS}
LINKER_LANGUAGE ${FUZZ_LINKER_LANGUAGE})
target_link_libraries(fuzz_attobj fido2_shared)
1 change: 1 addition & 0 deletions fuzz/export.gnu
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@
fido_cred_rp_id;
fido_cred_rp_name;
fido_cred_set_attstmt;
fido_cred_set_attobj;
fido_cred_set_authdata;
fido_cred_set_authdata_raw;
fido_cred_set_blob;
Expand Down
332 changes: 332 additions & 0 deletions fuzz/fuzz_attobj.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,332 @@
/*
* Copyright (c) 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
*/

#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "mutator_aux.h"
#include "wiredata_fido2.h"
#include "wiredata_u2f.h"
#include "dummy.h"

#include "../openbsd-compat/openbsd-compat.h"

struct param {
int seed;
char rp_id[MAXSTR];
struct blob cdh;
struct blob attobj;
uint8_t type;
};

static const uint8_t dummy_attestation_object[] = {
0xa3, 0x63, 0x66, 0x6d, 0x74, 0x66, 0x70, 0x61,
0x63, 0x6b, 0x65, 0x64, 0x67, 0x61, 0x74, 0x74,
0x53, 0x74, 0x6d, 0x74, 0xa3, 0x63, 0x61, 0x6c,
0x67, 0x26, 0x63, 0x73, 0x69, 0x67, 0x58, 0x46,
0x30, 0x44, 0x02, 0x20, 0x54, 0x92, 0x28, 0x3b,
0x83, 0x33, 0x47, 0x56, 0x68, 0x79, 0xb2, 0x0c,
0x84, 0x80, 0xcc, 0x67, 0x27, 0x8b, 0xfa, 0x48,
0x43, 0x0d, 0x3c, 0xb4, 0x02, 0x36, 0x87, 0x97,
0x3e, 0xdf, 0x2f, 0x65, 0x02, 0x20, 0x1b, 0x56,
0x17, 0x06, 0xe2, 0x26, 0x0f, 0x6a, 0xe9, 0xa9,
0x70, 0x99, 0x62, 0xeb, 0x3a, 0x04, 0x1a, 0xc4,
0xa7, 0x03, 0x28, 0x56, 0x7c, 0xed, 0x47, 0x08,
0x68, 0x73, 0x6a, 0xb6, 0x89, 0x0d, 0x63, 0x78,
0x35, 0x63, 0x81, 0x59, 0x02, 0xe6, 0x30, 0x82,
0x02, 0xe2, 0x30, 0x81, 0xcb, 0x02, 0x01, 0x01,
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55,
0x04, 0x03, 0x13, 0x12, 0x59, 0x75, 0x62, 0x69,
0x63, 0x6f, 0x20, 0x55, 0x32, 0x46, 0x20, 0x54,
0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e,
0x17, 0x0d, 0x31, 0x34, 0x30, 0x35, 0x31, 0x35,
0x31, 0x32, 0x35, 0x38, 0x35, 0x34, 0x5a, 0x17,
0x0d, 0x31, 0x34, 0x30, 0x36, 0x31, 0x34, 0x31,
0x32, 0x35, 0x38, 0x35, 0x34, 0x5a, 0x30, 0x1d,
0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04,
0x03, 0x13, 0x12, 0x59, 0x75, 0x62, 0x69, 0x63,
0x6f, 0x20, 0x55, 0x32, 0x46, 0x20, 0x54, 0x65,
0x73, 0x74, 0x20, 0x45, 0x45, 0x30, 0x59, 0x30,
0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d,
0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04,
0xdb, 0x0a, 0xdb, 0xf5, 0x21, 0xc7, 0x5c, 0xce,
0x63, 0xdc, 0xa6, 0xe1, 0xe8, 0x25, 0x06, 0x0d,
0x94, 0xe6, 0x27, 0x54, 0x19, 0x4f, 0x9d, 0x24,
0xaf, 0x26, 0x1a, 0xbe, 0xad, 0x99, 0x44, 0x1f,
0x95, 0xa3, 0x71, 0x91, 0x0a, 0x3a, 0x20, 0xe7,
0x3e, 0x91, 0x5e, 0x13, 0xe8, 0xbe, 0x38, 0x05,
0x7a, 0xd5, 0x7a, 0xa3, 0x7e, 0x76, 0x90, 0x8f,
0xaf, 0xe2, 0x8a, 0x94, 0xb6, 0x30, 0xeb, 0x9d,
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
0x82, 0x02, 0x01, 0x00, 0x95, 0x40, 0x6b, 0x50,
0x61, 0x7d, 0xad, 0x84, 0xa3, 0xb4, 0xeb, 0x88,
0x0f, 0xe3, 0x30, 0x0f, 0x2d, 0xa2, 0x0a, 0x00,
0xd9, 0x25, 0x04, 0xee, 0x72, 0xfa, 0x67, 0xdf,
0x58, 0x51, 0x0f, 0x0b, 0x47, 0x02, 0x9c, 0x3e,
0x41, 0x29, 0x4a, 0x93, 0xac, 0x29, 0x85, 0x89,
0x2d, 0xa4, 0x7a, 0x81, 0x32, 0x28, 0x57, 0x71,
0x01, 0xef, 0xa8, 0x42, 0x88, 0x16, 0x96, 0x37,
0x91, 0xd5, 0xdf, 0xe0, 0x8f, 0xc9, 0x3c, 0x8d,
0xb0, 0xcd, 0x89, 0x70, 0x82, 0xec, 0x79, 0xd3,
0xc6, 0x78, 0x73, 0x29, 0x32, 0xe5, 0xab, 0x6c,
0xbd, 0x56, 0x9f, 0xd5, 0x45, 0x91, 0xce, 0xc1,
0xdd, 0x8d, 0x64, 0xdc, 0xe9, 0x9c, 0x1f, 0x5e,
0x3c, 0xd2, 0xaf, 0x51, 0xa5, 0x82, 0x18, 0xaf,
0xe0, 0x37, 0xe7, 0x32, 0x9e, 0x76, 0x05, 0x77,
0x02, 0x7b, 0xe6, 0x24, 0xa0, 0x31, 0x56, 0x1b,
0xfd, 0x19, 0xc5, 0x71, 0xd3, 0xf0, 0x9e, 0xc0,
0x73, 0x05, 0x4e, 0xbc, 0x85, 0xb8, 0x53, 0x9e,
0xef, 0xc5, 0xbc, 0x9c, 0x56, 0xa3, 0xba, 0xd9,
0x27, 0x6a, 0xbb, 0xa9, 0x7a, 0x40, 0xd7, 0x47,
0x8b, 0x55, 0x72, 0x6b, 0xe3, 0xfe, 0x28, 0x49,
0x71, 0x24, 0xf4, 0x8f, 0xf4, 0x20, 0x81, 0xea,
0x38, 0xff, 0x7c, 0x0a, 0x4f, 0xdf, 0x02, 0x82,
0x39, 0x81, 0x82, 0x3b, 0xca, 0x09, 0xdd, 0xca,
0xaa, 0x0f, 0x27, 0xf5, 0xa4, 0x83, 0x55, 0x6c,
0x9a, 0x39, 0x9b, 0x15, 0x3a, 0x16, 0x63, 0xdc,
0x5b, 0xf9, 0xac, 0x5b, 0xbc, 0xf7, 0x9f, 0xbe,
0x0f, 0x8a, 0xa2, 0x3c, 0x31, 0x13, 0xa3, 0x32,
0x48, 0xca, 0x58, 0x87, 0xf8, 0x7b, 0xa0, 0xa1,
0x0a, 0x6a, 0x60, 0x96, 0x93, 0x5f, 0x5d, 0x26,
0x9e, 0x63, 0x1d, 0x09, 0xae, 0x9a, 0x41, 0xe5,
0xbd, 0x08, 0x47, 0xfe, 0xe5, 0x09, 0x9b, 0x20,
0xfd, 0x12, 0xe2, 0xe6, 0x40, 0x7f, 0xba, 0x4a,
0x61, 0x33, 0x66, 0x0d, 0x0e, 0x73, 0xdb, 0xb0,
0xd5, 0xa2, 0x9a, 0x9a, 0x17, 0x0d, 0x34, 0x30,
0x85, 0x6a, 0x42, 0x46, 0x9e, 0xff, 0x34, 0x8f,
0x5f, 0x87, 0x6c, 0x35, 0xe7, 0xa8, 0x4d, 0x35,
0xeb, 0xc1, 0x41, 0xaa, 0x8a, 0xd2, 0xda, 0x19,
0xaa, 0x79, 0xa2, 0x5f, 0x35, 0x2c, 0xa0, 0xfd,
0x25, 0xd3, 0xf7, 0x9d, 0x25, 0x18, 0x2d, 0xfa,
0xb4, 0xbc, 0xbb, 0x07, 0x34, 0x3c, 0x8d, 0x81,
0xbd, 0xf4, 0xe9, 0x37, 0xdb, 0x39, 0xe9, 0xd1,
0x45, 0x5b, 0x20, 0x41, 0x2f, 0x2d, 0x27, 0x22,
0xdc, 0x92, 0x74, 0x8a, 0x92, 0xd5, 0x83, 0xfd,
0x09, 0xfb, 0x13, 0x9b, 0xe3, 0x39, 0x7a, 0x6b,
0x5c, 0xfa, 0xe6, 0x76, 0x9e, 0xe0, 0xe4, 0xe3,
0xef, 0xad, 0xbc, 0xfd, 0x42, 0x45, 0x9a, 0xd4,
0x94, 0xd1, 0x7e, 0x8d, 0xa7, 0xd8, 0x05, 0xd5,
0xd3, 0x62, 0xcf, 0x15, 0xcf, 0x94, 0x7d, 0x1f,
0x5b, 0x58, 0x20, 0x44, 0x20, 0x90, 0x71, 0xbe,
0x66, 0xe9, 0x9a, 0xab, 0x74, 0x32, 0x70, 0x53,
0x1d, 0x69, 0xed, 0x87, 0x66, 0xf4, 0x09, 0x4f,
0xca, 0x25, 0x30, 0xc2, 0x63, 0x79, 0x00, 0x3c,
0xb1, 0x9b, 0x39, 0x3f, 0x00, 0xe0, 0xa8, 0x88,
0xef, 0x7a, 0x51, 0x5b, 0xe7, 0xbd, 0x49, 0x64,
0xda, 0x41, 0x7b, 0x24, 0xc3, 0x71, 0x22, 0xfd,
0xd1, 0xd1, 0x20, 0xb3, 0x3f, 0x97, 0xd3, 0x97,
0xb2, 0xaa, 0x18, 0x1c, 0x9e, 0x03, 0x77, 0x7b,
0x5b, 0x7e, 0xf9, 0xa3, 0xa0, 0xd6, 0x20, 0x81,
0x2c, 0x38, 0x8f, 0x9d, 0x25, 0xde, 0xe9, 0xc8,
0xf5, 0xdd, 0x6a, 0x47, 0x9c, 0x65, 0x04, 0x5a,
0x56, 0xe6, 0xc2, 0xeb, 0xf2, 0x02, 0x97, 0xe1,
0xb9, 0xd8, 0xe1, 0x24, 0x76, 0x9f, 0x23, 0x62,
0x39, 0x03, 0x4b, 0xc8, 0xf7, 0x34, 0x07, 0x49,
0xd6, 0xe7, 0x4d, 0x9a, 0x68, 0x61, 0x75, 0x74,
0x68, 0x44, 0x61, 0x74, 0x61, 0x58, 0xc4, 0x49,
0x96, 0x0d, 0xe5, 0x88, 0x0e, 0x8c, 0x68, 0x74,
0x34, 0x17, 0x0f, 0x64, 0x76, 0x60, 0x5b, 0x8f,
0xe4, 0xae, 0xb9, 0xa2, 0x86, 0x32, 0xc7, 0x99,
0x5c, 0xf3, 0xba, 0x83, 0x1d, 0x97, 0x63, 0x41,
0x00, 0x00, 0x00, 0x00, 0xf8, 0xa0, 0x11, 0xf3,
0x8c, 0x0a, 0x4d, 0x15, 0x80, 0x06, 0x17, 0x11,
0x1f, 0x9e, 0xdc, 0x7d, 0x00, 0x40, 0x53, 0xfb,
0xdf, 0xaa, 0xce, 0x63, 0xde, 0xc5, 0xfe, 0x47,
0xe6, 0x52, 0xeb, 0xf3, 0x5d, 0x53, 0xa8, 0xbf,
0x9d, 0xd6, 0x09, 0x6b, 0x5e, 0x7f, 0xe0, 0x0d,
0x51, 0x30, 0x85, 0x6a, 0xda, 0x68, 0x70, 0x85,
0xb0, 0xdb, 0x08, 0x0b, 0x83, 0x2c, 0xef, 0x44,
0xe2, 0x36, 0x88, 0xee, 0x76, 0x90, 0x6e, 0x7b,
0x50, 0x3e, 0x9a, 0xa0, 0xd6, 0x3c, 0x34, 0xe3,
0x83, 0xe7, 0xd1, 0xbd, 0x9f, 0x25, 0xa5, 0x01,
0x02, 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20,
0x17, 0x5b, 0x27, 0xa6, 0x56, 0xb2, 0x26, 0x0c,
0x26, 0x0c, 0x55, 0x42, 0x78, 0x17, 0x5d, 0x4c,
0xf8, 0xa2, 0xfd, 0x1b, 0xb9, 0x54, 0xdf, 0xd5,
0xeb, 0xbf, 0x22, 0x64, 0xf5, 0x21, 0x9a, 0xc6,
0x22, 0x58, 0x20, 0x87, 0x5f, 0x90, 0xe6, 0xfd,
0x71, 0x27, 0x9f, 0xeb, 0xe3, 0x03, 0x44, 0xbc,
0x8d, 0x49, 0xc6, 0x1c, 0x31, 0x3b, 0x72, 0xae,
0xd4, 0x53, 0xb1, 0xfe, 0x5d, 0xe1, 0x30, 0xfc,
0x2b, 0x1e, 0xd2
};

struct param *
unpack(const uint8_t *ptr, size_t len)
{
cbor_item_t *item = NULL, **v;
struct cbor_load_result cbor;
struct param *p;
int ok = -1;

if ((p = calloc(1, sizeof(*p))) == NULL ||
(item = cbor_load(ptr, len, &cbor)) == NULL ||
cbor.read != len ||
cbor_isa_array(item) == false ||
cbor_array_is_definite(item) == false ||
cbor_array_size(item) != 5 ||
(v = cbor_array_handle(item)) == NULL)
goto fail;

if (unpack_int(v[0], &p->seed) < 0 ||
unpack_string(v[1], p->rp_id) < 0 ||
unpack_blob(v[2], &p->cdh) < 0 ||
unpack_blob(v[3], &p->attobj) < 0 ||
unpack_byte(v[4], &p->type) < 0)
goto fail;

ok = 0;
fail:
if (ok < 0) {
free(p);
p = NULL;
}

if (item)
cbor_decref(&item);

return p;
}

size_t
pack(uint8_t *ptr, size_t len, const struct param *p)
{
cbor_item_t *argv[5], *array = NULL;
size_t cbor_alloc_len, cbor_len = 0;
unsigned char *cbor = NULL;

memset(argv, 0, sizeof(argv));

if ((array = cbor_new_definite_array(17)) == NULL ||
(argv[0] = pack_int(p->seed)) == NULL ||
(argv[1] = pack_string(p->rp_id)) == NULL ||
(argv[2] = pack_blob(&p->cdh)) == NULL ||
(argv[3] = pack_blob(&p->attobj)) == NULL ||
(argv[4] = pack_byte(p->type)) == NULL)
goto fail;

for (size_t i = 0; i < 5; i++)
if (cbor_array_push(array, argv[i]) == false)
goto fail;

if ((cbor_len = cbor_serialize_alloc(array, &cbor,
&cbor_alloc_len)) == 0 || cbor_len > len) {
cbor_len = 0;
goto fail;
}

memcpy(ptr, cbor, cbor_len);
fail:
for (size_t i = 0; i < 5; i++)
if (argv[i])
cbor_decref(&argv[i]);

if (array)
cbor_decref(&array);

free(cbor);

return cbor_len;
}

size_t
pack_dummy(uint8_t *ptr, size_t len)
{
struct param dummy;
uint8_t blob[MAXCORPUS];
size_t blob_len;

dummy.type = 1;

strlcpy(dummy.rp_id, dummy_rp_id, sizeof(dummy.rp_id));

dummy.cdh.len = sizeof(dummy_cdh);
dummy.attobj.len = sizeof(dummy_attestation_object);

memcpy(&dummy.cdh.body, &dummy_cdh, dummy.cdh.len);
memcpy(&dummy.attobj.body, dummy_attestation_object, dummy.attobj.len);

assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0);

if (blob_len > len) {
memcpy(ptr, blob, len);
return len;
}

memcpy(ptr, blob, blob_len);

return blob_len;
}

void
mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN
{
if (flags & MUTATE_SEED)
p->seed = (int)seed;

if (flags & MUTATE_PARAM) {
mutate_byte(&p->type);
p->attobj.len = sizeof(dummy_attestation_object);
memcpy(&p->attobj.body, &dummy_attestation_object,
p->attobj.len);
mutate_blob(&p->attobj);
}
}

void
test(const struct param *p)
{
fido_cred_t *cred = NULL;
int r, cose_alg;

prng_init((unsigned int)p->seed);
fuzz_clock_reset();
fido_init(FIDO_DEBUG);
fido_set_log_handler(consume_str);

if ((cred = fido_cred_new()) == NULL)
return;

switch (p->type & 3) {
case 0:
cose_alg = COSE_ES256;
break;
case 1:
cose_alg = COSE_RS256;
break;
case 2:
cose_alg = COSE_ES384;
break;
default:
cose_alg = COSE_EDDSA;
break;
}

r = fido_cred_set_type(cred, cose_alg);
consume(&r, sizeof(r));
r = fido_cred_set_rp(cred, p->rp_id, NULL);
consume(&r, sizeof(r));
r = fido_cred_set_clientdata_hash(cred, p->cdh.body, p->cdh.len);
consume(&r, sizeof(r));
r = fido_cred_set_attobj(cred, p->attobj.body, p->attobj.len);
consume(&r, sizeof(r));

consume_str(fido_cred_fmt(cred));
consume(fido_cred_attstmt_ptr(cred), fido_cred_attstmt_len(cred));
consume(fido_cred_authdata_ptr(cred), fido_cred_authdata_len(cred));
r = fido_cred_verify(cred);
consume(&r, sizeof(r));

fido_cred_free(&cred);
}
1 change: 1 addition & 0 deletions man/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ list(APPEND MAN_ALIAS
fido_credman_metadata_new fido_credman_rp_new
fido_credman_metadata_new fido_credman_set_dev_rk
fido_cred_set_authdata fido_cred_set_attstmt
fido_cred_set_authdata fido_cred_set_attobj
fido_cred_set_authdata fido_cred_set_authdata_raw
fido_cred_set_authdata fido_cred_set_blob
fido_cred_set_authdata fido_cred_set_clientdata
Expand Down
Loading
Loading