@@ -33,23 +33,35 @@ typedef struct {
33
33
size_t max_length ;
34
34
} ERC4361Field ;
35
35
36
- static size_t parse_field (const uint8_t * buffer ,
37
- size_t buffer_len ,
38
- char * output ,
39
- size_t max_length ) {
36
+ static int parse_field (const uint8_t * buffer , size_t buffer_len , char * output , size_t max_length ) {
37
+ // Add NULL check
38
+ if (buffer == NULL || output == NULL ) {
39
+ return -1 ;
40
+ }
41
+
42
+ // Check buffer_len to prevent buffer overflow
43
+ if (buffer_len == 0 || max_length == 0 ) {
44
+ return -1 ;
45
+ }
46
+
40
47
size_t field_length = 0 ;
41
- while (field_length < buffer_len && field_length < max_length - 1 ) {
48
+ // Ensure we don't exceed buffer_len or max_length-1 (for null terminator)
49
+ const size_t max_field_length = (buffer_len < max_length - 1 ) ? buffer_len : max_length - 1 ;
50
+
51
+ while (field_length < max_field_length ) {
52
+ // Safe to dereference buffer here as we've checked both pointer and bounds
42
53
if (buffer [field_length ] == '\n' || buffer [field_length ] == '\0' ||
43
54
buffer [field_length ] == ' ' ) {
44
55
break ;
45
56
}
46
57
field_length ++ ;
47
58
}
48
59
60
+ // Safe to use memcpy as we've validated both source and destination
49
61
memcpy (output , buffer , field_length );
50
62
output [field_length ] = '\0' ;
51
63
52
- return field_length ;
64
+ return ( int ) field_length ; // Safe cast as field_length is bounded by max_field_length
53
65
}
54
66
55
67
static bool has_newline (const char * buffer , size_t length ) {
@@ -62,6 +74,12 @@ static bool has_newline(const char *buffer, size_t length) {
62
74
}
63
75
64
76
void handler_sign_erc4361_message (dispatcher_context_t * dc , uint8_t protocol_version ) {
77
+ // Add NULL check with status word
78
+ if (dc == NULL ) {
79
+ SAFE_SEND_SW (dc , SW_BAD_STATE );
80
+ return ;
81
+ }
82
+
65
83
(void ) protocol_version ;
66
84
67
85
uint8_t bip32_path_len ;
@@ -172,15 +190,23 @@ void handler_sign_erc4361_message(dispatcher_context_t *dc, uint8_t protocol_ver
172
190
}
173
191
174
192
if (current_line == 0 ) {
175
- size_t domain_length =
193
+ int domain_length =
176
194
parse_field (parsing_buffer , parsing_buffer_len , domain , MAX_DOMAIN_LENGTH );
195
+ if (domain_length < 0 ) {
196
+ SAFE_SEND_SW (dc , SW_BAD_STATE );
197
+ return ;
198
+ }
177
199
total_bytes_read += domain_length ;
178
200
PRINTF ("Domain: %s\n" , domain );
179
201
}
180
202
181
203
if (current_line == 1 ) {
182
- size_t address_length =
204
+ int address_length =
183
205
parse_field (parsing_buffer , parsing_buffer_len , address , MAX_ADDRESS_LENGTH_STR );
206
+ if (address_length < 0 ) {
207
+ SAFE_SEND_SW (dc , SW_BAD_STATE );
208
+ return ;
209
+ }
184
210
total_bytes_read += address_length ;
185
211
PRINTF ("Address: %s\n" , address );
186
212
}
@@ -191,10 +217,14 @@ void handler_sign_erc4361_message(dispatcher_context_t *dc, uint8_t protocol_ver
191
217
ERC4361Field * field = & fields [i ];
192
218
if (parsing_buffer_len >= field -> name_length &&
193
219
memcmp (parsing_buffer , field -> name , field -> name_length ) == 0 ) {
194
- size_t field_length = parse_field (parsing_buffer + field -> name_length ,
195
- parsing_buffer_len - field -> name_length ,
196
- field -> output ,
197
- field -> max_length );
220
+ int field_length = parse_field (parsing_buffer + field -> name_length ,
221
+ parsing_buffer_len - field -> name_length ,
222
+ field -> output ,
223
+ field -> max_length );
224
+ if (field_length < 0 ) {
225
+ SAFE_SEND_SW (dc , SW_BAD_STATE );
226
+ return ;
227
+ }
198
228
total_bytes_read += field_length + field -> name_length ;
199
229
PRINTF ("%s%s\n" , field -> name , field -> output );
200
230
break ;
@@ -247,9 +277,7 @@ void handler_sign_erc4361_message(dispatcher_context_t *dc, uint8_t protocol_ver
247
277
issued_at ,
248
278
expiration_time )) {
249
279
SAFE_SEND_SW (dc , SW_DENY );
250
- if (!ui_post_processing_confirm_message (dc , false)) {
251
- PRINTF ("Error in ui_post_processing_confirm_message" );
252
- }
280
+ ui_post_processing_confirm_message (dc , false);
253
281
return ;
254
282
}
255
283
#endif
@@ -265,9 +293,7 @@ void handler_sign_erc4361_message(dispatcher_context_t *dc, uint8_t protocol_ver
265
293
if (sig_len < 0 ) {
266
294
// unexpected error when signing
267
295
SAFE_SEND_SW (dc , SW_BAD_STATE );
268
- if (!ui_post_processing_confirm_message (dc , false)) {
269
- PRINTF ("Error in ui_post_processing_confirm_message" );
270
- }
296
+ ui_post_processing_confirm_message (dc , false);
271
297
return ;
272
298
}
273
299
@@ -277,15 +303,19 @@ void handler_sign_erc4361_message(dispatcher_context_t *dc, uint8_t protocol_ver
277
303
uint8_t result [65 ];
278
304
memset (result , 0 , sizeof (result ));
279
305
306
+ // Verify r_length won't cause buffer overflow
307
+ if (sig [3 ] > MAX_DER_SIG_LEN - 5 ) { // -5 accounts for DER header and s_length byte
308
+ SAFE_SEND_SW (dc , SW_BAD_STATE );
309
+ ui_post_processing_confirm_message (dc , false);
310
+ return ;
311
+ }
280
312
// # Format signature into standard bitcoin format
281
313
int r_length = sig [3 ];
282
314
int s_length = sig [4 + r_length + 1 ];
283
315
284
316
if (r_length > 33 || s_length > 33 ) {
285
317
SAFE_SEND_SW (dc , SW_BAD_STATE ); // can never happen
286
- if (!ui_post_processing_confirm_message (dc , false)) {
287
- PRINTF ("Error in ui_post_processing_confirm_message" );
288
- }
318
+ ui_post_processing_confirm_message (dc , false);
289
319
return ;
290
320
}
291
321
@@ -301,9 +331,7 @@ void handler_sign_erc4361_message(dispatcher_context_t *dc, uint8_t protocol_ver
301
331
result [0 ] = 27 + 4 + ((info & CX_ECCINFO_PARITY_ODD ) ? 1 : 0 );
302
332
303
333
SEND_RESPONSE (dc , result , sizeof (result ), SW_OK );
304
- if (!ui_post_processing_confirm_message (dc , true)) {
305
- PRINTF ("Error in ui_post_processing_confirm_message" );
306
- }
334
+ ui_post_processing_confirm_message (dc , true);
307
335
return ;
308
336
}
309
337
}
0 commit comments