diff --git a/tuf/README.md b/tuf/README.md index 86c17c6c..7dce8abf 100644 --- a/tuf/README.md +++ b/tuf/README.md @@ -1,6 +1,7 @@ +#libtuf.py +![Repo Tools Diagram 1](https://raw.github.com/theupdateframework/tuf/repository-tools/docs/images/libtuf-diagram.png) ## Create TUF Repository -![Repo Tools Diagram 1](https://raw.github.com/SantiagoTorres/tuf/repository-tools/resources/images/TUF%20repository%20tools.png) ### Keys #### Create RSA Keys @@ -105,9 +106,9 @@ Not enough signatures for 'path/to/repository/metadata.staged/targets.txt' # Generate keys for the remaining top-level roles. The root keys have been set above. # The password argument may be omitted if a password prompt is needed. -generate_and_write_rsa_keypair("path/to/targets_key", password="pw") -generate_and_write_rsa_keypair("path/to/release_key", password="pw") -generate_and_write_rsa_keypair("path/to/timestamp_key", password="pw") +generate_and_write_rsa_keypair("path/to/targets_key", password="password") +generate_and_write_rsa_keypair("path/to/release_key", password="password") +generate_and_write_rsa_keypair("path/to/timestamp_key", password="password") # Add the public keys of the remaining top-level roles. repository.targets.add_key(import_rsa_publickey_from_file("path/to/targets_key.pub")) @@ -139,9 +140,9 @@ repository.timestamp.expiration = "2014-10-28 12:08:00" repository.targets.compressions = ["gz"] repository.release.compressions = ["gz"] -# Write all metadata to “path/to/repository/metadata/” +# Write all metadata to "path/to/repository/metadata/". # The common case is to crawl the filesystem for all roles in -# “path/to/repository/metadata/targets/”. +# "path/to/repository/metadata/targets/". repository.write() ``` @@ -158,7 +159,9 @@ $ mkdir django; echo 'file4' > django/file4.txt ``` ```python -# Load the repository created in the previous section. This repository contains metadata for +from tuf.libtuf import * + +# Load the repository created in the previous section. This repository so far contains metadata for # the top-level roles, but no targets. repository = load_repository("path/to/repository/") @@ -184,16 +187,16 @@ repository.targets.load_signing_key(private_targets_key) # Due to the load_repository(), we must also load the private keys of the other top-level roles # to generate a valid set of metadata. -private_root_key = import_rsa_privatekey_from_file("path/to/root_key") +private_root_key = import_rsa_privatekey_from_file("path/to/root_key") Enter a password for the RSA key: Confirm: -private_root_key2 = import_rsa_privatekey_from_file("path/to/root_key2") +private_root_key2 = import_rsa_privatekey_from_file("path/to/root_key2") Enter a password for the RSA key: Confirm: -private_release_key = import_rsa_privatekey_from_file("path/to/release_key") +private_release_key = import_rsa_privatekey_from_file("path/to/release_key") Enter a password for the RSA key: Confirm: -private_timestamp_key = import_rsa_privatekey_from_file("path/to/timestamp_key") +private_timestamp_key = import_rsa_privatekey_from_file("path/to/timestamp_key") Enter a password for the RSA key: Confirm: @@ -210,12 +213,12 @@ repository.write() ```python # Continuing from the previous section . . . -# Remove a target file listed in the “targets” metadata. The target file is not actually deleted +# Remove a target file listed in the "targets" metadata. The target file is not actually deleted # from the file system. repository.targets.remove_target("path/to/repository/targets/file3.txt") # repository.write() creates any new metadata files, updates those that have changed, and any that -# need updating to make a new “release” (new release.txt and timestamp.txt). +# need updating to make a new "release" (new release.txt and timestamp.txt). repository.write() ``` @@ -223,23 +226,24 @@ repository.write() ```python # Continuing from the previous section . . . -# Generate a key for a new delegated role named “unclaimed”. -generate_and_write_rsa_keypair("path/to/unclaimed_key", bits=2048, password="pw") +# Generate a key for a new delegated role named "unclaimed". +generate_and_write_rsa_keypair("path/to/unclaimed_key", bits=2048, password="password") public_unclaimed_key = import_rsa_publickey_from_file("path/to/unclaimed_key.pub") -# Make a delegation from “targets” to “targets/unclaimed”, for all targets in “list_of_targets”. -# The delegated role’s full name is not required. -# delegated(rolename, list_of_public_keys, list_of_file_paths, threshold, restricted_paths) +# Make a delegation from "targets" to "targets/unclaimed", initially containing zero targets. +# The delegated role’s full name is not expected. +# delegated(rolename, list_of_public_keys, list_of_file_paths, threshold, +# restricted_paths, path_hash_prefixes) repository.targets.delegate("unclaimed", [public_unclaimed_key], []) -# Load the private key of “targets/unclaimed” so that signatures are added and valid metadata -# is created. +# Load the private key of "targets/unclaimed" so that signatures are later added and valid +# metadata is created. private_unclaimed_key = import_rsa_privatekey_from_file("path/to/unclaimed_key") Enter a password for the RSA key: Confirm: repository.targets.unclaimed.load_signing_key(private_unclaimed_key) -# Update an attribute of the unclaimed role and add a target file. +# Update an attribute of the unclaimed role. repository.targets.unclaimed.version = 2 # Delegations may also be nested. Create the delegated role "targets/unclaimed/django", @@ -251,7 +255,7 @@ repository.targets.unclaimed.django.load_signing_key(private_unclaimed_key) repository.targets.unclaimed.django.add_target("path/to/repository/targets/django/file4.txt") repository.targets.unclaimed.django.compressions = ["gz"] -# Write the metadata of "targets/unclaimed", targets/unclaimed/django", targets, release, +# Write the metadata of "targets/unclaimed", "targets/unclaimed/django", targets, release, # and timestamp. repository.write() ``` @@ -263,7 +267,7 @@ repository.write() # Create a delegated role that will be revoked in the next step. repository.targets.unclaimed.delegate("flask", [public_unclaimed_key], []) -# Revoke “targets/unclaimed/flask” and write the metadata of all remaining roles. +# Revoke "targets/unclaimed/flask" and write the metadata of all remaining roles. repository.targets.unclaimed.revoke("flask") repository.write() ``` @@ -277,20 +281,22 @@ $ cp -r "path/to/repository/metadata.staged" "path/to/repository/metadata" ### Using TUF Within an Example Client Updater ```python +from tuf.libtuf import * + # The following function creates a directory structure that a client # downloading new software using tuf (via tuf/client/updater.py) will expect. # The root.txt metadata file must exist, and also the directories that hold the metadata files # downloaded from a repository. Software updaters integrating with TUF may use this # directory to store TUF updates saved on the client side. create_tuf_client_directory() -# moves metadata files “path/to/repository/” to “path/to/client/”. The repository in -# “path/to/repository/” is the repository created in the “Create TUF Repository” section. +# moves metadata files "path/to/repository/" to "path/to/client/". The repository in +# "path/to/repository/" is the repository created in the "Create TUF Repository" section. create_tuf_client_directory("path/to/repository/", "path/to/client/") ``` #### Test TUF Locally ```Bash # Run the local TUF repository server. -$ cd “path/to/repository/”; python -m SimpleHTTPServer 8001 +$ cd "path/to/repository/"; python -m SimpleHTTPServer 8001 # Retrieve targets from the TUF repository and save them to "path/to/client/". The # basic_client.py module is available in "tuf/client/". @@ -299,8 +305,7 @@ $ cd "path/to/client/" $ ls metadata/ -$ python basic_client.py --repo http://localhost:8001 - +$ basic_client.py --repo http://localhost:8001 $ ls . targets/ targets/django/ .: metadata targets tuf.log