diff options
author | Felix Lange <fjl@twurst.com> | 2016-03-03 08:15:42 +0800 |
---|---|---|
committer | Felix Lange <fjl@twurst.com> | 2016-04-12 21:58:07 +0800 |
commit | a9f26dcd0d14c0cb9f309ebccf81e8f741fc4636 (patch) | |
tree | 1a1e269194f3698737b0c1dbaf918c4e8dbae347 /accounts/key_store_passphrase.go | |
parent | ef63e9af55fcfe3255dddec3197bd8a807152c66 (diff) | |
download | dexon-a9f26dcd0d14c0cb9f309ebccf81e8f741fc4636.tar dexon-a9f26dcd0d14c0cb9f309ebccf81e8f741fc4636.tar.gz dexon-a9f26dcd0d14c0cb9f309ebccf81e8f741fc4636.tar.bz2 dexon-a9f26dcd0d14c0cb9f309ebccf81e8f741fc4636.tar.lz dexon-a9f26dcd0d14c0cb9f309ebccf81e8f741fc4636.tar.xz dexon-a9f26dcd0d14c0cb9f309ebccf81e8f741fc4636.tar.zst dexon-a9f26dcd0d14c0cb9f309ebccf81e8f741fc4636.zip |
accounts: cache key addresses
In order to avoid disk thrashing for Accounts and HasAccount,
address->key file mappings are now cached in memory. This makes it no
longer necessary to keep the key address in the file name. The address
of each key is derived from file content instead.
There are minor user-visible changes:
- "geth account list" now reports key file paths alongside the address.
- If multiple keys are present for an address, unlocking by address is
not possible. Users are directed to remove the duplicate files
instead. Unlocking by index is still possible.
- Key files are overwritten written in place when updating the password.
Diffstat (limited to 'accounts/key_store_passphrase.go')
-rw-r--r-- | accounts/key_store_passphrase.go | 73 |
1 files changed, 27 insertions, 46 deletions
diff --git a/accounts/key_store_passphrase.go b/accounts/key_store_passphrase.go index 3ee86588e..0cc598bbc 100644 --- a/accounts/key_store_passphrase.go +++ b/accounts/key_store_passphrase.go @@ -33,7 +33,8 @@ import ( "encoding/json" "errors" "fmt" - "io" + "io/ioutil" + "path/filepath" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" @@ -64,32 +65,37 @@ type keyStorePassphrase struct { scryptP int } -func newKeyStorePassphrase(path string, scryptN int, scryptP int) keyStore { - return &keyStorePassphrase{path, scryptN, scryptP} -} - -func (ks keyStorePassphrase) GenerateNewKey(rand io.Reader, auth string) (key *Key, err error) { - return generateNewKeyDefault(ks, rand, auth) -} - -func (ks keyStorePassphrase) GetKey(keyAddr common.Address, auth string) (key *Key, err error) { - return decryptKeyFromFile(ks.keysDirPath, keyAddr, auth) -} - -func (ks keyStorePassphrase) Cleanup(keyAddr common.Address) (err error) { - return cleanup(ks.keysDirPath, keyAddr) -} - -func (ks keyStorePassphrase) GetKeyAddresses() (addresses []common.Address, err error) { - return getKeyAddresses(ks.keysDirPath) +func (ks keyStorePassphrase) GetKey(addr common.Address, filename, auth string) (*Key, error) { + // Load the key from the keystore and decrypt its contents + keyjson, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + key, err := DecryptKey(keyjson, auth) + if err != nil { + return nil, err + } + // Make sure we're really operating on the requested key (no swap attacks) + if key.Address != addr { + return nil, fmt.Errorf("key content mismatch: have account %x, want %x", key.Address, addr) + } + return key, nil } -func (ks keyStorePassphrase) StoreKey(key *Key, auth string) error { +func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) error { keyjson, err := EncryptKey(key, auth, ks.scryptN, ks.scryptP) if err != nil { return err } - return writeKeyFile(key.Address, ks.keysDirPath, keyjson) + return writeKeyFile(filename, keyjson) +} + +func (ks keyStorePassphrase) JoinPath(filename string) string { + if filepath.IsAbs(filename) { + return filename + } else { + return filepath.Join(ks.keysDirPath, filename) + } } // EncryptKey encrypts a key using the specified scrypt parameters into a json @@ -139,14 +145,6 @@ func EncryptKey(key *Key, auth string, scryptN, scryptP int) ([]byte, error) { return json.Marshal(encryptedKeyJSONV3) } -func (ks keyStorePassphrase) DeleteKey(keyAddr common.Address, auth string) error { - // only delete if correct passphrase is given - if _, err := decryptKeyFromFile(ks.keysDirPath, keyAddr, auth); err != nil { - return err - } - return deleteKey(ks.keysDirPath, keyAddr) -} - // DecryptKey decrypts a key from a json blob, returning the private key itself. func DecryptKey(keyjson []byte, auth string) (*Key, error) { // Parse the json into a simple map to fetch the key version @@ -184,23 +182,6 @@ func DecryptKey(keyjson []byte, auth string) (*Key, error) { }, nil } -func decryptKeyFromFile(keysDirPath string, keyAddr common.Address, auth string) (*Key, error) { - // Load the key from the keystore and decrypt its contents - keyjson, err := getKeyFile(keysDirPath, keyAddr) - if err != nil { - return nil, err - } - key, err := DecryptKey(keyjson, auth) - if err != nil { - return nil, err - } - // Make sure we're really operating on the requested key (no swap attacks) - if keyAddr != key.Address { - return nil, fmt.Errorf("key content mismatch: have account %x, want %x", key.Address, keyAddr) - } - return key, nil -} - func decryptKeyV3(keyProtected *encryptedKeyJSONV3, auth string) (keyBytes []byte, keyId []byte, err error) { if keyProtected.Version != version { return nil, nil, fmt.Errorf("Version not supported: %v", keyProtected.Version) |