1
0
mirror of https://github.com/bitwarden/mobile synced 2026-01-09 03:53:15 +00:00

[PM-5731] feat: implement credential exclusion

This commit is contained in:
Andreas Coroiu
2024-01-24 14:18:27 +01:00
parent 19639b61c3
commit f0dde7eb82
4 changed files with 168 additions and 21 deletions

View File

@@ -42,5 +42,12 @@ namespace Bit.Core.Abstractions
/// <param name="pickCredentialParams">The parameters to use when asking the user to pick a credential.</param>
/// <returns>The ID of the cipher that contains the credentials the user picked.</returns>
Task<Fido2PickCredentialResult> PickCredentialAsync(Fido2PickCredentialParams pickCredentialParams);
/// <summary>
/// Inform the user that the operation was cancelled because their vault contains excluded credentials.
/// </summary>
/// <param name="existingCipherIds">The IDs of the excluded credentials.</param>
/// <returns>When user has confirmed the message</returns>
Task InformExcludedCredential(string[] existingCipherIds);
}
}

View File

@@ -23,7 +23,7 @@ namespace Bit.Core.Services
_userInterface = userInterface;
}
public Task<Fido2AuthenticatorMakeCredentialResult> MakeCredentialAsync(Fido2AuthenticatorMakeCredentialParams makeCredentialParams)
public async Task<Fido2AuthenticatorMakeCredentialResult> MakeCredentialAsync(Fido2AuthenticatorMakeCredentialParams makeCredentialParams)
{
if (makeCredentialParams.CredTypesAndPubKeyAlgs.All((p) => p.Algorithm != (int) Fido2AlgorithmIdentifier.ES256))
{
@@ -34,6 +34,20 @@ namespace Bit.Core.Services
throw new NotSupportedError();
}
// await _userInterface.EnsureUnlockedVault();
await _syncService.FullSyncAsync(false);
var existingCipherIds = await FindExcludedCredentials(
makeCredentialParams.ExcludeCredentialDescriptorList
);
if (existingCipherIds.Length > 0) {
_logService.Info(
"[Fido2Authenticator] Aborting due to excluded credential found in vault."
);
await _userInterface.InformExcludedCredential(existingCipherIds);
throw new NotAllowedError();
}
throw new NotImplementedException();
}
@@ -130,6 +144,40 @@ namespace Bit.Core.Services
}
}
///<summary>
/// Finds existing crendetials and returns the `CipherId` for each one
///</summary>
private async Task<string[]> FindExcludedCredentials(
PublicKeyCredentialDescriptor[] credentials
) {
var ids = new List<string>();
foreach (var credential in credentials)
{
try
{
ids.Add(GuidToStandardFormat(credential.Id));
} catch {}
}
if (ids.Count == 0) {
return [];
}
var ciphers = await _cipherService.GetAllDecryptedAsync();
return ciphers
.FindAll(
(cipher) =>
!cipher.IsDeleted &&
cipher.OrganizationId == null &&
cipher.Type == CipherType.Login &&
cipher.Login.HasFido2Credentials &&
ids.Contains(cipher.Login.MainFido2Credential.CredentialId)
)
.Select((cipher) => cipher.Id)
.ToArray();
}
private async Task<List<CipherView>> FindCredentialsById(PublicKeyCredentialDescriptor[] credentials, string rpId)
{
var ids = new List<string>();

View File

@@ -22,6 +22,11 @@ namespace Bit.Core.Utilities.Fido2
///</summary>
public PublicKeyCredentialAlgorithmDescriptor[] CredTypesAndPubKeyAlgs { get; set; }
///<summary>
///An OPTIONAL list of PublicKeyCredentialDescriptor objects provided by the Relying Party with the intention that, if any of these are known to the authenticator, it SHOULD NOT create a new credential. excludeCredentialDescriptorList contains a list of known credentials.
///</summary>
public PublicKeyCredentialDescriptor[] ExcludeCredentialDescriptorList { get; set; }
///<summary>
/// The effective resident key requirement for credential creation, a Boolean value determined by the client. Resident is synonymous with discoverable. */
///</summary>