Skip to content

Instantly share code, notes, and snippets.

@erickt
Last active July 30, 2018 17:04
Show Gist options
  • Save erickt/2b65ed09f6d9d7c42f172751d3f39e44 to your computer and use it in GitHub Desktop.
Save erickt/2b65ed09f6d9d7c42f172751d3f39e44 to your computer and use it in GitHub Desktop.

Revisions

  1. erickt revised this gist Jul 30, 2018. 1 changed file with 24 additions and 0 deletions.
    24 changes: 24 additions & 0 deletions tuf.rs
    Original file line number Diff line number Diff line change
    @@ -79,4 +79,28 @@
    .flatten();

    Box::new(updated)
    }

    /// Returns `true` if an update occurred and `false` otherwise.
    fn update_timestamp<V, U>(&self, repo: &mut V, config: &Config<U>) -> Result<TufFuture<bool>>
    where
    V: Repository<D>,
    U: PathTranslator,
    {
    let tuf = self.tuf.clone();

    let ts = repo
    .fetch_metadata(
    &MetadataPath::from_role(&Role::Timestamp),
    &MetadataVersion::None,
    config.max_timestamp_size,
    config.min_bytes_per_second,
    None,
    )
    .and_then(move |ts| {
    let mut tuf = tuf.lock().expect("poisoned lock");
    tuf.update_timestamp(&ts)
    });

    Ok(Box::new(ts))
    }
  2. erickt created this gist Jul 30, 2018.
    82 changes: 82 additions & 0 deletions tuf.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,82 @@
    /// Returns `true` if an update occurred and `false` otherwise.
    fn update_root<V, U>(&self, repo: Arc<V>, config: &Config<U>) -> TufFuture<bool>
    where
    V: Repository<D> + 'static,
    U: PathTranslator,
    {
    let err_msg = "TUF claimed no update occurred when one should have. \
    This is a programming error. Please report this as a bug.";

    let tuf = self.tuf.clone();
    let max_root_size = config.max_root_size;
    let min_bytes_per_second = config.min_bytes_per_second;

    let updated =
    repo.fetch_metadata(
    &MetadataPath::from_role(&Role::Root),
    &MetadataVersion::None,
    max_root_size,
    min_bytes_per_second,
    None,
    )
    .and_then(move |latest_root| {
    let latest_version =
    D::deserialize::<RootMetadata>(latest_root.signed())?.version();

    let root_version = {
    let tuf = tuf.lock().expect("poisoned lock");
    tuf.root().version()
    };

    if latest_version < root_version {
    return Err(Error::VerificationFailure(format!(
    "Latest root version is lower than current root version: {} < {}",
    latest_version, root_version,
    )));
    } else if latest_version == root_version {
    return Ok(Either::A(future::ok(false)));
    }

    let mut updated_roots = Vec::new();
    for i in (root_version + 1)..latest_version {
    let tuf = tuf.clone();

    updated_roots.push(
    repo
    .fetch_metadata(
    &MetadataPath::from_role(&Role::Root),
    &MetadataVersion::Number(i),
    max_root_size,
    min_bytes_per_second,
    None,
    )
    .map(move |signed| {
    let mut tuf = tuf.lock().expect("poisoned lock");

    if !tuf.update_root(&signed)? {
    error!("{}", err_msg);
    return Err(Error::Programming(err_msg.into()));
    }

    Ok(())
    }),
    );
    }

    Ok(Either::B(future::join_all(updated_roots).and_then(
    move |_| {
    let mut tuf = tuf.lock().expect("poisoned lock");

    if !tuf.update_root(&latest_root)? {
    error!("{}", err_msg);
    return Err(Error::Programming(err_msg.into()));
    }

    Ok(true)
    }
    )))
    })
    .flatten();

    Box::new(updated)
    }