From 2472e9416f36267d58a0779f086cec7dc4428dbc Mon Sep 17 00:00:00 2001 From: Jake Sanders Date: Wed, 15 Dec 2021 10:53:31 -0800 Subject: [PATCH 1/9] rename `Signer` files Signed-off-by: Jake Sanders --- internal/pkg/cosign/fulcio/{fulcio.go => signer.go} | 0 internal/pkg/cosign/payload/{payload.go => signer.go} | 0 internal/pkg/cosign/rekor/{rekor.go => signer.go} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename internal/pkg/cosign/fulcio/{fulcio.go => signer.go} (100%) rename internal/pkg/cosign/payload/{payload.go => signer.go} (100%) rename internal/pkg/cosign/rekor/{rekor.go => signer.go} (100%) diff --git a/internal/pkg/cosign/fulcio/fulcio.go b/internal/pkg/cosign/fulcio/signer.go similarity index 100% rename from internal/pkg/cosign/fulcio/fulcio.go rename to internal/pkg/cosign/fulcio/signer.go diff --git a/internal/pkg/cosign/payload/payload.go b/internal/pkg/cosign/payload/signer.go similarity index 100% rename from internal/pkg/cosign/payload/payload.go rename to internal/pkg/cosign/payload/signer.go diff --git a/internal/pkg/cosign/rekor/rekor.go b/internal/pkg/cosign/rekor/signer.go similarity index 100% rename from internal/pkg/cosign/rekor/rekor.go rename to internal/pkg/cosign/rekor/signer.go From 8c9b9056273f921c571e59fb02867b6d132c8db7 Mon Sep 17 00:00:00 2001 From: Jake Sanders Date: Wed, 15 Dec 2021 11:08:01 -0800 Subject: [PATCH 2/9] create `DSSEAttestor` interface Signed-off-by: Jake Sanders --- internal/pkg/cosign/dsse.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 internal/pkg/cosign/dsse.go diff --git a/internal/pkg/cosign/dsse.go b/internal/pkg/cosign/dsse.go new file mode 100644 index 00000000000..f76f65469f1 --- /dev/null +++ b/internal/pkg/cosign/dsse.go @@ -0,0 +1,30 @@ +// 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 cosign + +import ( + "context" + "crypto" + "io" + + "github.com/sigstore/cosign/pkg/oci" +) + +// DSSEAttestor creates attestations in the form of `oci.Signature`s +type DSSEAttestor interface { + // Attest creates an attestation, in the form of an `oci.Signature`, from the given payload. + // The signature and payload are stored as a DSSE envelope in `osi.Signature.Payload()` + DSSEAttest(ctx context.Context, payload io.Reader) (oci.Signature, crypto.PublicKey, error) +} From 9785ce00ef30dbb1cbaba14819fb18f3d2e50f12 Mon Sep 17 00:00:00 2001 From: Jake Sanders Date: Wed, 15 Dec 2021 11:10:08 -0800 Subject: [PATCH 3/9] create `payload.DSSEAttestor` Signed-off-by: Jake Sanders --- internal/pkg/cosign/payload/attestor.go | 86 ++++++++++++++++++++ internal/pkg/cosign/payload/attestor_test.go | 86 ++++++++++++++++++++ internal/pkg/cosign/payload/signer.go | 49 +++++++---- internal/pkg/cosign/payload/signer_test.go | 79 ++++++++++++++++++ 4 files changed, 284 insertions(+), 16 deletions(-) create mode 100644 internal/pkg/cosign/payload/attestor.go create mode 100644 internal/pkg/cosign/payload/attestor_test.go create mode 100644 internal/pkg/cosign/payload/signer_test.go diff --git a/internal/pkg/cosign/payload/attestor.go b/internal/pkg/cosign/payload/attestor.go new file mode 100644 index 00000000000..52e63e10744 --- /dev/null +++ b/internal/pkg/cosign/payload/attestor.go @@ -0,0 +1,86 @@ +// 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 + +import ( + "bytes" + "context" + "crypto" + "encoding/base64" + "encoding/json" + "io" + + "github.com/secure-systems-lab/go-securesystemslib/dsse" + "github.com/sigstore/cosign/internal/pkg/cosign" + "github.com/sigstore/cosign/pkg/oci" + "github.com/sigstore/cosign/pkg/oci/static" + "github.com/sigstore/cosign/pkg/types" + "github.com/sigstore/sigstore/pkg/signature" +) + +type payloadAttestor struct { + payloadSigner + + payloadType string +} + +var _ cosign.DSSEAttestor = (*payloadAttestor)(nil) + +// Attest implements `cosign.DSSEAttestor` +func (pa *payloadAttestor) DSSEAttest(ctx context.Context, payload io.Reader) (oci.Signature, crypto.PublicKey, error) { + p, err := io.ReadAll(payload) + if err != nil { + return nil, nil, err + } + pae := dsse.PAE(pa.payloadType, p) + + pb, sig, pk, err := pa.signPayload(ctx, bytes.NewReader(pae)) + if err != nil { + return nil, nil, err + } + + envelope := dsse.Envelope{ + PayloadType: pa.payloadType, + Payload: base64.StdEncoding.EncodeToString(pb), + Signatures: []dsse.Signature{{ + Sig: base64.StdEncoding.EncodeToString(sig), + }}, + } + + envelopeJSON, err := json.Marshal(envelope) + if err != nil { + return nil, nil, err + } + + opts := []static.Option{static.WithLayerMediaType(types.DssePayloadType)} + + att, err := static.NewAttestation(envelopeJSON, opts...) + if err != nil { + return nil, nil, err + } + + return att, pk, nil +} + +// NewDSSEAttestor returns a `cosign.DSSEAttestor` which uses the given `signature.Signer` to sign and create a DSSE attestation of given payloads. +func NewDSSEAttestor(payloadType string, + s signature.Signer, + sOpts []signature.SignOption, + pkOpts []signature.PublicKeyOption) cosign.DSSEAttestor { + return &payloadAttestor{ + payloadSigner: newSigner(s, sOpts, pkOpts), + payloadType: payloadType, + } +} diff --git a/internal/pkg/cosign/payload/attestor_test.go b/internal/pkg/cosign/payload/attestor_test.go new file mode 100644 index 00000000000..0c84bdc9f32 --- /dev/null +++ b/internal/pkg/cosign/payload/attestor_test.go @@ -0,0 +1,86 @@ +// 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 + +import ( + "bytes" + "context" + "crypto" + "encoding/base64" + "encoding/json" + "strings" + "testing" + + "github.com/secure-systems-lab/go-securesystemslib/dsse" + "github.com/sigstore/cosign/pkg/types" + "github.com/sigstore/sigstore/pkg/signature" +) + +func TestDSSEAttestor(t *testing.T) { + testPayloadType := "atTESTation type" + testSigner := NewDSSEAttestor(testPayloadType, mustGetNewSigner(t), nil, nil) + + testPayload := "test payload" + + ociSig, pub, err := testSigner.DSSEAttest(context.Background(), strings.NewReader(testPayload)) + if err != nil { + t.Fatalf("DSSEAttest() returned error: %v", err) + } + + gotMT, err := ociSig.MediaType() + if err != nil { + t.Fatalf("ociSig.MediaType() failed: %v", err) + } + if gotMT != types.DssePayloadType { + t.Errorf("got MediaType() %q, wanted %q", gotMT, types.DssePayloadType) + } + + verifier, err := signature.LoadVerifier(pub, crypto.SHA256) + if err != nil { + t.Fatalf("signature.LoadVerifier(pub) returned error: %v", err) + } + + gotOCISigPayload, err := ociSig.Payload() + if err != nil { + t.Fatalf("ociSig.Payload() returned error: %v", err) + } + + envelope := dsse.Envelope{} + if err := json.Unmarshal(gotOCISigPayload, &envelope); err != nil { + t.Fatalf("json.Unmarshal() failed: %v", err) + } + + if envelope.PayloadType != testPayloadType { + t.Errorf("got PayloadType %q, wanted %q", envelope.PayloadType, testPayloadType) + } + + if len(envelope.Signatures) != 1 { + t.Errorf("expected a single signature in the envelope, got: %v", envelope.Signatures) + } + + gotPayload, err := base64.StdEncoding.DecodeString(envelope.Payload) + if err != nil { + t.Fatalf("base64.StdEncoding.DecodeString(envelope.Payload) failed: %v", err) + } + + gotSig, err := base64.StdEncoding.DecodeString(envelope.Signatures[0].Sig) + if err != nil { + t.Fatalf("base64.StdEncoding.DecodeString(envelope.Signatures[0].Sig) failed: %v", err) + } + + if err = verifier.VerifySignature(bytes.NewReader(gotSig), bytes.NewReader(gotPayload)); err != nil { + t.Errorf("VerifySignature() returned error: %v", err) + } +} diff --git a/internal/pkg/cosign/payload/signer.go b/internal/pkg/cosign/payload/signer.go index 3ca86fe7b90..25882a6116c 100644 --- a/internal/pkg/cosign/payload/signer.go +++ b/internal/pkg/cosign/payload/signer.go @@ -38,40 +38,57 @@ var _ cosign.Signer = (*payloadSigner)(nil) // Sign implements `Signer` func (ps *payloadSigner) Sign(ctx context.Context, payload io.Reader) (oci.Signature, crypto.PublicKey, error) { - payloadBytes, err := io.ReadAll(payload) + payloadBytes, sig, pk, err := ps.signPayload(ctx, payload) if err != nil { return nil, nil, err } - sOpts := []signature.SignOption{signatureoptions.WithContext(ctx)} - sOpts = append(sOpts, ps.payloadSignerOpts...) - sig, err := ps.payloadSigner.SignMessage(bytes.NewReader(payloadBytes), sOpts...) + + b64sig := base64.StdEncoding.EncodeToString(sig) + ociSig, err := static.NewSignature(payloadBytes, b64sig) if err != nil { return nil, nil, err } - pkOpts := []signature.PublicKeyOption{signatureoptions.WithContext(ctx)} - pkOpts = append(pkOpts, ps.publicKeyProviderOpts...) - pk, err := ps.payloadSigner.PublicKey(pkOpts...) + return ociSig, pk, nil +} + +func (ps *payloadSigner) signPayload(ctx context.Context, payload io.Reader) (payloadBytes, sig []byte, pk crypto.PublicKey, err error) { + payloadBytes, err = io.ReadAll(payload) if err != nil { - return nil, nil, err + return nil, nil, nil, err } - b64sig := base64.StdEncoding.EncodeToString(sig) - ociSig, err := static.NewSignature(payloadBytes, b64sig) + sOpts := []signature.SignOption{signatureoptions.WithContext(ctx)} + sOpts = append(sOpts, ps.payloadSignerOpts...) + sig, err = ps.payloadSigner.SignMessage(bytes.NewReader(payloadBytes), sOpts...) if err != nil { - return nil, nil, err + return nil, nil, nil, err } - return ociSig, pk, nil + pkOpts := []signature.PublicKeyOption{signatureoptions.WithContext(ctx)} + pkOpts = append(pkOpts, ps.publicKeyProviderOpts...) + pk, err = ps.payloadSigner.PublicKey(pkOpts...) + if err != nil { + return nil, nil, nil, err + } + + return payloadBytes, sig, pk, nil } -// NewSigner returns a `cosign.Signer` uses the given `signature.Signer` to sign the requested payload, then returns the signature, the public key associated with it, the signed payload -func NewSigner(s signature.Signer, +func newSigner(s signature.Signer, sOpts []signature.SignOption, - pkOpts []signature.PublicKeyOption) cosign.Signer { - return &payloadSigner{ + pkOpts []signature.PublicKeyOption) payloadSigner { + return payloadSigner{ payloadSigner: s, payloadSignerOpts: sOpts, publicKeyProviderOpts: pkOpts, } } + +// NewSigner returns a `cosign.Signer` which uses the given `signature.Signer` to sign requested payloads. +func NewSigner(s signature.Signer, + sOpts []signature.SignOption, + pkOpts []signature.PublicKeyOption) cosign.Signer { + ps := newSigner(s, sOpts, pkOpts) + return &ps +} diff --git a/internal/pkg/cosign/payload/signer_test.go b/internal/pkg/cosign/payload/signer_test.go new file mode 100644 index 00000000000..8c4578ab650 --- /dev/null +++ b/internal/pkg/cosign/payload/signer_test.go @@ -0,0 +1,79 @@ +// 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 + +import ( + "bytes" + "context" + "crypto" + "encoding/base64" + "strings" + "testing" + + "github.com/sigstore/cosign/pkg/cosign" + "github.com/sigstore/sigstore/pkg/signature" +) + +func mustGetNewSigner(t *testing.T) signature.Signer { + t.Helper() + priv, err := cosign.GeneratePrivateKey() + if err != nil { + t.Fatalf("cosign.GeneratePrivateKey() failed: %v", err) + } + s, err := signature.LoadECDSASignerVerifier(priv, crypto.SHA256) + if err != nil { + t.Fatalf("signature.LoadECDSASignerVerifier(key, crypto.SHA256) failed: %v", err) + } + return s +} + +func TestSigner(t *testing.T) { + testSigner := NewSigner(mustGetNewSigner(t), nil, nil) + + testPayload := "test payload" + + ociSig, pub, err := testSigner.Sign(context.Background(), strings.NewReader(testPayload)) + if err != nil { + t.Fatalf("Sign() returned error: %v", err) + } + + verifier, err := signature.LoadVerifier(pub, crypto.SHA256) + if err != nil { + t.Fatalf("signature.LoadVerifier(pub) returned error: %v", err) + } + + b64Sig, err := ociSig.Base64Signature() + if err != nil { + t.Fatalf("ociSig.Base64Signature() returned error: %v", err) + } + + sig, err := base64.StdEncoding.DecodeString(b64Sig) + if err != nil { + t.Fatalf("base64.StdEncoding.DecodeString(b64Sig) returned error: %v", err) + } + + gotPayload, err := ociSig.Payload() + if err != nil { + t.Fatalf("ociSig.Payload() returned error: %v", err) + } + + if string(gotPayload) != testPayload { + t.Errorf("ociSig.Payload() returned %q, wanted %q", string(gotPayload), testPayload) + } + + if err = verifier.VerifySignature(bytes.NewReader(sig), bytes.NewReader(gotPayload)); err != nil { + t.Errorf("VerifySignature() returned error: %v", err) + } +} From 28942cc3fd0c360f4524405f60d919539ed016ca Mon Sep 17 00:00:00 2001 From: Jake Sanders Date: Wed, 15 Dec 2021 15:24:15 -0800 Subject: [PATCH 4/9] consolidate Sign and PublicKey options Signed-off-by: Jake Sanders --- cmd/cosign/cli/sign/sign.go | 2 +- internal/pkg/cosign/payload/attestor.go | 6 ++--- internal/pkg/cosign/payload/attestor_test.go | 2 +- internal/pkg/cosign/payload/signer.go | 26 +++++++++++++++----- internal/pkg/cosign/payload/signer_test.go | 2 +- 5 files changed, 26 insertions(+), 12 deletions(-) diff --git a/cmd/cosign/cli/sign/sign.go b/cmd/cosign/cli/sign/sign.go index 82861b533a9..8bcfcf30d85 100644 --- a/cmd/cosign/cli/sign/sign.go +++ b/cmd/cosign/cli/sign/sign.go @@ -204,7 +204,7 @@ func signDigest(ctx context.Context, digest name.Digest, payload []byte, ko KeyO } var s icos.Signer - s = ipayload.NewSigner(sv, nil, nil) + s = ipayload.NewSigner(sv) s = ifulcio.NewSigner(s, sv.Cert, sv.Chain) if ShouldUploadToTlog(ctx, digest, force, ko.RekorURL) { rClient, err := rekor.NewClient(ko.RekorURL) diff --git a/internal/pkg/cosign/payload/attestor.go b/internal/pkg/cosign/payload/attestor.go index 52e63e10744..0311839ccb2 100644 --- a/internal/pkg/cosign/payload/attestor.go +++ b/internal/pkg/cosign/payload/attestor.go @@ -75,12 +75,12 @@ func (pa *payloadAttestor) DSSEAttest(ctx context.Context, payload io.Reader) (o } // NewDSSEAttestor returns a `cosign.DSSEAttestor` which uses the given `signature.Signer` to sign and create a DSSE attestation of given payloads. +// Option types other than `signature.SignOption` and `signature.PublicKeyOption` cause a runtime panic. func NewDSSEAttestor(payloadType string, s signature.Signer, - sOpts []signature.SignOption, - pkOpts []signature.PublicKeyOption) cosign.DSSEAttestor { + signAndPublicKeyOptions ...interface{}) cosign.DSSEAttestor { return &payloadAttestor{ - payloadSigner: newSigner(s, sOpts, pkOpts), + payloadSigner: newSigner(s, signAndPublicKeyOptions...), payloadType: payloadType, } } diff --git a/internal/pkg/cosign/payload/attestor_test.go b/internal/pkg/cosign/payload/attestor_test.go index 0c84bdc9f32..97f6d3d19e5 100644 --- a/internal/pkg/cosign/payload/attestor_test.go +++ b/internal/pkg/cosign/payload/attestor_test.go @@ -30,7 +30,7 @@ import ( func TestDSSEAttestor(t *testing.T) { testPayloadType := "atTESTation type" - testSigner := NewDSSEAttestor(testPayloadType, mustGetNewSigner(t), nil, nil) + testSigner := NewDSSEAttestor(testPayloadType, mustGetNewSigner(t)) testPayload := "test payload" diff --git a/internal/pkg/cosign/payload/signer.go b/internal/pkg/cosign/payload/signer.go index 25882a6116c..7031c90a12f 100644 --- a/internal/pkg/cosign/payload/signer.go +++ b/internal/pkg/cosign/payload/signer.go @@ -19,6 +19,7 @@ import ( "context" "crypto" "encoding/base64" + "fmt" "io" "github.com/sigstore/cosign/internal/pkg/cosign" @@ -76,8 +77,21 @@ func (ps *payloadSigner) signPayload(ctx context.Context, payload io.Reader) (pa } func newSigner(s signature.Signer, - sOpts []signature.SignOption, - pkOpts []signature.PublicKeyOption) payloadSigner { + signAndPublicKeyOptions ...interface{}) payloadSigner { + var sOpts []signature.SignOption + var pkOpts []signature.PublicKeyOption + + for _, opt := range signAndPublicKeyOptions { + switch o := opt.(type) { + case signature.SignOption: + sOpts = append(sOpts, o) + case signature.PublicKeyOption: + pkOpts = append(pkOpts, o) + default: + panic(fmt.Sprintf("options must be of type `signature.SignOption` or `signature.PublicKeyOption`. Got a %T: %v", o, o)) + } + } + return payloadSigner{ payloadSigner: s, payloadSignerOpts: sOpts, @@ -86,9 +100,9 @@ func newSigner(s signature.Signer, } // NewSigner returns a `cosign.Signer` which uses the given `signature.Signer` to sign requested payloads. +// Option types other than `signature.SignOption` and `signature.PublicKeyOption` cause a runtime panic. func NewSigner(s signature.Signer, - sOpts []signature.SignOption, - pkOpts []signature.PublicKeyOption) cosign.Signer { - ps := newSigner(s, sOpts, pkOpts) - return &ps + signAndPublicKeyOptions ...interface{}) cosign.Signer { + signer := newSigner(s, signAndPublicKeyOptions...) + return &signer } diff --git a/internal/pkg/cosign/payload/signer_test.go b/internal/pkg/cosign/payload/signer_test.go index 8c4578ab650..72ed3407d3e 100644 --- a/internal/pkg/cosign/payload/signer_test.go +++ b/internal/pkg/cosign/payload/signer_test.go @@ -40,7 +40,7 @@ func mustGetNewSigner(t *testing.T) signature.Signer { } func TestSigner(t *testing.T) { - testSigner := NewSigner(mustGetNewSigner(t), nil, nil) + testSigner := NewSigner(mustGetNewSigner(t)) testPayload := "test payload" From fd6c64c88525ec22597a24a8048c8582b0e60b81 Mon Sep 17 00:00:00 2001 From: Jake Sanders Date: Wed, 15 Dec 2021 15:26:06 -0800 Subject: [PATCH 5/9] remove `pae` variable Signed-off-by: Jake Sanders --- internal/pkg/cosign/payload/attestor.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/pkg/cosign/payload/attestor.go b/internal/pkg/cosign/payload/attestor.go index 0311839ccb2..82a0dea7a2a 100644 --- a/internal/pkg/cosign/payload/attestor.go +++ b/internal/pkg/cosign/payload/attestor.go @@ -44,9 +44,8 @@ func (pa *payloadAttestor) DSSEAttest(ctx context.Context, payload io.Reader) (o if err != nil { return nil, nil, err } - pae := dsse.PAE(pa.payloadType, p) - pb, sig, pk, err := pa.signPayload(ctx, bytes.NewReader(pae)) + pb, sig, pk, err := pa.signPayload(ctx, bytes.NewReader(dsse.PAE(pa.payloadType, p))) if err != nil { return nil, nil, err } From 9ab8e7bed160f332c0f193248ab9e2716ec1b48f Mon Sep 17 00:00:00 2001 From: Jake Sanders Date: Wed, 15 Dec 2021 15:29:29 -0800 Subject: [PATCH 6/9] provide payload bytes directly to `signPayload` Signed-off-by: Jake Sanders --- internal/pkg/cosign/payload/attestor.go | 5 +++-- internal/pkg/cosign/payload/signer.go | 18 +++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/internal/pkg/cosign/payload/attestor.go b/internal/pkg/cosign/payload/attestor.go index 82a0dea7a2a..2954226ea84 100644 --- a/internal/pkg/cosign/payload/attestor.go +++ b/internal/pkg/cosign/payload/attestor.go @@ -15,7 +15,6 @@ package payload import ( - "bytes" "context" "crypto" "encoding/base64" @@ -45,7 +44,9 @@ func (pa *payloadAttestor) DSSEAttest(ctx context.Context, payload io.Reader) (o return nil, nil, err } - pb, sig, pk, err := pa.signPayload(ctx, bytes.NewReader(dsse.PAE(pa.payloadType, p))) + pb := dsse.PAE(pa.payloadType, p) + + sig, pk, err := pa.signPayload(ctx, pb) if err != nil { return nil, nil, err } diff --git a/internal/pkg/cosign/payload/signer.go b/internal/pkg/cosign/payload/signer.go index 7031c90a12f..9f20e76cfd3 100644 --- a/internal/pkg/cosign/payload/signer.go +++ b/internal/pkg/cosign/payload/signer.go @@ -39,7 +39,11 @@ var _ cosign.Signer = (*payloadSigner)(nil) // Sign implements `Signer` func (ps *payloadSigner) Sign(ctx context.Context, payload io.Reader) (oci.Signature, crypto.PublicKey, error) { - payloadBytes, sig, pk, err := ps.signPayload(ctx, payload) + payloadBytes, err := io.ReadAll(payload) + if err != nil { + return nil, nil, err + } + sig, pk, err := ps.signPayload(ctx, payloadBytes) if err != nil { return nil, nil, err } @@ -53,27 +57,23 @@ func (ps *payloadSigner) Sign(ctx context.Context, payload io.Reader) (oci.Signa return ociSig, pk, nil } -func (ps *payloadSigner) signPayload(ctx context.Context, payload io.Reader) (payloadBytes, sig []byte, pk crypto.PublicKey, err error) { - payloadBytes, err = io.ReadAll(payload) - if err != nil { - return nil, nil, nil, err - } +func (ps *payloadSigner) signPayload(ctx context.Context, payloadBytes []byte) (sig []byte, pk crypto.PublicKey, err error) { sOpts := []signature.SignOption{signatureoptions.WithContext(ctx)} sOpts = append(sOpts, ps.payloadSignerOpts...) sig, err = ps.payloadSigner.SignMessage(bytes.NewReader(payloadBytes), sOpts...) if err != nil { - return nil, nil, nil, err + return nil, nil, err } pkOpts := []signature.PublicKeyOption{signatureoptions.WithContext(ctx)} pkOpts = append(pkOpts, ps.publicKeyProviderOpts...) pk, err = ps.payloadSigner.PublicKey(pkOpts...) if err != nil { - return nil, nil, nil, err + return nil, nil, err } - return payloadBytes, sig, pk, nil + return sig, pk, nil } func newSigner(s signature.Signer, From 00a1a0e3bceb363054d8f7b3e5cbc04423b95275 Mon Sep 17 00:00:00 2001 From: Jake Sanders Date: Wed, 15 Dec 2021 15:32:38 -0800 Subject: [PATCH 7/9] don't inline payloadSigner Signed-off-by: Jake Sanders --- internal/pkg/cosign/payload/attestor.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/internal/pkg/cosign/payload/attestor.go b/internal/pkg/cosign/payload/attestor.go index 2954226ea84..22f07b03658 100644 --- a/internal/pkg/cosign/payload/attestor.go +++ b/internal/pkg/cosign/payload/attestor.go @@ -30,8 +30,7 @@ import ( ) type payloadAttestor struct { - payloadSigner - + signer payloadSigner payloadType string } @@ -46,7 +45,7 @@ func (pa *payloadAttestor) DSSEAttest(ctx context.Context, payload io.Reader) (o pb := dsse.PAE(pa.payloadType, p) - sig, pk, err := pa.signPayload(ctx, pb) + sig, pk, err := pa.signer.signPayload(ctx, pb) if err != nil { return nil, nil, err } @@ -80,7 +79,7 @@ func NewDSSEAttestor(payloadType string, s signature.Signer, signAndPublicKeyOptions ...interface{}) cosign.DSSEAttestor { return &payloadAttestor{ - payloadSigner: newSigner(s, signAndPublicKeyOptions...), - payloadType: payloadType, + signer: newSigner(s, signAndPublicKeyOptions...), + payloadType: payloadType, } } From 7e975f6b6b2262fe7df09c093ff67e3108153f8b Mon Sep 17 00:00:00 2001 From: Jake Sanders Date: Wed, 15 Dec 2021 15:36:38 -0800 Subject: [PATCH 8/9] unNeceSSarRy LeAdIng WhitESpaCe Signed-off-by: Jake Sanders --- internal/pkg/cosign/payload/signer.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/pkg/cosign/payload/signer.go b/internal/pkg/cosign/payload/signer.go index 9f20e76cfd3..2c4bffdf56a 100644 --- a/internal/pkg/cosign/payload/signer.go +++ b/internal/pkg/cosign/payload/signer.go @@ -58,7 +58,6 @@ func (ps *payloadSigner) Sign(ctx context.Context, payload io.Reader) (oci.Signa } func (ps *payloadSigner) signPayload(ctx context.Context, payloadBytes []byte) (sig []byte, pk crypto.PublicKey, err error) { - sOpts := []signature.SignOption{signatureoptions.WithContext(ctx)} sOpts = append(sOpts, ps.payloadSignerOpts...) sig, err = ps.payloadSigner.SignMessage(bytes.NewReader(payloadBytes), sOpts...) From 6ca3b3e134d5a514e501f3cc77c9a783ab783588 Mon Sep 17 00:00:00 2001 From: Jake Sanders Date: Wed, 15 Dec 2021 15:42:01 -0800 Subject: [PATCH 9/9] split signing and public key retrieval Signed-off-by: Jake Sanders --- internal/pkg/cosign/payload/attestor.go | 6 ++++- internal/pkg/cosign/payload/signer.go | 29 +++++++++++++++---------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/internal/pkg/cosign/payload/attestor.go b/internal/pkg/cosign/payload/attestor.go index 22f07b03658..b2ce7613561 100644 --- a/internal/pkg/cosign/payload/attestor.go +++ b/internal/pkg/cosign/payload/attestor.go @@ -45,7 +45,11 @@ func (pa *payloadAttestor) DSSEAttest(ctx context.Context, payload io.Reader) (o pb := dsse.PAE(pa.payloadType, p) - sig, pk, err := pa.signer.signPayload(ctx, pb) + sig, err := pa.signer.signPayload(ctx, pb) + if err != nil { + return nil, nil, err + } + pk, err := pa.signer.publicKey(ctx) if err != nil { return nil, nil, err } diff --git a/internal/pkg/cosign/payload/signer.go b/internal/pkg/cosign/payload/signer.go index 2c4bffdf56a..e36abaa83c5 100644 --- a/internal/pkg/cosign/payload/signer.go +++ b/internal/pkg/cosign/payload/signer.go @@ -43,7 +43,11 @@ func (ps *payloadSigner) Sign(ctx context.Context, payload io.Reader) (oci.Signa if err != nil { return nil, nil, err } - sig, pk, err := ps.signPayload(ctx, payloadBytes) + sig, err := ps.signPayload(ctx, payloadBytes) + if err != nil { + return nil, nil, err + } + pk, err := ps.publicKey(ctx) if err != nil { return nil, nil, err } @@ -57,22 +61,25 @@ func (ps *payloadSigner) Sign(ctx context.Context, payload io.Reader) (oci.Signa return ociSig, pk, nil } -func (ps *payloadSigner) signPayload(ctx context.Context, payloadBytes []byte) (sig []byte, pk crypto.PublicKey, err error) { - sOpts := []signature.SignOption{signatureoptions.WithContext(ctx)} - sOpts = append(sOpts, ps.payloadSignerOpts...) - sig, err = ps.payloadSigner.SignMessage(bytes.NewReader(payloadBytes), sOpts...) - if err != nil { - return nil, nil, err - } - +func (ps *payloadSigner) publicKey(ctx context.Context) (pk crypto.PublicKey, err error) { pkOpts := []signature.PublicKeyOption{signatureoptions.WithContext(ctx)} pkOpts = append(pkOpts, ps.publicKeyProviderOpts...) pk, err = ps.payloadSigner.PublicKey(pkOpts...) if err != nil { - return nil, nil, err + return nil, err + } + return pk, nil +} + +func (ps *payloadSigner) signPayload(ctx context.Context, payloadBytes []byte) (sig []byte, err error) { + sOpts := []signature.SignOption{signatureoptions.WithContext(ctx)} + sOpts = append(sOpts, ps.payloadSignerOpts...) + sig, err = ps.payloadSigner.SignMessage(bytes.NewReader(payloadBytes), sOpts...) + if err != nil { + return nil, err } - return sig, pk, nil + return sig, nil } func newSigner(s signature.Signer,