implement Unlock by Samsung Fingerprint (Pass SDK)

This commit is contained in:
Philipp Crocoll
2016-01-10 20:27:26 +01:00
parent 41d6b3ac5e
commit b67f5538ce
14 changed files with 333 additions and 78 deletions

6
.gitmodules vendored Normal file
View File

@@ -0,0 +1,6 @@
[submodule "SamsungPass"]
path = SamsungPass
url = https://github.com/sraiteri/Xamarin-Samsung-Pass.git
[submodule "src/SamsungPass"]
path = src/SamsungPass
url = https://github.com/sraiteri/Xamarin-Samsung-Pass.git

View File

@@ -47,6 +47,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AncientIconSet", "AncientIc
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FingerprintTest", "FingerprintTest\FingerprintTest.csproj", "{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FingerprintTest", "FingerprintTest\FingerprintTest.csproj", "{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SamsungPass", "SamsungPass\Xamarin.SamsungPass\SamsungPass\SamsungPass.csproj", "{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -524,6 +526,24 @@ Global
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU {52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU {52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU {52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Win32.ActiveCfg = Debug|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|x64.ActiveCfg = Debug|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|Any CPU.Build.0 = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|Win32.ActiveCfg = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|x64.ActiveCfg = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

1
src/SamsungPass Submodule

Submodule src/SamsungPass added at 1495b1ad79

View File

@@ -17,6 +17,12 @@ using Javax.Crypto.Spec;
namespace keepass2android namespace keepass2android
{ {
public interface IFingerprintAuthCallback
{
void OnFingerprintAuthSucceeded();
void OnFingerprintError(string toString);
}
public class FingerprintModule public class FingerprintModule
{ {
public Context Context { get; set; } public Context Context { get; set; }
@@ -106,7 +112,7 @@ namespace keepass2android
} }
} }
public abstract class FingerprintCrypt: FingerprintManager.AuthenticationCallback public abstract class FingerprintCrypt: FingerprintManager.AuthenticationCallback, IFingerprintIdentifier
{ {
protected const string FailedToInitCipher = "Failed to init Cipher"; protected const string FailedToInitCipher = "Failed to init Cipher";
public override void OnAuthenticationError(FingerprintState errorCode, ICharSequence errString) public override void OnAuthenticationError(FingerprintState errorCode, ICharSequence errString)
@@ -157,7 +163,9 @@ namespace keepass2android
} }
public abstract bool InitCipher(); public abstract bool Init();
protected static string GetAlias(string keyId) protected static string GetAlias(string keyId)
{ {
return "keepass2android." + keyId; return "keepass2android." + keyId;
@@ -175,6 +183,11 @@ namespace keepass2android
} }
} }
public void StartListening(Context ctx, IFingerprintAuthCallback callback)
{
StartListening(new FingerprintAuthCallbackAdapter(callback, ctx));
}
public void StartListening(FingerprintManager.AuthenticationCallback callback) public void StartListening(FingerprintManager.AuthenticationCallback callback)
{ {
if (!IsFingerprintAuthAvailable) if (!IsFingerprintAuthAvailable)
@@ -227,6 +240,13 @@ namespace keepass2android
} }
} }
public interface IFingerprintIdentifier
{
bool Init();
void StartListening(Context ctx, IFingerprintAuthCallback callback);
void StopListening();
}
public class FingerprintDecryption : FingerprintCrypt public class FingerprintDecryption : FingerprintCrypt
{ {
private readonly Context _context; private readonly Context _context;
@@ -245,9 +265,9 @@ namespace keepass2android
_iv = Base64.Decode(PreferenceManager.GetDefaultSharedPreferences(context).GetString(GetIvPrefKey(prefKey), null), 0); _iv = Base64.Decode(PreferenceManager.GetDefaultSharedPreferences(context).GetString(GetIvPrefKey(prefKey), null), 0);
} }
public override bool InitCipher() public override bool Init()
{ {
Kp2aLog.Log("FP: InitCipher for Dec"); Kp2aLog.Log("FP: Init for Dec");
try try
{ {
_keystore.Load(null); _keystore.Load(null);
@@ -355,9 +375,9 @@ namespace keepass2android
} }
} }
public override bool InitCipher() public override bool Init()
{ {
Kp2aLog.Log("FP: InitCipher for Enc "); Kp2aLog.Log("FP: Init for Enc ");
try try
{ {
_keystore.Load(null); _keystore.Load(null);

View File

@@ -0,0 +1,141 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
using Com.Samsung.Android.Sdk;
using Com.Samsung.Android.Sdk.Pass;
using Java.Lang;
namespace keepass2android
{
class FingerprintSamsungIdentifier: IFingerprintIdentifier
{
SpassFingerprint _spassFingerprint;
Spass _spass;
public FingerprintSamsungIdentifier(Context context)
{
_spass = new Spass();
try
{
_spass.Initialize(context);
}
catch (SecurityException)
{
//"Did you add the permission to the AndroidManifest.xml?");
throw;
}
if (_spass.IsFeatureEnabled(Spass.DeviceFingerprint))
{
_spassFingerprint = new SpassFingerprint(context);
}
else
{
throw new RuntimeException("Fingerprint Featue not available.");
}
}
public bool Init()
{
try
{
return _spassFingerprint.HasRegisteredFinger;
}
catch (UnsupportedOperationException)
{
return false;
}
}
class IdentifyListener : Java.Lang.Object, IIdentifyListener
{
private readonly IFingerprintAuthCallback _callback;
private readonly Context _context;
private readonly FingerprintSamsungIdentifier _id;
public IdentifyListener(IFingerprintAuthCallback callback, Context context, FingerprintSamsungIdentifier id)
{
_callback = callback;
_context = context;
_id = id;
}
public void OnFinished (int responseCode)
{
_id.Listening = false;
if (responseCode == SpassFingerprint.StatusAuthentificationSuccess)
{
_callback.OnFingerprintAuthSucceeded();
}
else if (responseCode == SpassFingerprint.StatusAuthentificationPasswordSuccess)
{
_callback.OnFingerprintAuthSucceeded();
}
}
public void OnReady ()
{
}
public void OnStarted ()
{
}
}
internal bool Listening
{
get; set;
}
public void StartListening(Context ctx, IFingerprintAuthCallback callback)
{
if (Listening) return;
try
{
_spassFingerprint.StartIdentifyWithDialog(ctx, new IdentifyListener(callback, ctx, this), false);
Listening = true;
}
catch (SpassInvalidStateException m)
{
callback.OnFingerprintError(m.Message);
}
catch (IllegalStateException ex)
{
callback.OnFingerprintError(ex.Message);
}
}
public void StopListening()
{
try
{
_spassFingerprint.CancelIdentify();
Listening = false;
}
catch (IllegalStateException ise)
{
Kp2aLog.Log(ise.Message);
}
}
}
}

View File

@@ -24,7 +24,7 @@ namespace keepass2android
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
Theme = "@style/MyTheme_ActionBar", MainLauncher = false)] Theme = "@style/MyTheme_ActionBar", MainLauncher = false)]
[IntentFilter(new[] { "kp2a.action.FingerprintSetupActivity" }, Categories = new[] { Intent.CategoryDefault })] [IntentFilter(new[] { "kp2a.action.FingerprintSetupActivity" }, Categories = new[] { Intent.CategoryDefault })]
public class FingerprintSetupActivity : LockCloseActivity public class FingerprintSetupActivity : LockCloseActivity, IFingerprintAuthCallback
{ {
private readonly ActivityDesign _activityDesign; private readonly ActivityDesign _activityDesign;
@@ -121,6 +121,27 @@ namespace keepass2android
if ((int) Build.VERSION.SdkInt >= 23) if ((int) Build.VERSION.SdkInt >= 23)
RequestPermissions(new[] {Manifest.Permission.UseFingerprint}, FingerprintPermissionRequestCode); RequestPermissions(new[] {Manifest.Permission.UseFingerprint}, FingerprintPermissionRequestCode);
else
{
try
{
//try to create a Samsung ID object
_samsungFingerprint = new FingerprintSamsungIdentifier(this);
if (!_samsungFingerprint.Init())
{
SetError(Resource.String.fingerprint_no_enrolled);
}
ShowRadioButtons();
}
catch (Exception)
{
_samsungFingerprint = null;
}
}
FindViewById(Resource.Id.container_fingerprint_unlock).Visibility = _samsungFingerprint == null
? ViewStates.Visible
: ViewStates.Gone;
} }
string CurrentPreferenceKey string CurrentPreferenceKey
@@ -181,11 +202,16 @@ namespace keepass2android
SetError(Resource.String.fingerprint_no_enrolled); SetError(Resource.String.fingerprint_no_enrolled);
return; return;
} }
ShowRadioButtons();
}
}
private void ShowRadioButtons()
{
FindViewById<TextView>(Resource.Id.tvFatalError).Visibility = ViewStates.Gone; FindViewById<TextView>(Resource.Id.tvFatalError).Visibility = ViewStates.Gone;
FindViewById(Resource.Id.radio_buttons).Visibility = ViewStates.Visible; FindViewById(Resource.Id.radio_buttons).Visibility = ViewStates.Visible;
FindViewById(Resource.Id.fingerprint_auth_container).Visibility = ViewStates.Gone; FindViewById(Resource.Id.fingerprint_auth_container).Visibility = ViewStates.Gone;
} }
}
private void ChangeUnlockMode(FingerprintUnlockMode oldMode, FingerprintUnlockMode newMode) private void ChangeUnlockMode(FingerprintUnlockMode oldMode, FingerprintUnlockMode newMode)
@@ -193,6 +219,15 @@ namespace keepass2android
if (oldMode == newMode) if (oldMode == newMode)
return; return;
if (_samsungFingerprint != null)
{
_unlockMode = newMode;
ISharedPreferencesEditor edit = PreferenceManager.GetDefaultSharedPreferences(this).Edit();
edit.PutString(App.Kp2a.GetDb().CurrentFingerprintModePrefKey, _unlockMode.ToString());
edit.Commit();
return;
}
if (newMode == FingerprintUnlockMode.Disabled) if (newMode == FingerprintUnlockMode.Disabled)
{ {
_unlockMode = newMode; _unlockMode = newMode;
@@ -207,10 +242,10 @@ namespace keepass2android
_enc = new FingerprintEncryption(new FingerprintModule(this), CurrentPreferenceKey); _enc = new FingerprintEncryption(new FingerprintModule(this), CurrentPreferenceKey);
try try
{ {
if (!_enc.InitCipher()) if (!_enc.Init())
throw new Exception("Failed to initialize cipher"); throw new Exception("Failed to initialize cipher");
ResetErrorTextRunnable(); ResetErrorTextRunnable();
_enc.StartListening(new SetupCallback(this)); _enc.StartListening(new FingerprintAuthCallbackAdapter(this, this));
} }
catch (Exception e) catch (Exception e)
{ {
@@ -227,7 +262,10 @@ namespace keepass2android
static readonly long SUCCESS_DELAY_MILLIS = 1300; static readonly long SUCCESS_DELAY_MILLIS = 1300;
private ImageView _fpIcon; private ImageView _fpIcon;
private TextView _fpTextView; private TextView _fpTextView;
public void OnAuthSucceeded()
private FingerprintSamsungIdentifier _samsungFingerprint;
public void OnFingerprintAuthSucceeded()
{ {
_unlockMode = _desiredUnlockMode; _unlockMode = _desiredUnlockMode;
@@ -248,6 +286,7 @@ namespace keepass2android
} }
public void OnFingerprintError(string error) public void OnFingerprintError(string error)
{ {
_fpIcon.SetImageResource(Resource.Drawable.ic_fingerprint_error); _fpIcon.SetImageResource(Resource.Drawable.ic_fingerprint_error);
@@ -270,7 +309,7 @@ namespace keepass2android
{ {
base.OnResume(); base.OnResume();
if (_enc != null) if (_enc != null)
_enc.StartListening(new SetupCallback(this)); _enc.StartListening(new FingerprintAuthCallbackAdapter(this, this));
} }
protected override void OnPause() protected override void OnPause()
@@ -281,33 +320,4 @@ namespace keepass2android
} }
} }
internal class SetupCallback : FingerprintManager.AuthenticationCallback
{
private readonly FingerprintSetupActivity _fingerprintSetupActivity;
public SetupCallback(FingerprintSetupActivity fingerprintSetupActivity)
{
_fingerprintSetupActivity = fingerprintSetupActivity;
}
public override void OnAuthenticationSucceeded(FingerprintManager.AuthenticationResult result)
{
_fingerprintSetupActivity.OnAuthSucceeded();
}
public override void OnAuthenticationError(FingerprintState errorCode, ICharSequence errString)
{
_fingerprintSetupActivity.OnFingerprintError(errString.ToString());
}
public override void OnAuthenticationHelp(FingerprintState helpCode, ICharSequence helpString)
{
_fingerprintSetupActivity.OnFingerprintError(helpString.ToString());
}
public override void OnAuthenticationFailed()
{
_fingerprintSetupActivity.OnFingerprintError(_fingerprintSetupActivity.Resources.GetString(Resource.String.fingerprint_not_recognized));
}
}
} }

View File

@@ -64,7 +64,6 @@ namespace KeeChallenge
private byte[] GenerateChallenge() private byte[] GenerateChallenge()
{ {
CryptoRandom rand = CryptoRandom.Instance;
byte[] chal = CryptoRandom.Instance.GetRandomBytes(challengeLenBytes); byte[] chal = CryptoRandom.Instance.GetRandomBytes(challengeLenBytes);
if (LT64) if (LT64)
{ {

View File

@@ -700,6 +700,7 @@ namespace keepass2android
private ActivityDesign _activityDesign; private ActivityDesign _activityDesign;
private FingerprintDecryption _fingerprintDec; private FingerprintDecryption _fingerprintDec;
private bool _fingerprintPermissionGranted; private bool _fingerprintPermissionGranted;
private PasswordActivityBroadcastReceiver _intentReceiver;
internal class MyActionBarDrawerToggle : ActionBarDrawerToggle internal class MyActionBarDrawerToggle : ActionBarDrawerToggle
@@ -757,6 +758,11 @@ namespace keepass2android
_activityDesign.ApplyTheme(); _activityDesign.ApplyTheme();
base.OnCreate(savedInstanceState); base.OnCreate(savedInstanceState);
_intentReceiver = new PasswordActivityBroadcastReceiver(this);
IntentFilter filter = new IntentFilter();
filter.AddAction(Intent.ActionScreenOff);
RegisterReceiver(_intentReceiver, filter);
//use FlagSecure to make sure the last (revealed) character of the master password is not visible in recent apps //use FlagSecure to make sure the last (revealed) character of the master password is not visible in recent apps
if (PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean( if (PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(
@@ -1800,7 +1806,7 @@ namespace keepass2android
btn.Tag = GetString(Resource.String.fingerprint_unlock_hint); btn.Tag = GetString(Resource.String.fingerprint_unlock_hint);
if (_fingerprintDec.InitCipher()) if (_fingerprintDec.Init())
{ {
btn.SetImageResource(Resource.Drawable.ic_fp_40px); btn.SetImageResource(Resource.Drawable.ic_fp_40px);
_fingerprintDec.StartListening(new FingerprintAuthCallbackAdapter(this, this)); _fingerprintDec.StartListening(new FingerprintAuthCallbackAdapter(this, this));
@@ -2044,13 +2050,36 @@ namespace keepass2android
} }
} }
private class PasswordActivityBroadcastReceiver : BroadcastReceiver
}
public interface IFingerprintAuthCallback
{ {
void OnFingerprintAuthSucceeded(); readonly PasswordActivity _activity;
void OnFingerprintError(string toString); public PasswordActivityBroadcastReceiver(PasswordActivity activity)
{
_activity = activity;
}
public override void OnReceive(Context context, Intent intent)
{
switch (intent.Action)
{
case Intent.ActionScreenOff:
Kp2aLog.Log("bla");
_activity.OnScreenLocked();
break;
}
} }
} }
private void OnScreenLocked()
{
if (_fingerprintDec != null)
_fingerprintDec.StopListening();
}
}
}

View File

@@ -99,4 +99,6 @@
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="keepass2android.keepass2android_debug.permission.KP2aInternalFileBrowsing" /> <uses-permission android:name="keepass2android.keepass2android_debug.permission.KP2aInternalFileBrowsing" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" /> <uses-permission android:name="android.permission.USE_FINGERPRINT" />
<!-- Samsung Pass permission -->
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
</manifest> </manifest>

View File

@@ -102,4 +102,6 @@
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing" /> <uses-permission android:name="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" /> <uses-permission android:name="android.permission.USE_FINGERPRINT" />
<!-- Samsung Pass permission -->
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
</manifest> </manifest>

View File

@@ -80,4 +80,6 @@
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" /> <uses-permission android:name="android.permission.USE_FINGERPRINT" />
<!-- Samsung Pass permission -->
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
</manifest> </manifest>

View File

@@ -43,7 +43,7 @@ namespace keepass2android
private QuickUnlockBroadcastReceiver _intentReceiver; private QuickUnlockBroadcastReceiver _intentReceiver;
private ActivityDesign _design; private ActivityDesign _design;
private bool _fingerprintPermissionGranted; private bool _fingerprintPermissionGranted;
private FingerprintDecryption _fingerprintDec; private IFingerprintIdentifier _fingerprintIdentifier;
private int _quickUnlockLength; private int _quickUnlockLength;
private const int FingerprintPermissionRequestCode = 0; private const int FingerprintPermissionRequestCode = 0;
@@ -141,6 +141,10 @@ namespace keepass2android
if ((int) Build.VERSION.SdkInt >= 23) if ((int) Build.VERSION.SdkInt >= 23)
RequestPermissions(new[] {Manifest.Permission.UseFingerprint}, FingerprintPermissionRequestCode); RequestPermissions(new[] {Manifest.Permission.UseFingerprint}, FingerprintPermissionRequestCode);
else
{
}
} }
@@ -176,7 +180,7 @@ namespace keepass2android
public void OnFingerprintAuthSucceeded() public void OnFingerprintAuthSucceeded()
{ {
_fingerprintDec.StopListening(); _fingerprintIdentifier.StopListening();
var btn = FindViewById<ImageButton>(Resource.Id.fingerprintbtn); var btn = FindViewById<ImageButton>(Resource.Id.fingerprintbtn);
btn.SetImageResource(Resource.Drawable.ic_fingerprint_success); btn.SetImageResource(Resource.Drawable.ic_fingerprint_success);
@@ -207,23 +211,42 @@ namespace keepass2android
return; return;
} }
if (_fingerprintPermissionGranted)
{
FingerprintModule fpModule = new FingerprintModule(this); FingerprintModule fpModule = new FingerprintModule(this);
_fingerprintDec = new FingerprintDecryption(fpModule, App.Kp2a.GetDb().CurrentFingerprintPrefKey, this, _fingerprintIdentifier = new FingerprintDecryption(fpModule, App.Kp2a.GetDb().CurrentFingerprintPrefKey, this,
App.Kp2a.GetDb().CurrentFingerprintPrefKey); App.Kp2a.GetDb().CurrentFingerprintPrefKey);
}
else
{
try
{
_fingerprintIdentifier = new FingerprintSamsungIdentifier(this);
btn.Click += (sender, args) =>
{
if (_fingerprintIdentifier.Init())
_fingerprintIdentifier.StartListening(this, this);
};
}
catch (Exception)
{
FindViewById<ImageButton>(Resource.Id.fingerprintbtn).Visibility = ViewStates.Gone;
return;
}
}
btn.Tag = GetString(Resource.String.fingerprint_unlock_hint); btn.Tag = GetString(Resource.String.fingerprint_unlock_hint);
if (_fingerprintDec.InitCipher()) if (_fingerprintIdentifier.Init())
{ {
btn.SetImageResource(Resource.Drawable.ic_fp_40px); btn.SetImageResource(Resource.Drawable.ic_fp_40px);
_fingerprintDec.StartListening(new FingerprintAuthCallbackAdapter(this, this)); _fingerprintIdentifier.StartListening(this, this);
} }
else else
{ {
//key invalidated permanently //key invalidated permanently
btn.SetImageResource(Resource.Drawable.ic_fingerprint_error); btn.SetImageResource(Resource.Drawable.ic_fingerprint_error);
btn.Tag = GetString(Resource.String.fingerprint_unlock_failed); btn.Tag = GetString(Resource.String.fingerprint_unlock_failed);
_fingerprintDec = null; _fingerprintIdentifier = null;
ClearFingerprintUnlockData(); ClearFingerprintUnlockData();
} }
@@ -233,7 +256,7 @@ namespace keepass2android
btn.SetImageResource(Resource.Drawable.ic_fingerprint_error); btn.SetImageResource(Resource.Drawable.ic_fingerprint_error);
btn.Tag = "Error initializing Fingerprint Unlock: " + e; btn.Tag = "Error initializing Fingerprint Unlock: " + e;
_fingerprintDec = null; _fingerprintIdentifier = null;
} }
@@ -294,23 +317,17 @@ namespace keepass2android
}, 50); }, 50);
if (_fingerprintPermissionGranted)
{
InitFingerprintUnlock();
}
else
{
FindViewById<ImageButton>(Resource.Id.fingerprintbtn).Visibility = ViewStates.Gone;
} InitFingerprintUnlock();
} }
protected override void OnPause() protected override void OnPause()
{ {
base.OnPause(); base.OnPause();
if (_fingerprintDec != null) if (_fingerprintIdentifier != null)
{ {
_fingerprintDec.StopListening(); _fingerprintIdentifier.StopListening();
} }
} }

View File

@@ -50,6 +50,7 @@
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:orientation="horizontal" android:orientation="horizontal"
android:id="@+id/container_fingerprint_unlock"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<RadioButton <RadioButton

View File

@@ -136,6 +136,7 @@
<Compile Include="EntryActivityClasses\ToggleVisibilityPopupMenuItem.cs" /> <Compile Include="EntryActivityClasses\ToggleVisibilityPopupMenuItem.cs" />
<Compile Include="EntryActivityClasses\WriteBinaryToFilePopupItem.cs" /> <Compile Include="EntryActivityClasses\WriteBinaryToFilePopupItem.cs" />
<Compile Include="FingerprintModule.cs" /> <Compile Include="FingerprintModule.cs" />
<Compile Include="FingerprintSamsungIdentifier.cs" />
<Compile Include="FingerprintSetupActivity.cs" /> <Compile Include="FingerprintSetupActivity.cs" />
<Compile Include="ExportDatabaseActivity.cs" /> <Compile Include="ExportDatabaseActivity.cs" />
<Compile Include="fileselect\FileChooserFileProvider.cs" /> <Compile Include="fileselect\FileChooserFileProvider.cs" />
@@ -756,6 +757,10 @@
<Project>{3DA3911E-36DE-465E-8F15-F1991B6437E5}</Project> <Project>{3DA3911E-36DE-465E-8F15-F1991B6437E5}</Project>
<Name>PluginSdkBinding</Name> <Name>PluginSdkBinding</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\SamsungPass\Xamarin.SamsungPass\SamsungPass\SamsungPass.csproj">
<Project>{3a4b8e88-fa9b-4663-bcda-21c12e3af98a}</Project>
<Name>SamsungPass</Name>
</ProjectReference>
<ProjectReference Include="..\TwofishCipher\TwofishCipher.csproj"> <ProjectReference Include="..\TwofishCipher\TwofishCipher.csproj">
<Project>{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}</Project> <Project>{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}</Project>
<Name>TwofishCipher</Name> <Name>TwofishCipher</Name>