Aktualizr
C++ SOTA Client
invstorage.h
1 #ifndef INVSTORAGE_H_
2 #define INVSTORAGE_H_
3 
4 #include <memory>
5 #include <string>
6 #include <utility>
7 
8 #include <boost/filesystem.hpp>
9 
10 #include "storage_config.h"
11 #include "uptane/tuf.h"
12 #include "utilities/types.h"
13 
14 class INvStorage;
15 class FSStorageRead;
16 class SQLStorage;
17 
18 class StorageException : public std::runtime_error {
19  public:
20  StorageException(const std::string& what) : std::runtime_error(what) {}
21  ~StorageException() noexcept override = default;
22 };
23 
24 using store_data_t = void (INvStorage::*)(const std::string&);
25 using load_data_t = bool (INvStorage::*)(std::string*);
26 
27 typedef std::pair<std::string, bool> InstalledVersion;
28 
29 typedef std::vector<std::pair<Uptane::EcuSerial, Uptane::HardwareIdentifier>> EcuSerials;
30 
31 enum class EcuState { kOld = 0, kNotRegistered };
32 
34  MisconfiguredEcu(Uptane::EcuSerial serial_in, Uptane::HardwareIdentifier hardware_id_in, EcuState state_in)
35  : serial(std::move(serial_in)), hardware_id(std::move(hardware_id_in)), state(state_in) {}
36  Uptane::EcuSerial serial;
37  Uptane::HardwareIdentifier hardware_id;
38  EcuState state;
39 };
40 
42  public:
43  class WriteError : public std::runtime_error {
44  public:
45  explicit WriteError(const std::string& what) : std::runtime_error(what) {}
46  };
47  virtual ~StorageTargetWHandle() = default;
48  virtual size_t wfeed(const uint8_t* buf, size_t size) = 0;
49  virtual void wcommit() = 0;
50  virtual void wabort() = 0;
51 
52  friend std::istream& operator>>(std::istream& is, StorageTargetWHandle& handle) {
53  std::array<uint8_t, 256> arr{};
54  while (!is.eof()) {
55  is.read(reinterpret_cast<char*>(arr.data()), arr.size());
56 
57  handle.wfeed(arr.data(), static_cast<size_t>(is.gcount()));
58  }
59  handle.wcommit();
60 
61  return is;
62  }
63 };
64 
66  public:
67  class ReadError : public std::runtime_error {
68  public:
69  explicit ReadError(const std::string& what) : std::runtime_error(what) {}
70  };
71  virtual ~StorageTargetRHandle() = default;
72  virtual size_t rsize() const = 0;
73  virtual size_t rread(uint8_t* buf, size_t size) = 0;
74  virtual void rclose() = 0;
75 
76  friend std::ostream& operator<<(std::ostream& os, StorageTargetRHandle& handle) {
77  std::array<uint8_t, 256> arr{};
78  size_t written = 0;
79  while (written < handle.rsize()) {
80  size_t nread = handle.rread(arr.data(), arr.size());
81 
82  os.write(reinterpret_cast<char*>(arr.data()), static_cast<std::streamsize>(nread));
83  written += nread;
84  }
85 
86  return os;
87  }
88 };
89 
90 // Functions loading/storing multiple pieces of data are supposed to do so atomically as far as implementation makes it
91 // possible
92 class INvStorage {
93  public:
94  explicit INvStorage(const StorageConfig& config) : config_(config) {}
95  virtual ~INvStorage() = default;
96  virtual StorageType type() = 0;
97  virtual void storePrimaryKeys(const std::string& public_key, const std::string& private_key) = 0;
98  virtual bool loadPrimaryKeys(std::string* public_key, std::string* private_key) = 0;
99  virtual bool loadPrimaryPublic(std::string* public_key) = 0;
100  virtual bool loadPrimaryPrivate(std::string* private_key) = 0;
101  virtual void clearPrimaryKeys() = 0;
102 
103  virtual void storeTlsCreds(const std::string& ca, const std::string& cert, const std::string& pkey) = 0;
104  virtual void storeTlsCa(const std::string& ca) = 0;
105  virtual void storeTlsCert(const std::string& cert) = 0;
106  virtual void storeTlsPkey(const std::string& pkey) = 0;
107  virtual bool loadTlsCreds(std::string* ca, std::string* cert, std::string* pkey) = 0;
108  virtual bool loadTlsCa(std::string* ca) = 0;
109  virtual bool loadTlsCert(std::string* cert) = 0;
110  virtual bool loadTlsPkey(std::string* cert) = 0;
111  virtual void clearTlsCreds() = 0;
112 
113  virtual void storeRoot(const std::string& data, Uptane::RepositoryType repo, Uptane::Version version) = 0;
114  virtual bool loadRoot(std::string* data, Uptane::RepositoryType repo, Uptane::Version version) = 0;
115  bool loadLatestRoot(std::string* data, Uptane::RepositoryType repo) {
116  return loadRoot(data, repo, Uptane::Version());
117  };
118  virtual void storeNonRoot(const std::string& data, Uptane::RepositoryType repo, Uptane::Role role) = 0;
119  virtual bool loadNonRoot(std::string* data, Uptane::RepositoryType repo, Uptane::Role role) = 0;
120  virtual void clearNonRootMeta(Uptane::RepositoryType repo) = 0;
121  virtual void clearMetadata() = 0;
122 
123  virtual void storeDeviceId(const std::string& device_id) = 0;
124  virtual bool loadDeviceId(std::string* device_id) = 0;
125  virtual void clearDeviceId() = 0;
126 
127  virtual void storeEcuSerials(const EcuSerials& serials) = 0;
128  virtual bool loadEcuSerials(EcuSerials* serials) = 0;
129  virtual void clearEcuSerials() = 0;
130 
131  virtual void storeMisconfiguredEcus(const std::vector<MisconfiguredEcu>& ecus) = 0;
132  virtual bool loadMisconfiguredEcus(std::vector<MisconfiguredEcu>* ecus) = 0;
133  virtual void clearMisconfiguredEcus() = 0;
134 
135  virtual void storeEcuRegistered() = 0; // should be called after storeDeviceId
136  virtual bool loadEcuRegistered() = 0;
137  virtual void clearEcuRegistered() = 0;
138 
139  virtual void storeInstalledVersions(const std::vector<Uptane::Target>& installed_versions,
140  const std::string& current_hash) = 0;
141  virtual std::string loadInstalledVersions(std::vector<Uptane::Target>* installed_versions) = 0;
142  virtual void clearInstalledVersions() = 0;
143 
144  virtual void storeInstallationResult(const data::OperationResult& result) = 0;
145  virtual bool loadInstallationResult(data::OperationResult* result) = 0;
146  virtual void clearInstallationResult() = 0;
147 
148  // Incremental file API
149  virtual std::unique_ptr<StorageTargetWHandle> allocateTargetFile(bool from_director, const std::string& filename,
150  size_t size) = 0;
151  virtual std::unique_ptr<StorageTargetRHandle> openTargetFile(const std::string& filename) = 0;
152  virtual void removeTargetFile(const std::string& filename) = 0;
153 
154  virtual void cleanUp() = 0;
155 
156  // Special constructors and utilities
157  static std::shared_ptr<INvStorage> newStorage(const StorageConfig& config, bool readonly = false);
158  static void FSSToSQLS(FSStorageRead& fs_storage, SQLStorage& sql_storage);
159 
160  // Not purely virtual
161  void importData(const ImportConfig& import_config);
162  void saveInstalledVersion(const Uptane::Target& target);
163 
164  private:
165  void importSimple(const boost::filesystem::path& base_path, store_data_t store_func, load_data_t load_func,
166  const BasedPath& imported_data_path);
167  void importUpdateSimple(const boost::filesystem::path& base_path, store_data_t store_func, load_data_t load_func,
168  const BasedPath& imported_data_path);
169  void importPrimaryKeys(const boost::filesystem::path& base_path, const BasedPath& import_pubkey_path,
170  const BasedPath& import_privkey_path);
171 
172  protected:
173  const StorageConfig& config_;
174 };
175 
176 #endif // INVSTORAGE_H_
General data structures.
Definition: types.cc:6
Metadata version numbers.
Definition: tuf.h:57
TUF Roles.
Definition: tuf.h:25
RepositoryType
This must match the repo_type table in sqlstorage.
Definition: tuf.h:18