forked from tangled.org/core
Monorepo for Tangled — https://tangled.org
at master 1.8 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 committerEmail := commit.Committer.Email 44 if did, exists := emailToDid[committerEmail]; exists { 45 // check if we've already fetched public keys for this did 46 pubKeys, ok := didPubkeyCache[did] 47 if !ok { 48 // fetch and cache public keys 49 keys, err := db.GetPublicKeysForDid(e, did) 50 if err != nil { 51 log.Printf("failed to fetch pubkey for %s: %v", committerEmail, err) 52 continue 53 } 54 pubKeys = keys 55 didPubkeyCache[did] = pubKeys 56 } 57 58 // try to verify with any associated pubkeys 59 payload := commit.Payload() 60 signature := commit.PGPSignature 61 for _, pk := range pubKeys { 62 if _, ok := crypto.VerifySignature([]byte(pk.Key), []byte(signature), []byte(payload)); ok { 63 64 fp, err := crypto.SSHFingerprint(pk.Key) 65 if err != nil { 66 log.Println("error computing ssh fingerprint:", err) 67 } 68 69 vc := verifiedCommit{fingerprint: fp, hash: commit.This} 70 vcs[vc] = struct{}{} 71 break 72 } 73 } 74 75 } 76 } 77 78 return vcs, nil 79}