How to Find and Use Certificate Template OIDs in C# for Enterprise CA Certificate Issuance


10 views

When working with Enterprise Certificate Authorities in C#, you'll often need the OID (Object Identifier) rather than the display name of your certificate template. Here's how to find it:

// PowerShell command to list all certificate templates with their OIDs
Get-ADObject -Filter {objectclass -eq "pKICertificateTemplate"} -Properties * | 
Select-Object Name,msPKI-Cert-Template-OID | 
Format-Table -AutoSize

Alternatively, you can use the CertTmpl.msc GUI:

  1. Open Certificate Templates console (certtmpl.msc)
  2. Right-click your template → Properties
  3. Navigate to the "Extensions" tab
  4. Look for "Certificate Template Information" extension
  5. The OID appears in the format: 1.3.6.1.4.1.311.21.8.x.y.z...

Here's a complete C# example using the Certificate Enrollment API (certenroll.dll):

using CERTENROLLLib;

public void RequestCertificate(string templateOID)
{
    // Initialize COM objects
    CX509Enrollment enroll = new CX509Enrollment();
    CX509CertificateRequestPkcs10 request = new CX509CertificateRequestPkcs10();
    CX509PrivateKey privateKey = new CX509PrivateKey();
    
    // Configure private key
    privateKey.ProviderName = "Microsoft RSA SChannel Cryptographic Provider";
    privateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE;
    privateKey.Length = 2048;
    privateKey.MachineContext = false;
    privateKey.Create();

    // Configure request
    request.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextUser, privateKey, "");
    
    // Set the template OID
    CObjectIds objectIds = new CObjectIds();
    CObjectId objectId = new CObjectId();
    objectId.InitializeFromValue(templateOID);
    objectIds.Add(objectId);
    
    CX509ExtensionTemplate templateExtension = new CX509ExtensionTemplate();
    templateExtension.InitializeEncode(objectIds);
    request.X509Extensions.Add((CX509Extension)templateExtension);

    // Complete enrollment
    enroll.InitializeFromRequest(request);
    enroll.Enroll();

    // Install certificate
    string certBase64 = enroll.RawData;
    // ... process certificate installation ...
}

For legacy systems still using VBScript:

Set objEnroll = CreateObject("X509Enrollment.CX509Enrollment")
Set objRequest = CreateObject("X509Enrollment.CX509CertificateRequestPkcs10")
Set objPrivateKey = CreateObject("X509Enrollment.CX509PrivateKey")

' Configure private key
objPrivateKey.ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
objPrivateKey.KeySpec = 1 ' AT_SIGNATURE
objPrivateKey.Length = 2048
objPrivateKey.MachineContext = False
objPrivateKey.Create()

' Configure request
objRequest.InitializeFromPrivateKey 1, objPrivateKey, ""

' Set template OID (replace with your actual OID)
Set objObjectIds = CreateObject("X509Enrollment.CObjectIds")
Set objObjectId = CreateObject("X509Enrollment.CObjectId")
objObjectId.InitializeFromValue "1.3.6.1.4.1.311.21.8.1234567.1234567.1234567890"
objObjectIds.Add objObjectId

Set objTemplateExtension = CreateObject("X509Enrollment.CX509ExtensionTemplate")
objTemplateExtension.InitializeEncode objObjectIds
objRequest.X509Extensions.Add objTemplateExtension

' Complete enrollment
objEnroll.InitializeFromRequest objRequest
objEnroll.Enroll

If you encounter errors when specifying template OIDs:

  • Verify the OID exists in your AD forest using the PowerShell command above
  • Ensure your account has enroll permissions for the template
  • Check the CA's certificate templates snap-in for any restrictions
  • For machine certificates, set MachineContext = true
  • When using VBScript, ensure the script runs with proper privileges

For more complex requirements, you might need to combine multiple templates or set additional attributes:

// Adding multiple template OIDs (superseded templates)
CObjectIds objectIds = new CObjectIds();
CObjectId primaryOid = new CObjectId();
primaryOid.InitializeFromValue("1.3.6.1.4.1.311.21.8.100.1");
objectIds.Add(primaryOid);

CObjectId secondaryOid = new CObjectId();
secondaryOid.InitializeFromValue("1.3.6.1.4.1.311.21.8.100.2");
objectIds.Add(secondaryOid);

When working with Microsoft Enterprise Certificate Authority (CA), each certificate template has a unique Object Identifier (OID) that's essential for programmatic certificate enrollment. Here are the methods to find it:

  • Using certtmpl.msc: Open Certificate Templates console, right-click a template → Properties → "General" tab → "Display name" field shows the OID in parentheses
  • Via PowerShell:
    Get-CATemplate | Select-Object Name, msPKI-Cert-Template-OID
  • Through ADSI Edit: Navigate to CN=Certificate Templates,CN=Public Key Services,CN=Services in Configuration partition

Here's how to properly specify the OID when requesting certificates through the CertEnroll interfaces:

// C# Example using CERTENROLLLib
string templateOID = "1.3.6.1.4.1.311.21.8.1234567.9876543.123456789";

IX509CertificateRequestCertificate request = new CX509CertificateRequestCertificate();
request.InitializeFromTemplate(
    X509CertificateEnrollmentContext.ContextUser,
    new CObjectId(templateOID),
    null);  // This is where the OID goes, not in the template name parameter

Developers often encounter these specific issues:

  • Incorrect OID format: Must be in dotted decimal notation (1.2.3.4 format)
  • Permission issues: The requesting account needs Enroll permission on the template
  • Template mismatch: Verify the OID matches exactly what's shown in certtmpl.msc

For legacy systems still using VBScript:

Const ENROLLMENT_TEMPLATE_OID = "1.3.6.1.4.1.311.21.8.1234567.9876543.123456789"

Set objRequest = CreateObject("X509Enrollment.CX509CertificateRequestCertificate")
Set objObjectId = CreateObject("X509Enrollment.CObjectId")
objObjectId.InitializeFromValue ENROLLMENT_TEMPLATE_OID

objRequest.InitializeFromTemplate _
    X509CertificateEnrollmentContextUser, _
    objObjectId, _
    ""  ' Empty string for template name

When things go wrong:

  1. Check the Windows Event Log (Applications and Services Logs → Microsoft → Windows → CAPI2)
  2. Enable CertSvc debugging (set registry value HKLM\System\CurrentControlSet\Services\CertSvc\Debug = 0xFFFF)
  3. Use certutil -v -template to verify template properties