Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
uptanerepository.cc
1 #include "uptane/uptanerepository.h"
2 
3 #include <stdio.h>
4 
5 #include <openssl/bio.h>
6 #include <openssl/pem.h>
7 #include <openssl/x509.h>
8 #include <boost/algorithm/hex.hpp>
9 #include <boost/algorithm/string/replace.hpp>
10 #include <boost/algorithm/string/trim.hpp>
11 #include <utility>
12 
13 #include "bootstrap/bootstrap.h"
14 #include "crypto/crypto.h"
15 #include "crypto/openssl_compat.h"
16 #include "logging/logging.h"
17 #include "storage/invstorage.h"
18 #include "utilities/utils.h"
19 
20 namespace Uptane {
21 
22 bool RepositoryCommon::initRoot(const std::string& root_raw) {
23  try {
24  root = Root(type, Utils::parseJSON(root_raw)); // initialization and format check
25  root = Root(type, Utils::parseJSON(root_raw), root); // signature verification against itself
26  } catch (const std::exception& e) {
27  LOG_ERROR << "Loading initial root failed: " << e.what();
28  return false;
29  }
30  return true;
31 }
32 
33 bool RepositoryCommon::verifyRoot(const std::string& root_raw) {
34  try {
35  int prev_version = rootVersion();
36  // 5.4.4.3.2.3. Version N+1 of the Root metadata file MUST have been signed
37  // by the following: (1) a threshold of keys specified in the latest Root
38  // metadata file (version N), and (2) a threshold of keys specified in the
39  // new Root metadata file being validated (version N+1).
40  root = Root(type, Utils::parseJSON(root_raw), root); // double signature verification
41  // 5.4.4.3.2.4. The version number of the latest Root metadata file (version
42  // N) must be less than or equal to the version number of the new Root
43  // metadata file (version N+1). NOTE: we do not accept an equal version
44  // number. It must increment.
45  if (root.version() != prev_version + 1) {
46  LOG_ERROR << "Version in root metadata doesn't match the expected value";
47  return false;
48  }
49  } catch (const std::exception& e) {
50  LOG_ERROR << "Signature verification for root metadata failed: " << e.what();
51  return false;
52  }
53  return true;
54 }
55 
56 void RepositoryCommon::resetRoot() { root = Root(Root::Policy::kAcceptAll); }
57 
58 bool RepositoryCommon::updateRoot(INvStorage& storage, const IMetadataFetcher& fetcher,
59  const RepositoryType repo_type) {
60  // 5.4.4.3.1. Load the previous Root metadata file.
61  {
62  std::string root_raw;
63  if (storage.loadLatestRoot(&root_raw, repo_type)) {
64  if (!initRoot(root_raw)) {
65  return false;
66  }
67  } else {
68  // This block is a hack only required as long as we have to explicitly
69  // fetch this to make the Director recognize new devices as "online".
70  if (repo_type == RepositoryType::Director()) {
71  if (!fetcher.fetchLatestRole(&root_raw, kMaxRootSize, repo_type, Role::Root())) {
72  return false;
73  }
74  }
75 
76  if (!fetcher.fetchRole(&root_raw, kMaxRootSize, repo_type, Role::Root(), Version(1))) {
77  return false;
78  }
79  if (!initRoot(root_raw)) {
80  return false;
81  }
82  storage.storeRoot(root_raw, repo_type, Version(1));
83  }
84  }
85 
86  // 5.4.4.3.2. Update to the latest Root metadata file.
87  for (int version = rootVersion() + 1; version < kMaxRotations; ++version) {
88  // 5.4.4.3.2.2. Try downloading a new version N+1 of the Root metadata file.
89  std::string root_raw;
90  if (!fetcher.fetchRole(&root_raw, kMaxRootSize, repo_type, Role::Root(), Version(version))) {
91  break;
92  }
93 
94  if (!verifyRoot(root_raw)) {
95  return false;
96  }
97 
98  // 5.4.4.3.2.5. Set the latest Root metadata file to the new Root metadata
99  // file.
100  storage.storeRoot(root_raw, repo_type, Version(version));
101  storage.clearNonRootMeta(repo_type);
102  }
103 
104  // 5.4.4.3.3. Check that the current (or latest securely attested) time is
105  // lower than the expiration timestamp in the latest Root metadata file.
106  // (Checks for a freeze attack.)
107  return !rootExpired();
108 }
109 
110 } // namespace Uptane
Version
Definition: helpers.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