| 
									
										
										
										
											2014-10-31 12:37:43 +01:00
										 |  |  | package crypto | 
					
						
							| 
									
										
										
										
											2014-06-29 16:02:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"sync" | 
					
						
							| 
									
										
										
										
											2014-10-23 15:01:27 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/ethutil" | 
					
						
							| 
									
										
										
										
											2014-12-04 17:09:47 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/logger" | 
					
						
							| 
									
										
										
										
											2014-06-29 16:02:23 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-04 17:09:47 +01:00
										 |  |  | var keylogger = logger.NewLogger("KEY") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 16:02:23 +01:00
										 |  |  | type KeyManager struct { | 
					
						
							|  |  |  | 	keyRing  *KeyRing | 
					
						
							|  |  |  | 	session  string | 
					
						
							|  |  |  | 	keyStore KeyStore            // interface | 
					
						
							|  |  |  | 	keyRings map[string]*KeyRing // cache | 
					
						
							|  |  |  | 	keyPair  *KeyPair | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NewDBKeyManager(db ethutil.Database) *KeyManager { | 
					
						
							|  |  |  | 	return &KeyManager{keyStore: &DBKeyStore{db: db}, keyRings: make(map[string]*KeyRing)} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NewFileKeyManager(basedir string) *KeyManager { | 
					
						
							|  |  |  | 	return &KeyManager{keyStore: &FileKeyStore{basedir: basedir}, keyRings: make(map[string]*KeyRing)} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyManager) KeyPair() *KeyPair { | 
					
						
							|  |  |  | 	return k.keyPair | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyManager) KeyRing() *KeyPair { | 
					
						
							|  |  |  | 	return k.keyPair | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyManager) PrivateKey() []byte { | 
					
						
							|  |  |  | 	return k.keyPair.PrivateKey | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyManager) PublicKey() []byte { | 
					
						
							|  |  |  | 	return k.keyPair.PublicKey | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyManager) Address() []byte { | 
					
						
							|  |  |  | 	return k.keyPair.Address() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyManager) save(session string, keyRing *KeyRing) error { | 
					
						
							|  |  |  | 	err := k.keyStore.Save(session, keyRing) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	k.keyRings[session] = keyRing | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyManager) load(session string) (*KeyRing, error) { | 
					
						
							|  |  |  | 	keyRing, found := k.keyRings[session] | 
					
						
							|  |  |  | 	if !found { | 
					
						
							|  |  |  | 		var err error | 
					
						
							|  |  |  | 		keyRing, err = k.keyStore.Load(session) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return keyRing, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func cursorError(cursor int, len int) error { | 
					
						
							|  |  |  | 	return fmt.Errorf("cursor %d out of range (0..%d)", cursor, len) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyManager) reset(session string, cursor int, keyRing *KeyRing) error { | 
					
						
							|  |  |  | 	if cursor >= keyRing.Len() { | 
					
						
							|  |  |  | 		return cursorError(cursor, keyRing.Len()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	lock := &sync.Mutex{} | 
					
						
							|  |  |  | 	lock.Lock() | 
					
						
							|  |  |  | 	defer lock.Unlock() | 
					
						
							|  |  |  | 	err := k.save(session, keyRing) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	k.session = session | 
					
						
							|  |  |  | 	k.keyRing = keyRing | 
					
						
							|  |  |  | 	k.keyPair = keyRing.GetKeyPair(cursor) | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyManager) SetCursor(cursor int) error { | 
					
						
							|  |  |  | 	if cursor >= k.keyRing.Len() { | 
					
						
							|  |  |  | 		return cursorError(cursor, k.keyRing.Len()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	k.keyPair = k.keyRing.GetKeyPair(cursor) | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyManager) Init(session string, cursor int, force bool) error { | 
					
						
							|  |  |  | 	var keyRing *KeyRing | 
					
						
							|  |  |  | 	if !force { | 
					
						
							|  |  |  | 		var err error | 
					
						
							|  |  |  | 		keyRing, err = k.load(session) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if keyRing == nil { | 
					
						
							|  |  |  | 		keyRing = NewGeneratedKeyRing(1) | 
					
						
							| 
									
										
										
										
											2014-12-04 17:09:47 +01:00
										 |  |  | 		keylogger.Infof("Created keypair. Private key: %x\n", keyRing.keys[0].PrivateKey) | 
					
						
							| 
									
										
										
										
											2014-06-29 16:02:23 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return k.reset(session, cursor, keyRing) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (k *KeyManager) InitFromSecretsFile(session string, cursor int, secretsfile string) error { | 
					
						
							|  |  |  | 	keyRing, err := NewKeyRingFromFile(secretsfile) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return k.reset(session, cursor, keyRing) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 20:26:55 +01:00
										 |  |  | func (k *KeyManager) InitFromString(session string, cursor int, secrets string) error { | 
					
						
							|  |  |  | 	keyRing, err := NewKeyRingFromString(secrets) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return k.reset(session, cursor, keyRing) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 16:02:23 +01:00
										 |  |  | func (k *KeyManager) Export(dir string) error { | 
					
						
							|  |  |  | 	fileKeyStore := FileKeyStore{dir} | 
					
						
							|  |  |  | 	return fileKeyStore.Save(k.session, k.keyRing) | 
					
						
							|  |  |  | } |