Exemplo n.º 1
0
 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!")
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    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