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));
}
}
}