Working with a Certificate Authority in C# (Updated)

Working with a Certificate Authority in C# (Updated)

Hello again.  This is a repost and move of an article I wrote a few years ago and for some reason forgot to move to my main blog here.  I'm reposting it here to give anyone who wants to comment or ask questions a fresh place to do so as I no longer have access to my MSDN blog.

Here is the original article...

This month I wanted to cover something that I worked on some time ago because I don't see a lot of information elsewhere on how to work with a CA programmatically.  This is probably because a lot of people don't really need to do this, and CertUtil is a great command-line utility that has a ton of features.  However, there may be a case or two where you want to write something yourself.  In the code below I will try to explain the basics of working with a Certificate Authority database.

The key to connecting to the Certificate Authority is the ICertView interface (http://msdn2.microsoft.com/en-us/library/aa385414(VS.85).aspx).  Through this interface you can get all the information you need from the CA.  To get a reference to ICertView you will need to include a reference to Certadm.dll.  This dll is present on server versions Windows 2000 and later.

Step 1:  Connecting to the Certificate Authority

Connecting to the CA is fairly simple.  Just create an instance of CCertView and use OpenConnection();

CERTADMINLib.CCertView CView = new CERTADMINLib.CCertViewClass();
CView.OpenConnection(server + “\\” + ca);

I would like to note that the ca parameter is the name of  your CA that you specified when you installed Certificate Services.

Step 2:  Get a column count and place columns into the view

int iColumnCount = 0;
iColumnCount = CView.GetColumnCount(0);
CView.SetResultColumnCount(iColumnCount);

// Place each column in the view.
for (int x = 0; x < iColumnCount; x++)
{
CView.SetResultColumn(x);
}

Step 3:  Open the View and reset the row position

//Open the View
CERTADMINLib.IEnumCERTVIEWROW rowsEnum;
rowsEnum = CView.OpenView();

CERTADMINLib.IEnumCERTVIEWCOLUMN objCol;
rowsEnum.Reset();

Step 4:  Enumerate Row and Column Information

There are too many columns to list here, but you should get the picture.  Pay attention to the PROPTYPE of the data that you want to retrieve.   Here are some constants you will need in your application:

public const int CV_OUT_BASE64 = 0x1;
public const int CV_OUT_BINARY = 0x2;
public const int CV_OUT_HEX = 0x4;
public const int CV_OUT_HEXASCII = 0x5;
public const int PROPTYPE_LONG = 0x1;
public const int PROPTYPE_DATE = 0x2;
public const int PROPTYPE_BINARY = 0x3;
public const int PROPTYPE_STRING = 0x4;
public const int PROPTYPE_MASK = 0xFF;

//Enumerate Rows
while (rowsEnum.Next() != -1)
{

//The Certificate object noted here is just a placeholder
//object that I defined to hold the data.
Certificate cert = new Certificate();
objCol = rowsEnum.EnumCertViewColumn();

//Enumerate Columns
while (objCol.Next() != -1)
{
switch (objCol.GetDisplayName())
{
case “Request Disposition Message”:
try
{
cert.DispMessage = objCol.GetValue(PROPTYPE_STRING).ToString();
}
catch
{
//Exception Handling
}
break;
case “Certificate Expiration Date”:
try
{
cert.ExpirationDate = objCol.GetValue(PROPTYPE_DATE).ToString();
}
catch
{
//Exception Handling
}
break;
default:
break;
}
}
}

That’s about it.  You can now add logic to work with your certificates.  Additional name properties are located here (http://msdn2.microsoft.com/en-us/library/aa386991(VS.85).aspx).  Happy coding.