def test_verify_challenge_tx_sequence_not_zero(self):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE
        anchor_name = "SDF"
        now = int(time.time())
        nonce = os.urandom(48)
        nonce_encoded = base64.b64encode(nonce)
        server_account = Account(server_kp.public_key, 10086)
        challenge_te = (
            TransactionBuilder(server_account, network_passphrase, 100)
            .append_manage_data_op(
                data_name="{} auth".format(anchor_name),
                data_value=nonce_encoded,
                source=client_kp.public_key,
            )
            .add_time_bounds(now, now + 900)
            .build()
        )

        challenge_te.sign(server_kp)
        challenge_te.sign(client_kp)
        challenge_tx_signed = challenge_te.to_xdr()

        with pytest.raises(
            InvalidSep10ChallengeError,
            match="The transaction sequence number should be zero.",
        ):
            verify_challenge_transaction(
                challenge_tx_signed, server_kp.public_key, network_passphrase
            )
    def test_verify_challenge_tx_operation_value_is_none(self):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE
        home_domain = "example.com"
        now = int(time.time())
        nonce_encoded = None
        server_account = Account(server_kp.public_key, -1)
        challenge_te = (TransactionBuilder(
            server_account, network_passphrase, 100).append_manage_data_op(
                data_name="{} auth".format(home_domain),
                data_value=nonce_encoded,
                source=client_kp.public_key,
            ).add_time_bounds(now, now + 900).build())

        challenge_te.sign(server_kp)
        challenge_te.sign(client_kp)
        challenge_tx_signed = challenge_te.to_xdr()

        with pytest.raises(
                InvalidSep10ChallengeError,
                match="Operation value should not be null.",
        ):
            verify_challenge_transaction(
                challenge_tx_signed,
                server_kp.public_key,
                home_domain,
                network_passphrase,
            )
    def test_verify_challenge_tx_dont_contains_timebound(self):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE
        anchor_name = "SDF"
        nonce = os.urandom(48)
        nonce_encoded = base64.b64encode(nonce)
        server_account = Account(server_kp.public_key, -1)
        challenge_te = (
            TransactionBuilder(server_account, network_passphrase, 100)
            .append_manage_data_op(
                data_name="{} auth".format(anchor_name),
                data_value=nonce_encoded,
                source=client_kp.public_key,
            )
            .build()
        )

        challenge_te.sign(server_kp)
        challenge_te.sign(client_kp)
        challenge_tx_signed = challenge_te.to_xdr()

        with pytest.raises(
            InvalidSep10ChallengeError, match="Transaction requires timebounds."
        ):
            verify_challenge_transaction(
                challenge_tx_signed, server_kp.public_key, network_passphrase
            )
    def test_verify_challenge_tx_not_within_range_of_the_specified_timebounds(self):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE
        anchor_name = "SDF"
        now = int(time.time())
        nonce = os.urandom(48)
        nonce_encoded = base64.b64encode(nonce)
        server_account = Account(server_kp.public_key, -1)
        challenge_te = (
            TransactionBuilder(server_account, network_passphrase, 100)
            .append_manage_data_op(
                data_name="{} auth".format(anchor_name),
                data_value=nonce_encoded,
                source=client_kp.public_key,
            )
            .add_time_bounds(now - 100, now - 50)
            .build()
        )

        challenge_te.sign(server_kp)
        challenge_te.sign(client_kp)
        challenge_tx_signed = challenge_te.to_xdr()

        with pytest.raises(
            InvalidSep10ChallengeError,
            match="Transaction is not within range of the specified timebounds.",
        ):
            verify_challenge_transaction(
                challenge_tx_signed, server_kp.public_key, network_passphrase
            )
    def test_verify_challenge_tx_source_is_different_to_server_account_id(
            self):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        network_passphrase = Network.TESTNET_NETWORK_PASSPHRASE
        anchor_name = "SDF"

        challenge = build_challenge_transaction(server_kp.secret,
                                                client_kp.public_key,
                                                anchor_name,
                                                network_passphrase)

        transaction = TransactionEnvelope.from_xdr(challenge,
                                                   Network(network_passphrase))
        transaction.sign(client_kp)

        challenge_tx = transaction.to_xdr()
        with pytest.raises(
                InvalidSep10ChallengeError,
                match=
                "Transaction source account is not equal to server's account.",
        ):
            verify_challenge_transaction(challenge_tx,
                                         Keypair.random().public_key,
                                         network_passphrase)
    def test_verify_challenge_tx_transaction_is_not_signed_by_the_server(self):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE
        anchor_name = "SDF"
        timeout = 900

        now = int(time.time())
        server_keypair = Keypair.from_secret(server_kp.secret)
        server_account = Account(account_id=server_keypair.public_key, sequence=-1)
        transaction_builder = TransactionBuilder(
            server_account, network_passphrase, 100
        )
        transaction_builder.add_time_bounds(min_time=now, max_time=now + timeout)
        nonce = os.urandom(48)
        nonce_encoded = base64.b64encode(nonce)
        transaction_builder.append_manage_data_op(
            data_name="{} auth".format(anchor_name),
            data_value=nonce_encoded,
            source=client_kp.public_key,
        )
        challenge = transaction_builder.build().to_xdr()

        transaction = TransactionEnvelope.from_xdr(challenge, network_passphrase)
        transaction.sign(client_kp)
        challenge_tx = transaction.to_xdr()
        with pytest.raises(
            InvalidSep10ChallengeError,
            match="Transaction not signed by server: {}".format(server_kp.public_key),
        ):
            verify_challenge_transaction(
                challenge_tx, server_kp.public_key, network_passphrase
            )
    def test_verify_challenge_tx_contain_subsequent_manage_data_ops_without_the_server_account_as_the_source_account(
        self, ):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE
        home_domain = "example.com"
        now = int(time.time())
        nonce = os.urandom(48)
        nonce_encoded = base64.b64encode(nonce)
        server_account = Account(server_kp.public_key, -1)
        challenge_te = (TransactionBuilder(
            server_account, network_passphrase, 100).append_manage_data_op(
                data_name="{} auth".format(home_domain),
                data_value=nonce_encoded,
                source=client_kp.public_key,
            ).append_manage_data_op(
                data_name="data key",
                data_value="data value",
                source=client_kp.public_key,
            ).add_time_bounds(now, now + 900).build())

        challenge_te.sign(server_kp)
        challenge_te.sign(client_kp)
        challenge_tx_signed = challenge_te.to_xdr()

        with pytest.raises(
                InvalidSep10ChallengeError,
                match="The transaction has operations that are unrecognized.",
        ):
            verify_challenge_transaction(
                challenge_tx_signed,
                server_kp.public_key,
                home_domain,
                network_passphrase,
            )
    def test_verify_challenge_tx_operation_value_is_not_a_64_bytes_base64_string(
            self):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE
        anchor_name = "SDF"
        now = int(time.time())
        nonce = os.urandom(32)
        server_account = Account(server_kp.public_key, -1)
        challenge_te = (TransactionBuilder(
            server_account, network_passphrase, 100).append_manage_data_op(
                data_name="{} auth".format(anchor_name),
                data_value=nonce,
                source=client_kp.public_key,
            ).add_time_bounds(now, now + 300).build())

        challenge_te.sign(server_kp)
        challenge_te.sign(client_kp)
        challenge_tx_signed = challenge_te.to_xdr()

        with pytest.raises(
                InvalidSep10ChallengeError,
                match=
                "Operation value should be a 64 bytes base64 random string.",
        ):
            verify_challenge_transaction(challenge_tx_signed,
                                         server_kp.public_key,
                                         network_passphrase)
    def test_verify_challenge_tx_contain_subsequent_manage_data_ops_with_server_account_as_source_account(
        self, ):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE
        domain_name = "example.com"
        now = int(time.time())
        nonce = os.urandom(48)
        nonce_encoded = base64.b64encode(nonce)
        server_account = Account(server_kp.public_key, -1)
        challenge_te = (TransactionBuilder(
            server_account, network_passphrase, 100).append_manage_data_op(
                data_name="{} auth".format(domain_name),
                data_value=nonce_encoded,
                source=client_kp.public_key,
            ).append_manage_data_op(
                data_name="data key",
                data_value="data value",
                source=server_kp.public_key,
            ).add_time_bounds(now, now + 900).build())

        challenge_te.sign(server_kp)
        challenge_te.sign(client_kp)
        challenge_tx_signed = challenge_te.to_xdr()

        verify_challenge_transaction(
            challenge_tx_signed,
            server_kp.public_key,
            domain_name,
            network_passphrase,
        )
Пример #10
0
    def test_verify_challenge_tx_contains_infinite_timebounds(self):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE
        domain_name = "example.com"
        now = int(time.time())
        nonce = os.urandom(48)
        nonce_encoded = base64.b64encode(nonce)
        server_account = Account(server_kp.public_key, -1)
        challenge_te = (
            TransactionBuilder(server_account, network_passphrase, 100)
            .append_manage_data_op(
                data_name="{} auth".format(domain_name),
                data_value=nonce_encoded,
                source=client_kp.public_key,
            )
            .add_time_bounds(now, 0)
            .build()
        )

        challenge_te.sign(server_kp)
        challenge_te.sign(client_kp)
        challenge_tx_signed = challenge_te.to_xdr()

        with pytest.raises(
            InvalidSep10ChallengeError,
            match="Transaction requires non-infinite timebounds.",
        ):
            verify_challenge_transaction(
                challenge_tx_signed,
                server_kp.public_key,
                domain_name,
                network_passphrase,
            )
Пример #11
0
    def test_verify_challenge_transaction_domain_name_mismatch_raise(self):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        timeout = 600
        network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE
        domain_name = "example.com"
        invalid_domain_name = "invalid_example.com"

        challenge = build_challenge_transaction(
            server_secret=server_kp.secret,
            client_account_id=client_kp.public_key,
            domain_name=domain_name,
            network_passphrase=network_passphrase,
            timeout=timeout,
        )

        transaction = TransactionEnvelope.from_xdr(challenge, network_passphrase)
        transaction.sign(client_kp)
        challenge_tx = transaction.to_xdr()
        with pytest.raises(
            InvalidSep10ChallengeError,
            match="The transaction's operation key name "
            "does not include the expected home domain.",
        ):
            verify_challenge_transaction(
                challenge_tx,
                server_kp.public_key,
                invalid_domain_name,
                network_passphrase,
            )
Пример #12
0
    def test_verify_challenge_tx_donot_contain_managedata_operation(self):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE
        domain_name = "example.com"
        now = int(time.time())
        server_account = Account(server_kp.public_key, -1)
        challenge_te = (
            TransactionBuilder(server_account, network_passphrase, 100)
            .append_set_options_op()
            .add_time_bounds(now, now + 900)
            .build()
        )

        challenge_te.sign(server_kp)
        challenge_te.sign(client_kp)
        challenge_tx_signed = challenge_te.to_xdr()

        with pytest.raises(
            InvalidSep10ChallengeError, match="Operation type should be ManageData."
        ):
            verify_challenge_transaction(
                challenge_tx_signed,
                server_kp.public_key,
                domain_name,
                network_passphrase,
            )
    def test_verify_challenge_tx_contain_zero_op(self, ):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE
        domain_name = "example.com"
        now = int(time.time())
        nonce = os.urandom(48)
        server_account = Account(server_kp.public_key, -1)
        challenge_te = (TransactionBuilder(server_account, network_passphrase,
                                           100).add_time_bounds(
                                               now, now + 900).build())

        challenge_te.sign(server_kp)
        challenge_te.sign(client_kp)
        challenge_tx_signed = challenge_te.to_xdr()

        with pytest.raises(
                InvalidSep10ChallengeError,
                match="Transaction should contain at least one operation.",
        ):
            verify_challenge_transaction(
                challenge_tx_signed,
                server_kp.public_key,
                domain_name,
                network_passphrase,
            )
    def test_verify_challenge_tx_contain_subsequent_ops_that_secend_op_no_source_account(
        self, ):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE
        domain_name = "example.com"
        now = int(time.time())
        nonce = os.urandom(48)
        nonce_encoded = base64.b64encode(nonce)
        server_account = Account(server_kp.public_key, -1)
        challenge_te = (TransactionBuilder(
            server_account, network_passphrase, 100).append_manage_data_op(
                data_name="{} auth".format(domain_name),
                data_value=nonce_encoded,
                source=client_kp.public_key,
            ).append_manage_data_op(data_name="Hello",
                                    data_value="world").add_time_bounds(
                                        now, now + 900).build())

        challenge_te.sign(server_kp)
        challenge_te.sign(client_kp)
        challenge_tx_signed = challenge_te.to_xdr()

        with pytest.raises(
                InvalidSep10ChallengeError,
                match="Operation should have a source account.",
        ):
            verify_challenge_transaction(
                challenge_tx_signed,
                server_kp.public_key,
                domain_name,
                network_passphrase,
            )
Пример #15
0
def _validate_envelope_xdr(envelope_xdr):
    """
    Validate the provided TransactionEnvelope XDR (base64 string). Return the
    appropriate error if it fails, else the empty string.
    """
    try:
        verify_challenge_transaction(challenge_transaction=envelope_xdr,
                                     server_account_id=settings.STELLAR_DISTRIBUTION_ACCOUNT_ADDRESS,
                                     network_passphrase=settings.STELLAR_NETWORK_PASSPHRASE)
    except InvalidSep10ChallengeError as err:
        return str(err)
    return ""
    def test_verify_challenge_tx_donot_contain_any_operation(self):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE
        now = int(time.time())
        server_account = Account(server_kp.public_key, -1)
        challenge_te = (TransactionBuilder(server_account, network_passphrase,
                                           100).add_time_bounds(
                                               now, now + 300).build())

        challenge_te.sign(server_kp)
        challenge_te.sign(client_kp)
        challenge_tx_signed = challenge_te.to_xdr()

        with pytest.raises(
                InvalidSep10ChallengeError,
                match="Transaction requires a single ManageData operation.",
        ):
            verify_challenge_transaction(challenge_tx_signed,
                                         server_kp.public_key,
                                         network_passphrase)
    def test_verify_challenge_transaction(self):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        timeout = 600
        network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE
        anchor_name = "SDF"

        challenge = build_challenge_transaction(
            server_secret=server_kp.secret,
            client_account_id=client_kp.public_key,
            anchor_name=anchor_name,
            network_passphrase=network_passphrase,
            timeout=timeout,
        )

        transaction = TransactionEnvelope.from_xdr(challenge, network_passphrase)
        transaction.sign(client_kp)
        challenge_tx = transaction.to_xdr()
        verify_challenge_transaction(
            challenge_tx, server_kp.public_key, network_passphrase
        )
    def test_verify_challenge_tx_transaction_is_not_signed_by_the_client(self):
        server_kp = Keypair.random()
        client_account_id = "GBDIT5GUJ7R5BXO3GJHFXJ6AZ5UQK6MNOIDMPQUSMXLIHTUNR2Q5CFNF"
        timeout = 600
        network_passphrase = Network.TESTNET_NETWORK_PASSPHRASE
        anchor_name = "SDF"

        challenge = build_challenge_transaction(
            server_secret=server_kp.secret,
            client_account_id=client_account_id,
            anchor_name=anchor_name,
            network_passphrase=network_passphrase,
            timeout=timeout,
        )

        with pytest.raises(
                InvalidSep10ChallengeError,
                match="Transaction not signed by any client signer.",
        ):
            verify_challenge_transaction(challenge, server_kp.public_key,
                                         network_passphrase)
    def test_verify_challenge_transaction_with_multi_domain_names(self):
        server_kp = Keypair.random()
        client_kp = Keypair.random()
        timeout = 600
        network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE
        home_domain = "example.com"

        challenge = build_challenge_transaction(
            server_secret=server_kp.secret,
            client_account_id=client_kp.public_key,
            home_domain=home_domain,
            network_passphrase=network_passphrase,
            timeout=timeout,
        )

        transaction = TransactionEnvelope.from_xdr(challenge,
                                                   network_passphrase)
        transaction.sign(client_kp)
        challenge_tx = transaction.to_xdr()
        verify_challenge_transaction(
            challenge_tx, server_kp.public_key,
            ["example.com2", "example.com1", home_domain], network_passphrase)