Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try out Attestations() #779

Merged
merged 1 commit into from
Sep 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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