-
Notifications
You must be signed in to change notification settings - Fork 114
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add centralized C++ utilities for oak::Variant.
Library can be imported via copybara and then used in the hostlibs. This will make the present ad-hoc solution in the hostlibs obsolete, and also keeps anthing variant-related (in particular the UUID definitions) with the proto definitions in open source. Bug: 373829620 Change-Id: I0e715126807a96fc2b48662350011d3e031a0521
- Loading branch information
1 parent
177e291
commit e41a678
Showing
5 changed files
with
328 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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,45 @@ | ||
# | ||
# Copyright 2025 The Project Oak Authors | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
|
||
package( | ||
default_visibility = ["//:default_visibility"], | ||
licenses = ["notice"], | ||
) | ||
|
||
cc_library( | ||
name = "variant", | ||
srcs = [ | ||
"uuids.h", | ||
"variant.cc", | ||
], | ||
hdrs = ["variant.h"], | ||
deps = [ | ||
"//proto:variant_cc_proto", | ||
"//proto/attestation:endorsement_cc_proto", | ||
"@com_google_absl//absl/log:check", | ||
"@com_google_absl//absl/strings", | ||
], | ||
) | ||
|
||
cc_test( | ||
name = "variant_test", | ||
srcs = ["variant_test.cc"], | ||
deps = [ | ||
":variant", | ||
"//proto/attestation:endorsement_cc_proto", | ||
"@com_google_googletest//:gtest_main", | ||
], | ||
) |
This file contains 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,41 @@ | ||
/* | ||
* Copyright 2025 The Project Oak Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#ifndef CC_UTILS_VARIANT_UUIDS_H_ | ||
#define CC_UTILS_VARIANT_UUIDS_H_ | ||
|
||
#include "absl/strings/string_view.h" | ||
|
||
namespace oak { | ||
namespace internal { | ||
|
||
constexpr absl::string_view kAmdSevSnpPlatformEndorsementUuid = | ||
"5a12d00f-48a0-4224-bff4-975c7657438f"; | ||
constexpr absl::string_view kFirmwareEndorsementUuid = | ||
"de4a0d55-60ea-4dc6-abd1-09ed744f80ea"; | ||
constexpr absl::string_view kKernelEndorsementUuid = | ||
"89511d65-5d35-4601-900b-1e6dbaf842b6"; | ||
constexpr absl::string_view kSystemEndorsementUuid = | ||
"4722655d-963d-4fc9-8443-f14571dd32a2"; | ||
constexpr absl::string_view kContainerEndorsementUuid = | ||
"7297a51f-a05d-49a1-afdb-64cdee07862d"; | ||
constexpr absl::string_view kApplicationEndorsementUuid = | ||
"e84ed714-669d-430a-a60f-8a651e5a5503"; | ||
|
||
} // namespace internal | ||
} // namespace oak | ||
|
||
#endif // CC_UTILS_VARIANT_UUIDS_H_ |
This file contains 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,139 @@ | ||
/* | ||
* Copyright 2025 The Project Oak Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include "cc/utils/variant/variant.h" | ||
|
||
#include <optional> | ||
#include <string> | ||
|
||
#include "absl/log/check.h" | ||
#include "absl/strings/escaping.h" | ||
#include "absl/strings/str_replace.h" | ||
#include "absl/strings/string_view.h" | ||
#include "cc/utils/variant/uuids.h" | ||
#include "proto/attestation/endorsement.pb.h" | ||
|
||
namespace oak { | ||
namespace { | ||
|
||
using ::oak::attestation::v1::AmdSevSnpEndorsement; | ||
using ::oak::attestation::v1::ApplicationEndorsement; | ||
using ::oak::attestation::v1::ContainerEndorsement; | ||
using ::oak::attestation::v1::FirmwareEndorsement; | ||
using ::oak::attestation::v1::KernelEndorsement; | ||
using ::oak::attestation::v1::SystemEndorsement; | ||
|
||
std::string RawUuid(absl::string_view uuidHex) { | ||
std::string strip = absl::StrReplaceAll(uuidHex, {{"-", ""}}); | ||
std::string raw; | ||
CHECK(absl::HexStringToBytes(strip, &raw)); | ||
CHECK_EQ(raw.length(), 16u); // 128 bits | ||
return raw; | ||
} | ||
|
||
template <typename T> | ||
Variant CreateVariant(absl::string_view uuidHex, const T& message) { | ||
std::string serialized; | ||
CHECK(message.SerializeToString(&serialized)); | ||
|
||
Variant variant; | ||
variant.set_id(RawUuid(uuidHex)); | ||
variant.set_value(serialized); | ||
return variant; | ||
} | ||
|
||
template <typename T> | ||
std::optional<T> ParseVariant(absl::string_view uuidHex, | ||
const Variant& variant) { | ||
if (RawUuid(uuidHex) != variant.id()) { | ||
return std::nullopt; | ||
} | ||
|
||
T message; | ||
message.ParseFromString(variant.value()); | ||
return message; | ||
} | ||
|
||
} // namespace | ||
|
||
template <> | ||
Variant ToVariant<AmdSevSnpEndorsement>(const AmdSevSnpEndorsement& message) { | ||
return CreateVariant(internal::kAmdSevSnpPlatformEndorsementUuid, message); | ||
} | ||
|
||
template <> | ||
Variant ToVariant<FirmwareEndorsement>(const FirmwareEndorsement& message) { | ||
return CreateVariant(internal::kFirmwareEndorsementUuid, message); | ||
} | ||
|
||
template <> | ||
Variant ToVariant<KernelEndorsement>(const KernelEndorsement& message) { | ||
return CreateVariant(internal::kKernelEndorsementUuid, message); | ||
} | ||
|
||
template <> | ||
Variant ToVariant<SystemEndorsement>(const SystemEndorsement& message) { | ||
return CreateVariant(internal::kSystemEndorsementUuid, message); | ||
} | ||
|
||
template <> | ||
Variant ToVariant<ContainerEndorsement>(const ContainerEndorsement& message) { | ||
return CreateVariant(internal::kContainerEndorsementUuid, message); | ||
} | ||
|
||
template <> | ||
Variant ToVariant<ApplicationEndorsement>( | ||
const ApplicationEndorsement& message) { | ||
return CreateVariant(internal::kApplicationEndorsementUuid, message); | ||
} | ||
|
||
template <> | ||
std::optional<AmdSevSnpEndorsement> FromVariant(const Variant& variant) { | ||
return ParseVariant<AmdSevSnpEndorsement>( | ||
internal::kAmdSevSnpPlatformEndorsementUuid, variant); | ||
} | ||
|
||
template <> | ||
std::optional<FirmwareEndorsement> FromVariant(const Variant& variant) { | ||
return ParseVariant<FirmwareEndorsement>(internal::kFirmwareEndorsementUuid, | ||
variant); | ||
} | ||
|
||
template <> | ||
std::optional<KernelEndorsement> FromVariant(const Variant& variant) { | ||
return ParseVariant<KernelEndorsement>(internal::kKernelEndorsementUuid, | ||
variant); | ||
} | ||
|
||
template <> | ||
std::optional<SystemEndorsement> FromVariant(const Variant& variant) { | ||
return ParseVariant<SystemEndorsement>(internal::kSystemEndorsementUuid, | ||
variant); | ||
} | ||
|
||
template <> | ||
std::optional<ContainerEndorsement> FromVariant(const Variant& variant) { | ||
return ParseVariant<ContainerEndorsement>(internal::kContainerEndorsementUuid, | ||
variant); | ||
} | ||
|
||
template <> | ||
std::optional<ApplicationEndorsement> FromVariant(const Variant& variant) { | ||
return ParseVariant<ApplicationEndorsement>( | ||
internal::kApplicationEndorsementUuid, variant); | ||
} | ||
|
||
} // namespace oak |
This file contains 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,38 @@ | ||
/* | ||
* Copyright 2025 The Project Oak Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#ifndef CC_UTILS_VARIANT_VARIANT_H_ | ||
#define CC_UTILS_VARIANT_VARIANT_H_ | ||
|
||
#include <optional> | ||
|
||
#include "proto/variant.pb.h" | ||
|
||
namespace oak { | ||
|
||
// Converts a proto message to a Variant proto. | ||
// Compiles as long as we have UUID coverage for message type T. | ||
template <typename T> | ||
Variant ToVariant(const T& message); | ||
|
||
// Converts a Variant proto to a proto message. | ||
// Returns empty whenever `variant` does not contain type T. | ||
template <typename T> | ||
std::optional<T> FromVariant(const Variant& variant); | ||
|
||
} // namespace oak | ||
|
||
#endif // CC_UTILS_VARIANT_VARIANT_H_ |
This file contains 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,65 @@ | ||
/* | ||
* Copyright 2025 The Project Oak Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include "cc/utils/variant/variant.h" | ||
|
||
#include <string> | ||
|
||
#include "gmock/gmock.h" | ||
#include "gtest/gtest.h" | ||
#include "proto/attestation/endorsement.pb.h" | ||
|
||
namespace oak { | ||
namespace { | ||
|
||
using ::oak::attestation::v1::AmdSevSnpEndorsement; | ||
using ::oak::attestation::v1::ApplicationEndorsement; | ||
using ::oak::attestation::v1::ContainerEndorsement; | ||
using ::oak::attestation::v1::FirmwareEndorsement; | ||
using ::oak::attestation::v1::KernelEndorsement; | ||
using ::oak::attestation::v1::SystemEndorsement; | ||
|
||
template <typename T> | ||
class VariantTest : public testing::Test { | ||
public: | ||
bool CompareProtos(const T& proto1, const T& proto2) { | ||
std::string serialized1, serialized2; | ||
EXPECT_TRUE(proto1.SerializeToString(&serialized1)); | ||
EXPECT_TRUE(proto2.SerializeToString(&serialized2)); | ||
return serialized1 == serialized2; | ||
} | ||
|
||
T CreateInstance() { return T(); } | ||
}; | ||
|
||
TYPED_TEST_SUITE_P(VariantTest); | ||
|
||
TYPED_TEST_P(VariantTest, Inverse) { | ||
TypeParam expected = this->CreateInstance(); | ||
TypeParam actual = FromVariant<TypeParam>(ToVariant(expected)).value(); | ||
EXPECT_TRUE(this->CompareProtos(actual, expected)); | ||
} | ||
|
||
REGISTER_TYPED_TEST_SUITE_P(VariantTest, Inverse); | ||
|
||
using TestTypes = testing::Types<AmdSevSnpEndorsement, FirmwareEndorsement, | ||
KernelEndorsement, SystemEndorsement, | ||
ContainerEndorsement, ApplicationEndorsement>; | ||
|
||
INSTANTIATE_TYPED_TEST_SUITE_P(TypedTestSuite, VariantTest, TestTypes); | ||
|
||
} // namespace | ||
} // namespace oak |