omemo-backend-signal-0.2.3/0000700000175000017500000000000013417462143015441 5ustar useruser00000000000000omemo-backend-signal-0.2.3/omemo_backend_signal/0000700000175000017500000000000013417462143021561 5ustar useruser00000000000000omemo-backend-signal-0.2.3/omemo_backend_signal/version.py0000600000175000017500000000002613417460471023622 0ustar useruser00000000000000__version__ = "0.2.3" omemo-backend-signal-0.2.3/omemo_backend_signal/backend.py0000600000175000017500000000042413374634274023534 0ustar useruser00000000000000from __future__ import absolute_import from omemo.backends import Backend from .doubleratchet import DoubleRatchet from .wireformat import WireFormat from .x3dh import State as X3DHState, X3DHPKEncoder BACKEND = Backend(WireFormat, X3DHState, X3DHPKEncoder, DoubleRatchet) omemo-backend-signal-0.2.3/omemo_backend_signal/doubleratchet/0000700000175000017500000000000013417462143024406 5ustar useruser00000000000000omemo-backend-signal-0.2.3/omemo_backend_signal/doubleratchet/rootchain.py0000600000175000017500000000055013405443774026756 0ustar useruser00000000000000from __future__ import absolute_import import doubleratchet class RootChain(doubleratchet.kdfchains.KDFChain): def __init__(self, key = None): super(RootChain, self).__init__( doubleratchet.recommended.RootKeyKDF( "SHA-256", "WhisperRatchet".encode("US-ASCII") ), key ) omemo-backend-signal-0.2.3/omemo_backend_signal/doubleratchet/symmetrickeyratchet.py0000600000175000017500000000047113405225643031063 0ustar useruser00000000000000from __future__ import absolute_import import doubleratchet from .sendrecvchain import SendRecvChain class SymmetricKeyRatchet(doubleratchet.ratchets.SymmetricKeyRatchet): def __init__(self): super(SymmetricKeyRatchet, self).__init__( SendRecvChain, SendRecvChain ) omemo-backend-signal-0.2.3/omemo_backend_signal/doubleratchet/__init__.py0000600000175000017500000000012113372774450026522 0ustar useruser00000000000000from __future__ import absolute_import from .doubleratchet import DoubleRatchet omemo-backend-signal-0.2.3/omemo_backend_signal/doubleratchet/cbcaead.py0000600000175000017500000000534713372774450026344 0ustar useruser00000000000000from __future__ import absolute_import import doubleratchet from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes, padding from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives.kdf.hkdf import HKDF class CBCAEAD(doubleratchet.AEAD): CRYPTOGRAPHY_BACKEND = default_backend() def __init__(self): super(CBCAEAD, self).__init__() def __getHKDFOutput(self, message_key): # Prepare the salt, which should be a string of 0x00 bytes with the length of # the hash digest salt = b"\x00" * 32 # Get 80 bytes from the HKDF calculation hkdf_out = HKDF( algorithm = hashes.SHA256(), length = 80, salt = salt, info = "WhisperMessageKeys".encode("US-ASCII"), backend = self.__class__.CRYPTOGRAPHY_BACKEND ).derive(message_key) # Split these 80 bytes in three parts return hkdf_out[:32], hkdf_out[32:64], hkdf_out[64:] def __getAES(self, key, iv): return Cipher( algorithms.AES(key), modes.CBC(iv), backend = self.__class__.CRYPTOGRAPHY_BACKEND ) def encrypt(self, plaintext, message_key, ad): encryption_key, authentication_key, iv = self.__getHKDFOutput(message_key) # Prepare PKCS#7 padded plaintext padder = padding.PKCS7(128).padder() plaintext = padder.update(plaintext) + padder.finalize() # Encrypt the plaintext using AES-256 (the 256 bit are implied by the key size), # CBC mode and the previously created key and iv aes_cbc = self.__getAES(encryption_key, iv).encryptor() ciphertext = aes_cbc.update(plaintext) + aes_cbc.finalize() return { "ciphertext" : ciphertext, "additional" : { "key" : authentication_key, "ad" : ad } } def decrypt(self, ciphertext, message_key, ad): decryption_key, authentication_key, iv = self.__getHKDFOutput(message_key) # Decrypt the plaintext using AES-256 (the 256 bit are implied by the key size), # CBC mode and the previously created key and iv aes_cbc = self.__getAES(decryption_key, iv).decryptor() plaintext = aes_cbc.update(ciphertext) + aes_cbc.finalize() # Remove the PKCS#7 padding from the plaintext unpadder = padding.PKCS7(128).unpadder() plaintext = unpadder.update(plaintext) + unpadder.finalize() return { "plaintext" : plaintext, "additional" : { "key" : authentication_key, "ad" : ad } } omemo-backend-signal-0.2.3/omemo_backend_signal/doubleratchet/sendrecvchain.py0000600000175000017500000000045613405225650027600 0ustar useruser00000000000000from __future__ import absolute_import import doubleratchet class SendRecvChain(doubleratchet.kdfchains.ConstKDFChain): def __init__(self, key): super(SendRecvChain, self).__init__( None, doubleratchet.recommended.ChainKeyKDF("SHA-256"), key ) omemo-backend-signal-0.2.3/omemo_backend_signal/doubleratchet/doubleratchet.py0000600000175000017500000000227413411546771027620 0ustar useruser00000000000000from __future__ import absolute_import import doubleratchet import x3dh from .cbcaead import CBCAEAD from .rootchain import RootChain from .symmetrickeyratchet import SymmetricKeyRatchet class DoubleRatchet(doubleratchet.ratchets.DoubleRatchet): def __init__( self, ad, root_key, own_key = None, other_pub = None ): super(DoubleRatchet, self).__init__( CBCAEAD(), # aead 5000, # message_key_store_max SymmetricKeyRatchet(), # symmetric_key_ratchet ad, # ad x3dh.implementations.KeyPairCurve25519, # encryption_key_pair_class RootChain(root_key), # root_chain own_key, other_pub ) def _makeAD(self, header, ad): return ad def encryptMessage(self, *args, **kwargs): result = super(DoubleRatchet, self).encryptMessage(*args, **kwargs) result["additional"] = result["ciphertext"]["additional"] result["ciphertext"] = result["ciphertext"]["ciphertext"] return result omemo-backend-signal-0.2.3/omemo_backend_signal/wireformat.py0000600000175000017500000001343413405223377024322 0ustar useruser00000000000000from __future__ import absolute_import import doubleratchet from omemo.backends import WireFormat as WF from omemo.exceptions import WireFormatException from . import whispertextprotocol_pb2 as wtp from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes, hmac CURRENT_MAJOR_VERSION = 3 CURRENT_MINOR_VERSION = 3 KEY_TYPE_25519 = 5 MAC_SIZE = 8 CRYPTOGRAPHY_BACKEND = default_backend() def calculateMAC(data, key, IK_sender, IK_receiver): global CRYPTOGRAPHY_BACKEND # Build the authentication auth = hmac.HMAC( key, hashes.SHA256(), backend = CRYPTOGRAPHY_BACKEND ) auth.update(IK_sender + IK_receiver + data) # Return the part of the mac that is used my libsignal return auth.finalize()[:MAC_SIZE] def checkVersion(data): try: version = ord(data[0]) except TypeError: version = data[0] major_version = (version >> 4) & 0x0F minor_version = (version >> 0) & 0x0F if major_version < CURRENT_MAJOR_VERSION or minor_version < CURRENT_MINOR_VERSION: raise WireFormatException("Legacy version detected.") if major_version > CURRENT_MAJOR_VERSION or minor_version > CURRENT_MINOR_VERSION: raise WireFormatException("Newer/unknown version detected.") return data[1:] def prependVersion(data): return bytes(bytearray([ CURRENT_MAJOR_VERSION << 4 | CURRENT_MINOR_VERSION ])) + data def decodePublicKey(key): if len(key) != 33: raise WireFormatException("The key field must contain 33 bytes of data.") try: key_type = ord(key[0]) except TypeError: key_type = key[0] if key_type != KEY_TYPE_25519: raise WireFormatException("Unknown key type.") return key[1:] def encodePublicKey(key): return bytes(bytearray([ KEY_TYPE_25519 ])) + key class WireFormat(WF): @staticmethod def messageFromWire(obj): # Due to the nature the mac is calculated by signal, the authentication # verification has to be done later in an additional step. # Remove the mac mac = obj[-MAC_SIZE:] obj = obj[:-MAC_SIZE] # Check and remove the version obj = checkVersion(obj) # Unpack the protobuf structure obj = wtp.SignalMessage.FromString(obj) if not ( obj.HasField("dh_ratchet_key") and obj.HasField("n") and obj.HasField("ciphertext") ): raise WireFormatException("Message incomplete.") return { "ciphertext": obj.ciphertext, "header": doubleratchet.Header( decodePublicKey(obj.dh_ratchet_key), obj.n, obj.pn ), "additional": mac } @staticmethod def finalizeMessageFromWire(obj, additional): dr_additional = additional["DoubleRatchet"] IK_own = dr_additional["ad"][:33] IK_other = dr_additional["ad"][33:] key = dr_additional["key"] mac = calculateMAC(obj[:-MAC_SIZE], key, IK_other, IK_own) if not additional["WireFormat"] == mac: raise WireFormatException("Message authentication failed.") @staticmethod def messageToWire(ciphertext, header, additional): # Build the protobuf structure wire = wtp.SignalMessage() wire.ciphertext = ciphertext wire.n = header.n if header.pn: wire.pn = header.pn else: wire.pn = 0 wire.dh_ratchet_key = encodePublicKey(header.dh_pub) data = wire.SerializeToString() # Prepend the message version data = prependVersion(data) # The specification of the DoubleRatchet protocol recommends to calculate the mac # of ad+ciphertext and append the result to the ciphertext. # WhisperSystems instead calculate the mac of ad + the whole protobuf encoded # message and truncate the mac to 8 bytes. # # This way the whole message is authenticated and not only the ciphertext. # (idk about the truncation though). dr_additional = additional["DoubleRatchet"] IK_own = dr_additional["ad"][:33] IK_other = dr_additional["ad"][33:] key = dr_additional["key"] data += calculateMAC(data, key, IK_own, IK_other) return data @staticmethod def preKeyMessageFromWire(obj): obj = checkVersion(obj) obj = wtp.PreKeySignalMessage.FromString(obj) if not ( obj.HasField("spk_id") and obj.HasField("ek") and obj.HasField("ik") and obj.HasField("signal_message") and obj.HasField("otpk_id") ): raise WireFormatException("Pre key message incomplete.") return { "session_init_data": { "registration_id": obj.registration_id, "otpk_id": obj.otpk_id, "spk_id": obj.spk_id, "ek": decodePublicKey(obj.ek), "ik": decodePublicKey(obj.ik) }, "message": obj.signal_message, "additional": None } @staticmethod def finalizePreKeyMessageFromWire(obj, additional): # TODO: Verify the mac of the contained message pass @staticmethod def preKeyMessageToWire(session_init_data, message, additional): wire = wtp.PreKeySignalMessage() wire.registration_id = 0 # This parameter has no use in OMEMO. wire.otpk_id = session_init_data["otpk_id"] wire.spk_id = session_init_data["spk_id"] wire.ek = encodePublicKey(session_init_data["ek"]) wire.ik = encodePublicKey(session_init_data["ik"]) wire.signal_message = message data = wire.SerializeToString() return prependVersion(data) omemo-backend-signal-0.2.3/omemo_backend_signal/__init__.py0000600000175000017500000000014713372774450023705 0ustar useruser00000000000000from __future__ import absolute_import from .version import __version__ from .backend import BACKEND omemo-backend-signal-0.2.3/omemo_backend_signal/whispertextprotocol_pb2.py0000600000175000017500000001424013417461333027051 0ustar useruser00000000000000# Generated by the protocol buffer compiler. DO NOT EDIT! # source: WhisperTextProtocol.proto import sys _b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection from google.protobuf import symbol_database as _symbol_database # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor.FileDescriptor( name='WhisperTextProtocol.proto', package='', syntax='proto2', serialized_options=None, serialized_pb=_b('\n\x19WhisperTextProtocol.proto\"R\n\rSignalMessage\x12\x16\n\x0e\x64h_ratchet_key\x18\x01 \x01(\x0c\x12\t\n\x01n\x18\x02 \x01(\r\x12\n\n\x02pn\x18\x03 \x01(\r\x12\x12\n\nciphertext\x18\x04 \x01(\x0c\"\x7f\n\x13PreKeySignalMessage\x12\x17\n\x0fregistration_id\x18\x05 \x01(\r\x12\x0f\n\x07otpk_id\x18\x01 \x01(\r\x12\x0e\n\x06spk_id\x18\x06 \x01(\r\x12\n\n\x02\x65k\x18\x02 \x01(\x0c\x12\n\n\x02ik\x18\x03 \x01(\x0c\x12\x16\n\x0esignal_message\x18\x04 \x01(\x0c') ) _SIGNALMESSAGE = _descriptor.Descriptor( name='SignalMessage', full_name='SignalMessage', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='dh_ratchet_key', full_name='SignalMessage.dh_ratchet_key', index=0, number=1, type=12, cpp_type=9, label=1, has_default_value=False, default_value=_b(""), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='n', full_name='SignalMessage.n', index=1, number=2, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='pn', full_name='SignalMessage.pn', index=2, number=3, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='ciphertext', full_name='SignalMessage.ciphertext', index=3, number=4, type=12, cpp_type=9, label=1, has_default_value=False, default_value=_b(""), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], serialized_options=None, is_extendable=False, syntax='proto2', extension_ranges=[], oneofs=[ ], serialized_start=29, serialized_end=111, ) _PREKEYSIGNALMESSAGE = _descriptor.Descriptor( name='PreKeySignalMessage', full_name='PreKeySignalMessage', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='registration_id', full_name='PreKeySignalMessage.registration_id', index=0, number=5, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='otpk_id', full_name='PreKeySignalMessage.otpk_id', index=1, number=1, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='spk_id', full_name='PreKeySignalMessage.spk_id', index=2, number=6, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='ek', full_name='PreKeySignalMessage.ek', index=3, number=2, type=12, cpp_type=9, label=1, has_default_value=False, default_value=_b(""), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='ik', full_name='PreKeySignalMessage.ik', index=4, number=3, type=12, cpp_type=9, label=1, has_default_value=False, default_value=_b(""), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='signal_message', full_name='PreKeySignalMessage.signal_message', index=5, number=4, type=12, cpp_type=9, label=1, has_default_value=False, default_value=_b(""), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], serialized_options=None, is_extendable=False, syntax='proto2', extension_ranges=[], oneofs=[ ], serialized_start=113, serialized_end=240, ) DESCRIPTOR.message_types_by_name['SignalMessage'] = _SIGNALMESSAGE DESCRIPTOR.message_types_by_name['PreKeySignalMessage'] = _PREKEYSIGNALMESSAGE _sym_db.RegisterFileDescriptor(DESCRIPTOR) SignalMessage = _reflection.GeneratedProtocolMessageType('SignalMessage', (_message.Message,), dict( DESCRIPTOR = _SIGNALMESSAGE, __module__ = 'WhisperTextProtocol_pb2' # @@protoc_insertion_point(class_scope:SignalMessage) )) _sym_db.RegisterMessage(SignalMessage) PreKeySignalMessage = _reflection.GeneratedProtocolMessageType('PreKeySignalMessage', (_message.Message,), dict( DESCRIPTOR = _PREKEYSIGNALMESSAGE, __module__ = 'WhisperTextProtocol_pb2' # @@protoc_insertion_point(class_scope:PreKeySignalMessage) )) _sym_db.RegisterMessage(PreKeySignalMessage) # @@protoc_insertion_point(module_scope) omemo-backend-signal-0.2.3/omemo_backend_signal/x3dh/0000700000175000017500000000000013417462143022427 5ustar useruser00000000000000omemo-backend-signal-0.2.3/omemo_backend_signal/x3dh/__init__.py0000600000175000017500000000015213374634157024550 0ustar useruser00000000000000from __future__ import absolute_import from .state import State from .x3dhpkencoder import X3DHPKEncoder omemo-backend-signal-0.2.3/omemo_backend_signal/x3dh/state.py0000600000175000017500000000427613405225667024141 0ustar useruser00000000000000from __future__ import absolute_import from .x3dhpkencoder import X3DHPKEncoder import x3dh class State(x3dh.State): def __init__(self): """ Sets the constructor parameters to the defaults used by OMEMO. The curve, min_num_otpks and max_num_otpks parameters were found in the XEP (https://xmpp.org/extensions/xep-0384.html). The hash_function and info_string parameters were found in the source code of libsignal-protocol-java (https://github.com/WhisperSystems/libsignal-protocol-java). The timeout for the SPK is defaulted to one week. """ return super(State, self).__init__( "WhisperText".encode("US-ASCII"), # info_string "25519", # curve "SHA-256", # hash_function 7 * 24 * 60 * 60, # spk_timeout 20, # min_num_otpks 100, # max_num_otpks X3DHPKEncoder # public_key_encoder_class ) def getSharedSecretActive(self, *args, **kwargs): # X3DH is specified to build the associated data as follows: IK_A || IK_B. # As per usual, WhisperSystems weren't satisfied with their own solution and # instead of using the ad as built by X3DH they ALWAYS do: # IK_sender || IK_receiver. # That means, when decrypting a message, a different ad is used as when encrypting # a message. # # To allow for this to happen, the ad is reordered so that it always has following # structure: IK_own || IK_other. result = super(State, self).getSharedSecretActive(*args, **kwargs) IK_own = result["ad"][:33] IK_other = result["ad"][33:] result["ad"] = IK_own + IK_other return result def getSharedSecretPassive(self, *args, **kwargs): result = super(State, self).getSharedSecretPassive(*args, **kwargs) # See getSharedSecretActive for an explanation IK_own = result["ad"][33:] IK_other = result["ad"][:33] result["ad"] = IK_own + IK_other return result omemo-backend-signal-0.2.3/omemo_backend_signal/x3dh/x3dhpkencoder.py0000600000175000017500000000070113374636675025561 0ustar useruser00000000000000from __future__ import absolute_import import omemo class X3DHPKEncoder(omemo.backends.X3DHPKEncoder): @staticmethod def encodePublicKey(key, key_type): if key_type == "25519": return b"\x05" + key raise NotImplementedError @staticmethod def decodePublicKey(key_encoded): if key_encoded[0:1] == b"\x05": return (key_encoded[1:], "25519") raise NotImplementedError omemo-backend-signal-0.2.3/setup.cfg0000600000175000017500000000004613417462143017264 0ustar useruser00000000000000[egg_info] tag_build = tag_date = 0 omemo-backend-signal-0.2.3/omemo_backend_signal.egg-info/0000700000175000017500000000000013417462143023253 5ustar useruser00000000000000omemo-backend-signal-0.2.3/omemo_backend_signal.egg-info/not-zip-safe0000600000175000017500000000000113417460403025500 0ustar useruser00000000000000 omemo-backend-signal-0.2.3/omemo_backend_signal.egg-info/SOURCES.txt0000600000175000017500000000155713417462142025150 0ustar useruser00000000000000README.md setup.py omemo_backend_signal/__init__.py omemo_backend_signal/backend.py omemo_backend_signal/version.py omemo_backend_signal/whispertextprotocol_pb2.py omemo_backend_signal/wireformat.py omemo_backend_signal.egg-info/PKG-INFO omemo_backend_signal.egg-info/SOURCES.txt omemo_backend_signal.egg-info/dependency_links.txt omemo_backend_signal.egg-info/not-zip-safe omemo_backend_signal.egg-info/requires.txt omemo_backend_signal.egg-info/top_level.txt omemo_backend_signal/doubleratchet/__init__.py omemo_backend_signal/doubleratchet/cbcaead.py omemo_backend_signal/doubleratchet/doubleratchet.py omemo_backend_signal/doubleratchet/rootchain.py omemo_backend_signal/doubleratchet/sendrecvchain.py omemo_backend_signal/doubleratchet/symmetrickeyratchet.py omemo_backend_signal/x3dh/__init__.py omemo_backend_signal/x3dh/state.py omemo_backend_signal/x3dh/x3dhpkencoder.pyomemo-backend-signal-0.2.3/omemo_backend_signal.egg-info/dependency_links.txt0000600000175000017500000000000113417462142027322 0ustar useruser00000000000000 omemo-backend-signal-0.2.3/omemo_backend_signal.egg-info/top_level.txt0000600000175000017500000000002513417462142026003 0ustar useruser00000000000000omemo_backend_signal omemo-backend-signal-0.2.3/omemo_backend_signal.egg-info/requires.txt0000600000175000017500000000014213417462142025651 0ustar useruser00000000000000X3DH<0.6,>=0.5.6 DoubleRatchet<0.7,>=0.6.0 OMEMO<0.11,>=0.9.0 cryptography>=1.7.1 protobuf>=2.6.1 omemo-backend-signal-0.2.3/omemo_backend_signal.egg-info/PKG-INFO0000600000175000017500000000407113417462142024353 0ustar useruser00000000000000Metadata-Version: 2.1 Name: omemo-backend-signal Version: 0.2.3 Summary: A backend for python-omemo offering compatibility with libsignal. Home-page: https://github.com/Syndace/python-omemo-backend-signal Author: Tim Henkes Author-email: tim@cifg.io License: GPLv3 Description: [![PyPI](https://img.shields.io/pypi/v/omemo-backend-signal.svg)](https://pypi.org/project/omemo-backend-signal/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/omemo-backend-signal.svg)](https://pypi.org/project/omemo-backend-signal/) # python-omemo-backend-signal #### A backend for python-omemo offering compatibility with libsignal. This library implements a backend for [python-omemo](https://github.com/Syndace/python-omemo) offering compatibility with libsignal ([C](https://github.com/signalapp/libsignal-protocol-c), [Java](https://github.com/signalapp/libsignal-protocol-java), [JavaScript](https://github.com/signalapp/libsignal-protocol-javascript)). Look at [python-omemo](https://github.com/Syndace/python-omemo) for further usage information. NOTE: This repository contains a compiled version of a [protobuf](https://developers.google.com/protocol-buffers/) structure definition file. The Makefile can be used to reproduce the compilation step. Tested to work with protoc v2.*, v3.0.0 and v3.6.1. Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: Topic :: Communications :: Chat Classifier: Topic :: Security :: Cryptography Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3) Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4 Description-Content-Type: text/markdown omemo-backend-signal-0.2.3/README.md0000600000175000017500000000201113417461515016716 0ustar useruser00000000000000[![PyPI](https://img.shields.io/pypi/v/omemo-backend-signal.svg)](https://pypi.org/project/omemo-backend-signal/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/omemo-backend-signal.svg)](https://pypi.org/project/omemo-backend-signal/) # python-omemo-backend-signal #### A backend for python-omemo offering compatibility with libsignal. This library implements a backend for [python-omemo](https://github.com/Syndace/python-omemo) offering compatibility with libsignal ([C](https://github.com/signalapp/libsignal-protocol-c), [Java](https://github.com/signalapp/libsignal-protocol-java), [JavaScript](https://github.com/signalapp/libsignal-protocol-javascript)). Look at [python-omemo](https://github.com/Syndace/python-omemo) for further usage information. NOTE: This repository contains a compiled version of a [protobuf](https://developers.google.com/protocol-buffers/) structure definition file. The Makefile can be used to reproduce the compilation step. Tested to work with protoc v2.*, v3.0.0 and v3.6.1. omemo-backend-signal-0.2.3/PKG-INFO0000600000175000017500000000407113417462143016542 0ustar useruser00000000000000Metadata-Version: 2.1 Name: omemo-backend-signal Version: 0.2.3 Summary: A backend for python-omemo offering compatibility with libsignal. Home-page: https://github.com/Syndace/python-omemo-backend-signal Author: Tim Henkes Author-email: tim@cifg.io License: GPLv3 Description: [![PyPI](https://img.shields.io/pypi/v/omemo-backend-signal.svg)](https://pypi.org/project/omemo-backend-signal/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/omemo-backend-signal.svg)](https://pypi.org/project/omemo-backend-signal/) # python-omemo-backend-signal #### A backend for python-omemo offering compatibility with libsignal. This library implements a backend for [python-omemo](https://github.com/Syndace/python-omemo) offering compatibility with libsignal ([C](https://github.com/signalapp/libsignal-protocol-c), [Java](https://github.com/signalapp/libsignal-protocol-java), [JavaScript](https://github.com/signalapp/libsignal-protocol-javascript)). Look at [python-omemo](https://github.com/Syndace/python-omemo) for further usage information. NOTE: This repository contains a compiled version of a [protobuf](https://developers.google.com/protocol-buffers/) structure definition file. The Makefile can be used to reproduce the compilation step. Tested to work with protoc v2.*, v3.0.0 and v3.6.1. Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: Topic :: Communications :: Chat Classifier: Topic :: Security :: Cryptography Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3) Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4 Description-Content-Type: text/markdown omemo-backend-signal-0.2.3/setup.py0000600000175000017500000000327213406740026017156 0ustar useruser00000000000000from setuptools import setup, find_packages import os import sys version_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "omemo_backend_signal", "version.py" ) version = {} try: execfile(version_file_path, version) except: with open(version_file_path) as fp: exec(fp.read(), version) with open("README.md") as f: long_description = f.read() setup( name = "omemo-backend-signal", version = version["__version__"], description = "A backend for python-omemo offering compatibility with libsignal.", long_description = long_description, long_description_content_type = "text/markdown", url = "https://github.com/Syndace/python-omemo-backend-signal", author = "Tim Henkes", author_email = "tim@cifg.io", license = "GPLv3", packages = find_packages(), install_requires = [ "X3DH>=0.5.6,<0.6", "DoubleRatchet>=0.6.0,<0.7", "OMEMO>=0.9.0,<0.11", "cryptography>=1.7.1", "protobuf>=2.6.1" ], python_requires = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", zip_safe = False, classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Topic :: Communications :: Chat", "Topic :: Security :: Cryptography", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ] )