1 #include "imagesrepository.h"
5 void ImagesRepository::resetMeta() {
9 timestamp = TimestampMeta();
12 bool ImagesRepository::verifyTimestamp(
const std::string& timestamp_raw) {
16 TimestampMeta(RepositoryType::Image(), Utils::parseJSON(timestamp_raw), std::make_shared<MetaWithKeys>(root));
17 }
catch (
const Exception& e) {
18 LOG_ERROR <<
"Signature verification for timestamp metadata failed";
25 bool ImagesRepository::fetchSnapshot(
INvStorage& storage,
const IMetadataFetcher& fetcher,
const int local_version) {
26 std::string images_snapshot;
27 const int64_t snapshot_size = (snapshotSize() > 0) ? snapshotSize() : kMaxSnapshotSize;
28 if (!fetcher.fetchLatestRole(&images_snapshot, snapshot_size, RepositoryType::Image(), Role::Snapshot())) {
31 const int remote_version = extractVersionUntrusted(images_snapshot);
38 if (!verifySnapshot(images_snapshot)) {
42 if (local_version > remote_version) {
44 }
else if (local_version < remote_version) {
45 storage.storeNonRoot(images_snapshot, RepositoryType::Image(), Role::Snapshot());
51 bool ImagesRepository::verifySnapshot(
const std::string& snapshot_raw) {
53 const std::string canonical = Utils::jsonToCanonicalStr(Utils::parseJSON(snapshot_raw));
54 bool hash_exists =
false;
55 for (
const auto& it : timestamp.snapshot_hashes()) {
57 case Hash::Type::kSha256:
58 if (Hash(Hash::Type::kSha256, boost::algorithm::hex(Crypto::sha256digest(canonical))) != it) {
59 LOG_ERROR <<
"Hash verification for snapshot metadata failed";
64 case Hash::Type::kSha512:
65 if (Hash(Hash::Type::kSha512, boost::algorithm::hex(Crypto::sha512digest(canonical))) != it) {
66 LOG_ERROR <<
"Hash verification for snapshot metadata failed";
76 LOG_ERROR <<
"No hash found for shapshot.json";
80 snapshot = Snapshot(RepositoryType::Image(), Utils::parseJSON(snapshot_raw), std::make_shared<MetaWithKeys>(root));
81 if (snapshot.version() != timestamp.snapshot_version()) {
84 }
catch (
const Exception& e) {
85 LOG_ERROR <<
"Signature verification for snapshot metadata failed";
92 bool ImagesRepository::fetchTargets(
INvStorage& storage,
const IMetadataFetcher& fetcher,
const int local_version) {
93 std::string images_targets;
94 const Role targets_role = Role::Targets();
96 auto targets_size = getRoleSize(Role::Targets());
97 if (targets_size <= 0) {
98 targets_size = kMaxImagesTargetsSize;
100 if (!fetcher.fetchLatestRole(&images_targets, targets_size, RepositoryType::Image(), targets_role)) {
103 const int remote_version = extractVersionUntrusted(images_targets);
105 if (!verifyTargets(images_targets)) {
109 if (local_version > remote_version) {
111 }
else if (local_version < remote_version) {
112 storage.storeNonRoot(images_targets, RepositoryType::Image(), targets_role);
118 bool ImagesRepository::verifyRoleHashes(
const std::string& role_data,
const Uptane::Role& role)
const {
119 const std::string canonical = Utils::jsonToCanonicalStr(Utils::parseJSON(role_data));
122 for (
const auto& it : snapshot.role_hashes(role)) {
124 case Hash::Type::kSha256:
125 if (Hash(Hash::Type::kSha256, boost::algorithm::hex(Crypto::sha256digest(canonical))) != it) {
126 LOG_ERROR <<
"Hash verification for " << role.ToString() <<
" metadata failed";
130 case Hash::Type::kSha512:
131 if (Hash(Hash::Type::kSha512, boost::algorithm::hex(Crypto::sha512digest(canonical))) != it) {
132 LOG_ERROR <<
"Hash verification for " << role.ToString() <<
" metadata failed";
144 int ImagesRepository::getRoleVersion(
const Uptane::Role& role)
const {
return snapshot.role_version(role); }
146 int64_t ImagesRepository::getRoleSize(
const Uptane::Role& role)
const {
return snapshot.role_size(role); }
148 bool ImagesRepository::verifyTargets(
const std::string& targets_raw) {
150 if (!verifyRoleHashes(targets_raw, Uptane::Role::Targets())) {
154 auto targets_json = Utils::parseJSON(targets_raw);
157 auto signer = std::make_shared<MetaWithKeys>(root);
158 targets = std::make_shared<Uptane::Targets>(
159 Targets(RepositoryType::Image(), Uptane::Role::Targets(), targets_json, signer));
161 if (targets->version() != snapshot.role_version(Uptane::Role::Targets())) {
164 }
catch (
const Exception& e) {
165 LOG_ERROR <<
"Signature verification for images targets metadata failed";
172 std::shared_ptr<Uptane::Targets> ImagesRepository::verifyDelegation(
const std::string& delegation_raw,
174 const Targets& parent_target) {
176 const Json::Value delegation_json = Utils::parseJSON(delegation_raw);
177 const std::string canonical = Utils::jsonToCanonicalStr(delegation_json);
180 auto signer = std::make_shared<MetaWithKeys>(parent_target);
181 return std::make_shared<Uptane::Targets>(Targets(RepositoryType::Image(), role, delegation_json, signer));
182 }
catch (
const Exception& e) {
183 LOG_ERROR <<
"Signature verification for images delegated targets metadata failed";
187 return std::shared_ptr<Uptane::Targets>(
nullptr);
190 bool ImagesRepository::updateMeta(
INvStorage& storage,
const IMetadataFetcher& fetcher) {
193 if (!updateRoot(storage, fetcher, RepositoryType::Image())) {
199 std::string images_timestamp;
201 if (!fetcher.fetchLatestRole(&images_timestamp, kMaxTimestampSize, RepositoryType::Image(), Role::Timestamp())) {
204 int remote_version = extractVersionUntrusted(images_timestamp);
207 std::string images_timestamp_stored;
208 if (storage.loadNonRoot(&images_timestamp_stored, RepositoryType::Image(), Role::Timestamp())) {
209 local_version = extractVersionUntrusted(images_timestamp_stored);
214 if (!verifyTimestamp(images_timestamp)) {
218 if (local_version > remote_version) {
220 }
else if (local_version < remote_version) {
221 storage.storeNonRoot(images_timestamp, RepositoryType::Image(), Role::Timestamp());
224 if (timestampExpired()) {
233 bool fetch_snapshot =
true;
235 std::string images_snapshot_stored;
236 if (storage.loadNonRoot(&images_snapshot_stored, RepositoryType::Image(), Role::Snapshot())) {
237 if (verifySnapshot(images_snapshot_stored)) {
238 fetch_snapshot =
false;
239 LOG_DEBUG <<
"Skipping Image repo Snapshot download; stored version is still current.";
241 local_version = snapshot.version();
247 if (fetch_snapshot) {
248 if (!fetchSnapshot(storage, fetcher, local_version)) {
253 if (snapshotExpired()) {
262 bool fetch_targets =
true;
263 int local_version = -1;
264 std::string images_targets_stored;
265 if (storage.loadNonRoot(&images_targets_stored, RepositoryType::Image(), Role::Targets())) {
266 if (verifyTargets(images_targets_stored)) {
267 fetch_targets =
false;
268 LOG_DEBUG <<
"Skipping Image repo Targets download; stored version is still current.";
271 local_version = targets->version();
277 if (!fetchTargets(storage, fetcher, local_version)) {
282 if (targetsExpired()) {
290 bool ImagesRepository::checkMetaOffline(
INvStorage& storage) {
294 std::string images_root;
295 if (!storage.loadLatestRoot(&images_root, RepositoryType::Image())) {
299 if (!initRoot(images_root)) {
310 std::string images_timestamp;
311 if (!storage.loadNonRoot(&images_timestamp, RepositoryType::Image(), Role::Timestamp())) {
315 if (!verifyTimestamp(images_timestamp)) {
319 if (timestampExpired()) {
326 std::string images_snapshot;
328 if (!storage.loadNonRoot(&images_snapshot, RepositoryType::Image(), Role::Snapshot())) {
332 if (!verifySnapshot(images_snapshot)) {
336 if (snapshotExpired()) {
343 std::string images_targets;
344 Role targets_role = Uptane::Role::Targets();
345 if (!storage.loadNonRoot(&images_targets, RepositoryType::Image(), targets_role)) {
349 if (!verifyTargets(images_targets)) {
353 if (targetsExpired()) {