<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jumping Through Hoops &#187; C#</title>
	<atom:link href="http://blog.jameshiggs.com/tags/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.jameshiggs.com</link>
	<description>James Higgs&#039;s Blog</description>
	<lastBuildDate>Sun, 04 Sep 2011 12:46:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>C#: How to accept an invalid SSL certificate programmatically</title>
		<link>http://blog.jameshiggs.com/2008/05/01/c-how-to-accept-an-invalid-ssl-certificate-programmatically/</link>
		<comments>http://blog.jameshiggs.com/2008/05/01/c-how-to-accept-an-invalid-ssl-certificate-programmatically/#comments</comments>
		<pubDate>Thu, 01 May 2008 17:30:12 +0000</pubDate>
		<dc:creator>higgis</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://blog.jameshiggs.com/?p=104</guid>
		<description><![CDATA[In the project I&#8217;m working on at the moment, we have a requirement to call some REST services using .NET#&#8217;s built-in System.Net.HttpWebRequest class. The calls will eventually be over SSL using a properly issued certificate when we go live, but for testing we&#8217;ve been using a self-signed certificate. When you navigate to an HTTP URL [...]]]></description>
			<content:encoded><![CDATA[<p>In the project I&#8217;m working on at the moment, we have a requirement to call some REST services using .NET#&#8217;s built-in <code>System.Net.HttpWebRequest</code> class. The calls will eventually be over SSL using a properly issued certificate when we go live, but for testing we&#8217;ve been using a self-signed certificate.</p>
<p>When you navigate to an HTTP URL with a dodgy certificate in a browser, you get a warning that gives you the option to ignore the problems. In code, this just results in an exception being thrown. The exception is a <code>System.Security.Authentication.AuthenticationException</code> (wrapped in a <code>System.Net.WebException</code>), with an error message of &#8220;The remote certificate is invalid according to the validation procedure.&#8221;</p>
<p>So, for testing, we needed to find a way to bypass the certificate validation. It turns out that you need to provide a <code>RemoteCertificateValidationCallback</code> delegate and attach it to <code>ServicePointManager.ServerCertificateValidationCallback</code>. What&#8217;s not clear is what happens if two threads are competing to set this property to different values, since it&#8217;s a static property. Reflector suggests that the property set method doesn&#8217;t do anything fancy, so you could easily get into a race condition.</p>
<p>Anyway, here&#8217;s s snippet that shows how to do this. Hopefully someone will find it useful, because it took me a while to find.</p>
<pre><code> // callback used to validate the certificate in an SSL conversation
private static bool ValidateRemoteCertificate(
object sender,
	X509Certificate certificate,
	X509Chain chain,
	SslPolicyErrors policyErrors
)
{
	if (Convert.ToBoolean(ConfigurationManager.AppSettings["IgnoreSslErrors"]))
	{
		// allow any old dodgy certificate...
		return true;
	}
	else
	{
		return policyErrors == SslPolicyErrors.None;
	}
}

private static string MakeRequest(string uri, string method, WebProxy proxy)
{
	HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
	webRequest.AllowAutoRedirect = true;
	webRequest.Method = method;

	// allows for validation of SSL conversations
	ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(
		ValidateRemoteCertificate
	);

	if (proxy != null)
	{
		webRequest.Proxy = proxy;
	}

	HttpWebResponse response = null;
	try
	{
		response = (HttpWebResponse)webRequest.GetResponse();

		using (Stream s = response.GetResponseStream())
		{
			using (StreamReader sr = new StreamReader(s))
			{
				return sr.ReadToEnd();
			}
		}
	}
	finally
	{
		if (response != null)
			response.Close();
	}
}</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.jameshiggs.com/2008/05/01/c-how-to-accept-an-invalid-ssl-certificate-programmatically/feed/</wfw:commentRss>
		<slash:comments>50</slash:comments>
		</item>
	</channel>
</rss>

