feat: add OMEMO 2 (urn:xmpp:omemo:2) support alongside 0.3.0#19
Merged
Conversation
aaa87c1 to
c148df0
Compare
Support both OMEMO versions, selected per device via a required `version` argument on SessionBuilder/SessionCipher/KeyHelper.generateSignedPreKey. Versions are identified by their XML namespace — "eu.siacs.conversations.axolotl" (formerly 0.3.0) and "urn:xmpp:omemo:2". The Double Ratchet and X3DH mechanics are shared; per-version differences live in a protocol "profile" (src/session/protocol-profile.ts): HKDF info strings, MAC length/associated data, the OMEMOMessage/OMEMOAuthenticatedMessage/ OMEMOKeyExchange wire format, and Ed25519<->Curve25519 identity-key handling. - native: add Curve25519<->Ed25519 public-key conversion wrappers, export them from the WASM build, and recompile. omemo:2 transfers the identity key in Ed25519 form while we keep Curve25519 internally; the Ed25519 key is derived from the public Curve25519 key via fe_montx_to_edy (sign bit 0), matching libomemo-c so the `ik` field and associated data interoperate. - protobufs: add OMEMO.proto + loadOMEMOMessages() (parsed with keepCase). - session: wire the profile through builder/cipher; per-version behavior (MAC form, registrationId-on-wire, Ed identity key) is carried as profile flags rather than version checks in the cipher. The omemo:2 signed pre-key signature is computed over the raw 32-byte Curve25519 form. - record: persist per-session protocolVersion + omemo:2 associated data; store the remote identity key in both its internal Curve and published Ed25519 (omemo:2 trust) forms; bump storage schema to v2 with auto-migration of legacy sessions. - api: export getProtocolProfile, OMEMOVersion, and the conversion helpers; EncryptResult gains an optional `kex` flag. - tests: internal round-trips and full end-to-end sessions for both versions, plus cross-implementation interop with libomemo-c (the library Dino uses), captured with no build dependency at test time and pinned in both directions: libomemo.js decrypts libomemo-c's actual omemo:2 messages and verifies its signed-pre-key signature (tools/gen-omemo2-vector.c), and libomemo-c decrypts libomemo.js's own omemo:2 output (tools/dec-omemo2-vector.c, a manual one-time confirmation). BREAKING CHANGE: `version` is now a required SessionBuilder/SessionCipher constructor argument (no default). 0.3.0-only consumers pass "eu.siacs.conversations.axolotl".
2.0.0 is the moment to lock the public API, so restrict it to what downstream consumers reasonably need and stop exporting low-level implementation details. Verified against the OMEMO 2 integration in converse.js, which uses only SessionBuilder/SessionCipher/KeyHelper/ OMEMOAddress and curvePubKeyToEd25519PubKey at runtime (WebCrypto handles its HKDF/AES/hashing). Removed from the public API (still available internally): - raw crypto primitives: encrypt, decrypt, sign, hash, HKDF, HKDFInternal, verifyMAC, ECDHE, getRandomBytes, createKeyPair, Ed25519Sign, Ed25519Verify - internalCrypto and the Curve25519 class - getProtocolProfile and the ProtocolProfile type (internal protocol machinery) Kept: SessionBuilder, SessionCipher, KeyHelper, OMEMOAddress, FingerprintGenerator, SessionRecord, InMemoryStore, startWorker/stopWorker, util, the Ed25519<->Curve conversion helpers (needed for omemo:2 fingerprints), and the contract types/enums. BREAKING CHANGE: the low-level crypto primitives, internalCrypto, the Curve25519 class, getProtocolProfile and ProtocolProfile are no longer exported from the package entry point.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Support both OMEMO versions, selected per device via a required
versionargument on SessionBuilder/SessionCipher/KeyHelper.generateSignedPreKey. Versions are identified by their XML namespace —"eu.siacs.conversations.axolotl" (formerly 0.3.0) and "urn:xmpp:omemo:2".
The Double Ratchet and X3DH mechanics are shared; per-version differences live in a protocol "profile" (src/session/protocol-profile.ts): HKDF info strings, MAC length/associated data, the OMEMOMessage/OMEMOAuthenticatedMessage/ OMEMOKeyExchange wire format, and Ed25519<->Curve25519 identity-key handling.
ikfield and associated data interoperate.kexflag.BREAKING CHANGE:
versionis now a required SessionBuilder/SessionCipher constructor argument (no default). 0.3.0-only consumers pass "eu.siacs.conversations.axolotl".