feat: add policy, oci, attestation
This commit is contained in:
27
internal/oci/http.go
Normal file
27
internal/oci/http.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package oci
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/hashicorp/go-cleanhttp"
|
||||
)
|
||||
|
||||
type userAgentTransporter struct {
|
||||
ua string
|
||||
rt http.RoundTripper
|
||||
}
|
||||
|
||||
type Option = func(*http.Client)
|
||||
|
||||
func (u *userAgentTransporter) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
req.Header.Set("User-Agent", u.ua)
|
||||
|
||||
return u.rt.RoundTrip(req)
|
||||
}
|
||||
|
||||
func HttpTransport() http.RoundTripper {
|
||||
return &userAgentTransporter{
|
||||
ua: "Docker-Client",
|
||||
rt: cleanhttp.DefaultTransport(),
|
||||
}
|
||||
}
|
||||
395
internal/oci/oci.go
Normal file
395
internal/oci/oci.go
Normal file
@@ -0,0 +1,395 @@
|
||||
package oci
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/distribution/reference"
|
||||
att "github.com/docker/attest/pkg/attestation"
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/layout"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/package-url/packageurl-go"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// parsePlatform parses the provided platform string or attempts to obtain
|
||||
// the platform of the current host system
|
||||
func parsePlatform(platformStr string) (*v1.Platform, error) {
|
||||
if platformStr == "" {
|
||||
cdp := platforms.Normalize(platforms.DefaultSpec())
|
||||
if cdp.OS != "windows" {
|
||||
cdp.OS = "linux"
|
||||
}
|
||||
return &v1.Platform{
|
||||
OS: cdp.OS,
|
||||
Architecture: cdp.Architecture,
|
||||
Variant: cdp.Variant,
|
||||
}, nil
|
||||
} else {
|
||||
return v1.ParsePlatform(platformStr)
|
||||
}
|
||||
}
|
||||
|
||||
func attestationManifestFromOCILayout(path string, platformStr string) (*AttestationManifest, error) {
|
||||
idx, err := layout.ImageIndexFromPath(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load image index: %w", err)
|
||||
}
|
||||
|
||||
idxm, err := idx.IndexManifest()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get digest: %w", err)
|
||||
}
|
||||
|
||||
idxDescriptor := idxm.Manifests[0]
|
||||
name := idxDescriptor.Annotations["org.opencontainers.image.ref.name"]
|
||||
idxDigest := idxDescriptor.Digest
|
||||
|
||||
mfs, err := idx.ImageIndex(idxDigest)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to extract ImageIndex for digest %s: %w", idxDigest.String(), err)
|
||||
}
|
||||
mfs2, err := mfs.IndexManifest()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to extract IndexManifest from ImageIndex: %w", err)
|
||||
}
|
||||
platform, err := parsePlatform(platformStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse platform: %w", err)
|
||||
}
|
||||
var imageDigest string
|
||||
for _, mf := range mfs2.Manifests {
|
||||
if mf.Platform.Equals(*platform) {
|
||||
imageDigest = mf.Digest.String()
|
||||
}
|
||||
}
|
||||
for _, mf := range mfs2.Manifests {
|
||||
if mf.Annotations[DockerReferenceType] != AttestationManifestType {
|
||||
continue
|
||||
}
|
||||
|
||||
if mf.Annotations[DockerReferenceDigest] != imageDigest {
|
||||
continue
|
||||
}
|
||||
|
||||
attestationImage, err := mfs.Image(mf.Digest)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to extract attestation image with digest %s: %w", mf.Digest.String(), err)
|
||||
}
|
||||
manifest, err := attestationImage.Manifest()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get manifest: %w", err)
|
||||
}
|
||||
attest := &AttestationManifest{
|
||||
Name: name,
|
||||
Image: attestationImage,
|
||||
Manifest: manifest,
|
||||
Descriptor: &mf,
|
||||
Digest: imageDigest,
|
||||
Platform: platform,
|
||||
}
|
||||
return attest, nil
|
||||
}
|
||||
return nil, errors.New("attestation manifest not found")
|
||||
|
||||
}
|
||||
|
||||
// implementation of AttestationResolver that closes over attestations from an oci layout
|
||||
type OCILayoutResolver struct {
|
||||
Path string
|
||||
Platform string
|
||||
*AttestationManifest
|
||||
}
|
||||
|
||||
func (r *OCILayoutResolver) ImagePlatformStr() string {
|
||||
return r.Platform
|
||||
}
|
||||
func (r *OCILayoutResolver) fetchAttestationManifest() (*AttestationManifest, error) {
|
||||
if r.AttestationManifest == nil {
|
||||
m, err := attestationManifestFromOCILayout(r.Path, r.Platform)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get attestation manifest: %w", err)
|
||||
}
|
||||
r.AttestationManifest = m
|
||||
}
|
||||
return r.AttestationManifest, nil
|
||||
}
|
||||
|
||||
func (r *OCILayoutResolver) Attestations(ctx context.Context, predicateType string) ([]*att.Envelope, error) {
|
||||
if r.AttestationManifest == nil {
|
||||
_, err := r.fetchAttestationManifest()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get attestation manifest: %w", err)
|
||||
}
|
||||
}
|
||||
attestationImage := r.AttestationManifest.Image
|
||||
layers, err := attestationImage.Layers()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to extract layers from attestation image: %w", err)
|
||||
}
|
||||
var envs []*att.Envelope
|
||||
manifest := r.AttestationManifest.Manifest
|
||||
for i, l := range manifest.Layers {
|
||||
if l.Annotations[InTotoPredicateType] != predicateType {
|
||||
continue
|
||||
}
|
||||
layer := layers[i]
|
||||
mt, err := layer.MediaType()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get layer media type: %w", err)
|
||||
}
|
||||
mts := string(mt)
|
||||
if !strings.HasSuffix(mts, "+dsse") {
|
||||
continue
|
||||
}
|
||||
var env = new(att.Envelope)
|
||||
// parse layer blob as json
|
||||
r, err := layer.Uncompressed()
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get layer contents: %w", err)
|
||||
}
|
||||
defer r.Close()
|
||||
err = json.NewDecoder(r).Decode(env)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode envelope: %w", err)
|
||||
}
|
||||
envs = append(envs, env)
|
||||
}
|
||||
return envs, nil
|
||||
}
|
||||
|
||||
func (r *OCILayoutResolver) ImageName(ctx context.Context) (string, error) {
|
||||
if r.AttestationManifest == nil {
|
||||
_, err := r.fetchAttestationManifest()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get attestation manifest: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return r.Name, nil
|
||||
}
|
||||
|
||||
func (r *OCILayoutResolver) ImageDigest(ctx context.Context) (string, error) {
|
||||
if r.AttestationManifest == nil {
|
||||
_, err := r.fetchAttestationManifest()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get attestation manifest: %w", err)
|
||||
}
|
||||
}
|
||||
return r.Digest, nil
|
||||
}
|
||||
|
||||
type RegistryResolver struct {
|
||||
Image string
|
||||
Platform string
|
||||
*AttestationManifest
|
||||
}
|
||||
|
||||
func (r *RegistryResolver) ImageName(ctx context.Context) (string, error) {
|
||||
return r.Image, nil
|
||||
}
|
||||
|
||||
func (r *RegistryResolver) ImagePlatformStr() string {
|
||||
return r.Platform
|
||||
}
|
||||
|
||||
func (r *RegistryResolver) ImageDigest(ctx context.Context) (string, error) {
|
||||
if r.AttestationManifest == nil {
|
||||
attest, err := FetchAttestationManifest(ctx, r.Image, r.Platform)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get attestation manifest: %w", err)
|
||||
}
|
||||
r.AttestationManifest = attest
|
||||
}
|
||||
return r.Digest, nil
|
||||
}
|
||||
|
||||
func (r *RegistryResolver) Attestations(ctx context.Context, predicateType string) ([]*att.Envelope, error) {
|
||||
if r.AttestationManifest == nil {
|
||||
attest, err := FetchAttestationManifest(ctx, r.Image, r.Platform)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get attestation manifest: %w", err)
|
||||
}
|
||||
r.AttestationManifest = attest
|
||||
}
|
||||
return ExtractEnvelopes(r.AttestationManifest, predicateType)
|
||||
}
|
||||
|
||||
func FetchAttestationManifest(ctx context.Context, image, platformStr string) (*AttestationManifest, error) {
|
||||
platform, err := parsePlatform(platformStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse platform %s: %w", platform, err)
|
||||
}
|
||||
|
||||
// we want to get to the image index, so ignoring platform for now
|
||||
options := withOptions(ctx, nil)
|
||||
ref, err := name.ParseReference(image)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse reference: %w", err)
|
||||
}
|
||||
|
||||
desc, err := remote.Index(ref, options...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to obtain index manifest: %w", err)
|
||||
}
|
||||
ix, err := desc.IndexManifest()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to obtain index manifest: %w", err)
|
||||
}
|
||||
digest, err := imageDigestForPlatform(ix, platform)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to obtain image for platform: %w", err)
|
||||
}
|
||||
ref, err = name.ParseReference(fmt.Sprintf("%s@%s", ref.Context().Name(), digest))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse attestation reference: %w", err)
|
||||
}
|
||||
|
||||
attestationDigest, err := attestationDigestForDigest(ix, digest, "attestation-manifest")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to obtain attestation for image: %w", err)
|
||||
}
|
||||
ref, err = name.ParseReference(fmt.Sprintf("%s@%s", ref.Context().Name(), attestationDigest))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse attestation reference: %w", err)
|
||||
}
|
||||
remoteDescriptor, err := remote.Get(ref, options...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get attestation: %w", err)
|
||||
}
|
||||
manifest := new(v1.Manifest)
|
||||
err = json.Unmarshal(remoteDescriptor.Manifest, manifest)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal attestation: %w", err)
|
||||
}
|
||||
attestationImage, err := remoteDescriptor.Image()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get attestation image: %w", err)
|
||||
}
|
||||
attest := &AttestationManifest{
|
||||
Name: image,
|
||||
Image: attestationImage,
|
||||
Manifest: manifest,
|
||||
Descriptor: &remoteDescriptor.Descriptor,
|
||||
Digest: digest,
|
||||
Platform: platform,
|
||||
}
|
||||
return attest, nil
|
||||
}
|
||||
|
||||
func withOptions(ctx context.Context, platform *v1.Platform) []remote.Option {
|
||||
// prepare options
|
||||
options := []remote.Option{remote.WithAuthFromKeychain(authn.DefaultKeychain), remote.WithTransport(HttpTransport()), remote.WithContext(ctx)}
|
||||
|
||||
// add in platform into remote Get operation; this might conflict with an explicit digest, but we are trying anyway
|
||||
if platform != nil {
|
||||
options = append(options, remote.WithPlatform(*platform))
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
func ExtractEnvelopes(ia *AttestationManifest, predicateType string) ([]*att.Envelope, error) {
|
||||
manifest := ia.Manifest
|
||||
im := ia.Image
|
||||
|
||||
var envs []*att.Envelope
|
||||
|
||||
ls, err := im.Layers()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get layers: %w", err)
|
||||
}
|
||||
for i, l := range manifest.Layers {
|
||||
if (strings.HasPrefix(string(l.MediaType), "application/vnd.in-toto.")) &&
|
||||
strings.HasSuffix(string(l.MediaType), "+dsse") &&
|
||||
l.Annotations[InTotoPredicateType] == predicateType {
|
||||
reader, err := ls[i].Uncompressed()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get layer contents: %w", err)
|
||||
}
|
||||
defer reader.Close()
|
||||
var env = new(att.Envelope)
|
||||
err = json.NewDecoder(reader).Decode(&env)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode envelope: %w", err)
|
||||
}
|
||||
envs = append(envs, env)
|
||||
}
|
||||
}
|
||||
|
||||
return envs, nil
|
||||
}
|
||||
|
||||
func imageDigestForPlatform(ix *v1.IndexManifest, platform *v1.Platform) (string, error) {
|
||||
for _, m := range ix.Manifests {
|
||||
if m.MediaType == ocispec.MediaTypeImageManifest || m.MediaType == "application/vnd.docker.distribution.manifest.v2+json" && m.Platform.Equals(*platform) {
|
||||
return m.Digest.String(), nil
|
||||
}
|
||||
}
|
||||
return "", errors.New(fmt.Sprintf("no image found for platform %v", platform))
|
||||
}
|
||||
|
||||
func attestationDigestForDigest(ix *v1.IndexManifest, imageDigest string, attestType string) (string, error) {
|
||||
for _, m := range ix.Manifests {
|
||||
if v, ok := m.Annotations["vnd.docker.reference.type"]; ok && v == attestType {
|
||||
if d, ok := m.Annotations["vnd.docker.reference.digest"]; ok && d == imageDigest {
|
||||
return m.Digest.String(), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", errors.New(fmt.Sprintf("no attestation found for image %s", imageDigest))
|
||||
}
|
||||
|
||||
func RefToPURL(ref string, platform string) (string, bool, error) {
|
||||
var isCanonical bool
|
||||
named, err := reference.ParseNormalizedNamed(ref)
|
||||
if err != nil {
|
||||
return "", false, fmt.Errorf("failed to parse ref %q: %w", ref, err)
|
||||
}
|
||||
var qualifiers []packageurl.Qualifier
|
||||
|
||||
if canonical, ok := named.(reference.Canonical); ok {
|
||||
qualifiers = append(qualifiers, packageurl.Qualifier{
|
||||
Key: "digest",
|
||||
Value: canonical.Digest().String(),
|
||||
})
|
||||
isCanonical = true
|
||||
} else {
|
||||
named = reference.TagNameOnly(named)
|
||||
}
|
||||
|
||||
version := ""
|
||||
if tagged, ok := named.(reference.Tagged); ok {
|
||||
version = tagged.Tag()
|
||||
}
|
||||
|
||||
name := reference.FamiliarName(named)
|
||||
|
||||
ns := ""
|
||||
parts := strings.Split(name, "/")
|
||||
if len(parts) > 1 {
|
||||
ns = strings.Join(parts[:len(parts)-1], "/")
|
||||
}
|
||||
name = parts[len(parts)-1]
|
||||
|
||||
pf, err := parsePlatform(platform)
|
||||
if err != nil {
|
||||
return "", false, fmt.Errorf("failed to parse platform %q: %w", platform, err)
|
||||
}
|
||||
if pf != nil {
|
||||
qualifiers = append(qualifiers, packageurl.Qualifier{
|
||||
Key: "platform",
|
||||
Value: pf.String(),
|
||||
})
|
||||
}
|
||||
|
||||
p := packageurl.NewPackageURL("docker", ns, name, version, qualifiers, "")
|
||||
return p.ToString(), isCanonical, nil
|
||||
}
|
||||
49
internal/oci/oci_test.go
Normal file
49
internal/oci/oci_test.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package oci
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRefToPurl(t *testing.T) {
|
||||
purl, canonical, err := RefToPURL("alpine", "arm64/linux")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "pkg:docker/alpine@latest?platform=arm64%2Flinux", purl)
|
||||
assert.False(t, canonical)
|
||||
|
||||
purl, canonical, err = RefToPURL("alpine:123", "arm64/linux")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "pkg:docker/alpine@123?platform=arm64%2Flinux", purl)
|
||||
assert.False(t, canonical)
|
||||
|
||||
purl, canonical, err = RefToPURL("google/alpine:123", "arm64/linux")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "pkg:docker/google/alpine@123?platform=arm64%2Flinux", purl)
|
||||
assert.False(t, canonical)
|
||||
|
||||
purl, canonical, err = RefToPURL("library/alpine:123", "arm64/linux")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "pkg:docker/alpine@123?platform=arm64%2Flinux", purl)
|
||||
assert.False(t, canonical)
|
||||
|
||||
purl, canonical, err = RefToPURL("docker.io/library/alpine:123", "arm64/linux")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "pkg:docker/alpine@123?platform=arm64%2Flinux", purl)
|
||||
assert.False(t, canonical)
|
||||
|
||||
purl, canonical, err = RefToPURL("localhost:5001/library/alpine:123", "arm64/linux")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "pkg:docker/localhost%3A5001/library/alpine@123?platform=arm64%2Flinux", purl)
|
||||
assert.False(t, canonical)
|
||||
|
||||
purl, canonical, err = RefToPURL("localhost:5001/alpine:123", "arm64/linux")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "pkg:docker/localhost%3A5001/alpine@123?platform=arm64%2Flinux", purl)
|
||||
assert.False(t, canonical)
|
||||
|
||||
purl, canonical, err = RefToPURL("localhost:5001/alpine@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b", "arm64/linux")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "pkg:docker/localhost%3A5001/alpine?digest=sha256%3Ac5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b&platform=arm64%2Flinux", purl)
|
||||
assert.True(t, canonical)
|
||||
}
|
||||
46
internal/oci/resolver.go
Normal file
46
internal/oci/resolver.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package oci
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
att "github.com/docker/attest/pkg/attestation"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
)
|
||||
|
||||
type AttestationManifest struct {
|
||||
// attestation image details
|
||||
Image v1.Image
|
||||
Manifest *v1.Manifest
|
||||
Descriptor *v1.Descriptor
|
||||
// details of subect image
|
||||
Name string
|
||||
Digest string
|
||||
Platform *v1.Platform
|
||||
}
|
||||
|
||||
type AttestationResolver interface {
|
||||
ImageName(ctx context.Context) (string, error)
|
||||
ImagePlatformStr() string
|
||||
ImageDigest(ctx context.Context) (string, error)
|
||||
Attestations(ctx context.Context, mediaType string) ([]*att.Envelope, error)
|
||||
}
|
||||
|
||||
type MockResolver struct {
|
||||
Envs []*att.Envelope
|
||||
}
|
||||
|
||||
func (r MockResolver) Attestations(ctx context.Context, mediaType string) ([]*att.Envelope, error) {
|
||||
return r.Envs, nil
|
||||
}
|
||||
|
||||
func (r MockResolver) ImageName(ctx context.Context) (string, error) {
|
||||
return "library/alpine:latest", nil
|
||||
}
|
||||
|
||||
func (r MockResolver) ImageDigest(ctx context.Context) (string, error) {
|
||||
return "sha256:test-digest", nil
|
||||
}
|
||||
|
||||
func (r MockResolver) ImagePlatformStr() string {
|
||||
return "linux/amd64"
|
||||
}
|
||||
8
internal/oci/types.go
Normal file
8
internal/oci/types.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package oci
|
||||
|
||||
const (
|
||||
DockerReferenceType = "vnd.docker.reference.type"
|
||||
DockerReferenceDigest = "vnd.docker.reference.digest"
|
||||
AttestationManifestType = "attestation-manifest"
|
||||
InTotoPredicateType = "in-toto.io/predicate-type"
|
||||
)
|
||||
@@ -1,8 +1,24 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/attest/internal/oci"
|
||||
"github.com/docker/attest/pkg/policy"
|
||||
"github.com/docker/attest/pkg/signerverifier"
|
||||
"github.com/docker/attest/pkg/tlog"
|
||||
"github.com/secure-systems-lab/go-securesystemslib/dsse"
|
||||
)
|
||||
|
||||
const (
|
||||
USE_MOCK_TL = true
|
||||
USE_MOCK_KMS = true
|
||||
USE_MOCK_POLICY = true
|
||||
|
||||
AwsRegion = "us-east-1"
|
||||
AwsKmsKeyArn = "arn:aws:kms:us-east-1:175142243308:alias/doi-signing" // sandbox
|
||||
)
|
||||
|
||||
func CreateTempDir(t *testing.T, dir, pattern string) string {
|
||||
@@ -20,3 +36,51 @@ func CreateTempDir(t *testing.T, dir, pattern string) string {
|
||||
})
|
||||
return tempDir
|
||||
}
|
||||
|
||||
func Setup(t *testing.T) (context.Context, dsse.SignerVerifier) {
|
||||
var tl tlog.TL
|
||||
if USE_MOCK_TL {
|
||||
tl = tlog.GetMockTL()
|
||||
} else {
|
||||
tl = &tlog.RekorTL{}
|
||||
}
|
||||
|
||||
ctx := tlog.WithTL(context.Background(), tl)
|
||||
|
||||
var policyEvaluator policy.PolicyEvaluator
|
||||
if USE_MOCK_POLICY {
|
||||
policyEvaluator = GetMockPolicy()
|
||||
} else {
|
||||
policyEvaluator = policy.NewRegoEvaluator(true)
|
||||
}
|
||||
|
||||
ctx = policy.WithPolicyEvaluator(ctx, policyEvaluator)
|
||||
|
||||
var signer dsse.SignerVerifier
|
||||
var err error
|
||||
if USE_MOCK_KMS {
|
||||
signer, err = GetMockSigner(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
signer, err = signerverifier.GetAWSSigner(ctx, AwsKmsKeyArn, AwsRegion)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
return ctx, signer
|
||||
}
|
||||
|
||||
func GetMockSigner(ctx context.Context) (dsse.SignerVerifier, error) {
|
||||
return signerverifier.GenKeyPair()
|
||||
}
|
||||
|
||||
func GetMockPolicy() policy.PolicyEvaluator {
|
||||
return &policy.MockPolicyEvaluator{
|
||||
EvaluateFunc: func(ctx context.Context, resolver oci.AttestationResolver, policy []*policy.PolicyFile, input *policy.PolicyInput) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
{"signatures":[{"keyid":"198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3","sig":"3044022039b56cd2e3597df74e57d200a652ba020cdc9a8cd050bd65b5f8e2640d50691d02205e073e4b6fc260acc64327a331e4440601af5b1cbff594ea91cf7b70d5828fb1"}],"signed":{"_type":"snapshot","expires":"2034-04-03T15:59:47Z","meta":{"targets.json":{"version":5},"test-role.json":{"version":3}},"spec_version":"1.0.31","version":6}}
|
||||
@@ -1 +0,0 @@
|
||||
{"signatures":[{"keyid":"198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3","sig":"3045022011f2afa9b448fcbbac983c11fc3e264e95d5d7a9c9527b09d83a316ee762635f022100d05197a78ccc7a713ebdb0bccb44844f67a7c5208af8d346e201064b7ce11055"}],"signed":{"_type":"timestamp","expires":"2034-04-03T15:59:47Z","meta":{"snapshot.json":{"version":6}},"spec_version":"1.0.31","version":6}}
|
||||
@@ -1,65 +0,0 @@
|
||||
{
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09",
|
||||
"sig": "3064023037bbb03c3472b140572a7d5a2895bd80e74435bbcb7053949731f81b104c6d05a0876590cd6a2e94d7ed619426a2f6fa02303adc8c9006fa5506fdd7ea87d2960074a537ad8bf2459f2863e806b47682cbb2f9b01b7502eaf5437a1a68fdaaeac114"
|
||||
}
|
||||
],
|
||||
"signed": {
|
||||
"_type": "root",
|
||||
"consistent_snapshot": true,
|
||||
"expires": "2034-04-02T17:00:22Z",
|
||||
"keys": {
|
||||
"198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3": {
|
||||
"keytype": "ecdsa",
|
||||
"keyval": {
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgDpP6O0sEt2R+l84WlfmqPBsFSby\nxJsJ6YmeUVgDk/wk9++8IAR6YBYewaKye56gMnIYjTFbyOI8WomA2NQFBw==\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"scheme": "ecdsa-sha2-nistp256",
|
||||
"x-tuf-on-ci-online-uri": "awskms:arn:aws:kms:us-east-1:175142243308:key/fbd8dab6-5677-4b57-87e6-8369c45b3b61"
|
||||
},
|
||||
"b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09": {
|
||||
"keytype": "ecdsa",
|
||||
"keyval": {
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3+asmp2GD6UijwWvMezwVG/BwFLuQa3o\nT6eRxFvkILGpVDbZ92ZYWidHl9LZ/eJUjhIjuVEkNVKoenw5KjKl8veP3MthZrQA\nSkYytOIwkidZo9Rk2dczbDcFSJvLGsmd\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"scheme": "ecdsa-sha2-nistp384",
|
||||
"x-tuf-on-ci-keyowner": "@mrjoelkamp"
|
||||
}
|
||||
},
|
||||
"roles": {
|
||||
"root": {
|
||||
"keyids": [
|
||||
"b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09"
|
||||
],
|
||||
"threshold": 1
|
||||
},
|
||||
"snapshot": {
|
||||
"keyids": [
|
||||
"198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3"
|
||||
],
|
||||
"threshold": 1,
|
||||
"x-tuf-on-ci-expiry-period": 3650,
|
||||
"x-tuf-on-ci-signing-period": 60
|
||||
},
|
||||
"targets": {
|
||||
"keyids": [
|
||||
"b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09"
|
||||
],
|
||||
"threshold": 1
|
||||
},
|
||||
"timestamp": {
|
||||
"keyids": [
|
||||
"198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3"
|
||||
],
|
||||
"threshold": 1,
|
||||
"x-tuf-on-ci-expiry-period": 3650,
|
||||
"x-tuf-on-ci-signing-period": 60
|
||||
}
|
||||
},
|
||||
"spec_version": "1.0.31",
|
||||
"version": 1,
|
||||
"x-tuf-on-ci-expiry-period": 3650,
|
||||
"x-tuf-on-ci-signing-period": 60
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":669,"digest":"sha256:ad4cacc170229608305ffccd8d09eeb59578fcb72ae394763cf7ef492175b1ee"},"layers":[{"mediaType":"application/vnd.tuf.metadata+json","size":2607,"digest":"sha256:a2e026ce65c198ee68a7ed2df6978ed0287bb38342f6ddb7bf934a456f1d6f87","annotations":{"tuf.io/filename":"2.root.json"}},{"mediaType":"application/vnd.tuf.metadata+json","size":2200,"digest":"sha256:61a98e1e86ae279e59415d927e38beae430d7e6d2bd6207054179429ea9b6763","annotations":{"tuf.io/filename":"1.root.json"}},{"mediaType":"application/vnd.tuf.metadata+json","size":410,"digest":"sha256:1fd0d9781f02486718fcbd7724db0e4c4ba47b649930cec22a3e7e6b6077ba38","annotations":{"tuf.io/filename":"6.snapshot.json"}},{"mediaType":"application/vnd.tuf.metadata+json","size":1683,"digest":"sha256:ea7713eb649ca1a33d79ebdccda9f7f066595b1b2c6e37e52dbfd250f5287260","annotations":{"tuf.io/filename":"5.targets.json"}},{"mediaType":"application/vnd.tuf.metadata+json","size":383,"digest":"sha256:4c1054844dba3241525cbd71ff9e58becca652fb1ce4a0e6ea55a01c4ec41950","annotations":{"tuf.io/filename":"timestamp.json"}}]}
|
||||
@@ -1 +0,0 @@
|
||||
{"signatures":[{"keyid":"b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09","sig":"3066023100e99acc5f74777ebf40376b60f0216e8fe1829c1a49a5f6a6899126c15de1df7a56533baf493b2b53159c50843a289102023100b6a006b24da62ea0b743fbe38e1497ff485bf3a0833894985fc27a0305ad0693eeb968a7b52723ed3c49af8bef2027b6"},{"keyid":"81cf5a78d6ea2cd904256b9d814b340289b765e6f75ec4397e4ebb7586cab664","sig":"30440220136debcc2f60dd1d63c9c2704f9b13c2cb2f5d2df58ea93f07f7c10f54f36742022059d7f8c6620e33506c6f1766394a32f86c9b008328f6398831ba7ebcf4ce0838"}],"signed":{"_type":"root","consistent_snapshot":true,"expires":"2034-04-03T08:45:50Z","keys":{"198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3":{"keytype":"ecdsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgDpP6O0sEt2R+l84WlfmqPBsFSby\nxJsJ6YmeUVgDk/wk9++8IAR6YBYewaKye56gMnIYjTFbyOI8WomA2NQFBw==\n-----END PUBLIC KEY-----\n"},"scheme":"ecdsa-sha2-nistp256","x-tuf-on-ci-online-uri":"awskms:arn:aws:kms:us-east-1:175142243308:key/fbd8dab6-5677-4b57-87e6-8369c45b3b61"},"81cf5a78d6ea2cd904256b9d814b340289b765e6f75ec4397e4ebb7586cab664":{"keytype":"ecdsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWmhpAfB7Q53UNluMhpkDxXXup4E0\n2Hh4PSgHC1Yh6brGl6Akq9a4io55LtZTk5mnCTqxuB+rc5cI/yaNUeWEqQ==\n-----END PUBLIC KEY-----\n"},"scheme":"ecdsa-sha2-nistp256","x-tuf-on-ci-keyowner":"@kipz"},"b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09":{"keytype":"ecdsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3+asmp2GD6UijwWvMezwVG/BwFLuQa3o\nT6eRxFvkILGpVDbZ92ZYWidHl9LZ/eJUjhIjuVEkNVKoenw5KjKl8veP3MthZrQA\nSkYytOIwkidZo9Rk2dczbDcFSJvLGsmd\n-----END PUBLIC KEY-----\n"},"scheme":"ecdsa-sha2-nistp384","x-tuf-on-ci-keyowner":"@mrjoelkamp"}},"roles":{"root":{"keyids":["b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09","81cf5a78d6ea2cd904256b9d814b340289b765e6f75ec4397e4ebb7586cab664"],"threshold":1},"snapshot":{"keyids":["198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3"],"threshold":1,"x-tuf-on-ci-expiry-period":3650,"x-tuf-on-ci-signing-period":60},"targets":{"keyids":["b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09","81cf5a78d6ea2cd904256b9d814b340289b765e6f75ec4397e4ebb7586cab664"],"threshold":1},"timestamp":{"keyids":["198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3"],"threshold":1,"x-tuf-on-ci-expiry-period":3650,"x-tuf-on-ci-signing-period":60}},"spec_version":"1.0.31","version":2,"x-tuf-on-ci-expiry-period":3650,"x-tuf-on-ci-signing-period":60}}
|
||||
@@ -1 +0,0 @@
|
||||
{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":669,"digest":"sha256:c927b30f17fa8c64e3c20b8f92b7e348733f9c1281b5b7e6b6d669a8a74230a7"},"layers":[{"mediaType":"application/vnd.tuf.metadata+json","size":2200,"digest":"sha256:61a98e1e86ae279e59415d927e38beae430d7e6d2bd6207054179429ea9b6763","annotations":{"tuf.io/filename":"1.root.json"}},{"mediaType":"application/vnd.tuf.metadata+json","size":2607,"digest":"sha256:a2e026ce65c198ee68a7ed2df6978ed0287bb38342f6ddb7bf934a456f1d6f87","annotations":{"tuf.io/filename":"2.root.json"}},{"mediaType":"application/vnd.tuf.metadata+json","size":410,"digest":"sha256:1fd0d9781f02486718fcbd7724db0e4c4ba47b649930cec22a3e7e6b6077ba38","annotations":{"tuf.io/filename":"6.snapshot.json"}},{"mediaType":"application/vnd.tuf.metadata+json","size":1683,"digest":"sha256:ea7713eb649ca1a33d79ebdccda9f7f066595b1b2c6e37e52dbfd250f5287260","annotations":{"tuf.io/filename":"5.targets.json"}},{"mediaType":"application/vnd.tuf.metadata+json","size":383,"digest":"sha256:4c1054844dba3241525cbd71ff9e58becca652fb1ce4a0e6ea55a01c4ec41950","annotations":{"tuf.io/filename":"timestamp.json"}}]}
|
||||
@@ -1 +0,0 @@
|
||||
{"architecture":"","created":"0001-01-01T00:00:00Z","history":[{"created":"0001-01-01T00:00:00Z"},{"created":"0001-01-01T00:00:00Z"},{"created":"0001-01-01T00:00:00Z"},{"created":"0001-01-01T00:00:00Z"},{"created":"0001-01-01T00:00:00Z"}],"os":"","rootfs":{"type":"layers","diff_ids":["sha256:a2e026ce65c198ee68a7ed2df6978ed0287bb38342f6ddb7bf934a456f1d6f87","sha256:61a98e1e86ae279e59415d927e38beae430d7e6d2bd6207054179429ea9b6763","sha256:1fd0d9781f02486718fcbd7724db0e4c4ba47b649930cec22a3e7e6b6077ba38","sha256:ea7713eb649ca1a33d79ebdccda9f7f066595b1b2c6e37e52dbfd250f5287260","sha256:4c1054844dba3241525cbd71ff9e58becca652fb1ce4a0e6ea55a01c4ec41950"]},"config":{}}
|
||||
@@ -1 +0,0 @@
|
||||
{"architecture":"","created":"0001-01-01T00:00:00Z","history":[{"created":"0001-01-01T00:00:00Z"},{"created":"0001-01-01T00:00:00Z"},{"created":"0001-01-01T00:00:00Z"},{"created":"0001-01-01T00:00:00Z"},{"created":"0001-01-01T00:00:00Z"}],"os":"","rootfs":{"type":"layers","diff_ids":["sha256:61a98e1e86ae279e59415d927e38beae430d7e6d2bd6207054179429ea9b6763","sha256:a2e026ce65c198ee68a7ed2df6978ed0287bb38342f6ddb7bf934a456f1d6f87","sha256:1fd0d9781f02486718fcbd7724db0e4c4ba47b649930cec22a3e7e6b6077ba38","sha256:ea7713eb649ca1a33d79ebdccda9f7f066595b1b2c6e37e52dbfd250f5287260","sha256:4c1054844dba3241525cbd71ff9e58becca652fb1ce4a0e6ea55a01c4ec41950"]},"config":{}}
|
||||
@@ -1 +0,0 @@
|
||||
{"signatures":[{"keyid":"b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09","sig":""},{"keyid":"81cf5a78d6ea2cd904256b9d814b340289b765e6f75ec4397e4ebb7586cab664","sig":"3046022100f892a496c9bd96082e3b06d5eae85429355876b8eb455aa04b53ab9051911d90022100a3e89c29b15bccfc2877278c0fb2d3b34500da6351e245ad0b3f8c0ae6b67eff"}],"signed":{"_type":"targets","delegations":{"keys":{"81cf5a78d6ea2cd904256b9d814b340289b765e6f75ec4397e4ebb7586cab664":{"keytype":"ecdsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWmhpAfB7Q53UNluMhpkDxXXup4E0\n2Hh4PSgHC1Yh6brGl6Akq9a4io55LtZTk5mnCTqxuB+rc5cI/yaNUeWEqQ==\n-----END PUBLIC KEY-----\n"},"scheme":"ecdsa-sha2-nistp256","x-tuf-on-ci-keyowner":"@kipz"},"b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09":{"keytype":"ecdsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----\nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3+asmp2GD6UijwWvMezwVG/BwFLuQa3o\nT6eRxFvkILGpVDbZ92ZYWidHl9LZ/eJUjhIjuVEkNVKoenw5KjKl8veP3MthZrQA\nSkYytOIwkidZo9Rk2dczbDcFSJvLGsmd\n-----END PUBLIC KEY-----\n"},"scheme":"ecdsa-sha2-nistp384","x-tuf-on-ci-keyowner":"@mrjoelkamp"}},"roles":[{"keyids":["b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09","81cf5a78d6ea2cd904256b9d814b340289b765e6f75ec4397e4ebb7586cab664"],"name":"test-role","paths":["test-role/*","test-role/*/*","test-role/*/*/*","test-role/*/*/*/*"],"terminating":true,"threshold":1}]},"expires":"2034-04-03T15:28:29Z","spec_version":"1.0.31","targets":{"test.txt":{"hashes":{"sha256":"02119a076ec3878c736c3a95e20794f5a8d5bce3d7ecc264681bb7334ca2e24b"},"length":31}},"version":5,"x-tuf-on-ci-expiry-period":3650,"x-tuf-on-ci-signing-period":60}}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"mediaType": "application/vnd.oci.image.index.v1+json",
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 1220,
|
||||
"digest": "sha256:a744a2f1e62ae4ce410822b5e3f5508dbaf6a76768a9d23741828172bab1dc97"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"imageLayoutVersion": "1.0.0"
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"signatures":[{"keyid":"b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09","sig":""},{"keyid":"81cf5a78d6ea2cd904256b9d814b340289b765e6f75ec4397e4ebb7586cab664","sig":"3044022015b6ebe9d30895e3be20e707a6738e38460197d90cae3dc37527ddb7c437868602207f85f3d4e068bef4c51a749f5d166cc7fe2cb9483999ea197e72395081c3aa61"}],"signed":{"_type":"targets","expires":"2034-04-03T15:39:02Z","spec_version":"1.0.31","targets":{"test-role/dir1/dir2/dir3/myfile.txt":{"hashes":{"sha256":"ea230621c53e0bb858ea5526125414f8957fb29c08350528d50a162c620f36b1"},"length":10},"test-role/test.txt":{"hashes":{"sha256":"d1bb6181284970ae43fbbc88b5e72f9a5942ebac20588aa0c4bf78ba621e1ee2"},"length":32}},"version":3,"x-tuf-on-ci-expiry-period":3650,"x-tuf-on-ci-signing-period":60}}
|
||||
@@ -1 +0,0 @@
|
||||
{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":233,"digest":"sha256:9edf24c022c2cd6796e87f49ec6a6ea2fad3e7c939c32a8219aaa4726792457c"},"layers":[{"mediaType":"application/vnd.tuf.metadata+json","size":764,"digest":"sha256:2b2d4fba192ec164e05e6d90399c5cf4a45e4fe2ddebb9066c55aa2bcf0a73d3","annotations":{"tuf.io/filename":"3.test-role.json"}}]}
|
||||
@@ -1 +0,0 @@
|
||||
{"architecture":"","created":"0001-01-01T00:00:00Z","history":[{"created":"0001-01-01T00:00:00Z"}],"os":"","rootfs":{"type":"layers","diff_ids":["sha256:2b2d4fba192ec164e05e6d90399c5cf4a45e4fe2ddebb9066c55aa2bcf0a73d3"]},"config":{}}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"mediaType": "application/vnd.oci.image.index.v1+json",
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 444,
|
||||
"digest": "sha256:7c8d8f5dfca62068e3a4b18bb41cf85dad23ec9cdc7d7d2e10bc37b86ebffff5"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"imageLayoutVersion": "1.0.0"
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
this is a top-level target file
|
||||
@@ -1 +0,0 @@
|
||||
{"architecture":"","created":"0001-01-01T00:00:00Z","history":[{"created":"0001-01-01T00:00:00Z"}],"os":"","rootfs":{"type":"layers","diff_ids":["sha256:02119a076ec3878c736c3a95e20794f5a8d5bce3d7ecc264681bb7334ca2e24b"]},"config":{}}
|
||||
@@ -1 +0,0 @@
|
||||
{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":233,"digest":"sha256:cf0c754e6415fab25e2f59fb6b010dcf0c2369f7a59a45ff29c693c844163ca7"},"layers":[{"mediaType":"application/vnd.tuf.target","size":31,"digest":"sha256:02119a076ec3878c736c3a95e20794f5a8d5bce3d7ecc264681bb7334ca2e24b","annotations":{"tuf.io/filename":"02119a076ec3878c736c3a95e20794f5a8d5bce3d7ecc264681bb7334ca2e24b.test.txt"}}]}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"mediaType": "application/vnd.oci.image.index.v1+json",
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 493,
|
||||
"digest": "sha256:cf70a3b91fd7dfaa30952dfa9f094809e6cd9bd7364942c7f067c747bc535f94"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"imageLayoutVersion": "1.0.0"
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":233,"digest":"sha256:d9941355ca037d7e878e04c1bc7cbf9c71a5d8035b6e27be0d9e5d9087599055"},"layers":[{"mediaType":"application/vnd.tuf.target","size":32,"digest":"sha256:d1bb6181284970ae43fbbc88b5e72f9a5942ebac20588aa0c4bf78ba621e1ee2","annotations":{"tuf.io/filename":"d1bb6181284970ae43fbbc88b5e72f9a5942ebac20588aa0c4bf78ba621e1ee2.test.txt"}}]}
|
||||
@@ -1 +0,0 @@
|
||||
{"architecture":"","created":"0001-01-01T00:00:00Z","history":[{"created":"0001-01-01T00:00:00Z"}],"os":"","rootfs":{"type":"layers","diff_ids":["sha256:ea230621c53e0bb858ea5526125414f8957fb29c08350528d50a162c620f36b1"]},"config":{}}
|
||||
@@ -1 +0,0 @@
|
||||
{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":233,"digest":"sha256:0b6b8fdb10421310b9aca2f1fb6ce51537baa243fb9fccca03f2ff3c15fb52f8"},"layers":[{"mediaType":"application/vnd.tuf.target","size":10,"digest":"sha256:ea230621c53e0bb858ea5526125414f8957fb29c08350528d50a162c620f36b1","annotations":{"tuf.io/filename":"ea230621c53e0bb858ea5526125414f8957fb29c08350528d50a162c620f36b1.myfile.txt"}}]}
|
||||
@@ -1 +0,0 @@
|
||||
this is a delegated targets file
|
||||
@@ -1 +0,0 @@
|
||||
{"architecture":"","created":"0001-01-01T00:00:00Z","history":[{"created":"0001-01-01T00:00:00Z"}],"os":"","rootfs":{"type":"layers","diff_ids":["sha256:d1bb6181284970ae43fbbc88b5e72f9a5942ebac20588aa0c4bf78ba621e1ee2"]},"config":{}}
|
||||
@@ -1 +0,0 @@
|
||||
hello tuf
|
||||
@@ -1 +0,0 @@
|
||||
{"schemaVersion":2,"mediaType":"application/vnd.oci.image.index.v1+json","manifests":[{"mediaType":"application/vnd.oci.image.manifest.v1+json","size":495,"digest":"sha256:8d320e9d3f3663613df6e4fca1651604a6c0323011023145a140b38f02105b04","annotations":{"tuf.io/filename":"test-role/dir1/dir2/dir3/ea230621c53e0bb858ea5526125414f8957fb29c08350528d50a162c620f36b1.myfile.txt"}},{"mediaType":"application/vnd.oci.image.manifest.v1+json","size":493,"digest":"sha256:0a4afcdad291941327b070ab4feaf052425fbf4ded864bc55c18cfefec8be6e2","annotations":{"tuf.io/filename":"test-role/d1bb6181284970ae43fbbc88b5e72f9a5942ebac20588aa0c4bf78ba621e1ee2.test.txt"}}]}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"imageLayoutVersion": "1.0.0"
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
{
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09",
|
||||
"sig": "3064023037bbb03c3472b140572a7d5a2895bd80e74435bbcb7053949731f81b104c6d05a0876590cd6a2e94d7ed619426a2f6fa02303adc8c9006fa5506fdd7ea87d2960074a537ad8bf2459f2863e806b47682cbb2f9b01b7502eaf5437a1a68fdaaeac114"
|
||||
}
|
||||
],
|
||||
"signed": {
|
||||
"_type": "root",
|
||||
"consistent_snapshot": true,
|
||||
"expires": "2034-04-02T17:00:22Z",
|
||||
"keys": {
|
||||
"198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3": {
|
||||
"keytype": "ecdsa",
|
||||
"keyval": {
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgDpP6O0sEt2R+l84WlfmqPBsFSby\nxJsJ6YmeUVgDk/wk9++8IAR6YBYewaKye56gMnIYjTFbyOI8WomA2NQFBw==\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"scheme": "ecdsa-sha2-nistp256",
|
||||
"x-tuf-on-ci-online-uri": "awskms:arn:aws:kms:us-east-1:175142243308:key/fbd8dab6-5677-4b57-87e6-8369c45b3b61"
|
||||
},
|
||||
"b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09": {
|
||||
"keytype": "ecdsa",
|
||||
"keyval": {
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3+asmp2GD6UijwWvMezwVG/BwFLuQa3o\nT6eRxFvkILGpVDbZ92ZYWidHl9LZ/eJUjhIjuVEkNVKoenw5KjKl8veP3MthZrQA\nSkYytOIwkidZo9Rk2dczbDcFSJvLGsmd\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"scheme": "ecdsa-sha2-nistp384",
|
||||
"x-tuf-on-ci-keyowner": "@mrjoelkamp"
|
||||
}
|
||||
},
|
||||
"roles": {
|
||||
"root": {
|
||||
"keyids": [
|
||||
"b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09"
|
||||
],
|
||||
"threshold": 1
|
||||
},
|
||||
"snapshot": {
|
||||
"keyids": [
|
||||
"198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3"
|
||||
],
|
||||
"threshold": 1,
|
||||
"x-tuf-on-ci-expiry-period": 3650,
|
||||
"x-tuf-on-ci-signing-period": 60
|
||||
},
|
||||
"targets": {
|
||||
"keyids": [
|
||||
"b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09"
|
||||
],
|
||||
"threshold": 1
|
||||
},
|
||||
"timestamp": {
|
||||
"keyids": [
|
||||
"198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3"
|
||||
],
|
||||
"threshold": 1,
|
||||
"x-tuf-on-ci-expiry-period": 3650,
|
||||
"x-tuf-on-ci-signing-period": 60
|
||||
}
|
||||
},
|
||||
"spec_version": "1.0.31",
|
||||
"version": 1,
|
||||
"x-tuf-on-ci-expiry-period": 3650,
|
||||
"x-tuf-on-ci-signing-period": 60
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
{
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09",
|
||||
"sig": "3066023100e99acc5f74777ebf40376b60f0216e8fe1829c1a49a5f6a6899126c15de1df7a56533baf493b2b53159c50843a289102023100b6a006b24da62ea0b743fbe38e1497ff485bf3a0833894985fc27a0305ad0693eeb968a7b52723ed3c49af8bef2027b6"
|
||||
},
|
||||
{
|
||||
"keyid": "81cf5a78d6ea2cd904256b9d814b340289b765e6f75ec4397e4ebb7586cab664",
|
||||
"sig": "30440220136debcc2f60dd1d63c9c2704f9b13c2cb2f5d2df58ea93f07f7c10f54f36742022059d7f8c6620e33506c6f1766394a32f86c9b008328f6398831ba7ebcf4ce0838"
|
||||
}
|
||||
],
|
||||
"signed": {
|
||||
"_type": "root",
|
||||
"consistent_snapshot": true,
|
||||
"expires": "2034-04-03T08:45:50Z",
|
||||
"keys": {
|
||||
"198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3": {
|
||||
"keytype": "ecdsa",
|
||||
"keyval": {
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgDpP6O0sEt2R+l84WlfmqPBsFSby\nxJsJ6YmeUVgDk/wk9++8IAR6YBYewaKye56gMnIYjTFbyOI8WomA2NQFBw==\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"scheme": "ecdsa-sha2-nistp256",
|
||||
"x-tuf-on-ci-online-uri": "awskms:arn:aws:kms:us-east-1:175142243308:key/fbd8dab6-5677-4b57-87e6-8369c45b3b61"
|
||||
},
|
||||
"81cf5a78d6ea2cd904256b9d814b340289b765e6f75ec4397e4ebb7586cab664": {
|
||||
"keytype": "ecdsa",
|
||||
"keyval": {
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWmhpAfB7Q53UNluMhpkDxXXup4E0\n2Hh4PSgHC1Yh6brGl6Akq9a4io55LtZTk5mnCTqxuB+rc5cI/yaNUeWEqQ==\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"scheme": "ecdsa-sha2-nistp256",
|
||||
"x-tuf-on-ci-keyowner": "@kipz"
|
||||
},
|
||||
"b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09": {
|
||||
"keytype": "ecdsa",
|
||||
"keyval": {
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3+asmp2GD6UijwWvMezwVG/BwFLuQa3o\nT6eRxFvkILGpVDbZ92ZYWidHl9LZ/eJUjhIjuVEkNVKoenw5KjKl8veP3MthZrQA\nSkYytOIwkidZo9Rk2dczbDcFSJvLGsmd\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"scheme": "ecdsa-sha2-nistp384",
|
||||
"x-tuf-on-ci-keyowner": "@mrjoelkamp"
|
||||
}
|
||||
},
|
||||
"roles": {
|
||||
"root": {
|
||||
"keyids": [
|
||||
"b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09",
|
||||
"81cf5a78d6ea2cd904256b9d814b340289b765e6f75ec4397e4ebb7586cab664"
|
||||
],
|
||||
"threshold": 1
|
||||
},
|
||||
"snapshot": {
|
||||
"keyids": [
|
||||
"198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3"
|
||||
],
|
||||
"threshold": 1,
|
||||
"x-tuf-on-ci-expiry-period": 3650,
|
||||
"x-tuf-on-ci-signing-period": 60
|
||||
},
|
||||
"targets": {
|
||||
"keyids": [
|
||||
"b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09",
|
||||
"81cf5a78d6ea2cd904256b9d814b340289b765e6f75ec4397e4ebb7586cab664"
|
||||
],
|
||||
"threshold": 1
|
||||
},
|
||||
"timestamp": {
|
||||
"keyids": [
|
||||
"198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3"
|
||||
],
|
||||
"threshold": 1,
|
||||
"x-tuf-on-ci-expiry-period": 3650,
|
||||
"x-tuf-on-ci-signing-period": 60
|
||||
}
|
||||
},
|
||||
"spec_version": "1.0.31",
|
||||
"version": 2,
|
||||
"x-tuf-on-ci-expiry-period": 3650,
|
||||
"x-tuf-on-ci-signing-period": 60
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09",
|
||||
"sig": ""
|
||||
},
|
||||
{
|
||||
"keyid": "81cf5a78d6ea2cd904256b9d814b340289b765e6f75ec4397e4ebb7586cab664",
|
||||
"sig": "3044022015b6ebe9d30895e3be20e707a6738e38460197d90cae3dc37527ddb7c437868602207f85f3d4e068bef4c51a749f5d166cc7fe2cb9483999ea197e72395081c3aa61"
|
||||
}
|
||||
],
|
||||
"signed": {
|
||||
"_type": "targets",
|
||||
"expires": "2034-04-03T15:39:02Z",
|
||||
"spec_version": "1.0.31",
|
||||
"targets": {
|
||||
"test-role/dir1/dir2/dir3/myfile.txt": {
|
||||
"hashes": {
|
||||
"sha256": "ea230621c53e0bb858ea5526125414f8957fb29c08350528d50a162c620f36b1"
|
||||
},
|
||||
"length": 10
|
||||
},
|
||||
"test-role/test.txt": {
|
||||
"hashes": {
|
||||
"sha256": "d1bb6181284970ae43fbbc88b5e72f9a5942ebac20588aa0c4bf78ba621e1ee2"
|
||||
},
|
||||
"length": 32
|
||||
}
|
||||
},
|
||||
"version": 3,
|
||||
"x-tuf-on-ci-expiry-period": 3650,
|
||||
"x-tuf-on-ci-signing-period": 60
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
{
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09",
|
||||
"sig": ""
|
||||
},
|
||||
{
|
||||
"keyid": "81cf5a78d6ea2cd904256b9d814b340289b765e6f75ec4397e4ebb7586cab664",
|
||||
"sig": "3046022100f892a496c9bd96082e3b06d5eae85429355876b8eb455aa04b53ab9051911d90022100a3e89c29b15bccfc2877278c0fb2d3b34500da6351e245ad0b3f8c0ae6b67eff"
|
||||
}
|
||||
],
|
||||
"signed": {
|
||||
"_type": "targets",
|
||||
"delegations": {
|
||||
"keys": {
|
||||
"81cf5a78d6ea2cd904256b9d814b340289b765e6f75ec4397e4ebb7586cab664": {
|
||||
"keytype": "ecdsa",
|
||||
"keyval": {
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWmhpAfB7Q53UNluMhpkDxXXup4E0\n2Hh4PSgHC1Yh6brGl6Akq9a4io55LtZTk5mnCTqxuB+rc5cI/yaNUeWEqQ==\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"scheme": "ecdsa-sha2-nistp256",
|
||||
"x-tuf-on-ci-keyowner": "@kipz"
|
||||
},
|
||||
"b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09": {
|
||||
"keytype": "ecdsa",
|
||||
"keyval": {
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3+asmp2GD6UijwWvMezwVG/BwFLuQa3o\nT6eRxFvkILGpVDbZ92ZYWidHl9LZ/eJUjhIjuVEkNVKoenw5KjKl8veP3MthZrQA\nSkYytOIwkidZo9Rk2dczbDcFSJvLGsmd\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"scheme": "ecdsa-sha2-nistp384",
|
||||
"x-tuf-on-ci-keyowner": "@mrjoelkamp"
|
||||
}
|
||||
},
|
||||
"roles": [
|
||||
{
|
||||
"keyids": [
|
||||
"b7474a42f2588fa92ed4a2ebea6047a7b1b2f7351f1cfe0912732c0d0fb0fc09",
|
||||
"81cf5a78d6ea2cd904256b9d814b340289b765e6f75ec4397e4ebb7586cab664"
|
||||
],
|
||||
"name": "test-role",
|
||||
"paths": [
|
||||
"test-role/*",
|
||||
"test-role/*/*",
|
||||
"test-role/*/*/*",
|
||||
"test-role/*/*/*/*"
|
||||
],
|
||||
"terminating": true,
|
||||
"threshold": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"expires": "2034-04-03T15:28:29Z",
|
||||
"spec_version": "1.0.31",
|
||||
"targets": {
|
||||
"test.txt": {
|
||||
"hashes": {
|
||||
"sha256": "02119a076ec3878c736c3a95e20794f5a8d5bce3d7ecc264681bb7334ca2e24b"
|
||||
},
|
||||
"length": 31
|
||||
}
|
||||
},
|
||||
"version": 5,
|
||||
"x-tuf-on-ci-expiry-period": 3650,
|
||||
"x-tuf-on-ci-signing-period": 60
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3",
|
||||
"sig": "3044022039b56cd2e3597df74e57d200a652ba020cdc9a8cd050bd65b5f8e2640d50691d02205e073e4b6fc260acc64327a331e4440601af5b1cbff594ea91cf7b70d5828fb1"
|
||||
}
|
||||
],
|
||||
"signed": {
|
||||
"_type": "snapshot",
|
||||
"expires": "2034-04-03T15:59:47Z",
|
||||
"meta": {
|
||||
"targets.json": {
|
||||
"version": 5
|
||||
},
|
||||
"test-role.json": {
|
||||
"version": 3
|
||||
}
|
||||
},
|
||||
"spec_version": "1.0.31",
|
||||
"version": 6
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3",
|
||||
"sig": "3045022011f2afa9b448fcbbac983c11fc3e264e95d5d7a9c9527b09d83a316ee762635f022100d05197a78ccc7a713ebdb0bccb44844f67a7c5208af8d346e201064b7ce11055"
|
||||
}
|
||||
],
|
||||
"signed": {
|
||||
"_type": "timestamp",
|
||||
"expires": "2034-04-03T15:59:47Z",
|
||||
"meta": {
|
||||
"snapshot.json": {
|
||||
"version": 6
|
||||
}
|
||||
},
|
||||
"spec_version": "1.0.31",
|
||||
"version": 6
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
this is a top-level target file
|
||||
@@ -1 +0,0 @@
|
||||
this is a delegated targets file
|
||||
@@ -1 +0,0 @@
|
||||
hello tuf
|
||||
10
internal/util/strings.go
Normal file
10
internal/util/strings.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package util
|
||||
|
||||
func StringInSlice(str string, list []string) bool {
|
||||
for _, v := range list {
|
||||
if v == str {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user