fix: npm publish verification (#705)

- adding support for IEEE P1363 formatted signatures
- fix the npm publish attestation bug. The verification always return
success, because it was not using PAE signature

---------

Signed-off-by: laurentsimon <laurentsimon@google.com>
Signed-off-by: laurentsimon <64505099+laurentsimon@users.noreply.github.com>
Co-authored-by: Ian Lewis <ianlewis@google.com>
Co-authored-by: Trishank Karthik Kuppusamy <trishank.kuppusamy@datadoghq.com>
This commit is contained in:
laurentsimon
2023-10-02 10:12:51 -07:00
committed by GitHub
parent 54010d9735
commit f6ae402f45
28 changed files with 1091 additions and 51 deletions

View File

@@ -1495,3 +1495,306 @@ func Test_runVerifyGHAContainerBased(t *testing.T) {
})
}
}
func Test_runVerifyNpmPackage(t *testing.T) {
// We cannot use t.Setenv due to parallelized tests.
os.Setenv("SLSA_VERIFIER_EXPERIMENTAL", "1")
t.Parallel()
tests := []struct {
name string
artifact string
builderID *string
source string
pkgVersion *string
pkgName *string
err error
}{
// npm CLI with tag.
{
name: "valid npm CLI builder",
artifact: "supreme-googles-cli-v02-tag.tgz",
source: "github.com/trishankatdatadog/supreme-goggles",
pkgVersion: PointerTo("1.0.5"),
pkgName: PointerTo("@trishankatdatadog/supreme-goggles"),
builderID: PointerTo("https://github.com/actions/runner/github-hosted"),
},
{
name: "valid npm CLI builder short runner name",
artifact: "supreme-googles-cli-v02-tag.tgz",
source: "github.com/trishankatdatadog/supreme-goggles",
pkgVersion: PointerTo("1.0.5"),
pkgName: PointerTo("@trishankatdatadog/supreme-goggles"),
builderID: PointerTo("https://github.com/actions/runner"),
},
{
name: "valid npm CLI builder no builder",
artifact: "supreme-googles-cli-v02-tag.tgz",
source: "github.com/trishankatdatadog/supreme-goggles",
pkgVersion: PointerTo("1.0.5"),
pkgName: PointerTo("@trishankatdatadog/supreme-goggles"),
err: serrors.ErrorInvalidBuilderID,
},
{
name: "valid npm CLI builder mismatch builder",
artifact: "supreme-googles-cli-v02-tag.tgz",
source: "github.com/trishankatdatadog/supreme-goggles",
pkgVersion: PointerTo("1.0.5"),
pkgName: PointerTo("@trishankatdatadog/supreme-goggles"),
builderID: PointerTo("https://github.com/actions/runner2"),
err: serrors.ErrorNotSupported,
},
{
name: "valid npm CLI builder no package name",
artifact: "supreme-googles-cli-v02-tag.tgz",
source: "github.com/trishankatdatadog/supreme-goggles",
pkgVersion: PointerTo("1.0.5"),
builderID: PointerTo("https://github.com/actions/runner/github-hosted"),
},
{
name: "valid npm CLI builder no package version",
artifact: "supreme-googles-cli-v02-tag.tgz",
source: "github.com/trishankatdatadog/supreme-goggles",
pkgName: PointerTo("@trishankatdatadog/supreme-goggles"),
builderID: PointerTo("https://github.com/actions/runner/github-hosted"),
},
{
name: "valid npm CLI builder mismatch source",
artifact: "supreme-googles-cli-v02-tag.tgz",
source: "github.com/trishankatdatadog/supreme-goggleS",
pkgVersion: PointerTo("1.0.5"),
pkgName: PointerTo("@trishankatdatadog/supreme-goggles"),
builderID: PointerTo("https://github.com/actions/runner/github-hosted"),
err: serrors.ErrorMismatchSource,
},
{
name: "valid npm CLI builder mismatch package version",
artifact: "supreme-googles-cli-v02-tag.tgz",
source: "github.com/trishankatdatadog/supreme-goggles",
pkgVersion: PointerTo("1.0.4"),
builderID: PointerTo("https://github.com/actions/runner/github-hosted"),
err: serrors.ErrorMismatchPackageVersion,
},
{
name: "valid npm CLI builder mismatch package name",
artifact: "supreme-googles-cli-v02-tag.tgz",
source: "github.com/trishankatdatadog/supreme-goggles",
pkgName: PointerTo("@trishankatdatadog/supreme-goggleS"),
builderID: PointerTo("https://github.com/actions/runner/github-hosted"),
err: serrors.ErrorMismatchPackageName,
},
{
name: "invalid signature provenance npm CLI",
artifact: "supreme-googles-cli-v02-tag-invalidsigprov.tgz",
source: "github.com/trishankatdatadog/supreme-goggles",
pkgName: PointerTo("@trishankatdatadog/supreme-goggles"),
builderID: PointerTo("https://github.com/actions/runner/github-hosted"),
err: serrors.ErrorInvalidSignature,
},
{
name: "invalid signature provenance npm CLI",
artifact: "supreme-googles-cli-v02-tag-invalidsigpub.tgz",
source: "github.com/trishankatdatadog/supreme-goggles",
pkgName: PointerTo("@trishankatdatadog/supreme-goggles"),
builderID: PointerTo("https://github.com/actions/runner/github-hosted"),
err: serrors.ErrorInvalidSignature,
},
// npm CLI with main branch.
{
name: "valid npm CLI builder",
artifact: "provenance-npm-test-cli-v02-prega.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgVersion: PointerTo("1.0.3"),
pkgName: PointerTo("@laurentsimon/provenance-npm-test"),
builderID: PointerTo("https://github.com/actions/runner/github-hosted"),
},
{
name: "valid npm CLI builder short runner name",
artifact: "provenance-npm-test-cli-v02-prega.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgVersion: PointerTo("1.0.3"),
pkgName: PointerTo("@laurentsimon/provenance-npm-test"),
builderID: PointerTo("https://github.com/actions/runner"),
},
{
name: "valid npm CLI builder no builder",
artifact: "provenance-npm-test-cli-v02-prega.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgVersion: PointerTo("1.0.3"),
pkgName: PointerTo("@laurentsimon/provenance-npm-test"),
err: serrors.ErrorInvalidBuilderID,
},
{
name: "valid npm CLI builder mismatch builder",
artifact: "provenance-npm-test-cli-v02-prega.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgVersion: PointerTo("1.0.3"),
pkgName: PointerTo("@laurentsimon/provenance-npm-test"),
builderID: PointerTo("https://github.com/actions/runner2"),
err: serrors.ErrorNotSupported,
},
{
name: "valid npm CLI builder no package name",
artifact: "provenance-npm-test-cli-v02-prega.tgz",
pkgVersion: PointerTo("1.0.3"),
source: "github.com/laurentsimon/provenance-npm-test",
builderID: PointerTo("https://github.com/actions/runner/github-hosted"),
},
{
name: "valid npm CLI builder no package version",
artifact: "provenance-npm-test-cli-v02-prega.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgName: PointerTo("@laurentsimon/provenance-npm-test"),
builderID: PointerTo("https://github.com/actions/runner/github-hosted"),
},
{
name: "valid npm CLI builder mismatch source",
artifact: "provenance-npm-test-cli-v02-prega.tgz",
source: "github.com/laurentsimon/provenance-npm-test2",
builderID: PointerTo("https://github.com/actions/runner/github-hosted"),
err: serrors.ErrorMismatchSource,
},
{
name: "valid npm CLI builder mismatch package version",
artifact: "provenance-npm-test-cli-v02-prega.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgVersion: PointerTo("1.0.4"),
builderID: PointerTo("https://github.com/actions/runner/github-hosted"),
err: serrors.ErrorMismatchPackageVersion,
},
{
name: "valid npm CLI builder mismatch package name",
artifact: "provenance-npm-test-cli-v02-prega.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgName: PointerTo("@laurentsimon/provenance-npm-test2"),
builderID: PointerTo("https://github.com/actions/runner/github-hosted"),
err: serrors.ErrorMismatchPackageName,
},
{
name: "invalid signature provenance npm CLI",
artifact: "provenance-npm-test-cli-v02-prega-invalidsigprov.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgName: PointerTo("@laurentsimon/provenance-npm-test2"),
builderID: PointerTo("https://github.com/actions/runner/github-hosted"),
err: serrors.ErrorInvalidSignature,
},
{
name: "invalid signature publish npm CLI",
artifact: "provenance-npm-test-cli-v02-prega-invalidsigpub.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgName: PointerTo("@laurentsimon/provenance-npm-test2"),
builderID: PointerTo("https://github.com/actions/runner/github-hosted"),
err: serrors.ErrorInvalidSignature,
},
// OSSF builder.
{
name: "valid npm OSSF builder",
artifact: "provenance-npm-test-ossf.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgVersion: PointerTo("1.0.5"),
pkgName: PointerTo("@laurentsimon/provenance-npm-test"),
builderID: PointerTo("https://github.com/slsa-framework/slsa-github-generator/.github/workflows/builder_nodejs_slsa3.yml"),
},
{
name: "valid npm OSSF builder no builder",
artifact: "provenance-npm-test-ossf.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgVersion: PointerTo("1.0.5"),
pkgName: PointerTo("@laurentsimon/provenance-npm-test"),
err: serrors.ErrorInvalidBuilderID,
},
{
name: "valid npm OSSF builder mismatch builder",
artifact: "provenance-npm-test-ossf.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgVersion: PointerTo("1.0.5"),
pkgName: PointerTo("@laurentsimon/provenance-npm-test"),
builderID: PointerTo("https://github.com/slsa-framework/slsa-github-generator/.github/workflows/builder_nodejs_slsa.yml"),
err: serrors.ErrorMismatchBuilderID,
},
{
name: "valid npm OSSF builder no package name",
artifact: "provenance-npm-test-ossf.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgVersion: PointerTo("1.0.5"),
builderID: PointerTo("https://github.com/slsa-framework/slsa-github-generator/.github/workflows/builder_nodejs_slsa3.yml"),
},
{
name: "valid npm OSSF builder no package version",
artifact: "provenance-npm-test-ossf.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgName: PointerTo("@laurentsimon/provenance-npm-test"),
builderID: PointerTo("https://github.com/slsa-framework/slsa-github-generator/.github/workflows/builder_nodejs_slsa3.yml"),
},
{
name: "valid npm OSSF builder mismatch package name",
artifact: "provenance-npm-test-ossf.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgVersion: PointerTo("1.0.5"),
pkgName: PointerTo("@laurentsimon/provenance-npm-test2"),
builderID: PointerTo("https://github.com/slsa-framework/slsa-github-generator/.github/workflows/builder_nodejs_slsa3.yml"),
err: serrors.ErrorMismatchPackageName,
},
{
name: "valid npm OSSF builder mismatch package version",
artifact: "provenance-npm-test-ossf.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgVersion: PointerTo("1.0.6"),
pkgName: PointerTo("@laurentsimon/provenance-npm-test"),
builderID: PointerTo("https://github.com/slsa-framework/slsa-github-generator/.github/workflows/builder_nodejs_slsa3.yml"),
err: serrors.ErrorMismatchPackageVersion,
},
{
name: "valid npm OSSF builder mismatch mismatch source",
artifact: "provenance-npm-test-ossf.tgz",
source: "github.com/laurentsimon/provenance-npm-test2",
pkgVersion: PointerTo("1.0.5"),
pkgName: PointerTo("@laurentsimon/provenance-npm-test"),
builderID: PointerTo("https://github.com/slsa-framework/slsa-github-generator/.github/workflows/builder_nodejs_slsa3.yml"),
err: serrors.ErrorMismatchSource,
},
{
name: "invalid signature provenance npm OSSF builder",
artifact: "provenance-npm-test-ossf-invalidsigprov.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgVersion: PointerTo("1.0.5"),
pkgName: PointerTo("@laurentsimon/provenance-npm-test"),
builderID: PointerTo("https://github.com/slsa-framework/slsa-github-generator/.github/workflows/builder_nodejs_slsa3.yml"),
err: serrors.ErrorInvalidSignature,
},
{
name: "invalid signature publish npm OSSF builder",
artifact: "provenance-npm-test-ossf-invalidsigpub.tgz",
source: "github.com/laurentsimon/provenance-npm-test",
pkgVersion: PointerTo("1.0.5"),
pkgName: PointerTo("@laurentsimon/provenance-npm-test"),
builderID: PointerTo("https://github.com/slsa-framework/slsa-github-generator/.github/workflows/builder_nodejs_slsa3.yml"),
err: serrors.ErrorInvalidSignature,
},
}
for _, tt := range tests {
tt := tt // Re-initializing variable so it is not changed while executing the closure below
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
artifactPath := filepath.Clean(filepath.Join(TEST_DIR, "npm", "gha", tt.artifact))
attestationsPath := fmt.Sprintf("%s.json", artifactPath)
cmd := verify.VerifyNpmPackageCommand{
AttestationsPath: attestationsPath,
BuilderID: tt.builderID,
SourceURI: tt.source,
PackageName: tt.pkgName,
PackageVersion: tt.pkgVersion,
}
_, err := cmd.Exec(context.Background(), []string{artifactPath})
if diff := cmp.Diff(tt.err, err, cmpopts.EquateErrors()); diff != "" {
t.Fatalf("unexpected error (-want +got): \n%s", diff)
}
})
}
}
func PointerTo[K any](object K) *K {
return &object
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -43,4 +43,5 @@ var (
ErrorInvalidSubject = errors.New("invalid subject")
ErrorInvalidHash = errors.New("invalid hash")
ErrorNotPresent = errors.New("not present")
ErrorInvalidPublicKey = errors.New("invalid public key")
)

View File

@@ -2,8 +2,6 @@ package gha
import (
"context"
"crypto/ecdsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/json"
@@ -33,7 +31,7 @@ const (
var errrorInvalidAttestations = errors.New("invalid npm attestations")
/*
NOTE: key available at https://registry.npmjs.org/-/npm/v1/keys
NOTE: key available at https://registry.npmjs.org/-/npm/v1/keys and https://github.com/sigstore/root-signing/blob/main/repository/repository/targets/registry.npmjs.org/7a8ec9678ad824cdccaa7a6dc0961caf8f8df61bc7274189122c123446248426.keys.json
https://docs.npmjs.com/about-registry-signatures
{
@@ -48,7 +46,8 @@ NOTE: key available at https://registry.npmjs.org/-/npm/v1/keys
]
}
*/
var npmRegistryPublicKey = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1Olb3zMAFFxXKHiIkQO5cJ3Yhl5i6UPp+IhuteBJbuHcA5UogKo0EWtlWwW6KSaKoTNEYL7JlCQiVnkhBktUgg=="
const npmRegistryPublicKey = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1Olb3zMAFFxXKHiIkQO5cJ3Yhl5i6UPp+IhuteBJbuHcA5UogKo0EWtlWwW6KSaKoTNEYL7JlCQiVnkhBktUgg=="
const npmRegistryPublicKeyID = "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"
type attestationSet struct {
Attestations []attestation `json:"attestations"`
@@ -138,54 +137,27 @@ func (n *Npm) verifyProvenanceAttestationSignature() error {
return nil
}
func (n *Npm) verifyPublishAttesttationSignature() error {
func (n *Npm) verifyPublishAttestationSignature() error {
// First verify the bundle and its rekor entry.
signedPublish, err := verifyBundleAndEntryFromBytes(n.ctx, n.publishAttestation.BundleBytes, n.root, false)
if err != nil {
return err
}
// Second, we verify the signature, which uses a static key.
// Extract payload.
env := signedPublish.Envelope
payload, err := utils.PayloadFromEnvelope(env)
if err != nil {
return err
}
// Extract the signature.
if len(env.Signatures) == 0 {
return fmt.Errorf("%w: no signatures found in envelope", serrors.ErrorNoValidSignature)
}
// The registry signs with a single, static, non-rotated key.
sig := env.Signatures[0].Sig
// TODO(#496): verify the keyid, both in DSSE and hint.
// Verify the signature.
payloadHash := sha256.Sum256(payload)
rawKey, err := base64.StdEncoding.DecodeString(npmRegistryPublicKey)
// Verify the PAE signature.
derKey, err := base64.StdEncoding.DecodeString(npmRegistryPublicKey)
if err != nil {
return fmt.Errorf("DecodeString: %w", err)
}
key, err := x509.ParsePKIXPublicKey(rawKey)
envVerifier, err := utils.DsseVerifierNew(derKey, utils.KeyFormatDER, npmRegistryPublicKeyID, nil)
if err != nil {
return fmt.Errorf("x509.ParsePKIXPublicKey: %w", err)
return err
}
pubKey, ok := key.(*ecdsa.PublicKey)
if !ok {
return fmt.Errorf("%w: public key not of type ECDSA", err)
}
rsig, err := utils.DecodeSignature(sig)
_, err = envVerifier.Verify(context.Background(), signedPublish.Envelope)
if err != nil {
return fmt.Errorf("decodeSigature: %w: %s", serrors.ErrorInvalidEncoding, err)
}
if ecdsa.VerifyASN1(pubKey, payloadHash[:], rsig) {
return fmt.Errorf("%w: %s", serrors.ErrorInvalidSignature, sig)
return fmt.Errorf("%w: %w", serrors.ErrorInvalidSignature, err)
}
// Verification done.
@@ -314,7 +286,7 @@ func (n *Npm) verifyBuilderID(
}
func verifyPublishPredicateVersion(att *SignedAttestation, expectedVersion string) error {
_, version, err := getPublishPredicateData(att)
_, version, err := publishPredicateData(att)
if err != nil {
return err
}
@@ -326,7 +298,7 @@ func verifyPublishPredicateVersion(att *SignedAttestation, expectedVersion strin
}
func verifyPublishPredicateName(att *SignedAttestation, expectedName string) error {
name, _, err := getPublishPredicateData(att)
name, _, err := publishPredicateData(att)
if err != nil {
return err
}
@@ -337,7 +309,26 @@ func verifyPublishPredicateName(att *SignedAttestation, expectedName string) err
return nil
}
func getPublishPredicateData(att *SignedAttestation) (string, string, error) {
func subjectsFromAttestation(att *SignedAttestation) ([]intoto.Subject, error) {
env := att.Envelope
pyld, err := base64.StdEncoding.DecodeString(env.Payload)
if err != nil {
return nil, fmt.Errorf("%w: %w", serrors.ErrorInvalidDssePayload, err)
}
statement := struct {
intoto.StatementHeader
}{}
if err := json.Unmarshal(pyld, &statement); err != nil {
return nil, fmt.Errorf("%w: %w", serrors.ErrorInvalidDssePayload, err)
}
if len(statement.Subject) == 0 {
return nil, fmt.Errorf("%w: no subjects", serrors.ErrorInvalidDssePayload)
}
return statement.Subject, nil
}
func publishPredicateData(att *SignedAttestation) (string, string, error) {
env := att.Envelope
pyld, err := base64.StdEncoding.DecodeString(env.Payload)
if err != nil {
@@ -377,8 +368,37 @@ func verifyProvenanceSubjectVersion(b *utils.TrustedBuilderID, att *SignedAttest
return nil
}
func (n *Npm) verifySubjectDigest(expectedHash string) error {
publishSubjects, err := subjectsFromAttestation(n.verifiedPublishAtt)
if err != nil {
return err
}
// 8 bit represented in hex, so 8/2=4.
bitLength := len(expectedHash) * 4
expectedAlgo := fmt.Sprintf("sha%v", bitLength)
if bitLength < 256 {
return fmt.Errorf("%w: expected minimum sha256, got %s", serrors.ErrorInvalidHash, expectedAlgo)
}
for _, subject := range publishSubjects {
digestSet := subject.Digest
hash, exists := digestSet[expectedAlgo]
if !exists {
continue
}
if hash == expectedHash {
return nil
}
}
// NOTE: We don't need to verify that the digest matches the one in the provenance
// because the provenance verification will verify the hash as well.
return fmt.Errorf("expected hash '%s' not found: %w", expectedHash, serrors.ErrorMismatchHash)
}
func verifyPublishSubjectVersion(att *SignedAttestation, expectedVersion string) error {
_, version, err := getPublishPredicateData(att)
_, version, err := publishPredicateData(att)
if err != nil {
return err
}
@@ -392,7 +412,7 @@ func verifyPublishSubjectVersion(att *SignedAttestation, expectedVersion string)
}
func verifyPublishSubjectName(att *SignedAttestation, expectedName string) error {
name, _, err := getPublishPredicateData(att)
name, _, err := publishPredicateData(att)
if err != nil {
return err
}

View File

@@ -798,6 +798,84 @@ func Test_verifyPackageName(t *testing.T) {
}
}
func Test_verifySubjectDigest(t *testing.T) {
t.Parallel()
ctx := context.Background()
trustedRoot, err := TrustedRootSingleton(ctx)
if err != nil {
t.Fatal(err)
}
tests := []struct {
name string
path string
hash string
err error
}{
{
name: "correct hash",
path: "npm-attestations.intoto.sigstore",
hash: "29d19f26233f4441328412b34fd73ed104ecfef62f14097890cccf7455b521b65c5acff851849faa85c85395aa22d401436f01f3afb61b19c780e906c88c7f20",
},
{
name: "incorrect hash",
path: "npm-attestations.intoto.sigstore",
hash: "39d19f26233f4441328412b34fd73ed104ecfef62f14097890cccf7455b521b65c5acff851849faa85c85395aa22d401436f01f3afb61b19c780e906c88c7f20",
err: serrors.ErrorMismatchHash,
},
{
name: "no subjects",
path: "npm-att-publish-nosubjects.intoto.sigstore",
hash: "29d19f26233f4441328412b34fd73ed104ecfef62f14097890cccf7455b521b65c5acff851849faa85c85395aa22d401436f01f3afb61b19c780e906c88c7f20",
err: serrors.ErrorInvalidDssePayload,
},
{
name: "no digest",
path: "npm-att-publish-nodigest.intoto.sigstore",
hash: "29d19f26233f4441328412b34fd73ed104ecfef62f14097890cccf7455b521b65c5acff851849faa85c85395aa22d401436f01f3afb61b19c780e906c88c7f20",
err: serrors.ErrorMismatchHash,
},
}
for _, tt := range tests {
tt := tt // Re-initializing variable so it is not changed while executing the closure below
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
content, err := os.ReadFile(filepath.Join("testdata", tt.path))
if err != nil {
panic(fmt.Errorf("os.ReadFile: %w", err))
}
npm, err := NpmNew(ctx, trustedRoot, content)
if err != nil {
panic(fmt.Errorf("NpmNew: %w", err))
}
// Set provenance attestation.
env, err := getEnvelopeFromBundleBytes(npm.provenanceAttestation.BundleBytes)
if err != nil {
panic(fmt.Errorf("getEnvelopeFromBundleBytes: %w", err))
}
npm.verifiedProvenanceAtt = &SignedAttestation{
Envelope: env,
}
env, err = getEnvelopeFromBundleBytes(npm.publishAttestation.BundleBytes)
if err != nil {
panic(fmt.Errorf("getEnvelopeFromBundleBytes: %w", err))
}
npm.verifiedPublishAtt = &SignedAttestation{
Envelope: env,
}
err = npm.verifySubjectDigest(tt.hash)
if !errCmp(err, tt.err) {
t.Errorf(cmp.Diff(err, tt.err))
}
})
}
}
func Test_verifyPackageVersion(t *testing.T) {
t.Parallel()
ctx := context.Background()
@@ -1115,3 +1193,97 @@ func Test_NpmNew(t *testing.T) {
})
}
}
func Test_verifyPublishAttestationSignature(t *testing.T) {
t.Parallel()
ctx := context.Background()
trustedRoot, err := TrustedRootSingleton(ctx)
if err != nil {
t.Fatal(err)
}
tests := []struct {
name string
path string
version string
err error
}{
{
name: "correct",
path: "npm-attestations.intoto.sigstore",
},
{
name: "incorrect signature",
path: "npm-att-publish-invalid-signature.intoto.sigstore",
err: serrors.ErrorInvalidSignature,
},
}
for _, tt := range tests {
tt := tt // Re-initializing variable so it is not changed while executing the closure below
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
content, err := os.ReadFile(filepath.Join("testdata", tt.path))
if err != nil {
panic(fmt.Errorf("os.ReadFile: %w", err))
}
npm, err := NpmNew(ctx, trustedRoot, content)
if err != nil {
t.Fatalf("unexpected error: \n%s", err)
}
err = npm.verifyPublishAttestationSignature()
if diff := cmp.Diff(tt.err, err, cmpopts.EquateErrors()); diff != "" {
t.Fatalf("unexpected error (-want +got): \n%s", diff)
}
})
}
}
func Test_verifyProvenanceAttestationSignature(t *testing.T) {
t.Parallel()
ctx := context.Background()
trustedRoot, err := TrustedRootSingleton(ctx)
if err != nil {
t.Fatal(err)
}
tests := []struct {
name string
path string
version string
err error
}{
{
name: "correct",
path: "npm-attestations.intoto.sigstore",
},
{
name: "incorrect signature",
path: "npm-att-prov-invalid-signature.intoto.sigstore",
err: serrors.ErrorInvalidSignature,
},
}
for _, tt := range tests {
tt := tt // Re-initializing variable so it is not changed while executing the closure below
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
content, err := os.ReadFile(filepath.Join("testdata", tt.path))
if err != nil {
panic(fmt.Errorf("os.ReadFile: %w", err))
}
npm, err := NpmNew(ctx, trustedRoot, content)
if err != nil {
t.Fatalf("unexpected error: \n%s", err)
}
err = npm.verifyProvenanceAttestationSignature()
if diff := cmp.Diff(tt.err, err, cmpopts.EquateErrors()); diff != "" {
t.Fatalf("unexpected error (-want +got): \n%s", diff)
}
})
}
}

View File

@@ -0,0 +1,94 @@
{
"attestations": [
{
"predicateType": "https://slsa.dev/provenance/v0.2",
"bundle": {
"mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1",
"verificationMaterial": {
"x509CertificateChain": {
"certificates": [
{
"rawBytes": "MIIDzTCCA1SgAwIBAgIUSUNeEjOTOlxw2mAmVuog6waz+NcwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjMwMjE1MTkzMzMyWhcNMjMwMjE1MTk0MzMyWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEVWrN2Ayc3U80RBnqrFssCXrFETeyMskQhLAXaOAbaPylLa6GiuhrZUEd+i2Q+kvtlOJN6WvJaoIirGUUw84scKOCAnMwggJvMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUgYNyCZHUpkzBfqlfSh2+dV/nqg8wHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wbwYDVR0RAQH/BGUwY4ZhaHR0cHM6Ly9naXRodWIuY29tL2xhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0Ly5naXRodWIvd29ya2Zsb3dzL3JlbGVhc2UueW1sQHJlZnMvaGVhZHMvbWFpbjA5BgorBgEEAYO/MAEBBCtodHRwczovL3Rva2VuLmFjdGlvbnMuZ2l0aHVidXNlcmNvbnRlbnQuY29tMB8GCisGAQQBg78wAQIEEXdvcmtmbG93X2Rpc3BhdGNoMDYGCisGAQQBg78wAQMEKDE2YmFiZmZiOTE1MzgxMWUxOTNjMDE5OTM5MzkxMzU3MzcyYjI1Y2UwJgYKKwYBBAGDvzABBAQYUHVibGlzaCBQYWNrYWdlIHRvIG5wbWpzMC4GCisGAQQBg78wAQUEIGxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0MB0GCisGAQQBg78wAQYED3JlZnMvaGVhZHMvbWFpbjCBiwYKKwYBBAHWeQIEAgR9BHsAeQB3AN09MGrGxxEyYxkeHJlnNwKiSl643jyt/4eKcoAvKe6OAAABhlaRXNMAAAQDAEgwRgIhAOZYHC2AyB4Mm5uV6etiegcdoB5t/3Q6e8pah2BH60urAiEAv9rv6WNIyPfXrP1yzykQldw9iExSBh/brNNjTLzP+wYwCgYIKoZIzj0EAwMDZwAwZAIwT+nOUcGmT+K1gtU/ETiJewRTXtX5bjFh0AEDWzVFlLQKk+CMCr+CmhJgfobd83qwAjAz9Wp4/krIgy+qD7oeCwlUH74MNgWpy2QU5Ox3J61wP2/0O7bhH5fDaGtYUFKZzwA="
},
{
"rawBytes": "MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow="
},
{
"rawBytes": "MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ"
}
]
},
"tlogEntries": [
{
"logIndex": "13420286",
"logId": {
"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
},
"kindVersion": {
"kind": "intoto",
"version": "0.0.2"
},
"integratedTime": "1676489612",
"inclusionPromise": {
"signedEntryTimestamp": "MEUCIG/LjJ5tqTgKvbA0F+96CJHIk2X0S+9cBz1Z04BfU7dLAiEA7cpf1Agv0VyEu0wR41nEZ9AZ6GVaYR5rf4AAYIZr4hk="
},
"inclusionProof": null,
"canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVI2VkVORFFURlRaMEYzU1VKQlowbFZVMVZPWlVWcVQxUlBiSGgzTW0xQmJWWjFiMmMyZDJGNkswNWpkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BOZDAxcVJURk5WR3Q2VFhwTmVWZG9ZMDVOYWsxM1RXcEZNVTFVYXpCTmVrMTVWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWV1YzSk9Na0Y1WXpOVk9EQlNRbTV4Y2taemMwTllja1pGVkdWNVRYTnJVV2hNUVZnS1lVOUJZbUZRZVd4TVlUWkhhWFZvY2xwVlJXUXJhVEpSSzJ0MmRHeFBTazQyVjNaS1lXOUphWEpIVlZWM09EUnpZMHRQUTBGdVRYZG5aMHAyVFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZWbldVNTVDa05hU0ZWd2EzcENabkZzWmxOb01pdGtWaTl1Y1djNGQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQySjNXVVJXVWpCU1FWRklMMEpIVlhkWk5GcG9ZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRESjRhR1JZU214aWJsSjZZVmN4ZGdwaWFUbDNZMjA1TWxwWE5XaGliVTVzVEZjMWQySlRNVEJhV0U0d1RIazFibUZZVW05a1YwbDJaREk1ZVdFeVduTmlNMlI2VEROS2JHSkhWbWhqTWxWMUNtVlhNWE5SU0Vwc1dtNU5kbUZIVm1oYVNFMTJZbGRHY0dKcVFUVkNaMjl5UW1kRlJVRlpUeTlOUVVWQ1FrTjBiMlJJVW5kamVtOTJURE5TZG1FeVZuVUtURzFHYW1SSGJIWmliazExV2pKc01HRklWbWxrV0U1c1kyMU9kbUp1VW14aWJsRjFXVEk1ZEUxQ09FZERhWE5IUVZGUlFtYzNPSGRCVVVsRlJWaGtkZ3BqYlhSdFlrYzVNMWd5VW5Cak0wSm9aRWRPYjAxRVdVZERhWE5IUVZGUlFtYzNPSGRCVVUxRlMwUkZNbGx0Um1sYWJWcHBUMVJGTVUxNlozaE5WMVY0Q2s5VVRtcE5SRVUxVDFSTk5VMTZhM2hOZWxVelRYcGplVmxxU1RGWk1sVjNTbWRaUzB0M1dVSkNRVWRFZG5wQlFrSkJVVmxWU0ZacFlrZHNlbUZEUWxFS1dWZE9jbGxYWkd4SlNGSjJTVWMxZDJKWGNIcE5RelJIUTJselIwRlJVVUpuTnpoM1FWRlZSVWxIZUdoa1dFcHNZbTVTZW1GWE1YWmlhVGwzWTIwNU1ncGFWelZvWW0xT2JFeFhOWGRpVXpFd1dsaE9NRTFDTUVkRGFYTkhRVkZSUW1jM09IZEJVVmxGUkROS2JGcHVUWFpoUjFab1draE5kbUpYUm5CaWFrTkNDbWwzV1V0TGQxbENRa0ZJVjJWUlNVVkJaMUk1UWtoelFXVlJRak5CVGpBNVRVZHlSM2g0UlhsWmVHdGxTRXBzYms1M1MybFRiRFkwTTJwNWRDODBaVXNLWTI5QmRrdGxOazlCUVVGQ2FHeGhVbGhPVFVGQlFWRkVRVVZuZDFKblNXaEJUMXBaU0VNeVFYbENORTF0TlhWV05tVjBhV1ZuWTJSdlFqVjBMek5STmdwbE9IQmhhREpDU0RZd2RYSkJhVVZCZGpseWRqWlhUa2w1VUdaWWNsQXhlWHA1YTFGc1pIYzVhVVY0VTBKb0wySnlUazVxVkV4NlVDdDNXWGREWjFsSkNrdHZXa2w2YWpCRlFYZE5SRnAzUVhkYVFVbDNWQ3R1VDFWalIyMVVLMHN4WjNSVkwwVlVhVXBsZDFKVVdIUllOV0pxUm1nd1FVVkVWM3BXUm14TVVVc0theXREVFVOeUswTnRhRXBuWm05aVpEZ3pjWGRCYWtGNk9WZHdOQzlyY2tsbmVTdHhSRGR2WlVOM2JGVklOelJOVG1kWGNIa3lVVlUxVDNnelNqWXhkd3BRTWk4d1R6ZGlhRWcxWmtSaFIzUlpWVVpMV25wM1FUMEtMUzB0TFMxRlRrUWdRMFZTVkVsR1NVTkJWRVV0TFMwdExRbz0iLCJzaWciOiJUVVZWUTBsUlJFcGhhRlJ3VTI1c2RqWkllbFZxTW5reEwxQkNXVXhHZVRob2FFb3JOV1ZCUWxrM2RYazRVbEJ6UjFGSlowcFdkVXd6UjNJNWVXSXlWRkJWUlUxek5rbGxhVFZJVUVoaWVVZHNObWw0WjJRME1YbDJlVEEzVWxFOSJ9XX0sImhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiIyYzVhZjNiZThjNzcxYzAwYzVhZGYwNDAxMzQ5YTg1NjM5NjA3Nzg4MzQwNjRhMmYyOTk5YzY4YmZiMWI0Njg4In0sInBheWxvYWRIYXNoIjp7ImFsZ29yaXRobSI6InNoYTI1NiIsInZhbHVlIjoiNjg5ZTE2NmNlM2I1Zjk5MTgxZDExYjcyYjg2OTJkODEwYjJlM2NkMTdmZWNiZjBiNzRmNDBmYTRmNmUzNjNkNSJ9fX19"
}
],
"timestampVerificationData": null
},
"dsseEnvelope": {
"payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInN1YmplY3QiOlt7Im5hbWUiOiJwa2c6bnBtLyU0MGxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0QDEuMC4wIiwiZGlnZXN0Ijp7InNoYTUxMiI6IjI5ZDE5ZjI2MjMzZjQ0NDEzMjg0MTJiMzRmZDczZWQxMDRlY2ZlZjYyZjE0MDk3ODkwY2NjZjc0NTViNTIxYjY1YzVhY2ZmODUxODQ5ZmFhODVjODUzOTVhYTIyZDQwMTQzNmYwMWYzYWZiNjFiMTljNzgwZTkwNmM4OGM3ZjIwIn19XSwicHJlZGljYXRlVHlwZSI6Imh0dHBzOi8vc2xzYS5kZXYvcHJvdmVuYW5jZS92MC4yIiwicHJlZGljYXRlIjp7ImJ1aWxkVHlwZSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9ucG0vY2xpL2doYUB2MSIsImJ1aWxkZXIiOnsiaWQiOiJodHRwczovL2dpdGh1Yi5jb20vbnBtL2NsaUA5LjUuMCJ9LCJpbnZvY2F0aW9uIjp7ImNvbmZpZ1NvdXJjZSI6eyJ1cmkiOiJnaXQraHR0cHM6Ly9naXRodWIuY29tL2xhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0QHJlZnMvaGVhZHMvbWFpbiIsImRpZ2VzdCI6eyJzaGExIjoiMTZiYWJmZmI5MTUzODExZTE5M2MwMTk5MzkzOTEzNTczNzJiMjVjZSJ9LCJlbnRyeVBvaW50IjoibGF1cmVudHNpbW9uL3Byb3ZlbmFuY2UtbnBtLXRlc3QvLmdpdGh1Yi93b3JrZmxvd3MvcmVsZWFzZS55bWxAcmVmcy9oZWFkcy9tYWluIn0sInBhcmFtZXRlcnMiOnt9LCJlbnZpcm9ubWVudCI6eyJHSVRIVUJfQUNUT1JfSUQiOiI2NDUwNTA5OSIsIkdJVEhVQl9FVkVOVF9OQU1FIjoid29ya2Zsb3dfZGlzcGF0Y2giLCJHSVRIVUJfUkVGIjoicmVmcy9oZWFkcy9tYWluIiwiR0lUSFVCX1JFRl9UWVBFIjoiYnJhbmNoIiwiR0lUSFVCX1JFUE9TSVRPUlkiOiJsYXVyZW50c2ltb24vcHJvdmVuYW5jZS1ucG0tdGVzdCIsIkdJVEhVQl9SRVBPU0lUT1JZX0lEIjoiNjAyMjIzOTQ1IiwiR0lUSFVCX1JFUE9TSVRPUllfT1dORVJfSUQiOiI2NDUwNTA5OSIsIkdJVEhVQl9SVU5fQVRURU1QVCI6IjEiLCJHSVRIVUJfUlVOX0lEIjoiNDE4NzQ2NDU3NyIsIkdJVEhVQl9SVU5fTlVNQkVSIjoiMiIsIkdJVEhVQl9TSEEiOiIxNmJhYmZmYjkxNTM4MTFlMTkzYzAxOTkzOTM5MTM1NzM3MmIyNWNlIiwiR0lUSFVCX1dPUktGTE9XX1JFRiI6ImxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0Ly5naXRodWIvd29ya2Zsb3dzL3JlbGVhc2UueW1sQHJlZnMvaGVhZHMvbWFpbiIsIkdJVEhVQl9XT1JLRkxPV19TSEEiOiIxNmJhYmZmYjkxNTM4MTFlMTkzYzAxOTkzOTM5MTM1NzM3MmIyNWNlIn19LCJtZXRhZGF0YSI6eyJidWlsZEludm9jYXRpb25JZCI6IjQxODc0NjQ1NzctMSIsImNvbXBsZXRlbmVzcyI6eyJwYXJhbWV0ZXJzIjpmYWxzZSwiZW52aXJvbm1lbnQiOmZhbHNlLCJtYXRlcmlhbHMiOmZhbHNlfSwicmVwcm9kdWNpYmxlIjpmYWxzZX0sIm1hdGVyaWFscyI6W3sidXJpIjoiZ2l0K2h0dHBzOi8vZ2l0aHViLmNvbS9sYXVyZW50c2ltb24vcHJvdmVuYW5jZS1ucG0tdGVzdCIsImRpZ2VzdCI6eyJzaGExIjoiMTZiYWJmZmI5MTUzODExZTE5M2MwMTk5MzkzOTEzNTczNzJiMjVjZiJ9fV19fQo=",
"payloadType": "application/vnd.in-toto+json",
"signatures": [
{
"sig": "MEUCIQDJahTpSnlv6HzUj2y1/PBYLFy8hhJ+5eABY7uy8RPsGQIgJVuL3Gr9yb2TPUEMs6Iei5HPHbyGl6ixgd41yvy07RQ=",
"keyid": ""
}
]
}
}
},
{
"predicateType": "https://github.com/npm/attestation/tree/main/specs/publish/v0.1",
"bundle": {
"mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1",
"verificationMaterial": {
"publicKey": {
"hint": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"
},
"tlogEntries": [
{
"logIndex": "13420289",
"logId": {
"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
},
"kindVersion": {
"kind": "intoto",
"version": "0.0.2"
},
"integratedTime": "1676489615",
"inclusionPromise": {
"signedEntryTimestamp": "MEUCICYgQbiFj7t0A9B/p4Hkq5H0gB41InPBFFnhEeuP4Fo0AiEA7fGqVACs5cFpoQGHX8HVDq/jKBWbS0gutPXpcOz6r6g="
},
"inclusionProof": null,
"canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiU0hBMjU2OmpsM2J3c3d1ODBQampva0NnaDBvMnc1YzJVNExoUUFFNTdnajljejFrekEiLCJwdWJsaWNLZXkiOiJMUzB0TFMxQ1JVZEpUaUJRVlVKTVNVTWdTMFZaTFMwdExTMEtUVVpyZDBWM1dVaExiMXBKZW1vd1EwRlJXVWxMYjFwSmVtb3dSRUZSWTBSUlowRkZNVTlzWWpONlRVRkdSbmhZUzBocFNXdFJUelZqU2pOWmFHdzFhVFpWVUhBclNXaDFkR1ZDU21KMVNHTkJOVlZ2WjB0dk1FVlhkR3hYZDFjMlMxTmhTMjlVVGtWWlREZEtiRU5SYVZadWEyaENhM1JWWjJjOVBRb3RMUzB0TFVWT1JDQlFWVUpNU1VNZ1MwVlpMUzB0TFMwPSIsInNpZyI6IlRVVlJRMGxETURGaFJqbFFZVWxtSzNOcVkzRlBiVzQwUVZaVU56bFBWMFJuVkZGVk5XVXZiVkp0TVcweVNIWjVRV2xCY0hCNk1FWkxWVzFEVjJwdVUyUnJORzB5VkdGTlpXMXFSRXRqUlcxTVdFSTRWVVpFTlZsYWRETTJaejA5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjkxNDU3YjdiYzg1NTgwY2Y2NTAxNDM5NDU5ZDYyOWI0YzBlOTUxNmFjNzc3NTllNGQwNzMwZjVlMTUxNjRkMDcifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI1ZmFmZTQwMmJiYzBiMTNhMmFmMmIzMjhjYmNjNmFiZTlmZTA1MGRkNDUzNjNkNTE1YWIyYzk4MjA3NDMwNjVkIn19fX0="
}
],
"timestampVerificationData": null
},
"dsseEnvelope": {
"payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInN1YmplY3QiOlt7Im5hbWUiOiJwa2c6bnBtLyU0MGxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0QDEuMC4wIiwiZGlnZXN0Ijp7InNoYTUxMiI6IjI5ZDE5ZjI2MjMzZjQ0NDEzMjg0MTJiMzRmZDczZWQxMDRlY2ZlZjYyZjE0MDk3ODkwY2NjZjc0NTViNTIxYjY1YzVhY2ZmODUxODQ5ZmFhODVjODUzOTVhYTIyZDQwMTQzNmYwMWYzYWZiNjFiMTljNzgwZTkwNmM4OGM3ZjIwIn19XSwicHJlZGljYXRlVHlwZSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9ucG0vYXR0ZXN0YXRpb24vdHJlZS9tYWluL3NwZWNzL3B1Ymxpc2gvdjAuMSIsInByZWRpY2F0ZSI6eyJuYW1lIjoiQGxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0IiwidmVyc2lvbiI6IjEuMC4wIiwicmVnaXN0cnkiOiJodHRwczovL3JlZ2lzdHJ5Lm5wbWpzLm9yZyJ9fQ==",
"payloadType": "application/vnd.in-toto+json",
"signatures": [
{
"sig": "MEQCIC01aF9PaIf+sjcqOmn4AVT79OWDgTQU5e/mRm1m2HvyAiAppz0FKUmCWjnSdk4m2TaMemjDKcEmLXB8UFD5YZt36g==",
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"
}
]
}
}
}
]
}

View File

@@ -0,0 +1,94 @@
{
"attestations": [
{
"predicateType": "https://slsa.dev/provenance/v0.2",
"bundle": {
"mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1",
"verificationMaterial": {
"x509CertificateChain": {
"certificates": [
{
"rawBytes": "MIIDzTCCA1SgAwIBAgIUSUNeEjOTOlxw2mAmVuog6waz+NcwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjMwMjE1MTkzMzMyWhcNMjMwMjE1MTk0MzMyWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEVWrN2Ayc3U80RBnqrFssCXrFETeyMskQhLAXaOAbaPylLa6GiuhrZUEd+i2Q+kvtlOJN6WvJaoIirGUUw84scKOCAnMwggJvMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUgYNyCZHUpkzBfqlfSh2+dV/nqg8wHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wbwYDVR0RAQH/BGUwY4ZhaHR0cHM6Ly9naXRodWIuY29tL2xhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0Ly5naXRodWIvd29ya2Zsb3dzL3JlbGVhc2UueW1sQHJlZnMvaGVhZHMvbWFpbjA5BgorBgEEAYO/MAEBBCtodHRwczovL3Rva2VuLmFjdGlvbnMuZ2l0aHVidXNlcmNvbnRlbnQuY29tMB8GCisGAQQBg78wAQIEEXdvcmtmbG93X2Rpc3BhdGNoMDYGCisGAQQBg78wAQMEKDE2YmFiZmZiOTE1MzgxMWUxOTNjMDE5OTM5MzkxMzU3MzcyYjI1Y2UwJgYKKwYBBAGDvzABBAQYUHVibGlzaCBQYWNrYWdlIHRvIG5wbWpzMC4GCisGAQQBg78wAQUEIGxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0MB0GCisGAQQBg78wAQYED3JlZnMvaGVhZHMvbWFpbjCBiwYKKwYBBAHWeQIEAgR9BHsAeQB3AN09MGrGxxEyYxkeHJlnNwKiSl643jyt/4eKcoAvKe6OAAABhlaRXNMAAAQDAEgwRgIhAOZYHC2AyB4Mm5uV6etiegcdoB5t/3Q6e8pah2BH60urAiEAv9rv6WNIyPfXrP1yzykQldw9iExSBh/brNNjTLzP+wYwCgYIKoZIzj0EAwMDZwAwZAIwT+nOUcGmT+K1gtU/ETiJewRTXtX5bjFh0AEDWzVFlLQKk+CMCr+CmhJgfobd83qwAjAz9Wp4/krIgy+qD7oeCwlUH74MNgWpy2QU5Ox3J61wP2/0O7bhH5fDaGtYUFKZzwA="
},
{
"rawBytes": "MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow="
},
{
"rawBytes": "MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ"
}
]
},
"tlogEntries": [
{
"logIndex": "13420286",
"logId": {
"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
},
"kindVersion": {
"kind": "intoto",
"version": "0.0.2"
},
"integratedTime": "1676489612",
"inclusionPromise": {
"signedEntryTimestamp": "MEUCIG/LjJ5tqTgKvbA0F+96CJHIk2X0S+9cBz1Z04BfU7dLAiEA7cpf1Agv0VyEu0wR41nEZ9AZ6GVaYR5rf4AAYIZr4hk="
},
"inclusionProof": null,
"canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVI2VkVORFFURlRaMEYzU1VKQlowbFZVMVZPWlVWcVQxUlBiSGgzTW0xQmJWWjFiMmMyZDJGNkswNWpkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BOZDAxcVJURk5WR3Q2VFhwTmVWZG9ZMDVOYWsxM1RXcEZNVTFVYXpCTmVrMTVWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWV1YzSk9Na0Y1WXpOVk9EQlNRbTV4Y2taemMwTllja1pGVkdWNVRYTnJVV2hNUVZnS1lVOUJZbUZRZVd4TVlUWkhhWFZvY2xwVlJXUXJhVEpSSzJ0MmRHeFBTazQyVjNaS1lXOUphWEpIVlZWM09EUnpZMHRQUTBGdVRYZG5aMHAyVFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZWbldVNTVDa05hU0ZWd2EzcENabkZzWmxOb01pdGtWaTl1Y1djNGQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQySjNXVVJXVWpCU1FWRklMMEpIVlhkWk5GcG9ZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRESjRhR1JZU214aWJsSjZZVmN4ZGdwaWFUbDNZMjA1TWxwWE5XaGliVTVzVEZjMWQySlRNVEJhV0U0d1RIazFibUZZVW05a1YwbDJaREk1ZVdFeVduTmlNMlI2VEROS2JHSkhWbWhqTWxWMUNtVlhNWE5SU0Vwc1dtNU5kbUZIVm1oYVNFMTJZbGRHY0dKcVFUVkNaMjl5UW1kRlJVRlpUeTlOUVVWQ1FrTjBiMlJJVW5kamVtOTJURE5TZG1FeVZuVUtURzFHYW1SSGJIWmliazExV2pKc01HRklWbWxrV0U1c1kyMU9kbUp1VW14aWJsRjFXVEk1ZEUxQ09FZERhWE5IUVZGUlFtYzNPSGRCVVVsRlJWaGtkZ3BqYlhSdFlrYzVNMWd5VW5Cak0wSm9aRWRPYjAxRVdVZERhWE5IUVZGUlFtYzNPSGRCVVUxRlMwUkZNbGx0Um1sYWJWcHBUMVJGTVUxNlozaE5WMVY0Q2s5VVRtcE5SRVUxVDFSTk5VMTZhM2hOZWxVelRYcGplVmxxU1RGWk1sVjNTbWRaUzB0M1dVSkNRVWRFZG5wQlFrSkJVVmxWU0ZacFlrZHNlbUZEUWxFS1dWZE9jbGxYWkd4SlNGSjJTVWMxZDJKWGNIcE5RelJIUTJselIwRlJVVUpuTnpoM1FWRlZSVWxIZUdoa1dFcHNZbTVTZW1GWE1YWmlhVGwzWTIwNU1ncGFWelZvWW0xT2JFeFhOWGRpVXpFd1dsaE9NRTFDTUVkRGFYTkhRVkZSUW1jM09IZEJVVmxGUkROS2JGcHVUWFpoUjFab1draE5kbUpYUm5CaWFrTkNDbWwzV1V0TGQxbENRa0ZJVjJWUlNVVkJaMUk1UWtoelFXVlJRak5CVGpBNVRVZHlSM2g0UlhsWmVHdGxTRXBzYms1M1MybFRiRFkwTTJwNWRDODBaVXNLWTI5QmRrdGxOazlCUVVGQ2FHeGhVbGhPVFVGQlFWRkVRVVZuZDFKblNXaEJUMXBaU0VNeVFYbENORTF0TlhWV05tVjBhV1ZuWTJSdlFqVjBMek5STmdwbE9IQmhhREpDU0RZd2RYSkJhVVZCZGpseWRqWlhUa2w1VUdaWWNsQXhlWHA1YTFGc1pIYzVhVVY0VTBKb0wySnlUazVxVkV4NlVDdDNXWGREWjFsSkNrdHZXa2w2YWpCRlFYZE5SRnAzUVhkYVFVbDNWQ3R1VDFWalIyMVVLMHN4WjNSVkwwVlVhVXBsZDFKVVdIUllOV0pxUm1nd1FVVkVWM3BXUm14TVVVc0theXREVFVOeUswTnRhRXBuWm05aVpEZ3pjWGRCYWtGNk9WZHdOQzlyY2tsbmVTdHhSRGR2WlVOM2JGVklOelJOVG1kWGNIa3lVVlUxVDNnelNqWXhkd3BRTWk4d1R6ZGlhRWcxWmtSaFIzUlpWVVpMV25wM1FUMEtMUzB0TFMxRlRrUWdRMFZTVkVsR1NVTkJWRVV0TFMwdExRbz0iLCJzaWciOiJUVVZWUTBsUlJFcGhhRlJ3VTI1c2RqWkllbFZxTW5reEwxQkNXVXhHZVRob2FFb3JOV1ZCUWxrM2RYazRVbEJ6UjFGSlowcFdkVXd6UjNJNWVXSXlWRkJWUlUxek5rbGxhVFZJVUVoaWVVZHNObWw0WjJRME1YbDJlVEEzVWxFOSJ9XX0sImhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiIyYzVhZjNiZThjNzcxYzAwYzVhZGYwNDAxMzQ5YTg1NjM5NjA3Nzg4MzQwNjRhMmYyOTk5YzY4YmZiMWI0Njg4In0sInBheWxvYWRIYXNoIjp7ImFsZ29yaXRobSI6InNoYTI1NiIsInZhbHVlIjoiNjg5ZTE2NmNlM2I1Zjk5MTgxZDExYjcyYjg2OTJkODEwYjJlM2NkMTdmZWNiZjBiNzRmNDBmYTRmNmUzNjNkNSJ9fX19"
}
],
"timestampVerificationData": null
},
"dsseEnvelope": {
"payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInN1YmplY3QiOlt7Im5hbWUiOiJwa2c6bnBtLyU0MGxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0QDEuMC4wIiwiZGlnZXN0Ijp7InNoYTUxMiI6IjI5ZDE5ZjI2MjMzZjQ0NDEzMjg0MTJiMzRmZDczZWQxMDRlY2ZlZjYyZjE0MDk3ODkwY2NjZjc0NTViNTIxYjY1YzVhY2ZmODUxODQ5ZmFhODVjODUzOTVhYTIyZDQwMTQzNmYwMWYzYWZiNjFiMTljNzgwZTkwNmM4OGM3ZjIwIn19XSwicHJlZGljYXRlVHlwZSI6Imh0dHBzOi8vc2xzYS5kZXYvcHJvdmVuYW5jZS92MC4yIiwicHJlZGljYXRlIjp7ImJ1aWxkVHlwZSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9ucG0vY2xpL2doYUB2MSIsImJ1aWxkZXIiOnsiaWQiOiJodHRwczovL2dpdGh1Yi5jb20vbnBtL2NsaUA5LjUuMCJ9LCJpbnZvY2F0aW9uIjp7ImNvbmZpZ1NvdXJjZSI6eyJ1cmkiOiJnaXQraHR0cHM6Ly9naXRodWIuY29tL2xhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0QHJlZnMvaGVhZHMvbWFpbiIsImRpZ2VzdCI6eyJzaGExIjoiMTZiYWJmZmI5MTUzODExZTE5M2MwMTk5MzkzOTEzNTczNzJiMjVjZSJ9LCJlbnRyeVBvaW50IjoibGF1cmVudHNpbW9uL3Byb3ZlbmFuY2UtbnBtLXRlc3QvLmdpdGh1Yi93b3JrZmxvd3MvcmVsZWFzZS55bWxAcmVmcy9oZWFkcy9tYWluIn0sInBhcmFtZXRlcnMiOnt9LCJlbnZpcm9ubWVudCI6eyJHSVRIVUJfQUNUT1JfSUQiOiI2NDUwNTA5OSIsIkdJVEhVQl9FVkVOVF9OQU1FIjoid29ya2Zsb3dfZGlzcGF0Y2giLCJHSVRIVUJfUkVGIjoicmVmcy9oZWFkcy9tYWluIiwiR0lUSFVCX1JFRl9UWVBFIjoiYnJhbmNoIiwiR0lUSFVCX1JFUE9TSVRPUlkiOiJsYXVyZW50c2ltb24vcHJvdmVuYW5jZS1ucG0tdGVzdCIsIkdJVEhVQl9SRVBPU0lUT1JZX0lEIjoiNjAyMjIzOTQ1IiwiR0lUSFVCX1JFUE9TSVRPUllfT1dORVJfSUQiOiI2NDUwNTA5OSIsIkdJVEhVQl9SVU5fQVRURU1QVCI6IjEiLCJHSVRIVUJfUlVOX0lEIjoiNDE4NzQ2NDU3NyIsIkdJVEhVQl9SVU5fTlVNQkVSIjoiMiIsIkdJVEhVQl9TSEEiOiIxNmJhYmZmYjkxNTM4MTFlMTkzYzAxOTkzOTM5MTM1NzM3MmIyNWNlIiwiR0lUSFVCX1dPUktGTE9XX1JFRiI6ImxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0Ly5naXRodWIvd29ya2Zsb3dzL3JlbGVhc2UueW1sQHJlZnMvaGVhZHMvbWFpbiIsIkdJVEhVQl9XT1JLRkxPV19TSEEiOiIxNmJhYmZmYjkxNTM4MTFlMTkzYzAxOTkzOTM5MTM1NzM3MmIyNWNlIn19LCJtZXRhZGF0YSI6eyJidWlsZEludm9jYXRpb25JZCI6IjQxODc0NjQ1NzctMSIsImNvbXBsZXRlbmVzcyI6eyJwYXJhbWV0ZXJzIjpmYWxzZSwiZW52aXJvbm1lbnQiOmZhbHNlLCJtYXRlcmlhbHMiOmZhbHNlfSwicmVwcm9kdWNpYmxlIjpmYWxzZX0sIm1hdGVyaWFscyI6W3sidXJpIjoiZ2l0K2h0dHBzOi8vZ2l0aHViLmNvbS9sYXVyZW50c2ltb24vcHJvdmVuYW5jZS1ucG0tdGVzdCIsImRpZ2VzdCI6eyJzaGExIjoiMTZiYWJmZmI5MTUzODExZTE5M2MwMTk5MzkzOTEzNTczNzJiMjVjZSJ9fV19fQ==",
"payloadType": "application/vnd.in-toto+json",
"signatures": [
{
"sig": "MEUCIQDJahTpSnlv6HzUj2y1/PBYLFy8hhJ+5eABY7uy8RPsGQIgJVuL3Gr9yb2TPUEMs6Iei5HPHbyGl6ixgd41yvy07RQ=",
"keyid": ""
}
]
}
}
},
{
"predicateType": "https://github.com/npm/attestation/tree/main/specs/publish/v0.1",
"bundle": {
"mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1",
"verificationMaterial": {
"publicKey": {
"hint": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"
},
"tlogEntries": [
{
"logIndex": "13420289",
"logId": {
"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
},
"kindVersion": {
"kind": "intoto",
"version": "0.0.2"
},
"integratedTime": "1676489615",
"inclusionPromise": {
"signedEntryTimestamp": "MEUCICYgQbiFj7t0A9B/p4Hkq5H0gB41InPBFFnhEeuP4Fo0AiEA7fGqVACs5cFpoQGHX8HVDq/jKBWbS0gutPXpcOz6r6g="
},
"inclusionProof": null,
"canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiU0hBMjU2OmpsM2J3c3d1ODBQampva0NnaDBvMnc1YzJVNExoUUFFNTdnajljejFrekEiLCJwdWJsaWNLZXkiOiJMUzB0TFMxQ1JVZEpUaUJRVlVKTVNVTWdTMFZaTFMwdExTMEtUVVpyZDBWM1dVaExiMXBKZW1vd1EwRlJXVWxMYjFwSmVtb3dSRUZSWTBSUlowRkZNVTlzWWpONlRVRkdSbmhZUzBocFNXdFJUelZqU2pOWmFHdzFhVFpWVUhBclNXaDFkR1ZDU21KMVNHTkJOVlZ2WjB0dk1FVlhkR3hYZDFjMlMxTmhTMjlVVGtWWlREZEtiRU5SYVZadWEyaENhM1JWWjJjOVBRb3RMUzB0TFVWT1JDQlFWVUpNU1VNZ1MwVlpMUzB0TFMwPSIsInNpZyI6IlRVVlJRMGxETURGaFJqbFFZVWxtSzNOcVkzRlBiVzQwUVZaVU56bFBWMFJuVkZGVk5XVXZiVkp0TVcweVNIWjVRV2xCY0hCNk1FWkxWVzFEVjJwdVUyUnJORzB5VkdGTlpXMXFSRXRqUlcxTVdFSTRWVVpFTlZsYWRETTJaejA5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjkxNDU3YjdiYzg1NTgwY2Y2NTAxNDM5NDU5ZDYyOWI0YzBlOTUxNmFjNzc3NTllNGQwNzMwZjVlMTUxNjRkMDcifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI1ZmFmZTQwMmJiYzBiMTNhMmFmMmIzMjhjYmNjNmFiZTlmZTA1MGRkNDUzNjNkNTE1YWIyYzk4MjA3NDMwNjVkIn19fX0="
}
],
"timestampVerificationData": null
},
"dsseEnvelope": {
"payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInN1YmplY3QiOlt7Im5hbWUiOiJwa2c6bnBtLyU0MGxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0QDEuMC4wIiwiZGlnZXN0IjoiMjlkMTlmMjYyMzNmNDQ0MTMyODQxMmIzNGZkNzNlZDEwNGVjZmVmNjJmMTQwOTc4OTBjY2NmNzQ1NWI1MjFiNjVjNWFjZmY4NTE4NDlmYWE4NWM4NTM5NWFhMjJkNDAxNDM2ZjAxZjNhZmI2MWIxOWM3ODBlOTA2Yzg4YzdmMjEifV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL2dpdGh1Yi5jb20vbnBtL2F0dGVzdGF0aW9uL3RyZWUvbWFpbi9zcGVjcy9wdWJsaXNoL3YwLjEiLCJwcmVkaWNhdGUiOnsibmFtZSI6IkBsYXVyZW50c2ltb24vcHJvdmVuYW5jZS1ucG0tdGVzdCIsInZlcnNpb24iOiIxLjAuMCIsInJlZ2lzdHJ5IjoiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcifX0K",
"payloadType": "application/vnd.in-toto+json",
"signatures": [
{
"sig": "MEQCIC01aF9PaIf+sjcqOmn4AVT79OWDgTQU5e/mRm1m2HvyAiAppz0FKUmCWjnSdk4m2TaMemjDKcEmLXB8UFD5YZt36g==",
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"
}
]
}
}
}
]
}

View File

@@ -0,0 +1,94 @@
{
"attestations": [
{
"predicateType": "https://slsa.dev/provenance/v0.2",
"bundle": {
"mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1",
"verificationMaterial": {
"x509CertificateChain": {
"certificates": [
{
"rawBytes": "MIIDzTCCA1SgAwIBAgIUSUNeEjOTOlxw2mAmVuog6waz+NcwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjMwMjE1MTkzMzMyWhcNMjMwMjE1MTk0MzMyWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEVWrN2Ayc3U80RBnqrFssCXrFETeyMskQhLAXaOAbaPylLa6GiuhrZUEd+i2Q+kvtlOJN6WvJaoIirGUUw84scKOCAnMwggJvMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUgYNyCZHUpkzBfqlfSh2+dV/nqg8wHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wbwYDVR0RAQH/BGUwY4ZhaHR0cHM6Ly9naXRodWIuY29tL2xhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0Ly5naXRodWIvd29ya2Zsb3dzL3JlbGVhc2UueW1sQHJlZnMvaGVhZHMvbWFpbjA5BgorBgEEAYO/MAEBBCtodHRwczovL3Rva2VuLmFjdGlvbnMuZ2l0aHVidXNlcmNvbnRlbnQuY29tMB8GCisGAQQBg78wAQIEEXdvcmtmbG93X2Rpc3BhdGNoMDYGCisGAQQBg78wAQMEKDE2YmFiZmZiOTE1MzgxMWUxOTNjMDE5OTM5MzkxMzU3MzcyYjI1Y2UwJgYKKwYBBAGDvzABBAQYUHVibGlzaCBQYWNrYWdlIHRvIG5wbWpzMC4GCisGAQQBg78wAQUEIGxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0MB0GCisGAQQBg78wAQYED3JlZnMvaGVhZHMvbWFpbjCBiwYKKwYBBAHWeQIEAgR9BHsAeQB3AN09MGrGxxEyYxkeHJlnNwKiSl643jyt/4eKcoAvKe6OAAABhlaRXNMAAAQDAEgwRgIhAOZYHC2AyB4Mm5uV6etiegcdoB5t/3Q6e8pah2BH60urAiEAv9rv6WNIyPfXrP1yzykQldw9iExSBh/brNNjTLzP+wYwCgYIKoZIzj0EAwMDZwAwZAIwT+nOUcGmT+K1gtU/ETiJewRTXtX5bjFh0AEDWzVFlLQKk+CMCr+CmhJgfobd83qwAjAz9Wp4/krIgy+qD7oeCwlUH74MNgWpy2QU5Ox3J61wP2/0O7bhH5fDaGtYUFKZzwA="
},
{
"rawBytes": "MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow="
},
{
"rawBytes": "MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ"
}
]
},
"tlogEntries": [
{
"logIndex": "13420286",
"logId": {
"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
},
"kindVersion": {
"kind": "intoto",
"version": "0.0.2"
},
"integratedTime": "1676489612",
"inclusionPromise": {
"signedEntryTimestamp": "MEUCIG/LjJ5tqTgKvbA0F+96CJHIk2X0S+9cBz1Z04BfU7dLAiEA7cpf1Agv0VyEu0wR41nEZ9AZ6GVaYR5rf4AAYIZr4hk="
},
"inclusionProof": null,
"canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVI2VkVORFFURlRaMEYzU1VKQlowbFZVMVZPWlVWcVQxUlBiSGgzTW0xQmJWWjFiMmMyZDJGNkswNWpkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BOZDAxcVJURk5WR3Q2VFhwTmVWZG9ZMDVOYWsxM1RXcEZNVTFVYXpCTmVrMTVWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWV1YzSk9Na0Y1WXpOVk9EQlNRbTV4Y2taemMwTllja1pGVkdWNVRYTnJVV2hNUVZnS1lVOUJZbUZRZVd4TVlUWkhhWFZvY2xwVlJXUXJhVEpSSzJ0MmRHeFBTazQyVjNaS1lXOUphWEpIVlZWM09EUnpZMHRQUTBGdVRYZG5aMHAyVFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZWbldVNTVDa05hU0ZWd2EzcENabkZzWmxOb01pdGtWaTl1Y1djNGQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQySjNXVVJXVWpCU1FWRklMMEpIVlhkWk5GcG9ZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRESjRhR1JZU214aWJsSjZZVmN4ZGdwaWFUbDNZMjA1TWxwWE5XaGliVTVzVEZjMWQySlRNVEJhV0U0d1RIazFibUZZVW05a1YwbDJaREk1ZVdFeVduTmlNMlI2VEROS2JHSkhWbWhqTWxWMUNtVlhNWE5SU0Vwc1dtNU5kbUZIVm1oYVNFMTJZbGRHY0dKcVFUVkNaMjl5UW1kRlJVRlpUeTlOUVVWQ1FrTjBiMlJJVW5kamVtOTJURE5TZG1FeVZuVUtURzFHYW1SSGJIWmliazExV2pKc01HRklWbWxrV0U1c1kyMU9kbUp1VW14aWJsRjFXVEk1ZEUxQ09FZERhWE5IUVZGUlFtYzNPSGRCVVVsRlJWaGtkZ3BqYlhSdFlrYzVNMWd5VW5Cak0wSm9aRWRPYjAxRVdVZERhWE5IUVZGUlFtYzNPSGRCVVUxRlMwUkZNbGx0Um1sYWJWcHBUMVJGTVUxNlozaE5WMVY0Q2s5VVRtcE5SRVUxVDFSTk5VMTZhM2hOZWxVelRYcGplVmxxU1RGWk1sVjNTbWRaUzB0M1dVSkNRVWRFZG5wQlFrSkJVVmxWU0ZacFlrZHNlbUZEUWxFS1dWZE9jbGxYWkd4SlNGSjJTVWMxZDJKWGNIcE5RelJIUTJselIwRlJVVUpuTnpoM1FWRlZSVWxIZUdoa1dFcHNZbTVTZW1GWE1YWmlhVGwzWTIwNU1ncGFWelZvWW0xT2JFeFhOWGRpVXpFd1dsaE9NRTFDTUVkRGFYTkhRVkZSUW1jM09IZEJVVmxGUkROS2JGcHVUWFpoUjFab1draE5kbUpYUm5CaWFrTkNDbWwzV1V0TGQxbENRa0ZJVjJWUlNVVkJaMUk1UWtoelFXVlJRak5CVGpBNVRVZHlSM2g0UlhsWmVHdGxTRXBzYms1M1MybFRiRFkwTTJwNWRDODBaVXNLWTI5QmRrdGxOazlCUVVGQ2FHeGhVbGhPVFVGQlFWRkVRVVZuZDFKblNXaEJUMXBaU0VNeVFYbENORTF0TlhWV05tVjBhV1ZuWTJSdlFqVjBMek5STmdwbE9IQmhhREpDU0RZd2RYSkJhVVZCZGpseWRqWlhUa2w1VUdaWWNsQXhlWHA1YTFGc1pIYzVhVVY0VTBKb0wySnlUazVxVkV4NlVDdDNXWGREWjFsSkNrdHZXa2w2YWpCRlFYZE5SRnAzUVhkYVFVbDNWQ3R1VDFWalIyMVVLMHN4WjNSVkwwVlVhVXBsZDFKVVdIUllOV0pxUm1nd1FVVkVWM3BXUm14TVVVc0theXREVFVOeUswTnRhRXBuWm05aVpEZ3pjWGRCYWtGNk9WZHdOQzlyY2tsbmVTdHhSRGR2WlVOM2JGVklOelJOVG1kWGNIa3lVVlUxVDNnelNqWXhkd3BRTWk4d1R6ZGlhRWcxWmtSaFIzUlpWVVpMV25wM1FUMEtMUzB0TFMxRlRrUWdRMFZTVkVsR1NVTkJWRVV0TFMwdExRbz0iLCJzaWciOiJUVVZWUTBsUlJFcGhhRlJ3VTI1c2RqWkllbFZxTW5reEwxQkNXVXhHZVRob2FFb3JOV1ZCUWxrM2RYazRVbEJ6UjFGSlowcFdkVXd6UjNJNWVXSXlWRkJWUlUxek5rbGxhVFZJVUVoaWVVZHNObWw0WjJRME1YbDJlVEEzVWxFOSJ9XX0sImhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiIyYzVhZjNiZThjNzcxYzAwYzVhZGYwNDAxMzQ5YTg1NjM5NjA3Nzg4MzQwNjRhMmYyOTk5YzY4YmZiMWI0Njg4In0sInBheWxvYWRIYXNoIjp7ImFsZ29yaXRobSI6InNoYTI1NiIsInZhbHVlIjoiNjg5ZTE2NmNlM2I1Zjk5MTgxZDExYjcyYjg2OTJkODEwYjJlM2NkMTdmZWNiZjBiNzRmNDBmYTRmNmUzNjNkNSJ9fX19"
}
],
"timestampVerificationData": null
},
"dsseEnvelope": {
"payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInN1YmplY3QiOlt7Im5hbWUiOiJwa2c6bnBtLyU0MGxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0QDEuMC4wIiwiZGlnZXN0Ijp7InNoYTUxMiI6IjI5ZDE5ZjI2MjMzZjQ0NDEzMjg0MTJiMzRmZDczZWQxMDRlY2ZlZjYyZjE0MDk3ODkwY2NjZjc0NTViNTIxYjY1YzVhY2ZmODUxODQ5ZmFhODVjODUzOTVhYTIyZDQwMTQzNmYwMWYzYWZiNjFiMTljNzgwZTkwNmM4OGM3ZjIwIn19XSwicHJlZGljYXRlVHlwZSI6Imh0dHBzOi8vc2xzYS5kZXYvcHJvdmVuYW5jZS92MC4yIiwicHJlZGljYXRlIjp7ImJ1aWxkVHlwZSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9ucG0vY2xpL2doYUB2MSIsImJ1aWxkZXIiOnsiaWQiOiJodHRwczovL2dpdGh1Yi5jb20vbnBtL2NsaUA5LjUuMCJ9LCJpbnZvY2F0aW9uIjp7ImNvbmZpZ1NvdXJjZSI6eyJ1cmkiOiJnaXQraHR0cHM6Ly9naXRodWIuY29tL2xhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0QHJlZnMvaGVhZHMvbWFpbiIsImRpZ2VzdCI6eyJzaGExIjoiMTZiYWJmZmI5MTUzODExZTE5M2MwMTk5MzkzOTEzNTczNzJiMjVjZSJ9LCJlbnRyeVBvaW50IjoibGF1cmVudHNpbW9uL3Byb3ZlbmFuY2UtbnBtLXRlc3QvLmdpdGh1Yi93b3JrZmxvd3MvcmVsZWFzZS55bWxAcmVmcy9oZWFkcy9tYWluIn0sInBhcmFtZXRlcnMiOnt9LCJlbnZpcm9ubWVudCI6eyJHSVRIVUJfQUNUT1JfSUQiOiI2NDUwNTA5OSIsIkdJVEhVQl9FVkVOVF9OQU1FIjoid29ya2Zsb3dfZGlzcGF0Y2giLCJHSVRIVUJfUkVGIjoicmVmcy9oZWFkcy9tYWluIiwiR0lUSFVCX1JFRl9UWVBFIjoiYnJhbmNoIiwiR0lUSFVCX1JFUE9TSVRPUlkiOiJsYXVyZW50c2ltb24vcHJvdmVuYW5jZS1ucG0tdGVzdCIsIkdJVEhVQl9SRVBPU0lUT1JZX0lEIjoiNjAyMjIzOTQ1IiwiR0lUSFVCX1JFUE9TSVRPUllfT1dORVJfSUQiOiI2NDUwNTA5OSIsIkdJVEhVQl9SVU5fQVRURU1QVCI6IjEiLCJHSVRIVUJfUlVOX0lEIjoiNDE4NzQ2NDU3NyIsIkdJVEhVQl9SVU5fTlVNQkVSIjoiMiIsIkdJVEhVQl9TSEEiOiIxNmJhYmZmYjkxNTM4MTFlMTkzYzAxOTkzOTM5MTM1NzM3MmIyNWNlIiwiR0lUSFVCX1dPUktGTE9XX1JFRiI6ImxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0Ly5naXRodWIvd29ya2Zsb3dzL3JlbGVhc2UueW1sQHJlZnMvaGVhZHMvbWFpbiIsIkdJVEhVQl9XT1JLRkxPV19TSEEiOiIxNmJhYmZmYjkxNTM4MTFlMTkzYzAxOTkzOTM5MTM1NzM3MmIyNWNlIn19LCJtZXRhZGF0YSI6eyJidWlsZEludm9jYXRpb25JZCI6IjQxODc0NjQ1NzctMSIsImNvbXBsZXRlbmVzcyI6eyJwYXJhbWV0ZXJzIjpmYWxzZSwiZW52aXJvbm1lbnQiOmZhbHNlLCJtYXRlcmlhbHMiOmZhbHNlfSwicmVwcm9kdWNpYmxlIjpmYWxzZX0sIm1hdGVyaWFscyI6W3sidXJpIjoiZ2l0K2h0dHBzOi8vZ2l0aHViLmNvbS9sYXVyZW50c2ltb24vcHJvdmVuYW5jZS1ucG0tdGVzdCIsImRpZ2VzdCI6eyJzaGExIjoiMTZiYWJmZmI5MTUzODExZTE5M2MwMTk5MzkzOTEzNTczNzJiMjVjZSJ9fV19fQ==",
"payloadType": "application/vnd.in-toto+json",
"signatures": [
{
"sig": "MEUCIQDJahTpSnlv6HzUj2y1/PBYLFy8hhJ+5eABY7uy8RPsGQIgJVuL3Gr9yb2TPUEMs6Iei5HPHbyGl6ixgd41yvy07RQ=",
"keyid": ""
}
]
}
}
},
{
"predicateType": "https://github.com/npm/attestation/tree/main/specs/publish/v0.1",
"bundle": {
"mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1",
"verificationMaterial": {
"publicKey": {
"hint": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"
},
"tlogEntries": [
{
"logIndex": "13420289",
"logId": {
"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
},
"kindVersion": {
"kind": "intoto",
"version": "0.0.2"
},
"integratedTime": "1676489615",
"inclusionPromise": {
"signedEntryTimestamp": "MEUCICYgQbiFj7t0A9B/p4Hkq5H0gB41InPBFFnhEeuP4Fo0AiEA7fGqVACs5cFpoQGHX8HVDq/jKBWbS0gutPXpcOz6r6g="
},
"inclusionProof": null,
"canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiU0hBMjU2OmpsM2J3c3d1ODBQampva0NnaDBvMnc1YzJVNExoUUFFNTdnajljejFrekEiLCJwdWJsaWNLZXkiOiJMUzB0TFMxQ1JVZEpUaUJRVlVKTVNVTWdTMFZaTFMwdExTMEtUVVpyZDBWM1dVaExiMXBKZW1vd1EwRlJXVWxMYjFwSmVtb3dSRUZSWTBSUlowRkZNVTlzWWpONlRVRkdSbmhZUzBocFNXdFJUelZqU2pOWmFHdzFhVFpWVUhBclNXaDFkR1ZDU21KMVNHTkJOVlZ2WjB0dk1FVlhkR3hYZDFjMlMxTmhTMjlVVGtWWlREZEtiRU5SYVZadWEyaENhM1JWWjJjOVBRb3RMUzB0TFVWT1JDQlFWVUpNU1VNZ1MwVlpMUzB0TFMwPSIsInNpZyI6IlRVVlJRMGxETURGaFJqbFFZVWxtSzNOcVkzRlBiVzQwUVZaVU56bFBWMFJuVkZGVk5XVXZiVkp0TVcweVNIWjVRV2xCY0hCNk1FWkxWVzFEVjJwdVUyUnJORzB5VkdGTlpXMXFSRXRqUlcxTVdFSTRWVVpFTlZsYWRETTJaejA5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjkxNDU3YjdiYzg1NTgwY2Y2NTAxNDM5NDU5ZDYyOWI0YzBlOTUxNmFjNzc3NTllNGQwNzMwZjVlMTUxNjRkMDcifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI1ZmFmZTQwMmJiYzBiMTNhMmFmMmIzMjhjYmNjNmFiZTlmZTA1MGRkNDUzNjNkNTE1YWIyYzk4MjA3NDMwNjVkIn19fX0="
}
],
"timestampVerificationData": null
},
"dsseEnvelope": {
"payload": "ewogICJfdHlwZSI6ICJodHRwczovL2luLXRvdG8uaW8vU3RhdGVtZW50L3YwLjEiLAogICJzdWJqZWN0IjogWwogICAgewogICAgICAibmFtZSI6ICJwa2c6bnBtLyU0MGxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0QDEuMC4wIgogICAgfQogIF0sCiAgInByZWRpY2F0ZVR5cGUiOiAiaHR0cHM6Ly9naXRodWIuY29tL25wbS9hdHRlc3RhdGlvbi90cmVlL21haW4vc3BlY3MvcHVibGlzaC92MC4xIiwKICAicHJlZGljYXRlIjogewogICAgIm5hbWUiOiAiQGxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0IiwKICAgICJ2ZXJzaW9uIjogIjEuMC4wIiwKICAgICJyZWdpc3RyeSI6ICJodHRwczovL3JlZ2lzdHJ5Lm5wbWpzLm9yZyIKICB9Cn0K",
"payloadType": "application/vnd.in-toto+json",
"signatures": [
{
"sig": "MEQCIC01aF9PaIf+sjcqOmn4AVT79OWDgTQU5e/mRm1m2HvyAiAppz0FKUmCWjnSdk4m2TaMemjDKcEmLXB8UFD5YZt36g==",
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"
}
]
}
}
}
]
}

View File

@@ -0,0 +1,94 @@
{
"attestations": [
{
"predicateType": "https://slsa.dev/provenance/v0.2",
"bundle": {
"mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1",
"verificationMaterial": {
"x509CertificateChain": {
"certificates": [
{
"rawBytes": "MIIDzTCCA1SgAwIBAgIUSUNeEjOTOlxw2mAmVuog6waz+NcwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjMwMjE1MTkzMzMyWhcNMjMwMjE1MTk0MzMyWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEVWrN2Ayc3U80RBnqrFssCXrFETeyMskQhLAXaOAbaPylLa6GiuhrZUEd+i2Q+kvtlOJN6WvJaoIirGUUw84scKOCAnMwggJvMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUgYNyCZHUpkzBfqlfSh2+dV/nqg8wHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wbwYDVR0RAQH/BGUwY4ZhaHR0cHM6Ly9naXRodWIuY29tL2xhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0Ly5naXRodWIvd29ya2Zsb3dzL3JlbGVhc2UueW1sQHJlZnMvaGVhZHMvbWFpbjA5BgorBgEEAYO/MAEBBCtodHRwczovL3Rva2VuLmFjdGlvbnMuZ2l0aHVidXNlcmNvbnRlbnQuY29tMB8GCisGAQQBg78wAQIEEXdvcmtmbG93X2Rpc3BhdGNoMDYGCisGAQQBg78wAQMEKDE2YmFiZmZiOTE1MzgxMWUxOTNjMDE5OTM5MzkxMzU3MzcyYjI1Y2UwJgYKKwYBBAGDvzABBAQYUHVibGlzaCBQYWNrYWdlIHRvIG5wbWpzMC4GCisGAQQBg78wAQUEIGxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0MB0GCisGAQQBg78wAQYED3JlZnMvaGVhZHMvbWFpbjCBiwYKKwYBBAHWeQIEAgR9BHsAeQB3AN09MGrGxxEyYxkeHJlnNwKiSl643jyt/4eKcoAvKe6OAAABhlaRXNMAAAQDAEgwRgIhAOZYHC2AyB4Mm5uV6etiegcdoB5t/3Q6e8pah2BH60urAiEAv9rv6WNIyPfXrP1yzykQldw9iExSBh/brNNjTLzP+wYwCgYIKoZIzj0EAwMDZwAwZAIwT+nOUcGmT+K1gtU/ETiJewRTXtX5bjFh0AEDWzVFlLQKk+CMCr+CmhJgfobd83qwAjAz9Wp4/krIgy+qD7oeCwlUH74MNgWpy2QU5Ox3J61wP2/0O7bhH5fDaGtYUFKZzwA="
},
{
"rawBytes": "MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow="
},
{
"rawBytes": "MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ"
}
]
},
"tlogEntries": [
{
"logIndex": "13420286",
"logId": {
"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
},
"kindVersion": {
"kind": "intoto",
"version": "0.0.2"
},
"integratedTime": "1676489612",
"inclusionPromise": {
"signedEntryTimestamp": "MEUCIG/LjJ5tqTgKvbA0F+96CJHIk2X0S+9cBz1Z04BfU7dLAiEA7cpf1Agv0VyEu0wR41nEZ9AZ6GVaYR5rf4AAYIZr4hk="
},
"inclusionProof": null,
"canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVI2VkVORFFURlRaMEYzU1VKQlowbFZVMVZPWlVWcVQxUlBiSGgzTW0xQmJWWjFiMmMyZDJGNkswNWpkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BOZDAxcVJURk5WR3Q2VFhwTmVWZG9ZMDVOYWsxM1RXcEZNVTFVYXpCTmVrMTVWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWV1YzSk9Na0Y1WXpOVk9EQlNRbTV4Y2taemMwTllja1pGVkdWNVRYTnJVV2hNUVZnS1lVOUJZbUZRZVd4TVlUWkhhWFZvY2xwVlJXUXJhVEpSSzJ0MmRHeFBTazQyVjNaS1lXOUphWEpIVlZWM09EUnpZMHRQUTBGdVRYZG5aMHAyVFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZWbldVNTVDa05hU0ZWd2EzcENabkZzWmxOb01pdGtWaTl1Y1djNGQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQySjNXVVJXVWpCU1FWRklMMEpIVlhkWk5GcG9ZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRESjRhR1JZU214aWJsSjZZVmN4ZGdwaWFUbDNZMjA1TWxwWE5XaGliVTVzVEZjMWQySlRNVEJhV0U0d1RIazFibUZZVW05a1YwbDJaREk1ZVdFeVduTmlNMlI2VEROS2JHSkhWbWhqTWxWMUNtVlhNWE5SU0Vwc1dtNU5kbUZIVm1oYVNFMTJZbGRHY0dKcVFUVkNaMjl5UW1kRlJVRlpUeTlOUVVWQ1FrTjBiMlJJVW5kamVtOTJURE5TZG1FeVZuVUtURzFHYW1SSGJIWmliazExV2pKc01HRklWbWxrV0U1c1kyMU9kbUp1VW14aWJsRjFXVEk1ZEUxQ09FZERhWE5IUVZGUlFtYzNPSGRCVVVsRlJWaGtkZ3BqYlhSdFlrYzVNMWd5VW5Cak0wSm9aRWRPYjAxRVdVZERhWE5IUVZGUlFtYzNPSGRCVVUxRlMwUkZNbGx0Um1sYWJWcHBUMVJGTVUxNlozaE5WMVY0Q2s5VVRtcE5SRVUxVDFSTk5VMTZhM2hOZWxVelRYcGplVmxxU1RGWk1sVjNTbWRaUzB0M1dVSkNRVWRFZG5wQlFrSkJVVmxWU0ZacFlrZHNlbUZEUWxFS1dWZE9jbGxYWkd4SlNGSjJTVWMxZDJKWGNIcE5RelJIUTJselIwRlJVVUpuTnpoM1FWRlZSVWxIZUdoa1dFcHNZbTVTZW1GWE1YWmlhVGwzWTIwNU1ncGFWelZvWW0xT2JFeFhOWGRpVXpFd1dsaE9NRTFDTUVkRGFYTkhRVkZSUW1jM09IZEJVVmxGUkROS2JGcHVUWFpoUjFab1draE5kbUpYUm5CaWFrTkNDbWwzV1V0TGQxbENRa0ZJVjJWUlNVVkJaMUk1UWtoelFXVlJRak5CVGpBNVRVZHlSM2g0UlhsWmVHdGxTRXBzYms1M1MybFRiRFkwTTJwNWRDODBaVXNLWTI5QmRrdGxOazlCUVVGQ2FHeGhVbGhPVFVGQlFWRkVRVVZuZDFKblNXaEJUMXBaU0VNeVFYbENORTF0TlhWV05tVjBhV1ZuWTJSdlFqVjBMek5STmdwbE9IQmhhREpDU0RZd2RYSkJhVVZCZGpseWRqWlhUa2w1VUdaWWNsQXhlWHA1YTFGc1pIYzVhVVY0VTBKb0wySnlUazVxVkV4NlVDdDNXWGREWjFsSkNrdHZXa2w2YWpCRlFYZE5SRnAzUVhkYVFVbDNWQ3R1VDFWalIyMVVLMHN4WjNSVkwwVlVhVXBsZDFKVVdIUllOV0pxUm1nd1FVVkVWM3BXUm14TVVVc0theXREVFVOeUswTnRhRXBuWm05aVpEZ3pjWGRCYWtGNk9WZHdOQzlyY2tsbmVTdHhSRGR2WlVOM2JGVklOelJOVG1kWGNIa3lVVlUxVDNnelNqWXhkd3BRTWk4d1R6ZGlhRWcxWmtSaFIzUlpWVVpMV25wM1FUMEtMUzB0TFMxRlRrUWdRMFZTVkVsR1NVTkJWRVV0TFMwdExRbz0iLCJzaWciOiJUVVZWUTBsUlJFcGhhRlJ3VTI1c2RqWkllbFZxTW5reEwxQkNXVXhHZVRob2FFb3JOV1ZCUWxrM2RYazRVbEJ6UjFGSlowcFdkVXd6UjNJNWVXSXlWRkJWUlUxek5rbGxhVFZJVUVoaWVVZHNObWw0WjJRME1YbDJlVEEzVWxFOSJ9XX0sImhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiIyYzVhZjNiZThjNzcxYzAwYzVhZGYwNDAxMzQ5YTg1NjM5NjA3Nzg4MzQwNjRhMmYyOTk5YzY4YmZiMWI0Njg4In0sInBheWxvYWRIYXNoIjp7ImFsZ29yaXRobSI6InNoYTI1NiIsInZhbHVlIjoiNjg5ZTE2NmNlM2I1Zjk5MTgxZDExYjcyYjg2OTJkODEwYjJlM2NkMTdmZWNiZjBiNzRmNDBmYTRmNmUzNjNkNSJ9fX19"
}
],
"timestampVerificationData": null
},
"dsseEnvelope": {
"payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInN1YmplY3QiOlt7Im5hbWUiOiJwa2c6bnBtLyU0MGxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0QDEuMC4wIiwiZGlnZXN0Ijp7InNoYTUxMiI6IjI5ZDE5ZjI2MjMzZjQ0NDEzMjg0MTJiMzRmZDczZWQxMDRlY2ZlZjYyZjE0MDk3ODkwY2NjZjc0NTViNTIxYjY1YzVhY2ZmODUxODQ5ZmFhODVjODUzOTVhYTIyZDQwMTQzNmYwMWYzYWZiNjFiMTljNzgwZTkwNmM4OGM3ZjIwIn19XSwicHJlZGljYXRlVHlwZSI6Imh0dHBzOi8vc2xzYS5kZXYvcHJvdmVuYW5jZS92MC4yIiwicHJlZGljYXRlIjp7ImJ1aWxkVHlwZSI6Imh0dHBzOi8vZ2l0aHViLmNvbS9ucG0vY2xpL2doYUB2MSIsImJ1aWxkZXIiOnsiaWQiOiJodHRwczovL2dpdGh1Yi5jb20vbnBtL2NsaUA5LjUuMCJ9LCJpbnZvY2F0aW9uIjp7ImNvbmZpZ1NvdXJjZSI6eyJ1cmkiOiJnaXQraHR0cHM6Ly9naXRodWIuY29tL2xhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0QHJlZnMvaGVhZHMvbWFpbiIsImRpZ2VzdCI6eyJzaGExIjoiMTZiYWJmZmI5MTUzODExZTE5M2MwMTk5MzkzOTEzNTczNzJiMjVjZSJ9LCJlbnRyeVBvaW50IjoibGF1cmVudHNpbW9uL3Byb3ZlbmFuY2UtbnBtLXRlc3QvLmdpdGh1Yi93b3JrZmxvd3MvcmVsZWFzZS55bWxAcmVmcy9oZWFkcy9tYWluIn0sInBhcmFtZXRlcnMiOnt9LCJlbnZpcm9ubWVudCI6eyJHSVRIVUJfQUNUT1JfSUQiOiI2NDUwNTA5OSIsIkdJVEhVQl9FVkVOVF9OQU1FIjoid29ya2Zsb3dfZGlzcGF0Y2giLCJHSVRIVUJfUkVGIjoicmVmcy9oZWFkcy9tYWluIiwiR0lUSFVCX1JFRl9UWVBFIjoiYnJhbmNoIiwiR0lUSFVCX1JFUE9TSVRPUlkiOiJsYXVyZW50c2ltb24vcHJvdmVuYW5jZS1ucG0tdGVzdCIsIkdJVEhVQl9SRVBPU0lUT1JZX0lEIjoiNjAyMjIzOTQ1IiwiR0lUSFVCX1JFUE9TSVRPUllfT1dORVJfSUQiOiI2NDUwNTA5OSIsIkdJVEhVQl9SVU5fQVRURU1QVCI6IjEiLCJHSVRIVUJfUlVOX0lEIjoiNDE4NzQ2NDU3NyIsIkdJVEhVQl9SVU5fTlVNQkVSIjoiMiIsIkdJVEhVQl9TSEEiOiIxNmJhYmZmYjkxNTM4MTFlMTkzYzAxOTkzOTM5MTM1NzM3MmIyNWNlIiwiR0lUSFVCX1dPUktGTE9XX1JFRiI6ImxhdXJlbnRzaW1vbi9wcm92ZW5hbmNlLW5wbS10ZXN0Ly5naXRodWIvd29ya2Zsb3dzL3JlbGVhc2UueW1sQHJlZnMvaGVhZHMvbWFpbiIsIkdJVEhVQl9XT1JLRkxPV19TSEEiOiIxNmJhYmZmYjkxNTM4MTFlMTkzYzAxOTkzOTM5MTM1NzM3MmIyNWNlIn19LCJtZXRhZGF0YSI6eyJidWlsZEludm9jYXRpb25JZCI6IjQxODc0NjQ1NzctMSIsImNvbXBsZXRlbmVzcyI6eyJwYXJhbWV0ZXJzIjpmYWxzZSwiZW52aXJvbm1lbnQiOmZhbHNlLCJtYXRlcmlhbHMiOmZhbHNlfSwicmVwcm9kdWNpYmxlIjpmYWxzZX0sIm1hdGVyaWFscyI6W3sidXJpIjoiZ2l0K2h0dHBzOi8vZ2l0aHViLmNvbS9sYXVyZW50c2ltb24vcHJvdmVuYW5jZS1ucG0tdGVzdCIsImRpZ2VzdCI6eyJzaGExIjoiMTZiYWJmZmI5MTUzODExZTE5M2MwMTk5MzkzOTEzNTczNzJiMjVjZSJ9fV19fQ==",
"payloadType": "application/vnd.in-toto+json",
"signatures": [
{
"sig": "MEUCIQDJahTpSnlv6HzUj2y1/PBYLFy8hhJ+5eABY7uy8RPsGQIgJVuL3Gr9yb2TPUEMs6Iei5HPHbyGl6ixgd41yvy07RQ=",
"keyid": ""
}
]
}
}
},
{
"predicateType": "https://github.com/npm/attestation/tree/main/specs/publish/v0.1",
"bundle": {
"mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1",
"verificationMaterial": {
"publicKey": {
"hint": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"
},
"tlogEntries": [
{
"logIndex": "13420289",
"logId": {
"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
},
"kindVersion": {
"kind": "intoto",
"version": "0.0.2"
},
"integratedTime": "1676489615",
"inclusionPromise": {
"signedEntryTimestamp": "MEUCICYgQbiFj7t0A9B/p4Hkq5H0gB41InPBFFnhEeuP4Fo0AiEA7fGqVACs5cFpoQGHX8HVDq/jKBWbS0gutPXpcOz6r6g="
},
"inclusionProof": null,
"canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiU0hBMjU2OmpsM2J3c3d1ODBQampva0NnaDBvMnc1YzJVNExoUUFFNTdnajljejFrekEiLCJwdWJsaWNLZXkiOiJMUzB0TFMxQ1JVZEpUaUJRVlVKTVNVTWdTMFZaTFMwdExTMEtUVVpyZDBWM1dVaExiMXBKZW1vd1EwRlJXVWxMYjFwSmVtb3dSRUZSWTBSUlowRkZNVTlzWWpONlRVRkdSbmhZUzBocFNXdFJUelZqU2pOWmFHdzFhVFpWVUhBclNXaDFkR1ZDU21KMVNHTkJOVlZ2WjB0dk1FVlhkR3hYZDFjMlMxTmhTMjlVVGtWWlREZEtiRU5SYVZadWEyaENhM1JWWjJjOVBRb3RMUzB0TFVWT1JDQlFWVUpNU1VNZ1MwVlpMUzB0TFMwPSIsInNpZyI6IlRVVlJRMGxETURGaFJqbFFZVWxtSzNOcVkzRlBiVzQwUVZaVU56bFBWMFJuVkZGVk5XVXZiVkp0TVcweVNIWjVRV2xCY0hCNk1FWkxWVzFEVjJwdVUyUnJORzB5VkdGTlpXMXFSRXRqUlcxTVdFSTRWVVpFTlZsYWRETTJaejA5In1dfSwiaGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjkxNDU3YjdiYzg1NTgwY2Y2NTAxNDM5NDU5ZDYyOWI0YzBlOTUxNmFjNzc3NTllNGQwNzMwZjVlMTUxNjRkMDcifSwicGF5bG9hZEhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI1ZmFmZTQwMmJiYzBiMTNhMmFmMmIzMjhjYmNjNmFiZTlmZTA1MGRkNDUzNjNkNTE1YWIyYzk4MjA3NDMwNjVkIn19fX0="
}
],
"timestampVerificationData": null
},
"dsseEnvelope": {
"payload": "ewogICJfdHlwZSI6ICJodHRwczovL2luLXRvdG8uaW8vU3RhdGVtZW50L3YwLjEiLAogICJwcmVkaWNhdGVUeXBlIjogImh0dHBzOi8vZ2l0aHViLmNvbS9ucG0vYXR0ZXN0YXRpb24vdHJlZS9tYWluL3NwZWNzL3B1Ymxpc2gvdjAuMSIsCiAgInByZWRpY2F0ZSI6IHsKICAgICJuYW1lIjogIkBsYXVyZW50c2ltb24vcHJvdmVuYW5jZS1ucG0tdGVzdCIsCiAgICAidmVyc2lvbiI6ICIxLjAuMCIsCiAgICAicmVnaXN0cnkiOiAiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmciCiAgfQp9Cg==",
"payloadType": "application/vnd.in-toto+json",
"signatures": [
{
"sig": "MEQCIC01aF9PaIf+sjcqOmn4AVT79OWDgTQU5e/mRm1m2HvyAiAppz0FKUmCWjnSdk4m2TaMemjDKcEmLXB8UFD5YZt36g==",
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"
}
]
}
}
}
]
}

View File

@@ -131,7 +131,7 @@ func verifyNpmEnvAndCert(env *dsse.Envelope,
// Users must always provide the builder ID.
if builderOpts == nil || builderOpts.ExpectedID == nil {
return nil, fmt.Errorf("builder ID is empty")
return nil, fmt.Errorf("%w: no expected builder ID", serrors.ErrorInvalidBuilderID)
}
// WARNING: builderID may be empty if it's not a trusted reusable builder workflow.
@@ -325,12 +325,7 @@ func (v *GHAVerifier) VerifyNpmPackage(ctx context.Context,
return nil, nil, err
}
// Verify publish attesttation signature.
if err := npm.verifyPublishAttesttationSignature(); err != nil {
return nil, nil, err
}
// Verify builder information.
// Verify provenance builder information.
builder, err := npm.verifyBuilderID(
provenanceOpts, builderOpts,
defaultBYOBReusableWorkflows)
@@ -338,6 +333,16 @@ func (v *GHAVerifier) VerifyNpmPackage(ctx context.Context,
return nil, nil, err
}
// Verify publish attesttation signature.
if err := npm.verifyPublishAttestationSignature(); err != nil {
return nil, nil, err
}
// Verify publish subject digest.
if err := npm.verifySubjectDigest(provenanceOpts.ExpectedDigest); err != nil {
return nil, nil, err
}
// Verify attestation headers.
if err := npm.verifyIntotoHeaders(); err != nil {
return nil, nil, err

View File

@@ -1,24 +1,71 @@
package utils
import (
"context"
"crypto"
"crypto/ecdsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"fmt"
"math/big"
intoto "github.com/in-toto/in-toto-golang/in_toto"
dsselib "github.com/secure-systems-lab/go-securesystemslib/dsse"
serrors "github.com/slsa-framework/slsa-verifier/v2/errors"
)
func EnvelopeFromBytes(payload []byte) (*dsselib.Envelope, error) {
var env dsselib.Envelope
err := json.Unmarshal(payload, &env)
if err != nil {
return nil, fmt.Errorf("%w: %w", serrors.ErrorInvalidDssePayload, err)
}
if env.PayloadType != intoto.PayloadType {
return nil, fmt.Errorf("%w: expected payload type %q, got %q",
serrors.ErrorInvalidDssePayload, intoto.PayloadType, env.PayloadType)
}
return &env, nil
}
func PayloadFromEnvelope(env *dsselib.Envelope) ([]byte, error) {
payload, err := base64.StdEncoding.DecodeString(env.Payload)
if err != nil {
return nil, fmt.Errorf("%w: %s", serrors.ErrorInvalidDssePayload, err.Error())
}
if payload == nil {
if len(payload) == 0 {
return nil, fmt.Errorf("%w: empty payload", serrors.ErrorInvalidFormat)
}
return payload, nil
}
func StatementFromBytes(payload []byte) (*intoto.Statement, error) {
var statement intoto.Statement
if err := json.Unmarshal(payload, &statement); err != nil {
return nil, fmt.Errorf("%w: %w", serrors.ErrorInvalidDssePayload, err)
}
if statement.Type != intoto.StatementInTotoV01 {
return nil, fmt.Errorf("%w: invalid statement type: %q", serrors.ErrorInvalidDssePayload, statement.Type)
}
return &statement, nil
}
func StatementFromEnvelope(env *dsselib.Envelope) (*intoto.Statement, error) {
payload, err := PayloadFromEnvelope(env)
if err != nil {
return nil, err
}
statement, err := StatementFromBytes(payload)
if err != nil {
return nil, err
}
return statement, nil
}
func DecodeSignature(s string) ([]byte, error) {
var errs []error
// First try the std decoding.
@@ -43,3 +90,110 @@ func DecodeSignature(s string) ([]byte, error) {
return nil, fmt.Errorf("%w: %v", serrors.ErrorInvalidEncoding, errs)
}
type SignatureEncoding int
const (
// The DER signature is encoded using ASN.1
// (https://tools.ietf.org/html/rfc5480#appendix-A):
// ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }. In particular, the
// encoding is:
// 0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s.
SignatureEncodingDER SignatureEncoding = iota
// The IEEE_P1363 signature's format is r || s, where r and s are zero-padded
// and have the same size in bytes as the order of the curve. For example, for
// NIST P-256 curve, r and s are zero-padded to 32 bytes.
SignatureEncodingIEEEP1363
)
type publicKey struct {
keyID string
pubKey *crypto.PublicKey
sigEncoding SignatureEncoding // Default is SignatureEncodingDER.
}
func (p *publicKey) Verify(ctx context.Context, data, sig []byte) error {
digest := sha256.Sum256(data)
if p.pubKey == nil {
return fmt.Errorf("%w: key is empty", serrors.ErrorInternal)
}
switch v := (*p.pubKey).(type) {
default:
return fmt.Errorf("unknown key type: %T", v)
case *ecdsa.PublicKey:
switch p.sigEncoding {
case SignatureEncodingDER:
if !ecdsa.VerifyASN1(v, digest[:], sig) {
return fmt.Errorf("%w: cannot verify signature",
serrors.ErrorInvalidSignature)
}
case SignatureEncodingIEEEP1363:
r := new(big.Int)
r.SetBytes(sig[:32])
s := new(big.Int)
s.SetBytes(sig[32:])
if !ecdsa.Verify(v, digest[:], r, s) {
return fmt.Errorf("%w: cannot verify signature",
serrors.ErrorInvalidSignature)
}
default:
return fmt.Errorf("unsupported encoding: %v", p.sigEncoding)
}
}
return nil
}
// KeyID implements dsse.Verifier.KeyID.
func (p *publicKey) KeyID() (string, error) {
return p.keyID, nil
}
// Public implements dsse.Verifier.Public.
func (p *publicKey) Public() crypto.PublicKey {
return p.pubKey
}
type KeyFormat int
const (
KeyFormatDER KeyFormat = iota
KeyFormatPEM
)
func DsseVerifierNew(content []byte, format KeyFormat, keyID string, sigEncoding *SignatureEncoding) (*dsselib.EnvelopeVerifier, error) {
if format == KeyFormatPEM {
block, rest := pem.Decode(content)
if rest != nil {
return nil, fmt.Errorf("%w: additional data found", serrors.ErrorInvalidPEM)
}
if block == nil {
return nil, fmt.Errorf("%w: unable to decode PEM format", serrors.ErrorInvalidPEM)
}
content = block.Bytes
}
key, err := x509.ParsePKIXPublicKey(content)
if err != nil {
return nil, fmt.Errorf("%w: %w", serrors.ErrorInvalidPublicKey, err)
}
pubKey, ok := key.(crypto.PublicKey)
if !ok {
return nil, fmt.Errorf("%w: not a public key", serrors.ErrorInvalidPublicKey)
}
dssePubKey := publicKey{
pubKey: &pubKey,
keyID: keyID,
}
if sigEncoding != nil {
dssePubKey.sigEncoding = *sigEncoding
}
verifier, err := dsselib.NewEnvelopeVerifier(&dssePubKey)
if err != nil {
return nil, fmt.Errorf("creating verifier: %w", err)
}
return verifier, nil
}