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

Add SWAP functionality #19

Closed
wants to merge 13 commits into from
95 changes: 73 additions & 22 deletions src/handler/get_public_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,48 +34,97 @@
#include "../ui/display.h"
#include "../helper/send_response.h"

int handler_get_public_key(buffer_t *cdata, bool display) {
explicit_bzero(&G_context, sizeof(G_context));
G_context.req_type = CONFIRM_ADDRESS;
/*****************************************************************************
* Ledger App Aptos.
* (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.
*****************************************************************************/

cx_ecfp_private_key_t private_key = {0};
cx_ecfp_public_key_t public_key = {0};
#include <stdint.h> // uint*_t
#include <stdbool.h> // bool
#include <stddef.h> // size_t
#include <string.h> // memset, explicit_bzero

if (!buffer_read_u8(cdata, &G_context.bip32_path_len) ||
!buffer_read_bip32_path(cdata, G_context.bip32_path, (size_t) G_context.bip32_path_len)) {
G_context.req_type = REQUEST_UNDEFINED;
#include "os.h"
#include "cx.h"
#include "io.h"
#include "buffer.h"

#include "get_public_key.h"
#include "../globals.h"
#include "../types.h"
#include "../sw.h"
#include "../crypto.h"
#include "../address.h"
#include "../ui/display.h"
#include "../helper/send_response.h"

int get_public_key(buffer_t *cdata,
uint8_t *output_bip32_path_len,
uint32_t *output_bip32_path,
pubkey_ctx_t *output_pubkey_ctx) {
if (!buffer_read_u8(cdata, output_bip32_path_len)) {
return io_send_sw(SW_WRONG_DATA_LENGTH);
}
if (!buffer_read_bip32_path(cdata, output_bip32_path, (size_t) *output_bip32_path_len)) {
return io_send_sw(SW_WRONG_DATA_LENGTH);
}

if (!validate_aptos_bip32_path(G_context.bip32_path, G_context.bip32_path_len)) {
G_context.req_type = REQUEST_UNDEFINED;
if (!validate_aptos_bip32_path(output_bip32_path, *output_bip32_path_len)) {
return io_send_sw(SW_GET_PUB_KEY_FAIL);
}

// derive private key according to BIP32 path
// Derive private key according to BIP32 path
cx_ecfp_private_key_t private_key = {0};
cx_err_t error = crypto_derive_private_key(&private_key,
G_context.pk_info.chain_code,
G_context.bip32_path,
G_context.bip32_path_len);
output_pubkey_ctx->chain_code,
output_bip32_path,
*output_bip32_path_len);
if (error != CX_OK) {
explicit_bzero(&private_key, sizeof(private_key));
PRINTF("crypto_derive_private_key error code: %x.\n", error);
G_context.req_type = REQUEST_UNDEFINED;
// Wipe the private key from memory to protect against memory attacks
explicit_bzero(&private_key, sizeof(private_key));
return io_send_sw(SW_GET_PUB_KEY_FAIL);
}

// generate corresponding public key
error = crypto_init_public_key(&private_key, &public_key, G_context.pk_info.raw_public_key);
// Generate corresponding public key
cx_ecfp_public_key_t public_key = {0};
error = crypto_init_public_key(&private_key, &public_key, output_pubkey_ctx->raw_public_key);
// Wipe the private key from memory to protect against memory attacks
explicit_bzero(&private_key, sizeof(private_key));

if (error != CX_OK) {
explicit_bzero(&private_key, sizeof(private_key));
PRINTF("crypto_init_public_key error code: %x.\n", error);
G_context.req_type = REQUEST_UNDEFINED;
return io_send_sw(SW_GET_PUB_KEY_FAIL);
}

// reset private key
explicit_bzero(&private_key, sizeof(private_key));
return 0;
}

int handler_get_public_key(buffer_t *cdata, bool display) {
explicit_bzero(&G_context, sizeof(G_context));
G_context.req_type = CONFIRM_ADDRESS;

int err = get_public_key(cdata,
&G_context.bip32_path_len,
G_context.bip32_path,
&G_context.pk_info);

if (err) {
G_context.req_type = REQUEST_UNDEFINED;
return err;
}

if (display) {
int ui_status = ui_display_address();
Expand All @@ -86,3 +135,5 @@ int handler_get_public_key(buffer_t *cdata, bool display) {
G_context.req_type = REQUEST_UNDEFINED; // all the work is done, reset the context
return helper_send_response_pubkey();
}


23 changes: 23 additions & 0 deletions src/handler/get_public_key.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,26 @@
*
*/
int handler_get_public_key(buffer_t *cdata, bool display);

/**
* Helper function for GET_PUBLIC_KEY and CHECK_ADDRESS command. If successfully parse
* BIP32 path, derive public key/chain. The public key is stored in output_public_key,
* and the BIP32 path and its length are stored in output_bip32_path and
* output_bip32_path_len respectively.
*
* @param[in] cdata
* Command data with BIP32 path.
* @param[out] output_bip32_path_len
* Integer pointer to store the length of the BIP32 path.
* @param[out] output_bip32_path
* Buffer to store the BIP32 path.
* @param[out] output_public_key
* Buffer to store the public key.
*
* @return zero if success, error code otherwise.
*
*/
int get_public_key(buffer_t *cdata,
uint8_t *output_bip32_path_len,
uint32_t output_bip32_path[MAX_BIP32_PATH],
pubkey_ctx_t *output_public_key);
94 changes: 94 additions & 0 deletions src/swap/handle_check_address.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*****************************************************************************
* Ledger App Aptos.
* (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.
*****************************************************************************/

#ifdef HAVE_SWAP
#include <string.h>
#include "swap.h"
#include "os.h"
#include "../address.h"
#include "../handler/get_public_key.h"
#include "../common/user_format.h"

// The address string length is 66, 2 characters for the prefix and 64 for the address
#define ADDRESS_STRING_LENGTH 66

/**
* Handler for CHECK_ADDRESS command. If successfully parse BIP32 path,
* derive public key and address, and compare it with the address to check.
*
*
* @param[in,out] params
* Command data address parameters and address to check.
*
*/
void swap_handle_check_address(check_address_parameters_t *params) {
PRINTF("Inside Aptos swap_handle_check_address\n");
params->result = 0;

// Checking that parameters are correct
if (params->address_parameters == NULL || params->address_parameters_length == 0) {
PRINTF("address_parameters is empty\n");
return;
}
PRINTF("address_parameters_length: %d\n", params->address_parameters_length);
PRINTF("address_parameters: %.*H\n", params->address_parameters_length, params->address_parameters);

if (params->address_to_check == NULL) {
PRINTF("address_to_check is empty\n");
return;
}

if (strlen(params->address_to_check) != ADDRESS_STRING_LENGTH) {
PRINTF("address_to_check length should be %d, not %d\n",
ADDRESS_STRING_LENGTH, strlen(params->address_to_check));
return;
}

// Calculate the public key from the BIP32 path
buffer_t cdata;
cdata.ptr = params->address_parameters;
cdata.size = params->address_parameters_length;
cdata.offset = 0;

uint8_t bip32_path_len;
uint32_t bip32_path[MAX_BIP32_PATH];
pubkey_ctx_t public_key;
if (get_public_key(&cdata, &bip32_path_len, bip32_path, &public_key) != 0) {
PRINTF("get_public_key failed\n");
return;
}
// Calculate the address from the public key, and decode it to readable format
uint8_t address[ADDRESS_LEN] = {0};
if (!address_from_pubkey(public_key.raw_public_key, address, sizeof(address))) {
return;
}
char prefixed_address[ADDRESS_STRING_LENGTH + 1];
if (0 > format_prefixed_hex(address, sizeof(address), prefixed_address, sizeof(prefixed_address))) {
return;
}

PRINTF("address_to_check: %s\n", params->address_to_check);
PRINTF("prefixed_address: %s\n", prefixed_address);
// Compare the strings
if (strcmp(params->address_to_check, prefixed_address) != 0) {
PRINTF("addresses does not match\n");
} else {
PRINTF("addresses match\n");
params->result = 1;
}
}
#endif
14 changes: 14 additions & 0 deletions src/swap/handle_get_printable_amount.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifdef HAVE_SWAP

#include <string.h> // memset, explicit_bzero
#include "handle_swap_sign_transaction.h"
#include "swap.h"
#include "os.h"
#include "constants.h"

/* Set empty printable_amount on error, printable amount otherwise */
void swap_handle_get_printable_amount(get_printable_amount_parameters_t* params) {
PRINTF("TODO: swap_handle_get_printable_amount\n");
}

#endif
21 changes: 21 additions & 0 deletions src/swap/handle_swap_sign_transaction.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifdef HAVE_SWAP

#include "handle_swap_sign_transaction.h"
#include "display.h"
#include "swap.h"
#include "string.h"
#include "os_lib.h"
#include "constants.h"
#include "os_utils.h"
#include "globals.h"

bool swap_copy_transaction_parameters(create_transaction_parameters_t* params) {
PRINTF("TODO: swap_copy_transaction_parameters\n");
return false;
}

void __attribute__((noreturn)) swap_finalize_exchange_sign_transaction(bool is_success) {
PRINTF("TODO: swap_finalize_exchange_sign_transaction\n");
}

#endif
Empty file.
Loading