byte[] ConvertToEncryptedMessage(NewCamdMessage message) { _logger.Debug($"Prepare message headers for {Name}"); var prepareData = new List <byte>(); prepareData.Add((byte)(message.MessageId >> 8)); prepareData.Add((byte)(message.MessageId & 0xFF)); prepareData.Add((byte)(message.ServiceId >> 8)); prepareData.Add((byte)(message.ServiceId & 0xFF)); prepareData.Add((byte)(message.ProviderId >> 16)); prepareData.Add((byte)((message.ProviderId >> 8) & 0xFF)); prepareData.Add((byte)(message.ProviderId & 0xFF)); prepareData.Add(0); prepareData.Add(0); prepareData.Add(0); _logger.Debug($"Correct message headers for {Name}"); message.Data[0] = (byte)message.Type; message.Data[1] = (byte)((message.Data[1] & 240) | (((message.Data.Length - 3) >> 8) & 255)); message.Data[2] = (byte)((message.Data.Length - 3) & 255); _logger.Debug($"Copy {message.Data.Length} bytes into the buffer for {Name}"); prepareData.AddRange(message.Data); //Fill up while (prepareData.Count % 8 != 7) { prepareData.Add(0); } _logger.Debug($"Encrypt data before sending to {Name}"); var padding = new byte[8]; _random.NextBytes(padding); //fill up bytes with padding data at the end var bufferLen = prepareData.Count; var paddingLen = (8 - ((bufferLen - 2) % 8)) % 8; var prepareDataArray = prepareData.ToArray(); Buffer.BlockCopy(padding, 0, prepareDataArray, bufferLen - paddingLen, paddingLen); prepareData = prepareDataArray.ToList(); //Add checksum prepareData.Add(XorSum(prepareData.ToArray())); var ivec = new byte[8]; _random.NextBytes(ivec); var dataToEncrypt = prepareData.ToArray(); var encrypted = _crypto.Encrypt(dataToEncrypt, _keyblock, ivec).ToList(); var dataToSend = new List <byte>(); dataToSend.Add((byte)((encrypted.Count + ivec.Length) >> 8)); dataToSend.Add((byte)((encrypted.Count + ivec.Length) & 0xFF)); dataToSend.AddRange(encrypted); dataToSend.AddRange(ivec); return(dataToSend.ToArray()); }
public void SendMessage(string logMessage, NewCamdMessage message) { var log = $"{logMessage}: {message.Type}"; var data = ConvertToEncryptedMessage(message); SendMessage(log, data); }
NewCamdMessage ParseMessage(byte[] buffer) { _logger.Debug("Read TripleDES Initialization Vector from encrypted message"); var ivec = buffer.Skip(buffer.Length - 8).Take(8).ToArray(); _logger.Debug("Decrypt the rest of the message"); var decryptedData = _crypto.Decrypt(buffer, buffer.Length - 8, _keyblock, ivec); _logger.Debug("Parse decrypted message"); var len = (((decryptedData[3 + NewCamdMessage.HeaderLength] << 8) | decryptedData[4 + NewCamdMessage.HeaderLength]) & 0x0FFF) + 3; if (len > decryptedData.Length) { throw new InvalidNewcamdMessage($"Decryption of the message from {Name} failed"); } var retValue = new NewCamdMessage { MessageId = ((decryptedData[0] << 8) | decryptedData[1]) & 0xFFFF, ServiceId = ((decryptedData[2] << 8) | decryptedData[3]) & 0xFFFF, ProviderId = decryptedData[4] << 16 | decryptedData[5] << 8 | decryptedData[6], Data = decryptedData.Skip(2 + NewCamdMessage.HeaderLength).Take(len).ToArray(), Type = (NewCamdMessageType)decryptedData[2 + NewCamdMessage.HeaderLength] }; _logger.Debug($"Received decrypted message msgid: {retValue.MessageId}, serviceid: {retValue.ServiceId}, providerid: {retValue.ProviderId}, length: {len}, type {retValue.Type} from {Name}"); return(retValue); }
void ReceiveMessage(NewCamdMessage message) { if (message == null) { return; } _logger.Debug($"Handle message: {message.Type} from {Name}"); switch (message.Type) { case NewCamdMessageType.MsgClient2ServerLogin: Login(message); break; case NewCamdMessageType.MsgCardDataReq: CardData(message); break; case NewCamdMessageType.MsgKeepalive: _logger.Debug($"{Name} - Keep connection alive"); _communication.SendMessage("Keep alive", message); break; case NewCamdMessageType.MsgKeyblockReq1: case NewCamdMessageType.MsgKeyblockReq2: KeyBlock(message); break; default: _logger.Error($"Unable to handle {message.Type}"); Dispose(); break; } }
void Login(NewCamdMessage message) { string username; string encryptedPassword; try { const int header = 3; var splitter = Array.IndexOf(message.Data, (byte)0, header); username = Encoding.ASCII.GetString(message.Data.Skip(header).Take(splitter - header).ToArray()); splitter++; encryptedPassword = Encoding.ASCII.GetString(message.Data.Skip(splitter).Take(message.Data.Length - splitter - 1).ToArray()); } catch (Exception ex) { _logger.Warn($"Couldn't read the login credentials from {Name}"); _logger.Debug("Exception at login", ex); Dispose(); return; } var expectedPassword = _crypto.UnixEncrypt(_settings.Password, "$1$abcdefgh$"); var loginValid = _settings.Username.Equals(username) && expectedPassword.Equals(encryptedPassword); message.Type = loginValid ? NewCamdMessageType.MsgClient2ServerLoginAck : NewCamdMessageType.MsgClient2ServerLoginNak; _logger.Info($"{Name} - Login is {message.Type}"); message.Data = new byte[3]; _communication.SendMessage("Login response", message); if (!loginValid) { return; } _communication.UpdateKeyBlock(encryptedPassword); }
void KeyBlock(NewCamdMessage message) { _logger.Info($"{Name} - Give keyblock info"); var header = new byte[] { (byte)message.Type, 1, 1 }; var keyInfo = _keyblock.DecryptBlock(message.Type, message.Data); message.Data = header.Concat(keyInfo).ToArray(); _communication.SendMessage("Key info", message); }
void CardData(NewCamdMessage message) { _logger.Info($"{Name} - Request card info"); message.Type = NewCamdMessageType.MsgCardData; message.Data = new byte[26]; //Provide CAID message.Data[4] = 0x56; message.Data[5] = 0x01; message.Data[14] = 1; //Set number of cards message.Data[17] = 1; //Set provider ID of card 1 _communication.SendMessage("Card info", message); }