| 
									
										
										
										
											2014-10-31 12:37:43 +01:00
										 |  |  | package crypto | 
					
						
							| 
									
										
										
										
											2014-06-29 16:02:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"io/ioutil" | 
					
						
							|  |  |  | 	"os" | 
					
						
							|  |  |  | 	"path" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2014-10-23 15:01:27 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/ethutil" | 
					
						
							| 
									
										
										
										
											2014-06-29 16:02:23 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type KeyStore interface { | 
					
						
							|  |  |  | 	Load(string) (*KeyRing, error) | 
					
						
							|  |  |  | 	Save(string, *KeyRing) error | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type DBKeyStore struct { | 
					
						
							|  |  |  | 	db ethutil.Database | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const dbKeyPrefix = "KeyRing" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *DBKeyStore) dbKey(session string) []byte { | 
					
						
							|  |  |  | 	return []byte(fmt.Sprintf("%s%s", dbKeyPrefix, session)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *DBKeyStore) Save(session string, keyRing *KeyRing) error { | 
					
						
							|  |  |  | 	k.db.Put(k.dbKey(session), keyRing.RlpEncode()) | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *DBKeyStore) Load(session string) (*KeyRing, error) { | 
					
						
							|  |  |  | 	data, err := k.db.Get(k.dbKey(session)) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-06-29 20:53:26 +01:00
										 |  |  | 		return nil, nil | 
					
						
							| 
									
										
										
										
											2014-06-29 16:02:23 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	var keyRing *KeyRing | 
					
						
							|  |  |  | 	keyRing, err = NewKeyRingFromBytes(data) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// if empty keyRing is found we return nil, no error | 
					
						
							|  |  |  | 	if keyRing.Len() == 0 { | 
					
						
							|  |  |  | 		return nil, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return keyRing, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type FileKeyStore struct { | 
					
						
							|  |  |  | 	basedir string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *FileKeyStore) Save(session string, keyRing *KeyRing) error { | 
					
						
							|  |  |  | 	var content []byte | 
					
						
							|  |  |  | 	var err error | 
					
						
							|  |  |  | 	var privateKeys []string | 
					
						
							|  |  |  | 	var publicKeys []string | 
					
						
							|  |  |  | 	var mnemonics []string | 
					
						
							|  |  |  | 	var addresses []string | 
					
						
							|  |  |  | 	keyRing.Each(func(keyPair *KeyPair) { | 
					
						
							|  |  |  | 		privateKeys = append(privateKeys, ethutil.Bytes2Hex(keyPair.PrivateKey)) | 
					
						
							|  |  |  | 		publicKeys = append(publicKeys, ethutil.Bytes2Hex(keyPair.PublicKey)) | 
					
						
							|  |  |  | 		addresses = append(addresses, ethutil.Bytes2Hex(keyPair.Address())) | 
					
						
							| 
									
										
										
										
											2014-06-29 20:28:54 +01:00
										 |  |  | 		mnemonics = append(mnemonics, keyPair.Mnemonic()) | 
					
						
							| 
									
										
										
										
											2014-06-29 16:02:23 +01:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	basename := session | 
					
						
							|  |  |  | 	if session == "" { | 
					
						
							|  |  |  | 		basename = "default" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	path := path.Join(k.basedir, basename) | 
					
						
							|  |  |  | 	content = []byte(strings.Join(privateKeys, "\n")) | 
					
						
							|  |  |  | 	err = ioutil.WriteFile(path+".prv", content, 0600) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	content = []byte(strings.Join(publicKeys, "\n")) | 
					
						
							|  |  |  | 	err = ioutil.WriteFile(path+".pub", content, 0644) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	content = []byte(strings.Join(addresses, "\n")) | 
					
						
							|  |  |  | 	err = ioutil.WriteFile(path+".addr", content, 0644) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	content = []byte(strings.Join(mnemonics, "\n")) | 
					
						
							|  |  |  | 	err = ioutil.WriteFile(path+".mne", content, 0600) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *FileKeyStore) Load(session string) (*KeyRing, error) { | 
					
						
							|  |  |  | 	basename := session | 
					
						
							|  |  |  | 	if session == "" { | 
					
						
							|  |  |  | 		basename = "default" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	secfile := path.Join(k.basedir, basename+".prv") | 
					
						
							|  |  |  | 	_, err := os.Stat(secfile) | 
					
						
							|  |  |  | 	// if file is not found then we return nil, no error | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return NewKeyRingFromFile(secfile) | 
					
						
							|  |  |  | } |