Skip to content
Closed
Show file tree
Hide file tree
Changes from 9 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
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ list(APPEND FIDO_SOURCES
es384.c
hid.c
info.c
int_array.c
Comment thread
bobomb marked this conversation as resolved.
Outdated
io.c
iso7816.c
largeblob.c
Expand Down
84 changes: 59 additions & 25 deletions src/cbor.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ cbor_encode_user_entity(const fido_user_t *user)
}

cbor_item_t *
cbor_encode_pubkey_param(int cose_alg)
cbor_encode_pubkey_param(fido_int_array_t *cose_alg_array)
{
cbor_item_t *item = NULL;
cbor_item_t *body = NULL;
Expand All @@ -478,29 +478,46 @@ cbor_encode_pubkey_param(int cose_alg)

memset(&alg, 0, sizeof(alg));

if ((item = cbor_new_definite_array(1)) == NULL ||
(body = cbor_new_definite_map(2)) == NULL ||
cose_alg > -1 || cose_alg < INT16_MIN)
goto fail;
if ((item = cbor_new_definite_array(1)) == NULL)
Comment thread
bobomb marked this conversation as resolved.
Outdated
goto fail;

alg.key = cbor_build_string("alg");
for (size_t i = 0; i < fido_int_array_get_count(cose_alg_array); i++) {
int cose_alg = cose_alg_array->ptr[i];

if (-cose_alg - 1 > UINT8_MAX)
alg.value = cbor_build_negint16((uint16_t)(-cose_alg - 1));
else
alg.value = cbor_build_negint8((uint8_t)(-cose_alg - 1));
if ((body = cbor_new_definite_map(2)) == NULL ||
cose_alg > -1 || cose_alg < INT16_MIN)
goto fail;

if (alg.key == NULL || alg.value == NULL) {
fido_log_debug("%s: cbor_build", __func__);
goto fail;
}
alg.key = cbor_build_string("alg");

if (cbor_map_add(body, alg) == false ||
cbor_add_string(body, "type", "public-key") < 0 ||
cbor_array_push(item, body) == false)
goto fail;
if (-cose_alg - 1 > UINT8_MAX)
alg.value = cbor_build_negint16((uint16_t)(-cose_alg - 1));
else
alg.value = cbor_build_negint8((uint8_t)(-cose_alg - 1));

if (alg.key == NULL || alg.value == NULL) {
fido_log_debug("%s: cbor_build", __func__);
goto fail;
}

if (cbor_map_add(body, alg) == false ||
cbor_add_string(body, "type", "public-key") < 0 ||
cbor_array_push(item, body) == false)
goto fail;

if (body != NULL)
cbor_decref(&body);
if (alg.key != NULL)
cbor_decref(&alg.key);
if (alg.value != NULL)
cbor_decref(&alg.value);

memset(&alg, 0, sizeof(alg));
}

ok = 0;

return (item);
fail:
if (ok < 0) {
if (item != NULL) {
Expand Down Expand Up @@ -1073,13 +1090,14 @@ cbor_decode_pubkey(const cbor_item_t *item, int *type, void *key)
}

static int
decode_attcred(const unsigned char **buf, size_t *len, int cose_alg,
decode_attcred(const unsigned char **buf, size_t *len, fido_int_array_t *cose_alg_array,
fido_attcred_t *attcred)
{
cbor_item_t *item = NULL;
struct cbor_load_result cbor;
uint16_t id_len;
int ok = -1;
bool cose_match = false;

fido_log_xxd(*buf, *len, "%s", __func__);

Expand Down Expand Up @@ -1115,11 +1133,27 @@ decode_attcred(const unsigned char **buf, size_t *len, int cose_alg,
goto fail;
}

if (attcred->type != cose_alg) {
fido_log_debug("%s: cose_alg mismatch (%d != %d)", __func__,
attcred->type, cose_alg);
goto fail;
}
for (size_t i = 0; i < fido_int_array_get_count(cose_alg_array); i++) {
Comment thread
bobomb marked this conversation as resolved.
Outdated
int cose_alg = cose_alg_array->ptr[i];
if (attcred->type != cose_alg) {
fido_log_debug("%s: cose_alg mismatch (%d != %d)", __func__,
attcred->type, cose_alg);
}
else {
cose_match = true;
}
}

if (!cose_match) {
fido_log_debug("%s: cose_alg failed to match any", __func__);
goto fail;
}

/* set the credential type to the attested credential type */
int cose[1] = { attcred->type };
fido_int_array_set(cose_alg_array, cose, 1);



*buf += cbor.read;
*len -= cbor.read;
Expand Down Expand Up @@ -1288,7 +1322,7 @@ decode_assert_extensions(const unsigned char **buf, size_t *len,
}

int
cbor_decode_cred_authdata(const cbor_item_t *item, int cose_alg,
cbor_decode_cred_authdata(const cbor_item_t *item, fido_int_array_t *cose_alg,
fido_blob_t *authdata_cbor, fido_authdata_t *authdata,
fido_attcred_t *attcred, fido_cred_ext_t *authdata_ext)
{
Expand Down
61 changes: 51 additions & 10 deletions src/cred.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ parse_makecred_reply(const cbor_item_t *key, const cbor_item_t *val, void *arg)
fido_log_debug("%s: fido_blob_decode", __func__);
return (-1);
}
return (cbor_decode_cred_authdata(val, cred->type,
return (cbor_decode_cred_authdata(val, &cred->type,
&cred->authdata_cbor, &cred->authdata, &cred->attcred,
&cred->authdata_ext));
case 3: /* attestation statement */
Expand Down Expand Up @@ -62,7 +62,7 @@ fido_dev_make_cred_tx(fido_dev_t *dev, fido_cred_t *cred, const char *pin,
memset(&f, 0, sizeof(f));
memset(argv, 0, sizeof(argv));

if (cred->cdh.ptr == NULL || cred->type == 0) {
if (cred->cdh.ptr == NULL || fido_int_array_is_empty(&cred->type)) {
fido_log_debug("%s: cdh=%p, type=%d", __func__,
(void *)cred->cdh.ptr, cred->type);
r = FIDO_ERR_INVALID_ARGUMENT;
Expand All @@ -72,7 +72,7 @@ fido_dev_make_cred_tx(fido_dev_t *dev, fido_cred_t *cred, const char *pin,
if ((argv[0] = fido_blob_encode(&cred->cdh)) == NULL ||
(argv[1] = cbor_encode_rp_entity(&cred->rp)) == NULL ||
(argv[2] = cbor_encode_user_entity(&cred->user)) == NULL ||
(argv[3] = cbor_encode_pubkey_param(cred->type)) == NULL) {
(argv[3] = cbor_encode_pubkey_param(&cred->type)) == NULL) {
fido_log_debug("%s: cbor encode", __func__);
r = FIDO_ERR_INTERNAL;
goto fail;
Expand Down Expand Up @@ -568,7 +568,7 @@ fido_cred_reset_tx(fido_cred_t *cred)
memset(&cred->user, 0, sizeof(cred->user));
memset(&cred->ext, 0, sizeof(cred->ext));

cred->type = 0;
fido_int_array_reset(&cred->type);
cred->rk = FIDO_OPT_OMIT;
cred->uv = FIDO_OPT_OMIT;
}
Expand Down Expand Up @@ -618,7 +618,7 @@ fido_cred_set_authdata(fido_cred_t *cred, const unsigned char *ptr, size_t len)
goto fail;
}

if (cbor_decode_cred_authdata(item, cred->type, &cred->authdata_cbor,
if (cbor_decode_cred_authdata(item, &cred->type, &cred->authdata_cbor,
&cred->authdata, &cred->attcred, &cred->authdata_ext) < 0) {
fido_log_debug("%s: cbor_decode_cred_authdata", __func__);
goto fail;
Expand Down Expand Up @@ -659,7 +659,7 @@ fido_cred_set_authdata_raw(fido_cred_t *cred, const unsigned char *ptr,
goto fail;
}

if (cbor_decode_cred_authdata(item, cred->type, &cred->authdata_cbor,
if (cbor_decode_cred_authdata(item, &cred->type, &cred->authdata_cbor,
&cred->authdata, &cred->attcred, &cred->authdata_ext) < 0) {
fido_log_debug("%s: cbor_decode_cred_authdata", __func__);
goto fail;
Expand Down Expand Up @@ -986,21 +986,62 @@ fido_cred_set_fmt(fido_cred_t *cred, const char *fmt)
int
fido_cred_set_type(fido_cred_t *cred, int cose_alg)
Comment thread
bobomb marked this conversation as resolved.
{
if (cred->type != 0)
return (FIDO_ERR_INVALID_ARGUMENT);
int cose_array[1] = { cose_alg };
if (cose_alg != COSE_ES256 && cose_alg != COSE_ES384 &&
cose_alg != COSE_RS256 && cose_alg != COSE_EDDSA)
return (FIDO_ERR_INVALID_ARGUMENT);

cred->type = cose_alg;
if (fido_int_array_set(&cred->type, cose_array, 1) != 0)
return (FIDO_ERR_INTERNAL);

return (FIDO_OK);
}

int
fido_cred_set_type_array(fido_cred_t* cred, int *cose_alg_array, size_t count)
Comment thread
bobomb marked this conversation as resolved.
{
if (cose_alg_array == NULL || count == 0)
return (FIDO_ERR_INVALID_ARGUMENT);

for (size_t i = 0; i < count; i++) {
int cose_alg = cose_alg_array[i];

if (cose_alg != COSE_ES256 && cose_alg != COSE_ES384 &&
cose_alg != COSE_RS256 && cose_alg != COSE_EDDSA)
return (FIDO_ERR_INVALID_ARGUMENT);
}

if (fido_int_array_set(&cred->type, cose_alg_array, count) != 0)
return (FIDO_ERR_INTERNAL);

return (FIDO_OK);
}

int
fido_cred_type(const fido_cred_t *cred)
{
return (cred->type);
if (fido_int_array_is_empty(&cred->type))
return 0;
/* return only the first, to ensure backwards compatibility */
Comment thread
bobomb marked this conversation as resolved.
Outdated
return cred->type.ptr[0];
}

const int *
fido_cred_type_array_ptr(const fido_cred_t* cred)
Comment thread
bobomb marked this conversation as resolved.
Outdated
{
if (fido_int_array_is_empty(&cred->type))
return 0;

return (cred->type.ptr);
}

size_t
fido_cred_type_array_len(const fido_cred_t* cred)
{
if (fido_int_array_is_empty(&cred->type))
return 0;

return (cred->type.count);
}

uint8_t
Expand Down
4 changes: 3 additions & 1 deletion src/credman.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,9 @@ credman_parse_rk(const cbor_item_t *key, const cbor_item_t *val, void *arg)
if (cbor_decode_pubkey(val, &cred->attcred.type,
&cred->attcred.pubkey) < 0)
return (-1);
cred->type = cred->attcred.type; /* XXX */
/* set cred type to what is returned by attested cred */
int cred_type[1] = { cred->attcred.type };
fido_int_array_set(&cred->type, cred_type, 1);
return (0);
case 10:
if (cbor_decode_uint64(val, &prot) < 0 || prot > INT_MAX ||
Expand Down
6 changes: 4 additions & 2 deletions src/extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ cbor_item_t *cbor_encode_pin_auth(const fido_dev_t *, const fido_blob_t *,
cbor_item_t *cbor_encode_pin_opt(const fido_dev_t *);
cbor_item_t *cbor_encode_pubkey(const fido_blob_t *);
cbor_item_t *cbor_encode_pubkey_list(const fido_blob_array_t *);
cbor_item_t *cbor_encode_pubkey_param(int);
cbor_item_t *cbor_encode_pubkey_param(fido_int_array_t *);
cbor_item_t *cbor_encode_rp_entity(const fido_rp_t *);
cbor_item_t *cbor_encode_str_array(const fido_str_array_t *);
cbor_item_t *cbor_encode_user_entity(const fido_user_t *);
Expand All @@ -59,8 +59,10 @@ cbor_item_t *es256_pk_encode(const es256_pk_t *, int);
/* cbor decoding functions */
int cbor_decode_attstmt(const cbor_item_t *, fido_attstmt_t *);
int cbor_decode_bool(const cbor_item_t *, bool *);
int cbor_decode_cred_authdata(const cbor_item_t *, int, fido_blob_t *,
int cbor_decode_cred_authdata(const cbor_item_t *, fido_int_array_t *, fido_blob_t *,
fido_authdata_t *, fido_attcred_t *, fido_cred_ext_t *);
int cbor_decode_cred_authdata_multiple_cose(const cbor_item_t *,
fido_blob_t *, fido_blob_t *, fido_authdata_t *, fido_attcred_t *, fido_cred_ext_t *);
int cbor_decode_assert_authdata(const cbor_item_t *, fido_blob_t *,
fido_authdata_t *, fido_assert_extattr_t *);
int cbor_decode_cred_id(const cbor_item_t *, fido_blob_t *);
Expand Down
6 changes: 5 additions & 1 deletion src/fido.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

#include "../openbsd-compat/openbsd-compat.h"
#include "blob.h"
#include "int_array.h"
#include "iso7816.h"
#include "extern.h"
#endif
Expand Down Expand Up @@ -110,6 +111,7 @@ const char *fido_dev_info_manufacturer_string(const fido_dev_info_t *);
const char *fido_dev_info_path(const fido_dev_info_t *);
const char *fido_dev_info_product_string(const fido_dev_info_t *);
const fido_dev_info_t *fido_dev_info_ptr(const fido_dev_info_t *, size_t);
const int *fido_cred_type_array_ptr(const fido_cred_t* cred);
const uint8_t *fido_cbor_info_protocols_ptr(const fido_cbor_info_t *);
const uint64_t *fido_cbor_info_certs_value_ptr(const fido_cbor_info_t *);
const unsigned char *fido_cbor_info_aaguid_ptr(const fido_cbor_info_t *);
Expand Down Expand Up @@ -166,6 +168,7 @@ int fido_cred_set_rk(fido_cred_t *, fido_opt_t);
int fido_cred_set_rp(fido_cred_t *, const char *, const char *);
int fido_cred_set_sig(fido_cred_t *, const unsigned char *, size_t);
int fido_cred_set_type(fido_cred_t *, int);
int fido_cred_set_type_array(fido_cred_t* cred, int* cose_alg_array, size_t count);
int fido_cred_set_uv(fido_cred_t *, fido_opt_t);
int fido_cred_type(const fido_cred_t *);
int fido_cred_set_user(fido_cred_t *, const unsigned char *, size_t,
Expand Down Expand Up @@ -223,7 +226,8 @@ size_t fido_cred_id_len(const fido_cred_t *);
size_t fido_cred_largeblob_key_len(const fido_cred_t *);
size_t fido_cred_pin_minlen(const fido_cred_t *);
size_t fido_cred_pubkey_len(const fido_cred_t *);
size_t fido_cred_sig_len(const fido_cred_t *);
size_t fido_cred_sig_len(const fido_cred_t*);
size_t fido_cred_type_array_len(const fido_cred_t* cred);
size_t fido_cred_user_id_len(const fido_cred_t *);
size_t fido_cred_x5c_len(const fido_cred_t *);

Expand Down
37 changes: 19 additions & 18 deletions src/fido/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,24 +167,24 @@ typedef struct fido_cred_ext {
} fido_cred_ext_t;

typedef struct fido_cred {
fido_blob_t cd; /* client data */
fido_blob_t cdh; /* client data hash */
fido_rp_t rp; /* relying party */
fido_user_t user; /* user entity */
fido_blob_array_t excl; /* list of credential ids to exclude */
fido_opt_t rk; /* resident key */
fido_opt_t uv; /* user verification */
fido_cred_ext_t ext; /* extensions */
int type; /* cose algorithm */
char *fmt; /* credential format */
fido_cred_ext_t authdata_ext; /* decoded extensions */
fido_blob_t authdata_cbor; /* cbor-encoded payload */
fido_blob_t authdata_raw; /* cbor-decoded payload */
fido_authdata_t authdata; /* decoded authdata payload */
fido_attcred_t attcred; /* returned credential (key + id) */
fido_attstmt_t attstmt; /* attestation statement (x509 + sig) */
fido_blob_t largeblob_key; /* decoded large blob key */
fido_blob_t blob; /* CTAP 2.1 credBlob */
fido_blob_t cd; /* client data */
fido_blob_t cdh; /* client data hash */
fido_rp_t rp; /* relying party */
fido_user_t user; /* user entity */
fido_blob_array_t excl; /* list of credential ids to exclude */
fido_opt_t rk; /* resident key */
fido_opt_t uv; /* user verification */
fido_cred_ext_t ext; /* extensions */
fido_int_array_t type; /* cose algorithm array */
char *fmt; /* credential format */
fido_cred_ext_t authdata_ext; /* decoded extensions */
fido_blob_t authdata_cbor; /* cbor-encoded payload */
fido_blob_t authdata_raw; /* cbor-decoded payload */
fido_authdata_t authdata; /* decoded authdata payload */
fido_attcred_t attcred; /* returned credential (key + id) */
fido_attstmt_t attstmt; /* attestation statement (x509 + sig) */
fido_blob_t largeblob_key; /* decoded large blob key */
fido_blob_t blob; /* CTAP 2.1 credBlob */
} fido_cred_t;

typedef struct fido_assert_extattr {
Expand Down Expand Up @@ -335,3 +335,4 @@ typedef struct eddsa_pk eddsa_pk_t;
#endif /* __cplusplus */

#endif /* !_FIDO_TYPES_H */

Loading