コード例 #1
0
    def sign_message(self, sequence, message, password):
        sig = None
        try:
            inputPath = self.get_derivation() + "/%d/%d" % sequence
            inputHash = Hash(msg_magic(message)).encode('hex')
            hasharray = []
            hasharray.append({'hash': inputHash, 'keypath': inputPath})
            hasharray = json.dumps(hasharray)

            msg = '{"sign":{"meta":"sign message", "data":%s}}' % (hasharray)

            dbb_client = self.plugin.get_client(self)

            if not dbb_client.is_paired():
                raise Exception("Could not sign message.")

            reply = dbb_client.hid_send_encrypt(msg)
            self.handler.show_message(_("Signing message ...\r\n\r\n" \
                                        "To continue, touch the Digital Bitbox's blinking light for 3 seconds.\r\n\r\n" \
                                        "To cancel, briefly touch the blinking light or wait for the timeout."))
            reply = dbb_client.hid_send_encrypt(
                msg
            )  # Send twice, first returns an echo for smart verification (not implemented)
            self.handler.clear_dialog()

            if 'error' in reply:
                raise Exception(reply['error']['message'])

            if 'sign' not in reply:
                raise Exception("Could not sign message.")

            if 'recid' in reply['sign'][0]:
                # firmware > v2.1.1
                sig = chr(27 + int(reply['sign'][0]['recid'], 16) +
                          4) + reply['sign'][0]['sig'].decode('hex')
                h = Hash(msg_magic(message))
                pk, compressed = pubkey_from_signature(sig, h)
                pk = point_to_ser(pk.pubkey.point, compressed)
                addr = public_key_to_p2pkh(pk)
                if verify_message(addr, sig, message) is False:
                    raise Exception("Could not sign message")
            elif 'pubkey' in reply['sign'][0]:
                # firmware <= v2.1.1
                for i in range(4):
                    sig = chr(27 + i +
                              4) + reply['sign'][0]['sig'].decode('hex')
                    try:
                        addr = public_key_to_p2pkh(
                            reply['sign'][0]['pubkey'].decode('hex'))
                        if verify_message(addr, sig, message):
                            break
                    except Exception:
                        continue
                else:
                    raise Exception("Could not sign message")

        except BaseException as e:
            self.give_error(e)
        return sig
コード例 #2
0
    def doVerify(self) -> None:
        addrtf = self.tf
        address_str = str(addrtf.text).strip()
        message = str(self.topTvDel.text)
        signature = str(self.botTvDel.text).strip()

        if not signature:
            parent().show_message(
                _("Please provide both a signature and a message to verify"))
            return

        try:
            address = Address.from_string(address_str)
        except:
            parent().show_error(_('Invalid Vitae address.'))
            return
        message = message.encode('utf-8')
        try:
            # This can raise on invalid base64
            sig = base64.b64decode(signature)
            verified = bitcoin.verify_message(
                address, sig, message)  # this raises too on failure
        except:
            verified = False

        if verified:
            parent().show_message(_("Signature verified"), title=_("Success"))
        else:
            parent().show_error(_("Wrong signature"))
コード例 #3
0
    def _process_server_reply(self, signed_version_dict):
        ''' Returns:
                - the new package version string if new version found from
                  server, e.g. '3.3.5', '3.3.5CS', etc
                - or the current version (version.PACKAGE_VERSION) if no new
                  version found.
                - None on failure (such as bad signature).

            May also raise on error. '''
        # example signed_version_dict:
        # {
        #     "3.9.9": {
        #         "bitcoincash:qphax4cg8sxuc0qnzk6sx25939ma7y877uz04s2z82": "IA+2QG3xPRn4HAIFdpu9eeaCYC7S5wS/sDxn54LJx6BdUTBpse3ibtfq8C43M7M1VfpGkD5tsdwl5C6IfpZD/gQ="
        #     },
        #     "3.9.9CS": {
        #         "bitcoincash:qphax4cg8sxuc0qnzk6sx25939ma7y877uz04s2z82": "IA+2QG3xPRn4HAIFdpu9eeaCYC7S5wS/sDxn54LJx6BdUTBpse3ibtfq8C43M7M1VfpGkD5tsdwl5C6IfpZD/gQ="
        #     },
        #     "3.9.9SLP": {
        #         "bitcoincash:qphax4cg8sxuc0qnzk6sx25939ma7y877uz04s2z82": "IA+2QG3xPRn4HAIFdpu9eeaCYC7S5wS/sDxn54LJx6BdUTBpse3ibtfq8C43M7M1VfpGkD5tsdwl5C6IfpZD/gQ="
        #     },
        # }
        # All signed messages above are signed with the address in the dict, and the message is the "3.9.9" or "3.9.9CS" etc string
        ct_matching = 0
        for version_msg, sigdict in signed_version_dict.items():
            # This looks quadratic, and it is. But the expected results are small.
            # We needed to do it this way to detect when there was no matching variant and/or no known-key match.
            if self.is_matching_variant(version_msg):
                for adr, sig in sigdict.items():
                    adr = address.Address.from_string(adr, net=MainNet) # may raise
                    if adr in self.VERSION_ANNOUNCEMENT_SIGNING_ADDRESSES:
                        ct_matching += 1
                        if self.is_newer(version_msg): # may raise
                            try:
                                is_verified = bitcoin.verify_message(adr, base64.b64decode(sig), version_msg.encode('utf-8'), net=MainNet)
                            except:
                                self.print_error("Exception when verifying version signature for", version_msg, ":", repr(sys.exc_info()[1]))
                                return None
                            if is_verified:
                                self.print_error("Got new version", version_msg)
                                return version_msg.strip()
                            else:
                                self.print_error("Got new version", version_msg, "but sigcheck failed!")
                                return None
        if 0 == ct_matching:
            # Hmm. None of the versions we saw matched our variant.
            # And/Or, none of the keys we saw matched keys we knew about.
            # This is an error condition, so return None
            self.print_error("Error: Got a valid reply from server but none of the variants match us and/or none of the signing keys are known!")
            return None
        return version.PACKAGE_VERSION
コード例 #4
0
def verify_signature_with_address(address: str, message: str,
                                  signature: str) -> bool:
    """Verify a message signature using a bitcoin address.

    :param address: Bitcoin address, either legacy or cashaddr
    :param message: Message to verify against the signature
    :param signature: Base64 encoded signature string.
    """
    try:
        sig = base64.b64decode(signature)
    except binascii.Error:
        return False
    addr = Address.from_string(address)
    message_bytes = message.encode("utf-8")

    return bitcoin.verify_message(addr, sig, message_bytes)
コード例 #5
0
    def do_verify(self):
        try:
            address = Address.from_string(self.address_e.text().strip())
        except Exception:
            self.show_message(_(f"Invalid {CURRENCY} address."))
            return
        message = self.message_e.toPlainText().strip().encode("utf-8")
        try:
            # This can throw on invalid base64
            sig = base64.b64decode(self.signature_e.toPlainText())
            verified = verify_message(address,
                                      sig,
                                      message,
                                      sigtype=self.get_sigtype())
        except Exception:
            verified = False

        if verified:
            self.show_message(_("Signature verified"))
        else:
            self.show_error(_("Wrong signature"))
コード例 #6
0
    def sign_message(self,
                     sequence,
                     message,
                     password,
                     sigtype=SignatureType.BITCOIN):
        if sigtype == SignatureType.ECASH:
            raise RuntimeError(
                _('eCash message signing is not available for {}').format(
                    self.device))
        sig = None
        try:
            message = message.encode('utf8')
            inputPath = self.get_derivation() + "/%d/%d" % sequence
            msg_hash = Hash(msg_magic(message))
            inputHash = to_hexstr(msg_hash)
            hasharray = []
            hasharray.append({'hash': inputHash, 'keypath': inputPath})
            hasharray = json.dumps(hasharray)

            msg = b'{"sign":{"meta":"sign message", "data":%s}}' % hasharray.encode(
                'utf8')

            dbb_client = self.plugin.get_client(self)

            if not dbb_client.is_paired():
                raise Exception(_("Could not sign message."))

            reply = dbb_client.hid_send_encrypt(msg)
            self.handler.show_message(
                _("Signing message ...") + "\n\n" +
                _("To continue, touch the Digital Bitbox's blinking light for 3 seconds."
                  ) + "\n\n" +
                _("To cancel, briefly touch the blinking light or wait for the timeout."
                  ))
            reply = dbb_client.hid_send_encrypt(
                msg
            )  # Send twice, first returns an echo for smart verification (not implemented)
            self.handler.finished()

            if 'error' in reply:
                raise Exception(reply['error']['message'])

            if 'sign' not in reply:
                raise Exception(_("Could not sign message."))

            if 'recid' in reply['sign'][0]:
                # firmware > v2.1.1
                sig = bytes([27 + int(reply['sign'][0]['recid'], 16) + 4
                             ]) + binascii.unhexlify(reply['sign'][0]['sig'])
                pk, compressed = pubkey_from_signature(sig, msg_hash)
                pk = point_to_ser(pk.pubkey.point, compressed)
                addr = public_key_to_p2pkh(pk)
                if verify_message(addr, sig, message) is False:
                    raise Exception(_("Could not sign message"))
            elif 'pubkey' in reply['sign'][0]:
                # firmware <= v2.1.1
                for i in range(4):
                    sig = bytes([27 + i + 4]) + binascii.unhexlify(
                        reply['sign'][0]['sig'])
                    try:
                        addr = public_key_to_p2pkh(
                            binascii.unhexlify(reply['sign'][0]['pubkey']))
                        if verify_message(addr, sig, message):
                            break
                    except Exception:
                        continue
                else:
                    raise Exception(_("Could not sign message"))

        except BaseException as e:
            self.give_error(e)
        return sig