mirror of
https://github.com/moparisthebest/keepass2android
synced 2025-03-03 02:11:44 -05:00
NfcChallenge code by Ben Rush
This commit is contained in:
parent
736bbd5ec3
commit
dfe0716635
@ -45,6 +45,7 @@ using MemoryStream = System.IO.MemoryStream;
|
|||||||
using Object = Java.Lang.Object;
|
using Object = Java.Lang.Object;
|
||||||
using Process = Android.OS.Process;
|
using Process = Android.OS.Process;
|
||||||
using String = System.String;
|
using String = System.String;
|
||||||
|
using KeeChallenge;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
@ -60,7 +61,9 @@ namespace keepass2android
|
|||||||
None = 0,
|
None = 0,
|
||||||
KeyFile = 1,
|
KeyFile = 1,
|
||||||
Otp = 2,
|
Otp = 2,
|
||||||
OtpRecovery = 3
|
OtpRecovery = 3,
|
||||||
|
Chal = 4,
|
||||||
|
ChalRecovery = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
public const String KeyDefaultFilename = "defaultFileName";
|
public const String KeyDefaultFilename = "defaultFileName";
|
||||||
@ -76,9 +79,12 @@ namespace keepass2android
|
|||||||
private const string ShowpasswordKey = "ShowPassword";
|
private const string ShowpasswordKey = "ShowPassword";
|
||||||
private const string KeyProviderIdOtp = "KP2A-OTP";
|
private const string KeyProviderIdOtp = "KP2A-OTP";
|
||||||
private const string KeyProviderIdOtpRecovery = "KP2A-OTPSecret";
|
private const string KeyProviderIdOtpRecovery = "KP2A-OTPSecret";
|
||||||
|
private const string KeyProviderIdChallenge = "KP2A-Chal";
|
||||||
|
private const string KeyProviderIdChallengeRecovery = "KP2A-ChalSecret";
|
||||||
|
|
||||||
private const int RequestCodePrepareDbFile = 1000;
|
private const int RequestCodePrepareDbFile = 1000;
|
||||||
private const int RequestCodePrepareOtpAuxFile = 1001;
|
private const int RequestCodePrepareOtpAuxFile = 1001;
|
||||||
|
private const int RequestCodePrepareChalAuxFile = 1001;
|
||||||
|
|
||||||
|
|
||||||
private Task<MemoryStream> _loadDbTask;
|
private Task<MemoryStream> _loadDbTask;
|
||||||
@ -104,6 +110,10 @@ namespace keepass2android
|
|||||||
return KeyProviders.Otp;
|
return KeyProviders.Otp;
|
||||||
if (_keyFileOrProvider == KeyProviderIdOtpRecovery)
|
if (_keyFileOrProvider == KeyProviderIdOtpRecovery)
|
||||||
return KeyProviders.OtpRecovery;
|
return KeyProviders.OtpRecovery;
|
||||||
|
if (_keyFileOrProvider == KeyProviderIdChallenge)
|
||||||
|
return KeyProviders.Chal;
|
||||||
|
if (_keyFileOrProvider == KeyProviderIdChallengeRecovery)
|
||||||
|
return KeyProviders.ChalRecovery;
|
||||||
return KeyProviders.KeyFile;
|
return KeyProviders.KeyFile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,6 +123,8 @@ namespace keepass2android
|
|||||||
|
|
||||||
private bool _starting;
|
private bool _starting;
|
||||||
private OtpInfo _otpInfo;
|
private OtpInfo _otpInfo;
|
||||||
|
private ChallengeInfo _chalInfo;
|
||||||
|
private byte[] _challengeResponse;
|
||||||
private readonly int[] _otpTextViewIds = new[] {Resource.Id.otp1, Resource.Id.otp2, Resource.Id.otp3, Resource.Id.otp4, Resource.Id.otp5, Resource.Id.otp6};
|
private readonly int[] _otpTextViewIds = new[] {Resource.Id.otp1, Resource.Id.otp2, Resource.Id.otp3, Resource.Id.otp4, Resource.Id.otp5, Resource.Id.otp6};
|
||||||
private const string OtpInfoKey = "OtpInfoKey";
|
private const string OtpInfoKey = "OtpInfoKey";
|
||||||
private const string EnteredOtpsKey = "EnteredOtpsKey";
|
private const string EnteredOtpsKey = "EnteredOtpsKey";
|
||||||
@ -120,6 +132,7 @@ namespace keepass2android
|
|||||||
private const string PasswordKey = "PasswordKey";
|
private const string PasswordKey = "PasswordKey";
|
||||||
private const string KeyFileOrProviderKey = "KeyFileOrProviderKey";
|
private const string KeyFileOrProviderKey = "KeyFileOrProviderKey";
|
||||||
|
|
||||||
|
|
||||||
private ActivityDesign _design;
|
private ActivityDesign _design;
|
||||||
|
|
||||||
public PasswordActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
public PasswordActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
||||||
@ -259,12 +272,26 @@ namespace keepass2android
|
|||||||
if (requestCode == RequestCodePrepareDbFile)
|
if (requestCode == RequestCodePrepareDbFile)
|
||||||
PerformLoadDatabase();
|
PerformLoadDatabase();
|
||||||
if (requestCode == RequestCodePrepareOtpAuxFile)
|
if (requestCode == RequestCodePrepareOtpAuxFile)
|
||||||
|
{
|
||||||
|
if (_keyFileOrProvider == KeyProviderIdChallenge)
|
||||||
|
{
|
||||||
|
if (!LoadChalFile()) break;
|
||||||
|
Intent chalIntent = new Intent(this, typeof(NfcChalActivity));
|
||||||
|
chalIntent.PutExtra("challenge", _chalInfo.Challenge);
|
||||||
|
StartActivityForResult(chalIntent, 0);
|
||||||
|
} else {
|
||||||
LoadOtpFile ();
|
LoadOtpFile ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NfcChalActivity.SUCCESS:
|
||||||
|
_challengeResponse = data.GetByteArrayExtra("chalresp");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void LoadOtpFile()
|
private void LoadOtpFile()
|
||||||
{
|
{
|
||||||
new LoadingDialog<object, object, object>(this, true,
|
new LoadingDialog<object, object, object>(this, true,
|
||||||
@ -301,6 +328,33 @@ namespace keepass2android
|
|||||||
).Execute();
|
).Execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool LoadChalFile()
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IFileStorage fileStorage = App.Kp2a.GetOtpAuxFileStorage(_ioConnection);
|
||||||
|
IOConnectionInfo iocAux = fileStorage.GetFilePath(fileStorage.GetParentPath(_ioConnection),
|
||||||
|
fileStorage.GetFilenameWithoutPathAndExt(_ioConnection) + ".xml");
|
||||||
|
|
||||||
|
_chalInfo = ChallengeInfo.Load(iocAux);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Kp2aLog.Log(e.ToString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_chalInfo == null)
|
||||||
|
{
|
||||||
|
Toast.MakeText(this,
|
||||||
|
GetString(Resource.String.CouldntLoadChalAuxFile) + " " + GetString(Resource.String.CouldntLoadChalAuxFile_Hint)
|
||||||
|
, ToastLength.Long).Show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void ShowOtpEntry(IList<string> prefilledOtps)
|
private void ShowOtpEntry(IList<string> prefilledOtps)
|
||||||
{
|
{
|
||||||
FindViewById(Resource.Id.otpInitView).Visibility = ViewStates.Gone;
|
FindViewById(Resource.Id.otpInitView).Visibility = ViewStates.Gone;
|
||||||
@ -585,6 +639,12 @@ namespace keepass2android
|
|||||||
case 3:
|
case 3:
|
||||||
_keyFileOrProvider = KeyProviderIdOtpRecovery;
|
_keyFileOrProvider = KeyProviderIdOtpRecovery;
|
||||||
break;
|
break;
|
||||||
|
case 4:
|
||||||
|
_keyFileOrProvider = KeyProviderIdChallenge;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
_keyFileOrProvider = KeyProviderIdChallengeRecovery;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Exception("Unexpected position " + args.Position + " / " +
|
throw new Exception("Unexpected position " + args.Position + " / " +
|
||||||
((ICursor) ((AdapterView) sender).GetItemAtPosition(args.Position)).GetString(1));
|
((ICursor) ((AdapterView) sender).GetItemAtPosition(args.Position)).GetString(1));
|
||||||
@ -669,6 +729,12 @@ namespace keepass2android
|
|||||||
case KeyProviders.OtpRecovery:
|
case KeyProviders.OtpRecovery:
|
||||||
FindViewById(Resource.Id.pass_ok).Enabled = FindViewById<EditText>(Resource.Id.pass_otpsecret).Text != "" && _password != "";
|
FindViewById(Resource.Id.pass_ok).Enabled = FindViewById<EditText>(Resource.Id.pass_otpsecret).Text != "" && _password != "";
|
||||||
break;
|
break;
|
||||||
|
case KeyProviders.Chal:
|
||||||
|
FindViewById(Resource.Id.pass_ok).Enabled = true;
|
||||||
|
break;
|
||||||
|
case KeyProviders.ChalRecovery:
|
||||||
|
FindViewById(Resource.Id.pass_ok).Enabled = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
@ -690,9 +756,15 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
FindViewById(Resource.Id.otps_pending).Visibility = _pendingOtps.Count > 0 ? ViewStates.Visible : ViewStates.Gone;
|
FindViewById(Resource.Id.otps_pending).Visibility = _pendingOtps.Count > 0 ? ViewStates.Visible : ViewStates.Gone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (KeyProviderType == KeyProviders.Chal)
|
||||||
|
{
|
||||||
|
FindViewById (Resource.Id.otpView).Visibility = ViewStates.Visible;
|
||||||
|
}
|
||||||
UpdateOkButtonState();
|
UpdateOkButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void PerformLoadDatabase()
|
private void PerformLoadDatabase()
|
||||||
{
|
{
|
||||||
//no need to check for validity of password because if this method is called, the Ok button was enabled (i.e. there was a valid password)
|
//no need to check for validity of password because if this method is called, the Ok button was enabled (i.e. there was a valid password)
|
||||||
@ -744,6 +816,29 @@ namespace keepass2android
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (KeyProviderType == KeyProviders.Chal)
|
||||||
|
{
|
||||||
|
byte[] secret = KeeChallenge.KeeChallengeProv.GetSecret(_chalInfo, _challengeResponse);
|
||||||
|
if (secret != null)
|
||||||
|
{
|
||||||
|
compositeKey.AddUserKey(new KcpCustomKey(KeeChallengeProv.Name, secret, true));
|
||||||
|
ChallengeInfo temp = KeeChallengeProv.Encrypt(secret);
|
||||||
|
IFileStorage fileStorage = App.Kp2a.GetOtpAuxFileStorage(_ioConnection);
|
||||||
|
IOConnectionInfo iocAux = fileStorage.GetFilePath(fileStorage.GetParentPath(_ioConnection),
|
||||||
|
fileStorage.GetFilenameWithoutPathAndExt(_ioConnection) + ".xml");
|
||||||
|
if(!temp.Save(iocAux))
|
||||||
|
{
|
||||||
|
Toast.MakeText(this, Resource.String.ErrorUpdatingChalAuxFile, ToastLength.Long).Show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Array.Clear(secret, 0, secret.Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Toast.MakeText(this, Resource.String.bad_resp, ToastLength.Long).Show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CheckBox cbQuickUnlock = (CheckBox) FindViewById(Resource.Id.enable_quickunlock);
|
CheckBox cbQuickUnlock = (CheckBox) FindViewById(Resource.Id.enable_quickunlock);
|
||||||
App.Kp2a.SetQuickUnlockEnabled(cbQuickUnlock.Checked);
|
App.Kp2a.SetQuickUnlockEnabled(cbQuickUnlock.Checked);
|
||||||
|
@ -491,6 +491,8 @@ Erstes öffentliches Release</string>
|
|||||||
<item>Kennwort + Schlüsseldatei</item>
|
<item>Kennwort + Schlüsseldatei</item>
|
||||||
<item>Kennwort + OTP</item>
|
<item>Kennwort + OTP</item>
|
||||||
<item>Kennwort + OTP Secret (Recovery-Modus)</item>
|
<item>Kennwort + OTP Secret (Recovery-Modus)</item>
|
||||||
|
<item>Password + Challenge-Response</item>
|
||||||
|
<item>Password + Challenge-Response secret (recovery mode)</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="AcceptAllServerCertificates_options">
|
<string-array name="AcceptAllServerCertificates_options">
|
||||||
<item>Fehler bei Zertifikatsvalidierung ignorieren</item>
|
<item>Fehler bei Zertifikatsvalidierung ignorieren</item>
|
||||||
|
@ -381,7 +381,7 @@
|
|||||||
|
|
||||||
<string name="error_adding_keyfile">Error while adding the keyfile!</string>
|
<string name="error_adding_keyfile">Error while adding the keyfile!</string>
|
||||||
|
|
||||||
<string name="init_otp">Load OTP auxiliary file…</string>
|
<string name="init_otp">Load auxiliary file…</string>
|
||||||
<string name="otp_explanation">Enter the next One-time-passwords (OTPs). Swipe your Yubikey NEO at the back of your device to enter via NFC.</string>
|
<string name="otp_explanation">Enter the next One-time-passwords (OTPs). Swipe your Yubikey NEO at the back of your device to enter via NFC.</string>
|
||||||
<string name="otp_hint">OTP %1$d</string>
|
<string name="otp_hint">OTP %1$d</string>
|
||||||
<string name="CouldntLoadOtpAuxFile">Could not load auxiliary OTP file!</string>
|
<string name="CouldntLoadOtpAuxFile">Could not load auxiliary OTP file!</string>
|
||||||
@ -396,6 +396,21 @@
|
|||||||
<string name="ErrorUpdatingOtpAuxFile">Error updating OTP auxiliary file!</string>
|
<string name="ErrorUpdatingOtpAuxFile">Error updating OTP auxiliary file!</string>
|
||||||
<string name="SavingOtpAuxFile">Saving auxiliary OTP file…</string>
|
<string name="SavingOtpAuxFile">Saving auxiliary OTP file…</string>
|
||||||
|
|
||||||
|
<string name="challenging">Challenging</string>
|
||||||
|
<string name="swipe">Please swipe your YubiKey NEO</string>
|
||||||
|
<string name="swipe_and_hold">Please swipe and hold your YubiKey NEO</string>
|
||||||
|
<string name="totp">Oath TOTP</string>
|
||||||
|
<string name="challenge_failed">Failed getting response, is the YubiKey configured in challenge-response mode?</string>
|
||||||
|
<string name="lost_tag">YubiKey NEO lost during operation</string>
|
||||||
|
<string name="tag_error">Error communication with YubiKey: </string>
|
||||||
|
<string name="nfc_off">NFC seems to be off, turn on?</string>
|
||||||
|
<string name="no_nfc">This device seems to not support NFC</string>
|
||||||
|
<string name="response_error">YubiKey Error</string>
|
||||||
|
<string name="bad_resp">The response from the YubiKey is incorrect</string>
|
||||||
|
<string name="CouldntLoadChalAuxFile">Could not load auxiliary challenge file!</string>
|
||||||
|
<string name="CouldntLoadChalAuxFile_Hint">Please use the KeeChallenge plugin in KeePass 2.x (PC) to configure your database for use with challenge-response!</string>
|
||||||
|
<string name="ErrorUpdatingChalAuxFile">Error updating OTP auxiliary file!</string>
|
||||||
|
|
||||||
<string name="loading">Loading…</string>
|
<string name="loading">Loading…</string>
|
||||||
|
|
||||||
<string name="get_regular_version">Get more storage types</string>
|
<string name="get_regular_version">Get more storage types</string>
|
||||||
@ -555,6 +570,8 @@ Initial public release
|
|||||||
<item>Password + Key file</item>
|
<item>Password + Key file</item>
|
||||||
<item>Password + OTP</item>
|
<item>Password + OTP</item>
|
||||||
<item>Password + OTP secret (recovery mode)</item>
|
<item>Password + OTP secret (recovery mode)</item>
|
||||||
|
<item>Password + Challenge-Response</item>
|
||||||
|
<item>Password + Challenge-Response secret (recovery mode)</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="AcceptAllServerCertificates_options">
|
<string-array name="AcceptAllServerCertificates_options">
|
||||||
<item>Ignore certificate validation failures</item>
|
<item>Ignore certificate validation failures</item>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user