blob: 8cfe897addc96aa62edbfabb5c150435dcbc83c2 [file] [log] [blame]
Jayanth Othayoth7ccaa2a2018-03-21 02:14:34 -05001#include "image_verify.hpp"
Gunnar Millsf6ed5892018-09-07 17:08:02 -05002
3#include <openssl/sha.h>
4
Brad Bishop9f44c992020-11-06 14:48:46 -05005#include <filesystem>
Gunnar Millsf6ed5892018-09-07 17:08:02 -05006#include <string>
7
8#include <gtest/gtest.h>
Gunnar Mills2a6981b2017-10-15 17:05:18 -05009
Jayanth Othayoth7ccaa2a2018-03-21 02:14:34 -050010using namespace openpower::software::image;
Gunnar Mills2a6981b2017-10-15 17:05:18 -050011
Jayanth Othayoth7ccaa2a2018-03-21 02:14:34 -050012class SignatureTest : public testing::Test
13{
14 static constexpr auto opensslCmd = "openssl dgst -sha256 -sign ";
15 static constexpr auto testPath = "/tmp/_testSig";
16
17 protected:
18 void command(const std::string& cmd)
19 {
20 auto val = std::system(cmd.c_str());
21 if (val)
22 {
23 std::cout << "COMMAND Error: " << val << std::endl;
24 }
25 }
26 virtual void SetUp()
27 {
28 // Create test base directory.
Brad Bishop9f44c992020-11-06 14:48:46 -050029 std::filesystem::create_directories(testPath);
Jayanth Othayoth7ccaa2a2018-03-21 02:14:34 -050030
31 // Create unique temporary path for images.
32 std::string tmpDir(testPath);
33 tmpDir += "/extractXXXXXX";
34 std::string imageDir = mkdtemp(const_cast<char*>(tmpDir.c_str()));
35
36 // Create unique temporary configuration path
37 std::string tmpConfDir(testPath);
38 tmpConfDir += "/confXXXXXX";
39 std::string confDir = mkdtemp(const_cast<char*>(tmpConfDir.c_str()));
40
41 extractPath = imageDir;
42 extractPath /= "images";
43
44 signedConfPath = confDir;
45 signedConfPath /= "conf";
46
47 signedConfPNORPath = confDir;
48 signedConfPNORPath /= "conf";
49 signedConfPNORPath /= "OpenBMC";
50
51 std::cout << "SETUP " << std::endl;
52
53 command("mkdir " + extractPath.string());
54 command("mkdir " + signedConfPath.string());
55 command("mkdir " + signedConfPNORPath.string());
56
57 std::string hashFile = signedConfPNORPath.string() + "/hashfunc";
58 command("echo \"HashType=RSA-SHA256\" > " + hashFile);
59
60 std::string manifestFile = extractPath.string() + "/" + "MANIFEST";
61 command("echo \"HashType=RSA-SHA256\" > " + manifestFile);
62 command("echo \"KeyType=OpenBMC\" >> " + manifestFile);
63
64 std::string pnorFile = extractPath.string() + "/" + "pnor.xz.squashfs";
65 command("echo \"pnor.xz.squashfs file \" > " + pnorFile);
66
67 std::string pkeyFile = extractPath.string() + "/" + "private.pem";
68 command("openssl genrsa -out " + pkeyFile + " 2048");
69
70 std::string pubkeyFile = extractPath.string() + "/" + "publickey";
71 command("openssl rsa -in " + pkeyFile + " -outform PEM " +
72 "-pubout -out " + pubkeyFile);
73
Patrick Williams7fb6c342023-05-10 07:50:18 -050074 std::string pubKeyConfFile = signedConfPNORPath.string() + "/" +
75 "publickey";
Jayanth Othayoth7ccaa2a2018-03-21 02:14:34 -050076 command("cp " + pubkeyFile + " " + signedConfPNORPath.string());
77 command(opensslCmd + pkeyFile + " -out " + pnorFile + ".sig " +
78 pnorFile);
79
80 command(opensslCmd + pkeyFile + " -out " + manifestFile + ".sig " +
81 manifestFile);
82 command(opensslCmd + pkeyFile + " -out " + pubkeyFile + ".sig " +
83 pubkeyFile);
84
Lei YU2b2d2292019-03-18 15:22:56 +080085 signature = std::make_unique<Signature>(extractPath, "pnor.xz.squashfs",
86 signedConfPath);
Jayanth Othayoth7ccaa2a2018-03-21 02:14:34 -050087 }
88 virtual void TearDown()
89 {
90 command("rm -rf " + std::string(testPath));
91 }
Jayanth Othayoth7ccaa2a2018-03-21 02:14:34 -050092 std::unique_ptr<Signature> signature;
Brad Bishop9f44c992020-11-06 14:48:46 -050093 std::filesystem::path extractPath;
94 std::filesystem::path signedConfPath;
95 std::filesystem::path signedConfPNORPath;
Jayanth Othayoth7ccaa2a2018-03-21 02:14:34 -050096};
97
Gunnar Millsa9cfced2018-04-08 15:01:57 -050098/** @brief Test for success scenario*/
Jayanth Othayoth7ccaa2a2018-03-21 02:14:34 -050099TEST_F(SignatureTest, TestSignatureVerify)
100{
101 EXPECT_TRUE(signature->verify());
102}
Jayanth Othayoth808c40d2018-03-21 06:08:06 -0500103
104/** @brief Test failure scenario with corrupted signature file*/
105TEST_F(SignatureTest, TestCorruptSignatureFile)
106{
107 // corrupt the image-kernel.sig file and ensure that verification fails
108 std::string kernelFile = extractPath.string() + "/" + "pnor.xz.squashfs";
109 command("echo \"dummy data\" > " + kernelFile + ".sig ");
110 EXPECT_FALSE(signature->verify());
111}
112
113/** @brief Test failure scenario with no public key in the image*/
114TEST_F(SignatureTest, TestNoPublicKeyInImage)
115{
116 // Remove publickey file from the image and ensure that verify fails
117 std::string pubkeyFile = extractPath.string() + "/" + "publickey";
118 command("rm " + pubkeyFile);
119 EXPECT_FALSE(signature->verify());
120}
121
122/** @brief Test failure scenario with invalid hash function value*/
123TEST_F(SignatureTest, TestInvalidHashValue)
124{
125 // Change the hashfunc value and ensure that verification fails
126 std::string hashFile = signedConfPNORPath.string() + "/hashfunc";
127 command("echo \"HashType=md5\" > " + hashFile);
128 EXPECT_FALSE(signature->verify());
129}
130
131/** @brief Test for failure scenario with no config file in system*/
132TEST_F(SignatureTest, TestNoConfigFileInSystem)
133{
134 // Remove the conf folder in the system and ensure that verify fails
135 command("rm -rf " + signedConfPNORPath.string());
136 EXPECT_FALSE(signature->verify());
137}