Use RAII to ensure KeyMint keyblobs deleted
If some check in a VTS test case fails, the test function may exit early
and not call CheckedDeleteKey(&some_keyblob), thus "leaking" a key blob.
This isn't normally an issue, but if the key blob happens to use a
feature that uses some secure storage (e.g. ROLLBACK_RESISTANCE or
USAGE_COUNT_LIMIT=1) then this may leak some scarse resource.
To avoid the chance of this, use an RAII holder to ensure that
manually-managed keyblobs (i.e. key blobs that are not held in the
key_blob_ member of the base test class) are always deleted.
Bug: 262212842
Test: VtsAidlKeyMintTargetTest
Change-Id: Ie8806095e249870484b9875eb660070607f339a3
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index b55e609..b2fd08e 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -176,6 +176,17 @@
std::string KeyMintAidlTestBase::keyblob_dir;
std::optional<bool> KeyMintAidlTestBase::expect_upgrade = std::nullopt;
+KeyBlobDeleter::~KeyBlobDeleter() {
+ if (key_blob_.empty()) {
+ return;
+ }
+ Status result = keymint_->deleteKey(key_blob_);
+ key_blob_.clear();
+ EXPECT_TRUE(result.isOk()) << result.getServiceSpecificError() << "\n";
+ ErrorCode rc = GetReturnErrorCode(result);
+ EXPECT_TRUE(rc == ErrorCode::OK || rc == ErrorCode::UNIMPLEMENTED) << result << "\n";
+}
+
uint32_t KeyMintAidlTestBase::boot_patch_level(
const vector<KeyCharacteristics>& key_characteristics) {
// The boot patchlevel is not available as a property, but should be present
@@ -229,16 +240,6 @@
return version >= 2;
}
-ErrorCode KeyMintAidlTestBase::GetReturnErrorCode(const Status& result) {
- if (result.isOk()) return ErrorCode::OK;
-
- if (result.getExceptionCode() == EX_SERVICE_SPECIFIC) {
- return static_cast<ErrorCode>(result.getServiceSpecificError());
- }
-
- return ErrorCode::UNKNOWN_ERROR;
-}
-
void KeyMintAidlTestBase::InitializeKeyMint(std::shared_ptr<IKeyMintDevice> keyMint) {
ASSERT_NE(keyMint, nullptr);
keymint_ = std::move(keyMint);
@@ -513,13 +514,9 @@
return GetReturnErrorCode(result);
}
-void KeyMintAidlTestBase::CheckedDeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob) {
- ErrorCode result = DeleteKey(key_blob, keep_key_blob);
- EXPECT_TRUE(result == ErrorCode::OK || result == ErrorCode::UNIMPLEMENTED) << result << endl;
-}
-
void KeyMintAidlTestBase::CheckedDeleteKey() {
- CheckedDeleteKey(&key_blob_);
+ ErrorCode result = DeleteKey(&key_blob_, /* keep_key_blob = */ false);
+ EXPECT_TRUE(result == ErrorCode::OK || result == ErrorCode::UNIMPLEMENTED) << result << endl;
}
ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
@@ -1986,6 +1983,16 @@
return AssertionSuccess();
}
+ErrorCode GetReturnErrorCode(const Status& result) {
+ if (result.isOk()) return ErrorCode::OK;
+
+ if (result.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+ return static_cast<ErrorCode>(result.getServiceSpecificError());
+ }
+
+ return ErrorCode::UNKNOWN_ERROR;
+}
+
X509_Ptr parse_cert_blob(const vector<uint8_t>& blob) {
const uint8_t* p = blob.data();
return X509_Ptr(d2i_X509(nullptr /* allocate new */, &p, blob.size()));