<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>Steve's Techspot - AllContent</title>
    <link>http://www.stevestechspot.com/</link>
    <description>The weblog of Steve Johnson</description>
    <language>en-us</language>
    <copyright>Steve Johnson</copyright>
    <lastBuildDate>Wed, 13 Jun 2007 06:00:00 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.9.6264.0</generator>
    <managingEditor>sjjohnson@pobox.com</managingEditor>
    <webMaster>sjjohnson@pobox.com</webMaster>
    <item>
      <trackback:ping>http://www.stevestechspot.com/Trackback.aspx?guid=102168a1-4d15-4a8f-bcc0-eee289e48c80</trackback:ping>
      <pingback:server>http://www.stevestechspot.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.stevestechspot.com/PermaLink,guid,102168a1-4d15-4a8f-bcc0-eee289e48c80.aspx</pingback:target>
      <dc:creator>Steve Johnson</dc:creator>
      <wfw:comment>http://www.stevestechspot.com/CommentView,guid,102168a1-4d15-4a8f-bcc0-eee289e48c80.aspx</wfw:comment>
      <wfw:commentRss>http://www.stevestechspot.com/SyndicationService.asmx/GetEntryCommentsRss?guid=102168a1-4d15-4a8f-bcc0-eee289e48c80</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
HttpConfig has been updated to work correctly with UAC on Vista.
</p>
        <p />
        <p>
Roger Lipscombe also pointed out some NullReferenceExceptions, which are also now
fixed. Thanks, Roger!
</p>
        <p />
        <p>
Download: <a href="/downloads/httpconfig.zip">exe</a><a href="/downloads/httpconfig_source.zip">source</a></p>
        <img width="0" height="0" src="http://www.stevestechspot.com/aggbug.ashx?id=102168a1-4d15-4a8f-bcc0-eee289e48c80" />
      </body>
      <title>HttpConfig Now Works Properly With UAC</title>
      <guid isPermaLink="false">http://www.stevestechspot.com/PermaLink,guid,102168a1-4d15-4a8f-bcc0-eee289e48c80.aspx</guid>
      <link>http://www.stevestechspot.com/HttpConfigNowWorksProperlyWithUAC.aspx</link>
      <pubDate>Wed, 13 Jun 2007 06:00:00 GMT</pubDate>
      <description>
		&lt;p&gt;
HttpConfig has been updated to work correctly with UAC on Vista.
&lt;/p&gt;
&lt;p /&gt;
&lt;p&gt;
Roger Lipscombe also pointed out some NullReferenceExceptions, which are also now
fixed. Thanks, Roger!
&lt;/p&gt;
&lt;p /&gt;
&lt;p&gt;
Download: &lt;a href="/downloads/httpconfig.zip"&gt;exe&lt;/a&gt; &lt;a href="/downloads/httpconfig_source.zip"&gt;source&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.stevestechspot.com/aggbug.ashx?id=102168a1-4d15-4a8f-bcc0-eee289e48c80" /&gt;</description>
      <comments>http://www.stevestechspot.com/CommentView,guid,102168a1-4d15-4a8f-bcc0-eee289e48c80.aspx</comments>
      <category>AllContent</category>
    </item>
    <item>
      <trackback:ping>http://www.stevestechspot.com/Trackback.aspx?guid=d84ac549-a40f-475c-b46f-dfda25fe82d9</trackback:ping>
      <pingback:server>http://www.stevestechspot.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.stevestechspot.com/PermaLink,guid,d84ac549-a40f-475c-b46f-dfda25fe82d9.aspx</pingback:target>
      <dc:creator>Steve Johnson</dc:creator>
      <wfw:comment>http://www.stevestechspot.com/CommentView,guid,d84ac549-a40f-475c-b46f-dfda25fe82d9.aspx</wfw:comment>
      <wfw:commentRss>http://www.stevestechspot.com/SyndicationService.asmx/GetEntryCommentsRss?guid=d84ac549-a40f-475c-b46f-dfda25fe82d9</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've updated HttpConfig to fix a couple of 64-bit bugs.
</p>
        <p />
        <p>
Download: <a href="/downloads/httpconfig.zip">exe</a><a href="/downloads/httpconfig_source.zip">source</a></p>
        <img width="0" height="0" src="http://www.stevestechspot.com/aggbug.ashx?id=d84ac549-a40f-475c-b46f-dfda25fe82d9" />
      </body>
      <title>HttpConfig Bug Fixes for 64-bit</title>
      <guid isPermaLink="false">http://www.stevestechspot.com/PermaLink,guid,d84ac549-a40f-475c-b46f-dfda25fe82d9.aspx</guid>
      <link>http://www.stevestechspot.com/HttpConfigBugFixesFor64bit.aspx</link>
      <pubDate>Wed, 30 May 2007 06:00:00 GMT</pubDate>
      <description>
		&lt;p&gt;
I've updated HttpConfig to fix a couple of 64-bit bugs.
&lt;/p&gt;
&lt;p /&gt;
&lt;p&gt;
Download: &lt;a href="/downloads/httpconfig.zip"&gt;exe&lt;/a&gt; &lt;a href="/downloads/httpconfig_source.zip"&gt;source&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.stevestechspot.com/aggbug.ashx?id=d84ac549-a40f-475c-b46f-dfda25fe82d9" /&gt;</description>
      <comments>http://www.stevestechspot.com/CommentView,guid,d84ac549-a40f-475c-b46f-dfda25fe82d9.aspx</comments>
      <category>AllContent</category>
    </item>
    <item>
      <trackback:ping>http://www.stevestechspot.com/Trackback.aspx?guid=50d9c991-19d7-4dd8-9ede-7c179fbef7cd</trackback:ping>
      <pingback:server>http://www.stevestechspot.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.stevestechspot.com/PermaLink,guid,50d9c991-19d7-4dd8-9ede-7c179fbef7cd.aspx</pingback:target>
      <dc:creator>Steve Johnson</dc:creator>
      <wfw:comment>http://www.stevestechspot.com/CommentView,guid,50d9c991-19d7-4dd8-9ede-7c179fbef7cd.aspx</wfw:comment>
      <wfw:commentRss>http://www.stevestechspot.com/SyndicationService.asmx/GetEntryCommentsRss?guid=50d9c991-19d7-4dd8-9ede-7c179fbef7cd</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
At long last, I've been able to update the HttpConfig GUI tool. I've fixed many bugs,
streamlined the UI, added graphical security editing and gotten the thing to run on
Vista.
</p>
        <p>
Thanks to <a href="http://www.pluralsight.com/blogs/keith/">Keith</a> and <a href="http://www.leastprivilege.com">Dominick</a> for
the inspiration to enhance the security stuff. Now that I'm using .NET 2.0 for this
app, I was able to get the EditSecurity API working purely in C#.
</p>
Enjoy! 
<p>
Download: <a href="/downloads/httpconfig.zip">exe</a> <a href="/downloads/httpconfig_source.zip">source</a></p><img width="0" height="0" src="http://www.stevestechspot.com/aggbug.ashx?id=50d9c991-19d7-4dd8-9ede-7c179fbef7cd" /></body>
      <title>HttpConfig Update</title>
      <guid isPermaLink="false">http://www.stevestechspot.com/PermaLink,guid,50d9c991-19d7-4dd8-9ede-7c179fbef7cd.aspx</guid>
      <link>http://www.stevestechspot.com/HttpConfigUpdate.aspx</link>
      <pubDate>Tue, 05 Dec 2006 06:00:00 GMT</pubDate>
      <description>
		&lt;p&gt;
At long last, I've been able to update the HttpConfig GUI tool. I've fixed many bugs,
streamlined the UI, added graphical security editing and gotten the thing to run on
Vista.
&lt;/p&gt;
&lt;p&gt;
Thanks to &lt;a href="http://www.pluralsight.com/blogs/keith/"&gt;Keith&lt;/a&gt; and &lt;a href="http://www.leastprivilege.com"&gt;Dominick&lt;/a&gt; for
the inspiration to enhance the security stuff. Now that I'm using .NET 2.0 for this
app, I was able to get the EditSecurity API working purely in C#.
&lt;/p&gt;
Enjoy! 
&lt;p&gt;
Download:&amp;nbsp;&lt;a href="/downloads/httpconfig.zip"&gt;exe&lt;/a&gt;&amp;nbsp;&lt;a href="/downloads/httpconfig_source.zip"&gt;source&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.stevestechspot.com/aggbug.ashx?id=50d9c991-19d7-4dd8-9ede-7c179fbef7cd" /&gt;</description>
      <comments>http://www.stevestechspot.com/CommentView,guid,50d9c991-19d7-4dd8-9ede-7c179fbef7cd.aspx</comments>
      <category>AllContent</category>
    </item>
    <item>
      <trackback:ping>http://www.stevestechspot.com/Trackback.aspx?guid=9e9c347f-da37-4997-969b-015bc560a4a7</trackback:ping>
      <pingback:server>http://www.stevestechspot.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.stevestechspot.com/PermaLink,guid,9e9c347f-da37-4997-969b-015bc560a4a7.aspx</pingback:target>
      <dc:creator>Steve Johnson</dc:creator>
      <wfw:comment>http://www.stevestechspot.com/CommentView,guid,9e9c347f-da37-4997-969b-015bc560a4a7.aspx</wfw:comment>
      <wfw:commentRss>http://www.stevestechspot.com/SyndicationService.asmx/GetEntryCommentsRss?guid=9e9c347f-da37-4997-969b-015bc560a4a7</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
As indicated in my last post, I'm posting a wrap-up to the <a href="http://www.stevestechspot.com/default.aspx?articleId=3f39efbd09e24beb9d5ae37ad2fb3862">SSL
cert saga</a>. Unfortunately, I've waited too long between posts and forgotten some
of what I had intended to write here. However, since I included more details in the
last post than I had intended, you're not missing much.
</p>
        <p>
One of the more interesting tasks involved in researching SSL cert problems was how
to locate the key containers. The manner in which key containers are persisted is
not documented anywhere that I know of, and I'm sure that's intentional as key container
persistence is an internal implementation detail. I knew from some work several years
ago that the MS RSA providers persist the key containers in the file system. I also
remembered the approximate location, but I couldn't remember all the details. I fired
up filemon and my memory was refreshed. The keys are stored in the common or user
profile, depending on whether the container is a machine or user keyset. However,
the containers are named in some bizarre guidish/hashy-looking format, so it's not
obvious at a glance which files belong to which key containers. I was able to locate
older key containers by opening them in TextPad because the name of the container
is embedded in ASCII text within the file itself. New containers were easy to locate
simply by sorting the files. However, I wanted to know how the filenames are derived.
I have a sick mind that way. I always want to know how things work behind the scenes.
After a few hours with FileMon, RegMon and the disassembler, I finally think I understand
how these filenames are derived. I'm going to document this process here for the curious
and so I can find this information the next time I need it. This information is applicable
to Win2K, WinXP and Win2K3. I don't yet have a Vista box to test this on, so I don't
know if it remains the same in that version of the OS.
</p>
        <p>
First of all, the key containers are persisted in the following locations:<br />
User keys: %PROFILE%\Application Data\Microsoft\Crypto\RSA\[SID string]<br />
Machine keys: %ALLUSERS%\Application Data\Microsoft\Crypto\RSA\MachineKeys
</p>
        <p>
The filenames look like so: d99e964c16600b1681cdfbad2d5d5eac_2f896382-3658-492e-9219-ce847feb6b8a
</p>
        <p>
The filename consists of a MD5-derived prefix and the MachineGuid, separated by an
underscore. The MachineGuid is a registry string value, located under the key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography".
The hash prefix is derived by performing the following operations:
</p>
        <p>
1 - Obtain the name of the key container. The private key container name for a cert
can be obtained via the CertGetCertificateContextProperty API, specifying the CERT_KEY_PROV_INFO_PROP_ID
property. You can also obtain the key container name by using the <a href="/downloads/checkcert.zip">checkcert
utility</a> from my last post.<br />
2 - Convert the key container name to lower case.<br />
3 - Append a null character<br />
4 - Convert the string to ASCII bytes<br />
5 - Perform an MD5 hash of the ASCII bytes<br />
6 - Treat each 4 byte block of the hash as a 32-bit integer, reversing each<br />
7 - Convert the resulting bytes to a hex string<br /></p>
        <p>
I'm including a sample class that demonstrates the code necessary to calculate the
full path and filename of an RSA key container. The class exposes a static method
called "GetRsaKeyContainerFilename" as well as methods that will allow you
to perform each step of this operation separately.
</p>
        <p>
There may be an API to do this, but I haven't been able to find it. I wasn't as concerned
with an easy way to do this as much as understanding the process, anyway.
</p>
        <p>
Download: <a href="/downloads/RsaUtil.zip">RsaUtil.zip</a></p>
        <img width="0" height="0" src="http://www.stevestechspot.com/aggbug.ashx?id=9e9c347f-da37-4997-969b-015bc560a4a7" />
      </body>
      <title>SSL Certificates - Wrap-up</title>
      <guid isPermaLink="false">http://www.stevestechspot.com/PermaLink,guid,9e9c347f-da37-4997-969b-015bc560a4a7.aspx</guid>
      <link>http://www.stevestechspot.com/SSLCertificatesWrapup.aspx</link>
      <pubDate>Sun, 20 Nov 2005 06:00:00 GMT</pubDate>
      <description>
		&lt;p&gt;
As indicated in my last post, I'm posting a wrap-up to the &lt;a href="http://www.stevestechspot.com/default.aspx?articleId=3f39efbd09e24beb9d5ae37ad2fb3862"&gt;SSL
cert saga&lt;/a&gt;. Unfortunately, I've waited too long between posts and forgotten some
of what I had intended to write here. However, since I included more details in the
last post than I had intended, you're not missing much.
&lt;/p&gt;
&lt;p&gt;
One of the more interesting tasks involved in researching SSL cert problems was how
to locate the key containers. The manner in which key containers are persisted is
not documented anywhere that I know of, and I'm sure that's intentional as key container
persistence is an internal implementation detail. I knew from some work several years
ago that the MS RSA providers persist the key containers in the file system. I also
remembered the approximate location, but I couldn't remember all the details. I fired
up filemon and my memory was refreshed. The keys are stored in the common or user
profile, depending on whether the container is a machine or user keyset. However,
the containers are named in some bizarre guidish/hashy-looking format, so it's not
obvious at a glance which files belong to which key containers. I was able to locate
older key containers by opening them in TextPad because the name of the container
is embedded in ASCII text within the file itself. New containers were easy to locate
simply by sorting the files. However, I wanted to know how the filenames are derived.
I have a sick mind that way. I always want to know how things work behind the scenes.
After a few hours with FileMon, RegMon and the disassembler, I finally think I understand
how these filenames are derived. I'm going to document this process here for the curious
and so I can find this information the next time I need it. This information is applicable
to Win2K, WinXP and Win2K3. I don't yet have a Vista box to test this on, so I don't
know if it remains the same in that version of the OS.
&lt;/p&gt;
&lt;p&gt;
First of all, the key containers are persisted in the following locations:&lt;br /&gt;
User keys: %PROFILE%\Application Data\Microsoft\Crypto\RSA\[SID string]&lt;br /&gt;
Machine keys: %ALLUSERS%\Application Data\Microsoft\Crypto\RSA\MachineKeys
&lt;/p&gt;
&lt;p&gt;
The filenames look like so: d99e964c16600b1681cdfbad2d5d5eac_2f896382-3658-492e-9219-ce847feb6b8a
&lt;/p&gt;
&lt;p&gt;
The filename consists of a MD5-derived prefix and the MachineGuid, separated by an
underscore. The MachineGuid is a registry string value, located under the key &amp;quot;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography&amp;quot;.
The hash prefix is derived by performing the following operations:
&lt;/p&gt;
&lt;p&gt;
1 - Obtain the name of the key container. The private key container name for a cert
can be obtained via the CertGetCertificateContextProperty API, specifying the CERT_KEY_PROV_INFO_PROP_ID
property. You can also obtain the key container name by using the &lt;a href="/downloads/checkcert.zip"&gt;checkcert
utility&lt;/a&gt; from my last post.&lt;br /&gt;
2 - Convert the key container name to lower case.&lt;br /&gt;
3 - Append a null character&lt;br /&gt;
4 - Convert the string to ASCII bytes&lt;br /&gt;
5 - Perform an MD5 hash of the ASCII bytes&lt;br /&gt;
6 - Treat each 4 byte block of the hash as a 32-bit integer, reversing each&lt;br /&gt;
7 - Convert the resulting bytes to a hex string&lt;br /&gt;
&lt;p&gt;
I'm including a sample class that demonstrates the code necessary to calculate the
full path and filename of an RSA key container. The class exposes a static method
called &amp;quot;GetRsaKeyContainerFilename&amp;quot; as well as methods that will allow you
to perform each step of this operation separately.
&lt;/p&gt;
&lt;p&gt;
There may be an API to do this, but I haven't been able to find it. I wasn't as concerned
with an easy way to do this as much as understanding the process, anyway.
&lt;/p&gt;
&lt;p&gt;
Download: &lt;a href="/downloads/RsaUtil.zip"&gt;RsaUtil.zip&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.stevestechspot.com/aggbug.ashx?id=9e9c347f-da37-4997-969b-015bc560a4a7" /&gt;</description>
      <comments>http://www.stevestechspot.com/CommentView,guid,9e9c347f-da37-4997-969b-015bc560a4a7.aspx</comments>
      <category>AllContent</category>
    </item>
    <item>
      <trackback:ping>http://www.stevestechspot.com/Trackback.aspx?guid=3f39efbd-09e2-4beb-9d5a-e37ad2fb3862</trackback:ping>
      <pingback:server>http://www.stevestechspot.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.stevestechspot.com/PermaLink,guid,3f39efbd-09e2-4beb-9d5a-e37ad2fb3862.aspx</pingback:target>
      <dc:creator>Steve Johnson</dc:creator>
      <wfw:comment>http://www.stevestechspot.com/CommentView,guid,3f39efbd-09e2-4beb-9d5a-e37ad2fb3862.aspx</wfw:comment>
      <wfw:commentRss>http://www.stevestechspot.com/SyndicationService.asmx/GetEntryCommentsRss?guid=3f39efbd-09e2-4beb-9d5a-e37ad2fb3862</wfw:commentRss>
      <slash:comments>7</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One of the joys Ive experienced in my recent dealings with the HTTP API and some lower-level
SChannel code is that of trying to generate proper SSL test certificates. During the
initial development phase of the product Im currently working on, we used one common
test certificate for all our test/dev servers. Later on, we began to generate different
certificates for each server so that we could test some cert verification code and
also verify that we knew exactly what was required of certificates to work with our
product. Needless to say (or I wouldnt have anything to write here), we immediately
began to have many problems. Some servers worked just fine, while others failed. On
the failing servers, test requests with WebRequest yielded the familiar but unhelpful
error "Could not establish secure channel for SSL/TLS". Attempts to connect from IE
produced the error "Cannot find server or DNS Error". In order to further troubleshoot,
I tried making a connection using a plain SChannel-based SSL socket. The connection
was established just fine and the client socket sent the hello message. As soon as
the client socket attempted to read the server response, an exception was thrown,
indicating that the connection had been closed by the server. Next, I enabled full
SChannel logging on the server and restarted. Attempts to connect left 2 messages
in the event logs: "Creating an SSL server credential", followed by "The SSL server
credentials private key has the following properties..." and NO error. Baffled, I
installed Microsofts <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=cabea1d0-5a10-41bc-83d4-06c814265282&amp;displaylang=en">SSL
Diagnostics</a> utility and attempted a handshake simulation. This yielded the error
"Unexpected error receiving data (0x80090304)", which error code is defined as SEC_E_INTERNAL_ERROR;
again, a most unhelpful description. This led me on a week-long study of X.509 certificates,
makecert.exe and the MS Crypto Providers key container implementation. Im going to
omit many details here in order to get to the point, which is to enumerate the problems
and solutions Ive found for our situation. Ill follow up with another post to describe
the gory details of this research in some depth. Anyway, simply stated, the problem
is that the certificate's private key is either inaccessible or the keyspec is incorrect.
</p>
        <p>
          <strong>Problems</strong>
        </p>
        <p>
Our problems basically boiled down to three root causes:
</p>
        <p>
1 - Improper import of good certificates, which caused them to appear faulty.
</p>
        <p>
2 - Use of a build of makecert.exe that generates key containers improperly
</p>
        <p>
3 - Failure to realize that makecert.exe does not, by default, generate certs that
use the correct keyspec for an SSL cert.
</p>
        <p>
Problem #1 - The problem with importing was that I sometimes imported the certificate
into the CurrentUser MY store and then, realizing that I'd imported into the wrong
store, copied the cert into the LocalMachine MY store. The problem is that once a
certificate is imported into a CurrentUser store, the private key container resides
in the users profile, where it cannot be found by a system process.
</p>
        <p>
Problem #2 - One of the first things I do when I create a development VM is to add
the path to the .NET SDK bin directory to my system path. I always want access to
the tools therein from any command prompt. Unfortunately, the makecert.exe in that
directory (v5.131.2157.1) wont work for generating SSL certs. The problem is that
even if you specify a LocalMachine store for the cert, the private key container it
generates is generated as a user key, not a machine key. Therefore, though everything
looks good, when you use the cert from a system process, you experience the symptoms
enumerated above. In order to use this build for SSL certs, youd have to pre-generate
the key container and reference the pre-created container on the makecert command
line.
</p>
        <p>
Problem #3 - There are two standard key types for RSA keys: signature and exchange.
Which key is used is defined by the keyspec property of the private key context belonging
to the certificate. The keyspec property must be set to "Exchange" in order for the
cert to work for SSL. This is obvious to me, but I never realized that makecert.exe
sets the keyspec to Signature by default, and there isnt a standard interface to view
this property of a certificate that Im aware of.
</p>
        <p>
          <strong>Solutions</strong>
        </p>
        <p>
Solution #1 - Import certificates intended for SSL usage into a LocalMachine store
directly. Dont try to copy a cert from a CurrentUser store into a LocalMachine store.
If youve mistakenly imported a cert into a CurrentUser store, you need to delete the
cert <em>and</em> the key container (deleting a certificate does not delete the key
container), and then import the cert into a LocalMachine store. See my next post for
details as to how to locate the key container and delete it.
</p>
        <p>
Solution #2 - Dont use v5.131.2157.1 of makecert.exe (the one in the .NET v1.1 SDK)
to generate SSL certificates. It always generates user key containers, which wont
work from a system process. Fortunately, the version of makecert.exe (v5.131.3790.0)
that ships with v2.0 of the .NET SDK, as well as the latest Platform SDKs, works properly.
</p>
        <p>
Solution #3 - Always use the command line option "-sky exchange" with makecert.exe
if youre generating SSL certificates. If you dont specify this, it will default to
the signature keyspec, which wont work for SSL.
</p>
        <p>
The difficulties Ive experienced have been compounded by the fact that any one or
more of these problems could be combined in a single situation, making it terribly
difficult to pinpoint precisely what is going on. To aid in the diagnosis of SSL certificate
problems, Im making available a little command line utility that I wrote for this
purpose.
</p>
        <p>
checkcert: <a href="/downloads/checkcert.zip">exe</a> <a href="/downloads/checkcert_source.zip">source</a></p>
        <p>
To use checkcert.exe, pass a store name and a cert subject search string (such as
the common name). Checkcert will display some key information about the cert that
is not available in the built-in tools (again, that Im aware of). Most importantly,
checkcert will display the private key container location and the keyspec. You want
to ensure that the key container location is "Machine" and that the keyspec is "Exchange"
for an SSL cert. I hope this information and the utility will save someone the hassle
of trying to unravel this mess from scratch.
</p>
        <img width="0" height="0" src="http://www.stevestechspot.com/aggbug.ashx?id=3f39efbd-09e2-4beb-9d5a-e37ad2fb3862" />
      </body>
      <title>SSL Certificates - Around in Circles</title>
      <guid isPermaLink="false">http://www.stevestechspot.com/PermaLink,guid,3f39efbd-09e2-4beb-9d5a-e37ad2fb3862.aspx</guid>
      <link>http://www.stevestechspot.com/SSLCertificatesAroundInCircles.aspx</link>
      <pubDate>Mon, 07 Nov 2005 06:00:00 GMT</pubDate>
      <description>
		&lt;p&gt;
One of the joys Ive experienced in my recent dealings with the HTTP API and some lower-level
SChannel code is that of trying to generate proper SSL test certificates. During the
initial development phase of the product Im currently working on, we used one common
test certificate for all our test/dev servers. Later on, we began to generate different
certificates for each server so that we could test some cert verification code and
also verify that we knew exactly what was required of certificates to work with our
product. Needless to say (or I wouldnt have anything to write here), we immediately
began to have many problems. Some servers worked just fine, while others failed. On
the failing servers, test requests with WebRequest yielded the familiar but unhelpful
error "Could not establish secure channel for SSL/TLS". Attempts to connect from IE
produced the error "Cannot find server or DNS Error". In order to further troubleshoot,
I tried making a connection using a plain SChannel-based SSL socket. The connection
was established just fine and the client socket sent the hello message. As soon as
the client socket attempted to read the server response, an exception was thrown,
indicating that the connection had been closed by the server. Next, I enabled full
SChannel logging on the server and restarted. Attempts to connect left 2 messages
in the event logs: "Creating an SSL server credential", followed by "The SSL server
credentials private key has the following properties..." and NO error. Baffled, I
installed Microsofts &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=cabea1d0-5a10-41bc-83d4-06c814265282&amp;amp;displaylang=en"&gt;SSL
Diagnostics&lt;/a&gt; utility and attempted a handshake simulation. This yielded the error
"Unexpected error receiving data (0x80090304)", which error code is defined as SEC_E_INTERNAL_ERROR;
again, a most unhelpful description. This led me on a week-long study of X.509 certificates,
makecert.exe and the MS Crypto Providers key container implementation. Im going to
omit many details here in order to get to the point, which is to enumerate the problems
and solutions Ive found for our situation. Ill follow up with another post to describe
the gory details of this research in some depth. Anyway, simply stated, the problem
is that the certificate's private key is either inaccessible or the keyspec is incorrect.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Problems&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Our problems basically boiled down to three root causes:
&lt;/p&gt;
&lt;p&gt;
1 - Improper import of good certificates, which caused them to appear faulty.
&lt;/p&gt;
&lt;p&gt;
2 - Use of a build of makecert.exe that generates key containers improperly
&lt;/p&gt;
&lt;p&gt;
3 - Failure to realize that makecert.exe does not, by default, generate certs that
use the correct keyspec for an SSL cert.
&lt;/p&gt;
&lt;p&gt;
Problem #1 - The problem with importing was that I sometimes imported the certificate
into the CurrentUser MY store and then, realizing that I'd imported into the wrong
store, copied the cert into the LocalMachine MY store. The problem is that once a
certificate is imported into a CurrentUser store, the private key container resides
in the users profile, where it cannot be found by a system process.
&lt;/p&gt;
&lt;p&gt;
Problem #2 - One of the first things I do when I create a development VM is to add
the path to the .NET SDK bin directory to my system path. I always want access to
the tools therein from any command prompt. Unfortunately, the makecert.exe in that
directory (v5.131.2157.1) wont work for generating SSL certs. The problem is that
even if you specify a LocalMachine store for the cert, the private key container it
generates is generated as a user key, not a machine key. Therefore, though everything
looks good, when you use the cert from a system process, you experience the symptoms
enumerated above. In order to use this build for SSL certs, youd have to pre-generate
the key container and reference the pre-created container on the makecert command
line.
&lt;/p&gt;
&lt;p&gt;
Problem #3 - There are two standard key types for RSA keys: signature and exchange.
Which key is used is defined by the keyspec property of the private key context belonging
to the certificate. The keyspec property must be set to "Exchange" in order for the
cert to work for SSL. This is obvious to me, but I never realized that makecert.exe
sets the keyspec to Signature by default, and there isnt a standard interface to view
this property of a certificate that Im aware of.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Solutions&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Solution #1 - Import certificates intended for SSL usage into a LocalMachine store
directly. Dont try to copy a cert from a CurrentUser store into a LocalMachine store.
If youve mistakenly imported a cert into a CurrentUser store, you need to delete the
cert &lt;em&gt;and&lt;/em&gt; the key container (deleting a certificate does not delete the key
container), and then import the cert into a LocalMachine store. See my next post for
details as to how to locate the key container and delete it.
&lt;/p&gt;
&lt;p&gt;
Solution #2 - Dont use v5.131.2157.1 of makecert.exe (the one in the .NET v1.1 SDK)
to generate SSL certificates. It always generates user key containers, which wont
work from a system process. Fortunately, the version of makecert.exe (v5.131.3790.0)
that ships with v2.0 of the .NET SDK, as well as the latest Platform SDKs, works properly.
&lt;/p&gt;
&lt;p&gt;
Solution #3 - Always use the command line option "-sky exchange" with makecert.exe
if youre generating SSL certificates. If you dont specify this, it will default to
the signature keyspec, which wont work for SSL.
&lt;/p&gt;
&lt;p&gt;
The difficulties Ive experienced have been compounded by the fact that any one or
more of these problems could be combined in a single situation, making it terribly
difficult to pinpoint precisely what is going on. To aid in the diagnosis of SSL certificate
problems, Im making available a little command line utility that I wrote for this
purpose.
&lt;/p&gt;
&lt;p&gt;
checkcert: &lt;a href="/downloads/checkcert.zip"&gt;exe&lt;/a&gt;&amp;nbsp;&lt;a href="/downloads/checkcert_source.zip"&gt;source&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
To use checkcert.exe, pass a store name and a cert subject search string (such as
the common name). Checkcert will display some key information about the cert that
is not available in the built-in tools (again, that Im aware of). Most importantly,
checkcert will display the private key container location and the keyspec. You want
to ensure that the key container location is "Machine" and that the keyspec is "Exchange"
for an SSL cert. I hope this information and the utility will save someone the hassle
of trying to unravel this mess from scratch.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.stevestechspot.com/aggbug.ashx?id=3f39efbd-09e2-4beb-9d5a-e37ad2fb3862" /&gt;</description>
      <comments>http://www.stevestechspot.com/CommentView,guid,3f39efbd-09e2-4beb-9d5a-e37ad2fb3862.aspx</comments>
      <category>AllContent</category>
    </item>
    <item>
      <trackback:ping>http://www.stevestechspot.com/Trackback.aspx?guid=c1f96ead-0baf-4d93-b969-5869bc8147dc</trackback:ping>
      <pingback:server>http://www.stevestechspot.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.stevestechspot.com/PermaLink,guid,c1f96ead-0baf-4d93-b969-5869bc8147dc.aspx</pingback:target>
      <dc:creator>Steve Johnson</dc:creator>
      <wfw:comment>http://www.stevestechspot.com/CommentView,guid,c1f96ead-0baf-4d93-b969-5869bc8147dc.aspx</wfw:comment>
      <wfw:commentRss>http://www.stevestechspot.com/SyndicationService.asmx/GetEntryCommentsRss?guid=c1f96ead-0baf-4d93-b969-5869bc8147dc</wfw:commentRss>
      <slash:comments>26</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've been doing a fair bit of development against the MS HTTP API lately, and I'm
weary of the httpcfg.exe utility. First of all, it's a right pain in the neck to find
in the first place. Once located and downloaded, it's equally painful to use, IMO.
Having read several articles on the net about the woes others were also experiencing
in using this tool, I decided to write a simple GUI application against the Http configuration
APIs. It's called, quite simply, HttpConfig. It won't win any points for UI flash,
but I do hope it will make life easier for some as it already has for me. Enjoy!
</p>
        <p>
        </p>
        <p>
Download: <a href="/downloads/httpconfig.zip">exe</a> <a href="/downloads/httpconfig_source.zip">source</a></p>
        <img width="0" height="0" src="http://www.stevestechspot.com/aggbug.ashx?id=c1f96ead-0baf-4d93-b969-5869bc8147dc" />
      </body>
      <title>A Better httpcfg</title>
      <guid isPermaLink="false">http://www.stevestechspot.com/PermaLink,guid,c1f96ead-0baf-4d93-b969-5869bc8147dc.aspx</guid>
      <link>http://www.stevestechspot.com/ABetterHttpcfg.aspx</link>
      <pubDate>Fri, 28 Oct 2005 06:00:00 GMT</pubDate>
      <description>
		&lt;p&gt;
I've been doing a fair bit of development against the MS HTTP API lately, and I'm
weary of the httpcfg.exe utility. First of all, it's a right pain in the neck to find
in the first place. Once located and downloaded, it's equally painful to use, IMO.
Having read several articles on the net about the woes others were also experiencing
in using this tool, I decided to write a simple GUI application against the Http configuration
APIs. It's called, quite simply, HttpConfig. It won't win any points for UI flash,
but I do hope it will make life easier for some as it already has for me. Enjoy!&lt;p&gt;
&lt;p&gt;
Download:&amp;nbsp;&lt;a href="/downloads/httpconfig.zip"&gt;exe&lt;/a&gt;&amp;nbsp;&lt;a href="/downloads/httpconfig_source.zip"&gt;source&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.stevestechspot.com/aggbug.ashx?id=c1f96ead-0baf-4d93-b969-5869bc8147dc" /&gt;</description>
      <comments>http://www.stevestechspot.com/CommentView,guid,c1f96ead-0baf-4d93-b969-5869bc8147dc.aspx</comments>
      <category>AllContent</category>
    </item>
  </channel>
</rss>