5 Targets getTrustedDelegation(
const Role &delegate_role,
const Targets &parent_targets,
6 const ImagesRepository &images_repo,
INvStorage &storage, Fetcher &fetcher,
8 std::string delegation_meta;
9 auto version_in_snapshot = images_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(
"images",
"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) {
28 if (!fetcher.fetchLatestRole(&delegation_meta, Uptane::kMaxImagesTargetsSize, RepositoryType::Image(),
34 if (!images_repo.verifyRoleHashes(delegation_meta, delegate_role)) {
38 auto delegation = ImagesRepository::verifyDelegation(delegation_meta, delegate_role, parent_targets);
39 if (delegation ==
nullptr) {
40 throw SecurityException(
"images",
"Delegation verification failed");
43 if (delegation_remote) {
44 if (delegation->version() != version_in_snapshot) {
45 throw VersionMismatch(
"images", delegate_role.ToString());
47 storage.storeDelegation(delegation_meta, delegate_role);
53 LazyTargetsList::DelegationIterator::DelegationIterator(
const ImagesRepository &repo,
54 std::shared_ptr<INvStorage> storage,
55 std::shared_ptr<Fetcher> fetcher,
bool is_end)
56 : repo_{repo}, storage_{std::move(storage)}, fetcher_{std::move(fetcher)}, is_end_{is_end} {
57 tree_ = std::make_shared<DelegatedTargetTreeNode>();
58 tree_node_ = tree_.get();
60 tree_node_->role = Role::Targets();
61 cur_targets_ = repo_.getTargets();
64 void LazyTargetsList::DelegationIterator::renewTargetsData() {
65 auto role = tree_node_->role;
67 if (role == Role::Targets()) {
68 cur_targets_ = repo_.getTargets();
71 std::stack<std::vector<std::shared_ptr<DelegatedTargetTreeNode>>::size_type> indices;
72 auto node = tree_node_->parent;
73 while (node->parent !=
nullptr) {
74 indices.push(node->parent_idx);
78 auto parent_targets = repo_.getTargets();
79 while (!indices.empty()) {
80 auto idx = indices.top();
83 auto fetched_role = Role(parent_targets->delegated_role_names_[idx],
true);
84 parent_targets = std::make_shared<const Targets>(
85 getTrustedDelegation(fetched_role, *parent_targets, repo_, *storage_, *fetcher_,
false));
88 std::make_shared<Targets>(getTrustedDelegation(role, *parent_targets, repo_, *storage_, *fetcher_,
false));
92 bool LazyTargetsList::DelegationIterator::operator==(
const LazyTargetsList::DelegationIterator &other)
const {
93 if (is_end_ && other.is_end_) {
97 return is_end_ == other.is_end_ && tree_node_->role == other.tree_node_->role && target_idx_ == other.target_idx_;
100 const Target &LazyTargetsList::DelegationIterator::operator*() {
102 throw std::runtime_error(
"Inconsistent delegation iterator");
109 if (!cur_targets_ || target_idx_ >= cur_targets_->targets.size()) {
110 throw std::runtime_error(
"Inconsistent delegation iterator");
113 return cur_targets_->targets[target_idx_];
116 LazyTargetsList::DelegationIterator LazyTargetsList::DelegationIterator::operator++() {
126 if (target_idx_ + 1 < cur_targets_->targets.size()) {
132 if (terminating_ || level_ >= kDelegationsMaxDepth) {
139 if (cur_targets_->delegated_role_names_.size() != tree_node_->children.size()) {
140 tree_node_->children.clear();
142 for (std::vector<std::shared_ptr<DelegatedTargetTreeNode>>::size_type i = 0;
143 i < cur_targets_->delegated_role_names_.size(); ++i) {
144 auto new_node = std::make_shared<DelegatedTargetTreeNode>();
146 new_node->role = Role(cur_targets_->delegated_role_names_[i],
true);
147 new_node->parent = tree_node_;
148 new_node->parent_idx = i;
150 tree_node_->children.push_back(new_node);
154 if (children_idx_ < tree_node_->children.size()) {
155 auto new_tree_node = tree_node_->children[children_idx_].get();
160 auto terminating_it = cur_targets_->terminating_role_.find(new_tree_node->role);
161 if (terminating_it == cur_targets_->terminating_role_.end()) {
162 throw std::runtime_error(
"Inconsistent delegation tree");
164 terminating_ = terminating_it->second;
166 cur_targets_.reset();
167 tree_node_ = new_tree_node;
172 if (tree_node_->parent !=
nullptr) {
173 auto new_tree_node = tree_node_->parent;
174 children_idx_ = tree_node_->parent_idx + 1;
176 terminating_ =
false;
178 cur_targets_.reset();
179 tree_node_ = new_tree_node;
181 target_idx_ = cur_targets_->targets.size();