+1.916.577.1977 | Downloads | Buy | Register | Login
 Search  
Wednesday, August 20, 2008
Search Blogs
 

Available Blogs
 

Previous Blogs
 

Technorati
 
More blogs about coversant.

About Coversant
 

Creating a Self-Signed X509Certificate2 in C#
 
Location: BlogsMullin' with Mullins    
Posted by: Chris Mullins 10/16/2006

There are all sorts of great classes for manipulating X509 Certificates.

Back in .NET 1.1, you could pull in the WSE 1.0/2.0 libraries, and get access to X509Certificate. Later, in .Net 2.0 + WSE 3.0, you got access to X509Certificate2.

Now, with .NET 3.0 we have WCF (codename: Indigo) and I was expecting a still newer, richer, set of classes for manipulating X509 Certificates (I was also expecting deep UDDI support, but alas, nothing...).

Creating self signed certificates has always been problematic in .Net, and it's (sadly) something that everyone dealing with security and testing has to do frequently. Managed code provides no way to create these certificates. The X509Certificate2 class provies a very rich infrastructure for manipulating existing X509 certs, but doesn't provide any mechanism for creating them.

After a signifigant amount of plugging away looking for a purely managed solution for creating an X509Certificate, I gave up. There appeared to be a few options if I wanted to use CAPICOM, but I have moral issues with COM interop, so I didn't go down that path.

The only good answer I could come up with was to shell out to MakeCert, and then read the resulting certificate. I know, I know. I don't like it much either - but it works.

There are a number of optimizations that could be made on the code below, not the least of which involve Code Address Security, cleaning up the file after we're done with it, providing a nice options wrapper around MakeCert, importing the certificate into the Certificate Store using CertMgr, and lots of other good things. If anyone modifies this code to do any of that, let me know! :)

Here's the code that I used to create the certificates:

using System;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography.X509Certificates;

public static X509Certificate2 CreateCertificate()
{
    // makecert -r -pe -n "CN=TestUser" -ss my -sr currentuser 
    //      -sky exchange .\TestUser.cer

    const string MakeCert = 
        "C:\\Program Files\\Microsoft Visual Studio 8\\" + 
        "Common7\\Tools\\Bin\\makecert.exe";

    string fileName = Path.ChangeExtension(Path.GetTempFileName(), "cer");
    string userName = Guid.NewGuid().ToString();

    string arguments = 
        string.Format("-r -pe -n \"CN={0}\" -ss my -sr currentuser -sky exchange \"{1}\"", 
        userName, fileName);

    Process p = Process.Start(MakeCert, arguments);
    p.WaitForExit();

    byte[] certBytes = ReadFile(fileName);
    X509Certificate2 cert = new X509Certificate2(certBytes);
    return cert;
}

internal static byte[] ReadFile(string fileName)
{
    using (FileStream f = new FileStream(fileName, FileMode.Open, FileAccess.Read))
    {
        int size = (int)f.Length;
        byte[] data = new byte[size];
        size = f.Read(data, 0, size);
        return data;
    }
}

This code is intended to be used mostly in Unit Tests where creating new certificates happens very frequently, and I know our SoapBox Server installer classes do something very similar during install to create Self-Signed certificates for XMPP domains.

There are all sorts of potential issues with this, not the least of which is verifying MakeCert is really at that path (it usually is!), verifing write-access to the temp directory, permission to create a new process, etc.

Copyright ©2006 Chris Mullins
Permalink |  Trackback

Comments (2)  
Re: Creating a Self-Signed X509Certificate2 in C#    By jconley on 10/19/2006
One note to get around that path -- and by the way it's not that way on my workstation since i'm running x64 -- is to just embed it in your assembly as a resource and extract it whenever you need it. Makecert is standalone. This is how we do it in the SoapBox Server installation package for creating a self signed cert. Mono's makecert is also an interesting option as it is managed code.

Re: Creating a Self-Signed X509Certificate2 in C#    By kyes on 6/7/2008
thanks for the code.

Digital Frame


©2008 Coversant, Inc. | Privacy Policy | About Coversant | Contact Info