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();
}
});
}