@@ -323,8 +323,13 @@ def finalizeInputFull(self, outputData):
323323 response = self .dongle .exchange (bytearray (apdu ))
324324 encryptedOutputData = encryptedOutputData + response [1 : 1 + response [0 ]]
325325 offset += dataLength
326- result ['confirmationNeeded' ] = response [1 + response [0 ]] <> 0x00
327- result ['confirmationType' ] = response [1 + response [0 ]]
326+ if len (response ) > 1 :
327+ result ['confirmationNeeded' ] = response [1 + response [0 ]] <> 0x00
328+ result ['confirmationType' ] = response [1 + response [0 ]]
329+ else :
330+ # Support for old style API before 1.0.2
331+ result ['confirmationNeeded' ] = response [0 ] <> 0x00
332+ result ['confirmationType' ] = response [0 ]
328333 if result ['confirmationType' ] == 0x02 :
329334 result ['keycardData' ] = response [1 + response [0 ] + 1 :] # legacy
330335 if result ['confirmationType' ] == 0x03 :
@@ -358,7 +363,7 @@ def untrustedHashSign(self, path, pin="", lockTime=0, sighashType=0x01):
358363 result [0 ] = 0x30
359364 return result
360365
361- def signMessagePrepare (self , path , message ):
366+ def signMessagePrepareV1 (self , path , message ):
362367 donglePath = parse_bip32_path (path )
363368 if self .needKeyCache :
364369 self .resolvePublicKeysInPath (path )
@@ -373,10 +378,57 @@ def signMessagePrepare(self, path, message):
373378 response = self .dongle .exchange (bytearray (apdu ))
374379 result ['confirmationNeeded' ] = response [0 ] <> 0x00
375380 result ['confirmationType' ] = response [0 ]
376- if result ['confirmationType' ] == 0x02 :
377- result ['keycardData' ] = response [1 :]
378- if result ['confirmationType' ] == 0x03 :
379- result ['secureScreenData' ] = response [1 :]
381+ if result ['confirmationType' ] == 0x02 :
382+ result ['keycardData' ] = response [1 :]
383+ if result ['confirmationType' ] == 0x03 :
384+ result ['secureScreenData' ] = response [1 :]
385+ return result
386+
387+ def signMessagePrepareV2 (self , path , message ):
388+ donglePath = parse_bip32_path (path )
389+ if self .needKeyCache :
390+ self .resolvePublicKeysInPath (path )
391+ result = {}
392+ offset = 0
393+ encryptedOutputData = ""
394+ while (offset < len (message )):
395+ params = [];
396+ if offset == 0 :
397+ params .extend (donglePath )
398+ params .append ((len (message ) >> 8 ) & 0xff )
399+ params .append (len (message ) & 0xff )
400+ p2 = 0x01
401+ else :
402+ p2 = 0x80
403+ blockLength = 255 - len (params )
404+ if ((offset + blockLength ) < len (message )):
405+ dataLength = blockLength
406+ else :
407+ dataLength = len (message ) - offset
408+ params .extend (bytearray (message [offset : offset + dataLength ]))
409+ apdu = [ self .BTCHIP_CLA , self .BTCHIP_INS_SIGN_MESSAGE , 0x00 , p2 ]
410+ apdu .append (len (params ))
411+ apdu .extend (params )
412+ response = self .dongle .exchange (bytearray (apdu ))
413+ encryptedOutputData = encryptedOutputData + response [1 : 1 + response [0 ]]
414+ offset += blockLength
415+ result ['confirmationNeeded' ] = response [1 + response [0 ]] <> 0x00
416+ result ['confirmationType' ] = response [1 + response [0 ]]
417+ if result ['confirmationType' ] == 0x03 :
418+ offset = 1 + response [0 ] + 1
419+ result ['secureScreenData' ] = response [offset :]
420+ result ['encryptedOutputData' ] = encryptedOutputData
421+
422+ return result
423+
424+ def signMessagePrepare (self , path , message ):
425+ try :
426+ result = self .signMessagePrepareV2 (path , message )
427+ except BTChipException as e :
428+ if (e .sw == 0x6b00 ): # Old firmware version, try older method
429+ result = self .signMessagePrepareV1 (path , message )
430+ else :
431+ raise
380432 return result
381433
382434 def signMessageSign (self , pin = "" ):
@@ -423,11 +475,11 @@ def setup(self, operationModeFlags, featuresFlag, keyVersion, keyVersionP2SH, us
423475 self .setKeymapEncoding (keymapEncoding )
424476 try :
425477 self .setTypingBehaviour (0xff , 0xff , 0xff , 0x10 )
426- except BTChipException as e :
427- if (e .sw == 0x6700 ): # Old firmware version, command not supported
428- pass
429- else :
430- raise
478+ except BTChipException as e :
479+ if (e .sw == 0x6700 ): # Old firmware version, command not supported
480+ pass
481+ else :
482+ raise
431483 return result
432484
433485 def setKeymapEncoding (self , keymapEncoding ):
0 commit comments