Esempio n. 1
0
        //
        // Used only by client SSL code, never returns null.
        //
        internal static string[] GetRequestCertificateAuthorities(SafeDeleteContext securityContext)
        {
            Interop.SspiCli.SecPkgContext_IssuerListInfoEx issuerList =
                (Interop.SspiCli.SecPkgContext_IssuerListInfoEx)SSPIWrapper.QueryContextAttributes(
                    GlobalSSPI.SSPISecureChannel,
                    securityContext,
                    Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX);

            string[] issuers = Array.Empty <string>();

            try
            {
                if (issuerList.cIssuers > 0)
                {
                    unsafe
                    {
                        uint count = issuerList.cIssuers;
                        issuers = new string[issuerList.cIssuers];
                        Interop.SspiCli.CERT_CHAIN_ELEMENT *pIL = (Interop.SspiCli.CERT_CHAIN_ELEMENT *)issuerList.aIssuers.DangerousGetHandle();
                        for (int i = 0; i < count; ++i)
                        {
                            Interop.SspiCli.CERT_CHAIN_ELEMENT *pIL2 = pIL + i;
                            if (pIL2->cbSize <= 0)
                            {
                                NetEventSource.Fail(securityContext, $"Interop.SspiCli._CERT_CHAIN_ELEMENT size is not positive: {pIL2->cbSize}");
                            }
                            if (pIL2->cbSize > 0)
                            {
                                uint   size = pIL2->cbSize;
                                byte * ptr  = (byte *)(pIL2->pCertContext);
                                byte[] x    = new byte[size];
                                for (int j = 0; j < size; j++)
                                {
                                    x[j] = *(ptr + j);
                                }

                                X500DistinguishedName x500DistinguishedName = new X500DistinguishedName(x);
                                issuers[i] = x500DistinguishedName.Name;
                                if (NetEventSource.IsEnabled)
                                {
                                    NetEventSource.Info(securityContext, "IssuerListEx[{issuers[i]}]");
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                if (issuerList.aIssuers != null)
                {
                    issuerList.aIssuers.Dispose();
                }
            }

            return(issuers);
        }
        //
        // Used only by client SSL code, never returns null.
        //
        internal static string[] GetRequestCertificateAuthorities(SafeDeleteContext securityContext)
        {
            Interop.SspiCli.SecPkgContext_IssuerListInfoEx issuerList = default;
            bool success = SSPIWrapper.QueryContextAttributes_SECPKG_ATTR_ISSUER_LIST_EX(GlobalSSPI.SSPISecureChannel, securityContext, ref issuerList, out SafeHandle sspiHandle);

            string[] issuers = Array.Empty <string>();
            try
            {
                if (success && issuerList.cIssuers > 0)
                {
                    unsafe
                    {
                        issuers = new string[issuerList.cIssuers];
                        var elements = new Span <Interop.SspiCli.CERT_CHAIN_ELEMENT>((void *)sspiHandle.DangerousGetHandle(), issuers.Length);
                        for (int i = 0; i < elements.Length; ++i)
                        {
                            if (elements[i].cbSize <= 0)
                            {
                                NetEventSource.Fail(securityContext, $"Interop.SspiCli._CERT_CHAIN_ELEMENT size is not positive: {elements[i].cbSize}");
                            }
                            if (elements[i].cbSize > 0)
                            {
                                byte[] x = new Span <byte>((byte *)elements[i].pCertContext, checked ((int)elements[i].cbSize)).ToArray();
                                var    x500DistinguishedName = new X500DistinguishedName(x);
                                issuers[i] = x500DistinguishedName.Name;
                                if (NetEventSource.IsEnabled)
                                {
                                    NetEventSource.Info(securityContext, "IssuerListEx[{issuers[i]}]");
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                sspiHandle?.Dispose();
            }

            return(issuers);
        }
Esempio n. 3
0
        public static object QueryContextAttributes(SSPIInterface secModule, SafeDeleteContext securityContext, Interop.SspiCli.ContextAttribute contextAttribute, out int errorCode)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(null, contextAttribute);
            }

            int  nativeBlockSize = IntPtr.Size;
            Type handleType      = null;

            switch (contextAttribute)
            {
            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES:
                nativeBlockSize = SecPkgContext_Sizes.SizeOf;
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES:
                nativeBlockSize = SecPkgContext_StreamSizes.SizeOf;
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES:
                handleType = typeof(SafeFreeContextBuffer);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_PACKAGE_INFO:
                handleType = typeof(SafeFreeContextBuffer);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO:
                handleType = typeof(SafeFreeContextBuffer);
                unsafe
                {
                    nativeBlockSize = sizeof(SecPkgContext_NegotiationInfoW);
                }
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET:
                handleType = typeof(SafeFreeContextBuffer);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT:
                handleType = typeof(SafeFreeCertContext);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_LOCAL_CERT_CONTEXT:
                handleType = typeof(SafeFreeCertContext);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX:
                nativeBlockSize = Marshal.SizeOf <Interop.SspiCli.SecPkgContext_IssuerListInfoEx>();
                handleType      = typeof(SafeFreeContextBuffer);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO:
                nativeBlockSize = Marshal.SizeOf <SecPkgContext_ConnectionInfo>();
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_APPLICATION_PROTOCOL:
                nativeBlockSize = Marshal.SizeOf <Interop.SecPkgContext_ApplicationProtocol>();
                break;

            default:
                throw new ArgumentException(System.StringsHelper.Format(Strings.net_invalid_enum, nameof(contextAttribute)), nameof(contextAttribute));
            }

            SafeHandle sspiHandle = null;
            object     attribute  = null;

            try
            {
                var nativeBuffer = new byte[nativeBlockSize];
                errorCode = secModule.QueryContextAttributes(securityContext, contextAttribute, nativeBuffer, handleType, out sspiHandle);
                if (errorCode != 0)
                {
                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Exit(null, $"ERROR = {ErrorDescription(errorCode)}");
                    }
                    return(null);
                }

                switch (contextAttribute)
                {
                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES:
                    attribute = new SecPkgContext_Sizes(nativeBuffer);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES:
                    attribute = new SecPkgContext_StreamSizes(nativeBuffer);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES:
                    attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle());
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_PACKAGE_INFO:
                    attribute = new SecurityPackageInfoClass(sspiHandle, 0);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO:
                    unsafe
                    {
                        fixed(void *ptr = &nativeBuffer[0])
                        {
                            attribute = new NegotiationInfoClass(sspiHandle, (int)((SecPkgContext_NegotiationInfoW *)ptr)->NegotiationState);
                        }
                    }
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET:
                    attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle());
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_LOCAL_CERT_CONTEXT:
                // Fall-through to RemoteCertificate is intentional.
                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT:
                    attribute  = sspiHandle;
                    sspiHandle = null;
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX:
                    attribute  = new Interop.SspiCli.SecPkgContext_IssuerListInfoEx(sspiHandle, nativeBuffer);
                    sspiHandle = null;
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO:
                    attribute = new SecPkgContext_ConnectionInfo(nativeBuffer);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_APPLICATION_PROTOCOL:
                    unsafe
                    {
                        fixed(void *ptr = nativeBuffer)
                        {
                            attribute = Marshal.PtrToStructure <Interop.SecPkgContext_ApplicationProtocol>(new IntPtr(ptr));
                        }
                    }
                    break;

                default:
                    // Will return null.
                    break;
                }
            }
            finally
            {
                if (sspiHandle != null)
                {
                    sspiHandle.Dispose();
                }
            }

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Exit(null, attribute);
            }
            return(attribute);
        }
Esempio n. 4
0
        public static object QueryContextAttributes(SSPIInterface secModule, SafeDeleteContext securityContext, Interop.SspiCli.ContextAttribute contextAttribute, out int errorCode)
        {
            if (NetEventSource.IsEnabled) NetEventSource.Enter(null, contextAttribute);

            int nativeBlockSize = IntPtr.Size;
            Type handleType = null;

            switch (contextAttribute)
            {
                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES:
                    nativeBlockSize = SecPkgContext_Sizes.SizeOf;
                    break;
                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES:
                    nativeBlockSize = SecPkgContext_StreamSizes.SizeOf;
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES:
                    handleType = typeof(SafeFreeContextBuffer);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_PACKAGE_INFO:
                    handleType = typeof(SafeFreeContextBuffer);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO:
                    handleType = typeof(SafeFreeContextBuffer);
                    nativeBlockSize = Marshal.SizeOf<SecPkgContext_NegotiationInfoW>();
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET:
                    handleType = typeof(SafeFreeContextBuffer);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT:
                    handleType = typeof(SafeFreeCertContext);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_LOCAL_CERT_CONTEXT:
                    handleType = typeof(SafeFreeCertContext);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX:
                    nativeBlockSize = Marshal.SizeOf<Interop.SspiCli.SecPkgContext_IssuerListInfoEx>();
                    handleType = typeof(SafeFreeContextBuffer);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO:
                    nativeBlockSize = Marshal.SizeOf<SecPkgContext_ConnectionInfo>();
                    break;

                default:
                    throw new ArgumentException(SR.Format(SR.net_invalid_enum, nameof(contextAttribute)), nameof(contextAttribute));
            }

            SafeHandle sspiHandle = null;
            object attribute = null;

            try
            {
                var nativeBuffer = new byte[nativeBlockSize];
                errorCode = secModule.QueryContextAttributes(securityContext, contextAttribute, nativeBuffer, handleType, out sspiHandle);
                if (errorCode != 0)
                {
                    if (NetEventSource.IsEnabled) NetEventSource.Exit(null, $"ERROR = {ErrorDescription(errorCode)}");
                    return null;
                }

                switch (contextAttribute)
                {
                    case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES:
                        attribute = new SecPkgContext_Sizes(nativeBuffer);
                        break;

                    case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES:
                        attribute = new SecPkgContext_StreamSizes(nativeBuffer);
                        break;

                    case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES:
                        attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle());
                        break;

                    case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_PACKAGE_INFO:
                        attribute = new SecurityPackageInfoClass(sspiHandle, 0);
                        break;

                    case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO:
                        unsafe
                        {
                            fixed (void* ptr = nativeBuffer)
                            {
                                attribute = new NegotiationInfoClass(sspiHandle, Marshal.ReadInt32(new IntPtr(ptr), SecPkgContext_NegotiationInfoW.NegotiationStateOffest));
                            }
                        }
                        break;

                    case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET:
                        attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle());
                        break;

                    case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_LOCAL_CERT_CONTEXT:
                    // Fall-through to RemoteCertificate is intentional.
                    case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT:
                        attribute = sspiHandle;
                        sspiHandle = null;
                        break;

                    case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX:
                        attribute = new Interop.SspiCli.SecPkgContext_IssuerListInfoEx(sspiHandle, nativeBuffer);
                        sspiHandle = null;
                        break;

                    case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO:
                        attribute = new SecPkgContext_ConnectionInfo(nativeBuffer);
                        break;
                    default:
                        // Will return null.
                        break;
                }
            }
            finally
            {
                if (sspiHandle != null)
                {
                    sspiHandle.Dispose();
                }
            }

            if (NetEventSource.IsEnabled) NetEventSource.Exit(null, attribute);
            return attribute;
        }
Esempio n. 5
0
        public static object QueryContextAttributes(SSPIInterface secModule, SafeDeleteContext securityContext, Interop.SspiCli.ContextAttribute contextAttribute, out int errorCode)
        {
            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Enter(nameof(QueryContextAttributes), contextAttribute.ToString());
            }

            int  nativeBlockSize = IntPtr.Size;
            Type handleType      = null;

            switch (contextAttribute)
            {
            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES:
                nativeBlockSize = SecPkgContext_Sizes.SizeOf;
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES:
                nativeBlockSize = SecPkgContext_StreamSizes.SizeOf;
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES:
                handleType = typeof(SafeFreeContextBuffer);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_PACKAGE_INFO:
                handleType = typeof(SafeFreeContextBuffer);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO:
                handleType      = typeof(SafeFreeContextBuffer);
                nativeBlockSize = Marshal.SizeOf <SecPkgContext_NegotiationInfoW>();
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET:
                handleType = typeof(SafeFreeContextBuffer);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT:
                handleType = typeof(SafeFreeCertContext);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_LOCAL_CERT_CONTEXT:
                handleType = typeof(SafeFreeCertContext);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX:
                nativeBlockSize = Marshal.SizeOf <Interop.SspiCli.SecPkgContext_IssuerListInfoEx>();
                handleType      = typeof(SafeFreeContextBuffer);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO:
                nativeBlockSize = Marshal.SizeOf <SecPkgContext_ConnectionInfo>();
                break;

            default:
                throw new ArgumentException(SR.Format(SR.net_invalid_enum, nameof(contextAttribute)), nameof(contextAttribute));
            }

            SafeHandle sspiHandle = null;
            object     attribute  = null;

            try
            {
                var nativeBuffer = new byte[nativeBlockSize];
                errorCode = secModule.QueryContextAttributes(securityContext, contextAttribute, nativeBuffer, handleType, out sspiHandle);
                if (errorCode != 0)
                {
                    if (GlobalLog.IsEnabled)
                    {
                        GlobalLog.Leave("Win32:QueryContextAttributes", "ERROR = " + ErrorDescription(errorCode));
                    }
                    return(null);
                }

                switch (contextAttribute)
                {
                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES:
                    attribute = new SecPkgContext_Sizes(nativeBuffer);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES:
                    attribute = new SecPkgContext_StreamSizes(nativeBuffer);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES:
                    attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle());
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_PACKAGE_INFO:
                    attribute = new SecurityPackageInfoClass(sspiHandle, 0);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO:
                    unsafe
                    {
                        fixed(void *ptr = nativeBuffer)
                        {
                            attribute = new NegotiationInfoClass(sspiHandle, Marshal.ReadInt32(new IntPtr(ptr), SecPkgContext_NegotiationInfoW.NegotiationStateOffest));
                        }
                    }
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET:
                    attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle());
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_LOCAL_CERT_CONTEXT:
                // Fall-through to RemoteCertificate is intentional.
                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT:
                    attribute  = sspiHandle;
                    sspiHandle = null;
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX:
                    attribute  = new Interop.SspiCli.SecPkgContext_IssuerListInfoEx(sspiHandle, nativeBuffer);
                    sspiHandle = null;
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO:
                    attribute = new SecPkgContext_ConnectionInfo(nativeBuffer);
                    break;

                default:
                    // Will return null.
                    break;
                }
            }
            finally
            {
                if (sspiHandle != null)
                {
                    sspiHandle.Dispose();
                }
            }

            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Leave(nameof(QueryContextAttributes), LoggingHash.ObjectToString(attribute));
            }

            return(attribute);
        }