Add basic cosign verification tests

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
This commit is contained in:
Stefan Prodan 2022-09-13 18:10:56 +03:00
parent 7c72acc5b0
commit 44b8288d83
No known key found for this signature in database
GPG Key ID: 3299AEB0E4085BAF
2 changed files with 46 additions and 46 deletions

View File

@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package controllers package controllers
import ( import (
@ -24,9 +25,6 @@ import (
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt" "fmt"
coptions "github.com/sigstore/cosign/cmd/cosign/cli/options"
"github.com/sigstore/cosign/cmd/cosign/cli/sign"
"github.com/sigstore/cosign/pkg/cosign"
"math/big" "math/big"
"net" "net"
"net/http" "net/http"
@ -55,6 +53,9 @@ import (
gcrv1 "github.com/google/go-containerregistry/pkg/v1" gcrv1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/mutate" "github.com/google/go-containerregistry/pkg/v1/mutate"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
coptions "github.com/sigstore/cosign/cmd/cosign/cli/options"
"github.com/sigstore/cosign/cmd/cosign/cli/sign"
"github.com/sigstore/cosign/pkg/cosign"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -1231,7 +1232,7 @@ func TestOCIRepository_verifyOCISourceSignature(t *testing.T) {
url string url string
reference *sourcev1.OCIRepositoryRef reference *sourcev1.OCIRepositoryRef
shouldSign bool shouldSign bool
wantErr bool wantErrMsg string
}{ }{
{ {
name: "signed image should pass verification", name: "signed image should pass verification",
@ -1246,6 +1247,7 @@ func TestOCIRepository_verifyOCISourceSignature(t *testing.T) {
Tag: "6.1.5", Tag: "6.1.5",
}, },
shouldSign: false, shouldSign: false,
wantErrMsg: "no matching signatures were found",
}, },
} }
@ -1256,6 +1258,29 @@ func TestOCIRepository_verifyOCISourceSignature(t *testing.T) {
Storage: testStorage, Storage: testStorage,
} }
pf := func(b bool) ([]byte, error) {
return []byte("cosign-password"), nil
}
keys, err := cosign.GenerateKeyPair(pf)
g.Expect(err).ToNot(HaveOccurred())
err = os.WriteFile(path.Join(tmpDir, "cosign.key"), keys.PrivateBytes, 0600)
g.Expect(err).ToNot(HaveOccurred())
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "cosign-key",
},
Data: map[string][]byte{
"cosign.pub": keys.PublicBytes,
}}
err = r.Create(ctx, secret)
if err != nil {
g.Expect(err).NotTo(HaveOccurred())
}
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
obj := &sourcev1.OCIRepository{ obj := &sourcev1.OCIRepository{
@ -1273,33 +1298,6 @@ func TestOCIRepository_verifyOCISourceSignature(t *testing.T) {
}, },
} }
pf := func(b bool) ([]byte, error) {
return []byte("foo"), nil
}
keys, err := cosign.GenerateKeyPair(pf)
if err != nil {
g.Expect(err).ToNot(HaveOccurred())
}
err = os.WriteFile("cosign.key", keys.PrivateBytes, 0600)
if err != nil {
g.Expect(err).ToNot(HaveOccurred())
}
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "cosign-key",
},
Data: map[string][]byte{
"cosign.pub": keys.PublicBytes,
}}
err = r.Create(ctx, secret)
if err != nil {
g.Expect(err).NotTo(HaveOccurred())
}
keychain, err := r.keychain(ctx, obj) keychain, err := r.keychain(ctx, obj)
if err != nil { if err != nil {
g.Expect(err).ToNot(HaveOccurred()) g.Expect(err).ToNot(HaveOccurred())
@ -1307,35 +1305,37 @@ func TestOCIRepository_verifyOCISourceSignature(t *testing.T) {
options := r.craneOptions(ctx, obj.Spec.Insecure) options := r.craneOptions(ctx, obj.Spec.Insecure)
options = append(options, crane.WithAuthFromKeychain(keychain)) options = append(options, crane.WithAuthFromKeychain(keychain))
url, err := r.getArtifactURL(obj, options) artifactURL, err := r.getArtifactURL(obj, options)
if err != nil { if err != nil {
g.Expect(err).ToNot(HaveOccurred()) g.Expect(err).ToNot(HaveOccurred())
} }
if tt.shouldSign { if tt.shouldSign {
ko := coptions.KeyOpts{ ko := coptions.KeyOpts{
KeyRef: "cosign.key", KeyRef: path.Join(tmpDir, "cosign.key"),
PassFunc: pf, PassFunc: pf,
} }
t.Logf("url: %s", url) ro := &coptions.RootOptions{
Timeout: timeout,
ro := &coptions.RootOptions{}
err = sign.SignCmd(ro, ko, coptions.RegistryOptions{Keychain: keychain}, nil, []string{url}, "", "", false, "", "", "", false, false, "", false)
if err != nil {
g.Expect(err).ToNot(HaveOccurred())
} }
err = sign.SignCmd(ro, ko, coptions.RegistryOptions{Keychain: keychain},
nil, []string{artifactURL}, "",
"", true, "",
"", "", false,
false, "", false)
g.Expect(err).ToNot(HaveOccurred())
} }
err = r.verifyOCISourceSignature(ctx, obj, url, keychain) err = r.verifyOCISourceSignature(ctx, obj, artifactURL, keychain)
if tt.wantErr { if tt.wantErrMsg != "" {
g.Expect(err).To(HaveOccurred()) g.Expect(err).ToNot(BeNil())
return g.Expect(err.Error()).To(ContainSubstring(tt.wantErrMsg))
} else {
g.Expect(err).ToNot(HaveOccurred())
} }
}) })
} }
} }
func TestOCIRepository_stalled(t *testing.T) { func TestOCIRepository_stalled(t *testing.T) {

2
go.mod
View File

@ -60,6 +60,7 @@ require (
github.com/prometheus/client_golang v1.13.0 github.com/prometheus/client_golang v1.13.0
github.com/sigstore/cosign v1.11.1 github.com/sigstore/cosign v1.11.1
github.com/sigstore/sigstore v1.4.0 github.com/sigstore/sigstore v1.4.0
github.com/sirupsen/logrus v1.9.0
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503 golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503
golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c
@ -292,7 +293,6 @@ require (
github.com/shopspring/decimal v1.2.0 // indirect github.com/shopspring/decimal v1.2.0 // indirect
github.com/sigstore/fulcio v0.5.3 // indirect github.com/sigstore/fulcio v0.5.3 // indirect
github.com/sigstore/rekor v0.11.0 // indirect github.com/sigstore/rekor v0.11.0 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
github.com/soheilhy/cmux v0.1.5 // indirect github.com/soheilhy/cmux v0.1.5 // indirect
github.com/spf13/afero v1.8.2 // indirect github.com/spf13/afero v1.8.2 // indirect