1 #include "image_repo.h"
3 void ImageRepo::addImage(
const std::string &name, Json::Value &target,
const std::string &hardware_id,
5 boost::filesystem::path repo_dir(path_ / ImageRepo::dir);
7 boost::filesystem::path targets_path =
8 delegation ? ((repo_dir /
"delegations") / delegation.name).string() +
".json" : repo_dir /
"targets.json";
9 Json::Value targets = Utils::parseJSONFile(targets_path)[
"signed"];
11 target[
"custom"][
"hardwareIds"][0] = hardware_id;
12 targets[
"targets"][name] = target;
13 targets[
"version"] = (targets[
"version"].asUInt()) + 1;
15 auto role = delegation ?
Uptane::Role(delegation.name,
true) :
Uptane::Role::Targets();
16 std::string signed_targets = Utils::jsonToCanonicalStr(signTuf(role, targets));
17 Utils::writeFile(targets_path, signed_targets);
21 void ImageRepo::addBinaryImage(
const boost::filesystem::path &image_path,
const boost::filesystem::path &targetname,
22 const std::string &hardware_id,
const std::string &url,
const Delegation &delegation) {
23 boost::filesystem::path repo_dir(path_ / ImageRepo::dir);
24 boost::filesystem::path targets_path = repo_dir /
"targets";
26 auto targetname_dir = targetname.parent_path();
27 boost::filesystem::create_directories(targets_path / targetname_dir);
28 boost::filesystem::copy_file(image_path, targets_path / targetname_dir / image_path.filename(),
29 boost::filesystem::copy_option::overwrite_if_exists);
31 std::string image = Utils::readFile(image_path);
34 target[
"length"] = Json::UInt64(image.size());
35 target[
"hashes"][
"sha256"] = boost::algorithm::to_lower_copy(boost::algorithm::hex(Crypto::sha256digest(image)));
36 target[
"hashes"][
"sha512"] = boost::algorithm::to_lower_copy(boost::algorithm::hex(Crypto::sha512digest(image)));
37 target[
"custom"][
"targetFormat"] =
"BINARY";
39 target[
"custom"][
"uri"] = url;
41 addImage(targetname.string(), target, hardware_id, delegation);
44 void ImageRepo::addCustomImage(
const std::string &name,
const Hash &hash,
const uint64_t length,
45 const std::string &hardware_id,
const std::string &url,
const Delegation &delegation,
46 const Json::Value &custom) {
48 target[
"length"] = Json::UInt(length);
49 if (hash.type() == Hash::Type::kSha256) {
50 target[
"hashes"][
"sha256"] = hash.HashString();
51 }
else if (hash.type() == Hash::Type::kSha512) {
52 target[
"hashes"][
"sha512"] = hash.HashString();
54 target[
"custom"] = custom;
56 target[
"custom"][
"uri"] = url;
58 addImage(name, target, hardware_id, delegation);
62 bool terminating, KeyType key_type) {
63 if (keys_.count(name) != 0) {
64 throw std::runtime_error(
"Delegation with the same name already exist.");
66 if (Uptane::Role::IsReserved(name.ToString())) {
67 throw std::runtime_error(
"Delegation name " + name.ToString() +
" is reserved.");
70 boost::filesystem::path repo_dir(path_ / ImageRepo::dir);
72 boost::filesystem::path parent_path(repo_dir);
73 if (parent_role.IsDelegation()) {
74 parent_path = parent_path /=
"delegations";
76 parent_path = parent_path /= (parent_role.ToString() +
".json");
78 if (!boost::filesystem::exists(parent_path)) {
79 throw std::runtime_error(
"Delegation role " + parent_role.ToString() +
" does not exist.");
82 generateKeyPair(key_type, name);
84 delegate[
"_type"] =
"Targets";
85 delegate[
"expires"] = expiration_time_;
86 delegate[
"version"] = 1;
87 delegate[
"targets"] = Json::objectValue;
89 std::string delegate_signed = Utils::jsonToCanonicalStr(signTuf(name, delegate));
90 Utils::writeFile((repo_dir /
"delegations" / name.ToString()).string() +
".json", delegate_signed);
92 Json::Value parent_notsigned = Utils::parseJSONFile(parent_path)[
"signed"];
94 auto keypair = keys_[name];
95 parent_notsigned[
"delegations"][
"keys"][keypair.public_key.KeyId()] = keypair.public_key.ToUptane();
97 role[
"name"] = name.ToString();
98 role[
"keyids"].append(keypair.public_key.KeyId());
99 role[
"paths"].append(path);
100 role[
"threshold"] = 1;
101 role[
"terminating"] = terminating;
102 parent_notsigned[
"delegations"][
"roles"].append(role);
103 parent_notsigned[
"version"] = (parent_notsigned[
"version"].asUInt()) + 1;
105 std::string signed_parent = Utils::jsonToCanonicalStr(signTuf(parent_role, parent_notsigned));
106 Utils::writeFile(parent_path, signed_parent);
111 boost::filesystem::path repo_dir(path_ / ImageRepo::dir);
112 if (parent_name.IsDelegation()) {
113 repo_dir = repo_dir /
"delegations";
115 Json::Value targets = Utils::parseJSONFile(repo_dir / (parent_name.ToString() +
".json"))[
"signed"];
117 auto keypair = keys_[name];
118 targets[
"delegations"][
"keys"].removeMember(
119 keypair.public_key.KeyId());
120 Json::Value new_roles(Json::arrayValue);
121 for (
const auto &role : targets[
"delegations"][
"roles"]) {
122 auto delegated_name = role[
"name"].asString();
123 if (delegated_name != name.ToString()) {
124 new_roles.append(role);
125 removeDelegationRecursive(name,
Uptane::Role(delegated_name,
true));
128 targets[
"delegations"][
"roles"] = new_roles;
129 targets[
"version"] = (targets[
"version"].asUInt()) + 1;
130 Utils::writeFile(repo_dir / (parent_name.ToString() +
".json"),
131 Utils::jsonToCanonicalStr(signTuf(parent_name, targets)));
134 void ImageRepo::revokeDelegation(
const Uptane::Role &name) {
135 if (keys_.count(name) == 0) {
136 throw std::runtime_error(
"Delegation does not exist.");
138 if (Uptane::Role::IsReserved(name.ToString())) {
139 throw std::runtime_error(
"Delegation name " + name.ToString() +
" is reserved.");
142 boost::filesystem::path keys_dir = path_ / (
"keys/image/" + name.ToString());
143 boost::filesystem::remove_all(keys_dir);
145 boost::filesystem::path repo_dir(path_ / ImageRepo::dir);
147 boost::filesystem::remove(repo_dir /
"delegations" / (name.ToString() +
".json"));
149 removeDelegationRecursive(name, Uptane::Role::Targets());
153 std::vector<std::string> ImageRepo::getDelegationTargets(
const Uptane::Role &name) {
154 std::vector<std::string>
result;
155 boost::filesystem::path repo_dir(path_ / ImageRepo::dir);
156 auto targets = Utils::parseJSONFile((repo_dir /
"delegations") / (name.ToString() +
".json"))[
"signed"][
"targets"];
157 for (
auto it = targets.begin(); it != targets.end(); ++it) {
158 result.push_back(it.key().asString());