fn sign()

in tuftool/src/root.rs [306:400]


    fn sign(
        path: &Path,
        key_source: &[Box<dyn KeySource>],
        cross_sign: Option<PathBuf>,
        ignore_threshold: bool,
    ) -> Result<()> {
        let root: Signed<Root> = load_file(path)?;
        // get the root based on cross-sign
        let loaded_root = match cross_sign {
            None => root.clone(),
            Some(cross_sign_root) => load_file(&cross_sign_root)?,
        };
        // sign the root
        let mut signed_root = SignedRole::new(
            root.signed.clone(),
            &KeyHolder::Root(loaded_root.signed),
            key_source,
            &SystemRandom::new(),
        )
        .context(error::SignRootSnafu { path })?;

        // append the existing signatures if present
        if !root.signatures.is_empty() {
            signed_root = signed_root
                .add_old_signatures(root.signatures)
                .context(error::SignRootSnafu { path })?;
        }

        // Quick check that root is signed by enough key IDs, in all its roles.
        for (roletype, rolekeys) in &signed_root.signed().signed.roles {
            let threshold = rolekeys.threshold.get();
            let keyids = rolekeys.keyids.len();
            if threshold > keyids as u64 {
                // Return an error when the referenced root.json isn't compliant with the
                // threshold. The referenced file could be a root.json used for cross signing,
                // which wasn't signed with enough keys.
                if !ignore_threshold {
                    return Err(error::Error::UnstableRoot {
                        role: *roletype,
                        threshold,
                        actual: keyids,
                    });
                }
                // Print out a warning to let the user know that the referenced root.json
                // file isn't compliant with the threshold specified for the role type.
                warn!(
                    "Loaded unstable root, role '{}' contains '{}' keys, expected '{}'",
                    *roletype, threshold, keyids
                );
            }
        }

        // Signature check for root
        let threshold = signed_root
            .signed()
            .signed
            .roles
            .get(&RoleType::Root)
            .ok_or(error::Error::UnstableRoot {
                // The code should never reach this point
                role: RoleType::Root,
                threshold: 0,
                actual: 0,
            })?
            .threshold
            .get();
        let signature_count = signed_root.signed().signatures.len();
        if threshold > signature_count as u64 {
            // Return an error when the "ignore-threshold" flag wasn't set
            if !ignore_threshold {
                return Err(error::Error::SignatureRoot {
                    threshold,
                    signature_count,
                });
            }
            // Print out a warning letting the user know that the target file isn't compliant with
            // the threshold used for the root role.
            warn!(
                "The root.json file requires at least {} signatures, the target file contains {}",
                threshold, signature_count
            );
        }

        // Use `tempfile::NamedTempFile::persist` to perform an atomic file write.
        let parent = path.parent().context(error::PathParentSnafu { path })?;
        let mut writer =
            NamedTempFile::new_in(parent).context(error::FileTempCreateSnafu { path: parent })?;
        writer
            .write_all(signed_root.buffer())
            .context(error::FileWriteSnafu { path })?;
        writer
            .persist(path)
            .context(error::FilePersistSnafu { path })?;
        Ok(())
    }