-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
127 lines (120 loc) · 3.4 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package main
import (
"flag"
"fmt"
"io"
"os"
protobundle "github.com/sigstore/protobuf-specs/gen/pb-go/bundle/v1"
protorekor "github.com/sigstore/protobuf-specs/gen/pb-go/rekor/v1"
"github.com/sigstore/rekor/pkg/client"
"github.com/sigstore/rekor/pkg/generated/client/entries"
"github.com/sigstore/rekor/pkg/generated/models"
"github.com/sigstore/rekor/pkg/tle"
bundle "github.com/sigstore/sigstore-go/pkg/bundle"
"golang.org/x/mod/semver"
"google.golang.org/protobuf/encoding/protojson"
)
var version string
var bundlePath string
var pretty bool
var inplace bool
func init() {
flag.Usage = func() {
println("Usage: sigstore-bundle-upgrade <path/to/sigstore/bundle>")
flag.PrintDefaults()
}
flag.BoolVar(&pretty, "pretty", false, "Pretty print the output")
flag.StringVar(&version, "version", "0.3", "Bundle version to upgrade to")
flag.BoolVar(&inplace, "in-place", false, "Update the bundle in place (otherwise print to stdout)")
flag.Parse()
if flag.NArg() != 1 {
flag.Usage()
os.Exit(1)
}
bundlePath = flag.Arg(0)
}
func main() {
if err := runConvert(); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
}
func runConvert() error {
b, err := bundle.LoadJSONFromPath(bundlePath)
if err != nil {
return err
}
mediaType, err := bundle.MediaTypeString(version)
if err != nil {
return err
}
if semver.Compare("v"+version, "v0.2") >= 0 {
if b.Bundle.VerificationMaterial.TlogEntries != nil {
for i := 0; i < len(b.Bundle.VerificationMaterial.TlogEntries); i++ {
if b.Bundle.VerificationMaterial.TlogEntries[i].InclusionProof == nil {
b.Bundle.VerificationMaterial.TlogEntries[i], err = convertTLogEntry(b.Bundle.VerificationMaterial.TlogEntries[i])
if err != nil {
return err
}
}
}
}
}
if semver.Compare("v"+version, "v0.3") >= 0 {
if certChain, ok := b.Bundle.VerificationMaterial.GetContent().(*protobundle.VerificationMaterial_X509CertificateChain); ok {
if len(certChain.X509CertificateChain.Certificates) == 0 {
return fmt.Errorf("certificate chain empty")
}
b.Bundle.VerificationMaterial.Content = &protobundle.VerificationMaterial_Certificate{
Certificate: certChain.X509CertificateChain.Certificates[0],
}
}
}
b.Bundle.MediaType = mediaType
marshalOptions := protojson.MarshalOptions{}
if pretty {
marshalOptions.Multiline = true
marshalOptions.Indent = "\t"
}
outBytes, err := marshalOptions.Marshal(b.Bundle)
if err != nil {
return err
}
outBytes = append(outBytes, []byte("\n")...)
var f io.WriteCloser
if inplace {
f, err = os.OpenFile(bundlePath, os.O_WRONLY|os.O_TRUNC, 0644)
if err != nil {
return err
}
} else {
f = os.Stdout
}
defer f.Close()
_, err = f.Write(outBytes)
if err != nil {
return err
}
return nil
}
func convertTLogEntry(entry *protorekor.TransparencyLogEntry) (*protorekor.TransparencyLogEntry, error) {
// TODO: support alternative transparency log servers
rekor, err := client.GetRekorClient("https://rekor.sigstore.dev")
if err != nil {
return nil, err
}
logEntries, err := rekor.Entries.GetLogEntryByIndex(&entries.GetLogEntryByIndexParams{
LogIndex: entry.LogIndex,
})
if err != nil {
return nil, err
}
if len(logEntries.Payload) != 1 {
return nil, fmt.Errorf("failed to retrieve inclusion proof")
}
var logEntry models.LogEntryAnon
for _, entry := range logEntries.Payload {
logEntry = entry
}
return tle.GenerateTransparencyLogEntry(logEntry)
}