Working with a Certificate Authority in C#

First of all I would like to apologize for the long delay between posts.  The holidays, a new baby, and work schedule had me running around quite a bit.  Anyway I'm back blogging and one of my new years resolutions was to keep doing brain dumps here in the hopes that it would help me lose the 20 pounds of sympathy weight that I gained during my wife's pregnancy. 

This month I wanted to cover something that I worked on some time ago because I dont see a lot of information elsewhere on how to work with a CA programmatically.  This is probably because a lot of people dont 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)

{

      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.