mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 12:05:22 +00:00
fix: fallback on biometric key failures and retry creating key, fix up notification issues
This commit is contained in:
parent
58dfd3b7cd
commit
ba60e8a8ee
@ -159,8 +159,8 @@ dependencies {
|
||||
testImplementation 'org.robolectric:shadows-multidex:4.4'
|
||||
}
|
||||
|
||||
def canonicalVersionCode = 286
|
||||
def canonicalVersionName = "1.13.5"
|
||||
def canonicalVersionCode = 287
|
||||
def canonicalVersionName = "1.13.6"
|
||||
|
||||
def postFixSize = 10
|
||||
def abiPostFix = ['armeabi-v7a' : 1,
|
||||
|
@ -46,6 +46,7 @@ import org.thoughtcrime.securesms.crypto.BiometricSecretProvider;
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||
import org.thoughtcrime.securesms.util.AnimationCompleteListener;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Signature;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
@ -68,6 +69,7 @@ public class PassphrasePromptActivity extends BaseActionBarActivity {
|
||||
|
||||
private boolean authenticated;
|
||||
private boolean failure;
|
||||
private boolean hasSignatureObject = true;
|
||||
|
||||
private KeyCachingService keyCachingService;
|
||||
|
||||
@ -205,7 +207,23 @@ public class PassphrasePromptActivity extends BaseActionBarActivity {
|
||||
if (fingerprintManager.isHardwareDetected() && fingerprintManager.hasEnrolledFingerprints()) {
|
||||
Log.i(TAG, "Listening for fingerprints...");
|
||||
fingerprintCancellationSignal = new CancellationSignal();
|
||||
fingerprintManager.authenticate(new FingerprintManagerCompat.CryptoObject(biometricSecretProvider.getOrCreateBiometricSignature(this)), 0, fingerprintCancellationSignal, fingerprintListener, null);
|
||||
Signature signature;
|
||||
try {
|
||||
signature = biometricSecretProvider.getOrCreateBiometricSignature(this);
|
||||
hasSignatureObject = true;
|
||||
throw new InvalidKeyException("e");
|
||||
} catch (InvalidKeyException e) {
|
||||
signature = null;
|
||||
hasSignatureObject = false;
|
||||
Log.e(TAG, "Error getting / creating signature", e);
|
||||
}
|
||||
fingerprintManager.authenticate(
|
||||
signature == null ? null : new FingerprintManagerCompat.CryptoObject(signature),
|
||||
0,
|
||||
fingerprintCancellationSignal,
|
||||
fingerprintListener,
|
||||
null
|
||||
);
|
||||
} else {
|
||||
Log.i(TAG, "firing intent...");
|
||||
Intent intent = keyguardManager.createConfirmDeviceCredentialIntent("Unlock Session", "");
|
||||
@ -230,8 +248,22 @@ public class PassphrasePromptActivity extends BaseActionBarActivity {
|
||||
public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
|
||||
Log.i(TAG, "onAuthenticationSucceeded");
|
||||
if (result.getCryptoObject() == null || result.getCryptoObject().getSignature() == null) {
|
||||
if (hasSignatureObject) {
|
||||
// authentication failed
|
||||
onAuthenticationFailed();
|
||||
} else {
|
||||
fingerprintPrompt.setImageResource(R.drawable.ic_check_white_48dp);
|
||||
fingerprintPrompt.getBackground().setColorFilter(getResources().getColor(R.color.green_500), PorterDuff.Mode.SRC_IN);
|
||||
fingerprintPrompt.animate().setInterpolator(new BounceInterpolator()).scaleX(1.1f).scaleY(1.1f).setDuration(500).setListener(new AnimationCompleteListener() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
handleAuthenticated();
|
||||
|
||||
fingerprintPrompt.setImageResource(R.drawable.ic_fingerprint_white_48dp);
|
||||
fingerprintPrompt.getBackground().setColorFilter(getResources().getColor(R.color.signal_primary), PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Signature object now successfully unlocked
|
||||
|
@ -6,6 +6,7 @@ import android.security.keystore.KeyGenParameterSpec
|
||||
import android.security.keystore.KeyProperties
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsession.utilities.Util
|
||||
import java.security.InvalidKeyException
|
||||
import java.security.KeyPairGenerator
|
||||
import java.security.KeyStore
|
||||
import java.security.PrivateKey
|
||||
@ -58,9 +59,20 @@ class BiometricSecretProvider {
|
||||
createAsymmetricKey(context)
|
||||
TextSecurePreferences.setFingerprintKeyGenerated(context)
|
||||
}
|
||||
val signature = try {
|
||||
val key = ks.getKey(BIOMETRIC_ASYM_KEY_ALIAS, null) as PrivateKey
|
||||
val signature = Signature.getInstance(SIGNATURE_ALGORITHM)
|
||||
signature.initSign(key)
|
||||
signature
|
||||
} catch (e: InvalidKeyException) {
|
||||
ks.deleteEntry(BIOMETRIC_ASYM_KEY_ALIAS)
|
||||
createAsymmetricKey(context)
|
||||
TextSecurePreferences.setFingerprintKeyGenerated(context)
|
||||
val key = ks.getKey(BIOMETRIC_ASYM_KEY_ALIAS, null) as PrivateKey
|
||||
val signature = Signature.getInstance(SIGNATURE_ALGORITHM)
|
||||
signature.initSign(key)
|
||||
signature
|
||||
}
|
||||
return signature
|
||||
}
|
||||
|
||||
|
@ -278,10 +278,10 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
||||
|
||||
try {
|
||||
if (notificationState.hasMultipleThreads()) {
|
||||
sendMultipleThreadNotification(context, notificationState, signal);
|
||||
for (long threadId : notificationState.getThreads()) {
|
||||
sendSingleThreadNotification(context, new NotificationState(notificationState.getNotificationsForThread(threadId)), false, true);
|
||||
}
|
||||
sendMultipleThreadNotification(context, notificationState, signal);
|
||||
} else if (notificationState.getMessageCount() > 0){
|
||||
sendSingleThreadNotification(context, notificationState, signal, false);
|
||||
} else {
|
||||
@ -305,7 +305,7 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
||||
String trimmedText = "";
|
||||
if (text != null) {
|
||||
int trimEnd = Math.min(text.length(), 50);
|
||||
trimmedText = text.subSequence(0,trimEnd) + (text.length() > 50 ? "..." : "");
|
||||
trimmedText = text.subSequence(0,trimEnd) + (text.length() >= 50 ? "..." : "");
|
||||
}
|
||||
return trimmedText;
|
||||
}
|
||||
|
@ -4,8 +4,9 @@ import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import com.google.firebase.messaging.FirebaseMessagingService
|
||||
import com.google.firebase.messaging.RemoteMessage
|
||||
import org.session.libsession.messaging.jobs.BatchMessageReceiveJob
|
||||
import org.session.libsession.messaging.jobs.JobQueue
|
||||
import org.session.libsession.messaging.jobs.MessageReceiveJob
|
||||
import org.session.libsession.messaging.jobs.MessageReceiveParameters
|
||||
import org.session.libsession.messaging.utilities.MessageWrapper
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsignal.utilities.Base64
|
||||
@ -27,7 +28,7 @@ class PushNotificationService : FirebaseMessagingService() {
|
||||
if (data != null) {
|
||||
try {
|
||||
val envelopeAsData = MessageWrapper.unwrap(data).toByteArray()
|
||||
val job = MessageReceiveJob(envelopeAsData)
|
||||
val job = BatchMessageReceiveJob(listOf(MessageReceiveParameters(envelopeAsData)), null)
|
||||
JobQueue.shared.add(job)
|
||||
} catch (e: Exception) {
|
||||
Log.d("Loki", "Failed to unwrap data for message due to error: $e.")
|
||||
|
@ -135,14 +135,12 @@ class BatchMessageReceiveJob(
|
||||
}
|
||||
storage.incrementUnread(threadId, trueUnreadCount)
|
||||
storage.updateThread(threadId, true)
|
||||
SSKEnvironment.shared.notificationManager.updateNotification(context, threadId)
|
||||
}
|
||||
}
|
||||
|
||||
// await all thread processing
|
||||
deferredThreadMap.awaitAll()
|
||||
}
|
||||
|
||||
SSKEnvironment.shared.notificationManager.updateNotification(context)
|
||||
if (failures.isEmpty()) {
|
||||
handleSuccess()
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user