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  return false;
67  }
68  }
69 
70  return true;
71 }
72 
73 bool DirectorRepository::updateMeta(INvStorage& storage, const IMetadataFetcher& fetcher) {
74  // Uptane step 2 (download time) is not implemented yet.
75  // Uptane step 3 (download metadata)
76 
77  // reset director repo to initial state before starting UPTANE iteration
78  resetMeta();
79 
80  if (!updateRoot(storage, fetcher, RepositoryType::Director())) {
81  return false;
82  }
83 
84  // Not supported: 3. Download and check the Timestamp metadata file from the Director repository, following the
85  // procedure in Section 5.4.4.4. Not supported: 4. Download and check the Snapshot metadata file from the Director
86  // repository, following the procedure in Section 5.4.4.5.
87 
88  // Update Director Targets Metadata
89  {
90  std::string director_targets;
91 
92  if (!fetcher.fetchLatestRole(&director_targets, kMaxDirectorTargetsSize, RepositoryType::Director(),
93  Role::Targets())) {
94  return false;
95  }
96  int remote_version = extractVersionUntrusted(director_targets);
97 
98  int local_version;
99  std::string director_targets_stored;
100  if (storage.loadNonRoot(&director_targets_stored, RepositoryType::Director(), Role::Targets())) {
101  local_version = extractVersionUntrusted(director_targets_stored);
102  if (!verifyTargets(director_targets_stored)) {
103  LOG_WARNING << "Unable to verify stored director targets metadata.";
104  }
105  } else {
106  local_version = -1;
107  }
108 
109  // Not supported: If the ECU performing the verification is the Primary ECU, it SHOULD also ensure that the Targets
110  // metadata from the Director repository doesn’t contain any ECU identifiers for ECUs not actually present in the
111  // vehicle.
112 
113  // Not supported: The followin steps of the Director's target metadata verification are missing in
114  // DirectorRepository::updateMeta()
115  // 6. If checking Targets metadata from the Director repository, verify that there are no delegations.
116  // 7. If checking Targets metadata from the Director repository, check that no ECU identifier is represented more
117  // than once.
118  // TODO: https://saeljira.it.here.com/browse/OTA-4118
119  if (!verifyTargets(director_targets)) {
120  return false;
121  }
122 
123  if (local_version > remote_version) {
124  return false;
125  } else if (local_version < remote_version && !usePreviousTargets()) {
126  storage.storeNonRoot(director_targets, RepositoryType::Director(), Role::Targets());
127  }
128 
129  if (targetsExpired()) {
130  return false;
131  }
132  }
133 
134  return true;
135 }
136 
137 void DirectorRepository::dropTargets(INvStorage& storage) {
138  storage.clearNonRootMeta(RepositoryType::Director());
139  resetMeta();
140 }
141 
142 bool DirectorRepository::matchTargetsWithImageTargets(const Uptane::Targets& image_targets) const {
143  // step 10 of https://uptane.github.io/papers/ieee-isto-6100.1.0.0.uptane-standard.html#rfc.section.5.4.4.2
144  // TBD: no delegation support, consider reusing of findTargetInDelegationTree()
145  // that needs to be moved into a common place to be resued by Primary and Secondary
146  const auto& image_target_array = image_targets.targets;
147  const auto& director_target_array = targets.targets;
148 
149  for (const auto& director_target : director_target_array) {
150  auto found_it = std::find_if(
151  image_target_array.begin(), image_target_array.end(),
152  [&director_target](const Target& image_target) { return director_target.MatchTarget(image_target); });
153 
154  if (found_it == image_target_array.end()) {
155  return false;
156  }
157  }
158 
159  return true;
160 }
161 
162 } // namespace Uptane
Uptane::Targets
Definition: tuf.h:437
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:109