1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-01 08:02:49 -05:00

[PM-4371] Implement PRF key rotation (#4157)

* Send rotateable keyset on list webauthn keys

* Implement basic prf key rotation

* Add validator for webauthn rotation

* Fix accounts controller tests

* Add webauthn rotation validator tests

* Introduce separate request model

* Fix tests

* Remove extra empty line

* Remove filtering in validator

* Don't send encrypted private key

* Fix tests

* Implement delegated webauthn db transactions

* Add backward compatibility

* Fix query not working

* Update migration sql

* Update dapper query

* Remove unused helper

* Rename webauthn to WebAuthnLogin

* Fix linter errors

* Fix tests

* Fix tests
This commit is contained in:
Bernd Schoolmann
2024-06-17 20:46:57 +02:00
committed by GitHub
parent a556462685
commit 3ad4bc1cab
19 changed files with 347 additions and 11 deletions

View File

@ -0,0 +1,93 @@
using Bit.Api.Auth.Models.Request.WebAuthn;
using Bit.Api.Auth.Validators;
using Bit.Core.Auth.Entities;
using Bit.Core.Auth.Repositories;
using Bit.Core.Entities;
using Bit.Core.Exceptions;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
using NSubstitute;
using Xunit;
namespace Bit.Api.Test.Auth.Validators;
[SutProviderCustomize]
public class WebAuthnLoginKeyRotationValidatorTests
{
[Theory]
[BitAutoData]
public async Task ValidateAsync_WrongWebAuthnKeys_Throws(
SutProvider<WebAuthnLoginKeyRotationValidator> sutProvider, User user,
IEnumerable<WebAuthnLoginRotateKeyRequestModel> webauthnRotateCredentialData)
{
var webauthnKeysToRotate = webauthnRotateCredentialData.Select(e => new WebAuthnLoginRotateKeyRequestModel
{
Id = Guid.Parse("00000000-0000-0000-0000-000000000001"),
EncryptedPublicKey = e.EncryptedPublicKey,
EncryptedUserKey = e.EncryptedUserKey
}).ToList();
var data = new WebAuthnCredential
{
Id = Guid.Parse("00000000-0000-0000-0000-000000000002"),
EncryptedPublicKey = "TestKey",
EncryptedUserKey = "Test"
};
sutProvider.GetDependency<IWebAuthnCredentialRepository>().GetManyByUserIdAsync(user.Id).Returns(new List<WebAuthnCredential> { data });
await Assert.ThrowsAsync<BadRequestException>(async () =>
await sutProvider.Sut.ValidateAsync(user, webauthnKeysToRotate));
}
[Theory]
[BitAutoData]
public async Task ValidateAsync_NullUserKey_Throws(
SutProvider<WebAuthnLoginKeyRotationValidator> sutProvider, User user,
IEnumerable<WebAuthnLoginRotateKeyRequestModel> webauthnRotateCredentialData)
{
var guid = Guid.NewGuid();
var webauthnKeysToRotate = webauthnRotateCredentialData.Select(e => new WebAuthnLoginRotateKeyRequestModel
{
Id = guid,
EncryptedPublicKey = e.EncryptedPublicKey,
}).ToList();
var data = new WebAuthnCredential
{
Id = guid,
EncryptedPublicKey = "TestKey",
EncryptedUserKey = "Test"
};
sutProvider.GetDependency<IWebAuthnCredentialRepository>().GetManyByUserIdAsync(user.Id).Returns(new List<WebAuthnCredential> { data });
await Assert.ThrowsAsync<BadRequestException>(async () =>
await sutProvider.Sut.ValidateAsync(user, webauthnKeysToRotate));
}
[Theory]
[BitAutoData]
public async Task ValidateAsync_NullPublicKey_Throws(
SutProvider<WebAuthnLoginKeyRotationValidator> sutProvider, User user,
IEnumerable<WebAuthnLoginRotateKeyRequestModel> webauthnRotateCredentialData)
{
var guid = Guid.NewGuid();
var webauthnKeysToRotate = webauthnRotateCredentialData.Select(e => new WebAuthnLoginRotateKeyRequestModel
{
Id = guid,
EncryptedUserKey = e.EncryptedUserKey,
}).ToList();
var data = new WebAuthnCredential
{
Id = guid,
EncryptedPublicKey = "TestKey",
EncryptedUserKey = "Test"
};
sutProvider.GetDependency<IWebAuthnCredentialRepository>().GetManyByUserIdAsync(user.Id).Returns(new List<WebAuthnCredential> { data });
await Assert.ThrowsAsync<BadRequestException>(async () =>
await sutProvider.Sut.ValidateAsync(user, webauthnKeysToRotate));
}
}