Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R4R: Improve crypto/keys and add keys mnemonic and keys new commands #2090

Merged
merged 29 commits into from
Oct 17, 2018

Conversation

ebuchman
Copy link
Member

@ebuchman ebuchman commented Aug 20, 2018

Ref: #2089 and #2091

Tagging @cwgoes @liamsi so they're aware

  • Linked to github-issue with discussion and accepted design OR link to spec that describes this work.
  • Updated all relevant documentation (docs/)
  • Updated all relevant code comments
  • Wrote tests
  • Added entries in PENDING.md that include links to the relevant issue or PR that most accurately describes the change.
  • Updated cmd/gaia and examples/

For Admin Use:

  • Added appropriate labels to PR (ex. wip, ready-for-review, docs)
  • Reviewers Assigned
  • Squashed all commits, uses message "Merge pull request #XYZ: [title]" (coding standards)

@ebuchman
Copy link
Member Author

some relevant background: tendermint/go-crypto#89 - it looks like the issue has been fixed both in tyler-smith and bartekn. tyler-smith repo is quite active again so we took the commit with the fix before all the new activity.

@ebuchman ebuchman changed the title [WIP] Improve crypto/keys Improve crypto/keys Aug 20, 2018
@codecov
Copy link

codecov bot commented Aug 20, 2018

Codecov Report

Merging #2090 into develop will decrease coverage by 2.23%.
The diff coverage is 71.25%.

@@            Coverage Diff             @@
##           develop   #2090      +/-   ##
==========================================
- Coverage    60.13%   57.9%   -2.24%     
==========================================
  Files          152     140      -12     
  Lines         8870    8119     -751     
==========================================
- Hits          5334    4701     -633     
+ Misses        3167    3121      -46     
+ Partials       369     297      -72

}

algo := keys.Secp256k1 // SigningAlgo(viper.GetString(flagType))
path := bip44Params.DerivationPath() // ccrypto.DerivationPath{44, 118, account, 0, index}
Copy link
Member Author

Choose a reason for hiding this comment

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

Does the ledger enforce BIP44 (ie. it knows the first three fields are hardened) or do we need to pass in hardened values here ?

Copy link
Member

Choose a reason for hiding this comment

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

* add tendermint fork of golang.org/x/crypto
* pin some transitive deps
* remove in favour of fork of golang.org/x/crypto/bcrypt at github.com/tendermint/crypto/bcrypt
@alexanderbez alexanderbez added T: UX wip C:Keys Keybase, KMS and HSMs labels Aug 20, 2018
@jaekwon
Copy link
Contributor

jaekwon commented Aug 20, 2018

It isn't clear in the client what the mnemonic password is vs the encryption password.
Also, we should probably have the user enter these passwords twice to verify...

Kinda think we should just not expose the mnemonic password for now... The KeyBase doesn't support it besides via the Derive function...

@ebuchman ebuchman changed the title R4R: Improve crypto/keys and add keys mnemonic and keys new R4R: Improve crypto/keys and add keys mnemonic and keys new commands Aug 30, 2018
Copy link
Contributor

@mslipper mslipper left a comment

Choose a reason for hiding this comment

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

Will PR in my work now.


// if we're using ledger, only thing we need is the path.
// generate key and we're done.
if viper.GetBool(client.FlagUseLedger) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could be part of the prompt flow, no? I.e., Do you want to use Ledger [y/n]?

Copy link
Member Author

Choose a reason for hiding this comment

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

Could be, but since its just boolean (and not really sensitive info) seems fine to leave as a flag

// get the mnemonic
var mnemonic string
if !useDefaults {
fmt.Println("> Enter your bip39 mnemonic.")
Copy link
Contributor

Choose a reason for hiding this comment

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

For all these prompts, I made a helper method in the client package in my PR you can use to prompt the user - client.GetString(). I'll merge that into this branch.

return err
}
fmt.Println("> Input length:", len(inputEntropy))
if len(inputEntropy) < 99 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want to require this amount of entropy from the user rather than warning them if the provided entropy is weak?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes

@rigelrozanski
Copy link
Contributor

sup with this PR is it WIP or R4R? seems inactive

@mslipper
Copy link
Contributor

Should be R4R as far as I know.

Copy link
Contributor

@rigelrozanski rigelrozanski left a comment

Choose a reason for hiding this comment

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

Cool, I fixed the lint here are some superficial comments

client/keys/new.go Show resolved Hide resolved
if isHardened(spl[3]) || isHardened(spl[4]) {
return nil,
fmt.Errorf("fourth and fifth field in path must not be hardened (ie. not contain the suffix ', got %v and %v", spl[3], spl[4])
}
Copy link
Contributor

Choose a reason for hiding this comment

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

all these if statements could be lumped into a switch statement - make it a bit more concise

Copy link
Member Author

Choose a reason for hiding this comment

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

How's that?

Copy link
Contributor

Choose a reason for hiding this comment

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

Having all those if statements lined up (which have returns, so they effectively act as chained if-else statements) act identically as a switch statement - I like compactness where it's appropriate but doesn't super matter here

Copy link
Member Author

Choose a reason for hiding this comment

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

Can you show me what the switch statement would look like? Each of these conditions is on a different piece of the slice, so not clear to me what we could switch on

crypto/keys/mintkey/mintkey.go Show resolved Hide resolved
crypto/keys/mintkey/mintkey.go Outdated Show resolved Hide resolved
client/keys/mnemonic.go Show resolved Hide resolved
client/input.go Outdated Show resolved Hide resolved
client/input.go Outdated
// GetString simply returns the trimmed string output of a given reader.
func GetString(prompt string, buf *bufio.Reader) (string, error) {
if inputIsTty() && prompt != "" {
fmt.Println(prompt)
Copy link
Contributor

Choose a reason for hiding this comment

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

Please redirect the prompt to stderr: fmt.Fprint(os.Stderr, prompt)

// nolint: gocyclo
func runNewCmd(cmd *cobra.Command, args []string) error {

if len(args) != 1 || len(args[0]) == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd use cobra.ExactArgs(1)

@fedekunze
Copy link
Collaborator

fedekunze commented Oct 16, 2018

From @NodeGuy #1442 (comment):

There's a bug in the current design:
POST /keys a new key with name Chris.
GET /keys/Chris returns the new key.
POST /keys a new key with name seed.
GET /keys/seed does not return the new key, violating the REST abstraction of keys as a collection.
This confused a contract test I wrote and I had to add extra code to work around the bug.

@rigelrozanski
Copy link
Contributor

Lol bucky you're getting slashed for leaving this PR open (and almost ready to merge) for 2 months

@ebuchman
Copy link
Member Author

Lol bucky you're getting slashed for leaving this PR open (and almost ready to merge) for 2 months

I had till midnight tonight and I totally made it. All comments addressed. Tests fail I think due to unrelated non-determinism ...

@ebuchman
Copy link
Member Author

From @NodeGuy #1442 (comment):

There's a bug in the current design:
POST /keys a new key with name Chris.
GET /keys/Chris returns the new key.
POST /keys a new key with name seed.
GET /keys/seed does not return the new key, violating the REST abstraction of keys as a collection.
This confused a contract test I wrote and I had to add extra code to work around the bug.

@fedekunze sounds like this should be a new issue?

@ebuchman
Copy link
Member Author

Sorry for the massive PR and for letting it hang so long guys. Thanks for all the nice review.

@rigelrozanski
Copy link
Contributor

rigelrozanski commented Oct 17, 2018

Yeah test_cover is failing due to lcd non-deterministic test (lcd_test.go:577)

CI:lint failing looks like a go-dep issue which should be addressed b4 merge

Gopkg.lock is out of sync with imports and/or Gopkg.toml. Run `dep check` for details.
input-digest mismatch
Makefile:193: recipe for target 'test_lint' failed

Copy link
Contributor

@rigelrozanski rigelrozanski left a comment

Choose a reason for hiding this comment

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

looks good - couple linting issues still need to pass before merge - but all my concerns addressed

@rigelrozanski rigelrozanski merged commit 1ee8dee into develop Oct 17, 2018
@rigelrozanski rigelrozanski deleted the bucky/keys branch October 17, 2018 18:00
@@ -133,5 +128,6 @@ func readLineFromBuf(buf *bufio.Reader) (string, error) {

// PrintPrefixed prints a string with > prefixed for use in prompts.
func PrintPrefixed(msg string) {
fmt.Printf("> %s\n", msg)
msg = fmt.Sprintf("> %s\n", msg)
fmt.Fprint(os.Stderr, msg)
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe it's better to avoid modifying msg and just do

fmt.Fprint(os.Stderr, fmt.Sprintf("> %s\n", msg))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C:Keys Keybase, KMS and HSMs T: UX
Projects
None yet
Development

Successfully merging this pull request may close these issues.