github.com/jonasnick/go-ethereum@v0.7.12-0.20150216215225-22176f05d387/crypto/key_manager.go (about)

     1  package crypto
     2  
     3  import (
     4  	"fmt"
     5  	"sync"
     6  
     7  	"github.com/jonasnick/go-ethereum/ethutil"
     8  	"github.com/jonasnick/go-ethereum/logger"
     9  )
    10  
    11  var keylogger = logger.NewLogger("KEY")
    12  
    13  type KeyManager struct {
    14  	keyRing  *KeyRing
    15  	session  string
    16  	keyStore KeyStore            // interface
    17  	keyRings map[string]*KeyRing // cache
    18  	keyPair  *KeyPair
    19  }
    20  
    21  func NewDBKeyManager(db ethutil.Database) *KeyManager {
    22  	return &KeyManager{keyStore: &DBKeyStore{db: db}, keyRings: make(map[string]*KeyRing)}
    23  }
    24  
    25  func NewFileKeyManager(basedir string) *KeyManager {
    26  	return &KeyManager{keyStore: &FileKeyStore{basedir: basedir}, keyRings: make(map[string]*KeyRing)}
    27  }
    28  
    29  func (k *KeyManager) KeyPair() *KeyPair {
    30  	return k.keyPair
    31  }
    32  
    33  func (k *KeyManager) KeyRing() *KeyPair {
    34  	return k.keyPair
    35  }
    36  
    37  func (k *KeyManager) PrivateKey() []byte {
    38  	return k.keyPair.PrivateKey
    39  }
    40  
    41  func (k *KeyManager) PublicKey() []byte {
    42  	return k.keyPair.PublicKey
    43  }
    44  
    45  func (k *KeyManager) Address() []byte {
    46  	return k.keyPair.Address()
    47  }
    48  
    49  func (k *KeyManager) save(session string, keyRing *KeyRing) error {
    50  	err := k.keyStore.Save(session, keyRing)
    51  	if err != nil {
    52  		return err
    53  	}
    54  	k.keyRings[session] = keyRing
    55  	return nil
    56  }
    57  
    58  func (k *KeyManager) load(session string) (*KeyRing, error) {
    59  	keyRing, found := k.keyRings[session]
    60  	if !found {
    61  		var err error
    62  		keyRing, err = k.keyStore.Load(session)
    63  		if err != nil {
    64  			return nil, err
    65  		}
    66  	}
    67  	return keyRing, nil
    68  }
    69  
    70  func cursorError(cursor int, len int) error {
    71  	return fmt.Errorf("cursor %d out of range (0..%d)", cursor, len)
    72  }
    73  
    74  func (k *KeyManager) reset(session string, cursor int, keyRing *KeyRing) error {
    75  	if cursor >= keyRing.Len() {
    76  		return cursorError(cursor, keyRing.Len())
    77  	}
    78  	lock := &sync.Mutex{}
    79  	lock.Lock()
    80  	defer lock.Unlock()
    81  	err := k.save(session, keyRing)
    82  	if err != nil {
    83  		return err
    84  	}
    85  	k.session = session
    86  	k.keyRing = keyRing
    87  	k.keyPair = keyRing.GetKeyPair(cursor)
    88  	return nil
    89  }
    90  
    91  func (k *KeyManager) SetCursor(cursor int) error {
    92  	if cursor >= k.keyRing.Len() {
    93  		return cursorError(cursor, k.keyRing.Len())
    94  	}
    95  	k.keyPair = k.keyRing.GetKeyPair(cursor)
    96  	return nil
    97  }
    98  
    99  func (k *KeyManager) Init(session string, cursor int, force bool) error {
   100  	var keyRing *KeyRing
   101  	if !force {
   102  		var err error
   103  		keyRing, err = k.load(session)
   104  		if err != nil {
   105  			return err
   106  		}
   107  	}
   108  	if keyRing == nil {
   109  		keyRing = NewGeneratedKeyRing(1)
   110  		keylogger.Infof("Created keypair. Private key: %x\n", keyRing.keys[0].PrivateKey)
   111  	}
   112  	return k.reset(session, cursor, keyRing)
   113  }
   114  
   115  func (k *KeyManager) InitFromSecretsFile(session string, cursor int, secretsfile string) error {
   116  	keyRing, err := NewKeyRingFromFile(secretsfile)
   117  	if err != nil {
   118  		return err
   119  	}
   120  	return k.reset(session, cursor, keyRing)
   121  }
   122  
   123  func (k *KeyManager) InitFromString(session string, cursor int, secrets string) error {
   124  	keyRing, err := NewKeyRingFromString(secrets)
   125  	if err != nil {
   126  		return err
   127  	}
   128  	return k.reset(session, cursor, keyRing)
   129  }
   130  
   131  func (k *KeyManager) Export(dir string) error {
   132  	fileKeyStore := FileKeyStore{dir}
   133  	return fileKeyStore.Save(k.session, k.keyRing)
   134  }