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