Add basic cosign verification tests
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
This commit is contained in:
parent
7c72acc5b0
commit
44b8288d83
|
@ -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
2
go.mod
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue