public async Task <SessionKeyResponse> RefreshSessionKey(RequestModel model)
        {
            var imei = Request.GetImei();

            using (var context = new ApplicationDbContext())
            {
                var keys = await context.Keys.Where(k => k.User.UserName == User.Identity.Name).ToListAsync();

                foreach (var currentKey in keys)
                {
                    currentKey.SessionKeyGenerated  = null;
                    context.Entry(currentKey).State = EntityState.Modified;
                }
                await context.SaveChangesAsync();

                var key = await context.Keys.FirstOrDefaultAsync(k => k.User.UserName == User.Identity.Name && k.Imei == imei);

                if (key == null || key.PublicKey == null)
                {
                    throw new HttpResponseException(Request.CreateCustomErrorResponse(HttpStatusCode.BadRequest, "Public key by email not found"));
                }

                var sessionKey = BouncyCastleHelper.GenerateSerpentKey();
                key.SessionKey           = BouncyCastleHelper.DbProtection(sessionKey);
                key.SessionKeyGenerated  = DateTime.UtcNow;
                context.Entry(key).State = EntityState.Modified;
                await context.SaveChangesAsync();

                return(new SessionKeyResponse {
                    EncryptedSessionKey = BouncyCastleHelper.EncryptSessionKey(sessionKey, BouncyCastleHelper.DbProtection(key.PublicKey, false))
                });
            }
        }
        public static AuthenticationProperties CreateProperties(ApplicationUser user, UserKey key)
        {
            IDictionary <string, string> data = new Dictionary <string, string>
            {
                { "userName", user.UserName }
            };

            if (key?.PublicSignKey != null)
            {
                data.Add("signHalfKey", BouncyCastleHelper.DbProtection(key.SignHalfKey, false));
            }
            if (key?.UserStorageKey != null)
            {
                data.Add("userStorageKey", BouncyCastleHelper.DbProtection(key.UserStorageKey, false));
            }
            return(new AuthenticationProperties(data));
        }
        public async Task <bool> SetSignatureKeys(SignatureRequestModel model)
        {
            var imei = Request.GetImei();

            if (imei == null)
            {
                throw new HttpResponseException(Request.CreateCustomErrorResponse(HttpStatusCode.BadRequest, "Imei not specified"));
            }
            if (model?.HalfPrivateSignKey == null || model.PublicSignKey == null)
            {
                throw new HttpResponseException(Request.CreateCustomErrorResponse(HttpStatusCode.BadRequest, "Keys not provided"));
            }

            using (var context = new ApplicationDbContext())
            {
                var key = await context.Keys.FirstOrDefaultAsync(k => k.Imei == imei && k.User.UserName == User.Identity.Name);

                if (key != null && (key.SignHalfKey != null || key.PublicSignKey != null))
                {
                    throw new HttpResponseException(Request.CreateCustomErrorResponse(HttpStatusCode.BadRequest, "Sign key are already defined"));
                }
                if (key == null)
                {
                    context.Keys.Add(new UserKey
                    {
                        Imei          = imei,
                        PublicSignKey = BouncyCastleHelper.DbProtection(model.PublicSignKey),
                        SignHalfKey   = BouncyCastleHelper.DbProtection(model.HalfPrivateSignKey),
                        User          = await context.Users.FirstOrDefaultAsync(u => u.UserName == User.Identity.Name)
                    });
                }
                else
                {
                    key.PublicSignKey        = BouncyCastleHelper.DbProtection(model.PublicSignKey);
                    key.SignHalfKey          = BouncyCastleHelper.DbProtection(model.HalfPrivateSignKey);
                    context.Entry(key).State = EntityState.Modified;
                }
                await context.SaveChangesAsync();
            }
            return(true);
        }
Beispiel #4
0
        public override async Task OnAuthorizationAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken)
        {
            await base.OnAuthorizationAsync(actionContext, cancellationToken);

            var principal = actionContext.RequestContext.Principal;
            var imei      = actionContext.Request.GetImei();
            var signature = actionContext.Request.GetSignature();

            if (imei == null || signature == null)
            {
                actionContext.Response = actionContext.Request.CreateCustomErrorResponse(HttpStatusCode.BadRequest, "There is no imei or signature");
                return;
            }
            UserKey key;

            using (var context = new ApplicationDbContext())
            {
                key = await context.Keys.FirstOrDefaultAsync(k => k.Imei == imei && k.User.UserName == principal.Identity.Name);

                if (key == null || key.SignHalfKey == null || key.PublicSignKey == null)
                {
                    actionContext.Response = actionContext.Request.CreateCustomErrorResponse(HttpStatusCode.MethodNotAllowed, "Sign key is not found");
                    return;
                }
            }

            var stream = await actionContext.Request.Content.ReadAsStreamAsync();

            var reader       = new StreamReader(stream);
            var jsonPostData = reader.ReadToEnd();

            stream.Seek(0, SeekOrigin.Begin);

            if (!BouncyCastleHelper.Verify(jsonPostData, signature, BouncyCastleHelper.DbProtection(key.PublicSignKey, false)))
            {
                actionContext.Response = actionContext.Request.CreateCustomErrorResponse(HttpStatusCode.BadRequest, "Sign is invalid");
                return;
            }
        }
        public async Task <bool> RefreshPublicKey(RequestModel model)
        {
            var imei = Request.GetImei();

            if (string.IsNullOrEmpty(imei) || string.IsNullOrEmpty(model.PublicKey))
            {
                throw new HttpResponseException(Request.CreateCustomErrorResponse(HttpStatusCode.BadRequest, "Imei and public key can not be null"));
            }

            using (var context = new ApplicationDbContext())
            {
                var user = await context.Users.FirstOrDefaultAsync(u => u.UserName == User.Identity.Name);

                if (user == null)
                {
                    throw new HttpResponseException(Request.CreateCustomErrorResponse(HttpStatusCode.InternalServerError, "User not found"));
                }
                var key = await context.Keys.FirstOrDefaultAsync(k => k.Imei == imei && k.User.UserName == User.Identity.Name);

                if (key == null)
                {
                    context.Keys.Add(new UserKey
                    {
                        Imei      = imei,
                        PublicKey = BouncyCastleHelper.DbProtection(model.PublicKey),
                        User      = user
                    });
                }
                else
                {
                    key.PublicKey            = BouncyCastleHelper.DbProtection(model.PublicKey);
                    context.Entry(key).State = EntityState.Modified;
                }
                await context.SaveChangesAsync();
            }
            return(true);
        }
        public async Task <NoteResponse> Post(RequestModel model)
        {
            var imei = Request.GetImei();

            if (string.IsNullOrEmpty(imei) || string.IsNullOrEmpty(model.Name))
            {
                throw new HttpResponseException(Request.CreateCustomErrorResponse(HttpStatusCode.BadRequest, "Imei and name can not be null"));
            }

            using (var context = new ApplicationDbContext())
            {
                var key = await context.Keys.FirstOrDefaultAsync(k => k.User.UserName == User.Identity.Name && k.Imei == imei);

                if (key == null || key.PublicKey == null)
                {
                    throw new HttpResponseException(Request.CreateCustomErrorResponse(HttpStatusCode.BadRequest, "Public key by email not found"));
                }

                if (key.SessionKey == null || key.SessionKeyGenerated == null || (DateTime.UtcNow - key.SessionKeyGenerated.Value).TotalMinutes > _sessionKeyExpirationInMinutes)
                {
                    throw new HttpResponseException(Request.CreateCustomErrorResponse(HttpStatusCode.Forbidden, "Session key not generated or has been expired"));
                }

                var text = await context.Notes.FirstOrDefaultAsync(n => n.Name == model.Name);

                if (text == null)
                {
                    throw new HttpResponseException(Request.CreateCustomErrorResponse(HttpStatusCode.NotFound, "Note with such name not found"));
                }

                return(new NoteResponse
                {
                    Name = text.Name,
                    EncryptedText = BouncyCastleHelper.EncryptNote(BouncyCastleHelper.DbProtection(text.Text, false), BouncyCastleHelper.DbProtection(key.SessionKey, false))
                });
            }
        }
        protected override void Seed(kbsrserver.Models.ApplicationDbContext context)
        {
            const string name1 = "*****@*****.**";
            const string name2 = "*****@*****.**";

            if (!(context.Users.Any(u => u.UserName == name1)))
            {
                var userStore    = new UserStore <ApplicationUser>(context);
                var userManager  = new UserManager <ApplicationUser>(userStore);
                var userToInsert = new ApplicationUser {
                    UserName = name1, PhoneNumber = "123",
                    Email    = name1
                };
                userManager.Create(userToInsert, "Password123*");

                context.SaveChanges();
            }

            if (!(context.Users.Any(u => u.UserName == name2)))
            {
                var userStore    = new UserStore <ApplicationUser>(context);
                var userManager  = new UserManager <ApplicationUser>(userStore);
                var userToInsert = new ApplicationUser
                {
                    UserName    = name2,
                    PhoneNumber = "123",
                    Email       = name2
                };
                var bytes  = Encoding.UTF8.GetBytes("Password123*");
                var hasher = new SHA256Managed();
                var hashed = hasher.ComputeHash(bytes).ToHexString();
                userManager.Create(userToInsert, hashed);

                context.SaveChanges();
            }

            context.Notes.AddOrUpdate(
                p => p.Name,
                new Note {
                Id = 1, Name = "Hello", Text = BouncyCastleHelper.DbProtection("Hello, World!")
            },
                new Note {
                Id = 2, Name = "Eldar", Text = BouncyCastleHelper.DbProtection(@"Eldar Gamisoniya
BSU
GROUP 12")
            }
                );

            context.SaveChanges();

            //  This method will be called after migrating to the latest version.

            //  You can use the DbSet<T>.AddOrUpdate() helper extension method
            //  to avoid creating duplicate seed data. E.g.
            //
            //    context.People.AddOrUpdate(
            //      p => p.FullName,
            //      new Person { FullName = "Andrew Peters" },
            //      new Person { FullName = "Brice Lambson" },
            //      new Person { FullName = "Rowan Miller" }
            //    );
            //
        }
        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            var userManager = context.OwinContext.GetUserManager <ApplicationUserManager>();

            var user = await userManager.FindByNameAsync(context.UserName);

            if (user == null || user.Attempts >= MaxAttempts)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect.");
                return;
            }
            context.
            if (!await userManager.CheckPasswordAsync(user, context.Password))
            {
                user.Attempts++;
                await userManager.UpdateAsync(user);

                await context.OwinContext.Get <ApplicationDbContext>().SaveChangesAsync();

                context.SetError("invalid_grant", "The user name or password is incorrect.");
                return;
            }
            user.Attempts = 0;
            await userManager.UpdateAsync(user);

            await context.OwinContext.Get <ApplicationDbContext>().SaveChangesAsync();

            string[] values;
            if (!context.Request.Headers.TryGetValue("Imei", out values))
            {
                context.SetError("no_imei", "Imei not specified");
                return;
            }
            var     imei = values.FirstOrDefault();
            UserKey key;

            try
            {
                using (var db = new ApplicationDbContext())
                {
                    var userEntity = await db.Users.FirstOrDefaultAsync(u => u.UserName == user.UserName);

                    key = await db.Keys.FirstOrDefaultAsync(k => k.User.UserName == userEntity.UserName && k.Imei == imei);

                    if (key == null)
                    {
                        key = new UserKey
                        {
                            Imei           = imei,
                            UserStorageKey = BouncyCastleHelper.DbProtection(BouncyCastleHelper.GenerateSerpentKey()),
                            User           = userEntity
                        };
                        db.Keys.Add(key);
                        await db.SaveChangesAsync();
                    }
                    else if (key.UserStorageKey == null)
                    {
                        key.UserStorageKey  = BouncyCastleHelper.DbProtection(BouncyCastleHelper.GenerateSerpentKey());
                        db.Entry(key).State = EntityState.Modified;
                        await db.SaveChangesAsync();
                    }
                }

                ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
                                                                                    OAuthDefaults.AuthenticationType);

                AuthenticationProperties properties = CreateProperties(user, key);
                AuthenticationTicket     ticket     = new AuthenticationTicket(oAuthIdentity, properties);
                context.Validated(ticket);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }