...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package mutate
16
17 import (
18 "bytes"
19 "crypto/x509"
20 "encoding/json"
21 "fmt"
22 "io"
23
24 v1 "github.com/google/go-containerregistry/pkg/v1"
25 "github.com/google/go-containerregistry/pkg/v1/types"
26 "github.com/sigstore/cosign/v2/pkg/cosign/bundle"
27 "github.com/sigstore/cosign/v2/pkg/oci"
28 "github.com/sigstore/cosign/v2/pkg/oci/static"
29 "github.com/sigstore/sigstore/pkg/cryptoutils"
30 )
31
32 type sigWrapper struct {
33 wrapped oci.Signature
34
35 annotations map[string]string
36 bundle *bundle.RekorBundle
37 rfc3161Timestamp *bundle.RFC3161Timestamp
38 cert *x509.Certificate
39 chain []*x509.Certificate
40 mediaType types.MediaType
41 }
42
43 var _ v1.Layer = (*sigWrapper)(nil)
44 var _ oci.Signature = (*sigWrapper)(nil)
45
46 func copyAnnotations(ann map[string]string) map[string]string {
47 new := make(map[string]string, len(ann))
48 for k, v := range ann {
49 new[k] = v
50 }
51 return new
52 }
53
54
55 func (sw *sigWrapper) Annotations() (map[string]string, error) {
56 if sw.annotations != nil {
57 return copyAnnotations(sw.annotations), nil
58 }
59 return sw.wrapped.Annotations()
60 }
61
62
63 func (sw *sigWrapper) Payload() ([]byte, error) {
64 return sw.wrapped.Payload()
65 }
66
67
68 func (sw *sigWrapper) Signature() ([]byte, error) {
69 return sw.wrapped.Signature()
70 }
71
72
73 func (sw *sigWrapper) Base64Signature() (string, error) {
74 return sw.wrapped.Base64Signature()
75 }
76
77
78 func (sw *sigWrapper) Cert() (*x509.Certificate, error) {
79 if sw.cert != nil {
80 return sw.cert, nil
81 }
82 return sw.wrapped.Cert()
83 }
84
85
86 func (sw *sigWrapper) Chain() ([]*x509.Certificate, error) {
87 if sw.chain != nil {
88 return sw.chain, nil
89 }
90 return sw.wrapped.Chain()
91 }
92
93
94 func (sw *sigWrapper) Bundle() (*bundle.RekorBundle, error) {
95 if sw.bundle != nil {
96 return sw.bundle, nil
97 }
98 return sw.wrapped.Bundle()
99 }
100
101
102 func (sw *sigWrapper) RFC3161Timestamp() (*bundle.RFC3161Timestamp, error) {
103 if sw.rfc3161Timestamp != nil {
104 return sw.rfc3161Timestamp, nil
105 }
106 return sw.wrapped.RFC3161Timestamp()
107 }
108
109
110 func (sw *sigWrapper) MediaType() (types.MediaType, error) {
111 if sw.mediaType != "" {
112 return sw.mediaType, nil
113 }
114 return sw.wrapped.MediaType()
115 }
116
117
118 func (sw *sigWrapper) Digest() (v1.Hash, error) {
119 return sw.wrapped.Digest()
120 }
121
122
123 func (sw *sigWrapper) DiffID() (v1.Hash, error) {
124 return sw.wrapped.DiffID()
125 }
126
127
128 func (sw *sigWrapper) Compressed() (io.ReadCloser, error) {
129 return sw.wrapped.Compressed()
130 }
131
132
133 func (sw *sigWrapper) Uncompressed() (io.ReadCloser, error) {
134 return sw.wrapped.Uncompressed()
135 }
136
137
138 func (sw *sigWrapper) Size() (int64, error) {
139 return sw.wrapped.Size()
140 }
141
142
143 func Signature(original oci.Signature, opts ...SignatureOption) (oci.Signature, error) {
144 newSig := sigWrapper{wrapped: original}
145
146 so := makeSignatureOption(opts...)
147 oldAnn, err := original.Annotations()
148 if err != nil {
149 return nil, fmt.Errorf("could not get annotations from signature to mutate: %w", err)
150 }
151
152 var newAnn map[string]string
153 if so.annotations != nil {
154 newAnn = copyAnnotations(so.annotations)
155 newAnn[static.SignatureAnnotationKey] = oldAnn[static.SignatureAnnotationKey]
156 for _, key := range []string{static.BundleAnnotationKey, static.CertificateAnnotationKey, static.ChainAnnotationKey, static.RFC3161TimestampAnnotationKey} {
157 if val, isSet := oldAnn[key]; isSet {
158 newAnn[key] = val
159 } else {
160 delete(newAnn, key)
161 }
162 }
163 } else {
164 newAnn = copyAnnotations(oldAnn)
165 }
166
167 if so.bundle != nil {
168 newSig.bundle = so.bundle
169 b, err := json.Marshal(so.bundle)
170 if err != nil {
171 return nil, err
172 }
173 newAnn[static.BundleAnnotationKey] = string(b)
174 }
175
176 if so.rfc3161Timestamp != nil {
177 newSig.rfc3161Timestamp = so.rfc3161Timestamp
178 b, err := json.Marshal(so.rfc3161Timestamp)
179 if err != nil {
180 return nil, err
181 }
182 newAnn[static.RFC3161TimestampAnnotationKey] = string(b)
183 }
184
185 if so.cert != nil {
186 var cert *x509.Certificate
187 var chain []*x509.Certificate
188
189 certs, err := cryptoutils.LoadCertificatesFromPEM(bytes.NewReader(so.cert))
190 if err != nil {
191 return nil, err
192 }
193 newAnn[static.CertificateAnnotationKey] = string(so.cert)
194 cert = certs[0]
195
196 delete(newAnn, static.ChainAnnotationKey)
197 if so.chain != nil {
198 chain, err = cryptoutils.LoadCertificatesFromPEM(bytes.NewReader(so.chain))
199 if err != nil {
200 return nil, err
201 }
202 newAnn[static.ChainAnnotationKey] = string(so.chain)
203 }
204
205 newSig.cert = cert
206 newSig.chain = chain
207 }
208
209 if so.mediaType != "" {
210 newSig.mediaType = so.mediaType
211 }
212
213 newSig.annotations = newAnn
214
215 return &newSig, nil
216 }
217
View as plain text