Struan Clark пре 2 година
родитељ
комит
d9407ea6d3
5 измењених фајлова са 111 додато и 43 уклоњено
  1. 1 1
      flipbip.h
  2. 50 23
      helpers/flipbip_file.c
  3. 13 3
      helpers/flipbip_file.h
  4. 1 1
      scenes/flipbip_scene_menu.c
  5. 46 15
      views/flipbip_scene_1.c

+ 1 - 1
flipbip.h

@@ -96,4 +96,4 @@ typedef enum {
     FlipBipStatusLoadError = 11,
     FlipBipStatusSaveError = 12,
     FlipBipStatusMnemonicCheckError = 13,
-} FlipBipStatus;
+} FlipBipStatus;

+ 50 - 23
helpers/flipbip_file.c

@@ -5,17 +5,19 @@
 #include <memzero.h>
 #include <rand.h>
 
+// #define FLIPBIP_APP_BASE_FOLDER APP_DATA_PATH("flipbip")
 #define FLIPBIP_APP_BASE_FOLDER EXT_PATH("apps_data/flipbip")
+#define FLIPBIP_APP_BASE_FOLDER_PATH(path) FLIPBIP_APP_BASE_FOLDER "/" path
 #define FLIPBIP_DAT_FILE_NAME ".flipbip.dat"
 // #define FLIPBIP_DAT_FILE_NAME ".flipbip.dat.txt"
 #define FLIPBIP_DAT_FILE_NAME_BAK ".flipbip.dat.bak"
 #define FLIPBIP_KEY_FILE_NAME ".flipbip.key"
 // #define FLIPBIP_KEY_FILE_NAME ".flipbip.key.txt"
 #define FLIPBIP_KEY_FILE_NAME_BAK ".flipbip.key.bak"
-#define FLIPBIP_DAT_PATH FLIPBIP_APP_BASE_FOLDER "/" FLIPBIP_DAT_FILE_NAME
-#define FLIPBIP_DAT_PATH_BAK FLIPBIP_APP_BASE_FOLDER "/" FLIPBIP_DAT_FILE_NAME_BAK
-#define FLIPBIP_KEY_PATH FLIPBIP_APP_BASE_FOLDER "/" FLIPBIP_KEY_FILE_NAME
-#define FLIPBIP_KEY_PATH_BAK FLIPBIP_APP_BASE_FOLDER "/" FLIPBIP_KEY_FILE_NAME_BAK
+#define FLIPBIP_DAT_PATH FLIPBIP_APP_BASE_FOLDER_PATH(FLIPBIP_DAT_FILE_NAME)
+#define FLIPBIP_DAT_PATH_BAK FLIPBIP_APP_BASE_FOLDER_PATH(FLIPBIP_DAT_FILE_NAME_BAK)
+#define FLIPBIP_KEY_PATH FLIPBIP_APP_BASE_FOLDER_PATH(FLIPBIP_KEY_FILE_NAME)
+#define FLIPBIP_KEY_PATH_BAK FLIPBIP_APP_BASE_FOLDER_PATH(FLIPBIP_KEY_FILE_NAME_BAK)
 
 const size_t FILE_HLEN = 4;
 const size_t FILE_KLEN = 256;
@@ -24,13 +26,19 @@ const char* FILE_HSTR = "fb01";
 const char* FILE_K1 = "fb0131d5cf688221c109163908ebe51debb46227c6cc8b37641910833222772a"
                       "baefe6d9ceb651842260e0d1e05e3b90d15e7d5ffaaabc0207bf200a117793a2";
 
-bool flipbip_load_settings(char* settings, bool key_file) {
+bool flipbip_load_settings(char* settings, const FlipBipFile file_type, const char* file_name) {
     bool ret = false;
     const char* path;
-    if(key_file) {
+    if(file_type == FlipBipFileKey) {
         path = FLIPBIP_KEY_PATH;
-    } else {
+    } else if(file_type == FlipBipFileDat) {
         path = FLIPBIP_DAT_PATH;
+    } else {
+        char path_buf[32] = {0};
+        strcpy(path_buf, FLIPBIP_APP_BASE_FOLDER);
+        strcpy(path_buf + strlen(path_buf), "/");
+        strcpy(path_buf + strlen(path_buf), file_name);
+        path = path_buf;
     }
 
     Storage* fs_api = furi_record_open(RECORD_STORAGE);
@@ -73,13 +81,19 @@ bool flipbip_load_settings(char* settings, bool key_file) {
     return ret;
 }
 
-bool flipbip_has_settings(bool key_file) {
+bool flipbip_has_settings(const FlipBipFile file_type, const char* file_name) {
     bool ret = false;
     const char* path;
-    if(key_file) {
+    if(file_type == FlipBipFileKey) {
         path = FLIPBIP_KEY_PATH;
-    } else {
+    } else if(file_type == FlipBipFileDat) {
         path = FLIPBIP_DAT_PATH;
+    } else {
+        char path_buf[32] = {0};
+        strcpy(path_buf, FLIPBIP_APP_BASE_FOLDER);
+        strcpy(path_buf + strlen(path_buf), "/");
+        strcpy(path_buf + strlen(path_buf), file_name);
+        path = path_buf;
     }
 
     Storage* fs_api = furi_record_open(RECORD_STORAGE);
@@ -91,16 +105,27 @@ bool flipbip_has_settings(bool key_file) {
     return ret;
 }
 
-bool flipbip_save_settings(const char* settings, bool key_file, bool append) {
+bool flipbip_save_settings(
+    const char* settings,
+    const FlipBipFile file_type,
+    const char* file_name,
+    const bool append) {
     bool ret = false;
     const char* path;
     const char* path_bak;
-    if(key_file) {
+    if(file_type == FlipBipFileKey) {
         path = FLIPBIP_KEY_PATH;
         path_bak = FLIPBIP_KEY_PATH_BAK;
-    } else {
+    } else if(file_type == FlipBipFileDat) {
         path = FLIPBIP_DAT_PATH;
         path_bak = FLIPBIP_DAT_PATH_BAK;
+    } else {
+        char path_buf[32] = {0};
+        strcpy(path_buf, FLIPBIP_APP_BASE_FOLDER);
+        strcpy(path_buf + strlen(path_buf), "/");
+        strcpy(path_buf + strlen(path_buf), file_name);
+        path = path_buf;
+        path_bak = NULL;
     }
     int open_mode = FSOM_OPEN_ALWAYS;
     if(append) {
@@ -126,13 +151,15 @@ bool flipbip_save_settings(const char* settings, bool key_file, bool append) {
     storage_file_close(settings_file);
     storage_file_free(settings_file);
 
-    File* settings_file_bak = storage_file_alloc(fs_api);
-    if(storage_file_open(settings_file_bak, path_bak, FSAM_WRITE, open_mode)) {
-        storage_file_write(settings_file_bak, settings, strlen(settings));
-        storage_file_write(settings_file_bak, "\n", 1);
+    if(path_bak != NULL) {
+        File* settings_file_bak = storage_file_alloc(fs_api);
+        if(storage_file_open(settings_file_bak, path_bak, FSAM_WRITE, open_mode)) {
+            storage_file_write(settings_file_bak, settings, strlen(settings));
+            storage_file_write(settings_file_bak, "\n", 1);
+        }
+        storage_file_close(settings_file_bak);
+        storage_file_free(settings_file_bak);
     }
-    storage_file_close(settings_file_bak);
-    storage_file_free(settings_file_bak);
 
     furi_record_close(RECORD_STORAGE);
 
@@ -147,7 +174,7 @@ bool flipbip_load_settings_secure(char* settings) {
     memzero(data, dlen);
 
     // load k2 from file
-    if(!flipbip_load_settings(data, true)) return false;
+    if(!flipbip_load_settings(data, FlipBipFileKey, NULL)) return false;
 
     // check header
     if(data[0] != FILE_HSTR[0] || data[1] != FILE_HSTR[1] || data[2] != FILE_HSTR[2] ||
@@ -173,7 +200,7 @@ bool flipbip_load_settings_secure(char* settings) {
     data -= FILE_HLEN;
 
     // load data from file
-    if(!flipbip_load_settings(data, false)) return false;
+    if(!flipbip_load_settings(data, FlipBipFileDat, NULL)) return false;
 
     // check header
     if(data[0] != FILE_HSTR[0] || data[1] != FILE_HSTR[1] || data[2] != FILE_HSTR[2] ||
@@ -237,7 +264,7 @@ bool flipbip_save_settings_secure(const char* settings) {
     // seek <-- header
     data -= FILE_HLEN;
     // save k2 to file
-    flipbip_save_settings(data, true, false);
+    flipbip_save_settings(data, FlipBipFileKey, NULL, false);
     // seek --> header
     data += FILE_HLEN;
     // zero k2 memory
@@ -250,7 +277,7 @@ bool flipbip_save_settings_secure(const char* settings) {
     // seek <-- header
     data -= FILE_HLEN;
     // save data to file
-    flipbip_save_settings(data, false, false);
+    flipbip_save_settings(data, FlipBipFileDat, NULL, false);
 
     // clear memory
     memzero(data, dlen);

+ 13 - 3
helpers/flipbip_file.h

@@ -1,8 +1,18 @@
 #include <stdbool.h>
 
-bool flipbip_has_settings(bool key_file);
-bool flipbip_load_settings(char* settings, bool key_file);
-bool flipbip_save_settings(const char* settings, bool key_file, bool append);
+typedef enum {
+    FlipBipFileDat,
+    FlipBipFileKey,
+    FlipBipFileOther,
+} FlipBipFile;
+
+bool flipbip_has_settings(const FlipBipFile file_type, const char* file_name);
+bool flipbip_load_settings(char* settings, const FlipBipFile file_type, const char* file_name);
+bool flipbip_save_settings(
+    const char* settings,
+    const FlipBipFile file_type,
+    const char* file_name,
+    const bool append);
 
 bool flipbip_load_settings_secure(char* settings);
 bool flipbip_save_settings_secure(const char* settings);

+ 1 - 1
scenes/flipbip_scene_menu.c

@@ -18,7 +18,7 @@ void flipbip_scene_menu_submenu_callback(void* context, uint32_t index) {
 void flipbip_scene_menu_on_enter(void* context) {
     FlipBip* app = context;
 
-    if(flipbip_has_settings(true) && flipbip_has_settings(false)) {
+    if(flipbip_has_settings(FlipBipFileKey, NULL) && flipbip_has_settings(FlipBipFileDat, NULL)) {
         submenu_add_item(
             app->submenu,
             "View BTC wallet",

+ 46 - 15
views/flipbip_scene_1.c

@@ -34,19 +34,28 @@
 #define PAGE_ADDR_BEGIN 9
 #define PAGE_ADDR_END 14 //18
 
+#define MAX_ADDR_LEN 42 + 1 // 42 = max length of address + null terminator
+
 #define TEXT_LOADING "Loading..."
 #define TEXT_NEW_WALLET "New wallet"
 #define TEXT_DEFAULT_COIN "Coin"
 #define TEXT_RECEIVE_ADDRESS "receive address:"
 #define TEXT_DEFAULT_DERIV "m/44'/X'/0'/0"
-
-const char* TEXT_INFO = "-Scroll pages with up/down-"
+const char *TEXT_INFO = "-Scroll pages with up/down-"
                         "p1,2)    Mnemonic/Seed     "
                         "p3)       xprv Root Key    "
                         "p4,5)  xprv/xpub Accnt Keys"
                         "p6,7)  xprv/xpub Extnd Keys"
                         "p8+)    Receive Addresses  ";
 
+#define TEXT_SAVE_QR "Save QR"
+#define TEXT_QRFILE_EXT "address.qrcode"
+const char *TEXT_QRFILE = "Filetype: QRCode\n"
+                          "Version: 0\n"
+                          "Message: ";
+
+
+
 // bip44_coin, xprv_version, xpub_version, addr_version, wif_version, addr_format
 const uint32_t COIN_INFO_ARRAY[3][6] = {
     {COIN_BTC, 0x0488ade4, 0x0488b21e, 0x00, 0x80, FlipBipCoinBTC0},
@@ -54,10 +63,10 @@ const uint32_t COIN_INFO_ARRAY[3][6] = {
     {COIN_DOGE, 0x02fac398, 0x02facafd, 0x1e, 0x9e, FlipBipCoinBTC0}};
 
 // coin_name, derivation_path
-const char* COIN_TEXT_ARRAY[3][2] = {
-    {"BTC", "m/44'/0'/0'/0"},
-    {"ETH", "m/44'/60'/0'/0"},
-    {"DOGE", "m/44'/3'/0'/0"}};
+const char* COIN_TEXT_ARRAY[3][3] = {
+    {"BTC", "m/44'/0'/0'/0", "bitcoin:"},
+    {"ETH", "m/44'/60'/0'/0", "ethereum:"},
+    {"DOGE", "m/44'/3'/0'/0", "dogecoin:"}};
 
 struct FlipBipScene1 {
     View* view;
@@ -82,6 +91,7 @@ typedef struct {
 
 // Node for the receive address
 static CONFIDENTIAL HDNode* s_addr_node = NULL;
+static char* s_addr_text = NULL;
 // Generic display text
 static CONFIDENTIAL char* s_disp_text1 = NULL;
 static CONFIDENTIAL char* s_disp_text2 = NULL;
@@ -203,6 +213,7 @@ static void
 
     // Use static node for address generation
     memcpy(s_addr_node, node, sizeof(HDNode));
+    memzero(s_addr_text, MAX_ADDR_LEN);
 
     hdnode_private_ckd(s_addr_node, addr_index);
     hdnode_fill_public_key(s_addr_node);
@@ -219,19 +230,20 @@ static void
         ecdsa_get_address(
             s_addr_node->public_key, coin_info[3], HASHER_SHA2_RIPEMD, HASHER_SHA2D, buf, buflen);
 
-        flipbip_scene_1_draw_generic(buf, 12);
+        strcpy(s_addr_text, buf);
+        flipbip_scene_1_draw_generic(s_addr_text, 12);
 
         //ecdsa_get_wif(addr_node->private_key, WIF_VERSION, HASHER_SHA2D, buf, buflen);
 
     } else if(coin_info[5] == FlipBipCoinETH60) { // ETH
         // ETH style address
         hdnode_get_ethereum_pubkeyhash(s_addr_node, (uint8_t*)buf);
-        char address[42 + 1] = {0};
-        address[0] = '0';
-        address[1] = 'x';
+        s_addr_text[0] = '0';
+        s_addr_text[1] = 'x';
         // Convert the hash to a hex string
-        flipbip_btox((uint8_t*)buf, 20, address + 2);
-        flipbip_scene_1_draw_generic(address, 12);
+        flipbip_btox((uint8_t*)buf, 20, s_addr_text + 2);
+        
+        flipbip_scene_1_draw_generic(s_addr_text, 12);
     }
 
     // Clear the address node
@@ -273,6 +285,7 @@ void flipbip_scene_1_draw(Canvas* canvas, FlipBipScene1Model* model) {
         flipbip_scene_1_draw_generic(model->xpub_extended, 20);
     } else if(model->page >= PAGE_ADDR_BEGIN && model->page <= PAGE_ADDR_END) {
         flipbip_scene_1_draw_address(model->node, model->coin, model->page - PAGE_ADDR_BEGIN);
+        elements_button_right(canvas, TEXT_SAVE_QR);
     }
 
     if(model->page == PAGE_LOADING) {
@@ -333,7 +346,8 @@ static int flipbip_scene_1_model_init(
     memzero(mnemonic, TEXT_BUFFER_SIZE);
 
     // Check if the mnemonic key & data is already saved in persistent storage, or overwrite is true
-    if(overwrite || (!flipbip_has_settings(true) && !flipbip_has_settings(false))) {
+    if(overwrite || (!flipbip_has_settings(FlipBipFileKey, NULL) &&
+                     !flipbip_has_settings(FlipBipFileDat, NULL))) {
         // Set mnemonic only mode
         model->mnemonic_only = true;
         // Generate a random mnemonic using trezor-crypto
@@ -468,9 +482,7 @@ bool flipbip_scene_1_input(InputEvent* event, void* context) {
                 },
                 true);
             break;
-        case InputKeyRight:
         case InputKeyDown:
-        case InputKeyOk:
             with_view_model(
                 instance->view,
                 FlipBipScene1Model * model,
@@ -499,6 +511,22 @@ bool flipbip_scene_1_input(InputEvent* event, void* context) {
                 },
                 true);
             break;
+        case InputKeyRight:
+        case InputKeyOk:
+            with_view_model(
+                instance->view,
+                FlipBipScene1Model * model,
+                {
+                    if (model->page >= PAGE_ADDR_BEGIN && model->page <= PAGE_ADDR_END) {
+                        char qrbuf[90] = {0};
+                        strcpy(qrbuf, TEXT_QRFILE);
+                        strcpy(qrbuf + strlen(qrbuf), COIN_TEXT_ARRAY[model->coin][2]);
+                        strcpy(qrbuf + strlen(qrbuf), s_addr_text);
+                        flipbip_save_settings(qrbuf, FlipBipFileOther, TEXT_QRFILE_EXT, false);
+                    }
+                },
+                true);
+            break;
         case InputKeyMAX:
             break;
         }
@@ -628,6 +656,7 @@ FlipBipScene1* flipbip_scene_1_alloc() {
 
     // allocate the address node
     s_addr_node = (HDNode*)malloc(sizeof(HDNode));
+    s_addr_text = (char*)malloc(MAX_ADDR_LEN);
 
     // allocate the display text
     s_disp_text1 = (char*)malloc(30 + 1);
@@ -649,6 +678,8 @@ void flipbip_scene_1_free(FlipBipScene1* instance) {
     // free the address node
     memzero(s_addr_node, sizeof(HDNode));
     free(s_addr_node);
+    memzero(s_addr_text, MAX_ADDR_LEN);
+    free(s_addr_text);
 
     // free the display text
     flipbip_scene_1_clear_text();