{ "info": { "author": "Tim Henkes", "author_email": "me@syndace.dev", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "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", "Topic :: Communications :: Chat", "Topic :: Security :: Cryptography" ], "description": "[![PyPI](https://img.shields.io/pypi/v/OMEMO.svg)](https://pypi.org/project/OMEMO/)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/OMEMO.svg)](https://pypi.org/project/OMEMO/)\n[![Build Status](https://travis-ci.org/Syndace/python-omemo.svg?branch=master)](https://travis-ci.org/Syndace/python-omemo)\n\n# python-omemo\n#### A Python implementation of the OMEMO Multi-End Message and Object Encryption protocol.\n\nThis python library offers an open implementation of the OMEMO Multi-End Message and Object Encryption protocol as specified [here](https://xmpp.org/extensions/xep-0384.html).\n\nGoals of this implementation are:\n- Do not depend on libsignal but offer a solid alternative to it\n- Stay away from GPL (this repo will soon switch to MIT)\n- Be flexible to changes that might happen to the OMEMO protocol\n- Keep the structure close to the spec\n- Provide the parts of the protocol (X3DH, Double Ratchet) as own projects\n\nThis library uses the [X3DH](https://github.com/Syndace/python-x3dh) and [DoubleRatchet](https://github.com/Syndace/python-doubleratchet) libraries, configures them with the parameters that OMEMO uses and manages all encryption sessions for you.\n\nThis library does NOT manage XML/stanzas.\n\n## Installation\n\n### pip\n\nYou can install this library and all of its dependencies via pip:\n\n```Bash\n$ pip install OMEMO\n```\n\n### AUR\n\nPpjet6 kindly maintains AUR packages of both the current master and the latest release:\n\n| Release/Branch | Python Version | Link |\n|:-------------- |:--------------:|:----------------------------------------------------------------------------:|\n| current master | 2 | [*\\*click\\**](https://aur.archlinux.org/packages/python2-omemo-syndace/) |\n| latest release | 2 | [*\\*click\\**](https://aur.archlinux.org/packages/python2-omemo-syndace-git/) |\n| current master | 3 | [*\\*click\\**](https://aur.archlinux.org/packages/python-omemo-syndace/) |\n| latest release | 3 | [*\\*click\\**](https://aur.archlinux.org/packages/python-omemo-syndace-git/) |\n\n## Usage\n\n### Choose a backend\n\nTo use this library you have to choose a backend first. Currently, you don't have a lot of choice: The only available backend is a backend offering libsignal compatibility, found [here](https://github.com/Syndace/python-omemo-backend-signal). Install your backend of choice and proceed to the next step.\n\n### Implement the Storage interface\n\nThe library has a lot of state/data that it has to persist between runs. To be as flexible as possible the library leaves it open for you to decide how to store the data. Simply implement the `Storage` interface found in `storage.py`. The file contains more info about how to implement the interface.\n\n### Decide on a one-time pre key policy\n\nThis part is kind of tricky as it requires a lot of knowledge about how the protocol works. Basically the key exchange mechanism used by the protocol assumes guaranteed message delivery and a response to the first message before another message is sent. Both conditions are not quite given in all environments, especially not in XMPP, which is the main use-case for this library. For that reason the library has to \"relax\" some of the protocols rules. Instead of always instantly deleting the keys used in the key exchange, it is now up to you to decide whether to keep keys or not. To do so, implement the `OTPKPolicy` interface found in `otpkpolicy.py` or use the default implementation `DefaultOTPKPolicy`. If you decide to implement the interface yourself, the `otpkpolicy.py` file contains more information on how to implement the interface.\n\n### Create a SessionManager\n\nNow that you have selected a backend, decided on how to store the data and when to delete the key exchange keys, it's time to create an instance of the core class of this library: the SessionManager.\n\nThe SessionManager handles message en- and decryption with all your contacts, trying to make it as easy as possible for you. The file `examples/sessions.py` contains a lot of well-commented code that shows how to create and use a SessionManager.\n\n## Specific information for usage in XMPP/Jabber\n\n### 1. Device list management\n\n#### 1.1. Device lists of your contacts\n\nThe first thing you have to set up is the device list management. To do so, subscribe to (or in [XEP-0163](https://xmpp.org/extensions/xep-0163.html) speak: announce interest in) the \"eu.siacs.conversations.axolotl.devicelist\" node. You will now receive updates to the device lists of all your OMEMO-enabled contacts. Upon receiving such an update, pass the contained list into the \"newDeviceList\" method of your SessionManager. Some pseudocode:\n```Python\nDEVICELIST_NODE = \"eu.siacs.conversations.axolotl.devicelist\"\n\ndef __init__():\n xep0163.announce_interest(DEVICELIST_NODE)\n\ndef onPEPUpdate(node, item, sender_jid):\n if node == DEVICELIST_NODE:\n devices = unpackDeviceList(item)\n sessionMgr.newDeviceList(devices, sender_jid)\n```\nThe SessionManager takes care of caching the device list and also remembers inactive devices for you. You can ask the SessionManager for stored device lists using the \"getDevices\" method.\n\n#### 1.2. Your own device list\n\nThe next thing to set up is the management of you own device list. The rule is quite simple: always make sure, that your own device id is contained in your device list. Whenever you load your OMEMO-using software, download the device list of your own jid and make sure your own device id is contained. After following the steps in 1.1., you will now also receive PEP updates about changes to your own device list. Use these updates to assert that your own device id is still contained in the list. Some more pseudocode:\n```Python\ndef __init__():\n own_device_list = xep0163.load_latest_entry(own_jid, DEVICELIST_NODE)\n manageOwnDeviceList(own_device_list)\n sessionMgr.newDeviceList(own_device_list, own_jid)\n\ndef onPEPUpdate(node, item, sender_jid):\n if node == DEVICELIST_NODE:\n devices = unpackDeviceList(item)\n \n if sender_jid == own_jid:\n manageOwnDeviceList(devices)\n \n sessionMgr.newDeviceList(devices, sender_jid)\n \ndef manageOwnDeviceList(devices):\n if not own_device in devices:\n devices.append(own_device)\n \n item = packDeviceList(devices)\n \n xep0163.publish(DEVICELIST_NODE, item)\n```\n\n### 2. Bundle management\n\nThe next thing you need to manager are the bundles used for the X3DH key exchange. Each device publishes its own bundle to a unique PEP node.\n\n**WIP**\n\n### 3. Decryption\n\n### 4. Encryption\n\n### 5. A note about trust management\n\n### 6. A note about fingerprints\n\nFingerprints initially were part of the library but I decided to remove them. Fingerprints are not specified at all, that's why I leave it open for the client dev to decide on a way to build and show fingerprints. Some implementations simply take the public part of the identity key and show it as a QR-code or encoded as hex bytes. Pseudocode:\n```Python\n# Get the ik public part from some bundle\nik_pub = some_bundle.ik\n\n# Show a qr code somehow...\nshowQRCode(ik_pub)\n\n# ...or create a hex byte representation\n# Wanted format: 01:23:45:67:89:AB:CD:EF\n# This is surprisingly tricky:\nimport codecs\nimport re\nik_pub_hex = codecs.getencoder(\"hex\")(ik_pub)[0].decode(\"US-ASCII\").upper()\nik_pub_hex = \":\".join(re.findall(\"..?\", ik_pub_hex))\n```\n\n### 7. A note about asynchronism", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/Syndace/python-omemo", "keywords": "", "license": "GPLv3", "maintainer": "", "maintainer_email": "", "name": "OMEMO", "package_url": "https://pypi.org/project/OMEMO/", "platform": "", "project_url": "https://pypi.org/project/OMEMO/", "project_urls": { "Homepage": "https://github.com/Syndace/python-omemo" }, "release_url": "https://pypi.org/project/OMEMO/0.10.5/", "requires_dist": null, "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "summary": "A Python implementation of the OMEMO Multi-End Message and Object Encryption protocol.", "version": "0.10.5" }, "last_serial": 5563233, "releases": { "0.10.0": [ { "comment_text": "", "digests": { "md5": "185d3d06a5cf068ec523b75ba2defb23", "sha256": "826cc82536f49e534bd67b267865a23bec6374122babd50aa5e01a90ef9eed8b" }, "downloads": -1, "filename": "OMEMO-0.10.0.tar.gz", "has_sig": false, "md5_digest": "185d3d06a5cf068ec523b75ba2defb23", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 21886, "upload_time": "2018-12-26T22:51:08", "url": "https://files.pythonhosted.org/packages/00/aa/23a3c223317817584ee7067e73f526e02083b5ebaf259a8948c5b0ab1816/OMEMO-0.10.0.tar.gz" } ], "0.10.1": [ { "comment_text": "", "digests": { "md5": "35b30ede8657aa695473425cb0a168b5", "sha256": "535e41f747188f14009604d2d8cca3e8cd579ba87ad2d16142986f4f04bec56a" }, "downloads": -1, "filename": "OMEMO-0.10.1.tar.gz", "has_sig": false, "md5_digest": "35b30ede8657aa695473425cb0a168b5", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 22246, "upload_time": "2018-12-27T18:09:38", "url": "https://files.pythonhosted.org/packages/f5/6d/a1cb4171a7933b37a3d013a881e2729c797c96f173bb178a7a1640a395c8/OMEMO-0.10.1.tar.gz" } ], "0.10.2": [ { "comment_text": "", "digests": { "md5": "a9a35d45ac5d9519c8a53a0dcdcf6ebc", "sha256": "4a875eae30a479108b351315f0e5385e573d06e7093d4abc136bc52ccf705754" }, "downloads": -1, "filename": "OMEMO-0.10.2.tar.gz", "has_sig": false, "md5_digest": "a9a35d45ac5d9519c8a53a0dcdcf6ebc", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 23179, "upload_time": "2018-12-29T01:34:09", "url": "https://files.pythonhosted.org/packages/7b/0e/a8e99c7f48a89d4390fb64694b434797705ea80bb29c340169242c3d827f/OMEMO-0.10.2.tar.gz" } ], "0.10.3": [ { "comment_text": "", "digests": { "md5": "b228de6736639e7c64f8e3415a4e2ed6", "sha256": "5fe74baaaf7b835c31b8974093aea188459dd42f6b304273d3c6148615e3df95" }, "downloads": -1, "filename": "OMEMO-0.10.3.tar.gz", "has_sig": false, "md5_digest": "b228de6736639e7c64f8e3415a4e2ed6", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 23786, "upload_time": "2018-12-29T20:13:50", "url": "https://files.pythonhosted.org/packages/5d/e0/2c84ec64f26b267f6cb2d79a4fc8563e2246ca64262c71dd384257b33bc0/OMEMO-0.10.3.tar.gz" } ], "0.10.4": [ { "comment_text": "", "digests": { "md5": "b3643ef89ba919b3d114a6daa5f96efa", "sha256": "20740fcb1be6445d7d872cc750dc2a7801811c1c30493b1d080ee81a675ef95f" }, "downloads": -1, "filename": "OMEMO-0.10.4.tar.gz", "has_sig": false, "md5_digest": "b3643ef89ba919b3d114a6daa5f96efa", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 24967, "upload_time": "2019-02-01T14:15:20", "url": "https://files.pythonhosted.org/packages/e4/75/49548f70016f8e656393868f4fa2ffdb7ebdfd59f10d832dd4d1d2d3279b/OMEMO-0.10.4.tar.gz" } ], "0.10.5": [ { "comment_text": "", "digests": { "md5": "459cd2594188807a1f78ff54635f3d7c", "sha256": "a6e091d9e5300725cf91cbe787b1f23e6b5b72be46e4ac749491bba8f91c6746" }, "downloads": -1, "filename": "OMEMO-0.10.5.tar.gz", "has_sig": false, "md5_digest": "459cd2594188807a1f78ff54635f3d7c", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 25284, "upload_time": "2019-07-21T12:11:16", "url": "https://files.pythonhosted.org/packages/74/b9/aa49565d47d9d70cc4c2608df281d656186e61224cf1083368e177850aad/OMEMO-0.10.5.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "c24d2adcea5595d77b5236d0aad21e90", "sha256": "72e740d6376cc43b9a97d5ffb88e26b05707245091c542b26713f125e4e2d4ba" }, "downloads": -1, "filename": "OMEMO-0.5.0.tar.gz", "has_sig": false, "md5_digest": "c24d2adcea5595d77b5236d0aad21e90", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 18616, "upload_time": "2018-07-29T11:56:18", "url": "https://files.pythonhosted.org/packages/65/42/281672edd3acb9cf06e71cd1195470b9e4c12a23da1d1149b0cc90ca9d36/OMEMO-0.5.0.tar.gz" } ], "0.6.0": [ { "comment_text": "", "digests": { "md5": "f42f70681bf510ed569e10195e3ebfa4", "sha256": "cb126027e83c6e7029f87aff7a207247afa40693588feab48d19d674d42a9b73" }, "downloads": -1, "filename": "OMEMO-0.6.0.tar.gz", "has_sig": false, "md5_digest": "f42f70681bf510ed569e10195e3ebfa4", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 20120, "upload_time": "2018-07-30T16:16:18", "url": "https://files.pythonhosted.org/packages/48/ab/521932cd7579424b2cdd79ca067904c395c48ab6d7e0cc67e81d956b1990/OMEMO-0.6.0.tar.gz" } ], "0.7.0": [ { "comment_text": "", "digests": { "md5": "a416833450861f9406d9db71fa7716d3", "sha256": "ce5ee5bb662bec4c7a73888a4b5ec97cf7196db5e1b6a55267c09caaeb1e7cd0" }, "downloads": -1, "filename": "OMEMO-0.7.0.tar.gz", "has_sig": false, "md5_digest": "a416833450861f9406d9db71fa7716d3", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 22401, "upload_time": "2018-08-01T11:29:31", "url": "https://files.pythonhosted.org/packages/15/48/d61bacbb150ca062bce0c0f4e58119476b4f1ee9a7fcfeac15ed663b74d5/OMEMO-0.7.0.tar.gz" } ], "0.7.1": [ { "comment_text": "", "digests": { "md5": "9599abb99ead9b5b2f911779d656c69f", "sha256": "a489021ba865bb874708f7f5b0959be5b6ea6b94d57a005ffbaccafb98ae8904" }, "downloads": -1, "filename": "OMEMO-0.7.1.tar.gz", "has_sig": false, "md5_digest": "9599abb99ead9b5b2f911779d656c69f", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 25483, "upload_time": "2018-09-09T15:09:01", "url": "https://files.pythonhosted.org/packages/69/d0/0597482a401b144d2671c533b4269105393201db82cd80fc5eedb142f14f/OMEMO-0.7.1.tar.gz" } ], "0.8.0": [ { "comment_text": "", "digests": { "md5": "d4eb2d5119469ce373c9f6c704764aef", "sha256": "45b0e9835aa9b7c3ee22c0460381ff32d359078c6c398ab2ecd83dc9e8826c80" }, "downloads": -1, "filename": "OMEMO-0.8.0.tar.gz", "has_sig": false, "md5_digest": "d4eb2d5119469ce373c9f6c704764aef", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 15364, "upload_time": "2018-11-16T10:01:27", "url": "https://files.pythonhosted.org/packages/4b/e2/1432e1d86d121003242fe9c6303ef0ae648a53d90051d75e788e87eefa4a/OMEMO-0.8.0.tar.gz" } ], "0.8.1": [ { "comment_text": "", "digests": { "md5": "ebd3c09ebed7d74ae667816efa121263", "sha256": "b679cc6c67a0769e2c76929882d4c2a6486c416bafa6d360efbfaa9c4a824f1d" }, "downloads": -1, "filename": "OMEMO-0.8.1.tar.gz", "has_sig": false, "md5_digest": "ebd3c09ebed7d74ae667816efa121263", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 15423, "upload_time": "2018-11-17T10:39:17", "url": "https://files.pythonhosted.org/packages/39/23/9e752d60c2bb78dc36f1410782025b0544dbb7d563241a090d47c04b8a0f/OMEMO-0.8.1.tar.gz" } ], "0.8.2": [ { "comment_text": "", "digests": { "md5": "a19dbcfcce0655bb03b5664d38da3188", "sha256": "116f7d8baae34af411d18329bd707e8c12065d727429881b0b4ec64c48d0c62b" }, "downloads": -1, "filename": "OMEMO-0.8.2.tar.gz", "has_sig": false, "md5_digest": "a19dbcfcce0655bb03b5664d38da3188", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 15413, "upload_time": "2018-11-17T12:07:40", "url": "https://files.pythonhosted.org/packages/7f/08/20dbfd5f7fbc11d1fe4f94f7c4d803e49f91d7e3d53bab3b6b98148bca02/OMEMO-0.8.2.tar.gz" } ], "0.9.0": [ { "comment_text": "", "digests": { "md5": "17bc7c892dd19003ee84b938a04f3b31", "sha256": "73fea2d02e6631c17a9c0280202da49a85e92b705b01500586733ee3a8ebb5dd" }, "downloads": -1, "filename": "OMEMO-0.9.0.tar.gz", "has_sig": false, "md5_digest": "17bc7c892dd19003ee84b938a04f3b31", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 20867, "upload_time": "2018-12-15T23:18:52", "url": "https://files.pythonhosted.org/packages/b8/db/41f64fa3362d6cc472f5ee4476aec892587652a9da5912ba608b26cc7a8e/OMEMO-0.9.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "459cd2594188807a1f78ff54635f3d7c", "sha256": "a6e091d9e5300725cf91cbe787b1f23e6b5b72be46e4ac749491bba8f91c6746" }, "downloads": -1, "filename": "OMEMO-0.10.5.tar.gz", "has_sig": false, "md5_digest": "459cd2594188807a1f78ff54635f3d7c", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", "size": 25284, "upload_time": "2019-07-21T12:11:16", "url": "https://files.pythonhosted.org/packages/74/b9/aa49565d47d9d70cc4c2608df281d656186e61224cf1083368e177850aad/OMEMO-0.10.5.tar.gz" } ] }