1
+ #include "pin.h"
2
+
3
+ #include <stdlib.h>
4
+ #include <lib/toolbox/args.h>
5
+ #include "../../../types/token_info.h"
6
+ #include "../../../types/user_pin_codes.h"
7
+ #include "../../../services/config/config.h"
8
+ #include "../../cli_helpers.h"
9
+ #include "../../../lib/polyfills/memset_s.h"
10
+ #include "../../../services/crypto/crypto.h"
11
+ #include "../../../ui/scene_director.h"
12
+
13
+ #define TOTP_CLI_COMMAND_PIN_COMMAND_SET "set"
14
+ #define TOTP_CLI_COMMAND_PIN_COMMAND_REMOVE "remove"
15
+
16
+ void totp_cli_command_pin_docopt_commands () {
17
+ TOTP_CLI_PRINTF (" " TOTP_CLI_COMMAND_PIN " Set\\change\\remove PIN\r\n" );
18
+ }
19
+
20
+ void totp_cli_command_pin_docopt_usage () {
21
+ TOTP_CLI_PRINTF (" " TOTP_CLI_COMMAND_NAME " " TOTP_CLI_COMMAND_PIN " " DOCOPT_REQUIRED (TOTP_CLI_COMMAND_PIN_COMMAND_SET " | " TOTP_CLI_COMMAND_PIN_COMMAND_REMOVE ) "\r\n" );
22
+ }
23
+
24
+ static bool totp_cli_read_pin (Cli * cli , uint8_t * pin , uint8_t * pin_length ) {
25
+ TOTP_CLI_PRINTF ("Enter new PIN (use arrow keys on your keyboard): " );
26
+ fflush (stdout );
27
+ uint8_t c ;
28
+ * pin_length = 0 ;
29
+ while (cli_read (cli , & c , 1 ) == 1 ) {
30
+ if (c == CliSymbolAsciiEsc ) {
31
+ uint8_t c2 ;
32
+ uint8_t c3 ;
33
+ if (cli_read_timeout (cli , & c2 , 1 , 0 ) == 1 &&
34
+ cli_read_timeout (cli , & c3 , 1 , 0 ) == 1 &&
35
+ c2 == 0x5b ) {
36
+ uint8_t code = 0 ;
37
+ switch (c3 ) {
38
+ case 0x44 : // left
39
+ code = PinCodeArrowLeft ;
40
+ break ;
41
+ case 0x41 : // up
42
+ code = PinCodeArrowUp ;
43
+ break ;
44
+ case 0x43 : // right
45
+ code = PinCodeArrowRight ;
46
+ break ;
47
+ case 0x42 : // down
48
+ code = PinCodeArrowDown ;
49
+ break ;
50
+ default :
51
+ break ;
52
+ }
53
+
54
+ if (code > 0 ) {
55
+ pin [* pin_length ] = code ;
56
+ * pin_length = * pin_length + 1 ;
57
+ putc ('*' , stdout );
58
+ fflush (stdout );
59
+ }
60
+ }
61
+ } else if (c == CliSymbolAsciiETX ) {
62
+ TOTP_CLI_DELETE_CURRENT_LINE ();
63
+ TOTP_CLI_PRINTF ("Cancelled by user\r\n" );
64
+ return false;
65
+ } else if (c == CliSymbolAsciiBackspace || c == CliSymbolAsciiDel ) {
66
+ if (* pin_length > 0 ) {
67
+ * pin_length = * pin_length - 1 ;
68
+ pin [* pin_length ] = 0 ;
69
+ TOTP_CLI_DELETE_LAST_CHAR ();
70
+ }
71
+ } else if (c == CliSymbolAsciiCR ) {
72
+ cli_nl ();
73
+ break ;
74
+ }
75
+ }
76
+
77
+ TOTP_CLI_DELETE_LAST_LINE ();
78
+ return true;
79
+ }
80
+
81
+ void totp_cli_command_pin_handle (PluginState * plugin_state , FuriString * args , Cli * cli ) {
82
+ UNUSED (plugin_state );
83
+ FuriString * temp_str = furi_string_alloc ();
84
+
85
+ bool do_change = false;
86
+ bool do_remove = false;
87
+ UNUSED (do_remove );
88
+ do {
89
+ if (!args_read_string_and_trim (args , temp_str )) {
90
+ TOTP_CLI_PRINT_INVALID_ARGUMENTS ();
91
+ break ;
92
+ }
93
+
94
+ if (furi_string_cmpi_str (temp_str , TOTP_CLI_COMMAND_PIN_COMMAND_SET ) == 0 ) {
95
+ do_change = true;
96
+ } else if (furi_string_cmpi_str (temp_str , TOTP_CLI_COMMAND_PIN_COMMAND_REMOVE ) == 0 ) {
97
+ do_remove = true;
98
+ } else {
99
+ TOTP_CLI_PRINT_INVALID_ARGUMENTS ();
100
+ break ;
101
+ }
102
+ } while (false);
103
+
104
+ if ((do_change || do_remove ) && totp_cli_ensure_authenticated (plugin_state , cli )) {
105
+ bool load_generate_token_scene = false;
106
+ do {
107
+ uint8_t old_iv [TOTP_IV_SIZE ];
108
+ memcpy (& old_iv [0 ], & plugin_state -> iv [0 ], TOTP_IV_SIZE );
109
+ uint8_t new_pin [TOTP_IV_SIZE ];
110
+ uint8_t new_pin_length = 0 ;
111
+ if (do_change ) {
112
+ if (!totp_cli_read_pin (cli , & new_pin [0 ], & new_pin_length ) ||
113
+ !totp_cli_ensure_authenticated (plugin_state , cli )) {
114
+ memset_s (& new_pin [0 ], TOTP_IV_SIZE , 0 , TOTP_IV_SIZE );
115
+ break ;
116
+ }
117
+ } else if (do_remove ) {
118
+ new_pin_length = 0 ;
119
+ memset (& new_pin [0 ], 0 , TOTP_IV_SIZE );
120
+ }
121
+
122
+ if (plugin_state -> current_scene == TotpSceneGenerateToken ) {
123
+ totp_scene_director_activate_scene (plugin_state , TotpSceneNone , NULL );
124
+ load_generate_token_scene = true;
125
+ }
126
+
127
+ TOTP_CLI_PRINTF ("Encrypting, please wait...\r\n" );
128
+
129
+ memset (& plugin_state -> iv [0 ], 0 , TOTP_IV_SIZE );
130
+ memset (& plugin_state -> base_iv [0 ], 0 , TOTP_IV_SIZE );
131
+ if (plugin_state -> crypto_verify_data != NULL ) {
132
+ free (plugin_state -> crypto_verify_data );
133
+ plugin_state -> crypto_verify_data = NULL ;
134
+ }
135
+
136
+ totp_crypto_seed_iv (plugin_state , new_pin_length > 0 ? & new_pin [0 ] : NULL , new_pin_length );
137
+ ListNode * node = plugin_state -> tokens_list ;
138
+ while (node != NULL ) {
139
+ TokenInfo * token_info = node -> data ;
140
+ size_t plain_token_length ;
141
+ uint8_t * plain_token = totp_crypto_decrypt (token_info -> token , token_info -> token_length , & old_iv [0 ], & plain_token_length );
142
+ free (token_info -> token );
143
+ token_info -> token = totp_crypto_encrypt (plain_token , plain_token_length , & plugin_state -> iv [0 ], & token_info -> token_length );
144
+ memset_s (plain_token , plain_token_length , 0 , plain_token_length );
145
+ free (plain_token );
146
+ node = node -> next ;
147
+ }
148
+
149
+ totp_full_save_config_file (plugin_state );
150
+
151
+ TOTP_CLI_DELETE_LAST_LINE ();
152
+
153
+ if (do_change ) {
154
+ TOTP_CLI_PRINTF ("PIN has been successfully changed\r\n" );
155
+ } else if (do_remove ) {
156
+ TOTP_CLI_PRINTF ("PIN has been successfully removed\r\n" );
157
+ }
158
+ } while (false);
159
+
160
+ if (load_generate_token_scene ) {
161
+ totp_scene_director_activate_scene (plugin_state , TotpSceneGenerateToken , NULL );
162
+ }
163
+ }
164
+
165
+ furi_string_free (temp_str );
166
+ }
0 commit comments