Code Monkey home page Code Monkey logo

omemo_dart's Introduction

omemo_dart

status-badge

omemo_dart is a Dart library to help developers of Dart/Flutter XMPP clients to implement OMEMO in its newest version - currently 0.8.3.

The library provides an implementation of the X3DH key exchange, the Double Ratchet with the OMEMO 0.8.3 specific ENCRYPT, DECRYPT and KDF_* functions and a very high-level OmemoSessionManager that manages all Double Ratchet sessions and provides a clean and simple interface for encrypting a message for all known Ratchet sessions we have with a user.

This library also has no dependency on any XMPP library. omemo_dart instead defines an intermediary format for the required data that you, the user, will need to transform to and from the stanza format of your preferred XMPP library yourself.

Important Notes

  • Please note that this library has not been audited for its security! Use at your own risk!
  • This library is not tested with other implementations of OMEMO 0.8.3 as I do not know of any client implementing spec compliant OMEMO 0.8.3. It does, however, work with itself.

Usage

Include omemo_dart in your pubspec.yaml like this:

# [...]

dependencies:
  omemo_dart:
    hosted: https://git.polynom.me/api/packages/PapaTutuWawa/pub
    version: ^0.5.0
  # [...]

# [...]

Example

This repository includes a documented "example" that explains the basic usage of the library while leaving out the XMPP specific bits. For a more functional and integrated example, see the omemo_client.dart example from moxxmpp.

Persistence

By default, omemo_dart uses in-memory implementations for everything. For a real-world application, this is unsuitable as OMEMO devices would be constantly added. In order to allow persistence, your application needs to keep track of the following:

  • The OmemoDevice assigned to the OmemoManager
  • JID -> [int]: The device list for each JID
  • (JID, device) -> Ratchet: The actual ratchet

If you also use the BlindTrustBeforeVerificationTrustManager, you additionally need to keep track of:

  • (JID, device) -> (int, bool): The trust level and the enablement state

Contributing

When submitting a PR, please run the linter using dart analyze and make sure that all tests still pass using dart test.

To ensure uniform commit message formatting, please also use gitlint to lint your commit messages' formatting.

License

Licensed under the MIT license.

See LICENSE.

Support

If you like what I do and you want to support me, feel free to donate to me on Ko-Fi.

omemo_dart's People

Contributors

papatutuwawa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

omemo_dart's Issues

All tests are pretty flaky

They very occasionally fail for the same reason:

  Instance of 'UnknownSignedPrekeyException'
  package:omemo_dart/src/omemo/sessionmanager.dart 185:7  OmemoSessionManager._addSessionFromKeyExchange
  ===== asynchronous gap ===========================
  package:omemo_dart/src/omemo/sessionmanager.dart 347:7  OmemoSessionManager.decryptMessage
  ===== asynchronous gap ===========================
  test/omemo_test.dart 254:24                             main.<fn>

Build an abstraction over message sending

Message sending a bit more involved since we need to check for new ratchets, handle unacked ratchets and so on. So having this one being handled by omemo_dart would be a huge improvement.

The session manager should be able to serialise and deserialise itself

  • Allow fully deserialising
  • Allow fully serialising itself
  • Add a commit and load function to allow users to just subclass, override those two functions and use their preferred storage solution
    • This should, however, be optional to provide a memoryless backend
    • This allows us to store ratchets individually, preventing us from having to serialise the entire manager everytime a message is encrypted or decrypted

Add missing tags

All newer versions have no tags attached to them. Add tags via git so that Github and Codeberg both have them.

Maybe that can be automated?

Empty OMEMO Messages should be allowed to bypass the trust manager

From XEP-0384

Clients MUST NOT use a newly built session to transmit data without user intervention. [...] This rule does not apply to empty OMEMO messages (as per Sending a message) that are used purely to transfer key material, e.g. as part of heartbeat messages or automatic key exchange completion.

Wrong behaviour on unacked ratchets

Whenever we send a message to an unacked ratchet, we are not supposed to generate a new one but instead just send the old key exchange until we are acked. The message numbering prevents this from being an issue.

Using the OmemoSessionManager to encrypt a second message to a Jid will causes an invalid HMAC exception

See the test Test by sending multiple messages back and forth in test/omemo_test.dart.

Edit: This bug does not seem to be triggered due to a bad ratchet since the Double Ratchet tests do not fail.

Unhandled exception:
Instance of 'InvalidMessageHMACException'
#0      decrypt (package:omemo_dart/src/double_ratchet/crypto.dart:44:5)
<asynchronous suspension>
#1      OmemoSessionManager.decryptMessage.<anonymous closure> (package:omemo_dart/src/omemo/sessionmanager.dart:329:22)
<asynchronous suspension>
#2      BasicLock.synchronized (package:synchronized/src/basic_lock.dart:33:16)
<asynchronous suspension>
#3      OmemoSessionManager.decryptMessage (package:omemo_dart/src/omemo/sessionmanager.dart:324:5)
<asynchronous suspension>
#4      OmemoEncryptionImplementation.decryptStanza (package:xmpp_omemo/src/transformers/message.dart:151:22)
<asynchronous suspension>
#5      OmemoMessageTransformer.transformToData (package:xmpp_omemo/src/transformers/message.dart:198:23)
<asynchronous suspension>
#6      MessageTransformerManager.transformToData (package:xmpp_im/src/transformers/manager.dart:92:22)
<asynchronous suspension>
#7      Stream.asyncMap.<anonymous closure>.add (dart:async/stream.dart:742:7)
<asynchronous suspension

Resetting all ratchets triggers an error

It seems like sending an empty OMEMO message somehow creates a ratchet with no chain sending key, thus triggering this
exception when trying to reply with an ack message.

E/flutter (23065): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Null check operator used on a null value
E/flutter (23065): #0      OmemoDoubleRatchet.ratchetEncrypt (package:omemo_dart/src/double_ratchet/double_ratchet.dart:310:35)
E/flutter (23065): #1      OmemoManager._encryptToJids (package:omemo_dart/src/omemo/omemomanager.dart:497:43)
E/flutter (23065): <asynchronous suspension>
E/flutter (23065): #2      BaseOmemoManager._onOutgoingStanza (package:moxxmpp/src/xeps/xep_0384/xep_0384.dart:342:20)
E/flutter (23065): <asynchronous suspension>
E/flutter (23065): #3      XmppConnection._runStanzaHandlers (package:moxxmpp/src/connection.dart:629:17)
E/flutter (23065): <asynchronous suspension>
E/flutter (23065): #4      XmppConnection.sendStanza (package:moxxmpp/src/connection.dart:454:18)
E/flutter (23065): <asynchronous suspension>
E/flutter (23065): #5      DiscoManager.discoInfoQuery (package:moxxmpp/src/xeps/xep_0030/xep_0030.dart:317:20)
E/flutter (23065): <asynchronous suspension>
E/flutter (23065): #6      StableIdManager._onMessage (package:moxxmpp/src/xeps/xep_0359.dart:73:22)
E/flutter (23065): <asynchronous suspension>
E/flutter (23065): #7      XmppConnection._runStanzaHandlers (package:moxxmpp/src/connection.dart:629:17)
E/flutter (23065): <asynchronous suspension>
E/flutter (23065): #8      XmppConnection._handleStanza (package:moxxmpp/src/connection.dart:706:30)
E/flutter (23065): <asynchronous suspension>
E/flutter (23065): #9      XmppConnection.handleXmlStream (package:moxxmpp/src/connection.dart:892:9)
E/flutter (23065): <asynchronous suspension>

Test a failed X3DH

If we, for example, look at UWPX whose signatures of the SPK are invalid, omemo_dart should not completely crash.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.