-
Notifications
You must be signed in to change notification settings - Fork 260
Introduce identity type map #8263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+181
−0
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
615438e
Introduce identity type map
maxtropets e52376a
Merge branch 'main' into f/multisign-part-1
maxtropets 3b2809d
Merge branch 'main' into f/multisign-part-1
achamayou bc6ba09
Name the EC identity type after its signature algorithm
maxtropets 7596f5f
Name identity types and kinds after what they are, not what they measure
maxtropets 46c2220
Drop speculative comment from IdentityKind
maxtropets 5e23dca
Name identity types after the signature scheme, not the JOSE prefix
maxtropets eb7a7f4
Merge branch 'main' into f/multisign-part-1
maxtropets 52ecb08
Name identity types by algorithm class, not by algorithm
maxtropets e26cb24
Merge branch 'f/multisign-part-1' of https://github.com/microsoft/CCF…
maxtropets a883c0c
Merge branch 'main' into f/multisign-part-1
maxtropets File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the Apache 2.0 License. | ||
|
|
||
| #include "service/tables/identity_types.h" | ||
|
|
||
| #include "ccf/kv/unit.h" | ||
|
|
||
| #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN | ||
| #include <array> | ||
| #include <cstdint> | ||
| #include <doctest/doctest.h> | ||
| #include <limits> | ||
| #include <set> | ||
| #include <stdexcept> | ||
| #include <string> | ||
| #include <vector> | ||
|
|
||
| using IdentityTypeSerialiser = | ||
| ccf::kv::serialisers::BlitSerialiser<ccf::IdentityType>; | ||
|
|
||
| static constexpr std::array<ccf::IdentityType, 2> IDENTITY_TYPES = { | ||
| ccf::IdentityType::CLASSICAL, ccf::IdentityType::PQ}; | ||
|
|
||
| TEST_CASE("CLASSICAL shares the serialised key of a single-Value table") | ||
| { | ||
| // ServiceValue is a Map with a single entry, whose key is 8 null bytes. A | ||
| // table keyed by IdentityType is therefore serialised identically to a | ||
| // ServiceValue for as long as CLASSICAL is its only entry. | ||
| REQUIRE( | ||
| IdentityTypeSerialiser::to_serialised(ccf::IdentityType::CLASSICAL) == | ||
| ccf::kv::serialisers::ZeroBlitUnitCreator::get()); | ||
|
|
||
| REQUIRE( | ||
| IdentityTypeSerialiser::to_serialised(ccf::IdentityType::PQ) != | ||
| ccf::kv::serialisers::ZeroBlitUnitCreator::get()); | ||
| } | ||
|
|
||
| TEST_CASE("IdentityType serialisation round-trips") | ||
| { | ||
| for (const auto identity_type : IDENTITY_TYPES) | ||
| { | ||
| const auto serialised = | ||
| IdentityTypeSerialiser::to_serialised(identity_type); | ||
| REQUIRE(serialised.size() == sizeof(uint64_t)); | ||
| REQUIRE( | ||
| IdentityTypeSerialiser::from_serialised(serialised) == identity_type); | ||
| } | ||
| } | ||
|
|
||
| TEST_CASE("Unknown identity types are rejected") | ||
| { | ||
| const auto unknown = | ||
| ccf::kv::serialisers::BlitSerialiser<uint64_t>::to_serialised( | ||
| std::numeric_limits<uint64_t>::max()); | ||
| REQUIRE_THROWS_AS( | ||
| IdentityTypeSerialiser::from_serialised(unknown), std::logic_error); | ||
| } | ||
|
|
||
| TEST_CASE("IdentityType names are distinct and stable") | ||
| { | ||
| // These names will appear in the ledger, so they must not change. | ||
| REQUIRE(nlohmann::json(ccf::IdentityType::CLASSICAL) == "CLASSICAL"); | ||
| REQUIRE(nlohmann::json(ccf::IdentityType::PQ) == "PQ"); | ||
|
|
||
| std::set<std::string> names; | ||
| for (const auto identity_type : IDENTITY_TYPES) | ||
| { | ||
| const nlohmann::json name = identity_type; | ||
| REQUIRE(names.insert(name.get<std::string>()).second); | ||
| } | ||
| REQUIRE(names.size() == IDENTITY_TYPES.size()); | ||
| } | ||
|
|
||
| TEST_CASE("Identity round-trips through JSON") | ||
| { | ||
| const ccf::Identity identity{ | ||
| ccf::IdentityKind::X509_SPKI_DER, std::vector<uint8_t>{1, 2, 3, 4}}; | ||
|
|
||
| const nlohmann::json j = identity; | ||
| REQUIRE(j["kind"] == "X509_SPKI_DER"); | ||
|
|
||
| REQUIRE(j.get<ccf::Identity>() == identity); | ||
| } | ||
|
|
||
| TEST_CASE("Identities round-trips through JSON") | ||
| { | ||
| const ccf::Identities identities{ | ||
| {ccf::IdentityType::CLASSICAL, | ||
| {ccf::IdentityKind::X509_CERT_DER, std::vector<uint8_t>{1, 2}}}, | ||
| {ccf::IdentityType::PQ, | ||
| {ccf::IdentityKind::X509_SPKI_DER, std::vector<uint8_t>{3, 4}}}}; | ||
|
|
||
| const nlohmann::json j = identities; | ||
| REQUIRE(j.get<ccf::Identities>() == identities); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the Apache 2.0 License. | ||
| #pragma once | ||
|
|
||
| #include "ccf/ds/json.h" | ||
| #include "ccf/kv/serialisers/blit_serialiser.h" | ||
|
|
||
| #include <cstdint> | ||
| #include <map> | ||
| #include <stdexcept> | ||
| #include <vector> | ||
|
|
||
| namespace ccf | ||
| { | ||
| enum class IdentityType : uint64_t | ||
| { | ||
| CLASSICAL = 0, | ||
| PQ = 1, | ||
| }; | ||
|
|
||
| DECLARE_JSON_ENUM( | ||
| IdentityType, | ||
| {{IdentityType::CLASSICAL, "CLASSICAL"}, {IdentityType::PQ, "PQ"}}); | ||
|
|
||
| enum class IdentityKind : uint8_t | ||
| { | ||
| X509_CERT_DER = 0, | ||
| X509_SPKI_DER = 1, | ||
| }; | ||
|
|
||
| DECLARE_JSON_ENUM( | ||
| IdentityKind, | ||
| {{IdentityKind::X509_CERT_DER, "X509_CERT_DER"}, | ||
| {IdentityKind::X509_SPKI_DER, "X509_SPKI_DER"}}); | ||
|
|
||
| using IdentityValue = std::vector<uint8_t>; | ||
|
|
||
| struct Identity | ||
| { | ||
| IdentityKind kind; | ||
| IdentityValue value; | ||
|
|
||
| bool operator==(const Identity&) const = default; | ||
| }; | ||
|
|
||
| DECLARE_JSON_TYPE(Identity); | ||
| DECLARE_JSON_REQUIRED_FIELDS(Identity, kind, value); | ||
|
maxtropets marked this conversation as resolved.
|
||
|
|
||
| using Identities = std::map<IdentityType, Identity>; | ||
| } | ||
|
|
||
| namespace ccf::kv::serialisers | ||
| { | ||
| // IdentityType is used as a KV key by tables which were previously a single | ||
| // Value. CLASSICAL is 0, so it serialises to the same bytes as the unit key | ||
| // of those tables, keeping their serialised form unchanged. | ||
| template <> | ||
| struct BlitSerialiser<ccf::IdentityType> | ||
| { | ||
| static SerialisedEntry to_serialised(const ccf::IdentityType& identity_type) | ||
| { | ||
| return BlitSerialiser<uint64_t>::to_serialised( | ||
| static_cast<uint64_t>(identity_type)); | ||
| } | ||
|
|
||
| static ccf::IdentityType from_serialised(const SerialisedEntry& data) | ||
| { | ||
| const auto value = BlitSerialiser<uint64_t>::from_serialised(data); | ||
| switch (value) | ||
| { | ||
| case static_cast<uint64_t>(ccf::IdentityType::CLASSICAL): | ||
| return ccf::IdentityType::CLASSICAL; | ||
| case static_cast<uint64_t>(ccf::IdentityType::PQ): | ||
| return ccf::IdentityType::PQ; | ||
| default: | ||
| throw std::logic_error( | ||
| fmt::format("Unknown identity type: {}", value)); | ||
| } | ||
| } | ||
| }; | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.