tough: Rust implementation of The Update Framework (TUF)

repository·develop·Indexed 42 days ago

https://github.com/awslabs/tough

A Rust-based ecosystem for implementing The Update Framework (TUF), featuring a client library for consuming secure updates and the tuftool CLI for repository maintainers to generate and sign metadata. Includes specialized crates such as tough-kms and tough-ssm for AWS-backed key management, and olpc-cjson for OLPC-style canonical JSON serialization.

Tokens
28.5K
Snippets
83
Records
116
Agent score
53%

What's inside tough

  1. Overview of the tough project

    develop

    The tough project provides tools for interacting with The Update Framework (TUF) repositories. It consists of two primary components:

    1. tough: A Rust client library designed for consuming TUF repositories.
    2. tuftool: A Rust command-line utility used for the generation and signing of TUF repositories.

    Additionally, the project includes specialized crates for key management, such as tough-kms and tough-ssm, which implement the KeySource trait for AWS services.

  2. Use AWS KMS as a key source for TUF repositories

    develop
    The tough-kms crate allows you to use AWS Key Management Service (KMS) as a source for keys used to sign a The Update Framework (TUF) repository. It achieves this by implementing the KeySource trait defined in the core tough Rust library. This enables secure, hardware-backed signing operations for TUF metadata using AWS KMS.
  3. How delegated targets work in tough

    develop

    Delegated targets create a chain of trust from a repository owner to developers by delegating specific paths in a repository to other roles. This creates a cryptographically verified delegation chain where updated targets are guaranteed to be from the developer who signed the metadata.

    In the tough library, there are two primary ways to manage these delegations:

    1. RepositoryEditor: Used by users who have access to the standard TUF roles (snapshot.json, timestamp.json, targets.json). It can edit the entire repository, create complete signed metadata, and manage the delegation chain (adding/updating roles).
    2. TargetsEditor: Used by delegated roles that do not have access to the standard TUF roles. It is used to edit specific targets metadata. Metadata produced by a TargetsEditor is signed but does not constitute a full repository; it must be loaded into a RepositoryEditor to complete the signed repository structure.
    // Conceptual usage of the two editor types
    // RepositoryEditor (Full access)
    // TargetsEditor (Delegated access only)
  4. Create a new TUF repository

    develop

    Use the tuftool create command to generate a signed TUF repository from a directory of target files. You must provide the root.json path, a signing key, the directory containing targets, and version/expiration metadata for targets, snapshot, and timestamp roles.

    tuftool create \
      --root "${ROOT}" \
      --key "${WRK}/keys/root.pem" \
      --add-targets "${WRK}/input" \
      --targets-expires 'in 3 weeks' \
      --targets-version 1 \
      --snapshot-expires 'in 3 weeks' \
      --snapshot-version 1 \
      --timestamp-expires 'in 1 week' \
      --timestamp-version 1 \
      --outdir "${WRK}/tuf-repo"
  5. Use tuftool via Docker container

    develop

    To avoid installing the Rust toolchain, you can build and run tuftool using Docker.

    1. Build the image: docker build -t tuftool .
    2. Run commands by mounting your host working directory to /share inside the container.

    Example for downloading to a local directory:

    docker run -it -v $(pwd):/share tuftool download "/share/some_directory" ...
    docker build -t tuftool .
    
    docker run -it -v $(pwd):/share tuftool download "/share/some_directory" ...
  6. Download a TUF repository

    develop

    Use tuftool download to fetch a repository. While typically used with HTTP/S URLs, it also supports local file URLs. You must specify the paths to the targets and metadata directories using the -t and -m flags.

    tuftool download \
       --root "${ROOT}" \
       -t "file://${WRK}/tuf-repo/targets" \
       -m "file://${WRK}/tuf-repo/metadata" \
       "${WRK}/tuf-downlaod"
  7. Use AWS SSM as a key source for TUF repositories

    develop
    The tough-ssm crate provides an implementation of the KeySource trait for the tough Rust library. This allows you to use AWS Systems Manager (SSM) Parameter Store to store and retrieve the cryptographic keys required to sign a The Update Framework (TUF) repository.
  8. Initialize and configure a TUF root.json

    develop

    Before creating a repository, you must initialize a root.json file, set expiration dates, define signing thresholds for standard roles (root, snapshot, targets, timestamp), and generate/add signing keys.

    Standard workflow:

    1. tuftool root init <path>: Create the file.
    2. tuftool root expire <path> <duration>: Set expiration (e.g., 'in 6 weeks').
    3. tuftool root set-threshold <path> <role> <threshold>: Define how many signatures are required for a role.
    4. tuftool root gen-rsa-key <path> <key_path> --role <role>: Create a new RSA key and add it to the root file.
    5. tuftool root add-key <path> -k <key_path> --role <role>: Add an existing key to a role.
    6. tuftool root sign <path> -k <key_path>: Sign the root.json file.
    # Example initialization
    tuftool root init "${ROOT}"
    tuftool root expire "${ROOT}" 'in 6 weeks'
    tuftool root set-threshold "${ROOT}" root 1
    tuftool root gen-rsa-key "${ROOT}" "${WRK}/keys/root.pem" --role root
    tuftool root sign "${ROOT}" -k "${WRK}/keys/root.pem"
  9. Add or remove keys from delegated roles using tuftool

    develop

    You can manage which keys are authorized to sign for a delegated role by using the add-key and remove-key subcommands under tuftool delegation.

    Adding a key

    Use add-key to authorize a new key for a delegated role. This requires the signing key of the parent role and the path to the new key. After adding the key, you must run tuftool update for the parent role to commit the changes to the repository metadata.

    Removing a key

    Use remove-key to revoke a specific key from a delegated role. You must provide the --keyid of the key being removed. Like adding a key, this requires a subsequent tuftool update to finalize the change in the repository.

    Note: Always follow a delegation change with a tuftool update command targeting the parent role to ensure the repository metadata is consistent.

    # Add a key to targets to sign role1
    tuftool delegation --signing-role targets add-key \
    --key path/to/repo/owner/key \
    --new-key path/to/new/role1/key \
    --expires in 2 days \
    --version 63 \
    --delegated-role role1 \
    --outdir targets/with/extra/role1/key \
    --root path/to/root.json \
    --metadata-url path/to/metadata
    
    # Update the repository with the new targets metadata
    tuftool update \
    --key path/to/repo/owner/key \
    --snapshot-version 74 \
    --snapshot-expires in 3 days \
    --targets-version 63 \
    --targets-expires in 7 days \
    --timestamp-version 593 \
    --timestamp-expires in 1 day \
    --role targets \
    --incoming-metadata targets/with/extra/role1/key \
    --outdir metadata/with/updated/role1/keys \
    --root path/to/root.json \
    --metadata-url path/to/metadata
  10. Remove a delegated role using tuftool

    develop

    To remove a delegated role from a parent role, use the tuftool delegation add-key command (as shown in the example, this appears to be the mechanism for modifying the delegation structure) or the relevant removal command to strip the delegation. After the delegation is removed, you must run tuftool update for the parent role to update the repository metadata.

    # Remove role1 from targets
    tuftool delegation --signing-role targets add-key \
    --key path/to/repo/owner/key \
    --delegated-role role1 \
    --expires in 2 days \
    --version 63 \
    --outdir targets/with/removed/role1/key \
    --root path/to/root.json \
    --metadata-url path/to/metadata
    
    # Update the repository with the new targets metadata
    tuftool update \
    --key path/to/repo/owner/key \
    --snapshot-version 74 \
    --targets-version 63 \
    --targets-expires in 7 days \
    --timestamp-version 593 \
    --timestamp-expires in 1 day \
    --role targets \
    --incoming-metadata targets/with/removed/role1/key \
    --outdir metadata/with/updated/role1/keys \
    --root path/to/root.json \
    --metadata-url path/to/metadata