Skip to content

Commit c942ccb

Browse files
authored
Encode COSE signature kids to hex to make them text-format friendly (#6703)
1 parent 44a5155 commit c942ccb

File tree

6 files changed

+15
-11
lines changed

6 files changed

+15
-11
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1212
### Changed
1313

1414
- The `read_ledger.py` tool now has a `--quiet` option which avoids printing anything per-transaction, as well as other performance improvements, which should make it more useful in verifying the integrity of large ledgers.
15+
- COSE signatures now set a kid that is a hex-encoded SHA-256 of the DER representation of the key used to produce them (#6703).
1516

1617
## [6.0.0-dev8]
1718

cddl/ccf-merkle-tree-cose-signature.cddl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ unprotected-headers = {
1313

1414
protected-headers = {
1515
&(alg: 1) => int, ; signing algoritm ID, as per RFC8152
16-
&(kid: 4) => bstr, ; signing key hash
16+
&(kid: 4) => bstr, ; Opaque key identifier, hex-encoded SHA-256 of the public key encoded as DER.
1717
&(cwt: 15) => cwt-map, ; CWT claims, as per RFC8392
1818
&(vds: 395) => int, ; verifiable data structure, as per COSE Receipts (draft) RFC (https://datatracker.ietf.org/doc/draft-ietf-cose-merkle-tree-proofs/)
1919
"ccf.v1" => ccf-map ; a set of CCF-specific parameters

python/src/ccf/cose.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,12 @@ def verify_receipt(
211211
# Extract the expected KID from the public key used for verification,
212212
# and check it against the value set in the COSE header before using
213213
# it to verify the proofs.
214-
expected_kid = sha256(
215-
key.public_bytes(Encoding.DER, PublicFormat.SubjectPublicKeyInfo)
216-
).digest()
214+
expected_kid = (
215+
sha256(key.public_bytes(Encoding.DER, PublicFormat.SubjectPublicKeyInfo))
216+
.digest()
217+
.hex()
218+
.encode()
219+
)
217220
receipt = Sign1Message.decode(receipt_bytes)
218221
cose_key = from_cryptography_eckey_obj(key)
219222
assert receipt.phdr[pycose.headers.KID] == expected_kid

src/crypto/openssl/cose_sign.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ namespace ccf::crypto
200200
}
201201

202202
std::shared_ptr<COSEParametersFactory> cose_params_int_bytes(
203-
int64_t key, const std::vector<uint8_t>& value)
203+
int64_t key, std::span<const uint8_t> value)
204204
{
205205
const size_t args_size = sizeof(key) + value.size() +
206206
+extra_size_for_int_tag + extra_size_for_seq_tag;
@@ -213,7 +213,7 @@ namespace ccf::crypto
213213
}
214214

215215
std::shared_ptr<COSEParametersFactory> cose_params_string_bytes(
216-
const std::string& key, const std::vector<uint8_t>& value)
216+
const std::string& key, std::span<const uint8_t> value)
217217
{
218218
const size_t args_size = key.size() + value.size() +
219219
extra_size_for_seq_tag + extra_size_for_seq_tag;

src/crypto/openssl/cose_sign.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,10 @@ namespace ccf::crypto
129129
const std::string& key, const std::string& value);
130130

131131
std::shared_ptr<COSEParametersFactory> cose_params_int_bytes(
132-
int64_t key, const std::vector<uint8_t>& value);
132+
int64_t key, std::span<const uint8_t> value);
133133

134134
std::shared_ptr<COSEParametersFactory> cose_params_string_bytes(
135-
const std::string& key, const std::vector<uint8_t>& value);
135+
const std::string& key, std::span<const uint8_t> value);
136136

137137
class COSEParametersPair : public COSEParametersFactory
138138
{

src/node/history.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -379,8 +379,8 @@ namespace ccf
379379
constexpr int64_t vds_merkle_tree = 2;
380380

381381
const auto& service_key_der = service_kp.public_key_der();
382-
std::vector<uint8_t> kid(SHA256_DIGEST_LENGTH);
383-
SHA256(service_key_der.data(), service_key_der.size(), kid.data());
382+
auto kid = ccf::crypto::Sha256Hash(service_key_der).hex_str();
383+
std::span<const uint8_t> kid_span{(uint8_t*)kid.data(), kid.size()};
384384

385385
const auto time_since_epoch =
386386
std::chrono::duration_cast<std::chrono::seconds>(
@@ -415,7 +415,7 @@ namespace ccf
415415
const auto pheaders = {
416416
// Key digest
417417
ccf::crypto::cose_params_int_bytes(
418-
ccf::crypto::COSE_PHEADER_KEY_ID, kid),
418+
ccf::crypto::COSE_PHEADER_KEY_ID, kid_span),
419419
// VDS
420420
ccf::crypto::cose_params_int_int(
421421
ccf::crypto::COSE_PHEADER_KEY_VDS, vds_merkle_tree),

0 commit comments

Comments
 (0)