<?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>unitstep.net &#187; http</title>
	<atom:link href="http://unitstep.net/blog/category/http/feed/" rel="self" type="application/rss+xml" />
	<link>http://unitstep.net</link>
	<description>the home of peter chng</description>
	<lastBuildDate>Mon, 19 Mar 2012 01:49:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Using cURL in PHP to access HTTPS (SSL/TLS) protected sites</title>
		<link>http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/</link>
		<comments>http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/#comments</comments>
		<pubDate>Wed, 06 May 2009 01:22:12 +0000</pubDate>
		<dc:creator>Peter Chng</dc:creator>
				<category><![CDATA[curl]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[pki]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[https]]></category>
		<category><![CDATA[ssl]]></category>
		<category><![CDATA[tls]]></category>

		<guid isPermaLink="false">http://unitstep.net/?p=877</guid>
		<description><![CDATA[From PHP, you can access the useful cURL Library (libcurl) to make requests to URLs using a variety of protocols such as HTTP, FTP, LDAP and even Gopher. (If you&#8217;ve spent time on the *nix command line, most environments also have the curl command available that uses the libcurl library) In practice, however, the most [...]]]></description>
			<content:encoded><![CDATA[<p class="image align-right"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/05/curl-https-padlock.jpg" alt="curl-https-padlock" title="curl-https-padlock" width="100" height="116" class="alignnone size-full wp-image-895" /></p>
<p>From <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym>, you can access the useful <a href="http://ca2.php.net/manual/en/book.curl.php">cURL Library (libcurl)</a> to make requests to URLs using a variety of protocols such as <acronym class="uttInitialism" title="HyperText Transfer Protocol">HTTP</acronym>, FTP, LDAP and even <a href="http://blog.delicious.com/blog/2009/04/delicious-now-supports-gopher.html">Gopher</a>.  (If you&#8217;ve spent time on the *nix command line, most environments also have the <code>curl</code> command available that uses the libcurl library)</p>
<p>In practice, however, the most commonly-used protocol tends to be <acronym class="uttInitialism" title="HyperText Transfer Protocol">HTTP</acronym>, especially when using <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> for server-to-server communication.  Typically this involves accessing another web server as part of a web service call, using some method such as <a href="http://www.w3.org/XML/" class="ubernym uttInitialism"><acronym class="uttInitialism" title="eXtensible Markup Language">XML</acronym></a>-RPC or REST to query a resource.  For example, <a href="http://delicious.com/">Delicious</a> offers <a href="http://delicious.com/help/api">a <acronym class="uttInitialism" title="HyperText Transfer Protocol">HTTP</acronym>-based API</a> to manipulate and read a user&#8217;s posts.  However, when trying to access a HTTPS resource (such as the delicious API), there&#8217;s a little more configuration you have to do before you can get cURL working right in <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym>.</p>
<h2>The problem</h2>
<p>If you simply try to access a HTTPS (SSL or TLS-protected resource) in <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> using cURL, you&#8217;re likely to run into some difficulty.  Say you have the following code: (Error handling omitted for brevity)</p>
<pre><code>// Initialize session and set <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym>.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);

// Set so curl_exec returns the result instead of outputting it.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// Get the response and close the channel.
$response = curl_exec($ch);
curl_close($ch);</code></pre>
<p>If <code>$url</code> points toward an HTTPS resource, you&#8217;re likely to encounter an error like the one below:</p>
<pre><code>Failed: Error Number: 60. Reason: SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed</code></pre>
<p>The problem is that cURL has not been configured to trust the server&#8217;s HTTPS certificate.  The concepts of certificates and PKI revolves around the trust of Certificate Authorities (CAs), and by default, cURL is setup to <strong>not trust any CAs</strong>, thus it won&#8217;t trust any web server&#8217;s certificate.  So why don&#8217;t you have problems visiting HTTPs sites through your web browser? As it happens, the browser developers were nice enough to <a href="/blog/2009/03/16/using-the-basic-constraints-extension-in-x509-v3-certificates-for-intermediate-cas/">include a list of default CAs to trust</a>, covering most situations, so as long as the website operator purchased a certificate from one of these CAs.</p>
<h2>The quick fix</h2>
<p>There are two ways to solve this problem.  Firstly, we can simply configure cURL to accept <strong>any server(peer) certificate</strong>.  This isn&#8217;t optimal from a security point of view, but if you&#8217;re not passing sensitive information back and forth, this is probably alright.  Simply add the following line before calling <code>curl_exec()</code>:</p>
<pre><code>curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);</code></pre>
<p>This basically causes cURL to blindly accept any server certificate, without doing any verification as to which CA signed it, and whether or not that CA is trusted.  If you&#8217;re at all concerned about the data you&#8217;re passing to or receiving from the server, you&#8217;ll want to enable this peer verification properly.  Doing so is a bit more complicated.</p>
<h2>The proper fix</h2>
<p>The proper fix involves setting the <code>CURLOPT_CAINFO</code> parameter.  This is used to point towards a CA certificate that cURL should trust.  Thus, any server/peer certificates issued by this CA will also be trusted.  In order to do this, we first need to get the CA certificate.  In this example, I&#8217;ll be using the <a href="https://api.del.icio.us/">https://api.del.icio.us/</a> server as a reference.</p>
<p>First, you&#8217;ll need to visit the <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym> with your web browser in order to grab the CA certificate.  Then, (in Firefox) open up the security details for the site by double-clicking on the padlock icon in the lower right corner:</p>
<p class="image">
<img src="http://unitstep.net/wordpress/wp-content/uploads/2009/05/curl-https-1.jpg" alt="curl-https-1" title="curl-https-1" width="263" height="84" class="alignnone size-full wp-image-891" />
</p>
<p>Then click on &#8220;View Certificate&#8221;:</p>
<p class="image">
<a href="http://unitstep.net/wordpress/wp-content/uploads/2009/05/curl-https-2.jpg"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/05/curl-https-2-300x250.jpg" alt="curl-https-2" title="curl-https-2" width="300" height="250" class="alignnone size-medium wp-image-890" /></a>
</p>
<p>Bring up the &#8220;Details&#8221; tab of the cerficates page, and <strong>select the certificate at the top of the hierarchy</strong>.  This is the CA certificate.</p>
<p class="image">
<a href="http://unitstep.net/wordpress/wp-content/uploads/2009/05/curl-https-3.jpg"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/05/curl-https-3-255x300.jpg" alt="curl-https-3" title="curl-https-3" width="255" height="300" class="alignnone size-medium wp-image-892" /></a>
</p>
<p>Then click &#8220;Export&#8221;, and save the CA certificate to your selected location, making sure to select the <strong>X.509 Certificate (PEM)</strong> as the save type/format.</p>
<p class="image">
<a href="http://unitstep.net/wordpress/wp-content/uploads/2009/05/curl-https-4.jpg"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/05/curl-https-4-300x223.jpg" alt="curl-https-4" title="curl-https-4" width="300" height="223" class="alignnone size-medium wp-image-893" /></a>
</p>
<p>Now we need to modify the cURL setup to use this CA certificate, with <code>CURLOPT_CAINFO</code> set to point to where we saved the CA certificate file to.</p>
<pre><code>curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/CAcerts/BuiltinObjectToken-EquifaxSecureCA.crt");</code></pre>
<p>The other option I&#8217;ve included, <code>CURLOPT_SSL_VERIFYHOST</code> can be set to the following integer values:</p>
<ul>
<li>0: Don&#8217;t check the common name (CN) attribute</li>
<li>1: Check that the common name attribute at least exists</li>
<li>2: Check that the common name exists and that it matches the host name of the server</li>
</ul>
<p>If you have <code>CURLOPT_SSL_VERIFYPEER</code> set to false, then from a security perspective, it doesn&#8217;t really matter what you&#8217;ve set <code>CURLOPT_SSL_VERIFYHOST</code> to, since without peer certificate verification, the server could use any certificate, including a self-signed one that was guaranteed to have a CN that matched the server&#8217;s host name.  So this setting is really only relevant if you&#8217;ve enabled certificate verification.</p>
<p>This ensures that not just any server certificate will be trusted by your cURL session.  For example, if an attacker were to somehow redirect traffic from <strong>api.delicious.com</strong> to their own server, the cURL session here would not properly initialize, since the attacker would not have access to a server certificate (i.e. would not have the private key) trusted by the CA we added.  These steps effectively export the trusted CA from the web browser to the cURL configuration.</p>
<h2>More information</h2>
<p>If you have the CA certificate, but it is not in the PEM format (i.e. it is in a binary or DER format that isn&#8217;t Base64-encoded), you&#8217;ll need to use something like OpenSSL to convert it to the PEM format.  The exact command differs depending on whether you&#8217;re converting from PKCS12 or DER format.</p>
<p>There is a <code>CURLOPT_CAPATH</code> option that allows you to specify a directory that holds multiple CA certificates to trust.  But it&#8217;s not as simple as dumping every single CA certificate in this directory.  Instead, they CA certificates must be named properly, and the <a href="http://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html">OpenSSL <code>c_rehash</code> utility can be used</a> to properly setup this directory for use by cURL.</p>
<hr/>Copyright &copy; 2012 <strong><a href="http://unitstep.net">unitstep.net</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact <strong><a href="mailto:webmaster@unitstep.net">webmaster@unitstep.net</a></strong> for more information.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/feed/</wfw:commentRss>
		<slash:comments>113</slash:comments>
		</item>
		<item>
		<title>Taking the www out of the web</title>
		<link>http://unitstep.net/blog/2006/12/27/taking-the-www-out-of-the-web/</link>
		<comments>http://unitstep.net/blog/2006/12/27/taking-the-www-out-of-the-web/#comments</comments>
		<pubDate>Wed, 27 Dec 2006 18:47:32 +0000</pubDate>
		<dc:creator>Peter Chng</dc:creator>
				<category><![CDATA[fix]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[http]]></category>

		<guid isPermaLink="false">http://unitstep.net/blog/2006/12/27/taking-the-www-out-of-the-web/</guid>
		<description><![CDATA[Despite the phrase &#8220;World-Wide Web&#8221; being as dated and passÃ© as claims of Al Gore &#8220;inventing the Internet&#8221;, the term persists today as the most popular and unnecessary subdomain for websites. Should it really be necessary to type &#8220;www&#8221; before every domain name? Furthermore, does it even have any more relevance? Since the major use [...]]]></description>
			<content:encoded><![CDATA[<p>Despite the phrase &#8220;World-Wide Web&#8221; being as dated and <i>passÃ©</i> as claims of Al Gore <a href="http://en.wikipedia.org/wiki/Al_gore#1999_CNN_interview">&#8220;inventing the Internet&#8221;</a>, the term persists today as the most popular and unnecessary subdomain for websites.  Should it really be necessary to type &#8220;www&#8221; before every domain name?  Furthermore, does it even have any more relevance?</p>
<p>Since the major use of Internet is for accessing websites, the &#8220;www&#8221; prefix shouldn&#8217;t be needed anymore.  It is an archaic holdover from a previous era, one where browser wars meant IE vs. Netscape and where Geocities was <em>the</em> place to be.  Thankfully, the folks over at <a href="http://no-www.org/">no-www</a> have been aiming to improve this for some time.</p>
<h3>So what&#8217;s the big deal?</h3>
<p>Well, it&#8217;s not such a big deal, more just a pet peeve of mine.  Most sites out there are thankfully configured well enough so that navigating to &#8220;domain.com&#8221; just redirects you to &#8220;www.domain.com&#8221; with no damage done.  However, some servers are setup so that navigating to &#8220;domain.com&#8221; <em>doesn&#8217;t</em> work, and this forces you to type in the &#8220;www&#8221; subdomain before.  This really doesn&#8217;t make sense in today&#8217;s world.</p>
<p>In my opinion, all websites should be set up with the no-www version as the default.  Using the &#8220;www&#8221; subdomain should redirect you to the no-www version, with no harm done.  This is known as <a href="http://no-www.org/faq.php">Class-B compliance</a>, according to the no-www folks, and it&#8217;s probably going to be the best way to go for some time, since many people still use the &#8220;www&#8221;, after having the phrase drilled into their heads during the late 90&#8242;s. </p>
<h3>So, how to fix it?</h3>
<p>If you&#8217;ve signed up for hosting from a provider, chances are they&#8217;ve already implemented some sort of compliance, but not the optimal type.  For example, most hosting providers will automatically redirect the no-www request to the www one.  So, under this configuration, someone entering &#8220;domain.com&#8221; would be redirected to &#8220;www.domain.com&#8221;.  No big deal, but things could be better.  After all, the no-www version is shorter and thus requires less typing and less space.  Good if you want to save a few cents on your business cards.</p>
<p>Fixing it is a simple effort that takes a minute or so.  All you have to do is edit the <code>.htaccess</code> file in the root of your website, if you&#8217;re using Apache.  Here&#8217;s the following directive I&#8217;m using.</p>
<pre>
<code># BEGIN no-www
&lt;IfModule mod_rewrite.c&gt;
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.unitstep\.net$ [NC]
RewriteRule ^(.*)$ http://unitstep.net/$1 [R=301,L]
&lt;/IfModule&gt;
# END no-www</code>
</pre>
<p>The <code>RewriteRule</code> uses a 301 &#8211; this is a special <acronym class="uttInitialism" title="HyperText Transfer Protocol">HTTP</acronym> code used to tell of a permanent redirection.  Browsers and search engines crawling your site will interpret this as an instruction that your website has permanently moved to the non-www address.  This is most important for search engines, so that they know that the no-www version is not <a href="http://googlewebmastercentral.blogspot.com/2006/12/deftly-dealing-with-duplicate-content.html">just a duplicate</a> or different website than the previous www version.  The 301 instruction tells them that the old www version doesn&#8217;t exist anymore, and it has been moved to the no-www address. </p>
<p>Taking it a step further, you could also redirect <em>any</em> subdomain to just the root.  For example, I also own the domain &#8220;peterchng.com&#8221;, and wanted to redirect any request to that address, subdomains included, to my main site.  Here&#8217;s the directives I used.</p>
<pre>
<code># BEGIN peterchng.com FORWARD
&lt;IfModule mod_rewrite.c&gt;
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(([a-zA-Z0-9]+)\.)*peterchng\.com$ [NC]
RewriteRule ^(.*)$ http://unitstep.net/$1 [R=301,L]
&lt;/IfModule&gt;
# END peterchng.com FORWARD</code>
</pre>
<p>Go ahead, try typing in <a href="http://who.the.heck.is.peterchng.com">&#8220;who.the.heck.is.peterchng.com&#8221;</a> into your browser, and you&#8217;ll see it redirects right back to this site.</p>
<p>You&#8217;ll want to be careful when using these directives &#8211; if you actually do have separate websites on different subdomains, they&#8217;ll be inaccessible if you do this!  I&#8217;ve been using it until I find a use for peterchng.com &#8211; or a different use for unitstep.net.  </p>
<h3>Why all the trouble then?</h3>
<p>With all the trouble of going of removing the &#8220;www&#8221; you may wonder why it was ever used in the first place.  Well, IIRC, in the early years of the Internet, websites or <acronym class="uttInitialism" title="HyperText Transfer Protocol">HTTP</acronym> wasn&#8217;t the main use.  Other services/protocols such as gopher, FTP and telnet were probably a lot more dominant.  So, it made sense to set up a separate subdomain that would be used to accept <acronym class="uttInitialism" title="HyperText Transfer Protocol">HTTP</acronym> connections.  This would make it easier for users to distinguish between the services offered from a particular domain.  However, since <acronym class="uttInitialism" title="HyperText Transfer Protocol">HTTP</acronym> has grown to eclipse those traditional services, the use of www is almost superfluous nowadays.</p>
<hr/>Copyright &copy; 2012 <strong><a href="http://unitstep.net">unitstep.net</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact <strong><a href="mailto:webmaster@unitstep.net">webmaster@unitstep.net</a></strong> for more information.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://unitstep.net/blog/2006/12/27/taking-the-www-out-of-the-web/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

