cryptohome: cert provision apis provide ek public key query.
It is meant to replace cryptohome client in ap-daemons.
BUG=b:173470557
TEST=hwsec.CertProvision
Change-Id: I559ad1cefbd6b17ca8eb4d83a4512755ae799025
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2587118
Reviewed-by: Yi Chou <yich@google.com>
Tested-by: Leo Lai <cylai@google.com>
Commit-Queue: Leo Lai <cylai@google.com>
diff --git a/cryptohome/cert/cert_provision.cc b/cryptohome/cert/cert_provision.cc
index ec825f3..a833a8d 100644
--- a/cryptohome/cert/cert_provision.cc
+++ b/cryptohome/cert/cert_provision.cc
@@ -307,4 +307,22 @@
return Status::Success;
}
+Status GetEndorsementPublicKey(std::string* ek_public_key) {
+ auto proxy = AttestationProxyFactory::Create();
+ // By design, the factory must return a valid object.
+ CHECK(proxy);
+ ::attestation::GetEndorsementInfoReply reply;
+ brillo::ErrorPtr error;
+ if (!proxy->GetEndorsementInfo(attestation::GetEndorsementInfoRequest(),
+ &reply, &error)) {
+ return ReportAndReturn(Status::DBusError, error->GetMessage());
+ }
+ if (reply.status() != ::attestation::STATUS_SUCCESS) {
+ return ReportAndReturn(Status::AttestationError,
+ "Failed to get endorsement info");
+ }
+ *ek_public_key = reply.ek_public_key();
+ return Status::Success;
+}
+
} // namespace cert_provision
diff --git a/cryptohome/cert/cert_provision_client.cc b/cryptohome/cert/cert_provision_client.cc
index 58e1b19..500b32f 100644
--- a/cryptohome/cert/cert_provision_client.cc
+++ b/cryptohome/cert/cert_provision_client.cc
@@ -35,6 +35,8 @@
printf(" --sign --label=<label> --in=<file_in> [--out=<file_out>]\n");
printf(" --mechanism=<mechanism>\n");
printf(" where mechanism: sha1_rsa, sha256_rsa, sha256_rsa_pss\n");
+ printf(" Get endorsement public key:'\n");
+ printf(" --get_ek_public_key\n");
}
int main(int argc, char** argv) {
@@ -174,6 +176,18 @@
} else {
puts(base::HexEncode(sig.data(), sig.size()).c_str());
}
+ } else if (cl->HasSwitch("get_ek_public_key")) {
+ std::string ek_public_key;
+ sts = cert_provision::GetEndorsementPublicKey(&ek_public_key);
+ if (sts != cert_provision::Status::Success) {
+ LOG(ERROR) << "Getting EK returned " << static_cast<int>(sts);
+ return 3;
+ }
+ if (ek_public_key.empty()) {
+ LOG(ERROR) << "Empty endorsement public key";
+ return 1;
+ }
+ puts(base::HexEncode(ek_public_key.data(), ek_public_key.size()).c_str());
}
return 0;
}
diff --git a/cryptohome/cert/cert_provision_unittest.cc b/cryptohome/cert/cert_provision_unittest.cc
index 757228f..c7bb9ed 100644
--- a/cryptohome/cert/cert_provision_unittest.cc
+++ b/cryptohome/cert/cert_provision_unittest.cc
@@ -41,9 +41,10 @@
namespace {
// Some arbitrary certificate label used for testing.
-const char kCertLabel[] = "test";
-const char kWrongLabel[] = "some wrong label";
-const char kFakeErrorMessage[] = "fake error message";
+constexpr char kCertLabel[] = "test";
+constexpr char kWrongLabel[] = "some wrong label";
+constexpr char kFakeErrorMessage[] = "fake error message";
+constexpr char kFakeEndorsementPublicKey[] = "fake public ek";
const char kBegCertificate[] = "-----BEGIN CERTIFICATE-----";
const char kEndCertificate[] = "-----END CERTIFICATE-----";
@@ -71,18 +72,21 @@
class RecordingAttestationProxy : public org::chromium::AttestationProxyMock {
public:
struct ReplySource {
+ attestation::GetEndorsementInfoReply get_endorsement_info_reply;
attestation::GetStatusReply get_status_reply;
attestation::EnrollReply enroll_reply;
attestation::GetCertificateReply get_cert_reply;
attestation::RegisterKeyWithChapsTokenReply register_key_reply;
};
struct ErrorSource {
+ brillo::ErrorPtr get_endorsement_info_error;
brillo::ErrorPtr get_status_error;
brillo::ErrorPtr enroll_error;
brillo::ErrorPtr get_cert_error;
brillo::ErrorPtr register_key_error;
};
struct RequestSink {
+ attestation::GetEndorsementInfoRequest get_endorsement_info_request;
attestation::GetStatusRequest get_status_request;
attestation::EnrollRequest enroll_request;
attestation::GetCertificateRequest get_cert_request;
@@ -96,6 +100,9 @@
: reply_source_(reply_source),
error_source_(error_source),
request_sink_(request_sink) {
+ ON_CALL(*this, GetEndorsementInfo(_, _, _, _))
+ .WillByDefault(
+ Invoke(this, &RecordingAttestationProxy::HandleGetEndorsementInfo));
ON_CALL(*this, GetStatus(_, _, _, _))
.WillByDefault(
Invoke(this, &RecordingAttestationProxy::HandleGetStatus));
@@ -109,6 +116,19 @@
this, &RecordingAttestationProxy::HandleRegisterKeyWithChapsToken));
}
+ bool HandleGetEndorsementInfo(
+ const attestation::GetEndorsementInfoRequest& request,
+ attestation::GetEndorsementInfoReply* reply,
+ brillo::ErrorPtr* error,
+ int /*timeout_ms*/) {
+ if (error_source_->get_endorsement_info_error) {
+ *error = std::move(error_source_->get_endorsement_info_error);
+ return false;
+ }
+ request_sink_->get_endorsement_info_request = request;
+ *reply = reply_source_->get_endorsement_info_reply;
+ return true;
+ }
bool HandleGetStatus(const attestation::GetStatusRequest& request,
attestation::GetStatusReply* reply,
brillo::ErrorPtr* error,
@@ -826,4 +846,27 @@
EXPECT_EQ(exepcted_error_message, progress_.back().message);
}
+TEST_F(CertProvisionTest, GetEndorsementPublicKeySuccess) {
+ attestation_proxy_factory_.get_reply_source()
+ ->get_endorsement_info_reply.set_ek_public_key(kFakeEndorsementPublicKey);
+ EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
+ GetEndorsementInfo(_, _, _, _));
+ std::string endorsment_public_key;
+ EXPECT_EQ(Status::Success, GetEndorsementPublicKey(&endorsment_public_key));
+ EXPECT_EQ(endorsment_public_key, kFakeEndorsementPublicKey);
+}
+
+TEST_F(CertProvisionTest, GetEndorsementPublicKeyDBusError) {
+ brillo::Error::AddTo(&attestation_proxy_factory_.get_error_source()
+ ->get_endorsement_info_error,
+ FROM_HERE, "", "", kFakeErrorMessage);
+ const std::string exepcted_error_message =
+ attestation_proxy_factory_.get_error_source()
+ ->get_endorsement_info_error->GetMessage();
+ EXPECT_CALL(*attestation_proxy_factory_.get_mock_proxy(),
+ GetEndorsementInfo(_, _, _, _));
+ std::string endorsment_public_key;
+ EXPECT_NE(Status::Success, GetEndorsementPublicKey(&endorsment_public_key));
+}
+
} // namespace cert_provision
diff --git a/cryptohome/cert_provision.h b/cryptohome/cert_provision.h
index a3553cd..27ec743 100644
--- a/cryptohome/cert_provision.h
+++ b/cryptohome/cert_provision.h
@@ -157,6 +157,10 @@
const std::string& data,
std::string* signature);
+// Gets endorsement public key of the TPM.
+CERT_PROVISION_EXPORT Status
+GetEndorsementPublicKey(std::string* ek_public_key);
+
} // namespace cert_provision
#endif // CRYPTOHOME_CERT_PROVISION_H_