summaryrefslogtreecommitdiff
path: root/cryptfs/config_file.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2016-02-06 19:20:54 +0100
committerJakob Unterwurzacher2016-02-06 19:22:35 +0100
commit2b8cbd944149afe51fadddbd67ee4499d1d86250 (patch)
tree76361984cc4394bbb9b19ae987aeaff71fb6073b /cryptfs/config_file.go
parentadcfbd79a8b8bb85cbee25996ab622a05de0dbc1 (diff)
Major refactoring: Split up "cryptfs" into several internal packages
"git status" for reference: deleted: cryptfs/cryptfs.go deleted: cryptfs/names_core.go modified: integration_tests/cli_test.go modified: integration_tests/helpers.go renamed: cryptfs/config_file.go -> internal/configfile/config_file.go renamed: cryptfs/config_test.go -> internal/configfile/config_test.go renamed: cryptfs/config_test/.gitignore -> internal/configfile/config_test/.gitignore renamed: cryptfs/config_test/PlaintextNames.conf -> internal/configfile/config_test/PlaintextNames.conf renamed: cryptfs/config_test/StrangeFeature.conf -> internal/configfile/config_test/StrangeFeature.conf renamed: cryptfs/config_test/v1.conf -> internal/configfile/config_test/v1.conf renamed: cryptfs/config_test/v2.conf -> internal/configfile/config_test/v2.conf renamed: cryptfs/kdf.go -> internal/configfile/kdf.go renamed: cryptfs/kdf_test.go -> internal/configfile/kdf_test.go renamed: cryptfs/cryptfs_content.go -> internal/contentenc/content.go new file: internal/contentenc/content_api.go renamed: cryptfs/content_test.go -> internal/contentenc/content_test.go renamed: cryptfs/file_header.go -> internal/contentenc/file_header.go renamed: cryptfs/intrablock.go -> internal/contentenc/intrablock.go renamed: cryptfs/address_translation.go -> internal/contentenc/offsets.go new file: internal/cryptocore/crypto_api.go renamed: cryptfs/gcm_go1.4.go -> internal/cryptocore/gcm_go1.4.go renamed: cryptfs/gcm_go1.5.go -> internal/cryptocore/gcm_go1.5.go renamed: cryptfs/nonce.go -> internal/cryptocore/nonce.go renamed: cryptfs/openssl_aead.go -> internal/cryptocore/openssl_aead.go renamed: cryptfs/openssl_benchmark.bash -> internal/cryptocore/openssl_benchmark.bash renamed: cryptfs/openssl_test.go -> internal/cryptocore/openssl_test.go new file: internal/nametransform/name_api.go new file: internal/nametransform/names_core.go renamed: cryptfs/names_diriv.go -> internal/nametransform/names_diriv.go renamed: cryptfs/names_noiv.go -> internal/nametransform/names_noiv.go renamed: cryptfs/names_test.go -> internal/nametransform/names_test.go new file: internal/nametransform/pad16.go renamed: cryptfs/log.go -> internal/toggledlog/log.go renamed: cryptfs/log_go1.4.go -> internal/toggledlog/log_go1.4.go renamed: cryptfs/log_go1.5.go -> internal/toggledlog/log_go1.5.go modified: main.go modified: masterkey.go modified: pathfs_frontend/file.go modified: pathfs_frontend/file_holes.go modified: pathfs_frontend/fs.go modified: pathfs_frontend/fs_dir.go modified: pathfs_frontend/names.go modified: test.bash
Diffstat (limited to 'cryptfs/config_file.go')
-rw-r--r--cryptfs/config_file.go188
1 files changed, 0 insertions, 188 deletions
diff --git a/cryptfs/config_file.go b/cryptfs/config_file.go
deleted file mode 100644
index 013b82d..0000000
--- a/cryptfs/config_file.go
+++ /dev/null
@@ -1,188 +0,0 @@
-package cryptfs
-
-import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "log"
-)
-import "os"
-
-const (
- // The dot "." is not used in base64url (RFC4648), hence
- // we can never clash with an encrypted file.
- ConfDefaultName = "gocryptfs.conf"
-)
-
-type ConfFile struct {
- // File the config is saved to. Not exported to JSON.
- filename string
- // Encrypted AES key, unlocked using a password hashed with scrypt
- EncryptedKey []byte
- // Stores parameters for scrypt hashing (key derivation)
- ScryptObject scryptKdf
- // The On-Disk-Format version this filesystem uses
- Version uint16
- // List of feature flags this filesystem has enabled.
- // If gocryptfs encounters a feature flag it does not support, it will refuse
- // mounting. This mechanism is analogous to the ext4 feature flags that are
- // stored in the superblock.
- FeatureFlags []string
-}
-
-// CreateConfFile - create a new config with a random key encrypted with
-// "password" and write it to "filename".
-// Uses scrypt with cost parameter logN.
-func CreateConfFile(filename string, password string, plaintextNames bool, logN int) error {
- var cf ConfFile
- cf.filename = filename
- cf.Version = HEADER_CURRENT_VERSION
-
- // Generate new random master key
- key := RandBytes(KEY_LEN)
-
- // Encrypt it using the password
- // This sets ScryptObject and EncryptedKey
- cf.EncryptKey(key, password, logN)
-
- // Set feature flags
- cf.FeatureFlags = append(cf.FeatureFlags, FlagGCMIV128)
- if plaintextNames {
- cf.FeatureFlags = append(cf.FeatureFlags, FlagPlaintextNames)
- } else {
- cf.FeatureFlags = append(cf.FeatureFlags, FlagDirIV)
- cf.FeatureFlags = append(cf.FeatureFlags, FlagEMENames)
- }
-
- // Write file to disk
- return cf.WriteFile()
-}
-
-// LoadConfFile - read config file from disk and decrypt the
-// contained key using password.
-//
-// Returns the decrypted key and the ConfFile object
-func LoadConfFile(filename string, password string) ([]byte, *ConfFile, error) {
- var cf ConfFile
- cf.filename = filename
-
- // Read from disk
- js, err := ioutil.ReadFile(filename)
- if err != nil {
- return nil, nil, err
- }
-
- // Unmarshal
- err = json.Unmarshal(js, &cf)
- if err != nil {
- Warn.Printf("Failed to unmarshal config file")
- return nil, nil, err
- }
-
- if cf.Version != HEADER_CURRENT_VERSION {
- return nil, nil, fmt.Errorf("Unsupported on-disk format %d", cf.Version)
- }
-
- for _, flag := range cf.FeatureFlags {
- if cf.isFeatureFlagKnown(flag) == false {
- return nil, nil, fmt.Errorf("Unsupported feature flag %s", flag)
- }
- }
-
- // Generate derived key from password
- scryptHash := cf.ScryptObject.DeriveKey(password)
-
- // Unlock master key using password-based key
- // We use stock go GCM instead of OpenSSL here as speed is not important
- // and we get better error messages
- cfs := NewCryptFS(scryptHash, false, false, false)
- key, err := cfs.DecryptBlock(cf.EncryptedKey, 0, nil)
- if err != nil {
- Warn.Printf("failed to unlock master key: %s", err.Error())
- Warn.Printf("Password incorrect.")
- return nil, nil, err
- }
-
- return key, &cf, nil
-}
-
-// EncryptKey - encrypt "key" using an scrypt hash generated from "password"
-// and store it in cf.EncryptedKey.
-// Uses scrypt with cost parameter logN and stores the scrypt parameters in
-// cf.ScryptObject.
-func (cf *ConfFile) EncryptKey(key []byte, password string, logN int) {
- // Generate derived key from password
- cf.ScryptObject = NewScryptKdf(logN)
- scryptHash := cf.ScryptObject.DeriveKey(password)
-
- // Lock master key using password-based key
- cfs := NewCryptFS(scryptHash, false, false, false)
- cf.EncryptedKey = cfs.EncryptBlock(key, 0, nil)
-}
-
-// WriteFile - write out config in JSON format to file "filename.tmp"
-// then rename over "filename".
-// This way a password change atomically replaces the file.
-func (cf *ConfFile) WriteFile() error {
- tmp := cf.filename + ".tmp"
- // 0400 permissions: gocryptfs.conf should be kept secret and never be written to.
- fd, err := os.OpenFile(tmp, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0400)
- if err != nil {
- return err
- }
- js, err := json.MarshalIndent(cf, "", "\t")
- if err != nil {
- return err
- }
- _, err = fd.Write(js)
- if err != nil {
- return err
- }
- err = fd.Sync()
- if err != nil {
- return err
- }
- err = fd.Close()
- if err != nil {
- return err
- }
- err = os.Rename(tmp, cf.filename)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-const (
- // Understood Feature Flags.
- // Also teach isFeatureFlagKnown() about any additions and
- // add it to CreateConfFile() if you want to have it enabled by default.
- FlagPlaintextNames = "PlaintextNames"
- FlagDirIV = "DirIV"
- FlagEMENames = "EMENames"
- FlagGCMIV128 = "GCMIV128"
-)
-
-// Verify that we understand a feature flag
-func (cf *ConfFile) isFeatureFlagKnown(flag string) bool {
- switch flag {
- case FlagPlaintextNames, FlagDirIV, FlagEMENames, FlagGCMIV128:
- return true
- default:
- return false
- }
-}
-
-// isFeatureFlagSet - is the feature flag "flagWant" enabled?
-func (cf *ConfFile) IsFeatureFlagSet(flagWant string) bool {
- if !cf.isFeatureFlagKnown(flagWant) {
- log.Panicf("BUG: Tried to use unsupported feature flag %s", flagWant)
- }
- for _, flag := range cf.FeatureFlags {
- if flag == flagWant {
- return true
- }
- }
- return false
-}