Exemple #1
0
    def __init__(
        self,
        currency: str,
        pubkey: str,
        challenge: Optional[str] = None,
        signature: Optional[str] = None,
    ) -> None:
        """
        Init Connect message document

        :param currency: Name of the currency
        :param pubkey: Public key of the node
        :param challenge: [Optional, default=None] Big random string, typically an uuid
        :param signature: [Optional, default=None] Base64 encoded signature of raw formated document
        """
        if signature is not None:
            signatures = [signature]
        else:
            signatures = []

        super().__init__(self.version, currency, signatures)

        self.pubkey = pubkey

        if challenge is None:
            # create challenge
            self.challenge = get_ws2p_challenge()
        else:
            self.challenge = challenge

        if signature is not None:
            # verify signature
            verifying_key = VerifyingKey(self.pubkey)
            verifying_key.verify_document(self)
    def test_ws2p_headv0(self):
        headv0, _ = HeadV0.from_inline("WS2P:HEAD:3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:"
                                    "54813-00000A24802B33B71A91B6E990038C145A4815A45C71E57B2F2EF393183C7E2C",
                                    "a1vAAM666kPsMCFTbkgkcCsqHf8nmXR+Lh3D3u+BaXzmArj7kwlItbdGUs4fc9QUG5Lp4TwPS7nhOM5t1Kt6CA==")

        verifying_key = VerifyingKey(headv0.pubkey)
        self.assertTrue(verifying_key.verify_ws2p_head(headv0))
Exemple #3
0
    def test_block_document(self):
        block_document = """Version: 10
Type: Block
Currency: g1
Number: 15145
PoWMin: 80
Time: 1493684276
MedianTime: 1493681245
UnitBase: 0
Issuer: 6fFt4zdvtNyVcfJn7Y41mKLmMDizyK3nVeNW3qdDXzpc
IssuersFrame: 106
IssuersFrameVar: 0
DifferentIssuersCount: 21
PreviousHash: 00000A0CE0AE54F3F6B63383F386067160C477B5338FB93AF3AF0776A959AA32
PreviousIssuer: D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx
MembersCount: 98
Identities:
Joiners:
Actives:
Leavers:
Revoked:
Excluded:
Certifications:
Transactions:
InnerHash: AA01ABD5C6D3F99A189C0CF0E37768DA0F876526AF93FE150E92B135D4AD0D85
Nonce: 10300000099432
"""
        block_signature = "Uxa3L+/m/dWLex2xSh7Jv1beAn4f99BmoYAs7iX3Lr+t1l5jzJpd9m4iI1cHppIizCgbg6ztaiZedQ+Mp6KuDg=="
        block = Block.from_signed_raw(block_document + block_signature + "\n")
        verifying_key = VerifyingKey(block.issuer)
        self.assertTrue(verifying_key.verify_document(block))
    def test_ws2p_headv2(self):
        headv2, _ = HeadV2.from_inline("WS2POCA:HEAD:2:D3krfq6J9AmfpKnS3gQVYoy7NzGCc61vokteTS8LJ4YH:"
                                       "99393-0000017256006BFA979565F1280488D5831DD66054069E46A3EDEB1AECDBBF13:cb36b021:"
                                       "duniter:1.6.21:1:20:19",
                                       "CgD1vaImPWZUCDFt5HDHUdjCTFcIwW5ndiCx6kXioFLZoz1a4WhCFYXvjI2N8+jEwQdWtf5+yNoHonqBSqirAQ==")

        verifying_key = VerifyingKey(headv2.pubkey)
        self.assertTrue(verifying_key.verify_ws2p_head(headv2))
    def test_ws2p_headv1(self):
        headv1, _ = HeadV1.from_inline("WS2POCAIC:HEAD:1:HbTqJ1Ts3RhJ8Rx4XkNyh1oSKmoZL1kY5U7t9mKTSjAB:"
                                       "102131-0000066028B991BDFE3FF6DBA84EF519F76B62EA3787BC29D9A05557675B1F16:1152e46e:"
                                       "duniter:1.6.21:1",
                                       "ZGpT8HG4uX5Hc96gqhzIkkELVjGQKDp2/L+7BTFG5ODxGYWd2VX/H+hdZRqf0iUWRNuhxlequ68kkwMaE6ymBw==")

        verifying_key = VerifyingKey(headv1.pubkey)
        self.assertTrue(verifying_key.verify_ws2p_head(headv1))
    def test_ws2p_headv0(self):
        headv0, _ = HeadV0.from_inline("WS2P:HEAD:3dnbnYY9i2bHMQUGyFp5GVvJ2wBkVpus31cDJA5cfRpj:"
                                       "54813-00000A24802B33B71A91B6E990038C145A4815A45C71E57B2F2EF393183C7E2C",
                                       "a1vAAM666kPsMCFTbkgkcCsqHf8nmXR+Lh3D3u"
                                       "+BaXzmArj7kwlItbdGUs4fc9QUG5Lp4TwPS7nhOM5t1Kt6CA==")

        verifying_key = VerifyingKey(headv0.pubkey)
        self.assertTrue(verifying_key.verify_ws2p_head(headv0))
Exemple #7
0
 def handle_new_node(self, peer):
     key = VerifyingKey(peer.pubkey)
     if key.verify_document(peer):
         if len(self._discovery_stack) < 1000 \
            and peer.signatures[0] not in [p.signatures[0] for p in self._discovery_stack]:
             self._logger.debug("Stacking new peer document : {0}".format(peer.pubkey))
             self._discovery_stack.append(peer)
     else:
         self._logger.debug("Wrong document received : {0}".format(peer.signed_raw()))
    def test_ws2p_headv2(self):
        headv2, _ = HeadV2.from_inline("WS2POCA:HEAD:2:D3krfq6J9AmfpKnS3gQVYoy7NzGCc61vokteTS8LJ4YH:"
                                       "99393-0000017256006BFA979565F1280488D5831DD66054069E46A3EDEB1AECDBBF13"
                                       ":cb36b021:duniter:1.6.21:1:20:19",
                                       "CgD1vaImPWZUCDFt5HDHUdjCTFcIwW5ndiCx6kXioFLZoz1a4WhCFYXvjI2N8+jEwQdWtf5"
                                       "+yNoHonqBSqirAQ==")

        verifying_key = VerifyingKey(headv2.pubkey)
        self.assertTrue(verifying_key.verify_ws2p_head(headv2))
    def test_ws2p_headv1(self):
        headv1, _ = HeadV1.from_inline("WS2POCAIC:HEAD:1:HbTqJ1Ts3RhJ8Rx4XkNyh1oSKmoZL1kY5U7t9mKTSjAB:"
                                       "102131-0000066028B991BDFE3FF6DBA84EF519F76B62EA3787BC29D9A05557675B1F16"
                                       ":1152e46e:duniter:1.6.21:1",
                                       "ZGpT8HG4uX5Hc96gqhzIkkELVjGQKDp2/L+7BTFG5ODxGYWd2VX/H"
                                       "+hdZRqf0iUWRNuhxlequ68kkwMaE6ymBw==")

        verifying_key = VerifyingKey(headv1.pubkey)
        self.assertTrue(verifying_key.verify_ws2p_head(headv1))
Exemple #10
0
 def handle_new_node(self, peer):
     key = VerifyingKey(peer.pubkey)
     if key.verify_document(peer):
         if len(self._discovery_stack) < 1000 \
             and peer.signatures[0] not in [p.signatures[0] for p in self._discovery_stack]:
             logging.debug("Stacking new peer document : {0}".format(peer.pubkey))
             self._discovery_stack.append(peer)
     else:
         logging.debug("Wrong document received : {0}".format(peer.signed_raw()))
Exemple #11
0
 def handle_new_node(self, peer):
     key = VerifyingKey(peer.pubkey)
     if key.verify_document(peer):
         if len(self._discovery_stack) < 1000 \
            and peer.blockUID.number + 2400 > self.current_buid().number \
            and peer.signatures not in [p.signatures[0] for p in self._discovery_stack]:
             self._logger.debug("Stacking new peer document : {0}".format(peer.pubkey))
             self._discovery_stack.append(peer)
     else:
         self._logger.debug("Wrong document received : {0}".format(peer.signed_raw()))
    def test_get_verified_data(self):
        sign_key = SigningKey.from_credentials("alice", "password", ScryptParams())

        message = "Hello world with utf-8 chars like éàè !"
        # Sign the message, the signed string is the message itself plus the
        # signature
        signed_message = sign_key.sign(bytes(message, 'utf-8'))  # type: bytes

        # Verify the message!
        verifier = VerifyingKey(sign_key.pubkey)
        verified_message = verifier.get_verified_data(signed_message)
        self.assertEqual(message, verified_message.decode('utf-8'))
    def test_peer_signature(self):
        signed_raw = """Version: 2
Type: Peer
Currency: test_net
PublicKey: 8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU
Block: 2086-00005D6FC6E22FB308D8815A565A01C66FFB7DC761D616DE0698F6322565F1D6
Endpoints:
BASIC_MERKLED_API testnet.duniter.inso.ovh 80
4aQ/sfqFAFUeYkkLdC2OfgXqTBjCIcMptpR/GIlGqbe4aFVJcy9NEVAFx7sHiLuAb+VNnec3XHHC+xOk3MLzDA==
"""""
        peer = Peer.from_signed_raw(signed_raw)
        pubkey = "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU"
        verifying_key = VerifyingKey(pubkey)
        self.assertTrue(verifying_key.verify_document(peer))
    def test_peer_signature(self):
        signed_raw = """Version: 2
Type: Peer
Currency: test_net
PublicKey: 8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU
Block: 2086-00005D6FC6E22FB308D8815A565A01C66FFB7DC761D616DE0698F6322565F1D6
Endpoints:
BASIC_MERKLED_API testnet.duniter.inso.ovh 80
4aQ/sfqFAFUeYkkLdC2OfgXqTBjCIcMptpR/GIlGqbe4aFVJcy9NEVAFx7sHiLuAb+VNnec3XHHC+xOk3MLzDA==
""" ""
        peer = Peer.from_signed_raw(signed_raw)
        pubkey = "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU"
        verifying_key = VerifyingKey(pubkey)
        self.assertTrue(verifying_key.verify_document(peer))
Exemple #15
0
    def test_transaction_document(self):
        transaction_document = """TX:10:1:6:6:2:1:0
278644-000004546FCB16F2851A8B6D1066219B0EBB3580C882850411618E35241719EA
8rYgYd64F2Y3Gfxwohjrc7K3zSNpDz79yNxRJorUwmse
1011:0:D:8rYgYd64F2Y3Gfxwohjrc7K3zSNpDz79yNxRJorUwmse:278052
1011:0:D:8rYgYd64F2Y3Gfxwohjrc7K3zSNpDz79yNxRJorUwmse:278333
1011:0:D:8rYgYd64F2Y3Gfxwohjrc7K3zSNpDz79yNxRJorUwmse:278609
1011:0:T:4116D06975AE613C96183390FC5A2BE2561F36C86F5CFE69EB23E3B517AA6F17:1
20330:0:T:56D8A0ACE3BC7E1173FF8BFB8A97A2F3353B6F3AEBCF4923C8BE2E81FDCC0685:1
11121:0:T:7CC29A8707D72936ED0EB9C618CEB3278DFAB4647B6639AA09620FA31EAD95D8:1
0:SIG(0)
1:SIG(0)
2:SIG(0)
3:SIG(0)
4:SIG(0)
5:SIG(0)
30000:0:SIG(2mKmto464oWCVsRgcYM6vpwsLsGk6MhMtrBKf7DTAU34)
5495:0:SIG(8rYgYd64F2Y3Gfxwohjrc7K3zSNpDz79yNxRJorUwmse)
Solde huile Millepertuis
rgjOmzFH5h+hkDbJLk1b88X7Z83HMgTa5rBckeMSdF/yZtItN3zMn09MphcXjffdrKcK+MebwoisLJqV+jXrDg==
"""
        tx = Transaction.from_compact("g1", transaction_document)
        verifying_key = VerifyingKey(tx.issuers[0])
        self.assertTrue(verifying_key.verify_document(tx))
 def test_from_sign_to_verify(self):
     sign_key = SigningKey("saltsalt", "passwordpassword")
     verify_key = VerifyingKey(sign_key.pubkey)
     self.assertEqual(verify_key.vk, sign_key.vk)
Exemple #17
0
from duniterpy.key import VerifyingKey

if __name__ == '__main__':

    if len(sys.argv) < 2:
        print("""
        Usage:
            python verify_signed_message.py SIGNED_MESSAGE_FILEPATH
        """)

    # capture signed message filepath argument
    signed_message_path = sys.argv[1]

    # ask public key of the signer
    pubkeyBase58 = input("Enter public key of the message issuer: ")

    # open signed message file
    with open(signed_message_path, 'rb') as file_handler:
        signed_message = file_handler.read()

    # Verify the message!
    verifier = VerifyingKey(pubkeyBase58)
    try:
        message = verifier.get_verified_data(signed_message).decode('utf-8')
        print("Signature valid for this message:")
    except ValueError as error:
        message = str(error)

    print(message)
 def test_from_sign_to_verify(self):
     sign_key = SigningKey("saltsalt", "passwordpassword", ScryptParams(4096, 16, 1))
     verify_key = VerifyingKey(sign_key.pubkey)
     self.assertEqual(verify_key.vk, sign_key.vk)
    def parse(ascii_armor_message: str, signing_key: Optional[SigningKey] = None,
              sender_pubkeys: Optional[List[str]] = None) -> dict:
        """
        Return a dict with parsed content (decrypted message, signature validation) ::

            {
               'message':
                   {
                       'fields': {},
                       'content': str,
                    },
               'signatures': [
                   {'pubkey': str, 'valid': bool, fields: {}}
               ]
           }

        :param ascii_armor_message: The Ascii Armor Message Block including BEGIN and END headers
        :param signing_key: Optional Libnacl SigningKey instance to decrypt message
        :param sender_pubkeys: Optional sender's public keys list to verify signatures
        :exception libnacl.CryptError: Raise an exception if keypair fail to decrypt the message
        :exception MissingSigningKeyException: Raise an exception if no keypair given for encrypted message

        :return:
        """
        # regex patterns
        regex_begin_message = compile(BEGIN_MESSAGE_HEADER)
        regex_end_message = compile(END_MESSAGE_HEADER)
        regex_begin_signature = compile(BEGIN_SIGNATURE_HEADER)
        regex_end_signature = compile(END_SIGNATURE_HEADER)
        regex_fields = compile("^(Version|Comment): (.+)$")

        # trim message to get rid of empty lines
        ascii_armor_message = ascii_armor_message.strip(" \t\n\r")

        # init vars
        parsed_result = {
            'message':
                {
                    'fields': {},
                    'content': '',
                },
            'signatures': []
        }  # type: Dict[str, Any]
        cursor_status = 0
        message = ''
        signatures_index = 0

        # parse each line...
        for line in ascii_armor_message.splitlines(True):

            # if begin message header detected...
            if regex_begin_message.match(line):
                cursor_status = ON_MESSAGE_FIELDS
                continue

            # if we are on the fields lines...
            if cursor_status == ON_MESSAGE_FIELDS:
                # parse field
                m = regex_fields.match(line.strip())
                if m:
                    # capture field
                    msg_field_name = m.groups()[0]
                    msg_field_value = m.groups()[1]
                    parsed_result['message']['fields'][msg_field_name] = msg_field_value
                    continue

                # if blank line...
                if line.strip("\n\t\r ") == '':
                    cursor_status = ON_MESSAGE_CONTENT
                    continue

            # if we are on the message content lines...
            if cursor_status == ON_MESSAGE_CONTENT:

                # if a header is detected, end of message content...
                if line.startswith(HEADER_PREFIX):

                    # if field Version is present, the message is encrypted...
                    if 'Version' in parsed_result['message']['fields']:

                        # If keypair instance to decrypt not given...
                        if signing_key is None:
                            # SigningKey keypair is mandatory to decrypt the message...
                            raise PARSER_MISSING_SIGNING_KEY_EXCEPTION

                        # decrypt message with secret key from keypair
                        message = AsciiArmor._decrypt(message, signing_key)

                    # save message content in result
                    parsed_result['message']['content'] = message

                    # if message end header...
                    if regex_end_message.match(line):
                        # stop parsing
                        break

                    # if signature begin header...
                    if regex_begin_signature.match(line):
                        # add signature dict in list
                        parsed_result['signatures'].append({
                            'fields': {}
                        })
                        cursor_status = ON_SIGNATURE_FIELDS
                        continue
                else:
                    # if field Version is present, the message is encrypted...
                    if 'Version' in parsed_result['message']['fields']:
                        # concatenate encrypted line to message content
                        message += line
                    else:
                        # concatenate cleartext striped dash escaped line to message content
                        message += AsciiArmor._parse_dash_escaped_line(line)

            # if we are on a signature fields zone...
            if cursor_status == ON_SIGNATURE_FIELDS:

                # parse field
                m = regex_fields.match(line.strip())
                if m:
                    # capture field
                    sig_field_name = m.groups()[0]
                    sig_field_value = m.groups()[1]
                    parsed_result['signatures'][signatures_index]['fields'][sig_field_name] = sig_field_value
                    continue

                # if blank line...
                if line.strip("\n\t\r ") == '':
                    cursor_status = ON_SIGNATURE_CONTENT
                    continue

            # if we are on the signature content...
            if cursor_status == ON_SIGNATURE_CONTENT:

                # if no public keys provided...
                if sender_pubkeys is None:
                    # raise exception
                    raise PARSER_MISSING_PUBLIC_KEYS_EXCEPTION

                # if end signature header detected...
                if regex_end_signature.match(line):
                    # end of parsing
                    break

                # if begin signature header detected...
                if regex_begin_signature.match(line):
                    signatures_index += 1
                    cursor_status = ON_SIGNATURE_FIELDS
                    continue

                for pubkey in sender_pubkeys:
                    verifier = VerifyingKey(pubkey)
                    signature = base64.b64decode(line)
                    parsed_result['signatures'][signatures_index]['pubkey'] = pubkey
                    try:
                        libnacl.crypto_sign_verify_detached(signature, message, verifier.vk)
                        parsed_result['signatures'][signatures_index]['valid'] = True
                    except ValueError:
                        parsed_result['signatures'][signatures_index]['valid'] = False

        return parsed_result
 def test_from_credentials(self):
     sign_key = SigningKey.from_credentials("alice", "password",
                                            ScryptParams())
     verify_key = VerifyingKey(sign_key.pubkey)
     self.assertEqual(verify_key.vk, sign_key.vk)