github.com/igggame/nebulas-go@v2.1.0+incompatible/crypto/keystore/memory_provider.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 keystore
    20  
    21  import (
    22  	"errors"
    23  
    24  	"sync"
    25  
    26  	"github.com/nebulasio/go-nebulas/crypto/cipher"
    27  )
    28  
    29  var (
    30  	// ErrNeedAlias need alias
    31  	ErrNeedAlias = errors.New("need alias")
    32  
    33  	// ErrNotFound not find key
    34  	ErrNotFound = errors.New("key not found")
    35  )
    36  
    37  // Entry keeps in memory
    38  type Entry struct {
    39  	key  Key
    40  	data []byte
    41  }
    42  
    43  // MemoryProvider handle keystore with ecdsa
    44  type MemoryProvider struct {
    45  
    46  	// name of ecdsa provider
    47  	name string
    48  
    49  	// version of ecdsa provider
    50  	version float32
    51  
    52  	// a map storage entry
    53  	entries map[string]Entry
    54  
    55  	// encrypt key
    56  	cipher *cipher.Cipher
    57  
    58  	mu sync.RWMutex
    59  }
    60  
    61  // NewMemoryProvider generate a provider with version
    62  func NewMemoryProvider(v float32, alg Algorithm) *MemoryProvider {
    63  	p := &MemoryProvider{name: "memoryProvider", version: v, entries: make(map[string]Entry)}
    64  	p.cipher = cipher.NewCipher(uint8(alg))
    65  	return p
    66  }
    67  
    68  // Aliases all entry in provider save
    69  func (p *MemoryProvider) Aliases() []string {
    70  	p.mu.RLock()
    71  	defer p.mu.RUnlock()
    72  
    73  	aliases := []string{}
    74  	for a := range p.entries {
    75  		aliases = append(aliases, a)
    76  	}
    77  	return aliases
    78  }
    79  
    80  // SetKey assigns the given key (that has already been protected) to the given alias.
    81  func (p *MemoryProvider) SetKey(a string, key Key, passphrase []byte) error {
    82  	if len(a) == 0 {
    83  		return ErrNeedAlias
    84  	}
    85  	if len(passphrase) == 0 {
    86  		return ErrInvalidPassphrase
    87  	}
    88  
    89  	encoded, err := key.Encoded()
    90  	if err != nil {
    91  		return err
    92  	}
    93  	data, err := p.cipher.Encrypt(encoded, passphrase)
    94  	if err != nil {
    95  		return err
    96  	}
    97  
    98  	p.mu.Lock()
    99  	defer p.mu.Unlock()
   100  
   101  	entry := Entry{key, data}
   102  	p.entries[a] = entry
   103  	return nil
   104  }
   105  
   106  // GetKey returns the key associated with the given alias, using the given
   107  // password to recover it.
   108  func (p *MemoryProvider) GetKey(a string, passphrase []byte) (Key, error) {
   109  	if len(a) == 0 {
   110  		return nil, ErrNeedAlias
   111  	}
   112  	if len(passphrase) == 0 {
   113  		return nil, ErrInvalidPassphrase
   114  	}
   115  
   116  	p.mu.RLock()
   117  	defer p.mu.RUnlock()
   118  
   119  	entry, ok := p.entries[a]
   120  	if !ok {
   121  		return nil, ErrNotFound
   122  	}
   123  	data, err := p.cipher.Decrypt(entry.data, passphrase)
   124  	if err != nil {
   125  		return nil, err
   126  	}
   127  	err = entry.key.Decode(data)
   128  	if err != nil {
   129  		return nil, err
   130  	}
   131  	return entry.key, nil
   132  }
   133  
   134  // Delete remove key
   135  func (p *MemoryProvider) Delete(a string) error {
   136  	p.mu.Lock()
   137  	defer p.mu.Unlock()
   138  
   139  	if &a == nil {
   140  		return ErrNeedAlias
   141  	}
   142  	delete(p.entries, a)
   143  	return nil
   144  }
   145  
   146  // ContainsAlias check provider contains key
   147  func (p *MemoryProvider) ContainsAlias(a string) (bool, error) {
   148  	p.mu.RLock()
   149  	defer p.mu.RUnlock()
   150  
   151  	if &a == nil {
   152  		return false, ErrNeedAlias
   153  	}
   154  
   155  	if _, ok := p.entries[a]; ok {
   156  		return true, nil
   157  	}
   158  	return false, ErrNotFound
   159  }
   160  
   161  // Clear clear all entries in provider
   162  func (p *MemoryProvider) Clear() error {
   163  	p.mu.Lock()
   164  	defer p.mu.Unlock()
   165  
   166  	if p.entries == nil {
   167  		return errors.New("need entries map")
   168  	}
   169  	p.entries = make(map[string]Entry)
   170  	return nil
   171  }