Пример #1
0
        private static int GssUnwrap(
            SafeGssContextHandle?context,
            byte[] buffer,
            int offset,
            int count)
        {
            Debug.Assert((buffer != null) && (buffer.Length > 0), "Invalid input buffer passed to Decrypt");
            Debug.Assert((offset >= 0) && (offset <= buffer.Length), "Invalid input offset passed to Decrypt");
            Debug.Assert((count >= 0) && (count <= (buffer.Length - offset)), "Invalid input count passed to Decrypt");

            Interop.NetSecurityNative.GssBuffer decryptedBuffer = default(Interop.NetSecurityNative.GssBuffer);
            try
            {
                Interop.NetSecurityNative.Status minorStatus;
                Interop.NetSecurityNative.Status status = Interop.NetSecurityNative.UnwrapBuffer(out minorStatus, context, buffer, offset, count, ref decryptedBuffer);
                if (status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE)
                {
                    throw new Interop.NetSecurityNative.GssApiException(status, minorStatus);
                }

                return(decryptedBuffer.Copy(buffer, offset));
            }
            finally
            {
                decryptedBuffer.Dispose();
            }
        }
        static byte[] GssWrap(
            SafeGssContextHandle context,
            bool encrypt,
            byte[] buffer,
            int offset,
            int count)
        {
            Debug.Assert((buffer != null) && (buffer.Length > 0), "Invalid input buffer passed to Encrypt");
            Debug.Assert((offset >= 0) && (offset < buffer.Length), "Invalid input offset passed to Encrypt");
            Debug.Assert((count >= 0) && (count <= (buffer.Length - offset)), "Invalid input count passed to Encrypt");

            Interop.NetSecurityNative.GssBuffer encryptedBuffer = default(Interop.NetSecurityNative.GssBuffer);
            try
            {
                Interop.NetSecurityNative.Status minorStatus;
                Interop.NetSecurityNative.Status status = Interop.NetSecurityNative.WrapBuffer(out minorStatus, context, encrypt, buffer, offset, count, ref encryptedBuffer);
                if (status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE)
                {
                    throw new Interop.NetSecurityNative.GssApiException(status, minorStatus);
                }

                return(encryptedBuffer.ToByteArray());
            }
            finally
            {
                encryptedBuffer.Dispose();
            }
        }
Пример #3
0
 protected override bool ReleaseHandle()
 {
     Interop.NetSecurityNative.Status minorStatus;
     Interop.NetSecurityNative.Status status = Interop.NetSecurityNative.ReleaseName(out minorStatus, ref handle);
     SetHandle(IntPtr.Zero);
     return(status == Interop.NetSecurityNative.Status.GSS_S_COMPLETE);
 }
Пример #4
0
        internal static int Encrypt(
            SafeDeleteContext securityContext,
            ReadOnlySpan <byte> buffer,
            bool isConfidential,
            bool isNtlm,
            [NotNull] ref byte[]?output)
        {
            SafeGssContextHandle gssContext = ((SafeDeleteNegoContext)securityContext).GssContext !;
            int resultSize;

            if (isNtlm && !isConfidential)
            {
                Interop.NetSecurityNative.GssBuffer micBuffer = default;
                try
                {
                    Interop.NetSecurityNative.Status minorStatus;
                    Interop.NetSecurityNative.Status status = Interop.NetSecurityNative.GetMic(
                        out minorStatus,
                        gssContext,
                        buffer,
                        ref micBuffer);
                    if (status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE)
                    {
                        throw new Interop.NetSecurityNative.GssApiException(status, minorStatus);
                    }

                    resultSize = micBuffer.Span.Length + buffer.Length;
                    if (output == null || output.Length < resultSize + 4)
                    {
                        output = new byte[resultSize + 4];
                    }

                    micBuffer.Span.CopyTo(output.AsSpan(4));
                    buffer.CopyTo(output.AsSpan(micBuffer.Span.Length + 4));
                    BinaryPrimitives.WriteInt32LittleEndian(output, resultSize);

                    return(resultSize + 4);
                }
                finally
                {
                    micBuffer.Dispose();
                }
            }

            byte[] tempOutput = GssWrap(gssContext, ref isConfidential, buffer);

            // Create space for prefixing with the length
            const int prefixLength = 4;

            output = new byte[tempOutput.Length + prefixLength];
            Array.Copy(tempOutput, 0, output, prefixLength, tempOutput.Length);
            resultSize = tempOutput.Length;
            BinaryPrimitives.WriteInt32LittleEndian(output, resultSize);

            return(resultSize + 4);
        }
Пример #5
0
 protected override unsafe bool ReleaseHandle()
 {
     Interop.NetSecurityNative.Status minorStatus;
     fixed(IntPtr *handleRef = &handle)
     {
         Interop.NetSecurityNative.Status status = Interop.NetSecurityNative.ReleaseName(&minorStatus, handleRef);
         SetHandle(IntPtr.Zero);
         return(status == Interop.NetSecurityNative.Status.GSS_S_COMPLETE);
     }
 }
Пример #6
0
            private static string GetGssApiDisplayStatus(Status status, bool isMinor)
            {
                GssBuffer displayBuffer = default(GssBuffer);

                try
                {
                    Interop.NetSecurityNative.Status minStat;
                    Interop.NetSecurityNative.Status displayCallStatus = isMinor ?
                                                                         DisplayMinorStatus(out minStat, status, ref displayBuffer):
                                                                         DisplayMajorStatus(out minStat, status, ref displayBuffer);
                    return((Status.GSS_S_COMPLETE != displayCallStatus) ? null : Marshal.PtrToStringAnsi(displayBuffer._data));
                }
                finally
                {
                    displayBuffer.Dispose();
                }
            }
Пример #7
0
        public static SafeGssNameHandle CreateTarget(string name)
        {
            Debug.Assert(!string.IsNullOrEmpty(name), "Invalid target name passed to SafeGssNameHandle create");
            SafeGssNameHandle retHandle;

            Interop.NetSecurityNative.Status minorStatus;
            Interop.NetSecurityNative.Status status = Interop.NetSecurityNative.ImportPrincipalName(
                out minorStatus, name, Encoding.UTF8.GetByteCount(name), out retHandle);

            if (status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE)
            {
                retHandle.Dispose();
                throw new Interop.NetSecurityNative.GssApiException(status, minorStatus);
            }

            return(retHandle);
        }
Пример #8
0
        internal static NegotiateAuthenticationStatusCode Unwrap(
            SafeDeleteContext securityContext,
            ReadOnlySpan <byte> input,
            IBufferWriter <byte> outputWriter,
            out bool isEncrypted)
        {
            SafeGssContextHandle gssContext = ((SafeDeleteNegoContext)securityContext).GssContext !;

            Interop.NetSecurityNative.GssBuffer decryptedBuffer = default(Interop.NetSecurityNative.GssBuffer);
            try
            {
                Interop.NetSecurityNative.Status minorStatus;
                Interop.NetSecurityNative.Status status = Interop.NetSecurityNative.UnwrapBuffer(out minorStatus, gssContext, out isEncrypted, input, ref decryptedBuffer);
                if (status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE)
                {
                    return(status switch
                    {
                        Interop.NetSecurityNative.Status.GSS_S_BAD_SIG => NegotiateAuthenticationStatusCode.MessageAltered,
                        _ => NegotiateAuthenticationStatusCode.InvalidToken
                    });
                }
Пример #9
0
        private static byte[] GssWrap(
            SafeGssContextHandle?context,
            bool encrypt,
            ReadOnlySpan <byte> buffer)
        {
            Interop.NetSecurityNative.GssBuffer encryptedBuffer = default;
            try
            {
                Interop.NetSecurityNative.Status minorStatus;
                Interop.NetSecurityNative.Status status = Interop.NetSecurityNative.WrapBuffer(out minorStatus, context, encrypt, buffer, ref encryptedBuffer);
                if (status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE)
                {
                    throw new Interop.NetSecurityNative.GssApiException(status, minorStatus);
                }

                return(encryptedBuffer.ToByteArray());
            }
            finally
            {
                encryptedBuffer.Dispose();
            }
        }
Пример #10
0
        private static int GssUnwrap(
            SafeGssContextHandle context,
            out bool encrypt,
            Span <byte> buffer)
        {
            Interop.NetSecurityNative.GssBuffer decryptedBuffer = default(Interop.NetSecurityNative.GssBuffer);
            try
            {
                Interop.NetSecurityNative.Status minorStatus;
                Interop.NetSecurityNative.Status status = Interop.NetSecurityNative.UnwrapBuffer(out minorStatus, context, out encrypt, buffer, ref decryptedBuffer);
                if (status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE)
                {
                    throw new Interop.NetSecurityNative.GssApiException(status, minorStatus);
                }

                decryptedBuffer.Span.CopyTo(buffer);
                return(decryptedBuffer.Span.Length);
            }
            finally
            {
                decryptedBuffer.Dispose();
            }
        }
Пример #11
0
        internal static int Decrypt(
            SafeDeleteContext securityContext,
            Span <byte> buffer,
            bool isConfidential,
            bool isNtlm,
            out int newOffset)
        {
            SafeGssContextHandle gssContext = ((SafeDeleteNegoContext)securityContext).GssContext !;

            if (isNtlm && !isConfidential)
            {
                const int NtlmSignatureLength = 16;

                if (buffer.Length < NtlmSignatureLength)
                {
                    Debug.Fail("Argument 'count' out of range.");
                    throw new Interop.NetSecurityNative.GssApiException(Interop.NetSecurityNative.Status.GSS_S_DEFECTIVE_TOKEN, 0);
                }

                Interop.NetSecurityNative.Status minorStatus;
                Interop.NetSecurityNative.Status status = Interop.NetSecurityNative.VerifyMic(
                    out minorStatus,
                    gssContext,
                    buffer.Slice(NtlmSignatureLength),
                    buffer.Slice(0, NtlmSignatureLength));
                if (status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE)
                {
                    throw new Interop.NetSecurityNative.GssApiException(status, minorStatus);
                }

                newOffset = NtlmSignatureLength;
                return(buffer.Length - NtlmSignatureLength);
            }

            newOffset = 0;
            return(GssUnwrap(gssContext, out _, buffer));
        }
Пример #12
0
        private static string GssGetUser(
            ref SafeGssContextHandle?context)
        {
            Interop.NetSecurityNative.GssBuffer token = default(Interop.NetSecurityNative.GssBuffer);

            try
            {
                Interop.NetSecurityNative.Status status
                    = Interop.NetSecurityNative.GetUser(out var minorStatus,
                                                        context,
                                                        ref token);

                if (status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE)
                {
                    throw new Interop.NetSecurityNative.GssApiException(status, minorStatus);
                }

                ReadOnlySpan <byte> tokenBytes = token.Span;
                int length = tokenBytes.Length;
                if (length > 0 && tokenBytes[length - 1] == '\0')
                {
                    // Some GSS-API providers (gss-ntlmssp) include the terminating null with strings, so skip that.
                    tokenBytes = tokenBytes.Slice(0, length - 1);
                }

#if NETSTANDARD2_0
                return(Encoding.UTF8.GetString(tokenBytes.ToArray(), 0, tokenBytes.Length));
#else
                return(Encoding.UTF8.GetString(tokenBytes));
#endif
            }
            finally
            {
                token.Dispose();
            }
        }
        private static string GssGetUser(
            ref SafeGssContextHandle context)
        {
            Interop.NetSecurityNative.GssBuffer token = default(Interop.NetSecurityNative.GssBuffer);

            try
            {
                Interop.NetSecurityNative.Status status
                    = Interop.NetSecurityNative.GetUser(out var minorStatus,
                                                        context,
                                                        ref token);

                if (status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE)
                {
                    throw new Interop.NetSecurityNative.GssApiException(status, minorStatus);
                }

                return(Encoding.UTF8.GetString(token.ToByteArray()));
            }
            finally
            {
                token.Dispose();
            }
        }
Пример #14
0
 protected override unsafe bool ReleaseHandle()
 {
     Interop.NetSecurityNative.Status status = Interop.NetSecurityNative.DeleteSecContext(out _, ref handle);
     SetHandle(IntPtr.Zero);
     return(status == Interop.NetSecurityNative.Status.GSS_S_COMPLETE);
 }