internal static int Decrypt(
SafeDeleteContext securityContext,
byte[] buffer,
int offset,
int count,
bool isConfidential,
bool isNtlm,
out int newOffset,
uint sequenceNumber)
{
if (offset < 0 || offset > (buffer == null ? 0 : buffer.Length))
{
NetEventSource.Fail(null, "Argument 'offset' out of range.");
throw new ArgumentOutOfRangeException(nameof(offset));
}
if (count < 0 || count > (buffer == null ? 0 : buffer.Length - offset))
{
NetEventSource.Fail(null, "Argument 'count' out of range.");
throw new ArgumentOutOfRangeException(nameof(count));
}
if (isNtlm)
{
return DecryptNtlm(securityContext, buffer, offset, count, isConfidential, out newOffset, sequenceNumber);
}
//
// Kerberos and up
//
var securityBuffer = new SecurityBuffer[2];
securityBuffer[0] = new SecurityBuffer(buffer, offset, count, SecurityBufferType.SECBUFFER_STREAM);
securityBuffer[1] = new SecurityBuffer(0, SecurityBufferType.SECBUFFER_DATA);
int errorCode;
if (isConfidential)
{
errorCode = SSPIWrapper.DecryptMessage(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, sequenceNumber);
}
else
{
errorCode = SSPIWrapper.VerifySignature(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, sequenceNumber);
}
if (errorCode != 0)
{
Exception e = new Win32Exception(errorCode);
if (NetEventSource.IsEnabled) NetEventSource.Error(null, e);
throw e;
}
if (securityBuffer[1].type != SecurityBufferType.SECBUFFER_DATA)
{
throw new InternalException();
}
newOffset = securityBuffer[1].offset;
return securityBuffer[1].size;
}