Giter Site home page Giter Site logo

tough's Introduction

tough

tough is a Rust client library for The Update Framework (TUF) repositories.

tuftool is a Rust command-line utility for generating and signing TUF repositories.

Integration Testing

Integration tests require, noxious, which is installed when running make integ.

Documentation

See tough - Rust for the latest tough library documentation.

See tuftool's README for more on how to use tuftool.

License

tough is licensed under the Apache License, Version 2.0 or the MIT license, at your option.

tough's People

Contributors

bcressey avatar cbgbt avatar dependabot-preview[bot] avatar dependabot[bot] avatar ecpullen avatar erickt avatar etungsten avatar flavio avatar iliana avatar jon-zu avatar jpculp avatar jpmcb avatar kdnakt avatar mchaker avatar morenol avatar nealmcb avatar phu-cinemo avatar rdimitrov avatar rpkelly avatar sam-aws avatar sanu11 avatar shepmaster avatar srgothi92 avatar stmcginnis avatar stockholmux avatar sunshowers avatar tjkirch avatar webern avatar xynnn007 avatar zmrow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tough's Issues

Move build_targets and process_target to tough

I found when using tough to build a repository with the new RepositoryEditor (in the absence of tuftool) that when I really wanted these functions in tough.

// Walk the directory specified, building a map of filename to Target structs.
// Hashing of the targets is done in parallel
fn build_targets<P>(indir: P, follow_links: bool) -> Result<HashMap<String, Target>>
where
    P: AsRef<Path>,
{
    let indir = indir.as_ref();
    WalkDir::new(indir)
        .follow_links(follow_links)
        .into_iter()
        .par_bridge()
        .filter_map(|entry| match entry {
            Ok(entry) => {
                if entry.file_type().is_file() {
                    Some(process_target(entry.path()))
                } else {
                    None
                }
            }
            Err(err) => Some(Err(err).context(error::WalkDir { directory: indir })),
        })
        .collect()
}

fn process_target(path: &Path) -> Result<(String, Target)> {
    // Build a Target from the path given. If it is not a file, this will fail
    let target = Target::from_path(path).context(error::TargetFromPath { path })?;

    // Get the file name as a string
    let target_name = path
        .file_name()
        .context(error::NoFileName { path })?
        .to_str()
        .context(error::PathUtf8 { path })?
        .to_owned();
    Ok((target_name, target))
}

`tuftool download` does not truncate existing files

If you tuftool download from one repo into a directory, then tuftool download another repo into the same directory, and those repos share a target filename, then the second file will be written over the first without the truncate flag.

This means you can see the full contents of the file from the second repo, then the remainder of the contents of the file from the first repo, starting at the byte number matching the length of the file from the second repo. I saw exactly this when downloading two Bottlerocket repos, since "manifest.json" is common to each.

Develop a benchmark for `Repository::read_target`

We've noticed some possible slowness fetching targets from what should be reasonably fast transports. It'd be nice to set up a benchmark (full end-to-end would be ideal, but it's probably easiest to bench the Read adapters).

Testing file for example tuftool commands

We have documentation with examples for using tuftool, but no guarantee that the examples continue to stay updated. We should add a test file containing the example commands so that the documentation remains updated.

tough-kms: Add Support for key create

I would like to use tuftool and generate tough-kms key programmatically and add it to root.json.

Dev Comments:
Currently, tough-ssm and LocalKeySource supports key generation using openssl. An attempt was made by exposing a create method in KeySource trait and let KeySource implementer generate key. But this involved moving openssl key generation to tough crate as default implementation of create which has security concerns. Find a new way to implement generate.

Add method for saving metadata relevant to a set of targets

I'd like to fetch a target from a TUF repo, store it locally, and also store with it the metadata necessary to form the trust chain from my trusted root metadata file to that target. This would allow me to continue using the target in a trusted way when a machine has not yet configured networking, for instance.

  • Store the root.json trust chain
  • Add a method that returns the set of metadata required to verify a set of targets

What my brain thinks might be a good interface for this right now:

fn metadata_chain(
    &self,
    targets: impl Iterator<Item = impl AsRef<str>>
) -> impl Iterator<Item = (String, Signed<Box<dyn Role>>)>

This is incredibly unwieldy and needs some work :)

tuftool: feature to dump stats

As mentioned by @bcressey

We should have a way to track these sizes over time so we'll know if we're getting close to any of these limits. Maybe a tuftool feature to dump stats.

That is, we should have a tuftool feature to dump the size stats as they relate to REPOSITORY_LIMITS. That way when we use tuftool we can make sure Bottlerocket repos are not approaching the size limits.

Move functionality out of tuftool into a library

When it comes to interacting and updating TUF repos, quite a bit of useful functionality is still contained in tuftool and isn't usable by outside code. This functionality should be put in a library.

Right off the bat I can see a few functions that should be split out:

  • tuftool/src/create.rs : write_metadata() : This function takes a role, computes its SHA/length, signs it, and writes it to the TUF output directory
  • tuftool/src/create.rs : process_target() : Given a &Path, this function computes its SHA/length, builds a Target object, and writes the file to the appropriate TUF output directory.
  • tuftool/src/source.rs : KeySource.read() : Fetching / parsing signing keys is necessary to sign a repo.
  • tuftool/src/key.rs: keys_for_root() : Given a signing key, get the appropriate root keys.
  • tuftool/src/key.rs : sign_metadata_inner() : This function does some crucial parsing root.json to get the proper keys to use to actually sign.

Add logging

With logging output, some types of issues would be easier to debug, and some outstanding events can be noted, for example removal of datastore files upon rotation.

`fn run` in tuftool/src/root.rs is long

    Checking tuftool v0.1.0 (/home/ec2-user/tough/tuftool)
warning: This function has a large number of lines.
   --> tuftool/src/root.rs:103:5
    |
103 | /     pub(crate) fn run(&self) -> Result<()> {
104 | |         match self {
105 | |             Command::Init { path } => write_file(
106 | |                 path,
...   |
231 | |         }
232 | |     }
    | |_____^
    |
note: lint level defined here
   --> tuftool/src/main.rs:5:9
    |
5   | #![warn(clippy::pedantic)]
    |         ^^^^^^^^^^^^^^^^
    = note: `#[warn(clippy::too_many_lines)]` implied by `#[warn(clippy::pedantic)]`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines

(Adding an #[allow] but opening this to track fixing it.)

fetch/io functions cleanup

Parameter ordering for functions in the fetch and io modules could use a refactor.

I think I want to fix these by dropping fn new since this is all internal code anyway.

HTTP retries

On connection resets, the Reader should retry the HTTP connection for the rest of the range (similar to wget’s default behavior).

Document a minimal tuftool use case

Per the discussion in #1, we should have a minimal example of how one can use tuftool to create a working tuf repository with some targets in it. This should probably go in tuftool's README. Currently I believe users need to dive into our test cases to try and figure out how to use the program.

SignedRepository: link/copy targets without consistent snapshot can overwrite

The target_path function in SignedRepository handles consistency checks when the target is known to the repo -- if the hash doesn't match, we refuse to continue. However, if you're using link/copy_targets to write targets for multiple repos into a single directory, and they have a target with the same name but different contents, and you're not using consistent snapshots, then the later-written file will overwrite the earlier one.

Ideally everyone uses consistent snapshots, or if they don't then they know not to share target names, but this is still a sharp corner if you do meet those conditions. We have the information we'd need to cause an error in this case. If the target path exists, checksum it - on match, we don't need to do anything; on failure, error out. (Note: the ring code we use to sha256 the role probably shouldn't be used for this; it would have to read the whole target into memory, and they could be any size.)

Figure out how to make hash types forward compatible

From an early code review:

Choosing only sha256 for Hashes means other users of the library can't choose other hashes without getting a deserialization error, right? Say we do this now, and get requests later to support the other TUF-supported hashes; would we be stuck, or would it be a backwards-compatible addition for sha256 users?

Consider making sha256 an Option<Decoded<Hex>> and providing code for making that easy to use throughout the library.

This is harder than just changing the internals, because the pub Target struct currently provides the hash information. Maybe it doesn't need to in order to be useful, since this library provides hash checking.

tuftool produces broken symlinks

tuftool's default mode creates symlinks to targets, but does not correctly handle the relative paths. So it only works if in_dir and out_dir both have the same parent, and the symlinks are broken otherwise.

This code needs to be fixed to do something similar to ln -r:

match self {
Copylike::Copy => fs::copy(src, dst).map(|_| ()),
Copylike::Hardlink => fs::hard_link(src, dst),
Copylike::Symlink => {
#[cfg(unix)]
{
std::os::unix::fs::symlink(src, dst)
}
#[cfg(windows)]
{
std::os::windows::fs::symlink_file(src, dst)
}
}
}

Provide access to the fetched metadata

Add root, snapshot, and timestamp methods to Repository to return references to the underlying signed metadata, and change targets to do the same, to permit consumers to make small changes to the metadata and re-sign it (such as adding a single target).

Enable Integration Tests in CI

As part of the work to add (and test) HTTP retries in #143, we added a test test_retries, in tough/tests/http.rs, which is #[ignored] in CI and used only for local development. We should enable it and get it to work in CI.

Docker exists on the CI runner, but on a first attempt, the test failed:

thread 'http_tests::test_retries' panicked at 'called `Result::unwrap()` on an `Err` value:
Transport { url: "http://localhost:3000/metadata/timestamp.json", source: HttpRetries { 
url: "http://localhost:3000/metadata/timestamp.json", tries: 9999, source: reqwest::Error { 
kind: Request, url: "http://localhost:3000/metadata/timestamp.json", source: 
hyper::Error(Connect, ConnectError("tcp connect error", Os { 
code: 111, kind: ConnectionRefused, message: "Connection refused" })) } }

This probably has something to do with networking, or not waiting long enough for the proxies to come up: needs further investigation.

Also, as @iliana suggests, we should create a 'feature' for the integ tests.
#143 (comment)

And document how to run them.

tough/schema: Determine the fate of `RoleType`

/// The type of metadata role.
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "kebab-case")]
pub enum RoleType {
/// The root role delegates trust to specific keys trusted for all other top-level roles used in
/// the system.
Root,
/// The snapshot role signs a metadata file that provides information about the latest version
/// of all targets metadata on the repository (the top-level targets role and all delegated
/// roles).
Snapshot,
/// The targets role's signature indicates which target files are trusted by clients.
Targets,
/// The timestamp role is used to prevent an adversary from replaying an out-of-date signed
/// metadata file whose signature has not yet expired.
Timestamp,
/// A delegated targets role
DelegatedTargets,
}

RoleType is used in a lot of places, and for some of those the DelegatedTargets role isn't a good fit. For instance:

$ tuftool root add-key ~/tmp/root.json aws-kms:///[removed] -r snaphsot
error: Invalid value for '--role <roles>...': unknown variant `snaphsot`, expected one of `root`, `snapshot`, `targets`, `timestamp`, `delegated-targets`

DelegatedTargets isn't a type of role that should be defined in root.json, so we might need a clearer distinction in our type model.

tuftool: present an error when creating an un-loadable tuf repo

This has similar intent to #119, which is that we could make it harder to use tuftool incorrectly.

It is possible to use tuftool create with a root.json that can never be satisfied. For example, if I have zero keys for the targets role while specifying a threshold for the same role greater than zero.

Maybe tuftool create should inspect the sanity of root.json before proceeding, and error out if root.json would make the created repo unusable.

Switch to async / std::future::Future across codebase

tough-ssm creates its own tokio runtime because it needs to use the rusoto which is async. However, this causes a problem if you're trying to use tough-ssm anywhere else that is async... (because multiple runtimes)

We've seen errors like this:

...
thread 'main' panicked at 'Cannot start a runtime from within a runtime. 
This happens because a function (like `block_on`) attempted to block the current thread 
while the thread is being used to drive asynchronous tasks.', 
...

We should probably change the KeySource trait to be async using the async-trait crate

Figure out something better than an `_extra` struct member

tough::schema struct types have an _extra member:

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct RoleKeys {
pub keyids: Vec<Decoded<Hex>>,
pub threshold: NonZeroU64,
/// Extra arguments found during deserialization.
///
/// We must store these to correctly verify signatures for this object.
///
/// If you're instantiating this struct, you should make this `HashMap::empty()`.
#[serde(flatten)]
pub _extra: HashMap<String, Value>,
}

This is to handle keys that tough doesn't know about (yet), while still correctly validating signatures during serialization.

It'd be nice if consumers can create these structs without having to specify _extra: HashMap::new() or ..Default::default(). Not sure if there's any type magick we can perform.

tuftool's native-tls/rustls switch doesn't affect reqwest

We have:

tough/tuftool/Cargo.toml

Lines 11 to 15 in 9ac95c8

[features]
default = ["rusoto"]
rusoto = ["rusoto-rustls"]
rusoto-native-tls = ["rusoto_core/native-tls", "rusoto_credential", "rusoto_ssm/native-tls"]
rusoto-rustls = ["rusoto_core/rustls", "rusoto_credential", "rusoto_ssm/rustls"]

but we also depend on reqwest, and we aren't switching which TLS implementation it uses.

Ideally I'd like to be able to enable/disable rusoto_ssm and switch between native-tls and rustls separately but I don't know if that's possible.

tuftool: Present error when signing would result in an empty signatures array

I recently tried to sign a root.json metadata file using tuftool with a call that looks like this:

tuftool sign root.json --root root.json --key fake-key.pem

Where the root.json file looked like this (below). Note that there are no key ids for roles.root.keyids.

The program silently did nothing. Instead I think the program should raise an error, or at least a warning, saying that it did not find any keys to sign with. Basically if a call to tuftool sign will result in an empty signatures array, then it is probably not what the user wants. A message to guide the user to the issue at hand would be helpful.

{
  "signed": {
    "_type": "root",
    "expires": "2020-05-17T00:00:00Z",
    "keys": {
      "35830956c27885ab8171a39421ffa6b582c8a71ce4c90aeb56db3f2ba67ad687": {
        "keytype": "rsa",
        "keyval": {
          "public": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0gEKoHTJaM3V4UE65S97\nfNvjS1bGamiGyi+/BZs2igW20navFjv6z+MsDgn//yufeobRr7/zFToDerIDyh3B\nue6lobo63hr0Q2DvtbGjuSa9a6imhXZLJRZ60NDNDMVGvGo65N0TBeOpSjBHBS3T\nl2WnvySQo16vn9IRc/Z+JeMftos81MTqW7Z2DasklTpuwelT8ou+K73QQiuDIreP\nXd7iItV/mZlumdRIklsEMVjPCARhd9nmC2CkZdurpXE4A0TPO1TOQ8wxw8ppqHbY\nJD2bupVRAA2jdgIi5vCouavJtmdGN8odMAkklkcmYBdYemJMy31eBvGzoPGiL7S2\n+wIDAQAB\n-----END PUBLIC KEY-----"
        },
        "scheme": "rsassa-pss-sha256"
      },
      "52112779ef03cced90fc7fb75f04262f85fc5f3caea7e09f09c30b8aad2e4bce": {
        "keytype": "rsa",
        "keyval": {
          "public": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2DNMuckhFIwkY4nhQqBN\nQ7Mqp9U/vQYSfgudF0KSEcQ/pE8HocZfh07vNz9M9M2aZd0aCma5S1gy9XmFZSTB\nk6aImiZpcKQ0eqow2WNZ84XeOpbDErHXJAgYKvq6cjYdRPkrR+jeErpAqn6lgcT4\nPH9AYJ2iAC6z4R3kwWxjqmbtzzUqgTP34wYcDyQNEh2rERuJ0dYT50s4Xa8yN+pE\nbB8forMGLUEYr44izQRuebkBZ+THMaIRqfhIjXHQbYJ0eYJEagtez3U2nB5LDDbd\nv33zFdsjsKRf9U+R9RULqfW0+x2Ya2CG3gtd+vAki7hYqIB4l0KVE1OtmXANSvHW\nHwIDAQAB\n-----END PUBLIC KEY-----"
        },
        "scheme": "rsassa-pss-sha256"
      },
      "86679d5b458c68f838d6fbbb26671a3b4b0376ef8292af0d8bd292c2035ae7c1": {
        "keytype": "rsa",
        "keyval": {
          "public": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwsfmRrCVggfEYYWD4NG0\n22UmSminR5J/+z9ribN+MtPeAemr0nFnJ3MFLinM4skH4+dOjEAZzLUvF+Wp+Pi7\n5SGlVBwX1Fdx1CatPEQ8oApfcpt+aId1bdSyzJ3/Zlhy0jgJudIMH4APv5hCImaR\niKQZixNIzZR8OG/tt16GaX1K+wZKoIiAuI8fw791wi92K9FL75rWF9rJ2PRS1htk\n9/yC/J2aPH5rJ0JWgh7dqjn/nA3mmMxPBCgC3FFk+8VPWRVZoS5LiYp3M7i68ckm\n99lYF3AO8Gekvro8XTIVbZy40aPk8vlM8gTpxXfuvR5EMPuD7f77IiLPS4cdFjqS\nuQIDAQAB\n-----END PUBLIC KEY-----"
        },
        "scheme": "rsassa-pss-sha256"
      },
      "94d0a1fe2cc32db21bf9c3f01ca8b2315ab6423306f103398d9f795032351cc7": {
        "keytype": "rsa",
        "keyval": {
          "public": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0I8psiWY40W1VE5p1pjz\nUiKWb0ecDTx6GiVpPZ+iLR4SfLmtfxVTt77+GPp/fbRVXE03SmUy+kI1zCngcS8n\nKnvhrp+s0AEKTQ1OTsYJX+ZvbiC7vrOTdQ8ZkUdVayQ05jdLO4SUSI0wpOd4L2ze\nUIMKLYtjeEogDLpTshTSmArUBJBLa7n33B1q3jQVbIEXSSw9q+3ednfxTVAUkcmc\nK3cdVtod5hLFUApED7S+DDoOf/7WcgyWQ7pFvdnt43PMdLnV//mVTfAW7mgJn1Dy\nMr+d6lEVEPnR0s9c+9AT/1ore3Mj2O3zdZtiMDZ8BZm+MxZk437EkAO0RaUif8pY\ngwIDAQAB\n-----END PUBLIC KEY-----"
        },
        "scheme": "rsassa-pss-sha256"
      },
      "e4dbdeea4cafe062b30878c258472bfa2a5acc574e9f310303acd90026300be7": {
        "keytype": "rsa",
        "keyval": {
          "public": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1AUu9TJl/BOEaOZrrXDd\nSteAW2hnifarXQXQHvuZREzhVDnT/LuL5rxRQYCEmIAWQHtgddSTQ/w2GkSv2UH1\n4pmvRW+nDF3HHzN9jlO/eI3lWGYr/ayTnbFDyO7XgUh+IkxOqdg+kj5VmvlOR3qO\nc0EQVnBI6gvd8KOnM7Nl+g4kY75zp3zteQ20SrMArfvzd8jbM+J4sGS33LiVEahX\noQMcBN2l9RV7CUNHlWX2mtb4vRVCoi5xAzvEs6Y0kmpuUSxU5MtlQufTYvgThLzR\nlck+l3i6xFwmjC/qf+gFYfcBMmkNAp8tuw2LslpJytF/GNPFOHX+/eq8T9PSwLR3\nCwIDAQAB\n-----END PUBLIC KEY-----"
        },
        "scheme": "rsassa-pss-sha256"
      }
    },
    "spec_version": "1.0.0",
    "version": 1,
    "consistent_snapshot": true,
    "roles": {
      "root": {
        "keyids": [],
        "threshold": 1
      },
      "snapshot": {
        "keyids": [
          "94d0a1fe2cc32db21bf9c3f01ca8b2315ab6423306f103398d9f795032351cc7"
        ],
        "threshold": 1
      },
      "targets": {
        "keyids": [
          "35830956c27885ab8171a39421ffa6b582c8a71ce4c90aeb56db3f2ba67ad687"
        ],
        "threshold": 1
      },
      "timestamp": {
        "keyids": [
          "52112779ef03cced90fc7fb75f04262f85fc5f3caea7e09f09c30b8aad2e4bce"
        ],
        "threshold": 1
      }
    }
  },
  "signatures": []
}

tuftool should be able to update an existing repository

tuftool can already refresh metadata for an existing repository. It should have the ability to add targets and re-sign the metadata for an existing repository.

I see this as having mostly the same interface as refresh, except with an extra argument --new-targets which is where we'll find any new targets.

Add ability to load a tuf repo while ignoring expiration dates

In our use case for Bottlerocket signed migrations, bottlerocket-os/bottlerocket#905, we want to ignore (or possibly extend) the expiration dates in the TUF metadata. Our reasoning is that it is better, and safe-enough, to do so then to perhaps have a Bottlerocket host fail to upgrade because an expiration occurred between the time the targets were cached locally and the time the restart occurs (when the cached repo must be used without network access).

@iliana has previously proposed using the type-system to indicate when a repo is being used in an unsafe state.

For alternatives considered, see the Bottlerocket issue linked above.

Documentation for Delegated Targets

Delegated targets add some complexity to the workflow of the RepositoryEditor it would be nice to have a DelegatedTargets.md to describe how users with different key access should use RepositoryEditor and TargetsEditor.

tuftool: add root cross-signing support

While working on #207, I discovered that tuftool root sign can only create self-signed signatures. This is normally fine if you're creating a brand new root, but if your current root is expiring and you wish to rotate out ≥ N − 1 keys (where N is the previous root's root signature threshold), you need to sign the new root with a key not defined in it.

Because tough needs the root.json to look up the key ID for a provided key source, it can't find the key ID for older keys, and I think this is what's preventing cross-signing from happening.

This might actually be a regression (I think) from previous versions of tuftool, where tuftool sign was a top-level command capable of signing any particular role. tuftool sign 2.root.json --root 1.root.json would perform key ID lookups from 1.root.json, then sign 2.root.json (at least in theory, didn't try it myself...).

There's two possible paths here, and I propose we take both:

  • Add an option to tuftool root sign that allows providing an alternate root role to look up key IDs from. This option would probably be called something similar to "cross-sign" to indicate why it's there.
  • Add some mechanism of manually specifying the key ID and permitted uses of a key source that would override any lookup from the root.json. This is a larger-scope escape hatch that can be used in other potential situations (most of which we may not understand or realize yet) to prevent needing to ever manually sign a role. The downside of this path is that it's easy to create an invalid signature or sign a role with a key not defined in any root role, which is why if we choose to do it, it should be in addition to a more explicit cross-sign option.

Unify file naming logic

Currently whenever a user must refer to a file for a role or target, they must build the filename using the version or, in the case of targets, the sha256. We should unify this naming in a single place.

tough/tough/src/lib.rs

Lines 780 to 784 in abb33f5

let path = if root.signed.consistent_snapshot {
format!("{}.targets.json", targets_meta.version)
} else {
"targets.json".to_owned()
};

We have this naming logic in 4 places now, maybe we should do it in one place? (tuftool/tests/refresh_command, Repository::*target_digest_and_filename, lib::load_targets, and now here)

Originally posted by @tjkirch in #125

Create test cases for root.json rotation

We need to add test cases to ensure root key rollovers are possible.

  • 1.root.json should list key A and be signed by key A
  • 2.root.json should list key B and be signed by keys A and B
  • other metadata should be signed by key B
  • Repository::load() should work when loaded from 1.root.json, and the version returned by root() should be 2

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.