Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
ipuptanesecondary.cc
1 #include <arpa/inet.h>
2 #include <netinet/tcp.h>
3 
4 #include "asn1/asn1_message.h"
5 #include "der_encoder.h"
6 #include "ipuptanesecondary.h"
7 #include "logging/logging.h"
8 
9 #include <memory>
10 
11 namespace Uptane {
12 
13 Uptane::SecondaryInterface::Ptr IpUptaneSecondary::connectAndCreate(const std::string& address, unsigned short port) {
14  LOG_INFO << "Connecting to and getting info about IP Secondary: " << address << ":" << port << "...";
15 
16  ConnectionSocket con_sock{address, port};
17 
18  if (con_sock.connect() != 0) {
19  LOG_ERROR << "Failed to connect to a secondary: " << std::strerror(errno);
20  return std::shared_ptr<Uptane::SecondaryInterface>();
21  }
22 
23  LOG_INFO << "Connected to IP Secondary: "
24  << "(" << address << ":" << port << ")";
25 
26  return create(address, port, *con_sock);
27 }
28 
29 Uptane::SecondaryInterface::Ptr IpUptaneSecondary::create(const std::string& address, unsigned short port, int con_fd) {
30  Asn1Message::Ptr req(Asn1Message::Empty());
31  req->present(AKIpUptaneMes_PR_getInfoReq);
32 
33  auto m = req->getInfoReq();
34 
35  auto resp = Asn1Rpc(req, con_fd);
36 
37  if (resp->present() != AKIpUptaneMes_PR_getInfoResp) {
38  LOG_ERROR << "Failed to get info response message from secondary";
39  throw std::runtime_error("Failed to obtain information about a secondary: " + address + std::to_string(port));
40  }
41  auto r = resp->getInfoResp();
42 
43  EcuSerial serial = EcuSerial(ToString(r->ecuSerial));
44  HardwareIdentifier hw_id = HardwareIdentifier(ToString(r->hwId));
45  std::string key = ToString(r->key);
46  auto type = static_cast<KeyType>(r->keyType);
47  PublicKey pub_key = PublicKey(key, type);
48 
49  LOG_INFO << "Got info on IP Secondary: "
50  << "hw-ID: " << hw_id << " serial: " << serial;
51 
52  return std::make_shared<IpUptaneSecondary>(address, port, serial, hw_id, pub_key);
53 }
54 
55 IpUptaneSecondary::IpUptaneSecondary(const std::string& address, unsigned short port, EcuSerial serial,
56  HardwareIdentifier hw_id, PublicKey pub_key)
57  : addr_{address, port}, serial_{std::move(serial)}, hw_id_{std::move(hw_id)}, pub_key_{std::move(pub_key)} {}
58 
59 bool IpUptaneSecondary::putMetadata(const RawMetaPack& meta_pack) {
60  LOG_INFO << "Sending Uptane metadata to the secondary";
61  Asn1Message::Ptr req(Asn1Message::Empty());
62  req->present(AKIpUptaneMes_PR_putMetaReq);
63 
64  auto m = req->putMetaReq();
65  m->image.present = image_PR_json;
66  SetString(&m->image.choice.json.root, meta_pack.image_root); // NOLINT
67  SetString(&m->image.choice.json.targets, meta_pack.image_targets); // NOLINT
68  SetString(&m->image.choice.json.snapshot, meta_pack.image_snapshot); // NOLINT
69  SetString(&m->image.choice.json.timestamp, meta_pack.image_timestamp); // NOLINT
70 
71  m->director.present = director_PR_json;
72  SetString(&m->director.choice.json.root, meta_pack.director_root); // NOLINT
73  SetString(&m->director.choice.json.targets, meta_pack.director_targets); // NOLINT
74 
75  auto resp = Asn1Rpc(req, getAddr());
76 
77  if (resp->present() != AKIpUptaneMes_PR_putMetaResp) {
78  LOG_ERROR << "Failed to get response to sending manifest to secondary";
79  return false;
80  }
81 
82  auto r = resp->putMetaResp();
83  return r->result == AKInstallationResult_success;
84 }
85 
86 bool IpUptaneSecondary::sendFirmware(const std::string& data) {
87  std::lock_guard<std::mutex> l(install_mutex);
88  LOG_INFO << "Sending firmware to the secondary";
89  Asn1Message::Ptr req(Asn1Message::Empty());
90  req->present(AKIpUptaneMes_PR_sendFirmwareReq);
91 
92  auto m = req->sendFirmwareReq();
93  SetString(&m->firmware, data);
94  auto resp = Asn1Rpc(req, getAddr());
95 
96  if (resp->present() != AKIpUptaneMes_PR_sendFirmwareResp) {
97  LOG_ERROR << "Failed to get response to sending firmware to secondary";
98  return false;
99  }
100 
101  auto r = resp->sendFirmwareResp();
102  return r->result == AKInstallationResult_success;
103 }
104 
105 data::ResultCode::Numeric IpUptaneSecondary::install(const std::string& target_name) {
106  LOG_INFO << "Invoking an installation of the target on the secondary: " << target_name;
107 
108  Asn1Message::Ptr req(Asn1Message::Empty());
109  req->present(AKIpUptaneMes_PR_installReq);
110 
111  // prepare request message
112  auto req_mes = req->installReq();
113  SetString(&req_mes->hash, target_name);
114  // send request and receive response, a request-response type of RPC
115  auto resp = Asn1Rpc(req, getAddr());
116 
117  // invalid type of an response message
118  if (resp->present() != AKIpUptaneMes_PR_installResp) {
119  LOG_ERROR << "Failed to get response to an installation request to secondary";
121  }
122 
123  // deserialize the response message
124  auto r = resp->installResp();
125 
126  return static_cast<data::ResultCode::Numeric>(r->result);
127 }
128 
129 Manifest IpUptaneSecondary::getManifest() const {
130  LOG_DEBUG << "Getting the manifest from secondary with serial " << getSerial();
131  Asn1Message::Ptr req(Asn1Message::Empty());
132 
133  req->present(AKIpUptaneMes_PR_manifestReq);
134 
135  auto resp = Asn1Rpc(req, getAddr());
136 
137  if (resp->present() != AKIpUptaneMes_PR_manifestResp) {
138  LOG_ERROR << "Failed to get public key response message from secondary";
139  return Json::Value();
140  }
141  auto r = resp->manifestResp();
142 
143  if (r->manifest.present != manifest_PR_json) {
144  LOG_ERROR << "Manifest wasn't in json format";
145  return Json::Value();
146  }
147  std::string manifest = ToString(r->manifest.choice.json); // NOLINT
148  return Utils::parseJSON(manifest);
149 }
150 } // namespace Uptane
Asn1Message::Empty
static Asn1Message::Ptr Empty()
Create a new Asn1Message, in order to fill it with data and send it.
Definition: asn1_message.h:46
ConnectionSocket
Definition: utils.h:145
data
General data structures.
Definition: types.cc:44
PublicKey
Definition: crypto.h:26
data::ResultCode::Numeric::kInternalError
SWM Internal integrity error.
data::ResultCode::Numeric
Numeric
Definition: types.h:125
Uptane
Base data types that are used in The Update Framework (TUF), part of UPTANE.
Definition: secondary_tcp_server.h:8