aboutsummaryrefslogtreecommitdiff
path: root/keyring
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2020-03-17 21:10:58 -0700
committerEric Biggers <ebiggers@google.com>2020-03-23 13:20:27 -0700
commitc123f5a24de5a25185653de8e6f970184fde035d (patch)
treeb61e89c74cc241fb6d5c6255e6063cebfec84614 /keyring
parentec85cc8f987647c2b264c1f95dadda0f71c3d991 (diff)
Improve error message when setting v2 policy is unsupported
If trying to encrypt a directory using a v2 policy fails due to the kernel lacking support for v2 policies, show a better error message. One way this can happen is if someone runs 'fscrypt setup' with a new kernel and then downgrades to an old kernel. Before: # echo -n hunter2 | fscrypt encrypt dir --source=custom_passphrase --name=foo --quiet [ERROR] fscrypt encrypt: inappropriate ioctl for device: system error: could not add key to the keyring After: # echo -n hunter2 | fscrypt encrypt dir --source=custom_passphrase --name=foo --quiet [ERROR] fscrypt encrypt: kernel is too old to support v2 encryption policies v2 encryption policies are only supported by kernel version 5.4 and later. Either use a newer kernel, or change policy_version to 1 in /etc/fscrypt.conf.
Diffstat (limited to 'keyring')
-rw-r--r--keyring/keyring.go48
1 files changed, 32 insertions, 16 deletions
diff --git a/keyring/keyring.go b/keyring/keyring.go
index f873bac..e232de3 100644
--- a/keyring/keyring.go
+++ b/keyring/keyring.go
@@ -43,15 +43,16 @@ import (
// Keyring error values
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")
- ErrKeyAddedByOtherUsers = errors.New("other users have added the key too")
- 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")
- ErrLinkUserKeyring = util.SystemError("could not link user keyring into root keyring")
+ 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")
+ ErrKeyAddedByOtherUsers = errors.New("other users have added the key too")
+ 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")
+ ErrLinkUserKeyring = util.SystemError("could not link user keyring into root keyring")
+ ErrV2PoliciesUnsupported = errors.New("kernel is too old to support v2 encryption policies")
)
// Options are the options which specify *which* keyring the key should be
@@ -69,16 +70,19 @@ type Options struct {
UseFsKeyringForV1Policies bool
}
-func shouldUseFsKeyring(descriptor string, options *Options) bool {
+func shouldUseFsKeyring(descriptor string, options *Options) (bool, error) {
// For v1 encryption policy keys, use the filesystem keyring if
// use_fs_keyring_for_v1_policies is set in /etc/fscrypt.conf and the
// kernel supports it.
if len(descriptor) == hex.EncodedLen(unix.FSCRYPT_KEY_DESCRIPTOR_SIZE) {
- return options.UseFsKeyringForV1Policies && isFsKeyringSupported(options.Mount)
+ return options.UseFsKeyringForV1Policies && isFsKeyringSupported(options.Mount), nil
}
// For v2 encryption policy keys, always use the filesystem keyring; the
// kernel doesn't support any other way.
- return true
+ if !isFsKeyringSupported(options.Mount) {
+ return true, ErrV2PoliciesUnsupported
+ }
+ return true, nil
}
// buildKeyDescription builds the description for an fscrypt key of type
@@ -101,7 +105,11 @@ func AddEncryptionKey(key *crypto.Key, descriptor string, options *Options) erro
if err := util.CheckValidLength(metadata.PolicyKeyLen, key.Len()); err != nil {
return errors.Wrap(err, "policy key")
}
- if shouldUseFsKeyring(descriptor, options) {
+ useFsKeyring, err := shouldUseFsKeyring(descriptor, options)
+ if err != nil {
+ return err
+ }
+ if useFsKeyring {
return fsAddEncryptionKey(key, descriptor, options.Mount, options.User)
}
return userAddKey(key, buildKeyDescription(options, descriptor), options.User)
@@ -111,7 +119,11 @@ func AddEncryptionKey(key *crypto.Key, descriptor string, options *Options) erro
// It uses either the filesystem keyring for the target Mount or the user
// keyring for the target User.
func RemoveEncryptionKey(descriptor string, options *Options, allUsers bool) error {
- if shouldUseFsKeyring(descriptor, options) {
+ useFsKeyring, err := shouldUseFsKeyring(descriptor, options)
+ if err != nil {
+ return err
+ }
+ if useFsKeyring {
user := options.User
if allUsers {
user = nil
@@ -154,10 +166,14 @@ func (status KeyStatus) String() string {
// 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) {
+ useFsKeyring, err := shouldUseFsKeyring(descriptor, options)
+ if err != nil {
+ return KeyStatusUnknown, err
+ }
+ if useFsKeyring {
return fsGetEncryptionKeyStatus(descriptor, options.Mount, options.User)
}
- _, err := userFindKey(buildKeyDescription(options, descriptor), options.User)
+ _, err = userFindKey(buildKeyDescription(options, descriptor), options.User)
if err != nil {
return KeyAbsent, nil
}