summaryrefslogtreecommitdiffstats
path: root/image_verify.hpp
blob: 3a7f911f751c29a0bd482cd30ac268c84ebe9229 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#pragma once
#include "utils.hpp"

#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <sys/mman.h>
#include <unistd.h>

#include <experimental/filesystem>
#include <set>

namespace phosphor
{
namespace software
{
namespace image
{

namespace fs = std::experimental::filesystem;
using Key_t = std::string;
using Hash_t = std::string;
using PublicKeyPath = fs::path;
using HashFilePath = fs::path;
using KeyHashPathPair = std::pair<HashFilePath, PublicKeyPath>;
using AvailableKeyTypes = std::set<Key_t>;

// RAII support for openSSL functions.
using BIO_MEM_Ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>;
using EVP_PKEY_Ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>;
using EVP_MD_CTX_Ptr =
    std::unique_ptr<EVP_MD_CTX, decltype(&::EVP_MD_CTX_free)>;

/** @struct CustomFd
 *
 *  RAII wrapper for file descriptor.
 */
struct CustomFd
{
  public:
    CustomFd() = delete;
    CustomFd(const CustomFd&) = delete;
    CustomFd& operator=(const CustomFd&) = delete;
    CustomFd(CustomFd&&) = default;
    CustomFd& operator=(CustomFd&&) = default;
    /** @brief Saves File descriptor and uses it to do file operation
     *
     *  @param[in] fd - File descriptor
     */
    CustomFd(int fd) : fd(fd)
    {
    }

    ~CustomFd()
    {
        if (fd >= 0)
        {
            close(fd);
        }
    }

    int operator()() const
    {
        return fd;
    }

  private:
    /** @brief File descriptor */
    int fd = -1;
};

/** @struct CustomMap
 *
 *  RAII wrapper for mmap.
 */
struct CustomMap
{
  private:
    /** @brief starting address of the map   */
    void* addr;

    /** @brief length of the mapping   */
    size_t length;

  public:
    CustomMap() = delete;
    CustomMap(const CustomMap&) = delete;
    CustomMap& operator=(const CustomMap&) = delete;
    CustomMap(CustomMap&&) = default;
    CustomMap& operator=(CustomMap&&) = default;

    /** @brief Saves starting address of the map and
     *         and length of the file.
     *  @param[in]  addr - Starting address of the map
     *  @param[in]  length - length of the map
     */
    CustomMap(void* addr, size_t length) : addr(addr), length(length)
    {
    }

    ~CustomMap()
    {
        munmap(addr, length);
    }

    void* operator()() const
    {
        return addr;
    }
};

/** @class Signature
 *  @brief Contains signature verification functions.
 *  @details The software image class that contains the signature
 *           verification functions for signed image.
 */
class Signature
{
  public:
    Signature() = delete;
    Signature(const Signature&) = delete;
    Signature& operator=(const Signature&) = delete;
    Signature(Signature&&) = default;
    Signature& operator=(Signature&&) = default;
    ~Signature() = default;

    /**
     * @brief Constructs Signature.
     * @param[in]  imageDirPath - image path
     * @param[in]  signedConfPath - Path of public key
     *                              hash function files
     */
    Signature(const fs::path& imageDirPath, const fs::path& signedConfPath);

    /**
     * @brief Image signature verification function.
     *        Verify the Manifest and public key file signature using the
     *        public keys available in the system first. After successful
     *        validation, continue the whole image files signature
     *        validation using the image specific public key and the
     *        hash function.
     *
     *        @return true if signature verification was successful,
     *                     false if not
     */
    bool verify();

  private:
    /**
     * @brief Function used for system level file signature validation
     *        of image specific publickey file and manifest file
     *        using the available public keys and hash functions
     *        in the system.
     *        Refer code-update documentation for more details.
     */
    bool systemLevelVerify();

    /**
     *  @brief Return all key types stored in the BMC based on the
     *         public key and hashfunc files stored in the BMC.
     *
     *  @return list
     */
    AvailableKeyTypes getAvailableKeyTypesFromSystem() const;

    /**
     *  @brief Return public key and hash function file names for the
     *  corresponding key type
     *
     *  @param[in]  key - key type
     *  @return Pair of hash and public key file names
     */
    inline KeyHashPathPair getKeyHashFileNames(const Key_t& key) const;

    /**
     * @brief Verify the file signature using public key and hash function
     *
     * @param[in]  - Image file path
     * @param[in]  - Signature file path
     * @param[in]  - Public key
     * @param[in]  - Hash function name
     * @return true if signature verification was successful, false if not
     */
    bool verifyFile(const fs::path& file, const fs::path& signature,
                    const fs::path& publicKey, const std::string& hashFunc);

    /**
     * @brief Create RSA object from the public key
     * @param[in]  - publickey
     * @param[out] - RSA Object.
     */
    inline RSA* createPublicRSA(const fs::path& publicKey);

    /**
     * @brief Memory map the  file
     * @param[in]  - file path
     * @param[in]  - file size
     * @param[out] - Custom Mmap address
     */
    CustomMap mapFile(const fs::path& path, size_t size);

    /** @brief Directory where software images are placed*/
    fs::path imageDirPath;

    /** @brief Path of public key and hash function files */
    fs::path signedConfPath;

    /** @brief key type defined in mainfest file */
    Key_t keyType;

    /** @brief Hash type defined in mainfest file */
    Hash_t hashType;
};

} // namespace image
} // namespace software
} // namespace phosphor
OpenPOWER on IntegriCloud