Merge "Support getting public key data" am: 66e76443a0 am: b20bf7566c
am: 9bc843973b

Change-Id: I19358df3283e604a8ae9805b02b726545375b409
diff --git a/fs_mgr/libfs_avb/avb_util.cpp b/fs_mgr/libfs_avb/avb_util.cpp
index 945087f..08f87b4 100644
--- a/fs_mgr/libfs_avb/avb_util.cpp
+++ b/fs_mgr/libfs_avb/avb_util.cpp
@@ -361,13 +361,21 @@
 }
 
 VBMetaVerifyResult VerifyVBMetaSignature(const VBMetaData& vbmeta,
-                                         const std::string& expected_public_key_blob) {
+                                         const std::string& expected_public_key_blob,
+                                         std::string* out_public_key_data) {
     const uint8_t* pk_data;
     size_t pk_len;
     ::AvbVBMetaVerifyResult vbmeta_ret;
 
     vbmeta_ret = avb_vbmeta_image_verify(vbmeta.data(), vbmeta.size(), &pk_data, &pk_len);
 
+    if (out_public_key_data != nullptr) {
+        out_public_key_data->clear();
+        if (pk_len > 0) {
+            out_public_key_data->append(reinterpret_cast<const char*>(pk_data), pk_len);
+        }
+    }
+
     switch (vbmeta_ret) {
         case AVB_VBMETA_VERIFY_RESULT_OK:
             if (pk_data == nullptr || pk_len <= 0) {
@@ -406,6 +414,7 @@
 
 std::unique_ptr<VBMetaData> VerifyVBMetaData(int fd, const std::string& partition_name,
                                              const std::string& expected_public_key_blob,
+                                             std::string* out_public_key_data,
                                              VBMetaVerifyResult* out_verify_result) {
     uint64_t vbmeta_offset = 0;
     uint64_t vbmeta_size = VBMetaData::kMaxVBMetaSize;
@@ -434,7 +443,8 @@
         return nullptr;
     }
 
-    auto verify_result = VerifyVBMetaSignature(*vbmeta, expected_public_key_blob);
+    auto verify_result =
+            VerifyVBMetaSignature(*vbmeta, expected_public_key_blob, out_public_key_data);
     if (out_verify_result != nullptr) *out_verify_result = verify_result;
 
     if (verify_result == VBMetaVerifyResult::kSuccess ||
@@ -494,10 +504,10 @@
 
 // Loads the vbmeta from a given path.
 std::unique_ptr<VBMetaData> LoadAndVerifyVbmetaByPath(
-    const std::string& image_path, const std::string& partition_name,
-    const std::string& expected_public_key_blob, bool allow_verification_error,
-    bool rollback_protection, bool is_chained_vbmeta, bool* out_verification_disabled,
-    VBMetaVerifyResult* out_verify_result) {
+        const std::string& image_path, const std::string& partition_name,
+        const std::string& expected_public_key_blob, bool allow_verification_error,
+        bool rollback_protection, bool is_chained_vbmeta, std::string* out_public_key_data,
+        bool* out_verification_disabled, VBMetaVerifyResult* out_verify_result) {
     // Ensures the device path (might be a symlink created by init) is ready to access.
     if (!WaitForFile(image_path, 1s)) {
         PERROR << "No such path: " << image_path;
@@ -511,8 +521,8 @@
     }
 
     VBMetaVerifyResult verify_result;
-    std::unique_ptr<VBMetaData> vbmeta =
-            VerifyVBMetaData(fd, partition_name, expected_public_key_blob, &verify_result);
+    std::unique_ptr<VBMetaData> vbmeta = VerifyVBMetaData(
+            fd, partition_name, expected_public_key_blob, out_public_key_data, &verify_result);
     if (!vbmeta) {
         LERROR << partition_name << ": Failed to load vbmeta, result: " << verify_result;
         return nullptr;
@@ -569,9 +579,10 @@
 
     bool verification_disabled = false;
     VBMetaVerifyResult verify_result;
-    auto vbmeta = LoadAndVerifyVbmetaByPath(
-        image_path, partition_name, expected_public_key_blob, allow_verification_error,
-        rollback_protection, is_chained_vbmeta, &verification_disabled, &verify_result);
+    auto vbmeta = LoadAndVerifyVbmetaByPath(image_path, partition_name, expected_public_key_blob,
+                                            allow_verification_error, rollback_protection,
+                                            is_chained_vbmeta, nullptr /* out_public_key_data */,
+                                            &verification_disabled, &verify_result);
 
     if (!vbmeta) {
         return VBMetaVerifyResult::kError;
diff --git a/fs_mgr/libfs_avb/avb_util.h b/fs_mgr/libfs_avb/avb_util.h
index 14918f2..4b54e27 100644
--- a/fs_mgr/libfs_avb/avb_util.h
+++ b/fs_mgr/libfs_avb/avb_util.h
@@ -79,10 +79,12 @@
 
 std::unique_ptr<VBMetaData> VerifyVBMetaData(int fd, const std::string& partition_name,
                                              const std::string& expected_public_key_blob,
+                                             std::string* out_public_key_data,
                                              VBMetaVerifyResult* out_verify_result);
 
 VBMetaVerifyResult VerifyVBMetaSignature(const VBMetaData& vbmeta,
-                                         const std::string& expected_public_key_blob);
+                                         const std::string& expected_public_key_blob,
+                                         std::string* out_public_key_data);
 
 bool VerifyPublicKeyBlob(const uint8_t* key, size_t length, const std::string& expected_key_blob);
 
@@ -94,10 +96,10 @@
 
 // Loads the single vbmeta from a given path.
 std::unique_ptr<VBMetaData> LoadAndVerifyVbmetaByPath(
-    const std::string& image_path, const std::string& partition_name,
-    const std::string& expected_public_key_blob, bool allow_verification_error,
-    bool rollback_protection, bool is_chained_vbmeta, bool* out_verification_disabled,
-    VBMetaVerifyResult* out_verify_result);
+        const std::string& image_path, const std::string& partition_name,
+        const std::string& expected_public_key_blob, bool allow_verification_error,
+        bool rollback_protection, bool is_chained_vbmeta, std::string* out_public_key_data,
+        bool* out_verification_disabled, VBMetaVerifyResult* out_verify_result);
 
 // Loads the top-level vbmeta and all its chained vbmeta images.
 // The actual device path is constructed at runtime by:
diff --git a/fs_mgr/libfs_avb/fs_avb.cpp b/fs_mgr/libfs_avb/fs_avb.cpp
index a1ae4e7..1af3b33 100644
--- a/fs_mgr/libfs_avb/fs_avb.cpp
+++ b/fs_mgr/libfs_avb/fs_avb.cpp
@@ -407,9 +407,10 @@
 
     bool verification_disabled = false;
     std::unique_ptr<VBMetaData> vbmeta = LoadAndVerifyVbmetaByPath(
-        fstab_entry->blk_device, "" /* partition_name, no need for a standalone path */,
-        expected_key_blob, allow_verification_error, rollback_protection,
-        false /* not is_chained_vbmeta */, &verification_disabled, nullptr /* out_verify_result */);
+            fstab_entry->blk_device, "" /* partition_name, no need for a standalone path */,
+            expected_key_blob, allow_verification_error, rollback_protection,
+            false /* not is_chained_vbmeta */, nullptr /* out_public_key_data */,
+            &verification_disabled, nullptr /* out_verify_result */);
 
     if (!vbmeta) {
         LERROR << "Failed to load vbmeta: " << fstab_entry->blk_device;
diff --git a/fs_mgr/libfs_avb/tests/avb_util_test.cpp b/fs_mgr/libfs_avb/tests/avb_util_test.cpp
index cda9396..835410f 100644
--- a/fs_mgr/libfs_avb/tests/avb_util_test.cpp
+++ b/fs_mgr/libfs_avb/tests/avb_util_test.cpp
@@ -391,13 +391,36 @@
                                                     "hashtree", signing_key, "SHA256_RSA4096",
                                                     10 /* rollback_index */);
 
-    auto expected_public_key = ExtractPublicKeyAvbBlob(signing_key);
-    EXPECT_EQ(VBMetaVerifyResult::kSuccess, VerifyVBMetaSignature(vbmeta, expected_public_key));
+    auto expected_public_key_blob = ExtractPublicKeyAvbBlob(signing_key);
+    EXPECT_EQ(VBMetaVerifyResult::kSuccess,
+              VerifyVBMetaSignature(vbmeta, expected_public_key_blob,
+                                    nullptr /* out_public_key_data */));
 
     // Converts the expected key into an 'unexpected' key.
-    expected_public_key[10] ^= 0x80;
+    expected_public_key_blob[10] ^= 0x80;
     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
-              VerifyVBMetaSignature(vbmeta, expected_public_key));
+              VerifyVBMetaSignature(vbmeta, expected_public_key_blob,
+                                    nullptr /* out_public_key_data */));
+}
+
+TEST_F(AvbUtilTest, VerifyVBMetaSignatureOutputPublicKeyData) {
+    const size_t image_size = 10 * 1024 * 1024;
+    const size_t partition_size = 15 * 1024 * 1024;
+    auto signing_key = data_dir_.Append("testkey_rsa4096.pem");
+    auto vbmeta = GenerateImageAndExtractVBMetaData("system", image_size, partition_size,
+                                                    "hashtree", signing_key, "SHA256_RSA4096",
+                                                    10 /* rollback_index */);
+    std::string out_public_key_data;
+    auto expected_public_key_blob = ExtractPublicKeyAvbBlob(signing_key);
+    EXPECT_EQ(VBMetaVerifyResult::kSuccess,
+              VerifyVBMetaSignature(vbmeta, expected_public_key_blob, &out_public_key_data));
+    EXPECT_EQ(out_public_key_data, expected_public_key_blob);
+
+    // Converts the expected key into an 'unexpected' key.
+    expected_public_key_blob[10] ^= 0x80;
+    EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
+              VerifyVBMetaSignature(vbmeta, expected_public_key_blob, &out_public_key_data));
+    EXPECT_NE(out_public_key_data, expected_public_key_blob);
 }
 
 bool AvbUtilTest::TestVBMetaModification(VBMetaVerifyResult expected_result,
@@ -410,7 +433,8 @@
     for (int n = 0; n <= kNumCheckIntervals; n++) {
         size_t o = std::min(length * n / kNumCheckIntervals, length - 1) + offset;
         d[o] ^= 0x80;
-        VBMetaVerifyResult result = VerifyVBMetaSignature(vbmeta, "" /* expected_public_key */);
+        VBMetaVerifyResult result = VerifyVBMetaSignature(vbmeta, "" /* expected_public_key_blob */,
+                                                          nullptr /* out_public_key_data */);
         d[o] ^= 0x80;
         if (result != expected_result) {
             return false;
@@ -456,7 +480,9 @@
             "system", image_size, partition_size, "hashtree", {} /* avb_signing_key */,
             "" /* avb_algorithm */, 10 /* rollback_index */);
 
-    EXPECT_EQ(VBMetaVerifyResult::kErrorVerification, VerifyVBMetaSignature(vbmeta, ""));
+    EXPECT_EQ(VBMetaVerifyResult::kErrorVerification,
+              VerifyVBMetaSignature(vbmeta, "" /* expected_public_key_blob */,
+                                    nullptr /* out_public_key_data */));
 }
 
 TEST_F(AvbUtilTest, VerifyVBMetaSignatureInvalidVBMeta) {
@@ -468,7 +494,9 @@
 
     VBMetaData invalid_vbmeta((const uint8_t*)vbmeta_buffer.data(), vbmeta_buffer.size(),
                               "invalid_vbmeta");
-    EXPECT_EQ(VBMetaVerifyResult::kError, VerifyVBMetaSignature(invalid_vbmeta, ""));
+    EXPECT_EQ(VBMetaVerifyResult::kError,
+              VerifyVBMetaSignature(invalid_vbmeta, "" /* expected_public_key_blob */,
+                                    nullptr /* out_public_Key_data */));
 }
 
 bool AvbUtilTest::CompareVBMeta(const base::FilePath& avb_image_path,
@@ -538,11 +566,15 @@
     ASSERT_TRUE(fd > 0);
 
     VBMetaVerifyResult verify_result;
-    std::unique_ptr<VBMetaData> vbmeta =
-            VerifyVBMetaData(fd, "vbmeta", "" /*expected_public_key_blob */, &verify_result);
+    std::string out_public_key_data;
+    std::unique_ptr<VBMetaData> vbmeta = VerifyVBMetaData(
+            fd, "vbmeta", "" /*expected_public_key_blob */, &out_public_key_data, &verify_result);
     EXPECT_TRUE(vbmeta != nullptr);
     EXPECT_EQ(VBMetaVerifyResult::kSuccess, verify_result);
 
+    auto rsa8192_public_key_blob = ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa8192.pem"));
+    EXPECT_EQ(rsa8192_public_key_blob, out_public_key_data);
+
     // Checkes the returned vbmeta content is the same as that extracted via avbtool.
     vbmeta->GetVBMetaHeader(true /* update_vbmeta_size */);
     EXPECT_TRUE(CompareVBMeta(vbmeta_path, *vbmeta));
@@ -562,11 +594,15 @@
     ASSERT_TRUE(fd > 0);
 
     VBMetaVerifyResult verify_result;
-    std::unique_ptr<VBMetaData> vbmeta =
-            VerifyVBMetaData(fd, "system", "" /*expected_public_key_blob */, &verify_result);
+    std::string out_public_key_data;
+    std::unique_ptr<VBMetaData> vbmeta = VerifyVBMetaData(
+            fd, "system", "" /*expected_public_key_blob */, &out_public_key_data, &verify_result);
     EXPECT_TRUE(vbmeta != nullptr);
     EXPECT_EQ(VBMetaVerifyResult::kSuccess, verify_result);
 
+    auto rsa8192_public_key_blob = ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa8192.pem"));
+    EXPECT_EQ(rsa8192_public_key_blob, out_public_key_data);
+
     // Checkes the returned vbmeta content is the same as that extracted via avbtool.
     EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
 }
@@ -618,11 +654,15 @@
     EXPECT_TRUE(footer != nullptr);
 
     VBMetaVerifyResult verify_result;
-    std::unique_ptr<VBMetaData> vbmeta =
-            VerifyVBMetaData(fd, "system", "" /*expected_public_key_blob */, &verify_result);
+    std::string out_public_key_data;
+    std::unique_ptr<VBMetaData> vbmeta = VerifyVBMetaData(
+            fd, "system", "" /*expected_public_key_blob */, &out_public_key_data, &verify_result);
     EXPECT_NE(nullptr, vbmeta);
     EXPECT_EQ(VBMetaVerifyResult::kSuccess, verify_result);
 
+    auto rsa8192_public_key_blob = ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa8192.pem"));
+    EXPECT_EQ(rsa8192_public_key_blob, out_public_key_data);
+
     // Modifies hash and signature, checks there is verification error.
     auto header = vbmeta->GetVBMetaHeader(true /* update_vbmeta_size */);
     size_t header_block_offset = 0;
@@ -637,7 +677,7 @@
     ASSERT_TRUE(hash_modified_fd > 0);
     // Should return ErrorVerification.
     vbmeta = VerifyVBMetaData(hash_modified_fd, "system", "" /*expected_public_key_blob */,
-                              &verify_result);
+                              nullptr /* out_public_key_data */, &verify_result);
     EXPECT_NE(nullptr, vbmeta);
     EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification, verify_result);
@@ -652,7 +692,7 @@
     ASSERT_TRUE(aux_modified_fd > 0);
     // Should return ErrorVerification.
     vbmeta = VerifyVBMetaData(aux_modified_fd, "system", "" /*expected_public_key_blob */,
-                              &verify_result);
+                              nullptr /* out_public_key_data */, &verify_result);
     EXPECT_NE(nullptr, vbmeta);
     EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification, verify_result);
@@ -662,7 +702,8 @@
     android::base::unique_fd ok_fd(open(system_path.value().c_str(), O_RDONLY | O_CLOEXEC));
     ASSERT_TRUE(ok_fd > 0);
     // Should return ResultOK..
-    vbmeta = VerifyVBMetaData(ok_fd, "system", "" /*expected_public_key_blob */, &verify_result);
+    vbmeta = VerifyVBMetaData(ok_fd, "system", "" /*expected_public_key_blob */,
+                              nullptr /* out_public_key_data */, &verify_result);
     EXPECT_NE(nullptr, vbmeta);
     EXPECT_TRUE(CompareVBMeta(system_path, *vbmeta));
     EXPECT_EQ(VBMetaVerifyResult::kSuccess, verify_result);
@@ -851,22 +892,22 @@
                  20, data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
                  "--internal_release_string \"unit test\"");
 
-    base::FilePath rsa4096_public_key =
-        ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
-
-    std::string expected_key_blob_4096;
-    EXPECT_TRUE(base::ReadFileToString(rsa4096_public_key, &expected_key_blob_4096));
+    std::string expected_key_blob_4096 =
+            ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa4096.pem"));
 
     bool verification_disabled;
     VBMetaVerifyResult verify_result;
+    std::string out_public_key_data;
     std::unique_ptr<VBMetaData> vbmeta = LoadAndVerifyVbmetaByPath(
-        system_path.value(), "system_other", expected_key_blob_4096,
-        false /* allow_verification_error */, false /* rollback_protection */,
-        false /* is_chained_vbmeta */, &verification_disabled, &verify_result);
+            system_path.value(), "system_other", expected_key_blob_4096,
+            false /* allow_verification_error */, false /* rollback_protection */,
+            false /* is_chained_vbmeta */, &out_public_key_data, &verification_disabled,
+            &verify_result);
 
     EXPECT_NE(nullptr, vbmeta);
     EXPECT_EQ(VBMetaVerifyResult::kSuccess, verify_result);
     EXPECT_EQ(false, verification_disabled);
+    EXPECT_EQ(expected_key_blob_4096, out_public_key_data);
 
     EXPECT_EQ(2112UL, vbmeta->size());
     EXPECT_EQ(system_path.value(), vbmeta->vbmeta_path());
@@ -885,11 +926,8 @@
                  20, data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
                  "--internal_release_string \"unit test\"");
 
-    base::FilePath rsa4096_public_key =
-        ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
-
-    std::string expected_key_blob_4096;
-    EXPECT_TRUE(base::ReadFileToString(rsa4096_public_key, &expected_key_blob_4096));
+    std::string expected_key_blob_4096 =
+            ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa4096.pem"));
 
     // Modifies the auxiliary data of system_other.img
     auto fd = OpenUniqueReadFd(system_path);
@@ -910,16 +948,18 @@
     VBMetaVerifyResult verify_result;
     // Not allow verification error.
     std::unique_ptr<VBMetaData> vbmeta = LoadAndVerifyVbmetaByPath(
-        system_path.value(), "system_other", expected_key_blob_4096,
-        false /* allow_verification_error */, false /* rollback_protection */,
-        false /* is_chained_vbmeta */, nullptr /* verification_disabled */, &verify_result);
+            system_path.value(), "system_other", expected_key_blob_4096,
+            false /* allow_verification_error */, false /* rollback_protection */,
+            false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
+            nullptr /* verification_disabled */, &verify_result);
     EXPECT_EQ(nullptr, vbmeta);
 
     // Allow verification error.
     vbmeta = LoadAndVerifyVbmetaByPath(
-        system_path.value(), "system_other", expected_key_blob_4096,
-        true /* allow_verification_error */, false /* rollback_protection */,
-        false /* is_chained_vbmeta */, nullptr /* verification_disabled */, &verify_result);
+            system_path.value(), "system_other", expected_key_blob_4096,
+            true /* allow_verification_error */, false /* rollback_protection */,
+            false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
+            nullptr /* verification_disabled */, &verify_result);
     EXPECT_NE(nullptr, vbmeta);
     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification, verify_result);
 
@@ -934,16 +974,18 @@
 
     // Not allow verification error.
     vbmeta = LoadAndVerifyVbmetaByPath(
-        system_path.value(), "system_other", expected_key_blob_4096,
-        false /* allow_verification_error */, false /* rollback_protection */,
-        false /* is_chained_vbmeta */, nullptr /* verification_disabled */, &verify_result);
+            system_path.value(), "system_other", expected_key_blob_4096,
+            false /* allow_verification_error */, false /* rollback_protection */,
+            false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
+            nullptr /* verification_disabled */, &verify_result);
     EXPECT_EQ(nullptr, vbmeta);
 
     // Allow verification error.
     vbmeta = LoadAndVerifyVbmetaByPath(
-        system_path.value(), "system_other", expected_key_blob_4096,
-        true /* allow_verification_error */, false /* rollback_protection */,
-        false /* is_chained_vbmeta */, nullptr /* verification_disabled */, &verify_result);
+            system_path.value(), "system_other", expected_key_blob_4096,
+            true /* allow_verification_error */, false /* rollback_protection */,
+            false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
+            nullptr /* verification_disabled */, &verify_result);
     EXPECT_NE(nullptr, vbmeta);
     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification, verify_result);
 }
@@ -959,24 +1001,22 @@
                  20, data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
                  "--internal_release_string \"unit test\"");
 
-    base::FilePath rsa2048_public_key =
-        ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa2048.pem"));
-    base::FilePath rsa4096_public_key =
-        ExtractPublicKeyAvb(data_dir_.Append("testkey_rsa4096.pem"));
-
-    std::string expected_key_blob_4096;
-    EXPECT_TRUE(base::ReadFileToString(rsa4096_public_key, &expected_key_blob_4096));
-    std::string unexpected_key_blob_2048;
-    EXPECT_TRUE(base::ReadFileToString(rsa2048_public_key, &unexpected_key_blob_2048));
+    std::string unexpected_key_blob_2048 =
+            ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa2048.pem"));
+    std::string expected_key_blob_4096 =
+            ExtractPublicKeyAvbBlob(data_dir_.Append("testkey_rsa4096.pem"));
 
     // Uses the correct expected public key.
     VBMetaVerifyResult verify_result;
+    std::string out_public_key_data;
     std::unique_ptr<VBMetaData> vbmeta = LoadAndVerifyVbmetaByPath(
-        system_path.value(), "system_other", expected_key_blob_4096,
-        false /* allow_verification_error */, false /* rollback_protection */,
-        false /* is_chained_vbmeta */, nullptr /* verification_disabled */, &verify_result);
+            system_path.value(), "system_other", expected_key_blob_4096,
+            false /* allow_verification_error */, false /* rollback_protection */,
+            false /* is_chained_vbmeta */, &out_public_key_data,
+            nullptr /* verification_disabled */, &verify_result);
     EXPECT_NE(nullptr, vbmeta);
     EXPECT_EQ(verify_result, VBMetaVerifyResult::kSuccess);
+    EXPECT_EQ(expected_key_blob_4096, out_public_key_data);
     EXPECT_EQ(2112UL, vbmeta->size());
     EXPECT_EQ(system_path.value(), vbmeta->vbmeta_path());
     EXPECT_EQ("system_other", vbmeta->partition());
@@ -984,17 +1024,23 @@
 
     // Uses the wrong expected public key with allow_verification_error set to false.
     vbmeta = LoadAndVerifyVbmetaByPath(
-        system_path.value(), "system_other", unexpected_key_blob_2048,
-        false /* allow_verification_error */, false /* rollback_protection */,
-        false /* is_chained_vbmeta */, nullptr /* verification_disabled */, &verify_result);
+            system_path.value(), "system_other", unexpected_key_blob_2048,
+            false /* allow_verification_error */, false /* rollback_protection */,
+            false /* is_chained_vbmeta */, &out_public_key_data,
+            nullptr /* verification_disabled */, &verify_result);
     EXPECT_EQ(nullptr, vbmeta);
+    // Checks out_public_key_data is still loaded properly, if the error is due
+    // to an unexpected public key instead of vbmeta image verification error.
+    EXPECT_EQ(expected_key_blob_4096, out_public_key_data);
 
     // Uses the wrong expected public key with allow_verification_error set to true.
     vbmeta = LoadAndVerifyVbmetaByPath(
-        system_path.value(), "system_other", unexpected_key_blob_2048,
-        true /* allow_verification_error */, false /* rollback_protection */,
-        false /* is_chained_vbmeta */, nullptr /* verification_disabled */, &verify_result);
+            system_path.value(), "system_other", unexpected_key_blob_2048,
+            true /* allow_verification_error */, false /* rollback_protection */,
+            false /* is_chained_vbmeta */, &out_public_key_data,
+            nullptr /* verification_disabled */, &verify_result);
     EXPECT_NE(nullptr, vbmeta);
+    EXPECT_EQ(expected_key_blob_4096, out_public_key_data);
     EXPECT_EQ(verify_result, VBMetaVerifyResult::kErrorVerification);
     EXPECT_EQ(2112UL, vbmeta->size());
     EXPECT_EQ(system_path.value(), vbmeta->vbmeta_path());
@@ -1023,10 +1069,12 @@
     SetVBMetaFlags(system_path, AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);
     bool verification_disabled;
     VBMetaVerifyResult verify_result;
+    std::string out_public_key_data;
     std::unique_ptr<VBMetaData> vbmeta = LoadAndVerifyVbmetaByPath(
-        system_path.value(), "system_other", expected_key_blob_4096,
-        true /* allow_verification_error */, false /* rollback_protection */,
-        false /* is_chained_vbmeta */, &verification_disabled, &verify_result);
+            system_path.value(), "system_other", expected_key_blob_4096,
+            true /* allow_verification_error */, false /* rollback_protection */,
+            false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
+            &verification_disabled, &verify_result);
 
     EXPECT_NE(nullptr, vbmeta);
     EXPECT_EQ(VBMetaVerifyResult::kErrorVerification, verify_result);
@@ -1040,9 +1088,10 @@
     // Since the vbmeta flags is modified, vbmeta will be nullptr
     // if verification error isn't allowed.
     vbmeta = LoadAndVerifyVbmetaByPath(
-        system_path.value(), "system_other", expected_key_blob_4096,
-        false /* allow_verification_error */, false /* rollback_protection */,
-        false /* is_chained_vbmeta */, &verification_disabled, &verify_result);
+            system_path.value(), "system_other", expected_key_blob_4096,
+            false /* allow_verification_error */, false /* rollback_protection */,
+            false /* is_chained_vbmeta */, nullptr /* out_public_key_data */,
+            &verification_disabled, &verify_result);
     EXPECT_EQ(nullptr, vbmeta);
 }