mirror of
https://github.com/bitwarden/mobile.git
synced 2024-11-25 12:05:59 +01:00
Use CipherByteArray to signify encrypted byte[] (#1366)
* Use CipherByteArray to signify encrypted byte[] * Rename CipherString and CipherByteArray to EncString and EncByteArray
This commit is contained in:
parent
10ea6a86e3
commit
a3b4ede8f3
@ -203,7 +203,7 @@ namespace Bit.App.Pages
|
||||
_vaultTimeoutService.PinProtectedKey);
|
||||
var encKey = await _cryptoService.GetEncKeyAsync(key);
|
||||
var protectedPin = await _storageService.GetAsync<string>(Constants.ProtectedPin);
|
||||
var decPin = await _cryptoService.DecryptToUtf8Async(new CipherString(protectedPin), encKey);
|
||||
var decPin = await _cryptoService.DecryptToUtf8Async(new EncString(protectedPin), encKey);
|
||||
failed = decPin != Pin;
|
||||
if (!failed)
|
||||
{
|
||||
@ -272,7 +272,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
var protectedPin = await _storageService.GetAsync<string>(Constants.ProtectedPin);
|
||||
var encKey = await _cryptoService.GetEncKeyAsync(key);
|
||||
var decPin = await _cryptoService.DecryptToUtf8Async(new CipherString(protectedPin), encKey);
|
||||
var decPin = await _cryptoService.DecryptToUtf8Async(new EncString(protectedPin), encKey);
|
||||
var pinKey = await _cryptoService.MakePinKeyAysnc(decPin, _email,
|
||||
kdf.GetValueOrDefault(KdfType.PBKDF2_SHA256), kdfIterations.GetValueOrDefault(5000));
|
||||
_vaultTimeoutService.PinProtectedKey = await _cryptoService.EncryptAsync(key.Key, pinKey);
|
||||
|
@ -140,7 +140,7 @@ namespace Bit.App.Pages
|
||||
var key = await _cryptoService.MakeKeyAsync(MasterPassword, email, kdf, kdfIterations);
|
||||
var masterPasswordHash = await _cryptoService.HashPasswordAsync(MasterPassword, key);
|
||||
|
||||
Tuple<SymmetricCryptoKey, CipherString> encKey;
|
||||
Tuple<SymmetricCryptoKey, EncString> encKey;
|
||||
var existingEncKey = await _cryptoService.GetEncKeyAsync();
|
||||
if (existingEncKey == null)
|
||||
{
|
||||
|
@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Models.Domain;
|
||||
|
||||
namespace Bit.Core.Abstractions
|
||||
{
|
||||
public interface IAzureFileUploadService
|
||||
{
|
||||
Task Upload(string uri, byte[] data, Func<Task<string>> renewalCallback);
|
||||
Task Upload(string uri, EncByteArray data, Func<Task<string>> renewalCallback);
|
||||
}
|
||||
}
|
||||
|
@ -17,11 +17,11 @@ namespace Bit.Core.Abstractions
|
||||
Task ClearOrgKeysAsync(bool memoryOnly = false);
|
||||
Task ClearPinProtectedKeyAsync();
|
||||
Task<byte[]> DecryptFromBytesAsync(byte[] encBytes, SymmetricCryptoKey key);
|
||||
Task<byte[]> DecryptToBytesAsync(CipherString cipherString, SymmetricCryptoKey key = null);
|
||||
Task<string> DecryptToUtf8Async(CipherString cipherString, SymmetricCryptoKey key = null);
|
||||
Task<CipherString> EncryptAsync(byte[] plainValue, SymmetricCryptoKey key = null);
|
||||
Task<CipherString> EncryptAsync(string plainValue, SymmetricCryptoKey key = null);
|
||||
Task<byte[]> EncryptToBytesAsync(byte[] plainValue, SymmetricCryptoKey key = null);
|
||||
Task<byte[]> DecryptToBytesAsync(EncString encString, SymmetricCryptoKey key = null);
|
||||
Task<string> DecryptToUtf8Async(EncString encString, SymmetricCryptoKey key = null);
|
||||
Task<EncString> EncryptAsync(byte[] plainValue, SymmetricCryptoKey key = null);
|
||||
Task<EncString> EncryptAsync(string plainValue, SymmetricCryptoKey key = null);
|
||||
Task<EncByteArray> EncryptToBytesAsync(byte[] plainValue, SymmetricCryptoKey key = null);
|
||||
Task<SymmetricCryptoKey> GetEncKeyAsync(SymmetricCryptoKey key = null);
|
||||
Task<List<string>> GetFingerprintAsync(string userId, byte[] publicKey = null);
|
||||
Task<SymmetricCryptoKey> GetKeyAsync();
|
||||
@ -33,17 +33,17 @@ namespace Bit.Core.Abstractions
|
||||
Task<bool> HasEncKeyAsync();
|
||||
Task<string> HashPasswordAsync(string password, SymmetricCryptoKey key);
|
||||
Task<bool> HasKeyAsync();
|
||||
Task<Tuple<SymmetricCryptoKey, CipherString>> MakeEncKeyAsync(SymmetricCryptoKey key);
|
||||
Task<Tuple<SymmetricCryptoKey, EncString>> MakeEncKeyAsync(SymmetricCryptoKey key);
|
||||
Task<SymmetricCryptoKey> MakeKeyAsync(string password, string salt, KdfType? kdf, int? kdfIterations);
|
||||
Task<SymmetricCryptoKey> MakeKeyFromPinAsync(string pin, string salt, KdfType kdf, int kdfIterations,
|
||||
CipherString protectedKeyCs = null);
|
||||
Task<Tuple<string, CipherString>> MakeKeyPairAsync(SymmetricCryptoKey key = null);
|
||||
EncString protectedKeyEs = null);
|
||||
Task<Tuple<string, EncString>> MakeKeyPairAsync(SymmetricCryptoKey key = null);
|
||||
Task<SymmetricCryptoKey> MakePinKeyAysnc(string pin, string salt, KdfType kdf, int kdfIterations);
|
||||
Task<Tuple<CipherString, SymmetricCryptoKey>> MakeShareKeyAsync();
|
||||
Task<Tuple<EncString, 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);
|
||||
Task<Tuple<SymmetricCryptoKey, EncString>> RemakeEncKeyAsync(SymmetricCryptoKey key);
|
||||
Task<EncString> RsaEncryptAsync(byte[] data, byte[] publicKey = null);
|
||||
Task SetEncKeyAsync(string encKey);
|
||||
Task SetEncPrivateKeyAsync(string encPrivateKey);
|
||||
Task SetKeyAsync(SymmetricCryptoKey key);
|
||||
|
@ -4,7 +4,7 @@ using Bit.Core.Models.Response;
|
||||
|
||||
namespace Bit.Core.Abstractions {
|
||||
public interface IFileUploadService {
|
||||
Task UploadCipherAttachmentFileAsync(AttachmentUploadDataResponse uploadData, string fileName, byte[] encryptedFileData);
|
||||
Task UploadSendFileAsync(SendFileUploadDataResponse uploadData, CipherString fileName, byte[] encryptedFileData);
|
||||
Task UploadCipherAttachmentFileAsync(AttachmentUploadDataResponse uploadData, string fileName, EncByteArray encryptedFileData);
|
||||
Task UploadSendFileAsync(SendFileUploadDataResponse uploadData, EncString fileName, EncByteArray encryptedFileData);
|
||||
}
|
||||
}
|
||||
|
@ -9,12 +9,12 @@ namespace Bit.Core.Abstractions
|
||||
public interface ISendService
|
||||
{
|
||||
void ClearCache();
|
||||
Task<(Send send, byte[] encryptedFileData)> EncryptAsync(SendView model, byte[] fileData, string password,
|
||||
Task<(Send send, EncByteArray 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<string> SaveWithServerAsync(Send sendData, byte[] encryptedFileData);
|
||||
Task<string> SaveWithServerAsync(Send sendData, EncByteArray encryptedFileData);
|
||||
Task UpsertAsync(params SendData[] send);
|
||||
Task ReplaceAsync(Dictionary<string, SendData> sends);
|
||||
Task ClearAsync(string userId);
|
||||
|
@ -6,7 +6,7 @@ namespace Bit.Core.Abstractions
|
||||
{
|
||||
public interface IVaultTimeoutService
|
||||
{
|
||||
CipherString PinProtectedKey { get; set; }
|
||||
EncString PinProtectedKey { get; set; }
|
||||
bool BiometricLocked { get; set; }
|
||||
|
||||
Task CheckVaultTimeoutAsync();
|
||||
|
@ -30,8 +30,8 @@ namespace Bit.Core.Models.Domain
|
||||
public string Url { get; set; }
|
||||
public string Size { get; set; }
|
||||
public string SizeName { get; set; }
|
||||
public CipherString Key { get; set; }
|
||||
public CipherString FileName { get; set; }
|
||||
public EncString Key { get; set; }
|
||||
public EncString FileName { get; set; }
|
||||
|
||||
public async Task<AttachmentView> DecryptAsync(string orgId)
|
||||
{
|
||||
|
@ -24,12 +24,12 @@ namespace Bit.Core.Models.Domain
|
||||
BuildDomainModel(this, obj, _map, alreadyEncrypted);
|
||||
}
|
||||
|
||||
public CipherString CardholderName { get; set; }
|
||||
public CipherString Brand { get; set; }
|
||||
public CipherString Number { get; set; }
|
||||
public CipherString ExpMonth { get; set; }
|
||||
public CipherString ExpYear { get; set; }
|
||||
public CipherString Code { get; set; }
|
||||
public EncString CardholderName { get; set; }
|
||||
public EncString Brand { get; set; }
|
||||
public EncString Number { get; set; }
|
||||
public EncString ExpMonth { get; set; }
|
||||
public EncString ExpYear { get; set; }
|
||||
public EncString Code { get; set; }
|
||||
|
||||
public Task<CardView> DecryptAsync(string orgId)
|
||||
{
|
||||
|
@ -58,8 +58,8 @@ namespace Bit.Core.Models.Domain
|
||||
public string Id { get; set; }
|
||||
public string OrganizationId { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
public CipherString Name { get; set; }
|
||||
public CipherString Notes { get; set; }
|
||||
public EncString Name { get; set; }
|
||||
public EncString Notes { get; set; }
|
||||
public Enums.CipherType Type { get; set; }
|
||||
public bool Favorite { get; set; }
|
||||
public bool OrganizationUseTotp { get; set; }
|
||||
|
@ -29,7 +29,7 @@ namespace Bit.Core.Models.Domain
|
||||
|
||||
public string Id { get; set; }
|
||||
public string OrganizationId { get; set; }
|
||||
public CipherString Name { get; set; }
|
||||
public EncString Name { get; set; }
|
||||
public string ExternalId { get; set; }
|
||||
public bool ReadOnly { get; set; }
|
||||
|
||||
|
@ -24,13 +24,13 @@ namespace Bit.Core.Models.Domain
|
||||
else
|
||||
{
|
||||
domainPropInfo.SetValue(domain,
|
||||
dataObjProp != null ? new CipherString(dataObjProp as string) : null, null);
|
||||
dataObjProp != null ? new EncString(dataObjProp as string) : null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void BuildDataModel<D, O>(D domain, O dataObj, HashSet<string> map,
|
||||
HashSet<string> notCipherStringList = null)
|
||||
HashSet<string> notEncryptedStringList = null)
|
||||
where D : Domain
|
||||
where O : Data.Data
|
||||
{
|
||||
@ -41,13 +41,13 @@ namespace Bit.Core.Models.Domain
|
||||
var domainPropInfo = domainType.GetProperty(prop);
|
||||
var domainProp = domainPropInfo.GetValue(domain);
|
||||
var dataObjPropInfo = dataObjType.GetProperty(prop);
|
||||
if (notCipherStringList?.Contains(prop) ?? false)
|
||||
if (notEncryptedStringList?.Contains(prop) ?? false)
|
||||
{
|
||||
dataObjPropInfo.SetValue(dataObj, domainProp, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
dataObjPropInfo.SetValue(dataObj, (domainProp as CipherString)?.EncryptedString, null);
|
||||
dataObjPropInfo.SetValue(dataObj, (domainProp as EncString)?.EncryptedString, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -62,7 +62,7 @@ namespace Bit.Core.Models.Domain
|
||||
{
|
||||
var domainPropInfo = domainType.GetProperty(propName);
|
||||
string val = null;
|
||||
if (domainPropInfo.GetValue(domain) is CipherString domainProp)
|
||||
if (domainPropInfo.GetValue(domain) is EncString domainProp)
|
||||
{
|
||||
val = await domainProp.DecryptAsync(orgId, key);
|
||||
}
|
||||
|
12
src/Core/Models/Domain/EncByteArray.cs
Normal file
12
src/Core/Models/Domain/EncByteArray.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace Bit.Core.Models.Domain
|
||||
{
|
||||
public class EncByteArray
|
||||
{
|
||||
public byte[] Buffer { get; }
|
||||
|
||||
public EncByteArray(byte[] encryptedByteArray)
|
||||
{
|
||||
Buffer = encryptedByteArray;
|
||||
}
|
||||
}
|
||||
}
|
@ -6,11 +6,11 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Models.Domain
|
||||
{
|
||||
public class CipherString
|
||||
public class EncString
|
||||
{
|
||||
private string _decryptedValue;
|
||||
|
||||
public CipherString(EncryptionType encryptionType, string data, string iv = null, string mac = null)
|
||||
public EncString(EncryptionType encryptionType, string data, string iv = null, string mac = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(data))
|
||||
{
|
||||
@ -37,7 +37,7 @@ namespace Bit.Core.Models.Domain
|
||||
Mac = mac;
|
||||
}
|
||||
|
||||
public CipherString(string encryptedString)
|
||||
public EncString(string encryptedString)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(encryptedString))
|
||||
{
|
@ -22,8 +22,8 @@ namespace Bit.Core.Models.Domain
|
||||
BuildDomainModel(this, obj, _map, alreadyEncrypted);
|
||||
}
|
||||
|
||||
public CipherString Name { get; set; }
|
||||
public CipherString Value { get; set; }
|
||||
public EncString Name { get; set; }
|
||||
public EncString Value { get; set; }
|
||||
public FieldType Type { get; set; }
|
||||
|
||||
public Task<FieldView> DecryptAsync(string orgId)
|
||||
|
@ -21,7 +21,7 @@ namespace Bit.Core.Models.Domain
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public CipherString Name { get; set; }
|
||||
public EncString Name { get; set; }
|
||||
public DateTime RevisionDate { get; set; }
|
||||
|
||||
public Task<FolderView> DecryptAsync()
|
||||
|
@ -36,24 +36,24 @@ namespace Bit.Core.Models.Domain
|
||||
BuildDomainModel(this, obj, _map, alreadyEncrypted);
|
||||
}
|
||||
|
||||
public CipherString Title { get; set; }
|
||||
public CipherString FirstName { get; set; }
|
||||
public CipherString MiddleName { get; set; }
|
||||
public CipherString LastName { get; set; }
|
||||
public CipherString Address1 { get; set; }
|
||||
public CipherString Address2 { get; set; }
|
||||
public CipherString Address3 { get; set; }
|
||||
public CipherString City { get; set; }
|
||||
public CipherString State { get; set; }
|
||||
public CipherString PostalCode { get; set; }
|
||||
public CipherString Country { get; set; }
|
||||
public CipherString Company { get; set; }
|
||||
public CipherString Email { get; set; }
|
||||
public CipherString Phone { get; set; }
|
||||
public CipherString SSN { get; set; }
|
||||
public CipherString Username { get; set; }
|
||||
public CipherString PassportNumber { get; set; }
|
||||
public CipherString LicenseNumber { get; set; }
|
||||
public EncString Title { get; set; }
|
||||
public EncString FirstName { get; set; }
|
||||
public EncString MiddleName { get; set; }
|
||||
public EncString LastName { get; set; }
|
||||
public EncString Address1 { get; set; }
|
||||
public EncString Address2 { get; set; }
|
||||
public EncString Address3 { get; set; }
|
||||
public EncString City { get; set; }
|
||||
public EncString State { get; set; }
|
||||
public EncString PostalCode { get; set; }
|
||||
public EncString Country { get; set; }
|
||||
public EncString Company { get; set; }
|
||||
public EncString Email { get; set; }
|
||||
public EncString Phone { get; set; }
|
||||
public EncString SSN { get; set; }
|
||||
public EncString Username { get; set; }
|
||||
public EncString PassportNumber { get; set; }
|
||||
public EncString LicenseNumber { get; set; }
|
||||
|
||||
public Task<IdentityView> DecryptAsync(string orgId)
|
||||
{
|
||||
|
@ -24,10 +24,10 @@ namespace Bit.Core.Models.Domain
|
||||
}
|
||||
|
||||
public List<LoginUri> Uris { get; set; }
|
||||
public CipherString Username { get; set; }
|
||||
public CipherString Password { get; set; }
|
||||
public EncString Username { get; set; }
|
||||
public EncString Password { get; set; }
|
||||
public DateTime? PasswordRevisionDate { get; set; }
|
||||
public CipherString Totp { get; set; }
|
||||
public EncString Totp { get; set; }
|
||||
|
||||
public async Task<LoginView> DecryptAsync(string orgId)
|
||||
{
|
||||
|
@ -21,7 +21,7 @@ namespace Bit.Core.Models.Domain
|
||||
BuildDomainModel(this, obj, _map, alreadyEncrypted);
|
||||
}
|
||||
|
||||
public CipherString Uri { get; set; }
|
||||
public EncString Uri { get; set; }
|
||||
public UriMatchType? Match { get; set; }
|
||||
|
||||
public Task<LoginUriView> DecryptAsync(string orgId)
|
||||
|
@ -21,7 +21,7 @@ namespace Bit.Core.Models.Domain
|
||||
LastUsedDate = obj.LastUsedDate.GetValueOrDefault();
|
||||
}
|
||||
|
||||
public CipherString Password { get; set; }
|
||||
public EncString Password { get; set; }
|
||||
public DateTime LastUsedDate { get; set; }
|
||||
|
||||
public Task<PasswordHistoryView> DecryptAsync(string orgId)
|
||||
|
@ -15,11 +15,11 @@ namespace Bit.Core.Models.Domain
|
||||
public string AccessId { get; set; }
|
||||
public string UserId { get; set; }
|
||||
public SendType Type { get; set; }
|
||||
public CipherString Name { get; set; }
|
||||
public CipherString Notes { get; set; }
|
||||
public EncString Name { get; set; }
|
||||
public EncString Notes { get; set; }
|
||||
public SendFile File { get; set; }
|
||||
public SendText Text { get; set; }
|
||||
public CipherString Key { get; set; }
|
||||
public EncString Key { get; set; }
|
||||
public int? MaxAccessCount { get; set; }
|
||||
public int AccessCount { get; set; }
|
||||
public DateTime RevisionDate { get; set; }
|
||||
|
@ -10,7 +10,7 @@ namespace Bit.Core.Models.Domain
|
||||
public string Id { get; set; }
|
||||
public string Size { get; set; }
|
||||
public string SizeName { get; set; }
|
||||
public CipherString FileName { get; set; }
|
||||
public EncString FileName { get; set; }
|
||||
|
||||
public SendFile() : base() { }
|
||||
|
||||
|
@ -8,7 +8,7 @@ namespace Bit.Core.Models.Domain
|
||||
{
|
||||
public class SendText : Domain
|
||||
{
|
||||
public CipherString Text { get; set; }
|
||||
public EncString Text { get; set; }
|
||||
public bool Hidden { get; set; }
|
||||
|
||||
public SendText() : base() { }
|
||||
|
@ -8,6 +8,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
@ -28,9 +29,9 @@ namespace Bit.Core.Services
|
||||
};
|
||||
}
|
||||
|
||||
public async Task Upload(string uri, byte[] data, Func<Task<string>> renewalCallback)
|
||||
public async Task Upload(string uri, EncByteArray data, Func<Task<string>> renewalCallback)
|
||||
{
|
||||
if (data.Length <= MAX_SINGLE_BLOB_UPLOAD_SIZE)
|
||||
if (data?.Buffer?.Length <= MAX_SINGLE_BLOB_UPLOAD_SIZE)
|
||||
{
|
||||
await AzureUploadBlob(uri, data);
|
||||
}
|
||||
@ -40,7 +41,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
private async Task AzureUploadBlob(string uri, byte[] data)
|
||||
private async Task AzureUploadBlob(string uri, EncByteArray data)
|
||||
{
|
||||
using (var requestMessage = new HttpRequestMessage())
|
||||
{
|
||||
@ -51,7 +52,7 @@ namespace Bit.Core.Services
|
||||
requestMessage.Headers.Add("x-ms-version", paramValues["sv"]);
|
||||
requestMessage.Headers.Add("x-ms-blob-type", "BlockBlob");
|
||||
|
||||
requestMessage.Content = new ByteArrayContent(data);
|
||||
requestMessage.Content = new ByteArrayContent(data.Buffer);
|
||||
requestMessage.Version = new Version(1, 0);
|
||||
requestMessage.Method = HttpMethod.Put;
|
||||
requestMessage.RequestUri = uriBuilder.Uri;
|
||||
@ -65,13 +66,13 @@ namespace Bit.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
private async Task AzureUploadBlocks(string uri, byte[] data, Func<Task<string>> renewalFunc)
|
||||
private async Task AzureUploadBlocks(string uri, EncByteArray data, Func<Task<string>> renewalFunc)
|
||||
{
|
||||
_httpClient.Timeout = TimeSpan.FromHours(3);
|
||||
var baseParams = HttpUtility.ParseQueryString(CoreHelpers.GetUri(uri).Query);
|
||||
var blockSize = MaxBlockSize(baseParams["sv"]);
|
||||
var blockIndex = 0;
|
||||
var numBlocks = Math.Ceiling((decimal)data.Length / blockSize);
|
||||
var numBlocks = Math.Ceiling((decimal)data.Buffer.Length / blockSize);
|
||||
var blocksStaged = new List<string>();
|
||||
|
||||
if (numBlocks > MAX_BLOCKS_PER_BLOB)
|
||||
@ -95,7 +96,7 @@ namespace Bit.Core.Services
|
||||
requestMessage.Headers.Add("x-ms-version", baseParams["sv"]);
|
||||
requestMessage.Headers.Add("x-ms-blob-type", "BlockBlob");
|
||||
|
||||
requestMessage.Content = new ByteArrayContent(data.Skip(blockIndex * blockSize).Take(blockSize).ToArray());
|
||||
requestMessage.Content = new ByteArrayContent(data.Buffer.Skip(blockIndex * blockSize).Take(blockSize).ToArray());
|
||||
requestMessage.Version = new Version(1, 0);
|
||||
requestMessage.Method = HttpMethod.Put;
|
||||
requestMessage.RequestUri = blockUriBuilder.Uri;
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Models.Domain;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@ -13,11 +14,11 @@ namespace Bit.Core.Services
|
||||
|
||||
private readonly ApiService _apiService;
|
||||
|
||||
public async Task Upload(string encryptedFileName, byte[] encryptedFileData, Func<MultipartFormDataContent, Task> apiCall)
|
||||
public async Task Upload(string encryptedFileName, EncByteArray encryptedFileData, Func<MultipartFormDataContent, Task> apiCall)
|
||||
{
|
||||
var fd = new MultipartFormDataContent($"--BWMobileFormBoundary{DateTime.UtcNow.Ticks}")
|
||||
{
|
||||
{ new ByteArrayContent(encryptedFileData), "data", encryptedFileName }
|
||||
{ new ByteArrayContent(encryptedFileData.Buffer), "data", encryptedFileName }
|
||||
};
|
||||
|
||||
await apiCall(fd);
|
||||
|
@ -568,7 +568,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
Key = orgEncAttachmentKey.EncryptedString,
|
||||
FileName = encFileName.EncryptedString,
|
||||
FileSize = encFileData.Length,
|
||||
FileSize = encFileData.Buffer.Length,
|
||||
};
|
||||
|
||||
var uploadDataResponse = await _apiService.PostCipherAttachmentAsync(cipher.Id, request);
|
||||
@ -588,12 +588,12 @@ namespace Bit.Core.Services
|
||||
|
||||
[Obsolete("Mar 25 2021: This method has been deprecated in favor of direct uploads. This method still exists for backward compatibility with old server versions.")]
|
||||
private async Task<CipherResponse> LegacyServerAttachmentFileUploadAsync(string cipherId,
|
||||
CipherString encFileName, byte[] encFileData, CipherString key)
|
||||
EncString encFileName, EncByteArray encFileData, EncString key)
|
||||
{
|
||||
var boundary = string.Concat("--BWMobileFormBoundary", DateTime.UtcNow.Ticks);
|
||||
var fd = new MultipartFormDataContent(boundary);
|
||||
fd.Add(new StringContent(key.EncryptedString), "key");
|
||||
fd.Add(new StreamContent(new MemoryStream(encFileData)), "data", encFileName.EncryptedString);
|
||||
fd.Add(new StreamContent(new MemoryStream(encFileData.Buffer)), "data", encFileName.EncryptedString);
|
||||
return await _apiService.PostCipherAttachmentLegacyAsync(cipherId, fd);
|
||||
}
|
||||
|
||||
@ -828,7 +828,7 @@ namespace Bit.Core.Services
|
||||
var boundary = string.Concat("--BWMobileFormBoundary", DateTime.UtcNow.Ticks);
|
||||
var fd = new MultipartFormDataContent(boundary);
|
||||
fd.Add(new StringContent(dataEncKey.Item2.EncryptedString), "key");
|
||||
fd.Add(new StreamContent(new MemoryStream(encData)), "data", encFileName.EncryptedString);
|
||||
fd.Add(new StreamContent(new MemoryStream(encData.Buffer)), "data", encFileName.EncryptedString);
|
||||
await _apiService.PostShareCipherAttachmentAsync(cipherId, attachmentView.Id, fd, organizationId);
|
||||
}
|
||||
|
||||
@ -1037,7 +1037,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
var modelPropInfo = modelType.GetProperty(propName);
|
||||
var modelProp = modelPropInfo.GetValue(model) as string;
|
||||
CipherString val = null;
|
||||
EncString val = null;
|
||||
if (!string.IsNullOrWhiteSpace(modelProp))
|
||||
{
|
||||
val = await _cryptoService.EncryptAsync(modelProp, key);
|
||||
|
@ -148,7 +148,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
byte[] decEncKey = null;
|
||||
var encKeyCipher = new CipherString(encKey);
|
||||
var encKeyCipher = new EncString(encKey);
|
||||
if (encKeyCipher.EncryptionType == EncryptionType.AesCbc256_B64)
|
||||
{
|
||||
decEncKey = await DecryptToBytesAsync(encKeyCipher, key);
|
||||
@ -205,7 +205,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
return null;
|
||||
}
|
||||
_privateKey = await DecryptToBytesAsync(new CipherString(encPrivateKey), null);
|
||||
_privateKey = await DecryptToBytesAsync(new EncString(encPrivateKey), null);
|
||||
return _privateKey;
|
||||
}
|
||||
|
||||
@ -389,7 +389,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
public async Task<SymmetricCryptoKey> MakeKeyFromPinAsync(string pin, string salt,
|
||||
KdfType kdf, int kdfIterations, CipherString protectedKeyCs = null)
|
||||
KdfType kdf, int kdfIterations, EncString protectedKeyCs = null)
|
||||
{
|
||||
if (protectedKeyCs == null)
|
||||
{
|
||||
@ -398,27 +398,27 @@ namespace Bit.Core.Services
|
||||
{
|
||||
throw new Exception("No PIN protected key found.");
|
||||
}
|
||||
protectedKeyCs = new CipherString(pinProtectedKey);
|
||||
protectedKeyCs = new EncString(pinProtectedKey);
|
||||
}
|
||||
var pinKey = await MakePinKeyAysnc(pin, salt, kdf, kdfIterations);
|
||||
var decKey = await DecryptToBytesAsync(protectedKeyCs, pinKey);
|
||||
return new SymmetricCryptoKey(decKey);
|
||||
}
|
||||
|
||||
public async Task<Tuple<CipherString, SymmetricCryptoKey>> MakeShareKeyAsync()
|
||||
public async Task<Tuple<EncString, SymmetricCryptoKey>> MakeShareKeyAsync()
|
||||
{
|
||||
var shareKey = await _cryptoFunctionService.RandomBytesAsync(64);
|
||||
var publicKey = await GetPublicKeyAsync();
|
||||
var encShareKey = await RsaEncryptAsync(shareKey, publicKey);
|
||||
return new Tuple<CipherString, SymmetricCryptoKey>(encShareKey, new SymmetricCryptoKey(shareKey));
|
||||
return new Tuple<EncString, SymmetricCryptoKey>(encShareKey, new SymmetricCryptoKey(shareKey));
|
||||
}
|
||||
|
||||
public async Task<Tuple<string, CipherString>> MakeKeyPairAsync(SymmetricCryptoKey key = null)
|
||||
public async Task<Tuple<string, EncString>> MakeKeyPairAsync(SymmetricCryptoKey key = null)
|
||||
{
|
||||
var keyPair = await _cryptoFunctionService.RsaGenerateKeyPairAsync(2048);
|
||||
var publicB64 = Convert.ToBase64String(keyPair.Item1);
|
||||
var privateEnc = await EncryptAsync(keyPair.Item2, key);
|
||||
return new Tuple<string, CipherString>(publicB64, privateEnc);
|
||||
return new Tuple<string, EncString>(publicB64, privateEnc);
|
||||
}
|
||||
|
||||
public async Task<SymmetricCryptoKey> MakePinKeyAysnc(string pin, string salt, KdfType kdf, int kdfIterations)
|
||||
@ -447,20 +447,20 @@ namespace Bit.Core.Services
|
||||
return Convert.ToBase64String(hash);
|
||||
}
|
||||
|
||||
public async Task<Tuple<SymmetricCryptoKey, CipherString>> MakeEncKeyAsync(SymmetricCryptoKey key)
|
||||
public async Task<Tuple<SymmetricCryptoKey, EncString>> MakeEncKeyAsync(SymmetricCryptoKey key)
|
||||
{
|
||||
var theKey = await GetKeyForEncryptionAsync(key);
|
||||
var encKey = await _cryptoFunctionService.RandomBytesAsync(64);
|
||||
return await BuildEncKeyAsync(theKey, encKey);
|
||||
}
|
||||
|
||||
public async Task<Tuple<SymmetricCryptoKey, CipherString>> RemakeEncKeyAsync(SymmetricCryptoKey key)
|
||||
public async Task<Tuple<SymmetricCryptoKey, EncString>> RemakeEncKeyAsync(SymmetricCryptoKey key)
|
||||
{
|
||||
var encKey = await GetEncKeyAsync();
|
||||
return await BuildEncKeyAsync(key, encKey.Key);
|
||||
}
|
||||
|
||||
public async Task<CipherString> EncryptAsync(string plainValue, SymmetricCryptoKey key = null)
|
||||
public async Task<EncString> EncryptAsync(string plainValue, SymmetricCryptoKey key = null)
|
||||
{
|
||||
if (plainValue == null)
|
||||
{
|
||||
@ -469,7 +469,7 @@ namespace Bit.Core.Services
|
||||
return await EncryptAsync(Encoding.UTF8.GetBytes(plainValue), key);
|
||||
}
|
||||
|
||||
public async Task<CipherString> EncryptAsync(byte[] plainValue, SymmetricCryptoKey key = null)
|
||||
public async Task<EncString> EncryptAsync(byte[] plainValue, SymmetricCryptoKey key = null)
|
||||
{
|
||||
if (plainValue == null)
|
||||
{
|
||||
@ -479,10 +479,10 @@ namespace Bit.Core.Services
|
||||
var iv = Convert.ToBase64String(encObj.Iv);
|
||||
var data = Convert.ToBase64String(encObj.Data);
|
||||
var mac = encObj.Mac != null ? Convert.ToBase64String(encObj.Mac) : null;
|
||||
return new CipherString(encObj.Key.EncType, data, iv, mac);
|
||||
return new EncString(encObj.Key.EncType, data, iv, mac);
|
||||
}
|
||||
|
||||
public async Task<byte[]> EncryptToBytesAsync(byte[] plainValue, SymmetricCryptoKey key = null)
|
||||
public async Task<EncByteArray> EncryptToBytesAsync(byte[] plainValue, SymmetricCryptoKey key = null)
|
||||
{
|
||||
var encValue = await AesEncryptAsync(plainValue, key);
|
||||
var macLen = 0;
|
||||
@ -498,10 +498,10 @@ namespace Bit.Core.Services
|
||||
Buffer.BlockCopy(encValue.Mac, 0, encBytes, 1 + encValue.Iv.Length, encValue.Mac.Length);
|
||||
}
|
||||
Buffer.BlockCopy(encValue.Data, 0, encBytes, 1 + encValue.Iv.Length + macLen, encValue.Data.Length);
|
||||
return encBytes;
|
||||
return new EncByteArray(encBytes);
|
||||
}
|
||||
|
||||
public async Task<CipherString> RsaEncryptAsync(byte[] data, byte[] publicKey = null)
|
||||
public async Task<EncString> RsaEncryptAsync(byte[] data, byte[] publicKey = null)
|
||||
{
|
||||
if (publicKey == null)
|
||||
{
|
||||
@ -512,21 +512,21 @@ namespace Bit.Core.Services
|
||||
throw new Exception("Public key unavailable.");
|
||||
}
|
||||
var encBytes = await _cryptoFunctionService.RsaEncryptAsync(data, publicKey, CryptoHashAlgorithm.Sha1);
|
||||
return new CipherString(EncryptionType.Rsa2048_OaepSha1_B64, Convert.ToBase64String(encBytes));
|
||||
return new EncString(EncryptionType.Rsa2048_OaepSha1_B64, Convert.ToBase64String(encBytes));
|
||||
}
|
||||
|
||||
public async Task<byte[]> DecryptToBytesAsync(CipherString cipherString, SymmetricCryptoKey key = null)
|
||||
public async Task<byte[]> DecryptToBytesAsync(EncString encString, SymmetricCryptoKey key = null)
|
||||
{
|
||||
var iv = Convert.FromBase64String(cipherString.Iv);
|
||||
var data = Convert.FromBase64String(cipherString.Data);
|
||||
var mac = !string.IsNullOrWhiteSpace(cipherString.Mac) ? Convert.FromBase64String(cipherString.Mac) : null;
|
||||
return await AesDecryptToBytesAsync(cipherString.EncryptionType, data, iv, mac, key);
|
||||
var iv = Convert.FromBase64String(encString.Iv);
|
||||
var data = Convert.FromBase64String(encString.Data);
|
||||
var mac = !string.IsNullOrWhiteSpace(encString.Mac) ? Convert.FromBase64String(encString.Mac) : null;
|
||||
return await AesDecryptToBytesAsync(encString.EncryptionType, data, iv, mac, key);
|
||||
}
|
||||
|
||||
public async Task<string> DecryptToUtf8Async(CipherString cipherString, SymmetricCryptoKey key = null)
|
||||
public async Task<string> DecryptToUtf8Async(EncString encString, SymmetricCryptoKey key = null)
|
||||
{
|
||||
return await AesDecryptToUtf8Async(cipherString.EncryptionType, cipherString.Data,
|
||||
cipherString.Iv, cipherString.Mac, key);
|
||||
return await AesDecryptToUtf8Async(encString.EncryptionType, encString.Data,
|
||||
encString.Iv, encString.Mac, key);
|
||||
}
|
||||
|
||||
public async Task<byte[]> DecryptFromBytesAsync(byte[] encBytes, SymmetricCryptoKey key)
|
||||
@ -809,10 +809,10 @@ namespace Bit.Core.Services
|
||||
return phrase;
|
||||
}
|
||||
|
||||
private async Task<Tuple<SymmetricCryptoKey, CipherString>> BuildEncKeyAsync(SymmetricCryptoKey key,
|
||||
private async Task<Tuple<SymmetricCryptoKey, EncString>> BuildEncKeyAsync(SymmetricCryptoKey key,
|
||||
byte[] encKey)
|
||||
{
|
||||
CipherString encKeyEnc = null;
|
||||
EncString encKeyEnc = null;
|
||||
if (key.Key.Length == 32)
|
||||
{
|
||||
var newKey = await StretchKeyAsync(key);
|
||||
@ -826,7 +826,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
throw new Exception("Invalid key size.");
|
||||
}
|
||||
return new Tuple<SymmetricCryptoKey, CipherString>(new SymmetricCryptoKey(encKey), encKeyEnc);
|
||||
return new Tuple<SymmetricCryptoKey, EncString>(new SymmetricCryptoKey(encKey), encKeyEnc);
|
||||
}
|
||||
|
||||
private class EncryptedObject
|
||||
|
@ -20,7 +20,7 @@ namespace Bit.Core.Services {
|
||||
private readonly ApiService _apiService;
|
||||
|
||||
public async Task UploadCipherAttachmentFileAsync(AttachmentUploadDataResponse uploadData,
|
||||
string encryptedFileName, byte[] encryptedFileData)
|
||||
string encryptedFileName, EncByteArray encryptedFileData)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -48,7 +48,7 @@ namespace Bit.Core.Services {
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UploadSendFileAsync(SendFileUploadDataResponse uploadData, CipherString fileName, byte[] encryptedFileData)
|
||||
public async Task UploadSendFileAsync(SendFileUploadDataResponse uploadData, EncString fileName, EncByteArray encryptedFileData)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -633,7 +633,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
var tasks = history.Select(async item =>
|
||||
{
|
||||
var decrypted = await _cryptoService.DecryptToUtf8Async(new CipherString(item.Password));
|
||||
var decrypted = await _cryptoService.DecryptToUtf8Async(new EncString(item.Password));
|
||||
return new GeneratedPasswordHistory
|
||||
{
|
||||
Password = decrypted,
|
||||
|
@ -81,7 +81,7 @@ namespace Bit.Core.Services
|
||||
await DeleteAsync(id);
|
||||
}
|
||||
|
||||
public async Task<(Send send, byte[] encryptedFileData)> EncryptAsync(SendView model, byte[] fileData,
|
||||
public async Task<(Send send, EncByteArray encryptedFileData)> EncryptAsync(SendView model, byte[] fileData,
|
||||
string password, SymmetricCryptoKey key = null)
|
||||
{
|
||||
if (model.Key == null)
|
||||
@ -103,7 +103,7 @@ namespace Bit.Core.Services
|
||||
Notes = await _cryptoService.EncryptAsync(model.Notes, model.CryptoKey),
|
||||
HideEmail = model.HideEmail
|
||||
};
|
||||
byte[] encryptedFileData = null;
|
||||
EncByteArray encryptedFileData = null;
|
||||
|
||||
if (password != null)
|
||||
{
|
||||
@ -197,9 +197,9 @@ namespace Bit.Core.Services
|
||||
_decryptedSendsCache = null;
|
||||
}
|
||||
|
||||
public async Task<string> SaveWithServerAsync(Send send, byte[] encryptedFileData)
|
||||
public async Task<string> SaveWithServerAsync(Send send, EncByteArray encryptedFileData)
|
||||
{
|
||||
var request = new SendRequest(send, encryptedFileData?.LongLength);
|
||||
var request = new SendRequest(send, encryptedFileData?.Buffer?.LongLength);
|
||||
SendResponse response = default;
|
||||
if (send.Id == null)
|
||||
{
|
||||
@ -243,11 +243,11 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
[Obsolete("Mar 25 2021: This method has been deprecated in favor of direct uploads. This method still exists for backward compatibility with old server versions.")]
|
||||
private async Task<SendResponse> LegacyServerSendFileUpload(SendRequest request, Send send, byte[] encryptedFileData) {
|
||||
private async Task<SendResponse> LegacyServerSendFileUpload(SendRequest request, Send send, EncByteArray encryptedFileData) {
|
||||
var fd = new MultipartFormDataContent($"--BWMobileFormBoundary{DateTime.UtcNow.Ticks}")
|
||||
{
|
||||
{ new StringContent(JsonConvert.SerializeObject(request)), "model" },
|
||||
{ new ByteArrayContent(encryptedFileData), "data", send.File.FileName.EncryptedString }
|
||||
{ new ByteArrayContent(encryptedFileData.Buffer), "data", send.File.FileName.EncryptedString }
|
||||
};
|
||||
|
||||
return await _apiService.PostSendFileAsync(fd);
|
||||
|
@ -48,7 +48,7 @@ namespace Bit.Core.Services
|
||||
_loggedOutCallback = loggedOutCallback;
|
||||
}
|
||||
|
||||
public CipherString PinProtectedKey { get; set; } = null;
|
||||
public EncString PinProtectedKey { get; set; } = null;
|
||||
public bool BiometricLocked { get; set; } = true;
|
||||
|
||||
public async Task<bool> IsLockedAsync()
|
||||
|
@ -140,7 +140,7 @@ namespace Bit.iOS.Core.Controllers
|
||||
_vaultTimeoutService.PinProtectedKey);
|
||||
var encKey = await _cryptoService.GetEncKeyAsync(key);
|
||||
var protectedPin = await _storageService.GetAsync<string>(Bit.Core.Constants.ProtectedPin);
|
||||
var decPin = await _cryptoService.DecryptToUtf8Async(new CipherString(protectedPin), encKey);
|
||||
var decPin = await _cryptoService.DecryptToUtf8Async(new EncString(protectedPin), encKey);
|
||||
failed = decPin != inputtedValue;
|
||||
if (!failed)
|
||||
{
|
||||
@ -191,7 +191,7 @@ namespace Bit.iOS.Core.Controllers
|
||||
{
|
||||
var protectedPin = await _storageService.GetAsync<string>(Bit.Core.Constants.ProtectedPin);
|
||||
var encKey = await _cryptoService.GetEncKeyAsync(key2);
|
||||
var decPin = await _cryptoService.DecryptToUtf8Async(new CipherString(protectedPin), encKey);
|
||||
var decPin = await _cryptoService.DecryptToUtf8Async(new EncString(protectedPin), encKey);
|
||||
var pinKey = await _cryptoService.MakePinKeyAysnc(decPin, email,
|
||||
kdf.GetValueOrDefault(KdfType.PBKDF2_SHA256), kdfIterations.GetValueOrDefault(5000));
|
||||
_vaultTimeoutService.PinProtectedKey = await _cryptoService.EncryptAsync(key2.Key, pinKey);
|
||||
|
@ -40,17 +40,17 @@ namespace Bit.Core.Test.Models.Domain
|
||||
var prefix = "decrypted_";
|
||||
var prefixBytes = Encoding.UTF8.GetBytes(prefix);
|
||||
|
||||
cryptoService.DecryptToBytesAsync(Arg.Any<CipherString>(), Arg.Any<SymmetricCryptoKey>())
|
||||
.Returns(info => prefixBytes.Concat(Encoding.UTF8.GetBytes(((CipherString)info[0]).EncryptedString)).ToArray());
|
||||
cryptoService.DecryptToBytesAsync(Arg.Any<EncString>(), Arg.Any<SymmetricCryptoKey>())
|
||||
.Returns(info => prefixBytes.Concat(Encoding.UTF8.GetBytes(((EncString)info[0]).EncryptedString)).ToArray());
|
||||
cryptoService.DecryptFromBytesAsync(Arg.Any<byte[]>(), Arg.Any<SymmetricCryptoKey>())
|
||||
.Returns(info => prefixBytes.Concat((byte[])info[0]).ToArray());
|
||||
cryptoService.DecryptToUtf8Async(Arg.Any<CipherString>(), Arg.Any<SymmetricCryptoKey>())
|
||||
.Returns(info => $"{prefix}{((CipherString)info[0]).EncryptedString}");
|
||||
cryptoService.DecryptToUtf8Async(Arg.Any<EncString>(), Arg.Any<SymmetricCryptoKey>())
|
||||
.Returns(info => $"{prefix}{((EncString)info[0]).EncryptedString}");
|
||||
ServiceContainer.Register("cryptoService", cryptoService);
|
||||
|
||||
var view = await send.DecryptAsync();
|
||||
|
||||
string expectedDecryptionString(CipherString encryptedString) =>
|
||||
string expectedDecryptionString(EncString encryptedString) =>
|
||||
encryptedString?.EncryptedString == null ? null : $"{prefix}{encryptedString.EncryptedString}";
|
||||
|
||||
TestHelper.AssertPropertyEqual(send, view, "Name", "Notes", "File", "Text", "Key", "UserId");
|
||||
|
@ -22,17 +22,17 @@ namespace Bit.Core.Test.Services
|
||||
{
|
||||
[Theory, UserCipherAutoData]
|
||||
public async Task SaveWithServerAsync_PrefersFileUploadService(SutProvider<CipherService> sutProvider,
|
||||
Cipher cipher, string fileName, byte[] data, AttachmentUploadDataResponse uploadDataResponse, CipherString encKey)
|
||||
Cipher cipher, string fileName, EncByteArray data, AttachmentUploadDataResponse uploadDataResponse, EncString encKey)
|
||||
{
|
||||
sutProvider.GetDependency<ICryptoService>().EncryptAsync(fileName, Arg.Any<SymmetricCryptoKey>())
|
||||
.Returns(new CipherString(fileName));
|
||||
sutProvider.GetDependency<ICryptoService>().EncryptToBytesAsync(data, Arg.Any<SymmetricCryptoKey>())
|
||||
.Returns(new EncString(fileName));
|
||||
sutProvider.GetDependency<ICryptoService>().EncryptToBytesAsync(data.Buffer, Arg.Any<SymmetricCryptoKey>())
|
||||
.Returns(data);
|
||||
sutProvider.GetDependency<ICryptoService>().MakeEncKeyAsync(Arg.Any<SymmetricCryptoKey>()).Returns(new Tuple<SymmetricCryptoKey, CipherString>(null, encKey));
|
||||
sutProvider.GetDependency<ICryptoService>().MakeEncKeyAsync(Arg.Any<SymmetricCryptoKey>()).Returns(new Tuple<SymmetricCryptoKey, EncString>(null, encKey));
|
||||
sutProvider.GetDependency<IApiService>().PostCipherAttachmentAsync(cipher.Id, Arg.Any<AttachmentRequest>())
|
||||
.Returns(uploadDataResponse);
|
||||
|
||||
await sutProvider.Sut.SaveAttachmentRawWithServerAsync(cipher, fileName, data);
|
||||
await sutProvider.Sut.SaveAttachmentRawWithServerAsync(cipher, fileName, data.Buffer);
|
||||
|
||||
await sutProvider.GetDependency<IFileUploadService>().Received(1)
|
||||
.UploadCipherAttachmentFileAsync(uploadDataResponse, fileName, data);
|
||||
@ -42,20 +42,20 @@ namespace Bit.Core.Test.Services
|
||||
[InlineUserCipherAutoData(HttpStatusCode.NotFound)]
|
||||
[InlineUserCipherAutoData(HttpStatusCode.MethodNotAllowed)]
|
||||
public async Task SaveWithServerAsync_FallsBackToLegacyFormData(HttpStatusCode statusCode,
|
||||
SutProvider<CipherService> sutProvider, Cipher cipher, string fileName, byte[] data,
|
||||
CipherResponse response, CipherString encKey)
|
||||
SutProvider<CipherService> sutProvider, Cipher cipher, string fileName, EncByteArray data,
|
||||
CipherResponse response, EncString encKey)
|
||||
{
|
||||
sutProvider.GetDependency<ICryptoService>().EncryptAsync(fileName, Arg.Any<SymmetricCryptoKey>())
|
||||
.Returns(new CipherString(fileName));
|
||||
sutProvider.GetDependency<ICryptoService>().EncryptToBytesAsync(data, Arg.Any<SymmetricCryptoKey>())
|
||||
.Returns(new EncString(fileName));
|
||||
sutProvider.GetDependency<ICryptoService>().EncryptToBytesAsync(data.Buffer, Arg.Any<SymmetricCryptoKey>())
|
||||
.Returns(data);
|
||||
sutProvider.GetDependency<ICryptoService>().MakeEncKeyAsync(Arg.Any<SymmetricCryptoKey>()).Returns(new Tuple<SymmetricCryptoKey, CipherString>(null, encKey));
|
||||
sutProvider.GetDependency<ICryptoService>().MakeEncKeyAsync(Arg.Any<SymmetricCryptoKey>()).Returns(new Tuple<SymmetricCryptoKey, EncString>(null, encKey));
|
||||
sutProvider.GetDependency<IApiService>().PostCipherAttachmentAsync(cipher.Id, Arg.Any<AttachmentRequest>())
|
||||
.Throws(new ApiException(new ErrorResponse {StatusCode = statusCode}));
|
||||
sutProvider.GetDependency<IApiService>().PostCipherAttachmentLegacyAsync(cipher.Id, Arg.Any<MultipartFormDataContent>())
|
||||
.Returns(response);
|
||||
|
||||
await sutProvider.Sut.SaveAttachmentRawWithServerAsync(cipher, fileName, data);
|
||||
await sutProvider.Sut.SaveAttachmentRawWithServerAsync(cipher, fileName, data.Buffer);
|
||||
|
||||
await sutProvider.GetDependency<IApiService>().Received(1)
|
||||
.PostCipherAttachmentLegacyAsync(cipher.Id, Arg.Any<MultipartFormDataContent>());
|
||||
@ -63,20 +63,20 @@ namespace Bit.Core.Test.Services
|
||||
|
||||
[Theory, UserCipherAutoData]
|
||||
public async Task SaveWithServerAsync_ThrowsOnBadRequestApiException(SutProvider<CipherService> sutProvider,
|
||||
Cipher cipher, string fileName, byte[] data, CipherString encKey)
|
||||
Cipher cipher, string fileName, EncByteArray data, EncString encKey)
|
||||
{
|
||||
sutProvider.GetDependency<ICryptoService>().EncryptAsync(fileName, Arg.Any<SymmetricCryptoKey>())
|
||||
.Returns(new CipherString(fileName));
|
||||
sutProvider.GetDependency<ICryptoService>().EncryptToBytesAsync(data, Arg.Any<SymmetricCryptoKey>())
|
||||
.Returns(new EncString(fileName));
|
||||
sutProvider.GetDependency<ICryptoService>().EncryptToBytesAsync(data.Buffer, Arg.Any<SymmetricCryptoKey>())
|
||||
.Returns(data);
|
||||
sutProvider.GetDependency<ICryptoService>().MakeEncKeyAsync(Arg.Any<SymmetricCryptoKey>())
|
||||
.Returns(new Tuple<SymmetricCryptoKey, CipherString>(null, encKey));
|
||||
.Returns(new Tuple<SymmetricCryptoKey, EncString>(null, encKey));
|
||||
var expectedException = new ApiException(new ErrorResponse { StatusCode = HttpStatusCode.BadRequest });
|
||||
sutProvider.GetDependency<IApiService>().PostCipherAttachmentAsync(cipher.Id, Arg.Any<AttachmentRequest>())
|
||||
.Throws(expectedException);
|
||||
|
||||
var actualException = await Assert.ThrowsAsync<ApiException>(async () =>
|
||||
await sutProvider.Sut.SaveAttachmentRawWithServerAsync(cipher, fileName, data));
|
||||
await sutProvider.Sut.SaveAttachmentRawWithServerAsync(cipher, fileName, data.Buffer));
|
||||
|
||||
Assert.Equal(expectedException.Error.StatusCode, actualException.Error.StatusCode);
|
||||
}
|
||||
@ -90,7 +90,7 @@ namespace Bit.Core.Test.Services
|
||||
|
||||
await sutProvider.Sut.DownloadAndDecryptAttachmentAsync(cipherId, attachment, null);
|
||||
|
||||
sutProvider.GetDependency<IApiService>().Received(1).GetAttachmentData(cipherId, attachment.Id);
|
||||
await sutProvider.GetDependency<IApiService>().Received(1).GetAttachmentData(cipherId, attachment.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,14 +175,14 @@ namespace Bit.Core.Test.Services
|
||||
sutProvider.GetDependency<IUserService>().GetUserIdAsync().Returns(userId);
|
||||
sutProvider.GetDependency<IApiService>().PostSendAsync(Arg.Any<SendRequest>()).Returns(response);
|
||||
|
||||
var fileContentBytes = Encoding.UTF8.GetBytes("This is the file content");
|
||||
var fileContentBytes = new EncByteArray(Encoding.UTF8.GetBytes("This is the file content"));
|
||||
|
||||
await sutProvider.Sut.SaveWithServerAsync(send, fileContentBytes);
|
||||
|
||||
Predicate<SendRequest> sendRequestPredicate = r =>
|
||||
{
|
||||
// Note Send -> SendRequest tested in SendRequestTests
|
||||
TestHelper.AssertPropertyEqual(new SendRequest(send, fileContentBytes?.LongLength), r);
|
||||
TestHelper.AssertPropertyEqual(new SendRequest(send, fileContentBytes.Buffer?.LongLength), r);
|
||||
return true;
|
||||
};
|
||||
|
||||
@ -208,7 +208,7 @@ namespace Bit.Core.Test.Services
|
||||
sutProvider.GetDependency<IUserService>().GetUserIdAsync().Returns(userId);
|
||||
sutProvider.GetDependency<IApiService>().PostFileTypeSendAsync(Arg.Any<SendRequest>()).Returns(response);
|
||||
|
||||
var fileContentBytes = Encoding.UTF8.GetBytes("This is the file content");
|
||||
var fileContentBytes = new EncByteArray(Encoding.UTF8.GetBytes("This is the file content"));
|
||||
|
||||
await sutProvider.Sut.SaveWithServerAsync(send, fileContentBytes);
|
||||
|
||||
@ -233,7 +233,7 @@ namespace Bit.Core.Test.Services
|
||||
sutProvider.GetDependency<IApiService>().PostFileTypeSendAsync(Arg.Any<SendRequest>()).Throws(new ApiException(error));
|
||||
sutProvider.GetDependency<IApiService>().PostSendFileAsync(Arg.Any<MultipartFormDataContent>()).Returns(response);
|
||||
|
||||
var fileContentBytes = Encoding.UTF8.GetBytes("This is the file content");
|
||||
var fileContentBytes = new EncByteArray(Encoding.UTF8.GetBytes("This is the file content"));
|
||||
|
||||
await sutProvider.Sut.SaveWithServerAsync(send, fileContentBytes);
|
||||
|
||||
@ -339,12 +339,12 @@ namespace Bit.Core.Test.Services
|
||||
|
||||
byte[] getPbkdf(string password, byte[] key) =>
|
||||
prefixBytes.Concat(Encoding.UTF8.GetBytes(password)).Concat(key).ToArray();
|
||||
CipherString encryptBytes(byte[] secret, SymmetricCryptoKey key) =>
|
||||
new CipherString($"{prefix}{Convert.ToBase64String(secret)}{Convert.ToBase64String(key.Key)}");
|
||||
CipherString encrypt(string secret, SymmetricCryptoKey key) =>
|
||||
new CipherString($"{prefix}{secret}{Convert.ToBase64String(key.Key)}");
|
||||
byte[] encryptFileBytes(byte[] secret, SymmetricCryptoKey key) =>
|
||||
secret.Concat(key.Key).ToArray();
|
||||
EncString encryptBytes(byte[] secret, SymmetricCryptoKey key) =>
|
||||
new EncString($"{prefix}{Convert.ToBase64String(secret)}{Convert.ToBase64String(key.Key)}");
|
||||
EncString encrypt(string secret, SymmetricCryptoKey key) =>
|
||||
new EncString($"{prefix}{secret}{Convert.ToBase64String(key.Key)}");
|
||||
EncByteArray encryptFileBytes(byte[] secret, SymmetricCryptoKey key) =>
|
||||
new EncByteArray(secret.Concat(key.Key).ToArray());
|
||||
|
||||
sutProvider.GetDependency<ICryptoFunctionService>().Pbkdf2Async(Arg.Any<string>(), Arg.Any<byte[]>(), Arg.Any<CryptoHashAlgorithm>(), Arg.Any<int>())
|
||||
.Returns(info => getPbkdf((string)info[0], (byte[])info[1]));
|
||||
@ -374,7 +374,7 @@ namespace Bit.Core.Test.Services
|
||||
case SendType.File:
|
||||
// Only set filename
|
||||
TestHelper.AssertPropertyEqual(encrypt(view.File.FileName, view.CryptoKey), send.File.FileName);
|
||||
Assert.Equal(encryptFileBytes(fileData, view.CryptoKey), encryptedFileData);
|
||||
Assert.Equal(encryptFileBytes(fileData, view.CryptoKey).Buffer, encryptedFileData.Buffer);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Untested send type");
|
||||
|
Loading…
Reference in New Issue
Block a user