Beispiel #1
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;
        }
Beispiel #2
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);
        }
Beispiel #3
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);
        }
        /// <summary>
        /// Gets SecPkgContext_Sizes via QueryContextAttributes call.
        /// Throws an exception if the call fails.
        /// </summary>
        /// <param name="phContext">Security context.</param>
        /// <param name="secPkgContext_Sizes">Reference to SecPkgContext_Sizes instance.</param>
        public static void QueryContextSizes(SecHandle phContext, ref SecPkgContext_Sizes secPkgContext_Sizes)
        {
            int result = 0;

            if (_isNT)
                result = QueryContextAttributes_NT(phContext, SECPKG_ATTR_SIZES, ref secPkgContext_Sizes);
            else
                result = QueryContextAttributes__(phContext, SECPKG_ATTR_SIZES, ref secPkgContext_Sizes);

            if (result != SspiApi.SEC_E_OK)
                throw GenuineExceptions.Get_Windows_SspiError(result);
        }
        /// <summary>
        /// Calls MakeSignature SSPI API function and saves obtained signature to 
        /// outputSignature parameter.
        /// Throws an exception if the call fails.
        /// </summary>
        /// <param name="phContext">Established security context handle.</param>
        /// <param name="contentBuffer">Content to make signature for.</param>
        /// <param name="outputSignature">Output stream to write signature to.</param>
        /// <param name="secPkgContext_Sizes">Security context size constants.</param>
        public static void MakeSignature(SspiApi.SecHandle phContext, 
            byte[] contentBuffer, BinaryWriter outputSignature, ref SecPkgContext_Sizes secPkgContext_Sizes)
        {
            SspiApi.SecBufferDescNative secDesc = new SspiApi.SecBufferDescNative();
            SspiApi.SecBufferNative[] secBuffers = new SspiApi.SecBufferNative[2];

            byte[] signBuffer = new byte[secPkgContext_Sizes.cbMaxSignature];
            using (GCHandleKeeper pinnedSignBuffer = new GCHandleKeeper(signBuffer, GCHandleType.Pinned))
            {
                // the first is for getting a sign
                secBuffers[0].BufferType = SspiApi.SECBUFFER_TOKEN;
                secBuffers[0].cbBuffer = secPkgContext_Sizes.cbMaxSignature;
                secBuffers[0].pvBuffer = pinnedSignBuffer.GCHandle.AddrOfPinnedObject();

                // pin contentBuffer
                secBuffers[1].BufferType = SspiApi.SECBUFFER_DATA;
                secBuffers[1].cbBuffer = (int) contentBuffer.Length;
                using (GCHandleKeeper pinnedContentBuffer = new GCHandleKeeper(contentBuffer, GCHandleType.Pinned))
                {
                    secBuffers[1].pvBuffer = pinnedContentBuffer.GCHandle.AddrOfPinnedObject();

                    // setup descriptor
                    secDesc.ulVersion = SspiApi.SECBUFFER_VERSION;
                    secDesc.cBuffers = 2;
                    using (GCHandleKeeper pinnedSecBuffers = new GCHandleKeeper(secBuffers, GCHandleType.Pinned))
                    {
                        secDesc.pBuffers = pinnedSecBuffers.GCHandle.AddrOfPinnedObject();

                        int result = 0;
                        if (_isNT)
                            result = MakeSignature_NT(phContext, 0, ref secDesc, 0);
                        else
                            result = MakeSignature__(phContext, 0, ref secDesc, 0);
                        if (result != SspiApi.SEC_E_OK)
                            throw GenuineExceptions.Get_Windows_SspiError(result);

                        outputSignature.Write(signBuffer, 0, secBuffers[0].cbBuffer);
                    }	// pin sec buffers
                }	// pin the content buffer
            }	// pin the signature buffer
        }
        /// <summary>
        /// Calls EncryptMessage SSPI API function.
        /// Throws an exception if the call fails.
        /// </summary>
        /// <param name="phContext">Established security context handle.</param>
        /// <param name="sourceContent">Source data.</param>
        /// <param name="outputContent">Writer to write encrypted data to.</param>
        /// <param name="secPkgContext_Sizes">Current package's sizes.</param>
        public static void EncryptMessage(SspiApi.SecHandle phContext, 
            Stream sourceContent, BinaryWriter outputContent,
            ref SecPkgContext_Sizes secPkgContext_Sizes)
        {
            SspiApi.SecBufferDescNative secDesc = new SspiApi.SecBufferDescNative();
            // for token, data and padding
            SspiApi.SecBufferNative[] secBuffers = new SspiApi.SecBufferNative[3];

            byte[] signature = new byte[secPkgContext_Sizes.cbSecurityTrailer];
            byte[] message = new byte[(int) sourceContent.Length];
            byte[] padding = new byte[secPkgContext_Sizes.cbBlockSize];

            GenuineUtility.ReadDataFromStream(sourceContent, message, 0, message.Length);

            using (GCHandleKeeper pinnedSignature = new GCHandleKeeper(signature, GCHandleType.Pinned))
            {
                // the first is for signature
                secBuffers[0].BufferType = SspiApi.SECBUFFER_TOKEN;
                secBuffers[0].cbBuffer = signature.Length;
                secBuffers[0].pvBuffer = pinnedSignature.GCHandle.AddrOfPinnedObject();

                using (GCHandleKeeper pinnedMessage = new GCHandleKeeper(message, GCHandleType.Pinned))
                {
                    // the second contains data
                    secBuffers[1].BufferType = SspiApi.SECBUFFER_DATA;
                    secBuffers[1].cbBuffer = message.Length;
                    secBuffers[1].pvBuffer = pinnedMessage.GCHandle.AddrOfPinnedObject();

                    using (GCHandleKeeper pinnedPadding = new GCHandleKeeper(padding, GCHandleType.Pinned))
                    {
                        // the third is for padding
                        secBuffers[2].BufferType = SspiApi.SECBUFFER_PADDING;
                        secBuffers[2].cbBuffer = padding.Length;
                        secBuffers[2].pvBuffer = pinnedPadding.GCHandle.AddrOfPinnedObject();

                        // setup descriptor
                        secDesc.ulVersion = SspiApi.SECBUFFER_VERSION;
                        secDesc.cBuffers = 3;
                        using (GCHandleKeeper pinnedSecBuffers = new GCHandleKeeper(secBuffers, GCHandleType.Pinned))
                        {
                            secDesc.pBuffers = pinnedSecBuffers.GCHandle.AddrOfPinnedObject();

                            // make the call
                            int result = 0;
                            if (_isNT)
                                result = EncryptMessage_NT(phContext, 0, ref secDesc, 0);
                            else
                                result = EncryptMessage__(phContext, 0, ref secDesc, 0);
                            if (result != SspiApi.SEC_E_OK)
                                throw GenuineExceptions.Get_Windows_SspiError(result);

                        }
                    }

                }
            }

            // write sizes
            outputContent.Write( (int) secBuffers[0].cbBuffer );
            outputContent.Write( (int) secBuffers[1].cbBuffer );
            outputContent.Write( (int) secBuffers[2].cbBuffer );

            // and content
            outputContent.Write( signature, 0, secBuffers[0].cbBuffer );
            outputContent.Write( message, 0, secBuffers[1].cbBuffer );
            outputContent.Write( padding, 0, secBuffers[2].cbBuffer );
        }
 private static extern int QueryContextAttributes__(SecHandle phContext,
     int ulAttribute, ref SecPkgContext_Sizes pBuffer);