1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package fuzz
17
18 import (
19 "archive/tar"
20 "bytes"
21 "compress/gzip"
22 "errors"
23 "fmt"
24 "os"
25 "strings"
26
27 fuzz "github.com/AdamKorcz/go-fuzz-headers-1"
28 "github.com/sigstore/rekor/pkg/types"
29 )
30
31
32 func getSignFilename(ff *fuzz.ConsumeFuzzer) (string, error) {
33 keyName, err := ff.GetString()
34 if err != nil {
35 return "", err
36 }
37 var b strings.Builder
38 b.WriteString(".SIGN.RSA.")
39 b.WriteString(keyName)
40 b.WriteString(".rsa.pub")
41 return b.String(), nil
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 func createPkgInfoFileContents(ff *fuzz.ConsumeFuzzer) ([]byte, error) {
73 var b strings.Builder
74 noOfRows, err := ff.GetInt()
75 if err != nil {
76 return []byte(""), err
77 }
78
79
80 header, err := ff.GetBytes()
81 if err != nil {
82 return []byte(""), err
83 }
84 b.Write(header)
85
86 for i := 0; i < noOfRows; i++ {
87 key, err := ff.GetBytes()
88 if err != nil {
89 return []byte(""), err
90 }
91 value, err := ff.GetBytes()
92 if err != nil {
93 return []byte(""), err
94 }
95 b.Write(key)
96 b.Write([]byte(" = "))
97 b.Write(value)
98 b.WriteString("\n")
99 }
100 return []byte(b.String()), nil
101 }
102
103
104 func addSignFile(ff *fuzz.ConsumeFuzzer, tarFiles []*fuzz.TarFile) ([]*fuzz.TarFile, error) {
105 SIGNFileContents, err := ff.GetBytes()
106 if err != nil {
107 return tarFiles, err
108 }
109
110 SIGNFileName, err := getSignFilename(ff)
111 if err != nil {
112 return tarFiles, err
113 }
114 signFile := &fuzz.TarFile{
115 Body: SIGNFileContents,
116 Hdr: &tar.Header{
117 Name: SIGNFileName,
118 Mode: 0644,
119 Size: int64(len(SIGNFileContents)),
120 Typeflag: tar.TypeReg,
121 Gid: 0,
122 Uid: 0,
123 },
124 }
125 tarFiles = append(tarFiles, signFile)
126
127 return tarFiles, nil
128 }
129
130
131
132 func shouldAddSignFile(ff *fuzz.ConsumeFuzzer, tarFiles []*fuzz.TarFile) bool {
133 shouldRequireSIGNFile, err := ff.GetBool()
134 if err != nil {
135 return false
136 }
137 if shouldRequireSIGNFile {
138 for _, tarFile := range tarFiles {
139 if strings.HasPrefix(tarFile.Hdr.Name, ".SIGN") {
140 return false
141 }
142 }
143 return true
144 }
145 return false
146 }
147
148
149
150 func shouldAddPkgInfoFile(ff *fuzz.ConsumeFuzzer, tarFiles []*fuzz.TarFile) bool {
151 shouldRequirePKGINFOFile, err := ff.GetBool()
152 if err != nil {
153 return false
154 }
155 if shouldRequirePKGINFOFile {
156 for _, tarFile := range tarFiles {
157 if strings.HasPrefix(tarFile.Hdr.Name, ".PKGINFO") {
158 return false
159 }
160 }
161 return true
162 }
163 return false
164 }
165
166
167 func addPkgInfoFile(ff *fuzz.ConsumeFuzzer, tarFiles []*fuzz.TarFile) ([]*fuzz.TarFile, error) {
168 tarFile := &fuzz.TarFile{}
169 PKGINFOFileContents, err := createPkgInfoFileContents(ff)
170 if err != nil {
171 return tarFiles, err
172 }
173 tarFile.Body = PKGINFOFileContents
174 tarFile.Hdr = &tar.Header{
175 Name: ".PKGINFO",
176 Mode: 0644,
177 Size: int64(len(PKGINFOFileContents)),
178 Typeflag: tar.TypeReg,
179 Gid: 0,
180 Uid: 0,
181 }
182
183 return tarFiles, nil
184 }
185
186 func AlpineArtifactBytes(ff *fuzz.ConsumeFuzzer) ([]byte, error) {
187 var tarFiles, tarFiles2 []*fuzz.TarFile
188 var err error
189
190 tarFiles, err = ff.TarFiles()
191 if err != nil {
192 return []byte(""), err
193 }
194 if shouldAddSignFile(ff, tarFiles) {
195 tarFiles, err = addSignFile(ff, tarFiles)
196 if err != nil {
197 return []byte(""), err
198 }
199 }
200
201 tarFiles2, err = ff.TarFiles()
202 if err != nil {
203 return []byte(""), err
204 }
205
206 if shouldAddPkgInfoFile(ff, tarFiles2) {
207 tarFiles2, err = addPkgInfoFile(ff, tarFiles2)
208 if err != nil {
209 return []byte(""), err
210 }
211 }
212
213 return concatenateTarArchives(tarFiles, tarFiles2)
214 }
215
216 func concatenateTarArchives(tarFiles1 []*fuzz.TarFile, tarFiles2 []*fuzz.TarFile) ([]byte, error) {
217 var buf1, buf2 bytes.Buffer
218 var err error
219
220 tw1 := tar.NewWriter(&buf1)
221 for _, tf := range tarFiles1 {
222 err = tw1.WriteHeader(tf.Hdr)
223 if err != nil {
224 return []byte(""), err
225 }
226 _, err = tw1.Write(tf.Body)
227 if err != nil {
228 return []byte(""), err
229 }
230 }
231 tw1.Close()
232 tarBytes := buf1.Bytes()
233
234 tw2 := tar.NewWriter(&buf2)
235 for _, tf := range tarFiles2 {
236 err = tw2.WriteHeader(tf.Hdr)
237 if err != nil {
238 return []byte(""), err
239 }
240 _, err = tw2.Write(tf.Body)
241 if err != nil {
242 return []byte(""), err
243 }
244 }
245 tw2.Close()
246 tarBytes2 := buf2.Bytes()
247
248 var b1 bytes.Buffer
249 w1 := gzip.NewWriter(&b1)
250 defer w1.Close()
251 _, err = w1.Write(tarBytes)
252 if err != nil {
253 return []byte(""), err
254 }
255 w1.Close()
256
257 var b2 bytes.Buffer
258 w2 := gzip.NewWriter(&b2)
259 defer w2.Close()
260 _, err = w2.Write(tarBytes2)
261 if err != nil {
262 return []byte(""), err
263 }
264 w2.Close()
265 concatenated := append(b1.Bytes(), b2.Bytes()...)
266 return concatenated, nil
267 }
268
269 func setAlpineArtifactFields(ff *fuzz.ConsumeFuzzer, props *types.ArtifactProperties) (func(), error) {
270 cleanup := func() {}
271
272 err := setArtifactHash(ff, props)
273 if err != nil {
274 return cleanup, err
275 }
276
277 artifactBytes, err := AlpineArtifactBytes(ff)
278 if err != nil {
279 return cleanup, err
280 }
281
282 shouldSetArtifactBytes, err := ff.GetBool()
283 if err != nil {
284 return cleanup, err
285 }
286
287 if shouldSetArtifactBytes {
288 props.ArtifactBytes = artifactBytes
289 return func() {
290
291 }, nil
292 }
293 artifactFile, err := createAbsFile(ff, "ArtifactFile", artifactBytes)
294 cleanup = func() {
295 os.Remove("ArtifactFile")
296 }
297 props.ArtifactPath = artifactFile
298 return cleanup, err
299 }
300
301
302 func CreateAlpineProps(ff *fuzz.ConsumeFuzzer) (types.ArtifactProperties, func(), error) {
303 props := &types.ArtifactProperties{}
304
305 cleanupArtifactFile, err := setAlpineArtifactFields(ff, props)
306 if err != nil {
307 return *props, cleanupArtifactFile, err
308 }
309 if props.ArtifactPath == nil && props.ArtifactBytes == nil {
310 return *props, cleanupArtifactFile, errors.New("ArtifactPath and ArtifactBytes cannot both be nil")
311 }
312
313 err = setAdditionalAuthenticatedData(ff, props)
314 if err != nil {
315 return *props, cleanupArtifactFile, errors.New("Failed setting AdditionalAuthenticatedData")
316 }
317
318 cleanupSignatureFile, err := setSignatureFields(ff, props)
319 if err != nil {
320 return *props, func() {
321 cleanupArtifactFile()
322 cleanupSignatureFile()
323 }, fmt.Errorf("failed setting signature fields: %w", err)
324 }
325
326 cleanupPublicKeyFile, err := setPublicKeyFields(ff, props)
327 if err != nil {
328 return *props, func() {
329 cleanupArtifactFile()
330 cleanupSignatureFile()
331 cleanupPublicKeyFile()
332 }, fmt.Errorf("failed setting public key fields: %w", err)
333 }
334
335 err = setPKIFormat(ff, props)
336 if err != nil {
337 return *props, func() {
338 cleanupArtifactFile()
339 cleanupSignatureFile()
340 cleanupPublicKeyFile()
341 }, fmt.Errorf("failed setting PKI Format: %w", err)
342 }
343
344 return *props, func() {
345 cleanupArtifactFile()
346 cleanupSignatureFile()
347 cleanupPublicKeyFile()
348 }, nil
349 }
350
View as plain text