/// <inheritdoc /> public Task Delete(int key) { AuthenticationChallengeModel challenge = null; if (!EntryDictionary.TryRemove(key, out challenge)) { throw new KeyNotFoundException($"Key: {key} not found."); } return(Task.CompletedTask); }
/// <inheritdoc /> public Task <AuthenticationChallengeModel> Retrieve(int key) { AuthenticationChallengeModel challenge = null; if (!EntryDictionary.TryGetValue(key, out challenge)) { throw new KeyNotFoundException($"Key: {key} not found."); } return(Task.FromResult(challenge)); }
/// <inheritdoc /> public async Task <bool> TryCreate(int key, AuthenticationChallengeModel model) { //TODO: Clean up exception info if (await HasEntry(key)) { return(false); } if (!EntryDictionary.TryAdd(key, model)) { return(false); } return(true); }
/// <inheritdoc /> public Task <int> Create(AuthenticationChallengeModel model) { throw new NotSupportedException($"Not supported to add entry to auth challenge repo with no manual key."); }
/// <inheritdoc /> public async Task HandleMessage(IPeerSessionMessageContext <AuthenticationServerPayload> context, AuthLogonProofRequest payload) { if (Logger.IsDebugEnabled) { Logger.Debug($"Recieved {payload.GetType().Name} Id: {context.Details.ConnectionId}"); } BigInteger A = payload.A.ToBigInteger(); //SRP6 Safeguard from specification: A % N cannot be 0. if (A % WoWSRP6ServerCryptoServiceProvider.N == 0) { //TODO: This can't be 0 or it breaks } //Check if we have a challenge entry for this connection //TODO: Add proper response code if (!await ChallengeRepository.HasEntry(context.Details.ConnectionId)) { await context.PayloadSendService.SendMessage(new AuthLogonProofResponse(new LogonProofFailure())); return; } //TODO: Refactor using (WoWSRP6PublicComponentHashServiceProvider hasher = new WoWSRP6PublicComponentHashServiceProvider()) { AuthenticationChallengeModel challenge = await ChallengeRepository.Retrieve(context.Details.ConnectionId); byte[] hash = hasher.Hash(A, challenge.PublicB); // Both: u = H(A, B) BigInteger u = hash .Take(20) .ToArray() .ToBigInteger(); BigInteger N = WoWSRP6ServerCryptoServiceProvider.N; //Host: S = (Av^u) ^ b (computes session key) BigInteger S = ((A * (challenge.V.ModPow(u, N)))) //TODO: Do we need % N here? .ModPow(challenge.PrivateB, N); //Host: K = H(S) BigInteger K = hasher.HashSessionKey(S); byte[] preMHash = T3.ToCleanByteArray() .Concat(hasher.Hash(challenge.Identity.Reinterpret(Encoding.ASCII)).Take(20).ToArray()) .Concat(challenge.Salt.ToCleanByteArray()) .Concat(payload.A) .Concat(challenge.PublicB.ToCleanByteArray()) .Concat(K.ToCleanByteArray()) .ToArray(); byte[] M = hasher.Hash(preMHash); Logger.Debug($"M: {M.Aggregate("", (s, b) => $"{s} {b}")}"); Logger.Debug($"M1: {payload.M1.Aggregate("", (s, b) => $"{s} {b}")}"); //TODO: Remove this test code if (TestClass.CompareBuffers(M, payload.M1, 20) == 0) { Logger.Debug($"Auth Proof Success."); byte[] M2 = hasher.Hash(payload.A.Concat(M).Concat(K.ToCleanByteArray()).ToArray()); //TODO: We also want to update last/login IP and other stuff await AccountRepository.UpdateSessionKey(challenge.AccountId, K); await context.PayloadSendService.SendMessage(new AuthLogonProofResponse(new LogonProofSuccess(M2))); } else { Logger.Debug($"Auth Proof Failure."); await context.PayloadSendService.SendMessage(new AuthLogonProofResponse(new LogonProofFailure())); } } //TODO: Implement }