Retrieving Client Certificate Extensions

Tue, May 19, 2009

Security, Technology

I received a request from my customer today to see if it’s possible to extract the extended information found in a client certificate.  The reason behind the question is based on the need to gather some information from a client certificate during a connection attempt to their ASP.NET websites.  I had worked on extracting basic certificate information on a couple of previous projects and I remembered this to be a bit of a challenge.

The main part of the problem is that the X509Certificate class only exposes a small subset of information from a client certificate, which didn’t include the Extensions class.  Fortunately .NET 3.5 provides additional functionality in the newer X509Certificate2 class.  I had stumbled on this while working on my VerifySSLCertificate application application a few weeks ago. 

I started by grabbing the client certificate provided during the page request and loading it into the X509Certificate2 class:

X509Certificate2 x509Cert2 = new X509Certificate2(Page.Request.ClientCertificate.Certificate);

Next I needed to locate the information for the Subject Alternative Name, displaying it in a nice format.  This was accomplished using the following syntax:

X509Extension sanExtension = (X509Extension)x509Cert2.Extensions["Subject Alternative Name"];
if (sanExtension != null)
{
    Response.Write(string.Format(para, "Subject Alternative Name:"));
    Response.Write(string.Format(subpara, sanExtension.Format(true)));
}

While I was at it I decided to grab the Enhanced Key Usage (EKU) entries.  This step took a little more effort as we had to enumerate each of the OID entries in the EKU:

X509EnhancedKeyUsageExtension ekuExtension =
	(X509EnhancedKeyUsageExtension)x509Cert2.Extensions["Enhanced Key Usage"];
if (ekuExtension != null)
{
    OidCollection ekuOids = ekuExtension.EnhancedKeyUsages;
    foreach (Oid ekuOid in ekuOids)
        Response.Write(string.Format(subpara, ekuOid.FriendlyName + " (OID: " + ekuOid.Value + ")"));
}

While this task turned out to be a pretty easy I have to say it took some time to find the right syntax and sample code to make it all come together.  Hopefully you will  be able to locate this sample code easier when the time comes that you need to do something similar.

Afterwards I decided to update the identify.aspx web page that I previously created and use on web servers to help identify exactly which web server I am connected.  This web page is useful when you are connecting to a URL which is load balanced between two or more web servers.  Simply copy identify.aspx page into the root of your web server and when you connect to that page you will see the server name, username, and client certificate information.  No more guessing which load balanced web server you are connected to.

IdentifyWebServer.zip

Comments are closed.