Skip to content

Commit bc3fdb4

Browse files
committed
Pass the PCK certificates down to Intel DCAP
Update the QE remote assertion generator so that certificates are passed through to the Intel code through the Intel architectural enclave API. Mark the QE assertion generator and verifier code/protos as public since QE-based assertions are now fully functional. PiperOrigin-RevId: 322399797 Change-Id: I1fff9f0f901f61e6f0d07bd42b284c84dbc16197
1 parent 68d11ed commit bc3fdb4

File tree

5 files changed

+48
-105
lines changed

5 files changed

+48
-105
lines changed

asylo/identity/attestation/sgx/BUILD

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ cc_proto_library(
5353
proto_library(
5454
name = "sgx_intel_ecdsa_qe_remote_assertion_authority_config_proto",
5555
srcs = ["sgx_intel_ecdsa_qe_remote_assertion_authority_config.proto"],
56-
visibility = ["//asylo:implementation"],
56+
visibility = ["//visibility:public"],
5757
deps = [
5858
"//asylo/crypto:certificate_proto",
5959
"//asylo/identity:identity_acl_proto",
@@ -62,7 +62,7 @@ proto_library(
6262

6363
cc_proto_library(
6464
name = "sgx_intel_ecdsa_qe_remote_assertion_authority_config_cc_proto",
65-
visibility = ["//asylo:implementation"],
65+
visibility = ["//visibility:public"],
6666
deps = ["sgx_intel_ecdsa_qe_remote_assertion_authority_config_proto"],
6767
)
6868

@@ -284,6 +284,7 @@ cc_library(
284284
hdrs = ["sgx_intel_ecdsa_qe_remote_assertion_generator.h"],
285285
copts = ASYLO_DEFAULT_COPTS,
286286
tags = sgx.tags(),
287+
visibility = ["//visibility:public"],
287288
deps = [
288289
":sgx_intel_ecdsa_qe_remote_assertion_authority_config_cc_proto",
289290
"//asylo/crypto:certificate_cc_proto",

asylo/identity/attestation/sgx/internal/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,8 @@ cc_library(
302302
copts = ASYLO_DEFAULT_COPTS,
303303
visibility = ["//asylo:implementation"],
304304
deps = [
305+
"//asylo/util:error_codes",
306+
"//asylo/util:status",
305307
"@linux_sgx//:public",
306308
"@sgx_dcap//:pce_types",
307309
"@sgx_dcap//:quote_wrapper_common",

asylo/identity/attestation/sgx/sgx_intel_ecdsa_qe_remote_assertion_generator.cc

Lines changed: 4 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
#include "QuoteVerification/Src/AttestationLibrary/include/QuoteVerification/QuoteConstants.h"
5050

5151
namespace asylo {
52-
namespace {
5352

5453
using asylo::sgx::AlignedReportdataPtr;
5554
using asylo::sgx::AlignedReportPtr;
@@ -63,43 +62,6 @@ using asylo::sgx::kSgxIntelEcdsaQeRemoteAssertionAuthority;
6362
using GeneratorInfo =
6463
SgxIntelEcdsaQeRemoteAssertionAuthorityConfig_GeneratorInfo;
6564

66-
// Implements the `absl::visit` pattern for appending the appropriate
67-
// certification data to a quote returned by the Intel quoting enclave.
68-
class AppendCertificationDataToQuote {
69-
public:
70-
explicit AppendCertificationDataToQuote(std::vector<uint8_t> *quote)
71-
: quote_(quote) {}
72-
73-
Status operator()(SgxIntelEcdsaQeRemoteAssertionGenerator::UseDcapDefault) {
74-
// Noop, leave the quote alone
75-
return Status::OkStatus();
76-
}
77-
78-
Status operator()(const CertificateInterfaceVector &pck_certificate_chain) {
79-
sgx::IntelQeQuote parsed_quote;
80-
ASYLO_ASSIGN_OR_RETURN(parsed_quote, sgx::ParseDcapPackedQuote(*quote_));
81-
82-
parsed_quote.cert_data.qe_cert_data_type =
83-
::intel::sgx::qvl::constants::PCK_ID_PCK_CERT_CHAIN;
84-
parsed_quote.cert_data.qe_cert_data.clear();
85-
for (const auto &cert : pck_certificate_chain) {
86-
Certificate pem_cert;
87-
ASYLO_ASSIGN_OR_RETURN(pem_cert,
88-
cert->ToCertificateProto(Certificate::X509_PEM));
89-
std::move(pem_cert.data().begin(), pem_cert.data().end(),
90-
std::back_inserter(parsed_quote.cert_data.qe_cert_data));
91-
}
92-
93-
*quote_ = sgx::PackDcapQuote(parsed_quote);
94-
return Status::OkStatus();
95-
}
96-
97-
private:
98-
std::vector<uint8_t> *quote_;
99-
};
100-
101-
} // namespace
102-
10365
SgxIntelEcdsaQeRemoteAssertionGenerator::
10466
SgxIntelEcdsaQeRemoteAssertionGenerator()
10567
: SgxIntelEcdsaQeRemoteAssertionGenerator(
@@ -140,28 +102,25 @@ Status SgxIntelEcdsaQeRemoteAssertionGenerator::Initialize(
140102
return Status::OkStatus();
141103
}
142104

143-
ASYLO_ASSIGN_OR_RETURN(members_view->certification_data,
144-
ReadCertificationData(parsed_config));
105+
ASYLO_RETURN_IF_ERROR(ReadCertificationData(parsed_config));
145106

146107
members_view->is_initialized = true;
147108
return Status::OkStatus();
148109
}
149110

150-
StatusOr<SgxIntelEcdsaQeRemoteAssertionGenerator::CertificationData>
151-
SgxIntelEcdsaQeRemoteAssertionGenerator::ReadCertificationData(
111+
Status SgxIntelEcdsaQeRemoteAssertionGenerator::ReadCertificationData(
152112
const SgxIntelEcdsaQeRemoteAssertionAuthorityConfig &config) const {
153113
switch (config.generator_info().certification_case()) {
154114
case GeneratorInfo::CERTIFICATION_NOT_SET:
155115
return Status(error::GoogleError::INVALID_ARGUMENT,
156116
"Generator info is missing certification info");
157117

158118
case GeneratorInfo::kPckCertificateChain:
159-
return CreateCertificateChain(
160-
{{Certificate::X509_PEM, X509Certificate::Create}},
119+
return intel_enclaves_->SetPckCertificateChain(
161120
config.generator_info().pck_certificate_chain());
162121

163122
case GeneratorInfo::kUseDcapDefault:
164-
return UseDcapDefault{};
123+
return Status::OkStatus();
165124
}
166125

167126
return Status(
@@ -236,9 +195,6 @@ Status SgxIntelEcdsaQeRemoteAssertionGenerator::Generate(
236195
std::vector<uint8_t> quote;
237196
ASYLO_ASSIGN_OR_RETURN(quote, intel_enclaves_->GetQeQuote(report));
238197

239-
ASYLO_RETURN_IF_ERROR(absl::visit(AppendCertificationDataToQuote{&quote},
240-
members_.ReaderLock()->certification_data));
241-
242198
assertion->mutable_assertion()->assign(quote.begin(), quote.end());
243199
assertion->mutable_description()->set_authority_type(AuthorityType());
244200
assertion->mutable_description()->set_identity_type(IdentityType());

asylo/identity/attestation/sgx/sgx_intel_ecdsa_qe_remote_assertion_generator.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include <memory>
2323
#include <string>
2424

25-
#include "absl/types/variant.h"
2625
#include "asylo/crypto/certificate_util.h"
2726
#include "asylo/identity/additional_authenticated_data_generator.h"
2827
#include "asylo/identity/attestation/enclave_assertion_generator.h"
@@ -44,12 +43,6 @@ namespace asylo {
4443
class SgxIntelEcdsaQeRemoteAssertionGenerator
4544
: public EnclaveAssertionGenerator {
4645
public:
47-
// Empty type used within the certification data variant
48-
struct UseDcapDefault {};
49-
50-
using CertificationData =
51-
absl::variant<UseDcapDefault, CertificateInterfaceVector>;
52-
5346
// Constructs a new `SgxIntelEcdsaQeAssertionGenerator` that internally uses
5447
// the `EnclaveDcapLibraryInterface`, which uses ocalls to invoke all
5548
// Intel DCAP APIs. Default-constructed objects generate assertions suitable
@@ -91,10 +84,9 @@ class SgxIntelEcdsaQeRemoteAssertionGenerator
9184
private:
9285
struct Members {
9386
bool is_initialized = false;
94-
CertificationData certification_data;
9587
};
9688

97-
StatusOr<CertificationData> ReadCertificationData(
89+
Status ReadCertificationData(
9890
const SgxIntelEcdsaQeRemoteAssertionAuthorityConfig &config) const;
9991

10092
MutexGuarded<Members> members_;

asylo/identity/attestation/sgx/sgx_intel_ecdsa_qe_remote_assertion_generator_test.cc

Lines changed: 38 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "asylo/crypto/util/bytes.h"
3434
#include "asylo/crypto/util/trivial_object_util.h"
3535
#include "asylo/identity/additional_authenticated_data_generator.h"
36+
#include "asylo/identity/attestation/sgx/internal/intel_certs/qe_identity.h"
3637
#include "asylo/identity/attestation/sgx/internal/intel_ecdsa_quote.h"
3738
#include "asylo/identity/attestation/sgx/internal/mock_intel_architectural_enclave_interface.h"
3839
#include "asylo/identity/attestation/sgx/sgx_intel_ecdsa_qe_remote_assertion_authority_config.pb.h"
@@ -46,6 +47,7 @@
4647
#include "asylo/test/util/memory_matchers.h"
4748
#include "asylo/test/util/proto_matchers.h"
4849
#include "asylo/test/util/status_matchers.h"
50+
#include "asylo/util/error_codes.h"
4951
#include "asylo/util/proto_parse_util.h"
5052
#include "asylo/util/status.h"
5153
#include "asylo/util/thread.h"
@@ -75,7 +77,9 @@ class SgxIntelEcdsaQeRemoteAssertionGeneratorTests : public testing::Test {
7577
EnclaveAssertionAuthorityConfig config;
7678
ASYLO_ASSERT_OK_AND_ASSIGN(
7779
config,
78-
experimental::CreateSgxIntelEcdsaQeRemoteAssertionAuthorityConfig());
80+
experimental::CreateSgxIntelEcdsaQeRemoteAssertionAuthorityConfig(
81+
sgx::GetFakePckCertificateChain(),
82+
ParseTextProtoOrDie(sgx::kIntelEcdsaQeIdentityTextproto)));
7983
valid_config_ = std::move(*config.mutable_config());
8084
}
8185

@@ -130,6 +134,8 @@ TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests,
130134

131135
TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests, InitializeWorksOnce) {
132136
EXPECT_FALSE(generator_.IsInitialized());
137+
EXPECT_CALL(*mock_intel_enclaves_, SetPckCertificateChain(_))
138+
.WillOnce(Return(Status::OkStatus()));
133139
EXPECT_THAT(generator_.Initialize(valid_config_), IsOk());
134140
EXPECT_TRUE(generator_.IsInitialized());
135141
EXPECT_THAT(generator_.Initialize(valid_config_),
@@ -163,6 +169,24 @@ TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests,
163169
StatusIs(error::GoogleError::INVALID_ARGUMENT));
164170
}
165171

172+
TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests,
173+
InitializeFailsWhenSetPckCertificateChainFails) {
174+
EXPECT_CALL(*mock_intel_enclaves_, SetPckCertificateChain(_))
175+
.WillOnce(Return(Status(error::GoogleError::INTERNAL, "kaboom")));
176+
EXPECT_THAT(generator_.Initialize(valid_config_),
177+
StatusIs(error::GoogleError::INTERNAL));
178+
}
179+
180+
TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests,
181+
InitializeSetsPckCertificateChain) {
182+
auto expected_certs = sgx::GetFakePckCertificateChain();
183+
EXPECT_CALL(
184+
*mock_intel_enclaves_,
185+
SetPckCertificateChain(EqualsProto(expected_certs)))
186+
.WillOnce(Return(Status::OkStatus()));
187+
EXPECT_THAT(generator_.Initialize(valid_config_), IsOk());
188+
}
189+
166190
TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests, IdentityType) {
167191
EXPECT_THAT(generator_.IdentityType(), Eq(CODE_IDENTITY));
168192
}
@@ -174,6 +198,8 @@ TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests, AuthorityType) {
174198

175199
TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests,
176200
CreateAssertionOfferSuccess) {
201+
EXPECT_CALL(*mock_intel_enclaves_, SetPckCertificateChain(_))
202+
.WillOnce(Return(Status::OkStatus()));
177203
ASSERT_THAT(generator_.Initialize(valid_config_), IsOk());
178204

179205
AssertionOffer assertion_offer;
@@ -192,6 +218,8 @@ TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests,
192218
}
193219

194220
TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests, CanGenerateSuccess) {
221+
EXPECT_CALL(*mock_intel_enclaves_, SetPckCertificateChain(_))
222+
.WillOnce(Return(Status::OkStatus()));
195223
ASSERT_THAT(generator_.Initialize(valid_config_), IsOk());
196224
AssertionRequest request;
197225
*request.mutable_description() = CreateValidAssertionDescription();
@@ -207,6 +235,8 @@ TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests,
207235

208236
TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests,
209237
CanGenerateFailsForIncompatibleDescription) {
238+
EXPECT_CALL(*mock_intel_enclaves_, SetPckCertificateChain(_))
239+
.WillOnce(Return(Status::OkStatus()));
210240
ASSERT_THAT(generator_.Initialize(valid_config_), IsOk());
211241
AssertionRequest request;
212242

@@ -232,6 +262,8 @@ TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests, GenerateSucceeds) {
232262
expected_report_data.data.replace(sizeof(kDataSha256) + sizeof(kAadPurpose),
233263
kAadUuid);
234264

265+
EXPECT_CALL(*mock_intel_enclaves_, SetPckCertificateChain(_))
266+
.WillOnce(Return(Status::OkStatus()));
235267
ASSERT_THAT(generator_.Initialize(valid_config_), IsOk());
236268
AssertionRequest request;
237269
*request.mutable_description() = CreateValidAssertionDescription();
@@ -258,51 +290,6 @@ TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests, GenerateSucceeds) {
258290
EXPECT_THAT(assertion.assertion(), ElementsAreArray(fake_quote));
259291
}
260292

261-
TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests,
262-
GenerateSucceedsWithUserSuppliedCertChain) {
263-
SgxIntelEcdsaQeRemoteAssertionAuthorityConfig config;
264-
auto cert_chain =
265-
config.mutable_generator_info()->mutable_pck_certificate_chain();
266-
*cert_chain = sgx::GetFakePckCertificateChain();
267-
268-
std::string expected_output_cert_chain;
269-
for (const auto &cert : cert_chain->certificates()) {
270-
ASSERT_THAT(cert.format(), Eq(Certificate::X509_PEM));
271-
absl::StrAppend(&expected_output_cert_chain, cert.data(), "\n");
272-
}
273-
274-
std::string serialized_config;
275-
ASSERT_TRUE(config.SerializeToString(&serialized_config));
276-
EXPECT_THAT(generator_.Initialize(serialized_config), IsOk());
277-
278-
EXPECT_CALL(*mock_intel_enclaves_, GetQeTargetinfo())
279-
.WillOnce(Return(CreateFakeTargetInfo()));
280-
EXPECT_CALL(*mock_hardware_interface_, GetReport(_, _))
281-
.WillOnce(Return(TrivialRandomObject<Report>()));
282-
283-
sgx::IntelQeQuote input_quote;
284-
RandomFillTrivialObject(&input_quote.header);
285-
RandomFillTrivialObject(&input_quote.body);
286-
auto fake_quote = TrivialRandomObject<UnsafeBytes<101>>();
287-
EXPECT_CALL(*mock_intel_enclaves_, GetQeQuote(_))
288-
.WillOnce(Return(sgx::PackDcapQuote(input_quote)));
289-
290-
AssertionRequest request;
291-
*request.mutable_description() = CreateValidAssertionDescription();
292-
293-
Assertion assertion;
294-
ASSERT_THAT(generator_.Generate("user data", request, &assertion), IsOk());
295-
sgx::IntelQeQuote output_quote;
296-
ASYLO_ASSERT_OK_AND_ASSIGN(output_quote,
297-
sgx::ParseDcapPackedQuote(assertion.assertion()));
298-
299-
ASSERT_THAT(output_quote.cert_data.qe_cert_data_type,
300-
Eq(::intel::sgx::qvl::constants::PCK_ID_PCK_CERT_CHAIN));
301-
EXPECT_THAT(std::string(output_quote.cert_data.qe_cert_data.begin(),
302-
output_quote.cert_data.qe_cert_data.end()),
303-
Eq(expected_output_cert_chain));
304-
}
305-
306293
TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests,
307294
GenerateFailsIfNotInitialized) {
308295
ASSERT_FALSE(generator_.IsInitialized());
@@ -314,6 +301,8 @@ TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests,
314301

315302
TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests,
316303
GenerateFailsForIncompatibleDescription) {
304+
EXPECT_CALL(*mock_intel_enclaves_, SetPckCertificateChain(_))
305+
.WillOnce(Return(Status::OkStatus()));
317306
ASSERT_THAT(generator_.Initialize(valid_config_), IsOk());
318307
AssertionRequest request;
319308
Assertion assertion;
@@ -335,6 +324,9 @@ TEST_F(SgxIntelEcdsaQeRemoteAssertionGeneratorTests,
335324
InitializeSucceedsOnceFromMultipleThreads) {
336325
constexpr int kNumThreads = 10;
337326

327+
EXPECT_CALL(*mock_intel_enclaves_, SetPckCertificateChain(_))
328+
.WillOnce(Return(Status::OkStatus()));
329+
338330
std::atomic<int> success_count(0);
339331
std::vector<Thread> threads;
340332
threads.reserve(kNumThreads);

0 commit comments

Comments
 (0)