1package main
2
3import (
4 "flag"
5 "fmt"
6 "io"
7 "os"
8 "strings"
9
10 "tangled.sh/tangled.sh/core/crypto"
11)
12
13func parseCommitObject(commitData string) (string, string, error) {
14 lines := strings.Split(commitData, "\n")
15
16 var payloadLines []string
17 var signatureLines []string
18 var inSignature bool
19 var foundSignature bool
20
21 for _, line := range lines {
22 if strings.HasPrefix(line, "gpgsig ") {
23 foundSignature = true
24 inSignature = true
25 // remove 'gpgsig' prefix
26 sigLine := strings.TrimPrefix(line, "gpgsig ")
27 signatureLines = append(signatureLines, sigLine)
28 continue
29 }
30
31 if inSignature {
32 // check if this line is part of the signature (starts with space)
33 if strings.HasPrefix(line, " ") {
34 // remove the leading space and add to signature
35 sigLine := strings.TrimPrefix(line, " ")
36 signatureLines = append(signatureLines, sigLine)
37 continue
38 } else {
39 // end of signature block
40 inSignature = false
41 // this line is part of payload, so add it
42 payloadLines = append(payloadLines, line)
43 }
44 } else {
45 // regular payload line
46 payloadLines = append(payloadLines, line)
47 }
48 }
49
50 if !foundSignature {
51 return "", commitData, nil // no signature found, return empty signature and full data as payload
52 }
53
54 signature := strings.Join(signatureLines, "\n")
55 payload := strings.Join(payloadLines, "\n")
56
57 return signature, payload, nil
58}
59
60func main() {
61 var pubkeyPath string
62 flag.StringVar(&pubkeyPath, "pubkey", "", "Path to the public key file")
63 flag.Parse()
64
65 var pubKey []byte
66 var err error
67 if pubkeyPath != "" {
68 pubKey, err = os.ReadFile(pubkeyPath)
69 if err != nil {
70 fmt.Fprintf(os.Stderr, "error reading public key file: %v\n", err)
71 os.Exit(1)
72 }
73 }
74
75 input, err := io.ReadAll(os.Stdin)
76 if err != nil {
77 fmt.Fprintf(os.Stderr, "error reading from stdin: %v\n", err)
78 os.Exit(1)
79 }
80
81 commitData := string(input)
82
83 signature, payload, err := parseCommitObject(commitData)
84 if err != nil {
85 fmt.Fprintf(os.Stderr, "error parsing commit: %v\n", err)
86 os.Exit(1)
87 }
88
89 fmt.Println("signature")
90 fmt.Println(signature)
91 fmt.Println()
92 fmt.Println("payload:")
93 fmt.Println(payload)
94
95 err, ok := crypto.VerifySignature(pubKey, []byte(signature), []byte(payload))
96 if err != nil {
97 fmt.Fprintf(os.Stderr, "%v\n", err)
98 os.Exit(1)
99 }
100 if ok {
101 fmt.Println("ok")
102 }
103}