1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-30 15:42:48 -05:00

[PM-17210] Prevent unintentionally corrupting private keys (#5285)

* Prevent unintentionally corrupting private keys

* Deny key update only when replacing existing keys

* Fix incorrect use of existing user public/encrypted private key

* Fix test

* Fix tests

* Re-add test

* Pass through error for set-password

* Fix test

* Increase test coverage and simplify checks
This commit is contained in:
Bernd Schoolmann
2025-02-06 21:38:50 +01:00
committed by GitHub
parent f7d882d760
commit 58d2a7ddaa
3 changed files with 108 additions and 55 deletions

View File

@ -266,8 +266,18 @@ public class AccountsController : Controller
throw new UnauthorizedAccessException();
}
try
{
user = model.ToUser(user);
}
catch (Exception e)
{
ModelState.AddModelError(string.Empty, e.Message);
throw new BadRequestException(ModelState);
}
var result = await _setInitialMasterPasswordCommand.SetInitialMasterPasswordAsync(
model.ToUser(user),
user,
model.MasterPasswordHash,
model.Key,
model.OrgIdentifier);

View File

@ -1,26 +1,36 @@
using System.ComponentModel.DataAnnotations;
using Bit.Core.Entities;
using Bit.Core.Utilities;
namespace Bit.Core.Auth.Models.Api.Request.Accounts;
public class KeysRequestModel
{
[Required]
public string PublicKey { get; set; }
[Required]
public string EncryptedPrivateKey { get; set; }
public User ToUser(User existingUser)
{
if (string.IsNullOrWhiteSpace(existingUser.PublicKey) && !string.IsNullOrWhiteSpace(PublicKey))
if (string.IsNullOrWhiteSpace(PublicKey) || string.IsNullOrWhiteSpace(EncryptedPrivateKey))
{
throw new InvalidOperationException("Public and private keys are required.");
}
if (string.IsNullOrWhiteSpace(existingUser.PublicKey) && string.IsNullOrWhiteSpace(existingUser.PrivateKey))
{
existingUser.PublicKey = PublicKey;
}
if (string.IsNullOrWhiteSpace(existingUser.PrivateKey))
{
existingUser.PrivateKey = EncryptedPrivateKey;
return existingUser;
}
else if (PublicKey == existingUser.PublicKey && CoreHelpers.FixedTimeEquals(EncryptedPrivateKey, existingUser.PrivateKey))
{
return existingUser;
}
else
{
throw new InvalidOperationException("Cannot replace existing key(s) with new key(s).");
}
return existingUser;
}
}