Skip to content

Commit 10c996f

Browse files
committed
chore: Address feedbacks remove re-parsing of xdr
1 parent 6207e64 commit 10c996f

File tree

8 files changed

+112
-222
lines changed

8 files changed

+112
-222
lines changed

apps/stellar_app/stellar_priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ typedef struct {
3434
// decoded transaction structures
3535
stellar_transaction_t *txn;
3636
stellar_payment_t *payment;
37+
size_t signature_data_len;
3738
} stellar_txn_context_t;
3839

3940
/*****************************************************************************

apps/stellar_app/stellar_txn.c

Lines changed: 36 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
/*****************************************************************************
9696
* PRIVATE TYPEDEFS
9797
*****************************************************************************/
98-
typedef stellar_sign_txn_signature_response_signature_t der_sig_t;
98+
typedef stellar_sign_txn_signature_response_signature_t stellar_sig_t;
9999

100100
/*****************************************************************************
101101
* STATIC FUNCTION PROTOTYPES
@@ -191,26 +191,25 @@ static bool get_user_verification(void);
191191
* @return false If signature could not be computed - maybe due to some error
192192
* during seed reconstruction phase
193193
*/
194-
static bool sign_txn(der_sig_t *der_signature);
194+
static bool sign_txn(stellar_sig_t *der_signature);
195195

196196
/**
197197
* @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
200199
*
201200
* @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
204203
* @param signature_base Output buffer for signature base data
205204
* @param base_len Output length of signature base data
206205
* @return int 0 on success, non-zero on error
207206
*/
207+
208208
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,
211211
uint8_t *signature_base,
212212
int *base_len);
213-
214213
/**
215214
* @brief Creates ED25519 signature for Stellar transaction
216215
* @details Signs the transaction hash using ED25519 algorithm
@@ -244,7 +243,7 @@ static int stellar_create_signature(stellar_transaction_t *tx,
244243
* or invalid request received from the host
245244
*/
246245
static bool send_signature(stellar_query_t *query,
247-
const der_sig_t *der_signature);
246+
const stellar_sig_t *der_signature);
248247

249248
/*****************************************************************************
250249
* STATIC VARIABLES
@@ -381,14 +380,17 @@ static bool fetch_valid_input(stellar_query_t *query) {
381380
stellar_txn_context->payment =
382381
(stellar_payment_t *)malloc(sizeof(stellar_payment_t));
383382

383+
int signature_data_len = 0;
384384
if (stellar_parse_transaction(stellar_txn_context->transaction,
385385
total_size,
386386
stellar_txn_context->txn,
387-
stellar_txn_context->payment) != 0) {
387+
stellar_txn_context->payment,
388+
&signature_data_len) != 0) {
388389
stellar_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG,
389390
ERROR_DATA_FLOW_INVALID_DATA);
390391
return false;
391392
}
393+
stellar_txn_context->signature_data_len = signature_data_len;
392394

393395
return true;
394396
}
@@ -398,14 +400,14 @@ static bool show_memo_details(const stellar_transaction_t *decoded_txn) {
398400
char memo_display[100] = {'\0'};
399401
snprintf(memo_display,
400402
sizeof(memo_display),
401-
ui_text_stellar_memo_text,
403+
ui_text_memo_text,
402404
decoded_txn->memo.text);
403405
return core_confirmation(memo_display, stellar_send_error);
404406
} else if (decoded_txn->memo_type == STELLAR_MEMO_ID) {
405407
char memo_display[50] = {'\0'};
406408
snprintf(memo_display,
407409
sizeof(memo_display),
408-
ui_text_stellar_memo_id,
410+
ui_text_memo_id,
409411
decoded_txn->memo.id);
410412
return core_confirmation(memo_display, stellar_send_error);
411413
} else if (decoded_txn->memo_type == STELLAR_MEMO_NONE) {
@@ -415,7 +417,7 @@ static bool show_memo_details(const stellar_transaction_t *decoded_txn) {
415417
decoded_txn->memo_type == STELLAR_MEMO_RETURN) {
416418
char memo_hash[80] = {'\0'};
417419
char temp[3];
418-
strcpy(memo_hash, "Memo Hash: ");
420+
strcpy(memo_hash, ui_text_memo_hash_prefix);
419421
for (int i = 0; i < 32; i++) {
420422
snprintf(temp, sizeof(temp), "%02x", decoded_txn->memo.hash[i]);
421423
strcat(memo_hash, temp);
@@ -425,7 +427,7 @@ static bool show_memo_details(const stellar_transaction_t *decoded_txn) {
425427
char memo_display[50] = {'\0'};
426428
snprintf(memo_display,
427429
sizeof(memo_display),
428-
ui_text_stellar_memo_unknown,
430+
ui_text_memo_unknown,
429431
decoded_txn->memo_type);
430432
return core_confirmation(memo_display, stellar_send_error);
431433
}
@@ -436,43 +438,20 @@ static bool get_user_verification(void) {
436438
const stellar_payment_t *payment = stellar_txn_context->payment;
437439

438440
char to_address[STELLAR_ADDRESS_LENGTH] = "";
439-
char from_address[STELLAR_ADDRESS_LENGTH] = "";
440441

441442
// Generate addresses for display
442443
if (!stellar_generate_address(payment->destination, to_address)) {
443444
stellar_send_error(ERROR_COMMON_ERROR_UNKNOWN_ERROR_TAG, 2);
444445
return false;
445446
}
446447

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-
452448
// Exchange validation
453449
if (use_signature_verification) {
454450
if (!exchange_validate_stored_signature(to_address, sizeof(to_address))) {
455451
return false;
456452
}
457453
}
458454

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-
476455
// Show destination address
477456
if (!core_scroll_page(
478457
ui_text_verify_address, to_address, stellar_send_error)) {
@@ -504,16 +483,6 @@ static bool get_user_verification(void) {
504483
return false;
505484
}
506485

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-
517486
// Handle memo display
518487
if (!show_memo_details(decoded_txn)) {
519488
return false;
@@ -524,105 +493,21 @@ static bool get_user_verification(void) {
524493
}
525494

526495
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,
529498
uint8_t *signature_base,
530499
int *base_len) {
531-
int offset = 0;
532-
533-
// 1. Network passphrase hash (32 bytes)
500+
// 1. Hash network passphrase
534501
uint8_t network_hash[32];
535502
sha256_Raw((const uint8_t *)network_passphrase,
536503
strlen(network_passphrase),
537504
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;
620505

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);
624509

625-
*base_len = offset;
510+
*base_len = 32 + signature_data_len;
626511
return 0;
627512
}
628513

@@ -640,8 +525,12 @@ static int stellar_create_signature(stellar_transaction_t *tx,
640525
? TESTNET_PASSPHRASE
641526
: MAINNET_PASSPHRASE;
642527

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+
645534
if (result != 0) {
646535
return result;
647536
}
@@ -658,7 +547,7 @@ static int stellar_create_signature(stellar_transaction_t *tx,
658547
return 0;
659548
}
660549

661-
static bool sign_txn(der_sig_t *der_signature) {
550+
static bool sign_txn(stellar_sig_t *der_signature) {
662551
uint8_t seed[64] = {0};
663552
uint8_t signature[STELLAR_SIGNATURE_SIZE] = {0};
664553

@@ -715,7 +604,7 @@ static bool sign_txn(der_sig_t *der_signature) {
715604
}
716605

717606
static bool send_signature(stellar_query_t *query,
718-
const der_sig_t *der_signature) {
607+
const stellar_sig_t *der_signature) {
719608
stellar_result_t result = init_stellar_result(STELLAR_RESULT_SIGN_TXN_TAG);
720609
result.sign_txn.which_response = STELLAR_SIGN_TXN_RESPONSE_SIGNATURE_TAG;
721610

@@ -724,8 +613,9 @@ static bool send_signature(stellar_query_t *query,
724613
return false;
725614
}
726615

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));
729619

730620
stellar_send_result(&result);
731621
return true;
@@ -739,7 +629,7 @@ void stellar_sign_transaction(stellar_query_t *query) {
739629
(stellar_txn_context_t *)malloc(sizeof(stellar_txn_context_t));
740630
memzero(stellar_txn_context, sizeof(stellar_txn_context_t));
741631

742-
der_sig_t der_signature = {0};
632+
stellar_sig_t der_signature = {0};
743633

744634
if (handle_initiate_query(query) && fetch_valid_input(query) &&
745635
get_user_verification() && sign_txn(&der_signature) &&

0 commit comments

Comments
 (0)