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);
        }
Beispiel #4
0
        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;
            }
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }