@@ -579,50 +579,77 @@ bool wallet_get_gaservice_fingerprint(const char* network, uint8_t* output, size
579579 return true;
580580}
581581
582- // Fetch the wallet's relevant gait service path based on the user signer's path
583- bool wallet_get_gaservice_path (
584- const uint32_t * path , const size_t path_len , uint32_t * ga_path , const size_t ga_path_len , size_t * written )
582+ static void wallet_get_gaservice_path_root (const bool subaccount_root , uint32_t * ga_path , const size_t ga_path_len )
585583{
586- if (!path || path_len == 0 || !ga_path || ga_path_len != MAX_GASERVICE_PATH_LEN || !written ) {
587- return false;
588- }
584+ JADE_ASSERT (ga_path );
585+ JADE_ASSERT (ga_path_len == GASERVICE_ROOT_PATH_LEN );
589586
590587 const keychain_t * const keychain = keychain_get ();
591588 JADE_ASSERT (keychain );
592589
593- // We only support the following cases
594- if (path_len == 2 ) {
595- // 1. 1/ptr
596- if (path [0 ] != PATH_BRANCH || path [1 ] >= MAX_PATH_PTR ) {
597- return false;
598- }
590+ // The first element is 3 for subaccount paths, or 1 otherwise
591+ ga_path [0 ] = subaccount_root ? 3 : 1 ;
599592
600- // gapath: 1/<ga service path (32)>/ptr
601- ga_path [0 ] = path [0 ];
602- // skip 1-32
603- ga_path [33 ] = path [1 ];
604- * written = 34 ;
593+ // GA service path goes in elements 1 - 32 incl.
594+ JADE_STATIC_ASSERT (sizeof (keychain -> gaservice_path ) == (ga_path_len - 1 ) * sizeof (ga_path [0 ]));
595+ memcpy (& ga_path [1 ], keychain -> gaservice_path , sizeof (keychain -> gaservice_path ));
596+ }
597+
598+ static bool wallet_get_gaservice_path_tail (const uint32_t * path , const size_t path_len , uint32_t * ga_path ,
599+ const size_t ga_path_len , size_t * written , bool * is_subaccount_path )
600+ {
601+ JADE_ASSERT (path );
602+ JADE_ASSERT (path_len );
603+ JADE_ASSERT (ga_path );
604+ JADE_ASSERT (ga_path_len >= MAX_GASERVICE_PATH_TAIL_LEN );
605+ JADE_ASSERT (written );
606+ JADE_ASSERT (is_subaccount_path );
607+
608+ // We only support the following cases - populate the path tail
609+ if (path_len == 2 && path [0 ] == PATH_BRANCH && path [1 ] < MAX_PATH_PTR ) {
610+ // 1. 1/ptr
611+ // service path tail: ptr
612+ ga_path [0 ] = path [1 ];
613+ * written = 1 ;
614+ * is_subaccount_path = false;
615+ return true;
616+ }
605617
606- } else if (path_len == 4 ) {
618+ if (path_len == 4 && path [0 ] == SUBACT_ROOT && path [1 ] > SUBACT_FLOOR && path [1 ] < SUBACT_CEILING
619+ && path [2 ] == PATH_BRANCH && path [3 ] < MAX_PATH_PTR ) {
607620 // 2. 3'/subact'/1/ptr
608- if (path [0 ] != SUBACT_ROOT || path [1 ] <= SUBACT_FLOOR || path [1 ] >= SUBACT_CEILING || path [2 ] != PATH_BRANCH
609- || path [3 ] >= MAX_PATH_PTR ) {
610- return false;
611- }
621+ // service path tail: subact/ptr
622+ ga_path [0 ] = unharden (path [1 ]);
623+ ga_path [1 ] = path [3 ];
624+ * written = 2 ;
625+ * is_subaccount_path = true;
626+ return true;
627+ }
612628
613- // gapath: 3/<ga service path (32)>/subact/ptr
614- ga_path [0 ] = unharden (path [0 ]);
615- // skip 1-32
616- ga_path [33 ] = unharden (path [1 ]);
617- ga_path [34 ] = path [3 ];
618- * written = 35 ;
619- } else {
629+ // Path pattern not recognised
630+ return false;
631+ }
632+
633+ // Fetch the wallet's relevant gait service path based on the user signer's path
634+ bool wallet_get_gaservice_path (
635+ const uint32_t * path , const size_t path_len , uint32_t * ga_path , const size_t ga_path_len , size_t * written )
636+ {
637+ if (!path || path_len == 0 || !ga_path || ga_path_len != MAX_GASERVICE_PATH_LEN || !written ) {
620638 return false;
621639 }
622640
623- // GA service path goes in elements 1 - 32 incl.
624- JADE_STATIC_ASSERT (sizeof (keychain -> gaservice_path ) == (ga_path_len - 1 ) * sizeof (ga_path [0 ]));
625- memcpy (& ga_path [1 ], keychain -> gaservice_path , sizeof (keychain -> gaservice_path ));
641+ // Populate the path tail based on the user path
642+ size_t tail_len = 0 ;
643+ bool is_subaccount_path = false;
644+ if (!wallet_get_gaservice_path_tail (path , path_len , & ga_path [GASERVICE_ROOT_PATH_LEN ],
645+ ga_path_len - GASERVICE_ROOT_PATH_LEN , & tail_len , & is_subaccount_path )) {
646+ // Path pattern not recognised
647+ return false;
648+ }
649+
650+ // Populate GA service path root
651+ wallet_get_gaservice_path_root (is_subaccount_path , ga_path , GASERVICE_ROOT_PATH_LEN );
652+ * written = GASERVICE_ROOT_PATH_LEN + tail_len ;
626653
627654 return true;
628655}
0 commit comments