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  size_t getWrittenSize() { return written_size_; }
52 
53  friend std::istream& operator>>(std::istream& is, StorageTargetWHandle& handle) {
54  std::array<uint8_t, 256> arr{};
55  while (!is.eof()) {
56  is.read(reinterpret_cast<char*>(arr.data()), arr.size());
57  handle.wfeed(arr.data(), static_cast<size_t>(is.gcount()));
58  }
59  return is;
60  }
61 
62  protected:
63  size_t written_size_{0};
64 };
65 
67  public:
68  class ReadError : public std::runtime_error {
69  public:
70  explicit ReadError(const std::string& what) : std::runtime_error(what) {}
71  };
72  virtual ~StorageTargetRHandle() = default;
73  virtual size_t rsize() const = 0;
74  virtual size_t rread(uint8_t* buf, size_t size) = 0;
75  virtual void rclose() = 0;
76 
77  friend std::ostream& operator<<(std::ostream& os, StorageTargetRHandle& handle) {
78  std::array<uint8_t, 256> arr{};
79  size_t written = 0;
80  while (written < handle.rsize()) {
81  size_t nread = handle.rread(arr.data(), arr.size());
82 
83  os.write(reinterpret_cast<char*>(arr.data()), static_cast<std::streamsize>(nread));
84  written += nread;
85  }
86 
87  return os;
88  }
89 };
90 
91 // Functions loading/storing multiple pieces of data are supposed to do so atomically as far as implementation makes it
92 // possible
93 class INvStorage {
94  public:
95  explicit INvStorage(const StorageConfig& config) : config_(config) {}
96  virtual ~INvStorage() = default;
97  virtual StorageType type() = 0;
98  virtual void storePrimaryKeys(const std::string& public_key, const std::string& private_key) = 0;
99  virtual bool loadPrimaryKeys(std::string* public_key, std::string* private_key) = 0;
100  virtual bool loadPrimaryPublic(std::string* public_key) = 0;
101  virtual bool loadPrimaryPrivate(std::string* private_key) = 0;
102  virtual void clearPrimaryKeys() = 0;
103 
104  virtual void storeTlsCreds(const std::string& ca, const std::string& cert, const std::string& pkey) = 0;
105  virtual void storeTlsCa(const std::string& ca) = 0;
106  virtual void storeTlsCert(const std::string& cert) = 0;
107  virtual void storeTlsPkey(const std::string& pkey) = 0;
108  virtual bool loadTlsCreds(std::string* ca, std::string* cert, std::string* pkey) = 0;
109  virtual bool loadTlsCa(std::string* ca) = 0;
110  virtual bool loadTlsCert(std::string* cert) = 0;
111  virtual bool loadTlsPkey(std::string* cert) = 0;
112  virtual void clearTlsCreds() = 0;
113 
114  virtual void storeRoot(const std::string& data, Uptane::RepositoryType repo, Uptane::Version version) = 0;
115  virtual bool loadRoot(std::string* data, Uptane::RepositoryType repo, Uptane::Version version) = 0;
116  bool loadLatestRoot(std::string* data, Uptane::RepositoryType repo) {
117  return loadRoot(data, repo, Uptane::Version());
118  };
119  virtual void storeNonRoot(const std::string& data, Uptane::RepositoryType repo, Uptane::Role role) = 0;
120  virtual bool loadNonRoot(std::string* data, Uptane::RepositoryType repo, Uptane::Role role) = 0;
121  virtual void clearNonRootMeta(Uptane::RepositoryType repo) = 0;
122  virtual void clearMetadata() = 0;
123 
124  virtual void storeDeviceId(const std::string& device_id) = 0;
125  virtual bool loadDeviceId(std::string* device_id) = 0;
126  virtual void clearDeviceId() = 0;
127 
128  virtual void storeEcuSerials(const EcuSerials& serials) = 0;
129  virtual bool loadEcuSerials(EcuSerials* serials) = 0;
130  virtual void clearEcuSerials() = 0;
131 
132  virtual void storeMisconfiguredEcus(const std::vector<MisconfiguredEcu>& ecus) = 0;
133  virtual bool loadMisconfiguredEcus(std::vector<MisconfiguredEcu>* ecus) = 0;
134  virtual void clearMisconfiguredEcus() = 0;
135 
136  virtual void storeEcuRegistered() = 0; // should be called after storeDeviceId
137  virtual bool loadEcuRegistered() = 0;
138  virtual void clearEcuRegistered() = 0;
139 
140  virtual void storeInstalledVersions(const std::vector<Uptane::Target>& installed_versions,
141  const std::string& current_hash) = 0;
142  virtual std::string loadInstalledVersions(std::vector<Uptane::Target>* installed_versions) = 0;
143  virtual void clearInstalledVersions() = 0;
144 
145  virtual void storeInstallationResult(const data::OperationResult& result) = 0;
146  virtual bool loadInstallationResult(data::OperationResult* result) = 0;
147  virtual void clearInstallationResult() = 0;
148 
149  // Incremental file API
150  virtual std::unique_ptr<StorageTargetWHandle> allocateTargetFile(bool from_director, const std::string& filename,
151  size_t size) = 0;
152  virtual std::unique_ptr<StorageTargetRHandle> openTargetFile(const std::string& filename) = 0;
153  virtual void removeTargetFile(const std::string& filename) = 0;
154 
155  virtual void cleanUp() = 0;
156 
157  // Special constructors and utilities
158  static std::shared_ptr<INvStorage> newStorage(const StorageConfig& config, bool readonly = false);
159  static void FSSToSQLS(FSStorageRead& fs_storage, SQLStorage& sql_storage);
160  static std::string fsReadInstalledVersions(const boost::filesystem::path& filename,
161  std::vector<Uptane::Target>* installed_versions);
162 
163  // Not purely virtual
164  void importData(const ImportConfig& import_config);
165  void saveInstalledVersion(const Uptane::Target& target);
166 
167  private:
168  void importSimple(const boost::filesystem::path& base_path, store_data_t store_func, load_data_t load_func,
169  const BasedPath& imported_data_path);
170  void importUpdateSimple(const boost::filesystem::path& base_path, store_data_t store_func, load_data_t load_func,
171  const BasedPath& imported_data_path);
172  void importPrimaryKeys(const boost::filesystem::path& base_path, const BasedPath& import_pubkey_path,
173  const BasedPath& import_privkey_path);
174  void importInstalledVersions(const boost::filesystem::path& base_path);
175 
176  protected:
177  const StorageConfig& config_;
178 };
179 
180 #endif // INVSTORAGE_H_
General data structures.
Definition: types.cc:44
Metadata version numbers.
Definition: tuf.h:58
TUF Roles.
Definition: tuf.h:26
RepositoryType
This must match the repo_type table in sqlstorage.
Definition: tuf.h:19