3030#include "parse.h"
3131#include "uint256.h"
3232
33+ #include "tokens.h"
3334
3435extern bool fidoActivated ;
3536
@@ -51,6 +52,7 @@ uint32_t set_result_get_publicKey(void);
5152#define P1_FIRST 0x00
5253#define P1_MORE 0x80
5354#define P1_LAST 0x90
55+ #define P1_TRC10_NAME 0xA0
5456#define P1_SIGN 0x10
5557
5658#define OFFSET_CLA 0
@@ -71,7 +73,7 @@ cx_sha256_t sha2;
7173volatile char fullAddress [BASE58CHECK_ADDRESS_SIZE + 1 ];
7274volatile char addressSummary [35 ];
7375volatile char fullAmount [50 ];
74- volatile char fullContract [50 ];
76+ volatile char fullContract [MAX_TOKEN_LENGTH ];
7577volatile char fullHash [HASH_SIZE * 2 + 1 ];
7678volatile char fullAmount2 [50 ];
7779volatile char exchangeContractDetail [50 ];
@@ -1587,7 +1589,7 @@ const bagl_element_t ui_approval_nanos[] = {
15871589 NULL ,
15881590 NULL ,
15891591 NULL },
1590- {{BAGL_LABELINE , 0x02 , 23 , 26 , 82 , 12 , 0x80 | 10 , 0 , 0 , 0xFFFFFF , 0x000000 ,
1592+ {{BAGL_LABELINE , 0x02 , 12 , 28 , 104 , 12 , 0x00 | 10 , 0 , 0 , 0xFFFFFF , 0x000000 ,
15911593 BAGL_FONT_OPEN_SANS_EXTRABOLD_11px | BAGL_FONT_ALIGNMENT_CENTER , 26 },
15921594 (char * )fullContract ,
15931595 0 ,
@@ -1952,7 +1954,7 @@ const bagl_element_t ui_approval_exchange_withdraw_nanos[] = {
19521954
19531955 {{BAGL_LABELINE , 0x03 , 0 , 12 , 128 , 32 , 0 , 0 , 0 , 0xFFFFFF , 0x000000 ,
19541956 BAGL_FONT_OPEN_SANS_REGULAR_11px | BAGL_FONT_ALIGNMENT_CENTER , 0 },
1955- "Token ID " ,
1957+ "Token Name " ,
19561958 0 ,
19571959 0 ,
19581960 0 ,
@@ -2116,7 +2118,7 @@ const bagl_element_t ui_approval_exchange_transaction_nanos[] = {
21162118
21172119 {{BAGL_LABELINE , 0x03 , 0 , 12 , 128 , 32 , 0 , 0 , 0 , 0xFFFFFF , 0x000000 ,
21182120 BAGL_FONT_OPEN_SANS_REGULAR_11px | BAGL_FONT_ALIGNMENT_CENTER , 0 },
2119- "Token ID " ,
2121+ "Token Name " ,
21202122 0 ,
21212123 0 ,
21222124 0 ,
@@ -2475,7 +2477,7 @@ void handleGetPublicKey(uint8_t p1, uint8_t p2, uint8_t *dataBuffer,
24752477#elif defined(TARGET_NANOS )
24762478 ux_step = 0 ;
24772479 ux_step_count = 2 ;
2478- UX_DISPLAY (ui_address_nanos , ui_address_prepro );
2480+ UX_DISPLAY (ui_address_nanos , ( bagl_element_callback_t ) ui_address_prepro );
24792481#endif // #if TARGET
24802482
24812483 * flags |= IO_ASYNCH_REPLY ;
@@ -2517,6 +2519,11 @@ void handleSign(uint8_t p1, uint8_t p2, uint8_t *workBuffer,
25172519 }
25182520
25192521 //Parse contract type
2522+ // Prevent buffer overflow
2523+ if (dataLength > MAX_RAW_TX ){
2524+ PRINTF ("RawTX buffer overflow\n" );
2525+ THROW (0x6A80 );
2526+ }
25202527 // Load raw Data
25212528 os_memmove (tmpCtx .transactionContext .rawTx , workBuffer , dataLength );
25222529 tmpCtx .transactionContext .rawTxLength = dataLength ;
@@ -2527,7 +2534,43 @@ void handleSign(uint8_t p1, uint8_t p2, uint8_t *workBuffer,
25272534 }
25282535 cx_sha256_init (& sha2 ); //init sha
25292536
2530- } else if ((p1 != P1_MORE ) && (p1 != P1_LAST )) {
2537+ } else if ((p1 & 0xF0 ) == P1_TRC10_NAME ) {
2538+ switch (txContent .contractType ){
2539+ case 2 : // transafer asset
2540+ case 41 : // create exchange
2541+ // Max 2 Tokens Name
2542+ if ((p1 & 0x07 )> 1 )
2543+ THROW (0x6A80 );
2544+ // Decode Token name and validate signature
2545+ if (parseTokenName ((p1 & 0x07 ),workBuffer , dataLength , & txContent ) != USTREAM_FINISHED ) {
2546+ PRINTF ("Unexpected parser status\n" );
2547+ THROW (0x6A80 );
2548+ }
2549+ // if not last token name, return
2550+ if (!(p1 & 0x08 )) THROW (0x9000 );
2551+ dataLength = 0 ;
2552+
2553+ break ;
2554+ case 42 : // exchange Inject
2555+ case 43 : // exchange withdraw
2556+ case 44 : // exchange transaction
2557+ // Max 1 pair set
2558+ if ((p1 & 0x07 )> 0 )
2559+ THROW (0x6A80 );
2560+ // error if not last
2561+ if (!(p1 & 0x08 )) THROW (0x6A80 );
2562+ // Decode Token name and validate signature
2563+ if (parseExchange ((p1 & 0x07 ),workBuffer , dataLength , & txContent ) != USTREAM_FINISHED ) {
2564+ PRINTF ("Unexpected parser status\n" );
2565+ THROW (0x6A80 );
2566+ }
2567+ dataLength = 0 ;
2568+ break ;
2569+ default :
2570+ // Error if any other contract
2571+ THROW (0x6A80 );
2572+ }
2573+ }else if ((p1 != P1_MORE ) && (p1 != P1_LAST )) {
25312574 THROW (0x6B00 );
25322575 }else {
25332576
@@ -2541,126 +2584,132 @@ void handleSign(uint8_t p1, uint8_t p2, uint8_t *workBuffer,
25412584 case 2 : // TRC10 Transfer
25422585 case 31 : // TRC20 Transfer
25432586 // get Hash
2544- cx_hash ((cx_hash_t * )& sha2 , CX_LAST , tmpCtx .transactionContext .rawTx ,
2545- tmpCtx .transactionContext .rawTxLength , tmpCtx .transactionContext .hash );
2546-
2587+ cx_hash ((cx_hash_t * )& sha2 , 0 , workBuffer , dataLength , NULL );
2588+ if ((p1 == P1_MORE ) || (p1 == P1_FIRST )) {
2589+ THROW (0x9000 );
2590+ }
2591+ cx_hash ((cx_hash_t * )& sha2 , CX_LAST , workBuffer ,
2592+ 0 , tmpCtx .transactionContext .hash );
2593+
25472594 if (txContent .contractType == 31 ){
25482595 convertUint256BE (txContent .TRC20Amount , 32 , & uint256 );
25492596 tostring256 (& uint256 , 10 , (char * )fullAmount2 , sizeof (fullAmount2 ));
2550- if (!adjustDecimals ((char * )fullAmount2 , strlen (fullAmount2 ), (char * )fullAmount , sizeof (fullAmount ), txContent .decimals ))
2597+ if (!adjustDecimals ((char * )fullAmount2 , strlen (( const char * ) fullAmount2 ), (char * )fullAmount , sizeof (fullAmount ), txContent .decimals [ 0 ] ))
25512598 THROW (0x6B00 );
25522599 }else
2553- print_amount (txContent .amount ,(void * )fullAmount ,sizeof (fullAmount ), (txContent .contractType == 1 )?SUN_DIG :0 );
2600+ print_amount (txContent .amount ,(void * )fullAmount ,sizeof (fullAmount ), (txContent .contractType == 1 )?SUN_DIG :txContent . decimals [ 0 ] );
25542601
25552602 getBase58FromAddres (txContent .destination ,
25562603 (void * )fullAddress , & sha2 );
25572604 fullAddress [BASE58CHECK_ADDRESS_SIZE ]= '\0' ;
2558-
2605+
25592606 // get token name
2560- os_memmove ((void * )fullContract , txContent .tokenName , txContent .tokenNameLength + 1 );
2607+ os_memmove ((void * )fullContract , txContent .tokenNames [ 0 ] , txContent .tokenNamesLength [ 0 ] + 1 );
25612608
25622609 #if defined(TARGET_BLUE )
25632610 G_ui_approval_blue_state = APPROVAL_TRANSFER ;
25642611 ui_approval_transaction_blue_init ();
25652612 #elif defined(TARGET_NANOS )
25662613 ux_step = 0 ;
25672614 ux_step_count = 4 ;
2568- UX_DISPLAY (ui_approval_nanos , ui_approval_prepro );
2615+ UX_DISPLAY (ui_approval_nanos ,( bagl_element_callback_t ) ui_approval_prepro );
25692616 #endif // #if TARGET_ID
25702617
25712618 break ;
25722619 case 41 : // exchange create
2573- cx_hash (& sha2 , 0 , workBuffer , dataLength , NULL );
2620+ cx_hash (( cx_hash_t * ) & sha2 , 0 , workBuffer , dataLength , NULL );
25742621 if ((p1 == P1_MORE ) || (p1 == P1_FIRST )) {
25752622 THROW (0x9000 );
25762623 }
2577- cx_hash (& sha2 , CX_LAST , workBuffer ,
2624+ cx_hash (( cx_hash_t * ) & sha2 , CX_LAST , workBuffer ,
25782625 0 , tmpCtx .transactionContext .hash );
25792626
2580- os_memmove ((void * )fullContract , txContent .tokenName , txContent .tokenNameLength + 1 );
2581- os_memmove ((void * )fullAddress , txContent .tokenName2 , txContent .tokenName2Length + 1 );
2582- print_amount (txContent .amount ,(void * )fullAmount ,sizeof (fullAmount ), (strncmp (txContent .tokenName , "TRX" , 3 )== 0 )?SUN_DIG :0 );
2583- print_amount (txContent .amount2 ,(void * )fullAmount2 ,sizeof (fullAmount2 ), (strncmp (txContent .tokenName2 , "TRX" , 3 )== 0 )?SUN_DIG :0 );
2627+ os_memmove ((void * )fullContract , txContent .tokenNames [ 0 ] , txContent .tokenNamesLength [ 0 ] + 1 );
2628+ os_memmove ((void * )fullAddress , txContent .tokenNames [ 1 ] , txContent .tokenNamesLength [ 1 ] + 1 );
2629+ print_amount (txContent .amount ,(void * )fullAmount ,sizeof (fullAmount ), (strncmp (( const char * ) txContent .tokenNames [ 0 ] , "TRX" , 3 )== 0 )?SUN_DIG :txContent . decimals [ 0 ] );
2630+ print_amount (txContent .amount2 ,(void * )fullAmount2 ,sizeof (fullAmount2 ), (strncmp (( const char * ) txContent .tokenNames [ 1 ] , "TRX" , 3 )== 0 )?SUN_DIG :txContent . decimals [ 1 ] );
25842631 // write exchange contract type
2585- if (!setExchangeContractDetail (txContent .contractType , exchangeContractDetail )) THROW (0x6A80 );
2632+ if (!setExchangeContractDetail (txContent .contractType , ( void * ) exchangeContractDetail )) THROW (0x6A80 );
25862633
25872634 #if defined(TARGET_BLUE )
25882635 G_ui_approval_blue_state = APPROVAL_TRANSACTION ;
25892636 ui_approval_exchange_create_blue_init ();
25902637 #elif defined(TARGET_NANOS )
25912638 ux_step = 0 ;
25922639 ux_step_count = 5 ;
2593- UX_DISPLAY (ui_approval_exchange_nanos , ui_approval_exchange_prepro );
2640+ UX_DISPLAY (ui_approval_exchange_nanos ,( bagl_element_callback_t ) ui_approval_exchange_prepro );
25942641 #endif // #if TARGET_ID
25952642 break ;
25962643 case 42 : // exchange Inject
25972644 case 43 : // exchange withdraw
2598- cx_hash (& sha2 , 0 , workBuffer , dataLength , NULL );
2645+ cx_hash (( cx_hash_t * ) & sha2 , 0 , workBuffer , dataLength , NULL );
25992646 if ((p1 == P1_MORE ) || (p1 == P1_FIRST )) {
26002647 THROW (0x9000 );
26012648 }
2602- cx_hash (& sha2 , CX_LAST , workBuffer ,
2649+ cx_hash (( cx_hash_t * ) & sha2 , CX_LAST , workBuffer ,
26032650 0 , tmpCtx .transactionContext .hash );
26042651
2605- os_memmove ((void * )fullContract , txContent .tokenName , txContent .tokenNameLength + 1 );
2652+ os_memmove ((void * )fullContract , txContent .tokenNames [ 0 ] , txContent .tokenNamesLength [ 0 ] + 1 );
26062653 print_amount (txContent .exchangeID ,(void * )fullAddress ,sizeof (fullAddress ), 0 );
2607- print_amount (txContent .amount ,(void * )fullAmount ,sizeof (fullAmount ), (strncmp (txContent .tokenName , "TRX" , 3 )== 0 )?SUN_DIG :0 );
2654+ print_amount (txContent .amount ,(void * )fullAmount ,sizeof (fullAmount ), (strncmp (( const char * ) txContent .tokenNames [ 0 ] , "TRX" , 3 )== 0 )?SUN_DIG :txContent . decimals [ 0 ] );
26082655 // write exchange contract type
2609- if (!setExchangeContractDetail (txContent .contractType , exchangeContractDetail )) THROW (0x6A80 );
2656+ if (!setExchangeContractDetail (txContent .contractType , ( void * ) exchangeContractDetail )) THROW (0x6A80 );
26102657
26112658 #if defined(TARGET_BLUE )
26122659 G_ui_approval_blue_state = APPROVAL_TRANSACTION ;
26132660 ui_approval_exchange_withdraw_blue_init ();
26142661 #elif defined(TARGET_NANOS )
26152662 ux_step = 0 ;
26162663 ux_step_count = 4 ;
2617- UX_DISPLAY (ui_approval_exchange_withdraw_nanos , ui_approval_exchange_withdraw_prepro );
2664+ UX_DISPLAY (ui_approval_exchange_withdraw_nanos ,( bagl_element_callback_t ) ui_approval_exchange_withdraw_prepro );
26182665 #endif // #if TARGET_ID
26192666 break ;
26202667 case 44 : // exchange transaction
2621- cx_hash (& sha2 , 0 , workBuffer , dataLength , NULL );
2668+ cx_hash (( cx_hash_t * ) & sha2 , 0 , workBuffer , dataLength , NULL );
26222669 if ((p1 == P1_MORE ) || (p1 == P1_FIRST )) {
26232670 THROW (0x9000 );
26242671 }
2625- cx_hash (& sha2 , CX_LAST , workBuffer ,
2672+ cx_hash (( cx_hash_t * ) & sha2 , CX_LAST , workBuffer ,
26262673 0 , tmpCtx .transactionContext .hash );
26272674
2628- os_memmove ((void * )fullContract , txContent .tokenName , txContent .tokenNameLength + 1 );
2675+ //os_memmove((void *)fullContract, txContent.tokenNames[0], txContent.tokenNamesLength[0]+1);
2676+ snprintf ((char * )fullContract , sizeof (fullContract ), "%s -> %s" , txContent .tokenNames [0 ], txContent .tokenNames [1 ]);
2677+
26292678 print_amount (txContent .exchangeID ,(void * )fullAddress ,sizeof (fullAddress ), 0 );
2630- print_amount (txContent .amount ,(void * )fullAmount ,sizeof (fullAmount ), ( strncmp ( txContent .tokenName , "TRX" , 3 ) == 0 )? SUN_DIG : 0 );
2631- print_amount (txContent .amount2 ,(void * )fullAmount2 ,sizeof (fullAmount2 ), ( strncmp ( txContent .tokenName , "TRX" , 3 ) == 0 )? 0 : SUN_DIG );
2679+ print_amount (txContent .amount ,(void * )fullAmount ,sizeof (fullAmount ), txContent .decimals [ 0 ] );
2680+ print_amount (txContent .amount2 ,(void * )fullAmount2 ,sizeof (fullAmount2 ), txContent .decimals [ 1 ] );
26322681 // write exchange contract type
2633- if (!setExchangeContractDetail (txContent .contractType , exchangeContractDetail )) THROW (0x6A80 );
2682+ if (!setExchangeContractDetail (txContent .contractType , ( void * ) exchangeContractDetail )) THROW (0x6A80 );
26342683
26352684 #if defined(TARGET_BLUE )
26362685 G_ui_approval_blue_state = APPROVAL_TRANSACTION ;
26372686 ui_approval_exchange_transaction_blue_init ();
26382687 #elif defined(TARGET_NANOS )
26392688 ux_step = 0 ;
26402689 ux_step_count = 5 ;
2641- UX_DISPLAY (ui_approval_exchange_transaction_nanos , ui_approval_exchange_transaction_prepro );
2690+ UX_DISPLAY (ui_approval_exchange_transaction_nanos , ( bagl_element_callback_t ) ui_approval_exchange_transaction_prepro );
26422691 #endif // #if TARGET_ID
26432692 break ;
26442693 default :
2645- cx_hash (& sha2 , 0 , workBuffer , dataLength , NULL );
2694+ cx_hash (( cx_hash_t * ) & sha2 , 0 , workBuffer , dataLength , NULL );
26462695 if ((p1 == P1_MORE ) || (p1 == P1_FIRST )) {
26472696 THROW (0x9000 );
26482697 }
2649- cx_hash (& sha2 , CX_LAST , workBuffer ,
2698+ cx_hash (( cx_hash_t * ) & sha2 , CX_LAST , workBuffer ,
26502699 0 , tmpCtx .transactionContext .hash );
26512700
26522701 // Write fullHash
2653- array_hexstr (fullHash , tmpCtx .transactionContext .hash , 32 );
2702+ array_hexstr (( char * ) fullHash , tmpCtx .transactionContext .hash , 32 );
26542703 // write contract type
2655- if (!setContractType (txContent .contractType , fullContract )) THROW (0x6A80 );
2704+ if (!setContractType (txContent .contractType , ( void * ) fullContract )) THROW (0x6A80 );
26562705
26572706 #if defined(TARGET_BLUE )
26582707 G_ui_approval_blue_state = APPROVAL_TRANSACTION ;
26592708 ui_approval_simple_transaction_blue_init ();
26602709 #elif defined(TARGET_NANOS )
26612710 ux_step = 0 ;
26622711 ux_step_count = 3 ;
2663- UX_DISPLAY (ui_approval_simple_nanos , ui_approval_simple_prepro );
2712+ UX_DISPLAY (ui_approval_simple_nanos ,( bagl_element_callback_t ) ui_approval_simple_prepro );
26642713 #endif // #if TARGET_ID
26652714 break ;
26662715 }
@@ -2714,7 +2763,7 @@ void handleApdu(volatile unsigned int *flags, volatile unsigned int *tx) {
27142763 G_io_apdu_buffer + OFFSET_CDATA ,
27152764 G_io_apdu_buffer [OFFSET_LC ], flags , tx );
27162765 break ;
2717-
2766+
27182767 case INS_GET_APP_CONFIGURATION :
27192768 // Request App configuration
27202769 handleGetAppConfiguration (
0 commit comments