mirror of
https://github.com/moparisthebest/keepass2android
synced 2025-03-02 02:01:43 -05:00
NfcChallenge code by Ben Rush
This commit is contained in:
parent
736bbd5ec3
commit
dfe0716635
src/keepass2android
@ -45,6 +45,7 @@ using MemoryStream = System.IO.MemoryStream;
|
||||
using Object = Java.Lang.Object;
|
||||
using Process = Android.OS.Process;
|
||||
using String = System.String;
|
||||
using KeeChallenge;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
@ -60,7 +61,9 @@ namespace keepass2android
|
||||
None = 0,
|
||||
KeyFile = 1,
|
||||
Otp = 2,
|
||||
OtpRecovery = 3
|
||||
OtpRecovery = 3,
|
||||
Chal = 4,
|
||||
ChalRecovery = 5
|
||||
}
|
||||
|
||||
public const String KeyDefaultFilename = "defaultFileName";
|
||||
@ -76,9 +79,12 @@ namespace keepass2android
|
||||
private const string ShowpasswordKey = "ShowPassword";
|
||||
private const string KeyProviderIdOtp = "KP2A-OTP";
|
||||
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 RequestCodePrepareOtpAuxFile = 1001;
|
||||
private const int RequestCodePrepareChalAuxFile = 1001;
|
||||
|
||||
|
||||
private Task<MemoryStream> _loadDbTask;
|
||||
@ -104,6 +110,10 @@ namespace keepass2android
|
||||
return KeyProviders.Otp;
|
||||
if (_keyFileOrProvider == KeyProviderIdOtpRecovery)
|
||||
return KeyProviders.OtpRecovery;
|
||||
if (_keyFileOrProvider == KeyProviderIdChallenge)
|
||||
return KeyProviders.Chal;
|
||||
if (_keyFileOrProvider == KeyProviderIdChallengeRecovery)
|
||||
return KeyProviders.ChalRecovery;
|
||||
return KeyProviders.KeyFile;
|
||||
}
|
||||
}
|
||||
@ -113,6 +123,8 @@ namespace keepass2android
|
||||
|
||||
private bool _starting;
|
||||
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 const string OtpInfoKey = "OtpInfoKey";
|
||||
private const string EnteredOtpsKey = "EnteredOtpsKey";
|
||||
@ -120,6 +132,7 @@ namespace keepass2android
|
||||
private const string PasswordKey = "PasswordKey";
|
||||
private const string KeyFileOrProviderKey = "KeyFileOrProviderKey";
|
||||
|
||||
|
||||
private ActivityDesign _design;
|
||||
|
||||
public PasswordActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
||||
@ -130,7 +143,7 @@ namespace keepass2android
|
||||
|
||||
public PasswordActivity()
|
||||
{
|
||||
_design = new ActivityDesign(this);
|
||||
_design = new ActivityDesign(this);
|
||||
}
|
||||
|
||||
|
||||
@ -259,12 +272,26 @@ namespace keepass2android
|
||||
if (requestCode == RequestCodePrepareDbFile)
|
||||
PerformLoadDatabase();
|
||||
if (requestCode == RequestCodePrepareOtpAuxFile)
|
||||
LoadOtpFile();
|
||||
{
|
||||
if (_keyFileOrProvider == KeyProviderIdChallenge)
|
||||
{
|
||||
if (!LoadChalFile()) break;
|
||||
Intent chalIntent = new Intent(this, typeof(NfcChalActivity));
|
||||
chalIntent.PutExtra("challenge", _chalInfo.Challenge);
|
||||
StartActivityForResult(chalIntent, 0);
|
||||
} else {
|
||||
LoadOtpFile ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NfcChalActivity.SUCCESS:
|
||||
_challengeResponse = data.GetByteArrayExtra("chalresp");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void LoadOtpFile()
|
||||
{
|
||||
new LoadingDialog<object, object, object>(this, true,
|
||||
@ -301,6 +328,33 @@ namespace keepass2android
|
||||
).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)
|
||||
{
|
||||
FindViewById(Resource.Id.otpInitView).Visibility = ViewStates.Gone;
|
||||
@ -585,6 +639,12 @@ namespace keepass2android
|
||||
case 3:
|
||||
_keyFileOrProvider = KeyProviderIdOtpRecovery;
|
||||
break;
|
||||
case 4:
|
||||
_keyFileOrProvider = KeyProviderIdChallenge;
|
||||
break;
|
||||
case 5:
|
||||
_keyFileOrProvider = KeyProviderIdChallengeRecovery;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unexpected position " + args.Position + " / " +
|
||||
((ICursor) ((AdapterView) sender).GetItemAtPosition(args.Position)).GetString(1));
|
||||
@ -592,10 +652,10 @@ namespace keepass2android
|
||||
UpdateKeyProviderUiState();
|
||||
};
|
||||
FindViewById(Resource.Id.init_otp).Click += (sender, args) =>
|
||||
{
|
||||
App.Kp2a.GetOtpAuxFileStorage(_ioConnection)
|
||||
.PrepareFileUsage(new FileStorageSetupInitiatorActivity(this, OnActivityResult, null), _ioConnection,
|
||||
RequestCodePrepareOtpAuxFile, false);
|
||||
{
|
||||
App.Kp2a.GetOtpAuxFileStorage(_ioConnection)
|
||||
.PrepareFileUsage(new FileStorageSetupInitiatorActivity(this, OnActivityResult, null), _ioConnection,
|
||||
RequestCodePrepareOtpAuxFile, false);
|
||||
};
|
||||
}
|
||||
else
|
||||
@ -669,6 +729,12 @@ namespace keepass2android
|
||||
case KeyProviders.OtpRecovery:
|
||||
FindViewById(Resource.Id.pass_ok).Enabled = FindViewById<EditText>(Resource.Id.pass_otpsecret).Text != "" && _password != "";
|
||||
break;
|
||||
case KeyProviders.Chal:
|
||||
FindViewById(Resource.Id.pass_ok).Enabled = true;
|
||||
break;
|
||||
case KeyProviders.ChalRecovery:
|
||||
FindViewById(Resource.Id.pass_ok).Enabled = true;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
@ -690,8 +756,14 @@ namespace keepass2android
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
private void PerformLoadDatabase()
|
||||
{
|
||||
@ -744,6 +816,29 @@ namespace keepass2android
|
||||
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);
|
||||
App.Kp2a.SetQuickUnlockEnabled(cbQuickUnlock.Checked);
|
||||
|
@ -491,6 +491,8 @@ Erstes öffentliches Release</string>
|
||||
<item>Kennwort + Schlüsseldatei</item>
|
||||
<item>Kennwort + OTP</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 name="AcceptAllServerCertificates_options">
|
||||
<item>Fehler bei Zertifikatsvalidierung ignorieren</item>
|
||||
|
@ -381,7 +381,7 @@
|
||||
|
||||
<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_hint">OTP %1$d</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="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="get_regular_version">Get more storage types</string>
|
||||
@ -555,6 +570,8 @@ Initial public release
|
||||
<item>Password + Key file</item>
|
||||
<item>Password + OTP</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 name="AcceptAllServerCertificates_options">
|
||||
<item>Ignore certificate validation failures</item>
|
||||
|
Loading…
x
Reference in New Issue
Block a user