Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
46ce66a8
Commit
46ce66a8
authored
Feb 25, 2015
by
Jeffrey Wilcke
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #385 from Gustav-Simonsson/account_manager_key_locking
Add automatic locking / unlocking of accounts
parents
b155b9d8
23f26580
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
91 additions
and
11 deletions
+91
-11
account_manager.go
accounts/account_manager.go
+40
-9
accounts_test.go
accounts/accounts_test.go
+51
-2
No files found.
accounts/account_manager.go
View file @
46ce66a8
...
...
@@ -34,9 +34,14 @@ package accounts
import
(
crand
"crypto/rand"
"errors"
"github.com/ethereum/go-ethereum/crypto"
"sync"
"time"
)
var
ErrLocked
=
errors
.
New
(
"account is locked; please request passphrase"
)
// TODO: better name for this struct?
type
Account
struct
{
Address
[]
byte
...
...
@@ -44,14 +49,17 @@ type Account struct {
type
AccountManager
struct
{
keyStore
crypto
.
KeyStore2
unlockedKeys
map
[
string
]
crypto
.
Key
unlockMilliseconds
time
.
Duration
mutex
sync
.
RWMutex
}
// TODO: get key by addr - modify KeyStore2 GetKey to work with addr
// TODO: pass through passphrase for APIs which require access to private key?
func
NewAccountManager
(
keyStore
crypto
.
KeyStore2
)
AccountManager
{
func
NewAccountManager
(
keyStore
crypto
.
KeyStore2
,
unlockMilliseconds
time
.
Duration
)
AccountManager
{
keysMap
:=
make
(
map
[
string
]
crypto
.
Key
)
am
:=
&
AccountManager
{
keyStore
:
keyStore
,
unlockedKeys
:
keysMap
,
unlockMilliseconds
:
unlockMilliseconds
,
}
return
*
am
}
...
...
@@ -60,11 +68,26 @@ func (am AccountManager) DeleteAccount(address []byte, auth string) error {
return
am
.
keyStore
.
DeleteKey
(
address
,
auth
)
}
func
(
am
*
AccountManager
)
Sign
(
fromAccount
*
Account
,
keyAuth
string
,
toSign
[]
byte
)
(
signature
[]
byte
,
err
error
)
{
func
(
am
*
AccountManager
)
Sign
(
fromAccount
*
Account
,
toSign
[]
byte
)
(
signature
[]
byte
,
err
error
)
{
am
.
mutex
.
RLock
()
unlockedKey
:=
am
.
unlockedKeys
[
string
(
fromAccount
.
Address
)]
am
.
mutex
.
RUnlock
()
if
unlockedKey
.
Address
==
nil
{
return
nil
,
ErrLocked
}
signature
,
err
=
crypto
.
Sign
(
toSign
,
unlockedKey
.
PrivateKey
)
return
signature
,
err
}
func
(
am
*
AccountManager
)
SignLocked
(
fromAccount
*
Account
,
keyAuth
string
,
toSign
[]
byte
)
(
signature
[]
byte
,
err
error
)
{
key
,
err
:=
am
.
keyStore
.
GetKey
(
fromAccount
.
Address
,
keyAuth
)
if
err
!=
nil
{
return
nil
,
err
}
am
.
mutex
.
RLock
()
am
.
unlockedKeys
[
string
(
fromAccount
.
Address
)]
=
*
key
am
.
mutex
.
RUnlock
()
go
unlockLater
(
am
,
fromAccount
.
Address
)
signature
,
err
=
crypto
.
Sign
(
toSign
,
key
.
PrivateKey
)
return
signature
,
err
}
...
...
@@ -80,8 +103,6 @@ func (am AccountManager) NewAccount(auth string) (*Account, error) {
return
ua
,
err
}
// set of accounts == set of keys in given key store
// TODO: do we need persistence of accounts as well?
func
(
am
*
AccountManager
)
Accounts
()
([]
Account
,
error
)
{
addresses
,
err
:=
am
.
keyStore
.
GetKeyAddresses
()
if
err
!=
nil
{
...
...
@@ -97,3 +118,13 @@ func (am *AccountManager) Accounts() ([]Account, error) {
}
return
accounts
,
err
}
func
unlockLater
(
am
*
AccountManager
,
addr
[]
byte
)
{
select
{
case
<-
time
.
After
(
time
.
Millisecond
*
am
.
unlockMilliseconds
)
:
}
am
.
mutex
.
RLock
()
// TODO: how do we know the key is actually gone from memory?
delete
(
am
.
unlockedKeys
,
string
(
addr
))
am
.
mutex
.
RUnlock
()
}
accounts/accounts_test.go
View file @
46ce66a8
...
...
@@ -6,19 +6,68 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/randentropy"
"github.com/ethereum/go-ethereum/ethutil"
"time"
)
func
TestAccountManager
(
t
*
testing
.
T
)
{
ks
:=
crypto
.
NewKeyStorePlain
(
ethutil
.
DefaultDataDir
()
+
"/testaccounts"
)
am
:=
NewAccountManager
(
ks
)
am
:=
NewAccountManager
(
ks
,
100
)
pass
:=
""
// not used but required by API
a1
,
err
:=
am
.
NewAccount
(
pass
)
toSign
:=
randentropy
.
GetEntropyCSPRNG
(
32
)
_
,
err
=
am
.
Sign
(
a1
,
pass
,
toSign
)
_
,
err
=
am
.
Sign
Locked
(
a1
,
pass
,
toSign
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
// Cleanup
time
.
Sleep
(
time
.
Millisecond
*
150
)
// wait for locking
accounts
,
err
:=
am
.
Accounts
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
for
_
,
account
:=
range
accounts
{
err
:=
am
.
DeleteAccount
(
account
.
Address
,
pass
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
}
}
func
TestAccountManagerLocking
(
t
*
testing
.
T
)
{
ks
:=
crypto
.
NewKeyStorePassphrase
(
ethutil
.
DefaultDataDir
()
+
"/testaccounts"
)
am
:=
NewAccountManager
(
ks
,
200
)
pass
:=
"foo"
a1
,
err
:=
am
.
NewAccount
(
pass
)
toSign
:=
randentropy
.
GetEntropyCSPRNG
(
32
)
// Signing without passphrase fails because account is locked
_
,
err
=
am
.
Sign
(
a1
,
toSign
)
if
err
!=
ErrLocked
{
t
.
Fatal
(
err
)
}
// Signing with passphrase works
_
,
err
=
am
.
SignLocked
(
a1
,
pass
,
toSign
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
// Signing without passphrase works because account is temp unlocked
_
,
err
=
am
.
Sign
(
a1
,
toSign
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
// Signing without passphrase fails after automatic locking
time
.
Sleep
(
time
.
Millisecond
*
time
.
Duration
(
250
))
_
,
err
=
am
.
Sign
(
a1
,
toSign
)
if
err
!=
ErrLocked
{
t
.
Fatal
(
err
)
}
// Cleanup
accounts
,
err
:=
am
.
Accounts
()
if
err
!=
nil
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment