Ver Fonte

Merge pull request #44566 from thaJeztah/23.0_backport_remove_trustkey_id_migration

[23.0 backport] use ad-hoc libtrust trustkey
Sebastiaan van Stijn há 2 anos atrás
pai
commit
3083236871

+ 1 - 1
cmd/dockerd/daemon_windows.go

@@ -24,7 +24,7 @@ func setDefaultUmask() error {
 }
 
 func getDaemonConfDir(root string) (string, error) {
-	return filepath.Join(root, `\config`), nil
+	return filepath.Join(root, "config"), nil
 }
 
 // preNotifyReady sends a message to the host when the API is active, but before the daemon is

+ 1 - 1
cmd/dockerd/docker_windows.go

@@ -24,7 +24,7 @@ func runDaemon(opts *daemonOptions) error {
 
 	// Windows specific settings as these are not defaulted.
 	if opts.configFile == "" {
-		opts.configFile = filepath.Join(opts.daemonConfig.Root, `config\daemon.json`)
+		opts.configFile = filepath.Join(opts.daemonConfig.Root, "config", "daemon.json")
 	}
 	if runAsService {
 		// If Windows SCM manages the service - no need for PID files

+ 0 - 2
cmd/dockerd/options.go

@@ -65,8 +65,6 @@ func (o *daemonOptions) installFlags(flags *pflag.FlagSet) {
 	flags.BoolVar(&o.TLS, FlagTLS, DefaultTLSValue, "Use TLS; implied by --tlsverify")
 	flags.BoolVar(&o.TLSVerify, FlagTLSVerify, dockerTLSVerify || DefaultTLSValue, "Use TLS and verify the remote")
 
-	// TODO use flag flags.String("identity"}, "i", "", "Path to libtrust key file")
-
 	o.TLSOptions = &tlsconfig.Options{}
 	tlsOptions := o.TLSOptions
 	flags.StringVar(&tlsOptions.CAFile, "tlscacert", filepath.Join(dockerCertPath, DefaultCaFile), "Trust certs signed only by this CA")

+ 0 - 13
daemon/daemon.go

@@ -1053,19 +1053,6 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
 		ContentNamespace:          config.ContainerdNamespace,
 	}
 
-	// This is a temporary environment variables used in CI to allow pushing
-	// manifest v2 schema 1 images to test-registries used for testing *pulling*
-	// these images.
-	if os.Getenv("DOCKER_ALLOW_SCHEMA1_PUSH_DONOTUSE") != "" {
-		imgSvcConfig.TrustKey, err = loadOrCreateTrustKey(config.TrustKeyPath)
-		if err != nil {
-			return nil, err
-		}
-		if err = system.MkdirAll(filepath.Join(config.Root, "trust"), 0700); err != nil {
-			return nil, err
-		}
-	}
-
 	// containerd is not currently supported with Windows.
 	// So sometimes d.containerdCli will be nil
 	// In that case we'll create a local content store... but otherwise we'll use containerd

+ 0 - 1
daemon/images/image_push.go

@@ -54,7 +54,6 @@ func (i *ImageService) PushImage(ctx context.Context, image, tag string, metaHea
 		},
 		ConfigMediaType: schema2.MediaTypeImageConfig,
 		LayerStores:     distribution.NewLayerProvidersFromStore(i.layerStore),
-		TrustKey:        i.trustKey,
 		UploadManager:   i.uploadManager,
 	}
 

+ 0 - 4
daemon/images/service.go

@@ -17,7 +17,6 @@ import (
 	"github.com/docker/docker/layer"
 	dockerreference "github.com/docker/docker/reference"
 	"github.com/docker/docker/registry"
-	"github.com/docker/libtrust"
 	"github.com/opencontainers/go-digest"
 	"github.com/pkg/errors"
 	"golang.org/x/sync/singleflight"
@@ -44,7 +43,6 @@ type ImageServiceConfig struct {
 	MaxDownloadAttempts       int
 	ReferenceStore            dockerreference.Store
 	RegistryService           registry.Service
-	TrustKey                  libtrust.PrivateKey
 	ContentStore              content.Store
 	Leases                    leases.Manager
 	ContentNamespace          string
@@ -61,7 +59,6 @@ func NewImageService(config ImageServiceConfig) *ImageService {
 		layerStore:                config.LayerStore,
 		referenceStore:            config.ReferenceStore,
 		registryService:           config.RegistryService,
-		trustKey:                  config.TrustKey,
 		uploadManager:             xfer.NewLayerUploadManager(config.MaxConcurrentUploads),
 		leases:                    config.Leases,
 		content:                   config.ContentStore,
@@ -80,7 +77,6 @@ type ImageService struct {
 	pruneRunning              int32
 	referenceStore            dockerreference.Store
 	registryService           registry.Service
-	trustKey                  libtrust.PrivateKey
 	uploadManager             *xfer.LayerUploadManager
 	leases                    leases.Manager
 	content                   content.Store

+ 0 - 57
daemon/trustkey.go

@@ -1,57 +0,0 @@
-package daemon // import "github.com/docker/docker/daemon"
-
-import (
-	"encoding/json"
-	"encoding/pem"
-	"fmt"
-	"os"
-	"path/filepath"
-
-	"github.com/docker/docker/pkg/ioutils"
-	"github.com/docker/docker/pkg/system"
-	"github.com/docker/libtrust"
-)
-
-// LoadOrCreateTrustKey attempts to load the libtrust key at the given path,
-// otherwise generates a new one
-// TODO: this should use more of libtrust.LoadOrCreateTrustKey which may need
-// a refactor or this function to be moved into libtrust
-func loadOrCreateTrustKey(trustKeyPath string) (libtrust.PrivateKey, error) {
-	err := system.MkdirAll(filepath.Dir(trustKeyPath), 0755)
-	if err != nil {
-		return nil, err
-	}
-	trustKey, err := libtrust.LoadKeyFile(trustKeyPath)
-	if err == libtrust.ErrKeyFileDoesNotExist {
-		trustKey, err = libtrust.GenerateECP256PrivateKey()
-		if err != nil {
-			return nil, fmt.Errorf("Error generating key: %s", err)
-		}
-		encodedKey, err := serializePrivateKey(trustKey, filepath.Ext(trustKeyPath))
-		if err != nil {
-			return nil, fmt.Errorf("Error serializing key: %s", err)
-		}
-		if err := ioutils.AtomicWriteFile(trustKeyPath, encodedKey, os.FileMode(0600)); err != nil {
-			return nil, fmt.Errorf("Error saving key file: %s", err)
-		}
-	} else if err != nil {
-		return nil, fmt.Errorf("Error loading key file %s: %s", trustKeyPath, err)
-	}
-	return trustKey, nil
-}
-
-func serializePrivateKey(key libtrust.PrivateKey, ext string) (encoded []byte, err error) {
-	if ext == ".json" || ext == ".jwk" {
-		encoded, err = json.Marshal(key)
-		if err != nil {
-			return nil, fmt.Errorf("unable to encode private key JWK: %s", err)
-		}
-	} else {
-		pemBlock, err := key.PEMBlock()
-		if err != nil {
-			return nil, fmt.Errorf("unable to encode private key PEM: %s", err)
-		}
-		encoded = pem.EncodeToMemory(pemBlock)
-	}
-	return
-}

+ 0 - 71
daemon/trustkey_test.go

@@ -1,71 +0,0 @@
-package daemon // import "github.com/docker/docker/daemon"
-
-import (
-	"os"
-	"path/filepath"
-	"testing"
-
-	"gotest.tools/v3/assert"
-	is "gotest.tools/v3/assert/cmp"
-	"gotest.tools/v3/fs"
-)
-
-// LoadOrCreateTrustKey
-func TestLoadOrCreateTrustKeyInvalidKeyFile(t *testing.T) {
-	tmpKeyFolderPath, err := os.MkdirTemp("", "api-trustkey-test")
-	assert.NilError(t, err)
-	defer os.RemoveAll(tmpKeyFolderPath)
-
-	tmpKeyFile, err := os.CreateTemp(tmpKeyFolderPath, "keyfile")
-	assert.NilError(t, err)
-	defer tmpKeyFile.Close()
-
-	_, err = loadOrCreateTrustKey(tmpKeyFile.Name())
-	assert.Check(t, is.ErrorContains(err, "Error loading key file"))
-}
-
-func TestLoadOrCreateTrustKeyCreateKeyWhenFileDoesNotExist(t *testing.T) {
-	tmpKeyFolderPath := fs.NewDir(t, "api-trustkey-test")
-	defer tmpKeyFolderPath.Remove()
-
-	// Without the need to create the folder hierarchy
-	tmpKeyFile := tmpKeyFolderPath.Join("keyfile")
-
-	key, err := loadOrCreateTrustKey(tmpKeyFile)
-	assert.NilError(t, err)
-	assert.Check(t, key != nil)
-
-	_, err = os.Stat(tmpKeyFile)
-	assert.NilError(t, err, "key file doesn't exist")
-}
-
-func TestLoadOrCreateTrustKeyCreateKeyWhenDirectoryDoesNotExist(t *testing.T) {
-	tmpKeyFolderPath := fs.NewDir(t, "api-trustkey-test")
-	defer tmpKeyFolderPath.Remove()
-	tmpKeyFile := tmpKeyFolderPath.Join("folder/hierarchy/keyfile")
-
-	key, err := loadOrCreateTrustKey(tmpKeyFile)
-	assert.NilError(t, err)
-	assert.Check(t, key != nil)
-
-	_, err = os.Stat(tmpKeyFile)
-	assert.NilError(t, err, "key file doesn't exist")
-}
-
-func TestLoadOrCreateTrustKeyCreateKeyNoPath(t *testing.T) {
-	defer os.Remove("keyfile")
-	key, err := loadOrCreateTrustKey("keyfile")
-	assert.NilError(t, err)
-	assert.Check(t, key != nil)
-
-	_, err = os.Stat("keyfile")
-	assert.NilError(t, err, "key file doesn't exist")
-}
-
-func TestLoadOrCreateTrustKeyLoadValidKey(t *testing.T) {
-	tmpKeyFile := filepath.Join("testdata", "keyfile")
-	key, err := loadOrCreateTrustKey(tmpKeyFile)
-	assert.NilError(t, err)
-	expected := "AWX2:I27X:WQFX:IOMK:CNAK:O7PW:VYNB:ZLKC:CVAE:YJP2:SI4A:XXAY"
-	assert.Check(t, is.Contains(key.String(), expected))
-}

+ 0 - 6
distribution/config.go

@@ -17,7 +17,6 @@ import (
 	"github.com/docker/docker/pkg/system"
 	refstore "github.com/docker/docker/reference"
 	"github.com/docker/docker/registry"
-	"github.com/docker/libtrust"
 	"github.com/opencontainers/go-digest"
 	specs "github.com/opencontainers/image-spec/specs-go/v1"
 	"github.com/pkg/errors"
@@ -47,8 +46,6 @@ type Config struct {
 	// ReferenceStore manages tags. This value is optional, when excluded
 	// content will not be tagged.
 	ReferenceStore refstore.Store
-	// RequireSchema2 ensures that only schema2 manifests are used.
-	RequireSchema2 bool
 }
 
 // ImagePullConfig stores pull configuration.
@@ -74,9 +71,6 @@ type ImagePushConfig struct {
 	ConfigMediaType string
 	// LayerStores manages layers.
 	LayerStores PushLayerProvider
-	// TrustKey is the private key for legacy signatures. This is typically
-	// an ephemeral key, since these signatures are no longer verified.
-	TrustKey libtrust.PrivateKey
 	// UploadManager dispatches uploads.
 	UploadManager *xfer.LayerUploadManager
 }

+ 0 - 4
distribution/pull_v2.go

@@ -438,10 +438,6 @@ func (p *puller) pullTag(ctx context.Context, ref reference.Named, platform *spe
 
 	switch v := manifest.(type) {
 	case *schema1.SignedManifest:
-		if p.config.RequireSchema2 {
-			return false, fmt.Errorf("invalid manifest: not schema2")
-		}
-
 		// give registries time to upgrade to schema2 and only warn if we know a registry has been upgraded long time ago
 		// TODO: condition to be removed
 		if reference.Domain(ref) == "docker.io" {

+ 7 - 2
distribution/push_v2.go

@@ -24,6 +24,7 @@ import (
 	"github.com/docker/docker/pkg/progress"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/registry"
+	"github.com/docker/libtrust"
 	"github.com/opencontainers/go-digest"
 	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
@@ -187,7 +188,7 @@ func (p *pusher) pushTag(ctx context.Context, ref reference.NamedTagged, id dige
 
 	putOptions := []distribution.ManifestServiceOption{distribution.WithTag(ref.Tag())}
 	if _, err = manSvc.Put(ctx, manifest, putOptions...); err != nil {
-		if runtime.GOOS == "windows" || p.config.TrustKey == nil || p.config.RequireSchema2 {
+		if runtime.GOOS == "windows" {
 			logrus.Warnf("failed to upload schema2 manifest: %v", err)
 			return err
 		}
@@ -211,7 +212,11 @@ func (p *pusher) pushTag(ctx context.Context, ref reference.NamedTagged, id dige
 		if err != nil {
 			return err
 		}
-		builder = schema1.NewConfigManifestBuilder(p.repo.Blobs(ctx), p.config.TrustKey, manifestRef, imgConfig)
+		pk, err := libtrust.GenerateECP256PrivateKey()
+		if err != nil {
+			return errors.Wrap(err, "unexpected error generating private key")
+		}
+		builder = schema1.NewConfigManifestBuilder(p.repo.Blobs(ctx), pk, manifestRef, imgConfig)
 		manifest, err = manifestFromBuilder(ctx, builder, descriptors)
 		if err != nil {
 			return err

+ 0 - 73
integration-cli/docker_cli_daemon_test.go

@@ -35,7 +35,6 @@ import (
 	"github.com/docker/docker/opts"
 	testdaemon "github.com/docker/docker/testutil/daemon"
 	units "github.com/docker/go-units"
-	"github.com/docker/libtrust"
 	"github.com/moby/sys/mount"
 	"golang.org/x/sys/unix"
 	"gotest.tools/v3/assert"
@@ -556,24 +555,6 @@ func (s *DockerDaemonSuite) TestDaemonAllocatesListeningPort(c *testing.T) {
 	}
 }
 
-func (s *DockerDaemonSuite) TestDaemonKeyGeneration(c *testing.T) {
-	// TODO: skip or update for Windows daemon
-	os.Remove("/etc/docker/key.json")
-	c.Setenv("DOCKER_ALLOW_SCHEMA1_PUSH_DONOTUSE", "1")
-	s.d.Start(c)
-	s.d.Stop(c)
-
-	k, err := libtrust.LoadKeyFile("/etc/docker/key.json")
-	if err != nil {
-		c.Fatalf("Error opening key file")
-	}
-	kid := k.KeyID()
-	// Test Key ID is a valid fingerprint (e.g. QQXN:JY5W:TBXI:MK3X:GX6P:PD5D:F56N:NHCS:LVRZ:JA46:R24J:XEFF)
-	if len(kid) != 59 {
-		c.Fatalf("Bad key ID: %s", kid)
-	}
-}
-
 // GH#11320 - verify that the daemon exits on failure properly
 // Note that this explicitly tests the conflict of {-b,--bridge} and {--bip} options as the means
 // to get a daemon init failure; no other tests for -b/--bip conflict are therefore required
@@ -1201,60 +1182,6 @@ func (s *DockerDaemonSuite) TestDaemonUnixSockCleanedUp(c *testing.T) {
 	}
 }
 
-func (s *DockerDaemonSuite) TestDaemonWithWrongkey(c *testing.T) {
-	type Config struct {
-		Crv string `json:"crv"`
-		D   string `json:"d"`
-		Kid string `json:"kid"`
-		Kty string `json:"kty"`
-		X   string `json:"x"`
-		Y   string `json:"y"`
-	}
-
-	os.Remove("/etc/docker/key.json")
-	c.Setenv("DOCKER_ALLOW_SCHEMA1_PUSH_DONOTUSE", "1")
-	s.d.Start(c)
-	s.d.Stop(c)
-
-	config := &Config{}
-	bytes, err := os.ReadFile("/etc/docker/key.json")
-	if err != nil {
-		c.Fatalf("Error reading key.json file: %s", err)
-	}
-
-	// byte[] to Data-Struct
-	if err := json.Unmarshal(bytes, &config); err != nil {
-		c.Fatalf("Error Unmarshal: %s", err)
-	}
-
-	// replace config.Kid with the fake value
-	config.Kid = "VSAJ:FUYR:X3H2:B2VZ:KZ6U:CJD5:K7BX:ZXHY:UZXT:P4FT:MJWG:HRJ4"
-
-	// NEW Data-Struct to byte[]
-	newBytes, err := json.Marshal(&config)
-	if err != nil {
-		c.Fatalf("Error Marshal: %s", err)
-	}
-
-	// write back
-	if err := os.WriteFile("/etc/docker/key.json", newBytes, 0400); err != nil {
-		c.Fatalf("Error os.WriteFile: %s", err)
-	}
-
-	defer os.Remove("/etc/docker/key.json")
-
-	if err := s.d.StartWithError(); err == nil {
-		c.Fatalf("It should not be successful to start daemon with wrong key: %v", err)
-	}
-
-	content, err := s.d.ReadLogFile()
-	assert.Assert(c, err == nil)
-
-	if !strings.Contains(string(content), "Public Key ID does not match") {
-		c.Fatalf("Missing KeyID message from daemon logs: %s", string(content))
-	}
-}
-
 func (s *DockerDaemonSuite) TestDaemonRestartKillWait(c *testing.T) {
 	s.d.StartWithBusybox(c)
 

+ 0 - 19
integration/daemon/daemon_test.go

@@ -29,25 +29,6 @@ const (
 	libtrustKeyID = "WTJ3:YSIP:CE2E:G6KJ:PSBD:YX2Y:WEYD:M64G:NU2V:XPZV:H2CR:VLUB"
 )
 
-func TestConfigDaemonLibtrustID(t *testing.T) {
-	skip.If(t, runtime.GOOS == "windows")
-
-	d := daemon.New(t)
-	defer d.Stop(t)
-
-	trustKey := filepath.Join(d.RootDir(), "key.json")
-	err := os.WriteFile(trustKey, []byte(libtrustKey), 0644)
-	assert.NilError(t, err)
-
-	cfg := filepath.Join(d.RootDir(), "daemon.json")
-	err = os.WriteFile(cfg, []byte(`{"deprecated-key-path": "`+trustKey+`"}`), 0644)
-	assert.NilError(t, err)
-
-	d.Start(t, "--config-file", cfg)
-	info := d.Info(t)
-	assert.Equal(t, info.ID, libtrustKeyID)
-}
-
 func TestConfigDaemonID(t *testing.T) {
 	skip.If(t, runtime.GOOS == "windows")