Decoding some certificate enrollment client events

The Events

Windows clients can request certificates on their own (autoenrollment) or with the help of a user. When enrolling for a certificate you may find this pair of events in your Application log:

Source: Microsoft-Windows-CertificateServicesClient-CertEnroll
Event ID: 64
Level: Information
User: S-1-5-18
User Name: NT AUTHORITY\SYSTEM
Computer: <servername>
Description: Certificate enrollment for Local system successfully load policy from policy server

Source: Microsoft-Windows-CertificateServicesClient-CertEnroll
Event ID: 65
Level: Information
User: S-1-5-18
User Name: NT AUTHORITY\SYSTEM
Computer: <servername>
Description: Certificate enrollment for Local system is successfully authenticated by policy server {AFD04357-74D7-47B3-82BC-BBE76F4E6F3D}

Obviously the local system successfully enrolled for a certificate, but what do these actually tell us?

Decoding

Let’s start with the first event with if 65 (remember, the newest events are at the top of the event log). It tells us that a CA, included in a certificate enrollment policy, identified by GUID, has successfully authenticated the system’s enrollment request. In the Windows help we find this about certificate enrollment policies:

Certificate enrollment policy provides the locations of certification authorities (CAs) and the types of certificates that can be requested. Organizations that are using Active Directory Domain Services (AD DS) can use Group Policy to provide certificate enrollment policy to domain members by using the Group Policy Management Console to configure the certificate enrollment policy settings. The Certificates snap-in can be used to configure certificate enrollment policy settings for individual client computers unless the Group Policy setting is configured to disable user-configured enrollment policy.

Unless you have added some yourself, there is one default certificate enrollment policy, the Active Directory Enrollment Policy.

To display the enrollment policies you can run certutil.exe –Policy. It will give you a list of your enrollment policies:

Name: Active Directory Enrollment Policy
Id: {AFD04357-74D7-47B3-82BC-BBE76F4E6F3D}
Url: ldap:
NextUpdate: EMPTY
LastUpdate: EMPTY
Url Flags = 15 (21)
  PsfLocationGroupPolicy — 1
  PsfAutoEnrollmentEnabled — 10 (16)
  0x4 (4)
Authentication = 2
  Kerberos — 2
AllowUntrustedCA: 0
Priority: 7ffffffd (2147483645)
CertUtil: -Policy command completed successfully.

If you look back at the events at the beginning of this post you will recognize the GUID in the event with ID 65. The GUID in the event is the Enrollment Policy ID. So that event is saying that the system was successfully authenticated against the Active Directory Enrollment Policy. Here is a screenshot of the policy as well:

image

NOTE: If you want to see the defalt certificate enrollment policy and create new ones you need to use Group Policy. You can also create new certificate enrollment policies using the Certificates MMC. See the links below:

Now, if you want to see which CAs are in that enrollment policy you can run certutil.exe –CA (my output is concatenated):

Name: Active Directory Enrollment Policy
Id: {AFD04357-74D7-47B3-82BC-BBE76F4E6F3D}
Url: ldap:
6 CAs:

CA[0]:
CAPropCommonName = <CA Name>
CAPropDNSName = <CA Server FQDN>
CAPropCertificateTypes =
  0: EFSRecovery
  1: EFS
  2: DomainController
  3: WebServer
  4: Machine
  5: User
  6: SubCA
  7: Administrator

CAPropSecurity = <SDDL>

Without the Certificate Enrollment Policy Web Service role service installed, the only way to get certificate policy information from Active Directory is by using LDAP. This can obviously be a problem so the Certificate Enrollment Policy Web Service role service was created to allow certificate policy information to be retreived over HTTPS also. The Web Service functions as a proxy; accepting client requests for policy over HTTPS and querying Active Directory for certificate policy information over LDAP.

So now we know what the first event (ID 65) means.

The next event is much easier; it just says that the system was able to load the certificate enrollment policy successfully from the CA.

More information:

“A certificate cloud not be found that can be used with this Extensible Authentication Protocol” error in IAS

After issuing a new certificate for a Windows Server 2003 running IAS this error presented itself in the IAS console when trying to configure EAP with the new certificate:

image

“A certificate could not be found that can be used with this Extensibel Authentication Protocol.”

This was accompanied by these two events in the System Log:

image

image

This was the new certificate, based on the default Computer template in Windows:

image

Notice the empty subject field, IAS/NPS does not accept certificates with empty subject names for use with EAP or Smart Cards. The certificate template that had been used for this certificate was a duplicate of the default Computer template. The template looked like this:

image

After creating a new template from the default Computer template, now with Subject name format set to Common name, and issuing a new certificate; IAS worked fine.

So don’t use certificate with blank subjects for your IAS/NPS servers…

An overview of groups used by Active Directory Certificate Services

This is a quick list of the groups associated with Active Directory Certificate Services.

CERTSVC_DCOM_ACCESS

Purpose: Grant DCOM access to Certificate Authority.

Default description: This group has no default description.

Group type: Local/Domain Local Security group.

Default members: Everyone/Domain Users and Domain Computers.

This group is created when Windows Server 2003 Service Pack 1 is installed on a Certificate Authority. If the CA is a member server (or in a workgroup); CERTSVC_DCOM_ACCESS is a computer local group, if the CA is a DC; CERTSVC_DCOM_ACCESS is a domain local group. Also when you install a Certificate Authority (CA) on a Windows Server 2003 machine that already has Service Pack 1 (or later); this group is created.

All security principals that need to enroll certificates from the CA must be a member, direct or indirect, of this group. If the CA is a member server; the Everyone security group is added to CERTSVC_DCOM_ACCESS. If the CA is a DC; the Domain Users and Domain Computers groups are added to CERTSVC_DCOM_ACCESS.

Only domains with a CA installed on a DC have this group, and only members servers with a CA have it as a computer local group. If you have several domains in your forest, only computers and users in the domain where the CA resides can request certificates. If other domains in the forest need to enroll certificates, security principals from those domains must be added to the group.

In Windows Server 2008 this group was replaced by the Certificate Service DCOM Access group (see own group into below).

More info:

  • Description of the changes to DCOM security settings after you install Windows Server 2003 Service Pack 1
  • Error message when a client computer requests a certificate from a computer that is running Windows Server 2003 with Service Pack 1: “The wizard cannot be started because of one or more of the following conditions”

    Certificate Service DCOM Access

    Purpose: Grant DCOM access to Certificate Authority.

    Default description: Members of this group are allowed to connect to Certification Authorities in the enterprise.

    Group type: Builtin Local Security Group.

    Default members: Authenticated Users.

    This group serves the same purpose as CERTSVC_DCOM_ACCESS, but is created in Windows Server 2008 domains. It grants access to Certificate Authorities, but is a Builtin local group as opposed to CERTSVC_DCOM_ACCESS, which is a Local or Domain Local group.

    Sometimes you will se both CERTSVC_DCOM_ACCESS and Certificate Service DCOM Access in a domain.

    Cert Publishers

    Purpose: Publish certificates to Active Directory.

    Default description: Enterprise certification and renewal agents

    Group Type: Global Security Group (Windows 2000)/Domain Local Security Group (Windows Server 2003 or later)

    Default members: Certificate Authority computer account from same domain as group.

    This group is created when an Active Directory domain is created. In Windows 2000 it is created as a Global Security Group, but in Windows Server 2003 or later it is created as a Domain Local Security Group.

    If a Windows 2000 domain is upgraded to Windows Server 2003 or later, this group remains as a Global Security Group; it is not automatically updated to Domain Local scope. To change the group scope you can run this command:

  • dsmod group CN=Cert Publishers,CN=Users,<domain DN> -scope l

    Sometimes you cannot change the group scope directly to Domain Local. In this case, you have to run 2 commands:

  • dsmod group CN=Cert Publishers,CN=Users,<domain DN> -scope u
    (This command changes the global group into a universal group.)
  • dsmod group CN=Cert Publishers,CN=Users,<domain DN> -scope l
    (This changes the group scope to Domain Local.)

    This group is granted Read userCertificate and Write userCertificate on all user and computer accounts in the domain where it resides. If the same domain contains a Certificate Authority the CA is added to this group, thus allowing it to publish certificates to the user or computer.

    The permissions granted to the Cert Publishers group in a domain are defined on the AdminSDHolder container located in <domain>/System. Changing the Cert Publishers group’s permissions on AdminSDHolder will change the permissions that Cert Publishers have on all objects in the domain.

    In a multi-domain forest, the CA computer account(s) must be added to this group in all the domains where you want the CA to be able to publish certificates.

    If you have a multi-domain forest the PowerShell script below will display the group scope and members of all the Cert Publishers groups in the forest:

    #
    # EnumerateAllCertPublishersMembers2.ps1
    # by Morgan Simonsen, Atea
    #
    # List the group type, scope and members of the Cert Publishers group
    # in every domain in a forest.
    #
    # More info:
    #
    https://morgansimonsen.wordpress.com/2012/01/24/an-overview-of-groups-used-by-active-directory-certificate-services/
    #

    $colCertPublishersGroups = @()

    $forest = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()

    Write-Host “Getting forest-wide membership of Cert Publishers groups…”

    # Get members of ‘Cert Publishers’ for forest-root domain
    $objTemp = New-Object System.Object
    $objTemp | Add-Member -type NoteProperty -name “Domain” -value $forest.name

    $group = Get-QADGroup -Identity ( $forest.name + “/users/Cert Publishers” ) -Service $forest.pdcroleowner #-ea silentlycontinue

    $objTemp | Add-Member -type NoteProperty -name “Group Name” -value $group.name
    $objTemp | Add-Member -type NoteProperty -name “Group Type” -value $group.grouptype
    $objTemp | Add-Member -type NoteProperty -name “Group Scope” -value $group.groupscope

    $members = Get-QADGroupMember -Identity ( $forest.name + “/users/Cert Publishers” ) -Service $forest.pdcroleowner #-ea silentlycontinue

    $objTemp | Add-Member -type NoteProperty -name “Members” -value $members

    If ( $members -ne $null )
    {
        ForEach ( $member in $members )
        {
            #Nothing
        }
    }
    $colCertPublishersGroups += $objTemp

    $domain = $null
    $group = $null
    $members = $null
    $objTemp = $null

    # Get members of ‘Cert Publishers’ for child domains
    $forest.children | ForEach `
    {
        $objTemp = New-Object System.Object
        $mydomain = Get-QADObject -Identity $_.name #-ea silentlycontinue

        $objTemp | Add-Member -type NoteProperty -name “Domain” -value $mydomain.name

        $group = Get-QADGroup -Identity ( $_.name + “/users/Cert Publishers” ) -Service $_.pdcroleowner #-ea silentlycontinue

        $objTemp | Add-Member -type NoteProperty -name “Group Name” -value $group.name
        $objTemp | Add-Member -type NoteProperty -name “Group Type” -value $group.grouptype
        $objTemp | Add-Member -type NoteProperty -name “Group Scope” -value $group.groupscope

        $members = Get-QADGroupMember -Identity ( $_.name + “/users/Cert Publishers” ) -Service $_.pdcroleowner #-ea silentlycontinue

        $objTemp | Add-Member -type NoteProperty -name “Members” -value $members

        If ( $members -ne $null )
        {
            ForEach ( $member in $members )
            {
                #Nothing
            }
        }
        $colCertPublishersGroups += $objTemp

        $domain = $null
        $group = $null
        $members = $null
        $objTemp = $null

    }

    $colCertPublishersGroups

    More info:

  • Certification Authority configuration to publish certificates in Active Directory of trusted domain
  • Cert Publishers scope changed from Global to Domain Local in Windows Server 2003
  • Enterprise CA May Not Publish Certificates from Child Domain or Trusted Domain