···11+package commitverify22+33+import (44+ "fmt"55+ "log"66+77+ "github.com/go-git/go-git/v5/plumbing/object"88+ "tangled.sh/tangled.sh/core/appview/db"99+ "tangled.sh/tangled.sh/core/crypto"1010+ "tangled.sh/tangled.sh/core/types"1111+)1212+1313+type verifiedCommit struct {1414+ fingerprint string1515+ hash string1616+}1717+1818+type VerifiedCommits map[verifiedCommit]struct{}1919+2020+func (vcs VerifiedCommits) IsVerified(hash string) bool {2121+ for vc := range vcs {2222+ if vc.hash == hash {2323+ return true2424+ }2525+ }2626+ return false2727+}2828+2929+func (vcs VerifiedCommits) Fingerprint(hash string) string {3030+ for vc := range vcs {3131+ if vc.hash == hash {3232+ return vc.fingerprint3333+ }3434+ }3535+ return ""3636+}3737+3838+func GetVerifiedObjectCommits(e db.Execer, emailToDid map[string]string, commits []*object.Commit) (VerifiedCommits, error) {3939+ ndCommits := []types.NiceDiff{}4040+ for _, commit := range commits {4141+ ndCommits = append(ndCommits, ObjectCommitToNiceDiff(commit))4242+ }4343+ return GetVerifiedCommits(e, emailToDid, ndCommits)4444+}4545+4646+func GetVerifiedCommits(e db.Execer, emailToDid map[string]string, ndCommits []types.NiceDiff) (VerifiedCommits, error) {4747+ vcs := VerifiedCommits{}4848+4949+ didPubkeyCache := make(map[string][]db.PublicKey)5050+5151+ for _, commit := range ndCommits {5252+ c := commit.Commit5353+5454+ committerEmail := c.Committer.Email5555+ if did, exists := emailToDid[committerEmail]; exists {5656+ // check if we've already fetched public keys for this did5757+ pubKeys, ok := didPubkeyCache[did]5858+ if !ok {5959+ // fetch and cache public keys6060+ keys, err := db.GetPublicKeysForDid(e, did)6161+ if err != nil {6262+ log.Printf("failed to fetch pubkey for %s: %v", committerEmail, err)6363+ continue6464+ }6565+ pubKeys = keys6666+ didPubkeyCache[did] = pubKeys6767+ }6868+6969+ // try to verify with any associated pubkeys7070+ for _, pk := range pubKeys {7171+ if _, ok := crypto.VerifyCommitSignature(pk.Key, commit); ok {7272+7373+ fp, err := crypto.SSHFingerprint(pk.Key)7474+ if err != nil {7575+ log.Println("error computing ssh fingerprint:", err)7676+ }7777+ fmt.Println(fp)7878+7979+ vc := verifiedCommit{fingerprint: fp, hash: c.This}8080+ vcs[vc] = struct{}{}8181+ break8282+ }8383+ }8484+8585+ }8686+ }8787+8888+ return vcs, nil8989+}9090+9191+// ObjectCommitToNiceDiff is a compatibility function to convert a9292+// commit object into a NiceDiff structure.9393+func ObjectCommitToNiceDiff(c *object.Commit) types.NiceDiff {9494+ var niceDiff types.NiceDiff9595+9696+ // set commit information9797+ niceDiff.Commit.Message = c.Message9898+ niceDiff.Commit.Author = c.Author9999+ niceDiff.Commit.This = c.Hash.String()100100+ niceDiff.Commit.Committer = c.Committer101101+ niceDiff.Commit.Tree = c.TreeHash.String()102102+ niceDiff.Commit.PGPSignature = c.PGPSignature103103+104104+ changeId, ok := c.ExtraHeaders["change-id"]105105+ if ok {106106+ niceDiff.Commit.ChangedId = string(changeId)107107+ }108108+109109+ // set parent hash if available110110+ if len(c.ParentHashes) > 0 {111111+ niceDiff.Commit.Parent = c.ParentHashes[0].String()112112+ }113113+114114+ // XXX: Stats and Diff fields are typically populated115115+ // after fetching the actual diff information, which isn't116116+ // directly available in the commit object itself.117117+118118+ return niceDiff119119+}
-52
appview/repo/repo_util.go
···44 "context"55 "crypto/rand"66 "fmt"77- "log"87 "math/big"98109 "github.com/go-git/go-git/v5/plumbing/object"1111- "tangled.sh/tangled.sh/core/appview/db"1212- "tangled.sh/tangled.sh/core/crypto"1313- "tangled.sh/tangled.sh/core/types"1410)15111612func uniqueEmails(commits []*object.Commit) []string {···8589 }86908791 return emailToDidOrHandle8888-}8989-9090-func verifiedObjectCommits(r *Repo, emailToDid map[string]string, commits []*object.Commit) (map[string]bool, error) {9191- ndCommits := []types.NiceDiff{}9292- for _, commit := range commits {9393- ndCommits = append(ndCommits, types.ObjectCommitToNiceDiff(commit))9494- }9595- return verifiedCommits(r, emailToDid, ndCommits)9696-}9797-9898-func verifiedCommits(r *Repo, emailToDid map[string]string, ndCommits []types.NiceDiff) (map[string]bool, error) {9999- hashToVerified := make(map[string]bool)100100-101101- didPubkeyCache := make(map[string][]db.PublicKey)102102-103103- for _, commit := range ndCommits {104104- c := commit.Commit105105-106106- committerEmail := c.Committer.Email107107- if did, exists := emailToDid[committerEmail]; exists {108108- // check if we've already fetched public keys for this did109109- pubKeys, ok := didPubkeyCache[did]110110- if !ok {111111- // fetch and cache public keys112112- keys, err := db.GetPublicKeysForDid(r.db, did)113113- if err != nil {114114- log.Printf("failed to fetch pubkey for %s: %v", committerEmail, err)115115- continue116116- }117117- pubKeys = keys118118- didPubkeyCache[did] = pubKeys119119- }120120-121121- verified := false122122-123123- // try to verify with any associated pubkeys124124- for _, pk := range pubKeys {125125- if _, ok := crypto.VerifyCommitSignature(pk.Key, commit); ok {126126- verified = true127127- break128128- }129129- }130130-131131- hashToVerified[c.This] = verified132132- }133133- }134134-135135- return hashToVerified, nil13692}1379313894func randomString(n int) string {
-30
types/diff.go
···77777878 return files7979}8080-8181-// ObjectCommitToNiceDiff is a compatibility function to convert a8282-// commit object into a NiceDiff structure.8383-func ObjectCommitToNiceDiff(c *object.Commit) NiceDiff {8484- var niceDiff NiceDiff8585-8686- // set commit information8787- niceDiff.Commit.Message = c.Message8888- niceDiff.Commit.Author = c.Author8989- niceDiff.Commit.This = c.Hash.String()9090- niceDiff.Commit.Committer = c.Committer9191- niceDiff.Commit.Tree = c.TreeHash.String()9292- niceDiff.Commit.PGPSignature = c.PGPSignature9393-9494- changeId, ok := c.ExtraHeaders["change-id"]9595- if ok {9696- niceDiff.Commit.ChangedId = string(changeId)9797- }9898-9999- // set parent hash if available100100- if len(c.ParentHashes) > 0 {101101- niceDiff.Commit.Parent = c.ParentHashes[0].String()102102- }103103-104104- // XXX: Stats and Diff fields are typically populated105105- // after fetching the actual diff information, which isn't106106- // directly available in the commit object itself.107107-108108- return niceDiff109109-}