forked from tangled.org/core
this repo has no description

appview: commitverify: move commit verification code to new package

Signed-off-by: Anirudh Oppiliappan <anirudh@tangled.sh>

anirudh.fi 9fb5e15b 0e596b62

verified
Changed files
+119 -82
appview
commitverify
repo
types
+119
appview/commitverify/verify.go
··· 1 + package commitverify 2 + 3 + import ( 4 + "fmt" 5 + "log" 6 + 7 + "github.com/go-git/go-git/v5/plumbing/object" 8 + "tangled.sh/tangled.sh/core/appview/db" 9 + "tangled.sh/tangled.sh/core/crypto" 10 + "tangled.sh/tangled.sh/core/types" 11 + ) 12 + 13 + type verifiedCommit struct { 14 + fingerprint string 15 + hash string 16 + } 17 + 18 + type VerifiedCommits map[verifiedCommit]struct{} 19 + 20 + func (vcs VerifiedCommits) IsVerified(hash string) bool { 21 + for vc := range vcs { 22 + if vc.hash == hash { 23 + return true 24 + } 25 + } 26 + return false 27 + } 28 + 29 + func (vcs VerifiedCommits) Fingerprint(hash string) string { 30 + for vc := range vcs { 31 + if vc.hash == hash { 32 + return vc.fingerprint 33 + } 34 + } 35 + return "" 36 + } 37 + 38 + func GetVerifiedObjectCommits(e db.Execer, emailToDid map[string]string, commits []*object.Commit) (VerifiedCommits, error) { 39 + ndCommits := []types.NiceDiff{} 40 + for _, commit := range commits { 41 + ndCommits = append(ndCommits, ObjectCommitToNiceDiff(commit)) 42 + } 43 + return GetVerifiedCommits(e, emailToDid, ndCommits) 44 + } 45 + 46 + func GetVerifiedCommits(e db.Execer, emailToDid map[string]string, ndCommits []types.NiceDiff) (VerifiedCommits, error) { 47 + vcs := VerifiedCommits{} 48 + 49 + didPubkeyCache := make(map[string][]db.PublicKey) 50 + 51 + for _, commit := range ndCommits { 52 + c := commit.Commit 53 + 54 + committerEmail := c.Committer.Email 55 + if did, exists := emailToDid[committerEmail]; exists { 56 + // check if we've already fetched public keys for this did 57 + pubKeys, ok := didPubkeyCache[did] 58 + if !ok { 59 + // fetch and cache public keys 60 + keys, err := db.GetPublicKeysForDid(e, did) 61 + if err != nil { 62 + log.Printf("failed to fetch pubkey for %s: %v", committerEmail, err) 63 + continue 64 + } 65 + pubKeys = keys 66 + didPubkeyCache[did] = pubKeys 67 + } 68 + 69 + // try to verify with any associated pubkeys 70 + for _, pk := range pubKeys { 71 + if _, ok := crypto.VerifyCommitSignature(pk.Key, commit); ok { 72 + 73 + fp, err := crypto.SSHFingerprint(pk.Key) 74 + if err != nil { 75 + log.Println("error computing ssh fingerprint:", err) 76 + } 77 + fmt.Println(fp) 78 + 79 + vc := verifiedCommit{fingerprint: fp, hash: c.This} 80 + vcs[vc] = struct{}{} 81 + break 82 + } 83 + } 84 + 85 + } 86 + } 87 + 88 + return vcs, nil 89 + } 90 + 91 + // ObjectCommitToNiceDiff is a compatibility function to convert a 92 + // commit object into a NiceDiff structure. 93 + func ObjectCommitToNiceDiff(c *object.Commit) types.NiceDiff { 94 + var niceDiff types.NiceDiff 95 + 96 + // set commit information 97 + niceDiff.Commit.Message = c.Message 98 + niceDiff.Commit.Author = c.Author 99 + niceDiff.Commit.This = c.Hash.String() 100 + niceDiff.Commit.Committer = c.Committer 101 + niceDiff.Commit.Tree = c.TreeHash.String() 102 + niceDiff.Commit.PGPSignature = c.PGPSignature 103 + 104 + changeId, ok := c.ExtraHeaders["change-id"] 105 + if ok { 106 + niceDiff.Commit.ChangedId = string(changeId) 107 + } 108 + 109 + // set parent hash if available 110 + if len(c.ParentHashes) > 0 { 111 + niceDiff.Commit.Parent = c.ParentHashes[0].String() 112 + } 113 + 114 + // XXX: Stats and Diff fields are typically populated 115 + // after fetching the actual diff information, which isn't 116 + // directly available in the commit object itself. 117 + 118 + return niceDiff 119 + }
-52
appview/repo/repo_util.go
··· 4 4 "context" 5 5 "crypto/rand" 6 6 "fmt" 7 - "log" 8 7 "math/big" 9 8 10 9 "github.com/go-git/go-git/v5/plumbing/object" 11 - "tangled.sh/tangled.sh/core/appview/db" 12 - "tangled.sh/tangled.sh/core/crypto" 13 - "tangled.sh/tangled.sh/core/types" 14 10 ) 15 11 16 12 func uniqueEmails(commits []*object.Commit) []string { ··· 89 85 } 90 86 91 87 return emailToDidOrHandle 92 - } 93 - 94 - func verifiedObjectCommits(r *Repo, emailToDid map[string]string, commits []*object.Commit) (map[string]bool, error) { 95 - ndCommits := []types.NiceDiff{} 96 - for _, commit := range commits { 97 - ndCommits = append(ndCommits, types.ObjectCommitToNiceDiff(commit)) 98 - } 99 - return verifiedCommits(r, emailToDid, ndCommits) 100 - } 101 - 102 - func verifiedCommits(r *Repo, emailToDid map[string]string, ndCommits []types.NiceDiff) (map[string]bool, error) { 103 - hashToVerified := make(map[string]bool) 104 - 105 - didPubkeyCache := make(map[string][]db.PublicKey) 106 - 107 - for _, commit := range ndCommits { 108 - c := commit.Commit 109 - 110 - committerEmail := c.Committer.Email 111 - if did, exists := emailToDid[committerEmail]; exists { 112 - // check if we've already fetched public keys for this did 113 - pubKeys, ok := didPubkeyCache[did] 114 - if !ok { 115 - // fetch and cache public keys 116 - keys, err := db.GetPublicKeysForDid(r.db, did) 117 - if err != nil { 118 - log.Printf("failed to fetch pubkey for %s: %v", committerEmail, err) 119 - continue 120 - } 121 - pubKeys = keys 122 - didPubkeyCache[did] = pubKeys 123 - } 124 - 125 - verified := false 126 - 127 - // try to verify with any associated pubkeys 128 - for _, pk := range pubKeys { 129 - if _, ok := crypto.VerifyCommitSignature(pk.Key, commit); ok { 130 - verified = true 131 - break 132 - } 133 - } 134 - 135 - hashToVerified[c.This] = verified 136 - } 137 - } 138 - 139 - return hashToVerified, nil 140 88 } 141 89 142 90 func randomString(n int) string {
-30
types/diff.go
··· 77 77 78 78 return files 79 79 } 80 - 81 - // ObjectCommitToNiceDiff is a compatibility function to convert a 82 - // commit object into a NiceDiff structure. 83 - func ObjectCommitToNiceDiff(c *object.Commit) NiceDiff { 84 - var niceDiff NiceDiff 85 - 86 - // set commit information 87 - niceDiff.Commit.Message = c.Message 88 - niceDiff.Commit.Author = c.Author 89 - niceDiff.Commit.This = c.Hash.String() 90 - niceDiff.Commit.Committer = c.Committer 91 - niceDiff.Commit.Tree = c.TreeHash.String() 92 - niceDiff.Commit.PGPSignature = c.PGPSignature 93 - 94 - changeId, ok := c.ExtraHeaders["change-id"] 95 - if ok { 96 - niceDiff.Commit.ChangedId = string(changeId) 97 - } 98 - 99 - // set parent hash if available 100 - if len(c.ParentHashes) > 0 { 101 - niceDiff.Commit.Parent = c.ParentHashes[0].String() 102 - } 103 - 104 - // XXX: Stats and Diff fields are typically populated 105 - // after fetching the actual diff information, which isn't 106 - // directly available in the commit object itself. 107 - 108 - return niceDiff 109 - }