95
95
/*****************************************************************************
96
96
* PRIVATE TYPEDEFS
97
97
*****************************************************************************/
98
- typedef stellar_sign_txn_signature_response_signature_t der_sig_t ;
98
+ typedef stellar_sign_txn_signature_response_signature_t stellar_sig_t ;
99
99
100
100
/*****************************************************************************
101
101
* STATIC FUNCTION PROTOTYPES
@@ -191,26 +191,25 @@ static bool get_user_verification(void);
191
191
* @return false If signature could not be computed - maybe due to some error
192
192
* during seed reconstruction phase
193
193
*/
194
- static bool sign_txn (der_sig_t * der_signature );
194
+ static bool sign_txn (stellar_sig_t * der_signature );
195
195
196
196
/**
197
197
* @brief Creates signature base data for Stellar transaction signing
198
- * @details Builds the standardized data structure that must be signed according
199
- * to Stellar protocol specifications
198
+ * @details Combines network passphrase hash with truncated XDR transaction data
200
199
*
201
200
* @param network_passphrase Network passphrase string (mainnet/testnet)
202
- * @param tx Parsed transaction structure
203
- * @param payment Parsed payment operation structure
201
+ * @param transaction_xdr Raw XDR transaction data
202
+ * @param signature_data_len Length of signature-relevant XDR data
204
203
* @param signature_base Output buffer for signature base data
205
204
* @param base_len Output length of signature base data
206
205
* @return int 0 on success, non-zero on error
207
206
*/
207
+
208
208
static int create_signature_base (const char * network_passphrase ,
209
- stellar_transaction_t * tx ,
210
- stellar_payment_t * payment ,
209
+ uint8_t * transaction_xdr ,
210
+ size_t signature_data_len ,
211
211
uint8_t * signature_base ,
212
212
int * base_len );
213
-
214
213
/**
215
214
* @brief Creates ED25519 signature for Stellar transaction
216
215
* @details Signs the transaction hash using ED25519 algorithm
@@ -244,7 +243,7 @@ static int stellar_create_signature(stellar_transaction_t *tx,
244
243
* or invalid request received from the host
245
244
*/
246
245
static bool send_signature (stellar_query_t * query ,
247
- const der_sig_t * der_signature );
246
+ const stellar_sig_t * der_signature );
248
247
249
248
/*****************************************************************************
250
249
* STATIC VARIABLES
@@ -381,14 +380,17 @@ static bool fetch_valid_input(stellar_query_t *query) {
381
380
stellar_txn_context -> payment =
382
381
(stellar_payment_t * )malloc (sizeof (stellar_payment_t ));
383
382
383
+ int signature_data_len = 0 ;
384
384
if (stellar_parse_transaction (stellar_txn_context -> transaction ,
385
385
total_size ,
386
386
stellar_txn_context -> txn ,
387
- stellar_txn_context -> payment ) != 0 ) {
387
+ stellar_txn_context -> payment ,
388
+ & signature_data_len ) != 0 ) {
388
389
stellar_send_error (ERROR_COMMON_ERROR_CORRUPT_DATA_TAG ,
389
390
ERROR_DATA_FLOW_INVALID_DATA );
390
391
return false;
391
392
}
393
+ stellar_txn_context -> signature_data_len = signature_data_len ;
392
394
393
395
return true;
394
396
}
@@ -398,14 +400,14 @@ static bool show_memo_details(const stellar_transaction_t *decoded_txn) {
398
400
char memo_display [100 ] = {'\0' };
399
401
snprintf (memo_display ,
400
402
sizeof (memo_display ),
401
- ui_text_stellar_memo_text ,
403
+ ui_text_memo_text ,
402
404
decoded_txn -> memo .text );
403
405
return core_confirmation (memo_display , stellar_send_error );
404
406
} else if (decoded_txn -> memo_type == STELLAR_MEMO_ID ) {
405
407
char memo_display [50 ] = {'\0' };
406
408
snprintf (memo_display ,
407
409
sizeof (memo_display ),
408
- ui_text_stellar_memo_id ,
410
+ ui_text_memo_id ,
409
411
decoded_txn -> memo .id );
410
412
return core_confirmation (memo_display , stellar_send_error );
411
413
} else if (decoded_txn -> memo_type == STELLAR_MEMO_NONE ) {
@@ -415,7 +417,7 @@ static bool show_memo_details(const stellar_transaction_t *decoded_txn) {
415
417
decoded_txn -> memo_type == STELLAR_MEMO_RETURN ) {
416
418
char memo_hash [80 ] = {'\0' };
417
419
char temp [3 ];
418
- strcpy (memo_hash , "Memo Hash: " );
420
+ strcpy (memo_hash , ui_text_memo_hash_prefix );
419
421
for (int i = 0 ; i < 32 ; i ++ ) {
420
422
snprintf (temp , sizeof (temp ), "%02x" , decoded_txn -> memo .hash [i ]);
421
423
strcat (memo_hash , temp );
@@ -425,7 +427,7 @@ static bool show_memo_details(const stellar_transaction_t *decoded_txn) {
425
427
char memo_display [50 ] = {'\0' };
426
428
snprintf (memo_display ,
427
429
sizeof (memo_display ),
428
- ui_text_stellar_memo_unknown ,
430
+ ui_text_memo_unknown ,
429
431
decoded_txn -> memo_type );
430
432
return core_confirmation (memo_display , stellar_send_error );
431
433
}
@@ -436,43 +438,20 @@ static bool get_user_verification(void) {
436
438
const stellar_payment_t * payment = stellar_txn_context -> payment ;
437
439
438
440
char to_address [STELLAR_ADDRESS_LENGTH ] = "" ;
439
- char from_address [STELLAR_ADDRESS_LENGTH ] = "" ;
440
441
441
442
// Generate addresses for display
442
443
if (!stellar_generate_address (payment -> destination , to_address )) {
443
444
stellar_send_error (ERROR_COMMON_ERROR_UNKNOWN_ERROR_TAG , 2 );
444
445
return false;
445
446
}
446
447
447
- if (!stellar_generate_address (decoded_txn -> source_account , from_address )) {
448
- stellar_send_error (ERROR_COMMON_ERROR_UNKNOWN_ERROR_TAG , 2 );
449
- return false;
450
- }
451
-
452
448
// Exchange validation
453
449
if (use_signature_verification ) {
454
450
if (!exchange_validate_stored_signature (to_address , sizeof (to_address ))) {
455
451
return false;
456
452
}
457
453
}
458
454
459
- // Show operation type
460
- char operation_display [50 ] = {'\0' };
461
- snprintf (operation_display ,
462
- sizeof (operation_display ),
463
- ui_text_stellar_operation ,
464
- decoded_txn -> operation_type == STELLAR_OPERATION_CREATE_ACCOUNT
465
- ? "CREATE_ACCOUNT"
466
- : "PAYMENT" );
467
- if (!core_confirmation (operation_display , stellar_send_error )) {
468
- return false;
469
- }
470
-
471
- // Show from address
472
- if (!core_scroll_page ("From:" , from_address , stellar_send_error )) {
473
- return false;
474
- }
475
-
476
455
// Show destination address
477
456
if (!core_scroll_page (
478
457
ui_text_verify_address , to_address , stellar_send_error )) {
@@ -504,16 +483,6 @@ static bool get_user_verification(void) {
504
483
return false;
505
484
}
506
485
507
- // Show sequence number
508
- char seq_display [50 ] = {'\0' };
509
- snprintf (seq_display ,
510
- sizeof (seq_display ),
511
- "Sequence: %llu" ,
512
- decoded_txn -> sequence_number );
513
- if (!core_confirmation (seq_display , stellar_send_error )) {
514
- return false;
515
- }
516
-
517
486
// Handle memo display
518
487
if (!show_memo_details (decoded_txn )) {
519
488
return false;
@@ -524,105 +493,21 @@ static bool get_user_verification(void) {
524
493
}
525
494
526
495
static int create_signature_base (const char * network_passphrase ,
527
- stellar_transaction_t * tx ,
528
- stellar_payment_t * payment ,
496
+ uint8_t * transaction_xdr ,
497
+ size_t signature_data_len ,
529
498
uint8_t * signature_base ,
530
499
int * base_len ) {
531
- int offset = 0 ;
532
-
533
- // 1. Network passphrase hash (32 bytes)
500
+ // 1. Hash network passphrase
534
501
uint8_t network_hash [32 ];
535
502
sha256_Raw ((const uint8_t * )network_passphrase ,
536
503
strlen (network_passphrase ),
537
504
network_hash );
538
- memcpy (signature_base + offset , network_hash , 32 );
539
- offset += 32 ;
540
-
541
- // 2. ENVELOPE_TYPE_TX (4 bytes)
542
- write_uint32_be (signature_base + offset , STELLAR_ENVELOPE_TYPE_TX );
543
- offset += 4 ;
544
-
545
- // 3. Source account type (4 bytes) + public key (32 bytes)
546
- write_uint32_be (signature_base + offset , STELLAR_KEY_TYPE_ED25519 );
547
- offset += 4 ;
548
- memcpy (signature_base + offset , tx -> source_account , STELLAR_PUBKEY_RAW_SIZE );
549
- offset += STELLAR_PUBKEY_RAW_SIZE ;
550
-
551
- // 4. Fee (4 bytes, big-endian)
552
- write_uint32_be (signature_base + offset , tx -> fee );
553
- offset += 4 ;
554
-
555
- // 5. Sequence number (8 bytes, big-endian)
556
- write_uint64_be (signature_base + offset , tx -> sequence_number );
557
- offset += 8 ;
558
-
559
- // 6. Time bounds (17 bytes total)
560
- write_uint32_be (signature_base + offset , 1 ); // has time bounds = true
561
- offset += 4 ;
562
- write_uint64_be (signature_base + offset , 0 ); // min_time = 0
563
- offset += 8 ;
564
- write_uint64_be (signature_base + offset , 0 ); // max_time = 0
565
- offset += 8 ;
566
-
567
- // 7. Memo
568
- write_uint32_be (signature_base + offset , tx -> memo_type );
569
- offset += 4 ;
570
-
571
- if (tx -> memo_type == STELLAR_MEMO_TEXT ) {
572
- int memo_len = strlen (tx -> memo .text );
573
- write_uint32_be (signature_base + offset , memo_len );
574
- offset += 4 ;
575
- memcpy (signature_base + offset , tx -> memo .text , memo_len );
576
- offset += memo_len ;
577
- // Add padding to 4-byte boundary
578
- int padding = (4 - (memo_len % 4 )) % 4 ;
579
- for (int i = 0 ; i < padding ; i ++ ) {
580
- signature_base [offset ++ ] = 0 ;
581
- }
582
- } else if (tx -> memo_type == STELLAR_MEMO_ID ) {
583
- write_uint64_be (signature_base + offset , tx -> memo .id );
584
- offset += 8 ;
585
- } else if (tx -> memo_type == STELLAR_MEMO_HASH ||
586
- tx -> memo_type == STELLAR_MEMO_RETURN ) {
587
- memcpy (signature_base + offset , tx -> memo .hash , 32 );
588
- offset += 32 ;
589
- }
590
-
591
- // 8. Operations count (4 bytes)
592
- write_uint32_be (signature_base + offset , 1 );
593
- offset += 4 ;
594
-
595
- // 9. Operation: has_source_account = false
596
- write_uint32_be (signature_base + offset , 0 );
597
- offset += 4 ;
598
-
599
- // 10. Operation type = PAYMENT OR CREATE_ACCOUNT
600
- write_uint32_be (signature_base + offset , tx -> operation_type );
601
- offset += 4 ;
602
-
603
- // 11. Payment/CreateAccount operation
604
- // Destination (type + pubkey)
605
- write_uint32_be (signature_base + offset , STELLAR_KEY_TYPE_ED25519 );
606
- offset += 4 ;
607
- memcpy (
608
- signature_base + offset , payment -> destination , STELLAR_PUBKEY_RAW_SIZE );
609
- offset += STELLAR_PUBKEY_RAW_SIZE ;
610
-
611
- // Asset (native) - only for PAYMENT operations
612
- if (tx -> operation_type == STELLAR_OPERATION_PAYMENT ) {
613
- write_uint32_be (signature_base + offset , STELLAR_ASSET_TYPE_NATIVE );
614
- offset += 4 ;
615
- }
616
-
617
- // Amount
618
- write_uint64_be (signature_base + offset , payment -> amount );
619
- offset += 8 ;
620
505
621
- // 12. Extension
622
- write_uint32_be (signature_base + offset , 0 );
623
- offset += 4 ;
506
+ // 2. Combine: network_hash + truncated_xdr (only signature-relevant part)
507
+ memcpy (signature_base , network_hash , 32 );
508
+ memcpy ( signature_base + 32 , transaction_xdr , signature_data_len ) ;
624
509
625
- * base_len = offset ;
510
+ * base_len = 32 + signature_data_len ;
626
511
return 0 ;
627
512
}
628
513
@@ -640,8 +525,12 @@ static int stellar_create_signature(stellar_transaction_t *tx,
640
525
? TESTNET_PASSPHRASE
641
526
: MAINNET_PASSPHRASE ;
642
527
643
- int result =
644
- create_signature_base (passphrase , tx , payment , signature_base , & base_len );
528
+ int result = create_signature_base (passphrase ,
529
+ stellar_txn_context -> transaction ,
530
+ stellar_txn_context -> signature_data_len ,
531
+ signature_base ,
532
+ & base_len );
533
+
645
534
if (result != 0 ) {
646
535
return result ;
647
536
}
@@ -658,7 +547,7 @@ static int stellar_create_signature(stellar_transaction_t *tx,
658
547
return 0 ;
659
548
}
660
549
661
- static bool sign_txn (der_sig_t * der_signature ) {
550
+ static bool sign_txn (stellar_sig_t * der_signature ) {
662
551
uint8_t seed [64 ] = {0 };
663
552
uint8_t signature [STELLAR_SIGNATURE_SIZE ] = {0 };
664
553
@@ -715,7 +604,7 @@ static bool sign_txn(der_sig_t *der_signature) {
715
604
}
716
605
717
606
static bool send_signature (stellar_query_t * query ,
718
- const der_sig_t * der_signature ) {
607
+ const stellar_sig_t * der_signature ) {
719
608
stellar_result_t result = init_stellar_result (STELLAR_RESULT_SIGN_TXN_TAG );
720
609
result .sign_txn .which_response = STELLAR_SIGN_TXN_RESPONSE_SIGNATURE_TAG ;
721
610
@@ -724,8 +613,9 @@ static bool send_signature(stellar_query_t *query,
724
613
return false;
725
614
}
726
615
727
- memcpy (
728
- & result .sign_txn .signature .signature , der_signature , sizeof (der_sig_t ));
616
+ memcpy (& result .sign_txn .signature .signature ,
617
+ der_signature ,
618
+ sizeof (stellar_sig_t ));
729
619
730
620
stellar_send_result (& result );
731
621
return true;
@@ -739,7 +629,7 @@ void stellar_sign_transaction(stellar_query_t *query) {
739
629
(stellar_txn_context_t * )malloc (sizeof (stellar_txn_context_t ));
740
630
memzero (stellar_txn_context , sizeof (stellar_txn_context_t ));
741
631
742
- der_sig_t der_signature = {0 };
632
+ stellar_sig_t der_signature = {0 };
743
633
744
634
if (handle_initiate_query (query ) && fetch_valid_input (query ) &&
745
635
get_user_verification () && sign_txn (& der_signature ) &&
0 commit comments