Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port send jslib to mobile #1219

Merged
merged 20 commits into from
Jan 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ jobs:
- name: Restore packages
run: nuget restore

- name: Run Core Tests
run: dotnet test test/Core.Test/Core.Test.csproj

- name: Build Play Store publisher
run: dotnet build ./store/google/Publisher/Publisher.csproj -p:Configuration=Release

Expand Down
66 changes: 66 additions & 0 deletions bitwarden-mobile.sln
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Extension", "src\iOS.Ex
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Autofill", "src\iOS.Autofill\iOS.Autofill.csproj", "{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "test\Common\Common.csproj", "{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Test", "test\Core.Test\Core.Test.csproj", "{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
Expand Down Expand Up @@ -351,6 +355,66 @@ Global
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhone.Build.0 = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|Any CPU.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhone.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhone.Build.0 = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|Any CPU.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|Any CPU.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhone.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhone.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.FDroid|iPhoneSimulator.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|Any CPU.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhone.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhone.Build.0 = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|Any CPU.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhone.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhone.Build.0 = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|Any CPU.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|Any CPU.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhone.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhone.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhoneSimulator.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.FDroid|iPhoneSimulator.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|Any CPU.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhone.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhone.Build.0 = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -366,6 +430,8 @@ Global
{599E0201-420A-4C3E-A7BA-5349F72E0B15} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{324BE76C-38FA-4F11-8BB1-95C7B3B1B545} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{4085B0A5-12A9-4993-B8B8-4ACE72E62E39} = {8904C536-C67D-420F-9971-51B26574C3AA}
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0} = {8904C536-C67D-420F-9971-51B26574C3AA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7D436EA3-8B7E-45D2-8D14-0730BD2E0410}
Expand Down
2 changes: 1 addition & 1 deletion src/Android/Android.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\App\App.csproj">
<Project>{9F1742A7-7D03-4BB3-8FCD-41BC3002B00A}</Project>
<Project>{EE44C6A1-2A85-45FE-8D9B-BF1D5F88809C}</Project>
cscharf marked this conversation as resolved.
Show resolved Hide resolved
<Name>App</Name>
</ProjectReference>
<ProjectReference Include="..\Core\Core.csproj">
Expand Down
7 changes: 7 additions & 0 deletions src/Core/Abstractions/IApiService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,12 @@ Task PostShareCipherAttachmentAsync(string id, string attachmentId, MultipartFor
Task PostTwoFactorEmailAsync(TwoFactorEmailRequest request);
Task PutDeviceTokenAsync(string identifier, DeviceTokenRequest request);
Task PostEventsCollectAsync(IEnumerable<EventRequest> request);

Task<SendResponse> GetSendAsync(string id);
Task<SendResponse> PostSendAsync(SendRequest request);
Task<SendResponse> PostSendFileAsync(MultipartFormDataContent data);
Task<SendResponse> PutSendAsync(string id, SendRequest request);
Task<SendResponse> PutSendRemovePasswordAsync(string id);
Task DeleteSendAsync(string id);
}
}
6 changes: 6 additions & 0 deletions src/Core/Abstractions/ICryptoFunctionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ public interface ICryptoFunctionService
Task<byte[]> Pbkdf2Async(byte[] password, string salt, CryptoHashAlgorithm algorithm, int iterations);
Task<byte[]> Pbkdf2Async(string password, byte[] salt, CryptoHashAlgorithm algorithm, int iterations);
Task<byte[]> Pbkdf2Async(byte[] password, byte[] salt, CryptoHashAlgorithm algorithm, int iterations);
Task<byte[]> HkdfAsync(byte[] ikm, string salt, string info, int outputByteSize, HkdfAlgorithm algorithm);
Task<byte[]> HkdfAsync(byte[] ikm, byte[] salt, string info, int outputByteSize, HkdfAlgorithm algorithm);
Task<byte[]> HkdfAsync(byte[] ikm, string salt, byte[] info, int outputByteSize, HkdfAlgorithm algorithm);
Task<byte[]> HkdfAsync(byte[] ikm, byte[] salt, byte[] info, int outputByteSize, HkdfAlgorithm algorithm);
Task<byte[]> HkdfExpandAsync(byte[] prk, string info, int outputByteSize, HkdfAlgorithm algorithm);
Task<byte[]> HkdfExpandAsync(byte[] prk, byte[] info, int outputByteSize, HkdfAlgorithm algorithm);
Task<byte[]> HashAsync(string value, CryptoHashAlgorithm algorithm);
Task<byte[]> HashAsync(byte[] value, CryptoHashAlgorithm algorithm);
Task<byte[]> HmacAsync(byte[] value, byte[] key, CryptoHashAlgorithm algorithm);
Expand Down
1 change: 1 addition & 0 deletions src/Core/Abstractions/ICryptoService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Task<SymmetricCryptoKey> MakeKeyFromPinAsync(string pin, string salt, KdfType kd
Task<Tuple<string, CipherString>> MakeKeyPairAsync(SymmetricCryptoKey key = null);
Task<SymmetricCryptoKey> MakePinKeyAysnc(string pin, string salt, KdfType kdf, int kdfIterations);
Task<Tuple<CipherString, SymmetricCryptoKey>> MakeShareKeyAsync();
Task<SymmetricCryptoKey> MakeSendKeyAsync(byte[] keyMaterial);
Task<int> RandomNumberAsync(int min, int max);
Task<Tuple<SymmetricCryptoKey, CipherString>> RemakeEncKeyAsync(SymmetricCryptoKey key);
Task<CipherString> RsaEncryptAsync(byte[] data, byte[] publicKey = null);
Expand Down
25 changes: 25 additions & 0 deletions src/Core/Abstractions/ISendService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Bit.Core.Models.Data;
using Bit.Core.Models.Domain;
using Bit.Core.Models.View;

namespace Bit.Core.Abstractions
{
public interface ISendService
{
void ClearCache();
Task<(Send send, CipherString encryptedFileData)> EncryptAsync(SendView model, byte[] fileData, string password,
SymmetricCryptoKey key = null);
Task<Send> GetAsync(string id);
Task<List<Send>> GetAllAsync();
Task<List<SendView>> GetAllDecryptedAsync();
Task SaveWithServerAsync(Send sendData, byte[] encryptedFileData);
Task UpsertAsync(params SendData[] send);
Task ReplaceAsync(Dictionary<string, SendData> sends);
Task ClearAsync(string userId);
Task DeleteAsync(params string[] ids);
Task DeleteWithServerAsync(string id);
Task RemovePasswordWithServerAsync(string id);
}
}
8 changes: 8 additions & 0 deletions src/Core/Enums/HdkfAlgorithm.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Bit.Core.Enums
{
public enum HkdfAlgorithm : byte
{
Sha256 = 1,
Sha512 = 2,
}
}
8 changes: 8 additions & 0 deletions src/Core/Enums/SendType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Bit.Core.Enums
{
public enum SendType
{
Text = 0,
File = 1,
}
}
12 changes: 12 additions & 0 deletions src/Core/Models/Api/SendFileApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Bit.Core.Models.Api
{
public class SendFileApi
{
public string Id { get; set; }
public string Url { get; set; }
public string FileName { get; set; }
public string Key { get; set; }
public string Size { get; set; }
public string SizeName { get; set; }
}
}
8 changes: 8 additions & 0 deletions src/Core/Models/Api/SendTextApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Bit.Core.Models.Api
{
public class SendTextApi
{
public string Text { get; set; }
public bool Hidden { get; set; }
}
}
58 changes: 58 additions & 0 deletions src/Core/Models/Data/SendData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using Bit.Core.Enums;
using Bit.Core.Models.Response;

namespace Bit.Core.Models.Data
{
public class SendData : Data
{
public SendData() { }

public SendData(SendResponse response, string userId)
{
Id = response.Id;
AccessId = response.AccessId;
UserId = userId;
Type = response.Type;
Name = response.Name;
Notes = response.Notes;
Key = response.Key;
MaxAccessCount = response.MaxAccessCount;
AccessCount = response.AccessCount;
RevisionDate = response.RevisionDate;
ExpirationDate = response.ExpirationDate;
DeletionDate = response.DeletionDate;
Password = response.Password;
Disabled = response.Disabled;

switch (Type)
{
case SendType.File:
File = new SendFileData(response.File);
break;
case SendType.Text:
Text = new SendTextData(response.Text);
break;
default:
break;
}
}

public string Id { get; set; }
public string AccessId { get; set; }
public string UserId { get; set; }
public SendType Type { get; set; }
public string Name { get; set; }
public string Notes { get; set; }
public SendFileData File { get; set; }
public SendTextData Text { get; set; }
public string Key { get; set; }
public int? MaxAccessCount { get; set; }
public int AccessCount { get; set; }
public DateTime RevisionDate { get; set; }
public DateTime? ExpirationDate { get; set; }
public DateTime DeletionDate { get; set; }
public string Password { get; set; }
public bool Disabled { get; set; }
}
}
27 changes: 27 additions & 0 deletions src/Core/Models/Data/SendFileData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Drawing;
using Bit.Core.Models.Api;

namespace Bit.Core.Models.Data
{
public class SendFileData : Data
{
public SendFileData() { }

public SendFileData(SendFileApi data)
{
Id = data.Id;
Url = data.Url;
FileName = data.FileName;
Key = data.Key;
Size = data.Size;
SizeName = data.SizeName;
}

public string Id { get; set; }
public string Url { get; set; }
public string FileName { get; set; }
public string Key { get; set; }
public string Size { get; set; }
public string SizeName { get; set; }
}
}
19 changes: 19 additions & 0 deletions src/Core/Models/Data/SendTextData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Drawing;
using Bit.Core.Models.Api;

namespace Bit.Core.Models.Data
{
public class SendTextData : Data
{
public SendTextData() { }

public SendTextData(SendTextApi data)
{
Text = data.Text;
Hidden = data.Hidden;
}

public string Text { get; set; }
public bool Hidden { get; set; }
}
}
9 changes: 6 additions & 3 deletions src/Core/Models/Domain/CipherString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public CipherString(string encryptedString)
public string Data { get; private set; }
public string Mac { get; private set; }

public async Task<string> DecryptAsync(string orgId = null)
public async Task<string> DecryptAsync(string orgId = null, SymmetricCryptoKey key = null)
{
if (_decryptedValue != null)
{
Expand All @@ -109,8 +109,11 @@ public async Task<string> DecryptAsync(string orgId = null)
var cryptoService = ServiceContainer.Resolve<ICryptoService>("cryptoService");
try
{
var orgKey = await cryptoService.GetOrgKeyAsync(orgId);
_decryptedValue = await cryptoService.DecryptToUtf8Async(this, orgKey);
if (key == null)
{
key = await cryptoService.GetOrgKeyAsync(orgId);
}
_decryptedValue = await cryptoService.DecryptToUtf8Async(this, key);
}
catch
{
Expand Down
4 changes: 2 additions & 2 deletions src/Core/Models/Domain/Domain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ protected void BuildDataModel<D, O>(D domain, O dataObj, HashSet<string> map,
}
}

protected async Task<V> DecryptObjAsync<V, D>(V viewModel, D domain, HashSet<string> map, string orgId)
protected async Task<V> DecryptObjAsync<V, D>(V viewModel, D domain, HashSet<string> map, string orgId, SymmetricCryptoKey key = null)
where V : View.View
{
var viewModelType = viewModel.GetType();
Expand All @@ -64,7 +64,7 @@ async Task decCsAndSetDec(string propName)
string val = null;
if (domainPropInfo.GetValue(domain) is CipherString domainProp)
{
val = await domainProp.DecryptAsync(orgId);
val = await domainProp.DecryptAsync(orgId, key);
}
var viewModelPropInfo = viewModelType.GetProperty(propName);
viewModelPropInfo.SetValue(viewModel, val, null);
Expand Down
Loading