7 #include <unordered_map>
9 #include <boost/filesystem.hpp>
11 #include "json/json.h"
15 enum class ProvisionMode { kSharedCred = 0, kDeviceCred, kSharedCredReuse, kDefault };
16 std::ostream &operator<<(std::ostream &os, ProvisionMode mode);
18 enum class StorageType { kFileSystem = 0, kSqlite };
19 std::ostream &operator<<(std::ostream &os, StorageType stype);
33 BasedPath(boost::filesystem::path p) : p_(std::move(p)) {}
34 boost::filesystem::path get(
const boost::filesystem::path &base)
const;
35 bool empty()
const {
return p_.empty(); }
36 bool operator==(
const BasedPath &b)
const {
return p_ == b.p_; }
37 bool operator!=(
const BasedPath &b)
const {
return !(*
this == b); }
40 boost::filesystem::path p_;
48 kFirstKnown = kED25519,
52 kLastKnown = kRSA4096,
56 inline std::ostream &operator<<(std::ostream &os,
const KeyType kt) {
59 case KeyType::kRSA2048:
62 case KeyType::kRSA3072:
65 case KeyType::kRSA4096:
68 case KeyType::kED25519:
75 os <<
'"' << kt_str <<
'"';
79 inline std::istream &operator>>(std::istream &is, KeyType &kt) {
83 std::transform(kt_str.begin(), kt_str.end(), kt_str.begin(), ::toupper);
84 kt_str.erase(std::remove(kt_str.begin(), kt_str.end(),
'"'), kt_str.end());
86 if (kt_str ==
"RSA2048") {
87 kt = KeyType::kRSA2048;
88 }
else if (kt_str ==
"RSA3072") {
89 kt = KeyType::kRSA3072;
90 }
else if (kt_str ==
"RSA4096") {
91 kt = KeyType::kRSA4096;
92 }
else if (kt_str ==
"ED25519") {
93 kt = KeyType::kED25519;
95 kt = KeyType::kUnknown;
100 enum class CryptoSource { kFile = 0, kPkcs11 };
102 inline std::ostream &operator<<(std::ostream &os, CryptoSource cs) {
105 case CryptoSource::kFile:
108 case CryptoSource::kPkcs11:
115 os <<
'"' << cs_str <<
'"';
122 explicit PublicKey(
const boost::filesystem::path &path);
124 explicit PublicKey(Json::Value uptane_json);
126 PublicKey(
const std::string &value, KeyType type);
128 std::string Value()
const {
return value_; }
130 KeyType Type()
const {
return type_; }
134 bool VerifySignature(
const std::string &signature,
const std::string &message)
const;
141 std::string KeyId()
const;
142 bool operator==(
const PublicKey &rhs)
const;
144 bool operator!=(
const PublicKey &rhs)
const {
return !(*
this == rhs); }
151 KeyType type_{KeyType::kUnknown};
162 enum class Type { kSha256, kSha512, kUnknownAlgorithm };
164 static Hash generate(Type type,
const std::string &
data);
165 Hash(
const std::string &type,
const std::string &hash);
166 Hash(Type type,
const std::string &hash);
168 bool HaveAlgorithm()
const {
return type_ != Type::kUnknownAlgorithm; }
169 bool operator==(
const Hash &other)
const;
170 bool operator!=(
const Hash &other)
const {
return !operator==(other); }
171 static std::string TypeString(Type type);
172 std::string TypeString()
const;
174 std::string HashString()
const {
return hash_; }
175 friend std::ostream &operator<<(std::ostream &os,
const Hash &h);
177 static std::string encodeVector(
const std::vector<Hash> &hashes);
178 static std::vector<Hash> decodeVector(std::string hashes_str);
185 std::ostream &operator<<(std::ostream &os,
const Hash &h);
191 static struct tm CurrentTime();
196 bool IsExpiredAt(
const TimeStamp &now)
const;
197 bool IsValid()
const;
198 std::string ToString()
const {
return time_; }
199 bool operator<(
const TimeStamp &other)
const;
200 bool operator>(
const TimeStamp &other)
const;
201 friend std::ostream &operator<<(std::ostream &os,
const TimeStamp &t);
202 bool operator==(
const TimeStamp &rhs)
const {
return time_ == rhs.time_; }
214 std::ostream &operator<<(std::ostream &os,
const TimeStamp &t);
219 using UpdateRequestId = std::string;
223 Json::Value toJson()
const;
224 static Package fromJson(
const std::string & );
244 kNeedCompletion = 21,
254 : num_code(in_num_code), text_code(std::move(text_code_in)) {}
256 bool operator==(
const ResultCode &rhs)
const {
return num_code == rhs.num_code && toString() == rhs.toString(); }
257 bool operator!=(
const ResultCode &rhs)
const {
return !(*
this == rhs); }
258 friend std::ostream &operator<<(std::ostream &os,
const ResultCode &result_code);
261 std::string text_code;
267 std::string toString()
const {
268 if (text_code !=
"") {
272 return std::string(string_repr.at(num_code));
276 std::string toRepr()
const;
277 static ResultCode fromRepr(
const std::string &repr);
280 static const std::map<Numeric, const char *> string_repr;
283 std::ostream &operator<<(std::ostream &os,
const ResultCode &result_code);
288 : success(result_code_in.num_code == ResultCode::Numeric::kOk ||
290 result_code(std::move(result_code_in)),
291 description(std::move(description_in)) {}
293 : success(success_in), result_code(std::move(result_code_in)), description(std::move(description_in)) {}
295 Json::Value toJson()
const;
296 bool isSuccess()
const {
return success; };
297 bool needCompletion()
const {
return result_code == ResultCode::Numeric::kNeedCompletion; }
300 ResultCode result_code{ResultCode::Numeric::kOk};
301 std::string description;
308 class RepositoryType;
312 using MetaBundle = std::unordered_map<std::pair<RepositoryType, Role>, std::string, MetaPairHash>;
317 : name(std::move(name_in)), len(len_in), hash(std::move(hash_in)) {}
326 static const int kMinLength = 0;
327 static const int kMaxLength = 200;
334 if (kMaxLength < hwid.length()) {
335 throw std::out_of_range(
"Hardware Identifier too long");
339 std::string ToString()
const {
return hwid_; }
352 std::ostream &operator<<(std::ostream &os, const HardwareIdentifier &hwid);
357 static const int kMinLength = 1;
358 static const int kMaxLength = 64;
360 static EcuSerial Unknown() { return EcuSerial("Unknown"); }
361 explicit EcuSerial(const std::string &ecu_serial) : ecu_serial_(ecu_serial) {
362 if (ecu_serial.length() < kMinLength) {
363 throw std::out_of_range("ECU serial identifier is too short");
365 if (kMaxLength < ecu_serial.length()) {
366 throw std::out_of_range("ECU serial identifier is too long");
370 std::string ToString() const { return ecu_serial_; }
372 bool operator==(const EcuSerial &rhs) const { return ecu_serial_ == rhs.ecu_serial_; }
373 bool operator!=(const EcuSerial &rhs) const { return !(*this == rhs); }
375 bool operator<(const EcuSerial &rhs) const { return ecu_serial_ < rhs.ecu_serial_; }
376 friend std::ostream &operator<<(std::ostream &os, const EcuSerial &ecu_serial);
377 friend struct std::hash<Uptane::EcuSerial>;
380 std::string ecu_serial_;
383 std::ostream &operator<<(std::ostream &os, const EcuSerial &ecu_serial);
385 using EcuMap = std::map<EcuSerial, HardwareIdentifier>;
390 Target(std::string filename, const Json::Value &content);
393 Target(std::string filename, EcuMap ecus, std::vector<Hash> hashes, uint64_t length, std::string correlation_id = "");
395 static Target Unknown();
397 const EcuMap &ecus() const { return ecus_; }
398 std::string filename() const { return filename_; }
399 std::string sha256Hash() const;
400 std::string sha512Hash() const;
401 const std::vector<Hash> &hashes() const { return hashes_; }
402 const std::vector<HardwareIdentifier> &hardwareIds() const { return hwids_; }
403 std::string custom_version() const { return custom_["version"].asString(); }
404 Json::Value custom_data() const { return custom_; }
405 void updateCustom(Json::Value &custom) { custom_ = custom; }
406 std::string correlation_id() const { return correlation_id_; }
407 void setCorrelationId(std::string correlation_id) { correlation_id_ = std::move(correlation_id); }
408 uint64_t length() const { return length_; }
409 bool IsValid() const { return valid; }
410 std::string uri() const { return uri_; }
411 void setUri(std::string uri) { uri_ = std::move(uri); }
412 bool MatchHash(const Hash &hash) const;
414 void InsertEcu(const std::pair<EcuSerial, HardwareIdentifier> &pair) { ecus_.insert(pair); }
416 bool IsForEcu(const EcuSerial &ecuIdentifier) const {
417 return (std::find_if(ecus_.cbegin(), ecus_.cend(),
418 [&ecuIdentifier](const std::pair<EcuSerial, HardwareIdentifier> &pair) {
419 return pair.first == ecuIdentifier;
429 bool IsOstree() const;
430 std::string type() const { return type_; }
433 bool operator==(const Target &t2) = delete;
434 bool MatchTarget(const Target &t2) const;
435 Json::Value toDebugJson() const;
436 friend std::ostream &operator<<(std::ostream &os, const Target &t);
437 InstalledImageInfo getTargetImageInfo() const { return {filename(), length(), sha256Hash()}; }
441 std::string filename_;
444 std::vector<Hash> hashes_;
445 std::vector<HardwareIdentifier> hwids_;
448 std::string correlation_id_;
451 std::string hashString(Hash::Type type) const;
454 std::ostream &operator<<(std::ostream &os, const Target &t);
456 class Manifest : public Json::Value {
458 Manifest(const Json::Value &value = Json::Value()) : Json::Value(value) {}
461 std::string filepath() const;
462 Hash installedImageHash() const;
463 std::string signature() const;
464 std::string signedBody() const;
465 bool verifySignature(const PublicKey &pub_key) const;
470 struct SecondaryInfo {
471 SecondaryInfo() : serial(Uptane::EcuSerial::Unknown()), hw_id(Uptane::HardwareIdentifier::Unknown()) {}
472 SecondaryInfo(Uptane::EcuSerial serial_in, Uptane::HardwareIdentifier hw_id_in, std::string type_in,
473 PublicKey pub_key_in, std::string extra_in)
474 : serial(std::move(serial_in)),
475 hw_id(std::move(hw_id_in)),
476 type(std::move(type_in)),
477 pub_key(std::move(pub_key_in)),
478 extra(std::move(extra_in)) {}
480 Uptane::EcuSerial serial;
481 Uptane::HardwareIdentifier hw_id;