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 }