Skip to content

Commit

Permalink
Verify sigs and attestations in parallel (#3066)
Browse files Browse the repository at this point in the history
* Verify sigs and attestations in parallel

This should significantly speed up verification time for images that have a lot of signature or attestations.

Signed-off-by: Priya Wadhwa <priya@chainguard.dev>

* Fix race condition with bundleVerified bool

Signed-off-by: Priya Wadhwa <priya@chainguard.dev>

---------

Signed-off-by: Priya Wadhwa <priya@chainguard.dev>
  • Loading branch information
priyawadhwa committed Jun 20, 2023
1 parent b0072d5 commit 9da30ea
Showing 1 changed file with 68 additions and 30 deletions.
98 changes: 68 additions & 30 deletions pkg/cosign/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"os"
"regexp"
"strings"
"sync"
"time"

"github.com/pkg/errors"
Expand Down Expand Up @@ -597,24 +598,42 @@ func verifySignatures(ctx context.Context, sigs oci.Signatures, h v1.Hash, co *C
}
}

validationErrs := []string{}
validationErrs := make([]string, len(sl))
signatures := make([]oci.Signature, len(sl))
bundlesVerified := make([]bool, len(sl))

for _, sig := range sl {
sig, err := static.Copy(sig)
if err != nil {
validationErrs = append(validationErrs, err.Error())
continue
}
verified, err := VerifyImageSignature(ctx, sig, h, co)
bundleVerified = bundleVerified || verified
if err != nil {
validationErrs = append(validationErrs, err.Error())
continue
var wg sync.WaitGroup

for i, sig := range sl {
wg.Add(1)
go func(sig oci.Signature, index int) {
defer wg.Done()
sig, err := static.Copy(sig)
if err != nil {
validationErrs[index] = err.Error()
return
}
verified, err := VerifyImageSignature(ctx, sig, h, co)
bundlesVerified[index] = verified
if err != nil {
validationErrs[index] = err.Error()
return
}
signatures[index] = sig
}(sig, i)
}
wg.Wait()

for _, s := range signatures {
if s != nil {
checkedSignatures = append(checkedSignatures, s)
}
}

// Phew, we made it.
checkedSignatures = append(checkedSignatures, sig)
for _, verified := range bundlesVerified {
bundleVerified = bundleVerified || verified
}

if len(checkedSignatures) == 0 {
// TODO: ErrNoMatchingSignatures.Unwrap should return []error,
// or we should replace "...%s" strings.Join with "...%w", errors.Join.
Expand Down Expand Up @@ -934,25 +953,44 @@ func verifyImageAttestations(ctx context.Context, atts oci.Signatures, h v1.Hash
return nil, false, err
}

validationErrs := []string{}
for _, att := range sl {
att, err := static.Copy(att)
if err != nil {
validationErrs = append(validationErrs, err.Error())
continue
}
if err := func(att oci.Signature) error {
verified, err := verifyInternal(ctx, att, h, verifyOCIAttestation, co)
bundleVerified = bundleVerified || verified
return err
}(att); err != nil {
validationErrs = append(validationErrs, err.Error())
continue
validationErrs := make([]string, len(sl))
attestations := make([]oci.Signature, len(sl))
bundlesVerified := make([]bool, len(sl))

var wg sync.WaitGroup

for i, att := range sl {
wg.Add(1)
go func(att oci.Signature, index int) {
defer wg.Done()
att, err := static.Copy(att)
if err != nil {
validationErrs[index] = err.Error()
return
}
if err := func(att oci.Signature) error {
verified, err := verifyInternal(ctx, att, h, verifyOCIAttestation, co)
bundlesVerified[index] = verified
return err
}(att); err != nil {
validationErrs[index] = err.Error()
return
}
attestations[index] = att
}(att, i)
}
wg.Wait()

for _, a := range attestations {
if a != nil {
checkedAttestations = append(checkedAttestations, a)
}
}

// Phew, we made it.
checkedAttestations = append(checkedAttestations, att)
for _, verified := range bundlesVerified {
bundleVerified = bundleVerified || verified
}

if len(checkedAttestations) == 0 {
return nil, false, &ErrNoMatchingAttestations{
fmt.Errorf("no matching attestations: %s", strings.Join(validationErrs, "\n ")),
Expand Down

0 comments on commit 9da30ea

Please sign in to comment.