@@ -97,7 +97,7 @@ func FindLedgerFilecoinApp() (*LedgerFilecoin, error) {
97
97
if err != nil {
98
98
defer ledgerAPI .Close ()
99
99
if err .Error () == "[APDU_CODE_CLA_NOT_SUPPORTED] Class not supported" {
100
- return nil , fmt .Errorf ("are you sure the Filecoin app is open? " )
100
+ return nil , fmt .Errorf ("Filecoin app is not open on the device " )
101
101
}
102
102
return nil , err
103
103
}
@@ -131,7 +131,7 @@ func (ledger *LedgerFilecoin) GetVersion() (*VersionInfo, error) {
131
131
}
132
132
133
133
if len (response ) < minVersionResponseLength {
134
- return nil , fmt .Errorf ("invalid response" )
134
+ return nil , fmt .Errorf ("invalid version response length: expected %d, got %d" , minVersionResponseLength , len ( response ) )
135
135
}
136
136
137
137
ledger .version = VersionInfo {
@@ -157,18 +157,7 @@ func (ledger *LedgerFilecoin) Sign(bip44Path []uint32, transaction []byte, curve
157
157
return nil , err
158
158
}
159
159
160
- // R,S,V and at least 1 bytes of the der sig
161
- if len (signatureBytes ) < signatureMinLength {
162
- return nil , fmt .Errorf ("The signature provided is too short." )
163
- }
164
-
165
- signatureAnswer := SignatureAnswer {
166
- signatureBytes [signatureROffset :signatureROffset + signatureRLength ],
167
- signatureBytes [signatureSOffset :signatureSOffset + signatureSLength ],
168
- signatureBytes [signatureVOffset ],
169
- signatureBytes [signatureDEROffset :]}
170
-
171
- return & signatureAnswer , nil
160
+ return parseSignatureResponse (signatureBytes )
172
161
}
173
162
174
163
// Deprecated: Use GetPublicKey instead.
@@ -207,12 +196,7 @@ func (ledger *LedgerFilecoin) ShowAddressPubKey(bip44Path []uint32, curve Crypto
207
196
}
208
197
209
198
func (ledger * LedgerFilecoin ) GetBip44bytes (bip44Path []uint32 , hardenCount int ) ([]byte , error ) {
210
- pathBytes , err := GetBip44bytes (bip44Path , hardenCount )
211
- if err != nil {
212
- return nil , err
213
- }
214
-
215
- return pathBytes , nil
199
+ return GetBip44bytes (bip44Path , hardenCount )
216
200
}
217
201
218
202
func (ledger * LedgerFilecoin ) sign (bip44Path []uint32 , transaction []byte , curve CryptoCurve ) ([]byte , error ) {
@@ -230,49 +214,7 @@ func (ledger *LedgerFilecoin) sign(bip44Path []uint32, transaction []byte, curve
230
214
return nil , err
231
215
}
232
216
233
- var finalResponse []byte
234
-
235
- var message []byte
236
-
237
- var chunkIndex int = 0
238
-
239
- for chunkIndex < len (chunks ) {
240
- payloadLen := byte (len (chunks [chunkIndex ]))
241
-
242
- if chunkIndex == 0 {
243
- header := []byte {CLA , INSSign , PayloadChunkInit , apduP2Default , payloadLen }
244
- message = append (header , chunks [chunkIndex ]... )
245
- } else {
246
-
247
- payloadDesc := byte (PayloadChunkAdd )
248
- if chunkIndex == (len (chunks ) - 1 ) {
249
- payloadDesc = byte (PayloadChunkLast )
250
- }
251
-
252
- header := []byte {CLA , INSSign , payloadDesc , apduP2Default , payloadLen }
253
- message = append (header , chunks [chunkIndex ]... )
254
- }
255
-
256
- response , err := ledger .api .Exchange (message )
257
- if err != nil {
258
- // FIXME: CBOR will be used instead
259
- if err .Error () == "[APDU_CODE_BAD_KEY_HANDLE] The parameters in the data field are incorrect" {
260
- // In this special case, we can extract additional info
261
- errorMsg := string (response )
262
- return nil , fmt .Errorf (errorMsg )
263
- }
264
- if err .Error () == "[APDU_CODE_DATA_INVALID] Referenced data reversibly blocked (invalidated)" {
265
- errorMsg := string (response )
266
- return nil , fmt .Errorf (errorMsg )
267
- }
268
- return nil , err
269
- }
270
-
271
- finalResponse = response
272
- chunkIndex ++
273
-
274
- }
275
- return finalResponse , nil
217
+ return ledger .processChunks (chunks , INSSign )
276
218
}
277
219
278
220
// SignPersonalMessageFVM signs a personal message for FVM (Filecoin Virtual Machine)
@@ -284,18 +226,7 @@ func (ledger *LedgerFilecoin) SignPersonalMessageFVM(bip44Path []uint32, message
284
226
return nil , err
285
227
}
286
228
287
- // R,S,V and at least 1 bytes of the der sig
288
- if len (signatureBytes ) < signatureMinLength {
289
- return nil , fmt .Errorf ("The signature provided is too short." )
290
- }
291
-
292
- signatureAnswer := SignatureAnswer {
293
- signatureBytes [signatureROffset :signatureROffset + signatureRLength ],
294
- signatureBytes [signatureSOffset :signatureSOffset + signatureSLength ],
295
- signatureBytes [signatureVOffset ],
296
- signatureBytes [signatureDEROffset :]}
297
-
298
- return & signatureAnswer , nil
229
+ return parseSignatureResponse (signatureBytes )
299
230
}
300
231
301
232
func (ledger * LedgerFilecoin ) signPersonalMessage (bip44Path []uint32 , message []byte ) ([]byte , error ) {
@@ -315,43 +246,7 @@ func (ledger *LedgerFilecoin) signPersonalMessage(bip44Path []uint32, message []
315
246
return nil , err
316
247
}
317
248
318
- var finalResponse []byte
319
- var chunkIndex int = 0
320
-
321
- for chunkIndex < len (chunks ) {
322
- payloadLen := byte (len (chunks [chunkIndex ]))
323
-
324
- var header []byte
325
- if chunkIndex == 0 {
326
- header = []byte {CLA , INSSignPersonalMsg , PayloadChunkInit , apduP2Default , payloadLen }
327
- } else {
328
- payloadDesc := byte (PayloadChunkAdd )
329
- if chunkIndex == (len (chunks ) - 1 ) {
330
- payloadDesc = byte (PayloadChunkLast )
331
- }
332
- header = []byte {CLA , INSSignPersonalMsg , payloadDesc , apduP2Default , payloadLen }
333
- }
334
-
335
- message := append (header , chunks [chunkIndex ]... )
336
-
337
- response , err := ledger .api .Exchange (message )
338
- if err != nil {
339
- // Handle specific error cases
340
- if err .Error () == "[APDU_CODE_BAD_KEY_HANDLE] The parameters in the data field are incorrect" {
341
- errorMsg := string (response )
342
- return nil , fmt .Errorf (errorMsg )
343
- }
344
- if err .Error () == "[APDU_CODE_DATA_INVALID] Referenced data reversibly blocked (invalidated)" {
345
- errorMsg := string (response )
346
- return nil , fmt .Errorf (errorMsg )
347
- }
348
- return nil , err
349
- }
350
-
351
- finalResponse = response
352
- chunkIndex ++
353
- }
354
- return finalResponse , nil
249
+ return ledger .processChunks (chunks , INSSignPersonalMsg )
355
250
}
356
251
357
252
// retrieveAddressPubKey returns the pubkey and address
@@ -363,18 +258,7 @@ func (ledger *LedgerFilecoin) SignRawBytes(bip44Path []uint32, message []byte) (
363
258
return nil , err
364
259
}
365
260
366
- // R,S,V and at least 1 bytes of the der sig
367
- if len (signatureBytes ) < signatureMinLength {
368
- return nil , fmt .Errorf ("The signature provided is too short." )
369
- }
370
-
371
- signatureAnswer := SignatureAnswer {
372
- signatureBytes [signatureROffset :signatureROffset + signatureRLength ],
373
- signatureBytes [signatureSOffset :signatureSOffset + signatureSLength ],
374
- signatureBytes [signatureVOffset ],
375
- signatureBytes [signatureDEROffset :]}
376
-
377
- return & signatureAnswer , nil
261
+ return parseSignatureResponse (signatureBytes )
378
262
}
379
263
380
264
func (ledger * LedgerFilecoin ) signRawBytes (bip44Path []uint32 , message []byte ) ([]byte , error ) {
@@ -395,46 +279,72 @@ func (ledger *LedgerFilecoin) signRawBytes(bip44Path []uint32, message []byte) (
395
279
return nil , err
396
280
}
397
281
398
- var finalResponse []byte
399
- var chunkIndex int = 0
282
+ return ledger .processChunks (chunks , INSSignRawBytes )
283
+ }
284
+
285
+ // encodeVarint encodes a uint64 as a varint (variable length integer)
286
+ func connectToDevice (ledgerAdmin ledger_go.LedgerAdmin , deviceIndex int ) (* LedgerFilecoin , error ) {
287
+ ledgerDevice , err := ledgerAdmin .Connect (deviceIndex )
288
+ if err != nil {
289
+ return nil , err
290
+ }
400
291
401
- for chunkIndex < len (chunks ) {
402
- payloadLen := byte (len (chunks [chunkIndex ]))
292
+ app := & LedgerFilecoin {ledgerDevice , VersionInfo {}}
293
+ return app , nil
294
+ }
403
295
404
- var header []byte
296
+ func parseSignatureResponse (signatureBytes []byte ) (* SignatureAnswer , error ) {
297
+ if len (signatureBytes ) < signatureMinLength {
298
+ return nil , fmt .Errorf ("signature too short" )
299
+ }
300
+
301
+ return & SignatureAnswer {
302
+ r : signatureBytes [signatureROffset :signatureROffset + signatureRLength ],
303
+ s : signatureBytes [signatureSOffset :signatureSOffset + signatureSLength ],
304
+ v : signatureBytes [signatureVOffset ],
305
+ derSignature : signatureBytes [signatureDEROffset :],
306
+ }, nil
307
+ }
308
+
309
+ func (ledger * LedgerFilecoin ) processChunks (chunks [][]byte , instruction byte ) ([]byte , error ) {
310
+ var finalResponse []byte
311
+
312
+ for chunkIndex , chunk := range chunks {
313
+ payloadLen := byte (len (chunk ))
314
+ payloadDesc := PayloadChunkAdd
315
+
405
316
if chunkIndex == 0 {
406
- header = []byte {CLA , INSSignRawBytes , PayloadChunkInit , apduP2Default , payloadLen }
407
- } else {
408
- payloadDesc := byte (PayloadChunkAdd )
409
- if chunkIndex == (len (chunks ) - 1 ) {
410
- payloadDesc = byte (PayloadChunkLast )
411
- }
412
- header = []byte {CLA , INSSignRawBytes , payloadDesc , apduP2Default , payloadLen }
317
+ payloadDesc = PayloadChunkInit
318
+ } else if chunkIndex == len (chunks )- 1 {
319
+ payloadDesc = PayloadChunkLast
413
320
}
414
321
415
- message := append (header , chunks [chunkIndex ]... )
322
+ header := []byte {CLA , instruction , byte (payloadDesc ), apduP2Default , payloadLen }
323
+ message := append (header , chunk ... )
416
324
417
325
response , err := ledger .api .Exchange (message )
418
326
if err != nil {
419
- // Handle specific error cases
420
- if err .Error () == "[APDU_CODE_BAD_KEY_HANDLE] The parameters in the data field are incorrect" {
421
- errorMsg := string (response )
422
- return nil , fmt .Errorf (errorMsg )
423
- }
424
- if err .Error () == "[APDU_CODE_DATA_INVALID] Referenced data reversibly blocked (invalidated)" {
425
- errorMsg := string (response )
426
- return nil , fmt .Errorf (errorMsg )
427
- }
428
- return nil , err
327
+ return nil , handleExchangeError (err , response )
429
328
}
430
329
431
330
finalResponse = response
432
- chunkIndex ++
433
331
}
332
+
434
333
return finalResponse , nil
435
334
}
436
335
437
- // encodeVarint encodes a uint64 as a varint (variable length integer)
336
+ func handleExchangeError (err error , response []byte ) error {
337
+ errorMsg := err .Error ()
338
+ switch {
339
+ case errorMsg == "[APDU_CODE_BAD_KEY_HANDLE] The parameters in the data field are incorrect" :
340
+ return fmt .Errorf (string (response ))
341
+ case errorMsg == "[APDU_CODE_DATA_INVALID] Referenced data reversibly blocked (invalidated)" :
342
+ return fmt .Errorf (string (response ))
343
+ default :
344
+ return err
345
+ }
346
+ }
347
+
438
348
func encodeVarint (value uint64 ) []byte {
439
349
buf := make ([]byte , binary .MaxVarintLen64 )
440
350
n := binary .PutUvarint (buf , value )
@@ -467,7 +377,7 @@ func (ledger *LedgerFilecoin) retrieveAddressPubKey(bip44Path []uint32, curve Cr
467
377
return nil , nil , "" , err
468
378
}
469
379
if len (response ) < minAddressResponseLength {
470
- return nil , nil , "" , fmt .Errorf ("Invalid response" )
380
+ return nil , nil , "" , fmt .Errorf ("invalid address response length: expected %d, got %d" , minAddressResponseLength , len ( response ) )
471
381
}
472
382
473
383
cursor := 0
0 commit comments