Harness the power of signify(1) to sign arbitrary git objects
1//! Verify signatures with [`libsignify`].
2
3use std::path::PathBuf;
4
5use anyhow::Result;
6use either::*;
7use git2::{Oid, Repository};
8
9use crate::utils;
10
11/// Execute the `raw verify` command.
12pub fn command(key_path: PathBuf, recover: bool, tree_rev: String) -> Result<()> {
13 let repo = utils::open_repository()?;
14 for public_key in utils::get_public_keys(key_path)?.into_values() {
15 verify(&repo, &public_key, &tree_rev, recover)?.either(
16 |_| anyhow::bail!("No signature found for tree {tree_rev}"),
17 |recovered_oid| {
18 if let Some(recovered_oid) = recovered_oid {
19 println!("{recovered_oid}");
20 }
21 Ok(())
22 },
23 )?;
24 }
25 Ok(())
26}
27
28/// Verify the signature under `tree_rev` with the given public key.
29pub fn verify(
30 repo: &Repository,
31 public_key: &utils::PublicKey,
32 tree_rev: &str,
33 recover: bool,
34) -> Result<Either<(), Option<Oid>>> {
35 let Some(tree_sig) = utils::TreeSignature::load(repo, tree_rev)? else {
36 return Ok(Left(()));
37 };
38 tree_sig.verify(public_key)?;
39 recover
40 .then(|| tree_sig.dereference())
41 .transpose()
42 .map(Right)
43}