aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli-tests/t_encrypt_raw_key.out48
-rwxr-xr-xcli-tests/t_encrypt_raw_key.sh19
-rw-r--r--cmd/fscrypt/keys.go46
3 files changed, 92 insertions, 21 deletions
diff --git a/cli-tests/t_encrypt_raw_key.out b/cli-tests/t_encrypt_raw_key.out
index 8765ba2..1f51dc0 100644
--- a/cli-tests/t_encrypt_raw_key.out
+++ b/cli-tests/t_encrypt_raw_key.out
@@ -1,5 +1,5 @@
-# Encrypt with raw_key protector
+# Encrypt with raw_key protector from file
ext4 filesystem "MNT" has 1 protector and 1 policy
PROTECTOR LINKED DESCRIPTION
@@ -17,9 +17,53 @@ Protected with 1 protector:
PROTECTOR LINKED DESCRIPTION
desc1 No raw key protector "prot"
-# Try to encrypt with raw_key protector, using wrong key length
+# Encrypt with raw_key protector from stdin
+ext4 filesystem "MNT" has 1 protector and 1 policy
+
+PROTECTOR LINKED DESCRIPTION
+desc6 No raw key protector "prot"
+
+POLICY UNLOCKED PROTECTORS
+desc7 Yes desc6
+"MNT/dir" is encrypted with fscrypt.
+
+Policy: desc7
+Options: padding:32 contents:AES_256_XTS filenames:AES_256_CTS policy_version:2
+Unlocked: Yes
+
+Protected with 1 protector:
+PROTECTOR LINKED DESCRIPTION
+desc6 No raw key protector "prot"
+
+# Try to encrypt with raw_key protector from file, using wrong key length
[ERROR] fscrypt encrypt: TMPDIR/raw_key: key file must be 32 bytes
ext4 filesystem "MNT" has 0 protectors and 0 policies
[ERROR] fscrypt status: file or directory "MNT/dir" is not
encrypted
+
+# Try to encrypt with raw_key protector from stdin, using wrong key length
+[ERROR] fscrypt encrypt: unexpected EOF
+ext4 filesystem "MNT" has 0 protectors and 0 policies
+
+[ERROR] fscrypt status: file or directory "MNT/dir" is not
+ encrypted
+
+# Encrypt with raw_key protector from file, unlock from stdin
+"MNT/dir" is now locked.
+ext4 filesystem "MNT" has 1 protector and 1 policy
+
+PROTECTOR LINKED DESCRIPTION
+desc11 No raw key protector "prot"
+
+POLICY UNLOCKED PROTECTORS
+desc12 Yes desc11
+"MNT/dir" is encrypted with fscrypt.
+
+Policy: desc12
+Options: padding:32 contents:AES_256_XTS filenames:AES_256_CTS policy_version:2
+Unlocked: Yes
+
+Protected with 1 protector:
+PROTECTOR LINKED DESCRIPTION
+desc11 No raw key protector "prot"
diff --git a/cli-tests/t_encrypt_raw_key.sh b/cli-tests/t_encrypt_raw_key.sh
index 260b094..e5c6d20 100755
--- a/cli-tests/t_encrypt_raw_key.sh
+++ b/cli-tests/t_encrypt_raw_key.sh
@@ -27,12 +27,27 @@ show_status()
fi
}
-begin "Encrypt with raw_key protector"
+begin "Encrypt with raw_key protector from file"
head -c 32 /dev/urandom > "$raw_key_file"
fscrypt encrypt --quiet --name=prot --source=raw_key --key="$raw_key_file" "$dir"
show_status true
-begin "Try to encrypt with raw_key protector, using wrong key length"
+begin "Encrypt with raw_key protector from stdin"
+head -c 32 /dev/urandom | fscrypt encrypt --quiet --name=prot --source=raw_key "$dir"
+show_status true
+
+begin "Try to encrypt with raw_key protector from file, using wrong key length"
head -c 16 /dev/urandom > "$raw_key_file"
_expect_failure "fscrypt encrypt --quiet --name=prot --source=raw_key --key='$raw_key_file' '$dir'"
show_status false
+
+begin "Try to encrypt with raw_key protector from stdin, using wrong key length"
+_expect_failure "head -c 16 /dev/urandom | fscrypt encrypt --quiet --name=prot --source=raw_key '$dir'"
+show_status false
+
+begin "Encrypt with raw_key protector from file, unlock from stdin"
+head -c 32 /dev/urandom > "$raw_key_file"
+fscrypt encrypt --quiet --name=prot --source=raw_key --key="$raw_key_file" "$dir"
+fscrypt lock "$dir"
+fscrypt unlock --quiet "$dir" < "$raw_key_file"
+show_status true
diff --git a/cmd/fscrypt/keys.go b/cmd/fscrypt/keys.go
index cb86404..b57c01d 100644
--- a/cmd/fscrypt/keys.go
+++ b/cmd/fscrypt/keys.go
@@ -22,6 +22,7 @@
package main
import (
+ "bufio"
"fmt"
"io"
"log"
@@ -106,6 +107,33 @@ func getPassphraseKey(prompt string) (*crypto.Key, error) {
return crypto.NewKeyFromReader(passphraseReader{})
}
+func makeRawKey(info actions.ProtectorInfo) (*crypto.Key, error) {
+ // When running non-interactively and no key was provided,
+ // try to read it from stdin
+ if keyFileFlag.Value == "" && !term.IsTerminal(stdinFd) {
+ return crypto.NewFixedLengthKeyFromReader(bufio.NewReader(os.Stdin),
+ metadata.InternalKeyLen)
+ }
+
+ prompt := fmt.Sprintf("Enter key file for protector %q: ", info.Name())
+ // Raw keys use a file containing the key data.
+ file, err := promptForKeyFile(prompt)
+ if err != nil {
+ return nil, err
+ }
+ defer file.Close()
+
+ fileInfo, err := file.Stat()
+ if err != nil {
+ return nil, err
+ }
+
+ if fileInfo.Size() != metadata.InternalKeyLen {
+ return nil, errors.Wrap(ErrKeyFileLength, file.Name())
+ }
+ return crypto.NewFixedLengthKeyFromReader(file, metadata.InternalKeyLen)
+}
+
// makeKeyFunc creates an actions.KeyFunc. This function customizes the KeyFunc
// to whether or not it supports retrying, whether it confirms the passphrase,
// and custom prefix for printing (if any).
@@ -179,23 +207,7 @@ func makeKeyFunc(supportRetry, shouldConfirm bool, prefix string) actions.KeyFun
if prefix != "" {
return nil, ErrNotPassphrase
}
- prompt := fmt.Sprintf("Enter key file for protector %q: ", info.Name())
- // Raw keys use a file containing the key data.
- file, err := promptForKeyFile(prompt)
- if err != nil {
- return nil, err
- }
- defer file.Close()
-
- fileInfo, err := file.Stat()
- if err != nil {
- return nil, err
- }
-
- if fileInfo.Size() != metadata.InternalKeyLen {
- return nil, errors.Wrap(ErrKeyFileLength, file.Name())
- }
- return crypto.NewFixedLengthKeyFromReader(file, metadata.InternalKeyLen)
+ return makeRawKey(info)
default:
return nil, ErrInvalidSource