Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plumb ways to add metadata about targets. #437

Merged
merged 2 commits into from
Nov 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 70 additions & 18 deletions pkg/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"archive/tar"
"compress/gzip"
"context"
"encoding/json"
"fmt"
"io"
"io/fs"
Expand All @@ -31,13 +32,27 @@ import (
"knative.dev/pkg/logging"
)

// CreateRepo creates and initializes a Tuf repo for Sigstore by adding
// keys to bytes. keys are typically for a basic setup like:
// "fulcio_v1.crt.pem" - Fulcio root cert in PEM format
// "ctfe.pub" - CTLog public key in PEM format
// "rekor.pub" - Rekor public key in PEM format
// but additional keys can be added here.
func CreateRepo(ctx context.Context, files map[string][]byte) (tuf.LocalStore, string, error) {
// TargetWithMetadata describes a TUF target with the given Name, Bytes, and
// CustomMetadata
type TargetWithMetadata struct {
Name string
Bytes []byte
CustomMetadata []byte
}

type CustomMetadata struct {
Usage string `json:"usage"`
Status string `json:"status"`
URI string `json:"uri"`
}
vaikas marked this conversation as resolved.
Show resolved Hide resolved

type sigstoreCustomMetadata struct {
Sigstore CustomMetadata `json:"sigstore"`
}

// CreateRepoWithMetadata will create a TUF repo for Sigstore by adding targets
// to the Root with custom metadata.
func CreateRepoWithMetadata(ctx context.Context, targets []TargetWithMetadata) (tuf.LocalStore, string, error) {
// TODO: Make this an in-memory fileystem.
tmpDir := os.TempDir()
dir := tmpDir + "tuf"
Expand All @@ -56,7 +71,6 @@ func CreateRepo(ctx context.Context, files map[string][]byte) (tuf.LocalStore, s
return nil, "", fmt.Errorf("failed to NewRepoIndent: %w", err)
}

// Added by vaikas
if err := r.Init(false); err != nil {
return nil, "", fmt.Errorf("failed to Init repo: %w", err)
}
Expand All @@ -71,17 +85,15 @@ func CreateRepo(ctx context.Context, files map[string][]byte) (tuf.LocalStore, s
}
}

targets := make([]string, 0, len(files))
for k, v := range files {
logging.FromContext(ctx).Infof("Adding %s file", k)
if err := writeStagedTarget(dir, k, v); err != nil {
return nil, "", fmt.Errorf("failed to write staged target %s: %w", k, err)
for _, t := range targets {
logging.FromContext(ctx).Infof("Adding file: %s", t.Name)
if err := writeStagedTarget(dir, t.Name, t.Bytes); err != nil {
return nil, "", fmt.Errorf("failed to write staged target %s: %w", t.Name, err)
}
err = r.AddTargetWithExpires(t.Name, t.CustomMetadata, expires)
if err != nil {
return nil, "", fmt.Errorf("failed to add AddTargetWithExpires: %w", err)
}
targets = append(targets, k)
}
err = r.AddTargetsWithExpires(targets, nil, expires)
if err != nil {
return nil, "", fmt.Errorf("failed to add AddTargetsWithExpires: %w", err)
}

// Snapshot, Timestamp, and Publish the repository.
Expand All @@ -97,6 +109,46 @@ func CreateRepo(ctx context.Context, files map[string][]byte) (tuf.LocalStore, s
return local, dir, nil
}

// CreateRepo creates and initializes a TUF repo for Sigstore by adding
// keys to bytes. keys are typically for a basic setup like:
// "fulcio_v1.crt.pem" - Fulcio root cert in PEM format
// "ctfe.pub" - CTLog public key in PEM format
// "rekor.pub" - Rekor public key in PEM format
// but additional keys can be added here.
//
// This will also deduce the Usage for the keys based off the filename:
// if the filename contains:
// - `fulcio` = it will get Usage set to `Fulcio`
// - `ctfe` = it will get Usage set to `CTFE`
// - `rekor` = it will get Usage set to `Rekor`
// - Anything else will get set to `Unknown`
func CreateRepo(ctx context.Context, files map[string][]byte) (tuf.LocalStore, string, error) {
targets := make([]TargetWithMetadata, 0, len(files))
for name, bytes := range files {
usage := ""
if strings.Contains(name, "fulcio") {
usage = "Fulcio"
} else if strings.Contains(name, "ctfe") {
usage = "CTFE"
} else if strings.Contains(name, "rekor") {
usage = "Rekor"
vaikas marked this conversation as resolved.
Show resolved Hide resolved
} else {
usage = "Unknown"
}
scmActive, err := json.Marshal(&sigstoreCustomMetadata{Sigstore: CustomMetadata{Usage: usage, Status: "Active"}})
if err != nil {
return nil, "", fmt.Errorf("failed to marshal custom metadata for %s: %w", name, err)
}
targets = append(targets, TargetWithMetadata{
Name: name,
Bytes: bytes,
CustomMetadata: scmActive,
})
}

return CreateRepoWithMetadata(ctx, targets)
}

func writeStagedTarget(dir, path string, data []byte) error {
path = filepath.Join(dir, "staged", "targets", path)
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
Expand Down
1 change: 0 additions & 1 deletion pkg/repo/repo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,5 +122,4 @@ func TestCompressUncompressFS(t *testing.T) {
if bytes.Compare(files["rekor.pub"], rtRekor) != 0 {
t.Errorf("Roundtripped rekor differs:\n%s\n%s", rekorPublicKey, string(rtRekor))
}

}