Beispiel #1
0
        public static HttpConfigSsl GetHttpSslConfig()
        {
            HttpConfigSsl result = new HttpConfigSsl();
            int           size;

            for (int count = 0;; count++)
            {
                HTTP_SERVICE_CONFIG_SSL_QUERY query = new HTTP_SERVICE_CONFIG_SSL_QUERY(HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryNext, new HTTP_SERVICE_CONFIG_SSL_KEY(), count);
                ErrorCode errorCode = HttpQueryServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, ref query, Marshal.SizeOf(query), null, 0, out size, IntPtr.Zero);
                if (errorCode != ErrorCode.ERROR_SUCCESS)
                {
                    if (errorCode == ErrorCode.ERROR_NO_MORE_ITEMS)
                    {
                        break;
                    }
                    if (errorCode != ErrorCode.ERROR_INSUFFICIENT_BUFFER)
                    {
                        throw new Win32Exception((int)errorCode);
                    }
                    byte[] buffer = new byte[size];
                    fixed(byte *b = buffer)
                    {
                        errorCode = HttpQueryServiceConfiguration(IntPtr.Zero, HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, ref query, Marshal.SizeOf(query), b, size, out size, IntPtr.Zero);
                        if (errorCode != ErrorCode.ERROR_SUCCESS)
                        {
                            throw new Win32Exception((int)errorCode);
                        }
                        HTTP_SERVICE_CONFIG_SSL_SET output = (HTTP_SERVICE_CONFIG_SSL_SET)Marshal.PtrToStructure((IntPtr)b, typeof(HTTP_SERVICE_CONFIG_SSL_SET));

                        result.Add(output.KeyDesc, output.ParamDesc);
                    }
                }
            }
            return(result);
        }
        /// <summary>
        /// Fetches the current SSL certificate configuration.
        /// </summary>
        public static List<SslCertificateBinding> GetSslCertificateBindings()
        {
            List<SslCertificateBinding> bindings = new List<SslCertificateBinding>();

            // initialize library.
            HttpError error = NativeMethods.HttpInitialize(
                new HTTPAPI_VERSION(1,0), 
                HttpInitFlag.HTTP_INITIALIZE_CONFIG, 
                IntPtr.Zero);
            
            if (error != HttpError.NO_ERROR)
            {
                throw ServiceResultException.Create(
                    StatusCodes.BadUnexpectedError,
                    "Could not initialize HTTP library.\r\nError={0}",
                    error);
            }

            // set up the iterator.
            HTTP_SERVICE_CONFIG_SSL_QUERY query = new HTTP_SERVICE_CONFIG_SSL_QUERY();

            query.QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryNext;
            query.KeyDesc.pIpPort = IntPtr.Zero;

            IntPtr pInput = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_QUERY)));
            NativeMethods.ZeroMemory(pInput, Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_QUERY)));

            IntPtr pOutput = IntPtr.Zero;

            try
            {
                // loop through each record.
                for (query.dwToken = 0; error == HttpError.NO_ERROR; query.dwToken++)
                {
                    // get the size of buffer to allocate.
                    Marshal.StructureToPtr(query, pInput, true);

                    int requiredBufferLength = 0;

                    error = NativeMethods.HttpQueryServiceConfiguration(
                        IntPtr.Zero,
                        HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                        pInput,
                        Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_QUERY)),
                        pOutput,
                        requiredBufferLength,
                        out requiredBufferLength,
                        IntPtr.Zero);

                    if (error == HttpError.ERROR_NO_MORE_ITEMS)
                    {
                        break;
                    }

                    if (error != HttpError.ERROR_INSUFFICIENT_BUFFER)
                    {
                        throw ServiceResultException.Create(
                            StatusCodes.BadUnexpectedError,
                            "Could not read SSL configuration information.\r\nError={0}",
                            error);
                    }

                    // allocate the buffer.
                    pOutput = Marshal.AllocHGlobal(requiredBufferLength);
                    NativeMethods.ZeroMemory(pOutput, requiredBufferLength);

                    // get the actual data.
                    error = NativeMethods.HttpQueryServiceConfiguration(
                        IntPtr.Zero,
                        HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                        pInput,
                        Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_QUERY)),
                        pOutput,
                        requiredBufferLength,
                        out requiredBufferLength,
                        IntPtr.Zero);

                    if (error != HttpError.NO_ERROR)
                    {
                        throw ServiceResultException.Create(
                            StatusCodes.BadUnexpectedError,
                            "Could not read SSL configuration information.\r\nError={0}",
                            error);
                    }

                    HTTP_SERVICE_CONFIG_SSL_SET sslSet = (HTTP_SERVICE_CONFIG_SSL_SET)Marshal.PtrToStructure(pOutput, typeof(HTTP_SERVICE_CONFIG_SSL_SET));

                    short family = Marshal.ReadInt16(sslSet.KeyDesc.pIpPort);
                    SslCertificateBinding binding = new SslCertificateBinding();

                    if (family == AF_INET)
                    {
                        SOCKADDR_IN inet = (SOCKADDR_IN)Marshal.PtrToStructure(sslSet.KeyDesc.pIpPort, typeof(SOCKADDR_IN));
                        binding.IPAddress = new IPAddress(inet.addr);
                        binding.Port = inet.port;
                    }

                    if (family == AF_INET6)
                    {
                        SOCKADDR_IN6 inet = (SOCKADDR_IN6)Marshal.PtrToStructure(sslSet.KeyDesc.pIpPort, typeof(SOCKADDR_IN6));
                        binding.IPAddress = new IPAddress(inet.addr, inet.scopeID);
                        binding.Port = inet.port;
                    }

                    binding.Port = (ushort)(((binding.Port & 0xFF00) >> 8) | ((binding.Port & 0x00FF) << 8));

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

                    binding.Thumbprint = Utils.ToHexString(bytes);
                    binding.ApplicationId = sslSet.ParamDesc.AppId;
                    binding.StoreName = sslSet.ParamDesc.pSslCertStoreName;
                    binding.DefaultCertCheckMode = sslSet.ParamDesc.DefaultCertCheckMode;
                    binding.DefaultRevocationFreshnessTime = sslSet.ParamDesc.DefaultRevocationFreshnessTime;
                    binding.DefaultRevocationUrlRetrievalTimeout = sslSet.ParamDesc.DefaultRevocationUrlRetrievalTimeout;
                    binding.DefaultSslCtlIdentifier = sslSet.ParamDesc.pDefaultSslCtlIdentifier;
                    binding.DefaultSslCtlStoreName = sslSet.ParamDesc.pDefaultSslCtlStoreName;
                    binding.DefaultFlags = sslSet.ParamDesc.DefaultFlags;

                    bindings.Add(binding);

                    Marshal.FreeHGlobal(pOutput);
                    pOutput = IntPtr.Zero;
                }
            }
            finally
            {
                if (pInput != IntPtr.Zero)
                {
                    Marshal.DestroyStructure(pInput, typeof(HTTP_SERVICE_CONFIG_SSL_QUERY));
                    Marshal.FreeHGlobal(pInput);
                }

                if (pOutput != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pOutput);
                }

                NativeMethods.HttpTerminate(HttpInitFlag.HTTP_INITIALIZE_CONFIG, IntPtr.Zero);
            }

            return bindings;
        }
Beispiel #3
0
        /// <summary>
        /// Fetches the current SSL certificate configuration.
        /// </summary>
        public static List <SslCertificateBinding> GetSslCertificateBindings()
        {
            List <SslCertificateBinding> bindings = new List <SslCertificateBinding>();

            // initialize library.
            HttpError error = NativeMethods.HttpInitialize(
                new HTTPAPI_VERSION(1, 0),
                HttpInitFlag.HTTP_INITIALIZE_CONFIG,
                IntPtr.Zero);

            if (error != HttpError.NO_ERROR)
            {
                throw ServiceResultException.Create(
                          StatusCodes.BadUnexpectedError,
                          "Could not initialize HTTP library.\r\nError={0}",
                          error);
            }

            // set up the iterator.
            HTTP_SERVICE_CONFIG_SSL_QUERY query = new HTTP_SERVICE_CONFIG_SSL_QUERY();

            query.QueryDesc       = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryNext;
            query.KeyDesc.pIpPort = IntPtr.Zero;

            IntPtr pInput = Marshal.AllocHGlobal(Marshal.SizeOf <HTTP_SERVICE_CONFIG_SSL_QUERY>());

            NativeMethods.ZeroMemory(pInput, Marshal.SizeOf <HTTP_SERVICE_CONFIG_SSL_QUERY>());

            IntPtr pOutput = IntPtr.Zero;

            try
            {
                // loop through each record.
                for (query.dwToken = 0; error == HttpError.NO_ERROR; query.dwToken++)
                {
                    // get the size of buffer to allocate.
                    Marshal.StructureToPtr(query, pInput, true);

                    int requiredBufferLength = 0;

                    error = NativeMethods.HttpQueryServiceConfiguration(
                        IntPtr.Zero,
                        HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                        pInput,
                        Marshal.SizeOf <HTTP_SERVICE_CONFIG_SSL_QUERY>(),
                        pOutput,
                        requiredBufferLength,
                        out requiredBufferLength,
                        IntPtr.Zero);

                    if (error == HttpError.ERROR_NO_MORE_ITEMS)
                    {
                        break;
                    }

                    if (error != HttpError.ERROR_INSUFFICIENT_BUFFER)
                    {
                        throw ServiceResultException.Create(
                                  StatusCodes.BadUnexpectedError,
                                  "Could not read SSL configuration information.\r\nError={0}",
                                  error);
                    }

                    // allocate the buffer.
                    pOutput = Marshal.AllocHGlobal(requiredBufferLength);
                    NativeMethods.ZeroMemory(pOutput, requiredBufferLength);

                    // get the actual data.
                    error = NativeMethods.HttpQueryServiceConfiguration(
                        IntPtr.Zero,
                        HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                        pInput,
                        Marshal.SizeOf <HTTP_SERVICE_CONFIG_SSL_QUERY>(),
                        pOutput,
                        requiredBufferLength,
                        out requiredBufferLength,
                        IntPtr.Zero);

                    if (error != HttpError.NO_ERROR)
                    {
                        throw ServiceResultException.Create(
                                  StatusCodes.BadUnexpectedError,
                                  "Could not read SSL configuration information.\r\nError={0}",
                                  error);
                    }

                    HTTP_SERVICE_CONFIG_SSL_SET sslSet = (HTTP_SERVICE_CONFIG_SSL_SET)Marshal.PtrToStructure <HTTP_SERVICE_CONFIG_SSL_SET>(pOutput);

                    short family = Marshal.ReadInt16(sslSet.KeyDesc.pIpPort);
                    SslCertificateBinding binding = new SslCertificateBinding();

                    if (family == AF_INET)
                    {
                        SOCKADDR_IN inet = (SOCKADDR_IN)Marshal.PtrToStructure <SOCKADDR_IN>(sslSet.KeyDesc.pIpPort);
                        binding.IPAddress = new IPAddress(inet.addr);
                        binding.Port      = inet.port;
                    }

                    if (family == AF_INET6)
                    {
                        SOCKADDR_IN6 inet = (SOCKADDR_IN6)Marshal.PtrToStructure <SOCKADDR_IN6>(sslSet.KeyDesc.pIpPort);
                        binding.IPAddress = new IPAddress(inet.addr, inet.scopeID);
                        binding.Port      = inet.port;
                    }

                    binding.Port = (ushort)(((binding.Port & 0xFF00) >> 8) | ((binding.Port & 0x00FF) << 8));

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

                    binding.Thumbprint                           = Utils.ToHexString(bytes);
                    binding.ApplicationId                        = sslSet.ParamDesc.AppId;
                    binding.StoreName                            = sslSet.ParamDesc.pSslCertStoreName;
                    binding.DefaultCertCheckMode                 = sslSet.ParamDesc.DefaultCertCheckMode;
                    binding.DefaultRevocationFreshnessTime       = sslSet.ParamDesc.DefaultRevocationFreshnessTime;
                    binding.DefaultRevocationUrlRetrievalTimeout = sslSet.ParamDesc.DefaultRevocationUrlRetrievalTimeout;
                    binding.DefaultSslCtlIdentifier              = sslSet.ParamDesc.pDefaultSslCtlIdentifier;
                    binding.DefaultSslCtlStoreName               = sslSet.ParamDesc.pDefaultSslCtlStoreName;
                    binding.DefaultFlags                         = sslSet.ParamDesc.DefaultFlags;

                    bindings.Add(binding);

                    Marshal.FreeHGlobal(pOutput);
                    pOutput = IntPtr.Zero;
                }
            }
            finally
            {
                if (pInput != IntPtr.Zero)
                {
                    Marshal.DestroyStructure <HTTP_SERVICE_CONFIG_SSL_QUERY>(pInput);
                    Marshal.FreeHGlobal(pInput);
                }

                if (pOutput != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pOutput);
                }

                NativeMethods.HttpTerminate(HttpInitFlag.HTTP_INITIALIZE_CONFIG, IntPtr.Zero);
            }

            return(bindings);
        }
Beispiel #4
0
 static extern ErrorCode HttpQueryServiceConfiguration(IntPtr nullHandle, HTTP_SERVICE_CONFIG_ID ConfigId, ref HTTP_SERVICE_CONFIG_SSL_QUERY pInputConfigInfo, int InputConfigInfoLength, byte *pOutputConfigInfo, int OutputConfigInfoLength, out int pReturnLength, IntPtr pOverlapped);
        /// <summary>
        /// Возвращает информацию о привязке сертификата к сетевому адресу и порту.
        /// </summary>
        public static BindCertificateInfo GetBindCertificate(IPEndPoint endPoint)
        {
            BindCertificateInfo result = null;

            CallHttpApi(() =>
            {
                var socketAddressHandle = CreateNativeSocketAddress(endPoint);
                var socketAddressPtr    = socketAddressHandle.AddrOfPinnedObject();

                // Запрос на получение записи конфигурации
                var query = new HTTP_SERVICE_CONFIG_SSL_QUERY
                {
                    QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryExact,
                    KeyDesc   = new HTTP_SERVICE_CONFIG_SSL_KEY(socketAddressPtr)
                };

                var queryPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_QUERY)));
                Marshal.StructureToPtr(query, queryPtr, false);

                var queryResultSize = 0;
                var queryResultPtr  = IntPtr.Zero;

                const HTTP_SERVICE_CONFIG_ID queryType = HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo;

                try
                {
                    // Получение записи конфигурации
                    var querySize    = Marshal.SizeOf(query);
                    var invokeResult = HttpQueryServiceConfiguration(IntPtr.Zero, queryType, queryPtr, querySize,
                                                                     queryResultPtr, queryResultSize, out queryResultSize, IntPtr.Zero);

                    // По запросу ничего не найдено
                    if (invokeResult == ERROR_FILE_NOT_FOUND)
                    {
                        return;
                    }

                    // Недостаточный размер буфера для помещения результата запроса
                    if (invokeResult == ERROR_INSUFFICIENT_BUFFER)
                    {
                        queryResultPtr = Marshal.AllocCoTaskMem(queryResultSize);

                        try
                        {
                            // Получение записи конфигурации (вторая попытка)
                            invokeResult = HttpQueryServiceConfiguration(IntPtr.Zero, queryType, queryPtr, querySize,
                                                                         queryResultPtr, queryResultSize, out queryResultSize, IntPtr.Zero);
                            ThrowWin32ExceptionIfError(invokeResult);

                            // Интерпретация полученного результата запроса из указателя
                            var queryResult =
                                (HTTP_SERVICE_CONFIG_SSL_SET)
                                Marshal.PtrToStructure(queryResultPtr, typeof(HTTP_SERVICE_CONFIG_SSL_SET));

                            var certificate = new byte[queryResult.ParamDesc.SslHashLength];
                            Marshal.Copy(queryResult.ParamDesc.pSslHash, certificate, 0, certificate.Length);

                            StoreName certificateStore;
                            Enum.TryParse(queryResult.ParamDesc.pSslCertStoreName, out certificateStore);

                            result = new BindCertificateInfo
                            {
                                EndPoint         = endPoint,
                                Certificate      = certificate,
                                CertificateStore = certificateStore,
                                ApplicationId    = queryResult.ParamDesc.AppId
                            };
                        }
                        finally
                        {
                            Marshal.FreeCoTaskMem(queryResultPtr);
                        }
                    }
                    else
                    {
                        ThrowWin32ExceptionIfError(invokeResult);
                    }
                }
                finally
                {
                    Marshal.FreeCoTaskMem(queryPtr);

                    if (socketAddressHandle.IsAllocated)
                    {
                        socketAddressHandle.Free();
                    }
                }
            });

            return(result);
        }
        /// <summary>
        /// Возвращает список с информацией о привязках сертификатов к сетевому адресу и порту.
        /// </summary>
        public static BindCertificateInfo[] GetBindCertificates()
        {
            var result = new List <BindCertificateInfo>();

            CallHttpApi(() =>
            {
                uint index = 0;
                uint invokeResult;

                do
                {
                    // Запрос на получение записи конфигурации
                    var query = new HTTP_SERVICE_CONFIG_SSL_QUERY
                    {
                        QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryNext,
                        dwToken   = index
                    };

                    var queryPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_QUERY)));
                    Marshal.StructureToPtr(query, queryPtr, false);

                    var queryResultSize = 0;
                    var queryResultPtr  = IntPtr.Zero;

                    const HTTP_SERVICE_CONFIG_ID queryType = HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo;

                    try
                    {
                        // Получение записи конфигурации
                        var querySize = Marshal.SizeOf(query);
                        invokeResult  = HttpQueryServiceConfiguration(IntPtr.Zero, queryType, queryPtr, querySize,
                                                                      queryResultPtr, queryResultSize, out queryResultSize, IntPtr.Zero);

                        // Перечисление не содержит элементов
                        if (invokeResult == ERROR_NO_MORE_ITEMS)
                        {
                            break;
                        }

                        // Недостаточный размер буфера для помещения результата запроса
                        if (invokeResult == ERROR_INSUFFICIENT_BUFFER)
                        {
                            queryResultPtr = Marshal.AllocCoTaskMem(queryResultSize);

                            try
                            {
                                // Получение записи конфигурации (вторая попытка)
                                invokeResult = HttpQueryServiceConfiguration(IntPtr.Zero, queryType, queryPtr, querySize,
                                                                             queryResultPtr, queryResultSize, out queryResultSize, IntPtr.Zero);
                                ThrowWin32ExceptionIfError(invokeResult);

                                // Интерпретация полученного результата запроса из указателя
                                var queryResult =
                                    (HTTP_SERVICE_CONFIG_SSL_SET)
                                    Marshal.PtrToStructure(queryResultPtr, typeof(HTTP_SERVICE_CONFIG_SSL_SET));

                                var certificate = new byte[queryResult.ParamDesc.SslHashLength];
                                Marshal.Copy(queryResult.ParamDesc.pSslHash, certificate, 0, certificate.Length);

                                StoreName certificateStore;
                                Enum.TryParse(queryResult.ParamDesc.pSslCertStoreName, out certificateStore);

                                result.Add(new BindCertificateInfo
                                {
                                    EndPoint         = CreateManagedSocketAddress(queryResult.KeyDesc.pIpPort),
                                    Certificate      = certificate,
                                    CertificateStore = certificateStore,
                                    ApplicationId    = queryResult.ParamDesc.AppId
                                });

                                index++;
                            }
                            finally
                            {
                                Marshal.FreeCoTaskMem(queryResultPtr);
                            }
                        }
                        else
                        {
                            ThrowWin32ExceptionIfError(invokeResult);
                        }
                    }
                    finally
                    {
                        Marshal.FreeCoTaskMem(queryPtr);
                    }
                }while (invokeResult == NOERROR);
            });

            return(result.ToArray());
        }
        public static SslCertificateInfo[] QuerySslCertificateInfo()
        {
            var result = new List<SslCertificateInfo>();

            CallHttpApi(
                delegate
            {
                uint token = 0;

                uint retVal;
                do
                {
                    HTTP_SERVICE_CONFIG_SSL_QUERY inputConfigInfoQuery =
                        new HTTP_SERVICE_CONFIG_SSL_QUERY
                        {
                            QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryNext,
                            dwToken = token
                        };

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

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

                    const HTTP_SERVICE_CONFIG_ID queryType = HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo;

                    try
                    {
                        int inputConfigInfoSize = Marshal.SizeOf(inputConfigInfoQuery);
                        retVal = HttpQueryServiceConfiguration(IntPtr.Zero,
                                                                queryType,
                                                                pInputConfigInfo,
                                                                inputConfigInfoSize,
                                                                pOutputConfigInfo,
                                                                returnLength,
                                                                out returnLength,
                                                                IntPtr.Zero);
                        if (ERROR_NO_MORE_ITEMS == retVal)
                            break;
                        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;
                                IPEndPoint ipPort = ReadSockaddrStructure(outputConfigInfo.KeyDesc.pIpPort);

                                var resultItem = new SslCertificateInfo
                                {
                                    AppId = appId,
                                    Hash = hash,
                                    StoreName = storeName,
                                    IpPort = ipPort
                                };
                                result.Add(resultItem);
                                token++;
                            }
                            finally
                            {
                                Marshal.FreeCoTaskMem(pOutputConfigInfo);
                            }
                        }
                        else
                        {
                            ThrowWin32ExceptionIfError(retVal);
                        }
                    }
                    finally
                    {
                        Marshal.FreeCoTaskMem(pInputConfigInfo);
                    }
                } while (NOERROR == retVal);
            });

            return result.ToArray();
        }
        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;
        }
Beispiel #9
0
        public static SslCertificateBinding[] GetSslCertificateBindings()
        {
            InitializeHttp();

            try
            {
                var bindings = new List <SslCertificateBinding>();

                uint recordNum = 0;
                while (true)
                {
                    var inputConfigInfoQuery = new HTTP_SERVICE_CONFIG_SSL_QUERY
                    {
                        QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryNext,
                        dwToken   = recordNum++
                    };

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

                    var pOutputConfigInfo = Marshal.AllocCoTaskMem(0);
                    var returnLength      = 0;

                    var retVal = HttpQueryServiceConfiguration(IntPtr.Zero,
                                                               HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                                                               pInputConfigInfo,
                                                               Marshal.SizeOf(inputConfigInfoQuery),
                                                               pOutputConfigInfo,
                                                               returnLength,
                                                               out returnLength,
                                                               IntPtr.Zero);

                    if (Win32ErrorCodes.InsufficientBuffer == retVal)
                    {
                        Marshal.FreeCoTaskMem(pOutputConfigInfo);
                        pOutputConfigInfo = Marshal.AllocCoTaskMem(Convert.ToInt32(returnLength));

                        retVal = HttpQueryServiceConfiguration(IntPtr.Zero,
                                                               HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
                                                               pInputConfigInfo,
                                                               Marshal.SizeOf(inputConfigInfoQuery),
                                                               pOutputConfigInfo,
                                                               returnLength,
                                                               out returnLength,
                                                               IntPtr.Zero);
                    }
                    else if (Win32ErrorCodes.NoMoreItems == retVal)
                    {
                        break;
                    }

                    if (Win32ErrorCodes.Ok == retVal)
                    {
                        var outputConfigInfo = (HTTP_SERVICE_CONFIG_SSL_SET)
                                               Marshal.PtrToStructure(pOutputConfigInfo, typeof(HTTP_SERVICE_CONFIG_SSL_SET));

                        var    paramInfo = outputConfigInfo.ParamDesc;
                        ushort port;
                        var    ipAddress         = ConvertSockAddrPtrToIPAddress(outputConfigInfo.KeyDesc.pIpPort, out port);
                        var    portBytes         = BitConverter.GetBytes(port);
                        var    reversedPortBytes = new [] { portBytes[1], portBytes[0] };
                        port = BitConverter.ToUInt16(reversedPortBytes, 0);

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

                        var hex = new StringBuilder(hash.Length * 2);
                        foreach (var b in hash)
                        {
                            hex.AppendFormat("{0:x2}", b);
                        }
                        var certificateHash = hex.ToString();

                        var appID = paramInfo.AppId;

                        var storeName = ConvertToStoreName(paramInfo.pSslCertStoreName);

                        var    verifyClientCertRevocation = ((paramInfo.DefaultCertCheckMode & 1) == 0);
                        var    verifyRevocationUsingCachedClientCertsOnly = (paramInfo.DefaultCertCheckMode & 2) == 2;
                        var    usageCheckEnabled          = (paramInfo.DefaultCertCheckMode & 16) == 0;
                        var    revocationFreshnessTime    = (uint)paramInfo.DefaultRevocationFreshnessTime;
                        var    urlRetrievalTimeout        = (uint)paramInfo.DefaultRevocationUrlRetrievalTimeout;
                        string ctlIdentifier              = paramInfo.pDefaultSslCtlIdentifier ?? String.Empty;
                        string ctlStoreName               = paramInfo.pDefaultSslCtlStoreName ?? String.Empty;
                        var    dsMapperUsageEnabled       = paramInfo.DefaultFlags.HasFlag(SslParamDefaultFlags.UseDsMapper);
                        var    negotiateClientCertificate = paramInfo.DefaultFlags.HasFlag(SslParamDefaultFlags.NegotiateClientCert);

                        var binding = new SslCertificateBinding(ipAddress, port, certificateHash, appID, storeName,
                                                                verifyClientCertRevocation,
                                                                verifyRevocationUsingCachedClientCertsOnly, usageCheckEnabled, revocationFreshnessTime, urlRetrievalTimeout,
                                                                ctlIdentifier, ctlStoreName, dsMapperUsageEnabled, negotiateClientCertificate);

                        bindings.Add(binding);
                    }
                    else
                    {
                        throw new Win32Exception();
                    }
                }

                return(bindings.ToArray());
            }
            finally
            {
                TerminateHttp();
            }
        }
Beispiel #10
0
        public static SslCertificateInfo[] QuerySslCertificateInfo()
        {
            var result = new List <SslCertificateInfo>();

            CallHttpApi(
                delegate
            {
                uint token = 0;

                uint retVal;
                do
                {
                    HTTP_SERVICE_CONFIG_SSL_QUERY inputConfigInfoQuery =
                        new HTTP_SERVICE_CONFIG_SSL_QUERY
                    {
                        QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryNext,
                        dwToken   = token
                    };

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

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

                    const HTTP_SERVICE_CONFIG_ID queryType = HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo;

                    try
                    {
                        int inputConfigInfoSize = Marshal.SizeOf(inputConfigInfoQuery);
                        retVal = HttpQueryServiceConfiguration(IntPtr.Zero,
                                                               queryType,
                                                               pInputConfigInfo,
                                                               inputConfigInfoSize,
                                                               pOutputConfigInfo,
                                                               returnLength,
                                                               out returnLength,
                                                               IntPtr.Zero);
                        if (ERROR_NO_MORE_ITEMS == retVal)
                        {
                            break;
                        }
                        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;
                                IPEndPoint ipPort = ReadSockaddrStructure(outputConfigInfo.KeyDesc.pIpPort);

                                var resultItem = new SslCertificateInfo
                                {
                                    AppId     = appId,
                                    Hash      = hash,
                                    StoreName = storeName,
                                    IpPort    = ipPort
                                };
                                result.Add(resultItem);
                                token++;
                            }
                            finally
                            {
                                Marshal.FreeCoTaskMem(pOutputConfigInfo);
                            }
                        }
                        else
                        {
                            ThrowWin32ExceptionIfError(retVal);
                        }
                    }
                    finally
                    {
                        Marshal.FreeCoTaskMem(pInputConfigInfo);
                    }
                } while (NOERROR == retVal);
            });

            return(result.ToArray());
        }
Beispiel #11
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);
        }