/// Verify and update the snapshot metadata.
Verify and update the snapshot metadata.
Verify and update the snapshot metadata .
pub fn update_snapshot(
        &mut self,
        raw_snapshot: &RawSignedMetadata<D, SnapshotMetadata>,
    ) -> Result<bool> {
        let verified = {
            /////////////////////////////////////////
            // FIXME(https://github.com/theupdateframework/specification/issues/113) Checking if
            // this metadata expired isn't part of the spec. Do we actually want to do this?
            let trusted_root = self.trusted_root_unexpired()?;
            let trusted_timestamp = self.trusted_timestamp_unexpired()?;
            let trusted_snapshot_version = self.trusted_snapshot_version();
            match trusted_timestamp
                .snapshot()
                .version()
                .cmp(&trusted_snapshot_version)
            {
                Ordering::Less => {
                    return Err(Error::VerificationFailure(format!(
                        "Attempted to roll back snapshot metadata at version {} to {}.",
                        trusted_snapshot_version,
                        trusted_timestamp.snapshot().version()
                    )));
                }
                Ordering::Equal => {
                    return Ok(false);
                }
                Ordering::Greater => {}
            }
            /////////////////////////////////////////
            // TUF-1.0.5 §5.3.1:
            //
            //     Check against timestamp metadata. The hashes and version number of the new
            //     snapshot metadata file MUST match the hashes (if any) and version number listed
            //     in the trusted timestamp metadata. If hashes and version do not match, discard
            //     the new snapshot metadata, abort the update cycle, and report the failure.
            // FIXME: rust-tuf checks the hash during download, but it would be better if we
            // checked the hash here to make it easier to validate we've correctly implemented the
            // spec.
            // NOTE(https://github.com/theupdateframework/specification/pull/112): Technically
            // we're supposed to check the version before checking the signature, but we do it
            // afterwards. That PR proposes formally moving the version check to after signature
            // verification.
            /////////////////////////////////////////
            // TUF-1.0.5 §5.3.2:
            //
            //     The new snapshot metadata file MUST have been signed by a threshold of keys
            //     specified in the trusted root metadata file. If the new snapshot metadata file
            //     is not signed as required, discard it, abort the update cycle, and report the
            //     signature failure.
            let new_snapshot = verify::verify_signatures(
                raw_snapshot,
                trusted_root.snapshot().threshold(),
                trusted_root.snapshot_keys(),
            )?;
            /////////////////////////////////////////
            // FIXME(https://github.com/theupdateframework/specification/pull/112): Actually check
            // the version.
            if new_snapshot.version() != trusted_timestamp.snapshot().version() {
                return Err(Error::VerificationFailure(format!(
                    "The timestamp metadata reported that the snapshot metadata should be at \
                     version {} but version {} was found instead.",
                    trusted_timestamp.snapshot().version(),
                    new_snapshot.version(),
                )));
            }
            /////////////////////////////////////////
            // TUF-1.0.5 §5.3.3: Check for a rollback attack.
            /////////////////////////////////////////
            // TUF-1.0.5 §5.3.3.1:
            //
            //     The version number of the trusted snapshot metadata file, if any, MUST be less
            //     than or equal to the version number of the new snapshot metadata file. If the
            //     new snapshot metadata file is older than the trusted metadata file, discard it,
            //     abort the update cycle, and report the potential rollback attack.
            if new_snapshot.version() < trusted_snapshot_version {
                return Err(Error::VerificationFailure(format!(
                    "Attempted to roll back snapshot metadata at version {} to {}",
                    trusted_snapshot_version,
                    new_snapshot.version(),
                )));
            }
            /////////////////////////////////////////
            // TUF-1.0.5 §5.3.3.2:
            //
            //     The version number of the targets metadata file, and all delegated targets
            //     metadata files (if any), in the trusted snapshot metadata file, if any, MUST be
            //     less than or equal to its version number in the new snapshot metadata file.
            //     Furthermore, any targets metadata filename that was listed in the trusted
            //     snapshot metadata file, if any, MUST continue to be listed in the new snapshot
            //     metadata file. If any of these conditions are not met, discard the new snapshot
            //     metadadata file, abort the update cycle, and report the failure.
            // FIXME(#295): Implement this section.
            /////////////////////////////////////////
            // TUF-1.0.5 §5.3.4:
            //
            //     Check for a freeze attack. The latest known time should be lower than the
            //     expiration timestamp in the new snapshot metadata file. If so, the new snapshot
            //     metadata file becomes the trusted snapshot metadata file. If the new snapshot
            //     metadata file is expired, discard it, abort the update cycle, and report the
            //     potential freeze attack.
            /////////////////////////////////////////
            // FIXME(#297): Verify why we don't check expiration here:
            // Note: this doesn't check the expiration because we need to be able to update it
            // regardless so we can prevent rollback attacks againsts targets/delegations.
            new_snapshot
        };
        // FIXME(#297): purging targets is not part of the spec. Do we need to do it?
        if self
            .trusted_targets
            .as_ref()
            .map(|s| s.version())
            .unwrap_or(0)
            != verified
                .meta()
                .get(&MetadataPath::from_role(&Role::Targets))
                .map(|m| m.version())
                .unwrap_or(0)
        {
            self.trusted_targets = None;
        }
        self.trusted_snapshot = Some(verified);
        // FIXME(#297): purging delegates is not part of the spec. Do we need to do it?
        self.purge_delegations();
        Ok(true)
    }
pub fn update_snapshot ( & mut self , raw_snapshot : & RawSignedMetadata < D , SnapshotMetadata > , ) -> Result < bool > { let verified = { ///////////////////////////////////////// // FIXME(https://github.com/theupdateframework/specification/issues/113) Checking if // this metadata expired isn't part of the spec. Do we actually want to do this? let trusted_root = self . trusted_root_unexpired ( ) ? ; let trusted_timestamp = self . trusted_timestamp_unexpired ( ) ? ; let trusted_snapshot_version = self . trusted_snapshot_version ( ) ; match trusted_timestamp . snapshot ( ) . version ( ) . cmp ( & trusted_snapshot_version ) { Ordering :: Less => { return Err ( Error :: VerificationFailure ( format ! ( " " trusted_snapshot_version trusted_timestamp snapshot ( ) version ( ) ) ) ) ; } Ordering :: Equal => { return Ok ( false ) ; } Ordering :: Greater => { } } ///////////////////////////////////////// // TUF-1.0.5 §5.3.1: // //     Check against timestamp metadata. The hashes and version number of the new //     snapshot metadata file MUST match the hashes (if any) and version number listed //     in the trusted timestamp metadata. If hashes and version do not match, discard //     the new snapshot metadata, abort the update cycle, and report the failure. // FIXME: rust-tuf checks the hash during download, but it would be better if we // checked the hash here to make it easier to validate we've correctly implemented the // spec. // NOTE(https://github.com/theupdateframework/specification/pull/112): Technically // we're supposed to check the version before checking the signature, but we do it // afterwards. That PR proposes formally moving the version check to after signature // verification. ///////////////////////////////////////// // TUF-1.0.5 §5.3.2: // //     The new snapshot metadata file MUST have been signed by a threshold of keys //     specified in the trusted root metadata file. If the new snapshot metadata file //     is not signed as required, discard it, abort the update cycle, and report the //     signature failure. let new_snapshot = verify :: verify_signatures ( raw_snapshot , trusted_root . snapshot ( ) . threshold ( ) , trusted_root . snapshot_keys ( ) , ) ? ; ///////////////////////////////////////// // FIXME(https://github.com/theupdateframework/specification/pull/112): Actually check // the version. if new_snapshot . version ( ) != trusted_timestamp . snapshot ( ) . version ( ) { return Err ( Error :: VerificationFailure ( format ! ( " \
 " trusted_timestamp snapshot ( ) version ( ) new_snapshot version ( ) ) ) ) ; } ///////////////////////////////////////// // TUF-1.0.5 §5.3.3: Check for a rollback attack. ///////////////////////////////////////// // TUF-1.0.5 §5.3.3.1: // //     The version number of the trusted snapshot metadata file, if any, MUST be less //     than or equal to the version number of the new snapshot metadata file. If the //     new snapshot metadata file is older than the trusted metadata file, discard it, //     abort the update cycle, and report the potential rollback attack. if new_snapshot . version ( ) < trusted_snapshot_version { return Err ( Error :: VerificationFailure ( format ! ( " " trusted_snapshot_version new_snapshot version ( ) ) ) ) ; } ///////////////////////////////////////// // TUF-1.0.5 §5.3.3.2: // //     The version number of the targets metadata file, and all delegated targets //     metadata files (if any), in the trusted snapshot metadata file, if any, MUST be //     less than or equal to its version number in the new snapshot metadata file. //     Furthermore, any targets metadata filename that was listed in the trusted //     snapshot metadata file, if any, MUST continue to be listed in the new snapshot //     metadata file. If any of these conditions are not met, discard the new snapshot //     metadadata file, abort the update cycle, and report the failure. // FIXME(#295): Implement this section. ///////////////////////////////////////// // TUF-1.0.5 §5.3.4: // //     Check for a freeze attack. The latest known time should be lower than the //     expiration timestamp in the new snapshot metadata file. If so, the new snapshot //     metadata file becomes the trusted snapshot metadata file. If the new snapshot //     metadata file is expired, discard it, abort the update cycle, and report the //     potential freeze attack. ///////////////////////////////////////// // FIXME(#297): Verify why we don't check expiration here: // Note: this doesn't check the expiration because we need to be able to update it // regardless so we can prevent rollback attacks againsts targets/delegations. new_snapshot } ; // FIXME(#297): purging targets is not part of the spec. Do we need to do it? if self . trusted_targets . as_ref ( ) . map ( | s | s . version ( ) ) . unwrap_or ( 0 ) != verified . meta ( ) . get ( & MetadataPath :: from_role ( & Role :: Targets ) ) . map ( | m | m . version ( ) ) . unwrap_or ( 0 ) { self . trusted_targets = None ; } self . trusted_snapshot = Some ( verified ) ; // FIXME(#297): purging delegates is not part of the spec. Do we need to do it? self . purge_delegations ( ) ; Ok ( true ) }
Verify and update the snapshot metadata.
Verify and update the snapshot metadata .
&mut self
raw_snapshot
&RawSignedMetadata<D, SnapshotMetadata>