Harness the power of signify(1) to sign arbitrary git objects
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

v2 signatures

+31 -27
+10 -18
src/raw/sign.rs
··· 3 3 use std::path::PathBuf; 4 4 5 5 use anyhow::{Context, Result}; 6 - use either::*; 7 6 use git2::{ObjectType, Oid, Repository}; 8 7 9 8 use crate::utils; ··· 26 25 .context("Failed to look-up git object id")?; 27 26 28 27 let object_ptr = object.id(); 29 - let object_mode_or_commit = match object 28 + let object_mode = match object 30 29 .kind() 31 30 .context("Failed to determine object kind to sign")? 32 31 { 33 - ObjectType::Blob => Left(0o100644), 34 - ObjectType::Tree => Left(0o040000), 35 - ObjectType::Commit => Right(object.as_commit().expect("The object is a commit")), 36 - ty @ (ObjectType::Any | ObjectType::Tag) => { 37 - anyhow::bail!("Unsupported or recursive object type {ty}"); 32 + ObjectType::Blob => 0o100644, 33 + ObjectType::Tree => 0o040000, 34 + ObjectType::Commit | ObjectType::Tag => 0o160000, 35 + ty @ ObjectType::Any => { 36 + anyhow::bail!("Unsupported object type {ty}"); 38 37 } 39 38 }; 40 39 ··· 68 67 tree_builder 69 68 .insert("signature", signature_blob, 0o100644) 70 69 .context("Failed to write signature to the tree")?; 71 - 72 - let parents = object_mode_or_commit.either( 73 - |object_mode| { 74 - tree_builder 75 - .insert("object", object_ptr, object_mode) 76 - .context("Failed to write object to the tree")?; 77 - anyhow::Ok(vec![]) 78 - }, 79 - |commit| anyhow::Ok(vec![commit]), 80 - )?; 70 + tree_builder 71 + .insert("object", object_ptr, object_mode) 72 + .context("Failed to write object to the tree")?; 81 73 82 74 let tree_oid = tree_builder 83 75 .write() ··· 93 85 &commit_author, 94 86 &format!("git-signify signature over {rev}"), 95 87 &tree, 96 - &parents, 88 + &[], 97 89 ) 98 90 .context("Failed to create git signature commit")?; 99 91
+21 -9
src/utils.rs
··· 82 82 V0, 83 83 /// Version 1 tree signatures. 84 84 V1, 85 + /// Version 2 tree signatures. 86 + V2, 85 87 } 86 88 87 89 impl TreeSignatureVersion { ··· 90 92 match blob.content() { 91 93 b"v0" => Ok(Self::V0), 92 94 b"v1" => Ok(Self::V1), 95 + b"v2" => Ok(Self::V2), 93 96 blob => Err(anyhow!( 94 97 "Invalid tree signature version {:?}", 95 98 String::from_utf8_lossy(blob) ··· 99 102 100 103 /// Return the current version. 101 104 pub const fn current() -> Self { 102 - TreeSignatureVersion::V1 105 + TreeSignatureVersion::V2 103 106 } 104 107 105 108 /// Encode the version as a string. ··· 107 110 match self { 108 111 Self::V0 => "v0", 109 112 Self::V1 => "v1", 113 + Self::V2 => "v2", 110 114 } 111 115 } 112 116 } ··· 273 277 }; 274 278 275 279 let object_pointer = tree.get_name("object").map_or_else( 276 - || { 277 - Ok(commit 280 + || match &version { 281 + TreeSignatureVersion::V0 => { 282 + anyhow::bail!("Attempted to parse v0 tree signature from commit object") 283 + } 284 + TreeSignatureVersion::V1 => Ok(commit 278 285 .parent(0) 279 286 .context( 280 287 "No signed `object` in the tree signature nor a parent commit \ 281 - to be signed could be found", 288 + to be signed could be found", 282 289 )? 283 - .into_object()) 290 + .into_object()), 291 + TreeSignatureVersion::V2 => { 292 + anyhow::bail!("No signed `object` could be found in the tree signature"); 293 + } 284 294 }, 285 295 |entry| { 286 296 entry.to_object(repo).with_context(|| { ··· 324 334 .map_err(Error::new) 325 335 .context("Failed to parse signify signature from git blob")? 326 336 } 327 - TreeSignatureVersion::V1 => { 337 + TreeSignatureVersion::V1 | TreeSignatureVersion::V2 => { 328 338 let signature_content = std::str::from_utf8(self.signature.content()) 329 339 .context("Found non-utf8 data in signify signature content")?; 330 340 ··· 348 358 TreeSignatureVersion::V0 => { 349 359 anyhow::bail!("minisign public keys not supported in v0"); 350 360 } 351 - TreeSignatureVersion::V1 => { 361 + TreeSignatureVersion::V1 | TreeSignatureVersion::V2 => { 352 362 let signature_content = std::str::from_utf8(self.signature.content()) 353 363 .context("Found non-utf8 data in minisign signature content")?; 354 364 ··· 378 388 match (&self.version, &self.algorithm, key) { 379 389 (TreeSignatureVersion::V0, TreeSignatureAlgo::Signify, PublicKey::Signify(_)) 380 390 | (TreeSignatureVersion::V1, TreeSignatureAlgo::Signify, PublicKey::Signify(_)) 381 - | (TreeSignatureVersion::V1, TreeSignatureAlgo::Minisign, PublicKey::Minisign(_)) => { 391 + | (TreeSignatureVersion::V1, TreeSignatureAlgo::Minisign, PublicKey::Minisign(_)) 392 + | (TreeSignatureVersion::V2, TreeSignatureAlgo::Signify, PublicKey::Signify(_)) 393 + | (TreeSignatureVersion::V2, TreeSignatureAlgo::Minisign, PublicKey::Minisign(_)) => { 382 394 Ok(()) 383 395 } 384 396 _ => { ··· 402 414 let oid_bytes = blob.content(); 403 415 Oid::from_bytes(oid_bytes).context("Failed to parse git object id from raw bytes") 404 416 } 405 - TreeSignatureVersion::V1 => Ok(self.object_pointer.id()), 417 + TreeSignatureVersion::V1 | TreeSignatureVersion::V2 => Ok(self.object_pointer.id()), 406 418 } 407 419 } 408 420 }