Browse Source
* [PM-1379] add DeviceCryptoService with establish trust logic * PM-1379 update api location and other minor refactors * pm-1379 fix encoding * update trusted device keys api call to Put * [PM-1379] rename DeviceCryptoService to DeviceTrustCryptoService - refactors to prevent side effects * [PM-1379] rearrange methods in DeviceTrustCryptoService * [PM-1379] rearrange methods in abstraction * [PM-1379] deconstruct tuples * [PM-1379] remove extra tasks2293
9 changed files with 141 additions and 0 deletions
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
using System.Threading.Tasks; |
||||
using Bit.Core.Models.Domain; |
||||
|
||||
namespace Bit.Core.Abstractions |
||||
{ |
||||
public interface IDeviceTrustCryptoService |
||||
{ |
||||
Task<SymmetricCryptoKey> GetDeviceKeyAsync(); |
||||
Task<DeviceResponse> TrustDeviceAsync(); |
||||
} |
||||
} |
||||
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
|
||||
namespace Bit.Core.Models.Request |
||||
{ |
||||
public class TrustedDeviceKeysRequest |
||||
{ |
||||
public string EncryptedUserKey { get; set; } |
||||
public string EncryptedPublicKey { get; set; } |
||||
public string EncryptedPrivateKey { get; set; } |
||||
} |
||||
} |
||||
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
using Bit.Core.Enums; |
||||
|
||||
public class DeviceResponse |
||||
{ |
||||
public string Id { get; set; } |
||||
public int Name { get; set; } |
||||
public string Identifier { get; set; } |
||||
public DeviceType Type { get; set; } |
||||
public string CreationDate { get; set; } |
||||
public string EncryptedUserKey { get; set; } |
||||
public string EncryptedPublicKey { get; set; } |
||||
public string EncryptedPrivateKey { get; set; } |
||||
} |
||||
@ -0,0 +1,81 @@
@@ -0,0 +1,81 @@
|
||||
|
||||
using System; |
||||
using System.Threading.Tasks; |
||||
using Bit.Core.Abstractions; |
||||
using Bit.Core.Models.Domain; |
||||
using Bit.Core.Models.Request; |
||||
|
||||
namespace Bit.Core.Services |
||||
{ |
||||
public class DeviceTrustCryptoService : IDeviceTrustCryptoService |
||||
{ |
||||
private readonly IApiService _apiService; |
||||
private readonly IAppIdService _appIdService; |
||||
private readonly ICryptoFunctionService _cryptoFunctionService; |
||||
private readonly ICryptoService _cryptoService; |
||||
private readonly IStateService _stateService; |
||||
|
||||
private const int DEVICE_KEY_SIZE = 64; |
||||
|
||||
public DeviceTrustCryptoService( |
||||
IApiService apiService, |
||||
IAppIdService appIdService, |
||||
ICryptoFunctionService cryptoFunctionService, |
||||
ICryptoService cryptoService, |
||||
IStateService stateService) |
||||
{ |
||||
_apiService = apiService; |
||||
_appIdService = appIdService; |
||||
_cryptoFunctionService = cryptoFunctionService; |
||||
_cryptoService = cryptoService; |
||||
_stateService = stateService; |
||||
} |
||||
|
||||
public async Task<SymmetricCryptoKey> GetDeviceKeyAsync() |
||||
{ |
||||
return await _stateService.GetDeviceKeyAsync(); |
||||
} |
||||
|
||||
private async Task SetDeviceKeyAsync(SymmetricCryptoKey deviceKey) |
||||
{ |
||||
await _stateService.SetDeviceKeyAsync(deviceKey); |
||||
} |
||||
|
||||
public async Task<DeviceResponse> TrustDeviceAsync() |
||||
{ |
||||
// Attempt to get user key |
||||
var userKey = await _cryptoService.GetEncKeyAsync(); |
||||
if (userKey == null) |
||||
{ |
||||
return null; |
||||
} |
||||
// Generate deviceKey |
||||
var deviceKey = await MakeDeviceKeyAsync(); |
||||
|
||||
// Generate asymmetric RSA key pair: devicePrivateKey, devicePublicKey |
||||
var (devicePublicKey, devicePrivateKey) = await _cryptoFunctionService.RsaGenerateKeyPairAsync(2048); |
||||
|
||||
// Send encrypted keys to server |
||||
var deviceIdentifier = await _appIdService.GetAppIdAsync(); |
||||
var deviceRequest = new TrustedDeviceKeysRequest |
||||
{ |
||||
EncryptedUserKey = (await _cryptoService.RsaEncryptAsync(userKey.EncKey, devicePublicKey)).EncryptedString, |
||||
EncryptedPublicKey = (await _cryptoService.EncryptAsync(devicePublicKey, userKey)).EncryptedString, |
||||
EncryptedPrivateKey = (await _cryptoService.EncryptAsync(devicePrivateKey, deviceKey)).EncryptedString, |
||||
}; |
||||
|
||||
var deviceResponse = await _apiService.UpdateTrustedDeviceKeysAsync(deviceIdentifier, deviceRequest); |
||||
|
||||
// Store device key if successful |
||||
await SetDeviceKeyAsync(deviceKey); |
||||
return deviceResponse; |
||||
} |
||||
|
||||
private async Task<SymmetricCryptoKey> MakeDeviceKeyAsync() |
||||
{ |
||||
// Create 512-bit device key |
||||
var randomBytes = await _cryptoFunctionService.RandomBytesAsync(DEVICE_KEY_SIZE); |
||||
return new SymmetricCryptoKey(randomBytes); |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue