internal static int DecryptNtlm( SafeDeleteContext securityContext, byte[] buffer, int offset, int count, bool isConfidential, out int newOffset, uint sequenceNumber) { const int ntlmSignatureLength = 16; // For the most part the arguments are verified in Decrypt(). if (count < ntlmSignatureLength) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("NTAuthentication#" + LoggingHash.HashString(securityContext) + "::DecryptNtlm", "Argument 'count' out of range."); } Debug.Fail("NTAuthentication#" + LoggingHash.HashString(securityContext) + "::DecryptNtlm", "Argument 'count' out of range."); throw new ArgumentOutOfRangeException(nameof(count)); } var securityBuffer = new SecurityBuffer[2]; securityBuffer[0] = new SecurityBuffer(buffer, offset, ntlmSignatureLength, SecurityBufferType.Token); securityBuffer[1] = new SecurityBuffer(buffer, offset + ntlmSignatureLength, count - ntlmSignatureLength, SecurityBufferType.Data); int errorCode; SecurityBufferType realDataType = SecurityBufferType.Data; if (isConfidential) { errorCode = SSPIWrapper.DecryptMessage(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, sequenceNumber); } else { realDataType |= SecurityBufferType.ReadOnlyFlag; securityBuffer[1].type = realDataType; errorCode = SSPIWrapper.VerifySignature(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, sequenceNumber); } if (errorCode != 0) { if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + LoggingHash.HashString(securityContext) + "::Decrypt() throw Error = " + errorCode.ToString("x", NumberFormatInfo.InvariantInfo)); } throw new Win32Exception(errorCode); } if (securityBuffer[1].type != realDataType) { throw new InternalException(); } newOffset = securityBuffer[1].offset; return(securityBuffer[1].size); }
internal SecurityStatus Decrypt(byte[] payload, ref int offset, ref int count) { if ((offset < 0) || (offset > ((payload == null) ? 0 : payload.Length))) { throw new ArgumentOutOfRangeException("offset"); } if ((count < 0) || (count > ((payload == null) ? 0 : (payload.Length - offset)))) { throw new ArgumentOutOfRangeException("count"); } SecurityBuffer[] input = new SecurityBuffer[] { new SecurityBuffer(payload, offset, count, BufferType.Data), new SecurityBuffer(null, BufferType.Empty), new SecurityBuffer(null, BufferType.Empty), new SecurityBuffer(null, BufferType.Empty) }; int num = SSPIWrapper.DecryptMessage(GlobalSSPI.SSPISecureChannel, this.m_SecurityContext, input, 0); count = 0; BufferType data = BufferType.Data; if (num != 0) { data = BufferType.Extra; } for (int i = 0; i < input.Length; i++) { if (input[i].type == data) { count = input[i].size; break; } } if ((data == BufferType.Data) && (count > 0)) { offset += this.m_HeaderSize; } return((SecurityStatus)num); }
public static SecurityStatusPal DecryptMessage(SafeDeleteContext securityContext, byte[] buffer, ref int offset, ref int count) { // Decryption using SCHANNEL requires four buffers. SecurityBuffer[] decspc = new SecurityBuffer[4]; decspc[0] = new SecurityBuffer(buffer, offset, count, SecurityBufferType.SECBUFFER_DATA); decspc[1] = new SecurityBuffer(null, SecurityBufferType.SECBUFFER_EMPTY); decspc[2] = new SecurityBuffer(null, SecurityBufferType.SECBUFFER_EMPTY); decspc[3] = new SecurityBuffer(null, SecurityBufferType.SECBUFFER_EMPTY); Interop.SECURITY_STATUS errorCode = (Interop.SECURITY_STATUS)SSPIWrapper.DecryptMessage( GlobalSSPI.SSPISecureChannel, securityContext, decspc, 0); count = 0; for (int i = 0; i < decspc.Length; i++) { // Successfully decoded data and placed it at the following position in the buffer, if ((errorCode == Interop.SECURITY_STATUS.OK && decspc[i].type == SecurityBufferType.SECBUFFER_DATA) // or we failed to decode the data, here is the encoded data. || (errorCode != Interop.SECURITY_STATUS.OK && decspc[i].type == SecurityBufferType.SECBUFFER_EXTRA)) { offset = decspc[i].offset; count = decspc[i].size; break; } } return(SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(errorCode)); }
private static int DecryptNtlm( SafeDeleteContext securityContext, byte[] buffer, int offset, int count, bool isConfidential, out int newOffset, uint sequenceNumber) { const int ntlmSignatureLength = 16; // For the most part the arguments are verified in Decrypt(). if (count < ntlmSignatureLength) { NetEventSource.Fail(null, "Argument 'count' out of range."); throw new ArgumentOutOfRangeException(nameof(count)); } TwoSecurityBuffers buffers = default; var securityBuffer = MemoryMarshal.CreateSpan(ref buffers._item0, 2); securityBuffer[0] = new SecurityBuffer(buffer, offset, ntlmSignatureLength, SecurityBufferType.SECBUFFER_TOKEN); securityBuffer[1] = new SecurityBuffer(buffer, offset + ntlmSignatureLength, count - ntlmSignatureLength, SecurityBufferType.SECBUFFER_DATA); int errorCode; SecurityBufferType realDataType = SecurityBufferType.SECBUFFER_DATA; if (isConfidential) { errorCode = SSPIWrapper.DecryptMessage(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, sequenceNumber); } else { realDataType |= SecurityBufferType.SECBUFFER_READONLY; securityBuffer[1].type = realDataType; errorCode = SSPIWrapper.VerifySignature(GlobalSSPI.SSPIAuth, securityContext, securityBuffer, sequenceNumber); } if (errorCode != 0) { Exception e = new Win32Exception(errorCode); if (NetEventSource.IsEnabled) { NetEventSource.Error(null, e); } throw new Win32Exception(errorCode); } if (securityBuffer[1].type != realDataType) { throw new InternalException(securityBuffer[1].type); } newOffset = securityBuffer[1].offset; return(securityBuffer[1].size); }
internal SecurityStatus Decrypt(byte[] payload, ref int offset, ref int count) { GlobalLog.Print("SecureChannel#" + Logging.HashString(this) + "::Decrypt() - offset: " + offset.ToString() + " size: " + count.ToString() + " buffersize: " + payload.Length.ToString()); if (offset < 0 || offset > (payload == null ? 0 : payload.Length)) { GlobalLog.Assert(false, "SecureChannel#" + Logging.HashString(this) + "::Encrypt", "Argument 'offset' out of range."); throw new ArgumentOutOfRangeException("offset"); } if (count < 0 || count > (payload == null ? 0 : payload.Length - offset)) { GlobalLog.Assert(false, "SecureChannel#" + Logging.HashString(this) + "::Encrypt", "Argument 'count' out of range."); throw new ArgumentOutOfRangeException("count"); } SecurityStatus secStatus = SSPIWrapper.DecryptMessage(GlobalSSPI.SSPISecureChannel, _securityContext, payload, ref offset, ref count); return(secStatus); }
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 // TwoSecurityBuffers buffers = default; var securityBuffer = MemoryMarshal.CreateSpan(ref buffers._item0, 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(securityBuffer[1].type); } newOffset = securityBuffer[1].offset; return(securityBuffer[1].size); }
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)) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("NTAuthentication#" + LoggingHash.HashString(securityContext) + "::Decrypt", "Argument 'offset' out of range."); } Debug.Fail("NTAuthentication#" + LoggingHash.HashString(securityContext) + "::Decrypt", "Argument 'offset' out of range."); throw new ArgumentOutOfRangeException(nameof(offset)); } if (count < 0 || count > (buffer == null ? 0 : buffer.Length - offset)) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("NTAuthentication#" + LoggingHash.HashString(securityContext) + "::Decrypt", "Argument 'count' out of range."); } Debug.Fail("NTAuthentication#" + LoggingHash.HashString(securityContext) + "::Decrypt", "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.Stream); securityBuffer[1] = new SecurityBuffer(0, SecurityBufferType.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) { if (GlobalLog.IsEnabled) { GlobalLog.Print("NTAuthentication#" + "::Decrypt() throw Error = " + errorCode.ToString("x", NumberFormatInfo.InvariantInfo)); } throw new Win32Exception(errorCode); } if (securityBuffer[1].type != SecurityBufferType.Data) { throw new InternalException(); } newOffset = securityBuffer[1].offset; return(securityBuffer[1].size); }