def set_2FA(self, client): if not client.cc.needs_2FA: use_2FA = client.handler.yes_no_question(MSG_USE_2FA) if (use_2FA): secret_2FA = urandom(20) secret_2FA_hex = secret_2FA.hex() # the secret must be shared with the second factor app (eg on a smartphone) try: help_txt = "Scan the QR-code with your Satochip-2FA app and make a backup of the following secret: " + secret_2FA_hex d = QRDialog(data=secret_2FA_hex, parent=None, title="Secret_2FA", show_text=False, help_text=help_txt) d.exec_() except Exception as e: print_error("SatochipPlugin: setup 2FA error: " + str(e)) return # further communications will require an id and an encryption key (for privacy). # Both are derived from the secret_2FA using a one-way function inside the Satochip amount_limit = 0 # i.e. always use (response, sw1, sw2) = client.cc.card_set_2FA_key(secret_2FA, amount_limit) if sw1 != 0x90 or sw2 != 0x00: print_error( f"Unable to set 2FA with error code:= {hex(256*sw1+sw2)}" ) #debugSatochip raise RuntimeError( f'Unable to setup 2FA with error code: {hex(256*sw1+sw2)}' ) else: client.handler.show_message("2FA enabled successfully!")
def set_2FA(self, client): if not client.cc.needs_2FA: use_2FA = client.handler.yes_no_question(MSG_USE_2FA) if (use_2FA): secret_2FA = urandom(20) secret_2FA_hex = secret_2FA.hex() # the secret must be shared with the second factor app (eg on a smartphone) try: d = QRDialog(secret_2FA_hex, None, "Scan secret 2FA and save a copy", True) d.exec_() except Exception as e: print_error("SatochipPlugin: setup 2FA error: " + str(e)) return # further communications will require an id and an encryption key (for privacy). # Both are derived from the secret_2FA using a one-way function inside the Satochip amount_limit = 0 # i.e. always use (response, sw1, sw2) = client.cc.card_set_2FA_key(secret_2FA, amount_limit) if sw1 != 0x90 or sw2 != 0x00: print_error( f"Unable to set 2FA with error code:= {hex(256*sw1+sw2)}" ) #debugSatochip raise RuntimeError( f'Unable to setup 2FA with error code: {hex(256*sw1+sw2)}' ) else: client.handler.show_message("2FA enabled successfully!") else: msg = _(f"2FA is already enabled!") client.handler.show_error(msg)
def setup_device(self, device_info, wizard): self.print_error("setup_device()") #debugSatochip if not LIBS_AVAILABLE: raise RuntimeError("No libraries available") devmgr = self.device_manager() device_id = device_info.device.id_ client = devmgr.client_by_id(device_id) if client is None: raise Exception( _('Failed to create a client for this device.') + '\n' + _('Make sure it is in the correct state.')) client.handler = self.create_handler(wizard) client.cc.parser.authentikey_from_storage = None # https://github.com/simpleledger/Electron-Cash-SLP/pull/101#issuecomment-561238614 # check applet version while True: (response, sw1, sw2, d) = client.cc.card_get_status() if sw1 == 0x90 and sw2 == 0x00: v_supported = ( CardConnector.SATOCHIP_PROTOCOL_MAJOR_VERSION << 8) + CardConnector.SATOCHIP_PROTOCOL_MINOR_VERSION v_applet = (d["protocol_major_version"] << 8) + d["protocol_minor_version"] self.print_error( f"Satochip version={hex(v_applet)} Electron Cash supported version= {hex(v_supported)}" ) #debugSatochip if (v_supported < v_applet): msg = ( _('The version of your Satochip is higher than supported by Electron Cash. You should update Electron Cash to ensure correct functioning!' ) + '\n' + f' Satochip version: {d["protocol_major_version"]}.{d["protocol_minor_version"]}' + '\n' + f' Supported version: {CardConnector.SATOCHIP_PROTOCOL_MAJOR_VERSION}.{CardConnector.SATOCHIP_PROTOCOL_MINOR_VERSION}' ) client.handler.show_error(msg) break # setup device (done only once) elif sw1 == 0x9c and sw2 == 0x04: # PIN dialog while True: msg = _("Enter a new PIN for your Satochip:") (is_PIN, pin_0, pin_0) = client.PIN_dialog(msg) if (not is_PIN): raise RuntimeError( _('Satochip setup aborted: a PIN is required!')) msg = _("Please confirm the PIN code for your Satochip:") (is_PIN, pin_confirm, pin_confirm) = client.PIN_dialog(msg) if (not is_PIN): raise RuntimeError( _('Satochip setup aborted: a PIN confirmation is required!' )) if (pin_0 != pin_confirm): msg = _( "The PIN values do not match! Please type PIN again!" ) client.handler.show_error(msg) else: break pin_0 = list(pin_0) client.cc.set_pin(0, pin_0) #cache PIN value in client pin_tries_0 = 0x05 ublk_tries_0 = 0x01 # PUK code can be used when PIN is unknown and the card is locked # We use a random value as the PUK is not used currently in the electrum GUI ublk_0 = list(urandom(16)) pin_tries_1 = 0x01 ublk_tries_1 = 0x01 pin_1 = list(urandom(16)) #the second pin is not used currently ublk_1 = list(urandom(16)) secmemsize = 32 # number of slot reserved in memory cache memsize = 0x0000 # RFU create_object_ACL = 0x01 create_key_ACL = 0x01 create_pin_ACL = 0x01 # setup self.print_error( "setup_device(): perform cardSetup:") #debugSatochip (response, sw1, sw2) = client.cc.card_setup( pin_tries_0, ublk_tries_0, pin_0, ublk_0, pin_tries_1, ublk_tries_1, pin_1, ublk_1, secmemsize, memsize, create_object_ACL, create_key_ACL, create_pin_ACL) if sw1 != 0x90 or sw2 != 0x00: self.print_error( "setup_device(): unable to set up applet! sw12=" + hex(sw1) + " " + hex(sw2)) #debugSatochip raise RuntimeError( 'Unable to setup the device with error code:' + hex(sw1) + ' ' + hex(sw2)) else: self.print_error("unknown get-status() error! sw12=", hex(sw1), " ", hex(sw2)) #debugSatochip raise RuntimeError('Unknown get-status() error code:' + hex(sw1) + ' ' + hex(sw2)) # verify pin: client.cc.card_verify_PIN() # get authentikey while True: try: authentikey = client.cc.card_bip32_get_authentikey() except UninitializedSeedError: # Option: setup 2-Factor-Authentication (2FA) if not client.cc.needs_2FA: use_2FA = client.handler.yes_no_question(MSG_USE_2FA) if (use_2FA): option_flags = 0x8000 # activate 2fa with hmac challenge-response secret_2FA = urandom(20) #secret_2FA=b'\0'*20 #for debug purpose secret_2FA_hex = secret_2FA.hex() amount_limit = 0 # i.e. always use (response, sw1, sw2) = client.cc.card_set_2FA_key( secret_2FA, amount_limit) # the secret must be shared with the second factor app (eg on a smartphone) try: d = QRDialog(secret_2FA_hex, None, "Secret_2FA", True) d.exec_() except Exception as e: self.print_error("setup_device(): setup 2FA: " + str(e)) # further communications will require an id and an encryption key (for privacy). # Both are derived from the secret_2FA using a one-way function inside the Satochip if sw1 != 0x90 or sw2 != 0x00: self.print_error( f"setup_device(): unable to set 2FA! sw12={hex(sw1)},{hex(sw2)}" ) #debugSatochip raise RuntimeError( f'Unable to setup 2FA with error code: {hex(sw1)} {hex(sw2)}' ) # seed dialog... self.print_error( "setup_device(): import seed:") #debugSatochip self.choose_seed(wizard) seed = list(self.bip32_seed) #seed= bytes([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]) # Bip32 test vectors authentikey = client.cc.card_bip32_import_seed(seed) hex_authentikey = authentikey.get_public_key_hex(compressed=True) self.print_error("setup_device(): authentikey=", hex_authentikey) #debugSatochip wizard.storage.put('authentikey', hex_authentikey) self.print_error("setup_device(): authentikey from storage=", wizard.storage.get('authentikey')) #debugSatochip break
def setup_device(self, device_info, wizard): self.print_error("setup_device()")#debugSatochip if not LIBS_AVAILABLE: raise RuntimeError("No libraries available") devmgr = self.device_manager() device_id = device_info.device.id_ client = devmgr.client_by_id(device_id) if client is None: raise Exception(_('Failed to create a client for this device.') + '\n' + _('Make sure it is in the correct state.')) client.handler = self.create_handler(wizard) client.cc.parser.authentikey_from_storage=None # https://github.com/simpleledger/Electron-Cash-SLP/pull/101#issuecomment-561238614 # check setup while(client.cc.card_present): # check that card is indeed a Satochip if (client.cc.card_type != "Satochip"): raise Exception(_('Failed to create a client for this device.') + '\n' + _('Inserted card is not a Satochip!')) (response, sw1, sw2, d) = client.cc.card_get_status() # check version if (client.cc.setup_done): v_supported= SATOCHIP_PROTOCOL_VERSION v_applet= d["protocol_version"] self.print_error(f"[SatochipPlugin] setup_device(): Satochip version={hex(v_applet)} Electrum supported version= {hex(v_supported)}")#debugSatochip if (v_supported<v_applet): msg=(_('The version of your Satochip is higher than supported by Electron Cash. You should update Electron Cash to ensure correct functioning!')+ '\n' + f' Satochip version: {d["protocol_major_version"]}.{d["protocol_minor_version"]}' + '\n' + f' Supported version: {SATOCHIP_PROTOCOL_MAJOR_VERSION}.{SATOCHIP_PROTOCOL_MINOR_VERSION}') client.handler.show_error(msg) if (client.cc.needs_secure_channel): client.cc.card_initiate_secure_channel() break # setup device (done only once) else: # PIN dialog msg = _("Enter a new PIN for your Satochip:") msg_confirm = _("Please confirm the PIN code for your Satochip:") msg_error = _("The PIN values do not match! Please type PIN again!") (is_PIN, pin_0)= client.PIN_setup_dialog(msg, msg_confirm, msg_error) pin_0= list(pin_0) client.cc.set_pin(0, pin_0) #cache PIN value in client pin_tries_0= 0x05; # PUK code can be used when PIN is unknown and the card is locked # We use a random value as the PUK is not used currently in the electrum GUI ublk_tries_0= 0x01; ublk_0= list(urandom(16)); pin_tries_1= 0x01 ublk_tries_1= 0x01 pin_1= list(urandom(16)); #the second pin is not used currently ublk_1= list(urandom(16)); secmemsize= 32 # number of slot reserved in memory cache memsize= 0x0000 # RFU create_object_ACL= 0x01 # RFU create_key_ACL= 0x01 # RFU create_pin_ACL= 0x01 # RFU # setup (response, sw1, sw2)=client.cc.card_setup(pin_tries_0, ublk_tries_0, pin_0, ublk_0, pin_tries_1, ublk_tries_1, pin_1, ublk_1, secmemsize, memsize, create_object_ACL, create_key_ACL, create_pin_ACL) if sw1!=0x90 or sw2!=0x00: self.print_error("setup_device(): unable to set up applet! sw12="+hex(sw1)+" "+hex(sw2))#debugSatochip raise RuntimeError('Unable to setup the device with error code:'+hex(sw1)+' '+hex(sw2)) # verify pin: client.cc.card_verify_PIN() # get authentikey while(client.cc.card_present): try: authentikey=client.cc.card_bip32_get_authentikey() except UninitializedSeedError: # Option: setup 2-Factor-Authentication (2FA) if not client.cc.needs_2FA: #use_2FA= client.handler.yes_no_question(MSG_USE_2FA) use_2FA= False # we put 2FA activation in advanced options as it confuses some users if (use_2FA): secret_2FA= urandom(20) #secret_2FA=b'\0'*20 #for debug purpose secret_2FA_hex=secret_2FA.hex() # the secret must be shared with the second factor app (eg on a smartphone) try: d = QRDialog(secret_2FA_hex, None, "Scan secret 2FA and save a copy", True) d.exec_() except Exception as e: self.print_error("setup_device(): setup 2FA: "+str(e)) # further communications will require an id and an encryption key (for privacy). # Both are derived from the secret_2FA using a one-way function inside the Satochip amount_limit= 0 # i.e. always use (response, sw1, sw2)=client.cc.card_set_2FA_key(secret_2FA, amount_limit) if sw1!=0x90 or sw2!=0x00: self.print_error(f"setup_device(): unable to set 2FA! sw12={hex(sw1)},{hex(sw2)}")#debugSatochip raise RuntimeError(f'Unable to setup 2FA with error code: {hex(sw1)} {hex(sw2)}') # seed dialog... self.print_error("setup_device(): import seed:") #debugSatochip self.choose_seed(wizard) seed= list(self.bip32_seed) authentikey= client.cc.card_bip32_import_seed(seed) hex_authentikey= authentikey.get_public_key_hex(compressed=True) self.print_error("setup_device(): authentikey=", hex_authentikey)#debugSatochip wizard.storage.put('authentikey', hex_authentikey) self.print_error("setup_device(): authentikey from storage=", wizard.storage.get('authentikey'))#debugSatochip break