1 #include <gtest/gtest.h>
6 #include <boost/filesystem.hpp>
8 #include "libaktualizr/config.h"
9 #include "logging/logging.h"
10 #include "test_utils.h"
11 #include "uptane_repo.h"
13 KeyType key_type = KeyType::kED25519;
14 std::string generate_repo_exec;
16 void check_repo(boost::filesystem::path repo_dir) {
17 Json::Value targets = Utils::parseJSONFile(repo_dir /
"targets.json")[
"signed"];
18 std::string signed_targets = Utils::readFile(repo_dir /
"targets.json");
20 Json::Value snapshot = Utils::parseJSONFile(repo_dir /
"snapshot.json")[
"signed"];
21 EXPECT_EQ(snapshot[
"meta"][
"targets.json"][
"version"].asUInt(), targets[
"version"].asUInt());
23 auto signed_snapshot = Utils::readFile(repo_dir /
"snapshot.json");
24 Json::Value timestamp = Utils::parseJSONFile(repo_dir /
"timestamp.json")[
"signed"];
25 EXPECT_EQ(timestamp[
"meta"][
"snapshot.json"][
"hashes"][
"sha256"].asString(),
26 boost::algorithm::to_lower_copy(boost::algorithm::hex(Crypto::sha256digest(signed_snapshot))));
27 EXPECT_EQ(timestamp[
"meta"][
"snapshot.json"][
"hashes"][
"sha512"].asString(),
28 boost::algorithm::to_lower_copy(boost::algorithm::hex(Crypto::sha512digest(signed_snapshot))));
29 EXPECT_EQ(timestamp[
"meta"][
"snapshot.json"][
"length"].asUInt(),
static_cast<Json::UInt
>(signed_snapshot.length()));
30 EXPECT_EQ(timestamp[
"meta"][
"snapshot.json"][
"version"].asUInt(), snapshot[
"version"].asUInt());
34 check_repo(temp_dir.Path() / ImageRepo::dir);
35 check_repo(temp_dir.Path() / DirectorRepo::dir);
40 TEST(uptane_generator, generate_repo) {
42 UptaneRepo repo(temp_dir.Path(),
"",
"correlation");
43 repo.generateRepo(key_type);
44 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() / DirectorRepo::dir /
"root.json"));
45 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() / DirectorRepo::dir /
"1.root.json"));
46 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() / DirectorRepo::dir /
"targets.json"));
47 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() / DirectorRepo::dir /
"timestamp.json"));
48 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() / ImageRepo::dir /
"root.json"));
49 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() / ImageRepo::dir /
"1.root.json"));
50 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() / ImageRepo::dir /
"targets.json"));
51 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() / ImageRepo::dir /
"timestamp.json"));
52 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() / DirectorRepo::dir /
"manifest"));
54 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() /
"keys/image/root/private.key"));
55 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() /
"keys/image/root/public.key"));
56 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() /
"keys/image/snapshot/private.key"));
57 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() /
"keys/image/snapshot/public.key"));
58 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() /
"keys/image/targets/private.key"));
59 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() /
"keys/image/targets/public.key"));
60 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() /
"keys/image/timestamp/private.key"));
61 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() /
"keys/image/timestamp/public.key"));
63 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() /
"keys/director/root/private.key"));
64 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() /
"keys/director/root/public.key"));
65 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() /
"keys/director/snapshot/private.key"));
66 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() /
"keys/director/snapshot/public.key"));
67 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() /
"keys/director/targets/private.key"));
68 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() /
"keys/director/targets/public.key"));
69 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() /
"keys/director/timestamp/private.key"));
70 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() /
"keys/director/timestamp/public.key"));
72 std::vector<std::string> keys;
73 std::function<void(
const boost::filesystem::path &path)> recursive_check;
74 recursive_check = [&keys, &recursive_check](
const boost::filesystem::path &path) {
75 for (
auto &p : boost::filesystem::directory_iterator(path)) {
76 if (p.status().type() == boost::filesystem::file_type::directory_file) {
77 recursive_check(p.path());
79 if (p.path().filename().string() ==
"key_type") {
82 std::string hash = Crypto::sha512digest(Utils::readFile(p.path()));
83 if (std::find(keys.begin(), keys.end(), hash) == keys.end()) {
86 FAIL() << p.path().string() <<
" is not unique";
91 recursive_check(temp_dir.Path() /
"keys");
93 Json::Value image_targets = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"targets.json");
94 EXPECT_EQ(image_targets[
"signed"][
"targets"].size(), 0);
95 Json::Value director_targets = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"targets.json");
96 EXPECT_EQ(director_targets[
"signed"][
"targets"].size(), 0);
97 EXPECT_EQ(director_targets[
"signed"][
"custom"][
"correlationId"],
"correlation");
104 TEST(uptane_generator, add_image) {
107 repo.generateRepo(key_type);
108 repo.addImage(temp_dir.Path() / DirectorRepo::dir /
"manifest", std::string(DirectorRepo::dir) +
"/manifest",
110 Json::Value image_targets = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"targets.json");
111 EXPECT_EQ(image_targets[
"signed"][
"targets"].size(), 1);
113 image_targets[
"signed"][
"targets"][std::string(DirectorRepo::dir) +
"/manifest"][
"custom"].isMember(
"uri"));
114 Json::Value director_targets = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"targets.json");
115 EXPECT_EQ(director_targets[
"signed"][
"targets"].size(), 0);
116 check_repo(temp_dir);
122 TEST(uptane_generator, copy_image) {
125 repo.generateRepo(key_type);
126 repo.addImage(temp_dir.Path() / DirectorRepo::dir /
"manifest",
"manifest",
"test-hw",
"", {});
127 repo.addTarget(
"manifest",
"test-hw",
"test-serial",
"");
129 Json::Value image_targets = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"targets.json");
130 EXPECT_EQ(image_targets[
"signed"][
"targets"].size(), 1);
131 EXPECT_FALSE(image_targets[
"signed"][
"targets"][
"manifest"][
"custom"].isMember(
"uri"));
132 Json::Value director_targets = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"targets.json");
133 EXPECT_EQ(director_targets[
"signed"][
"targets"].size(), 1);
134 EXPECT_FALSE(director_targets[
"signed"][
"targets"][
"manifest"][
"custom"].isMember(
"uri"));
135 check_repo(temp_dir);
141 TEST(uptane_generator, image_custom_url) {
144 repo.generateRepo(key_type);
145 repo.addImage(temp_dir.Path() / DirectorRepo::dir /
"manifest",
"manifest",
"test-hw",
"test-url", {});
146 repo.addTarget(
"manifest",
"test-hw",
"test-serial",
"");
148 Json::Value image_targets = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"targets.json");
149 EXPECT_EQ(image_targets[
"signed"][
"targets"].size(), 1);
150 EXPECT_EQ(image_targets[
"signed"][
"targets"][
"manifest"][
"custom"][
"uri"],
"test-url");
151 Json::Value director_targets = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"targets.json");
152 EXPECT_EQ(director_targets[
"signed"][
"targets"].size(), 1);
153 EXPECT_FALSE(director_targets[
"signed"][
"targets"][
"manifest"][
"custom"].isMember(
"uri"));
154 check_repo(temp_dir);
161 TEST(uptane_generator, both_custom_url) {
164 repo.generateRepo(key_type);
165 repo.addImage(temp_dir.Path() / DirectorRepo::dir /
"manifest",
"manifest",
"test-hw",
"test-url", {});
166 repo.addTarget(
"manifest",
"test-hw",
"test-serial",
"test-url2");
168 Json::Value image_targets = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"targets.json");
169 EXPECT_EQ(image_targets[
"signed"][
"targets"].size(), 1);
170 EXPECT_EQ(image_targets[
"signed"][
"targets"][
"manifest"][
"custom"][
"uri"],
"test-url");
171 Json::Value director_targets = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"targets.json");
172 EXPECT_EQ(director_targets[
"signed"][
"targets"].size(), 1);
173 EXPECT_EQ(director_targets[
"signed"][
"targets"][
"manifest"][
"custom"][
"uri"],
"test-url2");
174 check_repo(temp_dir);
181 TEST(uptane_generator, delegation) {
183 std::ostringstream keytype_stream;
184 keytype_stream << key_type;
185 std::string cmd = generate_repo_exec +
" generate " + temp_dir.Path().string() +
" --keytype " + keytype_stream.str();
187 int retval = Utils::shell(cmd, &output);
189 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n";
191 cmd = generate_repo_exec +
" adddelegation " + temp_dir.Path().string() +
" --keytype " + keytype_stream.str() +
192 " --dname test_delegate --dpattern 'tests/test_data/*.txt' --hwid primary_hw";
193 retval = Utils::shell(cmd, &output);
195 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n";
198 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() / ImageRepo::dir /
"delegations/test_delegate.json"));
199 auto targets = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"targets.json");
200 EXPECT_EQ(targets[
"signed"][
"delegations"][
"roles"][0][
"name"].asString(),
"test_delegate");
201 EXPECT_EQ(targets[
"signed"][
"delegations"][
"roles"][0][
"paths"][0].asString(),
"tests/test_data/*.txt");
203 cmd = generate_repo_exec +
" image " + temp_dir.Path().string() +
" --keytype " + keytype_stream.str() +
204 " --dname test_delegate --filename tests/test_data/firmware.txt --hwid primary_hw";
205 retval = Utils::shell(cmd, &output);
207 FAIL() <<
"'" << output <<
"' exited with error code " << retval <<
"\n";
210 auto test_delegate = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"delegations/test_delegate.json");
212 EXPECT_EQ(delegate_targets.targets.size(), 1);
213 EXPECT_EQ(delegate_targets.targets[0].filename(),
"tests/test_data/firmware.txt");
214 EXPECT_EQ(delegate_targets.targets[0].length(), 17);
215 EXPECT_EQ(delegate_targets.targets[0].sha256Hash(),
216 "d8e9caba8c1697fcbade1057f9c2488044192ff76bb64d4aba2c20e53dc33033");
218 cmd = generate_repo_exec +
" image " + temp_dir.Path().string() +
" --keytype " + keytype_stream.str() +
219 " --dname test_delegate --targetname tests/test_data/firmware2.txt --targetsha256 "
220 "d8e9caba8c1697fcbade1057f9c2488044192ff76bb64d4aba2c20e53dc33033 --targetlength 17 --hwid primary_hw";
221 retval = Utils::shell(cmd, &output);
223 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n";
226 auto test_delegate = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"delegations/test_delegate.json");
228 EXPECT_EQ(delegate_targets.targets.size(), 2);
229 EXPECT_EQ(delegate_targets.targets[1].filename(),
"tests/test_data/firmware2.txt");
230 EXPECT_EQ(delegate_targets.targets[1].length(), 17);
231 EXPECT_EQ(delegate_targets.targets[1].sha256Hash(),
232 "d8e9caba8c1697fcbade1057f9c2488044192ff76bb64d4aba2c20e53dc33033");
234 check_repo(temp_dir);
237 TEST(uptane_generator, delegation_revoke) {
239 std::ostringstream keytype_stream;
240 keytype_stream << key_type;
241 std::string cmd = generate_repo_exec +
" generate " + temp_dir.Path().string() +
" --keytype " + keytype_stream.str();
243 int retval = Utils::shell(cmd, &output);
245 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n";
247 cmd = generate_repo_exec +
" adddelegation " + temp_dir.Path().string() +
" --keytype " + keytype_stream.str();
248 cmd +=
" --dname test_delegate --dpattern 'tests/test_data/*.txt' ";
249 retval = Utils::shell(cmd, &output);
251 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n";
254 EXPECT_TRUE(boost::filesystem::exists(temp_dir.Path() / ImageRepo::dir /
"delegations/test_delegate.json"));
255 auto targets = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"targets.json");
256 EXPECT_EQ(targets[
"signed"][
"delegations"][
"roles"][0][
"name"].asString(),
"test_delegate");
257 EXPECT_EQ(targets[
"signed"][
"delegations"][
"roles"][0][
"paths"][0].asString(),
"tests/test_data/*.txt");
259 cmd = generate_repo_exec +
" image " + temp_dir.Path().string() +
" --keytype " + keytype_stream.str() +
260 " --dname test_delegate --filename tests/test_data/firmware.txt --hwid primary_hw";
261 retval = Utils::shell(cmd, &output);
263 FAIL() <<
"'" << output <<
"' exited with error code " << retval <<
"\n";
266 auto test_delegate = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"delegations/test_delegate.json");
268 EXPECT_EQ(delegate_targets.targets.size(), 1);
269 EXPECT_EQ(delegate_targets.targets[0].filename(),
"tests/test_data/firmware.txt");
270 EXPECT_EQ(delegate_targets.targets[0].length(), 17);
271 EXPECT_EQ(delegate_targets.targets[0].sha256Hash(),
272 "d8e9caba8c1697fcbade1057f9c2488044192ff76bb64d4aba2c20e53dc33033");
274 cmd = generate_repo_exec +
" image " + temp_dir.Path().string() +
" --keytype " + keytype_stream.str() +
275 " --dname test_delegate --targetname tests/test_data/firmware2.txt --targetsha256 "
276 "d8e9caba8c1697fcbade1057f9c2488044192ff76bb64d4aba2c20e53dc33033 --targetlength 17 --hwid primary_hw";
277 retval = Utils::shell(cmd, &output);
279 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n";
282 cmd = generate_repo_exec +
" addtarget " + temp_dir.Path().string() +
" --keytype " + keytype_stream.str() +
283 " --hwid primary_hw --serial CA:FE:A6:D2:84:9D --targetname tests/test_data/firmware.txt";
284 retval = Utils::shell(cmd, &output);
286 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n";
289 cmd = generate_repo_exec +
" signtargets " + temp_dir.Path().string() +
" --keytype " + keytype_stream.str();
290 retval = Utils::shell(cmd, &output);
292 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n";
295 auto test_delegate = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"delegations/test_delegate.json");
297 EXPECT_EQ(delegate_targets.targets.size(), 2);
298 EXPECT_EQ(delegate_targets.targets[1].filename(),
"tests/test_data/firmware2.txt");
299 EXPECT_EQ(delegate_targets.targets[1].length(), 17);
300 EXPECT_EQ(delegate_targets.targets[1].sha256Hash(),
301 "d8e9caba8c1697fcbade1057f9c2488044192ff76bb64d4aba2c20e53dc33033");
304 auto signed_targets = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"targets.json");
306 EXPECT_EQ(director_targets.targets.size(), 1);
307 EXPECT_EQ(director_targets.targets[0].filename(),
"tests/test_data/firmware.txt");
308 EXPECT_EQ(director_targets.targets[0].length(), 17);
309 EXPECT_EQ(director_targets.targets[0].sha256Hash(),
310 "d8e9caba8c1697fcbade1057f9c2488044192ff76bb64d4aba2c20e53dc33033");
312 check_repo(temp_dir);
314 cmd = generate_repo_exec +
" revokedelegation " + temp_dir.Path().string() +
" --keytype " + keytype_stream.str() +
315 " --dname test_delegate";
316 retval = Utils::shell(cmd, &output);
318 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n";
320 EXPECT_FALSE(boost::filesystem::exists(temp_dir.Path() / ImageRepo::dir /
"delegations/test_delegate.json"));
321 auto new_targets = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"targets.json");
322 EXPECT_EQ(new_targets[
"signed"][
"delegations"][
"keys"].size(), 0);
323 EXPECT_EQ(new_targets[
"signed"][
"delegations"][
"roles"].size(), 0);
324 EXPECT_EQ(new_targets[
"signed"][
"version"].asUInt(), 3);
325 auto signed_targets = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"targets.json");
327 EXPECT_EQ(director_targets.targets.size(), 0);
333 TEST(uptane_generator, sign) {
335 std::ostringstream keytype_stream;
336 keytype_stream << key_type;
337 std::string cmd = generate_repo_exec +
" generate " + temp_dir.Path().string() +
" --keytype " + keytype_stream.str();
339 int retval = Utils::shell(cmd, &output);
341 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n";
343 cmd = generate_repo_exec +
" sign " + temp_dir.Path().string();
344 cmd +=
" --repotype director --keyname snapshot";
345 std::string sign_cmd =
346 "echo \"{\\\"_type\\\":\\\"Snapshot\\\",\\\"expires\\\":\\\"2021-07-04T16:33:27Z\\\"}\" | " + cmd;
348 retval = Utils::shell(sign_cmd, &output);
350 FAIL() <<
"'" << sign_cmd <<
"' exited with error code " << retval <<
"\n";
352 auto json = Utils::parseJSON(output);
354 Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"root.json"));
355 root.UnpackSignedObject(Uptane::RepositoryType::Director(), Uptane::Role::Snapshot(), json);
356 EXPECT_NO_THROW(root.UnpackSignedObject(Uptane::RepositoryType::Director(), Uptane::Role::Snapshot(), json));
357 check_repo(temp_dir);
363 TEST(uptane_generator, image_custom) {
365 std::ostringstream keytype_stream;
366 keytype_stream << key_type;
367 std::string cmd = generate_repo_exec +
" generate " + temp_dir.Path().string() +
" --keytype " + keytype_stream.str();
369 int retval = Utils::shell(cmd, &output);
371 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n";
373 cmd = generate_repo_exec +
" image " + temp_dir.Path().string() +
374 " --targetname target1 --targetsha256 8ab755c16de6ee9b6224169b36cbf0f2a545f859be385501ad82cdccc240d0a6 "
375 "--targetlength 123 --hwid primary_hw";
376 retval = Utils::shell(cmd, &output);
378 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n";
381 Json::Value image_targets = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"targets.json");
382 EXPECT_EQ(image_targets[
"signed"][
"targets"].size(), 1);
383 EXPECT_EQ(image_targets[
"signed"][
"targets"][
"target1"][
"length"].asUInt(), 123);
384 EXPECT_FALSE(image_targets[
"signed"][
"targets"][
"target1"][
"custom"].isMember(
"uri"));
385 check_repo(temp_dir);
391 TEST(uptane_generator, emptytargets) {
393 std::ostringstream keytype_stream;
394 keytype_stream << key_type;
395 std::string cmd = generate_repo_exec +
" generate " + temp_dir.Path().string() +
" --keytype " + keytype_stream.str();
397 int retval = Utils::shell(cmd, &output);
399 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n";
401 cmd = generate_repo_exec +
" image " + temp_dir.Path().string() +
402 " --targetname target1 --targetsha256 8ab755c16de6ee9b6224169b36cbf0f2a545f859be385501ad82cdccc240d0a6 "
403 "--targetlength 123 --hwid primary_hw";
404 retval = Utils::shell(cmd, &output);
406 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n";
409 cmd = generate_repo_exec +
" addtarget " + temp_dir.Path().string() +
410 " --targetname target1 --hwid primary_hw --serial serial123";
411 retval = Utils::shell(cmd, &output);
413 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n";
416 Json::Value targets = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"staging/targets.json");
417 EXPECT_EQ(targets[
"targets"].size(), 1);
418 EXPECT_EQ(targets[
"targets"][
"target1"][
"length"].asUInt(), 123);
419 EXPECT_EQ(targets[
"targets"][
"target1"][
"hashes"][
"sha256"].asString(),
420 "8AB755C16DE6EE9B6224169B36CBF0F2A545F859BE385501AD82CDCCC240D0A6");
422 cmd = generate_repo_exec +
" emptytargets " + temp_dir.Path().string();
423 retval = Utils::shell(cmd, &output);
425 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n"
426 <<
"output: " << output;
429 Json::Value empty_targets = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"staging/targets.json");
430 EXPECT_EQ(empty_targets[
"targets"].size(), 0);
431 check_repo(temp_dir);
437 TEST(uptane_generator, oldtargets) {
440 repo.generateRepo(key_type);
441 Hash hash(Hash::Type::kSha256,
"8ab755c16de6ee9b6224169b36cbf0f2a545f859be385501ad82cdccc240d0a6");
442 repo.addCustomImage(
"target1", hash, 123,
"test-hw",
"");
443 repo.addCustomImage(
"target2", hash, 321,
"test-hw",
"");
444 repo.addTarget(
"target1",
"test-hw",
"test-serial",
"");
446 repo.addTarget(
"target2",
"test-hw",
"test-serial",
"");
448 Json::Value targets = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"staging/targets.json");
449 EXPECT_EQ(targets[
"targets"].size(), 2);
450 EXPECT_EQ(targets[
"targets"][
"target1"][
"length"].asUInt(), 123);
451 EXPECT_EQ(targets[
"targets"][
"target1"][
"hashes"][
"sha256"].asString(),
452 "8AB755C16DE6EE9B6224169B36CBF0F2A545F859BE385501AD82CDCCC240D0A6");
453 EXPECT_EQ(targets[
"targets"][
"target2"][
"length"].asUInt(), 321);
454 EXPECT_EQ(targets[
"targets"][
"target2"][
"hashes"][
"sha256"].asString(),
455 "8AB755C16DE6EE9B6224169B36CBF0F2A545F859BE385501AD82CDCCC240D0A6");
457 Json::Value targets_current = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"targets.json");
458 EXPECT_EQ(targets_current[
"signed"][
"targets"].size(), 1);
459 EXPECT_EQ(targets_current[
"signed"][
"targets"][
"target1"][
"length"].asUInt(), 123);
460 EXPECT_EQ(targets_current[
"signed"][
"targets"][
"target1"][
"hashes"][
"sha256"].asString(),
461 "8AB755C16DE6EE9B6224169B36CBF0F2A545F859BE385501AD82CDCCC240D0A6");
463 std::string cmd = generate_repo_exec +
" oldtargets " + temp_dir.Path().string();
465 int retval = Utils::shell(cmd, &output);
467 FAIL() <<
"'" << cmd <<
"' exited with error code " << retval <<
"\n"
468 <<
"output: " << output;
470 targets = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"staging/targets.json");
471 EXPECT_EQ(targets[
"targets"].size(), 1);
472 EXPECT_EQ(targets[
"targets"][
"target1"][
"length"].asUInt(), 123);
473 EXPECT_EQ(targets[
"targets"][
"target1"][
"hashes"][
"sha256"].asString(),
474 "8AB755C16DE6EE9B6224169B36CBF0F2A545F859BE385501AD82CDCCC240D0A6");
475 check_repo(temp_dir);
481 TEST(uptane_generator, generateCampaigns) {
484 repo.generateRepo(key_type);
485 repo.generateCampaigns();
486 Json::Value campaigns = Utils::parseJSONFile(temp_dir.Path() /
"campaigns.json");
488 EXPECT_EQ(campaigns[
"campaigns"][0][
"name"],
"campaign1");
489 EXPECT_EQ(campaigns[
"campaigns"][0][
"id"],
"c2eb7e8d-8aa0-429d-883f-5ed8fdb2a493");
490 EXPECT_EQ((campaigns[
"campaigns"][0][
"size"]).asInt64(), 62470);
491 EXPECT_EQ(campaigns[
"campaigns"][0][
"autoAccept"],
true);
492 EXPECT_EQ(campaigns[
"campaigns"][0][
"metadata"][0][
"type"],
"DESCRIPTION");
493 EXPECT_EQ(campaigns[
"campaigns"][0][
"metadata"][0][
"value"],
"this is my message to show on the device");
494 EXPECT_EQ(campaigns[
"campaigns"][0][
"metadata"][1][
"type"],
"ESTIMATED_INSTALLATION_DURATION");
495 EXPECT_EQ(campaigns[
"campaigns"][0][
"metadata"][1][
"value"],
"10");
496 EXPECT_EQ(campaigns[
"campaigns"][0][
"metadata"][2][
"type"],
"ESTIMATED_PREPARATION_DURATION");
497 EXPECT_EQ(campaigns[
"campaigns"][0][
"metadata"][2][
"value"],
"20");
503 TEST(uptane_generator, refreshDirectorRoot) {
506 repo.generateRepo(key_type);
507 repo.refresh(Uptane::RepositoryType::Director(), Uptane::Role::Root());
509 const Json::Value director_root = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"root.json");
510 EXPECT_EQ(director_root[
"signed"][
"version"].asUInt(), 2);
511 const Json::Value director_timestamp = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"timestamp.json");
512 EXPECT_EQ(director_timestamp[
"signed"][
"version"].asUInt(), 2);
513 const Json::Value director_snapshot = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"snapshot.json");
514 EXPECT_EQ(director_snapshot[
"signed"][
"version"].asUInt(), 2);
515 const Json::Value director_targets = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"targets.json");
516 EXPECT_EQ(director_targets[
"signed"][
"version"].asUInt(), 1);
518 const Json::Value image_root = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"root.json");
519 EXPECT_EQ(image_root[
"signed"][
"version"].asUInt(), 1);
520 const Json::Value image_timestamp = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"timestamp.json");
521 EXPECT_EQ(image_timestamp[
"signed"][
"version"].asUInt(), 1);
522 const Json::Value image_snapshot = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"snapshot.json");
523 EXPECT_EQ(image_snapshot[
"signed"][
"version"].asUInt(), 1);
524 const Json::Value image_targets = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"targets.json");
525 EXPECT_EQ(image_targets[
"signed"][
"version"].asUInt(), 1);
527 check_repo(temp_dir);
533 TEST(uptane_generator, refreshDirectorTargets) {
536 repo.generateRepo(key_type);
537 repo.refresh(Uptane::RepositoryType::Director(), Uptane::Role::Targets());
539 const Json::Value director_root = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"root.json");
540 EXPECT_EQ(director_root[
"signed"][
"version"].asUInt(), 1);
541 const Json::Value director_timestamp = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"timestamp.json");
542 EXPECT_EQ(director_timestamp[
"signed"][
"version"].asUInt(), 2);
543 const Json::Value director_snapshot = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"snapshot.json");
544 EXPECT_EQ(director_snapshot[
"signed"][
"version"].asUInt(), 2);
545 const Json::Value director_targets = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"targets.json");
546 EXPECT_EQ(director_targets[
"signed"][
"version"].asUInt(), 2);
548 const Json::Value image_root = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"root.json");
549 EXPECT_EQ(image_root[
"signed"][
"version"].asUInt(), 1);
550 const Json::Value image_timestamp = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"timestamp.json");
551 EXPECT_EQ(image_timestamp[
"signed"][
"version"].asUInt(), 1);
552 const Json::Value image_snapshot = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"snapshot.json");
553 EXPECT_EQ(image_snapshot[
"signed"][
"version"].asUInt(), 1);
554 const Json::Value image_targets = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"targets.json");
555 EXPECT_EQ(image_targets[
"signed"][
"version"].asUInt(), 1);
557 check_repo(temp_dir);
563 TEST(uptane_generator, refreshImageRoot) {
566 repo.generateRepo(key_type);
567 repo.refresh(Uptane::RepositoryType::Image(), Uptane::Role::Root());
569 const Json::Value director_root = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"root.json");
570 EXPECT_EQ(director_root[
"signed"][
"version"].asUInt(), 1);
571 const Json::Value director_timestamp = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"timestamp.json");
572 EXPECT_EQ(director_timestamp[
"signed"][
"version"].asUInt(), 1);
573 const Json::Value director_snapshot = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"snapshot.json");
574 EXPECT_EQ(director_snapshot[
"signed"][
"version"].asUInt(), 1);
575 const Json::Value director_targets = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"targets.json");
576 EXPECT_EQ(director_targets[
"signed"][
"version"].asUInt(), 1);
578 const Json::Value image_root = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"root.json");
579 EXPECT_EQ(image_root[
"signed"][
"version"].asUInt(), 2);
580 const Json::Value image_timestamp = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"timestamp.json");
581 EXPECT_EQ(image_timestamp[
"signed"][
"version"].asUInt(), 2);
582 const Json::Value image_snapshot = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"snapshot.json");
583 EXPECT_EQ(image_snapshot[
"signed"][
"version"].asUInt(), 2);
584 const Json::Value image_targets = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"targets.json");
585 EXPECT_EQ(image_targets[
"signed"][
"version"].asUInt(), 1);
587 check_repo(temp_dir);
593 TEST(uptane_generator, refreshImageTargets) {
596 repo.generateRepo(key_type);
597 repo.refresh(Uptane::RepositoryType::Image(), Uptane::Role::Targets());
599 const Json::Value director_root = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"root.json");
600 EXPECT_EQ(director_root[
"signed"][
"version"].asUInt(), 1);
601 const Json::Value director_timestamp = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"timestamp.json");
602 EXPECT_EQ(director_timestamp[
"signed"][
"version"].asUInt(), 1);
603 const Json::Value director_snapshot = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"snapshot.json");
604 EXPECT_EQ(director_snapshot[
"signed"][
"version"].asUInt(), 1);
605 const Json::Value director_targets = Utils::parseJSONFile(temp_dir.Path() / DirectorRepo::dir /
"targets.json");
606 EXPECT_EQ(director_targets[
"signed"][
"version"].asUInt(), 1);
608 const Json::Value image_root = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"root.json");
609 EXPECT_EQ(image_root[
"signed"][
"version"].asUInt(), 1);
610 const Json::Value image_timestamp = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"timestamp.json");
611 EXPECT_EQ(image_timestamp[
"signed"][
"version"].asUInt(), 2);
612 const Json::Value image_snapshot = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"snapshot.json");
613 EXPECT_EQ(image_snapshot[
"signed"][
"version"].asUInt(), 2);
614 const Json::Value image_targets = Utils::parseJSONFile(temp_dir.Path() / ImageRepo::dir /
"targets.json");
615 EXPECT_EQ(image_targets[
"signed"][
"version"].asUInt(), 2);
617 check_repo(temp_dir);
621 int main(
int argc,
char **argv) {
622 ::testing::InitGoogleTest(&argc, argv);
624 logger_set_threshold(boost::log::trivial::trace);
626 generate_repo_exec = argv[1];
628 std::cerr <<
"No generate-repo executable specified\n";
634 return RUN_ALL_TESTS();