Skip to content

Commit d6357aa

Browse files
committed
Merge pull request ethereum#631 from Gustav-Simonsson/improve_key_store_crypto
Improve key store crypto
2 parents 58d6ec6 + e389585 commit d6357aa

File tree

22 files changed

+241
-196
lines changed

22 files changed

+241
-196
lines changed

accounts/account_manager.go

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ and accounts persistence is derived from stored keys' addresses
3333
package accounts
3434

3535
import (
36-
"bytes"
3736
"crypto/ecdsa"
3837
crand "crypto/rand"
3938
"errors"
4039
"os"
4140
"sync"
4241
"time"
4342

43+
"github.com/ethereum/go-ethereum/common"
4444
"github.com/ethereum/go-ethereum/crypto"
4545
)
4646

@@ -50,12 +50,12 @@ var (
5050
)
5151

5252
type Account struct {
53-
Address []byte
53+
Address common.Address
5454
}
5555

5656
type Manager struct {
5757
keyStore crypto.KeyStore2
58-
unlocked map[string]*unlocked
58+
unlocked map[common.Address]*unlocked
5959
mutex sync.RWMutex
6060
}
6161

@@ -67,40 +67,40 @@ type unlocked struct {
6767
func NewManager(keyStore crypto.KeyStore2) *Manager {
6868
return &Manager{
6969
keyStore: keyStore,
70-
unlocked: make(map[string]*unlocked),
70+
unlocked: make(map[common.Address]*unlocked),
7171
}
7272
}
7373

74-
func (am *Manager) HasAccount(addr []byte) bool {
74+
func (am *Manager) HasAccount(addr common.Address) bool {
7575
accounts, _ := am.Accounts()
7676
for _, acct := range accounts {
77-
if bytes.Compare(acct.Address, addr) == 0 {
77+
if acct.Address == addr {
7878
return true
7979
}
8080
}
8181
return false
8282
}
8383

84-
func (am *Manager) Primary() (addr []byte, err error) {
84+
func (am *Manager) Primary() (addr common.Address, err error) {
8585
addrs, err := am.keyStore.GetKeyAddresses()
8686
if os.IsNotExist(err) {
87-
return nil, ErrNoKeys
87+
return common.Address{}, ErrNoKeys
8888
} else if err != nil {
89-
return nil, err
89+
return common.Address{}, err
9090
}
9191
if len(addrs) == 0 {
92-
return nil, ErrNoKeys
92+
return common.Address{}, ErrNoKeys
9393
}
9494
return addrs[0], nil
9595
}
9696

97-
func (am *Manager) DeleteAccount(address []byte, auth string) error {
97+
func (am *Manager) DeleteAccount(address common.Address, auth string) error {
9898
return am.keyStore.DeleteKey(address, auth)
9999
}
100100

101101
func (am *Manager) Sign(a Account, toSign []byte) (signature []byte, err error) {
102102
am.mutex.RLock()
103-
unlockedKey, found := am.unlocked[string(a.Address)]
103+
unlockedKey, found := am.unlocked[a.Address]
104104
am.mutex.RUnlock()
105105
if !found {
106106
return nil, ErrLocked
@@ -111,7 +111,7 @@ func (am *Manager) Sign(a Account, toSign []byte) (signature []byte, err error)
111111

112112
// TimedUnlock unlocks the account with the given address.
113113
// When timeout has passed, the account will be locked again.
114-
func (am *Manager) TimedUnlock(addr []byte, keyAuth string, timeout time.Duration) error {
114+
func (am *Manager) TimedUnlock(addr common.Address, keyAuth string, timeout time.Duration) error {
115115
key, err := am.keyStore.GetKey(addr, keyAuth)
116116
if err != nil {
117117
return err
@@ -124,7 +124,7 @@ func (am *Manager) TimedUnlock(addr []byte, keyAuth string, timeout time.Duratio
124124
// Unlock unlocks the account with the given address. The account
125125
// stays unlocked until the program exits or until a TimedUnlock
126126
// timeout (started after the call to Unlock) expires.
127-
func (am *Manager) Unlock(addr []byte, keyAuth string) error {
127+
func (am *Manager) Unlock(addr common.Address, keyAuth string) error {
128128
key, err := am.keyStore.GetKey(addr, keyAuth)
129129
if err != nil {
130130
return err
@@ -157,10 +157,10 @@ func (am *Manager) Accounts() ([]Account, error) {
157157
return accounts, err
158158
}
159159

160-
func (am *Manager) addUnlocked(addr []byte, key *crypto.Key) *unlocked {
160+
func (am *Manager) addUnlocked(addr common.Address, key *crypto.Key) *unlocked {
161161
u := &unlocked{Key: key, abort: make(chan struct{})}
162162
am.mutex.Lock()
163-
prev, found := am.unlocked[string(addr)]
163+
prev, found := am.unlocked[addr]
164164
if found {
165165
// terminate dropLater for this key to avoid unexpected drops.
166166
close(prev.abort)
@@ -169,12 +169,12 @@ func (am *Manager) addUnlocked(addr []byte, key *crypto.Key) *unlocked {
169169
// key, i.e. when Unlock was used.
170170
zeroKey(prev.PrivateKey)
171171
}
172-
am.unlocked[string(addr)] = u
172+
am.unlocked[addr] = u
173173
am.mutex.Unlock()
174174
return u
175175
}
176176

177-
func (am *Manager) dropLater(addr []byte, u *unlocked, timeout time.Duration) {
177+
func (am *Manager) dropLater(addr common.Address, u *unlocked, timeout time.Duration) {
178178
t := time.NewTimer(timeout)
179179
defer t.Stop()
180180
select {
@@ -186,9 +186,9 @@ func (am *Manager) dropLater(addr []byte, u *unlocked, timeout time.Duration) {
186186
// was launched with. we can check that using pointer equality
187187
// because the map stores a new pointer every time the key is
188188
// unlocked.
189-
if am.unlocked[string(addr)] == u {
189+
if am.unlocked[addr] == u {
190190
zeroKey(u.PrivateKey)
191-
delete(am.unlocked, string(addr))
191+
delete(am.unlocked, addr)
192192
}
193193
am.mutex.Unlock()
194194
}
@@ -204,7 +204,7 @@ func zeroKey(k *ecdsa.PrivateKey) {
204204

205205
// USE WITH CAUTION = this will save an unencrypted private key on disk
206206
// no cli or js interface
207-
func (am *Manager) Export(path string, addr []byte, keyAuth string) error {
207+
func (am *Manager) Export(path string, addr common.Address, keyAuth string) error {
208208
key, err := am.keyStore.GetKey(addr, keyAuth)
209209
if err != nil {
210210
return err

cmd/geth/admin.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ func (js *jsre) pendingTransactions(call otto.FunctionCall) otto.Value {
126126
// Add the accouns to a new set
127127
accountSet := set.New()
128128
for _, account := range accounts {
129-
accountSet.Add(common.BytesToAddress(account.Address))
129+
accountSet.Add(account.Address)
130130
}
131131

132132
//ltxs := make([]*tx, len(txs))
@@ -391,7 +391,7 @@ func (js *jsre) unlock(call otto.FunctionCall) otto.Value {
391391
}
392392
}
393393
am := js.ethereum.AccountManager()
394-
err = am.TimedUnlock(common.FromHex(addr), passphrase, time.Duration(seconds)*time.Second)
394+
err = am.TimedUnlock(common.HexToAddress(addr), passphrase, time.Duration(seconds)*time.Second)
395395
if err != nil {
396396
fmt.Printf("Unlock account failed '%v'\n", err)
397397
return otto.FalseValue()
@@ -433,7 +433,7 @@ func (js *jsre) newAccount(call otto.FunctionCall) otto.Value {
433433
fmt.Printf("Could not create the account: %v", err)
434434
return otto.UndefinedValue()
435435
}
436-
return js.re.ToVal(common.ToHex(acct.Address))
436+
return js.re.ToVal(acct.Address.Hex())
437437
}
438438

439439
func (js *jsre) nodeInfo(call otto.FunctionCall) otto.Value {

cmd/geth/js.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"strings"
2727

2828
"github.com/ethereum/go-ethereum/cmd/utils"
29+
"github.com/ethereum/go-ethereum/common"
2930
"github.com/ethereum/go-ethereum/common/docserver"
3031
"github.com/ethereum/go-ethereum/common/natspec"
3132
"github.com/ethereum/go-ethereum/eth"
@@ -164,7 +165,7 @@ func (self *jsre) UnlockAccount(addr []byte) bool {
164165
return false
165166
}
166167
// TODO: allow retry
167-
if err := self.ethereum.AccountManager().Unlock(addr, pass); err != nil {
168+
if err := self.ethereum.AccountManager().Unlock(common.BytesToAddress(addr), pass); err != nil {
168169
return false
169170
} else {
170171
fmt.Println("Account is now unlocked for this session.")

cmd/geth/js_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ type testjethre struct {
4545
}
4646

4747
func (self *testjethre) UnlockAccount(acc []byte) bool {
48-
err := self.ethereum.AccountManager().Unlock(acc, "")
48+
err := self.ethereum.AccountManager().Unlock(common.BytesToAddress(acc), "")
4949
if err != nil {
5050
panic("unable to unlock")
5151
}
@@ -68,7 +68,7 @@ func testJEthRE(t *testing.T) (string, *testjethre, *eth.Ethereum) {
6868
// set up mock genesis with balance on the testAddress
6969
core.GenesisData = []byte(testGenesis)
7070

71-
ks := crypto.NewKeyStorePassphrase(filepath.Join(tmp, "keys"))
71+
ks := crypto.NewKeyStorePassphrase(filepath.Join(tmp, "keystore"))
7272
am := accounts.NewManager(ks)
7373
ethereum, err := eth.New(&eth.Config{
7474
DataDir: tmp,

cmd/geth/main.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -365,11 +365,10 @@ func unlockAccount(ctx *cli.Context, am *accounts.Manager, account string) (pass
365365
// Load startup keys. XXX we are going to need a different format
366366
// Attempt to unlock the account
367367
passphrase = getPassPhrase(ctx, "", false)
368-
accbytes := common.FromHex(account)
369-
if len(accbytes) == 0 {
368+
if len(account) == 0 {
370369
utils.Fatalf("Invalid account address '%s'", account)
371370
}
372-
err = am.Unlock(accbytes, passphrase)
371+
err = am.Unlock(common.StringToAddress(account), passphrase)
373372
if err != nil {
374373
utils.Fatalf("Unlock account failed '%v'", err)
375374
}
@@ -385,11 +384,11 @@ func startEth(ctx *cli.Context, eth *eth.Ethereum) {
385384
account := ctx.GlobalString(utils.UnlockedAccountFlag.Name)
386385
if len(account) > 0 {
387386
if account == "primary" {
388-
accbytes, err := am.Primary()
387+
primaryAcc, err := am.Primary()
389388
if err != nil {
390389
utils.Fatalf("no primary account: %v", err)
391390
}
392-
account = common.ToHex(accbytes)
391+
account = primaryAcc.Hex()
393392
}
394393
unlockAccount(ctx, am, account)
395394
}

cmd/mist/gui.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ func (self *Gui) loadMergedMiningOptions() {
232232
func (gui *Gui) insertTransaction(window string, tx *types.Transaction) {
233233
var inout string
234234
from, _ := tx.From()
235-
if gui.eth.AccountManager().HasAccount(common.Hex2Bytes(from.Hex())) {
235+
if gui.eth.AccountManager().HasAccount(from) {
236236
inout = "send"
237237
} else {
238238
inout = "recv"

cmd/utils/flags.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ func GetChain(ctx *cli.Context) (*core.ChainManager, common.Database, common.Dat
346346

347347
func GetAccountManager(ctx *cli.Context) *accounts.Manager {
348348
dataDir := ctx.GlobalString(DataDirFlag.Name)
349-
ks := crypto.NewKeyStorePassphrase(filepath.Join(dataDir, "keys"))
349+
ks := crypto.NewKeyStorePassphrase(filepath.Join(dataDir, "keystore"))
350350
return accounts.NewManager(ks)
351351
}
352352

common/natspec/natspec_e2e_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"io/ioutil"
66
"os"
7+
"strings"
78
"testing"
89

910
"github.com/ethereum/go-ethereum/accounts"
@@ -84,7 +85,7 @@ type testFrontend struct {
8485
}
8586

8687
func (self *testFrontend) UnlockAccount(acc []byte) bool {
87-
self.ethereum.AccountManager().Unlock(acc, "password")
88+
self.ethereum.AccountManager().Unlock(common.BytesToAddress(acc), "password")
8889
return true
8990
}
9091

@@ -103,19 +104,19 @@ func testEth(t *testing.T) (ethereum *eth.Ethereum, err error) {
103104

104105
os.RemoveAll("/tmp/eth-natspec/")
105106

106-
err = os.MkdirAll("/tmp/eth-natspec/keys", os.ModePerm)
107+
err = os.MkdirAll("/tmp/eth-natspec/keystore", os.ModePerm)
107108
if err != nil {
108109
panic(err)
109110
}
110111

111112
// create a testAddress
112-
ks := crypto.NewKeyStorePassphrase("/tmp/eth-natspec/keys")
113+
ks := crypto.NewKeyStorePassphrase("/tmp/eth-natspec/keystore")
113114
am := accounts.NewManager(ks)
114115
testAccount, err := am.NewAccount("password")
115116
if err != nil {
116117
panic(err)
117118
}
118-
testAddress := common.Bytes2Hex(testAccount.Address)
119+
testAddress := strings.TrimPrefix(testAccount.Address.Hex(), "0x")
119120

120121
// set up mock genesis with balance on the testAddress
121122
core.GenesisData = []byte(`{

crypto/crypto.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,11 @@ func Decrypt(prv *ecdsa.PrivateKey, ct []byte) ([]byte, error) {
181181

182182
// Used only by block tests.
183183
func ImportBlockTestKey(privKeyBytes []byte) error {
184-
ks := NewKeyStorePassphrase(common.DefaultDataDir() + "/keys")
184+
ks := NewKeyStorePassphrase(common.DefaultDataDir() + "/keystore")
185185
ecKey := ToECDSA(privKeyBytes)
186186
key := &Key{
187187
Id: uuid.NewRandom(),
188-
Address: PubkeyToAddress(ecKey.PublicKey),
188+
Address: common.BytesToAddress(PubkeyToAddress(ecKey.PublicKey)),
189189
PrivateKey: ecKey,
190190
}
191191
err := ks.StoreKey(key, "")
@@ -231,13 +231,13 @@ func decryptPreSaleKey(fileContent []byte, password string) (key *Key, err error
231231
ecKey := ToECDSA(ethPriv)
232232
key = &Key{
233233
Id: nil,
234-
Address: PubkeyToAddress(ecKey.PublicKey),
234+
Address: common.BytesToAddress(PubkeyToAddress(ecKey.PublicKey)),
235235
PrivateKey: ecKey,
236236
}
237-
derivedAddr := common.Bytes2Hex(key.Address)
237+
derivedAddr := hex.EncodeToString(key.Address.Bytes()) // needed because .Hex() gives leading "0x"
238238
expectedAddr := preSaleKeyStruct.EthAddr
239239
if derivedAddr != expectedAddr {
240-
err = errors.New("decrypted addr not equal to expected addr")
240+
err = errors.New(fmt.Sprintf("decrypted addr not equal to expected addr ", derivedAddr, expectedAddr))
241241
}
242242
return key, err
243243
}
@@ -252,7 +252,7 @@ func aesCBCDecrypt(key []byte, cipherText []byte, iv []byte) (plainText []byte,
252252
decrypter.CryptBlocks(paddedPlainText, cipherText)
253253
plainText = PKCS7Unpad(paddedPlainText)
254254
if plainText == nil {
255-
err = errors.New("Decryption failed: PKCS7Unpad failed after decryption")
255+
err = errors.New("Decryption failed: PKCS7Unpad failed after AES decryption")
256256
}
257257
return plainText, err
258258
}

0 commit comments

Comments
 (0)