diff options
| -rw-r--r-- | actions/context.go | 13 | ||||
| -rw-r--r-- | actions/policy.go | 16 | ||||
| -rw-r--r-- | cmd/fscrypt/status.go | 18 | ||||
| -rw-r--r-- | keyring/fs_keyring.go | 211 | ||||
| -rw-r--r-- | keyring/keyring.go | 46 | ||||
| -rw-r--r-- | keyring/keyring_test.go | 132 | ||||
| -rw-r--r-- | keyring/user_keyring.go | 3 | ||||
| -rw-r--r-- | metadata/config_test.go | 3 | ||||
| -rw-r--r-- | metadata/metadata.pb.go | 133 | ||||
| -rw-r--r-- | metadata/metadata.proto | 1 |
10 files changed, 470 insertions, 106 deletions
diff --git a/actions/context.go b/actions/context.go index 7703db5..f7e98cf 100644 --- a/actions/context.go +++ b/actions/context.go @@ -58,10 +58,11 @@ type Context struct { // modified after being loaded to customise parameters. Config *metadata.Config // Mount is the filesystem relative to which all Protectors and Policies - // are added, edited, removed, and applied. + // are added, edited, removed, and applied, and to which policies using + // the filesystem keyring are provisioned. Mount *filesystem.Mount - // TargetUser is the user for which protectors are created and to whose - // keyring policies are provisioned. + // TargetUser is the user for whom protectors are created, and to whose + // keyring policies using the user keyring are provisioned. TargetUser *user.User } @@ -148,8 +149,10 @@ func (ctx *Context) getService() string { func (ctx *Context) getKeyringOptions() *keyring.Options { return &keyring.Options{ - User: ctx.TargetUser, - Service: ctx.getService(), + Mount: ctx.Mount, + User: ctx.TargetUser, + Service: ctx.getService(), + UseFsKeyringForV1Policies: ctx.Config.GetUseFsKeyringForV1Policies(), } } diff --git a/actions/policy.go b/actions/policy.go index 5bc2c5c..6ef83ce 100644 --- a/actions/policy.go +++ b/actions/policy.go @@ -44,8 +44,8 @@ var ( ) // PurgeAllPolicies removes all policy keys on the filesystem from the kernel -// keyring. In order for this removal to have an effect, the filesystem should -// also be unmounted. +// keyring. In order for this to fully take effect, the filesystem may also need +// to be unmounted or caches dropped. func PurgeAllPolicies(ctx *Context) error { if err := ctx.checkContext(); err != nil { return err @@ -60,6 +60,9 @@ func PurgeAllPolicies(ctx *Context) error { switch errors.Cause(err) { case nil, keyring.ErrKeyNotPresent: // We don't care if the key has already been removed + case keyring.ErrKeyFilesOpen: + log.Printf("Key for policy %s couldn't be fully removed because some files are still in-use", + policyDescriptor) default: return err } @@ -379,6 +382,12 @@ func (policy *Policy) IsProvisioned() bool { return policy.GetProvisioningStatus() == keyring.KeyPresent } +// IsFullyDeprovisioned returns true if the policy has been fully deprovisioned, +// including all files protected by it having been closed. +func (policy *Policy) IsFullyDeprovisioned() bool { + return policy.GetProvisioningStatus() == keyring.KeyAbsent +} + // Provision inserts the Policy key into the kernel keyring. This allows reading // and writing of files encrypted with this directory. Requires unlocked Policy. func (policy *Policy) Provision() error { @@ -390,7 +399,8 @@ func (policy *Policy) Provision() error { } // Deprovision removes the Policy key from the kernel keyring. This prevents -// reading and writing to the directory once the caches are cleared. +// reading and writing to the directory --- unless the target keyring is a user +// keyring, in which case caches must be dropped too. func (policy *Policy) Deprovision() error { return keyring.RemoveEncryptionKey(policy.Descriptor(), policy.Context.getKeyringOptions()) diff --git a/cmd/fscrypt/status.go b/cmd/fscrypt/status.go index 375899b..3f7f577 100644 --- a/cmd/fscrypt/status.go +++ b/cmd/fscrypt/status.go @@ -31,6 +31,7 @@ import ( "github.com/google/fscrypt/actions" "github.com/google/fscrypt/filesystem" + "github.com/google/fscrypt/keyring" "github.com/google/fscrypt/metadata" ) @@ -65,6 +66,19 @@ func yesNoString(b bool) string { return "No" } +func policyUnlockedStatus(policy *actions.Policy) string { + switch policy.GetProvisioningStatus() { + case keyring.KeyPresent: + return "Yes" + case keyring.KeyAbsent: + return "No" + case keyring.KeyAbsentButFilesBusy: + return "Partially (incompletely locked)" + default: + return "Unknown" + } +} + // writeGlobalStatus prints all the filesystems that use (or could use) fscrypt. func writeGlobalStatus(w io.Writer) error { mounts, err := filesystem.AllFilesystems() @@ -160,7 +174,7 @@ func writeFilesystemStatus(w io.Writer, ctx *actions.Context) error { continue } - fmt.Fprintf(t, "%s\t%s\t%s\n", descriptor, yesNoString(policy.IsProvisioned()), + fmt.Fprintf(t, "%s\t%s\t%s\n", descriptor, policyUnlockedStatus(policy), strings.Join(policy.ProtectorDescriptors(), ", ")) } return t.Flush() @@ -180,7 +194,7 @@ func writePathStatus(w io.Writer, path string) error { fmt.Fprintln(w) fmt.Fprintf(w, "Policy: %s\n", policy.Descriptor()) fmt.Fprintf(w, "Options: %s\n", policy.Options()) - fmt.Fprintf(w, "Unlocked: %s\n", yesNoString(policy.IsProvisioned())) + fmt.Fprintf(w, "Unlocked: %s\n", policyUnlockedStatus(policy)) fmt.Fprintln(w) options := policy.ProtectorOptions() diff --git a/keyring/fs_keyring.go b/keyring/fs_keyring.go new file mode 100644 index 0000000..bed23af --- /dev/null +++ b/keyring/fs_keyring.go @@ -0,0 +1,211 @@ +/* + * fs_keyring.go - Add/remove encryption policy keys to/from filesystem + * + * Copyright 2019 Google LLC + * Author: Eric Biggers (ebiggers@google.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package keyring + +/* +#include <string.h> +*/ +import "C" + +import ( + "encoding/hex" + "log" + "os" + "os/user" + "sync" + "unsafe" + + "github.com/pkg/errors" + "golang.org/x/sys/unix" + + "github.com/google/fscrypt/crypto" + "github.com/google/fscrypt/filesystem" +) + +var ( + fsKeyringSupported bool + fsKeyringSupportedKnown bool + fsKeyringSupportedLock sync.Mutex +) + +func checkForFsKeyringSupport(mount *filesystem.Mount) bool { + dir, err := os.Open(mount.Path) + if err != nil { + log.Printf("Unexpected error opening %q. Assuming filesystem keyring is unsupported.", + mount.Path) + return false + } + defer dir.Close() + + // FS_IOC_ADD_ENCRYPTION_KEY with a NULL argument will fail with ENOTTY + // if the ioctl isn't supported. Otherwise it should fail with EFAULT. + // + // Note that there's no need to check for FS_IOC_REMOVE_ENCRYPTION_KEY + // support separately, since it's guaranteed to be available if + // FS_IOC_ADD_ENCRYPTION_KEY is. There's also no need to check for + // support on every filesystem separately, since either the kernel + // supports the ioctls on all fscrypt-capable filesystems or it doesn't. + _, _, errno := unix.Syscall(unix.SYS_IOCTL, dir.Fd(), unix.FS_IOC_ADD_ENCRYPTION_KEY, 0) + if errno == unix.ENOTTY { + log.Printf("Kernel doesn't support filesystem keyring. Falling back to user keyring.") + return false + } + if errno == unix.EFAULT { + log.Printf("Detected support for filesystem keyring") + } else { + // EFAULT is expected, but as long as we didn't get ENOTTY the + // ioctl should be available. + log.Printf("Unexpected error from FS_IOC_ADD_ENCRYPTION_KEY(%q, NULL): %v", mount.Path, errno) + } + return true +} + +// isFsKeyringSupported returns true if the kernel supports the ioctls to +// add/remove fscrypt keys directly to/from the filesystem. For support to be +// detected, the given Mount must be for a filesystem that supports fscrypt. +func isFsKeyringSupported(mount *filesystem.Mount) bool { + fsKeyringSupportedLock.Lock() + defer fsKeyringSupportedLock.Unlock() + if !fsKeyringSupportedKnown { + fsKeyringSupported = checkForFsKeyringSupport(mount) + fsKeyringSupportedKnown = true + } + return fsKeyringSupported +} + +// buildKeySpecifier converts the key descriptor string to an FscryptKeySpecifier. +func buildKeySpecifier(spec *unix.FscryptKeySpecifier, descriptor string) error { + descriptorBytes, err := hex.DecodeString(descriptor) + if err != nil { + return errors.Errorf("key descriptor %q is invalid", descriptor) + } + switch len(descriptorBytes) { + case unix.FSCRYPT_KEY_DESCRIPTOR_SIZE: + spec.Type = unix.FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR + default: + return errors.Errorf("key descriptor %q has unknown length", descriptor) + } + copy(spec.U[:], descriptorBytes) + return nil +} + +// fsAddEncryptionKey adds the specified encryption key to the specified filesystem. +func fsAddEncryptionKey(key *crypto.Key, descriptor string, + mount *filesystem.Mount, user *user.User) error { + + dir, err := os.Open(mount.Path) + if err != nil { + return err + } + defer dir.Close() + + argKey, err := crypto.NewBlankKey(int(unsafe.Sizeof(unix.FscryptAddKeyArg{})) + key.Len()) + if err != nil { + return err + } + defer argKey.Wipe() + arg := (*unix.FscryptAddKeyArg)(argKey.UnsafePtr()) + + if err = buildKeySpecifier(&arg.Key_spec, descriptor); err != nil { + return err + } + + raw := unsafe.Pointer(uintptr(argKey.UnsafePtr()) + unsafe.Sizeof(*arg)) + arg.Raw_size = uint32(key.Len()) + C.memcpy(raw, key.UnsafePtr(), C.size_t(key.Len())) + + _, _, errno := unix.Syscall(unix.SYS_IOCTL, dir.Fd(), + unix.FS_IOC_ADD_ENCRYPTION_KEY, uintptr(argKey.UnsafePtr())) + log.Printf("FS_IOC_ADD_ENCRYPTION_KEY(%q, %s, <raw>) = %v", mount.Path, descriptor, errno) + if errno != 0 { + return errors.Wrap(ErrKeyAdd, errno.Error()) + } + return nil +} + +// fsRemoveEncryptionKey removes the specified encryption key from the specified +// filesystem. +func fsRemoveEncryptionKey(descriptor string, mount *filesystem.Mount, + user *user.User) error { + + dir, err := os.Open(mount.Path) + if err != nil { + return err + } + defer dir.Close() + + var arg unix.FscryptRemoveKeyArg + if err = buildKeySpecifier(&arg.Key_spec, descriptor); err != nil { + return err + } + + _, _, errno := unix.Syscall(unix.SYS_IOCTL, dir.Fd(), + unix.FS_IOC_REMOVE_ENCRYPTION_KEY, uintptr(unsafe.Pointer(&arg))) + log.Printf("FS_IOC_REMOVE_ENCRYPTION_KEY(%q, %s) = %v, removal_status_flags=0x%x", + mount.Path, descriptor, errno, arg.Removal_status_flags) + switch errno { + case 0: + if arg.Removal_status_flags&unix.FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY != 0 { + return ErrKeyFilesOpen + } + return nil + case unix.ENOKEY: + return ErrKeyNotPresent + default: + return errors.Wrap(ErrKeyRemove, errno.Error()) + } +} + +// fsGetEncryptionKeyStatus gets the status of the specified encryption key on +// the specified filesystem. +func fsGetEncryptionKeyStatus(descriptor string, mount *filesystem.Mount, + user *user.User) (KeyStatus, error) { + + dir, err := os.Open(mount.Path) + if err != nil { + return KeyStatusUnknown, err + } + defer dir.Close() + + var arg unix.FscryptGetKeyStatusArg + err = buildKeySpecifier(&arg.Key_spec, descriptor) + if err != nil { + return KeyStatusUnknown, err + } + + _, _, errno := unix.Syscall(unix.SYS_IOCTL, dir.Fd(), + unix.FS_IOC_GET_ENCRYPTION_KEY_STATUS, uintptr(unsafe.Pointer(&arg))) + log.Printf("FS_IOC_GET_ENCRYPTION_KEY_STATUS(%q, %s) = %v, status=%d, status_flags=0x%x", + mount.Path, descriptor, errno, arg.Status, arg.Status_flags) + if errno != 0 { + return KeyStatusUnknown, errors.Wrap(ErrKeySearch, errno.Error()) + } + switch arg.Status { + case unix.FSCRYPT_KEY_STATUS_ABSENT: + return KeyAbsent, nil + case unix.FSCRYPT_KEY_STATUS_PRESENT: + return KeyPresent, nil + case unix.FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED: + return KeyAbsentButFilesBusy, nil + default: + return KeyStatusUnknown, + errors.Wrapf(ErrKeySearch, "unknown key status (%d)", arg.Status) + } +} diff --git a/keyring/keyring.go b/keyring/keyring.go index 7a5fd64..f0bd1b7 100644 --- a/keyring/keyring.go +++ b/keyring/keyring.go @@ -19,7 +19,11 @@ // Package keyring manages adding, removing, and getting the status of // encryption policy keys to/from the kernel. Most public functions are in -// keyring.go, and they delegate to user_keyring.go. +// keyring.go, and they delegate to either user_keyring.go or fs_keyring.go, +// depending on whether a user keyring or a filesystem keyring is being used. +// +// v1 policies use the user keyring by default, but can be configured to use the +// filesystem keyring instead (requires root and kernel v5.4+). package keyring import ( @@ -29,6 +33,7 @@ import ( "github.com/pkg/errors" "github.com/google/fscrypt/crypto" + "github.com/google/fscrypt/filesystem" "github.com/google/fscrypt/metadata" "github.com/google/fscrypt/util" ) @@ -38,6 +43,7 @@ var ( ErrKeyAdd = util.SystemError("could not add key to the keyring") ErrKeyRemove = util.SystemError("could not remove key from the keyring") ErrKeyNotPresent = errors.New("key not present or already removed") + ErrKeyFilesOpen = errors.New("some files using the key are still open") ErrKeySearch = errors.New("could not find key with descriptor") ErrSessionUserKeying = errors.New("user keyring not linked into session keyring") ErrAccessUserKeyring = errors.New("could not access user keyring") @@ -47,22 +53,47 @@ var ( // Options are the options which specify *which* keyring the key should be // added/removed/gotten to, and how. type Options struct { + // Mount is the filesystem to which the key should be + // added/removed/gotten. + Mount *filesystem.Mount // User is the user for whom the key should be added/removed/gotten. User *user.User - // Service is the prefix to prepend to the description of the keys. + // Service is the prefix to prepend to the description of the keys in + // user keyrings. Not relevant for filesystem keyrings. Service string + // UseFsKeyringForV1Policies is true if keys for v1 encryption policies + // should be put in the filesystem's keyring (if supported) rather than + // in the user's keyring. Note that this makes AddEncryptionKey and + // RemoveEncryptionKey require root privileges. + UseFsKeyringForV1Policies bool } -// AddEncryptionKey adds an encryption policy key to a kernel keyring. +func shouldUseFsKeyring(descriptor string, options *Options) bool { + // Use the filesystem keyring if use_fs_keyring_for_v1_policies is set + // in /etc/fscrypt.conf and the kernel supports it. + return options.UseFsKeyringForV1Policies && isFsKeyringSupported(options.Mount) +} + +// AddEncryptionKey adds an encryption policy key to a kernel keyring. It uses +// either the filesystem keyring for the target Mount or the user keyring for +// the target User. func AddEncryptionKey(key *crypto.Key, descriptor string, options *Options) error { if err := util.CheckValidLength(metadata.PolicyKeyLen, key.Len()); err != nil { return errors.Wrap(err, "policy key") } + if shouldUseFsKeyring(descriptor, options) { + return fsAddEncryptionKey(key, descriptor, options.Mount, options.User) + } return userAddKey(key, options.Service+descriptor, options.User) } // RemoveEncryptionKey removes an encryption policy key from a kernel keyring. +// It uses either the filesystem keyring for the target Mount or the user +// keyring for the target User. func RemoveEncryptionKey(descriptor string, options *Options) error { + if shouldUseFsKeyring(descriptor, options) { + return fsRemoveEncryptionKey(descriptor, options.Mount, options.User) + } return userRemoveKey(options.Service+descriptor, options.User) } @@ -73,6 +104,7 @@ type KeyStatus int const ( KeyStatusUnknown = 0 + iota KeyAbsent + KeyAbsentButFilesBusy KeyPresent ) @@ -82,6 +114,8 @@ func (status KeyStatus) String() string { return "Unknown" case KeyAbsent: return "Absent" + case KeyAbsentButFilesBusy: + return "AbsentButFilesBusy" case KeyPresent: return "Present" default: @@ -90,8 +124,12 @@ func (status KeyStatus) String() string { } // GetEncryptionKeyStatus gets the status of an encryption policy key in a -// kernel keyring. +// kernel keyring. It uses either the filesystem keyring for the target Mount +// or the user keyring for the target User. func GetEncryptionKeyStatus(descriptor string, options *Options) (KeyStatus, error) { + if shouldUseFsKeyring(descriptor, options) { + return fsGetEncryptionKeyStatus(descriptor, options.Mount, options.User) + } _, err := userFindKey(options.Service+descriptor, options.User) if err != nil { return KeyAbsent, nil diff --git a/keyring/keyring_test.go b/keyring/keyring_test.go index 10ff874..9a4570b 100644 --- a/keyring/keyring_test.go +++ b/keyring/keyring_test.go @@ -24,6 +24,7 @@ import ( "golang.org/x/sys/unix" "github.com/google/fscrypt/crypto" + "github.com/google/fscrypt/filesystem" "github.com/google/fscrypt/metadata" "github.com/google/fscrypt/util" ) @@ -44,52 +45,125 @@ func makeKey(b byte, n int) (*crypto.Key, error) { } var ( - fakeValidDescriptor = "0123456789abcdef" defaultService = unix.FSCRYPT_KEY_DESC_PREFIX testUser, _ = util.EffectiveUser() fakeValidPolicyKey, _ = makeKey(42, metadata.PolicyKeyLen) fakeInvalidPolicyKey, _ = makeKey(42, metadata.PolicyKeyLen-1) + fakeV1Descriptor = "0123456789abcdef" ) -// Adds and removes a key with various services. -func TestAddRemoveKeys(t *testing.T) { - for _, service := range []string{defaultService, "ext4:", "f2fs:"} { - options := &Options{ - User: testUser, - Service: service, - } - if err := AddEncryptionKey(fakeValidPolicyKey, fakeValidDescriptor, options); err != nil { - t.Error(err) - } - if err := RemoveEncryptionKey(fakeValidDescriptor, options); err != nil { - t.Error(err) - } +func assertKeyStatus(t *testing.T, descriptor string, options *Options, + expectedStatus KeyStatus) { + status, err := GetEncryptionKeyStatus(descriptor, options) + if err != nil { + t.Error(err) + } + if status != expectedStatus { + t.Errorf("Expected key status %v but got key status %v", expectedStatus, status) } } -// Adds a key twice (both should succeed) -func TestAddTwice(t *testing.T) { - options := &Options{ - User: testUser, - Service: defaultService, +// getTestMount retrieves the Mount for a test filesystem, or skips the test if +// no test filesystem is available. +func getTestMount(t *testing.T) *filesystem.Mount { + root, err := util.TestRoot() + if err != nil { + t.Skip(err) + } + mount, err := filesystem.GetMount(root) + if err != nil { + t.Skip(err) + } + return mount +} + +// getTestMountV2 is like getTestMount, but it also checks that the filesystem +// keyring is supported. +func getTestMountV2(t *testing.T) *filesystem.Mount { + mount := getTestMount(t) + if !isFsKeyringSupported(mount) { + t.Skip("No support for fs keyring, skipping test.") + } + return mount +} + +func requireRoot(t *testing.T) { + if !util.IsUserRoot() { + t.Skip("Not root, skipping test.") } - if err := AddEncryptionKey(fakeValidPolicyKey, fakeValidDescriptor, options); err != nil { +} + +// testAddAndRemoveKey does the common tests for adding+removing keys that are +// run in multiple configurations (v1 policies with user keyring and v1 policies +// with fs keyring). +func testAddAndRemoveKey(t *testing.T, descriptor string, options *Options) { + + // Basic add, get status, and remove + if err := AddEncryptionKey(fakeValidPolicyKey, descriptor, options); err != nil { t.Error(err) } - if err := AddEncryptionKey(fakeValidPolicyKey, fakeValidDescriptor, options); err != nil { + assertKeyStatus(t, descriptor, options, KeyPresent) + if err := RemoveEncryptionKey(descriptor, options); err != nil { + t.Error(err) + } + assertKeyStatus(t, descriptor, options, KeyAbsent) + err := RemoveEncryptionKey(descriptor, options) + if err != ErrKeyNotPresent { + t.Error(err) + } + + // Adding a key twice should succeed + if err := AddEncryptionKey(fakeValidPolicyKey, descriptor, options); err != nil { + t.Error(err) + } + if err := AddEncryptionKey(fakeValidPolicyKey, descriptor, options); err != nil { t.Error("AddEncryptionKey should not fail if key already exists") } - RemoveEncryptionKey(fakeValidDescriptor, options) + RemoveEncryptionKey(descriptor, options) + assertKeyStatus(t, descriptor, options, KeyAbsent) + + // Adding a key with wrong length should fail + if err := AddEncryptionKey(fakeInvalidPolicyKey, descriptor, options); err == nil { + RemoveEncryptionKey(descriptor, options) + t.Error("AddEncryptionKey should fail with wrong-length key") + } + assertKeyStatus(t, descriptor, options, KeyAbsent) } -// Makes sure trying to add a key of the wrong length fails -func TestAddWrongLengthKey(t *testing.T) { +func TestUserKeyringDefaultService(t *testing.T) { options := &Options{ - User: testUser, - Service: defaultService, + User: testUser, + Service: defaultService, + UseFsKeyringForV1Policies: false, } - if err := AddEncryptionKey(fakeInvalidPolicyKey, fakeValidDescriptor, options); err == nil { - RemoveEncryptionKey(fakeValidDescriptor, options) - t.Error("AddEncryptionKey should fail with wrong-length key") + testAddAndRemoveKey(t, fakeV1Descriptor, options) +} + +func TestUserKeyringExt4Service(t *testing.T) { + options := &Options{ + User: testUser, + Service: "ext4:", + UseFsKeyringForV1Policies: false, + } + testAddAndRemoveKey(t, fakeV1Descriptor, options) +} + +func TestUserKeyringF2fsService(t *testing.T) { + options := &Options{ + User: testUser, + Service: "f2fs:", + UseFsKeyringForV1Policies: false, + } + testAddAndRemoveKey(t, fakeV1Descriptor, options) +} + +func TestFsKeyringV1PolicyKey(t *testing.T) { + requireRoot(t) + mount := getTestMountV2(t) + options := &Options{ + Mount: mount, + User: testUser, + UseFsKeyringForV1Policies: true, } + testAddAndRemoveKey(t, fakeV1Descriptor, options) } diff --git a/keyring/user_keyring.go b/keyring/user_keyring.go index adac71a..71f519d 100644 --- a/keyring/user_keyring.go +++ b/keyring/user_keyring.go @@ -1,5 +1,6 @@ /* - * user_keyring.go - Add/remove encryption policy keys to/from user keyrings + * user_keyring.go - Add/remove encryption policy keys to/from user keyrings. + * This is the deprecated mechanism; see fs_keyring.go for the new mechanism. * * Copyright 2017 Google Inc. * Author: Joe Richey (joerichey@google.com) diff --git a/metadata/config_test.go b/metadata/config_test.go index d184a87..3c20c51 100644 --- a/metadata/config_test.go +++ b/metadata/config_test.go @@ -49,7 +49,8 @@ var testConfigString = `{ "padding": "32", "contents": "AES_256_XTS", "filenames": "AES_256_CTS" - } + }, + "use_fs_keyring_for_v1_policies": false } ` diff --git a/metadata/metadata.pb.go b/metadata/metadata.pb.go index bd3ee2a..aa4eeff 100644 --- a/metadata/metadata.pb.go +++ b/metadata/metadata.pb.go @@ -45,7 +45,7 @@ func (x SourceType) String() string { return proto.EnumName(SourceType_name, int32(x)) } func (SourceType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{0} + return fileDescriptor_metadata_ff272c42a9f0f3d3, []int{0} } // Type of encryption; should match declarations of unix.FSCRYPT_MODE @@ -87,7 +87,7 @@ func (x EncryptionOptions_Mode) String() string { return proto.EnumName(EncryptionOptions_Mode_name, int32(x)) } func (EncryptionOptions_Mode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{3, 0} + return fileDescriptor_metadata_ff272c42a9f0f3d3, []int{3, 0} } // Cost parameters to be used in our hashing functions. @@ -104,7 +104,7 @@ func (m *HashingCosts) Reset() { *m = HashingCosts{} } func (m *HashingCosts) String() string { return proto.CompactTextString(m) } func (*HashingCosts) ProtoMessage() {} func (*HashingCosts) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{0} + return fileDescriptor_metadata_ff272c42a9f0f3d3, []int{0} } func (m *HashingCosts) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_HashingCosts.Unmarshal(m, b) @@ -159,7 +159,7 @@ func (m *WrappedKeyData) Reset() { *m = WrappedKeyData{} } func (m *WrappedKeyData) String() string { return proto.CompactTextString(m) } func (*WrappedKeyData) ProtoMessage() {} func (*WrappedKeyData) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{1} + return fileDescriptor_metadata_ff272c42a9f0f3d3, []int{1} } func (m *WrappedKeyData) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_WrappedKeyData.Unmarshal(m, b) @@ -219,7 +219,7 @@ func (m *ProtectorData) Reset() { *m = ProtectorData{} } func (m *ProtectorData) String() string { return proto.CompactTextString(m) } func (*ProtectorData) ProtoMessage() {} func (*ProtectorData) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{2} + return fileDescriptor_metadata_ff272c42a9f0f3d3, []int{2} } func (m *ProtectorData) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ProtectorData.Unmarshal(m, b) @@ -302,7 +302,7 @@ func (m *EncryptionOptions) Reset() { *m = EncryptionOptions{} } func (m *EncryptionOptions) String() string { return proto.CompactTextString(m) } func (*EncryptionOptions) ProtoMessage() {} func (*EncryptionOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{3} + return fileDescriptor_metadata_ff272c42a9f0f3d3, []int{3} } func (m *EncryptionOptions) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EncryptionOptions.Unmarshal(m, b) @@ -355,7 +355,7 @@ func (m *WrappedPolicyKey) Reset() { *m = WrappedPolicyKey{} } func (m *WrappedPolicyKey) String() string { return proto.CompactTextString(m) } func (*WrappedPolicyKey) ProtoMessage() {} func (*WrappedPolicyKey) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{4} + return fileDescriptor_metadata_ff272c42a9f0f3d3, []int{4} } func (m *WrappedPolicyKey) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_WrappedPolicyKey.Unmarshal(m, b) @@ -403,7 +403,7 @@ func (m *PolicyData) Reset() { *m = PolicyData{} } func (m *PolicyData) String() string { return proto.CompactTextString(m) } func (*PolicyData) ProtoMessage() {} func (*PolicyData) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{5} + return fileDescriptor_metadata_ff272c42a9f0f3d3, []int{5} } func (m *PolicyData) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PolicyData.Unmarshal(m, b) @@ -446,20 +446,21 @@ func (m *PolicyData) GetWrappedPolicyKeys() []*WrappedPolicyKey { // Data stored in the config file type Config struct { - Source SourceType `protobuf:"varint,1,opt,name=source,proto3,enum=metadata.SourceType" json:"source,omitempty"` - HashCosts *HashingCosts `protobuf:"bytes,2,opt,name=hash_costs,json=hashCosts,proto3" json:"hash_costs,omitempty"` - Compatibility string `protobuf:"bytes,3,opt,name=compatibility,proto3" json:"compatibility,omitempty"` - Options *EncryptionOptions `protobuf:"bytes,4,opt,name=options,proto3" json:"options,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Source SourceType `protobuf:"varint,1,opt,name=source,proto3,enum=metadata.SourceType" json:"source,omitempty"` + HashCosts *HashingCosts `protobuf:"bytes,2,opt,name=hash_costs,json=hashCosts,proto3" json:"hash_costs,omitempty"` + Compatibility string `protobuf:"bytes,3,opt,name=compatibility,proto3" json:"compatibility,omitempty"` + Options *EncryptionOptions `protobuf:"bytes,4,opt,name=options,proto3" json:"options,omitempty"` + UseFsKeyringForV1Policies bool `protobuf:"varint,5,opt,name=use_fs_keyring_for_v1_policies,json=useFsKeyringForV1Policies,proto3" json:"use_fs_keyring_for_v1_policies,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Config) Reset() { *m = Config{} } func (m *Config) String() string { return proto.CompactTextString(m) } func (*Config) ProtoMessage() {} func (*Config) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_fa046c95c3cd6aa1, []int{6} + return fileDescriptor_metadata_ff272c42a9f0f3d3, []int{6} } func (m *Config) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Config.Unmarshal(m, b) @@ -507,6 +508,13 @@ func (m *Config) GetOptions() *EncryptionOptions { return nil } +func (m *Config) GetUseFsKeyringForV1Policies() bool { + if m != nil { + return m.UseFsKeyringForV1Policies + } + return false +} + func init() { proto.RegisterType((*HashingCosts)(nil), "metadata.HashingCosts") proto.RegisterType((*WrappedKeyData)(nil), "metadata.WrappedKeyData") @@ -519,49 +527,52 @@ func init() { proto.RegisterEnum("metadata.EncryptionOptions_Mode", EncryptionOptions_Mode_name, EncryptionOptions_Mode_value) } -func init() { proto.RegisterFile("metadata/metadata.proto", fileDescriptor_metadata_fa046c95c3cd6aa1) } - -var fileDescriptor_metadata_fa046c95c3cd6aa1 = []byte{ - // 656 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0xef, 0x6a, 0xdb, 0x3c, - 0x14, 0xc6, 0x5f, 0xdb, 0x69, 0xd2, 0x9c, 0xfc, 0x79, 0x5d, 0xb5, 0x6f, 0x5f, 0xb3, 0x7d, 0x09, - 0xde, 0x06, 0x65, 0x94, 0x8e, 0x66, 0x74, 0x6c, 0x30, 0x06, 0x5d, 0x5a, 0xb6, 0xae, 0x94, 0x75, - 0x4a, 0xe8, 0x36, 0x18, 0x04, 0xd5, 0x56, 0x1b, 0x51, 0xdb, 0x12, 0x96, 0x42, 0xf0, 0xb7, 0x7d, - 0xdb, 0x05, 0xec, 0x5a, 0xb6, 0x8b, 0xd8, 0x55, 0x0d, 0xc9, 0xb1, 0xe3, 0xb4, 0x50, 0xba, 0x7d, - 0x31, 0x47, 0x8f, 0xa4, 0xf3, 0x1c, 0xfd, 0xa4, 0x63, 0xf8, 0x3f, 0xa6, 0x8a, 0x84, 0x44, 0x91, - 0x27, 0x45, 0xb0, 0x23, 0x52, 0xae, 0x38, 0x5a, 0x2d, 0xc6, 0xfe, 0x17, 0x68, 0xbf, 0x25, 0x72, - 0xc2, 0x92, 0xcb, 0x01, 0x97, 0x4a, 0x22, 0x04, 0x35, 0xc5, 0x62, 0xea, 0xd9, 0x3d, 0x6b, 0xcb, - 0xc1, 0x26, 0x46, 0x9b, 0x50, 0x8f, 0x69, 0xcc, 0xd3, 0xcc, 0x73, 0x8c, 0x3a, 0x1f, 0xa1, 0x1e, - 0xb4, 0x04, 0x49, 0x49, 0x14, 0xd1, 0x88, 0xc9, 0xd8, 0xab, 0x99, 0xc9, 0xaa, 0xe4, 0x7f, 0x86, - 0xee, 0xc7, 0x94, 0x08, 0x41, 0xc3, 0x63, 0x9a, 0x1d, 0x10, 0x45, 0x50, 0x17, 0xec, 0xa3, 0x33, - 0xcf, 0xea, 0x59, 0x5b, 0x6d, 0x6c, 0x1f, 0x9d, 0xa1, 0x07, 0xd0, 0xa1, 0x49, 0x90, 0x66, 0x42, - 0xd1, 0x70, 0x7c, 0x45, 0x33, 0x63, 0xdc, 0xc6, 0xed, 0x52, 0x3c, 0xa6, 0x99, 0x2e, 0x6a, 0x12, - 0x93, 0xc0, 0xd8, 0xb7, 0xb1, 0x89, 0xfd, 0xef, 0x36, 0x74, 0x4e, 0x53, 0xae, 0x68, 0xa0, 0x78, - 0x6a, 0x52, 0xef, 0xc2, 0x86, 0x28, 0x84, 0x71, 0x48, 0x65, 0x90, 0x32, 0xa1, 0x78, 0x6a, 0xcc, - 0x9a, 0x78, 0xbd, 0x9c, 0x3b, 0x28, 0xa7, 0xd0, 0x36, 0xd4, 0x25, 0x9f, 0xa6, 0x41, 0x7e, 0xde, - 0x6e, 0x7f, 0x63, 0xa7, 0x04, 0x35, 0x34, 0xfa, 0x28, 0x13, 0x14, 0xcf, 0xd7, 0xe8, 0x32, 0x12, - 0x12, 0x53, 0x53, 0x46, 0x13, 0x9b, 0x18, 0x6d, 0xc3, 0x4a, 0xa0, 0xc1, 0x99, 0xd3, 0xb7, 0xfa, - 0x9b, 0x8b, 0x04, 0x55, 0xac, 0x38, 0x5f, 0xa4, 0x33, 0x48, 0x12, 0x29, 0x6f, 0x25, 0x3f, 0x88, - 0x8e, 0x91, 0x0b, 0xce, 0x94, 0x85, 0x5e, 0xdd, 0xd0, 0xd3, 0x21, 0x7a, 0x01, 0xad, 0x59, 0x4e, - 0xcd, 0x10, 0x69, 0x98, 0xcc, 0xde, 0x22, 0xf3, 0x32, 0x52, 0x0c, 0xb3, 0x72, 0xec, 0xff, 0xb0, - 0x61, 0xed, 0x30, 0x47, 0xc7, 0x78, 0xf2, 0xde, 0x7c, 0x25, 0xf2, 0xa0, 0x21, 0x48, 0x18, 0xb2, - 0xe4, 0xd2, 0xc0, 0x70, 0x70, 0x31, 0x44, 0x2f, 0x61, 0x35, 0xe0, 0x89, 0xa2, 0x89, 0x92, 0x73, - 0x04, 0xbd, 0x85, 0xcf, 0x8d, 0x44, 0x3b, 0x27, 0x3c, 0xa4, 0xb8, 0xdc, 0x81, 0x5e, 0x41, 0xf3, - 0x82, 0x45, 0x54, 0x83, 0x90, 0x86, 0xca, 0x5d, 0xb6, 0x2f, 0xb6, 0xf8, 0xdf, 0x2c, 0xa8, 0x69, - 0x0d, 0xb5, 0xa0, 0x11, 0xd2, 0x0b, 0x32, 0x8d, 0x94, 0xfb, 0x0f, 0xfa, 0x17, 0x5a, 0xfb, 0x87, - 0xc3, 0x71, 0x7f, 0xef, 0xd9, 0xf8, 0xd3, 0x68, 0xe8, 0x5a, 0x55, 0xe1, 0xcd, 0xe0, 0xc4, 0xb5, - 0xab, 0xc2, 0xe0, 0xf5, 0xc0, 0x75, 0x96, 0x84, 0xd1, 0xd0, 0xad, 0x15, 0xc2, 0x6e, 0xff, 0xb9, - 0x59, 0xb1, 0xb2, 0x24, 0x8c, 0x86, 0x6e, 0x1d, 0xb5, 0x61, 0x75, 0x3f, 0x64, 0x24, 0x51, 0xd3, - 0xd8, 0x6d, 0xfa, 0x5f, 0x2d, 0x70, 0xe7, 0x58, 0x4f, 0x79, 0xc4, 0x82, 0x4c, 0x3f, 0xbb, 0xbf, - 0x78, 0x50, 0xd7, 0xae, 0xce, 0xfe, 0x83, 0xab, 0xfb, 0x69, 0x01, 0xe4, 0xde, 0xe6, 0x35, 0x3f, - 0x82, 0xee, 0x15, 0xcd, 0x6e, 0xda, 0x76, 0xae, 0x68, 0x56, 0x31, 0xdc, 0x83, 0x06, 0xcf, 0xe9, - 0xce, 0xcd, 0xee, 0xdf, 0x72, 0x01, 0xb8, 0x58, 0x8b, 0xde, 0xc1, 0x7a, 0x51, 0xa7, 0x30, 0x9e, - 0xba, 0x5c, 0x7d, 0x87, 0xce, 0x56, 0xab, 0x7f, 0xef, 0x46, 0xbd, 0x25, 0x13, 0xbc, 0x36, 0xbb, - 0xa6, 0x48, 0xff, 0x97, 0x05, 0xf5, 0x01, 0x4f, 0x2e, 0xd8, 0x65, 0xa5, 0x9f, 0xac, 0x3b, 0xf4, - 0xd3, 0x1e, 0xc0, 0x84, 0xc8, 0xc9, 0x38, 0x6f, 0x20, 0xfb, 0xd6, 0x06, 0x6a, 0xea, 0x95, 0xf9, - 0x2f, 0xea, 0x21, 0x74, 0x02, 0x1e, 0x0b, 0xa2, 0xd8, 0x39, 0x8b, 0x98, 0xca, 0xe6, 0xfd, 0xb8, - 0x2c, 0x56, 0xc1, 0xd4, 0xee, 0x0e, 0xe6, 0xf1, 0x07, 0x80, 0x45, 0xa5, 0xcb, 0xef, 0x12, 0x41, - 0x57, 0x90, 0x78, 0x2c, 0x88, 0x94, 0x62, 0x92, 0x12, 0x49, 0x5d, 0x0b, 0xfd, 0x07, 0x6b, 0xc1, - 0x54, 0x2a, 0xbe, 0x24, 0xdb, 0x7a, 0x5f, 0x4a, 0x66, 0x9a, 0xa9, 0xeb, 0x9c, 0xd7, 0xcd, 0x3f, - 0xf7, 0xe9, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4b, 0xbe, 0x84, 0xbc, 0x8e, 0x05, 0x00, 0x00, +func init() { proto.RegisterFile("metadata/metadata.proto", fileDescriptor_metadata_ff272c42a9f0f3d3) } + +var fileDescriptor_metadata_ff272c42a9f0f3d3 = []byte{ + // 693 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0xdf, 0x6b, 0x13, 0x41, + 0x10, 0xc7, 0xbd, 0x4b, 0x9a, 0x1f, 0x93, 0x1f, 0x5e, 0xb7, 0xb5, 0x9e, 0x0a, 0x12, 0xa2, 0x42, + 0x91, 0x52, 0x49, 0xa4, 0xa2, 0x20, 0x42, 0x4d, 0x5b, 0xad, 0xa5, 0x58, 0x2f, 0xa1, 0x2a, 0x08, + 0xc7, 0xf6, 0x6e, 0x93, 0x2c, 0xbd, 0xbb, 0x5d, 0x76, 0x37, 0x86, 0x7b, 0xf3, 0xcd, 0x27, 0x9f, + 0xfc, 0x5b, 0xf4, 0xef, 0x93, 0xdd, 0xcb, 0xcf, 0x16, 0x4a, 0xeb, 0xcb, 0x31, 0xfb, 0xdd, 0xd9, + 0x99, 0xd9, 0xcf, 0xce, 0x1c, 0xdc, 0x8d, 0x89, 0xc2, 0x21, 0x56, 0xf8, 0xd9, 0xd4, 0xd8, 0xe6, + 0x82, 0x29, 0x86, 0x4a, 0xd3, 0x75, 0xf3, 0x1b, 0x54, 0xdf, 0x63, 0x39, 0xa4, 0xc9, 0xa0, 0xc3, + 0xa4, 0x92, 0x08, 0x41, 0x5e, 0xd1, 0x98, 0xb8, 0x76, 0xc3, 0xda, 0xcc, 0x79, 0xc6, 0x46, 0x1b, + 0x50, 0x88, 0x49, 0xcc, 0x44, 0xea, 0xe6, 0x8c, 0x3a, 0x59, 0xa1, 0x06, 0x54, 0x38, 0x16, 0x38, + 0x8a, 0x48, 0x44, 0x65, 0xec, 0xe6, 0xcd, 0xe6, 0xa2, 0xd4, 0xfc, 0x0a, 0xf5, 0xcf, 0x02, 0x73, + 0x4e, 0xc2, 0x23, 0x92, 0xee, 0x61, 0x85, 0x51, 0x1d, 0xec, 0xc3, 0x53, 0xd7, 0x6a, 0x58, 0x9b, + 0x55, 0xcf, 0x3e, 0x3c, 0x45, 0x8f, 0xa0, 0x46, 0x92, 0x40, 0xa4, 0x5c, 0x91, 0xd0, 0x3f, 0x27, + 0xa9, 0x49, 0x5c, 0xf5, 0xaa, 0x33, 0xf1, 0x88, 0xa4, 0xba, 0xa8, 0x61, 0x8c, 0x03, 0x93, 0xbe, + 0xea, 0x19, 0xbb, 0xf9, 0xdb, 0x86, 0xda, 0x89, 0x60, 0x8a, 0x04, 0x8a, 0x09, 0x13, 0xba, 0x05, + 0xeb, 0x7c, 0x2a, 0xf8, 0x21, 0x91, 0x81, 0xa0, 0x5c, 0x31, 0x61, 0x92, 0x95, 0xbd, 0xb5, 0xd9, + 0xde, 0xde, 0x6c, 0x0b, 0x6d, 0x41, 0x41, 0xb2, 0x91, 0x08, 0xb2, 0xfb, 0xd6, 0xdb, 0xeb, 0xdb, + 0x33, 0x50, 0x5d, 0xa3, 0xf7, 0x52, 0x4e, 0xbc, 0x89, 0x8f, 0x2e, 0x23, 0xc1, 0x31, 0x31, 0x65, + 0x94, 0x3d, 0x63, 0xa3, 0x2d, 0x58, 0x09, 0x34, 0x38, 0x73, 0xfb, 0x4a, 0x7b, 0x63, 0x1e, 0x60, + 0x11, 0xab, 0x97, 0x39, 0xe9, 0x08, 0x12, 0x47, 0xca, 0x5d, 0xc9, 0x2e, 0xa2, 0x6d, 0xe4, 0x40, + 0x6e, 0x44, 0x43, 0xb7, 0x60, 0xe8, 0x69, 0x13, 0xbd, 0x82, 0xca, 0x38, 0xa3, 0x66, 0x88, 0x14, + 0x4d, 0x64, 0x77, 0x1e, 0x79, 0x19, 0xa9, 0x07, 0xe3, 0xd9, 0xba, 0xf9, 0xc7, 0x86, 0xd5, 0xfd, + 0x0c, 0x1d, 0x65, 0xc9, 0x47, 0xf3, 0x95, 0xc8, 0x85, 0x22, 0xc7, 0x61, 0x48, 0x93, 0x81, 0x81, + 0x91, 0xf3, 0xa6, 0x4b, 0xf4, 0x1a, 0x4a, 0x01, 0x4b, 0x14, 0x49, 0x94, 0x9c, 0x20, 0x68, 0xcc, + 0xf3, 0x5c, 0x0a, 0xb4, 0x7d, 0xcc, 0x42, 0xe2, 0xcd, 0x4e, 0xa0, 0x37, 0x50, 0xee, 0xd3, 0x88, + 0x68, 0x10, 0xd2, 0x50, 0xb9, 0xce, 0xf1, 0xf9, 0x91, 0xe6, 0x4f, 0x0b, 0xf2, 0x5a, 0x43, 0x15, + 0x28, 0x86, 0xa4, 0x8f, 0x47, 0x91, 0x72, 0x6e, 0xa1, 0xdb, 0x50, 0xd9, 0xdd, 0xef, 0xfa, 0xed, + 0x9d, 0x17, 0xfe, 0x97, 0x5e, 0xd7, 0xb1, 0x16, 0x85, 0x77, 0x9d, 0x63, 0xc7, 0x5e, 0x14, 0x3a, + 0x6f, 0x3b, 0x4e, 0x6e, 0x49, 0xe8, 0x75, 0x9d, 0xfc, 0x54, 0x68, 0xb5, 0x5f, 0x1a, 0x8f, 0x95, + 0x25, 0xa1, 0xd7, 0x75, 0x0a, 0xa8, 0x0a, 0xa5, 0xdd, 0x90, 0xe2, 0x44, 0x8d, 0x62, 0xa7, 0xdc, + 0xfc, 0x61, 0x81, 0x33, 0xc1, 0x7a, 0xc2, 0x22, 0x1a, 0xa4, 0xba, 0xed, 0xfe, 0xa3, 0xa1, 0x2e, + 0x3c, 0x9d, 0x7d, 0x83, 0xa7, 0xfb, 0x6b, 0x01, 0x64, 0xb9, 0x4d, 0x37, 0x3f, 0x81, 0xfa, 0x39, + 0x49, 0x2f, 0xa7, 0xad, 0x9d, 0x93, 0x74, 0x21, 0xe1, 0x0e, 0x14, 0x59, 0x46, 0x77, 0x92, 0xec, + 0xc1, 0x15, 0x0f, 0xe0, 0x4d, 0x7d, 0xd1, 0x07, 0x58, 0x9b, 0xd6, 0xc9, 0x4d, 0x4e, 0x5d, 0xae, + 0x7e, 0xc3, 0xdc, 0x66, 0xa5, 0x7d, 0xff, 0x52, 0xbd, 0x33, 0x26, 0xde, 0xea, 0xf8, 0x82, 0x22, + 0x9b, 0xbf, 0x6c, 0x28, 0x74, 0x58, 0xd2, 0xa7, 0x83, 0x85, 0x79, 0xb2, 0xae, 0x31, 0x4f, 0x3b, + 0x00, 0x43, 0x2c, 0x87, 0x7e, 0x36, 0x40, 0xf6, 0x95, 0x03, 0x54, 0xd6, 0x9e, 0xd9, 0x2f, 0xea, + 0x31, 0xd4, 0x02, 0x16, 0x73, 0xac, 0xe8, 0x19, 0x8d, 0xa8, 0x4a, 0x27, 0xf3, 0xb8, 0x2c, 0x2e, + 0x82, 0xc9, 0xdf, 0x00, 0xcc, 0x2e, 0x3c, 0x1c, 0x49, 0xe2, 0xf7, 0xa5, 0x06, 0x22, 0x68, 0x32, + 0xf0, 0xfb, 0x4c, 0xf8, 0xdf, 0x5b, 0x19, 0x26, 0x4a, 0xa4, 0x99, 0xdd, 0x92, 0x77, 0x6f, 0x24, + 0xc9, 0x81, 0x3c, 0xca, 0x7c, 0x0e, 0x98, 0x38, 0x6d, 0x9d, 0x4c, 0x1c, 0x9e, 0x7e, 0x02, 0x98, + 0x5f, 0x76, 0xb9, 0xb5, 0x11, 0xd4, 0x39, 0x8e, 0x7d, 0x8e, 0xa5, 0xe4, 0x43, 0x81, 0x25, 0x71, + 0x2c, 0x74, 0x07, 0x56, 0x83, 0x91, 0x54, 0x6c, 0x49, 0xb6, 0xf5, 0x39, 0x81, 0xc7, 0xba, 0x0a, + 0x27, 0x77, 0x56, 0x30, 0xbf, 0xed, 0xe7, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xd3, 0x31, 0x82, + 0x34, 0xd1, 0x05, 0x00, 0x00, } diff --git a/metadata/metadata.proto b/metadata/metadata.proto index 735181e..e682212 100644 --- a/metadata/metadata.proto +++ b/metadata/metadata.proto @@ -97,4 +97,5 @@ message Config { HashingCosts hash_costs = 2; string compatibility = 3; EncryptionOptions options = 4; + bool use_fs_keyring_for_v1_policies = 5; } |