Skip to content

Commit

Permalink
# wallet-security-solution
Browse files Browse the repository at this point in the history
 ## Features
  - password management:
    - Add, modify, clear password
    - Swap between normal wallets and encrypted wallets
  - message management:
    - Guarantee the security of funds: password verification is required for encrypted wallet transfer operations
    - Protect the security of private keys: encrypted wallets export private keys and delete passwords that require verification
    - Sealed messages are not affected: encrypted wallet sealed messages do not require verification passwords
 ## Usage
```
  lotus wallet addpasswd  # add password
  lotus wallet resetpasswd  # reset password
  lotus wallet clearpasswd  # clear password
  lotus wallet encrypt <fxxx>  # encrypted wallet
  lotus wallet decrypt <fxxx>  # normal wallet
```
  • Loading branch information
cdcdx committed Apr 27, 2022
1 parent 731da45 commit 5e6db2a
Show file tree
Hide file tree
Showing 20 changed files with 1,440 additions and 5 deletions.
45 changes: 45 additions & 0 deletions api/api_full.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,9 @@ type FullNode interface {
// WalletValidateAddress validates whether a given string can be decoded as a well-formed address
WalletValidateAddress(context.Context, string) (address.Address, error) //perm:read

// WalletCustomMethod wallet extension operation
WalletCustomMethod(context.Context, WalletMethod, []interface{}) (interface{}, error) //perm:admin

// Other

// MethodGroup: Client
Expand Down Expand Up @@ -1196,3 +1199,45 @@ type MsigTransaction struct {

Approved []address.Address
}

type AddrListEncrypt struct {
Addr address.Address
Encrypt bool
}
type WalletMethod int64

const (
Unknown WalletMethod = 0
WalletListForEnc WalletMethod = 1
WalletExportForEnc WalletMethod = 2
WalletDeleteForEnc WalletMethod = 3

WalletAddPasswd WalletMethod = 4
WalletResetPasswd WalletMethod = 5
WalletClearPasswd WalletMethod = 6
WalletCheckPasswd WalletMethod = 7

WalletEncrypt WalletMethod = 8
WalletDecrypt WalletMethod = 9
WalletIsEncrypt WalletMethod = 10
)

var WalletMethodStr = map[WalletMethod]string{
Unknown: "Unknown",
WalletListForEnc: "WalletListForEnc",
WalletExportForEnc: "WalletExportForEnc",
WalletDeleteForEnc: "WalletDeleteForEnc",

WalletAddPasswd: "WalletAddPasswd",
WalletResetPasswd: "WalletResetPasswd",
WalletClearPasswd: "WalletClearPasswd",
WalletCheckPasswd: "WalletCheckPasswd",

WalletEncrypt: "WalletEncrypt",
WalletDecrypt: "WalletDecrypt",
WalletIsEncrypt: "WalletIsEncrypt",
}

func (w WalletMethod) String() string {
return WalletMethodStr[w]
}
2 changes: 2 additions & 0 deletions api/api_wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,6 @@ type Wallet interface {
WalletExport(context.Context, address.Address) (*types.KeyInfo, error) //perm:admin
WalletImport(context.Context, *types.KeyInfo) (address.Address, error) //perm:admin
WalletDelete(context.Context, address.Address) error //perm:admin

WalletCustomMethod(context.Context, WalletMethod, []interface{}) (interface{}, error) //perm:admin
}
15 changes: 15 additions & 0 deletions api/mocks/mock_full.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions api/proxy_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions api/v0api/full.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ type FullNode interface {
// WalletValidateAddress validates whether a given string can be decoded as a well-formed address
WalletValidateAddress(context.Context, string) (address.Address, error) //perm:read

// WalletCustomMethod wallet extension operation
WalletCustomMethod(context.Context, api.WalletMethod, []interface{}) (interface{}, error) //perm:admin

// Other

// MethodGroup: Client
Expand Down
12 changes: 12 additions & 0 deletions api/v0api/proxy_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions api/v0api/v0mocks/mock_full.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 14 additions & 2 deletions chain/wallet/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,15 @@ func GenerateKey(typ types.KeyType) (*Key, error) {
if err != nil {
return nil, err
}

pk1, err := MakeByte(pk)
if err != nil {
return nil, err
}

ki := types.KeyInfo{
Type: typ,
PrivateKey: pk,
PrivateKey: pk1, //PrivateKey: pk,
}
return NewKey(ki)
}
Expand All @@ -39,7 +45,13 @@ func NewKey(keyinfo types.KeyInfo) (*Key, error) {
}

var err error
k.PublicKey, err = sigs.ToPublic(ActSigType(k.Type), k.PrivateKey)

pk, err := UnMakeByte(k.PrivateKey)
if err != nil {
return nil, err
}
k.PublicKey, err = sigs.ToPublic(ActSigType(k.Type), pk)

if err != nil {
return nil, err
}
Expand Down
5 changes: 5 additions & 0 deletions chain/wallet/ledger/ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,3 +240,8 @@ var dsLedgerPrefix = "/ledgerkey/"
func keyForAddr(addr address.Address) datastore.Key {
return datastore.NewKey(dsLedgerPrefix + addr.String())
}

// WalletCustomMethod dont use this method for LedgerWallet
func (lw *LedgerWallet) WalletCustomMethod(ctx context.Context, meth api.WalletMethod, args []interface{}) (interface{}, error) {
return nil, xerrors.Errorf("LedgerWallet do not support extension operations for the time being")
}
102 changes: 102 additions & 0 deletions chain/wallet/multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,105 @@ func (m MultiWallet) WalletDelete(ctx context.Context, address address.Address)
}

var _ api.Wallet = MultiWallet{}

// wallet-security list/export/import
//add MultiWallet Support extended
func (m MultiWallet) WalletListEncrypt(ctx context.Context) ([]api.AddrListEncrypt, error) {
out := make([]api.AddrListEncrypt, 0)
ws := nonNil(m.Remote, m.Ledger, m.Local)
for _, w := range ws {
if w == m.Local.Get() {
l, err := m.Local.WalletListEncrypt(ctx)
if err != nil {
return nil, err
}
out = append(out, l...)
} else {
l, err := w.WalletList(ctx)
if err != nil {
return nil, err
}
for _, v := range l {
out = append(out, api.AddrListEncrypt{
Addr: v,
Encrypt: false,
})
}
}
}
return out, nil
}
func (m MultiWallet) WalletExportEncrypt(ctx context.Context, address address.Address, passwd string) (*types.KeyInfo, error) {
w, err := m.find(ctx, address, m.Remote, m.Local)
if err != nil {
return nil, err
}
if w == nil {
return nil, xerrors.Errorf("key not found")
}
if w == m.Local.Get() {
return m.Local.WalletExportEncrypt(ctx, address, passwd)
}
return w.WalletExport(ctx, address)
}
func (m MultiWallet) WalletDeleteEncrypt(ctx context.Context, address address.Address, passwd string) error {
w, err := m.find(ctx, address, m.Remote, m.Ledger, m.Local)
if err != nil {
return err
}
if w == nil {
return nil
}
if w == m.Local.Get() {
return m.Local.WalletDeleteEncrypt(ctx, address, passwd)
}
return w.WalletDelete(ctx, address)
}

// WalletCustomMethod dont use this method for MultiWallet
func (m MultiWallet) WalletCustomMethod(ctx context.Context, meth api.WalletMethod, args []interface{}) (interface{}, error) {
switch meth {
case api.WalletListForEnc:
return m.WalletListEncrypt(ctx)
case api.WalletExportForEnc:
if len(args) < 2 {
return nil, xerrors.Errorf("args must is 2 for exec method, but get args is %v", len(args))
}
addr_str := args[0].(string)
addr, _ := address.NewFromString(addr_str)
passwd := args[1].(string)
return m.WalletExportEncrypt(ctx, addr, passwd)
case api.WalletDeleteForEnc:
if len(args) < 2 {
return nil, xerrors.Errorf("args must is 2 for exec method, but get args is %v", len(args))
}
addr_str := args[0].(string)
addr, _ := address.NewFromString(addr_str)
passwd := args[1].(string)
return nil, m.WalletDeleteEncrypt(ctx, addr, passwd)
case api.WalletEncrypt:
if len(args) < 2 {
return nil, xerrors.Errorf("args must is 2 for exec method, but get args is %v", len(args))
}
addr_str := args[0].(string)
addr, _ := address.NewFromString(addr_str)
passwd := args[1].(string)
return m.Local.WalletEncrypt(ctx, addr, passwd)
case api.WalletDecrypt:
if len(args) < 2 {
return nil, xerrors.Errorf("args must is 2 for exec method, but get args is %v", len(args))
}
addr_str := args[0].(string)
addr, _ := address.NewFromString(addr_str)
passwd := args[1].(string)
return m.Local.WalletDecrypt(ctx, addr, passwd)
case api.WalletIsEncrypt:
if len(args) < 1 {
return nil, xerrors.Errorf("args must is 1 for exec method, but get args is %v", len(args))
}
addr_str := args[0].(string)
addr, _ := address.NewFromString(addr_str)
return m.Local.WalletIsEncrypt(ctx, addr)
}
return m.Local.WalletCustomMethod(ctx, meth, args)
}
Loading

0 comments on commit 5e6db2a

Please sign in to comment.