예제 #1
0
    def test_bad_ristretto_redemption(self, voucher, counter, extra_tokens):
        """
        If the issuer returns a successful result with an invalid proof then
        ``RistrettoRedeemer.redeem`` returns a ``Deferred`` that fires with a
        ``Failure`` wrapping ``SecurityException``.
        """
        num_tokens = counter + extra_tokens
        signing_key = random_signing_key()
        issuer = RistrettoRedemption(signing_key)

        # Make it lie about the public key it is using.  This causes the proof
        # to be invalid since it proves the signature was made with a
        # different key than reported in the response.
        issuer.public_key = PublicKey.from_signing_key(random_signing_key())

        treq = treq_for_loopback_ristretto(issuer)
        redeemer = RistrettoRedeemer(treq, NOWHERE)
        random_tokens = redeemer.random_tokens_for_voucher(
            voucher, counter, num_tokens)
        d = redeemer.redeemWithCounter(
            voucher,
            counter,
            random_tokens,
        )
        self.addDetail(u"redeem Deferred", text_content(str(d)))
        self.assertThat(
            d,
            failed(
                AfterPreprocessing(
                    lambda f: f.value,
                    IsInstance(SecurityException),
                ), ),
        )
예제 #2
0
    def test_ristretto_pass_construction(self, voucher, counter, extra_tokens):
        """
        The passes constructed using unblinded tokens and messages pass the
        Ristretto verification check.
        """
        num_tokens = counter + extra_tokens
        message = b"hello world"
        signing_key = random_signing_key()
        issuer = RistrettoRedemption(signing_key)
        treq = treq_for_loopback_ristretto(issuer)
        redeemer = RistrettoRedeemer(treq, NOWHERE)

        random_tokens = redeemer.random_tokens_for_voucher(
            voucher, counter, num_tokens)
        d = redeemer.redeemWithCounter(
            voucher,
            counter,
            random_tokens,
        )

        def unblinded_tokens_to_passes(result):
            passes = redeemer.tokens_to_passes(message,
                                               result.unblinded_tokens)
            return passes

        d.addCallback(unblinded_tokens_to_passes)

        self.assertThat(
            d,
            succeeded(
                AfterPreprocessing(
                    partial(ristretto_verify, signing_key, message),
                    Equals(True),
                ), ),
        )
예제 #3
0
 def test_good_ristretto_redemption(self, voucher, counter, num_tokens):
     """
     If the issuer returns a successful result then
     ``RistrettoRedeemer.redeem`` returns a ``Deferred`` that fires with a
     list of ``UnblindedToken`` instances.
     """
     signing_key = random_signing_key()
     issuer = RistrettoRedemption(signing_key)
     treq = treq_for_loopback_ristretto(issuer)
     redeemer = RistrettoRedeemer(treq, NOWHERE)
     random_tokens = redeemer.random_tokens_for_voucher(
         voucher, counter, num_tokens)
     d = redeemer.redeemWithCounter(
         voucher,
         counter,
         random_tokens,
     )
     self.assertThat(
         d,
         succeeded(
             MatchesStructure(
                 unblinded_tokens=MatchesAll(
                     AllMatch(IsInstance(UnblindedToken), ),
                     HasLength(num_tokens),
                 ),
                 public_key=Equals(
                     PublicKey.from_signing_key(
                         signing_key).encode_base64(), ),
             ), ),
     )
예제 #4
0
 def setUp(self):
     super(PassValidationTests, self).setUp()
     self.clock = Clock()
     # anonymous_storage_server uses time.time() so get our Clock close to
     # the same time so we can do lease expiration calculations more
     # easily.
     self.clock.advance(time())
     self.anonymous_storage_server = self.useFixture(AnonymousStorageServer()).storage_server
     self.signing_key = random_signing_key()
     self.storage_server = ZKAPAuthorizerStorageServer(
         self.anonymous_storage_server,
         self.pass_value,
         self.signing_key,
         self.clock,
     )
예제 #5
0
def run():
    # server setup
    skey = p.random_signing_key()
    pk = p.PublicKey(skey)

    ## signing
    # client prepares a random token and blinding scalar
    token = p.RandomToken()

    # client blinds the token and sends it to the server
    blinded_token = token.blind()

    encoded = blinded_token.marshal_text()
    server_blinded_token = p.BlindedToken.unmarshal_text(encoded)

    # server signs blinded token
    signed_token = skey.sign(server_blinded_token)
예제 #6
0
    def setUp(self):
        super(ShareTests, self).setUp()
        self.canary = LocalReferenceable(None)
        self.anonymous_storage_server = self.useFixture(
            AnonymousStorageServer()).storage_server
        self.signing_key = random_signing_key()

        self.pass_factory = pass_factory(
            get_passes=privacypass_passes(self.signing_key))

        self.server = ZKAPAuthorizerStorageServer(
            self.anonymous_storage_server,
            self.pass_value,
            self.signing_key,
        )
        self.local_remote_server = LocalRemote(self.server)
        self.client = ZKAPAuthorizerStorageClient(
            self.pass_value,
            get_rref=lambda: self.local_remote_server,
            get_passes=self.pass_factory.get,
        )
예제 #7
0
    def setUp(self):
        super(ShareTests, self).setUp()
        self.canary = LocalReferenceable(None)
        self.anonymous_storage_server = self.useFixture(
            AnonymousStorageServer()).storage_server
        self.signing_key = random_signing_key()
        self.spent_passes = 0

        def counting_get_passes(message, count):
            self.spent_passes += count
            return get_passes(message, count, self.signing_key)

        self.server = ZKAPAuthorizerStorageServer(
            self.anonymous_storage_server,
            self.pass_value,
            self.signing_key,
        )
        self.local_remote_server = LocalRemote(self.server)
        self.client = ZKAPAuthorizerStorageClient(
            self.pass_value,
            get_rref=lambda: self.local_remote_server,
            get_passes=counting_get_passes,
        )
예제 #8
0
    def test_rejected_passes_reported(self, storage_index, renew_secret,
                                      cancel_secret, sharenums, size, data):
        """
        Any passes rejected by the storage server are reported with a
        ``MorePassesRequired`` exception sent to the client.
        """
        # Hypothesis causes our storage server to be used many times.  Clean
        # up between iterations.
        cleanup_storage_server(self.anonymous_storage_server)

        num_passes = required_passes(self.pass_value, [size] * len(sharenums))

        # Pick some passes to mess with.
        bad_pass_indexes = data.draw(
            lists(
                integers(
                    min_value=0,
                    max_value=num_passes - 1,
                ),
                min_size=1,
                max_size=num_passes,
                unique=True,
            ), )

        # Make some passes with a key untrusted by the server.
        bad_passes = get_passes(
            allocate_buckets_message(storage_index),
            len(bad_pass_indexes),
            random_signing_key(),
        )

        # Make some passes with a key trusted by the server.
        good_passes = get_passes(
            allocate_buckets_message(storage_index),
            num_passes - len(bad_passes),
            self.signing_key,
        )

        all_passes = []
        for i in range(num_passes):
            if i in bad_pass_indexes:
                all_passes.append(bad_passes.pop())
            else:
                all_passes.append(good_passes.pop())

        # Sanity checks
        self.assertThat(bad_passes, Equals([]))
        self.assertThat(good_passes, Equals([]))
        self.assertThat(all_passes, HasLength(num_passes))

        self.assertThat(
            # Bypass the client handling of MorePassesRequired so we can see
            # it.
            self.local_remote_server.callRemote(
                "allocate_buckets",
                list(pass_.pass_text.encode("ascii") for pass_ in all_passes),
                storage_index,
                renew_secret,
                cancel_secret,
                sharenums,
                size,
                canary=self.canary,
            ),
            failed(
                AfterPreprocessing(
                    lambda f: f.value,
                    Equals(
                        MorePassesRequired(
                            valid_count=num_passes - len(bad_pass_indexes),
                            required_count=num_passes,
                            signature_check_failed=bad_pass_indexes,
                        ), ),
                ), ),
        )
예제 #9
0
 def setUp(self):
     super(ValidationResultTests, self).setUp()
     self.signing_key = random_signing_key()