diff --git a/cli/command/container/create_test.go b/cli/command/container/create_test.go index b786b1f0cc..a5367dfc66 100644 --- a/cli/command/container/create_test.go +++ b/cli/command/container/create_test.go @@ -2,6 +2,7 @@ package container import ( "context" + "fmt" "io" "io/ioutil" "os" @@ -10,6 +11,7 @@ import ( "testing" "github.com/docker/cli/internal/test" + "github.com/docker/cli/internal/test/notary" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" @@ -119,6 +121,51 @@ func TestCreateContainerPullsImageIfMissing(t *testing.T) { assert.Check(t, is.Contains(stderr, "Unable to find image 'does-not-exist-locally:latest' locally")) } +func TestNewCreateCommandWithContentTrustErrors(t *testing.T) { + testCases := []struct { + name string + args []string + expectedError string + notaryFunc test.NotaryClientFuncType + }{ + { + name: "offline-notary-server", + notaryFunc: notary.GetOfflineNotaryRepository, + expectedError: "client is offline", + args: []string{"image:tag"}, + }, + { + name: "uninitialized-notary-server", + notaryFunc: notary.GetUninitializedNotaryRepository, + expectedError: "remote trust data does not exist", + args: []string{"image:tag"}, + }, + { + name: "empty-notary-server", + notaryFunc: notary.GetEmptyTargetsNotaryRepository, + expectedError: "No valid trust data for tag", + args: []string{"image:tag"}, + }, + } + for _, tc := range testCases { + cli := test.NewFakeCli(&fakeClient{ + createContainerFunc: func(config *container.Config, + hostConfig *container.HostConfig, + networkingConfig *network.NetworkingConfig, + containerName string, + ) (container.ContainerCreateCreatedBody, error) { + return container.ContainerCreateCreatedBody{}, fmt.Errorf("shouldn't try to pull image") + }, + }, test.EnableContentTrust) + cli.SetNotaryClient(tc.notaryFunc) + cmd := NewCreateCommand(cli) + cmd.SetOutput(ioutil.Discard) + cmd.SetArgs(tc.args) + err := cmd.Execute() + assert.ErrorContains(t, err, tc.expectedError) + } +} + type fakeNotFound struct{} func (f fakeNotFound) NotFound() bool { return true } diff --git a/cli/command/container/run_test.go b/cli/command/container/run_test.go index e05b120410..94dea46805 100644 --- a/cli/command/container/run_test.go +++ b/cli/command/container/run_test.go @@ -1,12 +1,15 @@ package container import ( + "fmt" "testing" "github.com/docker/cli/internal/test" + "github.com/docker/cli/internal/test/notary" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestRunLabel(t *testing.T) { @@ -23,3 +26,48 @@ func TestRunLabel(t *testing.T) { cmd.SetArgs([]string{"--label", "foo", "busybox"}) assert.NilError(t, cmd.Execute()) } + +func TestRunCommandWithContentTrustErrors(t *testing.T) { + testCases := []struct { + name string + args []string + expectedError string + notaryFunc test.NotaryClientFuncType + }{ + { + name: "offline-notary-server", + notaryFunc: notary.GetOfflineNotaryRepository, + expectedError: "client is offline", + args: []string{"image:tag"}, + }, + { + name: "uninitialized-notary-server", + notaryFunc: notary.GetUninitializedNotaryRepository, + expectedError: "remote trust data does not exist", + args: []string{"image:tag"}, + }, + { + name: "empty-notary-server", + notaryFunc: notary.GetEmptyTargetsNotaryRepository, + expectedError: "No valid trust data for tag", + args: []string{"image:tag"}, + }, + } + for _, tc := range testCases { + cli := test.NewFakeCli(&fakeClient{ + createContainerFunc: func(config *container.Config, + hostConfig *container.HostConfig, + networkingConfig *network.NetworkingConfig, + containerName string, + ) (container.ContainerCreateCreatedBody, error) { + return container.ContainerCreateCreatedBody{}, fmt.Errorf("shouldn't try to pull image") + }, + }, test.EnableContentTrust) + cli.SetNotaryClient(tc.notaryFunc) + cmd := NewRunCommand(cli) + cmd.SetArgs(tc.args) + err := cmd.Execute() + assert.Assert(t, err != nil) + assert.Assert(t, is.Contains(cli.ErrBuffer().String(), tc.expectedError)) + } +} diff --git a/cli/command/image/build_linux_test.go b/cli/command/image/build_linux_test.go index 59b2871b4e..30815321fa 100644 --- a/cli/command/image/build_linux_test.go +++ b/cli/command/image/build_linux_test.go @@ -41,6 +41,7 @@ func TestRunBuildResetsUidAndGidInContext(t *testing.T) { options := newBuildOptions() options.context = dir.Path() + options.untrusted = true err := runBuild(cli, options) assert.NilError(t, err) diff --git a/cli/command/image/build_test.go b/cli/command/image/build_test.go index fb370f99f5..e66e01772b 100644 --- a/cli/command/image/build_test.go +++ b/cli/command/image/build_test.go @@ -57,6 +57,7 @@ func TestRunBuildDockerfileFromStdinWithCompress(t *testing.T) { options.compress = true options.dockerfileName = "-" options.context = dir + options.untrusted = true err = runBuild(cli, options) assert.NilError(t, err) @@ -191,6 +192,7 @@ RUN echo hello world cli := test.NewFakeCli(&fakeClient{imageBuildFunc: fakeImageBuild}) options := newBuildOptions() options.context = tmpDir.Join("context-link") + options.untrusted = true assert.NilError(t, runBuild(cli, options)) assert.DeepEqual(t, files, []string{"Dockerfile"}) diff --git a/cli/command/image/pull.go b/cli/command/image/pull.go index 4f6d4f830d..60db336e4d 100644 --- a/cli/command/image/pull.go +++ b/cli/command/image/pull.go @@ -59,7 +59,7 @@ func runPull(cli command.Cli, opts pullOptions) error { } ctx := context.Background() - imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, AuthResolver(cli), distributionRef.String()) + imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, AuthResolver(cli), distributionRef.String()) if err != nil { return err } diff --git a/cli/command/image/pull_test.go b/cli/command/image/pull_test.go index 6ccbb91a05..df639232fa 100644 --- a/cli/command/image/pull_test.go +++ b/cli/command/image/pull_test.go @@ -93,7 +93,7 @@ func TestNewPullCommandWithContentTrustErrors(t *testing.T) { args: []string{"image:tag"}, }, { - name: "empty-notary-server", + name: "uninitialized-notary-server", notaryFunc: notary.GetUninitializedNotaryRepository, expectedError: "remote trust data does not exist", args: []string{"image:tag"}, diff --git a/cli/command/image/trust.go b/cli/command/image/trust.go index 7a70ef96c0..4dffff1289 100644 --- a/cli/command/image/trust.go +++ b/cli/command/image/trust.go @@ -198,7 +198,7 @@ func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.Image if err != nil { return err } - updatedImgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, AuthResolver(cli), trustedRef.String()) + updatedImgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, AuthResolver(cli), trustedRef.String()) if err != nil { return err } @@ -293,35 +293,24 @@ func imagePullPrivileged(ctx context.Context, cli command.Cli, imgRefAndAuth tru // TrustedReference returns the canonical trusted reference for an image reference func TrustedReference(ctx context.Context, cli command.Cli, ref reference.NamedTagged, rs registry.Service) (reference.Canonical, error) { - var ( - repoInfo *registry.RepositoryInfo - err error - ) - if rs != nil { - repoInfo, err = rs.ResolveRepository(ref) - } else { - repoInfo, err = registry.ParseRepositoryInfo(ref) - } + imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, rs, AuthResolver(cli), ref.String()) if err != nil { return nil, err } - // Resolve the Auth config relevant for this server - authConfig := command.ResolveAuthConfig(ctx, cli, repoInfo.Index) - - notaryRepo, err := trust.GetNotaryRepository(cli.In(), cli.Out(), command.UserAgent(), repoInfo, &authConfig, "pull") + notaryRepo, err := cli.NotaryClient(imgRefAndAuth, []string{"pull"}) if err != nil { return nil, errors.Wrap(err, "error establishing connection to trust repository") } t, err := notaryRepo.GetTargetByName(ref.Tag(), trust.ReleasesRole, data.CanonicalTargetsRole) if err != nil { - return nil, trust.NotaryError(repoInfo.Name.Name(), err) + return nil, trust.NotaryError(imgRefAndAuth.RepoInfo().Name.Name(), err) } // Only list tags in the top level targets role or the releases delegation role - ignore // all other delegation roles if t.Role != trust.ReleasesRole && t.Role != data.CanonicalTargetsRole { - return nil, trust.NotaryError(repoInfo.Name.Name(), client.ErrNoSuchTarget(ref.Tag())) + return nil, trust.NotaryError(imgRefAndAuth.RepoInfo().Name.Name(), client.ErrNoSuchTarget(ref.Tag())) } r, err := convertTarget(t.Target) if err != nil { diff --git a/cli/command/trust/common.go b/cli/command/trust/common.go index 29b0ee622e..9173e6eeeb 100644 --- a/cli/command/trust/common.go +++ b/cli/command/trust/common.go @@ -66,7 +66,7 @@ type trustKey struct { // This information is to be pretty printed or serialized into a machine-readable format. func lookupTrustInfo(cli command.Cli, remote string) (trustTagRowList, []client.RoleWithSignatures, []data.Role, error) { ctx := context.Background() - imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), remote) + imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, image.AuthResolver(cli), remote) if err != nil { return trustTagRowList{}, []client.RoleWithSignatures{}, []data.Role{}, err } diff --git a/cli/command/trust/revoke.go b/cli/command/trust/revoke.go index df2a22aa4d..31437b03f1 100644 --- a/cli/command/trust/revoke.go +++ b/cli/command/trust/revoke.go @@ -36,7 +36,7 @@ func newRevokeCommand(dockerCli command.Cli) *cobra.Command { func revokeTrust(cli command.Cli, remote string, options revokeOptions) error { ctx := context.Background() - imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), remote) + imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, image.AuthResolver(cli), remote) if err != nil { return err } diff --git a/cli/command/trust/sign.go b/cli/command/trust/sign.go index df5c088c9d..234a057c32 100644 --- a/cli/command/trust/sign.go +++ b/cli/command/trust/sign.go @@ -42,7 +42,7 @@ func newSignCommand(dockerCli command.Cli) *cobra.Command { func runSignImage(cli command.Cli, options signOptions) error { imageName := options.imageName ctx := context.Background() - imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), imageName) + imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, image.AuthResolver(cli), imageName) if err != nil { return err } diff --git a/cli/command/trust/signer_add.go b/cli/command/trust/signer_add.go index 874915cb1e..304aeec92f 100644 --- a/cli/command/trust/signer_add.go +++ b/cli/command/trust/signer_add.go @@ -82,7 +82,7 @@ func addSigner(cli command.Cli, options signerAddOptions) error { func addSignerToRepo(cli command.Cli, signerName string, repoName string, signerPubKeys []data.PublicKey) error { ctx := context.Background() - imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), repoName) + imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, image.AuthResolver(cli), repoName) if err != nil { return err } diff --git a/cli/command/trust/signer_remove.go b/cli/command/trust/signer_remove.go index 4aa2825c4f..27774632bf 100644 --- a/cli/command/trust/signer_remove.go +++ b/cli/command/trust/signer_remove.go @@ -80,7 +80,7 @@ func isLastSignerForReleases(roleWithSig data.Role, allRoles []client.RoleWithSi func removeSingleSigner(cli command.Cli, repoName, signerName string, forceYes bool) error { ctx := context.Background() - imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), repoName) + imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, image.AuthResolver(cli), repoName) if err != nil { return err } diff --git a/cli/trust/trust.go b/cli/trust/trust.go index 07fb0d09d6..23c23715f7 100644 --- a/cli/trust/trust.go +++ b/cli/trust/trust.go @@ -300,14 +300,23 @@ type ImageRefAndAuth struct { // GetImageReferencesAndAuth retrieves the necessary reference and auth information for an image name // as an ImageRefAndAuth struct -func GetImageReferencesAndAuth(ctx context.Context, authResolver func(ctx context.Context, index *registrytypes.IndexInfo) types.AuthConfig, imgName string) (ImageRefAndAuth, error) { +func GetImageReferencesAndAuth(ctx context.Context, rs registry.Service, + authResolver func(ctx context.Context, index *registrytypes.IndexInfo) types.AuthConfig, + imgName string, +) (ImageRefAndAuth, error) { ref, err := reference.ParseNormalizedNamed(imgName) if err != nil { return ImageRefAndAuth{}, err } // Resolve the Repository name from fqn to RepositoryInfo - repoInfo, err := registry.ParseRepositoryInfo(ref) + var repoInfo *registry.RepositoryInfo + if rs != nil { + repoInfo, err = rs.ResolveRepository(ref) + } else { + repoInfo, err = registry.ParseRepositoryInfo(ref) + } + if err != nil { return ImageRefAndAuth{}, err } diff --git a/dockerfiles/Dockerfile.dev b/dockerfiles/Dockerfile.dev index 5734b0cf3a..eba75e008a 100644 --- a/dockerfiles/Dockerfile.dev +++ b/dockerfiles/Dockerfile.dev @@ -1,7 +1,7 @@ FROM golang:1.9.4-alpine3.6 -RUN apk add -U git make bash coreutils ca-certificates +RUN apk add -U git make bash coreutils ca-certificates curl ARG VNDR_SHA=a6e196d8b4b0cbbdc29aebdb20c59ac6926bb384 RUN go get -d github.com/LK4D4/vndr && \ @@ -24,6 +24,12 @@ RUN go get -d github.com/dnephin/filewatcher && \ go build -v -o /usr/bin/filewatcher . && \ rm -rf /go/src/* /go/pkg/* /go/bin/* +# FIXME(vdemeester) only used for e2e, could be in e2e special image in the future +ARG NOTARY_VERSION=v0.6.0 +RUN export URL=https://github.com/theupdateframework/notary/releases/download; \ + curl -Ls $URL/${NOTARY_VERSION}/notary-Linux-amd64 -o /usr/local/bin/notary && \ + chmod +x /usr/local/bin/notary + ENV CGO_ENABLED=0 \ PATH=$PATH:/go/src/github.com/docker/cli/build \ DISABLE_WARN_OUTSIDE_CONTAINER=1 diff --git a/e2e/container/create_test.go b/e2e/container/create_test.go new file mode 100644 index 0000000000..7aef9136b6 --- /dev/null +++ b/e2e/container/create_test.go @@ -0,0 +1,31 @@ +package container + +import ( + "fmt" + "testing" + + "github.com/docker/cli/e2e/internal/fixtures" + "github.com/gotestyourself/gotestyourself/icmd" +) + +func TestCreateWithContentTrust(t *testing.T) { + dir := fixtures.SetupConfigFile(t) + defer dir.Remove() + image := fixtures.CreateMaskedTrustedRemoteImage(t, registryPrefix, "trust-create", "latest") + + defer func() { + icmd.RunCommand("docker", "image", "rm", image).Assert(t, icmd.Success) + }() + + result := icmd.RunCmd( + icmd.Command("docker", "create", image), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotary, + ) + result.Assert(t, icmd.Expected{ + Err: fmt.Sprintf("Tagging %s@sha", image[:len(image)-7]), + }) +} + +// FIXME(vdemeester) TestTrustedCreateFromBadTrustServer needs to be backport too (see https://github.com/moby/moby/pull/36515/files#diff-4b1e56bb77ac16f2ccf956fc24cf0a82L331) diff --git a/e2e/container/run_test.go b/e2e/container/run_test.go index 716ca3726b..3c954ae488 100644 --- a/e2e/container/run_test.go +++ b/e2e/container/run_test.go @@ -12,6 +12,8 @@ import ( "github.com/gotestyourself/gotestyourself/icmd" ) +const registryPrefix = "registry:5000" + func TestRunAttachedFromRemoteImageAndRemove(t *testing.T) { image := createRemoteImage(t) @@ -23,6 +25,26 @@ func TestRunAttachedFromRemoteImageAndRemove(t *testing.T) { golden.Assert(t, result.Stderr(), "run-attached-from-remote-and-remove.golden") } +func TestRunWithContentTrust(t *testing.T) { + dir := fixtures.SetupConfigFile(t) + defer dir.Remove() + image := fixtures.CreateMaskedTrustedRemoteImage(t, registryPrefix, "trust-run", "latest") + + defer func() { + icmd.RunCommand("docker", "image", "rm", image).Assert(t, icmd.Success) + }() + + result := icmd.RunCmd( + icmd.Command("docker", "run", image), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotary, + ) + result.Assert(t, icmd.Expected{ + Err: fmt.Sprintf("Tagging %s@sha", image[:len(image)-7]), + }) +} + // TODO: create this with registry API instead of engine API func createRemoteImage(t *testing.T) string { image := "registry:5000/alpine:test-run-pulls" diff --git a/e2e/image/build_test.go b/e2e/image/build_test.go index b94566d321..7a1255c493 100644 --- a/e2e/image/build_test.go +++ b/e2e/image/build_test.go @@ -2,13 +2,12 @@ package image import ( "fmt" - "strings" "testing" "github.com/docker/cli/e2e/internal/fixtures" + "github.com/docker/cli/internal/test/output" "github.com/gotestyourself/gotestyourself/fs" "github.com/gotestyourself/gotestyourself/icmd" - "github.com/pkg/errors" ) func TestBuildFromContextDirectoryWithTag(t *testing.T) { @@ -28,16 +27,72 @@ func TestBuildFromContextDirectoryWithTag(t *testing.T) { withWorkingDir(dir)) result.Assert(t, icmd.Expected{Err: icmd.None}) - assertBuildOutput(t, result.Stdout(), map[int]lineCompare{ - 0: prefix("Sending build context to Docker daemon"), - 1: equals("Step 1/4 : FROM\tregistry:5000/alpine:3.6"), - 3: equals("Step 2/4 : COPY\trun /usr/bin/run"), - 5: equals("Step 3/4 : RUN\t\trun"), - 7: equals("running"), - 8: prefix("Removing intermediate container "), - 10: equals("Step 4/4 : COPY\tdata /data"), - 12: prefix("Successfully built "), - 13: equals("Successfully tagged myimage:latest"), + output.Assert(t, result.Stdout(), map[int]func(string) error{ + 0: output.Prefix("Sending build context to Docker daemon"), + 1: output.Equals("Step 1/4 : FROM\tregistry:5000/alpine:3.6"), + 3: output.Equals("Step 2/4 : COPY\trun /usr/bin/run"), + 5: output.Equals("Step 3/4 : RUN\t\trun"), + 7: output.Equals("running"), + 8: output.Prefix("Removing intermediate container "), + 10: output.Equals("Step 4/4 : COPY\tdata /data"), + 12: output.Prefix("Successfully built "), + 13: output.Equals("Successfully tagged myimage:latest"), + }) +} + +func TestTrustedBuild(t *testing.T) { + dir := fixtures.SetupConfigFile(t) + defer dir.Remove() + image1 := fixtures.CreateMaskedTrustedRemoteImage(t, registryPrefix, "trust-build1", "latest") + image2 := fixtures.CreateMaskedTrustedRemoteImage(t, registryPrefix, "trust-build2", "latest") + + buildDir := fs.NewDir(t, "test-trusted-build-context-dir", + fs.WithFile("Dockerfile", fmt.Sprintf(` + FROM %s as build-base + RUN echo ok > /foo + FROM %s + COPY --from=build-base foo bar + `, image1, image2))) + defer buildDir.Remove() + + result := icmd.RunCmd( + icmd.Command("docker", "build", "-t", "myimage", "."), + withWorkingDir(buildDir), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotary, + ) + + result.Assert(t, icmd.Expected{ + Out: fmt.Sprintf("FROM %s@sha", image1[:len(image1)-7]), + Err: fmt.Sprintf("Tagging %s@sha", image1[:len(image1)-7]), + }) + result.Assert(t, icmd.Expected{ + Out: fmt.Sprintf("FROM %s@sha", image2[:len(image2)-7]), + }) +} + +func TestTrustedBuildUntrustedImage(t *testing.T) { + dir := fixtures.SetupConfigFile(t) + defer dir.Remove() + buildDir := fs.NewDir(t, "test-trusted-build-context-dir", + fs.WithFile("Dockerfile", fmt.Sprintf(` + FROM %s + RUN [] + `, fixtures.AlpineImage))) + defer buildDir.Remove() + + result := icmd.RunCmd( + icmd.Command("docker", "build", "-t", "myimage", "."), + withWorkingDir(buildDir), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotary, + ) + + result.Assert(t, icmd.Expected{ + ExitCode: 1, + Err: "does not have trust data for", }) } @@ -46,38 +101,3 @@ func withWorkingDir(dir *fs.Dir) func(*icmd.Cmd) { cmd.Dir = dir.Path() } } - -func assertBuildOutput(t *testing.T, actual string, expectedLines map[int]lineCompare) { - for i, line := range strings.Split(actual, "\n") { - cmp, ok := expectedLines[i] - if !ok { - continue - } - if err := cmp(line); err != nil { - t.Errorf("line %d: %s", i, err) - } - } - if t.Failed() { - t.Log(actual) - } -} - -type lineCompare func(string) error - -func prefix(expected string) func(string) error { - return func(actual string) error { - if strings.HasPrefix(actual, expected) { - return nil - } - return errors.Errorf("expected %s to start with %s", actual, expected) - } -} - -func equals(expected string) func(string) error { - return func(actual string) error { - if expected == actual { - return nil - } - return errors.Errorf("got %s, expected %s", actual, expected) - } -} diff --git a/e2e/image/pull_test.go b/e2e/image/pull_test.go index 6316a939e5..d8758d8e86 100644 --- a/e2e/image/pull_test.go +++ b/e2e/image/pull_test.go @@ -1,7 +1,6 @@ package image import ( - "fmt" "testing" "github.com/docker/cli/e2e/internal/fixtures" @@ -12,37 +11,55 @@ import ( const registryPrefix = "registry:5000" func TestPullWithContentTrust(t *testing.T) { - image := createMaskedTrustedRemoteImage(t, "trust", "latest") + dir := fixtures.SetupConfigFile(t) + defer dir.Remove() + image := fixtures.CreateMaskedTrustedRemoteImage(t, registryPrefix, "trust-pull", "latest") + defer func() { + icmd.RunCommand("docker", "image", "rm", image).Assert(t, icmd.Success) + }() - result := icmd.RunCmd(icmd.Command("docker", "pull", image), fixtures.WithTrust, fixtures.WithNotary) + result := icmd.RunCmd(icmd.Command("docker", "pull", image), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotary, + ) result.Assert(t, icmd.Success) golden.Assert(t, result.Stderr(), "pull-with-content-trust-err.golden") golden.Assert(t, result.Stdout(), "pull-with-content-trust.golden") } -// createMaskedTrustedRemoteImage creates a remote image that is signed with -// content trust, then pushes a different untrusted image at the same tag. -func createMaskedTrustedRemoteImage(t *testing.T, repo, tag string) string { - image := createTrustedRemoteImage(t, repo, tag) - createNamedUnsignedImageFromBusyBox(t, image) - return image -} +func TestPullWithContentTrustUsesCacheWhenNotaryUnavailable(t *testing.T) { + dir := fixtures.SetupConfigFile(t) + defer dir.Remove() + image := fixtures.CreateMaskedTrustedRemoteImage(t, registryPrefix, "trust-pull-unreachable", "latest") + defer func() { + icmd.RunCommand("docker", "image", "rm", image).Assert(t, icmd.Success) + }() + result := icmd.RunCmd(icmd.Command("docker", "pull", image), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotaryServer("https://invalidnotaryserver"), + ) + result.Assert(t, icmd.Expected{ + ExitCode: 1, + Err: "error contacting notary server", + }) -func createTrustedRemoteImage(t *testing.T, repo, tag string) string { - image := fmt.Sprintf("%s/%s:%s", registryPrefix, repo, tag) - icmd.RunCommand("docker", "pull", fixtures.AlpineImage).Assert(t, icmd.Success) - icmd.RunCommand("docker", "tag", fixtures.AlpineImage, image).Assert(t, icmd.Success) - result := icmd.RunCmd( - icmd.Command("docker", "push", image), - fixtures.WithPassphrase("root_password", "repo_password"), fixtures.WithTrust, fixtures.WithNotary) + // Do valid trusted pull to warm cache + result = icmd.RunCmd(icmd.Command("docker", "pull", image), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotary, + ) + result.Assert(t, icmd.Success) + result = icmd.RunCommand("docker", "rmi", image) result.Assert(t, icmd.Success) - icmd.RunCommand("docker", "rmi", image).Assert(t, icmd.Success) - return image -} -func createNamedUnsignedImageFromBusyBox(t *testing.T, image string) { - icmd.RunCommand("docker", "pull", fixtures.BusyboxImage).Assert(t, icmd.Success) - icmd.RunCommand("docker", "tag", fixtures.BusyboxImage, image).Assert(t, icmd.Success) - icmd.RunCommand("docker", "push", image).Assert(t, icmd.Success) - icmd.RunCommand("docker", "rmi", image).Assert(t, icmd.Success) + // Try pull again with invalid notary server, should use cache + result = icmd.RunCmd(icmd.Command("docker", "pull", image), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotaryServer("https://invalidnotaryserver"), + ) + result.Assert(t, icmd.Success) } diff --git a/e2e/image/push_test.go b/e2e/image/push_test.go new file mode 100644 index 0000000000..9adfa5817f --- /dev/null +++ b/e2e/image/push_test.go @@ -0,0 +1,378 @@ +package image + +import ( + "fmt" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/docker/cli/e2e/internal/fixtures" + "github.com/docker/cli/internal/test/output" + "github.com/gotestyourself/gotestyourself/assert" + "github.com/gotestyourself/gotestyourself/fs" + "github.com/gotestyourself/gotestyourself/golden" + "github.com/gotestyourself/gotestyourself/icmd" +) + +const ( + notary = "/usr/local/bin/notary" + + pubkey1 = "./testdata/notary/delgkey1.crt" + privkey1 = "./testdata/notary/delgkey1.key" + pubkey2 = "./testdata/notary/delgkey2.crt" + privkey2 = "./testdata/notary/delgkey2.key" + pubkey3 = "./testdata/notary/delgkey3.crt" + privkey3 = "./testdata/notary/delgkey3.key" + pubkey4 = "./testdata/notary/delgkey4.crt" + privkey4 = "./testdata/notary/delgkey4.key" +) + +func TestPushWithContentTrust(t *testing.T) { + dir := fixtures.SetupConfigFile(t) + defer dir.Remove() + image := createImage(t, registryPrefix, "trust-push", "latest") + + result := icmd.RunCmd(icmd.Command("docker", "push", image), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotary, + fixtures.WithPassphrase("foo", "bar"), + ) + result.Assert(t, icmd.Success) + golden.Assert(t, result.Stderr(), "push-with-content-trust-err.golden") + output.Assert(t, result.Stdout(), map[int]func(string) error{ + 0: output.Equals("The push refers to repository [registry:5000/trust-push]"), + 1: output.Equals("5bef08742407: Preparing"), + 3: output.Equals("latest: digest: sha256:641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d size: 528"), + 4: output.Equals("Signing and pushing trust metadata"), + 5: output.Equals(`Finished initializing "registry:5000/trust-push"`), + 6: output.Equals("Successfully signed registry:5000/trust-push:latest"), + }) +} + +func TestPushWithContentTrustUnreachableServer(t *testing.T) { + dir := fixtures.SetupConfigFile(t) + defer dir.Remove() + image := createImage(t, registryPrefix, "trust-push-unreachable", "latest") + + result := icmd.RunCmd(icmd.Command("docker", "push", image), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotaryServer("https://invalidnotaryserver"), + ) + result.Assert(t, icmd.Expected{ + ExitCode: 1, + Err: "error contacting notary server", + }) +} + +func TestPushWithContentTrustExistingTag(t *testing.T) { + dir := fixtures.SetupConfigFile(t) + defer dir.Remove() + image := createImage(t, registryPrefix, "trust-push-existing", "latest") + + result := icmd.RunCmd(icmd.Command("docker", "push", image)) + result.Assert(t, icmd.Success) + + result = icmd.RunCmd(icmd.Command("docker", "push", image), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotary, + fixtures.WithPassphrase("foo", "bar"), + ) + result.Assert(t, icmd.Expected{ + Out: "Signing and pushing trust metadata", + }) + + // Re-push + result = icmd.RunCmd(icmd.Command("docker", "push", image), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotary, + fixtures.WithPassphrase("foo", "bar"), + ) + result.Assert(t, icmd.Expected{ + Out: "Signing and pushing trust metadata", + }) +} + +func TestPushWithContentTrustReleasesDelegationOnly(t *testing.T) { + role := "targets/releases" + + dir := fixtures.SetupConfigFile(t) + defer dir.Remove() + copyPrivateKey(t, dir.Join("trust", "private"), privkey1) + notaryDir := setupNotaryConfig(t, dir) + defer notaryDir.Remove() + homeDir := fs.NewDir(t, "push_test_home") + defer notaryDir.Remove() + + baseRef := fmt.Sprintf("%s/%s", registryPrefix, "trust-push-releases-delegation") + targetRef := fmt.Sprintf("%s:%s", baseRef, "latest") + + // Init repository + notaryInit(t, notaryDir, homeDir, baseRef) + // Add delegation key (public key) + notaryAddDelegation(t, notaryDir, homeDir, baseRef, role, pubkey1) + // Publish it + notaryPublish(t, notaryDir, homeDir, baseRef) + // Import private key + notaryImportPrivateKey(t, notaryDir, homeDir, baseRef, role, privkey1) + + // Tag & push with content trust + icmd.RunCommand("docker", "pull", fixtures.AlpineImage).Assert(t, icmd.Success) + icmd.RunCommand("docker", "tag", fixtures.AlpineImage, targetRef).Assert(t, icmd.Success) + result := icmd.RunCmd(icmd.Command("docker", "push", targetRef), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotary, + fixtures.WithPassphrase("foo", "foo"), + ) + result.Assert(t, icmd.Expected{ + Out: "Signing and pushing trust metadata", + }) + + targetsInRole := notaryListTargetsInRole(t, notaryDir, homeDir, baseRef, role) + assert.Assert(t, targetsInRole["latest"] == role, "%v", targetsInRole) + targetsInRole = notaryListTargetsInRole(t, notaryDir, homeDir, baseRef, "targets") + assert.Assert(t, targetsInRole["latest"] != "targets", "%v", targetsInRole) + + result = icmd.RunCmd(icmd.Command("docker", "pull", targetRef), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotary, + ) + result.Assert(t, icmd.Success) +} + +func TestPushWithContentTrustSignsAllFirstLevelRolesWeHaveKeysFor(t *testing.T) { + dir := fixtures.SetupConfigFile(t) + defer dir.Remove() + copyPrivateKey(t, dir.Join("trust", "private"), privkey1) + copyPrivateKey(t, dir.Join("trust", "private"), privkey2) + copyPrivateKey(t, dir.Join("trust", "private"), privkey3) + notaryDir := setupNotaryConfig(t, dir) + defer notaryDir.Remove() + homeDir := fs.NewDir(t, "push_test_home") + defer notaryDir.Remove() + + baseRef := fmt.Sprintf("%s/%s", registryPrefix, "trust-push-releases-first-roles") + targetRef := fmt.Sprintf("%s:%s", baseRef, "latest") + + // Init repository + notaryInit(t, notaryDir, homeDir, baseRef) + // Add delegation key (public key) + notaryAddDelegation(t, notaryDir, homeDir, baseRef, "targets/role1", pubkey1) + notaryAddDelegation(t, notaryDir, homeDir, baseRef, "targets/role2", pubkey2) + notaryAddDelegation(t, notaryDir, homeDir, baseRef, "targets/role3", pubkey3) + notaryAddDelegation(t, notaryDir, homeDir, baseRef, "targets/role1/subrole", pubkey3) + // Import private key + notaryImportPrivateKey(t, notaryDir, homeDir, baseRef, "targets/role1", privkey1) + notaryImportPrivateKey(t, notaryDir, homeDir, baseRef, "targets/role2", privkey2) + notaryImportPrivateKey(t, notaryDir, homeDir, baseRef, "targets/role1/subrole", privkey3) + // Publish it + notaryPublish(t, notaryDir, homeDir, baseRef) + + // Tag & push with content trust + icmd.RunCommand("docker", "pull", fixtures.AlpineImage).Assert(t, icmd.Success) + icmd.RunCommand("docker", "tag", fixtures.AlpineImage, targetRef).Assert(t, icmd.Success) + result := icmd.RunCmd(icmd.Command("docker", "push", targetRef), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotary, + fixtures.WithPassphrase("foo", "foo"), + ) + result.Assert(t, icmd.Expected{ + Out: "Signing and pushing trust metadata", + }) + + // check to make sure that the target has been added to targets/role1 and targets/role2, and + // not targets (because there are delegations) or targets/role3 (due to missing key) or + // targets/role1/subrole (due to it being a second level delegation) + targetsInRole := notaryListTargetsInRole(t, notaryDir, homeDir, baseRef, "targets/role1") + assert.Assert(t, targetsInRole["latest"] == "targets/role1", "%v", targetsInRole) + targetsInRole = notaryListTargetsInRole(t, notaryDir, homeDir, baseRef, "targets/role2") + assert.Assert(t, targetsInRole["latest"] == "targets/role2", "%v", targetsInRole) + targetsInRole = notaryListTargetsInRole(t, notaryDir, homeDir, baseRef, "targets") + assert.Assert(t, targetsInRole["latest"] != "targets", "%v", targetsInRole) + + assert.NilError(t, os.RemoveAll(filepath.Join(dir.Join("trust")))) + // Try to pull, should fail because non of these are the release role + // FIXME(vdemeester) should be unit test + result = icmd.RunCmd(icmd.Command("docker", "pull", targetRef), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotary, + ) + result.Assert(t, icmd.Expected{ + ExitCode: 1, + }) +} + +func TestPushWithContentTrustSignsForRolesWithKeysAndValidPaths(t *testing.T) { + dir := fixtures.SetupConfigFile(t) + defer dir.Remove() + copyPrivateKey(t, dir.Join("trust", "private"), privkey1) + copyPrivateKey(t, dir.Join("trust", "private"), privkey2) + copyPrivateKey(t, dir.Join("trust", "private"), privkey3) + copyPrivateKey(t, dir.Join("trust", "private"), privkey4) + notaryDir := setupNotaryConfig(t, dir) + defer notaryDir.Remove() + homeDir := fs.NewDir(t, "push_test_home") + defer notaryDir.Remove() + + baseRef := fmt.Sprintf("%s/%s", registryPrefix, "trust-push-releases-keys-valid-paths") + targetRef := fmt.Sprintf("%s:%s", baseRef, "latest") + + // Init repository + notaryInit(t, notaryDir, homeDir, baseRef) + // Add delegation key (public key) + notaryAddDelegation(t, notaryDir, homeDir, baseRef, "targets/role1", pubkey1, "l", "z") + notaryAddDelegation(t, notaryDir, homeDir, baseRef, "targets/role2", pubkey2, "x", "y") + notaryAddDelegation(t, notaryDir, homeDir, baseRef, "targets/role3", pubkey3, "latest") + notaryAddDelegation(t, notaryDir, homeDir, baseRef, "targets/role4", pubkey4, "latest") + // Import private keys (except 3rd key) + notaryImportPrivateKey(t, notaryDir, homeDir, baseRef, "targets/role1", privkey1) + notaryImportPrivateKey(t, notaryDir, homeDir, baseRef, "targets/role2", privkey2) + notaryImportPrivateKey(t, notaryDir, homeDir, baseRef, "targets/role4", privkey4) + // Publish it + notaryPublish(t, notaryDir, homeDir, baseRef) + + // Tag & push with content trust + icmd.RunCommand("docker", "pull", fixtures.AlpineImage).Assert(t, icmd.Success) + icmd.RunCommand("docker", "tag", fixtures.AlpineImage, targetRef).Assert(t, icmd.Success) + result := icmd.RunCmd(icmd.Command("docker", "push", targetRef), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotary, + fixtures.WithPassphrase("foo", "foo"), + ) + result.Assert(t, icmd.Expected{ + Out: "Signing and pushing trust metadata", + }) + + // check to make sure that the target has been added to targets/role1 and targets/role4, and + // not targets (because there are delegations) or targets/role2 (due to path restrictions) or + // targets/role3 (due to missing key) + targetsInRole := notaryListTargetsInRole(t, notaryDir, homeDir, baseRef, "targets/role1") + assert.Assert(t, targetsInRole["latest"] == "targets/role1", "%v", targetsInRole) + targetsInRole = notaryListTargetsInRole(t, notaryDir, homeDir, baseRef, "targets/role4") + assert.Assert(t, targetsInRole["latest"] == "targets/role4", "%v", targetsInRole) + targetsInRole = notaryListTargetsInRole(t, notaryDir, homeDir, baseRef, "targets") + assert.Assert(t, targetsInRole["latest"] != "targets", "%v", targetsInRole) + + assert.NilError(t, os.RemoveAll(filepath.Join(dir.Join("trust")))) + // Try to pull, should fail because non of these are the release role + // FIXME(vdemeester) should be unit test + result = icmd.RunCmd(icmd.Command("docker", "pull", targetRef), + fixtures.WithConfig(dir.Path()), + fixtures.WithTrust, + fixtures.WithNotary, + ) + result.Assert(t, icmd.Expected{ + ExitCode: 1, + }) +} + +func createImage(t *testing.T, registryPrefix, repo, tag string) string { + image := fmt.Sprintf("%s/%s:%s", registryPrefix, repo, tag) + icmd.RunCommand("docker", "pull", fixtures.AlpineImage).Assert(t, icmd.Success) + icmd.RunCommand("docker", "tag", fixtures.AlpineImage, image).Assert(t, icmd.Success) + return image +} + +func withNotaryPassphrase(pwd string) func(*icmd.Cmd) { + return func(c *icmd.Cmd) { + c.Env = append(c.Env, []string{ + fmt.Sprintf("NOTARY_ROOT_PASSPHRASE=%s", pwd), + fmt.Sprintf("NOTARY_TARGETS_PASSPHRASE=%s", pwd), + fmt.Sprintf("NOTARY_SNAPSHOT_PASSPHRASE=%s", pwd), + fmt.Sprintf("NOTARY_DELEGATION_PASSPHRASE=%s", pwd), + }...) + } +} + +func notaryImportPrivateKey(t *testing.T, notaryDir, homeDir *fs.Dir, baseRef, role, privkey string) { + icmd.RunCmd( + icmd.Command(notary, "-c", notaryDir.Join("client-config.json"), "key", "import", privkey, "-g", baseRef, "-r", role), + withNotaryPassphrase("foo"), + fixtures.WithHome(homeDir.Path()), + ).Assert(t, icmd.Success) +} + +func notaryPublish(t *testing.T, notaryDir, homeDir *fs.Dir, baseRef string) { + icmd.RunCmd( + icmd.Command(notary, "-c", notaryDir.Join("client-config.json"), "publish", baseRef), + withNotaryPassphrase("foo"), + fixtures.WithHome(homeDir.Path()), + ).Assert(t, icmd.Success) +} + +func notaryAddDelegation(t *testing.T, notaryDir, homeDir *fs.Dir, baseRef, role, pubkey string, paths ...string) { + pathsArg := "--all-paths" + if len(paths) > 0 { + pathsArg = "--paths=" + strings.Join(paths, ",") + } + icmd.RunCmd( + icmd.Command(notary, "-c", notaryDir.Join("client-config.json"), "delegation", "add", baseRef, role, pubkey, pathsArg), + withNotaryPassphrase("foo"), + fixtures.WithHome(homeDir.Path()), + ).Assert(t, icmd.Success) +} + +func notaryInit(t *testing.T, notaryDir, homeDir *fs.Dir, baseRef string) { + icmd.RunCmd( + icmd.Command(notary, "-c", notaryDir.Join("client-config.json"), "init", baseRef), + withNotaryPassphrase("foo"), + fixtures.WithHome(homeDir.Path()), + ).Assert(t, icmd.Success) +} + +func notaryListTargetsInRole(t *testing.T, notaryDir, homeDir *fs.Dir, baseRef, role string) map[string]string { + result := icmd.RunCmd( + icmd.Command(notary, "-c", notaryDir.Join("client-config.json"), "list", baseRef, "-r", role), + fixtures.WithHome(homeDir.Path()), + ) + out := result.Combined() + + // should look something like: + // NAME DIGEST SIZE (BYTES) ROLE + // ------------------------------------------------------------------------------------------------------ + // latest 24a36bbc059b1345b7e8be0df20f1b23caa3602e85d42fff7ecd9d0bd255de56 1377 targets + + targets := make(map[string]string) + + // no target + lines := strings.Split(strings.TrimSpace(out), "\n") + if len(lines) == 1 && strings.Contains(out, "No targets present in this repository.") { + return targets + } + + // otherwise, there is at least one target + assert.Assert(t, len(lines) >= 3, "output is %s", out) + + for _, line := range lines[2:] { + tokens := strings.Fields(line) + assert.Assert(t, len(tokens) == 4) + targets[tokens[0]] = tokens[3] + } + + return targets +} + +func setupNotaryConfig(t *testing.T, dockerConfigDir fs.Dir) *fs.Dir { + return fs.NewDir(t, "notary_test", fs.WithMode(0700), + fs.WithFile("client-config.json", fmt.Sprintf(` +{ + "trust_dir": "%s", + "remote_server": { + "url": "%s" + } +}`, dockerConfigDir.Join("trust"), fixtures.NotaryURL)), + ) +} + +func copyPrivateKey(t *testing.T, dir, source string) { + icmd.RunCommand("/bin/cp", source, dir).Assert(t, icmd.Success) +} diff --git a/e2e/image/testdata/notary/delgkey1.crt b/e2e/image/testdata/notary/delgkey1.crt new file mode 100644 index 0000000000..2218f23c89 --- /dev/null +++ b/e2e/image/testdata/notary/delgkey1.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhTCCAm2gAwIBAgIJAP2EcMN2UXPcMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV +BAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMQ8wDQYD +VQQKEwZEb2NrZXIxEzARBgNVBAMTCmRlbGVnYXRpb24wHhcNMTYwOTI4MTc0ODQ4 +WhcNMjYwNjI4MTc0ODQ4WjBXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFTAT +BgNVBAcTDFNhbkZyYW5jaXNjbzEPMA0GA1UEChMGRG9ja2VyMRMwEQYDVQQDEwpk +ZWxlZ2F0aW9uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvgewhaYs +Ke5s2AM7xxKrT4A6n7hW17qSnBjonCcPcwTFmYqIOdxWjYITgJuHrTwB4ZhBqWS7 +tTsUUu6hWLMeB7Uo5/GEQAAZspKkT9G/rNKF9lbWK9PPhGGkeR01c/Q932m92Hsn +fCQ0Pp/OzD3nVTh0v9HKk+PObNMOCcqG87eYs4ylPRxs0RrE/rP+bEGssKQSbeCZ +wazDnO+kiatVgKQZ2CK23iFdRE1z2rzqVDeaFWdvBqrRdWnkOZClhlLgEQ5nK2yV +B6tSqOiI3MmHyHzIkGOQJp2/s7Pe0ckEkzsjTsJW8oKHlBBl6pRxHIKzNN4VFbeB +vvYvrogrDrC/owIDAQABo1QwUjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF +oDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUFoHfukRa6qGk1ncON64Z +ASKlZdkwDQYJKoZIhvcNAQELBQADggEBAEq9Adpd03CPmpbRtTAJGAkjjLFr60sV +2r+/l/m9R31ZCN9ymM9nxToQ8zfMdeAh/nnPcErziil2gDVqXueCNDkRj09tmDIE +Q1Oc92uyNZNgcECow77cKZCTZSTku+qsJrYaykH5vSnia8ltcKj8inJedIcpBR+p +608HEQvF0Eg5eaLPJwH48BCb0Gqdri1dJgrNnqptz7MDr8M+u7tHVulbAd3YxLlq +JH1W2bkVUx6esbn/MUE5HL5iTuOYREEINvBSmLdmmFkampmCnCB/bDEyJeL9bAkt +ZPIi0UNSnqFKLSP1Vf8AGLXt6iO7+1OGvtsDXEEYdXVOMsSXZtUuT7A= +-----END CERTIFICATE----- diff --git a/e2e/image/testdata/notary/delgkey1.key b/e2e/image/testdata/notary/delgkey1.key new file mode 100644 index 0000000000..cb37efc94a --- /dev/null +++ b/e2e/image/testdata/notary/delgkey1.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAvgewhaYsKe5s2AM7xxKrT4A6n7hW17qSnBjonCcPcwTFmYqI +OdxWjYITgJuHrTwB4ZhBqWS7tTsUUu6hWLMeB7Uo5/GEQAAZspKkT9G/rNKF9lbW +K9PPhGGkeR01c/Q932m92HsnfCQ0Pp/OzD3nVTh0v9HKk+PObNMOCcqG87eYs4yl +PRxs0RrE/rP+bEGssKQSbeCZwazDnO+kiatVgKQZ2CK23iFdRE1z2rzqVDeaFWdv +BqrRdWnkOZClhlLgEQ5nK2yVB6tSqOiI3MmHyHzIkGOQJp2/s7Pe0ckEkzsjTsJW +8oKHlBBl6pRxHIKzNN4VFbeBvvYvrogrDrC/owIDAQABAoIBAB/o8KZwsgfUhqh7 +WoViSCwQb0e0z7hoFwhpUl4uXPTGf1v6HEgDDPG0PwwgkdbwNaypQZVtWevj4NTQ +R326jjdjH1xbfQa2PZpz722L3jDqJR6plEtFxRoIv3KrCffPsrgabIu2mnnJJpDB +ixtW5cq0sT4ov2i4H0i85CWWwbSY/G/MHsvCuK9PhoCj9uToVqrf1KrAESE5q4fh +mPSYUL99KVnj7SZkUz+79rc8sLLPVks3szZACMlm1n05ZTj/d6Nd2ZZUO45DllIj +1XJghfWmnChrB/P/KYXgQ3Y9BofIAw1ra2y3wOZeqRFNsbmojcGldfdtN/iQzhEj +uk4ThokCgYEA9FTmv36N8qSPWuqX/KzkixDQ8WrDGohcB54kK98Wx4ijXx3i38SY +tFjO8YUS9GVo1+UgmRjZbzVX7xeum6+TdBBwOjNOxEQ4tzwiQBWDdGpli8BccdJ2 +OOIVxSslWhiUWfpYloXVetrR88iHbT882g795pbonDaJdXSLnij4UW8CgYEAxxrr +QFpsmOEZvI/yPSOGdG7A1RIsCeH+cEOf4cKghs7+aCtAHlIweztNOrqirl3oKI1r +I0zQl46WsaW8S/y99v9lmmnZbWwqLa4vIu0NWs0zaZdzKZw3xljMhgp4Ge69hHa2 +utCtAxcX+7q/yLlHoTiYwKdxX54iLkheCB8csw0CgYEAleEG820kkjXUIodJ2JwO +Tihwo8dEC6CeI6YktizRgnEVFqH0rCOjMO5Rc+KX8AfNOrK5PnD54LguSuKSH7qi +j04OKgWTSd43lF90+y63RtCFnibQDpp2HwrBJAQFk7EEP/XMJfnPLN/SbuMSADgM +kg8kPTFRW5Iw3DYz9z9WpE0CgYAkn6/8Q2XMbUOFqti9JEa8Lg8sYk5VdwuNbPMA +3QMYKQUk9ieyLB4c3Nik3+XCuyVUKEc31A5egmz3umu7cn8i6vGuiJ/k/8t2YZ7s +Bry5Ihu95Yzab5DW3Eiqs0xKQN79ebS9AluAwQO5Wy2h52rknfuDHIm/M+BHsSoS +xl5KFQKBgQCokCsYuX1z2GojHw369/R2aX3ovCGuHqy4k7fWxUrpHTHvth2+qNPr +84qLJ9rLWoZE5sUiZ5YdwCgW877EdfkT+v4aaBX79ixso5VdqgJ/PdnoNntah/Vq +njQiW1skn6/P5V/eyimN2n0VsyBr/zMDEtYTRP/Tb1zi/njFLQkZEA== +-----END RSA PRIVATE KEY----- diff --git a/e2e/image/testdata/notary/delgkey2.crt b/e2e/image/testdata/notary/delgkey2.crt new file mode 100644 index 0000000000..bec084790a --- /dev/null +++ b/e2e/image/testdata/notary/delgkey2.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhTCCAm2gAwIBAgIJAIq8naKlYAQfMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV +BAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMQ8wDQYD +VQQKEwZEb2NrZXIxEzARBgNVBAMTCmRlbGVnYXRpb24wHhcNMTYwOTI4MTc0ODQ4 +WhcNMjYwNjI4MTc0ODQ4WjBXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFTAT +BgNVBAcTDFNhbkZyYW5jaXNjbzEPMA0GA1UEChMGRG9ja2VyMRMwEQYDVQQDEwpk +ZWxlZ2F0aW9uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyY2EWYTW +5VHipw08t675upmD6a+akiuZ1z+XpuOxZCgjZ0aHfoOe8wGKg3Ohz7UCBdD5Mob/ +L/qvRlsCaqPHGZKIyyX1HDO4mpuQQFBhYxt+ZAO3AaawEUOw2rwwMDEjLnDDTSZM +z8jxCMvsJjBDqgb8g3z+AmjducQ/OH6llldgHIBY8ioRbROCL2PGgqywWq2fThav +c70YMxtKviBGDNCouYeQ8JMK/PuLwPNDXNQAagFHVARXiUv/ILHk7ImYnSGJUcuk +JTUGN2MBnpY0eakg7i+4za8sjjqOdn+2I6aVzlGJDSiRP72nkg/cE4BqMl9FrMwK +9iS8xa9yMDLUvwIDAQABo1QwUjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF +oDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUvQzzFmh3Sv3HcdExY3wx +/1u6JLAwDQYJKoZIhvcNAQELBQADggEBAJcmDme2Xj/HPUPwaN/EyCmjhY73EiHO +x6Pm16tscg5JGn5A+u3CZ1DmxUYl8Hp6MaW/sWzdtL0oKJg76pynadCWh5EacFR8 +u+2GV/IcN9mSX6JQzvrqbjSqo5/FehqBD+W5h3euwwApWA3STAadYeyEfmdOA3SQ +W1vzrA1y7i8qgTqeJ7UX1sEAXlIhBK2zPYaMB+en+ZOiPyNxJYj6IDdGdD2paC9L +6H9wKC+GAUTSdCWp89HP7ETSXEGr94AXkrwU+qNsiN+OyK8ke0EMngEPh5IQoplw +/7zEZCth3oKxvR1/4S5LmTVaHI2ZlbU4q9bnY72G4tw8YQr2gcBGo4w= +-----END CERTIFICATE----- diff --git a/e2e/image/testdata/notary/delgkey2.key b/e2e/image/testdata/notary/delgkey2.key new file mode 100644 index 0000000000..5ccabe908f --- /dev/null +++ b/e2e/image/testdata/notary/delgkey2.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAyY2EWYTW5VHipw08t675upmD6a+akiuZ1z+XpuOxZCgjZ0aH +foOe8wGKg3Ohz7UCBdD5Mob/L/qvRlsCaqPHGZKIyyX1HDO4mpuQQFBhYxt+ZAO3 +AaawEUOw2rwwMDEjLnDDTSZMz8jxCMvsJjBDqgb8g3z+AmjducQ/OH6llldgHIBY +8ioRbROCL2PGgqywWq2fThavc70YMxtKviBGDNCouYeQ8JMK/PuLwPNDXNQAagFH +VARXiUv/ILHk7ImYnSGJUcukJTUGN2MBnpY0eakg7i+4za8sjjqOdn+2I6aVzlGJ +DSiRP72nkg/cE4BqMl9FrMwK9iS8xa9yMDLUvwIDAQABAoIBAHmffvzx7ydESWwa +zcfdu26BkptiTvjjfJrqEd4wSewxWGPKqJqMXE8xX99A2KTZClZuKuH1mmnecQQY +iRXGrK9ewFMuHYGeKEiLlPlqR8ohXhyGLVm+t0JDwaXMp5t9G0i73O5iLTm5fNGd +FGxa9YnVW20Q8MqNczbVGH1D1zInhxzzOyFzBd4bBBJ8PdrUdyLpd7+RxY2ghnbT +p9ZANR2vk5zmDLJgZx72n/u+miJWuhY6p0v3Vq4z/HHgdhf+K6vpDdzTcYlA0rO4 +c/c+RKED3ZadGUD5QoLsmEN0e3FVSMPN1kt4ZRTqWfH8f2X4mLz33aBryTjktP6+ +1rX6ThECgYEA74wc1Tq23B5R0/GaMm1AK3Ko2zzTD8wK7NSCElh2dls02B+GzrEB +aE3A2GMQSuzb+EA0zkipwANBaqs3ZemH5G1pu4hstQsXCMd4jAJn0TmTXlplXBCf +PSc8ZUU6XcJENRr9Q7O9/TGlgahX+z0ndxYx/CMCsSu7XsMg4IZsbAcCgYEA12Vb +wKOVG15GGp7pMshr+2rQfVimARUP4gf3JnQmenktI4PfdnMW3a4L3DEHfLhIerwT +6lRp/NpxSADmuT4h1UO1l2lc+gmTVPw0Vbl6VwHpgS5Kfu4ZyM6n3S66f/dE4nu7 +hQF9yZz7vn5Agghak4p6a1wC1gdMzR1tvxFzk4kCgYByBMTskWfcWeok8Yitm+bB +R3Ar+kWT7VD97SCETusD5uG+RTNLSmEbHnc+B9kHcLo67YS0800pAeOvPBPARGnU +RmffRU5I1iB+o0MzkSmNItSMQoagTaEd4IEUyuC/I+qHRHNsOC+kRm86ycAm67LP +MhdUpe1wGxqyPjp15EXTHQKBgDKzFu+3EWfJvvKRKQ7dAh3BvKVkcl6a2Iw5l8Ej +YdM+JpPPfI/i8yTmzL/dgoem0Nii4IUtrWzo9fUe0TAVId2S/HFRSaNJEbbVTnRH +HjbQqmfPv5U08jjD+9siHp/0UfCFc1QRT8xe+RqTmReCY9+KntoaZEiAm2FEZgqt +TukRAoGAf7QqbTP5/UH1KSkX89F5qy/6GS3pw6TLj9Ufm/l/NO8Um8gag6YhEKWR +7HpkpCqjfWj8Av8ESR9cqddPGrbdqXFm9z7dCjlAd5T3Q3h/h+v+JzLQWbsI6WOb +SsOSWNyE006ZZdIiFwO6GfxpLI24sVtYKgyob6Q71oxSqfnrnT0= +-----END RSA PRIVATE KEY----- diff --git a/e2e/image/testdata/notary/delgkey3.crt b/e2e/image/testdata/notary/delgkey3.crt new file mode 100644 index 0000000000..f434b45fc8 --- /dev/null +++ b/e2e/image/testdata/notary/delgkey3.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhTCCAm2gAwIBAgIJAKHt/jxiWqMtMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV +BAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMQ8wDQYD +VQQKEwZEb2NrZXIxEzARBgNVBAMTCmRlbGVnYXRpb24wHhcNMTYwOTI4MTc0ODQ5 +WhcNMjYwNjI4MTc0ODQ5WjBXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFTAT +BgNVBAcTDFNhbkZyYW5jaXNjbzEPMA0GA1UEChMGRG9ja2VyMRMwEQYDVQQDEwpk +ZWxlZ2F0aW9uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqfbJk2Dk +C9FJVjV2+Q2CQrJphG3vFc1Qlu9jgVA5RhGmF9jJzetsclsV/95nBhinIGcSmPQA +l318G7Bz/cG/6O2n5+hj+S1+YOvQweReZj3d4kCeS86SOyLNTpMD9gsF0S8nR1RN +h0jD4t1vxAVeGD1o61U8/k0O5eDoeOfOSWZagKk5PhyrMZgNip4IrG46umCkFlrw +zMMcgQdwTQXywPqkr/LmYpqT1WpMlzHYTQEY8rKorIJQbPtHVYdr4UxYnNmk6fbU +biEP1DQlwjBWcFTsDLqXKP/K+e3O0/e/hMB0y7Tj9fZ7Viw0t5IKXZPsxMhwknUT +9vmPzIJO6NiniwIDAQABo1QwUjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF +oDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUdTXRP1EzxQ+UDZSoheVo +Mobud1cwDQYJKoZIhvcNAQELBQADggEBADV9asTWWdbmpkeRuKyi0xGho39ONK88 +xxkFlco766BVgemo/rGQj3oPuw6M6SzHFoJ6JUPjmLiAQDIGEU/2/b6LcOuLjP+4 +YejCcDTY3lSW/HMNoAmzr2foo/LngNGfe/qhVFUqV7GjFT9+XzFFBfIZ1cQiL2ed +kc8rgQxFPwWXFCSwaENWeFnMDugkd+7xanoAHq8GsJpg5fTruDTmJkUqC2RNiMLn +WM7QaqW7+lmUnMnc1IBoz0hFhgoiadWM/1RQxx51zTVw6Au1koIm4ZXu5a+/WyC8 +K1+HyUbc0AVaDaRBpRSOR9aHRwLGh6WQ4aUZQNyJroc999qfYrDEEV8= +-----END CERTIFICATE----- diff --git a/e2e/image/testdata/notary/delgkey3.key b/e2e/image/testdata/notary/delgkey3.key new file mode 100644 index 0000000000..a61d18cc3d --- /dev/null +++ b/e2e/image/testdata/notary/delgkey3.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAqfbJk2DkC9FJVjV2+Q2CQrJphG3vFc1Qlu9jgVA5RhGmF9jJ +zetsclsV/95nBhinIGcSmPQAl318G7Bz/cG/6O2n5+hj+S1+YOvQweReZj3d4kCe +S86SOyLNTpMD9gsF0S8nR1RNh0jD4t1vxAVeGD1o61U8/k0O5eDoeOfOSWZagKk5 +PhyrMZgNip4IrG46umCkFlrwzMMcgQdwTQXywPqkr/LmYpqT1WpMlzHYTQEY8rKo +rIJQbPtHVYdr4UxYnNmk6fbUbiEP1DQlwjBWcFTsDLqXKP/K+e3O0/e/hMB0y7Tj +9fZ7Viw0t5IKXZPsxMhwknUT9vmPzIJO6NiniwIDAQABAoIBAQCAr/ed3A2umO7T +FDYZik3nXBiiiW4t7r+nGGgZ3/kNgY1lnuHlROxehXLZwbX1mrLnyML/BjhwezV9 +7ZNVPd6laVPpNj6DyxtWHRZ5yARlm1Al39E7CpQTrF0QsiWcpGnqIa62xjDRTpnq +askV/Q5qggyvqmE9FnFCQpEiAjlhvp7F0kVHVJm9s3MK3zSyR0UTZ3cpYus2Jr2z +OotHgAMHq5Hgb3dvxOeE2xRMeYAVDujbkNzXm2SddAtiRdLhWDh7JIr3zXhp0HyN +4rLOyhlgz00oIGeDt/C0q3fRmghr3iZOG+7m2sUx0FD1Ru1dI9v2A+jYmIVNW6+x +YJk5PzxJAoGBANDj7AGdcHSci/LDBPoTTUiz3uucAd27/IJma/iy8mdbVfOAb0Fy +PRSPvoozlpZyOxg2J4eH/o4QxQR4lVKtnLKZLNHK2tg3LarwyBX1LiI3vVlB+DT1 +AmV8i5bJAckDhqFeEH5qdWZFi03oZsSXWEqX5iMYCrdK5lTZggcrFZeHAoGBANBL +fkk3knAdcVfTYpmHx18GBi2AsCWTd20KD49YBdbVy0Y2Jaa1EJAmGWpTUKdYx40R +H5CuGgcAviXQz3bugdTU1I3tAclBtpJNU7JkhuE+Epz0CM/6WERJrE0YxcGQA5ui +6fOguFyiXD1/85jrDBOKy74aoS7lYz9r/a6eqmjdAoGBAJpm/nmrIAZx+Ff2ouUe +A1Ar9Ch/Zjm5zEmu3zwzOU4AiyWz14iuoktifNq2iyalRNz+mnVpplToPFizsNwu +C9dPtXtU0DJlhtIFrD/evLz6KnGhe4/ZUm4lgyBvb2xfuNHqL5Lhqelwmil6EQxb +Oh3Y7XkfOjyFln89TwlxZUJdAoGAJRMa4kta7EvBTeGZLjyltvsqhFTghX+vBSCC +ToBbYbbiHJgssXSPAylU4sD7nR3HPwuqM6VZip+OOMrm8oNXZpuPTce+xqTEq1vK +JvmPrG3RAFDLdMFZjqYSXhKnuGE60yv3Ol8EEbDwfB3XLQPBPYU56Jdy0xcPSE2f +dMJXEJ0CgYEAisZw0nXw6lFeYecu642EGuU0wv1O9i21p7eho9QwOcsoTl4Q9l+M +M8iBv+qTHO+D19l4JbkGvy2H2diKoYduUFACcuiFYs8fjrT+4Z6DyOQAQGAf6Ylw +BFbU15k6KbA9v4mZDfd1tY9x62L/XO55ZxYG+J+q0e26tEThgD8cEog= +-----END RSA PRIVATE KEY----- diff --git a/e2e/image/testdata/notary/delgkey4.crt b/e2e/image/testdata/notary/delgkey4.crt new file mode 100644 index 0000000000..c8cbe46bdf --- /dev/null +++ b/e2e/image/testdata/notary/delgkey4.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhTCCAm2gAwIBAgIJANae++ZkUEWMMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV +BAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMQ8wDQYD +VQQKEwZEb2NrZXIxEzARBgNVBAMTCmRlbGVnYXRpb24wHhcNMTYwOTI4MTc0ODQ5 +WhcNMjYwNjI4MTc0ODQ5WjBXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFTAT +BgNVBAcTDFNhbkZyYW5jaXNjbzEPMA0GA1UEChMGRG9ja2VyMRMwEQYDVQQDEwpk +ZWxlZ2F0aW9uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqULAjgba +Y2I10WfqdmYnPfEqEe6iMDbzcgECb2xKafXcI4ltkQj1iO4zBTs0Ft9EzXFc5ZBh +pTjZrL6vrIa0y/CH2BiIHBJ0wRHx/40HXp4DSj3HZpVOlEMI3npRfBGNIBllUaRN +PWG7zL7DcKMIepBfPXyjBsxzH3yNiISq0W5hSiy+ImhSo3aipJUHHcp9Z9NgvpNC +3QvnxsGKRnECmDRDlxkq+FQu9Iqs/HWFYWgyfcsw+YTrWZq3qVnnqUouHO//c9PG +Ry3sZSDU97MwvkjvWys1e01Xvd3AbHx08YAsxih58i/OBKe81eD9NuZDP2KrjTxI +5xkXKhj6DV2NnQIDAQABo1QwUjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF +oDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUDt95hiqbQvi0KcvZGAUu +VisnztQwDQYJKoZIhvcNAQELBQADggEBAGi7qHai7MWbfeu6SlXhzIP3AIMa8TMi +lp/+mvPUFPswIVqYJ71MAN8uA7CTH3z50a2vYupGeOEtZqVJeRf+xgOEpwycncxp +Qz6wc6TWPVIoT5q1Hqxw1RD2MyKL+Y+QBDYwFxFkthpDMlX48I9frcqoJUWFxBF2 +lnRr/cE7BbPE3sMbXV3wGPlH7+eUf+CgzXJo2HB6THzagyEgNrDiz/0rCQa1ipFd +mNU3D/U6BFGmJNxhvSOtXX9escg8yjr05YwwzokHS2K4jE0ZuJPBd50C/Rvo3Mf4 +0h7/2Q95e7d42zPe9WYPu2F8KTWsf4r+6ddhKrKhYzXIcTAfHIOiO+U= +-----END CERTIFICATE----- diff --git a/e2e/image/testdata/notary/delgkey4.key b/e2e/image/testdata/notary/delgkey4.key new file mode 100644 index 0000000000..f473cc495a --- /dev/null +++ b/e2e/image/testdata/notary/delgkey4.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAqULAjgbaY2I10WfqdmYnPfEqEe6iMDbzcgECb2xKafXcI4lt +kQj1iO4zBTs0Ft9EzXFc5ZBhpTjZrL6vrIa0y/CH2BiIHBJ0wRHx/40HXp4DSj3H +ZpVOlEMI3npRfBGNIBllUaRNPWG7zL7DcKMIepBfPXyjBsxzH3yNiISq0W5hSiy+ +ImhSo3aipJUHHcp9Z9NgvpNC3QvnxsGKRnECmDRDlxkq+FQu9Iqs/HWFYWgyfcsw ++YTrWZq3qVnnqUouHO//c9PGRy3sZSDU97MwvkjvWys1e01Xvd3AbHx08YAsxih5 +8i/OBKe81eD9NuZDP2KrjTxI5xkXKhj6DV2NnQIDAQABAoIBAGK0ZKnuYSiXux60 +5MvK4pOCsa/nY3mOcgVHhW4IzpRgJdIrcFOlz9ncXrBsSAIWjX7o3u2Ydvjs4DOW +t8d6frB3QiDInYcRVDjLCD6otWV97Bk9Ua0G4N4hAWkMF7ysV4oihS1JDSoAdo39 +qOdki6s9yeyHZGKwk2oHLlowU5TxQMBA8DHmxqBII1HTm+8xRz45bcEqRXydYSUn +P1JuSU9jFqdylxU+Nrq6ehslMQ3y7qNWQyiLGxu6EmR+vgrzSU0s3iAOqCHthaOS +VBBXPL3DNEYUS+0QGnGrACuJhanOMBfdiO6Orelx6ZzWZm38PNGv0yBt0WCM+8/A +TtQNGkECgYEA1LqR6AH9XikUQ0+rM4526BgVuYqtjw21h4Lj9alaA+YTQntBBJOv +iAcUpnJiV4T8jzAMLeqpK8R/rbxRnK5S9jOV2gr+puk4L6tH46cgahBUESDigDp8 +6vK8ur6ubBcXNPh3AT6rsPj+Ph2EU3raqiYdouvCdga/OCYZb+jr6UkCgYEAy7Cr +l8WssI/8/ORcQ4MFJFNyfz/Y2beNXyLd1PX0H+wRSiGcKzeUuTHNtzFFpMbrK/nx +ZOPCT2ROdHsBHzp1L+WquCb0fyMVSiYiXBU+VCFDbUU5tBr3ycTc7VwuFPENOiha +IdlWgew/aW110FQHIaqe9g+htRe+mXe++faZtbUCgYB/MSJmNzJX53XvHSZ/CBJ+ +iVAMBSfq3caJRLCqRNzGcf1YBbwFUYxlZ95n+wJj0+byckcF+UW3HqE8rtmZNf3y +qTtTCLnj8JQgpGeybU4LPMIXD7N9+fqQvBwuCC7gABpnGJyHCQK9KNNTLnDdPRqb +G3ki3ZYC3dvdZaJV8E2FyQKBgQCMa5Mf4kqWvezueo+QizZ0QILibqWUEhIH0AWV +1qkhiKCytlDvCjYhJdBnxjP40Jk3i+t6XfmKud/MNTAk0ywOhQoYQeKz8v+uSnPN +f2ekn/nXzq1lGGJSWsDjcXTjQvqXaVIZm7cjgjaE+80IfaUc9H75qvUT3vaq3f5u +XC7DMQKBgQDMAzCCpWlEPbZoFMl6F49+7jG0/TiqM/WRUSQnNtufPMbrR9Je4QM1 +L1UCANCPaHFOncKYer15NfIV1ctt5MZKImevDsUaQO8CUlO+dzd5H8KvHw9E29gA +B22v8k3jIjsYeRL+UJ/sBnWHgxdAe/NEM+TdlP2oP9D1gTifutPqAg== +-----END RSA PRIVATE KEY----- diff --git a/e2e/image/testdata/notary/gen.sh b/e2e/image/testdata/notary/gen.sh new file mode 100755 index 0000000000..8d6381cec4 --- /dev/null +++ b/e2e/image/testdata/notary/gen.sh @@ -0,0 +1,18 @@ +for selfsigned in delgkey1 delgkey2 delgkey3 delgkey4; do + subj='/C=US/ST=CA/L=SanFrancisco/O=Docker/CN=delegation' + + openssl genrsa -out "${selfsigned}.key" 2048 + openssl req -new -key "${selfsigned}.key" -out "${selfsigned}.csr" -sha256 -subj "${subj}" + cat > "${selfsigned}.cnf" <