diff options
Diffstat (limited to 'src/cbor.c')
-rw-r--r-- | src/cbor.c | 105 |
1 files changed, 98 insertions, 7 deletions
@@ -1133,6 +1133,64 @@ fail: } static int +decode_attobj(const cbor_item_t *key, const cbor_item_t *val, void *arg) +{ + fido_cred_t *cred = arg; + char *name = NULL; + int ok = -1; + + if (cbor_string_copy(key, &name) < 0) { + fido_log_debug("%s: cbor type", __func__); + ok = 0; /* ignore */ + goto fail; + } + + if (!strcmp(name, "fmt")) { + if (cbor_decode_fmt(val, &cred->fmt) < 0) { + fido_log_debug("%s: cbor_decode_fmt", __func__); + goto fail; + } + } else if (!strcmp(name, "attStmt")) { + if (cbor_decode_attstmt(val, &cred->attstmt) < 0) { + fido_log_debug("%s: cbor_decode_attstmt", __func__); + goto fail; + } + } else if (!strcmp(name, "authData")) { + if (fido_blob_decode(val, &cred->authdata_raw) < 0) { + fido_log_debug("%s: fido_blob_decode", __func__); + goto fail; + } + if (cbor_decode_cred_authdata(val, cred->type, + &cred->authdata_cbor, &cred->authdata, &cred->attcred, + &cred->authdata_ext) < 0) { + fido_log_debug("%s: cbor_decode_cred_authdata", + __func__); + goto fail; + } + } + + ok = 0; +fail: + free(name); + + return (ok); +} + +/* XXX introduce fido_attobj_t? */ +int +cbor_decode_attobj(const cbor_item_t *item, fido_cred_t *cred) +{ + if (cbor_isa_map(item) == false || + cbor_map_is_definite(item) == false || + cbor_map_iter(item, cred, decode_attobj) < 0) { + fido_log_debug("%s: cbor type", __func__); + return (-1); + } + + return (0); +} + +static int decode_cred_extension(const cbor_item_t *key, const cbor_item_t *val, void *arg) { fido_cred_ext_t *authdata_ext = arg; @@ -1386,12 +1444,47 @@ cbor_decode_assert_authdata(const cbor_item_t *item, fido_blob_t *authdata_cbor, static int decode_x5c(const cbor_item_t *item, void *arg) { - fido_blob_t *x5c = arg; + fido_blob_array_t *x5c = arg; + fido_blob_t *list_ptr = NULL; + fido_blob_t x5c_blob; + + memset(&x5c_blob, 0, sizeof(x5c_blob)); + + if (fido_blob_decode(item, &x5c_blob) < 0) { + fido_log_debug("%s: fido_blob_decode", __func__); + return (-1); + } + + if (x5c->len == SIZE_MAX) { + fido_blob_reset(&x5c_blob); + return (-1); + } + + if ((list_ptr = recallocarray(x5c->ptr, x5c->len, + x5c->len + 1, sizeof(x5c_blob))) == NULL) { + fido_blob_reset(&x5c_blob); + return (-1); + } + + list_ptr[x5c->len++] = x5c_blob; + x5c->ptr = list_ptr; - if (x5c->len) - return (0); /* ignore */ + return (0); +} - return (fido_blob_decode(item, x5c)); +static int +decode_x5c_array(const cbor_item_t *item, fido_blob_array_t *arr) +{ + if (arr->len) { + fido_log_debug("%s: dup", __func__); + return (-1); + } + if (cbor_isa_array(item) == false || + cbor_array_is_definite(item) == false) { + fido_log_debug("%s: cbor", __func__); + return (-1); + } + return (cbor_array_iter(item, arr, decode_x5c)); } static int @@ -1427,9 +1520,7 @@ decode_attstmt_entry(const cbor_item_t *key, const cbor_item_t *val, void *arg) goto out; } } else if (!strcmp(name, "x5c")) { - if (cbor_isa_array(val) == false || - cbor_array_is_definite(val) == false || - cbor_array_iter(val, &attstmt->x5c, decode_x5c) < 0) { + if (decode_x5c_array(val, &attstmt->x5c)) { fido_log_debug("%s: x5c", __func__); goto out; } |