Skip to content

Commit 4eacec6

Browse files
authored
Use new CBOR wrappers in COSE verifier (#7573)
1 parent 7acf51e commit 4eacec6

File tree

1 file changed

+54
-160
lines changed

1 file changed

+54
-160
lines changed

src/crypto/openssl/cose_verifier.cpp

Lines changed: 54 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "ds/internal_logger.h"
1111
#include "x509_time.h"
1212

13+
#include <crypto/cbor.h>
1314
#include <openssl/evp.h>
1415
#include <openssl/ossl_typ.h>
1516
#include <openssl/x509.h>
@@ -27,72 +28,27 @@ namespace
2728
std::optional<int> extract_algorithm_from_header(
2829
std::span<const uint8_t> cose_msg)
2930
{
30-
UsefulBufC msg{cose_msg.data(), cose_msg.size()};
31-
QCBORError qcbor_result = QCBOR_SUCCESS;
31+
using namespace ccf::cbor;
3232

33-
QCBORDecodeContext ctx;
34-
QCBORDecode_Init(&ctx, msg, QCBOR_DECODE_MODE_NORMAL);
33+
auto cose_cbor =
34+
rethrow_with_msg([&]() { return parse(cose_msg); }, "Parse COSE CBOR");
3535

36-
QCBORDecode_EnterArray(&ctx, nullptr);
37-
qcbor_result = QCBORDecode_GetError(&ctx);
38-
if (qcbor_result != QCBOR_SUCCESS)
39-
{
40-
LOG_DEBUG_FMT("Failed to parse COSE_Sign1 outer array");
41-
return std::nullopt;
42-
}
43-
44-
const uint64_t tag = QCBORDecode_GetNthTagOfLast(&ctx, 0);
45-
if (tag != CBOR_TAG_COSE_SIGN1)
46-
{
47-
LOG_DEBUG_FMT("Failed to parse COSE_Sign1 tag");
48-
return std::nullopt;
49-
}
50-
51-
q_useful_buf_c protected_parameters = {};
52-
QCBORDecode_EnterBstrWrapped(
53-
&ctx, QCBOR_TAG_REQUIREMENT_NOT_A_TAG, &protected_parameters);
54-
QCBORDecode_EnterMap(&ctx, nullptr);
55-
56-
enum HeaderIndex : uint8_t
57-
{
58-
ALG_INDEX,
59-
END_INDEX
60-
};
61-
QCBORItem header_items[END_INDEX + 1];
62-
63-
header_items[ALG_INDEX].label.int64 = ccf::crypto::COSE_PHEADER_KEY_ALG;
64-
header_items[ALG_INDEX].uLabelType = QCBOR_TYPE_INT64;
65-
header_items[ALG_INDEX].uDataType = QCBOR_TYPE_INT64;
66-
67-
header_items[END_INDEX].uLabelType = QCBOR_TYPE_NONE;
68-
69-
QCBORDecode_GetItemsInMap(&ctx, static_cast<QCBORItem*>(header_items));
70-
qcbor_result = QCBORDecode_GetError(&ctx);
71-
if (qcbor_result != QCBOR_SUCCESS)
72-
{
73-
LOG_DEBUG_FMT("Failed to decode protected header");
74-
return std::nullopt;
75-
}
36+
const auto& cose_envelope = rethrow_with_msg(
37+
[&]() -> auto& { return cose_cbor->tag_at(18); }, "Parse COSE tag");
7638

77-
if (header_items[ALG_INDEX].uDataType == QCBOR_TYPE_NONE)
78-
{
79-
LOG_DEBUG_FMT("Failed to retrieve (missing) 'alg' parameter");
80-
return std::nullopt;
81-
}
39+
const auto& phdr_raw = rethrow_with_msg(
40+
[&]() -> auto& { return cose_envelope->array_at(0); },
41+
"Parse raw protected header");
8242

83-
const int alg = header_items[ALG_INDEX].val.int64;
43+
auto phdr = rethrow_with_msg(
44+
[&]() { return parse(phdr_raw->as_bytes()); }, "Decode protected header");
8445

85-
// Complete decode to ensure well-formed CBOR.
86-
87-
QCBORDecode_ExitMap(&ctx);
88-
QCBORDecode_ExitBstrWrapped(&ctx);
89-
90-
qcbor_result = QCBORDecode_GetError(&ctx);
91-
if (qcbor_result != QCBOR_SUCCESS)
92-
{
93-
LOG_DEBUG_FMT("Failed to decode protected header: {}", qcbor_result);
94-
return std::nullopt;
95-
}
46+
const int64_t alg = rethrow_with_msg(
47+
[&]() {
48+
return phdr->map_at(make_signed(ccf::crypto::COSE_PHEADER_KEY_ALG))
49+
->as_signed();
50+
},
51+
"Retrieve alg from protected header");
9652

9753
return alg;
9854
}
@@ -250,104 +206,42 @@ namespace ccf::crypto
250206
COSEEndorsementValidity extract_cose_endorsement_validity(
251207
std::span<const uint8_t> cose_msg)
252208
{
253-
UsefulBufC msg{cose_msg.data(), cose_msg.size()};
254-
QCBORError qcbor_result = QCBOR_SUCCESS;
255-
256-
QCBORDecodeContext ctx;
257-
QCBORDecode_Init(&ctx, msg, QCBOR_DECODE_MODE_NORMAL);
258-
259-
QCBORDecode_EnterArray(&ctx, nullptr);
260-
qcbor_result = QCBORDecode_GetError(&ctx);
261-
if (qcbor_result != QCBOR_SUCCESS)
262-
{
263-
throw std::logic_error("Failed to parse COSE_Sign1 outer array");
264-
}
265-
266-
const uint64_t tag = QCBORDecode_GetNthTagOfLast(&ctx, 0);
267-
if (tag != CBOR_TAG_COSE_SIGN1)
268-
{
269-
throw std::logic_error("Failed to parse COSE_Sign1 tag");
270-
}
271-
272-
q_useful_buf_c protected_parameters = {};
273-
274-
QCBORDecode_EnterBstrWrapped(
275-
&ctx, QCBOR_TAG_REQUIREMENT_NOT_A_TAG, &protected_parameters);
276-
277-
qcbor_result = QCBORDecode_GetError(&ctx);
278-
if (qcbor_result != QCBOR_SUCCESS)
279-
{
280-
throw std::logic_error("Failed to parse COSE_Sign1 as bstr");
281-
}
282-
283-
QCBORDecode_EnterMap(&ctx, nullptr); // phdr
284-
QCBORDecode_EnterMapFromMapSZ(&ctx, "ccf.v1"); // phdr["ccf.v1"]
285-
286-
qcbor_result = QCBORDecode_GetError(&ctx);
287-
if (qcbor_result != QCBOR_SUCCESS)
288-
{
289-
throw std::logic_error("Failed to parse COSE_Sign1 wrapped map");
290-
}
291-
292-
enum HeaderIndex : uint8_t
293-
{
294-
FROM_INDEX,
295-
TO_INDEX,
296-
END_INDEX
297-
};
298-
QCBORItem header_items[END_INDEX + 1];
299-
300-
header_items[FROM_INDEX].label.string = UsefulBufC{
301-
ccf::crypto::COSE_PHEADER_KEY_RANGE_BEGIN.data(),
302-
ccf::crypto::COSE_PHEADER_KEY_RANGE_BEGIN.size()};
303-
header_items[FROM_INDEX].uLabelType = QCBOR_TYPE_TEXT_STRING;
304-
header_items[FROM_INDEX].uDataType = QCBOR_TYPE_TEXT_STRING;
305-
306-
header_items[TO_INDEX].label.string = UsefulBufC{
307-
ccf::crypto::COSE_PHEADER_KEY_RANGE_END.data(),
308-
ccf::crypto::COSE_PHEADER_KEY_RANGE_END.size()};
309-
header_items[TO_INDEX].uLabelType = QCBOR_TYPE_TEXT_STRING;
310-
header_items[TO_INDEX].uDataType = QCBOR_TYPE_TEXT_STRING;
311-
312-
header_items[END_INDEX].uLabelType = QCBOR_TYPE_NONE;
313-
314-
QCBORDecode_GetItemsInMap(&ctx, static_cast<QCBORItem*>(header_items));
315-
qcbor_result = QCBORDecode_GetError(&ctx);
316-
if (qcbor_result != QCBOR_SUCCESS)
317-
{
318-
throw std::logic_error("Failed to decode protected header");
319-
}
320-
321-
if (header_items[FROM_INDEX].uDataType == QCBOR_TYPE_NONE)
322-
{
323-
throw std::logic_error(fmt::format(
324-
"Failed to retrieve (missing) {} parameter",
325-
ccf::crypto::COSE_PHEADER_KEY_RANGE_BEGIN));
326-
}
327-
328-
if (header_items[TO_INDEX].uDataType == QCBOR_TYPE_NONE)
329-
{
330-
throw std::logic_error(fmt::format(
331-
"Failed to retrieve (missing) {} parameter",
332-
ccf::crypto::COSE_PHEADER_KEY_RANGE_END));
333-
}
334-
335-
const auto from = qcbor_buf_to_string(header_items[FROM_INDEX].val.string);
336-
const auto to = qcbor_buf_to_string(header_items[TO_INDEX].val.string);
337-
338-
// Complete decode to ensure well-formed CBOR.
339-
340-
QCBORDecode_ExitMap(&ctx); // phdr["ccf.v1"]
341-
QCBORDecode_ExitMap(&ctx); // phdr
342-
QCBORDecode_ExitBstrWrapped(&ctx);
343-
344-
qcbor_result = QCBORDecode_GetError(&ctx);
345-
if (qcbor_result != QCBOR_SUCCESS)
346-
{
347-
throw std::logic_error(fmt::format(
348-
"Failed to decode protected header with error code: {}", qcbor_result));
349-
}
350-
351-
return COSEEndorsementValidity{.from_txid = from, .to_txid = to};
209+
using namespace ccf::cbor;
210+
211+
auto cose_cbor =
212+
rethrow_with_msg([&]() { return parse(cose_msg); }, "Parse COSE CBOR");
213+
214+
const auto& cose_envelope = rethrow_with_msg(
215+
[&]() -> auto& { return cose_cbor->tag_at(18); }, "Parse COSE tag");
216+
217+
const auto& phdr_raw = rethrow_with_msg(
218+
[&]() -> auto& { return cose_envelope->array_at(0); },
219+
"Parse raw protected header");
220+
221+
auto phdr = rethrow_with_msg(
222+
[&]() { return parse(phdr_raw->as_bytes()); }, "Decode protected header");
223+
224+
const auto& ccf_claims = rethrow_with_msg(
225+
[&]() -> auto& {
226+
return phdr->map_at(make_string(ccf::crypto::COSE_PHEADER_KEY_CCF));
227+
},
228+
"Retrieve CCF claims");
229+
230+
auto from = rethrow_with_msg(
231+
[&]() {
232+
return ccf_claims->map_at(make_string(COSE_PHEADER_KEY_RANGE_BEGIN))
233+
->as_string();
234+
},
235+
"Retrieve epoch range begin");
236+
237+
auto to = rethrow_with_msg(
238+
[&]() {
239+
return ccf_claims->map_at(make_string(COSE_PHEADER_KEY_RANGE_END))
240+
->as_string();
241+
},
242+
"Retrieve epoch range end");
243+
244+
return COSEEndorsementValidity{
245+
.from_txid = std::string(from), .to_txid = std::string(to)};
352246
}
353247
}

0 commit comments

Comments
 (0)