2 #include <netinet/tcp.h> 4 #include "asn1/asn1_message.h" 5 #include "der_encoder.h" 6 #include "ipuptanesecondary.h" 7 #include "logging/logging.h" 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 <<
"...";
18 if (con_sock.connect() == 0) {
19 LOG_INFO <<
"Connected to IP Secondary: " 20 <<
"(" << address <<
":" << port <<
")";
22 LOG_WARNING <<
"Failed to connect to a Secondary: " << std::strerror(errno);
26 return create(address, port, *con_sock);
29 Uptane::SecondaryInterface::Ptr IpUptaneSecondary::create(
const std::string& address,
unsigned short port,
int con_fd) {
31 req->present(AKIpUptaneMes_PR_getInfoReq);
33 auto m = req->getInfoReq();
35 auto resp = Asn1Rpc(req, con_fd);
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));
41 auto r = resp->getInfoResp();
45 std::string key = ToString(r->key);
46 auto type =
static_cast<KeyType
>(r->keyType);
49 LOG_INFO <<
"Got info from IP Secondary: " 50 <<
"hardware ID: " << hw_id <<
" serial: " << serial;
52 return std::make_shared<IpUptaneSecondary>(address, port, serial, hw_id, pub_key);
55 SecondaryInterface::Ptr IpUptaneSecondary::connectAndCheck(
const std::string& address,
unsigned short port,
62 auto sec = IpUptaneSecondary::connectAndCreate(address, port);
64 auto s = sec->getSerial();
66 LOG_ERROR <<
"Mismatch between Secondary serials " << s <<
" and " << serial;
69 auto h = sec->getHwId();
71 LOG_ERROR <<
"Mismatch between hardware IDs " << h <<
" and " << hw_id;
74 auto p = sec->getPublicKey();
75 if (pub_key.Type() == KeyType::kUnknown) {
76 LOG_INFO <<
"Secondary " << s <<
" do not have a known public key";
77 }
else if (p != pub_key) {
78 LOG_ERROR <<
"Mismatch between public keys " << p.Value() <<
" and " << pub_key.Value() <<
" for Secondary " 84 }
catch (std::exception& e) {
85 LOG_WARNING <<
"Could not connect to Secondary " << serial <<
" at " << address <<
":" << port
86 <<
" using previously known registration data";
89 return std::make_shared<IpUptaneSecondary>(address, port, std::move(serial), std::move(hw_id), std::move(pub_key));
92 IpUptaneSecondary::IpUptaneSecondary(
const std::string& address,
unsigned short port,
EcuSerial serial,
94 : addr_{address, port}, serial_{std::move(serial)}, hw_id_{std::move(hw_id)}, pub_key_{std::move(pub_key)} {}
96 bool IpUptaneSecondary::putMetadata(
const RawMetaPack& meta_pack) {
97 LOG_INFO <<
"Sending Uptane metadata to the Secondary";
99 req->present(AKIpUptaneMes_PR_putMetaReq);
101 auto m = req->putMetaReq();
102 m->image.present = image_PR_json;
103 SetString(&m->image.choice.json.root, meta_pack.image_root);
104 SetString(&m->image.choice.json.targets, meta_pack.image_targets);
105 SetString(&m->image.choice.json.snapshot, meta_pack.image_snapshot);
106 SetString(&m->image.choice.json.timestamp, meta_pack.image_timestamp);
108 m->director.present = director_PR_json;
109 SetString(&m->director.choice.json.root, meta_pack.director_root);
110 SetString(&m->director.choice.json.targets, meta_pack.director_targets);
112 auto resp = Asn1Rpc(req, getAddr());
114 if (resp->present() != AKIpUptaneMes_PR_putMetaResp) {
115 LOG_ERROR <<
"Failed to get response to sending manifest to Secondary";
119 auto r = resp->putMetaResp();
120 return r->result == AKInstallationResult_success;
123 bool IpUptaneSecondary::sendFirmware(
const std::string&
data) {
124 std::lock_guard<std::mutex> l(install_mutex);
125 LOG_INFO <<
"Sending firmware to the Secondary";
127 req->present(AKIpUptaneMes_PR_sendFirmwareReq);
129 auto m = req->sendFirmwareReq();
130 SetString(&m->firmware, data);
131 auto resp = Asn1Rpc(req, getAddr());
133 if (resp->present() != AKIpUptaneMes_PR_sendFirmwareResp) {
134 LOG_ERROR <<
"Failed to get response to sending firmware to Secondary";
138 auto r = resp->sendFirmwareResp();
139 return r->result == AKInstallationResult_success;
143 LOG_INFO <<
"Invoking an installation of the target on the Secondary: " << target_name;
146 req->present(AKIpUptaneMes_PR_installReq);
149 auto req_mes = req->installReq();
150 SetString(&req_mes->hash, target_name);
152 auto resp = Asn1Rpc(req, getAddr());
155 if (resp->present() != AKIpUptaneMes_PR_installResp) {
156 LOG_ERROR <<
"Failed to get response to an installation request to Secondary";
161 auto r = resp->installResp();
166 Manifest IpUptaneSecondary::getManifest()
const {
167 LOG_DEBUG <<
"Getting the manifest from Secondary with serial " << getSerial();
170 req->present(AKIpUptaneMes_PR_manifestReq);
172 auto resp = Asn1Rpc(req, getAddr());
174 if (resp->present() != AKIpUptaneMes_PR_manifestResp) {
175 LOG_ERROR <<
"Failed to get a response to a get manifest request to secondary";
176 return Json::Value();
178 auto r = resp->manifestResp();
180 if (r->manifest.present != manifest_PR_json) {
181 LOG_ERROR <<
"Manifest wasn't in json format";
182 return Json::Value();
184 std::string manifest = ToString(r->manifest.choice.json);
185 return Utils::parseJSON(manifest);
188 bool IpUptaneSecondary::ping()
const {
190 req->present(AKIpUptaneMes_PR_getInfoReq);
192 auto m = req->getInfoReq();
194 auto resp = Asn1Rpc(req, getAddr());
196 return resp->present() == AKIpUptaneMes_PR_getInfoResp;
static Asn1Message::Ptr Empty()
Create a new Asn1Message, in order to fill it with data and send it.
SWM Internal integrity error.
Base data types that are used in The Update Framework (TUF), part of Uptane.