From 78745551c077bf54151202138c2629f288769561 Mon Sep 17 00:00:00 2001 From: Determinant Date: Tue, 15 Sep 2020 23:55:34 -0400 Subject: WIP: geth-tavum --- accounts/keystore/keystore.go | 23 ++++++++++++++++++++--- accounts/keystore/passphrase.go | 11 ++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) (limited to 'accounts/keystore') diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index a3ce33f..1bcaf13 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -24,7 +24,6 @@ import ( "crypto/ecdsa" crand "crypto/rand" "errors" - "fmt" "math/big" "os" "path/filepath" @@ -44,6 +43,10 @@ var ( ErrLocked = accounts.NewAuthNeededError("password or unlock") ErrNoMatch = errors.New("no key for given address or file") ErrDecrypt = errors.New("could not decrypt key with given password") + + // ErrAccountAlreadyExists is returned if an account attempted to import is + // already present in the keystore. + ErrAccountAlreadyExists = errors.New("account already exists") ) // KeyStoreType is the reflect type of a keystore backend. @@ -67,7 +70,8 @@ type KeyStore struct { updateScope event.SubscriptionScope // Subscription scope tracking current live listeners updating bool // Whether the event notification loop is running - mu sync.RWMutex + mu sync.RWMutex + importMu sync.Mutex // Import Mutex locks the import to prevent two insertions from racing } type unlocked struct { @@ -443,14 +447,27 @@ func (ks *KeyStore) Import(keyJSON []byte, passphrase, newPassphrase string) (ac if err != nil { return accounts.Account{}, err } + ks.importMu.Lock() + defer ks.importMu.Unlock() + + if ks.cache.hasAddress(key.Address) { + return accounts.Account{ + Address: key.Address, + }, ErrAccountAlreadyExists + } return ks.importKey(key, newPassphrase) } // ImportECDSA stores the given key into the key directory, encrypting it with the passphrase. func (ks *KeyStore) ImportECDSA(priv *ecdsa.PrivateKey, passphrase string) (accounts.Account, error) { + ks.importMu.Lock() + defer ks.importMu.Unlock() + key := newKeyFromECDSA(priv) if ks.cache.hasAddress(key.Address) { - return accounts.Account{}, fmt.Errorf("account already exists") + return accounts.Account{ + Address: key.Address, + }, ErrAccountAlreadyExists } return ks.importKey(key, passphrase) } diff --git a/accounts/keystore/passphrase.go b/accounts/keystore/passphrase.go index fa5a09d..04f31ff 100644 --- a/accounts/keystore/passphrase.go +++ b/accounts/keystore/passphrase.go @@ -121,8 +121,9 @@ func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) er "This indicates that the keystore is corrupted. \n" + "The corrupted file is stored at \n%v\n" + "Please file a ticket at:\n\n" + - "https://github.com/ethereum/go-ethereum/issues." + + "https://github.com/ava-labs/go-ethereum/issues." + "The error was : %s" + //lint:ignore ST1005 This is a message for the user return fmt.Errorf(msg, tmpName, err) } } @@ -237,7 +238,7 @@ func DecryptKey(keyjson []byte, auth string) (*Key, error) { func DecryptDataV3(cryptoJson CryptoJSON, auth string) ([]byte, error) { if cryptoJson.Cipher != "aes-128-ctr" { - return nil, fmt.Errorf("Cipher not supported: %v", cryptoJson.Cipher) + return nil, fmt.Errorf("cipher not supported: %v", cryptoJson.Cipher) } mac, err := hex.DecodeString(cryptoJson.MAC) if err != nil { @@ -273,7 +274,7 @@ func DecryptDataV3(cryptoJson CryptoJSON, auth string) ([]byte, error) { 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) + return nil, nil, fmt.Errorf("version not supported: %v", keyProtected.Version) } keyId = uuid.Parse(keyProtected.Id) plainText, err := DecryptDataV3(keyProtected.Crypto, auth) @@ -335,13 +336,13 @@ func getKDFKey(cryptoJSON CryptoJSON, auth string) ([]byte, error) { c := ensureInt(cryptoJSON.KDFParams["c"]) prf := cryptoJSON.KDFParams["prf"].(string) if prf != "hmac-sha256" { - return nil, fmt.Errorf("Unsupported PBKDF2 PRF: %s", prf) + return nil, fmt.Errorf("unsupported PBKDF2 PRF: %s", prf) } key := pbkdf2.Key(authArray, salt, c, dkLen, sha256.New) return key, nil } - return nil, fmt.Errorf("Unsupported KDF: %s", cryptoJSON.KDF) + return nil, fmt.Errorf("unsupported KDF: %s", cryptoJSON.KDF) } // TODO: can we do without this when unmarshalling dynamic JSON? -- cgit v1.2.3-70-g09d2