From 3f16ef0ba8aa52554f997c70c41b4da9c8fb5135 Mon Sep 17 00:00:00 2001 From: Ilya Dmitrichenko Date: Wed, 27 Sep 2023 14:52:35 +0100 Subject: [PATCH] Avoid parsing URL in verification logic Signed-off-by: Ilya Dmitrichenko --- .../controller/ocirepository_controller.go | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/internal/controller/ocirepository_controller.go b/internal/controller/ocirepository_controller.go index b8c066e8b..d32ca42c7 100644 --- a/internal/controller/ocirepository_controller.go +++ b/internal/controller/ocirepository_controller.go @@ -430,7 +430,7 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch conditions.GetObservedGeneration(obj, sourcev1.SourceVerifiedCondition) != obj.Generation || conditions.IsFalse(obj, sourcev1.SourceVerifiedCondition) { - err := r.verifySignature(ctx, obj, ref.String(), opts...) + err := r.verifySignature(ctx, obj, ref, opts...) if err != nil { provider := obj.Spec.Verify.Provider if obj.Spec.Verify.SecretRef == nil { @@ -611,7 +611,7 @@ func (r *OCIRepositoryReconciler) digestFromRevision(revision string) string { // verifySignature verifies the authenticity of the given image reference URL. // First, it tries to use a key if a Secret with a valid public key is provided. // If not, it falls back to a keyless approach for verification. -func (r *OCIRepositoryReconciler) verifySignature(ctx context.Context, obj *ociv1.OCIRepository, url string, opt ...remote.Option) error { +func (r *OCIRepositoryReconciler) verifySignature(ctx context.Context, obj *ociv1.OCIRepository, ref name.Reference, opt ...remote.Option) error { ctxTimeout, cancel := context.WithTimeout(ctx, obj.Spec.Timeout.Duration) defer cancel() @@ -622,15 +622,6 @@ func (r *OCIRepositoryReconciler) verifySignature(ctx context.Context, obj *ociv soci.WithRemoteOptions(opt...), } - var nameOpts []name.Option - if obj.Spec.Insecure { - nameOpts = append(nameOpts, name.Insecure) - } - ref, err := name.ParseReference(url, nameOpts...) - if err != nil { - return err - } - // get the public keys from the given secret if secretRef := obj.Spec.Verify.SecretRef; secretRef != nil { certSecretName := types.NamespacedName{ @@ -665,7 +656,7 @@ func (r *OCIRepositoryReconciler) verifySignature(ctx context.Context, obj *ociv } if !signatureVerified { - return fmt.Errorf("no matching signatures were found for '%s'", url) + return fmt.Errorf("no matching signatures were found for '%s'", ref) } return nil @@ -687,20 +678,25 @@ func (r *OCIRepositoryReconciler) verifySignature(ctx context.Context, obj *ociv return nil } - return fmt.Errorf("no matching signatures were found for '%s'", url) + return fmt.Errorf("no matching signatures were found for '%s'", ref) } return nil } // parseRepository validates and extracts the repository URL. -func (r *OCIRepositoryReconciler) parseRepository(url string) (name.Repository, error) { - if !strings.HasPrefix(url, ociv1.OCIRepositoryPrefix) { +func (r *OCIRepositoryReconciler) parseRepository(obj *ociv1.OCIRepository) (name.Repository, error) { + if !strings.HasPrefix(obj.Spec.URL, ociv1.OCIRepositoryPrefix) { return name.Repository{}, fmt.Errorf("URL must be in format 'oci:////'") } - url = strings.TrimPrefix(url, ociv1.OCIRepositoryPrefix) - repo, err := name.NewRepository(url) + url := strings.TrimPrefix(obj.Spec.URL, ociv1.OCIRepositoryPrefix) + + options := []name.Option{} + if obj.Spec.Insecure { + options = append(options, name.Insecure) + } + repo, err := name.NewRepository(url, options...) if err != nil { return name.Repository{}, err } @@ -715,7 +711,7 @@ func (r *OCIRepositoryReconciler) parseRepository(url string) (name.Repository, // getArtifactRef determines which tag or revision should be used and returns the OCI artifact FQN. func (r *OCIRepositoryReconciler) getArtifactRef(obj *ociv1.OCIRepository, options []remote.Option) (name.Reference, error) { - repo, err := r.parseRepository(obj.Spec.URL) + repo, err := r.parseRepository(obj) if err != nil { return nil, invalidOCIURLError{err} }