/// <inheritdoc /> public Task HandleMessage(IPeerMessageContext <AuthenticationClientPayload> context, AuthLogonChallengeResponse payload) { AuthLogonProofRequest proof = null; //TODO: Change this console logging if (payload.Result != AuthenticationResult.Success) { Console.WriteLine($"Failed Auth: {payload.Result}"); } using (WoWSRP6ClientCryptoServiceProvider srpProvider = new WoWSRP6ClientCryptoServiceProvider(payload.Challenge.B.ToBigInteger(), payload.Challenge.N.ToBigInteger(), payload.Challenge.g.ToBigInteger())) { using (WoWSRP6PublicComponentHashServiceProvider hashingService = new WoWSRP6PublicComponentHashServiceProvider()) { //TODO: Remove hardcoded name/pass //Set the session key in the store for usage BigInteger unhashedKey = srpProvider.ComputeSessionKey("Glader".ToUpper(), "test", payload.Challenge.salt); Console.WriteLine($"SessionKey: {unhashedKey} KeySize: {unhashedKey.ToCleanByteArray().Length}"); proof = new AuthLogonProofRequest(srpProvider.A.ToCleanByteArray(), hashingService.ComputeSRP6M1(srpProvider.g, srpProvider.N, "Glader".ToUpper(), payload.Challenge.salt, srpProvider.A, srpProvider.B, unhashedKey)); //Set the session key as a hashed session key //SessionKeyStorage.SessionKey = hashingService.HashSessionKey(unhashedKey); } } Console.WriteLine("Sending Proof"); return(context.PayloadSendService.SendMessage(proof)); }
/// <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 }