summaryrefslogtreecommitdiffstats
path: root/src/cbor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cbor.c')
-rw-r--r--src/cbor.c105
1 files changed, 98 insertions, 7 deletions
diff --git a/src/cbor.c b/src/cbor.c
index ab99b34..b242cfa 100644
--- a/src/cbor.c
+++ b/src/cbor.c
@@ -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;
}