image_verify: Support full image

The code only supports verify the static.mtd.tar, but not
static.mtd.all.tar.

This change adds the signature verify for the full tarball.

Tested: Update .static.mtd.all.tar with Redfish API OK.
        Update .static.mtd.tar with Redfish API OK.

Signed-off-by: Henry Tian <tianxiaofeng@bytedance.com>
Signed-off-by: Lei YU <yulei.sh@bytedance.com>
Change-Id: I58a47d76ef090644cc1e870077f438b8768f6aa9
diff --git a/image_verify.cpp b/image_verify.cpp
index d7b676d..d9679c9 100644
--- a/image_verify.cpp
+++ b/image_verify.cpp
@@ -89,6 +89,7 @@
 {
     try
     {
+        bool valid;
         // Verify the MANIFEST and publickey file using available
         // public keys and hash on the system.
         if (false == systemLevelVerify())
@@ -100,26 +101,24 @@
         // image specific publickey file name.
         fs::path publicKeyFile(imageDirPath / PUBLICKEY_FILE_NAME);
 
-        // Validate the BMC image files.
-        for (const auto& bmcImage : bmcImages)
+        // Record the images which are being updated
+        // First check and Validate for the fullimage, then check and Validate
+        // for images with partitions
+        std::vector<std::string> imageUpdateList = {bmcFullImages};
+        valid =
+            checkAndVerifyImage(imageDirPath, publicKeyFile, imageUpdateList);
+        if (!valid)
         {
-            // Build Image File name
-            fs::path file(imageDirPath);
-            file /= bmcImage;
-
-            // Build Signature File name
-            fs::path sigFile(file);
-            sigFile.replace_extension(SIGNATURE_FILE_EXT);
-
-            // Verify the signature.
-            auto valid = verifyFile(file, sigFile, publicKeyFile, hashType);
-            if (valid == false)
+            imageUpdateList.clear();
+            imageUpdateList.assign(bmcImages.begin(), bmcImages.end());
+            valid = checkAndVerifyImage(imageDirPath, publicKeyFile,
+                                        imageUpdateList);
+            if (!valid)
             {
-                log<level::ERR>("Image file Signature Validation failed",
-                                entry("IMAGE=%s", bmcImage.c_str()));
                 return false;
             }
         }
+
         // Validate the optional image files.
         auto optionalImages = getOptionalImages();
         for (const auto& optionalImage : optionalImages)
@@ -135,7 +134,7 @@
                 sigFile.replace_extension(SIGNATURE_FILE_EXT);
 
                 // Verify the signature.
-                auto valid = verifyFile(file, sigFile, publicKeyFile, hashType);
+                valid = verifyFile(file, sigFile, publicKeyFile, hashType);
                 if (valid == false)
                 {
                     log<level::ERR>("Image file Signature Validation failed",
@@ -334,6 +333,38 @@
                      size);
 }
 
+bool Signature::checkAndVerifyImage(const std::string& filePath,
+                                    const std::string& publicKeyPath,
+                                    const std::vector<std::string>& imageList)
+{
+    bool valid = true;
+
+    for (auto& bmcImage : imageList)
+    {
+        fs::path file(filePath);
+        file /= bmcImage;
+
+        if (!fs::exists(file))
+        {
+            valid = false;
+            break;
+        }
+
+        fs::path sigFile(file);
+        sigFile.replace_extension(SIGNATURE_FILE_EXT);
+
+        // Verify the signature.
+        auto valid = verifyFile(file, sigFile, publicKeyPath, hashType);
+        if (valid == false)
+        {
+            log<level::ERR>("Image file Signature Validation failed",
+                            entry("IMAGE=%s", bmcImage.c_str()));
+            return false;
+        }
+    }
+
+    return valid;
+}
 } // namespace image
 } // namespace software
 } // namespace phosphor
diff --git a/image_verify.hpp b/image_verify.hpp
index f5acbb9..02e1093 100644
--- a/image_verify.hpp
+++ b/image_verify.hpp
@@ -10,6 +10,7 @@
 #include <filesystem>
 #include <set>
 #include <string>
+#include <vector>
 
 namespace phosphor
 {
@@ -209,6 +210,19 @@
 
     /** @brief Hash type defined in mainfest file */
     Hash_t hashType;
+
+    /** @brief Check and Verify the required image files
+     *
+     * @param[in] filePath - BMC tarball file path
+     * @param[in] publicKeyPath - publicKey file Path
+     * @param[in] imageList - Image filenames included in the BMC tarball
+     * @param[out] result - Boolean
+     *                      true if all image files are found in BMC tarball and
+     * Verify Sucess false if one of image files is missing
+     */
+    bool checkAndVerifyImage(const std::string& filePath,
+                             const std::string& publicKeyPath,
+                             const std::vector<std::string>& imageList);
 };
 
 } // namespace image