Skip to content

Commit db100b5

Browse files
authored
Use CBOR wrappers in COSE auth (#7574)
1 parent 3c482c4 commit db100b5

3 files changed

Lines changed: 189 additions & 244 deletions

File tree

src/crypto/cbor.cpp

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ namespace
3434
Signed value{0};
3535
if (!cbor_nondet_read_int64(cbor, &value))
3636
{
37-
throw CBORDecodeError("Failed to decode signed value");
37+
throw CBORDecodeError(
38+
Error::DECODE_FAILED, "Failed to decode signed value");
3839
}
3940
return std::make_unique<ValueImpl>(value);
4041
}
@@ -45,7 +46,8 @@ namespace
4546
uint64_t length = 0;
4647
if (!cbor_nondet_get_byte_string(cbor, &data, &length))
4748
{
48-
throw CBORDecodeError("Failed to decode byte string");
49+
throw CBORDecodeError(
50+
Error::DECODE_FAILED, "Failed to decode byte string");
4951
}
5052
Bytes value{data, static_cast<size_t>(length)};
5153
return std::make_unique<ValueImpl>(value);
@@ -57,7 +59,8 @@ namespace
5759
uint64_t length = 0;
5860
if (!cbor_nondet_get_text_string(cbor, &data, &length))
5961
{
60-
throw CBORDecodeError("Failed to decode text string");
62+
throw CBORDecodeError(
63+
Error::DECODE_FAILED, "Failed to decode text string");
6164
}
6265
String value{
6366
reinterpret_cast<const char*>(data), static_cast<size_t>(length)};
@@ -69,7 +72,8 @@ namespace
6972
cbor_nondet_array_iterator_t iter;
7073
if (!cbor_nondet_array_iterator_start(cbor, &iter))
7174
{
72-
throw CBORDecodeError("Failed to start array iterator");
75+
throw CBORDecodeError(
76+
Error::DECODE_FAILED, "Failed to start array iterator");
7377
}
7478

7579
Array array;
@@ -78,7 +82,8 @@ namespace
7882
cbor_nondet_t item;
7983
if (!cbor_nondet_array_iterator_next(&iter, &item))
8084
{
81-
throw CBORDecodeError("Failed to get next array item");
85+
throw CBORDecodeError(
86+
Error::DECODE_FAILED, "Failed to get next array item");
8287
}
8388
array.items.push_back(consume(item));
8489
}
@@ -90,7 +95,8 @@ namespace
9095
cbor_map_iterator iter;
9196
if (!cbor_nondet_map_iterator_start(cbor, &iter))
9297
{
93-
throw CBORDecodeError("Failed to start map iterator");
98+
throw CBORDecodeError(
99+
Error::DECODE_FAILED, "Failed to start map iterator");
94100
}
95101

96102
Map map;
@@ -100,7 +106,8 @@ namespace
100106
cbor_raw value_raw;
101107
if (!cbor_nondet_map_iterator_next(&iter, &key_raw, &value_raw))
102108
{
103-
throw CBORDecodeError("Failed to get next map entry");
109+
throw CBORDecodeError(
110+
Error::DECODE_FAILED, "Failed to get next map entry");
104111
}
105112
map.items.emplace_back(consume(key_raw), consume(value_raw));
106113
}
@@ -113,7 +120,8 @@ namespace
113120
cbor_nondet_t payload;
114121
if (!cbor_nondet_get_tagged(cbor, &payload, &tag))
115122
{
116-
throw CBORDecodeError("Failed to decode tagged value");
123+
throw CBORDecodeError(
124+
Error::DECODE_FAILED, "Failed to decode tagged value");
117125
}
118126

119127
Tagged tagged;
@@ -130,7 +138,8 @@ namespace
130138
Simple value{0};
131139
if (!cbor_nondet_read_simple_value(cbor, &value))
132140
{
133-
throw CBORDecodeError("Failed to decode simple value");
141+
throw CBORDecodeError(
142+
Error::DECODE_FAILED, "Failed to decode simple value");
134143
}
135144
return std::make_unique<ValueImpl>(value);
136145
}
@@ -156,7 +165,7 @@ namespace
156165
case CBOR_MAJOR_TYPE_SIMPLE_VALUE:
157166
return consume_simple(cbor);
158167
default:
159-
throw CBORDecodeError("Unknown CBOR major type");
168+
throw CBORDecodeError(Error::DECODE_FAILED, "Unknown CBOR major type");
160169
}
161170
}
162171

@@ -256,6 +265,16 @@ namespace
256265

257266
namespace ccf::cbor
258267
{
268+
CBORDecodeError::CBORDecodeError(Error err, const std::string& what) :
269+
std::runtime_error(what),
270+
error(err)
271+
{}
272+
273+
Error CBORDecodeError::error_code() const
274+
{
275+
return error;
276+
}
277+
259278
Value make_signed(int64_t value)
260279
{
261280
return std::make_unique<ValueImpl>(value);
@@ -285,7 +304,8 @@ namespace ccf::cbor
285304
&cbor_parse_size,
286305
&cbor))
287306
{
288-
throw CBORDecodeError("Failed to parse top-level cbor");
307+
throw CBORDecodeError(
308+
Error::DECODE_FAILED, "Failed to parse top-level cbor");
289309
}
290310

291311
return consume(cbor);
@@ -313,21 +333,22 @@ namespace ccf::cbor
313333
case SimpleValue::True:
314334
return true;
315335
default:
316-
throw CBORDecodeError("Simple value cannot be matched to boolean");
336+
throw CBORDecodeError(
337+
Error::TYPE_MISMATCH, "Simple value cannot be matched to boolean");
317338
}
318339
}
319340

320341
const Value& ValueImpl::array_at(size_t index) const
321342
{
322343
if (!std::holds_alternative<Array>(value))
323344
{
324-
throw CBORDecodeError("Not an array");
345+
throw CBORDecodeError(Error::TYPE_MISMATCH, "Not an array");
325346
}
326347

327348
const auto& arr = std::get<Array>(value);
328349
if (index >= arr.items.size())
329350
{
330-
throw CBORDecodeError("Array index out of bounds");
351+
throw CBORDecodeError(Error::OUT_OF_BOUND, "Array index out of bounds");
331352
}
332353

333354
return arr.items[index];
@@ -337,7 +358,7 @@ namespace ccf::cbor
337358
{
338359
if (!std::holds_alternative<Map>(value))
339360
{
340-
throw CBORDecodeError("Not a map");
361+
throw CBORDecodeError(Error::TYPE_MISMATCH, "Not a map");
341362
}
342363

343364
// Fail fast: Array, Map, Tagged are not supported as map keys in this
@@ -350,6 +371,7 @@ namespace ccf::cbor
350371
std::is_same_v<T, Tagged>)
351372
{
352373
throw CBORDecodeError(
374+
Error::TYPE_MISMATCH,
353375
"Array, Map, and Tagged values cannot be used as map keys");
354376
}
355377
},
@@ -390,7 +412,7 @@ namespace ccf::cbor
390412
}
391413
}
392414

393-
throw CBORDecodeError("Key not found in map");
415+
throw CBORDecodeError(Error::KEY_NOT_FOUND, "Key not found in map");
394416
}
395417

396418
size_t ValueImpl::size() const
@@ -405,20 +427,20 @@ namespace ccf::cbor
405427
const auto& map = std::get<Map>(value);
406428
return map.items.size();
407429
}
408-
throw CBORDecodeError("Not a collection");
430+
throw CBORDecodeError(Error::TYPE_MISMATCH, "Not a collection");
409431
}
410432

411433
const Value& ValueImpl::tag_at(uint64_t tag) const
412434
{
413435
if (!std::holds_alternative<Tagged>(value))
414436
{
415-
throw CBORDecodeError("Not a tagged value");
437+
throw CBORDecodeError(Error::TYPE_MISMATCH, "Not a tagged value");
416438
}
417439

418440
const auto& tagged = std::get<Tagged>(value);
419441
if (tagged.tag != tag)
420442
{
421-
throw CBORDecodeError("Tag does not match");
443+
throw CBORDecodeError(Error::KEY_NOT_FOUND, "Tag does not match");
422444
}
423445

424446
return tagged.item;
@@ -428,7 +450,7 @@ namespace ccf::cbor
428450
{
429451
if (!std::holds_alternative<Signed>(value))
430452
{
431-
throw CBORDecodeError("Not a signed value");
453+
throw CBORDecodeError(Error::TYPE_MISMATCH, "Not a signed value");
432454
}
433455
return std::get<Signed>(value);
434456
}
@@ -437,7 +459,7 @@ namespace ccf::cbor
437459
{
438460
if (!std::holds_alternative<Bytes>(value))
439461
{
440-
throw CBORDecodeError("Not a bytes value");
462+
throw CBORDecodeError(Error::TYPE_MISMATCH, "Not a bytes value");
441463
}
442464
return std::get<Bytes>(value);
443465
}
@@ -446,7 +468,7 @@ namespace ccf::cbor
446468
{
447469
if (!std::holds_alternative<String>(value))
448470
{
449-
throw CBORDecodeError("Not a string value");
471+
throw CBORDecodeError(Error::TYPE_MISMATCH, "Not a string value");
450472
}
451473
return std::get<String>(value);
452474
}
@@ -455,7 +477,7 @@ namespace ccf::cbor
455477
{
456478
if (!std::holds_alternative<Simple>(value))
457479
{
458-
throw CBORDecodeError("Not a simple value");
480+
throw CBORDecodeError(Error::TYPE_MISMATCH, "Not a simple value");
459481
}
460482
return std::get<Simple>(value);
461483
}

src/crypto/cbor.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,24 @@ namespace ccf::cbor
5353

5454
using Type = std::variant<Signed, Bytes, String, Array, Map, Tagged, Simple>;
5555

56-
using CBORDecodeError = std::runtime_error;
56+
enum class Error : uint8_t
57+
{
58+
UNDEFINED = 0,
59+
DECODE_FAILED = 1,
60+
KEY_NOT_FOUND = 2,
61+
OUT_OF_BOUND = 3,
62+
TYPE_MISMATCH = 4,
63+
};
64+
65+
class CBORDecodeError : public std::runtime_error
66+
{
67+
public:
68+
explicit CBORDecodeError(Error err, const std::string& what);
69+
[[nodiscard]] Error error_code() const;
70+
71+
private:
72+
Error error{Error::UNDEFINED};
73+
};
5774

5875
struct ValueImpl
5976
{
@@ -88,7 +105,8 @@ namespace ccf::cbor
88105
{
89106
if (!msg.empty())
90107
{
91-
throw CBORDecodeError(fmt::format("{}: {}", msg, err.what()));
108+
throw CBORDecodeError(
109+
err.error_code(), fmt::format("{}: {}", msg, err.what()));
92110
}
93111
throw err;
94112
}

0 commit comments

Comments
 (0)