1 #pragma once
2 #include "utils.hpp"
3 
4 #include <openssl/evp.h>
5 #include <openssl/pem.h>
6 #include <openssl/rsa.h>
7 #include <sys/mman.h>
8 #include <unistd.h>
9 
10 #include <filesystem>
11 #include <set>
12 #include <string>
13 
14 namespace openpower
15 {
16 namespace software
17 {
18 namespace image
19 {
20 
21 using Key_t = std::string;
22 using Hash_t = std::string;
23 using PublicKeyPath = std::filesystem::path;
24 using HashFilePath = std::filesystem::path;
25 using KeyHashPathPair = std::pair<HashFilePath, PublicKeyPath>;
26 using AvailableKeyTypes = std::set<Key_t>;
27 
28 // RAII support for openSSL functions.
29 using BIO_MEM_Ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>;
30 using EVP_PKEY_Ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>;
31 using EVP_MD_CTX_Ptr =
32     std::unique_ptr<EVP_MD_CTX, decltype(&::EVP_MD_CTX_free)>;
33 
34 /** @struct CustomFd
35  *
36  *  RAII wrapper for file descriptor.
37  */
38 struct CustomFd
39 {
40   public:
41     CustomFd() = delete;
42     CustomFd(const CustomFd&) = delete;
43     CustomFd& operator=(const CustomFd&) = delete;
44     CustomFd(CustomFd&&) = default;
45     CustomFd& operator=(CustomFd&&) = default;
46     /** @brief Saves File descriptor and uses it to do file operation
47      *
48      *  @param[in] fd - File descriptor
49      */
50     explicit CustomFd(int fd) : fd(fd)
51     {}
52 
53     ~CustomFd()
54     {
55         if (fd >= 0)
56         {
57             close(fd);
58         }
59     }
60 
61     int operator()() const
62     {
63         return fd;
64     }
65 
66   private:
67     /** @brief File descriptor */
68     int fd = -1;
69 };
70 
71 /** @struct CustomMap
72  *
73  *  RAII wrapper for mmap.
74  */
75 struct CustomMap
76 {
77   private:
78     /** @brief starting address of the map   */
79     void* addr;
80 
81     /** @brief length of the mapping   */
82     size_t length;
83 
84   public:
85     CustomMap() = delete;
86     CustomMap(const CustomMap&) = delete;
87     CustomMap& operator=(const CustomMap&) = delete;
88     CustomMap(CustomMap&&) = default;
89     CustomMap& operator=(CustomMap&&) = default;
90 
91     /** @brief Saves starting address of the map and
92      *         and length of the file.
93      *  @param[in]  addr - Starting address of the map
94      *  @param[in]  length - length of the map
95      */
96     CustomMap(void* addr, size_t length) : addr(addr), length(length)
97     {}
98 
99     ~CustomMap()
100     {
101         munmap(addr, length);
102     }
103 
104     void* operator()() const
105     {
106         return addr;
107     }
108 };
109 
110 /** @class Signature
111  *  @brief Contains signature verification functions.
112  *  @details The software image class that contains the signature
113  *           verification functions for signed image.
114  */
115 class Signature
116 {
117   public:
118     Signature() = delete;
119     Signature(const Signature&) = delete;
120     Signature& operator=(const Signature&) = delete;
121     Signature(Signature&&) = default;
122     Signature& operator=(Signature&&) = default;
123     ~Signature() = default;
124 
125     /**
126      * @brief Constructs Signature.
127      * @param[in]  imageDirPath - image path
128      * @param[in]  signedConfPath - Path of public key
129      *                              hash function files
130      */
131     explicit Signature(const std::filesystem::path& imageDirPath,
132                        const std::string& pnorFileName,
133                        const std::filesystem::path& signedConfPath);
134 
135     /**
136      * @brief Image signature verification function.
137      *        Verify the Manifest and public key file signature using the
138      *        public keys available in the system first. After successful
139      *        validation, continue the whole image files signature
140      *        validation using the image specific public key and the
141      *        hash function.
142      *
143      *        @return true if signature verification was successful,
144      *                     false if not
145      */
146     bool verify();
147 
148   private:
149     /**
150      * @brief Function used for system level file signature validation
151      *        of image specific publickey file and manifest file
152      *        using the available public keys and hash functions
153      *        in the system.
154      *        Refer code-update documentation for more details.
155      */
156     bool systemLevelVerify();
157 
158     /**
159      *  @brief Return all key types stored in the BMC based on the
160      *         public key and hashfunc files stored in the BMC.
161      *
162      *  @return list
163      */
164     AvailableKeyTypes getAvailableKeyTypesFromSystem() const;
165 
166     /**
167      *  @brief Return public key and hash function file names for the
168      *  corresponding key type
169      *
170      *  @param[in]  key - key type
171      *  @return Pair of hash and public key file names
172      */
173     inline KeyHashPathPair getKeyHashFileNames(const Key_t& key) const;
174 
175     /**
176      * @brief Verify the file signature using public key and hash function
177      *
178      * @param[in]  - Image file path
179      * @param[in]  - Signature file path
180      * @param[in]  - Public key
181      * @param[in]  - Hash function name
182      * @return true if signature verification was successful, false if not
183      */
184     bool verifyFile(const std::filesystem::path& file,
185                     const std::filesystem::path& signature,
186                     const std::filesystem::path& publicKey,
187                     const std::string& hashFunc);
188 
189     /**
190      * @brief Create RSA object from the public key
191      * @param[in]  - publickey
192      * @param[out] - RSA Object.
193      */
194     inline EVP_PKEY_Ptr createPublicRSA(const std::filesystem::path& publicKey);
195 
196     /**
197      * @brief Memory map the  file
198      * @param[in]  - file path
199      * @param[in]  - file size
200      * @param[out] - Custom Mmap address
201      */
202     CustomMap mapFile(const std::filesystem::path& path, size_t size);
203 
204     /** @brief Directory where software images are placed*/
205     std::filesystem::path imageDirPath;
206 
207     /** @brief The PNOR file name in imageDirPath */
208     std::string pnorFileName;
209 
210     /** @brief Path of public key and hash function files */
211     std::filesystem::path signedConfPath;
212 
213     /** @brief key type defined in mainfest file */
214     Key_t keyType;
215 
216     /** @brief Hash type defined in mainfest file */
217     Hash_t hashType;
218 };
219 
220 } // namespace image
221 } // namespace software
222 } // namespace openpower
223