1
0
mirror of https://github.com/bitwarden/server.git synced 2025-04-05 05:00:19 -05:00

Add prelogin response

This commit is contained in:
Bernd Schoolmann 2025-03-17 16:34:04 +01:00
parent ce003e8efc
commit 4968ea0adb
No known key found for this signature in database
2 changed files with 22 additions and 3 deletions

View File

@ -1,10 +1,13 @@
using System.Diagnostics; using System.Diagnostics;
using System.Text; using System.Text;
using System.Text.Json;
using Bit.Core; using Bit.Core;
using Bit.Core.Auth.Enums; using Bit.Core.Auth.Enums;
using Bit.Core.Auth.Models.Api.Request.Accounts; using Bit.Core.Auth.Models.Api.Request.Accounts;
using Bit.Core.Auth.Models.Api.Request.Opaque;
using Bit.Core.Auth.Models.Api.Response.Accounts; using Bit.Core.Auth.Models.Api.Response.Accounts;
using Bit.Core.Auth.Models.Business.Tokenables; using Bit.Core.Auth.Models.Business.Tokenables;
using Bit.Core.Auth.Repositories;
using Bit.Core.Auth.Services; using Bit.Core.Auth.Services;
using Bit.Core.Auth.UserFeatures.Registration; using Bit.Core.Auth.UserFeatures.Registration;
using Bit.Core.Auth.UserFeatures.WebAuthnLogin; using Bit.Core.Auth.UserFeatures.WebAuthnLogin;
@ -45,6 +48,7 @@ public class AccountsController : Controller
private readonly IReferenceEventService _referenceEventService; private readonly IReferenceEventService _referenceEventService;
private readonly IFeatureService _featureService; private readonly IFeatureService _featureService;
private readonly IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable> _registrationEmailVerificationTokenDataFactory; private readonly IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable> _registrationEmailVerificationTokenDataFactory;
private readonly IOpaqueKeyExchangeCredentialRepository _opaqueKeyExchangeCredentialRepository;
private readonly byte[] _defaultKdfHmacKey = null; private readonly byte[] _defaultKdfHmacKey = null;
private static readonly List<UserKdfInformation> _defaultKdfResults = private static readonly List<UserKdfInformation> _defaultKdfResults =
@ -93,6 +97,7 @@ public class AccountsController : Controller
IReferenceEventService referenceEventService, IReferenceEventService referenceEventService,
IFeatureService featureService, IFeatureService featureService,
IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable> registrationEmailVerificationTokenDataFactory, IDataProtectorTokenFactory<RegistrationEmailVerificationTokenable> registrationEmailVerificationTokenDataFactory,
IOpaqueKeyExchangeCredentialRepository opaqueKeyExchangeCredentialRepository,
GlobalSettings globalSettings GlobalSettings globalSettings
) )
{ {
@ -107,6 +112,7 @@ public class AccountsController : Controller
_referenceEventService = referenceEventService; _referenceEventService = referenceEventService;
_featureService = featureService; _featureService = featureService;
_registrationEmailVerificationTokenDataFactory = registrationEmailVerificationTokenDataFactory; _registrationEmailVerificationTokenDataFactory = registrationEmailVerificationTokenDataFactory;
_opaqueKeyExchangeCredentialRepository = opaqueKeyExchangeCredentialRepository;
if (CoreHelpers.SettingHasValue(globalSettings.KdfDefaultHashKey)) if (CoreHelpers.SettingHasValue(globalSettings.KdfDefaultHashKey))
{ {
@ -259,7 +265,17 @@ public class AccountsController : Controller
{ {
kdfInformation = GetDefaultKdf(model.Email); kdfInformation = GetDefaultKdf(model.Email);
} }
return new PreloginResponseModel(kdfInformation);
var user = await _userRepository.GetByEmailAsync(model.Email);
var credential = await _opaqueKeyExchangeCredentialRepository.GetByUserIdAsync(user.Id);
if (credential != null)
{
return new PreloginResponseModel(kdfInformation, JsonSerializer.Deserialize<CipherConfiguration>(credential.CipherConfiguration)!);
}
else
{
return new PreloginResponseModel(kdfInformation, null);
}
} }
[HttpGet("webauthn/assertion-options")] [HttpGet("webauthn/assertion-options")]

View File

@ -1,20 +1,23 @@
using Bit.Core.Enums; using Bit.Core.Auth.Models.Api.Request.Opaque;
using Bit.Core.Enums;
using Bit.Core.Models.Data; using Bit.Core.Models.Data;
namespace Bit.Identity.Models.Response.Accounts; namespace Bit.Identity.Models.Response.Accounts;
public class PreloginResponseModel public class PreloginResponseModel
{ {
public PreloginResponseModel(UserKdfInformation kdfInformation) public PreloginResponseModel(UserKdfInformation kdfInformation, CipherConfiguration opaqueConfiguration)
{ {
Kdf = kdfInformation.Kdf; Kdf = kdfInformation.Kdf;
KdfIterations = kdfInformation.KdfIterations; KdfIterations = kdfInformation.KdfIterations;
KdfMemory = kdfInformation.KdfMemory; KdfMemory = kdfInformation.KdfMemory;
KdfParallelism = kdfInformation.KdfParallelism; KdfParallelism = kdfInformation.KdfParallelism;
OpaqueConfiguration = opaqueConfiguration;
} }
public KdfType Kdf { get; set; } public KdfType Kdf { get; set; }
public int KdfIterations { get; set; } public int KdfIterations { get; set; }
public int? KdfMemory { get; set; } public int? KdfMemory { get; set; }
public int? KdfParallelism { get; set; } public int? KdfParallelism { get; set; }
public CipherConfiguration OpaqueConfiguration { get; set; }
} }