Creating a broadly compatible, modern SSL certificate with Active Directory Certificate Services

After recently hitting the default two year expiration point with our SharePoint development environment’s AD CS-issued SSL certificates, I set about updating that environment with a new five year template. I took this opportunity to see if I could make it as good as possible without breaking compatibility with anything. I will discuss some of these compatibility issues along the way. I will also make the certificate exportable, make sure it’s using the SHA256 hash (SHA1 will be deprecated in the near future), change the Certificate Authority (CA) configuration so that HTTP Distribution Points will be contactable from “outside the network”, and set permissions on the template in a way that it will be generally usable.

Steve Peschka tackled some of these basics about 18 months ago, but as he notes, his posts covers the simplest updates you can make. I think a few other options are worth considering. I don’t pretend to know all that there is to know about Active Directory Certificate Services (AD CS), or PKI in general, but I do think we can advance considerably beyond the default with a few changes. This is not a well-documented subject, so I hope to pull a few disparate resources together and propose an improved template. If you think anything here can be improved further, please post in the comments and I’ll try to incorporate that feedback.

Why use AD CS for SSL Certificates?

Before jumping in to the configuration, it’s worth explaining the benefits of AD CS. Purchasing certs is all good, but not always necessary or justifiable in non-production tiers. If we’re thinking of using free certificates then we’re choosing between self-signing or using an internal CA. There are a few reasons why I prefer to use AD CS over self-signed certificates, which I’ll cover here.

The most important reason is for managing trust. With AD CS your domain machines already implicitly trust the Root CA. For non-domain machines we only need to establish trust with that Root CA once, rather than for each certificate. This means that each time you build a new machine or use a new user account, you don’t need to step through the annoying process of manually establishing trust with self-signed certs. This may seem like overkill in a lab environment at a glance, but then you just need to think about a test scenario that requires three or more accounts and it starts to make sense. Over the life on an environment this will almost certainly simplify things. And remember that if a self-signed cert expires, then you will need to go through this all again.

The second reason to use AD CS is that it gives you more control, such as supporting Certificate Revocation Lists (CRLs). This has become increasingly important in recent years, as some things will rightly refuse to connect to SSL-secured resources unless they can confirm the certificate is not revoked.

Lastly, using AD CS-issued certs can emulate your production infrastructure better, improving test fidelity for performance evaluation, compatibility, etc. For instance, many self-signed options do not support Subject Alternate Names (SANs) well as an alternative to wildcards. In my experience, testing with SANs is pretty important where they will be used in production.

Certificate Authority Preparation

Before creating a new Certificate Template, we need to make sure the CA is configured as we want it. I will be adding HTTP endpoints to the default AIA and CDP Extensions, and I will update the CA Validity Period. It’s probable that if you’re stepping through this, you’re thinking of using AD CS in a lab, or some other non-production tier where all machines can be known to trust AD CS as a Root Authority. If so, you are the audience this article is written for. If you’re following this post for guidance on how to configure AD CS in your production environment, stop here. There are far better/more comprehensive resources, and they will not focus solely on SSL certificates.

For the purposes of this post I am assuming:

  1. Risks are exceptionally low in whatever environment you are using.
  2. You are in complete control of this environment.
  3. We are weighting maintenance/usability concerns high above security with this configuration. I still intend to improve upon the default security, but this is certainly not guidance for a production infrastructure.

Updating the AIA/CDP endpoints is important because if you test external access scenarios, like publishing something with the Web Application Proxy or UAG, then you need to make sure these endpoints are accessible from servers in a DMZ or outside the network altogether. In this context “outside the network” may signify another virtual machine on your workstation, or the workstation itself, but in any case, these non-domain resources need to be able to confirm the revocation status of certificates issued by your AD CS Root Authority. The best way to do that is over HTTP. Chances are LDAP and file shares are blocked from these locations.

I do not attempt to explain how you should securely publish the HTTP endpoint locations, as that’s a topic unto itself, but be aware that the Web Application Proxy does not support HTTP publishing and these endpoints must be requested over HTTP; SSL termination will not work; these HTTP endpoints cannot rely on SSL. At any rate, what I am explaining is how to get the HTTP endpoints in your certificates so clients know where to make a request. The example I provide here is an anti-practice, using the Domain Controller as this web server. I only take this approach because this environment is completely network-isolated and we need to make some inelegant workload consolidation decisions with desktop virtualisation. As I state above, this is not guidance fit for your production certificate infrastructure.

Updating the Validity Period is necessary because AD CS will not issue certificates longer than this period. The default AD CS lifetime is two years, so if we want a five or ten year certificate then we need to update this value accordingly. Note: the reason I have not configured this certificate for more than five years validity is that I don’t think we can assume anything in the template I’m creating here will be safe five years from now. Cryptography faces immense challenges at the moment, and the templates here do not push the boundaries of what is possible today at all. Indeed, I really wanted to create a template that uses Elliptic Curve Cryptography (ECC), as is now common on the web in Forward Secrecy, and as has been supported in AD CS since Windows Server 2008 with CNG certs – but sadly, the .NET Framework is not CNG-aware yet. It lacks support for the AD CS Key Storage Provider, so we can’t use these certificates in AD FS (and other places). The point I’m drifting away from rapidly is that these templates are merely as modern as I can make them without breaking compatibility, rather than being a safe configuration for the long term. And even if we aren’t purely concerned with safety, there is a risk that some or all of this might be deprecated if any of this legacy stuff is compromised. With all this in mind, five years feels like a sound enough compromise. If this feels a bit cowboy for your requirements then please choose a shorter validity period!

Configuring the CA for HTTP Distribution Points

In the Certificate Authority snap-in (certsrv.msc), right-click your CA and open the Properties dialogue. Make the following changes to enable HTTP endpoints.

AIA Changes
Un-tick the “Include in the AIA extension of issued certificate” box for the LDAP:// path, then select the HTTP:// path and tick the same box. Make sure this HTTP endpoint is the one you expect to be publishing over port 80 later, as explained above. Remember that this specific default HTTP path in my configuration is not a good practice. Make sure you are comfortable with this configuration before proceeding any further. Also remember that it may be necessary to change the C:\ drive path as needed (or not), if the HTTP path points somewhere other than the DC, but it won’t be necessary to change the tick boxes there.

The other locations are un-ticked by default and do not need to be changed.

CDP Changes
Leave the C:\… path tick boxes unchanged, as this is the publishing location only. Change the actual path only if certificates should be published elsewhere (if they will be served from somewhere else).

Un-tick the “Include in the CDP extension of issued certificates” box for the LDAP:// path.

Tick all three available boxes for the HTTP:// path. The same comments I make above apply to this HTTP endpoint.

Leave the FILE:// path completely un-ticked, as it comes by default.

The CA Properties dialogue box can be closed now.

Update CA Validity Period to Five Years

Before making Validity Period changes, confirm the current settings with the certutil tool.

We will be changing this validity period to 5 years. As noted above, you will not be able to issue certificates for longer than two years (or whatever the CA is set to presently) without making this change.

Restart Active Directory Certificate Services to commit both sets of changes above.

Create a Legacy CSP Certificate Template

At last we can create our new Certificate Template. From the Certificate Authority console, right-click in the Certificate Templates container and select “Manage” to open the Certificate Templates console. In Certificate Templates, right-click the Web Server template and select “Duplicate Template”.

As mentioned above, we’re sticking with the duplicated legacy compatibility settings. We must use the Legacy Cryptographic Service Provider (CSP) for full support, rather than the newer Key Storage Provider (KSP) category.

Note: although there doesn’t appear to be an option to specify an SHA256 hash with the Legacy Cryptographic Service Provider options in this Cryptography tab, I believe this is dictated by the AD CS configuration rather than these settings (I’m not clear in which AD CS version this was increased to SHA256 but it certainly behaves this way in Windows Server 2012). This mitigates some of the apparent need to use the new Key Storage Provider. The SHA256 hash is a significant improvement over SHA1. It would be great if we could effectively issue ECC certs from AD CS for SSL today, but at present the legacy SHA256 hash is the best we can use without degrading compatibility. Put another way, we can issue ECC certs, but we can’t always make use of them.

Default Compatibility Settings

On the General tab, give the template a name, a display name, and set the Validity period to 5 Years.

On the Request Handling tab, select the “Allow private key to be exported” tick box.

On the Security tab we configure permissions for the template (which can be changed later through the Certificate Authority console as needed). In my configuration, I created an AD DS Global group for web servers that need to be able to request SSL Certificates from AD CS. I added my SharePoint, Office Web Apps, AD FS, etc. Machine accounts to this group. Remember that if you’re adding members to this group in ADUC, the Computers Object Type need to be selectable in the picker to be able to find and add these accounts. Back in the new template’s Properties, I granted this group Read and Enroll rights.

Note: the machine accounts that will host SSL workloads need these rights. I am not 100% clear about the user rights required, if any, but I do not believe there are any (assuming the user account has access to the machine account’s Personal certificate store). If the machine account’s rights are missing, you will not be able to select the template when issuing the request (assuming we will be issuing the request from the Local Machine’s personal store). There are other approaches, but this is the most straight-forward. Also note: if a machine has been recently added to this group, and does not appear to have permission to request this new template, consider rebooting the machine, as the group membership may not appear in the machine account’s Kerberos ticket yet.

The Certificate Templates console can be closed now. Back in the Certificate Authority console, right-click Certificate Templates and select, “Add a new template to issue”. Select the new template.

The Certificate Authority Console can be closed now.

Request New Certificate from Legacy Template

From the machine that will host the SSL workload, open the Local Machine account’s certificate management console (certlm.msc). From the Personal store, right-click and select All Tasks -> Request New Certificate. Next, select the appropriate enrollment policy (there will probably only be an Active Directory policy), and on the Request Certificates page we should see the new template. Click the blue “More information is required…” link beside the yellow warning symbol to specify the certificate request.

Note: a SAN configuration can be specified in this request.

On the General tab, specify the Friendly name and Description. These will be visible where the certificate is used.

No changes are required on the other tabs. They have been specified by the template for the most part. After finishing with the Certificate Properties dialogue, the Request Certificates page shouldn’t have the yellow warning for the completed template as it did before we populated these details.

After pressing “Enroll” this should now succeed.

These last few steps can now be repeated whenever we need to issue or update an SSL certificate. Although AD CS is a difficult service to work with, it is possible to use it well. With a better Web Server template, we can address many of the shortcomings of SelfSSL, self-signed requests from IIS, AD CS requests from IIS, AD CS requests of the default Web Server template, makecert and other approaches to generating certificates without purchasing from a public CA. Ultimately there’s nothing wrong with purchasing them, but it is possible to save on those costs in pre-production tiers in some cases where all machines can reliably trust an internal CA (manually or automatically). With an improved template from AD CS we can reduce the number of places where trust needs to be declared manually and move toward a better compromise between operational stability, broad compatibility and security.

I haven’t made all of these same template changes across multiple versions of AD CS, so this post can be clearer on those points. I am initially hoping to raise awareness of what can and can’t be done with AD CS 2008 R2 and later. Please feel free to suggest improvements.

One thought on “Creating a broadly compatible, modern SSL certificate with Active Directory Certificate Services”

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.