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(
const 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);
236 kNeedCompletion = 21,
246 : num_code(in_num_code), text_code(std::move(text_code_in)) {}
248 bool operator==(
const ResultCode &rhs)
const {
return num_code == rhs.num_code && toString() == rhs.toString(); }
249 bool operator!=(
const ResultCode &rhs)
const {
return !(*
this == rhs); }
250 friend std::ostream &operator<<(std::ostream &os,
const ResultCode &result_code);
253 std::string text_code;
259 std::string toString()
const {
260 if (text_code !=
"") {
264 return std::string(string_repr.at(num_code));
268 std::string toRepr()
const;
269 static ResultCode fromRepr(
const std::string &repr);
272 static const std::map<Numeric, const char *> string_repr;
275 std::ostream &operator<<(std::ostream &os,
const ResultCode &result_code);
280 : success(result_code_in.num_code == ResultCode::Numeric::kOk ||
282 result_code(std::move(result_code_in)),
283 description(std::move(description_in)) {}
285 : success(success_in), result_code(std::move(result_code_in)), description(std::move(description_in)) {}
287 Json::Value toJson()
const;
288 bool isSuccess()
const {
return success; };
289 bool needCompletion()
const {
return result_code == ResultCode::Numeric::kNeedCompletion; }
292 ResultCode result_code{ResultCode::Numeric::kOk};
293 std::string description;
300 class RepositoryType;
304 using MetaBundle = std::unordered_map<std::pair<RepositoryType, Role>, std::string, MetaPairHash>;
309 : name(std::move(name_in)), len(len_in), hash(std::move(hash_in)) {}
318 static const int kMinLength = 0;
319 static const int kMaxLength = 200;
326 if (kMaxLength < hwid.length()) {
327 throw std::out_of_range(
"Hardware Identifier too long");
331 std::string ToString()
const {
return hwid_; }
344 std::ostream &operator<<(std::ostream &os, const HardwareIdentifier &hwid);
349 static const int kMinLength = 1;
350 static const int kMaxLength = 64;
352 static EcuSerial Unknown() { return EcuSerial("Unknown"); }
353 explicit EcuSerial(const std::string &ecu_serial) : ecu_serial_(ecu_serial) {
354 if (ecu_serial.length() < kMinLength) {
355 throw std::out_of_range("ECU serial identifier is too short");
357 if (kMaxLength < ecu_serial.length()) {
358 throw std::out_of_range("ECU serial identifier is too long");
362 std::string ToString() const { return ecu_serial_; }
364 bool operator==(const EcuSerial &rhs) const { return ecu_serial_ == rhs.ecu_serial_; }
365 bool operator!=(const EcuSerial &rhs) const { return !(*this == rhs); }
367 bool operator<(const EcuSerial &rhs) const { return ecu_serial_ < rhs.ecu_serial_; }
368 friend std::ostream &operator<<(std::ostream &os, const EcuSerial &ecu_serial);
369 friend struct std::hash<Uptane::EcuSerial>;
372 std::string ecu_serial_;
375 std::ostream &operator<<(std::ostream &os, const EcuSerial &ecu_serial);
377 using EcuMap = std::map<EcuSerial, HardwareIdentifier>;
382 Target(std::string filename, const Json::Value &content);
385 Target(std::string filename, EcuMap ecus, std::vector<Hash> hashes, uint64_t length, std::string correlation_id = "");
387 static Target Unknown();
389 const EcuMap &ecus() const { return ecus_; }
390 std::string filename() const { return filename_; }
391 std::string sha256Hash() const;
392 std::string sha512Hash() const;
393 const std::vector<Hash> &hashes() const { return hashes_; }
394 const std::vector<HardwareIdentifier> &hardwareIds() const { return hwids_; }
395 std::string custom_version() const;
396 Json::Value custom_data() const { return custom_; }
397 void updateCustom(Json::Value &custom) { custom_ = custom; }
398 std::string correlation_id() const { return correlation_id_; }
399 void setCorrelationId(std::string correlation_id) { correlation_id_ = std::move(correlation_id); }
400 uint64_t length() const { return length_; }
401 bool IsValid() const { return valid; }
402 std::string uri() const { return uri_; }
403 void setUri(std::string uri) { uri_ = std::move(uri); }
404 bool MatchHash(const Hash &hash) const;
406 void InsertEcu(const std::pair<EcuSerial, HardwareIdentifier> &pair) { ecus_.insert(pair); }
408 bool IsForEcu(const EcuSerial &ecuIdentifier) const {
409 return (std::find_if(ecus_.cbegin(), ecus_.cend(),
410 [&ecuIdentifier](const std::pair<EcuSerial, HardwareIdentifier> &pair) {
411 return pair.first == ecuIdentifier;
421 bool IsOstree() const;
422 std::string type() const { return type_; }
425 bool operator==(const Target &t2) = delete;
426 bool MatchTarget(const Target &t2) const;
427 Json::Value toDebugJson() const;
428 friend std::ostream &operator<<(std::ostream &os, const Target &t);
429 InstalledImageInfo getTargetImageInfo() const { return {filename(), length(), sha256Hash()}; }
433 std::string filename_;
436 std::vector<Hash> hashes_;
437 std::vector<HardwareIdentifier> hwids_;
440 std::string correlation_id_;
443 std::string hashString(Hash::Type type) const;
446 std::ostream &operator<<(std::ostream &os, const Target &t);
448 class Manifest : public Json::Value {
450 Manifest(const Json::Value &value = Json::Value()) : Json::Value(value) {}
453 std::string filepath() const;
454 Hash installedImageHash() const;
455 std::string signature() const;
456 std::string signedBody() const;
457 bool verifySignature(const PublicKey &pub_key) const;
462 struct SecondaryInfo {
463 SecondaryInfo() : serial(Uptane::EcuSerial::Unknown()), hw_id(Uptane::HardwareIdentifier::Unknown()) {}
464 SecondaryInfo(Uptane::EcuSerial serial_in, Uptane::HardwareIdentifier hw_id_in, std::string type_in,
465 PublicKey pub_key_in, std::string extra_in)
466 : serial(std::move(serial_in)),
467 hw_id(std::move(hw_id_in)),
468 type(std::move(type_in)),
469 pub_key(std::move(pub_key_in)),
470 extra(std::move(extra_in)) {}
472 Uptane::EcuSerial serial;
473 Uptane::HardwareIdentifier hw_id;