/// <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.");
 }
Пример #5
0
        /// <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
        }