| 47 | var ErrUnsupportedVerificationMaterial = errors.New("unsupported verification material") |
| 48 | |
| 49 | func VerifyBundle(ctx context.Context, bundleBytes []byte, tr *TrustedRoot) error { |
| 50 | if bundleBytes == nil { |
| 51 | return ErrMissingVerificationMaterial |
| 52 | } |
| 53 | |
| 54 | bundle := new(protobundle.Bundle) |
| 55 | // unmarshal and validate |
| 56 | if err := protojson.Unmarshal(bundleBytes, bundle); err != nil { |
| 57 | return fmt.Errorf("%w: %w", err, ErrInvalidBundle) |
| 58 | } |
| 59 | |
| 60 | // fix for old attestations |
| 61 | attestation.FixSignatureInBundle(bundle) |
| 62 | |
| 63 | sb := &sigstorebundle.Bundle{Bundle: bundle} |
| 64 | vc, err := sb.VerificationContent() |
| 65 | if err != nil { |
| 66 | if !errors.Is(err, sigstorebundle.ErrMissingVerificationMaterial) { |
| 67 | return fmt.Errorf("could not get verification material: %w", err) |
| 68 | } |
| 69 | } |
| 70 | |
| 71 | // Signature verification is MANDATORY |
| 72 | switch { |
| 73 | case vc != nil && vc.Certificate() != nil: |
| 74 | if err := verifyCertSignature(ctx, bundle, vc.Certificate(), tr); err != nil { |
| 75 | return err |
| 76 | } |
| 77 | case bundle.GetVerificationMaterial().GetPublicKey() != nil: |
| 78 | // Public-key bundles are not supported at this time |
| 79 | return fmt.Errorf("%w: public key verification material", ErrUnsupportedVerificationMaterial) |
| 80 | default: |
| 81 | // No certificate and no public key: nothing to verify the signature against. |
| 82 | return ErrMissingVerificationMaterial |
| 83 | } |
| 84 | |
| 85 | // The signature has been verified against a trusted certificate. The timestamp |
| 86 | // (if present) only validates the signing window; it can never be the sole |
| 87 | // verification material. |
| 88 | if err := VerifyTimestamps(sb, tr); err != nil && !errors.Is(err, ErrMissingVerificationMaterial) { |
| 89 | return fmt.Errorf("could not verify timestamps: %w", err) |
| 90 | } |
| 91 | |
| 92 | return nil |
| 93 | } |
| 94 | |
| 95 | // verifyCertSignature validates the signing certificate against the trusted root |
| 96 | // chain and verifies the DSSE envelope signature with the certificate's key. |