Skip to content
This repository was archived by the owner on Jul 15, 2018. It is now read-only.

Unify local and external keys in keybase interface #117

Merged
merged 25 commits into from
Jun 10, 2018

Conversation

cwgoes
Copy link
Contributor

@cwgoes cwgoes commented Jun 5, 2018

Rework PrivKey, Keybase, and Info to work with both locally stored and external keys (offline, HW wallets, etc).

This involves the following API changes:

  • Return errors on privkey.Sign() and privkey.PubKey(), as we may be querying an external datastore
  • Add methods to the Keybase interface to track Ledger HD ed25519 keys and offline keys, so that signing by name automatically looks up the right key and prompts the user for a password / communicates with the Ledger / prompts the user to sign offline, as appropriate.

@cwgoes cwgoes requested review from ebuchman and jaekwon as code owners June 5, 2018 03:04
@cwgoes cwgoes mentioned this pull request Jun 5, 2018
6 tasks
@cwgoes
Copy link
Contributor Author

cwgoes commented Jun 7, 2018

To-do:

  • Add way to track a watch-only key by pubkey
  • Correctly switch on .Sign() based on keytype
  • Add testcases
  • Test downstream in Cosmos SDK

@cwgoes
Copy link
Contributor Author

cwgoes commented Jun 7, 2018

@liamsi Thoughts on the API changes?

@liamsi
Copy link
Contributor

liamsi commented Jun 8, 2018

The interface changes look good to me! Totally in favour of sign returning an error. I also like changing Info to an interface. I might change the Create to CreateMneomnicKey or simply CreateMnemonic (as the key is clear because of the context/package name/iface name) in #118

@cwgoes cwgoes self-assigned this Jun 8, 2018
@cwgoes cwgoes force-pushed the cwgoes/unified-ledger-keybase branch 2 times, most recently from d245bae to 84bff8e Compare June 8, 2018 20:18
@cwgoes cwgoes force-pushed the cwgoes/unified-ledger-keybase branch from 84bff8e to 60827af Compare June 8, 2018 20:49
keys/keybase.go Outdated
case ledgerInfo:
case offlineInfo:
if passphrase != "yes" {
return fmt.Errorf("Enter exactly 'yes' to delete the key")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: Error messages shouldn be capitalized. Ideally, run golint before finalizing the PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed. Agreed on golint, unfortunately this repo is very noncompliant at the moment...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you can run go-lint only on the files you've modified. That would be great.. Otherwise, don't bother. I'll delete so much code in #116 ... after that nothing is left and it's secure and very compliant ;-)

@cwgoes cwgoes force-pushed the cwgoes/unified-ledger-keybase branch from 59609f8 to 94d6b8d Compare June 8, 2018 22:16
@cwgoes cwgoes changed the title WIP: Unify local and external keys in keybase interface Unify local and external keys in keybase interface Jun 9, 2018
liamsi
liamsi previously requested changes Jun 9, 2018
Copy link
Contributor

@liamsi liamsi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, left some nitpicks in comments

encode_test.go Outdated
checkAminoBinary(t, sig1, &sig2, -1) // Siganture size changes for Secp anyways.
assert.EqualValues(t, sig1, sig2)
checkAminoJSON(t, sig1, &sig3, false) // TODO also check Prefix bytes.
assert.EqualValues(t, sig1, sig3)

// Check (de/en)codings of PubKeys.
pubKey := tc.privKey.PubKey()
pubKey, err := tc.privKey.PubKey()
assert.Nil(t, err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this newly introduced asserts to assert.NoError? It slightly increases the readability of the tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All instances changed to assert.NoError.

keys/keybase.go Outdated
linfo := info.(offlineInfo)
fmt.Printf("Bytes to sign:\n%s", msg)
buf := bufio.NewReader(os.Stdin)
fmt.Printf("\nEnter encoded signature:\n")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be more specific: encoded in what?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amino-encoded signature (updated), for now at least.

if err != nil {
return nil, nil, err
}
cdc.MustUnmarshalBinary([]byte(signed), sig)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment, that 1) this will block until the user inputs the signature and 2) this assumes that the offline computer is aware of the structure to be signed (TXs?) and properly encodes it in amino. Are we writing the offline-signing software, too? Otherwise, it might be reasonable to assume some other more common encoding. Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that requiring Amino is suboptimal, let's track that separately though - #121.

Added a comment about blocking.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thanks! I'll join the discussion in #121 👍

case ledgerInfo:
case offlineInfo:
if passphrase != "yes" {
return fmt.Errorf("enter exactly 'yes' to delete the key")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is 'yes' always a user entered value? Otherwise: "call with seedphrase 'yes' to delete the key".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the only downstream consumer I know of, it is user-entered. Leaving for now, if in the future we have other consumers we should probably just change this API anyways.

Copy link

@ValarDragon ValarDragon Jun 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this support y also? (Alot of people are probably in the habit of this)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most bash commands don't delete keys (even just public keys, as in this case) though. IMO better to require that the user enter exactly 'yes'.

keys/keybase.go Outdated
}

func (kb dbKeybase) writePubKey(pub crypto.PubKey, name string) Info {
func (kb dbKeybase) writeLocalKey(priv crypto.PrivKey, name, passphrase string) Info {
// generate the encrypted privkey
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this actually generate anything? Proposal:
// encrypt private key using passphrase

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, reworded file so "generate" is only used for actually generating keys.

panic(err)
}
return bz
return cdc.MustMarshalBinaryBare(privKey)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, unrelated to your code but why do we amino encode these bytes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cwgoes cwgoes dismissed liamsi’s stale review June 10, 2018 02:20

Addressed.

Copy link
Contributor

@liamsi liamsi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@liamsi liamsi merged commit c21f67c into develop Jun 10, 2018
@cwgoes cwgoes deleted the cwgoes/unified-ledger-keybase branch June 10, 2018 08:09
@liamsi liamsi mentioned this pull request Jun 12, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants