From 525174068f3205f6ba8c9fc6661f4c530e5d7cc4 Mon Sep 17 00:00:00 2001 From: Ike Kottlowski Date: Thu, 20 Mar 2025 14:59:34 -0400 Subject: [PATCH] feat (opaque-ke) : moved endpoints to Identity. --- .../Auth/Controllers/AccountsController.cs | 9 ++++--- .../Services/IOpaqueKeyExchangeService.cs | 2 +- .../Controllers/AccountsController.cs | 10 ------- .../OpaqueKeyExchangeController.cs | 27 ++++++++++++++++--- 4 files changed, 30 insertions(+), 18 deletions(-) rename src/{Api/Auth => Identity}/Controllers/OpaqueKeyExchangeController.cs (67%) diff --git a/src/Api/Auth/Controllers/AccountsController.cs b/src/Api/Auth/Controllers/AccountsController.cs index 9f90d0c4b3..59f9516974 100644 --- a/src/Api/Auth/Controllers/AccountsController.cs +++ b/src/Api/Auth/Controllers/AccountsController.cs @@ -209,11 +209,12 @@ public class AccountsController : Controller throw new UnauthorizedAccessException(); } - // TODO: should this be feature flagged Guid? opaqueSessionId = null; - if (model.OpaqueSessionId != null) - { - opaqueSessionId = Guid.Parse(model.OpaqueSessionId); + if(_featureService.IsEnabled(FeatureFlagKeys.OpaqueKeyExchange)){ + if (model.OpaqueSessionId != null) + { + opaqueSessionId = Guid.Parse(model.OpaqueSessionId); + } } var result = await _userService.ChangePasswordAsync(user, model.MasterPasswordHash, diff --git a/src/Core/Auth/Services/IOpaqueKeyExchangeService.cs b/src/Core/Auth/Services/IOpaqueKeyExchangeService.cs index b6652847bb..b6e692a917 100644 --- a/src/Core/Auth/Services/IOpaqueKeyExchangeService.cs +++ b/src/Core/Auth/Services/IOpaqueKeyExchangeService.cs @@ -28,7 +28,7 @@ public interface IOpaqueKeyExchangeService /// void public Task FinishRegistration(Guid sessionId, byte[] registrationUpload, User user, RotateableOpaqueKeyset keyset); /// - /// Returns server crypto material for the client to consume and reply with a login request to the identity/token endpoint. + /// Returns server crypto material for the client to consume and reply to the finish-login endpoint for authentication. /// To protect against account enumeration we will always return a deterministic response based on the user's email. /// /// client crypto material diff --git a/src/Identity/Controllers/AccountsController.cs b/src/Identity/Controllers/AccountsController.cs index 9b32eef1c3..9c8a110be1 100644 --- a/src/Identity/Controllers/AccountsController.cs +++ b/src/Identity/Controllers/AccountsController.cs @@ -1,7 +1,6 @@ using System.Diagnostics; using System.Text; using System.Text.Json; -using Bit.Api.Auth.Models.Response.Opaque; using Bit.Core; using Bit.Core.Auth.Enums; using Bit.Core.Auth.Models.Api.Request.Accounts; @@ -291,15 +290,6 @@ public class AccountsController : Controller }; } - // TODO: (1) This should be on own controller (2) reconcile this w/ start login on existing controller - [HttpPost("opaque-ke/start-login")] - [RequireFeature(FeatureFlagKeys.OpaqueKeyExchange)] - public async Task GetOpaqueKeyExchangeStartLoginMaterial([FromBody] OpaqueLoginStartRequest request) - { - var result = await _opaqueKeyExchangeService.StartLogin(Convert.FromBase64String(request.CredentialRequest), request.Email); - return new OpaqueLoginStartResponse(result.Item1, Convert.ToBase64String(result.Item2)); - } - private UserKdfInformation GetDefaultKdf(string email) { if (_defaultKdfHmacKey == null) diff --git a/src/Api/Auth/Controllers/OpaqueKeyExchangeController.cs b/src/Identity/Controllers/OpaqueKeyExchangeController.cs similarity index 67% rename from src/Api/Auth/Controllers/OpaqueKeyExchangeController.cs rename to src/Identity/Controllers/OpaqueKeyExchangeController.cs index 66eb9b17cc..90a005d754 100644 --- a/src/Api/Auth/Controllers/OpaqueKeyExchangeController.cs +++ b/src/Identity/Controllers/OpaqueKeyExchangeController.cs @@ -1,3 +1,5 @@ +using Bit.Api.Auth.Models.Request.Opaque; +using Bit.Api.Auth.Models.Response.Opaque; using Bit.Core; using Bit.Core.Auth.Models.Api.Request.Opaque; using Bit.Core.Auth.Models.Api.Response.Opaque; @@ -7,11 +9,10 @@ using Bit.Core.Utilities; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -namespace Bit.Api.Auth.Controllers; +namespace Bit.Identity.Controllers; -// TODO: move to identity [RequireFeature(FeatureFlagKeys.OpaqueKeyExchange)] -[Route("opaque")] +[Route("opaque-ke")] [Authorize("Application")] public class OpaqueKeyExchangeController( IOpaqueKeyExchangeService opaqueKeyExchangeService, @@ -37,6 +38,8 @@ public class OpaqueKeyExchangeController( { var user = await _userService.GetUserByPrincipalAsync(User) ?? throw new UnauthorizedAccessException(); + // todo check response + await _opaqueKeyExchangeService.FinishRegistration( request.SessionId, Convert.FromBase64String(request.RegistrationUpload), user, request.KeySet); } @@ -46,6 +49,24 @@ public class OpaqueKeyExchangeController( { var user = await _userService.GetUserByPrincipalAsync(User) ?? throw new UnauthorizedAccessException(); + // todo check response await _opaqueKeyExchangeService.WriteCacheCredentialToDatabase(request.SessionId, user); } + + [AllowAnonymous] + [HttpPost("start-login")] + public async Task StartOpaqueLoginAsync([FromBody] OpaqueLoginStartRequest request) + { + var result = await _opaqueKeyExchangeService.StartLogin(Convert.FromBase64String(request.CredentialRequest), request.Email); + return new OpaqueLoginStartResponse(result.Item1, Convert.ToBase64String(result.Item2)); + } + + [AllowAnonymous] + [HttpPost("finish-login")] + public async Task FinishLoginAsync([FromBody] OpaqueLoginFinishRequest request) + { + var result = await _opaqueKeyExchangeService.FinishLogin( + request.SessionId, Convert.FromBase64String(request.CredentialFinalization)); + return result; + } }