diff --git a/Pipfile.lock b/Pipfile.lock index 4fab48a..3b50856 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -18,86 +18,79 @@ "default": { "certifi": { "hashes": [ - "sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd", - "sha256:f05def092c44fbf25834a51509ef6e631dc19765ab8a57b4e7ab85531f0a9cf4" + "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c", + "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830" ], - "version": "==2020.11.8" + "version": "==2020.12.5" }, "cffi": { "hashes": [ - "sha256:005f2bfe11b6745d726dbb07ace4d53f057de66e336ff92d61b8c7e9c8f4777d", - "sha256:09e96138280241bd355cd585148dec04dbbedb4f46128f340d696eaafc82dd7b", - "sha256:0b1ad452cc824665ddc682400b62c9e4f5b64736a2ba99110712fdee5f2505c4", - "sha256:0ef488305fdce2580c8b2708f22d7785ae222d9825d3094ab073e22e93dfe51f", - "sha256:15f351bed09897fbda218e4db5a3d5c06328862f6198d4fb385f3e14e19decb3", - "sha256:22399ff4870fb4c7ef19fff6eeb20a8bbf15571913c181c78cb361024d574579", - "sha256:23e5d2040367322824605bc29ae8ee9175200b92cb5483ac7d466927a9b3d537", - "sha256:2791f68edc5749024b4722500e86303a10d342527e1e3bcac47f35fbd25b764e", - "sha256:2f9674623ca39c9ebe38afa3da402e9326c245f0f5ceff0623dccdac15023e05", - "sha256:3363e77a6176afb8823b6e06db78c46dbc4c7813b00a41300a4873b6ba63b171", - "sha256:33c6cdc071ba5cd6d96769c8969a0531be2d08c2628a0143a10a7dcffa9719ca", - "sha256:3b8eaf915ddc0709779889c472e553f0d3e8b7bdf62dab764c8921b09bf94522", - "sha256:3cb3e1b9ec43256c4e0f8d2837267a70b0e1ca8c4f456685508ae6106b1f504c", - "sha256:3eeeb0405fd145e714f7633a5173318bd88d8bbfc3dd0a5751f8c4f70ae629bc", - "sha256:44f60519595eaca110f248e5017363d751b12782a6f2bd6a7041cba275215f5d", - "sha256:4d7c26bfc1ea9f92084a1d75e11999e97b62d63128bcc90c3624d07813c52808", - "sha256:529c4ed2e10437c205f38f3691a68be66c39197d01062618c55f74294a4a4828", - "sha256:6642f15ad963b5092d65aed022d033c77763515fdc07095208f15d3563003869", - "sha256:85ba797e1de5b48aa5a8427b6ba62cf69607c18c5d4eb747604b7302f1ec382d", - "sha256:8f0f1e499e4000c4c347a124fa6a27d37608ced4fe9f7d45070563b7c4c370c9", - "sha256:a624fae282e81ad2e4871bdb767e2c914d0539708c0f078b5b355258293c98b0", - "sha256:b0358e6fefc74a16f745afa366acc89f979040e0cbc4eec55ab26ad1f6a9bfbc", - "sha256:bbd2f4dfee1079f76943767fce837ade3087b578aeb9f69aec7857d5bf25db15", - "sha256:bf39a9e19ce7298f1bd6a9758fa99707e9e5b1ebe5e90f2c3913a47bc548747c", - "sha256:c11579638288e53fc94ad60022ff1b67865363e730ee41ad5e6f0a17188b327a", - "sha256:c150eaa3dadbb2b5339675b88d4573c1be3cb6f2c33a6c83387e10cc0bf05bd3", - "sha256:c53af463f4a40de78c58b8b2710ade243c81cbca641e34debf3396a9640d6ec1", - "sha256:cb763ceceae04803adcc4e2d80d611ef201c73da32d8f2722e9d0ab0c7f10768", - "sha256:cc75f58cdaf043fe6a7a6c04b3b5a0e694c6a9e24050967747251fb80d7bce0d", - "sha256:d80998ed59176e8cba74028762fbd9b9153b9afc71ea118e63bbf5d4d0f9552b", - "sha256:de31b5164d44ef4943db155b3e8e17929707cac1e5bd2f363e67a56e3af4af6e", - "sha256:e66399cf0fc07de4dce4f588fc25bfe84a6d1285cc544e67987d22663393926d", - "sha256:f0620511387790860b249b9241c2f13c3a80e21a73e0b861a2df24e9d6f56730", - "sha256:f4eae045e6ab2bb54ca279733fe4eb85f1effda392666308250714e01907f394", - "sha256:f92cdecb618e5fa4658aeb97d5eb3d2f47aa94ac6477c6daf0f306c5a3b9e6b1", - "sha256:f92f789e4f9241cd262ad7a555ca2c648a98178a953af117ef7fad46aa1d5591" + "sha256:00a1ba5e2e95684448de9b89888ccd02c98d512064b4cb987d48f4b40aa0421e", + "sha256:00e28066507bfc3fe865a31f325c8391a1ac2916219340f87dfad602c3e48e5d", + "sha256:045d792900a75e8b1e1b0ab6787dd733a8190ffcf80e8c8ceb2fb10a29ff238a", + "sha256:0638c3ae1a0edfb77c6765d487fee624d2b1ee1bdfeffc1f0b58c64d149e7eec", + "sha256:105abaf8a6075dc96c1fe5ae7aae073f4696f2905fde6aeada4c9d2926752362", + "sha256:155136b51fd733fa94e1c2ea5211dcd4c8879869008fc811648f16541bf99668", + "sha256:1a465cbe98a7fd391d47dce4b8f7e5b921e6cd805ef421d04f5f66ba8f06086c", + "sha256:1d2c4994f515e5b485fd6d3a73d05526aa0fcf248eb135996b088d25dfa1865b", + "sha256:2c24d61263f511551f740d1a065eb0212db1dbbbbd241db758f5244281590c06", + "sha256:51a8b381b16ddd370178a65360ebe15fbc1c71cf6f584613a7ea08bfad946698", + "sha256:594234691ac0e9b770aee9fcdb8fa02c22e43e5c619456efd0d6c2bf276f3eb2", + "sha256:5cf4be6c304ad0b6602f5c4e90e2f59b47653ac1ed9c662ed379fe48a8f26b0c", + "sha256:64081b3f8f6f3c3de6191ec89d7dc6c86a8a43911f7ecb422c60e90c70be41c7", + "sha256:6bc25fc545a6b3d57b5f8618e59fc13d3a3a68431e8ca5fd4c13241cd70d0009", + "sha256:798caa2a2384b1cbe8a2a139d80734c9db54f9cc155c99d7cc92441a23871c03", + "sha256:7c6b1dece89874d9541fc974917b631406233ea0440d0bdfbb8e03bf39a49b3b", + "sha256:840793c68105fe031f34d6a086eaea153a0cd5c491cde82a74b420edd0a2b909", + "sha256:8d6603078baf4e11edc4168a514c5ce5b3ba6e3e9c374298cb88437957960a53", + "sha256:9cc46bc107224ff5b6d04369e7c595acb700c3613ad7bcf2e2012f62ece80c35", + "sha256:9f7a31251289b2ab6d4012f6e83e58bc3b96bd151f5b5262467f4bb6b34a7c26", + "sha256:9ffb888f19d54a4d4dfd4b3f29bc2c16aa4972f1c2ab9c4ab09b8ab8685b9c2b", + "sha256:a5ed8c05548b54b998b9498753fb9cadbfd92ee88e884641377d8a8b291bcc01", + "sha256:a7711edca4dcef1a75257b50a2fbfe92a65187c47dab5a0f1b9b332c5919a3fb", + "sha256:af5c59122a011049aad5dd87424b8e65a80e4a6477419c0c1015f73fb5ea0293", + "sha256:b18e0a9ef57d2b41f5c68beefa32317d286c3d6ac0484efd10d6e07491bb95dd", + "sha256:b4e248d1087abf9f4c10f3c398896c87ce82a9856494a7155823eb45a892395d", + "sha256:ba4e9e0ae13fc41c6b23299545e5ef73055213e466bd107953e4a013a5ddd7e3", + "sha256:c6332685306b6417a91b1ff9fae889b3ba65c2292d64bd9245c093b1b284809d", + "sha256:d5ff0621c88ce83a28a10d2ce719b2ee85635e85c515f12bac99a95306da4b2e", + "sha256:d9efd8b7a3ef378dd61a1e77367f1924375befc2eba06168b6ebfa903a5e59ca", + "sha256:df5169c4396adc04f9b0a05f13c074df878b6052430e03f50e68adf3a57aa28d", + "sha256:ebb253464a5d0482b191274f1c8bf00e33f7e0b9c66405fbffc61ed2c839c775", + "sha256:ec80dc47f54e6e9a78181ce05feb71a0353854cc26999db963695f950b5fb375", + "sha256:f032b34669220030f905152045dfa27741ce1a6db3324a5bc0b96b6c7420c87b", + "sha256:f60567825f791c6f8a592f3c6e3bd93dd2934e3f9dac189308426bd76b00ef3b", + "sha256:f803eaa94c2fcda012c047e62bc7a51b0bdabda1cad7a92a522694ea2d76e49f" ], - "version": "==1.14.3" + "version": "==1.14.4" }, "chardet": { "hashes": [ - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", + "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5" ], - "version": "==3.0.4" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==4.0.0" }, "cryptography": { "hashes": [ - "sha256:07ca431b788249af92764e3be9a488aa1d39a0bc3be313d826bbec690417e538", - "sha256:13b88a0bd044b4eae1ef40e265d006e34dbcde0c2f1e15eb9896501b2d8f6c6f", - "sha256:32434673d8505b42c0de4de86da8c1620651abd24afe91ae0335597683ed1b77", - "sha256:3cd75a683b15576cfc822c7c5742b3276e50b21a06672dc3a800a2d5da4ecd1b", - "sha256:4e7268a0ca14536fecfdf2b00297d4e407da904718658c1ff1961c713f90fd33", - "sha256:545a8550782dda68f8cdc75a6e3bf252017aa8f75f19f5a9ca940772fc0cb56e", - "sha256:55d0b896631412b6f0c7de56e12eb3e261ac347fbaa5d5e705291a9016e5f8cb", - "sha256:5849d59358547bf789ee7e0d7a9036b2d29e9a4ddf1ce5e06bb45634f995c53e", - "sha256:6dc59630ecce8c1f558277ceb212c751d6730bd12c80ea96b4ac65637c4f55e7", - "sha256:7117319b44ed1842c617d0a452383a5a052ec6aa726dfbaffa8b94c910444297", - "sha256:75e8e6684cf0034f6bf2a97095cb95f81537b12b36a8fedf06e73050bb171c2d", - "sha256:7b8d9d8d3a9bd240f453342981f765346c87ade811519f98664519696f8e6ab7", - "sha256:a035a10686532b0587d58a606004aa20ad895c60c4d029afa245802347fab57b", - "sha256:a4e27ed0b2504195f855b52052eadcc9795c59909c9d84314c5408687f933fc7", - "sha256:a733671100cd26d816eed39507e585c156e4498293a907029969234e5e634bc4", - "sha256:a75f306a16d9f9afebfbedc41c8c2351d8e61e818ba6b4c40815e2b5740bb6b8", - "sha256:bd717aa029217b8ef94a7d21632a3bb5a4e7218a4513d2521c2a2fd63011e98b", - "sha256:d25cecbac20713a7c3bc544372d42d8eafa89799f492a43b79e1dfd650484851", - "sha256:d26a2557d8f9122f9bf445fc7034242f4375bd4e95ecda007667540270965b13", - "sha256:d3545829ab42a66b84a9aaabf216a4dce7f16dbc76eb69be5c302ed6b8f4a29b", - "sha256:d3d5e10be0cf2a12214ddee45c6bd203dab435e3d83b4560c03066eda600bfe3", - "sha256:efe15aca4f64f3a7ea0c09c87826490e50ed166ce67368a68f315ea0807a20df" + "sha256:0003a52a123602e1acee177dc90dd201f9bb1e73f24a070db7d36c588e8f5c7d", + "sha256:0e85aaae861d0485eb5a79d33226dd6248d2a9f133b81532c8f5aae37de10ff7", + "sha256:594a1db4511bc4d960571536abe21b4e5c3003e8750ab8365fafce71c5d86901", + "sha256:69e836c9e5ff4373ce6d3ab311c1a2eed274793083858d3cd4c7d12ce20d5f9c", + "sha256:788a3c9942df5e4371c199d10383f44a105d67d401fb4304178020142f020244", + "sha256:7e177e4bea2de937a584b13645cab32f25e3d96fc0bc4a4cf99c27dc77682be6", + "sha256:83d9d2dfec70364a74f4e7c70ad04d3ca2e6a08b703606993407bf46b97868c5", + "sha256:84ef7a0c10c24a7773163f917f1cb6b4444597efd505a8aed0a22e8c4780f27e", + "sha256:9e21301f7a1e7c03dbea73e8602905a4ebba641547a462b26dd03451e5769e7c", + "sha256:9f6b0492d111b43de5f70052e24c1f0951cb9e6022188ebcb1cc3a3d301469b0", + "sha256:a69bd3c68b98298f490e84519b954335154917eaab52cf582fa2c5c7efc6e812", + "sha256:b4890d5fb9b7a23e3bf8abf5a8a7da8e228f1e97dc96b30b95685df840b6914a", + "sha256:c366df0401d1ec4e548bebe8f91d55ebcc0ec3137900d214dd7aac8427ef3030", + "sha256:dc42f645f8f3a489c3dd416730a514e7a91a59510ddaadc09d04224c098d3302" ], "index": "pypi", - "version": "==3.2.1" + "version": "==3.3.1" }, "idna": { "hashes": [ @@ -141,11 +134,11 @@ }, "requests": { "hashes": [ - "sha256:7f1a0b932f4a60a1a65caa4263921bb7d9ee911957e0ae4a23a6dd08185ad5f8", - "sha256:e786fa28d8c9154e6a4de5d46a1d921b8749f8b74e28bde23768e5e16eece998" + "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", + "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.25.0" + "version": "==2.25.1" }, "securesystemslib": { "hashes": [ @@ -160,16 +153,16 @@ "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.15.0" }, "tuf": { "hashes": [ - "sha256:a3bb7a86cecf9d5356666ce14378d6f39151720547fb9cf2cc4e1497b340c567", - "sha256:e0653e1339031d018212d593879f96152af212aaf07a205ebcfc65d62f76679c" + "sha256:9ea8d7014ea879e5ca41be7959ee9e097bd19e538da8d7023c7e317c8df4d590", + "sha256:f3148939ea748f2d04412dba43ffe33bc94521ccb8d8051eef98ba2b40c8d96f" ], "index": "pypi", - "version": "==0.15.0" + "version": "==0.16.0" }, "urllib3": { "hashes": [ diff --git a/README.md b/README.md index f26a6d4..ace63e3 100644 --- a/README.md +++ b/README.md @@ -1 +1,24 @@ -# example-repository-offline \ No newline at end of file +# Example Repository + +This repository is a first python3-based proof-of-concept to +set up a server-side repository as an example. + + +## Setup for Python 3.9 + + pipenv install + +## Usage + +Setting up a new repo: './init.py' + +Adding a target to a repo: './add_target.py /path/to/my-file.tar.gz project-name/my-file.tar.gz' + +Removing an existing target from the repo: './remove_target.py project-name/my-file.tar.gz' + +## Next steps + +* Make the basic folders and paths configurable via argv +* Set up the keys outside of the folders +* Add commands for removing / invalidating keys +* Consider hashed bins diff --git a/add_target.py b/add_target.py old mode 100644 new mode 100755 index 5ddd019..6a034c3 --- a/add_target.py +++ b/add_target.py @@ -1,37 +1,28 @@ -# Set up new repository +#!/usr/bin/env python3 -from tuf import repository_tool as rt -import os -import shutil +# Load a target file into an existing Repository +# import our own "utils" module +from utils import * +import sys +from os import * -def loadkey(filename): - pathpriv = 'tufkeystore/{}_key'.format(filename) - pathpub = '{}.pub'.format(pathpriv) - public_key = rt.import_ed25519_publickey_from_file(pathpub) - private_key = rt.import_ed25519_privatekey_from_file(password='pw', filepath=pathpriv) - return (public_key, private_key) +# base variables, +# @todo should be configurable via argv +basefolder = 'tuf-testrepo' +keystore = 'tufkeystore' +reponame = 'tufrepo' -def add_target(repo_dir, target): - os.chdir(repo_dir) - repository = rt.load_repository('tufrepo') - (public_root_key, private_root_key) = loadkey('root') - (public_targets_key, private_targets_key) = loadkey('targets') - (public_snapshots_key, private_snapshots_key) = loadkey('snapshot') - (public_timestamps_key, private_timestamps_key) = loadkey('timestamp') - #repository.root.add_verification_key(public_root_key) - repository.root.load_signing_key(private_root_key) - # Add additional roles - #repository.targets.add_verification_key(public_targets_key) - repository.targets.load_signing_key(private_targets_key) - #repository.snapshot.add_verification_key(public_snapshots_key) - repository.snapshot.load_signing_key(private_snapshots_key) - #repository.timestamp.add_verification_key(public_timestamps_key) - repository.timestamp.load_signing_key(private_timestamps_key) - repository.status() - repository.targets.add_targets([target]) - # Make it so (consistently) - repository.mark_dirty(['root', 'snapshot', 'targets', 'timestamp']) - repository.writeall(consistent_snapshot=True) +absolute_source = sys.argv[1] +absolute_source = os.path.abspath(absolute_source) +target_location = sys.argv[2] +absolute_target = os.path.abspath(os.path.join(basefolder, reponame, 'targets', target_location)); -add_target('tuf-testrepo', 'my-file.txt') +print('Load existing TUF repository') +repository = tuf.load_repo(basefolder, reponame) + +print('Load signing keys into repo') +tuf.load_signing_keys_into_repo(repository, keystore) + +print('Adding target ', target_location, ' to repo') +tuf.add_target(repository, target_location, absolute_source, absolute_target) \ No newline at end of file diff --git a/init.py b/init.py old mode 100644 new mode 100755 index 73e5393..fcfcf59 --- a/init.py +++ b/init.py @@ -1,40 +1,16 @@ -# Set up new repository +#!/usr/bin/env python3 -from tuf import repository_tool as rt -import os -import shutil +# Set up new repository +# should only be called once -# shorthand to create keypairs -def write_and_import_keypair(filename): - pathpriv = 'tufkeystore/{}_key'.format(filename) - pathpub = '{}.pub'.format(pathpriv) - rt.generate_and_write_ed25519_keypair(password='pw', filepath=pathpriv) - public_key = rt.import_ed25519_publickey_from_file(pathpub) - private_key = rt.import_ed25519_privatekey_from_file(password='pw', filepath=pathpriv) - return (public_key, private_key) +# import our own "utils" module +from utils import * +import sys -# shorthand to create full repo with all keys, only do this once -def create_repo(repo_dir): - os.mkdir(repo_dir) - os.chdir(repo_dir) - (public_root_key, private_root_key) = write_and_import_keypair('root') - (public_targets_key, private_targets_key) = write_and_import_keypair('targets') - (public_snapshots_key, private_snapshots_key) = write_and_import_keypair('snapshot') - (public_timestamps_key, private_timestamps_key) = write_and_import_keypair('timestamp') - # Bootstrap Repository - repository = rt.create_new_repository("tufrepo", repo_dir) - repository.root.add_verification_key(public_root_key) - repository.root.load_signing_key(private_root_key) - # Add additional roles - repository.targets.add_verification_key(public_targets_key) - repository.targets.load_signing_key(private_targets_key) - repository.snapshot.add_verification_key(public_snapshots_key) - repository.snapshot.load_signing_key(private_snapshots_key) - repository.timestamp.add_verification_key(public_timestamps_key) - repository.timestamp.load_signing_key(private_timestamps_key) - repository.status() - # Make it so (consistently) - repository.mark_dirty(['root', 'snapshot', 'targets', 'timestamp']) - repository.writeall(consistent_snapshot=True) +# base variables, should be configurable via argv +basefolder = 'tuf-testrepo' +# keystore folder is expected to be put inside the repo folder +keystore = 'tufkeystore' +reponame = 'tufrepo' -create_repo('tuf-testrepo') +create_repo(basefolder, keystore, reponame) \ No newline at end of file diff --git a/remove_target.py b/remove_target.py new file mode 100755 index 0000000..3c37ba5 --- /dev/null +++ b/remove_target.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 + +# Removes an existing target file from a repository + +# import our own "utils" module +from utils import * +import sys +from os import * + +# base variables, +# @todo should be configurable via argv +basefolder = 'tuf-testrepo' +keystore = 'tufkeystore' +reponame = 'tufrepo' + +target_location = sys.argv[1] +absolute_target = os.path.abspath(os.path.join(basefolder, reponame, 'targets', target_location)); + +print('Load existing TUF repository') +repository = load_repo(basefolder, reponame) + +print('Load signing keys into repo') +load_signing_keys_into_repo(repository, keystore) + +print('Removing target ', target_location, ' from repo') +remove_target(repository, target_location, absolute_target) \ No newline at end of file diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..f34f25a --- /dev/null +++ b/utils.py @@ -0,0 +1,90 @@ +# common utilities for other scripts + + +from tuf import repository_tool as rt +import os +import shutil + +# shorthand to create keypairs +def write_and_import_keypair(keystorefolder, filename): + pathpriv = keystorefolder + '/{}_key'.format(filename) + pathpub = '{}.pub'.format(pathpriv) + rt.generate_and_write_ed25519_keypair(password='pw', filepath=pathpriv) + public_key = rt.import_ed25519_publickey_from_file(pathpub) + private_key = rt.import_ed25519_privatekey_from_file(password='pw', filepath=pathpriv) + return (public_key, private_key) + +# loads keys from the files, should be used whenever someone wants to interact with the +# the repository (e.g. adding a new target) +def loadkey(keystorefolder, filename): + pathpriv = keystorefolder + '/{}_key'.format(filename) + pathpub = '{}.pub'.format(pathpriv) + public_key = rt.import_ed25519_publickey_from_file(pathpub) + private_key = rt.import_ed25519_privatekey_from_file(password='pw', filepath=pathpriv) + return (public_key, private_key) + +# shorthand to create full repo with all keys, only do this once +def create_repo(basefolder, keystorefolder, reponame): + if not os.path.isdir(basefolder): + os.mkdir(basefolder) + os.chdir(basefolder) + (public_root_key, private_root_key) = write_and_import_keypair(keystorefolder, 'root') + (public_targets_key, private_targets_key) = write_and_import_keypair(keystorefolder, 'targets') + (public_snapshots_key, private_snapshots_key) = write_and_import_keypair(keystorefolder, 'snapshot') + (public_timestamps_key, private_timestamps_key) = write_and_import_keypair(keystorefolder, 'timestamp') + # Bootstrap Repository + repository = rt.create_new_repository(reponame, basefolder) + repository.root.add_verification_key(public_root_key) + repository.root.load_signing_key(private_root_key) + # Add additional roles + repository.targets.add_verification_key(public_targets_key) + repository.targets.load_signing_key(private_targets_key) + repository.snapshot.add_verification_key(public_snapshots_key) + repository.snapshot.load_signing_key(private_snapshots_key) + repository.timestamp.add_verification_key(public_timestamps_key) + repository.timestamp.load_signing_key(private_timestamps_key) + repository.status() + # Make it happen (consistently) + repository.mark_dirty(['root', 'snapshot', 'targets', 'timestamp']) + repository.writeall(consistent_snapshot=True) + +def load_repo(basefolder, reponame): + os.chdir(basefolder) + repository = rt.load_repository(reponame) + return repository + + +def load_signing_keys_into_repo(repository, keystorefolder): + (public_root_key, private_root_key) = loadkey(keystorefolder, 'root') + (public_targets_key, private_targets_key) = loadkey(keystorefolder, 'targets') + (public_snapshots_key, private_snapshots_key) = loadkey(keystorefolder, 'snapshot') + (public_timestamps_key, private_timestamps_key) = loadkey(keystorefolder, 'timestamp') + #repository.root.add_verification_key(public_root_key) + repository.root.load_signing_key(private_root_key) + # Add additional roles + #repository.targets.add_verification_key(public_targets_key) + repository.targets.load_signing_key(private_targets_key) + #repository.snapshot.add_verification_key(public_snapshots_key) + repository.snapshot.load_signing_key(private_snapshots_key) + #repository.timestamp.add_verification_key(public_timestamps_key) + repository.timestamp.load_signing_key(private_timestamps_key) + + +def add_target(repository, target, absolute_source, absolute_target): + repository.status() + # copy absolute_source into targets folder + # Copy the source file to the targets location as TUF expects the file to already be present + os.makedirs(os.path.dirname(absolute_target), exist_ok=True) + shutil.copyfile(absolute_source, absolute_target) + + repository.targets.add_targets([target]) + repository.mark_dirty(['snapshot', 'targets', 'timestamp']) + repository.writeall(consistent_snapshot=True) + + +def remove_target(repository, target, absolute_target): + repository.status() + repository.targets.remove_target(target) + os.remove(absolute_target) + repository.mark_dirty(['snapshot', 'targets', 'timestamp']) + repository.writeall(consistent_snapshot=True)