mirror of
https://github.com/bitwarden/mobile
synced 2025-12-16 00:03:22 +00:00
[PM-2713] fix casting issues and pin
This commit is contained in:
@@ -439,18 +439,18 @@ namespace Bit.App.Pages
|
|||||||
var email = await _stateService.GetEmailAsync();
|
var email = await _stateService.GetEmailAsync();
|
||||||
var pinKey = await _cryptoService.MakePinKeyAsync(pin, email, kdfConfig);
|
var pinKey = await _cryptoService.MakePinKeyAsync(pin, email, kdfConfig);
|
||||||
var userKey = await _cryptoService.GetUserKeyAsync();
|
var userKey = await _cryptoService.GetUserKeyAsync();
|
||||||
var pinProtectedKey = await _cryptoService.EncryptAsync(userKey.Key, pinKey);
|
var protectedPinKey = await _cryptoService.EncryptAsync(userKey.Key, pinKey);
|
||||||
|
|
||||||
var encPin = await _cryptoService.EncryptAsync(pin);
|
var encPin = await _cryptoService.EncryptAsync(pin);
|
||||||
await _stateService.SetProtectedPinAsync(encPin.EncryptedString);
|
await _stateService.SetProtectedPinAsync(encPin.EncryptedString);
|
||||||
|
|
||||||
if (masterPassOnRestart)
|
if (masterPassOnRestart)
|
||||||
{
|
{
|
||||||
await _stateService.SetUserKeyPinEphemeralAsync(pinProtectedKey);
|
await _stateService.SetUserKeyPinEphemeralAsync(protectedPinKey);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await _stateService.SetUserKeyPinAsync(pinProtectedKey);
|
await _stateService.SetUserKeyPinAsync(protectedPinKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ namespace Bit.Core.Services
|
|||||||
public async Task<Tuple<UserKey, EncString>> EncryptUserKeyWithMasterKeyAsync(MasterKey masterKey, UserKey userKey = null)
|
public async Task<Tuple<UserKey, EncString>> EncryptUserKeyWithMasterKeyAsync(MasterKey masterKey, UserKey userKey = null)
|
||||||
{
|
{
|
||||||
userKey ??= await GetUserKeyAsync();
|
userKey ??= await GetUserKeyAsync();
|
||||||
return await BuildProtectedSymmetricKey<UserKey>(masterKey, userKey.Key);
|
return await BuildProtectedSymmetricKey(masterKey, userKey.Key, keyBytes => new UserKey(keyBytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<UserKey> DecryptUserKeyWithMasterKeyAsync(MasterKey masterKey, EncString encUserKey = null, string userId = null)
|
public async Task<UserKey> DecryptUserKeyWithMasterKeyAsync(MasterKey masterKey, EncString encUserKey = null, string userId = null)
|
||||||
@@ -174,7 +174,7 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
else if (encUserKey.EncryptionType == EncryptionType.AesCbc256_HmacSha256_B64)
|
else if (encUserKey.EncryptionType == EncryptionType.AesCbc256_HmacSha256_B64)
|
||||||
{
|
{
|
||||||
var newKey = await StretchKeyAsync(masterKey);
|
var newKey = await StretchKeyAsync(masterKey, keyBytes => new MasterKey(keyBytes));
|
||||||
decUserKey = await DecryptToBytesAsync(encUserKey, newKey);
|
decUserKey = await DecryptToBytesAsync(encUserKey, newKey);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -197,7 +197,7 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
var newSymKey = await _cryptoFunctionService.RandomBytesAsync(64);
|
var newSymKey = await _cryptoFunctionService.RandomBytesAsync(64);
|
||||||
return await BuildProtectedSymmetricKey<SymmetricCryptoKey>(key, newSymKey);
|
return await BuildProtectedSymmetricKey(key, newSymKey, keyBytes => new SymmetricCryptoKey(keyBytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Tuple<SymmetricCryptoKey, EncString>> MakeDataEncKeyAsync(OrgKey key)
|
public async Task<Tuple<SymmetricCryptoKey, EncString>> MakeDataEncKeyAsync(OrgKey key)
|
||||||
@@ -208,7 +208,7 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
var newSymKey = await _cryptoFunctionService.RandomBytesAsync(64);
|
var newSymKey = await _cryptoFunctionService.RandomBytesAsync(64);
|
||||||
return await BuildProtectedSymmetricKey<SymmetricCryptoKey>(key, newSymKey);
|
return await BuildProtectedSymmetricKey(key, newSymKey, keyBytes => new SymmetricCryptoKey(keyBytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> HashMasterKeyAsync(string password, MasterKey masterKey, HashPurpose hashPurpose = HashPurpose.ServerAuthorization)
|
public async Task<string> HashMasterKeyAsync(string password, MasterKey masterKey, HashPurpose hashPurpose = HashPurpose.ServerAuthorization)
|
||||||
@@ -423,7 +423,7 @@ namespace Bit.Core.Services
|
|||||||
public async Task<PinKey> MakePinKeyAsync(string pin, string salt, KdfConfig config)
|
public async Task<PinKey> MakePinKeyAsync(string pin, string salt, KdfConfig config)
|
||||||
{
|
{
|
||||||
var pinKey = await MakeKeyAsync(pin, salt, config, keyBytes => new PinKey(keyBytes));
|
var pinKey = await MakeKeyAsync(pin, salt, config, keyBytes => new PinKey(keyBytes));
|
||||||
return await StretchKeyAsync(pinKey) as PinKey;
|
return await StretchKeyAsync(pinKey, keyBytes => new PinKey(keyBytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task ClearPinKeysAsync(string userId = null)
|
public Task ClearPinKeysAsync(string userId = null)
|
||||||
@@ -819,14 +819,16 @@ namespace Bit.Core.Services
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<SymmetricCryptoKey> StretchKeyAsync(SymmetricCryptoKey key)
|
// TODO: This needs to be moved into SymmetricCryptoKey model to remove the keyCreator hack
|
||||||
|
private async Task<TKey> StretchKeyAsync<TKey>(SymmetricCryptoKey key, Func<byte[], TKey> keyCreator)
|
||||||
|
where TKey : SymmetricCryptoKey
|
||||||
{
|
{
|
||||||
var newKey = new byte[64];
|
var newKey = new byte[64];
|
||||||
var enc = await _cryptoFunctionService.HkdfExpandAsync(key.Key, Encoding.UTF8.GetBytes("enc"), 32, HkdfAlgorithm.Sha256);
|
var enc = await _cryptoFunctionService.HkdfExpandAsync(key.Key, Encoding.UTF8.GetBytes("enc"), 32, HkdfAlgorithm.Sha256);
|
||||||
Buffer.BlockCopy(enc, 0, newKey, 0, 32);
|
Buffer.BlockCopy(enc, 0, newKey, 0, 32);
|
||||||
var mac = await _cryptoFunctionService.HkdfExpandAsync(key.Key, Encoding.UTF8.GetBytes("mac"), 32, HkdfAlgorithm.Sha256);
|
var mac = await _cryptoFunctionService.HkdfExpandAsync(key.Key, Encoding.UTF8.GetBytes("mac"), 32, HkdfAlgorithm.Sha256);
|
||||||
Buffer.BlockCopy(mac, 0, newKey, 32, 32);
|
Buffer.BlockCopy(mac, 0, newKey, 32, 32);
|
||||||
return new SymmetricCryptoKey(newKey);
|
return keyCreator(newKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<string> HashPhrase(byte[] hash, int minimumEntropy = 64)
|
private List<string> HashPhrase(byte[] hash, int minimumEntropy = 64)
|
||||||
@@ -853,13 +855,14 @@ namespace Bit.Core.Services
|
|||||||
return phrase;
|
return phrase;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Tuple<T, EncString>> BuildProtectedSymmetricKey<T>(SymmetricCryptoKey key,
|
// TODO: This needs to be moved into SymmetricCryptoKey model to remove the keyCreator hack
|
||||||
byte[] encKey) where T : SymmetricCryptoKey
|
private async Task<Tuple<TKey, EncString>> BuildProtectedSymmetricKey<TKey>(SymmetricCryptoKey key,
|
||||||
|
byte[] encKey, Func<byte[], TKey> keyCreator) where TKey : SymmetricCryptoKey
|
||||||
{
|
{
|
||||||
EncString 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, keyCreator);
|
||||||
encKeyEnc = await EncryptAsync(encKey, newKey);
|
encKeyEnc = await EncryptAsync(encKey, newKey);
|
||||||
}
|
}
|
||||||
else if (key.Key.Length == 64)
|
else if (key.Key.Length == 64)
|
||||||
@@ -870,10 +873,10 @@ namespace Bit.Core.Services
|
|||||||
{
|
{
|
||||||
throw new Exception("Invalid key size.");
|
throw new Exception("Invalid key size.");
|
||||||
}
|
}
|
||||||
return new Tuple<T, EncString>(new SymmetricCryptoKey(encKey) as T, encKeyEnc);
|
return new Tuple<TKey, EncString>(keyCreator(encKey), encKeyEnc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This intantiator needs to be moved into each key type in order to get rid of the keyCreator hack
|
// TODO: This needs to be moved into SymmetricCryptoKey model to remove the keyCreator hack
|
||||||
private async Task<TKey> MakeKeyAsync<TKey>(string password, string salt, KdfConfig kdfConfig, Func<byte[], TKey> keyCreator)
|
private async Task<TKey> MakeKeyAsync<TKey>(string password, string salt, KdfConfig kdfConfig, Func<byte[], TKey> keyCreator)
|
||||||
where TKey : SymmetricCryptoKey
|
where TKey : SymmetricCryptoKey
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -312,18 +312,18 @@ namespace Bit.iOS.Core.Controllers
|
|||||||
{
|
{
|
||||||
var masterKey = await _cryptoService.MakeMasterKeyAsync(inputtedValue, email, kdfConfig);
|
var masterKey = await _cryptoService.MakeMasterKeyAsync(inputtedValue, email, kdfConfig);
|
||||||
|
|
||||||
var storedPasswordHash = await _cryptoService.GetPasswordHashAsync();
|
var storedPasswordHash = await _cryptoService.GetMasterKeyHashAsync();
|
||||||
if (storedPasswordHash == null)
|
if (storedPasswordHash == null)
|
||||||
{
|
{
|
||||||
var oldKey = await _secureStorageService.GetAsync<string>("oldKey");
|
var oldKey = await _secureStorageService.GetAsync<string>("oldKey");
|
||||||
if (masterKey.KeyB64 == oldKey)
|
if (masterKey.KeyB64 == oldKey)
|
||||||
{
|
{
|
||||||
var localPasswordHash = await _cryptoService.HashPasswordAsync(inputtedValue, masterKey, HashPurpose.LocalAuthorization);
|
var localPasswordHash = await _cryptoService.HashMasterKeyAsync(inputtedValue, masterKey, HashPurpose.LocalAuthorization);
|
||||||
await _secureStorageService.RemoveAsync("oldKey");
|
await _secureStorageService.RemoveAsync("oldKey");
|
||||||
await _cryptoService.SetPasswordHashAsync(localPasswordHash);
|
await _cryptoService.SetMasterKeyHashAsync(localPasswordHash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var passwordValid = await _cryptoService.CompareAndUpdatePasswordHashAsync(inputtedValue, masterKey);
|
var passwordValid = await _cryptoService.CompareAndUpdateKeyHashAsync(inputtedValue, masterKey);
|
||||||
if (passwordValid)
|
if (passwordValid)
|
||||||
{
|
{
|
||||||
await AppHelpers.ResetInvalidUnlockAttemptsAsync();
|
await AppHelpers.ResetInvalidUnlockAttemptsAsync();
|
||||||
|
|||||||
@@ -285,18 +285,18 @@ namespace Bit.iOS.Core.Controllers
|
|||||||
{
|
{
|
||||||
var masterKey = await _cryptoService.MakeMasterKeyAsync(inputtedValue, email, kdfConfig);
|
var masterKey = await _cryptoService.MakeMasterKeyAsync(inputtedValue, email, kdfConfig);
|
||||||
|
|
||||||
var storedPasswordHash = await _cryptoService.GetPasswordHashAsync();
|
var storedPasswordHash = await _cryptoService.GetMasterKeyHashAsync();
|
||||||
if (storedPasswordHash == null)
|
if (storedPasswordHash == null)
|
||||||
{
|
{
|
||||||
var oldKey = await _secureStorageService.GetAsync<string>("oldKey");
|
var oldKey = await _secureStorageService.GetAsync<string>("oldKey");
|
||||||
if (masterKey.KeyB64 == oldKey)
|
if (masterKey.KeyB64 == oldKey)
|
||||||
{
|
{
|
||||||
var localPasswordHash = await _cryptoService.HashPasswordAsync(inputtedValue, masterKey, HashPurpose.LocalAuthorization);
|
var localPasswordHash = await _cryptoService.HashMasterKeyAsync(inputtedValue, masterKey, HashPurpose.LocalAuthorization);
|
||||||
await _secureStorageService.RemoveAsync("oldKey");
|
await _secureStorageService.RemoveAsync("oldKey");
|
||||||
await _cryptoService.SetPasswordHashAsync(localPasswordHash);
|
await _cryptoService.SetMasterKeyHashAsync(localPasswordHash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var passwordValid = await _cryptoService.CompareAndUpdatePasswordHashAsync(inputtedValue, masterKey);
|
var passwordValid = await _cryptoService.CompareAndUpdateKeyHashAsync(inputtedValue, masterKey);
|
||||||
if (passwordValid)
|
if (passwordValid)
|
||||||
{
|
{
|
||||||
await AppHelpers.ResetInvalidUnlockAttemptsAsync();
|
await AppHelpers.ResetInvalidUnlockAttemptsAsync();
|
||||||
|
|||||||
Reference in New Issue
Block a user