Ejemplo n.º 1
0
        public static void DeleteCertificateBinding(params IPEndPoint[] ipPorts)
        {
            if (ipPorts == null || ipPorts.Length == 0)
            {
                return;
            }

            CallHttpApi(
                delegate
            {
                foreach (var ipPort in ipPorts)
                {
                    HTTP_SERVICE_CONFIG_SSL_SET configSslSet =
                        new HTTP_SERVICE_CONFIG_SSL_SET();

                    GCHandle sockAddrHandle = CreateSockaddrStructure(ipPort);
                    IntPtr pIpPort          = sockAddrHandle.AddrOfPinnedObject();
                    HTTP_SERVICE_CONFIG_SSL_KEY httpServiceConfigSslKey =
                        new HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort);
                    configSslSet.KeyDesc = httpServiceConfigSslKey;

                    IntPtr pInputConfigInfo =
                        Marshal.AllocCoTaskMem(
                            Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SET)));
                    Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false);

                    try
                    {
                        uint retVal = HttpDeleteServiceConfiguration(IntPtr.Zero,
                                                                     HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                                                                     pInputConfigInfo,
                                                                     Marshal.SizeOf(configSslSet),
                                                                     IntPtr.Zero);
                        ThrowWin32ExceptionIfError(retVal);
                    }
                    finally
                    {
                        Marshal.FreeCoTaskMem(pInputConfigInfo);
                        if (sockAddrHandle.IsAllocated)
                        {
                            sockAddrHandle.Free();
                        }
                    }
                }
            });
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Create the parameter for the configuration operation
        /// </summary>
        private static HTTP_SERVICE_CONFIG_SSL_SET CreateParameter(IPAddress ipAddress, int port, byte[] hash, StoreName store)
        {
            HTTP_SERVICE_CONFIG_SSL_SET   configSslSet            = new HTTP_SERVICE_CONFIG_SSL_SET();
            HTTP_SERVICE_CONFIG_SSL_KEY   httpServiceConfigSslKey = new HTTP_SERVICE_CONFIG_SSL_KEY();
            HTTP_SERVICE_CONFIG_SSL_PARAM configSslParam          = new HTTP_SERVICE_CONFIG_SSL_PARAM();

            IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, port);
            // serialize the endpoint to a SocketAddress and create an array to hold the values.  Pin the array.
            SocketAddress socketAddress = ipEndPoint.Serialize();

            byte[]   socketBytes         = new byte[socketAddress.Size];
            GCHandle handleSocketAddress = GCHandle.Alloc(socketBytes, GCHandleType.Pinned);

            // Should copy the first 16 bytes (the SocketAddress has a 32 byte buffer, the size will only be 16,
            //which is what the SOCKADDR accepts
            for (int i = 0; i < socketAddress.Size; ++i)
            {
                socketBytes[i] = socketAddress[i];
            }

            httpServiceConfigSslKey.pIpPort = handleSocketAddress.AddrOfPinnedObject();

            GCHandle handleHash = GCHandle.Alloc(hash, GCHandleType.Pinned);

            configSslParam.AppId = new Guid((Assembly.GetEntryAssembly().GetCustomAttributes(typeof(GuidAttribute), false)[0] as GuidAttribute).Value);
            configSslParam.DefaultCertCheckMode                 = 0;
            configSslParam.DefaultFlags                         = HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT;
            configSslParam.DefaultRevocationFreshnessTime       = 0;
            configSslParam.DefaultRevocationUrlRetrievalTimeout = 0;
            configSslParam.pSslCertStoreName                    = store.ToString();
            configSslParam.pSslHash      = handleHash.AddrOfPinnedObject();
            configSslParam.SslHashLength = hash.Length;
            configSslSet.ParamDesc       = configSslParam;
            configSslSet.KeyDesc         = httpServiceConfigSslKey;

            return(configSslSet);
        }
Ejemplo n.º 3
0
 public HTTP_SERVICE_CONFIG_SSL_QUERY(HTTP_SERVICE_CONFIG_QUERY_TYPE QueryDesc, HTTP_SERVICE_CONFIG_SSL_KEY KeyDesc, int dwToken)
 {
     this.QueryDesc = QueryDesc;
     this.KeyDesc   = KeyDesc;
     this.dwToken   = dwToken;
 }
        public static void DeleteCertificateBinding(params IPEndPoint[] ipPorts)
        {
            if (ipPorts == null || ipPorts.Length == 0)
                return;

            CallHttpApi(
            delegate
            {
                foreach (var ipPort in ipPorts)
                {
                    HTTP_SERVICE_CONFIG_SSL_SET configSslSet =
                        new HTTP_SERVICE_CONFIG_SSL_SET();

                    GCHandle sockAddrHandle = CreateSockaddrStructure(ipPort);
                    IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject();
                    HTTP_SERVICE_CONFIG_SSL_KEY httpServiceConfigSslKey =
                        new HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort);
                    configSslSet.KeyDesc = httpServiceConfigSslKey;

                    IntPtr pInputConfigInfo =
                        Marshal.AllocCoTaskMem(
                            Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SET)));
                    Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false);

                    try
                    {
                        uint retVal = HttpDeleteServiceConfiguration(IntPtr.Zero,
                                                                        HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                                                                        pInputConfigInfo,
                                                                        Marshal.SizeOf(configSslSet),
                                                                        IntPtr.Zero);
                        ThrowWin32ExceptionIfError(retVal);
                    }
                    finally
                    {
                        Marshal.FreeCoTaskMem(pInputConfigInfo);
                        if (sockAddrHandle.IsAllocated)
                            sockAddrHandle.Free();
                    }
                }
            });
        }
        public static void BindCertificate(IPEndPoint ipPort, byte[] hash, string storeName, Guid appId)
        {
            if (ipPort == null) throw new ArgumentNullException(nameof(ipPort));
            if (hash == null) throw new ArgumentNullException(nameof(hash));

            CallHttpApi(
                delegate
            {
                HTTP_SERVICE_CONFIG_SSL_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SET();

                GCHandle sockAddrHandle = CreateSockaddrStructure(ipPort);
                IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject();
                HTTP_SERVICE_CONFIG_SSL_KEY httpServiceConfigSslKey =
                    new HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort);
                HTTP_SERVICE_CONFIG_SSL_PARAM configSslParam = new HTTP_SERVICE_CONFIG_SSL_PARAM();


                GCHandle handleHash = GCHandle.Alloc(hash, GCHandleType.Pinned);
                configSslParam.AppId = appId;
                configSslParam.DefaultCertCheckMode = 0;
                configSslParam.DefaultFlags = 0; //HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT;
                configSslParam.DefaultRevocationFreshnessTime = 0;
                configSslParam.DefaultRevocationUrlRetrievalTimeout = 0;
                configSslParam.pSslCertStoreName = storeName;
                configSslParam.pSslHash = handleHash.AddrOfPinnedObject();
                configSslParam.SslHashLength = hash.Length;
                configSslSet.ParamDesc = configSslParam;
                configSslSet.KeyDesc = httpServiceConfigSslKey;

                IntPtr pInputConfigInfo =
                    Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SET)));
                Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false);

                try
                {
                    uint retVal = HttpSetServiceConfiguration(IntPtr.Zero,
                                                                HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                                                                pInputConfigInfo,
                                                                Marshal.SizeOf(configSslSet),
                                                                IntPtr.Zero);

                    if (ERROR_ALREADY_EXISTS != retVal)
                    {
                        ThrowWin32ExceptionIfError(retVal);
                    }
                    else
                    {
                        retVal = HttpDeleteServiceConfiguration(IntPtr.Zero,
                                                                HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                                                                pInputConfigInfo,
                                                                Marshal.SizeOf(configSslSet),
                                                                IntPtr.Zero);
                        ThrowWin32ExceptionIfError(retVal);

                        retVal = HttpSetServiceConfiguration(IntPtr.Zero,
                                                                HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                                                                pInputConfigInfo,
                                                                Marshal.SizeOf(configSslSet),
                                                                IntPtr.Zero);
                        ThrowWin32ExceptionIfError(retVal);
                    }
                }
                finally
                {
                    Marshal.FreeCoTaskMem(pInputConfigInfo);
                    if (handleHash.IsAllocated)
                        handleHash.Free();
                    if (sockAddrHandle.IsAllocated)
                        sockAddrHandle.Free();
                }
            });
        }
        public static SslCertificateInfo QuerySslCertificateInfo(IPEndPoint ipPort)
        {
            SslCertificateInfo result = null;

            uint retVal;
            CallHttpApi(delegate
            {
                GCHandle sockAddrHandle = CreateSockaddrStructure(ipPort);
                IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject();
                HTTP_SERVICE_CONFIG_SSL_KEY sslKey = new HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort);

                HTTP_SERVICE_CONFIG_SSL_QUERY inputConfigInfoQuery =
                    new HTTP_SERVICE_CONFIG_SSL_QUERY
                    {
                        QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryExact,
                        KeyDesc = sslKey
                    };

                IntPtr pInputConfigInfo =
                    Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_QUERY)));
                Marshal.StructureToPtr(inputConfigInfoQuery, pInputConfigInfo, false);

                IntPtr pOutputConfigInfo = IntPtr.Zero;
                int returnLength = 0;

                try
                {
                    HTTP_SERVICE_CONFIG_ID queryType = HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo;
                    int inputConfigInfoSize = Marshal.SizeOf(inputConfigInfoQuery);
                    retVal = HttpQueryServiceConfiguration(IntPtr.Zero,
                                                            queryType,
                                                            pInputConfigInfo,
                                                            inputConfigInfoSize,
                                                            pOutputConfigInfo,
                                                            returnLength,
                                                            out returnLength,
                                                            IntPtr.Zero);
                    if (retVal == ERROR_FILE_NOT_FOUND)
                        return;

                    if (ERROR_INSUFFICIENT_BUFFER == retVal) // ERROR_INSUFFICIENT_BUFFER = 122
                    {
                        pOutputConfigInfo = Marshal.AllocCoTaskMem(returnLength);

                        try
                        {
                            retVal = HttpQueryServiceConfiguration(IntPtr.Zero,
                                                                                    queryType,
                                                                                    pInputConfigInfo,
                                                                                    inputConfigInfoSize,
                                                                                    pOutputConfigInfo,
                                                                                    returnLength,
                                                                                    out returnLength,
                                                                                    IntPtr.Zero);
                            ThrowWin32ExceptionIfError(retVal);

                            var outputConfigInfo =
                                (HTTP_SERVICE_CONFIG_SSL_SET)
                                Marshal.PtrToStructure(pOutputConfigInfo, typeof(HTTP_SERVICE_CONFIG_SSL_SET));

                            byte[] hash = new byte[outputConfigInfo.ParamDesc.SslHashLength];
                            Marshal.Copy(outputConfigInfo.ParamDesc.pSslHash, hash, 0, hash.Length);

                            Guid appId = outputConfigInfo.ParamDesc.AppId;
                            string storeName = outputConfigInfo.ParamDesc.pSslCertStoreName;

                            result = new SslCertificateInfo { AppId = appId, Hash = hash, StoreName = storeName, IpPort = ipPort };
                        }
                        finally
                        {
                            Marshal.FreeCoTaskMem(pOutputConfigInfo);
                        }
                    }
                    else
                    {
                        ThrowWin32ExceptionIfError(retVal);
                    }
                }
                finally
                {
                    Marshal.FreeCoTaskMem(pInputConfigInfo);
                    if (sockAddrHandle.IsAllocated)
                        sockAddrHandle.Free();
                }
            });

            return result;
        }
Ejemplo n.º 7
0
        public static void BindCertificate(string ipAddress, int port, byte[] hash)
        {
            TraceSource.WriteInfo(
                PortAclUtility.TraceType,
                "Started to Bind certificate to port. ipAddress: {0}, port: {1}, hash: {2}. Current thread identity: {3}",
                ipAddress,
                port,
                BitConverter.ToString(hash),
                Thread.CurrentPrincipal.Identity.Name);

            uint retVal = (uint)NOERROR; // NOERROR = 0

            HTTPAPI_VERSION httpApiVersion = new HTTPAPI_VERSION(1, 0);

            retVal = HttpInitialize(httpApiVersion, HTTP_INITIALIZE_CONFIG, IntPtr.Zero);

            TraceSource.WriteInfo(
                PortAclUtility.TraceType,
                "HttpInitialize completed with return value: {0}.",
                retVal);

            if ((uint)NOERROR == retVal)
            {
                HTTP_SERVICE_CONFIG_SSL_SET   configSslSet            = new HTTP_SERVICE_CONFIG_SSL_SET();
                HTTP_SERVICE_CONFIG_SSL_KEY   httpServiceConfigSslKey = new HTTP_SERVICE_CONFIG_SSL_KEY();
                HTTP_SERVICE_CONFIG_SSL_PARAM configSslParam          = new HTTP_SERVICE_CONFIG_SSL_PARAM();

                IPAddress ip = IPAddress.Any; //IPAddress.Parse("0.0.0.0");

                IPEndPoint ipEndPoint = new IPEndPoint(ip, port);
                // serialize the endpoint to a SocketAddress and create an array to hold the values.  Pin the array.
                SocketAddress socketAddress       = ipEndPoint.Serialize();
                byte[]        socketBytes         = new byte[socketAddress.Size];
                GCHandle      handleSocketAddress = GCHandle.Alloc(socketBytes, GCHandleType.Pinned);
                // Should copy the first 16 bytes (the SocketAddress has a 32 byte buffer, the size will only be 16,
                //which is what the SOCKADDR accepts
                for (int i = 0; i < socketAddress.Size; ++i)
                {
                    socketBytes[i] = socketAddress[i];
                }

                httpServiceConfigSslKey.pIpPort = handleSocketAddress.AddrOfPinnedObject();

                GCHandle handleHash = GCHandle.Alloc(hash, GCHandleType.Pinned);
                configSslParam.AppId = Guid.NewGuid();
                configSslParam.DefaultCertCheckMode                 = 0;
                configSslParam.DefaultFlags                         = HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT;
                configSslParam.DefaultRevocationFreshnessTime       = 0;
                configSslParam.DefaultRevocationUrlRetrievalTimeout = 0;
                configSslParam.pSslCertStoreName                    = StoreName.My.ToString();
                configSslParam.pSslHash      = handleHash.AddrOfPinnedObject();
                configSslParam.SslHashLength = hash.Length;
                configSslSet.ParamDesc       = configSslParam;
                configSslSet.KeyDesc         = httpServiceConfigSslKey;

                IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SET)));
                Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false);

                retVal = HttpSetServiceConfiguration(IntPtr.Zero,
                                                     HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                                                     pInputConfigInfo,
                                                     Marshal.SizeOf(configSslSet),
                                                     IntPtr.Zero);

                TraceSource.WriteInfo(
                    PortAclUtility.TraceType,
                    "HttpSetServiceConfiguration completed with return value: {0}.",
                    retVal);

                if ((uint)ERROR_ALREADY_EXISTS == retVal)  // ERROR_ALREADY_EXISTS = 183
                {
                    retVal = HttpDeleteServiceConfiguration(IntPtr.Zero,
                                                            HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                                                            pInputConfigInfo,
                                                            Marshal.SizeOf(configSslSet),
                                                            IntPtr.Zero);

                    TraceSource.WriteInfo(
                        PortAclUtility.TraceType,
                        "HttpDeleteServiceConfiguration completed with return value: {0}.",
                        retVal);

                    if ((uint)NOERROR == retVal)
                    {
                        retVal = HttpSetServiceConfiguration(IntPtr.Zero,
                                                             HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                                                             pInputConfigInfo,
                                                             Marshal.SizeOf(configSslSet),
                                                             IntPtr.Zero);

                        TraceSource.WriteInfo(
                            PortAclUtility.TraceType,
                            "HttpSetServiceConfiguration completed with return value: {0}.",
                            retVal);
                    }
                }

                handleSocketAddress.Free();
                handleHash.Free();
                Marshal.FreeCoTaskMem(pInputConfigInfo);
                HttpTerminate(HTTP_INITIALIZE_CONFIG, IntPtr.Zero);
            }

            if ((uint)NOERROR != retVal)
            {
                TraceSource.WriteError(
                    PortAclUtility.TraceType,
                    "BindCertificate failed with error: {0}.",
                    retVal);

                throw new Win32Exception(Convert.ToInt32(retVal));
            }
        }
Ejemplo n.º 8
0
        public static void BindCertificate(IPEndPoint ipPort, byte[] hash, string storeName, Guid appId)
        {
            if (ipPort == null)
            {
                throw new ArgumentNullException(nameof(ipPort));
            }
            if (hash == null)
            {
                throw new ArgumentNullException(nameof(hash));
            }

            CallHttpApi(
                delegate
            {
                HTTP_SERVICE_CONFIG_SSL_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SET();

                GCHandle sockAddrHandle = CreateSockaddrStructure(ipPort);
                IntPtr pIpPort          = sockAddrHandle.AddrOfPinnedObject();
                HTTP_SERVICE_CONFIG_SSL_KEY httpServiceConfigSslKey =
                    new HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort);
                HTTP_SERVICE_CONFIG_SSL_PARAM configSslParam = new HTTP_SERVICE_CONFIG_SSL_PARAM();


                GCHandle handleHash  = GCHandle.Alloc(hash, GCHandleType.Pinned);
                configSslParam.AppId = appId;
                configSslParam.DefaultCertCheckMode                 = 0;
                configSslParam.DefaultFlags                         = 0; //HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT;
                configSslParam.DefaultRevocationFreshnessTime       = 0;
                configSslParam.DefaultRevocationUrlRetrievalTimeout = 0;
                configSslParam.pSslCertStoreName                    = storeName;
                configSslParam.pSslHash      = handleHash.AddrOfPinnedObject();
                configSslParam.SslHashLength = hash.Length;
                configSslSet.ParamDesc       = configSslParam;
                configSslSet.KeyDesc         = httpServiceConfigSslKey;

                IntPtr pInputConfigInfo =
                    Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SET)));
                Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false);

                try
                {
                    uint retVal = HttpSetServiceConfiguration(IntPtr.Zero,
                                                              HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                                                              pInputConfigInfo,
                                                              Marshal.SizeOf(configSslSet),
                                                              IntPtr.Zero);

                    if (ERROR_ALREADY_EXISTS != retVal)
                    {
                        ThrowWin32ExceptionIfError(retVal);
                    }
                    else
                    {
                        retVal = HttpDeleteServiceConfiguration(IntPtr.Zero,
                                                                HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                                                                pInputConfigInfo,
                                                                Marshal.SizeOf(configSslSet),
                                                                IntPtr.Zero);
                        ThrowWin32ExceptionIfError(retVal);

                        retVal = HttpSetServiceConfiguration(IntPtr.Zero,
                                                             HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                                                             pInputConfigInfo,
                                                             Marshal.SizeOf(configSslSet),
                                                             IntPtr.Zero);
                        ThrowWin32ExceptionIfError(retVal);
                    }
                }
                finally
                {
                    Marshal.FreeCoTaskMem(pInputConfigInfo);
                    if (handleHash.IsAllocated)
                    {
                        handleHash.Free();
                    }
                    if (sockAddrHandle.IsAllocated)
                    {
                        sockAddrHandle.Free();
                    }
                }
            });
        }
Ejemplo n.º 9
0
        public static SslCertificateInfo QuerySslCertificateInfo(IPEndPoint ipPort)
        {
            SslCertificateInfo result = null;

            uint retVal;

            CallHttpApi(delegate
            {
                GCHandle sockAddrHandle            = CreateSockaddrStructure(ipPort);
                IntPtr pIpPort                     = sockAddrHandle.AddrOfPinnedObject();
                HTTP_SERVICE_CONFIG_SSL_KEY sslKey = new HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort);

                HTTP_SERVICE_CONFIG_SSL_QUERY inputConfigInfoQuery =
                    new HTTP_SERVICE_CONFIG_SSL_QUERY
                {
                    QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryExact,
                    KeyDesc   = sslKey
                };

                IntPtr pInputConfigInfo =
                    Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_QUERY)));
                Marshal.StructureToPtr(inputConfigInfoQuery, pInputConfigInfo, false);

                IntPtr pOutputConfigInfo = IntPtr.Zero;
                int returnLength         = 0;

                try
                {
                    HTTP_SERVICE_CONFIG_ID queryType = HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo;
                    int inputConfigInfoSize          = Marshal.SizeOf(inputConfigInfoQuery);
                    retVal = HttpQueryServiceConfiguration(IntPtr.Zero,
                                                           queryType,
                                                           pInputConfigInfo,
                                                           inputConfigInfoSize,
                                                           pOutputConfigInfo,
                                                           returnLength,
                                                           out returnLength,
                                                           IntPtr.Zero);
                    if (retVal == ERROR_FILE_NOT_FOUND)
                    {
                        return;
                    }

                    if (ERROR_INSUFFICIENT_BUFFER == retVal) // ERROR_INSUFFICIENT_BUFFER = 122
                    {
                        pOutputConfigInfo = Marshal.AllocCoTaskMem(returnLength);

                        try
                        {
                            retVal = HttpQueryServiceConfiguration(IntPtr.Zero,
                                                                   queryType,
                                                                   pInputConfigInfo,
                                                                   inputConfigInfoSize,
                                                                   pOutputConfigInfo,
                                                                   returnLength,
                                                                   out returnLength,
                                                                   IntPtr.Zero);
                            ThrowWin32ExceptionIfError(retVal);

                            var outputConfigInfo =
                                (HTTP_SERVICE_CONFIG_SSL_SET)
                                Marshal.PtrToStructure(pOutputConfigInfo, typeof(HTTP_SERVICE_CONFIG_SSL_SET));

                            byte[] hash = new byte[outputConfigInfo.ParamDesc.SslHashLength];
                            Marshal.Copy(outputConfigInfo.ParamDesc.pSslHash, hash, 0, hash.Length);

                            Guid appId       = outputConfigInfo.ParamDesc.AppId;
                            string storeName = outputConfigInfo.ParamDesc.pSslCertStoreName;

                            result = new SslCertificateInfo {
                                AppId = appId, Hash = hash, StoreName = storeName, IpPort = ipPort
                            };
                        }
                        finally
                        {
                            Marshal.FreeCoTaskMem(pOutputConfigInfo);
                        }
                    }
                    else
                    {
                        ThrowWin32ExceptionIfError(retVal);
                    }
                }
                finally
                {
                    Marshal.FreeCoTaskMem(pInputConfigInfo);
                    if (sockAddrHandle.IsAllocated)
                    {
                        sockAddrHandle.Free();
                    }
                }
            });

            return(result);
        }