private void TrustContact() { int recepientId = TextEncoder.ReadInt(stream); using (Context context = new Context(config)) { var key = context.UsersKeys .Where(u => u.RecepientId == recepientId) .Where(u => u.SenderId == user.UserId) .SingleOrDefault(); if (key != null) { key.Trusted = true; } else { Log("Receiving new key."); key = new UsersKeys() { RecepientId = recepientId, SenderId = user.UserId, EncryptedAesKey = BinaryEncoder.ReceiveBytes(stream), Trusted = true }; context.Add(key); } context.SaveChanges(); } Log("Trust contact done."); }
public static JsonCapsula GetJsonDecoded(Context context, byte[] message, long senderId) { byte[] aesBinKey = context.Contacts .Where(u => u.PublicId == senderId) .Select(u => u.ReceiveAesKey) .SingleOrDefault(); AESPassword key = new AESPassword(aesBinKey); byte[] decrypted = key.Decrypt(message); MemoryStream stream = new MemoryStream(decrypted); JsonTypes type = (JsonTypes)BinaryEncoder.ReadInt(stream); string jsonText = TextEncoder.ReadString(stream); byte[] attechment = null; int isAttechment = BinaryEncoder.ReadInt(stream); if (isAttechment == 1) { attechment = BinaryEncoder.ReceiveBytes(stream); } IJType jmessage; switch (type) { case JsonTypes.ALARM: jmessage = JsonConvert.DeserializeObject <JAlarm>(jsonText); break; case JsonTypes.CONTACT: jmessage = JsonConvert.DeserializeObject <JContact>(jsonText); break; case JsonTypes.MESSAGES: jmessage = JsonConvert.DeserializeObject <JMessage>(jsonText); break; case JsonTypes.MESSAGES_THREAD: jmessage = JsonConvert.DeserializeObject <JMessageThread>(jsonText); break; default: throw new Exception("Unknown JsonType."); } return(new JsonCapsula() { Attechment = attechment, Message = jmessage }); }
public static byte[] DecryptAndVerify(byte[] data, X509Certificate2 myCert, X509Certificate2 senderCert) { RSA privateKey = myCert.GetRSAPrivateKey(); MemoryStream stream = new MemoryStream(data); byte[] signiture = BinaryEncoder.ReceiveBytes(stream); byte[] decrypted = privateKey.Decrypt(BinaryEncoder.ReceiveBytes(stream), encryptionPadding); if (!Verify(decrypted, signiture, senderCert)) { throw new Exception("The signiture of data isn't correct."); } return(decrypted); }
private void TrustContact() { int recepientId = BinaryEncoder.ReadInt(stream); using (Context context = new Context(config)) { var key = context.UsersKeys .Where(u => u.RecepientId == recepientId) .Where(u => u.SenderId == connectionInfo.UserId) .SingleOrDefault(); if (BinaryEncoder.ReadInt(stream) == 0) { Log("No new key will be received."); key.Trusted = true; } else { Log("Receiving new key."); var aesKey = BinaryEncoder.ReceiveBytes(stream); if (key != null) { Log("Updating denied!"); //key.AesKey = aesKey; key.Trusted = true; } else { key = new UsersKeys() { RecepientId = recepientId, SenderId = connectionInfo.UserId, AesKey = aesKey, Trusted = true }; context.Add(key); } } context.SaveChanges(); } Log("Trust contact done."); }
public static HandshakeReturnCapsula Login(Logger logger, Stream stream, X509Certificate2 cert, string password, string userName = null, int?clientId = null) { ClientHandshake clientHandshake = new ClientHandshake() { PemCertificate = X509Certificate2Utils.ExportToPem(cert), UserName = userName, ClientId = clientId, ServerPassword = password }; if (userName != null && userName.Length > DataConstants.USER_NAME_MAX_LENGHT) { throw new Exception("Username is too long."); } TextEncoder.SendJson(stream, clientHandshake); byte[] encrypted = BinaryEncoder.ReceiveBytes(stream); byte[] decrypted = RSAEncoder.Decrypt(encrypted, cert); BinaryEncoder.SendBytes(stream, decrypted); ServerHandshake serverHandshake = TextEncoder.ReadJson <ServerHandshake>(stream); logger.Log("Handshake", "Handshake", serverHandshake.Errors, false); if (!serverHandshake.Succeeded) { throw new Exception($"Handshake failed\n{serverHandshake.Errors}"); } return(new HandshakeReturnCapsula() { UserId = serverHandshake.UserId, UserName = serverHandshake.UserName, ClientId = serverHandshake.ClientId, SelfAesPassword = serverHandshake.SelfAesKey == null ? null : new AESPassword(RSAEncoder.DecryptAndVerify(serverHandshake.SelfAesKey, cert, cert)) }); }
public static ConnectionInfo Run(Stream stream, Action <string> log, ServerConfig config) { ClientHandshake clientHandshake = TextEncoder.ReadJson <ClientHandshake>(stream); X509Certificate2 clientCertificate = X509Certificate2Utils.ImportFromPem(clientHandshake.PemCertificate); log($"Logging user sent username {clientHandshake.UserName}\n Certificate:\n {clientHandshake.PemCertificate}"); ServerHandshake errorHandshake = new ServerHandshake() { Errors = "", NewUser = false, Succeeded = false, UserId = -1, UserName = "" }; if (config.Password != null && !config.Password.Equals(clientHandshake.ServerPassword)) { errorHandshake.Errors = "Server password is wrong."; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } log("Generating random bytes"); byte[] randomBytes = LUtils.GenerateRandomBytes(TcpConstants.HANDSHAKE_LENGHT); log("Sending encrypted bytes"); BinaryEncoder.SendBytes(stream, RSAEncoder.Encrypt(randomBytes, clientCertificate)); byte[] received = BinaryEncoder.ReceiveBytes(stream); if (!randomBytes.SequenceEqual(received)) { log("Client's certificate verification failed."); errorHandshake.Errors = "Client's certificate verification failed."; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } log("Certificate verification succeeded."); Users user; String message; Clients client; byte[] aesKey = null; bool newUser = false; using (Context context = new Context(config)) { byte[] hash = SHA256Utils.ComputeByteSha256Hash(clientCertificate); user = context.Users.SingleOrDefault(u => u.PublicCertificateSha256.SequenceEqual(hash)); if (user == null) { log("User doesn't exist yet. I'll try to create him."); newUser = true; log("Checking the uniquity of username."); String userName = clientHandshake.UserName; if (context.Users.SingleOrDefault(u => u.UserName.Equals(userName)) != null) { errorHandshake.Errors = "Username isn't unique."; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } else if (userName.Length > 45) { errorHandshake.Errors = "Username is too long (max. 45 chars)"; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } else if (userName.Length < 4) { errorHandshake.Errors = "Username is too short (min. 4 chars)"; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } else if (!Validators.ValidateRegexUserName(userName)) { errorHandshake.Errors = "Username must match this regex ^[a-zA-Z][-a-zA-Z0-9_]+$ (Vaguely can't contain special chars and spaces)"; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } log("Creating user."); user = new Users() { PublicCertificate = clientHandshake.PemCertificate, PublicCertificateSha256 = hash, UserName = clientHandshake.UserName }; context.Users.Add(user); context.SaveChanges(); message = "User successfully created."; log("User successfully created."); } else { message = "User exists."; log("User exists."); } client = new Clients() { UserId = user.Id }; if (clientHandshake.ClientId == null) { log($"Loading self-aes key."); aesKey = context.UsersKeys .Where(u => u.RecepientId == user.Id) .Where(u => u.SenderId == user.Id) .Select(u => u.AesKey) .SingleOrDefault(); context.Add(client); context.SaveChanges(); log($"Added client with Id {client.Id}."); } else { client.Id = (int)clientHandshake.ClientId; if (context.Clients.Where(u => u.Id == client.Id).Single().UserId != user.Id) { errorHandshake.Errors = "This client id isn't owned by this user."; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } log($"Client with Id {client.Id} has logged in."); } } ServerHandshake toSend = new ServerHandshake() { Errors = message, NewUser = newUser, Succeeded = true, UserId = user.Id, UserName = user.UserName, ClientId = client.Id, SelfAesKey = aesKey }; TextEncoder.SendJson(stream, toSend); ConnectionInfo ret = new ConnectionInfo(user, clientCertificate, client.Id); log($"Handshake successeded. User {ret.UserName} with id {ret.UserId} has logged in. Client has id {client.Id}."); return(ret); }
public int Pull() { int changes = 0; ThrowExceptionIfNotConnected(); lock (mutex) { Log("Sending PULL command."); BinaryEncoder.SendCommand(stream, ConnectionCommand.PULL); #if (DEBUG) Log("Sending ClientPullCapsula."); #endif ClientPullCapsula clientCapsula; using (Context context = new Context(config)) { clientCapsula = new ClientPullCapsula() { AesKeysUserIds = context.Contacts .Where(u => u.ReceiveAesKey == null) .Select(u => u.PublicId) .ToArray() }; } TextEncoder.SendJson(stream, clientCapsula); ServerPullCapsula capsula = TextEncoder.ReadJson <ServerPullCapsula>(stream); #if (DEBUG) Log("Received ServerPullCapsula."); #endif changes += capsula.AesKeysUserIds.Count; changes += capsula.Messages.Count; using (Context context = new Context(config)) { #if (DEBUG) Log("Receiving and saving AES keys."); #endif foreach (var id in capsula.AesKeysUserIds) { var user = new UContact(context.Contacts.Where(con => con.PublicId == id).SingleOrDefault()); try { user.ReceiveAesKey = RSAEncoder.DecryptAndVerify(BinaryEncoder.ReceiveBytes(stream), MyCertificate, X509Certificate2Utils.ImportFromPem(user.PublicCertificate)); } catch (Exception ex) { Log($"Loading of Receive AESKey from {user.PublicId} has failed."); logger.LogException(this, ex); } PushOperations.Update(context, user, UserId, UserId); } context.SaveChanges(); #if (DEBUG) Log("Receiving and saving messages."); #endif foreach (PullMessage metaMessage in capsula.Messages) { BlobMessages metaBlob = new BlobMessages() { PublicId = metaMessage.PublicId, SenderId = metaMessage.SenderId, Failed = 0, DoDelete = 0 }; context.BlobMessages.Add(metaBlob); context.SaveChanges(); try { PullMessageParser.ParseEncryptedMessage(context, BinaryEncoder.ReceiveBytes(stream), metaBlob.SenderId, metaBlob.Id, UserId); } catch (Exception ex) { Log($"Loading of message {metaMessage.PublicId} has failed."); metaBlob.Failed = 1; logger.LogException(this, ex); } context.SaveChanges(); } } Log("Pull have been done."); } return(changes); }
public void Pull() { Log("Sending PULL command."); TextEncoder.SendCommand(stream, ConnectionCommand.PULL); PullCapsula capsula = TextEncoder.ReadPullCapsula(stream); #if (DEBUG) Log("Received PullCapsula."); #endif using (Context context = new Context(config)) { #if (DEBUG) Log("Saving new users."); #endif foreach (PullUser user in capsula.Users) { context.Contacts.Add(new Contacts { PublicId = user.UserId, PublicCertificate = user.PublicCertificate, UserName = user.UserName }); } context.SaveChanges(); #if (DEBUG) Log("Saving trusted contacts."); #endif context.Database.ExecuteSqlCommand("update CONTACTS set TRUSTED=0;"); context.SaveChanges(); foreach (var user in context.Contacts .Where(users => capsula.TrustedUserIds.Contains(users.PublicId))) { user.Trusted = 1; } context.SaveChanges(); #if (DEBUG) Log("Receiving and saving AES keys."); #endif foreach (var id in capsula.AesKeysUserIds) { var user = context.Contacts.Where(con => con.PublicId == id).SingleOrDefault(); user.ReceiveAesKey = RSAEncoder.Decrypt(BinaryEncoder.ReceiveBytes(stream), ClientCertificate); } context.SaveChanges(); #if (DEBUG) Log("Receiving and saving messages."); #endif foreach (PullMessage metaMessage in capsula.Messages) { BlobMessages metaBlob = new BlobMessages() { PublicId = metaMessage.PublicId, SenderId = metaMessage.SenderId, Failed = 0, DoDelete = 0 }; context.BlobMessages.Add(metaBlob); context.SaveChanges(); try { PullMessageParser.ParseEncryptedMessage(context, BinaryEncoder.ReceiveBytes(stream), metaBlob.SenderId, metaBlob.Id, UserId); } catch (Exception ex) { Log($"Loading of message {metaMessage.PublicId} has failed."); metaBlob.Failed = 1; logger.LogException(this, ex); } context.SaveChanges(); } } Log("Pull have been done."); }
public static UserCapsula Run(Stream stream, Action <string> log, ServerConfig config) { ClientHandshake clientHandshake = TextEncoder.ReadClientHandshake(stream); X509Certificate2 clientCertificate = X509Certificate2Utils.ImportFromPem(clientHandshake.PemCertificate); log($"Logging user sent username {clientHandshake.UserName}\n Certificate:\n {clientHandshake.PemCertificate}"); log("Generating random bytes"); byte[] randomBytes = LUtils.GenerateRandomBytes(TcpConstants.HANDSHAKE_LENGHT); log("Sending encrypted bytes"); BinaryEncoder.SendBytes(stream, RSAEncoder.Encrypt(randomBytes, clientCertificate)); ServerHandshake errorHandshake = new ServerHandshake() { Errors = "", NewUser = false, Succeeded = false, UserId = -1, UserName = "" }; byte[] received = BinaryEncoder.ReceiveBytes(stream); if (!randomBytes.SequenceEqual(received)) { log("Sending error to client."); errorHandshake.Errors = "Client's certificate verification failed."; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } log("Certificate verification succeeded."); Users user; String message; Clients client; bool newUser = false; using (Context context = new Context(config)) { SHA1 sha = new SHA1CryptoServiceProvider(); byte[] hash = sha.ComputeHash(clientCertificate.RawData); user = context.Users.SingleOrDefault(u => u.PublicCertificateSha1.SequenceEqual(hash)); if (user == null) { log("User doesn't exist yet. I'll try to create him."); newUser = true; log("Checking the uniquity of username."); String userName = clientHandshake.UserName; if (context.Users.SingleOrDefault(u => u.UserName.Equals(userName)) != null) { log("Username isn't unique."); errorHandshake.Errors = "Username isn't unique."; TextEncoder.SendJson(stream, errorHandshake); throw new Exception(errorHandshake.Errors); } log("Creating user."); user = new Users() { PublicCertificate = clientHandshake.PemCertificate, PublicCertificateSha1 = hash, UserName = clientHandshake.UserName }; context.Users.Add(user); context.SaveChanges(); message = "User successfully created."; log("User successfully created."); } else { message = "User exists."; log("User exists."); } client = new Clients() { UserId = user.Id }; if (clientHandshake.ClientId == null) { context.Add(client); context.SaveChanges(); log($"Added client with Id {client.Id}."); } else { log($"Client with Id {client.Id} has logged in."); } } ServerHandshake toSend = new ServerHandshake() { Errors = message, NewUser = newUser, Succeeded = true, UserId = user.Id, UserName = user.UserName, ClientId = client.Id }; TextEncoder.SendJson(stream, toSend); UserCapsula ret = new UserCapsula(user, clientCertificate); log($"Handshake successeded. User {ret.UserName} with id {ret.UserId} has logged in"); return(ret); }
private void Pull() { #if (DEBUG) Log("Pulling started."); Log("Receiving PushCapsula."); #endif PushCapsula capsula = TextEncoder.ReadJson <PushCapsula>(stream); PushResponse response = new PushResponse() { MessageIds = new List <long>() }; using (Context context = new Context(config)) { #if (DEBUG) Log($"Receiving and saving {capsula.PushMessages.Count} blobs."); #endif foreach (var pushMessage in capsula.PushMessages) { BlobMessages blobMessage = new BlobMessages() { Content = BinaryEncoder.ReceiveBytes(stream), RecepientId = pushMessage.RecepientId, SenderId = connectionInfo.UserId, Priority = pushMessage.Priority }; context.BlobMessages.Add(blobMessage); context.SaveChanges(); if (pushMessage.RecepientId == connectionInfo.UserId) { response.MessageIds.Add(blobMessage.Id); context.ClientsMessagesDownloaded.Add(new ClientsMessagesDownloaded() { BlobMessagesId = blobMessage.Id, ClientsId = connectionInfo.ClientId }); } context.SaveChanges(); } #if (DEBUG) Log($"Deleting {capsula.MessageToDeleteIds.Count} blobs."); #endif foreach (var toDeleteId in capsula.MessageToDeleteIds) { var toDelete = context.BlobMessages .Where(u => u.RecepientId == connectionInfo.UserId && u.Id == toDeleteId).SingleOrDefault(); if (toDelete != null) { context.BlobMessages.Remove(toDelete); } } context.SaveChanges(); } #if (DEBUG) Log("Sending push response."); #endif TextEncoder.SendJson(stream, response); #if (DEBUG) Log("Pulling ended."); #endif }