diff --git a/lib/src/double_ratchet/double_ratchet.dart b/lib/src/double_ratchet/double_ratchet.dart index bd3297a..78b7bbd 100644 --- a/lib/src/double_ratchet/double_ratchet.dart +++ b/lib/src/double_ratchet/double_ratchet.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'package:cryptography/cryptography.dart'; import 'package:hex/hex.dart'; import 'package:meta/meta.dart'; @@ -356,6 +355,7 @@ class OmemoDoubleRatchet { ..message = headerBytes; } + /// Returns a copy of the ratchet. OmemoDoubleRatchet clone() { return OmemoDoubleRatchet( dhs, @@ -375,6 +375,15 @@ class OmemoDoubleRatchet { ); } + /// Computes the fingerprint of the double ratchet, according to + /// XEP-0384. + Future get fingerprint async { + final curveKey = await ik.toCurve25519(); + return HEX.encode( + await curveKey.getBytes(), + ); + } + @visibleForTesting Future equals(OmemoDoubleRatchet other) async { final dhrMatch = dhr == null diff --git a/lib/src/omemo/omemo.dart b/lib/src/omemo/omemo.dart index 1c5fd33..060a683 100644 --- a/lib/src/omemo/omemo.dart +++ b/lib/src/omemo/omemo.dart @@ -755,8 +755,43 @@ class OmemoManager { await _leaveRatchetCriticalSection(jid); } - // TODO - Future?> getFingerprintsForJid(String jid) async => null; + /// If ratchets with [jid] exists, returns a list of fingerprints for each + /// ratchet. + /// + /// If not ratchets exists, returns null. + Future?> getFingerprintsForJid(String jid) async { + await _getFingerprintsForJidImpl(jid); + final result = await _getFingerprintsForJidImpl(jid); + await _leaveRatchetCriticalSection(jid); + + return result; + } + + Future?> _getFingerprintsForJidImpl(String jid) async { + // Check if we know of the JID. + if (!_deviceList.containsKey(jid)) { + return null; + } + + final devices = _deviceList[jid]!; + final fingerprints = List.empty(growable: true); + for (final device in devices) { + final ratchet = _ratchetMap[RatchetMapKey(jid, device)]; + if (ratchet == null) { + _log.warning('getFingerprintsForJid: Ratchet $jid:$device not found.'); + continue; + } + + fingerprints.add( + DeviceFingerprint( + device, + await ratchet.fingerprint, + ), + ); + } + + return fingerprints; + } /// Returns the device used for encryption and decryption. Future getDevice() => _deviceLock.synchronized(() => _device);