1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-05 23:46:56 +00:00
kyverno/pkg/notaryv2/notaryv2.go
Jim Bugwadia 29997fe446
Notary v2 (#6011)
* fix make debug-deploy

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* improve log messages

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* initial update

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* initial update

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* update registry credentials handling order

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* comment out ACR helper - breaks anonymous image pull

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* merge main and refactor verifiers

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix opt init

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* remove local address

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* update to NotaryV2 RC

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix fmt

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* update deps

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* format imports

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* remove env and no-op statement

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix merge issues

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix linter issue

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* remove unused field

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* make fmt

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* renable ACR credential helper

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* Update .vscode/launch.json

Signed-off-by: shuting <shutting06@gmail.com>

---------

Signed-off-by: Jim Bugwadia <jim@nirmata.com>
Signed-off-by: shuting <shutting06@gmail.com>
Co-authored-by: shuting <shuting@nirmata.com>
Co-authored-by: shuting <shutting06@gmail.com>
2023-02-20 16:26:10 +00:00

132 lines
3.5 KiB
Go

package notaryv2
import (
"bytes"
"context"
"github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/images"
"github.com/kyverno/kyverno/pkg/logging"
_ "github.com/notaryproject/notation-core-go/signature/cose"
_ "github.com/notaryproject/notation-core-go/signature/jws"
"github.com/notaryproject/notation-go"
"github.com/notaryproject/notation-go/verifier"
"github.com/notaryproject/notation-go/verifier/trustpolicy"
"github.com/pkg/errors"
"github.com/sigstore/sigstore/pkg/cryptoutils"
"go.uber.org/multierr"
)
func NewVerifier() images.ImageVerifier {
return &notaryV2Verifier{
log: logging.WithName("NotaryV2"),
}
}
type notaryV2Verifier struct {
log logr.Logger
}
func (v *notaryV2Verifier) VerifySignature(ctx context.Context, opts images.Options) (*images.Response, error) {
v.log.V(2).Info("verifying image", "reference", opts.ImageRef)
certsPEM := combineCerts(opts)
certs, err := cryptoutils.LoadCertificatesFromPEM(bytes.NewReader([]byte(certsPEM)))
if err != nil {
return nil, errors.Wrapf(err, "failed to parse certificates")
}
trustStore := NewTrustStore("kyverno", certs)
policyDoc := v.buildPolicy()
notationVerifier, err := verifier.New(policyDoc, trustStore, nil)
if err != nil {
return nil, errors.Wrapf(err, "failed to created verifier")
}
repo, parsedRef, err := parseReference(ctx, opts.ImageRef, opts.RegistryClient)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse image reference: %s", opts.ImageRef)
}
digest, err := parsedRef.Digest()
if err != nil {
return nil, errors.Wrapf(err, "failed to fetch digest")
}
ref := parsedRef.String()
remoteVerifyOptions := notation.RemoteVerifyOptions{
ArtifactReference: ref,
MaxSignatureAttempts: 10,
}
targetDesc, outcomes, err := notation.Verify(context.TODO(), notationVerifier, repo, remoteVerifyOptions)
if err != nil {
return nil, errors.Wrapf(err, "failed to verify %s", ref)
}
if err := v.verifyOutcomes(outcomes); err != nil {
return nil, err
}
if targetDesc.Digest != digest {
return nil, errors.Errorf("digest mismatch")
}
v.log.V(2).Info("verified image", "type", targetDesc.MediaType, "digest", targetDesc.Digest, "size", targetDesc.Size)
resp := &images.Response{
Digest: targetDesc.Digest.String(),
Statements: nil,
}
return resp, nil
}
func combineCerts(opts images.Options) string {
certs := opts.Cert
if opts.CertChain != "" {
if certs != "" {
certs = certs + "\n"
}
certs = certs + opts.CertChain
}
return certs
}
func (v *notaryV2Verifier) buildPolicy() *trustpolicy.Document {
return &trustpolicy.Document{
Version: "1.0",
TrustPolicies: []trustpolicy.TrustPolicy{
{
Name: "kyverno",
RegistryScopes: []string{"*"},
SignatureVerification: trustpolicy.SignatureVerification{VerificationLevel: trustpolicy.LevelStrict.Name},
TrustStores: []string{"ca:kyverno"},
TrustedIdentities: []string{"*"},
},
},
}
}
func (v *notaryV2Verifier) verifyOutcomes(outcomes []*notation.VerificationOutcome) error {
var errs []error
for _, outcome := range outcomes {
if outcome.Error != nil {
errs = append(errs, outcome.Error)
continue
}
content := outcome.EnvelopeContent.Payload.Content
contentType := outcome.EnvelopeContent.Payload.ContentType
v.log.Info("content", "type", contentType, "data", content)
}
return multierr.Combine(errs...)
}
func (v *notaryV2Verifier) FetchAttestations(ctx context.Context, opts images.Options) (*images.Response, error) {
return nil, errors.Errorf("not implemented")
}