def test_unsigned_announcement(self):
        """
        An incorrectly signed announcement is not delivered to subscribers.
        """
        private_key, public_key = ed25519.create_signing_keypair()
        public_key_str = ed25519.string_from_verifying_key(public_key)

        ic = IntroducerClient(
            Tub(),
            "pb://",
            u"fake_nick",
            "0.0.0",
            "1.2.3",
            (0, u"i am a nonce"),
            FilePath(self.mktemp()),
        )
        received = {}
        ic.subscribe_to("good-stuff", partial(setitem, received))

        # Deliver a good message to prove our test code is valid.
        ann = {"service-name": "good-stuff", "payload": "hello"}
        ann_t = sign_to_foolscap(ann, private_key)
        ic.got_announcements([ann_t])

        self.assertEqual(
            {public_key_str[len("pub-"):]: ann},
            received,
        )
        received.clear()

        # Now deliver one without a valid signature and observe that it isn't
        # delivered to the subscriber.
        ann = {"service-name": "good-stuff", "payload": "bad stuff"}
        (msg, sig, key) = sign_to_foolscap(ann, private_key)
        # Drop a base32 word from the middle of the key to invalidate the
        # signature.
        sig_a = bytearray(sig)
        sig_a[20:22] = []
        sig = bytes(sig_a)
        ann_t = (msg, sig, key)
        ic.got_announcements([ann_t])

        # The received announcements dict should remain empty because we
        # should not receive the announcement with the invalid signature.
        self.assertEqual(
            {},
            received,
        )
    def test_sign(self):
        ann = {"key1": "value1"}
        sk_s,vk_s = keyutil.make_keypair()
        sk,ignored = keyutil.parse_privkey(sk_s)
        ann_t = sign_to_foolscap(ann, sk)
        (msg, sig, key) = ann_t
        self.failUnlessEqual(type(msg), type("".encode("utf-8"))) # bytes
        self.failUnlessEqual(json.loads(msg.decode("utf-8")), ann)
        self.failUnless(sig.startswith("v0-"))
        self.failUnless(key.startswith("v0-"))
        (ann2,key2) = unsign_from_foolscap(ann_t)
        self.failUnlessEqual(ann2, ann)
        self.failUnlessEqual("pub-"+key2, vk_s)

        # not signed
        self.failUnlessRaises(UnknownKeyError,
                              unsign_from_foolscap, (msg, None, key))
        self.failUnlessRaises(UnknownKeyError,
                              unsign_from_foolscap, (msg, sig, None))
        # bad signature
        bad_ann = {"key1": "value2"}
        bad_msg = json.dumps(bad_ann).encode("utf-8")
        self.failUnlessRaises(keyutil.BadSignatureError,
                              unsign_from_foolscap, (bad_msg,sig,key))

        # unrecognized signatures
        self.failUnlessRaises(UnknownKeyError,
                              unsign_from_foolscap, (bad_msg,"v999-sig",key))
        self.failUnlessRaises(UnknownKeyError,
                              unsign_from_foolscap, (bad_msg,sig,"v999-key"))
def make_ann_t(ic, furl, privkey, seqnum):
    assert privkey
    ann_d = ic.create_announcement_dict("storage", make_ann(furl))
    ann_d["seqnum"] = seqnum
    ann_d["nonce"] = "nonce"
    ann_t = sign_to_foolscap(ann_d, privkey)
    return ann_t
Beispiel #4
0
def make_ann_t(ic, furl, privkey, seqnum):
    assert privkey
    ann_d = ic.create_announcement_dict("storage", make_ann(furl))
    ann_d["seqnum"] = seqnum
    ann_d["nonce"] = "nonce"
    ann_t = sign_to_foolscap(ann_d, privkey)
    return ann_t
Beispiel #5
0
    def test_sign(self):
        ann = {"key1": "value1"}
        sk_s, vk_s = keyutil.make_keypair()
        sk, ignored = keyutil.parse_privkey(sk_s)
        ann_t = sign_to_foolscap(ann, sk)
        (msg, sig, key) = ann_t
        self.failUnlessEqual(type(msg), type("".encode("utf-8")))  # bytes
        self.failUnlessEqual(json.loads(msg.decode("utf-8")), ann)
        self.failUnless(sig.startswith("v0-"))
        self.failUnless(key.startswith("v0-"))
        (ann2, key2) = unsign_from_foolscap(ann_t)
        self.failUnlessEqual(ann2, ann)
        self.failUnlessEqual("pub-" + key2, vk_s)

        # not signed
        self.failUnlessRaises(UnknownKeyError, unsign_from_foolscap,
                              (msg, None, key))
        self.failUnlessRaises(UnknownKeyError, unsign_from_foolscap,
                              (msg, sig, None))
        # bad signature
        bad_ann = {"key1": "value2"}
        bad_msg = json.dumps(bad_ann).encode("utf-8")
        self.failUnlessRaises(keyutil.BadSignatureError, unsign_from_foolscap,
                              (bad_msg, sig, key))

        # unrecognized signatures
        self.failUnlessRaises(UnknownKeyError, unsign_from_foolscap,
                              (bad_msg, "v999-sig", key))
        self.failUnlessRaises(UnknownKeyError, unsign_from_foolscap,
                              (bad_msg, sig, "v999-key"))
Beispiel #6
0
    def test_sign(self):
        ann = {"key1": "value1"}
        private_key, public_key = ed25519.create_signing_keypair()
        public_key_str = ed25519.string_from_verifying_key(public_key)
        ann_t = sign_to_foolscap(ann, private_key)
        (msg, sig, key) = ann_t
        self.failUnlessEqual(type(msg), type("".encode("utf-8")))  # bytes
        self.failUnlessEqual(json.loads(msg.decode("utf-8")), ann)
        self.failUnless(sig.startswith("v0-"))
        self.failUnless(key.startswith("v0-"))
        (ann2, key2) = unsign_from_foolscap(ann_t)
        self.failUnlessEqual(ann2, ann)
        self.failUnlessEqual("pub-" + key2, public_key_str)

        # not signed
        self.failUnlessRaises(UnknownKeyError, unsign_from_foolscap,
                              (msg, None, key))
        self.failUnlessRaises(UnknownKeyError, unsign_from_foolscap,
                              (msg, sig, None))
        # bad signature
        bad_ann = {"key1": "value2"}
        bad_msg = json.dumps(bad_ann).encode("utf-8")
        self.failUnlessRaises(BadSignature, unsign_from_foolscap,
                              (bad_msg, sig, key))

        # unrecognized signatures
        self.failUnlessRaises(UnknownKeyError, unsign_from_foolscap,
                              (bad_msg, "v999-sig", key))
        self.failUnlessRaises(UnknownKeyError, unsign_from_foolscap,
                              (bad_msg, sig, "v999-key"))
Beispiel #7
0
 def create_announcement(self, service_name, ann, signing_key):
     full_ann = {
         "version": 0,
         "nickname": self._nickname,
         "app-versions": self._app_versions,
         "my-version": self._my_version,
         "oldest-supported": self._oldest_supported,
         "service-name": service_name,
     }
     full_ann.update(ann)
     return sign_to_foolscap(full_ann, signing_key)
Beispiel #8
0
    def create_announcement(self, service_name, ann, signing_key):
        full_ann = { "version": 0,
                     "nickname": self._nickname,
                     "app-versions": self._app_versions,
                     "my-version": self._my_version,
                     "oldest-supported": self._oldest_supported,

                     "service-name": service_name,
                     }
        full_ann.update(ann)
        return sign_to_foolscap(full_ann, signing_key)
Beispiel #9
0
    def publish(self, service_name, ann, signing_key):
        # we increment the seqnum every time we publish something new
        current_seqnum, current_nonce = self._sequencer()

        ann_d = self.create_announcement_dict(service_name, ann)
        self._outbound_announcements[service_name] = ann_d

        # publish all announcements with the new seqnum and nonce
        for service_name,ann_d in self._outbound_announcements.items():
            ann_d["seqnum"] = current_seqnum
            ann_d["nonce"] = current_nonce
            ann_t = sign_to_foolscap(ann_d, signing_key)
            self._published_announcements[service_name] = ann_t
        self._maybe_publish()
Beispiel #10
0
    def publish(self, service_name, ann, signing_key):
        # we increment the seqnum every time we publish something new
        current_seqnum, current_nonce = self._sequencer()

        ann_d = self.create_announcement_dict(service_name, ann)
        self._outbound_announcements[service_name] = ann_d

        # publish all announcements with the new seqnum and nonce
        for service_name, ann_d in self._outbound_announcements.items():
            ann_d["seqnum"] = current_seqnum
            ann_d["nonce"] = current_nonce
            ann_t = sign_to_foolscap(ann_d, signing_key)
            self._published_announcements[service_name] = ann_t
        self._maybe_publish()
Beispiel #11
0
    def create_announcement(self, service_name, ann, signing_key, _mod=None):
        full_ann = { "version": 0,
                     "seqnum": time.time(),
                     "nickname": self._nickname,
                     "app-versions": self._app_versions,
                     "my-version": self._my_version,
                     "oldest-supported": self._oldest_supported,

                     "service-name": service_name,
                     }
        full_ann.update(ann)
        if _mod:
            full_ann = _mod(full_ann) # for unit tests
        return sign_to_foolscap(full_ann, signing_key)