Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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));
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
        }