Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
directorrepository.cc
1 #include "directorrepository.h"
2 
3 namespace Uptane {
4 
5 void DirectorRepository::resetMeta() {
6  resetRoot();
7  targets = Targets();
8  latest_targets = Targets();
9 }
10 
11 bool DirectorRepository::targetsExpired() {
12  if (latest_targets.isExpired(TimeStamp::Now())) {
13  last_exception = Uptane::ExpiredMetadata(type.toString(), Role::Targets().ToString());
14  return true;
15  }
16  return false;
17 }
18 
19 bool DirectorRepository::targetsSanityCheck() {
20  // 5.4.4.6.6. If checking Targets metadata from the Director repository,
21  // verify that there are no delegations.
22  if (!latest_targets.delegated_role_names_.empty()) {
23  last_exception =
24  Uptane::InvalidMetadata(type.toString(), Role::Targets().ToString(), "Found unexpected delegation.");
25  return false;
26  }
27  // 5.4.4.6.7. If checking Targets metadata from the Director repository,
28  // check that no ECU identifier is represented more than once.
29  std::set<Uptane::EcuSerial> ecu_ids;
30  for (const auto& target : targets.targets) {
31  for (const auto& ecu : target.ecus()) {
32  if (ecu_ids.find(ecu.first) == ecu_ids.end()) {
33  ecu_ids.insert(ecu.first);
34  } else {
35  last_exception = Uptane::InvalidMetadata(type.toString(), Role::Targets().ToString(), "Found repeated ECU ID.");
36  return false;
37  }
38  }
39  }
40  return true;
41 }
42 
43 bool DirectorRepository::usePreviousTargets() const {
44  // Don't store the new targets if they are empty and we've previously received
45  // a non-empty list.
46  return !targets.targets.empty() && latest_targets.targets.empty();
47 }
48 
49 bool DirectorRepository::verifyTargets(const std::string& targets_raw) {
50  try {
51  // Verify the signature:
52  latest_targets = Targets(RepositoryType::Director(), Role::Targets(), Utils::parseJSON(targets_raw),
53  std::make_shared<MetaWithKeys>(root));
54  if (!usePreviousTargets()) {
55  targets = latest_targets;
56  }
57  } catch (const Uptane::Exception& e) {
58  LOG_ERROR << "Signature verification for Director Targets metadata failed";
59  last_exception = e;
60  return false;
61  }
62  return true;
63 }
64 
65 bool DirectorRepository::checkMetaOffline(INvStorage& storage) {
66  resetMeta();
67  // Load Director Root Metadata
68  {
69  std::string director_root;
70  if (!storage.loadLatestRoot(&director_root, RepositoryType::Director())) {
71  return false;
72  }
73 
74  if (!initRoot(director_root)) {
75  return false;
76  }
77 
78  if (rootExpired()) {
79  return false;
80  }
81  }
82 
83  // Load Director Targets Metadata
84  {
85  std::string director_targets;
86 
87  if (!storage.loadNonRoot(&director_targets, RepositoryType::Director(), Role::Targets())) {
88  return false;
89  }
90 
91  if (!verifyTargets(director_targets)) {
92  return false;
93  }
94 
95  if (targetsExpired()) {
96  return false;
97  }
98 
99  if (!targetsSanityCheck()) {
100  return false;
101  }
102  }
103 
104  return true;
105 }
106 
107 bool DirectorRepository::updateMeta(INvStorage& storage, const IMetadataFetcher& fetcher) {
108  // Uptane step 2 (download time) is not implemented yet.
109  // Uptane step 3 (download metadata)
110 
111  // reset Director repo to initial state before starting Uptane iteration
112  resetMeta();
113 
114  if (!updateRoot(storage, fetcher, RepositoryType::Director())) {
115  return false;
116  }
117 
118  // Not supported: 3. Download and check the Timestamp metadata file from the Director repository, following the
119  // procedure in Section 5.4.4.4. Not supported: 4. Download and check the Snapshot metadata file from the Director
120  // repository, following the procedure in Section 5.4.4.5.
121 
122  // Update Director Targets Metadata
123  {
124  std::string director_targets;
125 
126  if (!fetcher.fetchLatestRole(&director_targets, kMaxDirectorTargetsSize, RepositoryType::Director(),
127  Role::Targets())) {
128  return false;
129  }
130  int remote_version = extractVersionUntrusted(director_targets);
131 
132  int local_version;
133  std::string director_targets_stored;
134  if (storage.loadNonRoot(&director_targets_stored, RepositoryType::Director(), Role::Targets())) {
135  local_version = extractVersionUntrusted(director_targets_stored);
136  if (!verifyTargets(director_targets_stored)) {
137  LOG_WARNING << "Unable to verify stored Director Targets metadata.";
138  }
139  } else {
140  local_version = -1;
141  }
142 
143  if (!verifyTargets(director_targets)) {
144  return false;
145  }
146 
147  if (local_version > remote_version) {
148  return false;
149  } else if (local_version < remote_version && !usePreviousTargets()) {
150  storage.storeNonRoot(director_targets, RepositoryType::Director(), Role::Targets());
151  }
152 
153  if (targetsExpired()) {
154  return false;
155  }
156 
157  if (!targetsSanityCheck()) {
158  return false;
159  }
160  }
161 
162  return true;
163 }
164 
165 void DirectorRepository::dropTargets(INvStorage& storage) {
166  storage.clearNonRootMeta(RepositoryType::Director());
167  resetMeta();
168 }
169 
170 bool DirectorRepository::matchTargetsWithImageTargets(const Uptane::Targets& image_targets) const {
171  // step 10 of https://uptane.github.io/papers/ieee-isto-6100.1.0.0.uptane-standard.html#rfc.section.5.4.4.2
172  // TBD: no delegation support, consider reusing of findTargetInDelegationTree()
173  // that needs to be moved into a common place to be resued by Primary and Secondary
174  const auto& image_target_array = image_targets.targets;
175  const auto& director_target_array = targets.targets;
176 
177  for (const auto& director_target : director_target_array) {
178  auto found_it = std::find_if(
179  image_target_array.begin(), image_target_array.end(),
180  [&director_target](const Target& image_target) { return director_target.MatchTarget(image_target); });
181 
182  if (found_it == image_target_array.end()) {
183  return false;
184  }
185  }
186 
187  return true;
188 }
189 
190 } // namespace Uptane
Uptane::InvalidMetadata
Definition: exceptions.h:67
Uptane::ExpiredMetadata
Definition: exceptions.h:60
Uptane::Targets
Definition: tuf.h:440
Uptane::Exception
Definition: exceptions.h:10
Uptane
Base data types that are used in The Update Framework (TUF), part of Uptane.
Definition: secondary_tcp_server.h:8
INvStorage
Definition: invstorage.h:126