From 9fb5e15b99af96fff2403d79a18f274daae11bdd Mon Sep 17 00:00:00 2001 From: Anirudh Oppiliappan Date: Sun, 1 Jun 2025 18:01:10 +0300 Subject: [PATCH] appview: commitverify: move commit verification code to new package Change-Id: rmsnoztsmtrvrsqoyomzyytypupykzkp Signed-off-by: Anirudh Oppiliappan --- appview/commitverify/verify.go | 119 +++++++++++++++++++++++++++++++++ appview/repo/repo_util.go | 52 -------------- types/diff.go | 30 --------- 3 files changed, 119 insertions(+), 82 deletions(-) create mode 100644 appview/commitverify/verify.go diff --git a/appview/commitverify/verify.go b/appview/commitverify/verify.go new file mode 100644 index 0000000..eace4cb --- /dev/null +++ b/appview/commitverify/verify.go @@ -0,0 +1,119 @@ +package commitverify + +import ( + "fmt" + "log" + + "github.com/go-git/go-git/v5/plumbing/object" + "tangled.sh/tangled.sh/core/appview/db" + "tangled.sh/tangled.sh/core/crypto" + "tangled.sh/tangled.sh/core/types" +) + +type verifiedCommit struct { + fingerprint string + hash string +} + +type VerifiedCommits map[verifiedCommit]struct{} + +func (vcs VerifiedCommits) IsVerified(hash string) bool { + for vc := range vcs { + if vc.hash == hash { + return true + } + } + return false +} + +func (vcs VerifiedCommits) Fingerprint(hash string) string { + for vc := range vcs { + if vc.hash == hash { + return vc.fingerprint + } + } + return "" +} + +func GetVerifiedObjectCommits(e db.Execer, emailToDid map[string]string, commits []*object.Commit) (VerifiedCommits, error) { + ndCommits := []types.NiceDiff{} + for _, commit := range commits { + ndCommits = append(ndCommits, ObjectCommitToNiceDiff(commit)) + } + return GetVerifiedCommits(e, emailToDid, ndCommits) +} + +func GetVerifiedCommits(e db.Execer, emailToDid map[string]string, ndCommits []types.NiceDiff) (VerifiedCommits, error) { + vcs := VerifiedCommits{} + + didPubkeyCache := make(map[string][]db.PublicKey) + + for _, commit := range ndCommits { + c := commit.Commit + + committerEmail := c.Committer.Email + if did, exists := emailToDid[committerEmail]; exists { + // check if we've already fetched public keys for this did + pubKeys, ok := didPubkeyCache[did] + if !ok { + // fetch and cache public keys + keys, err := db.GetPublicKeysForDid(e, did) + if err != nil { + log.Printf("failed to fetch pubkey for %s: %v", committerEmail, err) + continue + } + pubKeys = keys + didPubkeyCache[did] = pubKeys + } + + // try to verify with any associated pubkeys + for _, pk := range pubKeys { + if _, ok := crypto.VerifyCommitSignature(pk.Key, commit); ok { + + fp, err := crypto.SSHFingerprint(pk.Key) + if err != nil { + log.Println("error computing ssh fingerprint:", err) + } + fmt.Println(fp) + + vc := verifiedCommit{fingerprint: fp, hash: c.This} + vcs[vc] = struct{}{} + break + } + } + + } + } + + return vcs, nil +} + +// ObjectCommitToNiceDiff is a compatibility function to convert a +// commit object into a NiceDiff structure. +func ObjectCommitToNiceDiff(c *object.Commit) types.NiceDiff { + var niceDiff types.NiceDiff + + // set commit information + niceDiff.Commit.Message = c.Message + niceDiff.Commit.Author = c.Author + niceDiff.Commit.This = c.Hash.String() + niceDiff.Commit.Committer = c.Committer + niceDiff.Commit.Tree = c.TreeHash.String() + niceDiff.Commit.PGPSignature = c.PGPSignature + + changeId, ok := c.ExtraHeaders["change-id"] + if ok { + niceDiff.Commit.ChangedId = string(changeId) + } + + // set parent hash if available + if len(c.ParentHashes) > 0 { + niceDiff.Commit.Parent = c.ParentHashes[0].String() + } + + // XXX: Stats and Diff fields are typically populated + // after fetching the actual diff information, which isn't + // directly available in the commit object itself. + + return niceDiff +} diff --git a/appview/repo/repo_util.go b/appview/repo/repo_util.go index 2dca88e..461245f 100644 --- a/appview/repo/repo_util.go +++ b/appview/repo/repo_util.go @@ -4,13 +4,9 @@ import ( "context" "crypto/rand" "fmt" - "log" "math/big" "github.com/go-git/go-git/v5/plumbing/object" - "tangled.sh/tangled.sh/core/appview/db" - "tangled.sh/tangled.sh/core/crypto" - "tangled.sh/tangled.sh/core/types" ) func uniqueEmails(commits []*object.Commit) []string { @@ -91,54 +87,6 @@ func emailToDidOrHandle(r *Repo, emailToDidMap map[string]string) map[string]str return emailToDidOrHandle } -func verifiedObjectCommits(r *Repo, emailToDid map[string]string, commits []*object.Commit) (map[string]bool, error) { - ndCommits := []types.NiceDiff{} - for _, commit := range commits { - ndCommits = append(ndCommits, types.ObjectCommitToNiceDiff(commit)) - } - return verifiedCommits(r, emailToDid, ndCommits) -} - -func verifiedCommits(r *Repo, emailToDid map[string]string, ndCommits []types.NiceDiff) (map[string]bool, error) { - hashToVerified := make(map[string]bool) - - didPubkeyCache := make(map[string][]db.PublicKey) - - for _, commit := range ndCommits { - c := commit.Commit - - committerEmail := c.Committer.Email - if did, exists := emailToDid[committerEmail]; exists { - // check if we've already fetched public keys for this did - pubKeys, ok := didPubkeyCache[did] - if !ok { - // fetch and cache public keys - keys, err := db.GetPublicKeysForDid(r.db, did) - if err != nil { - log.Printf("failed to fetch pubkey for %s: %v", committerEmail, err) - continue - } - pubKeys = keys - didPubkeyCache[did] = pubKeys - } - - verified := false - - // try to verify with any associated pubkeys - for _, pk := range pubKeys { - if _, ok := crypto.VerifyCommitSignature(pk.Key, commit); ok { - verified = true - break - } - } - - hashToVerified[c.This] = verified - } - } - - return hashToVerified, nil -} - func randomString(n int) string { const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" result := make([]byte, n) diff --git a/types/diff.go b/types/diff.go index 1adbaa4..5978dc6 100644 --- a/types/diff.go +++ b/types/diff.go @@ -77,33 +77,3 @@ func (d *NiceDiff) ChangedFiles() []string { return files } - -// ObjectCommitToNiceDiff is a compatibility function to convert a -// commit object into a NiceDiff structure. -func ObjectCommitToNiceDiff(c *object.Commit) NiceDiff { - var niceDiff NiceDiff - - // set commit information - niceDiff.Commit.Message = c.Message - niceDiff.Commit.Author = c.Author - niceDiff.Commit.This = c.Hash.String() - niceDiff.Commit.Committer = c.Committer - niceDiff.Commit.Tree = c.TreeHash.String() - niceDiff.Commit.PGPSignature = c.PGPSignature - - changeId, ok := c.ExtraHeaders["change-id"] - if ok { - niceDiff.Commit.ChangedId = string(changeId) - } - - // set parent hash if available - if len(c.ParentHashes) > 0 { - niceDiff.Commit.Parent = c.ParentHashes[0].String() - } - - // XXX: Stats and Diff fields are typically populated - // after fetching the actual diff information, which isn't - // directly available in the commit object itself. - - return niceDiff -} -- 2.43.0