Ejemplo n.º 1
0
        /// <summary>
        /// Serialize the Message to output stream
        /// </summary>
        /// <param name="message"></param>
        /// <param name="TargetStream"></param>
        /// <returns>The size of the serialzed message</returns>
        internal int EncryptMessage(Connection conn, IMessage message, MemoryStream TargetStream)
        {
            PayloadWriter pw         = new PayloadWriter(TargetStream);
            int           PayloadPos = pw.Position;

            Serializer.Serialize(TargetStream, message);

            //return (int)TargetStream.Length;

            #region Security
            //compress data
            if (CompressionAlgorithm.QuickLZ == (conn.CompressionAlgorithm & CompressionAlgorithm.QuickLZ))
            {
                UnsafeQuickLZ quickLz    = new UnsafeQuickLZ();
                byte[]        compressed = quickLz.compress(TargetStream.GetBuffer(), (uint)Connection.HEADER_SIZE, (uint)TargetStream.Length - Connection.HEADER_SIZE);

                if (compressed != null &&
                    compressed.Length + Connection.HEADER_SIZE < TargetStream.Length) //only apply compression if it's smaller then the original data
                {
                    TargetStream.Position = Connection.HEADER_SIZE;
                    TargetStream.Write(compressed, 0, compressed.Length);

                    if (TargetStream.Length != compressed.Length + Connection.HEADER_SIZE)
                    {
                        TargetStream.SetLength(compressed.Length + Connection.HEADER_SIZE);
                    }
                }
            }

            //encrypt all the data
            if (EncAlgorithm.HwAES == (conn.EncryptionAlgorithm & EncAlgorithm.HwAES))
            {
                lock (conn.EncAES)
                {
                    //no need to re-size the stream here, AES will encrypt at the same size or bigger then the stream, so data will be overwritten
                    byte[] encrypted = conn.EncAES.Encrypt(TargetStream.GetBuffer(), Connection.HEADER_SIZE, (int)TargetStream.Length - Connection.HEADER_SIZE);
                    TargetStream.Position = Connection.HEADER_SIZE;
                    TargetStream.Write(encrypted, 0, encrypted.Length);
                }
            }
            if (EncAlgorithm.WopEx == (conn.EncryptionAlgorithm & EncAlgorithm.WopEx))
            {
                lock (conn.PayloadEncryption)
                {
                    conn.PayloadEncryption.Encrypt(TargetStream.GetBuffer(), Connection.HEADER_SIZE, (int)TargetStream.Length - Connection.HEADER_SIZE);
                }
            }
            #endregion

            return(pw.Length - PayloadPos);
        }
 private UnsafeQuickLZ quickLz; //change to safe or unsafe
 public QuickLzProtection()
     : base()
 {
     this.quickLz = new UnsafeQuickLZ();
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Save the changes and apply Header Information
        /// </summary>
        public void Commit(Connection conn)
        {
            bool UseFragments = PayloadFrames.Count > 1;
            int  FullLength   = 0;
            byte FragmentId   = (byte)(UseFragments ? 1 : 0);

            //count all the payload, this is the original size
            for (int i = 0; i < PayloadFrames.Count; i++)
            {
                FullLength += (int)PayloadFrames[i].Length - Connection.HEADER_SIZE;
            }

            #region Encryption & Compression
            //compress all the data
            for (int i = 0; i < PayloadFrames.Count; i++)
            {
                MemoryStream stream = PayloadFrames[i];
                if (CompressionAlgorithm.QuickLZ == (conn.CompressionAlgorithm & CompressionAlgorithm.QuickLZ))
                {
                    UnsafeQuickLZ quickLz    = new UnsafeQuickLZ();
                    byte[]        compressed = quickLz.compress(stream.GetBuffer(), (uint)Connection.HEADER_SIZE, (uint)stream.Length - Connection.HEADER_SIZE);

                    if (compressed != null &&
                        compressed.Length + Connection.HEADER_SIZE < stream.Length) //only apply compression if it's smaller then the original data
                    {
                        stream.Position = Connection.HEADER_SIZE;
                        stream.Write(compressed, 0, compressed.Length);

                        if (stream.Length != compressed.Length + Connection.HEADER_SIZE)
                        {
                            stream.SetLength(compressed.Length + Connection.HEADER_SIZE);
                        }
                    }
                }
            }

            //encrypt all the data
            for (int i = 0; i < PayloadFrames.Count; i++)
            {
                MemoryStream stream = PayloadFrames[i];
                if (EncAlgorithm.HwAES == (conn.EncryptionAlgorithm & EncAlgorithm.HwAES))
                {
                    lock (conn.EncAES)
                    {
                        //no need to re-size the stream here, AES will encrypt at the same size or bigger then the stream, so data will be overwritten
                        byte[] encrypted = conn.EncAES.Encrypt(stream.GetBuffer(), Connection.HEADER_SIZE, (int)stream.Length - Connection.HEADER_SIZE);
                        stream.Position = Connection.HEADER_SIZE;
                        stream.Write(encrypted, 0, encrypted.Length);
                    }
                }
                if (EncAlgorithm.WopEx == (conn.EncryptionAlgorithm & EncAlgorithm.WopEx))
                {
                    lock (conn.PayloadEncryption)
                    {
                        conn.PayloadEncryption.Encrypt(stream.GetBuffer(), Connection.HEADER_SIZE, (int)stream.Length - Connection.HEADER_SIZE);
                    }
                }
            }
            #endregion

            for (int i = 0; i < PayloadFrames.Count; i++)
            {
                PayloadWriter pw = new PayloadWriter(PayloadFrames[i]);
                pw.Position = 0;

                //if (pw.Length - Connection.HEADER_SIZE > ushort.MaxValue)
                //    throw new OverflowException(); //should never happen if Write(...) is handled correctly

                ushort PayloadLength = (ushort)(pw.Length - Connection.HEADER_SIZE);

                byte CurPacketId = 0;
                int  FeatureId   = feature != null?feature.GetFeatureId() : -1;

                ushort ConnectionId = OpSocket != null ? OpSocket.ConnectionId : (ushort)0;

                if (i + 1 >= PayloadFrames.Count && UseFragments)
                {
                    FragmentId += 128;
                }

                byte checksum = 0;
                checksum += (byte)PayloadLength;
                checksum += FragmentId;
                checksum += CurPacketId;
                checksum += (byte)ConnectionId;
                checksum += (byte)HeaderId;
                checksum += (byte)FullLength;
                checksum += (byte)FeatureId;

                pw.WriteUShort(PayloadLength); //length
                pw.WriteByte(CurPacketId);     //cur packet id
                pw.WriteUShort(ConnectionId);  //Connection Id
                pw.WriteUShort(HeaderId);      //Header Id
                pw.WriteByte(FragmentId);
                pw.WriteByte(checksum);
                pw.WriteThreeByteInteger(FullLength); //the full packet size, mainly used for Fragmentation
                pw.WriteInteger(FeatureId);

                if (UseFragments)
                {
                    FragmentId++;
                }
            }
        }