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() const { return latest_targets.isExpired(TimeStamp::Now()); }
12 
13 bool DirectorRepository::usePreviousTargets() const {
14  // Don't store the new targets if they are empty and we've previously received
15  // a non-empty list.
16  return !targets.targets.empty() && latest_targets.targets.empty();
17 }
18 
19 bool DirectorRepository::verifyTargets(const std::string& targets_raw) {
20  try {
21  // Verify the signature:
22  latest_targets = Targets(RepositoryType::Director(), Role::Targets(), Utils::parseJSON(targets_raw),
23  std::make_shared<MetaWithKeys>(root));
24  if (!usePreviousTargets()) {
25  targets = latest_targets;
26  }
27  } catch (const Uptane::Exception& e) {
28  LOG_ERROR << "Signature verification for director targets metadata failed";
29  last_exception = e;
30  return false;
31  }
32  return true;
33 }
34 
35 bool DirectorRepository::checkMetaOffline(INvStorage& storage) {
36  resetMeta();
37  // Load Director Root Metadata
38  {
39  std::string director_root;
40  if (!storage.loadLatestRoot(&director_root, RepositoryType::Director())) {
41  return false;
42  }
43 
44  if (!initRoot(director_root)) {
45  return false;
46  }
47 
48  if (rootExpired()) {
49  return false;
50  }
51  }
52 
53  // Load Director Targets Metadata
54  {
55  std::string director_targets;
56 
57  if (!storage.loadNonRoot(&director_targets, RepositoryType::Director(), Role::Targets())) {
58  return false;
59  }
60 
61  if (!verifyTargets(director_targets)) {
62  return false;
63  }
64 
65  if (targetsExpired()) {
66  last_exception = Uptane::ExpiredMetadata(type.toString(), Role::Targets().ToString());
67  return false;
68  }
69  }
70 
71  return true;
72 }
73 
74 bool DirectorRepository::updateMeta(INvStorage& storage, const IMetadataFetcher& fetcher) {
75  // Uptane step 2 (download time) is not implemented yet.
76  // Uptane step 3 (download metadata)
77 
78  // reset director repo to initial state before starting UPTANE iteration
79  resetMeta();
80 
81  if (!updateRoot(storage, fetcher, RepositoryType::Director())) {
82  return false;
83  }
84 
85  // Not supported: 3. Download and check the Timestamp metadata file from the Director repository, following the
86  // procedure in Section 5.4.4.4. Not supported: 4. Download and check the Snapshot metadata file from the Director
87  // repository, following the procedure in Section 5.4.4.5.
88 
89  // Update Director Targets Metadata
90  {
91  std::string director_targets;
92 
93  if (!fetcher.fetchLatestRole(&director_targets, kMaxDirectorTargetsSize, RepositoryType::Director(),
94  Role::Targets())) {
95  return false;
96  }
97  int remote_version = extractVersionUntrusted(director_targets);
98 
99  int local_version;
100  std::string director_targets_stored;
101  if (storage.loadNonRoot(&director_targets_stored, RepositoryType::Director(), Role::Targets())) {
102  local_version = extractVersionUntrusted(director_targets_stored);
103  if (!verifyTargets(director_targets_stored)) {
104  LOG_WARNING << "Unable to verify stored director targets metadata.";
105  }
106  } else {
107  local_version = -1;
108  }
109 
110  // Not supported: If the ECU performing the verification is the Primary ECU, it SHOULD also ensure that the Targets
111  // metadata from the Director repository doesn’t contain any ECU identifiers for ECUs not actually present in the
112  // vehicle.
113 
114  // Not supported: The followin steps of the Director's target metadata verification are missing in
115  // DirectorRepository::updateMeta()
116  // 6. If checking Targets metadata from the Director repository, verify that there are no delegations.
117  // 7. If checking Targets metadata from the Director repository, check that no ECU identifier is represented more
118  // than once.
119  // TODO: https://saeljira.it.here.com/browse/OTA-4118
120  if (!verifyTargets(director_targets)) {
121  return false;
122  }
123 
124  if (local_version > remote_version) {
125  return false;
126  } else if (local_version < remote_version && !usePreviousTargets()) {
127  storage.storeNonRoot(director_targets, RepositoryType::Director(), Role::Targets());
128  }
129 
130  if (targetsExpired()) {
131  last_exception = Uptane::ExpiredMetadata(type.toString(), Role::Targets().ToString());
132  return false;
133  }
134  }
135 
136  return true;
137 }
138 
139 void DirectorRepository::dropTargets(INvStorage& storage) {
140  storage.clearNonRootMeta(RepositoryType::Director());
141  resetMeta();
142 }
143 
144 bool DirectorRepository::matchTargetsWithImageTargets(const Uptane::Targets& image_targets) const {
145  // step 10 of https://uptane.github.io/papers/ieee-isto-6100.1.0.0.uptane-standard.html#rfc.section.5.4.4.2
146  // TBD: no delegation support, consider reusing of findTargetInDelegationTree()
147  // that needs to be moved into a common place to be resued by Primary and Secondary
148  const auto& image_target_array = image_targets.targets;
149  const auto& director_target_array = targets.targets;
150 
151  for (const auto& director_target : director_target_array) {
152  auto found_it = std::find_if(
153  image_target_array.begin(), image_target_array.end(),
154  [&director_target](const Target& image_target) { return director_target.MatchTarget(image_target); });
155 
156  if (found_it == image_target_array.end()) {
157  return false;
158  }
159  }
160 
161  return true;
162 }
163 
164 } // namespace Uptane
Uptane::ExpiredMetadata
Definition: exceptions.h:60
Uptane::Targets
Definition: tuf.h:439
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