def handleSenderKeyMessage(self, node): encMessageProtocolEntity = EncryptedMessageProtocolEntity(node) enc_ = encMessageProtocolEntity.getEnc(EncProtocolEntity.TYPE_SKMSG) senderKeyName = SenderKeyName( encMessageProtocolEntity.sender, AxolotlAddress( Jid.denormalize(encMessageProtocolEntity.participant), 0)) groupCipher = GroupCipher(self.store, senderKeyName) try: plaintext = groupCipher.decrypt(enc_.getData()) paddingByte = plaintext[-1] if type(plaintext[-1]) is int else ord( plaintext[-1]) padding = paddingByte & 0xFF self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext[:-padding]) except NoSessionException: logger.warning( "No session for %s, going to send a retry", Jid.denormalize(encMessageProtocolEntity.getAuthor())) retry = RetryOutgoingReceiptProtocolEntity.fromMessageNode( node, self.store.getLocalRegistrationId()) self.toLower(retry.toProtocolTreeNode()) except Exception as ex: # (AttributeError, TypeError) logger.error('Exception in handleSenderKeyMessage: %s' % ex) raise
def handleSenderKeyMessage(self, node): encMessageProtocolEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode( node) enc = encMessageProtocolEntity.getEnc(EncProtocolEntity.TYPE_SKMSG) senderKeyName = SenderKeyName( encMessageProtocolEntity.getFrom(True), AxolotlAddress(encMessageProtocolEntity.getParticipant(False), 0)) groupCipher = GroupCipher(self.store, senderKeyName) try: plaintext = groupCipher.decrypt(enc.getData()) #print("Plain before:", plaintext) padding = ord(plaintext[-1]) & 0xFF plaintext = plaintext[:-padding] plaintext = plaintext.encode() if sys.version_info >= ( 3, 0) else plaintext #print("Plain:", plaintext) self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext) except NoSessionException as e: logger.warning("No session for %s, going to send a retry", encMessageProtocolEntity.getAuthor(False)) retry = RetryOutgoingReceiptProtocolEntity.fromMessageNode( node, self.store.getLocalRegistrationId()) self.toLower(retry.toProtocolTreeNode())
def test_basicRatchet(self): aliceStore = InMemorySenderKeyStore(); bobStore = InMemorySenderKeyStore(); aliceSessionBuilder = GroupSessionBuilder(aliceStore) bobSessionBuilder = GroupSessionBuilder(bobStore) aliceGroupCipher = GroupCipher(aliceStore, GROUP_SENDER) bobGroupCipher = GroupCipher(bobStore, GROUP_SENDER); sentAliceDistributionMessage = aliceSessionBuilder.create(GROUP_SENDER); receivedAliceDistributionMessage = SenderKeyDistributionMessage(serialized = sentAliceDistributionMessage.serialize()); bobSessionBuilder.process(GROUP_SENDER, receivedAliceDistributionMessage) ciphertextFromAlice = aliceGroupCipher.encrypt("smert ze smert") ciphertextFromAlice2 = aliceGroupCipher.encrypt("smert ze smert2") ciphertextFromAlice3 = aliceGroupCipher.encrypt("smert ze smert3") plaintextFromAlice = bobGroupCipher.decrypt(ciphertextFromAlice) try: bobGroupCipher.decrypt(ciphertextFromAlice) raise AssertionError("Should have ratcheted forward!") except DuplicateMessageException as dme: # good pass plaintextFromAlice2 = bobGroupCipher.decrypt(ciphertextFromAlice2) plaintextFromAlice3 = bobGroupCipher.decrypt(ciphertextFromAlice3) self.assertEqual(plaintextFromAlice,"smert ze smert") self.assertEqual(plaintextFromAlice2, "smert ze smert2") self.assertEqual(plaintextFromAlice3, "smert ze smert3")
def handleSenderKeyMessage(self, node): encMessageProtocolEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode(node) enc = encMessageProtocolEntity.getEnc(EncProtocolEntity.TYPE_SKMSG) senderKeyName = SenderKeyName(encMessageProtocolEntity.getFrom(True), AxolotlAddress(encMessageProtocolEntity.getParticipant(False), 0)) groupCipher = GroupCipher(self.store, senderKeyName) try: plaintext = groupCipher.decrypt(enc.getData()) padding = ord(plaintext[-1]) & 0xFF self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext[:-padding]) except NoSessionException as e: logger.error(e) retry = RetryOutgoingReceiptProtocolEntity.fromMessageNode(node) retry.setRegData(self.store.getLocalRegistrationId()) self.toLower(retry.toProtocolTreeNode())
def getGroupCipher(self, groupId, senderId): senderKeyName = SenderKeyName(groupId, AxolotlAddress(senderId, 0)) if senderKeyName in self.groupCiphers: groupCipher = self.groupCiphers[senderKeyName] else: groupCipher = GroupCipher(self.store, senderKeyName) self.groupCiphers[senderKeyName] = groupCipher return groupCipher
def handleSenderKeyMessage(self, node): encMessageProtocolEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode(node) enc = encMessageProtocolEntity.getEnc(EncProtocolEntity.TYPE_SKMSG) senderKeyName = SenderKeyName(encMessageProtocolEntity.getFrom(True), AxolotlAddress(encMessageProtocolEntity.getParticipant(False), 0)) groupCipher = GroupCipher(self.store, senderKeyName) try: plaintext = groupCipher.decrypt(enc.getData()) padding = ord(plaintext[-1]) & 0xFF plaintext = plaintext[:-padding] plaintext = plaintext.encode() if sys.version_info >= (3, 0) else plaintext self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext) except NoSessionException as e: logger.warning("No session for %s, going to send a retry", encMessageProtocolEntity.getAuthor(False)) retry = RetryOutgoingReceiptProtocolEntity.fromMessageNode(node, self.store.getLocalRegistrationId()) self.toLower(retry.toProtocolTreeNode())
def handleSenderKeyMessage(self, node): encMessageProtocolEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode( node) enc = encMessageProtocolEntity.getEnc(EncProtocolEntity.TYPE_SKMSG) senderKeyName = SenderKeyName( encMessageProtocolEntity.getFrom(True), AxolotlAddress(encMessageProtocolEntity.getParticipant(False), 0)) groupCipher = GroupCipher(self.store, senderKeyName) try: plaintext = groupCipher.decrypt(enc.getData()) if type(plaintext) == bytes: # DEBUG SET RECEIPT # self.toLower(OutgoingReceiptProtocolEntity(node["id"], node["from"], 'read', participant=node["participant"]).toProtocolTreeNode()) if plaintext[0:1] == b'\n': msg = plaintext[3:3 + plaintext[1:2][-1]] elif plaintext[2:3] == b'\x01': msg = plaintext[5:5 + plaintext[4:5][-1]] if msg[0:1] == b'\x01': msg = plaintext[6:6 + plaintext[4:5][-1]] else: msg = plaintext[4:4 + plaintext[3:4][-1]] # self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext) self.handleConversationMessage(node, msg.decode()) # self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext.split(b'\x8a')[0]) return try: padding = ord(plaintext[-1]) & 0xFF plaintext = plaintext[:-padding] plaintext = plaintext.encode() if sys.version_info >= ( 3, 0) else plaintext self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext) except Exception as ex: #(AttributeError, TypeError) logger.error('Exception') logger.error('Exception %s' % ex) except NoSessionException as e: logger.warning("No session for %s, going to send a retry", encMessageProtocolEntity.getAuthor(False)) retry = RetryOutgoingReceiptProtocolEntity.fromMessageNode( node, self.store.getLocalRegistrationId()) self.toLower(retry.toProtocolTreeNode())
def _get_group_cipher(self, groupid, username): logger.debug("get_group_cipher(groupid=%s, username=%s)" % (groupid, username)) senderkeyname = SenderKeyName(groupid, AxolotlAddress(username, 0)) if senderkeyname in self._group_ciphers: group_cipher = self._group_ciphers[senderkeyname] else: group_cipher = GroupCipher(self._store.senderKeyStore, senderkeyname) self._group_ciphers[senderkeyname] = group_cipher return group_cipher
def test_basicEncryptDecrypt(self): aliceStore = InMemorySenderKeyStore(); bobStore = InMemorySenderKeyStore(); aliceSessionBuilder = GroupSessionBuilder(aliceStore) bobSessionBuilder = GroupSessionBuilder(bobStore) aliceGroupCipher = GroupCipher(aliceStore, GROUP_SENDER) bobGroupCipher = GroupCipher(bobStore, GROUP_SENDER); sentAliceDistributionMessage = aliceSessionBuilder.create(GROUP_SENDER); receivedAliceDistributionMessage = SenderKeyDistributionMessage(serialized = sentAliceDistributionMessage.serialize()); bobSessionBuilder.process(GROUP_SENDER, receivedAliceDistributionMessage) ciphertextFromAlice = aliceGroupCipher.encrypt("smert ze smert") plaintextFromAlice = bobGroupCipher.decrypt(ciphertextFromAlice) self.assertEqual(plaintextFromAlice, "smert ze smert")
def test_noSession(self): aliceStore = InMemorySenderKeyStore(); bobStore = InMemorySenderKeyStore(); aliceSessionBuilder = GroupSessionBuilder(aliceStore) bobSessionBuilder = GroupSessionBuilder(bobStore) aliceGroupCipher = GroupCipher(aliceStore, GROUP_SENDER) bobGroupCipher = GroupCipher(bobStore, GROUP_SENDER); sentAliceDistributionMessage = aliceSessionBuilder.create(GROUP_SENDER); receivedAliceDistributionMessage = SenderKeyDistributionMessage(serialized = sentAliceDistributionMessage.serialize()); ciphertextFromAlice = aliceGroupCipher.encrypt("smert ze smert"); try: plaintextFromAlice = bobGroupCipher.decrypt(ciphertextFromAlice); raise AssertionError("Should be no session!"); except NoSessionException as e: pass
def test_outOfOrder(self): aliceStore = InMemorySenderKeyStore(); bobStore = InMemorySenderKeyStore(); aliceSessionBuilder = GroupSessionBuilder(aliceStore) bobSessionBuilder = GroupSessionBuilder(bobStore) aliceGroupCipher = GroupCipher(aliceStore, GROUP_SENDER) bobGroupCipher = GroupCipher(bobStore, GROUP_SENDER); sentAliceDistributionMessage = aliceSessionBuilder.create(GROUP_SENDER); receivedAliceDistributionMessage = SenderKeyDistributionMessage(serialized = sentAliceDistributionMessage.serialize()); bobSessionBuilder.process(GROUP_SENDER, receivedAliceDistributionMessage) ciphertexts = [] for i in range(0, 100): ciphertexts.append(aliceGroupCipher.encrypt("up the punks")) while len(ciphertexts) > 0: index = KeyHelper.getRandomSequence(2147483647) % len(ciphertexts) ciphertext = ciphertexts.pop(index) plaintext = bobGroupCipher.decrypt(ciphertext) self.assertEqual(plaintext, "up the punks")