mirror of
https://github.com/bitwarden/mobile
synced 2026-02-14 07:13:18 +00:00
PM-115 Fix attachment encryption on new cipher item encryption model
This commit is contained in:
@@ -123,7 +123,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
await _deviceActionService.ShowLoadingAsync(AppResources.Saving);
|
||||
_cipherDomain = await _cipherService.SaveAttachmentRawWithServerAsync(
|
||||
_cipherDomain, FileName, FileData);
|
||||
_cipherDomain, Cipher, FileName, FileData);
|
||||
Cipher = await _cipherDomain.DecryptAsync();
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
_platformUtilsService.ShowToast("success", null, AppResources.AttachementAdded);
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Bit.Core.Abstractions
|
||||
Task<Cipher> GetAsync(string id);
|
||||
Task<CipherView> GetLastUsedForUrlAsync(string url);
|
||||
Task ReplaceAsync(Dictionary<string, CipherData> ciphers);
|
||||
Task<Cipher> SaveAttachmentRawWithServerAsync(Cipher cipher, string filename, byte[] data);
|
||||
Task<Cipher> SaveAttachmentRawWithServerAsync(Cipher cipher, CipherView cipherView, string filename, byte[] data);
|
||||
Task SaveCollectionsWithServerAsync(Cipher cipher);
|
||||
Task SaveNeverDomainAsync(string domain);
|
||||
Task SaveWithServerAsync(Cipher cipher);
|
||||
|
||||
@@ -597,11 +597,12 @@ namespace Bit.Core.Services
|
||||
await UpsertAsync(data);
|
||||
}
|
||||
|
||||
public async Task<Cipher> SaveAttachmentRawWithServerAsync(Cipher cipher, string filename, byte[] data)
|
||||
public async Task<Cipher> SaveAttachmentRawWithServerAsync(Cipher cipher, CipherView cipherView, string filename, byte[] data)
|
||||
{
|
||||
var orgKey = await _cryptoService.GetOrgKeyAsync(cipher.OrganizationId);
|
||||
var encFileName = await _cryptoService.EncryptAsync(filename, orgKey);
|
||||
var (attachmentKey, orgEncAttachmentKey) = await _cryptoService.MakeEncKeyAsync(orgKey);
|
||||
var key = await UpdateCipherAndGetCipherKeyAsync(cipher, cipherView, orgKey);
|
||||
var encFileName = await _cryptoService.EncryptAsync(filename, key);
|
||||
var (attachmentKey, encAttachmentKey) = await _cryptoService.MakeEncKeyAsync(key);
|
||||
var encFileData = await _cryptoService.EncryptToBytesAsync(data, attachmentKey);
|
||||
|
||||
CipherResponse response;
|
||||
@@ -609,7 +610,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
var request = new AttachmentRequest
|
||||
{
|
||||
Key = orgEncAttachmentKey.EncryptedString,
|
||||
Key = encAttachmentKey.EncryptedString,
|
||||
FileName = encFileName.EncryptedString,
|
||||
FileSize = encFileData.Buffer.Length,
|
||||
};
|
||||
@@ -621,7 +622,7 @@ namespace Bit.Core.Services
|
||||
}
|
||||
catch (ApiException e) when (e.Error.StatusCode == System.Net.HttpStatusCode.NotFound || e.Error.StatusCode == System.Net.HttpStatusCode.MethodNotAllowed)
|
||||
{
|
||||
response = await LegacyServerAttachmentFileUploadAsync(cipher.Id, encFileName, encFileData, orgEncAttachmentKey);
|
||||
response = await LegacyServerAttachmentFileUploadAsync(cipher.Id, encFileName, encFileData, encAttachmentKey);
|
||||
}
|
||||
|
||||
var userId = await _stateService.GetActiveUserIdAsync();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using AutoFixture;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
|
||||
@@ -26,16 +28,36 @@ namespace Bit.Core.Test.AutoFixture
|
||||
}
|
||||
}
|
||||
|
||||
internal class UserCipherView : ICustomization
|
||||
{
|
||||
public void Customize(IFixture fixture)
|
||||
{
|
||||
byte[] getRandomBytes(int size)
|
||||
{
|
||||
Random random = new Random();
|
||||
|
||||
byte[] bytes = new byte[size];
|
||||
random.NextBytes(bytes);
|
||||
return bytes;
|
||||
};
|
||||
|
||||
fixture.Customize<CipherView>(composer => composer
|
||||
.Without(c => c.OrganizationId)
|
||||
.Without(c => c.Attachments)
|
||||
.With(c => c.Key, new SymmetricCryptoKey(getRandomBytes(32), Enums.EncryptionType.AesCbc128_HmacSha256_B64)));
|
||||
}
|
||||
}
|
||||
|
||||
internal class UserCipherAutoDataAttribute : CustomAutoDataAttribute
|
||||
{
|
||||
public UserCipherAutoDataAttribute() : base(new SutProviderCustomization(),
|
||||
new UserCipher())
|
||||
new UserCipher(), new UserCipherView())
|
||||
{ }
|
||||
}
|
||||
internal class InlineUserCipherAutoDataAttribute : InlineCustomAutoDataAttribute
|
||||
{
|
||||
public InlineUserCipherAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
|
||||
typeof(UserCipher) }, values)
|
||||
typeof(UserCipher), typeof(UserCipherView) }, values)
|
||||
{ }
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Bit.Core.Test.Services
|
||||
{
|
||||
[Theory, UserCipherAutoData]
|
||||
public async Task SaveWithServerAsync_PrefersFileUploadService(SutProvider<CipherService> sutProvider,
|
||||
Cipher cipher, string fileName, EncByteArray data, AttachmentUploadDataResponse uploadDataResponse, EncString encKey)
|
||||
Cipher cipher, CipherView cipherView, string fileName, EncByteArray data, AttachmentUploadDataResponse uploadDataResponse, EncString encKey)
|
||||
{
|
||||
var encFileName = new EncString(fileName);
|
||||
sutProvider.GetDependency<ICryptoService>().EncryptAsync(fileName, Arg.Any<SymmetricCryptoKey>())
|
||||
@@ -33,7 +33,7 @@ namespace Bit.Core.Test.Services
|
||||
sutProvider.GetDependency<IApiService>().PostCipherAttachmentAsync(cipher.Id, Arg.Any<AttachmentRequest>())
|
||||
.Returns(uploadDataResponse);
|
||||
|
||||
await sutProvider.Sut.SaveAttachmentRawWithServerAsync(cipher, fileName, data.Buffer);
|
||||
await sutProvider.Sut.SaveAttachmentRawWithServerAsync(cipher, cipherView, fileName, data.Buffer);
|
||||
|
||||
await sutProvider.GetDependency<IFileUploadService>().Received(1)
|
||||
.UploadCipherAttachmentFileAsync(uploadDataResponse, encFileName, data);
|
||||
@@ -43,7 +43,7 @@ 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, EncByteArray data,
|
||||
SutProvider<CipherService> sutProvider, Cipher cipher, CipherView cipherView, string fileName, EncByteArray data,
|
||||
CipherResponse response, EncString encKey)
|
||||
{
|
||||
sutProvider.GetDependency<ICryptoService>().EncryptAsync(fileName, Arg.Any<SymmetricCryptoKey>())
|
||||
@@ -56,7 +56,7 @@ namespace Bit.Core.Test.Services
|
||||
sutProvider.GetDependency<IApiService>().PostCipherAttachmentLegacyAsync(cipher.Id, Arg.Any<MultipartFormDataContent>())
|
||||
.Returns(response);
|
||||
|
||||
await sutProvider.Sut.SaveAttachmentRawWithServerAsync(cipher, fileName, data.Buffer);
|
||||
await sutProvider.Sut.SaveAttachmentRawWithServerAsync(cipher, cipherView, fileName, data.Buffer);
|
||||
|
||||
await sutProvider.GetDependency<IApiService>().Received(1)
|
||||
.PostCipherAttachmentLegacyAsync(cipher.Id, Arg.Any<MultipartFormDataContent>());
|
||||
@@ -64,7 +64,7 @@ namespace Bit.Core.Test.Services
|
||||
|
||||
[Theory, UserCipherAutoData]
|
||||
public async Task SaveWithServerAsync_ThrowsOnBadRequestApiException(SutProvider<CipherService> sutProvider,
|
||||
Cipher cipher, string fileName, EncByteArray data, EncString encKey)
|
||||
Cipher cipher, CipherView cipherView, string fileName, EncByteArray data, EncString encKey)
|
||||
{
|
||||
sutProvider.GetDependency<ICryptoService>().EncryptAsync(fileName, Arg.Any<SymmetricCryptoKey>())
|
||||
.Returns(new EncString(fileName));
|
||||
@@ -77,7 +77,7 @@ namespace Bit.Core.Test.Services
|
||||
.Throws(expectedException);
|
||||
|
||||
var actualException = await Assert.ThrowsAsync<ApiException>(async () =>
|
||||
await sutProvider.Sut.SaveAttachmentRawWithServerAsync(cipher, fileName, data.Buffer));
|
||||
await sutProvider.Sut.SaveAttachmentRawWithServerAsync(cipher, cipherView, fileName, data.Buffer));
|
||||
|
||||
Assert.Equal(expectedException.Error.StatusCode, actualException.Error.StatusCode);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user