Monorepo for Tangled
at master 85 lines 2.0 kB view raw
1package commitverify 2 3import ( 4 "log" 5 6 "tangled.org/core/appview/db" 7 "tangled.org/core/appview/models" 8 "tangled.org/core/crypto" 9 "tangled.org/core/types" 10) 11 12type verifiedCommit struct { 13 fingerprint string 14 hash string 15} 16 17type VerifiedCommits map[verifiedCommit]struct{} 18 19func (vcs VerifiedCommits) IsVerified(hash string) bool { 20 for vc := range vcs { 21 if vc.hash == hash { 22 return true 23 } 24 } 25 return false 26} 27 28func (vcs VerifiedCommits) Fingerprint(hash string) string { 29 for vc := range vcs { 30 if vc.hash == hash { 31 return vc.fingerprint 32 } 33 } 34 return "" 35} 36 37func GetVerifiedCommits(e db.Execer, emailToDid map[string]string, ndCommits []types.Commit) (VerifiedCommits, error) { 38 vcs := VerifiedCommits{} 39 40 didPubkeyCache := make(map[string][]models.PublicKey) 41 42 for _, commit := range ndCommits { 43 // skip unsigned commits early: no signature means no DB lookup needed, 44 // and most commits in a typical log are unsigned. 45 if commit.PGPSignature == "" { 46 continue 47 } 48 49 committerEmail := commit.Committer.Email 50 if did, exists := emailToDid[committerEmail]; exists { 51 // check if we've already fetched public keys for this did 52 pubKeys, ok := didPubkeyCache[did] 53 if !ok { 54 // fetch and cache public keys 55 keys, err := db.GetPublicKeysForDid(e, did) 56 if err != nil { 57 log.Printf("failed to fetch pubkey for %s: %v", committerEmail, err) 58 continue 59 } 60 pubKeys = keys 61 didPubkeyCache[did] = pubKeys 62 } 63 64 // try to verify with any associated pubkeys 65 payload := commit.Payload() 66 signature := commit.PGPSignature 67 for _, pk := range pubKeys { 68 if _, ok := crypto.VerifySignature([]byte(pk.Key), []byte(signature), []byte(payload)); ok { 69 70 fp, err := crypto.SSHFingerprint(pk.Key) 71 if err != nil { 72 log.Println("error computing ssh fingerprint:", err) 73 } 74 75 vc := verifiedCommit{fingerprint: fp, hash: commit.This} 76 vcs[vc] = struct{}{} 77 break 78 } 79 } 80 81 } 82 } 83 84 return vcs, nil 85}