aboutsummaryrefslogtreecommitdiff
path: root/actions/recovery_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'actions/recovery_test.go')
-rw-r--r--actions/recovery_test.go90
1 files changed, 90 insertions, 0 deletions
diff --git a/actions/recovery_test.go b/actions/recovery_test.go
new file mode 100644
index 0000000..4332972
--- /dev/null
+++ b/actions/recovery_test.go
@@ -0,0 +1,90 @@
+/*
+ * recovery_test.go - tests for recovery passphrases
+ *
+ * Copyright 2019 Google LLC
+ *
+ * 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 actions
+
+import (
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+
+ "github.com/google/fscrypt/crypto"
+)
+
+func TestRecoveryPassphrase(t *testing.T) {
+ tempDir, err := ioutil.TempDir("", "fscrypt")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(tempDir)
+ recoveryFile := filepath.Join(tempDir, "recovery.txt")
+
+ firstProtector, policy, err := makeBoth()
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer cleanupPolicy(policy)
+ defer cleanupProtector(firstProtector)
+
+ // Add a recovery passphrase and verify that it worked correctly.
+ passphrase, recoveryProtector, err := AddRecoveryPassphrase(policy, "foo")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer cleanupProtector(recoveryProtector)
+ if passphrase.Len() != 20 {
+ t.Error("Recovery passphrase has wrong length")
+ }
+ if recoveryProtector.data.Name != "Recovery passphrase for foo" {
+ t.Error("Recovery passphrase protector has wrong name")
+ }
+ if len(policy.ProtectorDescriptors()) != 2 {
+ t.Error("There should be 2 protectors now")
+ }
+ getPassphraseFn := func(info ProtectorInfo, retry bool) (*crypto.Key, error) {
+ return passphrase.Clone()
+ }
+ recoveryProtector.Lock()
+ if err = recoveryProtector.Unlock(getPassphraseFn); err != nil {
+ t.Fatal(err)
+ }
+
+ // Test writing the recovery instructions.
+ if err = WriteRecoveryInstructions(passphrase, recoveryFile); err != nil {
+ t.Fatal(err)
+ }
+ contentsBytes, err := ioutil.ReadFile(recoveryFile)
+ if err != nil {
+ t.Fatal(err)
+ }
+ contents := string(contentsBytes)
+ if !strings.Contains(contents, string(passphrase.Data())) {
+ t.Error("Recovery instructions don't actually contain the passphrase!")
+ }
+
+ // Test for protector naming collision.
+ if passphrase, recoveryProtector, err = AddRecoveryPassphrase(policy, "foo"); err != nil {
+ t.Fatal(err)
+ }
+ defer cleanupProtector(recoveryProtector)
+ if recoveryProtector.data.Name != "Recovery passphrase for foo (2)" {
+ t.Error("Recovery passphrase protector has wrong name (after naming collision)")
+ }
+}