| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | /* | 
					
						
							|  |  |  | 	This file is part of go-ethereum | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	go-ethereum is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | 	it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | 	the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | 	(at your option) any later version. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	go-ethereum is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | 	but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | 	GNU General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	You should have received a copy of the GNU Lesser General Public License | 
					
						
							|  |  |  | 	along with go-ethereum.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @authors | 
					
						
							|  |  |  |  * 	Gustav Simonsson <gustav.simonsson@gmail.com> | 
					
						
							|  |  |  |  * @date 2015 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package crypto | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-01-25 02:07:20 +01:00
										 |  |  | 	"encoding/hex" | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	"encoding/json" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2015-04-02 21:14:25 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2015-01-15 17:45:45 +01:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	"io/ioutil" | 
					
						
							|  |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2015-05-12 14:24:11 +02:00
										 |  |  | 	"path/filepath" | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TODO: rename to KeyStore when replacing existing KeyStore | 
					
						
							|  |  |  | type KeyStore2 interface { | 
					
						
							| 
									
										
										
										
											2015-01-15 17:45:45 +01:00
										 |  |  | 	// create new key using io.Reader entropy source and optionally using auth string | 
					
						
							|  |  |  | 	GenerateNewKey(io.Reader, string) (*Key, error) | 
					
						
							| 
									
										
										
										
											2015-04-02 21:14:25 +02:00
										 |  |  | 	GetKey(common.Address, string) (*Key, error) // key from addr and auth string | 
					
						
							|  |  |  | 	GetKeyAddresses() ([]common.Address, error)  // get all addresses | 
					
						
							|  |  |  | 	StoreKey(*Key, string) error                 // store key optionally using auth string | 
					
						
							|  |  |  | 	DeleteKey(common.Address, string) error      // delete key by addr and auth string | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-07 16:06:26 +01:00
										 |  |  | type keyStorePlain struct { | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	keysDirPath string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-07 16:06:26 +01:00
										 |  |  | func NewKeyStorePlain(path string) KeyStore2 { | 
					
						
							| 
									
										
										
										
											2015-01-19 22:12:22 +01:00
										 |  |  | 	return &keyStorePlain{path} | 
					
						
							| 
									
										
										
										
											2015-01-07 16:06:26 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-15 17:45:45 +01:00
										 |  |  | func (ks keyStorePlain) GenerateNewKey(rand io.Reader, auth string) (key *Key, err error) { | 
					
						
							|  |  |  | 	return GenerateNewKeyDefault(ks, rand, auth) | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-15 17:45:45 +01:00
										 |  |  | func GenerateNewKeyDefault(ks KeyStore2, rand io.Reader, auth string) (key *Key, err error) { | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	defer func() { | 
					
						
							|  |  |  | 		if r := recover(); r != nil { | 
					
						
							|  |  |  | 			err = fmt.Errorf("GenerateNewKey error: %v", r) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2015-01-15 17:45:45 +01:00
										 |  |  | 	key = NewKey(rand) | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	err = ks.StoreKey(key, auth) | 
					
						
							| 
									
										
										
										
											2015-01-07 16:06:26 +01:00
										 |  |  | 	return key, err | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-02 21:14:25 +02:00
										 |  |  | func (ks keyStorePlain) GetKey(keyAddr common.Address, auth string) (key *Key, err error) { | 
					
						
							| 
									
										
										
										
											2015-01-25 02:07:20 +01:00
										 |  |  | 	fileContent, err := GetKeyFile(ks.keysDirPath, keyAddr) | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-01-07 16:06:26 +01:00
										 |  |  | 		return nil, err | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	key = new(Key) | 
					
						
							|  |  |  | 	err = json.Unmarshal(fileContent, key) | 
					
						
							| 
									
										
										
										
											2015-01-07 16:06:26 +01:00
										 |  |  | 	return key, err | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-02 21:14:25 +02:00
										 |  |  | func (ks keyStorePlain) GetKeyAddresses() (addresses []common.Address, err error) { | 
					
						
							| 
									
										
										
										
											2015-01-25 02:07:20 +01:00
										 |  |  | 	return GetKeyAddresses(ks.keysDirPath) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-07 16:06:26 +01:00
										 |  |  | func (ks keyStorePlain) StoreKey(key *Key, auth string) (err error) { | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	keyJSON, err := json.Marshal(key) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-01-07 16:06:26 +01:00
										 |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-25 02:07:20 +01:00
										 |  |  | 	err = WriteKeyFile(key.Address, ks.keysDirPath, keyJSON) | 
					
						
							| 
									
										
										
										
											2015-01-07 16:06:26 +01:00
										 |  |  | 	return err | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-02 21:14:25 +02:00
										 |  |  | func (ks keyStorePlain) DeleteKey(keyAddr common.Address, auth string) (err error) { | 
					
						
							|  |  |  | 	keyDirPath := filepath.Join(ks.keysDirPath, keyAddr.Hex()) | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	err = os.RemoveAll(keyDirPath) | 
					
						
							| 
									
										
										
										
											2015-01-07 16:06:26 +01:00
										 |  |  | 	return err | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-02 21:14:25 +02:00
										 |  |  | func GetKeyFile(keysDirPath string, keyAddr common.Address) (fileContent []byte, err error) { | 
					
						
							| 
									
										
										
										
											2015-04-21 17:00:30 +02:00
										 |  |  | 	fileName := hex.EncodeToString(keyAddr[:]) | 
					
						
							| 
									
										
										
										
											2015-05-12 14:24:11 +02:00
										 |  |  | 	return ioutil.ReadFile(filepath.Join(keysDirPath, fileName, fileName)) | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-02 21:14:25 +02:00
										 |  |  | func WriteKeyFile(addr common.Address, keysDirPath string, content []byte) (err error) { | 
					
						
							| 
									
										
										
										
											2015-04-21 17:00:30 +02:00
										 |  |  | 	addrHex := hex.EncodeToString(addr[:]) | 
					
						
							| 
									
										
										
										
											2015-05-12 14:24:11 +02:00
										 |  |  | 	keyDirPath := filepath.Join(keysDirPath, addrHex) | 
					
						
							|  |  |  | 	keyFilePath := filepath.Join(keyDirPath, addrHex) | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	err = os.MkdirAll(keyDirPath, 0700) // read, write and dir search for user | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-01-07 16:06:26 +01:00
										 |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-07 16:06:26 +01:00
										 |  |  | 	return ioutil.WriteFile(keyFilePath, content, 0600) // read, write for user | 
					
						
							| 
									
										
										
										
											2014-12-31 15:39:33 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-01-25 02:07:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-02 21:14:25 +02:00
										 |  |  | func GetKeyAddresses(keysDirPath string) (addresses []common.Address, err error) { | 
					
						
							| 
									
										
										
										
											2015-01-25 02:07:20 +01:00
										 |  |  | 	fileInfos, err := ioutil.ReadDir(keysDirPath) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-23 05:52:41 +02:00
										 |  |  | 	for _, fileInfo := range fileInfos { | 
					
						
							| 
									
										
										
										
											2015-02-24 18:03:10 +01:00
										 |  |  | 		address, err := hex.DecodeString(fileInfo.Name()) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-04-02 21:14:25 +02:00
										 |  |  | 		addresses = append(addresses, common.BytesToAddress(address)) | 
					
						
							| 
									
										
										
										
											2015-01-25 02:07:20 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return addresses, err | 
					
						
							|  |  |  | } |