public static void SendMessage(Message msg, KeyStore ks) { byte[] convAesKey = null; int recipientId = -1; using (DataContext db = new DataContext()) { var conv = GetConversation(msg.SenderId, msg.RecipientId, db); msg.ConversationId = conv.ConId; // Non-blocking execution of setting unread Task.Run(() => SetUnread(conv.ConId, msg.RecipientId)); if (msg.SenderId == conv.UserAId) { convAesKey = Crypt.Instance.DecryptRsa(conv.KeyA, ks.rsaPrivate); recipientId = conv.UserBId; } else if (msg.SenderId == conv.UserBId) { convAesKey = Crypt.Instance.DecryptRsa(conv.KeyB, ks.rsaPrivate); recipientId = conv.UserAId; } SecureMessage dbMsg = msg.ToDatabase(recipientId, convAesKey); if (convAesKey == null || recipientId == -1) { throw new ChatException("Recipient invalid or message could not be encrypted"); } // Add to database db.SecureMessage.Add(dbMsg); db.SaveChanges(); } }
/// <summary> /// Validate the user's password /// </summary> /// <param name="password">The user's password</param> /// <param name="checkEmailValidity">Whether to check if the email address is verified</param> /// <returns></returns> internal AuthResult ValidateLogin(string password, bool checkEmailValidity = true) { using (DataContext db = new DataContext()) { Users user = Users.FindByEmail(this.Email, db); if (user == null) { AuthLogger.Instance.UserNotFound(Email); return(AuthResult.UserNotFound); } // Check IP string userip = GetIP(); if (UserIPList.CheckUserIPList(userip, user, db)) { Debug.WriteLine("CHK TRUE"); MailClient m = new MailClient(Email); m.Subject = "Unrecognised login from IP Address " + userip; m.AddLine("An unrecognised login has been found"); m.AddLine("If this wasn't you, please contact us."); m.Send(user.FullName, "Contact Us", "https://haxnet.azurewebsites.net/Contact"); } else { Debug.WriteLine("CHK FALSE"); } if (checkEmailValidity && !EmailConfirm.IsEmailValidated(user)) { EmailConfirm.SendEmailForConfirmation(user, db); return(AuthResult.EmailNotVerified); } byte[] bPassword = Encoding.UTF8.GetBytes(password); byte[] bSalt = user.Salt; byte[] bHash = Crypt.Instance.Hash(bPassword, bSalt); if (user.Hash.SequenceEqual(bHash)) { AuthLogger.Instance.PasswordSuccess(user.Email, user.UserID); } else { AuthLogger.Instance.PasswordFail(user.Email, user.UserID); return(AuthResult.PasswordIncorrect); } try { db.Entry(user).Reference(usr => usr.UserKeyStore).Load(); if (user.UserKeyStore == null) { user.UserKeyStore = KeyStore.DefaultDbKeyStore(password, bSalt, user.UserID); db.SaveChanges(); } TempKeyStore = new KeyStore(user.UserKeyStore, password, bSalt); return(AuthResult.Success); } catch (KeyStoreException) { return(AuthResult.KeyStoreInvalid); } } throw new AuthException("Login has no result, database failure might have occured."); }
public static ICollection <Message> RetrieveMessages(int retriever, int other, KeyStore ks, int amount = -1) { ICollection <Message> decryptedMessages = new List <Message>(); List <SecureMessage> dbMsgList = null; byte[] convAesKey = null; Stopwatch sw = new Stopwatch(); sw.Start(); using (DataContext db = new DataContext()) { var dbConv = GetConversation(retriever, other, db); if (dbConv == null) { throw new ChatException("Message could not be retrieved"); } if (retriever == dbConv.UserAId) { convAesKey = Crypt.Instance.DecryptRsa(dbConv.KeyA, ks.rsaPrivate); if (dbConv.UnreadForA == true) { dbConv.UnreadForA = false; db.SaveChanges(); } } else if (retriever == dbConv.UserBId) { convAesKey = Crypt.Instance.DecryptRsa(dbConv.KeyB, ks.rsaPrivate); if (dbConv.UnreadForB == true) { dbConv.UnreadForB = false; db.SaveChanges(); } } if (convAesKey == null) { throw new ChatException("Message could not be decrypted (AES from RSA)"); } // DB Query for messages that match query var dbMsgQueryable = db.SecureMessage .Where(m => (m.ConId == dbConv.ConId)) .OrderByDescending(m => m.MsgId); int rows = dbMsgQueryable.Count(); // If the number of rows exceeds the number of rows, return all the rows if (amount > rows) { amount = -1; } // Get the specified number of rows from the database if (amount > 0) { dbMsgList = dbMsgQueryable.Take(amount).ToList(); } else { dbMsgList = dbMsgQueryable.ToList(); } // Convert each message into decrypted form foreach (SecureMessage dbMsg in dbMsgList) { decryptedMessages.Add(new Message(dbMsg, convAesKey)); } sw.Stop(); Debug.WriteLine("Messages retrieval & decryption took: " + sw.ElapsedMilliseconds + "ms"); } return(decryptedMessages.Reverse().ToList()); }