TameMyCerts is a policy module for Microsoft Active Directory Certificate Services (AD CS) enterprise certification authorities that enables security automation for a lot of use cases in the PKI field.
It is developed in germany by PKI expert Uwe Gradenegger (https://www.gradenegger.eu/).
The module supports, amongst other functions, inspecting certificate requests for certificate templates that allow the subject information to be specified by the enrollee against a defined policy. If any of the requested identities violates the defined rules, the certificate request automatically gets denied by the certification authority. Requested identities can also be mapped against Active Directory to apply restrictions based on group memberships, or even to pull certificate content from AD.
Therefore, the module helps you to tame your certs! It has already proven itself in countless productive deployments of enterprise-grade scale.
TameMyCerts is Open Source Software. Find it on GitHub (https://github.com/Sleepw4lker/TameMyCerts).
For enterprise deployments, commercial support and maintenance agreements are being offered as well.
Enterprises in a modern, digitalized, highly connected world strongly rely on digital certificates. Certificates are used for a variety of use cases like…
Authentication to on-premises or cloud resources.
Enabling remote access for users for them to be able to work remotely from anywhere, with any kind of device.
Securing web-based transactions.
Ensuring authenticity in electronic document workflows.
Organizations around the world rely on Microsoft Active Directory Certificate Services (AD CS) (https://learn.microsoft.com/en-us/windows-server/identity/ad-cs/active-directory-certificate-services-overview) for issuing digital certificates within their Microsoft identity ecosystem. Microsoft AD CS is a suite of roles provided by the Microsoft Windows Server operating system. Its main role is the certification authority (CA), which is responsible for processing certificate requests and issuing digital certificates.
The core of a digital certificate is the identity it provides. A CAs main responsibility is to verify and attest the enrollees identity. Trusting a certification authority means trusting the content of the digital certificates it is issuing and the identities it attests.
AD CS uses the concept of certificate templates to define rules that shall be applied to incoming certificate requests and issued certificates.
AD CS knows of two kinds of certificate templates and requests:
The fact whether a certificate template qualifies as online or offline derives from the settings within the “Subject” tab of the certificate template settings.
AD CS was originally designed around the Microsoft Active Directory ecosystem and as such to heavily rely on online certificate templates for authentication of enrollees and ensuring their identities.
However, many modern use cases require switching the certification authority to use offline certificate templates, where the certification authority has no control over the issued certificates content. This opens up a large surface for various attacks against the certification authority. In a worst case, the entire Active Directory environment of a company could be compromised because of an abused certification authority or certificate template (refer to https://posts.specterops.io/certified-pre-owned-d95910965cd2 for further details).
AD CS uses on the concept of policy modules (https://learn.microsoft.com/en-us/windows/win32/seccrypto/certificate-services-architecture) to determine if a certificate shall be issued. A policy module is a piece of software that is loaded into the certification authority process on start-up of the CA service. Think of it as a plug-in.
A policy module for AD CS has two main purposes:
Modify content of issued certificates, such as determining the Subject Distringuished Name (DN) and adding extensions to an issued certificate.
Decide whether a certificate request shall be issued, put into pending state, or get denied.
Microsoft designed AD CS in a way so that custom policy modules could be developed by individual contributors to enhance the provided functionality. TameMyCerts is such a policy module, which allows to extend the functionality that is provided by AD CS. Unique about TameMyCerts is that it is made available to the public via a free license.
Refer to the Typical use cases for the TameMyCerts policy module chapter in the Appendix section of the document to learn more on typical use cases where TameMyCerts can add value.
The caveat in developing a custom policy module is that there can only be one module active at a time. Usually this means that all the functionality of the Windows Default policy module would have to be re-implemented by the custom module, which is complex and prone to errors.
TameMyCerts solves the issue: It shims the Windows Default policy module, which means all the original functionality is preserved, but additional checks can be performed afterwards.
TameMyCerts passes incoming certificate requests to the Windows Default policy module and only gets active afterwards, if a configuration has been made. This means all certificate templates that don’t have a policy configuration file specified are completely left untouched and behave exactly as without having TameMyCerts installed.
This approach was adopted from a code sample that initially was published by Microsoft (a mirror can be found at https://github.com/Sleepw4lker/capolmod) and is in alignment with their recommendations for the development of custom policy modules (https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc783853(v=ws.10)#certificate-services-architecture).
You configure your certificate templates as usual. You then define your rules in eXtended Markup Language (XML) files, one per certificate template you want to “tame”. During installation, you point TameMyCerts to the path where it shall search for your configuration files. If there is no configuration file defined for a given certificate template, TameMyCerts does not apply any additional logic, thus preserving the original behavior of the Windows Default policy module.
TameMyCerts is intended to be installed on a server with the Certification Authority role installed.
The following modes for the certification authority role are supported by TameMyCerts:
CA mode | Support status |
---|---|
Enterprise Root | supported |
Enterprise Issuing | supported |
Standalone Root | not supported |
Standalone Issuing | not supported |
The module was successfully tested and is supported with the following operating systems:
Microsoft Windows Server vNext Insider Preview (Build 25977)
Microsoft Windows Server 2022
Microsoft Windows Server 2019
Microsoft Windows Server 2016
Other Microsoft Windows Server operating systems may work but are not supported.
For Windows Server 2016, Microsoft .NET Framework 4.7.2 (https://support.microsoft.com/en-us/topic/microsoft-net-framework-4-7-2-offline-installer-for-windows-05a72734-2127-a15d-50cf-daf56d5faec2) must be installed. Windows Server versions newer than Windows Server 2016 already fulfill this requirement.
Ensure that the prerequisites are being met by the destination machine prior to installing TameMyCerts.
If you signed up for a maintenance contract, you get a ZIP file containing the module binary as well as an installer script and some example configuration files to get you started.
To install the module, first create a directory on the certification authority where you intend to store the policy configuration files.
Then run install.ps1 as local Administrator. The script will register the module, create the required registry values and configure the policy module as the active one for the certification authority.
The installation script restarts the certification authority service during installation and uninstallation.
You must specify the -PolicyDirectory Parameter which specifies the local path for the XML configuration files you define for each certificate template.
Example:
.\Install.ps1 -PolicyDirectory C:\PolicyFiles
Afterwards, TameMyCerts is automatically enabled as the active policy module, which can be reviewed in the properties dialog of the certification authority in the certification authority management console (certsrv.msc).
As the policy module daisy-chains the Windows default policy module, it also uses all of its registry settings. Therefore, the install script copies this data from the Windows Default module registry key to a new one for the TameMyCerts policy module. Each change you perform with certutil commands that would configure the Windows Default policy module is now written to the TameMyCerts policy module registry key. Should you decide to uninstall it later on, use the provided installer script as well to ensure the settings get copied back so that they stay consistent.
The process of upgrading from a previous version is the same as installing the module. Simply proceed as you would install TameMyCerts for the first time.
Depending on the version you previously used, it may be necessary to adjust your policy configuration files. Refer to the upgrade instructions in the Technical Reference section of the document.
To uninstall the module, run install.ps1 as Administrator. You must specify the -Uninstall parameter.
The installation script restarts the certification authority service during installation and uninstallation.
Example:
.\Install.ps1 -Uninstall
The script will unregister the module, copy the registry settings back and configure the Windows Default policy module as the active one.
The TameMyCerts policy module uses eXtended Markup Language (XML) files to describe what shall be done with incoming certificate requests for a given certificate template. This approach has the benefit that changes can easily be tracked with version control systems like Git and annotated with inline comments.
Create a policy configuration file in XML format for each certificate template you want to apply a policy for in the folder you specified during installation.
Please ensure the file is encoded as UTF-8 if you plan to support special characters like german “Umlauts”.
Name the file exactly as the certificate template (“cn” LDAP attribute) that shall get examined.
For example, if your certificate template is named “TameMyCertsWebServer”, you create a policy configuration file named “TameMyCertsWebServer.xml”. You can get the object name of the certificate template from the certificate template management console or via Windows PowerShell.
Note that certificate template names allow several characters that are not valid for file names (e.g. “<>|*?\/). If you have such a template, simply omit these characters when naming the file.
Each policy configuration file starts with a basic definition of a CertificateRequestPolicy as shown below:
CertificateRequestPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<<!-- Directives go here -->
CertificateRequestPolicy> </
The distribution package of TameMyCerts contains various example files (https://github.com/Sleepw4lker/TameMyCerts/tree/main/examples) to get started with the most common use cases.
The policy configuration files get loaded when an incoming certificate request is processed. Therefore it is not necessary to restart the certification authority service after a policy configuration file has been created or changed. As long as the configuration file does not change, subsequent certificate requests for the same certificate template will be served from an internal cache.
If TameMyCerts is not able to parse the policy configuration file (e.g. because of a syntax error), the certificate request gets denied and an entry is written into the servers event log, pointing to the possible cause of the issue.
You can now configure the file as desired. Some of the settings described in subsequent chapters apply only to offline requests and will have no effect when configured for online certificate templates.
A basic policy configuration file that restricts all certificate request for a given offline certificate template to having a commonName of “Hello World”, and nothing else. All certificate requests that do not comply with these settings will get denied.
CertificateRequestPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Subject>
<SubjectRule>
<Field>commonName</Field>
<Mandatory>true</Mandatory>
<Patterns>
<Pattern>
<Expression>^Hello World$</Expression>
<Pattern>
</Patterns>
</SubjectRule>
</Subject>
</CertificateRequestPolicy> </
Applies to online and offline certificate templates.
TameMyCerts supports an Audit-only mode, in which certificate requests get allowed regardless of the verification result. This helps by sharpending policies before applying them to existing deployments. If a certificate request would be denied in regular mode, TameMyCerts will log this to the event log of the certification authority to allow administrators further research.
You enable Audit only mode by configuring the AuditOnly directive.
AuditOnly>true</AuditOnly> <
Applies to online and offline certificate templates.
The “Windows Default” policy is only capable to enforce a minimum key length, but not the key algorithm and not the maximum key length to be used. This may lead to issuance of certificates using weak keys, e.g. when submitting a request using a small RSA key to a certificate template that is configured to use an ECC key.
You can specify the following parameters for the private key:
The MinimumKeyLength directive specifies the minimum key length the certificate request must use. Defaults to “0” (any key size is allowed). Though the Windows Default policy module also verifies this, this may become handy in a migration scenario where you publish the same template both on the old and new certification authority and plan to increase key size when switching to the new one whilst keeping the productive system unchanged.
The MaximumKeyLength directive specifies the maximum key length the certificate request can use. Defaults to “0” (any key size is allowed).
The key algorithm is automatically determined based on the settings of the used certificate template and is enforced automatically.
Key size must exactly be 384 bits, assuming the certificate template uses an ECC key and specifies a minimum key size of 384 bits (thus minimum and maximum key size are equal).
MaximumKeyLength>384</MaximumKeyLength> <
Key size must exactly be 384 bits, assuming the certificate template uses an ECC key and specifies a lower key size.
MinimumKeyLength>384</MinimumKeyLength>
<MaximumKeyLength>384</MaximumKeyLength> <
Key size must be between 2048 and 4096 bits, assuming the certificate template uses an RSA key and specifies a lower key size.
MinimumKeyLength>2048</MinimumKeyLength>
<MaximumKeyLength>4096</MaximumKeyLength> <
Applies to online and offline certificate templates.
Certificate requests can contain information about which cryptographic provider (https://www.gradenegger.eu/en/basics-cryptographic-service-provider-csp-and-key-storage-provider-ksp/) was used to create the key pair. This information can be used to apply a policy which providers are permitted to get a certificate issued and which are not.
Please be aware that only certificate requests that have been made with the Microsoft API (e.g. Autoenrollment, MMC, certreq, PSCertificateEnrollment (https://www.powershellgallery.com/packages/PSCertificateEnrollment) and similar apps) will contain information about the provider that was used to create the certificate request.
Please be also aware that the provider information may potentially be manipulated by the enrollee during the request creation process. Therefore, this method is less secure than serious attestation methods for TPMs (https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/tpm-key-attestation) or Smartcards.
The AllowedCryptoProviders directive contains a list of one or more Cryptographic Service Provider (CSP) or Key Storage Provider (KSP) names that are permitted for the creation of the certificate requests private key. For example, you could configure a certificate template to use the machines Trusted Platform Module (TPM) by specifying the Microsoft Platform Crypto Provider and a fallback to the Microsoft Software Key Storage Provider, whereas the policy for TameMyCerts would only permit requests for the Microsoft Platform Crypto Provider to be issued. This way, you could identify machines where the TPM is in a nonfunctional state by evaluating denied certificate requests.
The DisallowedCryptoProviders directive contains a list of one or more Cryptographic Service Provider (CSP) or Key Storage Provider (KSP) names that are disallowed for the creation of the certificate requests private key.
Configured values are processed case-insensitive.
Key Storage Providers shipped with Windows include:
Cryptographic Service Provider shipped with Windows include:
Some providers are whitelisted and all others are forbidden:
AllowedCryptoProviders>
<string>Microsoft Platform Crypto Provider</string>
<string>Microsoft Software Key Storage Provider</string>
<AllowedCryptoProviders> </
Some providers are blacklisted and all others are allowed:
DisallowedCryptoProviders>
<string>Microsoft Platform Crypto Provider</string>
<DisallowedCryptoProviders> </
Applies to online and offline certificate templates.
Certificate requests can contain information about which process was used to create the key pair. This information can be used to apply a policy which processes are permitted to get a certificate issued and which are not (e.g. you want to allow only Autoenrollment but not manually requesting a certificate).
Please be aware that only certficate requests that have been made with the Microsoft API (e.g. Autoenrollment, MMC, certreq, PSCertificateEnrollment (https://www.powershellgallery.com/packages/PSCertificateEnrollment) and similar apps) will contain information about the process that was used to create the certificate request.
Please be also aware that the process information may be manipulated by the enrollee during the request creation process. This is therefore an enforcement on a best-effort basis.
Reading the process names from the certificate request requires parsing the inline certificate request from the certification authority database. There are rare cases where this might fail. Should this happen, the process name is treated as nonexistent, which will lead to the request being denied if a proces rule is configured for the certificate template.
The AllowedProcesses directive contains a list of one or more process names that are permitted to get a certificate issued. For example, if you would like to restrict certificate enrollment for a certificate template to Autoenrollment only, you would permit “taskhostw.exe”.
The DisallowedProcesses directive contains a list of one or more process names that are disallowed to get a certificate issued. For example, if you would like to deny certificate enrollment via certreq.exe, you could enter it here.
Though both directives can be used at the same time, it is recommended to only use either AllowedProcesses or DisallowedProcesses in a policy.
Commonly used process names could be:
Process name | Description |
---|---|
taskhostw.exe | Windows Autoenrollment |
mmc.exe | Manual certificate enrollment with the Microsoft Management Console (MMC) |
certreq.exe | Manual or scripted certificate enrollment with certreq.exe |
powershell.exe | Manual or scripted certificate enrollment with a PowerShell module like PSCertificateEnrollment (https://www.powershellgallery.com/packages/PSCertificateEnrollment) |
Configured values are processed case-insensitive.
Some processes are whitelisted and all others are forbidden:
AllowedProcesses>
<string>taskhostw.exe</string>
<string>powershell.exe</string>
<AllowedProcesses> </
Some processes are blacklisted and all others are allowed:
DisallowedProcesses>
<string>mmc.exe</string>
<string>powershell.exe</string>
<DisallowedProcesses> </
Applies only to offline certificate templates.
TameMyCerts allows to take control about which certificate content can be requested via an “offline” certificate template.
You can apply the following rules:
Ensure that a specific field is present in the Subject DN.
Ensure that a specific field is present only a specified number of times (usually once).
Ensure that a specific field contains a value, or that the value does not exceed a specific length.
Allow optional fields in the Subject DN (but not enforce them).
Ensure that a specific field conforms to one or more regular expression.
Ensure that a specific field conforms to one or more Classless Inter-Domain Routing (CIDR) mask ,if the field content is an Internet Protocol (IP) address.
Rules for Subject RDNs get specified within a “SubjectRule” node under “Subject” section.
Any Subject RDN that is not defined is considered forbidden and will result in any certificate request containing it getting denied.
A “SubjectRule” can/must contain the following nodes:
Parameter | Mandatory | Description |
---|---|---|
Field | yes | Specifies the type of the certificate field. See the below list for possible values. Please be aware that this parameter is interpreted case-sensitive. |
Mandatory | no | Specifies if this field must (true) or may (false) appear in the certificate request presented. Defaults to “false”. |
MaxOccurrences | no | Specifies how often this field may appear within a certificate request. Should always be 1 for must Subject RDN types. Defaults to 1. Note that more than one field of same type can only be used when the ReadSubjectFromRequest directive is set to true. |
MinLength | no | Specifies the minimum amount of characters the field must contain, to avoid empty RDNs being requested. Defaults to 1. Note that you also can define minimum lengths for parts or the entire field content via regular expressions in the Patterns directive. |
MaxLength | no | Specifies the maximum amount of characters the field may contain. Defaults to 128. Note that there is also an upper limit set by the certification authority (https://learn.microsoft.com/en-us/windows/win32/seccrypto/name-properties). Also note that you also can define maximum lengths for parts or the entire field content via regular expressions in the Patterns directive. |
Patterns | yes | For any field type you can define one or more “Pattern” directives describing expressions of which the requested field content must match at least one of to get either permitted or denied. The node is required, so if you would want to allow any content, simply configure a Pattern directive with “^.*$” as expression. For instructions on how to configure the Patterns directive, consult the Pattern section within the Technical Reference chapter of this document. |
To define a policy for one or more subject Relative Distinguished Name (RDN) types, adjust the “field” to one of the following (as defined in ITU-T X.520 (https://www.itu.int/itu-t/recommendations/rec.aspx?rec=X.520) and IETF RFC 4519 (https://datatracker.ietf.org/doc/html/rfc4519#section-2)).
Each RDN type can only be defined once in a policy definition file! Though you may specify that a certificate request contains more than one RDN of the same type, you would have to specify the criteria for all of them in the same rule. It is advised to allow each RDN type only once in a certificate request.
The following RDN types are enabled/allowed by default on AD CS and are therefore useable with TameMyCerts:
countryName
commonName
domainComponent
emailAddress
organizationName
organizationalUnitName
localityName
stateOrProvinceName
The following RDNs can additionally be defined in a policy configuration but must explicitly be enabled in the certification authority configuration by modifying its SubjectTemplate registry value (https://learn.microsoft.com/en-us/windows/win32/seccrypto/name-properties):
givenName
initials
surname
streetAddress
title
unstructuredName
unstructuredAddress
serialNumber
Please be aware that the SubjectTemplate registry value of the CA uses a different syntax for field type names than AD CS does.
Under certain circumstances, it is also possible to modify the Subject Distinguished Name (DN) using values from a mapped Active Directory object or from static values.
Incoming requests must contain exactly one commonName which must be a DNS-Name beneath the tamemycerts.com Domain. The whole content may not be longer than 64 characters in total.
Subject>
<SubjectRule>
<Field>commonName</Field>
<Mandatory>true</Mandatory>
<MaxLength>64</MaxLength>
<Patterns>
<Pattern>
<Expression>^[-_a-zA-Z0-9]*\.tamemycerts\.com$</Expression>
<Pattern>
</Patterns>
</SubjectRule>
</Subject> </
Incoming requests must contain exactly one commonName which must be a DNS-Name beneath the tamemycerts.com Domain. The whole content may not be longer than 64 characters in total. It may not contain the blacklisted words “porn” or “gambling”.
Subject>
<SubjectRule>
<Field>commonName</Field>
<Mandatory>true</Mandatory>
<MaxLength>64</MaxLength>
<Patterns>
<Pattern>
<Expression>^[-_a-zA-Z0-9]*\.tamemycerts\.com$</Expression>
<Pattern>
</Pattern>
<Expression>^.*(porn|gambling).*$</Expression>
<Action>Deny</Action>
<Pattern>
</Patterns>
</SubjectRule>
</Subject> </
Incoming requests must contain exactly one commonName which must be a DNS-Name beneath the tamemycerts.com Domain. It also may contain exactly one countryName but if so, it must be “DE” or “US”.
Subject>
<SubjectRule>
<Field>commonName</Field>
<Mandatory>true</Mandatory>
<MaxLength>64</MaxLength>
<Patterns>
<Pattern>
<Expression>^[-_a-zA-Z0-9]*\.tamemycerts\.com$</Expression>
<Pattern>
</Patterns>
</SubjectRule>
</SubjectRule>
<Field>countryName</Field>
<Mandatory>false</Mandatory>
<Patterns>
<Pattern>
<Expression>^(DE|US)$</Expression>
<Pattern>
</Patterns>
</SubjectRule>
</Subject> </
You should use this only if there is a definitve requirement to do so. Avoid using it in any other case.
Processing certificate requests with RDNs that are not part of the default set requires enabling the CRLF_REBUILD_MODIFIED_SUBJECT_ONLY flag (https://www.gradenegger.eu/en/use-of-undefined-relative-distinguished-names-rdn-in-issued-certificates/) on the certification authority, which should be used with extreme caution.
A common use case for this feature is supporting the requirements of eIDAS in form of adding an organization identifier (OI) to a certificate request and thus to an issued certificate.
This mode may have trouble with malformed certificate requests.
By default, TameMyCerts will use the data from the record provided by the certification authority (“how the certificate would get issued”) to analyze the Subject Distinguished Name. This allows for best compatibility and security, but has its drawbacks. The certification authority design assumes that there is only a specific set of field types and that there is only one per type.
If you have the need to inspect Subject Relative Distinguished Names that are not part of the default set, you can instruct TameMyCerts to parse the Subject Distinguished Name from the original certificate request (“how the certificate was originally requested”) by setting the ReadSubjectFromRequest directive.
ReadSubjectFromRequest>true<ReadSubjectFromRequest> <
Now, the following additional RDNs can be used in a subject rule:
postalCode
description
postOfficeBox
telephoneNumber
any other “unknown” (not part of the standard set or described above) RDN can be specified in a subject rule by using its object identifier (OID). The OID must be specified with an “OID.” prefix, e.g. “OID.1.2.3.4”.
Applies only to offline certificate templates.
Rules for the Subject Alternative Name (SAN) get specified within a “SubjectRule” node under “SubjectAlternativeName” section. The syntax and logic for the “SubjectRule” is the exact same as for Rules for the Subject Distinguished Name (Subject DN).
To define a policy for one or more subject alternative name (SAN) type, adjust the “field” to one of the following (as defined in IETF RFC 5280 (https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.6).
dNSName
iPAddress
rfc822Name
uniformResourceIdentifier
userPrincipalName
Other SAN types are currently not supported. However, the ones that are supported should be sufficient for the majority of use cases.
Under certain circumstances, it is also possible to supplement DNS Names and IP Addresses from the Subject Distinguished Name into the Subject Alternative Name extension.
Incoming requests may contain exactly one userPrincipalName, but if present, it must be beneath the tamemycerts.com Domain.
SubjectAlternativeName>
<SubjectRule>
<Field>userPrincipalName</Field>
<<!-- other directives have been left out for simplicity -->
Patterns>
<Pattern>
<Expression>^[-_a-zA-Z0-9\.]*\@tamemycerts\.com$</Expression>
<Pattern>
</Patterns>
</SubjectRule>
</SubjectAlternativeName> </
Applies only to offline certificate templates.
IETF RFC 2818 (https://www.rfc-editor.org/rfc/rfc2818) states that identities in certificates intended to be used with HTTP over TLS (aka HTTPS) shall get presented in form of one or more entries of type dNSName in the Subject Alternative Name. It is deprecated and discouraged to use the commonName field in the Subject Distinguished Name for this purpose. Google started to enforce the IETF RFC in 2019, so any browser that is based on Chromium (e.g. Chrome, Edge, Opera) will distrust HTTPS certificates that dont contain a Subject Alternative Name. Other recent browsers behave in a similar manner.
Sadly, some applications are still unable to generate appropriate certificate requests. The feature for supplementing DNS names allows to transfer all DNS names or IP addresses that are found in the commonName of a certificate request into a Subject Alternative Name certificate extension (either adding to an existing or creating a newly-constructed one). Therefore, non-compliant certificate requests are automatically made compliant.
Enabling this feature will also mean you will have to make the commonName mandatory in your policy under rules for the Subject Distinguished Name of a CSR.
You enable the feature by configuring SupplementDnsNames directive.
SupplementDnsNames>true</SupplementDnsNames> <
This configuration accepts certificate requests with a commonName and dNSName withing the tamemycerts.com DNS domain. WHilst the commonName field is mandatory, the dNSName field is optional. Should the request not contain a SAN in form of a dNSName, the value within the commonName will be used to create a SAN extension containing it in form of a dNSName.
Subject>
<SubjectRule>
<Field>commonName</Field>
<Mandatory>true</Mandatory>
<Patterns>
<Pattern>
<Expression>^[-_a-zA-Z0-9]*\.tamemycerts\.com$</Expression>
<Pattern>
</Patterns>
</SubjectRule>
</Subject>
</SubjectAlternativeName>
<SubjectRule>
<Field>userPrincipalName</Field>
<Mandatory>false</Mandatory>
<Patterns>
<Pattern>
<Expression>^[-_a-zA-Z0-9]*\.tamemycerts\.com$</Expression>
<Pattern>
</Patterns>
</SubjectRule>
</SubjectAlternativeName>
</SupplementDnsNames>true</SupplementDnsNames> <
Applies to online and offline certificate templates.
TameMyCerts allows to configure certificates issued for a specific certificate template to expire at an exactly configured point in time. This can be useful in scenarios where you want to ensure that e.g. certificates with weak keys get phased out until a specified point in time.
The behavior is as follows:
If the configured expiration date exceeds the regular certificate expiration date as configured in the certificate template (or certificate authority), no change is made to the issued certificate.
If the configured expiration date has not yet passed but is less than the regular expiration date as configured in the certificate template (or certifificate authority), the expiration date is set to the configured point in time.
If the configured expiration date has passed, certificate requests for the given certificate template get denied.
You configure the expiration date with the NotAfter directive in your policy configuration file.
The time gets specified as an ISO 8601 compliant string in the following syntax:
'yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffzzz'
See the original Microsoft documentation (https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings) for further explanation.
All certificates will expire on Dec 31, 2022 23:59:59 Europe/Berlin (UTC+1) time. After that date has passed, all certificate requests for this template get denied.
NotAfter>2022-12-31T23:59:59.0000000+01:00</NotAfter> <
Applies to online and offline certificate templates.
Directory Services mapping allows you to map an identity in a certificate request back to an Active Directory object. This way, a variety of policies can be applied, containing:
Verify that there is a user or computer object to which the certificate request belongs.
Verify that the object is not disabled.
Verify that the object is located in a specific Organizational Unit (OU).
Verify that the object is member of a specific security group, or that it is not member of a specific security group.
Enable features that depend on DS mapping like supplementing the Security Identifier (SID) certificate extension or Modifying the Subject DN or Subject Alternative Name with values from Active Directory.
When using DS mapping with an offline certificate template, Directory Services mapping setting get processed after Rules for the Subject Distinguished Name (Subject DN) and Rules for the Subject Alternative Name (SAN), so ensure you have these configured as well.
Rules for Directory Mapping get specified within the DirectoryServicesMapping node.
When using an online certificate template, the object category as well as certificate and directory services attributes are determined automatically.
When using an offline certificate template, the certificate attribute that was chosen for DS mapping is mandatory to occur in the certificate request and must occur only once. Ensure this via an appropriate Subject rules or Subject Alternative Name rules.
TameMyCerts is only able to map exactly one of the requested identities to an Active Directory object. Usually a certificate request contains multiple fields that can be used as identity (e.g. commonName and userPrincipalName). Which field of the issued certificate is used by to determine the certificate holders identity depends on the verifying application. You should therefore overwrite other identites by either modifying the Subject DN or the Subject Alternative Name with values from Active Directory (e.g. map userPrincipalName and overwrite commonName from the mapped Active Directory object to ensure strict rule enforcement.
Parameter | Mandatory | Description |
---|---|---|
CertificateAttribute | no | The field which is taken from the certificate request as the identity to map to a corresponding Active Directory object. May contain any identity that is listed above for either the Subject Distinguished Name, or for the Subject Alternative Name. Defaults to “userPrincipalName”. Automatically determined for online certificate templates. |
DirectoryServicesAttribute | no | The attribute of the Active Directory object that must match the certificate attribute. May be “cn”, “name”, “sAMAccountName”, “userPrincipalName” or “dNSHostName”. Defaults to “userPrincipalName”. Automatically determined for online certificate templates. |
ObjectCategory | no | The category of the Active Directory object to be searched for. May be “computer” or “user”. Defaults to “user” for offline certificate templates. Automatically determined for online certificate templates. |
SearchRoot | no | The distinguished name of the LDAP path the search for the Active Directory object shall start from. Defaults to using the global catalog for the entire forest. |
AllowedSecurityGroups | no | A list of distinguished names of security groups the account must be member of (request gets denied if it is not member of at least one of them). |
DisallowedSecurityGroups | no | A list of distinguished names of security groups the account must not be member of (request gets denied if it is member of at least one of them). |
AllowedOrganizationalUnits | no | A list of distinguished names of organizational units the account must be member of (request gets denied if it is not member of at least one of them). |
DisallowedOrganizationalUnits | no | A list of distinguished names of organizational units the account must not be member of (request gets denied if it is member of at least one of them). |
PermitDisabledAccounts | no | Permits certificates to get issued even if the Active Directory object is disabled. |
SupplementServicePrincipalNames | no | Set to true to supplement DNS names found in the ServicePrincipalName attribute of the mapped AD object. See Supplementing Service Principal Names for more details. |
DirectoryObjectRules | no | You can define one or more DirectoryObjectRule directives. See Configuring directory object rules for further reference. |
AddSidUniformResourceIdentifier | no | Adds the security identifier (SID) of the mapped AD object into the Subject Alternative Name (SAN) certificate extension of the issued certificate. The entry will be in form of a uniformResourceIdentifier (“tag:microsoft.com,2022-09-14:sid:<value>”). This “strong” mapping method was introduced by Microsoft in April 2023 (https://techcommunity.microsoft.com/t5/ask-the-directory-services-team/preview-of-san-uri-for-certificate-strong-mapping-for-kb5014754/bc-p/3794144#M965). |
The AllowedOrganizationalUnits and DisallowedOrganizationalUnits directives match also for nested organizational units. E.g. if you whitelist DC=intra,DC=tamemycerts,DC=com and the object resides in OU=Users,DC=intra,DC=tamemycerts,DC=com, this will match as well.
If you configure TameMyCerts to add the SID uniform resource identifier, you should ensure that the resulting certificate will contain a Subject Alternative Name of type dNSName (for mapped computer objects) or userPrincipalName (for mapped user objects) as this will be used to map the certificate to the AD object during authentication. You can either achieve this by having the field being put into the certificate request (and governing requested certificate content), or add the Subject Alternative Name from Active Directory via Directory Services mapping.
Please be aware of the following limitations:
The sAMAccountName Active Directory attribute is only unique per Domain, but not on Forest level. TameMyCerts denies a certificate request if more than one account with the same identifier is found. Avoid this by either using unique directory attributes, or by specifying the SearchRoot parameter accordingly.
The userPrincipalName attribute may not be populated by default for user accounts.
TameMyCerts uses the MemberOf (https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-ada2/cc24555b-61c7-49a2-9748-167b8ce5a512) Active Directory attribute (against the mapped accounts domain). Make sure you understand the following limitations when using:
It is currently not possible to use the primary group of a mapped Active Directory object (e.g. “Domain Users”, “Domain Guests”) for use with the AllowedSecurityGroups and DisallowedSecurityGroups directives.
The mapped Active Directory object must be an explicit (no nested groups) member of the configured security groups. If you want to restrict certificate issuance for highly privileged accounts, you could use the “Protected Users” (https://learn.microsoft.com/en-us/windows-server/security/credentials-protection-and-management/protected-users-security-group) built-in security group.
It is only possible to define groups that are in the same domain as the mapped account.
You must escape LDAP-reserved characters (e.g. “=”, “,”, “\”) with a backward slash (“\”), if present, for SearchRoot, AllowedSecurityGroups and DisallowedSecurityGroups.
The certification authority needs LDAP network access to all Domain Controllers that are involved in the DS mapping process. In addition, LDAP Global Catalog (GC) access is required as well when SearchRoot is not explicitly specified. Consult the official Microsoft documentation (https://learn.microsoft.com/en-us/troubleshoot/windows-server/identity/config-firewall-for-ad-domains-and-trusts) for further information.
Enabling the mapping with default values for user objects in an offline template:
DirectoryServicesMapping /> <
Enabling the mapping with default values for user and computer objects in an online template:
DirectoryServicesMapping /> <
Enabling the mapping with default values for computer objects in an offline template:
DirectoryServicesMapping>
<CertificateAttribute>dNSName</CertificateAttribute>
<DirectoryServicesAttribute>dNSHostName</DirectoryServicesAttribute>
<ObjectCategory>computer</ObjectCategory>
<DirectoryServicesMapping> </
Specifying an LDAP path as search root:
DirectoryServicesMapping>
<<!-- other directives have been left out for simplicity -->
SearchRoot>OU=TameMyCerts Users,DC=tamemycerts,DC=local</SearchRoot>
<DirectoryServicesMapping> </
Specifying an LDAP path as search root with escaping of LDAP-reserved characters:
DirectoryServicesMapping>
<<!-- other directives have been left out for simplicity -->
SearchRoot>OU=Users\,Computers\,and others,DC=tamemycerts,DC=local</SearchRoot>
<DirectoryServicesMapping> </
Permitting the issuance of certificates for disabled accounts:
DirectoryServicesMapping>
<<!-- other directives have been left out for simplicity -->
PermitDisabledAccounts>true</PermitDisabledAccounts>
<DirectoryServicesMapping> </
Filtering on security group memberships of a mapped object:
DirectoryServicesMapping>
<<!-- other directives have been left out for simplicity -->
AllowedSecurityGroups>
<string>CN=An allowed Group,DC=tamemycerts,DC=local</string>
<AllowedSecurityGroups>
</DisallowedSecurityGroups>
<string>CN=A forbidden Group,DC=tamemycerts,DC=local</string>
<DisallowedSecurityGroups>
</DirectoryServicesMapping> </
Adding the SID uniform resource identifier to the certificates SAN:
DirectoryServicesMapping>
<<!-- other directives have been left out for simplicity -->
AddSidUniformResourceIdentifier>true</AddSidUniformResourceIdentifier>
<DirectoryServicesMapping> </
For an example on how to add the SID certificate extension to an issued certificate, see section “Working with the SID certificate extension”.
Applies to online and offline certificate templates. Requires Directory Services Mapping to be enabled.
Directory services mapping can be configured to apply conditions that must match for attributes of a mapped directory object.
The configuration goes as follows:
Parameter | Mandatory | Description |
---|---|---|
DirectoryServicesAttribute | yes | The attribute of the mapped object that shall be evaluated. |
Mandatory | no | Specified if the attribute may be omitted if it is invalid or empty. If set to “true”, requests will get denied in such a case. |
Patterns | yes | You can define one or more “Pattern” directives describing expressions of which the sAMAccountName attribute of the mapped AD object must match at least one of to get either permitted or denied. |
For a list of supported Active Directory attributes, consult the DirectoryServicesAttribute section within the Technical Reference chapter of this document.
For instructions on how to configure the Patterns directive, consult the Pattern section within the Technical Reference chapter of this document.
DirectoryServicesMapping>
<<!-- other directives have been removed for this example -->
DirectoryObjectRules>
<DirectoryObjectRule>
<DirectoryServicesAttribute>description</DirectoryServicesAttribute>
<Mandatory>true</Mandatory>
<Patterns>
<Pattern>
<Expression>^Admin$</Expression>
<TreatAs>RegEx</TreatAs>
<Action>Deny</Action>
<Pattern>
</Patterns>
</DirectoryObjectRule>
</DirectoryObjectRules>
</DirectoryServicesMapping> </
Applies only to offline certificate templates. Certificates from online certificate templates automatically get a SID certificate extension from the Windows Default policy module.
The SID certificate extension gets processed after Rules for the Subject Distinguished Name (Subject DN) and Rules for the Subject Alternative Name (SAN), so ensure you have these configured as well. If you plan to add the SID extension from an Active Directory object to an issued certificate, you must also configure Directory Services mapping.
Microsoft introduced another mapping method in form of a uniformResourceIndicator in April 2023 (https://techcommunity.microsoft.com/t5/ask-the-directory-services-team/preview-of-san-uri-for-certificate-strong-mapping-for-kb5014754/bc-p/3794144#M965), which is also supported by TameMyCerts and can be configured within Directory Services mapping.
The security identifier certificate extension was introduced by Microsoft with the May 2022 cumulative update for Windows Server (KB5014754) (https://support.microsoft.com/en-us/topic/kb5014754-certificate-based-authentication-changes-on-windows-domain-controllers-ad2c23b0-15d8-4340-a468-4d4f3b188f16). The patch causes Active Directory to require this certificate extension to process certificate-bases logons. There is a compatibility mode, which Microsoft plans to automatically disable on February 11, 2025.
As Microsoft only ensured that the extension will be present in certificates originating from online certificate templates, this probably will cause trouble when certificates originating from offline certificate templates (e.g. mobile devices managed by Intune, AirWatch/Workspace One, MobileIron and the like) are used for certificate-bases logons against Active Directory. A popular example is Wifi or VPN logons that use the Microsoft Network Policy Server.
TameMyCerts is able to process the new certificate extension in a variety of ways:
Deny requests containg the extension.
Pass the extension as-is into the issued certificate.
Add the extension from the properties of a mapped Active Directory object.
Remove the extension if it is part of the originating certificate request.
If TameMyCerts shall process the SID certificate extension, you configure it with the SecurityIdentifierExtension directive within a policy configuration file.
You can configure four modes:
Action | Description |
---|---|
Deny (default) | All certificate requests that contain a security identifier certificate extension will get denied if this is set. |
Allow | If a certificate request contains a security identifier extension, it will get passed as-is into the issued certificate. |
Add | Adds the value of the objectSid (https://learn.microsoft.com/en-us/windows/win32/adschema/a-objectsid) attribute of the Active Directory object belonging to the certificate request to the issued certificate. Can therefore only be used in combination with Directory Services mapping. |
Remove | If a certificate request contains a security identifier extension, it will not get passed into the issued certificate. |
If you configure TameMyCerts to add the SID certificate extension, you should ensure that the resulting certificate will contain a Subject Alternative Name of type dNSName (for mapped computer objects) or userPrincipalName (for mapped user objects) as this will be used to map the certificate to the AD object during authentication. You can either achieve this by having the field being put into the certificate request (and governing requested certificate content), or add the Subject Alternative Name from Active Directory via Directory Services mapping.
All certificate requests that contain a security identifier certificate extension will get denied.
SecurityIdentifierExtension>Deny</SecurityIdentifierExtension> <
All certificate requests that contain a security identifier certificate extension will get allowed and the resulting certificate will contain the requested SID extension.
SecurityIdentifierExtension>Allow</SecurityIdentifierExtension> <
All certificate requests that contain a security identifier certificate extension will get allowed and the resulting certificate will not contain the requested SID extension
SecurityIdentifierExtension>Remove</SecurityIdentifierExtension> <
All certificate requests get the SID extension built from a mapped Active directory object (requires Directory Services mapping to be configured).
SecurityIdentifierExtension>Add</SecurityIdentifierExtension> <
Applies to online and offline certificate templates.
TamyMyCerts allows modifying the Subject Distinguished Name (DN) of a certificate before it gets issued. It is capable of retrieving properties from a mapped Active Directory object and put these values into the Subject DN of a certificate. The resulting value can be either an attribute of a mapped Active Directory object, a field of the originating certificate request, a static value, or a combination of all.
This is useful in the following scenarios:
You define a OutboundSubject directive containing OutboundSubjectRule rules.
The OutboundSubjectRule directive can be configured as follows:
Parameter | Mandatory | Description |
---|---|---|
Field | yes | The Relative Distinguished Name that shall be populated. |
Value | yes | The value that shall be put into the configured certificate field. Can contain variables. |
Mandatory | no | Specified if the configured value may be omitted if one of the variables is invalid or empty. If set to “true”, requests will get denied in such a case. Defaults to false. |
Force | no | Specifies how to act when the originating certificate request already contains a field of the specified type. If set to true and a field of same type is present, it gets overwritten with the configured value. If set to false, no action is made. Defaults to false. |
You may specify the following Relative Distinguished Names (RDN) for the “Field” directive:
RDN | Maximum length | Typical AD attributes | Remarks |
---|---|---|---|
emailAddress | 128 | ||
commonName | 64 | name, sAMAccountName, displayName, userPrincipalName | |
organizationName | 64 | company | |
organizationalUnitName | 64 | department | |
localityName | 128 | l | |
stateOrProvinceName | 128 | st | |
countryName | 2 | c | |
title | 64 | title | not enabled by default |
givenName | 16 | givenName | not enabled by default |
initials | 5 | initials | not enabled by default |
surname | 40 | sn | not enabled by default |
streetAddress | 30 | streetAddress | not enabled by default |
unstructuredName | 1024 | n/a | |
unstructuredAddress | 1024 | n/a | |
serialNumber | 1024 | n/a |
The field names are processed case-sensitive.
The Value may contain a static string, or can be combined with attributes of mapped Active Directory objects, or content from the certificate request.
You configure variables with the following syntax:
{Modifier:PropertyNameGoesHere}
The following modifiers are currently supported:
Modifier | Description |
---|---|
ad | Attributes of mapped Active Directory objects. For a list of supported Active Directory attributes, consult the DirectoryServicesAttribute section within the Technical Reference chapter of this document. |
sdn | Fields from the Subject Distinguished Name of the certificate request. |
san | Fields from the Subject Alternative Name of the certificate request. |
Note that if you plan to insert attributes from mapped Active Directory objects, you need to configure DirectoryServicesMapping.
Configuring an invalid Field will lead to certificate requests getting denied.
Configuring a Value that violates length constraints for the selected Field will lead to certificate requests getting denied.
Issued certificates will have a commonName field which will contain the content of the userPrincipalName AD attribute of the mapped AD object. Furthermore, the emailAddress field will be populated with the content of the mail AD attribute. Should the userPrincipalName AD attribute not be populated in AD, the request will get denied. Should the mail AD attribute not be populated in AD, the certificate will get issued but not include an emailAddress field.
DirectoryServicesMapping />
<OutboundSubject>
<OutboundSubjectRule>
<Field>commonName</Field>
<Value>{ad:userPrincipalName}</Value>
<Mandatory>true</Mandatory>
<Force>true</Force>
<OutboundSubjectRule>
</OutboundSubjectRule>
<Field>emailAddress</Field>
<Value>{ad:mail}</Value>
<OutboundSubjectRule>
</OutboundSubject> </
The commonName will be built out of the two AD attributes sn (surname) and givenName. Assuming the given name is “John” and the surname is “Doe”, the commonName in the issued certificate will be “Doe, John”.
DirectoryServicesMapping />
<OutboundSubject>
<OutboundSubjectRule>
<Field>commonName</Field>
<Value>{ad:sn}, {ad:givenName}</Value>
<Mandatory>true</Mandatory>
<Force>true</Force>
<OutboundSubjectRule>
</OutboundSubject> </
The commonName will be built out of the AD attribute name and a static string. Assuming the name is “John Doe”, the commonName in the issued certificate will be “John Doe is an awesome fellow!”.
DirectoryServicesMapping />
<OutboundSubject>
<OutboundSubjectRule>
<Field>commonName</Field>
<Value>{ad:name} is an awesome fellow!</Value>
<Mandatory>true</Mandatory>
<Force>true</Force>
<OutboundSubjectRule>
</OutboundSubject> </
The commonName will be built out of the displayName AD attribute. The organizationName will be “TameMyCerts”, regardless if the originating certificate request did contain this field.
OutboundSubject>
<OutboundSubjectRule>
<Field>commonName</Field>
<Value>{ad:displayName}</Value>
<Mandatory>true</Mandatory>
<Force>true</Force>
<OutboundSubjectRule>
</OutboundSubjectRule>
<Field>organizationName</Field>
<Value>TameMyCerts</Value>
<Force>true</Force>
<OutboundSubjectRule>
</OutboundSubject> </
Transfering the first dNSName of the Subject Alternative Name into the commonName field of the issued certificate.
<!-- does not require DirectoryServicesMapping -->
OutboundSubject>
<OutboundSubjectRule>
<Field>commonName</Field>
<Value>{san:dNSName}</Value>
<Mandatory>true</Mandatory>
<Force>true</Force>
<OutboundSubjectRule>
</OutboundSubject> </
Applies to online and offline certificate templates.
TamyMyCerts allows modifying the Subject Alternative Name (SAN) of a certificate before it gets issued. It is capable of retrieving properties from a mapped Active Directory object and put these values into the SAN of a certificate. The resulting value can be either an attribute of a mapped AD object, a field of the originating certificate request, a static value, or a combination of all.
You define a OutboundSubjectAlternativeName directive containing OutboundSubjectRule rules. The syntax and logic for the “SubjectRule” is the exact same as for Modifying the Subject Distinguished Name of issued certificates.
The OutboundSubjectRule directive can be configured as follows:
Parameter | Mandatory | Description |
---|---|---|
Field | yes | The Relative Distinguished Name that shall be populated. |
Value | yes | The value that shall be put into the configured certificate field. Can contain variables. |
Mandatory | no | Specified if the configured value may be omitted if one of the variables is invalid or empty. If set to “true”, requests will get denied in such a case. Defaults to false. |
Force | no | Specifies how to act when the originating certificate request already contains a field of the specified type. If set to true and a field of same type is present, an additional entry with the configured value gets added to the SAN. If set to false, no action is made. Defaults to false. |
You may specify the following Subject Alternative Name types for the “Field” directive:
dnsName
rfc822Name
uniformResourceIdentifier
userPrincipalName
ipAddress
The field names are processed case-sensitive.
The SAN gets supplemented with a dNSName containing the name attribute of a computer object (so that the unqualified DNS name is part of the SAN) .
DirectoryServicesMapping />
<OutboundSubjectAlternativeName>
<OutboundSubjectRule>
<Field>dNSName</Field>
<Value>{ad:name}</Value>
<Mandatory>true</Mandatory>
<OutboundSubjectRule>
</OutboundSubjectAlternativeName> </
The commonName (given that it is a DNS name) from the Subject DN is transferred to the Subject Alternative Name (SAN) in form of a dNSName.
<!-- does not require DirectoryServicesMapping -->
OutboundSubjectAlternativeName>
<OutboundSubjectRule>
<Field>dNSName</Field>
<Value>{sdn:commonName}</Value>
<Mandatory>true</Mandatory>
<OutboundSubjectRule>
</OutboundSubjectAlternativeName> </
Applies to online and offline certificate templates. Requires Directory Services Mapping to be enabled.
TameMyCerts can add DNS names found in the Service Principal Names (https://learn.microsoft.com/en-us/windows/win32/ad/service-principal-names) (SPNs) of mapped AD objects to the Subject Alternative Name (SAN) extension of issued certificates.
This allows to automatically add aliases and custom names required for Kerberos authentication to issued certificates.
This feature might be dangerous in cases there are no strict controls about how SPNs are registered for your AD accounts. Please use the feature carefully!
As the Service Principal Names (SPNs) usually also contain the non-qualified hostname of a machine, this identity gets added to the SAN as well.
You enable the feature by configuring SupplementServicePrincipalNames directive.
DirectoryServicesMapping>
<<!-- other directives have been left out for simplicity -->
SupplementServicePrincipalNames>true</SupplementServicePrincipalNames>
<DirectoryServicesMapping> </
Applies to online and offline certificate templates.
The directives are:
CrlDistributionPoints
AuthorityInformationAccess
OnlineCertificateStatusProtocol
Each of those can contain one or more uniform resource identifiers (URIs). TameMyCerts supports the same token variables as the original Microsoft product (https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc737264(v=ws.10)), namely:
Microsoft Token name | Description | Variable |
---|---|---|
ServerDNSName | The DNS name of the CA server | %1 |
ServerShortName | The NetBIOS name of the CA server | %2 |
CaName | The name of the CA | %3 |
Cert_Suffix | The renewal extension of the CA | %4 |
CertificateName | Not applicable. | %4 |
ConfigurationContainer | The location of the configuration container in Active Directory | %6 |
CATruncatedName | The “sanitized” name of the CA, 32 characters with a hash on the end | %7 |
CRLNameSuffix | The renewal extension for the CRL | %8 |
CDPObjectClass | %10 | |
CAObjectClass | %11 |
Online Certificate Status Protocol (OCSP) URIs should only be configured in combination with Authority Information Access (AIA) URIs as they get written into the same certificate extension.
Issuing CRL Distribution Point (CDP) URIs on a per-template basis:
CrlDistributionPoints>
<string>http://%1/CertData/%3%8%9.crl</string>
<string>ldap:///CN=%7%8,CN=%3,CN=cdp,CN=Public Key Services,CN=Services,%6%10</string>
<CrlDistributionPoints> </
Issuing Authority Information Access (AIA) URIs on a per-template basis:
AuthorityInformationAccess>
<string>http://%1/CertData/%3%4.crt</string>
<string>ldap:///CN=%7,CN=AIA,CN=Public Key Services,CN=Services,%6%11</string>
<AuthorityInformationAccess> </
Issuing Online Certificate Status Protocol (OCSP) URIs on a per-template basis:
OnlineCertificateStatusProtocol>
<string>http://ocsp.tamemycerts.com/ocsp</string>
<OnlineCertificateStatusProtocol> </
Applies to online and offline certificate templates. Does not support Audit only mode. This feature is independent from certificate templates. It can only be enabled used globally on a certification authority level.
The Windows Default policy module allows to specify the exact expiration date (https://learn.microsoft.com/en-us/troubleshoot/windows-server/identity/change-certificates-expiration-date) (NotAfter) for a certificate by specifying an “ExpirationDate” attribute whilst submitting the certificate request. TameMyCerts adds support for a “StartDate” attribute which does the exact same for the begin of the certificates validity period (the “NotBefore” certificate property).
To enable the feature, you must enable the EDITF_ATTRIBUTEENDDATE flag for the policy module of the certification authority and restart the certification authority service afterwards.
certutil -setreg Policy\Editflags +EDITF_ATTRIBUTEENDDATE
net stop certsvc
net start certsvc
Now you can specify both StartDate and ExpirationDate request attribute in IETF RFC 2616 (https://datatracker.ietf.org/doc/html/rfc2616) compliant form whilst submitting the certificate request.
A syntax example for a compliant date form could be:
Tue, 1 Mar 2022 08:00:00 GMT
When an invalid date is being requested, the certificate request will get denied with error code ERROR_INVALID_TIME.
TameMyCerts currently only supports specifying “StartDate” whilst submitting the certificate request but not as custom attributes within the certificate request itself. The alternative method of specifying “ValidityPeriod” and “ValidityPeriodUnits” for the expiration date can currently not be used in combination with the “StartDate” attribute as it gets applied afterwards and thus won’t deliver the expected result.
Requesting a certificate that shall be valid from Mar 1, 2022 08:00 until Mar 1, 2022 16:00:
certreq ^
-config "caserver.tamemycerts.local\TameMyCerts CA" ^
-attrib "CertificateTemplate:TameMyCertsWebServer\nStartDate:Tue, 1 Mar 2022 08:00:00 GMT\nExpirationDate:Tue, 1 Mar 2022 16:00:00 GMT" ^
-submit "MyCertificateRequest.req"
Applies to online and offline certificate templates.
For any certificate template that has a policy configuration defined, TameMyCerts will ensure that the resulting certificate will contain an identity, either in the Subject Distinguished Name or the Subject Alternative Name. If the resulting certificate would not contain an identity, the certificate request will get denied and an event will be logged.
Should you have the requirement to issue such certificates regardless of not containing an identity, you may change the behavior with the PermitEmptyIdentites directive:
PermitEmptyIdentites>true</PermitEmptyIdentites> <
Applies to online and offline certificate templates.
TameMyCerts will automatically deny certificate requests when they contain a “san” request attribute and the certification authority has the insecure EDITF_ATTRIBUTESUBJECTALTNAME2 (https://www.gradenegger.eu/en/take-over-the-active-directory-overall-structure-with-the-flag-editf_attributesubjectaltname2/) flag set. This combination can allow an attacker to request certificates with arbitrary identities, resulting in a complete takeover of your Active Directory. Therefore, this behavior can neither be configured nor disabled.
Instead of using the “san” request attribute in combination with EDITF_ATTRIBUTESUBJECTALTNAME2, you should ensure that certificate request already contain a Subject Alternative Name (SAN) extension. In case where this is not possible, the Supplementing DNS Names and IP Addresses feature can be used.
Please be aware that if no policy file exists for a given certificate template, the request gets accepted as this would be the original behavior of the Windows Default policy module.
If a certificate request violates the defined policy, the certification authority will deny it with one of the below error codes and messages. The CA will log Event with ID 53 (https://www.gradenegger.eu/en/details-of-the-event-with-id-53-of-the-source-microsoft-windows-certificationauthority/). The error code/message will also be handed over to the requesting client over the DCOM protocol as answer to the certificate request.
TameMyCerts will also write its own Logs which contain detailled information about why a certificate request was denied, amongst others.
The following error codes can be thrown by the policy module back to the requestor when a request was denied:
Message | Symbol | Description |
---|---|---|
The permissions on the certificate template do not allow the current user to enroll for this type of certificate. | CERTSRV_E_TEMPLATE_DENIED | Occurs if the process used to create the certificate request is unknown, not allowed or explicitly disallowed. Also occurs when Directory Services mapping encounters an error. |
The certificate has an invalid name. The name is not included in the permitted list or is explicitly excluded. | CERT_E_INVALID_NAME | Occurs if the requests Subject Distinghuished Name or Subject Slternative Name violates the defined rules. |
The public key does not meet the minimum size required by the specified certificate template. | CERTSRV_E_KEY_LENGTH | Occurs if the requests public key violates the defined rules for key algorithm or maximum key length. |
An internal error occurred. | ERROR_INVALID_DATA | Occurs if the policy module is unable to interpret the given policy file. |
The specified time is invalid. | ERROR_INVALID_TIME | Occurs if an invalid date was requested for the “StartDate” certificate request attribute. |
TameMyCerts features the following caches:
Certificate template configuration is read by TameMyCerts from the CA servers registry every 5 minutes to reduce CPU load.
Note that updates made to a certificate template in Active Directory are not instantly replicated to the CA servers registry, as this part of the registry is only updated every 8 hours.
Certificate Request policy files are loaded on first use and are then served from memory as long as they do not change. This reduces CPU and storage load. When the file gets modified and therefore the modification date of the file gets updated, it will get re-loaded on next use.
Should you, for example, copy a previous version of a policy configuration file back to the configured directory, it will not get read because it would have an older modification date. You would have to save it again so that it has a newer timestamp. Alternatively, you could re-start ehe certification authority service, as this will invalidate the cache.
TameMyCerts currently does only support the following Subject Alternative Name types:
dnsName
rfc822Name
uniformResourceIdentifier
userPrincipalName
ipAddress
If a certificate request contains an unsupported SAN type, the behavior is as follows:
If the certificate template is an online template, this limitation doesn’t matter.
If the certificate template is an offline template,
If no policy configuration file exists, the SAN extension gets issued as requested.
If you don’t modify the SAN of a requested certificate through a policy configuration, the SAN extension gets issued as requested.
If you modify the SAN of a requested certificate through a policy configuration, all unsupported SAN types get stripped from the issued certificates SAN extension.
When an error parsing the policy configuration file is thrown, remember that the actual line may be above or below the one noted in the log entry.
This is expected as there is a chaching involved. The cache is read from the local certificate template cache of the CA server and updated every five minutes. Therefore, you can do one of the following to solve this:
Wait until the local certificate template gets updated automatically. This can take up to eight hours.
Update the local certificate template cache on your own. To do this, run the following command as an administrator:
certutil -pulse
You’ll then still have to wait up to 5 minutes or restart the CA service afterwards for the certificate template to get recognized.
Certificate requests that contain relative distinguished with empty values (e.g. CN=““) are treated as if the RDN was missing when a subject rule is applied. This is because TameMyCerts doesn’t inspect the actual certificate request but how the certification authority would issue the certificate. Microsoft AD CS does remove relative distinguished names containing empty values.
As TameMyCerts follows the original Microsoft concept of certificate templates, it does not support standalone certification authorities (as these do not use certificate templates).
At the moment, TameMyCerts can not be combined with other policy modules except the Windows Default policy module that is shipped with Active Directory Certificate Services. A common example for an incompatible module would be the policy modules shipped with Microsoft Identity Manager Certificate Management (MIM CM).
In addition to the certification authorities regular log entries, the policy module will also write a detailed log entry if a certificate request was denied due to a policy violation or failure. Find the logs under the Application event log with the TameMyCerts Event Source.
ID | Type | Description |
---|---|---|
1 | Information | Occurs if the Windows Default policy was successfully loaded and TameMyCerts is ready to process incoming requests. |
2 | Error | Occurs if the Windows Default policy was not successfully loaded during CA service startup. Will cause the CA service to not start. |
4 | Error | Occurs if the Windows Default policy was not successfully unloaded during CA service shutdown. |
5 | Warning | Occurs if Audit only mode is enabled for a certificate template and a certificate request would get denied because of a policy violation. Contains a detailed information which kind of policy violation caused the request to get denied. |
6 | Warning | Occurs if a certificate request was denied because of a policy violation. Contains a detailed information which kind of policy violation caused the request to get denied. |
7 | Warning | Occurs if there is no policy configuration file defined for the certificate template used certificate request. The certificate request gets allowed in this case. |
9 | Error | Occurs it the TameMyCerts policy module is loaded on a standalone certification authority, which is unsupported at the moment. Will cause the CA service to not start. |
10 | Error | Occurs if a certificate request was denied because because the policy file for the certificate template could not be interpreted. |
11 | Information | Occurs if the Windows Default policy module denied a certificate request, thus the additional logic of TameMyCerts was not triggered at all for the given request. |
Events 1 and 11 occur only if the certification authoritys LogLevel setting (https://www.gradenegger.eu/en/configure-log-level-log-level-for-the-certification-authority-event-log/) is configured to 4 (CERTLOG_VERBOSE) or higher.
The Pattern parameter is defined as follows:
Parameter | Mandatory | Description |
---|---|---|
Expression | yes | Specifies the expression the field gets matched against. |
TreatAs | no | Specifies how the expression is to be interpreted by TameMyCerts. Defaults to RegEx. |
Action | no | Specifies if a match for the pattern will “Allow” the certificate to get issued (the default) or “Deny” the certificate request. |
The TreatAs directive can be configured to one of the following values:
Value | Description |
---|---|
RegEx | Treat the value to be analyzed as a case sensitive regular expression (the default). |
RegExIgnoreCase | Treat the value to be analyzed as a case insensitive regular expression. |
Cidr | Treat the value to be analyzed as an IP address that must be within an IPv4 or IPv6 subnet in CIDR notation, e.g. 192.168.0.0/16. |
ExactMatch | The value to be analyzed must exactly match the configured expression (case sensitive). |
ExactMatchIgnoreCase | The value to be analyzed must exactly match the configured expression (case insensitive). |
The following Active Directory attributes are supported as “DirectoryServicesAttribute”:
Attribute | In Global Catalog | Remarks |
---|---|---|
c | yes | |
co | no | |
company | no | |
department | no | |
departmentNumber | no | |
description | yes | |
displayName | yes | |
division | no | |
dNSHostName | yes | Computer objects only |
employeeID | no | |
employeeNumber | no | |
employeeType | no | |
extensionAttribute1 | no | only available when Microsoft Exchange is used in the environment |
extensionAttribute2 | no | only available when Microsoft Exchange is used in the environment |
extensionAttribute3 | no | only available when Microsoft Exchange is used in the environment |
extensionAttribute4 | no | only available when Microsoft Exchange is used in the environment |
extensionAttribute5 | no | only available when Microsoft Exchange is used in the environment |
extensionAttribute6 | no | only available when Microsoft Exchange is used in the environment |
extensionAttribute7 | no | only available when Microsoft Exchange is used in the environment |
extensionAttribute8 | no | only available when Microsoft Exchange is used in the environment |
extensionAttribute9 | no | only available when Microsoft Exchange is used in the environment |
extensionAttribute12 | no | only available when Microsoft Exchange is used in the environment |
extensionAttribute10 | no | only available when Microsoft Exchange is used in the environment |
extensionAttribute12 | no | only available when Microsoft Exchange is used in the environment |
extensionAttribute11 | no | only available when Microsoft Exchange is used in the environment |
extensionAttribute12 | no | only available when Microsoft Exchange is used in the environment |
extensionAttribute13 | no | only available when Microsoft Exchange is used in the environment |
extensionAttribute14 | no | only available when Microsoft Exchange is used in the environment |
extensionAttribute15 | no | only available when Microsoft Exchange is used in the environment |
facsimileTelephoneNumber | no | |
gecos | no | |
givenName | yes | |
homePhone | yes | |
homePostalAddress | no | |
info | no | |
initials | no | |
l | yes | |
location | yes | Computer objects only |
yes | ||
mailNickname | no | |
middleName | no | |
mobile | no | |
name | yes | |
otherMailbox | no | |
otherMobile | no | |
otherPager | no | |
otherTelephone | no | |
pager | no | |
personalPager | no | |
personalTitle | no | |
postalAddress | no | |
postalCode | no | |
postOfficeBox | no | |
sAMAccountName | yes | |
sn | yes | |
st | yes | |
street | yes | |
streetAddress | no | |
telephoneNumber | no | |
title | no | |
userPrincipalName | yes |
If you are upgrading from a TameMyCerts version older than 1.6, you must adjust some elements in your policy configuration files.
TameMyCerts version 1.5 and lower used the following syntax:
DirectoryServicesMapping>
<<!-- other directives have been left out for simplicity -->
SubjectDistinguishedName>
<RelativeDistinguishedName>
<Field>emailAddress</Field>
<DirectoryServicesAttribute>mail</DirectoryServicesAttribute>
<Mandatory>true</Mandatory>
<RelativeDistinguishedName>
</SubjectDistinguishedName>
</DirectoryServicesMapping> </
TameMyCerts version 1.6 and newer now uses the following syntax:
DirectoryServicesMapping>
<<!-- other directives have been left out for simplicity -->
DirectoryServicesMapping>
</OutboundSubject>
<OutboundSubjectRule>
<Field>emailAddress</Field>
<Value>{ad:mail}</Value>
<Mandatory>true</Mandatory>
<Force>true</Force>
<OutboundSubjectRule>
</OutboundSubject> </
If you are upgrading from a TameMyCerts version older than 1.2, you must adjust some elements in your policy configuration files.
TameMyCerts version 1.1 and lower used the following syntax:
SubjectRule>
<Field>organizationalUnit</Field>
<<!-- other directives have been left out for simplicity -->
SubjectRule> </
TameMyCerts version 1.2 now uses the following syntax:
SubjectRule>
<Field>organizationalUnitName</Field>
<<!-- other directives have been left out for simplicity -->
SubjectRule> </
If you are upgrading from a TameMyCerts version older than 1.1, you must adjust some elements in your policy configuration files.
TameMyCerts version 1.0 used the following syntax:
SubjectRule>
<Field>commonName</Field>
<AllowedPatterns>
<string>^[-_a-zA-Z0-9]*\.tamemycerts\.com$</string>
<AllowedPatterns>
</DisallowedPatterns>
<string>^.*(porn|gambling).*$</string>
<DisallowedPatterns>
</SubjectRule> </
TameMyCerts version 1.1 now uses the following syntax:
SubjectRule>
<Field>commonName</Field>
<Patterns>
<Pattern>
<Expression>^[-_a-zA-Z0-9]*\.tamemycerts\.com$</Expression>
<Pattern>
</Pattern>
<Expression>^.*(porn|gambling).*$</Expression>
<Action>Deny</Action>
<Pattern>
</Patterns>
</SubjectRule> </
Enterprise use Mobile Device Management (MDM) products to provision and manage their mobile devices like smartphones, tablet computers or even entire desktop computers, over-the-air (OTA).
Common MDM products include:
All these systems follow a similar concept: They act as an intermediary between the managed device, the coprorate directory service, and the certification authority. All of them provide some kind connector to submit certificate requests to a Microsoft AD CS certification authority.
Microsoft Intune uses the Network Device Enrollment Service (NDES) (https://learn.microsoft.com/en-us/windows-server/identity/ad-cs/network-device-enrollment-service-overview) role as a connector between Intune and the certification authority. NDES, like the certificaton authority, allows for custom-developed policy modules. Microsoft provides a policy module for NDES in combination with Intune, therefore it is not possible to add another policy module to an Intune-enabled NDES instance. However, TameMyCerts, as it resides on the CA, can coexist perfectly well with an Intune-enabled NDES instance, including the Intune policy module there.
All MDM systems require the certificate template to be configured as an offline certificate template. This means that the certification authority must accept any identity contained in a certificate request. Furthermore, all certificate requests are submitted to the certification authority using a single service account. If this account is compromised or otherwise abused, if the MDM system is misconfigured or has a software flaw, the certification authority will issue virtually any possible identity, including those of the CEO or highly privileged system accounts and administrators, which can lead to a variety of security disasters.
TameMyCerts can restrict the requested certificate content to precisely-defined certificate fields as well as apply syntax rules to these. In addition, TameMyCerts is able to map requested identities back to their underlying Active Directory objects and can decide whether a certificate shall be issued based on enablement status, group memberships and other criteria.
Many enterprises nowadays want to establish paperless processes to ease and speed up internal approval and signature processes. This has become even more important in the times of employees predominantly working remotely. Whilst Microsoft AD CS is capable of automating certificate issuance processes, its possibilities to influence the certificate content are limited.
TameMyCerts allows to define advanced rules to build the Subject Distinguished names or Subject Alternative Names with either statically defined values, or by pulling the necessary data from Active Directory. This drastically extends the possibilities of certificate Autoenrollment in the Windows ecosystem.
For example, you could populate a certificates Common Name with the displayName Active Directory attribute and set a static value for the organizationName field as well.
Beginning with Version 58, Google decided to remove the support for certificates containing only a Subject DN (https://developer.chrome.com/blog/chrome-58-deprecations/#remove-support-for-commonname-matching-in-certificates). From thereon, certificates not containing a Subject Alternate Name in form of a DNS name were treated as invalid by Google Chrome. Soon, other major browser vendors adopted this approach.
This behavior is in compliance to the IETF RFC 2818 (https://tools.ietf.org/html/rfc2818) dating back to the year 2000. Certificates for web servers must therefore use the Subject Alternative Name (SAN) for their identity. Sadly, there are still a lot of products in use that are not capable of creating a Certificate Signing Request containing a SAN in form of a DNS name.
Sadly, many HowTos on the web instruct CA administrators to enable the EDITF_ATTRIBUTESUBJECTALTNAME2 flag on their CAs in the belief this would enable them the issuance of SANs for certificate requests not containine one. However, doing so opens a large security hole, as this setting allows anyone to request any identity for any certificate template published on the certification authority.
Luckily, there are better ways to reach the intended goal.
With TameMyCerts, there is a secure, yet automatic method available to fix those certificates without the need of enabling insecure flags on the CA. TameMyCerts can be instructed to transfer the content of the Subject DN into a SAN extension prior to issuing the certificate. Furthermore, TameMyCerts ensures that attempts to abuse the certification authority are detected and such requests wil get denied, should an insecure flag still be enabled.
Many HowTos on the web instruct CA administrators to enable the EDITF_ATTRIBUTESUBJECTALTNAME2 flag on their CAs. However, this opens a large security hole, as this setting allows anyone to request any identity for any certificate template. These kinds of attack against Microsoft Active Directory Certificate Services have widely become known as “ESC6” (https://posts.specterops.io/certified-pre-owned-d95910965cd2) in the security scene.
When the EDITF_ATTRIBUTESUBJECTALTNAME2 flag is enabled in the certification authoritys configuration - either by lack of knowledge or by accident - an attacker can send a “SAN” request attribute to the CA (https://www.gradenegger.eu/en/take-over-the-active-directory-overall-structure-with-the-flag-editf_attributesubjectaltname2/), instructing it to add the specified content to the Subject Alternative Name (SAN) extension of the issued certificate, regardless of a certificate templates settings.
TameMyCerts ensures that such attempts to abuse the certification authority are detected and requests wil get denied, should an insecure flag still be enabled. The denied certificate request is getting logged, so that an alert could be triggered.
Administrators sometimes enable the setting to be able to add SANs to certificate requests not containing them (e.g. because the host on which the original certificate request was made is not capable of requesting SANs). In the most common use case of Web Server certificates, certificates without a SAN (in form of a DNS Name) will get rejected by applications (any modern web browser like Mozilla Firefox, Google Chrome, Microsoft Edge, and so on).
TameMyCerts provides a secure alternative to this approach in that it is able to detect DNS Names and IP addresses found in the Common Name of a certificate request and automatically transfer them to a newly-built SAN certificate extension.
This version was released on Nov 12, 2023.
TameMyCerts has developed into a reliable, secure and stable enterprise product. Many organizations around the world are relying on it to improve their security and their PKI workflows. Professional development, testing and documentation consumes a considerable amount of time and resources. Whilst still being fully committed on keeping source code available for the community, digitally signed binaries, a print-optimized documentation and priority support are benefits only available for customers with an active maintenance contract.
This is a major release containing lots of bug fixes for edge-cases as well as many new exciting features, whilst staying backwards-compatible to existing configuration files.
This version was released on Jan 31, 2023.
This is a quality improvement only release. TameMyCerts now uses the interfaces provided by the certification authority to determine Subject and Subject Alternative Name information.
This version was released on Dec 30, 2022.
This is a quality improvement only release. TameMyCerts is now covered by automated integration tests which allow testing parts of the code base otherwise not testable with unit tests.
This version was released on Nov 15, 2022.
This version was released on Aug 11, 2022.
This version was released on Mar 10, 2022.
This version was released on Feb 15, 2022.
This is the initial release of TameMyCerts made publicly available.
Abbreviation | Description |
---|---|
ACME | Automatic Certificate Management Environment |
AD CS | Active Directory Certificate Services |
AD DS | Active Directory Domain Services |
AIA | Authority Information Access |
CA | Certification Authority |
CDP | CRL Distribution Point |
CN | Common Name |
CRL | Certificate Revocation List |
CSR | Certificate Signing Request |
CRLDP | CRL Distribution Point |
DN | Distinguished Name |
DNS | Domain Name System |
GC | Global Catalog |
HTTP | HyperText Transfer Protocol |
HTTPS | HyperText Transfer Protocol, Secure |
IETF | Internet Engineering Task Force |
IP | Internet Protocol |
IPv4 | Internet Protocol Version 4 |
IPv6 | Internet Protocol Version 6 |
ITU-T | International Telecommunication Union Telecommunication Standardization Sector |
LDAP | Lightweigt Directory Access Protocol |
MDM | Mobile Device Management |
MMC | Microsoft Management Console |
NAC | Network Access Control |
NDES | Network Device Enrollment Service |
OCSP | Online Certificate Status Protocol |
PKI | Public Key Infrastructure |
RA | Registration Authority |
RDN | Relative Distinguished Name |
REST | Representational State Transfer |
RFC | Request for comment |
SAN | Subject Alternative Name |
SCEP | Simple Certificate Enrollment Protocol |
SID | Security Identifier |
URI | Uniform Resource Identifier |
URL | Uniform Resource Locator |
VA | Validation Authority |
XML | eXtended Markup Language |