@@ -141,12 +141,21 @@ type SignOptions struct {
141
141
// Sign signs the OCI artifact and push the signature to the Repository.
142
142
// The descriptor of the sign content is returned upon successful signing.
143
143
func Sign (ctx context.Context , signer Signer , repo registry.Repository , signOpts SignOptions ) (ocispec.Descriptor , error ) {
144
+ artifactMenifestDesc , _ , err := SignOCI (ctx , signer , repo , signOpts )
145
+ return artifactMenifestDesc , err
146
+ }
147
+
148
+ // SignOCI signs the OCI artifact and push the signature to the Repository.
149
+ //
150
+ // Both artifact and signature manifest descriptors are returned upon successful
151
+ // signing.
152
+ func SignOCI (ctx context.Context , signer Signer , repo registry.Repository , signOpts SignOptions ) (artifactManifestDesc ocispec.Descriptor , sigManifestDesc ocispec.Descriptor , err error ) {
144
153
// sanity check
145
154
if err := validateSignArguments (signer , signOpts .SignerSignOptions ); err != nil {
146
- return ocispec.Descriptor {}, err
155
+ return ocispec.Descriptor {}, ocispec. Descriptor {}, err
147
156
}
148
157
if repo == nil {
149
- return ocispec.Descriptor {}, errors .New ("repo cannot be nil" )
158
+ return ocispec.Descriptor {}, ocispec. Descriptor {}, errors .New ("repo cannot be nil" )
150
159
}
151
160
152
161
logger := log .GetLogger (ctx )
@@ -155,30 +164,30 @@ func Sign(ctx context.Context, signer Signer, repo registry.Repository, signOpts
155
164
// artifactRef is a valid full reference
156
165
artifactRef = ref .Reference
157
166
}
158
- targetDesc , err : = repo .Resolve (ctx , artifactRef )
167
+ artifactManifestDesc , err = repo .Resolve (ctx , artifactRef )
159
168
if err != nil {
160
- return ocispec.Descriptor {}, fmt .Errorf ("failed to resolve reference: %w" , err )
169
+ return ocispec.Descriptor {}, ocispec. Descriptor {}, fmt .Errorf ("failed to resolve reference: %w" , err )
161
170
}
162
171
163
172
// artifactRef is a tag or a digest, if it's a digest it has to match
164
173
// the resolved digest
165
- if artifactRef != targetDesc .Digest .String () {
174
+ if artifactRef != artifactManifestDesc .Digest .String () {
166
175
if _ , err := digest .Parse (artifactRef ); err == nil {
167
176
// artifactRef is a digest, but does not match the resolved digest
168
- return ocispec.Descriptor {}, fmt .Errorf ("user input digest %s does not match the resolved digest %s" , artifactRef , targetDesc .Digest .String ())
177
+ return ocispec.Descriptor {}, ocispec. Descriptor {}, fmt .Errorf ("user input digest %s does not match the resolved digest %s" , artifactRef , artifactManifestDesc .Digest .String ())
169
178
}
170
179
171
180
// artifactRef is a tag
172
181
logger .Warnf ("Always sign the artifact using digest(`@sha256:...`) rather than a tag(`:%s`) because tags are mutable and a tag reference can point to a different artifact than the one signed" , artifactRef )
173
- logger .Infof ("Resolved artifact tag `%s` to digest `%v` before signing" , artifactRef , targetDesc .Digest )
182
+ logger .Infof ("Resolved artifact tag `%s` to digest `%v` before signing" , artifactRef , artifactManifestDesc .Digest )
174
183
}
175
- descToSign , err := addUserMetadataToDescriptor (ctx , targetDesc , signOpts .UserMetadata )
184
+ descToSign , err := addUserMetadataToDescriptor (ctx , artifactManifestDesc , signOpts .UserMetadata )
176
185
if err != nil {
177
- return ocispec.Descriptor {}, err
186
+ return ocispec.Descriptor {}, ocispec. Descriptor {}, err
178
187
}
179
188
sig , signerInfo , err := signer .Sign (ctx , descToSign , signOpts .SignerSignOptions )
180
189
if err != nil {
181
- return ocispec.Descriptor {}, err
190
+ return ocispec.Descriptor {}, ocispec. Descriptor {}, err
182
191
}
183
192
184
193
var pluginAnnotations map [string ]string
@@ -188,21 +197,21 @@ func Sign(ctx context.Context, signer Signer, repo registry.Repository, signOpts
188
197
logger .Debug ("Generating annotation" )
189
198
annotations , err := generateAnnotations (signerInfo , pluginAnnotations )
190
199
if err != nil {
191
- return ocispec.Descriptor {}, err
200
+ return ocispec.Descriptor {}, ocispec. Descriptor {}, err
192
201
}
193
202
logger .Debugf ("Generated annotations: %+v" , annotations )
194
- logger .Debugf ("Pushing signature of artifact descriptor: %+v, signature media type: %v" , targetDesc , signOpts .SignatureMediaType )
195
- _ , _ , err = repo .PushSignature (ctx , signOpts .SignatureMediaType , sig , targetDesc , annotations )
203
+ logger .Debugf ("Pushing signature of artifact descriptor: %+v, signature media type: %v" , artifactManifestDesc , signOpts .SignatureMediaType )
204
+ _ , sigManifestDesc , err = repo .PushSignature (ctx , signOpts .SignatureMediaType , sig , artifactManifestDesc , annotations )
196
205
if err != nil {
197
206
var referrerError * remote.ReferrersError
198
207
199
208
// do not log an error for failing to delete referral index
200
209
if ! errors .As (err , & referrerError ) || ! referrerError .IsReferrersIndexDelete () {
201
210
logger .Error ("Failed to push the signature" )
202
211
}
203
- return ocispec.Descriptor {}, ErrorPushSignatureFailed {Msg : err .Error ()}
212
+ return ocispec.Descriptor {}, ocispec. Descriptor {}, ErrorPushSignatureFailed {Msg : err .Error ()}
204
213
}
205
- return targetDesc , nil
214
+ return artifactManifestDesc , sigManifestDesc , nil
206
215
}
207
216
208
217
// SignBlob signs the arbitrary data from blobReader and returns
0 commit comments