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