forked from sigstore/sigstore
-
Notifications
You must be signed in to change notification settings - Fork 0
/
payload.go
105 lines (91 loc) · 3.72 KB
/
payload.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
//
// Copyright 2021 The Sigstore Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package payload TODO: add meaningfull description
package payload
import (
"encoding/json"
"fmt"
"github.com/google/go-containerregistry/pkg/name"
)
// CosignSignatureType is the value of `critical.type` in a SimpleContainerImage payload.
const CosignSignatureType = "cosign container image signature"
// SimpleContainerImage describes the structure of a basic container image signature payload, as defined at:
// https://github.com/containers/image/blob/master/docs/containers-signature.5.md#json-data-format
type SimpleContainerImage struct {
Critical Critical `json:"critical"` // Critical data critical to correctly evaluating the validity of the signature
Optional map[string]interface{} `json:"optional"` // Optional optional metadata about the image
}
// Critical data critical to correctly evaluating the validity of a signature
type Critical struct {
Identity Identity `json:"identity"` // Identity claimed identity of the image
Image Image `json:"image"` // Image identifies the container that the signature applies to
Type string `json:"type"` // Type must be 'atomic container signature'
}
// Identity is the claimed identity of the image
type Identity struct {
DockerReference string `json:"docker-reference"` // DockerReference is a reference used to refer to or download the image
}
// Image identifies the container image that the signature applies to
type Image struct {
DockerManifestDigest string `json:"docker-manifest-digest"` // DockerManifestDigest the manifest digest of the signed container image
}
// Cosign describes a container image signed using Cosign
type Cosign struct {
Image name.Digest
Annotations map[string]interface{}
}
// SimpleContainerImage returns information about a container image in the github.com/containers/image/signature format
func (p Cosign) SimpleContainerImage() SimpleContainerImage {
return SimpleContainerImage{
Critical: Critical{
Identity: Identity{
DockerReference: p.Image.Repository.Name(),
},
Image: Image{
DockerManifestDigest: p.Image.DigestStr(),
},
Type: CosignSignatureType,
},
Optional: p.Annotations,
}
}
// MarshalJSON marshals the container signature into a []byte of JSON data
func (p Cosign) MarshalJSON() ([]byte, error) {
return json.Marshal(p.SimpleContainerImage())
}
var _ json.Marshaler = Cosign{}
// UnmarshalJSON unmarshals []byte of JSON data into a container signature object
func (p *Cosign) UnmarshalJSON(data []byte) error {
if string(data) == "null" {
// JSON "null" is a no-op by convention
return nil
}
var simple SimpleContainerImage
if err := json.Unmarshal(data, &simple); err != nil {
return err
}
if simple.Critical.Type != CosignSignatureType {
return fmt.Errorf("Cosign signature payload was of an unknown type: %q", simple.Critical.Type)
}
digestStr := simple.Critical.Identity.DockerReference + "@" + simple.Critical.Image.DockerManifestDigest
digest, err := name.NewDigest(digestStr)
if err != nil {
return fmt.Errorf("could not parse image digest string %q: %w", digestStr, err)
}
p.Image = digest
p.Annotations = simple.Optional
return nil
}
var _ json.Unmarshaler = (*Cosign)(nil)