Update for core changes

This commit is contained in:
Niels Andriesse 2019-10-07 15:30:20 +11:00
parent 4f46c6317b
commit 19ec4db687
8 changed files with 82 additions and 79 deletions

View File

@ -81,11 +81,17 @@ import org.webrtc.PeerConnectionFactory;
import org.webrtc.PeerConnectionFactory.InitializationOptions; import org.webrtc.PeerConnectionFactory.InitializationOptions;
import org.webrtc.voiceengine.WebRtcAudioManager; import org.webrtc.voiceengine.WebRtcAudioManager;
import org.webrtc.voiceengine.WebRtcAudioUtils; import org.webrtc.voiceengine.WebRtcAudioUtils;
import org.whispersystems.libsignal.IdentityKeyPair;
import org.whispersystems.libsignal.logging.SignalProtocolLoggerProvider; import org.whispersystems.libsignal.logging.SignalProtocolLoggerProvider;
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope; import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
import org.whispersystems.signalservice.internal.push.SignalServiceProtos; import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
import org.whispersystems.signalservice.loki.api.*; import org.whispersystems.signalservice.loki.api.LokiAPIDatabaseProtocol;
import org.whispersystems.signalservice.loki.api.LokiGroupChat;
import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI;
import org.whispersystems.signalservice.loki.api.LokiLongPoller;
import org.whispersystems.signalservice.loki.api.LokiP2PAPI;
import org.whispersystems.signalservice.loki.api.LokiP2PAPIDelegate;
import org.whispersystems.signalservice.loki.api.LokiRSSFeed;
import org.whispersystems.signalservice.loki.api.LokiStorageAPI;
import org.whispersystems.signalservice.loki.utilities.Analytics; import org.whispersystems.signalservice.loki.utilities.Analytics;
import java.security.Security; import java.security.Security;
@ -428,7 +434,8 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
if (userHexEncodedPublicKey != null && IdentityKeyUtil.hasIdentityKey(this)) { if (userHexEncodedPublicKey != null && IdentityKeyUtil.hasIdentityKey(this)) {
byte[] userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(this).getPrivateKey().serialize(); byte[] userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(this).getPrivateKey().serialize();
LokiAPIDatabaseProtocol database = DatabaseFactory.getLokiAPIDatabase(this); LokiAPIDatabaseProtocol database = DatabaseFactory.getLokiAPIDatabase(this);
LokiStorageAPI.Companion.configure(userHexEncodedPublicKey, userPrivateKey, database); boolean isDebugMode = BuildConfig.DEBUG;
LokiStorageAPI.Companion.configure(isDebugMode, userHexEncodedPublicKey, userPrivateKey, database);
} }
} }

View File

@ -39,9 +39,21 @@ import org.thoughtcrime.securesms.crypto.SecurityEvent;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl; import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl;
import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore; import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore;
import org.thoughtcrime.securesms.database.*; import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.AttachmentDatabase;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.database.GroupReceiptDatabase;
import org.thoughtcrime.securesms.database.MessagingDatabase;
import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult; import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult;
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId; import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.PushDatabase;
import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.StickerDatabase;
import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.database.model.StickerRecord; import org.thoughtcrime.securesms.database.model.StickerRecord;
@ -110,9 +122,9 @@ import org.whispersystems.signalservice.api.messages.multidevice.StickerPackOper
import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage; import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
import org.whispersystems.signalservice.api.messages.shared.SharedContact; import org.whispersystems.signalservice.api.messages.shared.SharedContact;
import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.loki.api.LokiDeviceLinkingSession; import org.whispersystems.signalservice.loki.api.DeviceLinkingSession;
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation;
import org.whispersystems.signalservice.loki.api.LokiStorageAPI; import org.whispersystems.signalservice.loki.api.LokiStorageAPI;
import org.whispersystems.signalservice.loki.api.PairingAuthorisation;
import org.whispersystems.signalservice.loki.crypto.LokiServiceCipher; import org.whispersystems.signalservice.loki.crypto.LokiServiceCipher;
import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus; import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus;
import org.whispersystems.signalservice.loki.messaging.LokiServiceMessage; import org.whispersystems.signalservice.loki.messaging.LokiServiceMessage;
@ -267,8 +279,8 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
acceptFriendRequestIfNeeded(envelope, content); acceptFriendRequestIfNeeded(envelope, content);
// Loki - Store pre key bundle if needed // Loki - Store pre key bundle if needed
if (content.lokiMessage.isPresent()) { if (content.lokiServiceMessage.isPresent()) {
LokiServiceMessage lokiMessage = content.lokiMessage.get(); LokiServiceMessage lokiMessage = content.lokiServiceMessage.get();
if (lokiMessage.getPreKeyBundleMessage() != null) { if (lokiMessage.getPreKeyBundleMessage() != null) {
Log.d("Loki", "Received a pre key bundle from: " + envelope.getSource() + "."); Log.d("Loki", "Received a pre key bundle from: " + envelope.getSource() + ".");
int registrationID = TextSecurePreferences.getLocalRegistrationId(context); int registrationID = TextSecurePreferences.getLocalRegistrationId(context);
@ -1015,10 +1027,10 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
} }
} }
private boolean isAuthorisationValid(@NonNull LokiPairingAuthorisation authorisation) { private boolean isAuthorisationValid(@NonNull PairingAuthorisation authorisation) {
boolean isSecondaryDevice = TextSecurePreferences.isSecondaryDevice(context); boolean isSecondaryDevice = TextSecurePreferences.isSecondaryDevice(context);
String ourPubKey = TextSecurePreferences.getLocalNumber(context); String ourPubKey = TextSecurePreferences.getLocalNumber(context);
boolean isRequest = authorisation.getType() == LokiPairingAuthorisation.Type.REQUEST; boolean isRequest = authorisation.getType() == PairingAuthorisation.Type.REQUEST;
if (authorisation.getRequestSignature() == null) { if (authorisation.getRequestSignature() == null) {
Log.w("Loki", "Received a pairing request with missing request signature. Ignored."); Log.w("Loki", "Received a pairing request with missing request signature. Ignored.");
@ -1037,9 +1049,9 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
return authorisation.verify(); return authorisation.verify();
} }
private void handlePairingAuthorisation(@NonNull LokiPairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) { private void handlePairingAuthorisation(@NonNull PairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) {
String ourNumber = TextSecurePreferences.getLocalNumber(context); String ourNumber = TextSecurePreferences.getLocalNumber(context);
if (authorisation.getType() == LokiPairingAuthorisation.Type.REQUEST) { if (authorisation.getType() == PairingAuthorisation.Type.REQUEST) {
handlePairingRequest(authorisation, envelope); handlePairingRequest(authorisation, envelope);
} else if (authorisation.getSecondaryDevicePublicKey().equals(ourNumber)) { } else if (authorisation.getSecondaryDevicePublicKey().equals(ourNumber)) {
// If we were listed as a secondary device, it means we got a confirmation back from the primary device // If we were listed as a secondary device, it means we got a confirmation back from the primary device
@ -1047,18 +1059,18 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
} }
} }
private void handlePairingRequest(@NonNull LokiPairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope) { private void handlePairingRequest(@NonNull PairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope) {
boolean valid = isAuthorisationValid(authorisation); boolean valid = isAuthorisationValid(authorisation);
LokiDeviceLinkingSession linkingSession = LokiDeviceLinkingSession.Companion.getShared(); DeviceLinkingSession linkingSession = DeviceLinkingSession.Companion.getShared();
if (valid && linkingSession.isListeningForLinkingRequest()) { if (valid && linkingSession.isListeningForLinkingRequests()) {
linkingSession.receivedLinkingRequest(authorisation); linkingSession.processLinkingRequest(authorisation);
} else { } else {
// Remove pre key bundle from the user // Remove pre key bundle from the user
DatabaseFactory.getLokiPreKeyBundleDatabase(context).removePreKeyBundle(envelope.getSource()); DatabaseFactory.getLokiPreKeyBundleDatabase(context).removePreKeyBundle(envelope.getSource());
} }
} }
private void handlePairingAuthorisationForSelf(@NonNull LokiPairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) { private void handlePairingAuthorisationForSelf(@NonNull PairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) {
if (TextSecurePreferences.isSecondaryDevice(context)) { if (TextSecurePreferences.isSecondaryDevice(context)) {
Log.w("Loki", "Received an unexpected pairing authorisation (device is already paired as secondary device). Ignoring."); Log.w("Loki", "Received an unexpected pairing authorisation (device is already paired as secondary device). Ignoring.");
return; return;
@ -1069,17 +1081,17 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
return; return;
} }
if (!LokiDeviceLinkingSession.Companion.getShared().isListeningForLinkingRequest()) { if (!DeviceLinkingSession.Companion.getShared().isListeningForLinkingRequests()) {
Log.w("Loki", "Received authorisation but device is not is listening."); Log.w("Loki", "Received authorisation but device is not is listening.");
return; return;
} }
// Unimplemented for REQUEST // Unimplemented for REQUEST
if (authorisation.getType() != LokiPairingAuthorisation.Type.GRANT) { return; } if (authorisation.getType() != PairingAuthorisation.Type.GRANT) { return; }
Log.d("Loki", "Receiving pairing authorisation from: " + authorisation.getPrimaryDevicePublicKey()); Log.d("Loki", "Receiving pairing authorisation from: " + authorisation.getPrimaryDevicePublicKey());
// Send out accept event // Send out accept event
LokiDeviceLinkingSession.Companion.getShared().acceptedLinkingRequest(authorisation); DeviceLinkingSession.Companion.getShared().processLinkingAuthorization(authorisation);
// Set the current device as secondary and update our authorisations // Set the current device as secondary and update our authorisations
String ourNumber = TextSecurePreferences.getLocalNumber(context); String ourNumber = TextSecurePreferences.getLocalNumber(context);
@ -1092,7 +1104,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
// Propagate the updates to the file server // Propagate the updates to the file server
LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared(); LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared();
if (storageAPI != null) { storageAPI.updateOurDeviceMappings(); } if (storageAPI != null) { storageAPI.updateUserDeviceMappings(); }
// Update display names // Update display names
if (content.senderDisplayName.isPresent() && content.senderDisplayName.get().length() > 0) { if (content.senderDisplayName.isPresent() && content.senderDisplayName.get().length() > 0) {

View File

@ -5,14 +5,14 @@ import android.support.v7.app.AlertDialog
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.logging.Log import org.thoughtcrime.securesms.logging.Log
import org.whispersystems.signalservice.loki.api.LokiDeviceLinkingSession
import org.whispersystems.signalservice.loki.api.LokiDeviceLinkingSessionListener
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation
import org.whispersystems.signalservice.loki.api.LokiStorageAPI
import org.whispersystems.signalservice.loki.utilities.retryIfNeeded
import org.thoughtcrime.securesms.util.Util import org.thoughtcrime.securesms.util.Util
import org.whispersystems.signalservice.loki.api.DeviceLinkingSession
import org.whispersystems.signalservice.loki.api.DeviceLinkingSessionListener
import org.whispersystems.signalservice.loki.api.LokiStorageAPI
import org.whispersystems.signalservice.loki.api.PairingAuthorisation
import org.whispersystems.signalservice.loki.utilities.retryIfNeeded
class DeviceLinkingDialog private constructor(private val context: Context, private val mode: DeviceLinkingView.Mode, private val delegate: DeviceLinkingDialogDelegate? = null): DeviceLinkingViewDelegate, LokiDeviceLinkingSessionListener { class DeviceLinkingDialog private constructor(private val context: Context, private val mode: DeviceLinkingView.Mode, private val delegate: DeviceLinkingDialogDelegate? = null): DeviceLinkingViewDelegate, DeviceLinkingSessionListener {
private lateinit var view: DeviceLinkingView private lateinit var view: DeviceLinkingView
private lateinit var dialog: AlertDialog private lateinit var dialog: AlertDialog
@ -42,20 +42,20 @@ class DeviceLinkingDialog private constructor(private val context: Context, priv
// region Private functions // region Private functions
private fun startListening() { private fun startListening() {
LokiDeviceLinkingSession.shared.startListeningForLinkingRequests() DeviceLinkingSession.shared.startListeningForLinkingRequests()
LokiDeviceLinkingSession.shared.addListener(this) DeviceLinkingSession.shared.addListener(this)
} }
private fun stopListening() { private fun stopListening() {
LokiDeviceLinkingSession.shared.stopListeningForLinkingRequests() DeviceLinkingSession.shared.stopListeningForLinkingRequests()
LokiDeviceLinkingSession.shared.removeListener(this) DeviceLinkingSession.shared.removeListener(this)
} }
// endregion // endregion
// region Dialog View Delegate // region Dialog View Delegate
override fun authorise(pairing: LokiPairingAuthorisation): Boolean { override fun authorise(pairing: PairingAuthorisation): Boolean {
val signedAuthorisation = pairing.sign(LokiPairingAuthorisation.Type.GRANT, userPrivateKey) val signedAuthorisation = pairing.sign(PairingAuthorisation.Type.GRANT, userPrivateKey)
if (signedAuthorisation == null || signedAuthorisation.type != LokiPairingAuthorisation.Type.GRANT) { if (signedAuthorisation == null || signedAuthorisation.type != PairingAuthorisation.Type.GRANT) {
Log.e("Loki", "Failed to sign grant authorisation") Log.e("Loki", "Failed to sign grant authorisation")
return false return false
} }
@ -71,7 +71,7 @@ class DeviceLinkingDialog private constructor(private val context: Context, priv
DatabaseFactory.getLokiAPIDatabase(context).insertOrUpdatePairingAuthorisation(signedAuthorisation) DatabaseFactory.getLokiAPIDatabase(context).insertOrUpdatePairingAuthorisation(signedAuthorisation)
// Update the api // Update the api
LokiStorageAPI.shared?.updateOurDeviceMappings() LokiStorageAPI.shared?.updateUserDeviceMappings()
return true return true
} }
@ -93,22 +93,22 @@ class DeviceLinkingDialog private constructor(private val context: Context, priv
// endregion // endregion
// region Loki Device Session Listener // region Loki Device Session Listener
override fun onDeviceLinkingRequestReceived(authorisation: LokiPairingAuthorisation) { override fun requestUserAuthorization(authorisation: PairingAuthorisation) {
Util.runOnMain { Util.runOnMain {
view.requestUserAuthorization(authorisation) view.requestUserAuthorization(authorisation)
} }
// Stop listening to any more requests // Stop listening to any more requests
LokiDeviceLinkingSession.shared.stopListeningForLinkingRequests() DeviceLinkingSession.shared.stopListeningForLinkingRequests()
} }
override fun onDeviceLinkRequestAccepted(authorisation: LokiPairingAuthorisation) { override fun onDeviceLinkRequestAuthorized(authorisation: PairingAuthorisation) {
Util.runOnMain { Util.runOnMain {
view.onDeviceLinkAuthorized(authorisation) view.onDeviceLinkAuthorized(authorisation)
} }
// Stop listening to any more requests // Stop listening to any more requests
LokiDeviceLinkingSession.shared.stopListeningForLinkingRequests() DeviceLinkingSession.shared.stopListeningForLinkingRequests()
} }
// endregion // endregion
} }

View File

@ -1,6 +1,6 @@
package org.thoughtcrime.securesms.loki package org.thoughtcrime.securesms.loki
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation import org.whispersystems.signalservice.loki.api.PairingAuthorisation
interface DeviceLinkingDialogDelegate { interface DeviceLinkingDialogDelegate {
fun handleDeviceLinkAuthorized() {} fun handleDeviceLinkAuthorized() {}
@ -8,5 +8,5 @@ interface DeviceLinkingDialogDelegate {
} }
interface DeviceLinkingViewDelegate: DeviceLinkingDialogDelegate { interface DeviceLinkingViewDelegate: DeviceLinkingDialogDelegate {
fun authorise(pairing: LokiPairingAuthorisation): Boolean { return false } fun authorise(pairing: PairingAuthorisation): Boolean { return false }
} }

View File

@ -4,22 +4,14 @@ import android.content.Context
import android.graphics.Color import android.graphics.Color
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.os.Handler import android.os.Handler
import android.os.Looper
import android.util.AttributeSet import android.util.AttributeSet
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.widget.LinearLayout import android.widget.LinearLayout
import kotlinx.android.synthetic.main.view_device_linking.view.* import kotlinx.android.synthetic.main.view_device_linking.view.*
import network.loki.messenger.R import network.loki.messenger.R
import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.libsignal.util.guava.Optional import org.whispersystems.signalservice.loki.api.PairingAuthorisation
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage
import org.whispersystems.signalservice.api.push.SignalServiceAddress
import org.whispersystems.signalservice.loki.api.LokiDeviceLinkingSession
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
import org.whispersystems.signalservice.loki.utilities.removing05PrefixIfNeeded import org.whispersystems.signalservice.loki.utilities.removing05PrefixIfNeeded
import java.io.File import java.io.File
@ -28,7 +20,7 @@ import java.io.FileOutputStream
class DeviceLinkingView private constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, private val mode: Mode, private var delegate: DeviceLinkingViewDelegate) : LinearLayout(context, attrs, defStyleAttr) { class DeviceLinkingView private constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, private val mode: Mode, private var delegate: DeviceLinkingViewDelegate) : LinearLayout(context, attrs, defStyleAttr) {
private lateinit var languageFileDirectory: File private lateinit var languageFileDirectory: File
var dismiss: (() -> Unit)? = null var dismiss: (() -> Unit)? = null
var pairingAuthorisation: LokiPairingAuthorisation? = null var pairingAuthorisation: PairingAuthorisation? = null
private set private set
// region Types // region Types
@ -91,14 +83,14 @@ class DeviceLinkingView private constructor(context: Context, attrs: AttributeSe
// endregion // endregion
// region Device Linking // region Device Linking
fun requestUserAuthorization(authorisation: LokiPairingAuthorisation) { fun requestUserAuthorization(authorisation: PairingAuthorisation) {
// To be called when a linking request has been received // To be called when a linking request has been received
if (mode != Mode.Master) { if (mode != Mode.Master) {
Log.w("Loki", "Received request for pairing authorisation on a slave device") Log.w("Loki", "Received request for pairing authorisation on a slave device")
return return
} }
if (authorisation.type != LokiPairingAuthorisation.Type.REQUEST) { if (authorisation.type != PairingAuthorisation.Type.REQUEST) {
Log.w("Loki", "Received request for GRANT pairing authorisation! It shouldn't be possible!!") Log.w("Loki", "Received request for GRANT pairing authorisation! It shouldn't be possible!!")
return return
} }
@ -132,7 +124,7 @@ class DeviceLinkingView private constructor(context: Context, attrs: AttributeSe
} }
} }
fun onDeviceLinkAuthorized(authorisation: LokiPairingAuthorisation) { fun onDeviceLinkAuthorized(authorisation: PairingAuthorisation) {
// To be called when a device link was accepted by the primary device // To be called when a device link was accepted by the primary device
if (mode == Mode.Master || pairingAuthorisation != null) { return } if (mode == Mode.Master || pairingAuthorisation != null) { return }
pairingAuthorisation = authorisation pairingAuthorisation = authorisation

View File

@ -8,7 +8,7 @@ import org.thoughtcrime.securesms.util.Base64
import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.loki.api.LokiAPIDatabaseProtocol import org.whispersystems.signalservice.loki.api.LokiAPIDatabaseProtocol
import org.whispersystems.signalservice.loki.api.LokiAPITarget import org.whispersystems.signalservice.loki.api.LokiAPITarget
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation import org.whispersystems.signalservice.loki.api.PairingAuthorisation
// TODO: Clean this up a bit // TODO: Clean this up a bit
@ -105,14 +105,14 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
database.insertOrUpdate(receivedMessageHashValuesCache, row, "$userID = ?", wrap(userPublicKey)) database.insertOrUpdate(receivedMessageHashValuesCache, row, "$userID = ?", wrap(userPublicKey))
} }
override fun getGroupChatAuthToken(server: String): String? { override fun getAuthToken(server: String): String? {
val database = databaseHelper.readableDatabase val database = databaseHelper.readableDatabase
return database.get(groupChatAuthTokenTable, "${Companion.server} = ?", wrap(server)) { cursor -> return database.get(groupChatAuthTokenTable, "${Companion.server} = ?", wrap(server)) { cursor ->
cursor.getString(cursor.getColumnIndexOrThrow(token)) cursor.getString(cursor.getColumnIndexOrThrow(token))
} }
} }
override fun setGroupChatAuthToken(server: String, newValue: String?) { override fun setAuthToken(server: String, newValue: String?) {
val database = databaseHelper.writableDatabase val database = databaseHelper.writableDatabase
if (newValue != null) { if (newValue != null) {
val row = wrap(mapOf(Companion.server to server, token to newValue)) val row = wrap(mapOf(Companion.server to server, token to newValue))
@ -152,18 +152,18 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
database.insertOrUpdate(lastDeletionServerIDCache, row, "$lastDeletionServerIDCacheIndex = ?", wrap(index)) database.insertOrUpdate(lastDeletionServerIDCache, row, "$lastDeletionServerIDCacheIndex = ?", wrap(index))
} }
override fun getPairingAuthorisations(pubKey: String): List<LokiPairingAuthorisation> { override fun getPairingAuthorisations(hexEncodedPublicKey: String): List<PairingAuthorisation> {
val database = databaseHelper.readableDatabase val database = databaseHelper.readableDatabase
return database.getAll(multiDeviceAuthTable, "$primaryDevice = ? OR $secondaryDevice = ?", arrayOf(pubKey, pubKey)) { cursor -> return database.getAll(multiDeviceAuthTable, "$primaryDevice = ? OR $secondaryDevice = ?", arrayOf(hexEncodedPublicKey, hexEncodedPublicKey)) { cursor ->
val primaryDevicePubKey = cursor.getString(primaryDevice) val primaryDevicePubKey = cursor.getString(primaryDevice)
val secondaryDevicePubKey = cursor.getString(secondaryDevice) val secondaryDevicePubKey = cursor.getString(secondaryDevice)
val requestSignature: ByteArray? = if (cursor.isNull(cursor.getColumnIndexOrThrow(requestSignature))) null else cursor.getBase64EncodedData(requestSignature) val requestSignature: ByteArray? = if (cursor.isNull(cursor.getColumnIndexOrThrow(requestSignature))) null else cursor.getBase64EncodedData(requestSignature)
val grantSignature: ByteArray? = if (cursor.isNull(cursor.getColumnIndexOrThrow(grantSignature))) null else cursor.getBase64EncodedData(grantSignature) val grantSignature: ByteArray? = if (cursor.isNull(cursor.getColumnIndexOrThrow(grantSignature))) null else cursor.getBase64EncodedData(grantSignature)
LokiPairingAuthorisation(primaryDevicePubKey, secondaryDevicePubKey, requestSignature, grantSignature) PairingAuthorisation(primaryDevicePubKey, secondaryDevicePubKey, requestSignature, grantSignature)
} }
} }
override fun insertOrUpdatePairingAuthorisation(authorisation: LokiPairingAuthorisation) { override fun insertOrUpdatePairingAuthorisation(authorisation: PairingAuthorisation) {
val database = databaseHelper.writableDatabase val database = databaseHelper.writableDatabase
val values = ContentValues() val values = ContentValues()
values.put(primaryDevice, authorisation.primaryDevicePublicKey) values.put(primaryDevice, authorisation.primaryDevicePublicKey)
@ -173,9 +173,9 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
database.insertOrUpdate(multiDeviceAuthTable, values, "$primaryDevice = ? AND $secondaryDevice = ?", arrayOf(authorisation.primaryDevicePublicKey, authorisation.secondaryDevicePublicKey)) database.insertOrUpdate(multiDeviceAuthTable, values, "$primaryDevice = ? AND $secondaryDevice = ?", arrayOf(authorisation.primaryDevicePublicKey, authorisation.secondaryDevicePublicKey))
} }
override fun removePairingAuthorisations(pubKey: String) { override fun removePairingAuthorisations(hexEncodedPublicKey: String) {
val database = databaseHelper.readableDatabase val database = databaseHelper.readableDatabase
database.delete(multiDeviceAuthTable, "$primaryDevice = ? OR $secondaryDevice = ?", arrayOf(pubKey, pubKey)) database.delete(multiDeviceAuthTable, "$primaryDevice = ? OR $secondaryDevice = ?", arrayOf(hexEncodedPublicKey, hexEncodedPublicKey))
} }
} }

View File

@ -1,35 +1,27 @@
package org.thoughtcrime.securesms.loki package org.thoughtcrime.securesms.loki
import android.content.Context import android.content.Context
import android.os.Handler
import android.os.Looper
import nl.komponents.kovenant.Promise import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.deferred import nl.komponents.kovenant.deferred
import nl.komponents.kovenant.functional.map
import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.database.Address import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.jobs.BaseJob
import org.thoughtcrime.securesms.jobs.PushTextSendJob
import org.thoughtcrime.securesms.logging.Log import org.thoughtcrime.securesms.logging.Log
import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.libsignal.util.guava.Optional import org.whispersystems.libsignal.util.guava.Optional
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair
import org.whispersystems.signalservice.api.messages.SignalServiceContent
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope
import org.whispersystems.signalservice.api.push.SignalServiceAddress import org.whispersystems.signalservice.api.push.SignalServiceAddress
import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation
import org.whispersystems.signalservice.loki.api.LokiStorageAPI import org.whispersystems.signalservice.loki.api.LokiStorageAPI
import org.whispersystems.signalservice.loki.api.PairingAuthorisation
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus
fun getAllDevices(context: Context, pubKey: String, storageAPI: LokiStorageAPI, block: (devicePubKey: String, isFriend: Boolean, friendCount: Int) -> Unit) { fun getAllDevices(context: Context, pubKey: String, storageAPI: LokiStorageAPI, block: (devicePubKey: String, isFriend: Boolean, friendCount: Int) -> Unit) {
val ourPubKey = TextSecurePreferences.getLocalNumber(context) val ourPubKey = TextSecurePreferences.getLocalNumber(context)
// Get all the devices and run our logic on them // Get all the devices and run our logic on them
storageAPI.getAllDevices(pubKey).success { items -> storageAPI.getAllDevicePublicKeys(pubKey).success { items ->
val devices = items.toMutableSet() val devices = items.toMutableSet()
// Remove our self if we intended this message to go to another recipient // Remove our self if we intended this message to go to another recipient
if (pubKey != ourPubKey) { if (pubKey != ourPubKey) {
@ -51,7 +43,7 @@ fun shouldAutomaticallyBecomeFriendsWithDevice(pubKey: String, context: Context)
// If so then we add them automatically as a friend // If so then we add them automatically as a friend
val deferred = deferred<Boolean, Unit>() val deferred = deferred<Boolean, Unit>()
storageAPI.getPrimaryDevice(pubKey).success { primaryDevicePubKey -> storageAPI.getPrimaryDevicePublicKey(pubKey).success { primaryDevicePubKey ->
// Make sure we have a primary device // Make sure we have a primary device
if (primaryDevicePubKey == null) { if (primaryDevicePubKey == null) {
deferred.resolve(false) deferred.resolve(false)
@ -63,7 +55,7 @@ fun shouldAutomaticallyBecomeFriendsWithDevice(pubKey: String, context: Context)
if (primaryDevicePubKey == ourPubKey) { if (primaryDevicePubKey == ourPubKey) {
// If the friend request is from our secondary device then we need to confirm and check that we have it registered. // If the friend request is from our secondary device then we need to confirm and check that we have it registered.
// If we do then add it // If we do then add it
storageAPI.getSecondaryDevices(ourPubKey).success { secondaryDevices -> storageAPI.getSecondaryDevicePublicKeys(ourPubKey).success { secondaryDevices ->
// We should become friends if the pubKey is in our secondary device list // We should become friends if the pubKey is in our secondary device list
deferred.resolve(secondaryDevices.contains(pubKey)) deferred.resolve(secondaryDevices.contains(pubKey))
}.fail { }.fail {
@ -88,13 +80,13 @@ fun shouldAutomaticallyBecomeFriendsWithDevice(pubKey: String, context: Context)
return deferred.promise return deferred.promise
} }
fun sendAuthorisationMessage(context: Context, contactHexEncodedPublicKey: String, authorisation: LokiPairingAuthorisation): Promise<Unit, Exception> { fun sendAuthorisationMessage(context: Context, contactHexEncodedPublicKey: String, authorisation: PairingAuthorisation): Promise<Unit, Exception> {
val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender() val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender()
val address = SignalServiceAddress(contactHexEncodedPublicKey) val address = SignalServiceAddress(contactHexEncodedPublicKey)
val message = SignalServiceDataMessage.newBuilder().withBody("").withPairingAuthorisation(authorisation) val message = SignalServiceDataMessage.newBuilder().withBody("").withPairingAuthorisation(authorisation)
// A REQUEST should always act as a friend request. A GRANT should always be replying back as a normal message. // A REQUEST should always act as a friend request. A GRANT should always be replying back as a normal message.
if (authorisation.type == LokiPairingAuthorisation.Type.REQUEST) { if (authorisation.type == PairingAuthorisation.Type.REQUEST) {
val preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(address.number) val preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(address.number)
message.asFriendRequest(true).withPreKeyBundle(preKeyBundle) message.asFriendRequest(true).withPreKeyBundle(preKeyBundle)
} }

View File

@ -25,7 +25,7 @@ import org.thoughtcrime.securesms.util.Hex
import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.curve25519.Curve25519 import org.whispersystems.curve25519.Curve25519
import org.whispersystems.libsignal.util.KeyHelper import org.whispersystems.libsignal.util.KeyHelper
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation import org.whispersystems.signalservice.loki.api.PairingAuthorisation
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
import org.whispersystems.signalservice.loki.utilities.Analytics import org.whispersystems.signalservice.loki.utilities.Analytics
import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation
@ -206,7 +206,7 @@ class SeedActivity : BaseActionBarActivity() {
// Build the pairing request // Build the pairing request
val primaryDevicePublicKey = publicKeyEditText.text.trim().toString() val primaryDevicePublicKey = publicKeyEditText.text.trim().toString()
val authorisation = LokiPairingAuthorisation(primaryDevicePublicKey, hexEncodedPublicKey).sign(LokiPairingAuthorisation.Type.REQUEST, keyPair.privateKey.serialize()) val authorisation = PairingAuthorisation(primaryDevicePublicKey, hexEncodedPublicKey).sign(PairingAuthorisation.Type.REQUEST, keyPair.privateKey.serialize())
if (authorisation == null) { if (authorisation == null) {
Log.w("Loki", "Failed to sign outgoing pairing request :(") Log.w("Loki", "Failed to sign outgoing pairing request :(")
resetRegistration() resetRegistration()