コード例 #1
0
        public static void BindSni(Tuple<string, int> binding, byte[] hash, string storeName, Guid appId)
        {
            if (binding == null) throw new ArgumentNullException(nameof(binding));
            if (hash == null) throw new ArgumentNullException(nameof(hash));

            if (Environment.OSVersion.Version < new Version(6, 2))
            {
                return;
            }

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


                    HTTP_SERVICE_CONFIG_SSL_SNI_KEY httpServiceConfigSslKey =
                        new HTTP_SERVICE_CONFIG_SSL_SNI_KEY();
                    httpServiceConfigSslKey.Host = binding.Item1;
                    httpServiceConfigSslKey.IpPort = CreateSockAddrStorageStructure(binding.Item2);
                    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_SNI_SET)));
                    Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false);

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

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

                            retVal = HttpSetServiceConfiguration(IntPtr.Zero,
                                                                    HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSslSniCertInfo,
                                                                    pInputConfigInfo,
                                                                    Marshal.SizeOf(configSslSet),
                                                                    IntPtr.Zero);
                            ThrowWin32ExceptionIfError(retVal);
                        }
                    }
                    finally
                    {
                        Marshal.FreeCoTaskMem(pInputConfigInfo);
                        if (handleHash.IsAllocated)
                            handleHash.Free();
                    }
                });
        }
コード例 #2
0
        public static void DeleteSniBinding(params Tuple<string, int>[] bindings)
        {
            if (bindings == null || bindings.Length == 0)
                return;

            if (Environment.OSVersion.Version < new Version(6, 2))
            {
                return;
            }

            CallHttpApi(
            delegate
            {
                foreach (var binding in bindings)
                {
                    HTTP_SERVICE_CONFIG_SSL_SNI_SET configSslSet =
                        new HTTP_SERVICE_CONFIG_SSL_SNI_SET();

                    HTTP_SERVICE_CONFIG_SSL_SNI_KEY httpServiceConfigSslKey =
                        new HTTP_SERVICE_CONFIG_SSL_SNI_KEY();
                    httpServiceConfigSslKey.Host = binding.Item1;
                    httpServiceConfigSslKey.IpPort = CreateSockAddrStorageStructure(binding.Item2);
                    configSslSet.KeyDesc = httpServiceConfigSslKey;

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

                    try
                    {
                        uint retVal = HttpDeleteServiceConfiguration(IntPtr.Zero,
                                                                        HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSslSniCertInfo,
                                                                        pInputConfigInfo,
                                                                        Marshal.SizeOf(configSslSet),
                                                                        IntPtr.Zero);
                        ThrowWin32ExceptionIfError(retVal);
                    }
                    finally
                    {
                        Marshal.FreeCoTaskMem(pInputConfigInfo);
                    }
                }
            });
        }
コード例 #3
0
        public static SslSniInfo QuerySslSniInfo(Tuple<string, int> binding)
        {
            if (string.IsNullOrWhiteSpace(binding.Item1))
            {
                return null;
            }

            if (Environment.OSVersion.Version < new Version(6, 2))
            {
                return null;
            }

            SslSniInfo result = null;

            uint retVal;
            CallHttpApi(delegate
            {
                HTTP_SERVICE_CONFIG_SSL_SNI_KEY sslKey = new HTTP_SERVICE_CONFIG_SSL_SNI_KEY();
                sslKey.Host = binding.Item1;
                sslKey.IpPort = CreateSockAddrStorageStructure(binding.Item2);

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

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

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

                try
                {
                    HTTP_SERVICE_CONFIG_ID queryType = HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSslSniCertInfo;
                    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_SNI_SET)
                                Marshal.PtrToStructure(pOutputConfigInfo, typeof(HTTP_SERVICE_CONFIG_SSL_SNI_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;

                            var host = outputConfigInfo.KeyDesc.Host;
                            var ipPort = ReadSockAddrStorageStructure(outputConfigInfo.KeyDesc.IpPort);

                            result = new SslSniInfo { AppId = appId, Hash = hash, StoreName = storeName, Port = ipPort.Port, Host = host };
                        }
                        finally
                        {
                            Marshal.FreeCoTaskMem(pOutputConfigInfo);
                        }
                    }
                    else
                    {
                        ThrowWin32ExceptionIfError(retVal);
                    }
                }
                finally
                {
                    Marshal.FreeCoTaskMem(pInputConfigInfo);
                }
            });

            return result;
        }