5 Targets getTrustedDelegation(
const Role &delegate_role,
const Targets &parent_targets,
6 const ImageRepository &image_repo,
INvStorage &storage, Fetcher &fetcher,
8 std::string delegation_meta;
9 auto version_in_snapshot = image_repo.getRoleVersion(delegate_role);
11 if (storage.loadDelegation(&delegation_meta, delegate_role)) {
12 auto version = extractVersionUntrusted(delegation_meta);
14 if (version > version_in_snapshot) {
15 throw SecurityException(
"image",
"Rollback attempt on delegated targets");
16 }
else if (version < version_in_snapshot) {
17 delegation_meta.clear();
18 storage.deleteDelegation(delegate_role);
22 bool delegation_remote = delegation_meta.empty();
23 if (delegation_remote) {
29 fetcher.fetchLatestRole(&delegation_meta, Uptane::kMaxImageTargetsSize, RepositoryType::Image(), delegate_role);
30 }
catch (
const std::exception &e) {
31 LOG_ERROR <<
"Fetch role error: " << e.what();
37 image_repo.verifyRoleHashes(delegation_meta, delegate_role,
false);
38 }
catch (
const std::exception &e) {
39 LOG_ERROR <<
"Role hashes error: " << e.what();
43 auto delegation = ImageRepository::verifyDelegation(delegation_meta, delegate_role, parent_targets);
44 if (delegation ==
nullptr) {
45 throw SecurityException(
"image",
"Delegation verification failed");
48 if (delegation_remote) {
49 if (delegation->version() != version_in_snapshot) {
50 throw VersionMismatch(
"image", delegate_role.ToString());
52 storage.storeDelegation(delegation_meta, delegate_role);
58 LazyTargetsList::DelegationIterator::DelegationIterator(
const ImageRepository &repo,
59 std::shared_ptr<INvStorage> storage,
60 std::shared_ptr<Fetcher> fetcher,
bool is_end)
61 : repo_{repo}, storage_{std::move(storage)}, fetcher_{std::move(fetcher)}, is_end_{is_end} {
62 tree_ = std::make_shared<DelegatedTargetTreeNode>();
63 tree_node_ = tree_.get();
65 tree_node_->role = Role::Targets();
66 cur_targets_ = repo_.getTargets();
69 void LazyTargetsList::DelegationIterator::renewTargetsData() {
70 auto role = tree_node_->role;
72 if (role == Role::Targets()) {
73 cur_targets_ = repo_.getTargets();
76 std::stack<std::vector<std::shared_ptr<DelegatedTargetTreeNode>>::size_type> indices;
77 auto *node = tree_node_->parent;
78 while (node->parent !=
nullptr) {
79 indices.push(node->parent_idx);
83 auto parent_targets = repo_.getTargets();
84 while (!indices.empty()) {
85 auto idx = indices.top();
88 auto fetched_role = Role(parent_targets->delegated_role_names_[idx],
true);
89 parent_targets = std::make_shared<const Targets>(
90 getTrustedDelegation(fetched_role, *parent_targets, repo_, *storage_, *fetcher_,
false));
93 std::make_shared<Targets>(getTrustedDelegation(role, *parent_targets, repo_, *storage_, *fetcher_,
false));
97 bool LazyTargetsList::DelegationIterator::operator==(
const LazyTargetsList::DelegationIterator &other)
const {
98 if (is_end_ && other.is_end_) {
102 return is_end_ == other.is_end_ && tree_node_->role == other.tree_node_->role && target_idx_ == other.target_idx_;
105 const Target &LazyTargetsList::DelegationIterator::operator*() {
107 throw std::runtime_error(
"Inconsistent delegation iterator");
114 if (!cur_targets_ || target_idx_ >= cur_targets_->targets.size()) {
115 throw std::runtime_error(
"Inconsistent delegation iterator");
118 return cur_targets_->targets[target_idx_];
121 LazyTargetsList::DelegationIterator LazyTargetsList::DelegationIterator::operator++() {
131 if (target_idx_ + 1 < cur_targets_->targets.size()) {
137 if (terminating_ || level_ >= kDelegationsMaxDepth) {
144 if (cur_targets_->delegated_role_names_.size() != tree_node_->children.size()) {
145 tree_node_->children.clear();
147 for (std::vector<std::shared_ptr<DelegatedTargetTreeNode>>::size_type i = 0;
148 i < cur_targets_->delegated_role_names_.size(); ++i) {
149 auto new_node = std::make_shared<DelegatedTargetTreeNode>();
151 new_node->role = Role(cur_targets_->delegated_role_names_[i],
true);
152 new_node->parent = tree_node_;
153 new_node->parent_idx = i;
155 tree_node_->children.push_back(new_node);
159 if (children_idx_ < tree_node_->children.size()) {
160 auto *new_tree_node = tree_node_->children[children_idx_].get();
165 auto terminating_it = cur_targets_->terminating_role_.find(new_tree_node->role);
166 if (terminating_it == cur_targets_->terminating_role_.end()) {
167 throw std::runtime_error(
"Inconsistent delegation tree");
169 terminating_ = terminating_it->second;
171 cur_targets_.reset();
172 tree_node_ = new_tree_node;
177 if (tree_node_->parent !=
nullptr) {
178 auto *new_tree_node = tree_node_->parent;
179 children_idx_ = tree_node_->parent_idx + 1;
181 terminating_ =
false;
183 cur_targets_.reset();
184 tree_node_ = new_tree_node;
186 target_idx_ = cur_targets_->targets.size();