public static byte[] GetPacketBuffer(BaseSocketConnection connection, byte[] buffer, ref int bufferSize)
        {
            byte[] result = null;
            buffer = CryptUtils.EncryptData(connection, buffer);

            switch (connection.DelimiterType)
            {
            case DelimiterType.dtNone:

                //----- No Delimiter!
                bufferSize = buffer.Length;

                result = connection.BaseHost.BufferManager.TakeBuffer(bufferSize);
                Buffer.BlockCopy(buffer, 0, result, 0, buffer.Length);


                break;

            case DelimiterType.dtMessageTailExcludeOnReceive:
            case DelimiterType.dtMessageTailIncludeOnReceive:

                if (connection.Delimiter?.Length > 0)
                {
                    //----- Need delimiter!
                    bufferSize = buffer.Length + connection.Delimiter.Length;

                    result = connection.BaseHost.BufferManager.TakeBuffer(bufferSize);
                    Buffer.BlockCopy(buffer, 0, result, 0, buffer.Length);
                    Buffer.BlockCopy(connection.Delimiter, 0, result, buffer.Length, connection.Delimiter.Length);
                }
                else
                {
                    bufferSize = buffer.Length;

                    result = connection.BaseHost.BufferManager.TakeBuffer(bufferSize);
                    Buffer.BlockCopy(buffer, 0, result, 0, buffer.Length);
                }

                break;
            }

            return(result);
        }
        private byte[] ReadMessageWithMessageTail(byte[] connectionDelimiter, CallbackData callbackData, ref bool socketWasRead)
        {
            string stringDelimiter = Encoding.GetEncoding(1252).GetString(connectionDelimiter);

            byte[] rawBuffer = null;

            BaseSocketConnection connection  = callbackData.Connection;
            MessageBuffer        readMessage = callbackData.Buffer;

            //----- Message with delimiter!
            int delimiterSize = connectionDelimiter.Length;

            bool readPacket = false;
            bool readSocket = false;

            do
            {
                rawBuffer = null;

                if (readMessage.PacketOffSet > delimiterSize)
                {
                    int index = Encoding.GetEncoding(1252).GetString(readMessage.PacketBuffer).IndexOf(stringDelimiter);

                    if (index >= 0)
                    {
                        rawBuffer = readMessage.GetRawBufferWithTail(connection, index, delimiterSize);

                        //----- Decrypt!
                        rawBuffer = CryptUtils.DecryptData(connection, rawBuffer, FMessageBufferSize);

                        if (readMessage.PacketOffSet == 0)
                        {
                            readPacket = false;
                            readSocket = false;
                        }
                        else
                        {
                            readPacket = true;
                            readSocket = false;

                            FireOnReceived(connection, rawBuffer, false);
                        }
                    }
                    else
                    {
                        readPacket = false;
                        readSocket = true;
                    }
                }
                else
                {
                    readPacket = false;
                    readSocket = (readMessage.PacketOffSet > 0);
                }
            } while (readPacket);

            //----- Adjust room for more!
            readMessage.Resize(FMessageBufferSize);

            if (readSocket)
            {
                if (connection.Active)
                {
                    //----- Read More!
                    if (connection.Stream != null)
                    {
                        //----- Ssl!
                        connection.Stream.BeginRead(readMessage.PacketBuffer, readMessage.PacketOffSet, readMessage.PacketRemaining, new AsyncCallback(BeginReadCallback), callbackData);
                    }
                    else
                    {
                        //----- Socket!
                        connection.Socket.BeginReceive(readMessage.PacketBuffer, readMessage.PacketOffSet, readMessage.PacketRemaining, SocketFlags.None, new AsyncCallback(BeginReadCallback), callbackData);
                    }
                }
            }

            socketWasRead = readSocket;
            return(rawBuffer);
        }
        private byte[] ReadMessageWithPacketHeader(byte[] connectionDelimiter, CallbackData callbackData, ref bool socketWasRead)
        {
            byte[] rawBuffer = null;

            BaseSocketConnection connection  = callbackData.Connection;
            MessageBuffer        readMessage = callbackData.Buffer;

            //----- Message with delimiter!
            int delimiterSize = connectionDelimiter.Length + 3;

            bool readPacket = false;
            bool readSocket = false;

            do
            {
                rawBuffer = null;

                if (readMessage.PacketOffSet > delimiterSize)
                {
                    //----- Has Delimiter!
                    for (int i = 0; i < connectionDelimiter.Length; i++)
                    {
                        if (connectionDelimiter[i] != readMessage.PacketBuffer[i])
                        {
                            //----- Bad Delimiter!
                            throw new BadDelimiterException("Message delimiter is different from Host delimiter.");
                        }
                    }

                    //----- Get Length!
                    int messageLength = (readMessage.PacketBuffer[connectionDelimiter.Length] << 16)
                                        + (readMessage.PacketBuffer[connectionDelimiter.Length + 1] << 8)
                                        + (readMessage.PacketBuffer[connectionDelimiter.Length + 2]);

                    if (messageLength > FMessageBufferSize)
                    {
                        throw new MessageLengthException("Message length is greater than Host maximum message length.");
                    }

                    //----- Check Length!
                    if (messageLength == readMessage.PacketOffSet)
                    {
                        //----- Equal -> Get rawBuffer!
                        rawBuffer = readMessage.GetRawBuffer(messageLength, delimiterSize);

                        //----- Decrypt!
                        rawBuffer = CryptUtils.DecryptData(connection, rawBuffer, FMessageBufferSize);

                        readPacket = false;
                        readSocket = false;
                    }
                    else
                    {
                        if (messageLength < readMessage.PacketOffSet)
                        {
                            //----- Less -> Get rawBuffer and fire event!
                            rawBuffer = readMessage.GetRawBuffer(messageLength, delimiterSize);

                            //----- Decrypt!
                            rawBuffer = CryptUtils.DecryptData(connection, rawBuffer, FMessageBufferSize);

                            readPacket = true;
                            readSocket = false;

                            FireOnReceived(connection, rawBuffer, false);
                        }
                        else
                        {
                            if (messageLength > readMessage.PacketOffSet)
                            {
                                //----- Greater -> Read Socket!
                                if (messageLength > readMessage.PacketLength)
                                {
                                    readMessage.Resize(messageLength);
                                }

                                readPacket = false;
                                readSocket = true;
                            }
                        }
                    }
                }
                else
                {
                    if (readMessage.PacketRemaining < delimiterSize)
                    {
                        //----- Adjust room for more!
                        readMessage.Resize(readMessage.PacketLength + delimiterSize);
                    }

                    readPacket = false;
                    readSocket = true;
                }
            } while (readPacket);

            if (readSocket)
            {
                if (connection.Active)
                {
                    //----- Read More!
                    if (connection.Stream != null)
                    {
                        //----- Ssl!
                        connection.Stream.BeginRead(readMessage.PacketBuffer, readMessage.PacketOffSet, readMessage.PacketRemaining, new AsyncCallback(BeginReadCallback), callbackData);
                    }
                    else
                    {
                        //----- Socket!
                        connection.Socket.BeginReceive(readMessage.PacketBuffer, readMessage.PacketOffSet, readMessage.PacketRemaining, SocketFlags.None, new AsyncCallback(BeginReadCallback), callbackData);
                    }
                }
            }

            socketWasRead = readSocket;
            return(rawBuffer);
        }
Example #4
0
        /// <summary>
        /// Gets a packet message!
        /// </summary>
        /// <param name="connection">
        /// Socket connection.
        /// </param>
        /// <param name="buffer">
        /// Data.
        /// </param>
        public static MessageBuffer GetPacketMessage(BaseSocketConnection connection, byte[] buffer)
        {
            byte[]        workBuffer    = null;
            MessageBuffer messageBuffer = null;

            workBuffer = CryptUtils.EncryptData(connection, buffer);

            switch (connection.DelimiterType)
            {
            case DelimiterType.dtNone:

                //----- No Delimiter!
                messageBuffer = new MessageBuffer(buffer, workBuffer);
                break;

            case DelimiterType.dtPacketHeader:

                if (connection.Delimiter != null && connection.Delimiter.Length >= 0)
                {
                    //----- Need delimiter!
                    int    delimiterSize = connection.Delimiter.Length + 3;
                    byte[] result        = new byte[workBuffer.Length + delimiterSize];

                    int messageLength = result.Length;

                    //----- Delimiter!
                    for (int i = 0; i < connection.Delimiter.Length; i++)
                    {
                        result[i] = connection.Delimiter[i];
                    }

                    //----- Length!
                    result[connection.Delimiter.Length]     = Convert.ToByte((messageLength & 0xFF0000) >> 16);
                    result[connection.Delimiter.Length + 1] = Convert.ToByte((messageLength & 0xFF00) >> 8);
                    result[connection.Delimiter.Length + 2] = Convert.ToByte(messageLength & 0xFF);

                    Buffer.BlockCopy(workBuffer, 0, result, delimiterSize, workBuffer.Length);

                    messageBuffer = new MessageBuffer(buffer, result);
                }

                break;

            case DelimiterType.dtMessageTailExcludeOnReceive:
            case DelimiterType.dtMessageTailIncludeOnReceive:

                if (connection.Delimiter != null && connection.Delimiter.Length >= 0)
                {
                    //----- Need delimiter!
                    byte[] result = new byte[workBuffer.Length + connection.Delimiter.Length];

                    Buffer.BlockCopy(workBuffer, 0, result, 0, workBuffer.Length);
                    Buffer.BlockCopy(connection.Delimiter, 0, result, workBuffer.Length, connection.Delimiter.Length);

                    messageBuffer = new MessageBuffer(buffer, result);
                }

                break;
            }

            return(messageBuffer);
        }
Example #5
0
        private void InitializeConnectionReceiveCallback(IAsyncResult ar)
        {
            if (!Disposed)
            {
                BaseSocketConnection connection  = null;
                MessageBuffer        readMessage = null;

                try
                {
                    CallbackData callbackData = (CallbackData)ar.AsyncState;

                    connection  = callbackData.Connection;
                    readMessage = callbackData.Buffer;

                    if (connection.Active)
                    {
                        bool readSocket = true;
                        bool completed  = false;

                        int readBytes = connection.Socket.EndReceive(ar);

                        if (readBytes > 0)
                        {
                            readMessage.PacketOffSet += readBytes;
                            byte[] message = null;

                            try
                            {
                                message = Convert.FromBase64String(Encoding.GetEncoding(1252).GetString(readMessage.PacketBuffer, 0, readMessage.PacketOffSet));
                            }
                            catch (FormatException)
                            {
                                //----- Base64 transformation error!
                            }

                            if ((message != null) && (Encoding.GetEncoding(1252).GetString(message).Contains("</AuthMessage>")))
                            {
                                //----- Get RSA provider!
                                RSACryptoServiceProvider serverPrivateKey;
                                RSACryptoServiceProvider clientPublicKey = new RSACryptoServiceProvider();
                                byte[] signMessage;

                                FCryptoService.OnSymmetricAuthenticate(connection, out serverPrivateKey, out signMessage);

                                //----- Deserialize authentication message!
                                MemoryStream m = new MemoryStream();
                                m.Write(message, 0, message.Length);
                                m.Position = 0;

                                XmlSerializer xml = new XmlSerializer(typeof(AuthMessage));
                                AuthMessage   am  = (AuthMessage)xml.Deserialize(m);

                                //----- Generates symmetric algoritm!
                                SymmetricAlgorithm sa = CryptUtils.CreateSymmetricAlgoritm(connection.EncryptType);
                                sa.Key = serverPrivateKey.Decrypt(am.SessionKey, false);
                                sa.IV  = serverPrivateKey.Decrypt(am.SessionIV, false);

                                //----- Adjust connection cryptors!
                                connection.Encryptor = sa.CreateEncryptor();
                                connection.Decryptor = sa.CreateDecryptor();

                                //----- Verify sign!
                                clientPublicKey.FromXmlString(Encoding.UTF8.GetString(CryptUtils.DecryptDataForAuthenticate(sa, am.SourceKey, PaddingMode.ISO10126)));

                                m.SetLength(0);
                                m.Write(am.SourceKey, 0, am.SourceKey.Length);
                                m.Write(am.SessionKey, 0, am.SessionKey.Length);
                                m.Write(signMessage, 0, signMessage.Length);

                                if (clientPublicKey.VerifyData(CryptUtils.EncryptDataForAuthenticate(sa, m.ToArray(), PaddingMode.PKCS7), new SHA1CryptoServiceProvider(), am.Sign))
                                {
                                    completed = true;
                                }

                                readSocket = false;

                                m.Close();
                                am.SessionIV.Initialize();
                                am.SessionKey.Initialize();
                                serverPrivateKey.Clear();
                                clientPublicKey.Clear();

                                readMessage  = null;
                                callbackData = null;

                                if (!completed)
                                {
                                    throw new SymmetricAuthenticationException("Symmetric sign error.");
                                }

                                FHost.FireOnConnected(connection);
                            }

                            if (readSocket)
                            {
                                connection.Socket.BeginReceive(readMessage.PacketBuffer, readMessage.PacketOffSet, readMessage.PacketRemaining, SocketFlags.None, new AsyncCallback(InitializeConnectionReceiveCallback), callbackData);
                            }
                        }
                        else
                        {
                            throw new SymmetricAuthenticationException("Symmetric authentication error.");
                        }
                    }
                }
                catch (Exception ex)
                {
                    FHost.FireOnException(connection, ex);
                }
            }
        }
Example #6
0
        protected void InitializeCryptService(BaseSocketConnection connection)
        {
            //----- None!
            if (connection.EncryptType == EncryptType.etNone || connection.EncryptType == EncryptType.etBase64)
            {
                FHost.FireOnConnected(connection);
            }

            //----- Symmetric!
            if (connection.EncryptType == EncryptType.etRijndael || connection.EncryptType == EncryptType.etTripleDES)
            {
                if (FHost.HostType == HostType.htClient)
                {
                    //----- Get RSA provider!
                    RSACryptoServiceProvider serverPublicKey;
                    RSACryptoServiceProvider clientPrivateKey = new RSACryptoServiceProvider();
                    byte[] signMessage;

                    FCryptoService.OnSymmetricAuthenticate(connection, out serverPublicKey, out signMessage);

                    //----- Generates symmetric algoritm!
                    SymmetricAlgorithm sa = CryptUtils.CreateSymmetricAlgoritm(connection.EncryptType);
                    sa.GenerateIV();
                    sa.GenerateKey();

                    //----- Adjust connection cryptors!
                    connection.Encryptor = sa.CreateEncryptor();
                    connection.Decryptor = sa.CreateDecryptor();

                    //----- Create authenticate structure!
                    AuthMessage am = new AuthMessage();
                    am.SessionIV  = serverPublicKey.Encrypt(sa.IV, false);
                    am.SessionKey = serverPublicKey.Encrypt(sa.Key, false);
                    am.SourceKey  = CryptUtils.EncryptDataForAuthenticate(sa, Encoding.UTF8.GetBytes(clientPrivateKey.ToXmlString(false)), PaddingMode.ISO10126);

                    //----- Sign message with am.SourceKey, am.SessionKey and signMessage!
                    //----- Need to use PaddingMode.PKCS7 in sign!
                    MemoryStream m = new MemoryStream();
                    m.Write(am.SourceKey, 0, am.SourceKey.Length);
                    m.Write(am.SessionKey, 0, am.SessionKey.Length);
                    m.Write(signMessage, 0, signMessage.Length);

                    am.Sign = clientPrivateKey.SignData(CryptUtils.EncryptDataForAuthenticate(sa, m.ToArray(), PaddingMode.PKCS7), new SHA1CryptoServiceProvider());

                    //----- Serialize authentication message!
                    XmlSerializer xml = new XmlSerializer(typeof(AuthMessage));
                    m.SetLength(0);
                    xml.Serialize(m, am);

                    //----- Send structure!
                    MessageBuffer mb = new MessageBuffer(0);
                    mb.PacketBuffer = Encoding.GetEncoding(1252).GetBytes(Convert.ToBase64String(m.ToArray()));
                    connection.Socket.BeginSend(mb.PacketBuffer, mb.PacketOffSet, mb.PacketRemaining, SocketFlags.None, new AsyncCallback(InitializeConnectionSendCallback), new CallbackData(connection, mb));

                    m.Close();
                    am.SessionIV.Initialize();
                    am.SessionKey.Initialize();
                    serverPublicKey.Clear();
                    clientPrivateKey.Clear();
                }
                else
                {
                    //----- Create empty authenticate structure!
                    MessageBuffer mb = new MessageBuffer(8192);

                    //----- Start receive structure!
                    connection.Socket.BeginReceive(mb.PacketBuffer, mb.PacketOffSet, mb.PacketRemaining, SocketFlags.None, new AsyncCallback(InitializeConnectionReceiveCallback), new CallbackData(connection, mb));
                }
            }

            //----- Asymmetric!
            if (connection.EncryptType == EncryptType.etSSL)
            {
                if (FHost.HostType == HostType.htClient)
                {
                    //----- Get SSL items!
                    X509Certificate2Collection certs = null;
                    string serverName      = null;
                    bool   checkRevocation = true;

                    FCryptoService.OnSSLClientAuthenticate(connection, out serverName, ref certs, ref checkRevocation);

                    //----- Authneticate SSL!
                    SslStream ssl = new SslStream(new NetworkStream(connection.Socket), true, new RemoteCertificateValidationCallback(ValidateServerCertificateCallback));

                    if (certs == null)
                    {
                        ssl.BeginAuthenticateAsClient(serverName, new AsyncCallback(SslAuthenticateCallback), new AuthenticateCallbackData(connection, ssl, HostType.htClient));
                    }
                    else
                    {
                        ssl.BeginAuthenticateAsClient(serverName, certs, System.Security.Authentication.SslProtocols.Default, checkRevocation, new AsyncCallback(SslAuthenticateCallback), new AuthenticateCallbackData(connection, ssl, HostType.htClient));
                    }
                }
                else
                {
                    //----- Get SSL items!
                    X509Certificate2 cert = null;
                    bool             clientAuthenticate = false;
                    bool             checkRevocation    = true;

                    FCryptoService.OnSSLServerAuthenticate(connection, out cert, out clientAuthenticate, ref checkRevocation);

                    //----- Authneticate SSL!
                    SslStream ssl = new SslStream(new NetworkStream(connection.Socket));
                    ssl.BeginAuthenticateAsServer(cert, clientAuthenticate, System.Security.Authentication.SslProtocols.Default, checkRevocation, new AsyncCallback(SslAuthenticateCallback), new AuthenticateCallbackData(connection, ssl, HostType.htServer));
                }
            }
        }