This commit is contained in:
Philipp Crocoll 2014-07-15 06:19:35 +02:00
commit 85499844bd
60 changed files with 2669 additions and 420 deletions

24
.gitignore vendored
View File

@ -258,3 +258,27 @@ Thumbs.db
/src/java/PluginInputStick/bin
/src/java/PluginInputStick/icons
/src/PluginSdkBinding/bin/Release
/src/MasterPassword/bin/Debug
/src/MasterPassword/obj/Debug
/src/MasterPassword/obj/Release
/src/MPTest/bin/Debug
/src/MPTest/obj/Debug
/src/MasterKeePlugin/obj/Release
/src/MasterKeePlugin/bin/Debug
/src/MasterKeePlugin/bin/Release
/src/MasterKeePlugin/obj/Debug
/src/PluginSdkBinding/obj/Release
/src/MasterPassword/bin/Release
/src/java/MasterKee
/src/PluginSdkBinding/obj/ReleaseNoNet

View File

@ -1,18 +1,28 @@
using System;
using System.Collections.Generic;
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using KeeChallenge;
using KeePassLib.Serialization;
using keepass2android;
using keepass2android.Io;
namespace ArtTestApp
{
[Activity(Label = "ArtTestApp", MainLauncher = true, Icon = "@drawable/icon")]
public class Activity1 : Activity
{
private ChallengeInfo _chalInfo;
private byte[] _challengeSecret;
private IOConnectionInfo _ioConnectionInfo;
private IOConnectionInfo _ioConnectionInfoOut;
private const int RequestCodeChallengeYubikey = 98;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
@ -20,30 +30,87 @@ namespace ArtTestApp
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
_ioConnectionInfo = new IOConnectionInfo() { Path = "/mnt/sdcard/keepass/keechallenge.xml" };
_ioConnectionInfoOut = new IOConnectionInfo() { Path = "/mnt/sdcard/keepass/keechallengeOut.xml" };
// Get our button from the layout resource,
// and attach an event to it
FindViewById<Button>(Resource.Id.MyButton1).Click += (sender, args) =>
{
try
{
StartActivity(typeof (Activity2));
}
catch (Exception ex)
{
Toast.MakeText(this, ex.ToString(), ToastLength.Long).Show();
}
Decrypt(_ioConnectionInfo);
};
FindViewById<Button>(Resource.Id.MyButton2).Click += (sender, args) =>
{
Intent i = new Intent("blabla");
StartActivityForResult(i, 1);
Decrypt(_ioConnectionInfoOut);
};
FindViewById<Button>(Resource.Id.MyButton3).Click += (sender, args) => StartActivityForResult(typeof(PrefActivity), 1);
}
private void Decrypt(IOConnectionInfo ioConnectionInfo)
{
try
{
//StartActivity(typeof (Activity2));
_chalInfo = ChallengeInfo.Load(ioConnectionInfo);
Intent chalIntent = new Intent("com.yubichallenge.NFCActivity.CHALLENGE");
chalIntent.PutExtra("challenge", _chalInfo.Challenge);
chalIntent.PutExtra("slot", 2);
chalIntent.AddFlags(ActivityFlags.SingleTop);
IList<ResolveInfo> activities = PackageManager.QueryIntentActivities(chalIntent, 0);
bool isIntentSafe = activities.Count > 0;
if (isIntentSafe)
{
StartActivityForResult(chalIntent, RequestCodeChallengeYubikey);
}
}
catch (Exception ex)
{
Toast.MakeText(this, ex.ToString(), ToastLength.Long).Show();
}
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (requestCode == RequestCodeChallengeYubikey && resultCode == Result.Ok)
{
try
{
byte[] challengeResponse = data.GetByteArrayExtra("response");
_challengeSecret = KeeChallengeProv.GetSecret(_chalInfo, challengeResponse);
Array.Clear(challengeResponse, 0, challengeResponse.Length);
}
catch (Exception e)
{
Kp2aLog.Log(e.ToString());
Toast.MakeText(this, "Error: " + e.Message, ToastLength.Long).Show();
return;
}
if (_challengeSecret != null)
{
Toast.MakeText(this, "OK!", ToastLength.Long).Show();
ChallengeInfo temp = KeeChallengeProv.Encrypt(_challengeSecret, _chalInfo.IV);
if (!temp.Save(_ioConnectionInfoOut))
{
Toast.MakeText(this, "error writing file", ToastLength.Long).Show();
return;
}
}
else
{
Toast.MakeText(this, "Not good :-(", ToastLength.Long).Show();
return;
}
}
}
}
}

View File

@ -50,6 +50,9 @@
<ItemGroup>
<Compile Include="Activity1.cs" />
<Compile Include="Activity2.cs" />
<Compile Include="App.cs" />
<Compile Include="ChallengeInfo.cs" />
<Compile Include="KeeChallenge.cs" />
<Compile Include="PrefActivity.cs" />
<Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
@ -73,6 +76,16 @@
<ItemGroup>
<AndroidResource Include="Resources\Xml\pref.xml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj">
<Project>{545b4a6b-8bba-4fbe-92fc-4ac060122a54}</Project>
<Name>KeePassLib2Android</Name>
</ProjectReference>
<ProjectReference Include="..\Kp2aBusinessLogic\Kp2aBusinessLogic.csproj">
<Project>{53a9cb7f-6553-4bc0-b56b-9410bb2e59aa}</Project>
<Name>Kp2aBusinessLogic</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -29,6 +29,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginTOTP", "PluginTOTP\Pl
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginHostTest", "PluginHostTest\PluginHostTest.csproj", "{C9F4AE81-0996-4E17-B3F2-D0F652F6AC50}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MasterKeePlugin", "MasterKeePlugin\MasterKeePlugin.csproj", "{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MasterPassword", "MasterPassword\MasterPassword.csproj", "{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MPTest", "MPTest\MPTest.csproj", "{96A3EA5A-7024-479F-A5B1-06654D0867A3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -284,8 +290,8 @@ Global
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.Release|x64.ActiveCfg = Release|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{F46F101D-4076-4E0A-9781-105598E2F42A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@ -336,6 +342,66 @@ Global
{C9F4AE81-0996-4E17-B3F2-D0F652F6AC50}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU
{C9F4AE81-0996-4E17-B3F2-D0F652F6AC50}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{C9F4AE81-0996-4E17-B3F2-D0F652F6AC50}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Debug|Win32.ActiveCfg = Debug|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Debug|x64.ActiveCfg = Debug|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Release|Any CPU.Build.0 = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Release|Any CPU.Deploy.0 = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Release|Win32.ActiveCfg = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Release|x64.ActiveCfg = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.ReleaseNoNet|Any CPU.Deploy.0 = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Debug|Win32.ActiveCfg = Debug|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Debug|x64.ActiveCfg = Debug|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Release|Any CPU.Build.0 = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Release|Win32.ActiveCfg = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Release|x64.ActiveCfg = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Debug|Win32.ActiveCfg = Debug|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Debug|x64.ActiveCfg = Debug|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Release|Any CPU.Build.0 = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Release|Win32.ActiveCfg = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Release|x64.ActiveCfg = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

72
src/MPTest/MPTest.csproj Normal file
View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{96A3EA5A-7024-479F-A5B1-06654D0867A3}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MPTest</RootNamespace>
<AssemblyName>MPTest</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="MpTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MasterPassword\MasterPassword.csproj">
<Project>{2f7cb5b4-ac2a-4790-b0f3-42e6c9a060d5}</Project>
<Name>MasterPassword</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

16
src/MPTest/Main.cs Normal file
View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MPTest
{
class Program
{
static int Main()
{
return 0;
}
}
}

84
src/MPTest/MpTest.cs Normal file
View File

@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using MasterPassword;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MPTest
{
[TestClass()]
public class MpAlgorithmTests
{
static sbyte[] ToSignedByteArray(byte[] unsigned)
{
sbyte[] signed = new sbyte[unsigned.Length];
Buffer.BlockCopy(unsigned, 0, signed, 0, unsigned.Length);
return signed;
}
static byte[] ToUnsignedByteArray(sbyte[] signed)
{
byte[] unsigned = new byte[signed.Length];
Buffer.BlockCopy(signed, 0, unsigned, 0, signed.Length);
return unsigned;
}
private static byte[] HashHMAC(byte[] key, byte[] message)
{
var hash = new HMACSHA256(key);
return hash.ComputeHash(message);
}
[TestMethod()]
public void GenerateKeyTest()
{
sbyte[] expectedRes =
{
-103, 59, -64, -27, 39, -62, 10, -76, -24, -28, -111, -75, 13, -128, -80, -101, 39, 41, -98, -22,
-42, 61, -75, 38, -107, -40, 111, 61, 108, 63, 60, 82, 92, -39, 72, 14, 14, -26, 93, 67, 83, 25, -32, 5, 32, 102,
-126, 24, 15, 65, 9, 17, 0, 123, 91, 105, -46, -99, -64, 123, -12, 80, -37, -77
};
var result = MpAlgorithm.GetKeyForPassword("u", "test");
Assert.IsTrue(expectedRes.SequenceEqual(ToSignedByteArray(result)));
}
[TestMethod]
public void GenerateContentTest()
{
var key = MpAlgorithm.GetKeyForPassword("u", "test");
string password = MpAlgorithm.GenerateContent("Long Password", "strn", key, 1, HashHMAC);
Assert.AreEqual("LapdKebv2_Tele", password);
}
[TestMethod]
public void GenerateContentWithUmlautsTest()
{
var key = MpAlgorithm.GetKeyForPassword("uÜ", "testÖ");
string password = MpAlgorithm.GenerateContent("Long Password", "strnÄ", key, 1, HashHMAC);
Assert.AreEqual("YepiHedo1*Kada", password);
}
[TestMethod]
public void GenerateContentWithUmlautsAndCounterTest()
{
var key = MpAlgorithm.GetKeyForPassword("uÜ", "testÖ");
string password = MpAlgorithm.GenerateContent("Long Password", "strnÄ", key, 42, HashHMAC);
Assert.AreEqual("Gasc3!YeluMoqb", password);
}
[TestMethod]
public void GetKeyWithUmlautsTest()
{
var key = MpAlgorithm.GetKeyForPassword("uÜ", "testÖ");
sbyte[] expected =
{
-53, -69, -89, 48, 122, 56, 34, 13, -70, -103, 102, 90, -96, -75, 45, 68, 43, 67, 97, 60, 84, -90, 98, -95, -2, -2, 99, -60, -121, -2, -26, -45, 53, -31, 47, 0, -46, -97, 77, -41, 63, -15, -30, 60, 4, -120, 32, 122, -94, 42, 122, -103, -61, -115, 75, -123, -15, 47, 61, -100, -119, 115, 118, 82
};
Assert.IsTrue(expected.SequenceEqual(ToSignedByteArray(key)));
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die mit einer Assembly verknüpft sind.
[assembly: AssemblyTitle("MPTest")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MPTest")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
[assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
[assembly: Guid("5fbae881-f9e4-4aa1-adff-4721cad61250")]
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
//
// Hauptversion
// Nebenversion
// Buildnummer
// Revision
//
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
// übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

3
src/MPTest/app.config Normal file
View File

@ -0,0 +1,3 @@
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>

View File

@ -0,0 +1,38 @@
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.Views;
using Android.Widget;
using Keepass2android.Pluginsdk;
namespace MasterKeePlugin
{
[BroadcastReceiver(Exported = true)]
[IntentFilter(new[] { Strings.ActionTriggerRequestAccess, Strings.ActionReceiveAccess, Strings.ActionRevokeAccess })]
public class AccessReceiver: PluginAccessBroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Android.Util.Log.Debug("KP2A_MasterKee", intent.Action);
base.OnReceive(context, intent);
}
public override IList<string> Scopes
{
get
{
return new List<string>
{
Strings.ScopeCurrentEntry,
Strings.ScopeQueryCredentialsForOwnPackage
};
}
}
}
}

View File

@ -0,0 +1,80 @@
using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Java.Util;
using KeePassLib.Utility;
using Keepass2android.Pluginsdk;
namespace MasterKeePlugin
{
[BroadcastReceiver(Exported = true)]
[IntentFilter(new[] {Strings.ActionOpenEntry, Strings.ActionEntryActionSelected })]
public class ActionReceiver: PluginActionBroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Android.Util.Log.Debug("KP2A_MasterKee", intent.Action);
base.OnReceive(context, intent);
}
private static byte[] HashHMAC(byte[] key, byte[] message)
{
var hash = new HMACSHA256(key);
return hash.ComputeHash(message);
}
protected override void OpenEntry(OpenEntryAction oe)
{
string masterkey;
Android.Util.Log.Debug("KP2A_MasterKee", "Opening entry...");
if (oe.EntryFields.TryGetValue("MK_MasterKey", out masterkey))
{
Android.Util.Log.Debug("KP2A_MasterKee", "Entry is MK entry.");
string type;
if (!oe.EntryFields.TryGetValue("MK_Type", out type))
type = "Long Password";
int counter = 1;
string strCounter;
if (oe.EntryFields.TryGetValue("MK_Site_Counter", out strCounter))
{
int.TryParse(strCounter, out counter);
}
Android.Util.Log.Debug("KP2A_MasterKee", "Calculating password...");
string calculatedKey = MasterPassword.MpAlgorithm.GenerateContent(type,
oe.EntryFields[KeepassDefs.TitleField],
MemUtil.HexStringToByteArray(masterkey),
counter,
HashHMAC
);
Android.Util.Log.Debug("KP2A_MasterKee", "ok. Returning data.");
try
{
oe.SetEntryField(KeepassDefs.PasswordField, calculatedKey, true);
oe.SetEntryField("MK_MasterKey", "", true);
oe.SetEntryField("MK_Type", "", true);
oe.SetEntryField("MK_Site_Counter", "", true);
}
catch (Exception e)
{
Android.Util.Log.Debug("KP2A_MasterKee", e.ToString());
}
}
Android.Util.Log.Debug("KP2A_MasterKee", "Done.");
}
protected override void ActionSelected(ActionSelectedAction asa)
{
}
}
}

View File

@ -0,0 +1,26 @@
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.Views;
using Android.Widget;
namespace MasterKeePlugin
{
//TODO remove?
[Activity(Label = "@string/AddMkEntry")]
public class AddMasterKeeActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
}
}
}

View File

@ -0,0 +1,19 @@
Any raw assets you want to be deployed with your application can be placed in
this directory (and child directories) and given a Build Action of "AndroidAsset".
These files will be deployed with you package and will be accessible using Android's
AssetManager, like this:
public class ReadAsset : Activity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
InputStream input = Assets.Open ("my_asset.txt");
}
}
Additionally, some Android functions will automatically load asset files:
Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");

View File

@ -0,0 +1,156 @@
using System;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Java.Lang;
using MasterKeePlugin;
using Exception = System.Exception;
using Object = Java.Lang.Object;
namespace keepass2android.Utils
{
public class LoadingDialog<TParams, TProgress, TResult> : AsyncTask<TParams, TProgress, TResult>
{
private readonly Context _context;
private readonly string _message;
private readonly bool _cancelable;
readonly Func<Object[], Object> _doInBackground;
readonly Action<Object> _onPostExecute;
private ProgressDialog mDialog;
/**
* Default is {@code 500}ms
*/
private int mDelayTime = 500;
/**
* Flag to use along with {@link #mDelayTime}
*/
private bool mFinished = false;
private Exception mLastException;
public LoadingDialog(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
public LoadingDialog(Context context, string message, bool cancelable, Func<Object[], Object> doInBackground,
Action<Object> onPostExecute)
{
_context = context;
_message = message;
_cancelable = cancelable;
_doInBackground = doInBackground;
_onPostExecute = onPostExecute;
Initialize();
}
private void Initialize()
{
mDialog = new ProgressDialog(_context);
mDialog.SetMessage(_message);
mDialog.Indeterminate = true;
mDialog.SetCancelable(_cancelable);
if (_cancelable)
{
mDialog.SetCanceledOnTouchOutside(true);
mDialog.CancelEvent += (sender, args) => mDialog.Cancel();
}
}
protected override void OnPreExecute()
{
new Handler().PostDelayed(() =>
{
if (!mFinished)
{
try
{
/*
* sometime the activity has been finished before we
* show this dialog, it will raise error
*/
mDialog.Show();
}
catch (Exception t)
{
Android.Util.Log.Debug("LD", t.ToString());
}
}
}
, mDelayTime);
}
/**
* If you override this method, you must call {@code super.onCancelled()} at
* beginning of the method.
*/
protected override void OnCancelled() {
DoFinish();
base.OnCancelled();
}// onCancelled()
private void DoFinish() {
mFinished = true;
try {
/*
* Sometime the activity has been finished before we dismiss this
* dialog, it will raise error.
*/
mDialog.Dismiss();
} catch (Exception e)
{
Android.Util.Log.Debug("LD", e.ToString());
}
}// doFinish()
/**
* Sets last exception. This method is useful in case an exception raises
* inside {@link #doInBackground(Void...)}
*
* @param t
* {@link Throwable}
*/
protected void SetLastException(Exception e) {
mLastException = e;
}// setLastException()
/**
* Gets last exception.
*
* @return {@link Throwable}
*/
protected Exception GetLastException() {
return mLastException;
}// getLastException()
protected override Object DoInBackground(params Object[] @params)
{
return _doInBackground(@params);
}
protected override TResult RunInBackground(params TParams[] @params)
{
throw new NotImplementedException();
}
protected override void OnPostExecute(Object result)
{
DoFinish();
if (_onPostExecute != null)
_onPostExecute(result);
}
}
}

View File

@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using Android.App;
using Android.Content;
using Android.Preferences;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Keepass2android.Pluginsdk;
namespace MasterKeePlugin
{
[Activity(Label = "MasterKee", MainLauncher = true, Icon = "@drawable/ic_launcher")]
public class MainActivity : Activity
{
private const string KEY_MK_ENTRY_ID = "KEY_MK_ENTRY_ID";
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
Button buttonSelect = FindViewById<Button>(Resource.Id.btnSelectMaster);
buttonSelect.Click += delegate {
var intent = Kp2aControl.QueryEntryIntentForOwnPackage;
try
{
StartActivityForResult(intent, 123);
}
catch (ActivityNotFoundException)
{
Toast.MakeText(this, "No Keepass2Android host app found. Please install Keepass2Android 0.9.4 or above!", ToastLength.Long).Show();
}
};
Button buttonCreateMaster = FindViewById<Button>(Resource.Id.btnSetupMaster);
buttonCreateMaster.Click += delegate
{
StartActivityForResult(new Intent(this, typeof (SetupMasterEntryActivity)), 124);
};
FindViewById(Resource.Id.btnAddEntry).Click += delegate
{
//StartActivityForResult(new Intent(this, typeof()), 125);
var prefs = PreferenceManager.GetDefaultSharedPreferences(this);
Dictionary<string, string> fields = new Dictionary<string, string>();
fields["MK_Site_Counter"] = "1";
fields["MK_Type"] = "Long Password";
fields[KeepassDefs.PasswordField] = "{MASTERKEE}";
fields["MK_MasterKey"] = "{REF:P@I:" + prefs.GetString(KEY_MK_ENTRY_ID, "") + "}";
try
{
StartActivityForResult(Kp2aControl.GetAddEntryIntent(fields, new List<string>() { "MK_MasterKey" }), 125);
}
catch (ActivityNotFoundException)
{
Toast.MakeText(this, "No Keepass2Android host app found. Please install Keepass2Android 0.9.4 or above!", ToastLength.Long).Show();
}
};
}
protected override void OnResume()
{
base.OnResume();
var prefs = PreferenceManager.GetDefaultSharedPreferences(this);
if (prefs.Contains(KEY_MK_ENTRY_ID))
{
Button buttonCreateMaster = FindViewById<Button>(Resource.Id.btnSetupMaster);
buttonCreateMaster.Visibility = ViewStates.Gone;
Button buttonSelect = FindViewById<Button>(Resource.Id.btnSelectMaster);
buttonSelect.Visibility = ViewStates.Gone;
FindViewById(Resource.Id.btnAddEntry).Visibility = ViewStates.Visible;
}
else
{
FindViewById(Resource.Id.btnAddEntry).Visibility = ViewStates.Gone;
}
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if ((requestCode == 123) && (resultCode == Result.Ok))
{
string masterEntryId = data.GetStringExtra(Strings.ExtraEntryId);
if (!String.IsNullOrEmpty(masterEntryId))
{
var prefs = PreferenceManager.GetDefaultSharedPreferences(this);
prefs.Edit().PutString(KEY_MK_ENTRY_ID, masterEntryId).Commit();
}
}
}
}
}

View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}</ProjectGuid>
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MasterKeePlugin</RootNamespace>
<AssemblyName>MasterKeePlugin</AssemblyName>
<FileAlignment>512</FileAlignment>
<AndroidApplication>true</AndroidApplication>
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AndroidUseSharedRuntime>True</AndroidUseSharedRuntime>
<AndroidLinkMode>None</AndroidLinkMode>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
</PropertyGroup>
<ItemGroup>
<Reference Include="Mono.Android" />
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AccessReceiver.cs" />
<Compile Include="ActionReceiver.cs" />
<Compile Include="AddMasterKeeActivity.cs" />
<Compile Include="LoadingDialog.cs" />
<Compile Include="MainActivity.cs" />
<Compile Include="MemUtil.cs" />
<Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SetupMasterEntryActivity.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\AboutResources.txt" />
<None Include="Assets\AboutAssets.txt" />
<AndroidResource Include="Resources\layout\Setup.axml" />
<AndroidResource Include="Resources\layout\AddMkEntry.axml">
<SubType>AndroidResource</SubType>
</AndroidResource>
<AndroidResource Include="Resources\drawable-xxhdpi\Thumbs.db" />
<AndroidResource Include="Resources\drawable-xxxhdpi\Thumbs.db" />
<AndroidResource Include="Resources\drawable-hdpi\Thumbs.db" />
<AndroidResource Include="Resources\drawable-mdpi\Thumbs.db" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\layout\Main.axml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\values\Strings.xml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\Icon.png" />
</ItemGroup>
<ItemGroup>
<TransformFile Include="Properties\AndroidManifest.xml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MasterPassword\MasterPassword.csproj">
<Project>{2f7cb5b4-ac2a-4790-b0f3-42e6c9a060d5}</Project>
<Name>MasterPassword</Name>
</ProjectReference>
<ProjectReference Include="..\PluginSdkBinding\PluginSdkBinding.csproj">
<Project>{3da3911e-36de-465e-8f15-f1991b6437e5}</Project>
<Name>PluginSdkBinding</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\ic_menu_view.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxhdpi\ic_launcher.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xxxhdpi\ic_launcher.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-hdpi\ic_launcher.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-mdpi\ic_launcher.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable-xhdpi\ic_launcher.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\ic_launcher.png" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,567 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.Diagnostics;
using System.IO;
#if !KeePassLibSD
using System.IO.Compression;
#else
using KeePassLibSD;
#endif
namespace KeePassLib.Utility
{
/// <summary>
/// Contains static buffer manipulation and string conversion routines.
/// </summary>
public static class MemUtil
{
private static readonly uint[] m_vSBox = new uint[256] {
0xCD2FACB3, 0xE78A7F5C, 0x6F0803FC, 0xBCF6E230,
0x3A321712, 0x06403DB1, 0xD2F84B95, 0xDF22A6E4,
0x07CE9E5B, 0x31788A0C, 0xF683F6F4, 0xEA061F49,
0xFA5C2ACA, 0x4B9E494E, 0xB0AB25BA, 0x767731FC,
0x261893A7, 0x2B09F2CE, 0x046261E4, 0x41367B4B,
0x18A7F225, 0x8F923C0E, 0x5EF3A325, 0x28D0435E,
0x84C22919, 0xED66873C, 0x8CEDE444, 0x7FC47C24,
0xFCFC6BA3, 0x676F928D, 0xB4147187, 0xD8FB126E,
0x7D798D17, 0xFF82E424, 0x1712FA5B, 0xABB09DD5,
0x8156BA63, 0x84E4D969, 0xC937FB9A, 0x2F1E5BFC,
0x178ECA11, 0x0E71CD5F, 0x52AAC6F4, 0x71EEFC8F,
0x7090D749, 0x21CACA31, 0x92996378, 0x0939A8A8,
0xE9EE1934, 0xD2718616, 0xF2500543, 0xB911873C,
0xD3CB3EEC, 0x2BA0DBEB, 0xB42D0A27, 0xECE67C0F,
0x302925F0, 0x6114F839, 0xD39E6307, 0xE28970D6,
0xEB982F99, 0x941B4CDF, 0xC540E550, 0x8124FC45,
0x98B025C7, 0xE2BF90EA, 0x4F57C976, 0xCF546FE4,
0x59566DC8, 0xE3F4360D, 0xF5F9D231, 0xD6180B22,
0xB54E088A, 0xB5DFE6A6, 0x3637A36F, 0x056E9284,
0xAFF8FBC5, 0x19E01648, 0x8611F043, 0xDAE44337,
0xF61B6A1C, 0x257ACD9E, 0xDD35F507, 0xEF05CAFA,
0x05EB4A83, 0xFC25CA92, 0x0A4728E6, 0x9CF150EF,
0xAEEF67DE, 0xA9472337, 0x57C81EFE, 0x3E5E009F,
0x02CB03BB, 0x2BA85674, 0xF21DC251, 0x78C34A34,
0xABB1F5BF, 0xB95A2FBD, 0x1FB47777, 0x9A96E8AC,
0x5D2D2838, 0x55AAC92A, 0x99EE324E, 0x10F6214B,
0x58ABDFB1, 0x2008794D, 0xBEC880F0, 0xE75E5341,
0x88015C34, 0x352D8FBF, 0x622B7F6C, 0xF5C59EA2,
0x1F759D8E, 0xADE56159, 0xCC7B4C25, 0x5B8BC48C,
0xB6BD15AF, 0x3C5B5110, 0xE74A7C3D, 0xEE613161,
0x156A1C67, 0x72C06817, 0xEA0A6F69, 0x4CECF993,
0xCA9D554C, 0x8E20361F, 0x42D396B9, 0x595DE578,
0x749D7955, 0xFD1BA5FD, 0x81FC160E, 0xDB97E28C,
0x7CF148F7, 0x0B0B3CF5, 0x534DE605, 0x46421066,
0xD4B68DD1, 0x9E479CE6, 0xAE667A9D, 0xBC082082,
0xB06DD6EF, 0x20F0F23F, 0xB99E1551, 0xF47A2E3A,
0x71DA50C6, 0x67B65779, 0x2A8CB376, 0x1EA71EEE,
0x29ABCD50, 0xB6EB0C6B, 0x23C10511, 0x6F3F2144,
0x6AF23012, 0xF696BD9E, 0xB94099D8, 0xAD5A9C81,
0x7A0794FA, 0x7EDF59D6, 0x1E72E574, 0x8561913C,
0x4E4D568F, 0xEECB9928, 0x9C124D2E, 0x0848B82C,
0xF1CA395F, 0x9DAF43DC, 0xF77EC323, 0x394E9B59,
0x7E200946, 0x8B811D68, 0x16DA3305, 0xAB8DE2C3,
0xE6C53B64, 0x98C2D321, 0x88A97D81, 0xA7106419,
0x8E52F7BF, 0x8ED262AF, 0x7CCA974E, 0xF0933241,
0x040DD437, 0xE143B3D4, 0x3019F56F, 0xB741521D,
0xF1745362, 0x4C435F9F, 0xB4214D0D, 0x0B0C348B,
0x5051D189, 0x4C30447E, 0x7393D722, 0x95CEDD0B,
0xDD994E80, 0xC3D22ED9, 0x739CD900, 0x131EB9C4,
0xEF1062B2, 0x4F0DE436, 0x52920073, 0x9A7F3D80,
0x896E7B1B, 0x2C8BBE5A, 0xBD304F8A, 0xA993E22C,
0x134C41A0, 0xFA989E00, 0x39CE9726, 0xFB89FCCF,
0xE8FBAC97, 0xD4063FFC, 0x935A2B5A, 0x44C8EE83,
0xCB2BC7B6, 0x02989E92, 0x75478BEA, 0x144378D0,
0xD853C087, 0x8897A34E, 0xDD23629D, 0xBDE2A2A2,
0x581D8ECC, 0x5DA8AEE8, 0xFF8AAFD0, 0xBA2BCF6E,
0x4BD98DAC, 0xF2EDB9E4, 0xFA2DC868, 0x47E84661,
0xECEB1C7D, 0x41705CA4, 0x5982E4D4, 0xEB5204A1,
0xD196CAFB, 0x6414804D, 0x3ABD4B46, 0x8B494C26,
0xB432D52B, 0x39C5356B, 0x6EC80BF7, 0x71BE5483,
0xCEC4A509, 0xE9411D61, 0x52F341E5, 0xD2E6197B,
0x4F02826C, 0xA9E48838, 0xD1F8F247, 0xE4957FB3,
0x586CCA99, 0x9A8B6A5B, 0x4998FBEA, 0xF762BE4C,
0x90DFE33C, 0x9731511E, 0x88C6A82F, 0xDD65A4D4
};
/// <summary>
/// Convert a hexadecimal string to a byte array. The input string must be
/// even (i.e. its length is a multiple of 2).
/// </summary>
/// <param name="strHex">String containing hexadecimal characters.</param>
/// <returns>Returns a byte array. Returns <c>null</c> if the string parameter
/// was <c>null</c> or is an uneven string (i.e. if its length isn't a
/// multiple of 2).</returns>
/// <exception cref="System.ArgumentNullException">Thrown if <paramref name="strHex" />
/// is <c>null</c>.</exception>
public static byte[] HexStringToByteArray(string strHex)
{
if(strHex == null) { Debug.Assert(false); throw new ArgumentNullException("strHex"); }
int nStrLen = strHex.Length;
if((nStrLen & 1) != 0) { Debug.Assert(false); return null; }
byte[] pb = new byte[nStrLen / 2];
byte bt;
char ch;
for(int i = 0; i < nStrLen; i += 2)
{
ch = strHex[i];
if((ch >= '0') && (ch <= '9'))
bt = (byte)(ch - '0');
else if((ch >= 'a') && (ch <= 'f'))
bt = (byte)(ch - 'a' + 10);
else if((ch >= 'A') && (ch <= 'F'))
bt = (byte)(ch - 'A' + 10);
else { Debug.Assert(false); bt = 0; }
bt <<= 4;
ch = strHex[i + 1];
if((ch >= '0') && (ch <= '9'))
bt += (byte)(ch - '0');
else if((ch >= 'a') && (ch <= 'f'))
bt += (byte)(ch - 'a' + 10);
else if((ch >= 'A') && (ch <= 'F'))
bt += (byte)(ch - 'A' + 10);
else { Debug.Assert(false); }
pb[i >> 1] = bt;
}
return pb;
}
/// <summary>
/// Convert a byte array to a hexadecimal string.
/// </summary>
/// <param name="pbArray">Input byte array.</param>
/// <returns>Returns the hexadecimal string representing the byte
/// array. Returns <c>null</c>, if the input byte array was <c>null</c>. Returns
/// an empty string, if the input byte array has length 0.</returns>
public static string ByteArrayToHexString(byte[] pbArray)
{
if(pbArray == null) return null;
int nLen = pbArray.Length;
if(nLen == 0) return string.Empty;
StringBuilder sb = new StringBuilder();
byte bt, btHigh, btLow;
for(int i = 0; i < nLen; ++i)
{
bt = pbArray[i];
btHigh = bt; btHigh >>= 4;
btLow = (byte)(bt & 0x0F);
if(btHigh >= 10) sb.Append((char)('A' + btHigh - 10));
else sb.Append((char)('0' + btHigh));
if(btLow >= 10) sb.Append((char)('A' + btLow - 10));
else sb.Append((char)('0' + btLow));
}
return sb.ToString();
}
/// <summary>
/// Set all bytes in a byte array to zero.
/// </summary>
/// <param name="pbArray">Input array. All bytes of this array will be set
/// to zero.</param>
public static void ZeroByteArray(byte[] pbArray)
{
Debug.Assert(pbArray != null); if(pbArray == null) throw new ArgumentNullException("pbArray");
// for(int i = 0; i < pbArray.Length; ++i)
// pbArray[i] = 0;
Array.Clear(pbArray, 0, pbArray.Length);
}
/// <summary>
/// Convert 2 bytes to a 16-bit unsigned integer using Little-Endian
/// encoding.
/// </summary>
/// <param name="pb">Input bytes. Array must contain at least 2 bytes.</param>
/// <returns>16-bit unsigned integer.</returns>
public static ushort BytesToUInt16(byte[] pb)
{
Debug.Assert((pb != null) && (pb.Length == 2));
if(pb == null) throw new ArgumentNullException("pb");
if(pb.Length != 2) throw new ArgumentException();
return (ushort)((ushort)pb[0] | ((ushort)pb[1] << 8));
}
/// <summary>
/// Convert 4 bytes to a 32-bit unsigned integer using Little-Endian
/// encoding.
/// </summary>
/// <param name="pb">Input bytes.</param>
/// <returns>32-bit unsigned integer.</returns>
public static uint BytesToUInt32(byte[] pb)
{
Debug.Assert((pb != null) && (pb.Length == 4));
if(pb == null) throw new ArgumentNullException("pb");
if(pb.Length != 4) throw new ArgumentException("Input array must contain 4 bytes!");
return (uint)pb[0] | ((uint)pb[1] << 8) | ((uint)pb[2] << 16) |
((uint)pb[3] << 24);
}
/// <summary>
/// Convert 8 bytes to a 64-bit unsigned integer using Little-Endian
/// encoding.
/// </summary>
/// <param name="pb">Input bytes.</param>
/// <returns>64-bit unsigned integer.</returns>
public static ulong BytesToUInt64(byte[] pb)
{
Debug.Assert((pb != null) && (pb.Length == 8));
if(pb == null) throw new ArgumentNullException("pb");
if(pb.Length != 8) throw new ArgumentException();
return (ulong)pb[0] | ((ulong)pb[1] << 8) | ((ulong)pb[2] << 16) |
((ulong)pb[3] << 24) | ((ulong)pb[4] << 32) | ((ulong)pb[5] << 40) |
((ulong)pb[6] << 48) | ((ulong)pb[7] << 56);
}
/// <summary>
/// Convert a 16-bit unsigned integer to 2 bytes using Little-Endian
/// encoding.
/// </summary>
/// <param name="uValue">16-bit input word.</param>
/// <returns>Two bytes representing the 16-bit value.</returns>
public static byte[] UInt16ToBytes(ushort uValue)
{
byte[] pb = new byte[2];
unchecked
{
pb[0] = (byte)uValue;
pb[1] = (byte)(uValue >> 8);
}
return pb;
}
/// <summary>
/// Convert a 32-bit unsigned integer to 4 bytes using Little-Endian
/// encoding.
/// </summary>
/// <param name="uValue">32-bit input word.</param>
/// <returns>Four bytes representing the 32-bit value.</returns>
public static byte[] UInt32ToBytes(uint uValue)
{
byte[] pb = new byte[4];
unchecked
{
pb[0] = (byte)uValue;
pb[1] = (byte)(uValue >> 8);
pb[2] = (byte)(uValue >> 16);
pb[3] = (byte)(uValue >> 24);
}
return pb;
}
/// <summary>
/// Convert a 64-bit unsigned integer to 8 bytes using Little-Endian
/// encoding.
/// </summary>
/// <param name="uValue">64-bit input word.</param>
/// <returns>Eight bytes representing the 64-bit value.</returns>
public static byte[] UInt64ToBytes(ulong uValue)
{
byte[] pb = new byte[8];
unchecked
{
pb[0] = (byte)uValue;
pb[1] = (byte)(uValue >> 8);
pb[2] = (byte)(uValue >> 16);
pb[3] = (byte)(uValue >> 24);
pb[4] = (byte)(uValue >> 32);
pb[5] = (byte)(uValue >> 40);
pb[6] = (byte)(uValue >> 48);
pb[7] = (byte)(uValue >> 56);
}
return pb;
}
public static bool ArraysEqual(byte[] x, byte[] y)
{
// Return false if one of them is null (not comparable)!
if((x == null) || (y == null)) { Debug.Assert(false); return false; }
if(x.Length != y.Length) return false;
for(int i = 0; i < x.Length; ++i)
{
if(x[i] != y[i]) return false;
}
return true;
}
public static void XorArray(byte[] pbSource, int nSourceOffset,
byte[] pbBuffer, int nBufferOffset, int nLength)
{
if(pbSource == null) throw new ArgumentNullException("pbSource");
if(nSourceOffset < 0) throw new ArgumentException();
if(pbBuffer == null) throw new ArgumentNullException("pbBuffer");
if(nBufferOffset < 0) throw new ArgumentException();
if(nLength < 0) throw new ArgumentException();
if((nSourceOffset + nLength) > pbSource.Length) throw new ArgumentException();
if((nBufferOffset + nLength) > pbBuffer.Length) throw new ArgumentException();
for(int i = 0; i < nLength; ++i)
pbBuffer[nBufferOffset + i] ^= pbSource[nSourceOffset + i];
}
/// <summary>
/// Fast hash that can be used e.g. for hash tables.
/// The algorithm might change in the future; do not store
/// the hashes for later use.
/// </summary>
public static uint Hash32(byte[] v, int iStart, int iLength)
{
uint u = 0x326F637B;
if(v == null) { Debug.Assert(false); return u; }
if(iStart < 0) { Debug.Assert(false); return u; }
if(iLength < 0) { Debug.Assert(false); return u; }
int m = iStart + iLength;
if(m > v.Length) { Debug.Assert(false); return u; }
for(int i = iStart; i < m; ++i)
{
u ^= m_vSBox[v[i]];
u *= 3;
}
return u;
}
public static void CopyStream(Stream sSource, Stream sTarget)
{
Debug.Assert((sSource != null) && (sTarget != null));
if(sSource == null) throw new ArgumentNullException("sSource");
if(sTarget == null) throw new ArgumentNullException("sTarget");
const int nBufSize = 4096;
byte[] pbBuf = new byte[nBufSize];
while(true)
{
int nRead = sSource.Read(pbBuf, 0, nBufSize);
if(nRead == 0) break;
sTarget.Write(pbBuf, 0, nRead);
}
// Do not close any of the streams
}
public static byte[] Read(Stream s, int nCount)
{
if(s == null) throw new ArgumentNullException("s");
if(nCount < 0) throw new ArgumentOutOfRangeException("nCount");
byte[] pb = new byte[nCount];
int iOffset = 0;
while(nCount > 0)
{
int iRead = s.Read(pb, iOffset, nCount);
if(iRead == 0) break;
iOffset += iRead;
nCount -= iRead;
}
if(iOffset != pb.Length)
{
byte[] pbPart = new byte[iOffset];
Array.Copy(pb, pbPart, iOffset);
return pbPart;
}
return pb;
}
public static void Write(Stream s, byte[] pbData)
{
if(s == null) { Debug.Assert(false); return; }
if(pbData == null) { Debug.Assert(false); return; }
s.Write(pbData, 0, pbData.Length);
}
public static byte[] Compress(byte[] pbData)
{
if(pbData == null) throw new ArgumentNullException("pbData");
if(pbData.Length == 0) return pbData;
MemoryStream msCompressed = new MemoryStream();
GZipStream gz = new GZipStream(msCompressed, CompressionMode.Compress);
MemoryStream msSource = new MemoryStream(pbData, false);
MemUtil.CopyStream(msSource, gz);
gz.Close();
msSource.Close();
byte[] pbCompressed = msCompressed.ToArray();
msCompressed.Close();
return pbCompressed;
}
public static byte[] Decompress(byte[] pbCompressed)
{
if(pbCompressed == null) throw new ArgumentNullException("pbCompressed");
if(pbCompressed.Length == 0) return pbCompressed;
MemoryStream msCompressed = new MemoryStream(pbCompressed, false);
GZipStream gz = new GZipStream(msCompressed, CompressionMode.Decompress);
MemoryStream msData = new MemoryStream();
MemUtil.CopyStream(gz, msData);
gz.Close();
msCompressed.Close();
byte[] pbData = msData.ToArray();
msData.Close();
return pbData;
}
public static int IndexOf<T>(T[] vHaystack, T[] vNeedle)
where T : IEquatable<T>
{
if(vHaystack == null) throw new ArgumentNullException("vHaystack");
if(vNeedle == null) throw new ArgumentNullException("vNeedle");
if(vNeedle.Length == 0) return 0;
for(int i = 0; i <= (vHaystack.Length - vNeedle.Length); ++i)
{
bool bFound = true;
for(int m = 0; m < vNeedle.Length; ++m)
{
if(!vHaystack[i + m].Equals(vNeedle[m]))
{
bFound = false;
break;
}
}
if(bFound) return i;
}
return -1;
}
public static T[] Mid<T>(T[] v, int iOffset, int iLength)
{
if(v == null) throw new ArgumentNullException("v");
if(iOffset < 0) throw new ArgumentOutOfRangeException("iOffset");
if(iLength < 0) throw new ArgumentOutOfRangeException("iLength");
if((iOffset + iLength) > v.Length) throw new ArgumentException();
T[] r = new T[iLength];
Array.Copy(v, iOffset, r, 0, iLength);
return r;
}
public static IEnumerable<T> Union<T>(IEnumerable<T> a, IEnumerable<T> b,
IEqualityComparer<T> cmp)
{
if(a == null) throw new ArgumentNullException("a");
if(b == null) throw new ArgumentNullException("b");
Dictionary<T, bool> d = ((cmp != null) ?
(new Dictionary<T, bool>(cmp)) : (new Dictionary<T, bool>()));
foreach(T ta in a)
{
if(d.ContainsKey(ta)) continue; // Prevent duplicates
d[ta] = true;
yield return ta;
}
foreach(T tb in b)
{
if(d.ContainsKey(tb)) continue; // Prevent duplicates
d[tb] = true;
yield return tb;
}
yield break;
}
public static IEnumerable<T> Intersect<T>(IEnumerable<T> a, IEnumerable<T> b,
IEqualityComparer<T> cmp)
{
if(a == null) throw new ArgumentNullException("a");
if(b == null) throw new ArgumentNullException("b");
Dictionary<T, bool> d = ((cmp != null) ?
(new Dictionary<T, bool>(cmp)) : (new Dictionary<T, bool>()));
foreach(T tb in b) { d[tb] = true; }
foreach(T ta in a)
{
if(d.Remove(ta)) // Prevent duplicates
yield return ta;
}
yield break;
}
public static IEnumerable<T> Except<T>(IEnumerable<T> a, IEnumerable<T> b,
IEqualityComparer<T> cmp)
{
if(a == null) throw new ArgumentNullException("a");
if(b == null) throw new ArgumentNullException("b");
Dictionary<T, bool> d = ((cmp != null) ?
(new Dictionary<T, bool>(cmp)) : (new Dictionary<T, bool>()));
foreach(T tb in b) { d[tb] = true; }
foreach(T ta in a)
{
if(d.ContainsKey(ta)) continue;
d[ta] = true; // Prevent duplicates
yield return ta;
}
yield break;
}
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="keepass2android.plugin.masterkee" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
<uses-sdk android:minSdkVersion="14" />
<application android:label="MasterKeePlugin" android:icon="@drawable/ic_launcher"></application>
</manifest>

View File

@ -0,0 +1,30 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Android.App;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("MasterKeePlugin")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MasterKeePlugin")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,50 @@
Images, layout descriptions, binary blobs and string dictionaries can be included
in your application as resource files. Various Android APIs are designed to
operate on the resource IDs instead of dealing with images, strings or binary blobs
directly.
For example, a sample Android app that contains a user interface layout (main.xml),
an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
would keep its resources in the "Resources" directory of the application:
Resources/
drawable-hdpi/
icon.png
drawable-ldpi/
icon.png
drawable-mdpi/
icon.png
layout/
main.xml
values/
strings.xml
In order to get the build system to recognize Android resources, set the build action to
"AndroidResource". The native Android APIs do not operate directly with filenames, but
instead operate on resource IDs. When you compile an Android application that uses resources,
the build system will package the resources for distribution and generate a class called
"Resource" that contains the tokens for each one of the resources included. For example,
for the above Resources layout, this is what the Resource class would expose:
public class Resource {
public class drawable {
public const int icon = 0x123;
}
public class layout {
public const int main = 0x456;
}
public class strings {
public const int first_string = 0xabc;
public const int second_string = 0xbcd;
}
}
You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main
to reference the layout/main.xml file, or Resource.strings.first_string to reference the first
string in the dictionary file values/strings.xml.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</LinearLayout>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="12dp">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/ExplainMkMasterEntry" />
<Button
android:id="@+id/btnSetupMaster"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/SetUpMkMasterEntry" />
<Button
android:id="@+id/btnSelectMaster"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/SelectMkMasterEntry" />
<Button
android:id="@+id/btnAddEntry"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/AddMkEntry" />
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:text="Your name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textView1" />
<EditText
android:inputType="textPersonName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/etUser" />
<TextView
android:text="Your MasterKee master password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textView2" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/toggle_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:src="@drawable/ic_menu_view" />
<EditText
android:id="@+id/entry_password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignTop="@id/toggle_password"
android:layout_toLeftOf="@id/toggle_password"
android:hint="@string/hint_pass"
android:inputType="textPassword"
android:singleLine="true"
android:typeface="monospace" />
<!-- Confirm Password -->
<EditText
android:id="@+id/entry_confpassword"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/entry_password"
android:hint="@string/hint_conf_pass"
android:inputType="textPassword"
android:singleLine="true"
android:typeface="monospace" />
</RelativeLayout>
<Button
android:text="@string/button_ok"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button_ok" />
</LinearLayout>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="ExplainMkMasterEntry">Your Master Password used for generating MasterKee passwords must be stored inside a special entry in your Keepass2Android database. Please create such an entry and then select it in your database (The current KP2A plugin interface requires this as a 2-step process). After creating and selecting the entry, you will be able to create new entries for sites.</string>
<string name="SelectMkMasterEntry">Select existing master entry</string>
<string name="SetUpMkMasterEntry">Create new master entry</string>
<string name="ApplicationName">MasterKeePlugin</string>
<string name="hint_conf_pass">confirm password</string>
<string name="hint_pass">password</string>
<string name="button_ok">OK</string>
<string name="error_pass_match">Passwords do not match.</string>
<string name="deriving_key">Calculating derived key... This might take a few seconds.</string>
<string name="AddMkEntry">Add MasterKee entry</string>
<string name="kp2aplugin_title">MasterKee Plugin</string>
<string name="kp2aplugin_shortdesc">Plugin to generate passwords compatible with the MasterPassword approach by Maarten Billemont giving you the ability to restore passwords even if your database is lost.</string>
<string name="kp2aplugin_author">Philipp Crocoll</string>
</resources>

View File

@ -0,0 +1,121 @@
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.Text;
using Android.Views;
using Android.Widget;
using KeePassLib.Utility;
using Keepass2android.Pluginsdk;
using keepass2android.Utils;
using Object = Java.Lang.Object;
namespace MasterKeePlugin
{
[Activity(Label = "Setup Master Entry")]
public class SetupMasterEntryActivity : Activity
{
private bool _showPassword;
private bool TryGetPassword(out string pass)
{
TextView passView = (TextView)FindViewById(Resource.Id.entry_password);
pass = passView.Text;
if (_showPassword)
return true;
TextView passConfView = (TextView)FindViewById(Resource.Id.entry_confpassword);
String confpass = passConfView.Text;
// Verify that passwords match
if (!pass.Equals(confpass))
{
// Passwords do not match
Toast.MakeText(this, Resource.String.error_pass_match, ToastLength.Long).Show();
return false;
}
return true;
}
private void MakePasswordMaskedOrVisible()
{
TextView password = (TextView)FindViewById(Resource.Id.entry_password);
TextView confpassword = (TextView)FindViewById(Resource.Id.entry_confpassword);
if (_showPassword)
{
password.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
confpassword.Visibility = ViewStates.Gone;
}
else
{
password.InputType = InputTypes.ClassText | InputTypes.TextVariationPassword;
confpassword.Visibility = ViewStates.Visible;
}
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Setup);
ImageButton btnTogglePassword = (ImageButton)FindViewById(Resource.Id.toggle_password);
btnTogglePassword.Click += (sender, e) =>
{
_showPassword = !_showPassword;
MakePasswordMaskedOrVisible();
};
FindViewById(Resource.Id.button_ok).Click += delegate(object sender, EventArgs args)
{
string password;
if (!TryGetPassword(out password))
return;
string username = FindViewById<EditText>(Resource.Id.etUser).Text;
new LoadingDialog<object, object, object>(this, GetString(Resource.String.deriving_key), false,
delegate
{
return
MemUtil.ByteArrayToHexString(
MasterPassword.MpAlgorithm.GetKeyForPassword(username, password));
},
delegate(Object res)
{
string derivedKey = (string) res;
AddMasterKeeEntry(derivedKey, username);
}
).Execute();
};
}
private void AddMasterKeeEntry(string derivedKey, string username)
{
Dictionary<string, string> fields = new Dictionary<string, string>();
fields[KeepassDefs.TitleField] = "MasterKee master entry";
fields[KeepassDefs.UserNameField] = username;
fields[KeepassDefs.UrlField] = "androidapp://" + PackageName;
fields[KeepassDefs.PasswordField] = derivedKey;
try
{
StartActivityForResult(Kp2aControl.GetAddEntryIntent(fields, new List<string>()), 123);
//TODO: get created entry id and store
Finish();
}
catch (ActivityNotFoundException)
{
Toast.MakeText(this, "No Keepass2Android host app found. Please install Keepass2Android 0.9.4 or above!", ToastLength.Long).Show();
}
}
}
}

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MasterPassword</RootNamespace>
<AssemblyName>MasterPassword</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Compile Include="MPAlgorithm.cs" />
<Compile Include="MpPasswordPlistData.cs" />
<Compile Include="PList.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="CryptSharp">
<HintPath>..\packages\CryptSharpOfficial.2.0.0.0\lib\CryptSharp.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,106 @@
using System;
using System.Linq;
using System.Text;
using CryptSharp.Utility;
using MasterPassword.Data;
namespace MasterPassword
{
public partial class MpAlgorithm
{
static readonly PList PlistData = new PList(plist);
private const int MP_N = 32768;
private const int MP_r = 8;
private const int MP_p = 2;
private const int MP_dkLen = 64;
public static byte[] GetKeyForPassword(string user, string password)
{
var salt = Combine(Encoding.UTF8.GetBytes("com.lyndir.masterpassword"),
IntAsByteArray(user.Length),
Encoding.UTF8.GetBytes(user));
var key = SCrypt.ComputeDerivedKey(Encoding.UTF8.GetBytes(password),
salt,
MP_N,
MP_r,
MP_p, null, MP_dkLen);
return key;
}
static byte[] Combine(params byte[][] arrays)
{
byte[] ret = new byte[arrays.Sum(x => x.Length)];
int offset = 0;
foreach (byte[] data in arrays)
{
Buffer.BlockCopy(data, 0, ret, offset, data.Length);
offset += data.Length;
}
return ret;
}
static byte[] IntAsByteArray(int intValue)
{
byte[] intBytes = BitConverter.GetBytes(intValue);
if (BitConverter.IsLittleEndian)
Array.Reverse(intBytes);
return intBytes;
}
public static String GenerateContent(string elementType, string siteName, byte[] key, int counter, Func<byte[], byte[], byte[]> hmacFunc)
{
if (counter == 0)
{
throw new Exception("counter==0 not support in .net. ");
//TODO: what does this line do in Java?
//counter = (int) (System.currentTimeMillis() / (300 * 1000)) * 300;
}
byte[] nameLengthBytes = IntAsByteArray(siteName.Length);
byte[] counterBytes = IntAsByteArray(counter);
byte[] seed = hmacFunc(key, Combine(Encoding.UTF8.GetBytes("com.lyndir.masterpassword"), //
nameLengthBytes, //
Encoding.UTF8.GetBytes(siteName), //
counterBytes));
//logger.trc( "seed is: %s", CryptUtils.encodeBase64( seed ) );
//Preconditions.checkState( seed.length > 0 );
int templateIndex = seed[0] & 0xFF; // Mask the integer's sign.
//MPTemplate template = templates.getTemplateForTypeAtRollingIndex( type, templateIndex );
//MPTemplate template = null;
var generatedEntities = PlistData["MPElementGeneratedEntity"];
//TODO catch wrong elementType!
var templatesLongPwd = generatedEntities[elementType];
string template = templatesLongPwd[templateIndex % templatesLongPwd.Count];
//logger.trc( "type: %s, template: %s", type, template );
StringBuilder password = new StringBuilder(template.Length);
for (int i = 0; i < template.Length; ++i)
{
int characterIndex = seed[i + 1] & 0xFF; // Mask the integer's sign.
char c = template[i];
PList listOfCharacterSets = PlistData["MPCharacterClasses"];
var listOfCharacters = listOfCharacterSets.Single(kvp => { return kvp.Key == c.ToString(); }).Value;
char passwordCharacter = listOfCharacters[characterIndex % listOfCharacters.Length];
/*logger.trc( "class: %s, index: %d, byte: 0x%02X, chosen password character: %s", characterClass, characterIndex, seed[i + 1],
passwordCharacter );
*/
password.Append(passwordCharacter);
}
return password.ToString();
}
}
}

View File

@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MasterPassword
{
public partial class MpAlgorithm
{
private const string plist = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<plist version=""1.0"">
<dict>
<key>MPElementGeneratedEntity</key>
<dict>
<key>Maximum Security Password</key>
<array>
<string>anoxxxxxxxxxxxxxxxxx</string>
<string>axxxxxxxxxxxxxxxxxno</string>
</array>
<key>Long Password</key>
<array>
<string>CvcvnoCvcvCvcv</string>
<string>CvcvCvcvnoCvcv</string>
<string>CvcvCvcvCvcvno</string>
<string>CvccnoCvcvCvcv</string>
<string>CvccCvcvnoCvcv</string>
<string>CvccCvcvCvcvno</string>
<string>CvcvnoCvccCvcv</string>
<string>CvcvCvccnoCvcv</string>
<string>CvcvCvccCvcvno</string>
<string>CvcvnoCvcvCvcc</string>
<string>CvcvCvcvnoCvcc</string>
<string>CvcvCvcvCvccno</string>
<string>CvccnoCvccCvcv</string>
<string>CvccCvccnoCvcv</string>
<string>CvccCvccCvcvno</string>
<string>CvcvnoCvccCvcc</string>
<string>CvcvCvccnoCvcc</string>
<string>CvcvCvccCvccno</string>
<string>CvccnoCvcvCvcc</string>
<string>CvccCvcvnoCvcc</string>
<string>CvccCvcvCvccno</string>
</array>
<key>Medium Password</key>
<array>
<string>CvcnoCvc</string>
<string>CvcCvcno</string>
</array>
<key>Basic Password</key>
<array>
<string>aaanaaan</string>
<string>aannaaan</string>
<string>aaannaaa</string>
</array>
<key>Short Password</key>
<array>
<string>Cvcn</string>
</array>
<key>PIN</key>
<array>
<string>nnnn</string>
</array>
</dict>
<key>MPCharacterClasses</key>
<dict>
<key>V</key>
<string>AEIOU</string>
<key>C</key>
<string>BCDFGHJKLMNPQRSTVWXYZ</string>
<key>v</key>
<string>aeiou</string>
<key>c</key>
<string>bcdfghjklmnpqrstvwxyz</string>
<key>A</key>
<string>AEIOUBCDFGHJKLMNPQRSTVWXYZ</string>
<key>a</key>
<string>AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz</string>
<key>n</key>
<string>0123456789</string>
<key>o</key>
<string>@&amp;%?,=[]_:-+*$#!'^~;()/.</string>
<key>x</key>
<string>AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&amp;*()</string>
</dict>
</dict>
</plist>
";
}
}

View File

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
namespace MasterPassword.Data
{
public class PList : Dictionary<string, dynamic>
{
public PList()
{
}
public PList(string data)
{
Read(data);
}
public void Read(string data)
{
Clear();
//XDocument doc = XDocument.Load(file);
XDocument doc = XDocument.Load(XmlReader.Create(new StringReader(data)));
XElement plist = doc.Element("plist");
XElement dict = plist.Element("dict");
var dictElements = dict.Elements();
Parse(this, dictElements);
}
private void Parse(PList dict, IEnumerable<XElement> elements)
{
for (int i = 0; i < elements.Count(); i += 2)
{
XElement key = elements.ElementAt(i);
XElement val = elements.ElementAt(i + 1);
dict[key.Value] = ParseValue(val);
}
}
private List<dynamic> ParseArray(IEnumerable<XElement> elements)
{
List<dynamic> list = new List<dynamic>();
foreach (XElement e in elements)
{
dynamic one = ParseValue(e);
list.Add(one);
}
return list;
}
private dynamic ParseValue(XElement val)
{
switch (val.Name.ToString())
{
case "string":
return val.Value;
case "integer":
return int.Parse(val.Value);
case "real":
return float.Parse(val.Value);
case "true":
return true;
case "false":
return false;
case "dict":
PList plist = new PList();
Parse(plist, val.Elements());
return plist;
case "array":
List<dynamic> list = ParseArray(val.Elements());
return list;
default:
throw new ArgumentException("Unsupported");
}
}
}
}

View File

@ -0,0 +1,30 @@
using System.Resources;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über folgende
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die einer Assembly zugeordnet sind.
[assembly: AssemblyTitle("MasterPassword")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MasterPassword")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("de")]
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
//
// Hauptversion
// Nebenversion
// Buildnummer
// Revision
//
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
// durch Einsatz von '*', wie in nachfolgendem Beispiel:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CryptSharpOfficial" version="2.0.0.0" targetFramework="portable-win+net45+MonoAndroid10+MonoTouch10" />
</packages>

View File

@ -100,6 +100,9 @@
<SubType>AndroidResource</SubType>
</AndroidResource>
<AndroidResource Include="Resources\Layout\sftp_credentials.axml" />
<AndroidResource Include="Resources\Layout\Setup.axml">
<SubType>AndroidResource</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\Layout\Main.axml" />

View File

@ -1,32 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
<resources>
<string name="about_feedback">Feedback</string>
<string name="about_homepage">Homepage</string>
<string name="AboutText">Keepass2Android is a password manager providing read/write access to KeePass 2.x databases on Android.</string>
<string name="CreditsText">The User Interface is based on a port of KeepassDroid developed by Brian Pellin. Code for database operations is based on KeePass by Dominik Reichl. The Android robot is reproduced or modified from work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License.</string>
<string name="CreditsTextSFTP">SFTP support is implemented using the JSch library under BSD licence, created by JCraft, Inc.</string>
<string name="accept">Accept</string>
<string name="about_feedback">Feedback</string>
<string name="about_homepage">Homepage</string>
<string name="AboutText">Keepass2Android is a password manager providing read/write access to KeePass 2.x databases on Android.</string>
<string name="CreditsText">The User Interface is based on a port of KeepassDroid developed by Brian Pellin. Code for database operations is based on KeePass by Dominik Reichl. The Android robot is reproduced or modified from work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License.</string>
<string name="CreditsTextSFTP">SFTP support is implemented using the JSch library under BSD licence, created by JCraft, Inc.</string>
<string name="accept">Accept</string>
<string name="deny">Deny</string>
<string name="add_entry">Add entry</string>
<string name="add_url_entry">Create entry for URL</string>
<string name="add_group">Add group</string>
<string name="add_group_title">Add Group</string>
<string name="edit_group_title">Edit Group</string>
<string name="algorithm">Algorithm</string>
<string name="algorithm_colon">Algorithm</string>
<string name="app_name">Keepass2Android</string>
<string name="short_app_name">KP2A</string>
<string name="app_name_nonet">Keepass2Android Offline</string>
<string name="short_app_name_nonet">KP2A Offline</string>
<string name="app_timeout">Application timeout</string>
<string name="app_timeout_summary">Time before locking database when the application is inactive.</string>
<string name="kill_app_label">Kill application process</string>
<string name="show_kill_app">Close-Button</string>
<string name="show_kill_app_summary">Show a button in password screen to kill the application process (for paranoid users)</string>
<string name="application">Application</string>
<string name="application_settings">Application settings</string>
<string name="add_entry">Add entry</string>
<string name="add_url_entry">Create entry for URL</string>
<string name="add_group">Add group</string>
<string name="add_group_title">Add Group</string>
<string name="edit_group_title">Edit Group</string>
<string name="algorithm">Algorithm</string>
<string name="algorithm_colon">Algorithm</string>
<string name="app_name">Keepass2Android</string>
<string name="short_app_name">KP2A</string>
<string name="app_name_nonet">Keepass2Android Offline</string>
<string name="short_app_name_nonet">KP2A Offline</string>
<string name="app_timeout">Application timeout</string>
<string name="app_timeout_summary">Time before locking database when the application is inactive.</string>
<string name="kill_app_label">Kill application process</string>
<string name="show_kill_app">Close-Button</string>
<string name="show_kill_app_summary">Show a button in password screen to kill the application process (for paranoid users)</string>
<string name="application">Application</string>
<string name="application_settings">Application settings</string>
<string name="security_prefs">Security</string>
<string name="display_prefs">Display</string>
<string name="password_access_prefs">Password entry access</string>
@ -35,155 +34,154 @@
<string name="keyboard_prefs">Keyboard</string>
<string name="export_prefs">Export database...</string>
<string name="brackets">Brackets</string>
<string name="cancel">Cancel</string>
<string name="ClearClipboard">Clipboard cleared.</string>
<string name="clipboard_timeout">Clipboard timeout</string>
<string name="clipboard_timeout_summary">Time before clearing clipboard after copying username or password</string>
<string name="copy_username">Select to copy username to clipboard</string>
<string name="copy_password">Select to copy password to clipboard</string>
<string name="available_through_keyboard">Entry is available through KP2A Keyboard</string>
<string name="not_possible_im_picker">Could not open dialog to select input method. Please activate keyboard manually.</string>
<string name="please_activate_keyboard">Please enable the Keepass2Android keyboard in your system settings.</string>
<string name="creating_db_key">Creating database key…</string>
<string name="current_group">Current Group</string>
<string name="current_group_root">Current Group: Root</string>
<string name="database">Database</string>
<string name="digits">Digits</string>
<string name="disclaimer_formal">Keepass2Android comes with ABSOLUTELY NO WARRANTY; This is free software, and you are welcome to redistribute it under the conditions of the GPL version 2 or later.</string>
<string name="ellipsis">\u2026</string>
<string name="enter_filename">Enter database filename</string>
<string name="entry_accessed">Accessed</string>
<string name="entry_cancel">Cancel</string>
<string name="entry_comment">Comments</string>
<string name="entry_tags">Tags</string>
<string name="entry_override_url">Override URL</string>
<string name="entry_confpassword">Confirm password</string>
<string name="entry_created">Created</string>
<string name="entry_expires">Expires</string>
<string name="entry_keyfile">Key file (optional)</string>
<string name="entry_modified">Modified</string>
<string name="entry_password">Password</string>
<string name="entry_save">Save</string>
<string name="entry_title">Name</string>
<string name="entry_url">URL</string>
<string name="entry_user_name">User Name</string>
<string name="entry_extra_strings">Extra string fields</string>
<string name="entry_binaries">File attachments</string>
<string name="error_can_not_handle_uri">Keepass2Android cannot handle this uri.</string>
<string name="error_could_not_create_group">Error creating group.</string>
<string name="error_could_not_create_parent">Could not create parent directory.</string>
<string name="error_database_exists">This file already exists.</string>
<string name="error_database_settings">Failed to determine database settings.</string>
<string name="error_failed_to_launch_link">Failed to launch link.</string>
<string name="error_filename_required">A filename is required.</string>
<string name="error_file_not_create">Could not create file</string>
<string name="error_invalid_db">Invalid database.</string>
<string name="error_invalid_path">Invalid path.</string>
<string name="error_no_name">A name is required.</string>
<string name="error_nopass">A password or a keyfile is required.</string>
<string name="error_pass_gen_type">At least one password generation type must be selected</string>
<string name="error_pass_match">Passwords do not match.</string>
<string name="error_rounds_not_number">Rounds must be a number.</string>
<string name="error_title_required">A title is required.</string>
<string name="error_wrong_length">Enter a positive integer on length field</string>
<string name="FileNotFound">File not found.</string>
<string name="file_browser">File Browser</string>
<string name="generate_password">Generate Password</string>
<string name="group">Group</string>
<string name="hint_comment">comment</string>
<string name="hint_conf_pass">confirm password</string>
<string name="hint_generated_password">generated password</string>
<string name="hint_group_name">Group name</string>
<string name="hint_keyfile">key file</string>
<string name="hint_length">length</string>
<string name="hint_pass">password</string>
<string name="hint_login_pass">Password</string>
<string name="hint_title">name</string>
<string name="hint_url">url</string>
<string name="hint_override_url">override url</string>
<string name="hint_tags">tag1, tag2</string>
<string name="hint_username">username</string>
<string name="InvalidPassword">Invalid password or key file.</string>
<string name="invalid_algorithm">Invalid algorithm.</string>
<string name="invalid_db_sig">Database format not recognized.</string>
<string name="keyfile_does_not_exist">Key file does not exist.</string>
<string name="keyfile_is_empty">Key file is empty.</string>
<string name="length">Length</string>
<string name="list_size_title">Group list size</string>
<string name="list_size_summary">Text size in the group list</string>
<string name="loading_database">Loading database…</string>
<string name="lowercase">Lower-case</string>
<string name="MaskedPassword">*****</string>
<string name="maskpass_title">Mask password</string>
<string name="maskpass_summary">Hide passwords by default</string>
<string name="menu_about">About</string>
<string name="menu_change_key">Change Master Key</string>
<string name="menu_copy_pass">Copy Password</string>
<string name="menu_copy_user">Copy User</string>
<string name="menu_create">Create</string>
<string name="menu_app_settings">Settings</string>
<string name="menu_db_settings">Database settings</string>
<string name="menu_delete">Delete</string>
<string name="menu_move">Move to another group</string>
<string name="menu_donate">Donate a beer...</string>
<string name="menu_edit">Edit</string>
<string name="menu_hide_password">Hide Password</string>
<string name="menu_lock">Lock Database</string>
<string name="menu_open">Open</string>
<string name="menu_rename">Rename</string>
<string name="menu_search">Search</string>
<string name="menu_search_advanced">Advanced Search</string>
<string name="menu_url">Go to URL</string>
<string name="cancel">Cancel</string>
<string name="ClearClipboard">Clipboard cleared.</string>
<string name="clipboard_timeout">Clipboard timeout</string>
<string name="clipboard_timeout_summary">Time before clearing clipboard after copying username or password</string>
<string name="copy_username">Select to copy username to clipboard</string>
<string name="copy_password">Select to copy password to clipboard</string>
<string name="available_through_keyboard">Entry is available through KP2A Keyboard</string>
<string name="not_possible_im_picker">Could not open dialog to select input method. Please activate keyboard manually.</string>
<string name="please_activate_keyboard">Please enable the Keepass2Android keyboard in your system settings.</string>
<string name="creating_db_key">Creating database key…</string>
<string name="current_group">Current Group</string>
<string name="current_group_root">Current Group: Root</string>
<string name="database">Database</string>
<string name="digits">Digits</string>
<string name="disclaimer_formal">Keepass2Android comes with ABSOLUTELY NO WARRANTY; This is free software, and you are welcome to redistribute it under the conditions of the GPL version 2 or later.</string>
<string name="ellipsis">\u2026</string>
<string name="enter_filename">Enter database filename</string>
<string name="entry_accessed">Accessed</string>
<string name="entry_cancel">Cancel</string>
<string name="entry_comment">Comments</string>
<string name="entry_tags">Tags</string>
<string name="entry_override_url">Override URL</string>
<string name="entry_confpassword">Confirm password</string>
<string name="entry_created">Created</string>
<string name="entry_expires">Expires</string>
<string name="entry_keyfile">Key file (optional)</string>
<string name="entry_modified">Modified</string>
<string name="entry_password">Password</string>
<string name="entry_save">Save</string>
<string name="entry_title">Name</string>
<string name="entry_url">URL</string>
<string name="entry_user_name">User Name</string>
<string name="entry_extra_strings">Extra string fields</string>
<string name="entry_binaries">File attachments</string>
<string name="error_can_not_handle_uri">Keepass2Android cannot handle this uri.</string>
<string name="error_could_not_create_group">Error creating group.</string>
<string name="error_could_not_create_parent">Could not create parent directory.</string>
<string name="error_database_exists">This file already exists.</string>
<string name="error_database_settings">Failed to determine database settings.</string>
<string name="error_failed_to_launch_link">Failed to launch link.</string>
<string name="error_filename_required">A filename is required.</string>
<string name="error_file_not_create">Could not create file</string>
<string name="error_invalid_db">Invalid database.</string>
<string name="error_invalid_path">Invalid path.</string>
<string name="error_no_name">A name is required.</string>
<string name="error_nopass">A password or a keyfile is required.</string>
<string name="error_pass_gen_type">At least one password generation type must be selected</string>
<string name="error_pass_match">Passwords do not match.</string>
<string name="error_rounds_not_number">Rounds must be a number.</string>
<string name="error_title_required">A title is required.</string>
<string name="error_wrong_length">Enter a positive integer on length field</string>
<string name="FileNotFound">File not found.</string>
<string name="file_browser">File Browser</string>
<string name="generate_password">Generate Password</string>
<string name="group">Group</string>
<string name="hint_comment">comment</string>
<string name="hint_conf_pass">confirm password</string>
<string name="hint_generated_password">generated password</string>
<string name="hint_group_name">Group name</string>
<string name="hint_keyfile">key file</string>
<string name="hint_length">length</string>
<string name="hint_pass">password</string>
<string name="hint_login_pass">Password</string>
<string name="hint_title">name</string>
<string name="hint_url">url</string>
<string name="hint_override_url">override url</string>
<string name="hint_tags">tag1, tag2</string>
<string name="hint_username">username</string>
<string name="InvalidPassword">Invalid password or key file.</string>
<string name="invalid_algorithm">Invalid algorithm.</string>
<string name="invalid_db_sig">Database format not recognized.</string>
<string name="keyfile_does_not_exist">Key file does not exist.</string>
<string name="keyfile_is_empty">Key file is empty.</string>
<string name="length">Length</string>
<string name="list_size_title">Group list size</string>
<string name="list_size_summary">Text size in the group list</string>
<string name="loading_database">Loading database…</string>
<string name="lowercase">Lower-case</string>
<string name="MaskedPassword">*****</string>
<string name="maskpass_title">Mask password</string>
<string name="maskpass_summary">Hide passwords by default</string>
<string name="menu_about">About</string>
<string name="menu_change_key">Change Master Key</string>
<string name="menu_copy_pass">Copy Password</string>
<string name="menu_copy_user">Copy User</string>
<string name="menu_create">Create</string>
<string name="menu_app_settings">Settings</string>
<string name="menu_db_settings">Database settings</string>
<string name="menu_delete">Delete</string>
<string name="menu_move">Move to another group</string>
<string name="menu_donate">Donate a beer...</string>
<string name="menu_edit">Edit</string>
<string name="menu_hide_password">Hide Password</string>
<string name="menu_lock">Lock Database</string>
<string name="menu_open">Open</string>
<string name="menu_rename">Rename</string>
<string name="menu_search">Search</string>
<string name="menu_search_advanced">Advanced Search</string>
<string name="menu_url">Go to URL</string>
<string name="menu_change_db">Change database…</string>
<string name="minus">Minus</string>
<string name="never">Never</string>
<string name="yes">Yes</string>
<string name="no">No</string>
<string name="no_keys">No entries in the database or group.</string>
<string name="no_results">No search results</string>
<string name="no_url_handler">No handler for this url.</string>
<string name="open_recent">Open recent database (click to open)</string>
<string name="omitbackup_title">Don\'t search backup and recycle bin entries</string>
<string name="omitbackup_summary">Omit \'Backup\' and Recycle Bin group from search results</string>
<string name="pass_filename">KeePass database filename</string>
<string name="password_title">Enter database password</string>
<string name="master_key_type">Select master key type:</string>
<string name="progress_create">Creating new database…</string>
<string name="create_database">Create database</string>
<string name="progress_title">Working…</string>
<string name="remember_keyfile_summary">Remembers the location of keyfiles</string>
<string name="remember_keyfile_title">Save keyfile</string>
<string name="remove_from_filelist">Remove</string>
<string name="rijndael">Rijndael (AES)</string>
<string name="root">Root</string>
<string name="rounds">Encryption Rounds</string>
<string name="rounds_explaination">Higher encryption rounds provide additional protection against brute force attacks, but can really slow down loading and saving.</string>
<string name="rounds_hint">rounds</string>
<string name="database_name">Database name</string>
<string name="default_username">Default user name for new entries</string>
<string name="saving_database">Saving database…</string>
<string name="minus">Minus</string>
<string name="never">Never</string>
<string name="yes">Yes</string>
<string name="no">No</string>
<string name="no_keys">No entries in the database or group.</string>
<string name="no_results">No search results</string>
<string name="no_url_handler">No handler for this url.</string>
<string name="open_recent">Open recent database (click to open)</string>
<string name="omitbackup_title">Don\'t search backup and recycle bin entries</string>
<string name="omitbackup_summary">Omit \'Backup\' and Recycle Bin group from search results</string>
<string name="pass_filename">KeePass database filename</string>
<string name="password_title">Enter database password</string>
<string name="master_key_type">Select master key type:</string>
<string name="progress_create">Creating new database…</string>
<string name="create_database">Create database</string>
<string name="progress_title">Working…</string>
<string name="remember_keyfile_summary">Remembers the location of keyfiles</string>
<string name="remember_keyfile_title">Save keyfile</string>
<string name="remove_from_filelist">Remove</string>
<string name="rijndael">Rijndael (AES)</string>
<string name="root">Root</string>
<string name="rounds">Encryption Rounds</string>
<string name="rounds_explaination">Higher encryption rounds provide additional protection against brute force attacks, but can really slow down loading and saving.</string>
<string name="rounds_hint">rounds</string>
<string name="database_name">Database name</string>
<string name="default_username">Default user name for new entries</string>
<string name="saving_database">Saving database…</string>
<string name="exporting_database">Exporting database…</string>
<string name="export_database_successful">Database exported successfully!</string>
<string name="space">Space</string>
<string name="search_label">Search</string>
<string name="show_password">Show password</string>
<string name="sort_name">Sort by name</string>
<string name="sort_db">Sort by creation date</string>
<string name="special">Special</string>
<string name="search_hint">Find what</string>
<string name="search_results">Search results</string>
<string name="search_in">Search in</string>
<string name="select_other_entry">Select another entry</string>
<string name="select_group_then_add">Open the desired group, then press "%1$s"!</string>
<string name="search_label">Search</string>
<string name="show_password">Show password</string>
<string name="sort_name">Sort by name</string>
<string name="sort_db">Sort by creation date</string>
<string name="special">Special</string>
<string name="search_hint">Find what</string>
<string name="search_results">Search results</string>
<string name="search_in">Search in</string>
<string name="select_other_entry">Select another entry</string>
<string name="select_group_then_add">Open the desired group, then press "%1$s"!</string>
<string name="insert_element_here">Insert here</string>
<string name="twofish">Twofish</string>
<string name="underline">Underline</string>
<string name="unsupported_db_version">Unsupported database version.</string>
<string name="uppercase">Upper-case</string>
<string name="warning_read_only">Your sd card is currently read-only. You may not be able to save changes to your database.</string>
<string name="warning_unmounted">Your sd card is not currently mounted on your device. You will not be able to load or create your database.</string>
<string name="version_label">Version</string>
<string name="twofish">Twofish</string>
<string name="underline">Underline</string>
<string name="unsupported_db_version">Unsupported database version.</string>
<string name="uppercase">Upper-case</string>
<string name="warning_read_only">Your sd card is currently read-only. You may not be able to save changes to your database.</string>
<string name="warning_unmounted">Your sd card is not currently mounted on your device. You will not be able to load or create your database.</string>
<string name="version_label">Version</string>
<string name="version_history">Version history</string>
<string name="author">Keepass2Android is developed by Philipp Crocoll.</string>
<string name="further_authors">Thanks to code contributions by %1$s.</string>
@ -192,109 +190,97 @@
<string name="credit_keyboard">The KP2A keyboard is based on the Gingerbread keyboard by the Android Open Source Project and uses the Plugin Manager code from Hacker\'s Keyboard by Klaus Weidner.</string>
<string name="please_note">Please note</string>
<string name="contributors">Contributors</string>
<string name="regular_expression">Regular expression</string>
<string name="TanExpiresOnUse_title">Tan expires on use</string>
<string name="TanExpiresOnUse_summary">Mark TAN entries expired when using them</string>
<string name="ShowUsernameInList_title">Display username in list</string>
<string name="ShowUsernameInList_summary">Display usernames below entry titles. Useful for multiple accounts or TANs.</string>
<string name="regular_expression">Regular expression</string>
<string name="TanExpiresOnUse_title">Tan expires on use</string>
<string name="TanExpiresOnUse_summary">Mark TAN entries expired when using them</string>
<string name="ShowUsernameInList_title">Display username in list</string>
<string name="ShowUsernameInList_summary">Display usernames below entry titles. Useful for multiple accounts or TANs.</string>
<string name="RememberRecentFiles_title">Remember databases</string>
<string name="RememberRecentFiles_summary">Remember recently opened databases and show them in the Open database screen.</string>
<string name="kp2a_findUrl">Keepass2Android: Find password</string>
<string name="excludeExpiredEntries">Exclude expired entries</string>
<string name="search_options">Options</string>
<string name="caseSensitive">Case sensitive</string>
<string name="start_open_file">Open file...</string>
<string name="start_create">Create new database...</string>
<string name="start_open_url">Open URL...</string>
<string name="start_create_import">Import file to new database...</string>
<string name="enter_filename_details_url">The complete URL must be specified including protocol like http://.</string>
<string name="enter_filename_details_create_import">File to import will be selected in the next step.</string>
<string name="enable_quickunlock">Enable QuickUnlock</string>
<string name="QuickUnlock_label">Enter last %1$d characters of your password:</string>
<string name="QuickUnlock_button">QuickUnlock!</string>
<string name="QuickUnlock_lockButton">Close database</string>
<string name="QuickUnlockDefaultEnabled_title">Enable QuickUnlock by default</string>
<string name="QuickUnlockDefaultEnabled_summary">Defines whether QuickUnlock is enabled by default or not.</string>
<string name="QuickUnlockIconHidden_title">Hide QuickUnlock icon</string>
<string name="QuickUnlockIconHidden_summary">QuickUnlock unfortunately does not work without displaying a notification icon. Select this option to use a transparent icon.</string>
<string name="QuickUnlockIconHidden16_title">Hide QuickUnlock icon</string>
<string name="QuickUnlockIconHidden16_summary">QuickUnlock requires a notification to work properly. Select this option to display a notification without an icon.</string>
<string name="QuickUnlockLength_title">Length of QuickUnlock key</string>
<string name="QuickUnlockLength_summary">Maximum number of characters used as QuickUnlock password.</string>
<string name="QuickUnlock_fail">QuickUnlock failed: incorrect password!</string>
<string name="BinaryDirectory_title">File attachments directory</string>
<string name="BinaryDirectory_summary">Directory where file attachments are saved to.</string>
<string name="SaveAttachmentDialog_title">Save attachment</string>
<string name="SaveAttachmentDialog_text">Please select where to save the attachment.</string>
<string name="SaveAttachmentDialog_save">Save to SD card</string>
<string name="SaveAttachmentDialog_open">Save to cache and open</string>
<string name="SaveAttachment_doneMessage">Saved file to %1$s.</string>
<string name="SaveAttachment_Failed">Could not save attachment to %1$s.</string>
<string name="excludeExpiredEntries">Exclude expired entries</string>
<string name="search_options">Options</string>
<string name="caseSensitive">Case sensitive</string>
<string name="start_open_file">Open file...</string>
<string name="start_create">Create new database...</string>
<string name="start_open_url">Open URL...</string>
<string name="start_create_import">Import file to new database...</string>
<string name="enter_filename_details_url">The complete URL must be specified including protocol like http://.</string>
<string name="enter_filename_details_create_import">File to import will be selected in the next step.</string>
<string name="enable_quickunlock">Enable QuickUnlock</string>
<string name="QuickUnlock_label">Enter last %1$d characters of your password:</string>
<string name="QuickUnlock_button">QuickUnlock!</string>
<string name="QuickUnlock_lockButton">Close database</string>
<string name="QuickUnlockDefaultEnabled_title">Enable QuickUnlock by default</string>
<string name="QuickUnlockDefaultEnabled_summary">Defines whether QuickUnlock is enabled by default or not.</string>
<string name="QuickUnlockIconHidden_title">Hide QuickUnlock icon</string>
<string name="QuickUnlockIconHidden_summary">QuickUnlock unfortunately does not work without displaying a notification icon. Select this option to use a transparent icon.</string>
<string name="QuickUnlockIconHidden16_title">Hide QuickUnlock icon</string>
<string name="QuickUnlockIconHidden16_summary">QuickUnlock requires a notification to work properly. Select this option to display a notification without an icon.</string>
<string name="QuickUnlockLength_title">Length of QuickUnlock key</string>
<string name="QuickUnlockLength_summary">Maximum number of characters used as QuickUnlock password.</string>
<string name="QuickUnlock_fail">QuickUnlock failed: incorrect password!</string>
<string name="BinaryDirectory_title">File attachments directory</string>
<string name="BinaryDirectory_summary">Directory where file attachments are saved to.</string>
<string name="SaveAttachmentDialog_title">Save attachment</string>
<string name="SaveAttachmentDialog_text">Please select where to save the attachment.</string>
<string name="SaveAttachmentDialog_save">Save to SD card</string>
<string name="SaveAttachmentDialog_open">Save to cache and open</string>
<string name="SaveAttachment_doneMessage">Saved file to %1$s.</string>
<string name="SaveAttachment_Failed">Could not save attachment to %1$s.</string>
<string name="AddUrlToEntryDialog_title">Remember search text?</string>
<string name="AddUrlToEntryDialog_text">Would you like to store the search text "%1$s" in the selected entry in order to find it automatically next time?</string>
<string name="error_invalid_expiry_date">Invalid date/time format for expiry date!</string>
<string name="error_string_key">A field name is required for each string.</string>
<string name="field_name">Field Name</string>
<string name="field_value">Field value</string>
<string name="protection">Protected field</string>
<string name="add_binary">Add file attachment...</string>
<string name="add_extra_string">Add additional string</string>
<string name="error_string_key">A field name is required for each string.</string>
<string name="field_name">Field Name</string>
<string name="field_value">Field value</string>
<string name="protection">Protected field</string>
<string name="add_binary">Add file attachment...</string>
<string name="add_extra_string">Add additional string</string>
<string name="delete_extra_string">Delete additional string</string>
<string name="database_loaded_quickunlock_enabled">%1$s: Locked. QuickUnlock enabled.</string>
<string name="database_loaded_unlocked">%1$s: Unlocked.</string>
<string name="credentials_dialog_title">Enter server credentials</string>
<string name="UseFileTransactions_title">File transactions</string>
<string name="UseFileTransactions_summary">Use file transactions for writing databases</string>
<string name="credentials_dialog_title">Enter server credentials</string>
<string name="UseFileTransactions_title">File transactions</string>
<string name="UseFileTransactions_summary">Use file transactions for writing databases</string>
<string name="LockWhenScreenOff_title">Lock when screen off</string>
<string name="LockWhenScreenOff_summary">Lock the database when screen is switched off.</string>
<string name="LockWhenScreenOff_summary">Lock the database when screen is switched off.</string>
<string name="UseOfflineCache_title">Database caching</string>
<string name="UseOfflineCache_summary">Keep a copy of remote database files in the application cache directory. This allows to use remote databases even when offline.</string>
<string name="AcceptAllServerCertificates_title">SSL certificates</string>
<string name="AcceptAllServerCertificates_summary">Define the behavior when certificate validation fails. Note: you can install certificates on your device if validation fails!</string>
<string name="ClearOfflineCache_title">Clear cache?</string>
<string name="ClearOfflineCache_question">This will delete all cached database files. Any changes you made while being offline which have not yet been synchronized will be lost! Continue?</string>
<string name="CheckForFileChangesOnSave_title">Check for modifications</string>
<string name="CheckForFileChangesOnSave_summary">Check whether the file was modified externally before saving changes.</string>
<string name="ShowCopyToClipboardNotification_title">Clipboard notifications</string>
<string name="ShowCopyToClipboardNotification_summary">Make username and password accessible through the notification bar and clipboard. Beware of password sniffers!</string>
<string name="ShowKp2aKeyboardNotification_title">KP2A keyboard notification</string>
<string name="ShowKp2aKeyboardNotification_summary">Make full entry accessible through the KP2A keyboard (recommended).</string>
<string name="OpenKp2aKeyboardAutomatically_title">Switch keyboard</string>
<string name="OpenKp2aKeyboardAutomatically_summary">Open keyboard selection dialog when entry is available through KP2A keyboard after search from the browser.</string>
<string name="CheckForFileChangesOnSave_title">Check for modifications</string>
<string name="CheckForFileChangesOnSave_summary">Check whether the file was modified externally before saving changes.</string>
<string name="ShowCopyToClipboardNotification_title">Clipboard notifications</string>
<string name="ShowCopyToClipboardNotification_summary">Make username and password accessible through the notification bar and clipboard. Beware of password sniffers!</string>
<string name="ShowKp2aKeyboardNotification_title">KP2A keyboard notification</string>
<string name="ShowKp2aKeyboardNotification_summary">Make full entry accessible through the KP2A keyboard (recommended).</string>
<string name="OpenKp2aKeyboardAutomatically_title">Switch keyboard</string>
<string name="OpenKp2aKeyboardAutomatically_summary">Open keyboard selection dialog when entry is available through KP2A keyboard after search from the browser.</string>
<string name="kp2a_switch_rooted">Auto-switch on rooted devices</string>
<string name="kp2a_switch_rooted_summary">On rooted devices, it is possible to automatically switch to the Keepass2Android keyboard (after search for an entry or by clicking the KP2A keyboard notification) and to switch back to the previous keyboard without showing the Input method picker. This also requires to install the Secure Settings app. See the KP2A documentation for more information!</string>
<string name="kp2a_switch_rooted_summary">On rooted devices, it is possible to automatically switch to the Keepass2Android keyboard (after search for an entry or by clicking the KP2A keyboard notification) and to switch back to the previous keyboard without showing the Input method picker. This also requires to install the Secure Settings app. See the KP2A documentation for more information!</string>
<string name="ShowUnlockedNotification_title">Notification icon while unlocked</string>
<string name="ShowUnlockedNotification_summary">Show a notification icon while the database is unlocked.</string>
<string name="PreloadDatabaseEnabled_title">Pre-load database file</string>
<string name="PreloadDatabaseEnabled_summary">Start background loading or downloading of the database file during password entry.</string>
<string name="AskOverwriteBinary">Do you want to overwrite the existing binary with the same name?</string>
<string name="AskOverwriteBinary_title">Overwrite existing binary?</string>
<string name="AskOverwriteBinary_yes">Overwrite</string>
<string name="AskOverwriteBinary_no">Rename</string>
<string name="AttachFailed">Failed to add file attachment.</string>
<string name="RecycleBin">Recycle Bin</string>
<string name="AskDeletePermanentlyEntry">Do you want to delete this entry permanently? Press No to recycle.</string>
<string name="AskDeletePermanentlyGroup">Do you want to delete this group permanently? Press No to recycle.</string>
<string name="AskDeletePermanently_title">Delete permanently?</string>
<string name="AskReloadFile_title">Reload file?</string>
<string name="AskReloadFile">The file which is currently open was changed by another program. Do you want to reload it?</string>
<string name="AskDiscardChanges">Do you really want to discard the changes made? (The Save button is at the top of the form.)</string>
<string name="AskDiscardChanges_title">Discard changes?</string>
<string name="suggest_improvements">Suggest or vote for improvements</string>
<string name="rate_app">Rate this app</string>
<string name="translate_app">Translate KP2A</string>
<string name="AskOverwriteBinary_title">Overwrite existing binary?</string>
<string name="AskOverwriteBinary_yes">Overwrite</string>
<string name="AskOverwriteBinary_no">Rename</string>
<string name="AttachFailed">Failed to add file attachment.</string>
<string name="RecycleBin">Recycle Bin</string>
<string name="AskDeletePermanentlyEntry">Do you want to delete this entry permanently? Press No to recycle.</string>
<string name="AskDeletePermanentlyGroup">Do you want to delete this group permanently? Press No to recycle.</string>
<string name="AskDeletePermanently_title">Delete permanently?</string>
<string name="AskReloadFile_title">Reload file?</string>
<string name="AskReloadFile">The file which is currently open was changed by another program. Do you want to reload it?</string>
<string name="AskDiscardChanges">Do you really want to discard the changes made? (The Save button is at the top of the form.)</string>
<string name="AskDiscardChanges_title">Discard changes?</string>
<string name="suggest_improvements">Suggest or vote for improvements</string>
<string name="rate_app">Rate this app</string>
<string name="translate_app">Translate KP2A</string>
<string name="AddingEntry">Adding entry…</string>
<string name="AddingGroup">Adding group…</string>
<string name="DeletingEntry">Deleting entry…</string>
@ -310,7 +296,6 @@
<string name="SynchronizingDatabase">Merging changes…</string>
<string name="YesSynchronize">Yes, merge</string>
<string name="NoOverwrite">No, overwrite</string>
<string name="SynchronizingCachedDatabase">Synchronizing cached database…</string>
<string name="DownloadingRemoteFile">Downloading remote file…</string>
<string name="UploadingFile">Uploading file…</string>
@ -318,7 +303,6 @@
<string name="FilesInSync">Files are in sync.</string>
<string name="SynchronizedDatabaseSuccessfully">Database synchronized successfully!</string>
<string name="CheckingDatabaseForChanges">Checking database for changes…</string>
<string name="CouldNotSaveToRemote">Could not save to remote: %1$s. Save again or use the Synchronize menu when remote connection is available again.</string>
<string name="CouldNotLoadFromRemote">Could not open from remote: %1$s. Loaded file from local cache. You can still make changes in the database and synchronize them later.</string>
<string name="UpdatedRemoteFileOnLoad">Updated remote file.</string>
@ -326,35 +310,24 @@
<string name="LoadedFromRemoteInSync">Remote file and cache are synchronized.</string>
<string name="UpdatedCachedFileOnLoad">Updated local cache copy of %1$s.</string>
<string name="RemoteDatabaseUnchanged">No changes detected.</string>
<string name="ResolvedCacheConflictByUsingRemoteOtpAux">Updated cached OTP auxiliary file: Remote counter was higher.</string>
<string name="ResolvedCacheConflictByUsingLocalOtpAux">Updated remote OTP auxiliary file: Local counter was higher.</string>
<string name="SynchronizingOtpAuxFile">Synchronizing OTP auxiliary file…</string>
<string name="database_file">database file</string>
<string name="otp_aux_file">OTP auxiliary file</string>
<string name="ErrorOcurred">An error occured:</string>
<string name="synchronize_database_menu">Synchronize database…</string>
<string name="CannotMoveGroupHere">Cannot move group to this group.</string>
<string name="donate_question">Today, it\'s Oktoberfest! If you like Keepass2Android: wouldn\'t today be a good day to buy me a beer?</string>
<string name="donate_bday_question">May 10th? It\'s my birthday! If you like this app, why not send me some birthday greetings along with a little birthday gift? This would really make me happy! :-)</string>
<string name="donate_missedbday_question">Oh, you missed my birthday on May 10th! If you like this app, why not send me some birthday greetings and a little birthday gift? It is not yet too late to make me happy! :-)</string>
<string name="ok_donate">Tell me more!</string>
<string name="no_thanks">No, I don\'t like it that much</string>
<string name="hint_sftp_host">host (ex: 192.168.0.1)</string>
<string name="hint_sftp_port">port</string>
<string name="initial_directory">Initial directory (optional):</string>
<string name="enter_sftp_login_title">Enter SFTP login data:</string>
<string name="select_storage_type">Select the storage type:</string>
<string name="filestoragename_file">Local file</string>
<string name="filestoragename_androidget">Get from third-party app</string>
<string name="filestoragename_androidsend">Send to third-party app</string>
@ -367,25 +340,19 @@
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestoragename_sftp">SFTP (SSH File Transfer)</string>
<string name="filestorage_setup_title">File access initialization</string>
<string name="database_location">Database location</string>
<string name="help_database_location">You can store your database locally on your Android device or in the cloud (non-Offline version only). Keepass2Android makes the database available even if you are offline. As the database is securely encrypted with AES 256 bit encryption, nobody will be able to access your passwords except you. We recommend to select Dropbox: It\'s accessible on all your devices and even provides backups of previous file versions.</string>
<string name="hint_database_location">Select where you want to store the database:</string>
<string name="button_change_location">Change location</string>
<string name="master_password">Master password</string>
<string name="help_master_password">Your database is encrypted with the password you enter here. Choose a strong password in order to keep the database safe! Tip: Make up a sentence or two and use the first letters of the words as password. Include punctuation marks.</string>
<string name="hint_master_password">Select a master password to protect your database:</string>
<string name="key_file">Key file</string>
<string name="help_key_file">A key file is basically a password stored in a file. Key files are typically stronger than master passwords, because the key can be a lot more complicated; however it\'s also harder to keep them secret. If you store your database in the cloud, don\'t store the key file there as well! This would make it completely useless! Important: Do not change the contents of the key file after creating the database!</string>
<string name="hint_key_file">Choose if you want to use a key file in addition to your master password:</string>
<string name="use_key_file">Use key file</string>
<string name="error_adding_keyfile">Error while adding the keyfile!</string>
<string name="init_otp">Load OTP 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>
@ -400,12 +367,9 @@
<string name="OtpKeyError">Failed to create OTP key! Make sure you have entered the correct OTPs.</string>
<string name="ErrorUpdatingOtpAuxFile">Error updating OTP auxiliary file!</string>
<string name="SavingOtpAuxFile">Saving auxiliary OTP file…</string>
<string name="loading">Loading…</string>
<string name="enable_plugin_title">Enable plug-in?</string>
<string name="enable_plugin_question">Keepass2Android detected a plug-in with name: %1$s from package name: %2$s. Do you want to enable this plug-in? It will have access to the data stored in your Keepass databases.</string>
<string name="plugins">Plug-ins</string>
<string name="plugin_packagename">Package name:</string>
<string name="plugin_description">Description (not verified):</string>
@ -413,22 +377,16 @@
<string name="plugin_enabled">enabled</string>
<string name="plugin_disabled">disabled</string>
<string name="plugins_text">Click plug-in to enable/disable</string>
<string name="get_regular_version">Get more storage types</string>
<string name="CertificateWarning">Warning: Server certificate validation failed: %1$s. Install appropriate root certificate on your device or see settings!</string>
<string name="CertificateFailure">Error: Server certificate validation failed! Install appropriate root certificate on your device or see settings!</string>
<string name="export_fileformats_title">Select file format</string>
<string name="ChangeLog_title">Change log</string>
<string name="ChangeLog_0_9_3_r5">
<b>Version 0.9.3 r5</b>\n
* Incorporated fixes from Xamarin: Keepass2Android now compatible with ART on Android 4.4.2. Finally!\n
* Bug fixes: bugs in synchronization (refresh display, correct check for changes on http), bugs on Android 2.x devices, bugs in Google Drive and OneDrive storage implementations, clear clipboard on close database, bug opening attachments, display problems with keyboard\n
</string>
<string name="ChangeLog_0_9_3">
<b>Version 0.9.3</b>\n
* New keyboard with many improvements. See settings to customize.\n
@ -437,7 +395,6 @@
* Added workaround for bug in ART (Android 4.4.2)\n
* Bug fixes\n
</string>
<string name="ChangeLog_0_9_2">
<b>Version 0.9.2</b>\n
* Added OTP support (compatible with OtpKeyProv plugin)\n
@ -448,16 +405,13 @@
* Improved SSL certificate validation\n
* Bug fixes\n
</string>
<string name="ChangeLog_0_9_1">
<b>Version 0.9.1</b>\n
* Integrated SkyDrive support (Keepass2Android regular edition only)\n
* Fixed problems with Google Drive integration\n
* Added NTLM support
</string>
<string name="ChangeLog_0_9">
<string name="ChangeLog_0_9">
<b>Version 0.9</b>\n
* Integrated Dropbox and Google Drive support (read/write databases; Keepass2Android regular edition only)\n
* Integrated custom file browser (based on android-filechooser by HBA)\n
@ -465,8 +419,6 @@
* Included custom font DejaVu Sans Mono for displaying passwords\n
* Bug fixes
</string>
<string name="ChangeLog_0_8_6">
<b>Version 0.8.6</b>\n
* Support for Twofish cipher\n
@ -475,7 +427,6 @@
* QuickUnlock icon can be made transparent (see settings)\n
* Bug fixes
</string>
<string name="ChangeLog_0_8_5">
<b>Version 0.8.5</b>\n
* Remote files are stored in the local application cache to allow offline usage (including editing and later synchronization). See settings. \n
@ -485,7 +436,7 @@
* Entries can be added to root group\n
* Bug fixes (resolving reference fields, problems with keyboard on Italian an Chinese devices)
</string>
<string name="ChangeLog_0_8_4">
<string name="ChangeLog_0_8_4">
<b>Version 0.8.4</b>\n
* External database changes are detected and merged when saving\n
* Improved loading performance\n
@ -496,7 +447,8 @@
Thanks to Alex Vallat for his code contributions!\n
Thanks to Niki Hüttner (www.close-cut.de) for the new logo!\n
</string>
<string name="ChangeLog_0_8_3"><b>Version 0.8.3</b>\n
<string name="ChangeLog_0_8_3">
<b>Version 0.8.3</b>\n
* Username/TAN index displayed in entry list (see settings)\n
* Entries can be created if search from browser doesn\'t return results\n
* KP2A keyboard provides possibility to search for credentials for current app\n
@ -505,27 +457,32 @@
* Placeholders in entry fields are replaced before copying (most placeholders supported)\n
* minor bug fixes
</string>
<string name="ChangeLog_0_8_2"><b>Version 0.8.2</b>\n
<string name="ChangeLog_0_8_2">
<b>Version 0.8.2</b>\n
* Support for Digest Authentication in WebDAV\n
* Bugfixes (OI File manager, Open URL)
</string>
<string name="ChangeLog_0_8_1"><b>Version 0.8.1</b>\n
<string name="ChangeLog_0_8_1">
<b>Version 0.8.1</b>\n
* KP2A Offline and "Online" can be installed both again\n
* Added new translations (thanks to all contributors!)
</string>
<string name="ChangeLog_0_8"><b>Version 0.8</b>\n
<string name="ChangeLog_0_8">
<b>Version 0.8</b>\n
* Improved user interface especially for Android 4.x devices\n
* Allow using deliberate file managers for selecting existing files\n
* Added safer way for opening attachments (through cache directory)\n
* fixed bugs in Edit activity\n
* probably introduced new bugs :-)
</string>
<string name="ChangeLog_keptDonate">Extended possibility to donate a beer or something else</string>
<string name="ChangeLog_0_7"><b>Version 0.7</b>\n
<string name="ChangeLog_keptDonate">Extended possibility to donate a beer or something else</string>
<string name="ChangeLog_0_7">
<b>Version 0.7</b>\n
* Increased loading speed: key transformations now 10x faster!\n
* Added Keepass2Android soft-keyboard: Switch to this keyboard for entering credentials. Shields you from clipboard-based password sniffers (disable old clipboard notifications in the options)\n
* Added option to donate a beer or something else (see menu)</string>
<string name="ChangeLog"><b>Version 0.6.2</b>\n
<string name="ChangeLog">
<b>Version 0.6.2</b>\n
* Google Drive/Dropbox/... integration: Use the official Google Drive or Dropbox App and open any .kdbx-file. This will now bring up KP2A.\n
* Improved Search Dialog \n
* Improved search results for Share URL with subdomains\n
@ -539,39 +496,36 @@
<b>Version 0.6</b>\n
Initial public release
</string>
<string-array name="clipboard_timeout_options">
<item>30 seconds</item>
<item>1 minute</item>
<item>5 minutes</item>
<item>10 minutes</item>
<item>15 minutes</item>
<item>30 minutes</item>
<item>1 hour</item>
<item>Never</item>
</string-array>
<string-array name="clipboard_timeout_options">
<item>30 seconds</item>
<item>1 minute</item>
<item>5 minutes</item>
<item>10 minutes</item>
<item>15 minutes</item>
<item>30 minutes</item>
<item>1 hour</item>
<item>Never</item>
</string-array>
<string-array name="export_fileformat_options">
<item>Keepass 2 database (.kdbx)</item>
<item>Keepass 2 XML (unencrypted) (.xml)</item>
<item>Keepass CSV (unencrypted) (.csv)</item>
</string-array>
<string-array name="list_size_options">
<item>Small</item>
<item>Medium</item>
<item>Large</item>
</string-array>
<string-array name="list_size_options">
<item>Small</item>
<item>Medium</item>
<item>Large</item>
</string-array>
<string-array name="design_options">
<item>Holo Light</item>
<item>Holo Dark</item>
</string-array>
<string name="design_title">Design</string>
<string-array name="cred_remember_modes">
<item>Do not remember username and password</item>
<item>Remember username only</item>
<item>Remember username and password</item>
</string-array>
<item>Do not remember username and password</item>
<item>Remember username only</item>
<item>Remember username and password</item>
</string-array>
<string-array name="password_modes">
<item>Password only</item>
<item>Password + Key file</item>
@ -583,5 +537,5 @@ Initial public release
<item>Warn when validation fails</item>
<item>Do not accept invalid certificates</item>
</string-array>
</resources>
<string name="button_ok">Button</string>
</resources>

View File

@ -31,6 +31,15 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseNoNet|AnyCPU'">
<OutputPath>bin\ReleaseNoNet\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Mono.Android" />
<Reference Include="System" />

View File

@ -28,7 +28,3 @@ using Android.App;
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
// Add some common permissions, these can be removed if not needed
[assembly: UsesPermission(Android.Manifest.Permission.Internet)]
[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]

View File

@ -590,9 +590,14 @@ public class GoogleDriveFileStorage extends JavaFileStorageBase {
credential.setSelectedAccountName(accountName);
return new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential)
.setApplicationName("Keepass2Android")
.setApplicationName(getApplicationName())
.build();
}
protected String getApplicationName()
{
return "Keepass2Android";
}
private Drive getDriveService(String accountName)
{

View File

@ -6,7 +6,7 @@
<string name="open_entry_for_app">Bejegyzés keresése: \"%1$s\"</string>
<string name="kp2a_user">Felhasználó</string>
<string name="kp2a_password">Jelszó</string>
<string name="kp2a_prefs">Hitelesítőadatok bevitele</string>
<string name="kp2a_prefs">Hitelesítő adatok bevitele</string>
<string name="kp2a_auto_fill">Automatikus kitöltés engedélyezve</string>
<string name="kp2a_auto_fill_summary">Egy üres mezőbe lépve annak automatikus kitöltése, ha a billentyűzet számára van elérhető Keepass2Android bejegyzés és az tartalmaz a mezőhöz megadott útmutatásnak megfelelő értéket.</string>
<string name="kp2a_remember_auto_fill">A mezők útmutatásának tárolása</string>

View File

@ -7,14 +7,14 @@
<string name="kp2a_user">Používateľ</string>
<string name="kp2a_password">Heslo</string>
<string name="kp2a_prefs">Nastavenia zadávania údajov</string>
<string name="kp2a_auto_fill">Automatické dopĺňanie zapnuté</string>
<string name="kp2a_auto_fill">Autom. dopĺňanie zap.</string>
<string name="kp2a_auto_fill_summary">Pri vstupe do prázdneho políčka automaticky doplniť text, ak je dostupný záznam Keepass2Android pre klávesnicu a aj pole ktoré je v zhode s pomocným textom pre pole.</string>
<string name="kp2a_remember_auto_fill">Zapamätať si pomocné texty pre pole</string>
<string name="kp2a_remember_auto_fill">Pamätať si nápovedu poľa</string>
<string name="kp2a_remember_auto_fill_summary">Ak je textové pole vyplnené manuálnym vybraním hodnoty Keepass2Android, pamätať si hodnotu zadanú do poľa. Textové pole bude neskôr detegované podľa pomocného textu.</string>
<string name="kp2a_simple_keyboard">Jednoduchá klávesnica</string>
<string name="kp2a_simple_keyboard_summary">Ak je dostupný záznam pre klávesnicu, zobraziť klávesnicu s 1 riadkom. Ak je vypnutá, pri stlačení klávesy Keepass2Android sa zobrazí dialóg.</string>
<string name="kp2a_lock_on_sendgodone">Po dokončení uzamknúť databázu</string>
<string name="kp2a_simple_keyboard_summary">Ak je dostupný záznam pre klávesnicu, zobraziť klávesnicu s 1 riadkom. Ak je vypnutá, pri stlačení tlač. Keepass2Android sa zobrazí dialóg.</string>
<string name="kp2a_lock_on_sendgodone">Po skončení uzamknúť datab.</string>
<string name="kp2a_lock_on_sendgodone_summary">Automaticky uzamknúť databázu po stlačení tlač. Hotovo/Odoslať/Prejsť na 1-riadkovej klávesnici.</string>
<string name="kp2a_switch_on_sendgodone">Po dokončení prepnúť klávesnicu</string>
<string name="kp2a_switch_on_sendgodone">Po skončení prepnúť kláv.</string>
<string name="kp2a_switch_on_sendgodone_summary">Prepnúť klávesnicu naspäť po stlačení tlačidla Hotovo/Odoslať/Prejsť na 1-riadkovej klávesnici.</string>
</resources>

View File

@ -12,9 +12,9 @@
<string name="kp2a_remember_auto_fill">记忆字段提示文本</string>
<string name="kp2a_remember_auto_fill_summary">如果通过手动选择 Keepass2Android 填充字段,请记住哪个字段在对应字段中输入。该字段是后来由其提示文本重新检测到。</string>
<string name="kp2a_simple_keyboard">简单键盘</string>
<string name="kp2a_simple_keyboard_summary">当一个条目是可用时显示的 1 行键盘。如果禁用,当按 Keepass2Android 键时则是显示一个对话框。</string>
<string name="kp2a_simple_keyboard_summary">当一个条目是可用时显示单行键盘。如果禁用,当按 Keepass2Android 键时则是显示一个对话框。</string>
<string name="kp2a_lock_on_sendgodone">完成时锁定数据库</string>
<string name="kp2a_lock_on_sendgodone_summary">当点击 1 行键盘上的完成或发送键时,自动锁定数据库。</string>
<string name="kp2a_lock_on_sendgodone_summary">当点击行键盘上的完成或发送键时,自动锁定数据库。</string>
<string name="kp2a_switch_on_sendgodone">完成后切换键盘</string>
<string name="kp2a_switch_on_sendgodone_summary">当点击 1 行键盘上的完成或发送键时,自动切换键盘。</string>
<string name="kp2a_switch_on_sendgodone_summary">当点击行键盘上的完成或发送键时,自动切换键盘。</string>
</resources>

View File

@ -44,7 +44,7 @@ public class AccessManager
public static ArrayList<String> stringToStringArray(String s) {
ArrayList<String> strings = new ArrayList<String>();
if ((s != null) && (s != "")) {
if (TextUtils.isEmpty(s) == false) {
try {
JSONArray a = new JSONArray(s);
for (int i = 0; i < a.length(); i++) {
@ -116,9 +116,10 @@ public class AccessManager
Log.d(_tag, "hostPackage is empty!");
return null;
}
Log.d(_tag, "trying to find prefs for "+hostPackage);
SharedPreferences prefs = getPrefsForHost(ctx, hostPackage);
String scopesString = prefs.getString(PREF_KEY_SCOPE, "");
Log.d(_tag, "scopes: "+ scopesString);
Log.d(_tag, "available scopes: "+ scopesString);
ArrayList<String> currentScope = stringToStringArray(scopesString);
if (isSubset(scopes, currentScope))
{
@ -147,6 +148,7 @@ public class AccessManager
String accessToken) {
SharedPreferences prefs = getPrefsForHost(ctx, hostPackage);
Log.d(_tag, "removing AccessToken.");
if (prefs.getString(PREF_KEY_TOKEN, "").equals(accessToken))
{
Editor edit = prefs.edit();

View File

@ -6,6 +6,7 @@ import android.R.anim;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
/**
* Broadcast flow between Host and Plugin
@ -30,10 +31,13 @@ import android.content.Intent;
*
*/
public abstract class PluginAccessBroadcastReceiver extends BroadcastReceiver {
private static final String _tag = "Kp2aPluginSDK";
@Override
public void onReceive(Context ctx, Intent intent) {
String action = intent.getAction();
android.util.Log.d("KP2A.pluginsdk", "received broadcast with action="+action);
android.util.Log.d(_tag, "received broadcast with action="+action);
if (action == null)
return;
if (action.equals(Strings.ACTION_TRIGGER_REQUEST_ACCESS))
@ -84,7 +88,7 @@ public abstract class PluginAccessBroadcastReceiver extends BroadcastReceiver {
}
rpi.putStringArrayListExtra(Strings.EXTRA_SCOPES, getScopes());
Log.d(_tag, "requesting access for "+getScopes().size()+" tokens.");
ctx.sendBroadcast(rpi);
}

View File

@ -22,7 +22,7 @@ namespace keepass2android
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.SetTitle(ctx.GetString(Resource.String.ChangeLog_title));
String[] changeLog = {
ctx.GetString(Resource.String.PreviewWarning),
//ctx.GetString(Resource.String.PreviewWarning),
ctx.GetString(Resource.String.ChangeLog_0_9_4),
ctx.GetString(Resource.String.ChangeLog_0_9_3_r5),
ctx.GetString(Resource.String.ChangeLog_0_9_3),

View File

@ -31,11 +31,13 @@ namespace keepass2android
{
_valueView.Visibility = ViewStates.Gone;
_keyView.Visibility = ViewStates.Gone;
_container.Visibility = ViewStates.Gone;
}
else
{
_valueView.Visibility = ViewStates.Visible;
_keyView.Visibility = ViewStates.Visible;
_container.Visibility = ViewStates.Visible;
_valueView.Text = value;
}
}

View File

@ -27,6 +27,7 @@ using System.Xml;
using KeePassLib.Keys;
using KeePassLib.Utility;
using KeePassLib.Cryptography;
using KeePassLib.Cryptography.Cipher;
using KeePassLib.Serialization;
using keepass2android;
@ -83,33 +84,26 @@ namespace KeeChallenge
byte[] key = sha.ComputeHash(resp); // get a 256 bit key from the 160 bit hmac response
byte[] secretHash = sha.ComputeHash(secret);
AesManaged aes = new AesManaged();
aes.KeySize = key.Length * sizeof(byte) * 8; //pedantic, but foolproof
aes.Key = key;
aes.GenerateIV();
aes.Padding = PaddingMode.PKCS7;
byte[] iv = aes.IV;
StandardAesEngine aes = new StandardAesEngine();
const uint aesIVLenBytes = 16 ;
byte[] IV = CryptoRandom.Instance.GetRandomBytes(aesIVLenBytes);
byte[] encrypted;
ICryptoTransform enc = aes.CreateEncryptor();
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, enc, CryptoStreamMode.Write))
using (CryptoStream csEncrypt = (CryptoStream)aes.EncryptStream(msEncrypt, key, IV))
{
csEncrypt.Write(secret, 0, secret.Length);
csEncrypt.FlushFinalBlock();
encrypted = msEncrypt.ToArray();
csEncrypt.Close();
csEncrypt.Clear();
}
encrypted = msEncrypt.ToArray();
msEncrypt.Close();
}
ChallengeInfo inf = new ChallengeInfo (encrypted, aes.IV, challenge, secretHash);
ChallengeInfo inf = new ChallengeInfo (encrypted, IV, challenge, secretHash);
sha.Clear();
aes.Clear();
return inf;
}
@ -125,21 +119,14 @@ namespace KeeChallenge
SHA256 sha = SHA256Managed.Create();
byte[] key = sha.ComputeHash(yubiResp); // get a 256 bit key from the 160 bit hmac response
AesManaged aes = new AesManaged();
aes.KeySize = key.Length * sizeof(byte) * 8; //pedantic, but foolproof
aes.Key = key;
aes.IV = inf.IV;
aes.Padding = PaddingMode.PKCS7;
StandardAesEngine aes = new StandardAesEngine();
ICryptoTransform dec = aes.CreateDecryptor();
using (MemoryStream msDecrypt = new MemoryStream(inf.EncryptedSecret))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, dec, CryptoStreamMode.Read))
using (CryptoStream csDecrypt = (CryptoStream)aes.DecryptStream(msDecrypt, key, inf.IV))
{
csDecrypt.Read(secret, 0, secret.Length);
csDecrypt.Close();
csDecrypt.Clear();
}
msDecrypt.Close();
}
@ -157,7 +144,6 @@ namespace KeeChallenge
//return the secret
sha.Clear();
aes.Clear();
return true;
}
@ -168,7 +154,7 @@ namespace KeeChallenge
/// </summary>
/// <param name="inf">A pre-populated object containing minimally the IV, EncryptedSecret and Verification fields.
/// This should be populated from the database.xml auxilliary file</param>
/// <param name="resp">The Yubikey's response to the issued challenge</param>
/// <param name="resp" >The Yubikey's response to the issued challenge</param>
/// <returns>The common secret, used as a composite key to encrypt a Keepass database</returns>
public static byte[] GetSecret(ChallengeInfo inf, byte[] resp)
{

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="44" android:versionName="0.9.4-preview1c" package="keepass2android.keepass2android" android:installLocation="auto">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="45" android:versionName="0.9.4" package="keepass2android.keepass2android" android:installLocation="auto">
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" />
<permission android:description="@string/permission_desc" android:icon="@drawable/ic_launcher" android:label="KP2A internal file browsing" android:name="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing" android:protectionLevel="signature" />
<application android:label="keepass2android" android:icon="@drawable/ic_launcher">

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="42"
android:versionName="0.9.3-r5"
android:versionCode="47"
android:versionName="0.9.4"
package="keepass2android.keepass2android_nonet"
android:installLocation="auto">
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="14" />
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" />
<application android:label="keepass2android" android:icon="@drawable/ic_launcher_offline">
<provider android:name="group.pals.android.lib.ui.filechooser.providers.localfile.LocalFileProvider" android:authorities="keepass2android.keepass2android_nonet.android-filechooser.localfile" android:exported="false" />
<provider android:name="group.pals.android.lib.ui.filechooser.providers.history.HistoryProvider" android:authorities="keepass2android.keepass2android_nonet.android-filechooser.history" android:exported="false" />

View File

@ -4343,11 +4343,11 @@ namespace keepass2android
// aapt resource value: 0x7f090159
public const int brackets = 2131296601;
// aapt resource value: 0x7f0902e4
public const int browser_intall_text = 2131296996;
// aapt resource value: 0x7f0902e5
public const int building_search_idx = 2131296997;
public const int browser_intall_text = 2131296997;
// aapt resource value: 0x7f0902e6
public const int building_search_idx = 2131296998;
// aapt resource value: 0x7f090297
public const int button_change_location = 2131296919;
@ -4478,14 +4478,14 @@ namespace keepass2android
// aapt resource value: 0x7f090101
public const int db_key = 2131296513;
// aapt resource value: 0x7f0902e6
public const int decrypting_db = 2131296998;
// aapt resource value: 0x7f0902e7
public const int decrypting_entry = 2131296999;
public const int decrypting_db = 2131296999;
// aapt resource value: 0x7f0902e8
public const int default_checkbox = 2131297000;
public const int decrypting_entry = 2131297000;
// aapt resource value: 0x7f0902e9
public const int default_checkbox = 2131297001;
// aapt resource value: 0x7f0900f3
public const int default_file_path = 2131296499;
@ -4571,8 +4571,8 @@ namespace keepass2android
// aapt resource value: 0x7f09016a
public const int entry_accessed = 2131296618;
// aapt resource value: 0x7f0902e9
public const int entry_and_or = 2131297001;
// aapt resource value: 0x7f0902ea
public const int entry_and_or = 2131297002;
// aapt resource value: 0x7f09017b
public const int entry_binaries = 2131296635;
@ -4628,8 +4628,8 @@ namespace keepass2android
// aapt resource value: 0x7f09029f
public const int error_adding_keyfile = 2131296927;
// aapt resource value: 0x7f0902ea
public const int error_arc4 = 2131297002;
// aapt resource value: 0x7f0902eb
public const int error_arc4 = 2131297003;
// aapt resource value: 0x7f09017c
public const int error_can_not_handle_uri = 2131296636;
@ -4643,8 +4643,11 @@ namespace keepass2android
// aapt resource value: 0x7f09017f
public const int error_database_exists = 2131296639;
// aapt resource value: 0x7f0902e4
public const int error_database_settings = 2131296996;
// aapt resource value: 0x7f090180
public const int error_database_settings = 2131296640;
public const int error_database_settinoverrgs = 2131296640;
// aapt resource value: 0x7f090181
public const int error_failed_to_launch_link = 2131296641;
@ -4670,8 +4673,8 @@ namespace keepass2android
// aapt resource value: 0x7f090187
public const int error_nopass = 2131296647;
// aapt resource value: 0x7f0902eb
public const int error_out_of_memory = 2131297003;
// aapt resource value: 0x7f0902ec
public const int error_out_of_memory = 2131297004;
// aapt resource value: 0x7f090188
public const int error_pass_gen_type = 2131296648;
@ -4682,8 +4685,8 @@ namespace keepass2android
// aapt resource value: 0x7f09018a
public const int error_rounds_not_number = 2131296650;
// aapt resource value: 0x7f0902ec
public const int error_rounds_too_large = 2131297004;
// aapt resource value: 0x7f0902ed
public const int error_rounds_too_large = 2131297005;
// aapt resource value: 0x7f090221
public const int error_string_key = 2131296801;
@ -4871,11 +4874,11 @@ namespace keepass2android
// aapt resource value: 0x7f0901e8
public const int insert_element_here = 2131296744;
// aapt resource value: 0x7f0902ed
public const int install_from_market = 2131297005;
// aapt resource value: 0x7f0902ee
public const int install_from_website = 2131297006;
public const int install_from_market = 2131297006;
// aapt resource value: 0x7f0902ef
public const int install_from_website = 2131297007;
// aapt resource value: 0x7f09019f
public const int invalid_algorithm = 2131296671;
@ -5087,8 +5090,8 @@ namespace keepass2android
// aapt resource value: 0x7f0901b8
public const int menu_hide_password = 2131296696;
// aapt resource value: 0x7f0902ef
public const int menu_homepage = 2131297007;
// aapt resource value: 0x7f0902f0
public const int menu_homepage = 2131297008;
// aapt resource value: 0x7f0901b9
public const int menu_lock = 2131296697;

View File

@ -5,6 +5,7 @@
<string name="about_homepage">WEBサイト</string>
<string name="AboutText">\"Keepass2Android\"はパスワードマネージャソフト\"KeePass\"をAndroid上で利用する為のアプリです。</string>
<string name="accept">決定</string>
<string name="deny">拒否</string>
<string name="add_entry">エントリーを追加</string>
<string name="add_url_entry">URL のエントリを作成します。</string>
<string name="add_group">グループを追加</string>
@ -21,11 +22,14 @@
<string name="kill_app_label">アプリのプロセスを終了</string>
<string name="application">アプリケーション</string>
<string name="application_settings">アプリケーション設定</string>
<string name="ShowGroupnameInSearchResult_title">検索結果にグループ名を表示する</string>
<string name="security_prefs">セキュリティ</string>
<string name="display_prefs">表示</string>
<string name="password_access_prefs">パスワードエントリーへのアクセス</string>
<string name="QuickUnlock_prefs">クイック解除</string>
<string name="FileHandling_prefs">ファイル操作</string>
<string name="keyboard_prefs">キーボード</string>
<string name="export_prefs">データベースのエクスポート</string>
<string name="brackets">カッコ</string>
<string name="cancel">キャンセル</string>
<string name="ClearClipboard">クリップボードを消去しました。</string>
@ -43,7 +47,7 @@
<string name="digits">数字</string>
<string name="disclaimer_formal">Keepass2Android によって作られたフリーソフトウェアであり、無保証です。GPLバージョン2以上の条件下でこれを再頒布することができます。</string>
<string name="ellipsis">\u2026</string>
<string name="enter_filename">データベースファイル</string>
<string name="enter_filename">データベースファイル名の入力</string>
<string name="entry_accessed">最終アクセス日</string>
<string name="entry_cancel">キャンセル</string>
<string name="entry_comment">備考</string>
@ -52,6 +56,7 @@
<string name="entry_confpassword">パスワードの確認</string>
<string name="entry_created">作成日</string>
<string name="entry_expires">有効期限</string>
<string name="entry_group_name">グループ名</string>
<string name="entry_keyfile">キーファイル(オプション)</string>
<string name="entry_modified">更新日</string>
<string name="entry_password">パスワード</string>
@ -108,7 +113,7 @@
<string name="MaskedPassword">*****</string>
<string name="maskpass_title">パスワードを隠す</string>
<string name="maskpass_summary">パスワード欄をアスタリスクで表示します</string>
<string name="menu_about">について</string>
<string name="menu_about">Keepass2Androidについて</string>
<string name="menu_change_key">マスターキーを変更</string>
<string name="menu_copy_pass">パスワードをコピー</string>
<string name="menu_copy_user">ユーザー名をコピー</string>
@ -117,6 +122,7 @@
<string name="menu_db_settings">データベース設定</string>
<string name="menu_delete">削除</string>
<string name="menu_move">別のグループへ移動</string>
<string name="menu_move_light">移動</string>
<string name="menu_donate">ビールの寄付...</string>
<string name="menu_edit">編集</string>
<string name="menu_hide_password">パスワードを隠す</string>
@ -139,6 +145,7 @@
<string name="omitbackup_summary">\"バックアップ\"と\"ごみ箱\"を検索対象から除外します</string>
<string name="pass_filename">KeePassデータベースファイル</string>
<string name="password_title">データベースのパスワード設定</string>
<string name="master_key_type">マスターキータイプの選択</string>
<string name="progress_create">データベースファイルを作成中&#8230;</string>
<string name="create_database">データベースを作成</string>
<string name="progress_title">実行中&#8230;</string>
@ -153,6 +160,8 @@
<string name="database_name">データベース名</string>
<string name="default_username">新しいエントリのデフォルトユーザー名</string>
<string name="saving_database">データベースを保存中&#8230;</string>
<string name="exporting_database">データベースをエクスポート中&#8230;</string>
<string name="export_database_successful">データベースのエクスポートが完了しました。</string>
<string name="space">半角スペース</string>
<string name="search_label">検索</string>
<string name="show_password">パスワードを表示</string>
@ -195,10 +204,27 @@
<string name="QuickUnlock_lockButton">データベースを閉じる</string>
<string name="QuickUnlockDefaultEnabled_title">クイック解除をデフォルトで有効にする</string>
<string name="QuickUnlockIconHidden_title">クイック解除アイコンを隠す</string>
<string name="QuickUnlockIconHidden16_title">クイックアンロックアイコンを隠す</string>
<string name="QuickUnlockLength_title">クイック解除キーの長さ</string>
<string name="QuickUnlock_fail">クイック解除に失敗しました: パスワードが正しくありません!</string>
<string name="BinaryDirectory_title">添付ファイルのディレクトリ</string>
<string name="SaveAttachmentDialog_title">添付ファイルを保存</string>
<string name="SaveAttachmentDialog_save">SDカードに保存</string>
<string name="field_name">フィールド名</string>
<string name="field_value">フィールド値</string>
<string name="add_binary">ファイルを添付</string>
<string name="credentials_dialog_title">サーバーの資格情報を入力してください。</string>
<string name="LockWhenScreenOff_title">スクリーンオフ時にロックする</string>
<string name="LockWhenScreenOff_summary">スクリーンがオフに切り替わったときデータベースをロックします。</string>
<string name="NoDonateOption_title">寄付オプションを表示しない</string>
<string name="UseOfflineCache_title">データベース キャッシュ</string>
<string name="AcceptAllServerCertificates_title">SSL 証明書</string>
<string name="ClearOfflineCache_title">キャッシュをクリアしますか?</string>
<string name="CheckForFileChangesOnSave_title">変更をチェック</string>
<string name="AskOverwriteBinary_title">既存のバイナリを上書きしますか。</string>
<string name="AskOverwriteBinary_yes">上書き</string>
<string name="AskOverwriteBinary_no">名前の変更</string>
<string name="RecycleBin">ごみ箱</string>
<string name="AskReloadFile">現在開いているファイルは、別のプログラムによって変更されました。それを再読み込みしますか。</string>
<string name="AskDiscardChanges">今までの変更を破棄しますか。([保存] ボタンは、フォームの上部にあります。) </string>
<string name="AskDiscardChanges_title">変更を破棄しますか。</string>
@ -210,19 +236,86 @@
<string name="DeletingEntry">エントリの削除</string>
<string name="DeletingGroup">グループの削除</string>
<string name="SettingPassword">パスワードの設定</string>
<string name="UndoingChanges">変更を元に戻しています。</string>
<string name="TransformingKey">マスターキーを変換しています。</string>
<string name="ParsingDatabase">データベースを解析しています.</string>
<string name="CheckingTargetFileForChanges">ターゲット ファイルの変更を確認しています。</string>
<string name="TitleSyncQuestion">変更をマージしますか?</string>
<string name="SynchronizingDatabase">変更をマージしています・・・</string>
<string name="YesSynchronize">はい、マージします。</string>
<string name="NoOverwrite">いいえ、上書きします。</string>
<string name="DownloadingRemoteFile">リモート ファイルをダウンロードしています.</string>
<string name="UploadingFile">ファイルをアップロードしています.</string>
<string name="RestoringRemoteFile">リモートファイルを復元しています。</string>
<string name="CheckingDatabaseForChanges">データベースの変更を確認しています。</string>
<string name="RemoteDatabaseUnchanged">変更は検出されませんでした。</string>
<string name="database_file">データベースファイル</string>
<string name="ErrorOcurred">エラーが発生しました</string>
<string name="synchronize_database_menu">データベースの同期</string>
<string name="hint_sftp_host">ホスト(例: 192.168.0.1)</string>
<string name="hint_sftp_port">ポート</string>
<string name="initial_directory">初期ディレクトリ (省略可能):</string>
<string name="select_storage_type">ストレージタイプの選択</string>
<string name="filestoragename_file">端末内ファイル</string>
<string name="filestoragename_ftp">FTP</string>
<string name="filestoragename_http">HTTP (WebDav)</string>
<string name="filestoragename_https">HTTPS (WebDav)</string>
<string name="filestoragename_dropbox">Dropbox</string>
<string name="filestoragename_dropboxKP2A">Dropbox (KP2A フォルダー)</string>
<string name="filestoragename_gdrive">Google ドライブ</string>
<string name="filestoragename_skydrive">OneDrive</string>
<string name="filestorage_setup_title">ファイルのアクセスの初期化</string>
<string name="database_location">データベースの場所</string>
<string name="master_password">マスター パスワード</string>
<string name="hint_master_password">データベースを保護するマスター パスワードを選択します。</string>
<string name="key_file">キー ファイル</string>
<string name="use_key_file">キーファイルを使用する</string>
<string name="loading">読み込み中&#8230;</string>
<string name="plugins">プラグイン</string>
<string name="plugin_packagename">パッケージ名:</string>
<string name="plugin_enabled">有効</string>
<string name="plugin_disabled">無効</string>
<string name="plugin_web">オンラインでプラグインを見つける</string>
<string name="plugin_enabled_checkbox">有効</string>
<string name="SCOPE_CURRENT_ENTRY_title">現在のエントリーデータ</string>
<string name="export_fileformats_title">ファイル形式の選択</string>
<string-array name="clipboard_timeout_options">
<item>30秒</item>
<item>1分</item>
<item>5分</item>
<item>10 minutes</item>
<item>15 minutes</item>
<item>30 minutes</item>
<item>1 hour</item>
<item>Never</item>
<item>10分</item>
<item>15分</item>
<item>30分</item>
<item>1時間</item>
<item>無し</item>
</string-array>
<string-array name="export_fileformat_options">
<item>Keepass 2 データベース (.kdbx)</item>
<item>Keepass 2 XML (暗号化なし) (.xml)</item>
<item>Keepass CSV (暗号化なし) (.csv)</item>
</string-array>
<string-array name="list_size_options">
<item></item>
<item></item>
<item></item>
</string-array>
<string name="design_title">デザイン</string>
<string-array name="cred_remember_modes">
<item>Do not remember username and password</item>
<item>ユーザー名のみ保存</item>
<item>ユーザー名とパスワードを保存</item>
</string-array>
<string-array name="password_modes">
<item>パスワードのみ</item>
<item>パスワード + キー ファイル</item>
<item>パスワード + OTP</item>
<item>Password + OTP secret (recovery mode)</item>
<item>パスワード + チャレンジ レスポンス</item>
<item>Password + Challenge-Response secret (recovery mode)</item>
</string-array>
<string-array name="AcceptAllServerCertificates_options">
<item>証明書検証エラーを無視する</item>
<item>Warn when validation fails</item>
<item>無効な証明書を受け入れない</item>
</string-array>
</resources>

View File

@ -255,9 +255,9 @@
<string name="LockWhenNavigateBack_title">Uzamknúť pri opustení aplikácie</string>
<string name="LockWhenNavigateBack_summary">Uzamknúť databázu pri opustení aplikácie stlačením tlačidla Späť.</string>
<string name="NoDonateOption_title">Skryť možnosti prispenia</string>
<string name="NoDonateOption_summary">Toto nastavenie je určené pre sponzorov. Je dostupné po použiť Keepass2Android, len na chvíľu.</string>
<string name="NoDonateOption_summary">Toto nastavenie je určené pre sponzorov. Je dostupné po použi Keepass2Android, len na chvíľu.</string>
<string name="NoDonateOption_question">Bez príspevkov by táto aplikácia neexistovala a nebolo by možné ju neustále vylepšovať! Ak ste ešte neprispeli na jej vývoj, prosím zvážte možnosť prispenia teraz.</string>
<string name="UseOfflineCache_title">Uloženie databázy do vyr. pamäte</string>
<string name="UseOfflineCache_title">Ukladať do vyr. pamäte</string>
<string name="UseOfflineCache_summary">Zachovať kópiu súborov vzdialenej databázy v priečinku vyr. pamäte programu. Takto môžete používať vzdialené databázy aj v režime offline.</string>
<string name="AcceptAllServerCertificates_title">Certifikáty SSL</string>
<string name="AcceptAllServerCertificates_summary">Definujte postup pri zlyhaní overenia certifikátu. Poznámka: pri zlyhaní overenia môžete na zariadenie nainštalovať certifikáty!</string>
@ -272,7 +272,7 @@
<string name="OpenKp2aKeyboardAutomatically_title">Prepnúť klávesnicu</string>
<string name="OpenKp2aKeyboardAutomatically_summary">Otvoriť dialóg výberu klávesnice, ak je po vyhľadaní z prehliadača alebo klávesnice dostupný záznam zadávaný cez klávesnicu KP2A.</string>
<string name="kp2a_switch_rooted">Prepínať, ak je dostupný root</string>
<string name="kp2a_switch_rooted_summary">Na zariadeniach s najvyššími opráveniami je možné automaticky prepínať na klávesnicu Keepass2Android a naspäť na predchádzajúcu klávesnicu, bez zobrazenia metódy vstupu. Prepnutie je možné po vyhľadaní záznamu alebo kliknutí na notifikáciu klávesnice KP2A. Táto funkcia vyžaduje inštaláciu Secure Settings app. Viac informácií získate v dokumentácii KP2A!</string>
<string name="kp2a_switch_rooted_summary">Na zariadeniach s najvyššími oprávneniami je možné automaticky prepínať na klávesnicu Keepass2Android a naspäť na predchádzajúcu klávesnicu, bez zobrazenia metódy vstupu. Prepnutie je možné po vyhľadaní záznamu alebo kliknutí na notifikáciu klávesnice KP2A. Táto funkcia vyžaduje inštaláciu Secure Settings app. Viac informácií získate v dokumentácii KP2A!</string>
<string name="ShowUnlockedNotification_title">Notifikačná ikona počas odomknutia</string>
<string name="ShowUnlockedNotification_summary">Zobraziť prichádzajúcu notifikáciu aj pri odomknutej databáze.</string>
<string name="PreloadDatabaseEnabled_title">Vopred načítať databázu</string>
@ -384,7 +384,7 @@
<string name="CouldntLoadChalAuxFile">Nemožno načítať doplnkový súbor pre výzvu!</string>
<string name="CouldntLoadChalAuxFile_Hint">Prosím použite prídavný modul KeeChallenge v programe KeePass 2.x (PC) pre nakonfigurovanie databázy na použitie s odpoveďou na výzvu!</string>
<string name="ErrorUpdatingChalAuxFile">Chyba pri aktualizovaní doplnkového súboru OTP!</string>
<string name="TrayTotp_SeedField_title">Názov prvotného (seed) poľa TOTP</string>
<string name="TrayTotp_SeedField_title">Názov seed poľa TOTP</string>
<string name="TrayTotp_SeedField_summary">Ak používate prídavný modul pre Keepass 2 s názvom \"TrayTotp\", nie s predvolenými nastaveniami, zadajte názov pre prvotné (seed) pole, podľa nastavení v PC.</string>
<string name="TrayTotp_SettingsField_title">Názov poľa pre nastavenia TOTP</string>
<string name="TrayTotp_SettingsField_summary">Sem zadajte názov poľa s nastaveniami pre TrayTotp.</string>

View File

@ -80,7 +80,7 @@
<string name="error_could_not_create_group">Error creating group.</string>
<string name="error_could_not_create_parent">Could not create parent directory.</string>
<string name="error_database_exists">This file already exists.</string>
<string name="error_database_settings">Failed to determine database settings.</string>
<string name="error_database_settinoverrgs">Failed to determine database settings.</string>
<string name="error_failed_to_launch_link">Failed to launch link.</string>
<string name="error_filename_required">A filename is required.</string>
<string name="error_file_not_create">Could not create file</string>

View File

@ -385,7 +385,9 @@
<AndroidResource Include="Resources\menu\group.xml" />
<AndroidResource Include="Resources\menu\password.xml" />
<AndroidResource Include="Resources\values\colors.xml" />
<AndroidResource Include="Resources\values\config.xml" />
<AndroidResource Include="Resources\values\config.xml">
<SubType>Designer</SubType>
</AndroidResource>
<AndroidResource Include="Resources\values\styles.xml">
<SubType>Designer</SubType>
</AndroidResource>
@ -906,7 +908,9 @@
<AndroidResource Include="Resources\drawable\ic_launcher_gray_bday.png" />
</ItemGroup>
<ItemGroup>
<TransformFile Include="Properties\AndroidManifest.xml" />
<TransformFile Include="Properties\AndroidManifest.xml">
<SubType>Designer</SubType>
</TransformFile>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\collections_new_label_holodark.png" />