Skip to content

Commit

Permalink
Try out Attestations(). (#779)
Browse files Browse the repository at this point in the history
I know I just killed this off for being NYI, but I don't like the fact that we need `WithSignatureSuffix` to access things.

Related: #666
Signed-off-by: Matt Moore <[email protected]>
  • Loading branch information
mattmoor authored Sep 24, 2021
1 parent c9bd912 commit 182936d
Show file tree
Hide file tree
Showing 17 changed files with 357 additions and 23 deletions.
15 changes: 5 additions & 10 deletions cmd/cosign/cli/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,27 +209,22 @@ func AttestCmd(ctx context.Context, ko sign.KeyOpts, regOpts options.RegistryOpt
opts = append(opts, static.WithBundle(bundle))
}

clientOpts := append(
regOpts.ClientOpts(ctx),
ociremote.WithSignatureSuffix(ociremote.AttestationTagSuffix),
)

sig, err := static.NewAttestation(signedPayload, opts...)
if err != nil {
return err
}

se, err := ociremote.SignedEntity(digest, clientOpts...)
se, err := ociremote.SignedEntity(digest, regOpts.ClientOpts(ctx)...)
if err != nil {
return err
}

// Attach the signature to the entity.
newSE, err := mutate.AttachSignatureToEntity(se, sig, mutate.WithDupeDetector(dd))
// Attach the attestation to the entity.
newSE, err := mutate.AttachAttestationToEntity(se, sig, mutate.WithDupeDetector(dd))
if err != nil {
return err
}

// Publish the signatures associated with this entity
return ociremote.WriteSignatures(digest.Repository, newSE, clientOpts...)
// Publish the attestations associated with this entity
return ociremote.WriteAttestations(digest.Repository, newSE, regOpts.ClientOpts(ctx)...)
}
2 changes: 2 additions & 0 deletions cmd/cosign/cli/verify/verify_attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ func (c *VerifyAttestationCommand) Exec(ctx context.Context, args []string) (err
return err
}

// TODO(mattmoor): Add some sort of configuration to have this
// use Attestations() in place of Signatures().
verified, bundleVerified, err := cosign.Verify(ctx, ref, co)
if err != nil {
return err
Expand Down
4 changes: 1 addition & 3 deletions pkg/cosign/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,7 @@ func Verify(ctx context.Context, signedImgRef name.Reference, co *CheckOpts) (ch
}
}

opts := co.RegistryClientOpts

se, err := ociremote.SignedEntity(signedImgRef, opts...)
se, err := ociremote.SignedEntity(signedImgRef, co.RegistryClientOpts...)
if err != nil {
return nil, false, err
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/oci/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@ type SignedEntity interface {
// Signatures returns the set of signatures currently associated with this
// entity, or the empty equivalent if none are found.
Signatures() (Signatures, error)

// Attestations returns the set of attestations currently associated with this
// entity, or the empty equivalent if none are found.
Attestations() (Signatures, error)
}
79 changes: 79 additions & 0 deletions pkg/oci/mutate/mutate.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ func (i *indexWrapper) Signatures() (oci.Signatures, error) {
return empty.Signatures(), nil
}

// Attestations implements oic.SignedImageIndex
func (i *indexWrapper) Attestations() (oci.Signatures, error) {
return empty.Signatures(), nil
}

// SignedImage implements oic.SignedImageIndex
func (i *indexWrapper) SignedImage(h v1.Hash) (oci.SignedImage, error) {
for _, add := range i.addendum {
Expand Down Expand Up @@ -128,6 +133,18 @@ func AttachSignatureToEntity(se oci.SignedEntity, sig oci.Signature, opts ...Sig
}
}

// AttachAttestationToEntity attaches the provided attestation to the provided entity.
func AttachAttestationToEntity(se oci.SignedEntity, att oci.Signature, opts ...SignOption) (oci.SignedEntity, error) {
switch obj := se.(type) {
case oci.SignedImage:
return AttachAttestationToImage(obj, att, opts...)
case oci.SignedImageIndex:
return AttachAttestationToImageIndex(obj, att, opts...)
default:
return nil, fmt.Errorf("unsupported type: %T", se)
}
}

// AttachSignatureToImage attaches the provided signature to the provided image.
func AttachSignatureToImage(si oci.SignedImage, sig oci.Signature, opts ...SignOption) (oci.SignedImage, error) {
return &signedImage{
Expand All @@ -137,9 +154,19 @@ func AttachSignatureToImage(si oci.SignedImage, sig oci.Signature, opts ...SignO
}, nil
}

// AttachAttestationToImage attaches the provided signature to the provided image.
func AttachAttestationToImage(si oci.SignedImage, att oci.Signature, opts ...SignOption) (oci.SignedImage, error) {
return &signedImage{
SignedImage: si,
att: att,
so: makeSignOpts(opts...),
}, nil
}

type signedImage struct {
oci.SignedImage
sig oci.Signature
att oci.Signature
so *signOpts
}

Expand All @@ -148,6 +175,8 @@ func (si *signedImage) Signatures() (oci.Signatures, error) {
base, err := si.SignedImage.Signatures()
if err != nil {
return nil, err
} else if si.sig == nil {
return base, nil
}
if si.so.dd != nil {
if existing, err := si.so.dd.Find(base, si.sig); err != nil {
Expand All @@ -160,6 +189,25 @@ func (si *signedImage) Signatures() (oci.Signatures, error) {
return AppendSignatures(base, si.sig)
}

// Attestations implements oci.SignedImage
func (si *signedImage) Attestations() (oci.Signatures, error) {
base, err := si.SignedImage.Attestations()
if err != nil {
return nil, err
} else if si.att == nil {
return base, nil
}
if si.so.dd != nil {
if existing, err := si.so.dd.Find(base, si.att); err != nil {
return nil, err
} else if existing != nil {
// Just return base if the signature is redundant
return base, nil
}
}
return AppendSignatures(base, si.att)
}

// AttachSignatureToImageIndex attaches the provided signature to the provided image index.
func AttachSignatureToImageIndex(sii oci.SignedImageIndex, sig oci.Signature, opts ...SignOption) (oci.SignedImageIndex, error) {
return &signedImageIndex{
Expand All @@ -169,11 +217,21 @@ func AttachSignatureToImageIndex(sii oci.SignedImageIndex, sig oci.Signature, op
}, nil
}

// AttachAttestationToImageIndex attaches the provided attestation to the provided image index.
func AttachAttestationToImageIndex(sii oci.SignedImageIndex, att oci.Signature, opts ...SignOption) (oci.SignedImageIndex, error) {
return &signedImageIndex{
ociSignedImageIndex: sii,
att: att,
so: makeSignOpts(opts...),
}, nil
}

type ociSignedImageIndex oci.SignedImageIndex

type signedImageIndex struct {
ociSignedImageIndex
sig oci.Signature
att oci.Signature
so *signOpts
}

Expand All @@ -182,6 +240,8 @@ func (sii *signedImageIndex) Signatures() (oci.Signatures, error) {
base, err := sii.ociSignedImageIndex.Signatures()
if err != nil {
return nil, err
} else if sii.sig == nil {
return base, nil
}
if sii.so.dd != nil {
if existing, err := sii.so.dd.Find(base, sii.sig); err != nil {
Expand All @@ -193,3 +253,22 @@ func (sii *signedImageIndex) Signatures() (oci.Signatures, error) {
}
return AppendSignatures(base, sii.sig)
}

// Attestations implements oci.SignedImageIndex
func (sii *signedImageIndex) Attestations() (oci.Signatures, error) {
base, err := sii.ociSignedImageIndex.Attestations()
if err != nil {
return nil, err
} else if sii.att == nil {
return base, nil
}
if sii.so.dd != nil {
if existing, err := sii.so.dd.Find(base, sii.att); err != nil {
return nil, err
} else if existing != nil {
// Just return base if the signature is redundant
return base, nil
}
}
return AppendSignatures(base, sii.att)
}
Loading

0 comments on commit 182936d

Please sign in to comment.