1
0
mirror of https://github.com/bitwarden/mobile.git synced 2024-11-21 11:25:56 +01:00

Removed BouncyCastle in favor of PCLCrypto. Created KeyDerivationService for Android using BouncyCastle. Applied key derivation service to CryptoService. Create iOS Test project.

This commit is contained in:
Kyle Spearrin 2016-08-01 20:23:46 -04:00
parent fc07844bb6
commit 6f800896c3
28 changed files with 3842 additions and 3060 deletions

View File

@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Extension", "src\iOS.Ex
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Core", "src\iOS.Core\iOS.Core.csproj", "{B2538ADA-B605-4D6F-ACD2-62A409680F84}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Test", "test\iOS.Test\iOS.Test.csproj", "{6702027A-F726-4149-863E-7CB924674B9A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
@ -313,6 +315,38 @@ Global
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|x64.Build.0 = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|x86.ActiveCfg = Release|Any CPU
{B2538ADA-B605-4D6F-ACD2-62A409680F84}.Release|x86.Build.0 = Release|Any CPU
{6702027A-F726-4149-863E-7CB924674B9A}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
{6702027A-F726-4149-863E-7CB924674B9A}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
{6702027A-F726-4149-863E-7CB924674B9A}.Ad-Hoc|x64.ActiveCfg = Ad-Hoc|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.AppStore|ARM.ActiveCfg = AppStore|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.AppStore|iPhone.Build.0 = AppStore|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
{6702027A-F726-4149-863E-7CB924674B9A}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
{6702027A-F726-4149-863E-7CB924674B9A}.AppStore|x64.ActiveCfg = AppStore|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.AppStore|x86.ActiveCfg = AppStore|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Debug|Any CPU.ActiveCfg = Debug|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Debug|ARM.ActiveCfg = Debug|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Debug|iPhone.ActiveCfg = Debug|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Debug|iPhone.Build.0 = Debug|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{6702027A-F726-4149-863E-7CB924674B9A}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{6702027A-F726-4149-863E-7CB924674B9A}.Debug|x64.ActiveCfg = Debug|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Debug|x86.ActiveCfg = Debug|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Release|Any CPU.ActiveCfg = Release|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Release|ARM.ActiveCfg = Release|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Release|iPhone.ActiveCfg = Release|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Release|iPhone.Build.0 = Release|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{6702027A-F726-4149-863E-7CB924674B9A}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{6702027A-F726-4149-863E-7CB924674B9A}.Release|x64.ActiveCfg = Release|iPhone
{6702027A-F726-4149-863E-7CB924674B9A}.Release|x86.ActiveCfg = Release|iPhone
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -324,5 +358,6 @@ Global
{A300DCE1-8D10-4267-B96A-CB01AEB7C220} = {0D790714-ECF8-4A83-BE4A-E9C84DD1BB5D}
{32F5A2D6-F54D-4DA1-AE26-0A980D48F422} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
{B2538ADA-B605-4D6F-ACD2-62A409680F84} = {EC730FD9-F623-4B6C-B503-95CDCFBCF277}
{6702027A-F726-4149-863E-7CB924674B9A} = {0D790714-ECF8-4A83-BE4A-E9C84DD1BB5D}
EndGlobalSection
EndGlobal

View File

@ -35,7 +35,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AndroidUseSharedRuntime>True</AndroidUseSharedRuntime>
<AndroidLinkMode>None</AndroidLinkMode>
<AndroidLinkMode>Full</AndroidLinkMode>
<AndroidLinkSkip>Xamarin.GooglePlayServices.Gcm;</AndroidLinkSkip>
<EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk>
<BundleAssemblies>False</BundleAssemblies>
@ -89,6 +89,10 @@
<HintPath>..\..\packages\AndHUD.1.2.0\lib\MonoAndroid\AndHUD.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="BouncyCastle.Crypto, Version=1.8.1.0, Culture=neutral, PublicKeyToken=0e99375e54769942">
<HintPath>..\..\packages\BouncyCastle.1.8.1\lib\BouncyCastle.Crypto.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FormsViewGroup, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.2.3.0.107\lib\MonoAndroid10\FormsViewGroup.dll</HintPath>
<Private>True</Private>
@ -271,6 +275,7 @@
<Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Services\AppInfoService.cs" />
<Compile Include="Services\ClipboardService.cs" />
<Compile Include="Services\BouncyCastleKeyDerivationService.cs" />
<Compile Include="Services\KeyStoreStorageService.cs" />
<Compile Include="MainActivity.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />

View File

@ -114,6 +114,7 @@ namespace Bit.Android
.RegisterType<ISqlService, SqlService>(new ContainerControlledLifetimeManager())
.RegisterType<ISecureStorageService, KeyStoreStorageService>(new ContainerControlledLifetimeManager())
.RegisterType<ICryptoService, CryptoService>(new ContainerControlledLifetimeManager())
.RegisterType<IKeyDerivationService, BouncyCastleKeyDerivationService>(new ContainerControlledLifetimeManager())
.RegisterType<IAuthService, AuthService>(new ContainerControlledLifetimeManager())
.RegisterType<IFolderService, FolderService>(new ContainerControlledLifetimeManager())
.RegisterType<ISiteService, SiteService>(new ContainerControlledLifetimeManager())

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,20 @@
using System;
using Bit.App.Abstractions;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
namespace Bit.Android.Services
{
public class BouncyCastleKeyDerivationService : IKeyDerivationService
{
private const int KeyLength = 256; // 32 bytes
public byte[] DeriveKey(byte[] password, byte[] salt, uint rounds)
{
var generator = new Pkcs5S2ParametersGenerator(new Sha256Digest());
generator.Init(password, salt, Convert.ToInt32(rounds));
return ((KeyParameter)generator.GenerateDerivedMacParameters(KeyLength)).GetKey();
}
}
}

View File

@ -3,6 +3,7 @@
<package id="Acr.Support" version="2.1.0" targetFramework="monoandroid60" />
<package id="Acr.UserDialogs" version="6.0.1" targetFramework="monoandroid60" />
<package id="AndHUD" version="1.2.0" targetFramework="monoandroid60" />
<package id="BouncyCastle" version="1.8.1" targetFramework="monoandroid60" />
<package id="CommonServiceLocator" version="1.3" targetFramework="monoandroid60" />
<package id="HockeySDK.Xamarin" version="4.1.0-beta3" targetFramework="monoandroid60" />
<package id="modernhttpclient" version="2.4.2" targetFramework="monoandroid50" />

View File

@ -2,6 +2,6 @@
{
public interface IKeyDerivationService
{
byte[] DeriveKey(string password, string salt);
byte[] DeriveKey(byte[] password, byte[] salt, uint rounds);
}
}

View File

@ -197,10 +197,6 @@
<HintPath>..\..\packages\Acr.UserDialogs.6.0.1\lib\portable-win+net45+wp8+win8+wpa81\Acr.UserDialogs.Interface.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="crypto, Version=1.8.0.0, Culture=neutral, PublicKeyToken=0e99375e54769942, processorArchitecture=MSIL">
<HintPath>..\..\packages\Portable.BouncyCastle.1.8.0\lib\portable-net45+win8+wpa81+MonoTouch10+MonoAndroid10+xamarinmac20+xamarinios10\crypto.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="HockeySDK, Version=1.0.6018.21545, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\HockeySDK.Xamarin.4.1.0-beta3\lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10\HockeySDK.dll</HintPath>
<Private>True</Private>
@ -221,6 +217,26 @@
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\portable-net45+wp80+win8+wpa81\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="PCLCrypto, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d4421c8a4786956c, processorArchitecture=MSIL">
<HintPath>..\..\packages\PCLCrypto.2.0.147\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\PCLCrypto.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="PInvoke.BCrypt, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
<HintPath>..\..\packages\PInvoke.BCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.BCrypt.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="PInvoke.Kernel32, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
<HintPath>..\..\packages\PInvoke.Kernel32.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Kernel32.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="PInvoke.NCrypt, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
<HintPath>..\..\packages\PInvoke.NCrypt.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.NCrypt.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="PInvoke.Windows.Core, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
<HintPath>..\..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Plugin.Connectivity, Version=2.1.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xam.Plugin.Connectivity.2.2.2\lib\portable-net45+wp80+wp81+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10+Xamarin.Mac20+UAP10\Plugin.Connectivity.dll</HintPath>
<Private>True</Private>
@ -277,6 +293,10 @@
<HintPath>..\..\packages\SQLitePCL.raw.0.9.2\lib\portable-net45+netcore45+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\SQLitePCL.raw.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Validation, Version=2.2.0.0, Culture=neutral, PublicKeyToken=2fc06f0d701809a7, processorArchitecture=MSIL">
<HintPath>..\..\packages\Validation.2.2.8\lib\portable-net40+sl50+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\Validation.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.2.3.0.107\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Core.dll</HintPath>
<Private>True</Private>

View File

@ -3,13 +3,7 @@ using System.Diagnostics;
using System.Text;
using Bit.App.Abstractions;
using Bit.App.Models;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;
using PCLCrypto;
namespace Bit.App.Services
{
@ -17,35 +11,30 @@ namespace Bit.App.Services
{
private const string KeyKey = "key";
private const int InitializationVectorSize = 16;
private const int KeySize = 256;
private const int Iterations = 5000;
private readonly Random _random = new Random();
private readonly ISecureStorageService _secureStorage;
private KeyParameter _keyParameter;
private readonly IKeyDerivationService _keyDerivationService;
private byte[] _key;
public CryptoService(ISecureStorageService secureStorage)
public CryptoService(
ISecureStorageService secureStorage,
IKeyDerivationService keyDerivationService)
{
_secureStorage = secureStorage;
_keyDerivationService = keyDerivationService;
}
public byte[] Key
{
get
{
if(_keyParameter != null)
if(_key == null)
{
return _keyParameter.GetKey();
_key = _secureStorage.Retrieve(KeyKey);
}
var storedKey = _secureStorage.Retrieve(KeyKey);
if(storedKey == null)
{
return null;
}
_keyParameter = new KeyParameter(storedKey);
return _keyParameter.GetKey();
return _key;
}
set
{
@ -56,7 +45,7 @@ namespace Bit.App.Services
else
{
_secureStorage.Delete(KeyKey);
_keyParameter = null;
_key = null;
}
}
}
@ -88,16 +77,10 @@ namespace Bit.App.Services
var plaintextBytes = Encoding.UTF8.GetBytes(plaintextValue);
var iv = GenerateRandomInitializationVector();
var keyParamWithIV = new ParametersWithIV(_keyParameter, iv, 0, InitializationVectorSize);
var aesBlockCipher = new CbcBlockCipher(new AesEngine());
var cipher = new PaddedBufferedBlockCipher(aesBlockCipher);
cipher.Init(true, keyParamWithIV);
var encryptedBytes = new byte[cipher.GetOutputSize(plaintextBytes.Length)];
var length = cipher.ProcessBytes(plaintextBytes, encryptedBytes, 0);
cipher.DoFinal(encryptedBytes, length);
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var cryptoKey = provider.CreateSymmetricKey(Key);
var iv = WinRTCrypto.CryptographicBuffer.GenerateRandom(provider.BlockLength);
var encryptedBytes = WinRTCrypto.CryptographicEngine.Encrypt(cryptoKey, plaintextBytes, iv);
return new CipherString(Convert.ToBase64String(iv), Convert.ToBase64String(encryptedBytes));
}
@ -115,14 +98,11 @@ namespace Bit.App.Services
try
{
var keyParamWithIV = new ParametersWithIV(_keyParameter, encyptedValue.InitializationVectorBytes, 0, InitializationVectorSize);
var aesBlockCipher = new CbcBlockCipher(new AesEngine());
var cipher = new PaddedBufferedBlockCipher(aesBlockCipher);
cipher.Init(false, keyParamWithIV);
byte[] comparisonBytes = new byte[cipher.GetOutputSize(encyptedValue.CipherTextBytes.Length)];
var length = cipher.ProcessBytes(encyptedValue.CipherTextBytes, comparisonBytes, 0);
cipher.DoFinal(comparisonBytes, length);
return Encoding.UTF8.GetString(comparisonBytes, 0, comparisonBytes.Length).TrimEnd('\0');
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var cryptoKey = provider.CreateSymmetricKey(Key);
var decryptedBytes = WinRTCrypto.CryptographicEngine.Decrypt(cryptoKey, encyptedValue.CipherTextBytes,
encyptedValue.InitializationVectorBytes);
return Encoding.UTF8.GetString(decryptedBytes, 0, decryptedBytes.Length).TrimEnd('\0');
}
catch(Exception e)
{
@ -146,9 +126,8 @@ namespace Bit.App.Services
var passwordBytes = Encoding.UTF8.GetBytes(password);
var saltBytes = Encoding.UTF8.GetBytes(salt);
var generator = new Pkcs5S2ParametersGenerator(new Sha256Digest());
generator.Init(passwordBytes, saltBytes, Iterations);
return ((KeyParameter)generator.GenerateDerivedMacParameters(KeySize)).GetKey();
var key = _keyDerivationService.DeriveKey(passwordBytes, saltBytes, 5000);
return key;
}
public string MakeKeyFromPasswordBase64(string password, string salt)
@ -170,10 +149,8 @@ namespace Bit.App.Services
}
var passwordBytes = Encoding.UTF8.GetBytes(password);
var generator = new Pkcs5S2ParametersGenerator(new Sha256Digest());
generator.Init(key, passwordBytes, 1);
return ((KeyParameter)generator.GenerateDerivedMacParameters(KeySize)).GetKey();
var hash = _keyDerivationService.DeriveKey(key, passwordBytes, 1);
return hash;
}
public string HashPasswordBase64(byte[] key, string password)
@ -181,12 +158,5 @@ namespace Bit.App.Services
var hash = HashPassword(key, password);
return Convert.ToBase64String(hash);
}
private byte[] GenerateRandomInitializationVector()
{
var iv = new byte[InitializationVectorSize];
_random.NextBytes(iv);
return iv;
}
}
}

View File

@ -5,13 +5,18 @@
<package id="HockeySDK.Xamarin" version="4.1.0-beta3" targetFramework="portable45-net45+win8+wpa81" />
<package id="modernhttpclient" version="2.4.2" targetFramework="portable45-net45+win8+wpa81" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="portable45-net45+win8+wpa81" />
<package id="PCLCrypto" version="2.0.147" targetFramework="portable45-net45+win8+wpa81" />
<package id="PInvoke.BCrypt" version="0.3.2" targetFramework="portable45-net45+win8+wpa81" />
<package id="PInvoke.Kernel32" version="0.3.2" targetFramework="portable45-net45+win8+wpa81" />
<package id="PInvoke.NCrypt" version="0.3.2" targetFramework="portable45-net45+win8+wpa81" />
<package id="PInvoke.Windows.Core" version="0.3.2" targetFramework="portable45-net45+win8+wpa81" />
<package id="Plugin.Fingerprint" version="1.2.0" targetFramework="portable45-net45+win8+wpa81" />
<package id="Portable.BouncyCastle" version="1.8.0" targetFramework="portable45-net45+win8+wpa81" />
<package id="Splat" version="1.6.2" targetFramework="portable45-net45+win8+wpa81" />
<package id="sqlite-net-pcl" version="1.1.2" targetFramework="portable45-net45+win8+wpa81" />
<package id="SQLitePCL.bundle_green" version="0.9.2" targetFramework="portable45-net45+win8+wpa81" />
<package id="SQLitePCL.raw" version="0.9.2" targetFramework="portable45-net45+win8+wpa81" />
<package id="Unity" version="3.5.1405-prerelease" targetFramework="portable45-net45+win8+wpa81" />
<package id="Validation" version="2.2.8" targetFramework="portable45-net45+win8+wpa81" />
<package id="Xam.Plugin.Connectivity" version="2.2.2" targetFramework="portable45-net45+win8+wpa81" />
<package id="Xam.Plugin.DeviceInfo" version="2.0.2" targetFramework="portable45-net45+win8+wpa81" />
<package id="Xam.Plugin.PushNotification" version="1.2.2" targetFramework="portable45-net45+win8+wpa81" developmentDependency="true" />

View File

@ -2,25 +2,24 @@
using Foundation;
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace Bit.iOS.Services
namespace Bit.iOS.Core.Services
{
public class KeyDerivationService : IKeyDerivationService
public class CommonCryptoKeyDerivationService : IKeyDerivationService
{
private const uint PBKDFAlgorithm = 2; // PBKDF2
private const uint PseudoRandomAlgorithm = 3; // SHA256
private const uint Rounds = 5000;
private const uint KeyLength = 32; // 256 bit
public byte[] DeriveKey(string password, string salt)
public byte[] DeriveKey(byte[] password, byte[] salt, uint rounds)
{
var passwordData = NSData.FromArray(Encoding.UTF8.GetBytes(password));
var saltData = NSData.FromArray(Encoding.UTF8.GetBytes(salt));
var passwordData = NSData.FromArray(password);
var saltData = NSData.FromArray(salt);
var keyData = new NSMutableData();
keyData.Length = 32;
var result = CCKeyCerivationPBKDF(PBKDFAlgorithm, passwordData.Bytes, passwordData.Length, saltData.Bytes,
saltData.Length, PseudoRandomAlgorithm, Rounds, keyData.MutableBytes, keyData.Length);
keyData.Length = KeyLength;
var result = CCKeyCerivationPBKDF(PBKDFAlgorithm, passwordData.Bytes, passwordData.Length, saltData.Bytes,
saltData.Length, PseudoRandomAlgorithm, rounds, keyData.MutableBytes, keyData.Length);
byte[] keyBytes = new byte[keyData.Length];
Marshal.Copy(keyData.Bytes, keyBytes, 0, Convert.ToInt32(keyData.Length));
@ -29,7 +28,7 @@ namespace Bit.iOS.Services
// ref: http://opensource.apple.com//source/CommonCrypto/CommonCrypto-55010/CommonCrypto/CommonKeyDerivation.h
[DllImport(ObjCRuntime.Constants.libSystemLibrary, EntryPoint = "CCKeyDerivationPBKDF")]
public extern static int CCKeyCerivationPBKDF(uint algorithm, IntPtr password, nuint passwordLen,
private extern static int CCKeyCerivationPBKDF(uint algorithm, IntPtr password, nuint passwordLen,
IntPtr salt, nuint saltLen, uint prf, nuint rounds, IntPtr derivedKey, nuint derivedKeyLength);
}
}

View File

@ -77,6 +77,7 @@
<Compile Include="HockeyAppCrashManagerDelegate.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\KeyChainStorageService.cs" />
<Compile Include="Services\CommonCryptoKeyDerivationService.cs" />
<Compile Include="Services\Settings.cs" />
<Compile Include="Services\SqlService.cs" />
<Compile Include="Utilities\Dialogs.cs" />

View File

@ -250,6 +250,7 @@ namespace Bit.iOS.Extension
.RegisterType<ISqlService, SqlService>(new ContainerControlledLifetimeManager())
.RegisterType<ISecureStorageService, KeyChainStorageService>(new ContainerControlledLifetimeManager())
.RegisterType<ICryptoService, CryptoService>(new ContainerControlledLifetimeManager())
.RegisterType<IKeyDerivationService, CommonCryptoKeyDerivationService>(new ContainerControlledLifetimeManager())
.RegisterType<IAuthService, AuthService>(new ContainerControlledLifetimeManager())
.RegisterType<IFolderService, FolderService>(new ContainerControlledLifetimeManager())
.RegisterType<ISiteService, SiteService>(new ContainerControlledLifetimeManager())

View File

@ -23,9 +23,19 @@
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>i386</MtouchArch>
<MtouchLink>None</MtouchLink>
<MtouchDebug>true</MtouchDebug>
<MtouchLink>Full</MtouchLink>
<MtouchDebug>True</MtouchDebug>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchSdkVersion />
<MtouchProfiling>False</MtouchProfiling>
<MtouchFastDev>False</MtouchFastDev>
<MtouchUseLlvm>False</MtouchUseLlvm>
<MtouchUseThumb>False</MtouchUseThumb>
<MtouchUseSGen>False</MtouchUseSGen>
<MtouchUseRefCounting>False</MtouchUseRefCounting>
<OptimizePNGs>True</OptimizePNGs>
<MtouchFloat32>False</MtouchFloat32>
<MtouchI18n />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<DebugType>none</DebugType>

View File

@ -236,6 +236,7 @@ namespace Bit.iOS
.RegisterType<ISqlService, SqlService>(new ContainerControlledLifetimeManager())
.RegisterType<ISecureStorageService, KeyChainStorageService>(new ContainerControlledLifetimeManager())
.RegisterType<ICryptoService, CryptoService>(new ContainerControlledLifetimeManager())
.RegisterType<IKeyDerivationService, CommonCryptoKeyDerivationService>(new ContainerControlledLifetimeManager())
.RegisterType<IAuthService, AuthService>(new ContainerControlledLifetimeManager())
.RegisterType<IFolderService, FolderService>(new ContainerControlledLifetimeManager())
.RegisterType<ISiteService, SiteService>(new ContainerControlledLifetimeManager())

View File

@ -17,14 +17,15 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<DefineConstants>DEBUG;__UNIFIED__;__MOBILE__;__IOS__</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>i386, x86_64</MtouchArch>
<MtouchLink>None</MtouchLink>
<MtouchLink>Full</MtouchLink>
<MtouchDebug>True</MtouchDebug>
<MtouchSdkVersion>9.3</MtouchSdkVersion>
<MtouchSdkVersion>
</MtouchSdkVersion>
<CodesignKey>iPhone Developer</CodesignKey>
<CodesignProvision>
</CodesignProvision>
@ -42,6 +43,7 @@
<MtouchTlsProvider>Default</MtouchTlsProvider>
<MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler>
<MtouchFloat32>False</MtouchFloat32>
<MtouchI18n />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<DebugType>none</DebugType>
@ -140,7 +142,6 @@
<Compile Include="Services\ClipboardService.cs" />
<Compile Include="Main.cs" />
<Compile Include="AppDelegate.cs" />
<Compile Include="Services\KeyDerivationService.cs" />
<Compile Include="Services\ReflectionService.cs" />
<None Include="app.config" />
<None Include="Entitlements.plist" />

View File

@ -8,23 +8,6 @@ namespace Bit.App.Test
{
public class CryptoServiceTests
{
[Fact]
public void MakeKeyFromPasswordBase64()
{
var service = new CryptoService(Substitute.For<ISecureStorageService>());
var key = service.MakeKeyFromPasswordBase64("123456", "salt");
Assert.Equal(key, GetKey());
}
[Fact]
public void HashPasswordBase64()
{
var service = new CryptoService(Substitute.For<ISecureStorageService>());
var key = Convert.FromBase64String(GetKey());
var hash = service.HashPasswordBase64(key, "123456");
Assert.Equal(hash, "7Bsl4ponrsFu0jGl4yMeLZp5tKqx6g4tLrXhMszIsjQ=");
}
[Fact]
public void EncryptDecrypt()
{
@ -41,17 +24,14 @@ namespace Bit.App.Test
private string EncryptDecryptValue(string value)
{
var storage = Substitute.For<ISecureStorageService>();
storage.Retrieve("key").Returns(Convert.FromBase64String(GetKey()));
var storageService = Substitute.For<ISecureStorageService>();
var keyService = Substitute.For<IKeyDerivationService>();
storageService.Retrieve("key").Returns(
Convert.FromBase64String("QpSYI5k0bLQXEygUEHn4wMII3ERatuWDFBszk7JAhbQ="));
var service = new CryptoService(storage);
var service = new CryptoService(storageService, keyService);
var encryptedHi = service.Encrypt(value);
return service.Decrypt(encryptedHi);
}
private string GetKey()
{
return "QpSYI5k0bLQXEygUEHn4wMII3ERatuWDFBszk7JAhbQ=";
}
}
}

View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Foundation;
using UIKit;
using MonoTouch.NUnit.UI;
namespace Bit.iOS.Test
{
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to
// application events from iOS.
[Register("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate
{
// class-level declarations
UIWindow window;
TouchRunner runner;
//
// This method is invoked when the application has loaded and is ready to run. In this
// method you should instantiate the window, load the UI into it and then make the window
// visible.
//
// You have 17 seconds to return from this method, or iOS will terminate your application.
//
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
// create a new window instance based on the screen size
window = new UIWindow(UIScreen.MainScreen.Bounds);
runner = new TouchRunner(window);
// register every tests included in the main application/assembly
runner.Add(System.Reflection.Assembly.GetExecutingAssembly());
window.RootViewController = new UINavigationController(runner.GetViewController());
// make the window visible
window.MakeKeyAndVisible();
return true;
}
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>

34
test/iOS.Test/Info.plist Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDisplayName</key>
<string>bitwarden test</string>
<key>CFBundleIdentifier</key>
<string>com.8bit.bitwarden.test</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>MinimumOSVersion</key>
<string></string>
</dict>
</plist>

View File

@ -0,0 +1,34 @@
using System;
using System.Text;
using System.Linq;
using NUnit.Framework;
using Bit.iOS.Core.Services;
namespace Bit.iOS.Test
{
[TestFixture]
public class KeyDerivationTests
{
[Test]
public void MakeKeyFromPasswordBase64()
{
var service = new CommonCryptoKeyDerivationService();
var key = service.DeriveKey(Encoding.UTF8.GetBytes("123456"), Encoding.UTF8.GetBytes("salt"), 5000);
Assert.True(key.SequenceEqual(GetKey()));
}
[Test]
public void HashPasswordBase64()
{
var service = new CommonCryptoKeyDerivationService();
var hash = service.DeriveKey(GetKey(), Encoding.UTF8.GetBytes("123456"), 1);
var hashBytes = Convert.FromBase64String("7Bsl4ponrsFu0jGl4yMeLZp5tKqx6g4tLrXhMszIsjQ=");
Assert.True(hash.SequenceEqual(hashBytes));
}
private byte[] GetKey()
{
return Convert.FromBase64String("QpSYI5k0bLQXEygUEHn4wMII3ERatuWDFBszk7JAhbQ=");
}
}
}

15
test/iOS.Test/Main.cs Normal file
View File

@ -0,0 +1,15 @@
using UIKit;
namespace Bit.iOS.Test
{
public class Application
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, "AppDelegate");
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 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("Bit.iOS.Test")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("bitwarden")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("6702027a-f726-4149-863e-7cb924674b9a")]
// 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")]

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

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)' == '' ">iPhoneSimulator</Platform>
<ProjectGuid>{6702027A-F726-4149-863E-7CB924674B9A}</ProjectGuid>
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Exe</OutputType>
<RootNamespace>Bit.iOS.Test</RootNamespace>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
<AssemblyName>BitiOSTest</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>i386</MtouchArch>
<MtouchLink>None</MtouchLink>
<MtouchDebug>true</MtouchDebug>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhoneSimulator\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchLink>None</MtouchLink>
<MtouchArch>i386</MtouchArch>
<ConsolePause>false</ConsolePause>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhone\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchDebug>true</MtouchDebug>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhone\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<ConsolePause>false</ConsolePause>
<CodesignKey>iPhone Developer</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Ad-Hoc|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\iPhone\Ad-Hoc</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<BuildIpa>True</BuildIpa>
<CodesignProvision>Automatic:AdHoc</CodesignProvision>
<CodesignKey>iPhone Distribution</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'AppStore|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\iPhone\AppStore</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<CodesignProvision>Automatic:AppStore</CodesignProvision>
<CodesignKey>iPhone Distribution</CodesignKey>
</PropertyGroup>
<ItemGroup>
<Compile Include="KeyDerivationTests.cs" />
<Compile Include="Main.cs" />
<Compile Include="AppDelegate.cs" />
<None Include="Info.plist" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Content Include="Entitlements.plist" />
</ItemGroup>
<ItemGroup>
<BundleResource Include="Resources\Default.png" />
<BundleResource Include="Resources\Default@2x.png" />
<BundleResource Include="Resources\Default-568h@2x.png" />
</ItemGroup>
<ItemGroup>
<Reference Include="MonoTouch.NUnitLite" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Xamarin.iOS" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\iOS.Core\iOS.Core.csproj">
<Project>{b2538ada-b605-4d6f-acd2-62a409680f84}</Project>
<Name>iOS.Core</Name>
<IsAppExtension>false</IsAppExtension>
<IsWatchApp>false</IsWatchApp>
</ProjectReference>
<ProjectReference Include="..\..\src\iOS\iOS.csproj">
<Project>{1f78403f-9a28-405b-9289-b9dbeb55f074}</Project>
<Name>iOS</Name>
<IsAppExtension>false</IsAppExtension>
<IsWatchApp>false</IsWatchApp>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
</Project>

View File

@ -0,0 +1,125 @@
<?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)' == '' ">iPhoneSimulator</Platform>
<ProjectGuid>{6702027A-F726-4149-863E-7CB924674B9A}</ProjectGuid>
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Exe</OutputType>
<RootNamespace>Bit.iOS.Test</RootNamespace>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
<AssemblyName>Bit.iOS.Test</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>i386</MtouchArch>
<MtouchLink>None</MtouchLink>
<MtouchDebug>true</MtouchDebug>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhoneSimulator\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchLink>None</MtouchLink>
<MtouchArch>i386</MtouchArch>
<ConsolePause>false</ConsolePause>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhone\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchDebug>true</MtouchDebug>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhone\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<ConsolePause>false</ConsolePause>
<CodesignKey>iPhone Developer</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Ad-Hoc|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\iPhone\Ad-Hoc</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<BuildIpa>True</BuildIpa>
<CodesignProvision>Automatic:AdHoc</CodesignProvision>
<CodesignKey>iPhone Distribution</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'AppStore|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\iPhone\AppStore</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<CodesignProvision>Automatic:AppStore</CodesignProvision>
<CodesignKey>iPhone Distribution</CodesignKey>
</PropertyGroup>
<ItemGroup>
<Compile Include="KeyDerivationTests.cs" />
<Compile Include="Main.cs" />
<Compile Include="AppDelegate.cs" />
<Compile Include="UnitTests1.cs" />
<None Include="Info.plist" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Content Include="Entitlements.plist" />
</ItemGroup>
<ItemGroup>
<BundleResource Include="Resources\Default.png" />
<BundleResource Include="Resources\Default@2x.png" />
<BundleResource Include="Resources\Default-568h@2x.png" />
</ItemGroup>
<ItemGroup>
<Reference Include="MonoTouch.NUnitLite" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Xamarin.iOS" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\iOS.Core\iOS.Core.csproj">
<Project>{b2538ada-b605-4d6f-acd2-62a409680f84}</Project>
<Name>iOS.Core</Name>
<IsAppExtension>false</IsAppExtension>
<IsWatchApp>false</IsWatchApp>
</ProjectReference>
<ProjectReference Include="..\..\src\iOS\iOS.csproj">
<Project>{1f78403f-9a28-405b-9289-b9dbeb55f074}</Project>
<Name>iOS</Name>
<IsAppExtension>false</IsAppExtension>
<IsWatchApp>false</IsWatchApp>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
</Project>