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
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 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"))
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)
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()
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()
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)