summaryrefslogtreecommitdiff
path: root/src/cbor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cbor.c')
-rw-r--r--src/cbor.c108
1 files changed, 82 insertions, 26 deletions
diff --git a/src/cbor.c b/src/cbor.c
index 3e03592..3928325 100644
--- a/src/cbor.c
+++ b/src/cbor.c
@@ -314,6 +314,35 @@ fail:
314} 314}
315 315
316static int 316static int
317cbor_add_uint8(cbor_item_t *item, const char *key, uint8_t value)
318{
319 struct cbor_pair pair;
320 int ok = -1;
321
322 memset(&pair, 0, sizeof(pair));
323
324 if ((pair.key = cbor_build_string(key)) == NULL ||
325 (pair.value = cbor_build_uint8(value)) == NULL) {
326 fido_log_debug("%s: cbor_build", __func__);
327 goto fail;
328 }
329
330 if (!cbor_map_add(item, pair)) {
331 fido_log_debug("%s: cbor_map_add", __func__);
332 goto fail;
333 }
334
335 ok = 0;
336fail:
337 if (pair.key)
338 cbor_decref(&pair.key);
339 if (pair.value)
340 cbor_decref(&pair.value);
341
342 return (ok);
343}
344
345static int
317cbor_add_arg(cbor_item_t *item, uint8_t n, cbor_item_t *arg) 346cbor_add_arg(cbor_item_t *item, uint8_t n, cbor_item_t *arg)
318{ 347{
319 struct cbor_pair pair; 348 struct cbor_pair pair;
@@ -535,19 +564,29 @@ fail:
535} 564}
536 565
537cbor_item_t * 566cbor_item_t *
538cbor_encode_extensions(int ext) 567cbor_encode_extensions(const fido_cred_ext_t *ext)
539{ 568{
540 cbor_item_t *item = NULL; 569 cbor_item_t *item = NULL;
570 size_t size = 0;
541 571
542 if (ext == 0 || ext != FIDO_EXT_HMAC_SECRET) 572 if (ext->mask & FIDO_EXT_HMAC_SECRET)
543 return (NULL); 573 size++;
544 574 if (ext->mask & FIDO_EXT_CRED_PROTECT)
545 if ((item = cbor_new_definite_map(1)) == NULL) 575 size++;
576 if (size == 0 || (item = cbor_new_definite_map(size)) == NULL)
546 return (NULL); 577 return (NULL);
547 578
548 if (cbor_add_bool(item, "hmac-secret", FIDO_OPT_TRUE) < 0) { 579 if (ext->mask & FIDO_EXT_HMAC_SECRET) {
549 cbor_decref(&item); 580 if (cbor_add_bool(item, "hmac-secret", FIDO_OPT_TRUE) < 0) {
550 return (NULL); 581 cbor_decref(&item);
582 return (NULL);
583 }
584 }
585 if (ext->mask & FIDO_EXT_CRED_PROTECT) {
586 if (cbor_add_uint8(item, "credProtect", ext->prot) < 0) {
587 cbor_decref(&item);
588 return (NULL);
589 }
551 } 590 }
552 591
553 return (item); 592 return (item);
@@ -1082,26 +1121,35 @@ fail:
1082static int 1121static int
1083decode_extension(const cbor_item_t *key, const cbor_item_t *val, void *arg) 1122decode_extension(const cbor_item_t *key, const cbor_item_t *val, void *arg)
1084{ 1123{
1085 int *authdata_ext = arg; 1124 fido_cred_ext_t *authdata_ext = arg;
1086 char *type = NULL; 1125 char *type = NULL;
1087 int ok = -1; 1126 int ok = -1;
1088 1127
1089 if (cbor_string_copy(key, &type) < 0 || strcmp(type, "hmac-secret")) { 1128 if (cbor_string_copy(key, &type) < 0) {
1090 fido_log_debug("%s: cbor type", __func__); 1129 fido_log_debug("%s: cbor type", __func__);
1091 ok = 0; /* ignore */ 1130 ok = 0; /* ignore */
1092 goto out; 1131 goto out;
1093 } 1132 }
1094 1133
1095 if (cbor_isa_float_ctrl(val) == false || 1134 if (strcmp(type, "hmac-secret") == 0) {
1096 cbor_float_get_width(val) != CBOR_FLOAT_0 || 1135 if (cbor_isa_float_ctrl(val) == false ||
1097 cbor_is_bool(val) == false || *authdata_ext != 0) { 1136 cbor_float_get_width(val) != CBOR_FLOAT_0 ||
1098 fido_log_debug("%s: cbor type", __func__); 1137 cbor_is_bool(val) == false) {
1099 goto out; 1138 fido_log_debug("%s: cbor type", __func__);
1139 goto out;
1140 }
1141 if (cbor_ctrl_value(val) == CBOR_CTRL_TRUE)
1142 authdata_ext->mask |= FIDO_EXT_HMAC_SECRET;
1143 } else if (strcmp(type, "credProtect") == 0) {
1144 if (cbor_isa_uint(val) == false ||
1145 cbor_int_get_width(val) != CBOR_INT_8) {
1146 fido_log_debug("%s: cbor type", __func__);
1147 goto out;
1148 }
1149 authdata_ext->mask |= FIDO_EXT_CRED_PROTECT;
1150 authdata_ext->prot = cbor_get_uint8(val);
1100 } 1151 }
1101 1152
1102 if (cbor_ctrl_value(val) == CBOR_CTRL_TRUE)
1103 *authdata_ext |= FIDO_EXT_HMAC_SECRET;
1104
1105 ok = 0; 1153 ok = 0;
1106out: 1154out:
1107 free(type); 1155 free(type);
@@ -1110,7 +1158,8 @@ out:
1110} 1158}
1111 1159
1112static int 1160static int
1113decode_extensions(const unsigned char **buf, size_t *len, int *authdata_ext) 1161decode_extensions(const unsigned char **buf, size_t *len,
1162 fido_cred_ext_t *authdata_ext)
1114{ 1163{
1115 cbor_item_t *item = NULL; 1164 cbor_item_t *item = NULL;
1116 struct cbor_load_result cbor; 1165 struct cbor_load_result cbor;
@@ -1118,8 +1167,9 @@ decode_extensions(const unsigned char **buf, size_t *len, int *authdata_ext)
1118 1167
1119 fido_log_debug("%s: buf=%p, len=%zu", __func__, (const void *)*buf, 1168 fido_log_debug("%s: buf=%p, len=%zu", __func__, (const void *)*buf,
1120 *len); 1169 *len);
1170 fido_log_xxd(*buf, *len);
1121 1171
1122 *authdata_ext = 0; 1172 memset(authdata_ext, 0, sizeof(*authdata_ext));
1123 1173
1124 if ((item = cbor_load(*buf, *len, &cbor)) == NULL) { 1174 if ((item = cbor_load(*buf, *len, &cbor)) == NULL) {
1125 fido_log_debug("%s: cbor_load", __func__); 1175 fido_log_debug("%s: cbor_load", __func__);
@@ -1129,7 +1179,6 @@ decode_extensions(const unsigned char **buf, size_t *len, int *authdata_ext)
1129 1179
1130 if (cbor_isa_map(item) == false || 1180 if (cbor_isa_map(item) == false ||
1131 cbor_map_is_definite(item) == false || 1181 cbor_map_is_definite(item) == false ||
1132 cbor_map_size(item) != 1 ||
1133 cbor_map_iter(item, authdata_ext, decode_extension) < 0) { 1182 cbor_map_iter(item, authdata_ext, decode_extension) < 0) {
1134 fido_log_debug("%s: cbor type", __func__); 1183 fido_log_debug("%s: cbor type", __func__);
1135 goto fail; 1184 goto fail;
@@ -1204,7 +1253,7 @@ fail:
1204int 1253int
1205cbor_decode_cred_authdata(const cbor_item_t *item, int cose_alg, 1254cbor_decode_cred_authdata(const cbor_item_t *item, int cose_alg,
1206 fido_blob_t *authdata_cbor, fido_authdata_t *authdata, 1255 fido_blob_t *authdata_cbor, fido_authdata_t *authdata,
1207 fido_attcred_t *attcred, int *authdata_ext) 1256 fido_attcred_t *attcred, fido_cred_ext_t *authdata_ext)
1208{ 1257{
1209 const unsigned char *buf = NULL; 1258 const unsigned char *buf = NULL;
1210 size_t len; 1259 size_t len;
@@ -1227,6 +1276,7 @@ cbor_decode_cred_authdata(const cbor_item_t *item, int cose_alg,
1227 len = cbor_bytestring_length(item); 1276 len = cbor_bytestring_length(item);
1228 1277
1229 fido_log_debug("%s: buf=%p, len=%zu", __func__, (const void *)buf, len); 1278 fido_log_debug("%s: buf=%p, len=%zu", __func__, (const void *)buf, len);
1279 fido_log_xxd(buf, len);
1230 1280
1231 if (fido_buf_read(&buf, &len, authdata, sizeof(*authdata)) < 0) { 1281 if (fido_buf_read(&buf, &len, authdata, sizeof(*authdata)) < 0) {
1232 fido_log_debug("%s: fido_buf_read", __func__); 1282 fido_log_debug("%s: fido_buf_read", __func__);
@@ -1316,6 +1366,7 @@ decode_attstmt_entry(const cbor_item_t *key, const cbor_item_t *val, void *arg)
1316{ 1366{
1317 fido_attstmt_t *attstmt = arg; 1367 fido_attstmt_t *attstmt = arg;
1318 char *name = NULL; 1368 char *name = NULL;
1369 int cose_alg = 0;
1319 int ok = -1; 1370 int ok = -1;
1320 1371
1321 if (cbor_string_copy(key, &name) < 0) { 1372 if (cbor_string_copy(key, &name) < 0) {
@@ -1326,11 +1377,16 @@ decode_attstmt_entry(const cbor_item_t *key, const cbor_item_t *val, void *arg)
1326 1377
1327 if (!strcmp(name, "alg")) { 1378 if (!strcmp(name, "alg")) {
1328 if (cbor_isa_negint(val) == false || 1379 if (cbor_isa_negint(val) == false ||
1329 cbor_int_get_width(val) != CBOR_INT_8 || 1380 cbor_get_int(val) > UINT16_MAX) {
1330 cbor_get_uint8(val) != -COSE_ES256 - 1) {
1331 fido_log_debug("%s: alg", __func__); 1381 fido_log_debug("%s: alg", __func__);
1332 goto out; 1382 goto out;
1333 } 1383 }
1384 if ((cose_alg = -(int)cbor_get_int(val) - 1) != COSE_ES256 &&
1385 cose_alg != COSE_RS256 && cose_alg != COSE_EDDSA) {
1386 fido_log_debug("%s: unsupported cose_alg=%d", __func__,
1387 cose_alg);
1388 goto out;
1389 }
1334 } else if (!strcmp(name, "sig")) { 1390 } else if (!strcmp(name, "sig")) {
1335 if (cbor_bytestring_copy(val, &attstmt->sig.ptr, 1391 if (cbor_bytestring_copy(val, &attstmt->sig.ptr,
1336 &attstmt->sig.len) < 0) { 1392 &attstmt->sig.len) < 0) {