private static CertificateBinding CreateCertificateBindingInfo(HttpApi.HTTP_SERVICE_CONFIG_SSL_SET configInfo) { byte[] hash = new byte[configInfo.ParamDesc.SslHashLength]; Marshal.Copy(configInfo.ParamDesc.pSslHash, hash, 0, hash.Length); Guid appId = configInfo.ParamDesc.AppId; string storeName = configInfo.ParamDesc.pSslCertStoreName; IPEndPoint ipPort = SockaddrInterop.ReadSockaddrStructure(configInfo.KeyDesc.pIpPort); var checkModes = configInfo.ParamDesc.DefaultCertCheckMode; var options = new BindingOptions { DoNotVerifyCertificateRevocation = HasFlag(checkModes, HttpApi.CertCheckModes.DoNotVerifyCertificateRevocation), VerifyRevocationWithCachedCertificateOnly = HasFlag(checkModes, HttpApi.CertCheckModes.VerifyRevocationWithCachedCertificateOnly), EnableRevocationFreshnessTime = HasFlag(checkModes, HttpApi.CertCheckModes.EnableRevocationFreshnessTime), NoUsageCheck = HasFlag(checkModes, HttpApi.CertCheckModes.NoUsageCheck), RevocationFreshnessTime = TimeSpan.FromSeconds(configInfo.ParamDesc.DefaultRevocationFreshnessTime), RevocationUrlRetrievalTimeout = TimeSpan.FromMilliseconds(configInfo.ParamDesc.DefaultRevocationUrlRetrievalTimeout), SslCtlIdentifier = configInfo.ParamDesc.pDefaultSslCtlIdentifier, SslCtlStoreName = configInfo.ParamDesc.pDefaultSslCtlStoreName, NegotiateCertificate = HasFlag(configInfo.ParamDesc.DefaultFlags, HttpApi.HTTP_SERVICE_CONFIG_SSL_FLAG.NEGOTIATE_CLIENT_CERT), UseDsMappers = HasFlag(configInfo.ParamDesc.DefaultFlags, HttpApi.HTTP_SERVICE_CONFIG_SSL_FLAG.USE_DS_MAPPER), DoNotPassRequestsToRawFilters = HasFlag(configInfo.ParamDesc.DefaultFlags, HttpApi.HTTP_SERVICE_CONFIG_SSL_FLAG.NO_RAW_FILTER), }; var result = new CertificateBinding(GetThumbrint(hash), storeName, ipPort, appId, options); return(result); }
public bool Bind(CertificateBinding binding) { bool bindingUpdated = false; HttpApi.CallHttpApi( delegate { GCHandle sockAddrHandle = SockaddrInterop.CreateSockaddrStructure(binding.IpPort); IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject(); var httpServiceConfigSslKey = new HttpApi.HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort); byte[] hash = GetHash(binding.Thumbprint); GCHandle handleHash = GCHandle.Alloc(hash, GCHandleType.Pinned); var options = binding.Options; var configSslParam = new HttpApi.HTTP_SERVICE_CONFIG_SSL_PARAM { AppId = binding.AppId, DefaultCertCheckMode = (options.DoNotVerifyCertificateRevocation ? HttpApi.CertCheckModes.DoNotVerifyCertificateRevocation : 0) | (options.VerifyRevocationWithCachedCertificateOnly ? HttpApi.CertCheckModes.VerifyRevocationWithCachedCertificateOnly : 0) | (options.EnableRevocationFreshnessTime ? HttpApi.CertCheckModes.EnableRevocationFreshnessTime : 0) | (options.NoUsageCheck ? HttpApi.CertCheckModes.NoUsageCheck : 0), DefaultFlags = (options.NegotiateCertificate ? HttpApi.HTTP_SERVICE_CONFIG_SSL_FLAG.NEGOTIATE_CLIENT_CERT : 0) | (options.UseDsMappers ? HttpApi.HTTP_SERVICE_CONFIG_SSL_FLAG.USE_DS_MAPPER : 0) | (options.DoNotPassRequestsToRawFilters ? HttpApi.HTTP_SERVICE_CONFIG_SSL_FLAG.NO_RAW_FILTER : 0), DefaultRevocationFreshnessTime = (int)options.RevocationFreshnessTime.TotalSeconds, DefaultRevocationUrlRetrievalTimeout = (int)options.RevocationUrlRetrievalTimeout.TotalMilliseconds, pSslCertStoreName = binding.StoreName, pSslHash = handleHash.AddrOfPinnedObject(), SslHashLength = hash.Length, pDefaultSslCtlIdentifier = options.SslCtlIdentifier, pDefaultSslCtlStoreName = options.SslCtlStoreName }; var configSslSet = new HttpApi.HTTP_SERVICE_CONFIG_SSL_SET { ParamDesc = configSslParam, KeyDesc = httpServiceConfigSslKey }; IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem( Marshal.SizeOf(typeof(HttpApi.HTTP_SERVICE_CONFIG_SSL_SET))); Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false); try { uint retVal = HttpApi.HttpSetServiceConfiguration(IntPtr.Zero, HttpApi.HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); if (HttpApi.ERROR_ALREADY_EXISTS != retVal) { HttpApi.ThrowWin32ExceptionIfError(retVal); } else { retVal = HttpApi.HttpDeleteServiceConfiguration(IntPtr.Zero, HttpApi.HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); HttpApi.ThrowWin32ExceptionIfError(retVal); retVal = HttpApi.HttpSetServiceConfiguration(IntPtr.Zero, HttpApi.HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, Marshal.SizeOf(configSslSet), IntPtr.Zero); HttpApi.ThrowWin32ExceptionIfError(retVal); bindingUpdated = true; } } finally { Marshal.FreeCoTaskMem(pInputConfigInfo); if (handleHash.IsAllocated) { handleHash.Free(); } if (sockAddrHandle.IsAllocated) { sockAddrHandle.Free(); } } }); return(bindingUpdated); }
private static CertificateBinding QueryExact(IPEndPoint ipPort) { CertificateBinding result = null; uint retVal; HttpApi.CallHttpApi( delegate { GCHandle sockAddrHandle = SockaddrInterop.CreateSockaddrStructure(ipPort); IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject(); var sslKey = new HttpApi.HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort); var inputConfigInfoQuery = new HttpApi.HTTP_SERVICE_CONFIG_SSL_QUERY { QueryDesc = HttpApi.HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryExact, KeyDesc = sslKey }; IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem( Marshal.SizeOf(typeof(HttpApi.HTTP_SERVICE_CONFIG_SSL_QUERY))); Marshal.StructureToPtr(inputConfigInfoQuery, pInputConfigInfo, false); IntPtr pOutputConfigInfo = IntPtr.Zero; int returnLength = 0; try { int inputConfigInfoSize = Marshal.SizeOf(inputConfigInfoQuery); retVal = HttpApi.HttpQueryServiceConfiguration(IntPtr.Zero, HttpApi.HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, inputConfigInfoSize, pOutputConfigInfo, returnLength, out returnLength, IntPtr.Zero); if (retVal == HttpApi.ERROR_FILE_NOT_FOUND) { return; } if (HttpApi.ERROR_INSUFFICIENT_BUFFER == retVal) { pOutputConfigInfo = Marshal.AllocCoTaskMem(returnLength); try { retVal = HttpApi.HttpQueryServiceConfiguration(IntPtr.Zero, HttpApi.HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo, pInputConfigInfo, inputConfigInfoSize, pOutputConfigInfo, returnLength, out returnLength, IntPtr.Zero); HttpApi.ThrowWin32ExceptionIfError(retVal); var outputConfigInfo = (HttpApi.HTTP_SERVICE_CONFIG_SSL_SET) Marshal.PtrToStructure(pOutputConfigInfo, typeof(HttpApi.HTTP_SERVICE_CONFIG_SSL_SET)); result = CreateCertificateBindingInfo(outputConfigInfo); } finally { Marshal.FreeCoTaskMem(pOutputConfigInfo); } } else { HttpApi.ThrowWin32ExceptionIfError(retVal); } } finally { Marshal.FreeCoTaskMem(pInputConfigInfo); if (sockAddrHandle.IsAllocated) { sockAddrHandle.Free(); } } }); return(result); }