I have the desired result through utility the certutil:
PS C:\>> certutil -config "dev.root.ad\Dev Issuing CA" –Catemplates –v | select-string displayname
displayName = DEMO AnyConnect 4 years
displayName = ECS User
But on C# I have problems. This my code:
using CERTADMINLib;
using CERTCLILib;
namespace Services
{
public class CATemplates
{
public const Int32 CrPropTemplates = 0x0000001D; // Configured Certificate Templates
public const Int32 ProptypeString = 4;
public static String GetCAPropertyDisplayName(string configString)
{
var request = new CCertRequest();
//var templates = (String)request.GetCAProperty(configString, CrPropTemplates, 0, ProptypeString, 0);
var displayName = request.GetCAPropertyDisplayName(configString, CrPropTemplates);
return displayName;
}
}
}
I have COMException:
System.Runtime.InteropServices.COMException: 'CCertRequest::GetCAPropertyDisplayName: The permissions on this certification authority do not allow the current user to enroll for certificates. 0x80094011 (-2146877423 CERTSRV_E_ENROLL_DENIED)'
Through CCertAdmin I have same COMException.
I would like to find a solution without adding any permissions in local system and Domain. Do as well in the certutil. Magic certutil in parameter "-v"
This call:
var displayName = request.GetCAPropertyDisplayName(configString, CrPropTemplates);
is incorrect. ICertRequest::GetCAPropertyDisplayName
gets display name of CA property, not the template. Commented line is correct one:
//var templates = (String)request.GetCAProperty(configString, CrPropTemplates, 0, ProptypeString, 0);
uncomment this line. You will get a string with OID and template common name on separate line. Split the string by \n
character and take only lines that contain template name. Then query directory services to get the template object. They are stored at
"LDAP://CN={template name}, CN=Certificate Templates, CN=Public Key Services, CN=Services, {ConfigurationNamingContext}"
Configuration naming context is retrieved from LDAP://RootDSE
. After getting template object from DS read displayName
DS attribute to get display name of certificate template.
Update:
as for exception: make sure if caller has "Request Certificates" permission on CA server itself.
why certutil works in this context? It seems that it doesn't use ICertRequest::GetCAProperty
method to retrieve templates and read them from Active Directory CA object (under Enrollment Services container). You may do the same. Read list of assigned templates from CA object and then read templates to get display name.
User contributions licensed under CC BY-SA 3.0