Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
Jimmy Hartzell committed Nov 2, 2018
2 parents 0a7f725 + e6ca045 commit f2940ac
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 57 deletions.
64 changes: 32 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -535,51 +535,39 @@ on your device:
$ tezos-client list connected ledgers
```

The output of this command includes six Tezos addresses derived from the secret
The output of this command includes three Tezos addresses derived from the secret
stored on the device, via different signing curves and BIP32 paths.

```
Found a valid Tezos application running on Ledger Nano S at [0001:0014:00].
Found a Tezos Wallet 1.4.0 (commit 764625b1) application running on Ledger Nano S at [0001:002a:00].
To add the root key of this ledger, use one of
tezos-client import secret key ledger_<...>_ed ledger://tz1Rctvczeh7WK91NfT9LUSrYJFceyhJKUQN # Ed25519 signature
tezos-client import secret key ledger_<...>_secp ledger://tz2EhYFRUhY4YiinHYxb7PncETZXP9BfRSPj # Secp256k1 signature
tezos-client import secret key ledger_<...>_p2 ledger://tz3RZ5JvhuSAg3i4qBSaoCKqXwmqhswqeNgF # P-256 signature
Each of these tz* is a valid Tezos address.
To use a derived address, add a hardened BIP32 path suffix at the end of the URI.
For instance, to use keys at BIP32 path m/44'/1729'/0'/0', use one of
tezos-client import secret key ledger_<...>_ed_0_0 "ledger://tz1Rctvczeh7WK91NfT9LUSrYJFceyhJKUQN/0'/0'"
tezos-client import secret key ledger_<...>_secp_0_0 "ledger://tz2EhYFRUhY4YiinHYxb7PncETZXP9BfRSPj/0'/0'"
tezos-client import secret key ledger_<...>_p2_0_0 "ledger://tz3RZ5JvhuSAg3i4qBSaoCKqXwmqhswqeNgF/0'/0'"
In this case, your Tezos address will be a derived tz*.
It will be displayed when you do the import, or using command `show ledger path`.
To use keys at BIP32 path m/44'/1729'/0'/0' (default Tezos key path), use one of
tezos-client import secret key ledger_jhartzell "ledger://major-squirrel-thick-hedgehog/ed25519/0'/0'"
tezos-client import secret key ledger_jhartzell "ledger://major-squirrel-thick-hedgehog/secp256k1/0'/0'"
tezos-client import secret key ledger_jhartzell "ledger://major-squirrel-thick-hedgehog/P-256/0'/0'"
```

The first three are addressed constructed directly from the root key for each
encryption system (`ed25519`, `secp256k1`, or P-256). The second three show you
examples of how to append a BIP32 path to the root key to construct a new
address.
These show you how to import keys with a specific signing curve and derivation path. The
animal-based name (e.g. `major-squirrel-thick-hedgehog`) is a unique identifier for your
Ledger device, to enable the client to distinguish different Ledger devices. This is combined with
a derivation path (which may but probably should not be empty) to indicate one of
the possible keys on the Ledger Nano S.

The Ledger Nano S does not currently support non-hardened path components. All
components of all paths must be hardened, which is indicated by following them
with a `'` character. This character may need to be escaped from the shell
through backslashes `\` or double-quotes `"`.

You'll need to choose one of the six commands starting with `tezos-client import
secret key ...` to run.

* `ed25519` is the standard recommended curve
* If you know you're always going to use only one key, use a root key; you can
only have one root account per device per signing curve. If you might want
to leave open the possibility of using your device for multiple keys,
use a BIP32 path. We recommend the latter.
You'll need to choose one of the three commands starting with
`tezos-client import secret key ...` to run. `ed25519` is the standard recommended curve.

If you use a BIP32 path, be sure to write it down. You need the full address to
use your tez. This means that if you lose all your devices and need to set
everything up again, you will need three things:
The BIP32 path is the part that in the example commands read `0'/0'`. You
can change it, but if you do (and even if you don't), be sure to write
down. You need the full address to use your tez. This means that if you
lose all your devices and need to set everything up again, you will need
three things:

1. The mnemonic phrase
1. The mnemonic phrase -- this is the phrase from your Ledger device itself when you set it up, not the animal mnemonic you see on the command line. They are different.
2. Which signing curve you chose
3. The BIP32 path, if you used one

Expand Down Expand Up @@ -937,12 +925,24 @@ tezos-client list connected ledgers
### Display Debug Logs
If you are worried about bugs, you should configure your system to display debug logs. Add the
following line to `~/.bashrc` and to `~/.bash_profile`:
following line to `~/.bashrc` and to `~/.bash_profile`, or set the equivalent environnment
variable in whatever system you use to launch your daemons:
```
export TEZOS_LOG="client.signer.ledger -> debug"
```
If you have a bug report, it is far more likely we'll be able to fix it if you include the
entire output of the transaction, including debug messages enabled by that command above.
Please copy and paste the entire run of the command (for `tezos-client`) or everything
involving the failed block level and the previous one (for baking); if you need to anonymize
the PKH then please do so by using `XXX` or similar rather than by removing those entire lines.
We need as much context as possible to help troubleshoot.
`script` is also a useful command for logging all the output of a long-running process.
If you run `script <file-name>` it opens a new shell where everything output and typed
is also output to that file, giving you a transcript of your terminal session.
### Two Ledger Devices at the Same Time
Two Ledger devices with the same seed should not ever be plugged in at the same time. This confuses
Expand Down
Binary file added glyphs/icon_back.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added glyphs/icon_dashboard.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 13 additions & 7 deletions src/apdu_sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,6 @@ static bool prompt_transaction(const void *data, size_t length, cx_curve_t curve
END_TRY;
#endif

// If the source is an implicit contract,...
if (ops->operation.source.originated == 0) {
// ... it had better match our key, otherwise why are we signing it?
if (memcmp(&ops->operation.source, &ops->signing, sizeof(ops->signing))) return false;
}
// OK, it passes muster.

// Now to display it to make sure it's what the user intended.
static const uint32_t TYPE_INDEX = 0;
static const uint32_t SOURCE_INDEX = 1;
Expand Down Expand Up @@ -313,6 +306,19 @@ static bool prompt_transaction(const void *data, size_t length, cx_curve_t curve

ui_prompt(transaction_prompts, NULL, ok, cxl);
}
case OPERATION_TAG_NONE:
{
// Parser function guarantees this has a reveal
static const char *const reveal_prompts[] = {
"Reveal Key",
"Key",
NULL,
};

strcpy(get_value_buffer(TYPE_INDEX), "To Blockchain");

ui_prompt(reveal_prompts, NULL, ok, cxl);
}
}
}

Expand Down
14 changes: 12 additions & 2 deletions src/operations.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ struct parsed_operation_group *parse_operations(const void *data, size_t length,
const struct operation_group_header *ogh = NEXT_TYPE(struct operation_group_header);
if (ogh->magic_byte != MAGIC_BYTE_UNSAFE_OP) PARSE_ERROR();

// Start out with source = signing, for reveals
// TODO: This is slightly hackish
memcpy(&out.operation.source, &out.signing, sizeof(out.signing));

while (ix < length) {
const struct operation_header *hdr = NEXT_TYPE(struct operation_header);

Expand All @@ -163,6 +167,7 @@ struct parsed_operation_group *parse_operations(const void *data, size_t length,
advance_ix(&ix, length, klen);
if (memcmp(out.public_key.W, data + ix - klen, klen) != 0) PARSE_ERROR();

out.has_reveal = true;
continue;
}

Expand All @@ -176,9 +181,12 @@ struct parsed_operation_group *parse_operations(const void *data, size_t length,
out.operation.tag = (uint8_t)tag;
parse_contract(&out.operation.source, &hdr->contract);

// If the source is an implicit contract,...
if (out.operation.source.originated == 0) {
if (memcmp(&out.operation.source, &out.signing, sizeof(out.signing))) PARSE_ERROR();
// ... it had better match our key, otherwise why are we signing it?
if (memcmp(&out.operation.source, &out.signing, sizeof(out.signing))) return false;
}
// OK, it passes muster.

// This should by default be blanked out
out.operation.delegate.curve_code = TEZOS_NO_CURVE;
Expand Down Expand Up @@ -238,7 +246,9 @@ struct parsed_operation_group *parse_operations(const void *data, size_t length,
}
}

if (out.operation.tag == OPERATION_TAG_NONE) PARSE_ERROR(); // Must have one non-reveal op
if (out.operation.tag == OPERATION_TAG_NONE && !out.has_reveal) {
PARSE_ERROR(); // Must have at least one op
}

return &out; // Success!
}
1 change: 1 addition & 0 deletions src/operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ struct parsed_operation {
struct parsed_operation_group {
cx_ecfp_public_key_t public_key; // compressed
uint64_t total_fee;
bool has_reveal;
struct parsed_contract signing;
struct parsed_operation operation;
};
Expand Down
22 changes: 7 additions & 15 deletions src/ui.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "ui.h"

#include "ui_menu.h"

#include "baking_auth.h"
#include "keys.h"
#include "to_string.h"
Expand Down Expand Up @@ -30,6 +32,7 @@ void require_pin(void) {
os_ux_blocking(&params);
}

#ifdef BAKING_APP
const bagl_element_t ui_idle_screen[] = {
// type userid x y w h str rad
// fill fg bg fid iid txt touchparams... ]
Expand Down Expand Up @@ -58,19 +61,14 @@ const bagl_element_t ui_idle_screen[] = {
//0, NULL, NULL, NULL },
{{BAGL_LABELINE, 0x01, 0, 12, 128, 12, 0, 0, 0, 0xFFFFFF, 0x000000,
BAGL_FONT_OPEN_SANS_EXTRABOLD_11px | BAGL_FONT_ALIGNMENT_CENTER, 0},
#ifdef BAKING_APP
"Last Block Level",
#else
"Tezos",
#endif
0,
0,
0,
NULL,
NULL,
NULL},

#ifdef BAKING_APP
{{BAGL_LABELINE, 0x01, 0, 26, 128, 12, 0, 0, 0, 0xFFFFFF, 0x000000,
BAGL_FONT_OPEN_SANS_EXTRABOLD_11px | BAGL_FONT_ALIGNMENT_CENTER, 0},
idle_text,
Expand All @@ -80,23 +78,17 @@ const bagl_element_t ui_idle_screen[] = {
NULL,
NULL,
NULL},
#endif

{{BAGL_LABELINE, 0x02, 0, 12, 128, 12, 0, 0, 0, 0xFFFFFF, 0x000000,
BAGL_FONT_OPEN_SANS_EXTRABOLD_11px | BAGL_FONT_ALIGNMENT_CENTER, 0},
#ifdef BAKING_APP
"Baking Key",
#else
"Wallet App",
#endif
0,
0,
0,
NULL,
NULL,
NULL},

#ifdef BAKING_APP
{{BAGL_LABELINE, 0x02, 23, 26, 82, 12, 0x80 | 10, 0, 0, 0xFFFFFF, 0x000000,
BAGL_FONT_OPEN_SANS_EXTRABOLD_11px | BAGL_FONT_ALIGNMENT_CENTER, 26},
baking_auth_text,
Expand All @@ -106,19 +98,21 @@ const bagl_element_t ui_idle_screen[] = {
NULL,
NULL,
NULL},
#endif
};

static bool do_nothing(void) {
return false;
}
#endif

static void ui_idle(void) {
#ifdef BAKING_APP
update_auth_text();
#endif
ui_display(ui_idle_screen, sizeof(ui_idle_screen)/sizeof(*ui_idle_screen),
do_nothing, exit_app, 2);
#else
main_menu();
#endif
}

void change_idle_display(uint32_t new) {
Expand All @@ -129,8 +123,6 @@ void change_idle_display(uint32_t new) {
void ui_initial_screen(void) {
#ifdef BAKING_APP
change_idle_display(N_data.highest_level);
#else
require_pin();
#endif
ui_idle();
}
Expand Down
2 changes: 1 addition & 1 deletion src/ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ typedef bool (*callback_t)(void); // return true to go back to idle screen
void ui_initial_screen(void);
void ui_init(void);
__attribute__((noreturn))
bool exit_app(void);
bool exit_app(void); // Might want to send it arguments to use as callback

void ui_display(const bagl_element_t *elems, size_t sz, callback_t ok_c, callback_t cxl_c,
uint32_t step_count);
Expand Down
35 changes: 35 additions & 0 deletions src/ui_menu.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "ui_menu.h"

#include "glyphs.h"
#include "ui.h"

#include "os.h"
#include "cx.h"

#ifndef BAKING_APP

void exit_app_cb(__attribute__((unused)) unsigned int cb) {
exit_app();
}

// Mutually recursive static variables require forward declarations
static const ux_menu_entry_t main_menu_data[];
static const ux_menu_entry_t about_menu_data[];

static const ux_menu_entry_t about_menu_data[] = {
{NULL, NULL, 0, NULL, "Tezos Wallet", "Version " VERSION, 0, 0},
{main_menu_data, NULL, 1, &C_icon_back, "Back", NULL, 61, 40}, // TODO: Put icon for "back" in
UX_MENU_END
};

static const ux_menu_entry_t main_menu_data[] = {
{NULL, NULL, 0, NULL, "Use wallet to", "view accounts", 0, 0},
{about_menu_data, NULL, 0, NULL, "About", NULL, 0, 0},
{NULL, exit_app_cb, 0, &C_icon_dashboard, "Quit app", NULL, 50, 29}, // TODO: Put icon for "dashboard" in
UX_MENU_END
};

void main_menu() {
UX_MENU_DISPLAY(0, main_menu_data, NULL);
}
#endif
3 changes: 3 additions & 0 deletions src/ui_menu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

void main_menu(void);

0 comments on commit f2940ac

Please sign in to comment.