diff --git a/keys/keybase.go b/keys/keybase.go index bdffb9dce..5fa32635e 100644 --- a/keys/keybase.go +++ b/keys/keybase.go @@ -1,6 +1,7 @@ package keys import ( + "sort" "strings" "github.com/pkg/errors" @@ -23,10 +24,7 @@ type dbKeybase struct { func New(db dbm.DB, codec Codec) dbKeybase { return dbKeybase{ - es: encryptedStorage{ - db: db, - coder: coder, - }, + db: db, codec: codec, } } @@ -66,7 +64,7 @@ func (kb dbKeybase) Create(name, passphrase, algo string) (Info, string, error) // it under name, protected by passphrase. // // Result similar to New(), except it doesn't return the seed again... -func (s dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { +func (kb dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { words := strings.Split(strings.TrimSpace(seedphrase), " ") secret, err := kb.codec.WordsToBytes(words) if err != nil { @@ -89,14 +87,14 @@ func (s dbKeybase) Recover(name, passphrase, seedphrase string) (Info, error) { } // List loads the keys from the storage and enforces alphabetical order -func (s dbKeybase) List() ([]Info, error) { - res, err := s.es.List() - sort.SortSlice(res) +func (kb dbKeybase) List() ([]Info, error) { + res, err := kb.es.List() + sort.Slice(res, func(a, b int) bool { return res[a].Name < res[b].Name }) return res, err } // Get returns the public information about one key -func (s dbKeybase) Get(name string) (Info, error) { +func (kb dbKeybase) Get(name string) (Info, error) { _, info, err := kb.es.store.Get(name) return info, err } @@ -105,14 +103,15 @@ func (s dbKeybase) Get(name string) (Info, error) { // this public key // // If no key for this name, or the passphrase doesn't match, returns an error -func (s dbKeybase) Sign(name, passphrase string, msg []byte) (crypto.Signature, crypto.PubKey, error) { - key, _, err := kb.es.Get(name, passphrase) +func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig crypto.Signature, pk crypto.PubKey, err error) { + var key crypto.PrivKey + key, _, err = kb.es.Get(name, passphrase) if err != nil { - return err + return } - sig := key.Sign(tx.SignBytes()) - pubkey := key.PubKey() - return tx.Sign(pubkey, sig) + sig = key.Sign(msg) + pk = key.PubKey() + return } // Export decodes the private key with the current password, encodes @@ -121,7 +120,7 @@ func (s dbKeybase) Sign(name, passphrase string, msg []byte) (crypto.Signature, // // This is designed to copy from one device to another, or provide backups // during version updates. -func (s dbKeybase) Export(name, oldpass, transferpass string) ([]byte, error) { +func (kb dbKeybase) Export(name, oldpass, transferpass string) ([]byte, error) { key, _, err := kb.es.Get(name, oldpass) if err != nil { return nil, err @@ -134,7 +133,7 @@ func (s dbKeybase) Export(name, oldpass, transferpass string) ([]byte, error) { // Import accepts bytes generated by Export along with the same transferpass // If they are valid, it stores the password under the given name with the // new passphrase. -func (s dbKeybase) Import(name, newpass, transferpass string, data []byte) error { +func (kb dbKeybase) Import(name, newpass, transferpass string, data []byte) error { key, err := kb.es.coder.Decrypt(data, transferpass) if err != nil { return err @@ -145,7 +144,7 @@ func (s dbKeybase) Import(name, newpass, transferpass string, data []byte) error // Delete removes key forever, but we must present the // proper passphrase before deleting it (for security) -func (s dbKeybase) Delete(name, passphrase string) error { +func (kb dbKeybase) Delete(name, passphrase string) error { // verify we have the proper password before deleting _, _, err := kb.es.Get(name, passphrase) if err != nil { @@ -158,7 +157,7 @@ func (s dbKeybase) Delete(name, passphrase string) error { // // oldpass must be the current passphrase used for encoding, newpass will be // the only valid passphrase from this time forward -func (s dbKeybase) Update(name, oldpass, newpass string) error { +func (kb dbKeybase) Update(name, oldpass, newpass string) error { key, _, err := kb.es.Get(name, oldpass) if err != nil { return err @@ -197,3 +196,25 @@ func generateByType(typ byte, secret []byte) (crypto.PrivKey, error) { return crypto.PrivKey{}, err } } + +func encrypt(key crypto.PrivKey, pass string) ([]byte, error) { + if pass == "" { + return key.Bytes(), nil + } + s := secret(pass) + cipher := crypto.EncryptSymmetric(key.Bytes(), s) + return cipher, nil +} + +func decrypt(data []byte, pass string) (key crypto.PrivKey, err error) { + private := data + if pass != "" { + s := secret(pass) + private, err = crypto.DecryptSymmetric(data, s) + if err != nil { + return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase") + } + } + key, err = crypto.PrivKeyFromBytes(private) + return key, errors.Wrap(err, "Invalid Passphrase") +} diff --git a/keys/types.go b/keys/types.go index 110cd3ded..b126f7267 100644 --- a/keys/types.go +++ b/keys/types.go @@ -10,6 +10,13 @@ type Info struct { PubKey crypto.PubKey `json:"pubkey"` } +func info(name string, privKey crypto.PrivKey) Info { + return Info{ + Name: name, + PubKey: privKey.PubKey(), + } +} + // Keybase allows simple CRUD on a keystore, as an aid to signing type Keybase interface { // Sign some bytes