github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/account/keystore/mem_provider_impl.go (about)

     1  // Copyright (C) 2017 go-nebulas authors
     2  //
     3  // This file is part of the go-nebulas library.
     4  //
     5  // the go-nebulas library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // the go-nebulas library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU General Public License
    16  // along with the go-nebulas library.  If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  
    19  package account
    20  
    21  import (
    22  	"errors"
    23  	"fmt"
    24  
    25  	"sync"
    26  
    27  	"github.com/sixexorg/magnetic-ring/crypto"
    28  	"github.com/sixexorg/magnetic-ring/crypto/cipher"
    29  )
    30  
    31  var (
    32  	// ErrNeedAlias need alias
    33  	ErrNeedAlias = errors.New("need alias")
    34  
    35  	// ErrNotFound not find key
    36  	ErrNotFound = errors.New("key not found")
    37  )
    38  
    39  //在内存中保存的私钥
    40  // Entry keeps in memory
    41  type Entry struct {
    42  	key  crypto.PrivateKey
    43  	data []byte
    44  }
    45  
    46  // MemoryProvider handle keystore with ecdsa
    47  type MemoryProvider struct {
    48  
    49  	// name of ecdsa provider
    50  	name string
    51  
    52  	// version of ecdsa provider
    53  	version float32
    54  
    55  	// a map storage entry
    56  	entries map[string]Entry
    57  
    58  	// encrypt key
    59  	cipher *cipher.Cipher
    60  
    61  	mu sync.RWMutex
    62  }
    63  
    64  // NewMemoryProvider generate a provider with version
    65  func NewMemoryProvider(v float32) *MemoryProvider {
    66  	p := &MemoryProvider{name: "memoryProvider", version: v, entries: make(map[string]Entry)}
    67  	p.cipher = cipher.NewCipher()
    68  	return p
    69  }
    70  
    71  // Aliases all entry in provider save
    72  func (p *MemoryProvider) Aliases() []string {
    73  	p.mu.RLock()
    74  	defer p.mu.RUnlock()
    75  
    76  	aliases := []string{}
    77  	for a := range p.entries {
    78  		aliases = append(aliases, a)
    79  	}
    80  	return aliases
    81  }
    82  
    83  // SetKey assigns the given key (that has already been protected) to the given alias.
    84  func (p *MemoryProvider) SetKey(a string, key crypto.PrivateKey, passphrase []byte) error {
    85  	if len(a) == 0 {
    86  		return ErrNeedAlias
    87  	}
    88  	if len(passphrase) == 0 {
    89  		return errors.New("password length must > 0")
    90  	}
    91  
    92  	encoded := key.Bytes()
    93  
    94  
    95  	data, err := p.cipher.Encrypt(encoded, passphrase)
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	p.mu.Lock()
   101  	defer p.mu.Unlock()
   102  
   103  	entry := Entry{key, data}
   104  	p.entries[a] = entry
   105  	return nil
   106  }
   107  
   108  // GetKey returns the key associated with the given alias, using the given
   109  // password to recover it.
   110  func (p *MemoryProvider) GetKey(a string, passphrase []byte) (crypto.PrivateKey, error) {
   111  	if len(a) == 0 {
   112  		return nil, ErrNeedAlias
   113  	}
   114  	if len(passphrase) == 0 {
   115  		return nil, errors.New("need password")
   116  	}
   117  
   118  	p.mu.RLock()
   119  	defer p.mu.RUnlock()
   120  
   121  	entry, ok := p.entries[a]
   122  	if !ok {
   123  		fmt.Printf("final here 001\n")
   124  		return nil, ErrNotFound
   125  	}
   126  	//解密出私钥
   127  	data, err := p.cipher.Decrypt(entry.data, passphrase)
   128  	if err != nil {
   129  		return nil, err
   130  	}
   131  
   132  
   133  	entry.key,err = crypto.ToPrivateKey(data)
   134  
   135  	if err != nil {
   136  		return nil, err
   137  	}
   138  
   139  	return entry.key, nil
   140  }
   141  
   142  // Delete remove key
   143  func (p *MemoryProvider) Delete(a string) error {
   144  	p.mu.Lock()
   145  	defer p.mu.Unlock()
   146  
   147  	if &a == nil {
   148  		return ErrNeedAlias
   149  	}
   150  	delete(p.entries, a)
   151  	return nil
   152  }
   153  
   154  // ContainsAlias check provider contains key
   155  func (p *MemoryProvider) ContainsAlias(a string) (bool, error) {
   156  	p.mu.RLock()
   157  	defer p.mu.RUnlock()
   158  
   159  	if &a == nil {
   160  		return false, ErrNeedAlias
   161  	}
   162  
   163  	if _, ok := p.entries[a]; ok {
   164  		return true, nil
   165  	}
   166  	return false, ErrNotFound
   167  }
   168  
   169  // Clear clear all entries in provider
   170  func (p *MemoryProvider) Clear() error {
   171  	p.mu.Lock()
   172  	defer p.mu.Unlock()
   173  
   174  	if p.entries == nil {
   175  		return errors.New("need entries map")
   176  	}
   177  	p.entries = make(map[string]Entry)
   178  	return nil
   179  }