Skip to content

Commit

Permalink
feat: get app settings command
Browse files Browse the repository at this point in the history
  • Loading branch information
krigga committed Mar 14, 2024
1 parent da5d7a4 commit a82aafe
Show file tree
Hide file tree
Showing 49 changed files with 133 additions and 0 deletions.
21 changes: 21 additions & 0 deletions doc/COMMANDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
| `SIGN_TX` | 0x06 | Sign transaction given BIP32 path and raw transaction |
| `GET_ADDRESS_PROOF` | 0x08 | Sign an address proof in TON Connect 2 compliant format given BIP32 path and proof parameters |
| `SIGN_DATA` | 0x09 | Sign custom data in TON Connect 2 compliant format |
| `GET_APP_SETTINGS` | 0x0A | Get app settings |

## GET_VERSION

Expand Down Expand Up @@ -129,6 +130,26 @@ Then an arbitrary number of chunks with serialized custom data (see [CUSTOM_DATA
| --- | --- | --- |
| 98 | 0x9000 | `len(signature) (1)` \|\| <br> `signature (64)` \|\| <br> `len(hash) (1)` \|\| <br> `hash (32)` \|\||

## GET_APP_SETTINGS

### Command

| CLA | INS | P1 | P2 | Lc | CData |
| --- | --- | --- | --- | --- | --- |
| 0xE0 | 0x0A | 0x00 | 0x00 | 0x00 | - |

### Response

True/false settings are sent as bitfields, currently all settings fit in one byte, future versions may add additional flags to that byte or add new bytes.

In the current version, `flags` has:
- bit `0x01` set if blind signing is enabled
- bit `0x02` set if expert mode is enabled

| Response length (bytes) | SW | RData |
| --- | --- | --- |
| 1 | 0x9000 | `flags (1)` |

## Status Words

| SW | SW name | Description |
Expand Down
7 changes: 7 additions & 0 deletions src/apdu/dispatcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "../handler/get_public_key.h"
#include "../handler/sign_tx.h"
#include "../handler/sign_data.h"
#include "../handler/get_app_settings.h"

int apdu_dispatcher(const command_t *cmd) {
if (cmd->cla != CLA) {
Expand Down Expand Up @@ -132,6 +133,12 @@ int apdu_dispatcher(const command_t *cmd) {
buf.offset = 0;

return handler_sign_data(&buf, (bool) (cmd->p2 & P2_FIRST), (bool) (cmd->p2 & P2_MORE));
case GET_APP_SETTINGS:
if (cmd->p1 != P1_NONE || cmd->p2 != P2_NONE) {
return io_send_sw(SW_WRONG_P1P2);
}

return handler_get_app_settings();
default:
return io_send_sw(SW_INS_NOT_SUPPORTED);
}
Expand Down
40 changes: 40 additions & 0 deletions src/handler/get_app_settings.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*****************************************************************************
* Ledger App Boilerplate.
* (c) 2020 Ledger SAS.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*****************************************************************************/

#include <stdint.h> // uint*_t

#include "get_app_settings.h"
#include "../globals.h"
#include "../io.h"
#include "../sw.h"
#include "common/buffer.h"

int handler_get_app_settings() {
uint8_t flags = 0x00;

if (N_storage.blind_signing_enabled) {
flags |= 0x01;
}

if (N_storage.expert_mode) {
flags |= 0x02;
}

buffer_t rdata = {.ptr = (uint8_t *) &flags, .size = sizeof(flags), .offset = 0};

return io_send_response(&rdata, SW_OK);
}
11 changes: 11 additions & 0 deletions src/handler/get_app_settings.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

#include "os.h"

/**
* Handler for GET_APP_SETTINGS command. Send APDU response with app settings.
*
* @return zero or positive integer if success, negative integer otherwise.
*
*/
int handler_get_app_settings(void);
1 change: 1 addition & 0 deletions src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ typedef enum {
SIGN_TX = 0x06, /// sign transaction with BIP32 path
GET_ADDRESS_PROOF = 0x08, /// get an address proof in TON Connect format
SIGN_DATA = 0x09, /// sign data in TON Connect format
GET_APP_SETTINGS = 0x0a, /// get app settings
} command_e;

/**
Expand Down
9 changes: 9 additions & 0 deletions tests/application_client/ton_command_sender.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class InsType(IntEnum):
SIGN_TX = 0x06
GET_ADDRESS_PROOF = 0x08
SIGN_DATA = 0x09
GET_APP_SETTINGS = 0x0A

class Errors(IntEnum):
SW_DENY = 0x6985
Expand Down Expand Up @@ -96,6 +97,14 @@ def get_public_key(self, path: str) -> RAPDU:
data=pack_derivation_path(path))


def get_app_settings(self) -> RAPDU:
return self.backend.exchange(cla=CLA,
ins=InsType.GET_APP_SETTINGS,
p1=P1.P1_NONE,
p2=P2.P2_NONE,
data=b"")


@contextmanager
def get_public_key_with_confirmation(self,
path: str,
Expand Down
Binary file added tests/snapshots/nanos/test_app_settings/00000.png
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 tests/snapshots/nanos/test_app_settings/00001.png
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 tests/snapshots/nanos/test_app_settings/00002.png
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 tests/snapshots/nanos/test_app_settings/00003.png
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 tests/snapshots/nanos/test_app_settings/00004.png
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 tests/snapshots/nanos/test_app_settings/00005.png
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 tests/snapshots/nanos/test_app_settings/00006.png
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 tests/snapshots/nanos/test_app_settings/00007.png
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 tests/snapshots/nanos/test_app_settings/00008.png
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 tests/snapshots/nanos/test_app_settings/00009.png
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 tests/snapshots/nanos/test_app_settings/00010.png
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 tests/snapshots/nanos/test_app_settings/00011.png
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 tests/snapshots/nanosp/test_app_settings/00000.png
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 tests/snapshots/nanosp/test_app_settings/00001.png
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 tests/snapshots/nanosp/test_app_settings/00002.png
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 tests/snapshots/nanosp/test_app_settings/00003.png
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 tests/snapshots/nanosp/test_app_settings/00004.png
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 tests/snapshots/nanosp/test_app_settings/00005.png
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 tests/snapshots/nanosp/test_app_settings/00006.png
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 tests/snapshots/nanosp/test_app_settings/00007.png
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 tests/snapshots/nanosp/test_app_settings/00008.png
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 tests/snapshots/nanosp/test_app_settings/00009.png
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 tests/snapshots/nanosp/test_app_settings/00010.png
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 tests/snapshots/nanosp/test_app_settings/00011.png
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 tests/snapshots/nanox/test_app_settings/00000.png
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 tests/snapshots/nanox/test_app_settings/00001.png
Binary file added tests/snapshots/nanox/test_app_settings/00002.png
Binary file added tests/snapshots/nanox/test_app_settings/00003.png
Binary file added tests/snapshots/nanox/test_app_settings/00004.png
Binary file added tests/snapshots/nanox/test_app_settings/00005.png
Binary file added tests/snapshots/nanox/test_app_settings/00006.png
Binary file added tests/snapshots/nanox/test_app_settings/00007.png
Binary file added tests/snapshots/nanox/test_app_settings/00008.png
Binary file added tests/snapshots/nanox/test_app_settings/00009.png
Binary file added tests/snapshots/nanox/test_app_settings/00010.png
Binary file added tests/snapshots/nanox/test_app_settings/00011.png
Binary file added tests/snapshots/stax/test_app_settings/00000.png
Binary file added tests/snapshots/stax/test_app_settings/00001.png
Binary file added tests/snapshots/stax/test_app_settings/00002.png
Binary file added tests/snapshots/stax/test_app_settings/00003.png
Binary file added tests/snapshots/stax/test_app_settings/00004.png
Binary file added tests/snapshots/stax/test_app_settings/00005.png
44 changes: 44 additions & 0 deletions tests/test_settings_cmd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from application_client.ton_command_sender import BoilerplateCommandSender
from utils import ROOT_SCREENSHOT_PATH
from ragger.navigator import NavInsID, NavIns

# In this test we check the behavior of the device when asked to provide the app version
def test_app_settings(firmware, backend, navigator, test_name):
# Use the app interface instead of raw interface
client = BoilerplateCommandSender(backend)
rapdu = client.get_app_settings()
assert(len(rapdu.data) == 1 and rapdu.data[0] == 0x00)

# Enable blind signing and expert mode
if firmware.device.startswith("nano"):
navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH,
test_name,
[
NavInsID.RIGHT_CLICK,
NavInsID.BOTH_CLICK,
NavInsID.BOTH_CLICK,
NavInsID.RIGHT_CLICK,
NavInsID.BOTH_CLICK,
NavInsID.RIGHT_CLICK,
NavInsID.BOTH_CLICK,
NavInsID.RIGHT_CLICK,
NavInsID.BOTH_CLICK,
NavInsID.RIGHT_CLICK,
NavInsID.BOTH_CLICK,
],
screen_change_before_first_instruction=False)
else:
navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH,
test_name,
[
NavInsID.USE_CASE_HOME_INFO,
NavInsID.USE_CASE_SETTINGS_NEXT,
NavIns(NavInsID.TOUCH, (354, 125)),
NavIns(NavInsID.TOUCH, (354, 272)),
NavInsID.USE_CASE_SETTINGS_MULTI_PAGE_EXIT,
],
screen_change_before_first_instruction=False)

rapdu = client.get_app_settings()
assert(len(rapdu.data) == 1 and rapdu.data[0] == (0x01 | 0x02))

0 comments on commit a82aafe

Please sign in to comment.