A newer version of this documentation is available.

View Latest

InvokeMessage.cs

Contains the functions for sending SOAP messages. Including the logic for signing, encrypting, and constructing the messages. Uses the RequestClient class to send the SOAP-envelopes to the correct endpoint.

// ------------------------------------------------------------------------------------------
// <copyright file="InvokeMessage.cs" company="Pointsharp AB">
//   Pointsharp AB
// </copyright>
// <summary>
//   Defines the Client partial class.
// </summary>
// ------------------------------------------------------------------------------------------

namespace SecMaker.NiP.Client
{
    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Xml;

    public partial class Client
    {
        /// <summary>
        /// Invokes the SOAP message request.
        /// </summary>
        /// <returns>
        /// Returns the SOAP message response as System.String.
        /// </returns>
        public string InvokeMessage(bool verbose)
        {
            var sContractName =
                Utility.GetNodeName(_sMessage);

            var useEncryption =
                UseEncryption(sContractName);

            if (useEncryption)
            {
                EncryptMessage();
            }

            RequestClient.Url = _sUrl;
            RequestClient.DataToSend = _sMessage;
            RequestClient.Method = RequestClient.HttpVerbEnum.POST;
            RequestClient.ActionName = sContractName;
            RequestClient.ContentType = "text/xml; charset=\"utf-8\"";

            _sMessage =
                RequestClient.InvokeClient();

            if (useEncryption)
            {
                DecryptMessage();
            }
            if (verbose)
            {
                Console.WriteLine(_sMessage);
            }
            return _sMessage;
        }

        /// <summary>
        /// Returns condition of using encryption.
        /// GetVersion, Login and GetObject:ApplicationInfo are exceptions for encryption because the user not has beed logged on yet.
        /// </summary>
        /// <param name="contractName">
        /// Contract name of the call as System.String.
        /// </param>
        /// <returns>
        /// Returns condition as System.Boolean.
        /// </returns>
        private bool UseEncryption(string contractName)
        {
            if (_encryptionDisabled)
            {
                return false;
            }
            else return
              (contractName != "GetVersion") &&
              (contractName != "Login") &&
              (contractName != "Logout") &&
              (!_sMessage.ToUpper().Contains("APPLICATIONINFO"));
        }

        /// <summary>
        /// Encrypts the Info element of the requests and inserts the blob, instead of Info, Info into the message.
        /// </summary>
        private void EncryptMessage()
        {
            var sInfo = Utility.GetInfoTest(_sMessage);

            if (!string.IsNullOrEmpty(sInfo))
            {
                Derive();
                var data = Utility.ToBytes(Utility.FormatInfoBlob(sInfo, _sBlobFormat));

                data = Utility.Compress(data, _sCompressionMode);

                data = Utility.AesEncryption(data, _key, _iv);

                var sb = new StringBuilder();

                sb.Append("<Info>");
                sb.Append("<SessionId>");
                sb.Append(_sSessionId);
                sb.Append("</SessionId>");
                sb.Append("<Blob>");
                sb.Append(Utility.ToBase64String(data));
                sb.Append("</Blob>");
                sb.Append("<Count>");
                sb.Append(_counter);
                sb.Append("</Count>");
                sb.Append("</Info>");
                RegexOptions options = RegexOptions.Singleline;
                Regex regex = new Regex("<Info>.*</Info>", options);

                _sMessage = regex.Replace(_sMessage, sb.ToString());
            }
        }


        /// <summary>
        /// Decrypts the Blob element of the reponse and inserts the Info element, instead of Blob, into the message.
        /// </summary>
        private void DecryptMessage()
        {
            if ((_key == null) || (_iv == null))
            {
                Derive();
            }
            //If the message is not a success we have nothing to decrypt
            if (!_sMessage.Contains("NPR_SUCCESS"))
            {
                return;
            }
            var sBlob =
                Utility.ParseXmlElem(_sMessage, "<Blob>");

            var data =
                Convert.FromBase64String(sBlob);

            data =
                Utility.AesDecryption(data, _key, _iv);

            data =
                Utility.Decompress(data, _sCompressionMode);

            _sMessage =
                _sMessage.Replace("<Blob>", string.Empty);

            _sMessage =
                _sMessage.Replace("</Blob>", string.Empty);
            _sMessage =
                _sMessage.Replace(sBlob, Utility.ReformatInfoBlob(
                    Utility.ToString(data)
                    , _sBlobFormat));
        }
    }
}