private byte[] DecryptSendDataIndication(byte[] userData, SecurityHeaderType securityHeaderType)
{
// Parse security header
int index = 0;
TS_SECURITY_HEADER header = ParseTsSecurityHeader(userData, ref index, securityHeaderType);
// If header is absent, data is not encrypted, return directly
if (null == header)
{
return userData;
}
// Get remain data with security header removed
int remainLength = userData.Length - index;
byte[] remainData = GetBytes(userData, ref index, remainLength);
// Header is present, but still data is not encrypted, return directly
bool isEncryptFlagExist = IsFlagExist((UInt16)header.flags,
(UInt16)TS_SECURITY_HEADER_flags_Values.SEC_ENCRYPT);
bool isRedirectFlagExist = IsFlagExist((UInt16)header.flags,
(UInt16)TS_SECURITY_HEADER_flags_Values.SEC_REDIRECTION_PKT);
if ((!isEncryptFlagExist) && (!isRedirectFlagExist))
{
return remainData;
}
if (isRedirectFlagExist)
{
SecurityHeaderType oldType = securityHeaderType;
UpdateSecurityHeaderType(ref securityHeaderType);
if (oldType != securityHeaderType)
{
index = 0;
header = ParseTsSecurityHeader(userData, ref index, securityHeaderType);
remainLength = userData.Length - index;
remainData = GetBytes(userData, ref index, remainLength);
}
}
// Get data signature (Fips/NonFips only)
byte[] signature;
switch (securityHeaderType)
{
case SecurityHeaderType.NonFips:
TS_SECURITY_HEADER1 nonFipsHeader = (TS_SECURITY_HEADER1)header;
signature = nonFipsHeader.dataSignature;
break;
case SecurityHeaderType.Fips:
TS_SECURITY_HEADER2 fipsHeader = (TS_SECURITY_HEADER2)header;
signature = fipsHeader.dataSignature;
break;
case SecurityHeaderType.Basic:
signature = null;
break;
case SecurityHeaderType.None:
signature = null;
break;
default:
throw new FormatException(ConstValue.ERROR_MESSAGE_ENUM_UNRECOGNIZED);
}
// Check if "Salted MAC Generation" was used in PDU generation
bool isSalted = IsFlagExist((UInt16)header.flags,
(UInt16)TS_SECURITY_HEADER_flags_Values.SEC_SECURE_CHECKSUM);
// Decryption
byte[] decryptedData = null;
if (!clientContext.Decrypt(remainData, signature, isSalted, out decryptedData))
{
// If decryption failed
throw new FormatException(ConstValue.ERROR_MESSAGE_DECRYPTION_FAILED);
}
return decryptedData;
}