···11mod fingerprint;
22mod raw;
33-//mod sign;
33+mod sign;
44mod utils;
55//mod verify;
66···2828 /// The path to the base64 encoded key to hash
2929 #[arg(short = 'k', long)]
3030 key: PathBuf,
3131+ },
3232+ /// Sign an arbitrary object
3333+ Sign {
3434+ /// The path to the base64 encoded secret key to sign with
3535+ #[arg(short = 'k', long)]
3636+ secret_key: PathBuf,
3737+3838+ /// The git revision to sign
3939+ git_rev: String,
3140 },
3241}
3342···7180 git_tree: rev,
7281 }) => raw::verify::command(public_key, recover, rev),
7382 Action::Fingerprint { key } => fingerprint::command(key),
8383+ Action::Sign {
8484+ secret_key,
8585+ git_rev: rev,
8686+ } => sign::command(secret_key, rev),
7487 }
7588}
+31
src/sign.rs
···11+//! Create signatures with [`libsignify`] and store references
22+//! to them in git.
33+44+use std::path::PathBuf;
55+66+use anyhow::{Context, Result};
77+88+use crate::raw::sign::sign;
99+use crate::utils;
1010+1111+/// Execute the `sign` command.
1212+pub fn command(key_path: PathBuf, rev: String) -> Result<()> {
1313+ let repo = utils::open_repository()?;
1414+ let secret_key = utils::get_secret_key(key_path)?;
1515+ let tree_oid = sign(&repo, &secret_key, &rev)?;
1616+ let signed_object = {
1717+ let tree_sig = utils::TreeSignature::load_oid(&repo, tree_oid)?;
1818+ tree_sig.dereference()?
1919+ };
2020+ let key_fingerprint = utils::hash_bytes(&secret_key.public().key()[..])?;
2121+ let reference = format!("refs/signify/signatures/{key_fingerprint}/{signed_object}");
2222+ repo.reference(
2323+ &reference, tree_oid,
2424+ // references to signatures will never change, so it is
2525+ // safe to force overwriting faulty references
2626+ true, "",
2727+ )
2828+ .context("Failed to store reference to signature")?;
2929+ println!("Signature stored under: {reference}");
3030+ Ok(())
3131+}