Wednesday, April 11, 2012

Creating a Two Tier PKI With Windows 2008r2


I've recently undertaken the task of setting up a Public Key Infrastructure (offline Root, online issuer) for my current engagement. I've been through this a few times and there is a lot of info out there, so rather than write a detailed step-by-step, I'm going to list major notes & "gotchas" while providing links to other blogs and tech articles.

Update note: This article was authored in April of 2012, when SHA2xx adoption by network devices was such that SHA1 was still predominant in enterprises. When instructed below to use SHA1 for the online CA, please do not. SHA256 should be considered the minimum as of 2016.

Why an offline root? 


An offline root is a much more secure option than having your online issuing enterprise CA serve as root because if the root CA were to be compromised it could invalidate your entire PKI. By keeping your root CA offline (unplugged or shut down) you make it nearly impossible to compromise that box. In that scenario, if one of your online issuing CAs is compromised you will only need to revoke the certificates issued from that level down. (or just that CA depending on circumstances) This will save you from having to re-build from scratch.

More info: Technet Wiki entry by Kurt Hudson, Ed Price and others

Prerequisites:  

  • Assumes there is no existing CA infrastructure. If you have one you will need to either A>Decommission or B> Transition. Follow the Decom link for more info there; the transition piece can have many variables so I won't cover that here.
  • Assumes you have licenses for Windows. As of 2008, you will need at least 1 Standard edition (for the offline root) and 1 Enterprise edition. (for full functionality of the issuing CA, you can use Standard with slightly reduced functionality)

Step 1: Setup Offline CA

Setup Server

  • Setup a new Windows 2008r2 Standard Edition server. If running on a virtualization platform err on the side of compatibility vs. performance when selecting virtual hardware. Make sure you record the admin password for your company since after getting the system setup it'll be quite a long time before you need to log on again.
  • DO NOT JOIN THIS SERVER TO YOUR DOMAIN then fix your caps lock key. (mine was stuck) 
  • Enable RDP if desired. (available under 3>Customize This Server in the "Initial Configuration Tasks") The rest of this guide assumes you're connected via RDP.
  • Name the server as desired, then activate and then fully update using Windows Update. Make sure the time & time zone are set correctly. 

Install Certificate Services

  • From Server Manager, select "Roles->Add Roles"
  • On the Server Roles page, select "Active Directory Certificate Services" and hit "Next"
  • Under "Role Services", select "Certification Authority" only & hit "Next". 
  • The "Setup Type" should default to "Standalone"; ensure the "CA Type" defaults to "Root CA".
  • On the "Private Key" step, select "Create a new private key" and then we have a couple choices to make under "Cryptography"
    • CSP: Generally stick with the default "RSA#Microsoft Software Key Storage Provider" unless you have need of a different CSP by way of other network hardware such as smart cards, etc. You should know if you need a different CSP. If you don't, you don't. :)
    • Hash Algorithm: This can be a bit tough; SHA256 (SHA2) is a much more secure hash than SHA1, but some systems may not be able to use it. (WinXP SP2, some Oracle services) You'll need to weigh the risk here. In my scenario I'm deploying this time around for a small/mid business with significant legacy equipment, so I'll favor compatibility over security. If you're unsure, follow my lead and select the "SHA1" algorithm. If you're certain you can get away with it, (not WinXP SP3 will have enroll issues) select "SHA256" or better.
    • Key character length: This is a similar discussion as the hash. If you plan on having a key duration longer than 10 years, (which I'll recommend in a moment) it is generally suggested (2 links there) to shoot for 4096 bit, but that may have compatibility and performance tradeoffs. One notorious offender has been Cisco, but their main IOS resolved that issue in ver 12.4T. That said, ensure all devices you will need certs on and select for 4096 if possible. If you are unsure on not capable of verifying, select 2048.
    • "Allow administrator interaction when the private key is accessed by the CA.": Check this if your CSP (above) requires it. The default Microsoft Software KSP does NOT require it.
  • For "CA Name": Set a good common name for the root CA. This should not reflect the machine name but rather the organization, i.e. "MyCompany Root CA". Keep it short and without special characters. Set the Distinguished name suffix to something that doesn't reveal security information about your internal structure. This does not need to match AD as this isn't an AD integrated system. It can be blank if desired. I'm using "OU=PKI,O=CompanyName,C=US" where US is the country code. (use yours as appropriate)
  • Validity Period: 20 years. A good rule of thumb is that top level CAs must be at least twice the duration of the CA directly below it. Do 10 if you like, but I see little reason for it. See here for further considerations.
  • Certificate Database: Default locations for the offline root CA. We'll change the locations for performance reasons on the issuing CA but that's not a concern here.
  • Accept the rest of the dialogs and continue. 

Step 2: Configure Offline CA

Change the Default Cert Request Action

First we'll ensure that certificate requests will NOT be automatically processed by the Root CA. Note: this appears to be correct by default in Win2k8r2, but due to its importance I'm leaving the step in.
  • Open the cert authority and drill to Certification Authority->CA Name
  • Right Click->Properties
  • Policy Module->Properties
  • Check the box that says "Set the certificate request status to pending."
  • Click "OK" twice to get back to the main CA MMC

Set the CRL Publication Interval

The CRL defines which certificates have been revoked. You need to strike a balance between administrative overhead and time for effect on revocation. Since this CA is offline each time the CRL needs to be published it will be a manual process. The only certificate revocation that will be published by this is for a subordinate CA. For my scenario I'll be using the CRL publishing interval of 6 months.
  • Expand your Root CA object and Right Click "Revoked Certificates"->Properties
  • Set "CRL publication interval" to the desired time frame. I'm recommending 6 months.
  • Ensure "Publish Delta CRLs" is not checked.
  • Click "OK"

Set Configuration DN, Domain DN and Certificate Validity Period Registry Keys

Note: You can skip the ca\DSxxxxxxDN steps if you NEVER plan on publishing CRLs or Certs via Active Directory, but its an easy step so I don't recommend it.  

When you use variables in the AIA and CDP paths for the LDAP publication (i.e. ) these registry keys are referenced to populate those fields with the correct information. 
  • Open a command prompt as administrator
  • Execute "certutil -setreg ca\DSConfigDN CN=Configuration, DNpath" (i.e. certutil -setreg ca\DSConfigDN CN=Configuration,DC=CompanyName,DC=local)
  • Execute "certutil -setreg ca\DSDomainDN DNpath"
    • DNpath should be the appropriate path. To get it correct you can use ADSIEdit to connect to the default naming context. 
  • Execute "certutil -setreg ca\ValidityPeriodUnits 10" 
  • Execute "certutil -setreg ca\ValidityPeriod "Years"
    • These last two commands set the default duration of certificates issued. Since we will only issue for intermediate CAs we'll set it for 10 years. If you set your RootCA for 10 rather than 20 earlier, follow your own lead and set this to 5 instead.

Set CDP and AIA Locations

The CDP and AIA locations specify the place clients can retrieve the CRL and certificate. Remember this CA is offline, so we need a maintainable future proof strategy to serve those up. For that reason, I'm recommending that the primary delivery method be http using a custom DNS name dedicated for the task. I'll then use our public web infrastructure (with split DNS) and rely on the SLA associated with that platform. I can then use host headers to parse out the PKI requests and have everything served up on port 80. I will be using the hostname pki.company.net. Substitute yours where appropriate. Alternatively it would be easy to use the custom DNS to point to your (not yet built) online issuing CA. Additionally we'll publish to LDAP as well. Note that the default paths will work for that since we set the registry locations, but I'll still be making some additional changes for added security. See here, here, and here for more info.

Note: After the changes below you may be prompted multiple times to restart the CA service. Don't do it then; we'll restart it all when we're done here.
  • Select the CA name at the root and Right Click->Properties
  • Select "Extensions" and ensure "CRL Distribution Point (CDP)" is selected
  • Select "C:\Windows..." and ensure only "Publish CRLs to this location" is checked
  • Select "ldap:///..." and click "Remove"  (IF you want added security...I'll explain why in a moment)
  • Select "http://..." and click "Remove"
  • Select "file://...." and click "Remove"
  • Click "Add..." and type the following in "Location:" ldap:///CN=<CATruncatedName><CRLNameSuffix>,CN=01,CN=CDP,CN=Public Key Services,CN=Services,<ConfigurationContainer><CDPObjectClass> and click "OK".
    • Important note: This is one place where I'm taking an extra measure of security; normally the CN=01 would be CN=(machinename), but I would prefer not to reveal the real name of the internal server in the CDP string. I'll be using a two digit incrementing integer for top level CAs and a three digit incrementing integer for CAs down the tree. Feel free to leave this to the default of machinename if you desire.
  • With the new ldap:/// entry selected, ensure "Include in all CRLs. Specifies where to publish in the Active Directory when publishing manually." and "Include in the CDP extension of issued certificates" are checked
  • Click "Apply" 
  • Click "Add..." and type the following in "Location:" http://pki.company.net/CertEnroll/<CaName><CRLNameSuffix><DeltaCRLAllowed>.crl   (substitute the correct DNS name for your company)
  • With the new http:// entry selected, ensure "Include in CRLs. Clients use this to find Delta CRL locations." and "Include in the CDP extension of issued certificates" are checked
  • Click "Apply"
  • Under "Select extension:" select "Authority Information Access (AIA)"
  • If you chose to obscure the servername as listed a few points above: Select "C:\windows..." and click "Remove"
  • Select "http://..." and click "Remove"
  • Select "file://...." and click "Remove"
  • If you chose to obscure the servername as listed a few points above: Click "Add..." and type the following in "Location:" C:\windows\system32\certsrv\CertEnroll\01_<CaName><CertificateName>.crt
  • Click "Apply"
  • Click "Add..." and type the following in "Location:" http://pki.company.net/CertEnroll/01_<CaName><CertificateName>.crt Substitute pki.company.net for you URL and if you did NOT opt to obscure the servername replace 001 with <ServerShortName>.
  • With the new http:// entry selected, ensure "Include in the AIA extension of issued certificates" is checked
  • Click "OK"
  • When prompted to restart certificate services, select yes.
Notes: The default LDAP location for AIA should be fine provided you did the registry entry stuff above. The default C: and http:// locations are fine if you don't want to obscure the server names. At this point, double check all your entries. If you proceed from here and find out there was a typo in any one of these entries later you will have to revoke the issuing CA cert to re-mediate the problem.

Step 3: Setup Online CA

In this part of the exercise we'll install all the online CA features on one box. Depending on your environment you may want to split some of the services across multiple machines.  For scalability info, see: here.

Note, you may want to take a quick moment at this time to review Appendix A below regarding the role of the CAPolicy.inf file. 

Setup Server

  • Setup a new Windows 2008r2 server. For full functionality on the issuing CA, use Enterprise edition. (Note 2012 has full functionality in standard and up) I recommend x64 for scalability reasons. If possible I'd recommend having a separate drive to house either the DB or the logs for performance reasons. (unless the drive is on the same subsystem) This server should be joined to the domain before you start installing certificate services.
  • Enable RDP if desired. (available under 3>Customize This Server in the "Initial Configuration Tasks") The rest of this guide assumes you're connected via RDP.
  • Name the server as desired, then activate and then fully update using Windows Update. Make sure the time & time zone are set correctly. 

Install Certificate Services

  • From Server Manager, select "Roles->Add Roles"
  • On the Server Roles page, select "Active Directory Certificate Services" and hit "Next"
Note: the next step will prompt you to add additional role services required by two of the main roles. When prompted, click "Add Required Role Services" to continue. 
  • Under "Role Services", select "Certification Authority", "Certification Authority Web Enrollment","Online Responder" (if you plan on using OCSP, if you don't know what it is don't bother yet), and "Certificate Enrollment Policy Web Service" then click "Next". 
  • Change "Setup Type" to "Enterprise" and click "Next".
  • Change "CA Type" to "Subordinate CA" and click "Next".
  • On the "Private Key" step, select "Create a new private key" and then we have a couple choices to make under "Cryptography"
    • Refer to the info above for details about CSP, Hash, and Key Character Length. For my main issuing CA, which this will be, I will be selecting options to ensure compatibility. I would advise (at the time of this writing) against using 4096 bit for the issuing CA for performance reasons. 
    • CSP: "RSA#Microsoft Software Key Storage Provider" (unless otherwise needed)
    • Hash: "SHA1" (Unless you're brave enough for something nicer :) ) 
    • Key Character Length: 2048
    • "Allow administrator interaction when the private key is accessed by the CA.": Check this if your CSP (above) requires it. The default Microsoft Software KSP does NOT require it.
  • For "CA Name": Set a good common name for the issuing CA. This should not reflect the machine name but rather the organization, i.e. "MyCompany Intermediate CA xx". (Where xx is an increment) Keep it short and without special characters. Set the Distinguished name suffix to the same as the root CA.
  • Certificate Request: Select "Save a certificate request to file and manually send it later to a parent CA:" and save it locally to send over later. 
  • Validity Period: 20 years. A good rule of thumb is that top level CAs must be at least twice the duration of the CA directly below it. Do 10 if you like, but I see little reason for it. See here for further considerations.
  • Certificate Database: Optimally the database location and database log location should be placed on a disk other than the OS disk. (different disk, not just performance) If performance is a very large consideration (i.e. very, very heavy load) you can split the DB from the DB log location as well. I'll be placing both on D:. Create folders and place the certificate database location to D:\pki\CertServ and set the Certificate database log location to D:\pki\CertLog
  • Authentication Type: Select "Windows Integrated Authentication"
    • Note there may be situations one may want to use other methods, i.e. allowing requests originating from the internet. 
  • Server Authentication Certificate: Unless you already have a certificate for this server, select "Choose and assign a certificate for SSL later"
  • Web Server (IIS)->Role Services: Accept Defaults. The appropriate role services should already be selected, only add or remove if you have unique IIS needs. 
  • Confirmation: Save the report if you like and then click "Install"
  • Results: You will get a warning about the installation being incomplete since the Sub CA certificate needs to be processed. Save the report if desired and click "Close"  

Publish Root CA CRL & CRT to AD

  • Fire up & login to the Root CA and then Open the Root CA Certificate Authority
  • Expand the CA and right click on "Revoked Certificates"->"All Tasks"->"Publish"
  • Keep "New CRL" selected and click "OK".
  • Navigate to "C:\Windows\System32\certsrv\CartEnroll" 
  • IF you changed the AIA location above to replace the machinename with 01 as I did, rename the .crt file so that the machinename portion of the file is replace with 01. I.E. servername_mycompany root ca.crt becomes 01_mycompany root ca.crt
  • Copy the .crt and .crl files to a domain controller  (You will need to map a drive)
  • Log onto the domain controller the files were copied to and open an elevated cmd prompt
  • Navigate to where the files reside and publish the RootCA cert: certutil -dspublish -f "01_My Company Root CA.crt" RootCA
    • Where: certutil is the tool, -dspublish is the action, -f creates a new container in AD, and RootCA specifies the cert is a Root CA cert. Important Note: For these certutil commands to run successfully you must be in the Enterprise Admin group.
  • Publish the CRL: certutil -dspublish -f  "My Company Root CA.crl"

Publish Root Cert to Clients via GPO

  • May as well do this while we're still on the DC: Open Group Policy Management & Right Click Default Domain Policy->Edit
  • Drill to Computer Configuration->Policies->Windows Settings->Security Settings->Trusted Root Certification Authorities
  • Right Click->Import->Next
  • Select the Root Certificate->Next->Keep default of "Place all certificates in the following store"->Next->Finish
  • Log off DC

Publish Root CA CRL & CRT to Web

This step depends entirely on what type of web infrastructure you plan on using, so I'll skip it with only the following advice: Make sure the CRL and the CRT are available from the CDP and AIA locations you advertised earlier. If using the split DNS approach test the retrieval from internal and external clients. Make sure you allow + signs on IIS7 or higher by allowing "double escaping" in Request Filtering.

Set Sub CA CDP and AIA

If you planned a good infrastructure for your Offline CA, you can leverage that here as well.
  • Log on to Sub CA
  • Select the CA name and Right Click->Properties
  • Hit "OK" on the Active Directory Certificate Services warning. 
  • Select "Extensions" and ensure "CRL Distribution Point (CDP)" is selected
  • Select "C:\Windows..." and ensure "Publish CRLs to this location" and "Publish Delta CRLs to this location" are checked
  • Select "ldap:///..." and click "Remove"  (IF you want added security...I'll explain why in a moment)
  • Select "http://..." and click "Remove"
  • Select "file://...." and click "Remove"
  • Click "Add..." and type the following in "Location:" ldap:///CN=<CATruncatedName><CRLNameSuffix>,CN=001,CN=CDP,CN=Public Key Services,CN=Services,<ConfigurationContainer><CDPObjectClass> and click "OK".
    • Note: This is another place where I'm taking an extra measure of security; normally the CN=001 would be CN=(machinename), but I would prefer not to reveal the real name of the internal server in the CDP string. Since this is a sub CA I'm using a three digit incrementing integer. Feel free to leave this to the default of machinename if you desire.
  • With the new ldap:/// entry selected, ensure "Publish CRLs to this location","Include in all CRLs. Specifies where to publish in the Active Directory when publishing manually.", "Include in CRLs. Clients use this to find Delta CRL locations","Include in the CDP extension of issued certificates", and "Publish Delta CRLs to this location" are checked
  • Click "Apply" 
  • Click "Add..." and type the following in "Location:" http://pki.company.net/CertEnroll/<CaName><CRLNameSuffix><DeltaCRLAllowed>.crl   (substitute the correct DNS name for your company)
  • With the new http:// entry selected, ensure "Include in CRLs. Clients use this to find Delta CRL locations." and "Include in the CDP extension of issued certificates" are checked
  • Click "Apply"
  • Under "Select extension:" select "Authority Information Access (AIA)"
  • If you chose to obscure the servername as listed a few points above: Select "C:\windows..." and click "Remove"
  • Select "http://..." and click "Remove"
  • Select "file://...." and click "Remove"
  • If you chose to obscure the servername as listed a few points above: Click "Add..." and type the following in "Location:"C:\windows\system32\certsrv\CertEnroll\001_<CaName><CertificateName>.crt
  • Click "Apply"
  • Click "Add..." and type the following in "Location:" http://pki.company.net/CertEnroll/001_<CaName><CertificateName>.crt Substitute pki.company.net for you URL and if you did NOT opt to obscure the servername replace 001 with <ServerShortName>.
  • With the new http:// entry selected, ensure "Include in the AIA extension of issued certificates" is checked
  • Click "OK"

Process and Install Sub CA Certificate

  • Log onto Sub CA
  • Copy the previously created certificate request from the root of C:\ to the Offline CA
  • Log onto the Offline CA and Open the Certificate Authority 
  • Right Click the Root of the CA->"All Tasks"->"Submit New Request"->Select the request you just copied over
  • Click "Pending Requests"->Right Click (should be ID2)->"All Tasks"->"Issue"
  • Click "Issued Certificates"->Right Click (should be ID2)->"Export Binary Data"
  • Keep "Binary Certificate" selected and choose "Save binary data" & click "OK"
  • Save as "cert.p7b" locally and then move it to the Sub CA
  • Back on the Sub CA: Right click the root of the CA->"All Tasks"->"Install CA Certificate" & Select the p7b from the Root CA
  • Start the CA with the "Play" button at the top. 
  • Make sure you delete the requests and generated certificates (*.req and *.p7b)  from the filesystem on all servers.
  • If you chose to obscure the servername as listed a few points above: You may need to manually add the CRL to AD for the first publish due to a bug; Open a CMD window as administrator and execute certutil -dspublish -f  C:\windows\system32\certsrv\certenroll\CRLFileName.crl

Publish Sub CA CRL & CRT to Web

If you used the built-in web server you don't have much to worry about here, but if you, like I did, utilized your external facing web farm to leverage split DNS and that SLA, you'll need to devise a way to publish the CRL (and delta) regularly to the web farm. Since that shouldn't be part of the same domain you may need to get creative. I'm thinking about creating a dedicated service account, giving it an EFS cert, and then storing the powershell script on the server with the username/password required in there. That way only the svc acct will be able to read the script. I won't outline that now though... perhaps in a future post.

Test AIA and CDP Points With an Issued Certificate

With the first issued cert from your Sub CA, drop to a command line as administrator and execute: certutil -verify -urlfetch certname.cer . This will display the result of checking the AIA and CDP of both the root and the Sub. If there are any problems go back and clear them up now before issuing any more certs. If there is an issue with the root you'll have to fix it and re-issue the Sub CA cert.

When you're done, take the issuing CA Offline.

Step 4: Template Configuration, etc.  

At this point you're actually done with the setup, but it's not all that functional yet. The next section is a start on getting the system to actively issue certificates. Before proceeding in these steps it is recommended that you mess around a bit to familiarize yourself with the product. The examples below are only a few of what could and should be many different certificate templates for a fully featured PKI. Please take time to understand certificate templates before calling it completed and firing up your infrastructure.

Important Note:  Throughout this next step I will make a couple references to enabling auto-enrollment security permissions on a given certificate template. While this is what we will ultimately want, I recommend that you first enable enroll only, test the template with a manual enrollment & use, and then circle back and enable auto-enrollment after you have verified proper functionality.

Make Desired Certificate Template Modifications

Before opening the floodgates for certificate auto-enrollment, you will want to modify certificate templates as desired. Cert templates control everything from cert duration to cert purpose. There are some that are installed by default, but I'd highly recommend familiarizing yourself with the concepts and making necessary changes before certificates are issued. Here are some great links to get you there:
At a minimum I would configure user and EFS templates for key archival. For more information regarding Key Recovery Agents, see "Identify a Key Recovery Agent" at Technet. As a demonstration, let's setup Key Archival and fix up the basicEFS template:

Key Recovery Agent Setup

First, we need to select an account for the KRA:
  • Create or select a user that will act as the Key Recovery Agent. Choose wisely and document accordingly; this acct will need be around for awhile. I created a separate account for just this purpose.
Now, let's modify the Key Recovery Agent template:
  • On the issuing CA, Right Click "Certificate Templates" and click Manage
  • Right click "Key Recovery Agent" and click "Duplicate"
  • Select Windows 2003. This will make the template V2... if we don't need V3 functionality don't create it. 
  • Under "General" change the Template Display Name to Key Recovery Agent for CompanyName; I like to append the company name to the default name so you know on what it is based and who it's for. Leave the Template Name as is. (it will auto change)
  • Under "Request Handling" ensure that "Allow private key to be exported" is checked. This will allow us to export the key and save it somewhere safe. 
  • Under "Superseded Templates" click "Add...", select "Key Recovery Agent" and click "OK".
  • Under "Security" add the account you chose earlier and give it "Read" and "Enroll" rights.
  • Click "OK"
  • Start the CA server (Temporarily to for these tasks) 
  • Back on the CA, under "Certificate Templates", right click in a blank space on the middle plane and select "New"->"Certificate Template To Issue"
  • Select your new EFS certificate template and click "OK"
  • Repeat the last two steps for your new Key Recovery Agent. 
  • Select "Basic EFS" and press delete; click "Yes" to confirm 
 Now let's get a key for the KRA. The easiest way I know of to do this is as follows:

  • Open an administrative Command Prompt
  • Execute "runas /user:domain\kraAccount mmc" then hit Enter and type the password. Substitute the domain and kraAccount with the right account info. 
  • Add the certificates snap-in (personal) to the MMC and click "OK"
  • Right click on "Certificates (Current User)"->"Personal"->"All Tasks"->"Request New Certificate"
  • Click Next
  • You should see "Active Directory Enrollment Policy" under "Configured by your administrator". Select it and click "Next". 
  • Select "Key Recovery Agent for MultiTech" and click "Enroll"
  • After that completes, go back to your Issuing CA and look under "Pending Requests"
  • Right click the pending cert and approve
  • Navigate to "Issued Certificates"
  • Right click the newly issued KRA cert and Right Click->"All Tasks"->"Export Binary Data"
  • Select "Save binary data to a file" and save the cert (as whatever.p7b) to somewhere you can get to with the client.
  • Back at the client, Right click "Personal"->"All Tasks"->"Import" 
  • When prompted, select your new cert and navigate through the wizard. 
  • After importing, select the newly imported cert (under personal->certificates) and Right Click->"All Tasks"->"Export"
  • Hit "Next", "Yes, Export the Private Key", "Next", "Personal Information Exchange...","Next", type a password, "Next", select a location, "Next","Finish"
  • Copy that key to a safe location that will be backed up. 
Enable the Recovery Agent on the Issuing CA
  • On the Issuing CA, right click the CA name and click "Properties"
  • Hit the "Recovery Agents" tab and select "Archive the key"
  • Click "Add" and hit "OK" when presented with the cert you just created.
  • Click "OK"
  • Restart the service when prompted.

Modify the Basic EFS Template 

  • On the issuing CA, Right Click "Certificate Templates" and click Manage
  • Right click "Basic EFS" and click "Duplicate"
  • Select Windows 2003. This will make the template V2... if we don't need V3 functionality don't create it. 
  • Under "General" change the Template Display Name to Basic EFS for CompanyName; I like to append the company name to the default name so you know on what it is based and who it's for. Leave the Template Name as is. (it will auto change) 
  • Check "Do not automatically re-enroll if a duplicate certificate exists in Active Directory". Publish in Active Directory should already be checked. This will ensure if a user already has pulled an EFS cert and stored it in AD that the old one will be used rather than grabbing a new one.
  • Under "Request Handling" check "Archive subject's encryption private key". This will store a copy of the private key on the CA so that you can use the key recovery agent to get it in the future if it is a problem.
  • Under "Superseded Templates" click "Add...", select "Basic EFS" and click "OK". This will force people who pulled an EFS template to get a new cert with this one.
  • Under "Security" check "Autoenroll" for "Domain Admins", "Enterprise Admins", and "Domain Users" and/or anyone you would want to use EFS. (Important, see the note below)
  • Click "OK"
  • Start the CA server (Temporarily to import cert) 
  • Back on the CA, under "Certificate Templates", right click in a blank space on the middle plane and select "New"->"Certificate Template To Issue"
  • Select your new EFS certificate template and click "OK"
  • Select "Basic EFS" and press delete; click "Yes" to confirm 
  • Stop your CA to prevent issuing more certs before you have completed your template tweaks
Note: Unless you fully understand EFS, don't go forward without revoking the permissions to "Domain Users" on the template. If you have users who have files already encrypted with local or other PKI keys you'll need a migration strategy. It may be worthwhile to initially set the template to "enroll" rather than "autoenroll" and then use "cipher.exe /K" to gen a new key, "cipher.exe /U" to update previous files, and then "cipher.exe /x" to export the key for other machines. (remember the private key is not stored in Active Directory) For more info, see: 

Zow, that was fun. So much so I'll do another one. The default DC cert is the Windows 2000 geared "Domain Controller". If you, like I, have all 2008 or higher DCs you can use the "Kerberos Authentication" template. If you have mixed 2003/2008 or just 2003 use the "Domain Controller Authentication" template.
  • On the issuing CA, Right Click "Certificate Templates" and click Manage
  • Right click "Kerberos Authentication" and click "Duplicate"
  • Select Windows 2003. This will make the template V2... if we don't need V3 functionality don't create it. 
  • Under "General" change the Template Display Name to Kerberos Authentication for CompanyName; Leave the Template Name as is.
  • Under "Superseded Templates" click "Add...", select "Domain Controller" and click "OK". Rinse and repeat for "Domain Controller Authentication" 
  • Click "OK"
  • Start the CA server (Temporarily to import cert) 
  • Back on the CA, under "Certificate Templates", right click in a blank space on the middle plane and select "New"->"Certificate Template To Issue"
  • Select your new Kerberos certificate template and click "OK"
  • Select "Domain Controller" and press delete; click "Yes" to confirm  
  • Select "Domain Controller Authentication" and press delete; click "Yes" to confirm  (Unless you have 2k3 DCs)
To get SSL encrypted LDAP working, follow the instructions in this article.

Let's make one for Terminal Services & Standard Machine ID/Encryption:

Note: Let me save you some time & research and just state that you cannot automatically add the NETBIOS name as a subject alternative name with templates. If you want so suppress the certificate warnings on RDP connections you'll need to use the FQDN.
  • On the issuing CA, Right Click "Certificate Templates" and click Manage
  • Right click "Computer" and click "Duplicate"
  • Select Windows 2003. This will make the template V2... if we don't need V3 functionality don't create it. 
  • Under "General" change the Template Display Name to ComputerForCompanyName; Leave the Template Name as is.
    • Note: Per several articles, Microsoft dictates that: "Important: You must set the certificate template’s attributes Template display name and Template name to the same value."  Because of this, I've omitted all spaces from the Computer certificate in this demonstration. 
  • Under "Superseded Templates" click "Add...", select "Computer" and click "OK".  
  • Under "Security" check "Enroll" and "Autoenroll" for any Machines you want to autoenroll. You will have to add the specific machines/groups if need be.
  • Click "OK"
  • Start the CA server (Temporarily to import cert) 
  • Back on the CA, under "Certificate Templates", right click in a blank space on the middle plane and select "New"->"Certificate Template To Issue"
  • Select your new Computer certificate template and click "OK"
  • Select "Computer" and press delete; click "Yes" to confirm

Edit GPO to Specify Certificate Template

At the desired level (be it Default Domain Policy or a policy that applies to servers only, etc.) edit the target GPO. This procedure will automatically set templates for Windows Vista and higher machines. For 2k3 & XP you'll need to open the certificates MMC and request a cert manually. Fortunately they will detect the issuing CA and process the request from template quickly.
  • Navigate to "Computer Configuration"->"Administrative Templates"->"Windows Components"->"Remote Desktop Services"->"Remote Desktop Session Host"->"Security"
  • Edit "Server Authentication Certificate Template" 
  • Enable the setting and type the template name (ComputerForCompanyName)
  • Click "OK" and close the GPO Object

Configure Default Domain Policy for Auto-enrollment

  • Open group policy management and edit the "Default Domain Policy"
  • Navigate to "Computer Configuration"->"Windows Settings"->"Security Settings"->"Public Key Policies" and modify "Certificate Services Client - Auto-Enrollment Properties"
  • Set "Configuration Model" to "Enabled" and check "Renew expired certificates..." and "Update certificates that use certificate template" and click "OK"
  • Navigate to "User Configuration"->"Windows Settings"->"Security Settings"->"Public Key Policies" and modify "Certificate Services Client - Auto-Enrollment Properties"
  • Set "Configuration Model" to "Enabled" and check "Renew expired certificates..." and "Update certificates that use certificate template". Enable "Expiration Notification" if you like and click "OK"
Now double check everything. If all elements look to be configured correctly feel free to start up the issuing CA and watch the requests come in.

Congrats! You have setup an enterprise class Certificate Authority, one of the most crucial security components of any enterprise infrastructure. You probably deserve a caffeinated beverage now.

Appendix A: When to use a CAPolicy.inf file  

Note: See Windows 2008r2 CAPolicy.inf syntax for implementation specifics

The %systemroot%\CAPolicy.inf file can be put into place on a target CA to further customize the creation of the certificate associated with that CA and SubCAs. If you do wish to customize the Root CA cert with any of the values listed below you'll need to do so prior to the creation of the CA cert; you can't add this stuff after the fact without re-issuing impacted certs.

In Windows 2003, it was necessary to always use a CAPolicy.inf file to ensure the root didn't have a CDP or AID associated with its cert, but that was fixed in Windows 2008. Due to this, it's no longer required to use the CAPolicy.inf file for a proper implementation, but there are some points where you may still want one. Here are the major ones:


PolicyStatementExtension: Use this to issue a legal notice, link to your use policy, or (if you need to) specify an OID. (You'll know if you do, generally applicable for external facing CAs issuing certs to third parties) Important note, if you plan on using certificate templates with issuance policies, you should take a look at this reported issue and follow the advice there. The easiest one of his steps to implement at PKI hierarchy creation time is #2. I'll copy his logic here in case the link goes bad:  (OID 2.5.29.32.0 is shared among all MS PKI deployments)

[Version]
Signature= “$Windows NT$”
[PolicyStatementExtension]
Policies = AllIssuancePolicy
Critical = FALSE
[AllIssuancePolicy]
OID = 2.5.29.32.0

CRLDistributionPoint: This is only applicable for the RootCA and shouldn't be used in most cases. Most platforms don't honor CRLs for a root CA anyhow. Doing so would question the concept of a trusted root.

AuthorityInformationAccess: Same as above; you would only have the AIA if you already have the cert, and if you already have the root cert you either do or don't trust it already.

EnhanceKeyUsageExtension: Use this to limit the usage of this CA cert (or otherwise) to specific uses. If omitted, the CA can be used to issue any type of cert. Obviously you'll leave this blank in most scenarios.

BasicConstraintsExtension: If you are relatively certain of your long term hierarchy you may want to use this on the root CA to limit how many SubCAs may fall under this root CA. If set to 1 for example it would make it impossible for a SubCA to issue a cert for a lower level SubCA. If you desire to implement this on a SubCA but not the root, configure the registry rather than using the CAPolicy.inf.

CrossCertificateDistributionPoints: Use to specify a CCDP location (URL) if your CA has been certified by a third party PKI. You may also specify the SyncDeltaTime (how often the URL is updated) here if desired. This value will only be used when you have negotiated a cross-PKI certification. Obviously you would know if you've done this. :)

RequestAttribues: Generally used on a SubCA; this allows you to change the default SubCA template that will be used. To use this value you will need to have duplicated the Sub CA template to a new name, apply the changes you desire, publish the template, and set the CertificateTemplate value to your duplicated template. The default template is version 1, so if you would like a version 2 or 3 certificate for your SubCA you'll need to use this field.

certsrv_server: Control the renewal settings for issuing CA certs. Usually not used because 1> The defaults are sufficient for most and 2> They can be changed "on the fly" (with services restart) in the registry on CAs for all certs issued thereafter. You may want to take a look at setting LoadDefautTemplates to 0 if you want to ensure your CA doesn't issue any certs until you publish your custom templates. You will see it recommended in some places to explicitly set the renewal validity here even if you do use the defaults, but I opt not to. Though it may be spelled out directly in this text file, I'm more a proponent of handing off the "Tyranny of the Default" (thanks Steve Gibson) to anyone down the line. Generally this will ease troubleshooting because assumptions of the default are true. I.E. only change it if the default values will not work for you.

Now to address the oft-asked question "Do I need a CAPolicy file?" directly: Can you get by without a CAPolicy.inf in Windows 2008r2? Yes. Should you? Only after you review and understand its role in the process can you safely ignore it. More often than not you will want to use it to tweak a setting or two.

More references for CAPolicy.inf:
Designing and Implementing a PKI Part 2
Windows Server 2008r2 CAPolicy.inf Syntax
MS Social: CAPolicy.inf questions
CAPolicy.inf syntax

Appendix B: Publish new CRLs from Offline CA

Every six months (in our implementation) you will need to publish the new certificate revocation list to keep everything running smoothly. To do so:
  • Fire up the offline Root CA & login as admin
  • Open & expand CA object in the CA management MMC
  • Right click "Revoked Certificates"->"All Tasks"->"Publish"
  • Navigate to "C:\Windows\System32\certsrv\CertEnroll"
  • The new CRL should be there; now you need to copy it to the appropriate path on the webserver and publish to AD. Copying to the webserver speaks for itself, AD info follows:
  • Copy the file to a domain joined computer & log on to that box with Domain Admin privs
  • Open a command prompt as administrator  
  • Execute the command:  certutil -dspublish "My Company Root CA.crl"
  • Done! Log off the PC and shut down the Offline CA for another six months.

Questions/Comments/Improvements please let me know. Thanks and good luck!

16 comments:

Damon Rodriguez said...

Hi Toby,
This is a very extensive and well put together documentation and it is helping me learn about using and implementing a PKI in my infrastructure so I'd like to Thank you for putting it together.

I do have a question about using HTTP for CDP and AIA. I was following the technet guide which said to use a CNAME instead of an A record. Is there a benefit to using one over the other? I was just going to add a cname that pointed to my Enterprise SubCA and continue but your post is giving me pause.

-Damon

Toby Meyer said...

Hi Damon! I'm glad my guide is helping you. Regarding A vs.CNAME, you can use either without worry. I suspect the guidance to use a CNAME is to underscore the importance of being flexible with your hostname. At its core though, as long as the client can resolve it successfully you're good to go.

The key to a successful long term deployment is ensuring you select a DNS name that you can use for the foreseeable future. When you choose this name, take into account how you will use these certificates. If there is any chance you'll use certificates externally, (say you want to deploy Direct Access down the road...) you may want to use "split DNS" and make the CNAME used for the CDP and AIA accessible both inside and outside your network. Say for example your company owned the internet domain widgets.com. To ensure the certificate CRL look-up will work no matter where the client is, you could set the CDP and AIA to http:\\pki.widgets.com\path and then set that CNAME (or A record) inside your network to point to an internally accessible server and set the CNAME (or A record) outside your network to point to an externally accessible server.

(*Side note item, not related to PKI setup*) If you do choose to use split-DNS you may want to take this into account as well: If your company uses WiFi for mobile devices you may also want to setup a NAT rule on the inside interface of your firewall to redirect the external IP to the internal IP to account for mobile devices utilizing company WiFi that have a cached external DNS entry.

If you do not see external access as a future need then setting a CNAME to the internal server will serve you just fine. Note that if you do have access to set your internal DNS though it wouldn't hurt to use a name that may be internet accessible in the future and just not put that into place yet. (I.E. set to pki.widgets.com but don't actually make that host externally)

Hopefully that addresses your question; if no feel free to post a followup & thanks for reading!

Damon Rodriguez said...

Toby,
Thank you for responding so quickly. Your example of Direct Access is exactly why I asked. Another question which has come up is OCSP. Do you know of anything that may require an OCSP? I'm trying to justify the cost of an Enterprise license. Thanks again.

Toby Meyer said...

Good question Damon. I haven't run into anything yet that *requires* OCSP. Unfortunately a lot of clients seem to handle OCSP differently at this time which is really hampering its takeoff. I'm hesitant to admit this because has some important benefits over CRL, but I have shied away from it for reasons like this(though fixed) , this , and this. If you do go down the road of OCSP you will need to take measures to ensure your clients use it which will vary depending on the client application. It may be worthwhile in some highly-secure environments with a very dynamic cert load, but note that it can be defeated anyhow. I guess long story short I would not recommend it at this time unless you had a specific need.

As for the enterprise license, take a look here and here for other differences. I'd take particular note of the SMTP exit module which allows for SMTP notifications of certificate enrollment, etc. That said, there is some confusion out there regarding what one can and cannot do with standard vs. enterprise. Standard R2 is much better than standard non-r2 2008; it can do version 3 templates. (among other things) There is alot of training material out there that still references 2008 standard, much of which was my basis for insisting on enterprise. (see this) If it's a big point of contention you could possibly go down to standard, but it never hurts to have the capability to use the other features should you want them in the future. Another option would be to go to 2012, which doesn't change much setup wise(I'll write something up soon) but does introduce some welcome new features. Using 2012 all features are available on standard or higher. Know that you can mix 2008(r2) and 2012 CAs without problem. I updated my article to better illustrate the differences, thanks for bringing it up!

Hopefully that addresses your question, let me know if you have any others. Thanks!,

Damon Rodriguez said...

Again Thanks for the quick response. We have decided to go with the Online Responder since we like to have it in case we need it later. I haven't had time to even look at 2012 yet. it's something I'm planning to take a look in a couple of months. I have one last question for you. I see that you didn't use a CApolicy.inf file. Everything I've read so far has said to use it. Does your Step By Step take that into consideration? Meaning are your steps covering the settings that would be put into a CAPolicy.inf file?

Toby Meyer said...

Great question again! I've added an appendix to the article because while the specific implementation I was documenting didn't include one, most do. Take a look @ the newly added Appendix A and the links contained therein to determine your need & settings. Good luck and feel free to post issues or progress!

Damon Rodriguez said...

Oops. I did not add the OID as i didn't think it was necessary on the Offline CA. Will that hurt me going forward?

Toby Meyer said...

No worries! It's really only for issuing CAs and even then only in some specific cases. (if you'll be using issuance policies to control how certs are issued. I do not recommend adding any issuance policy restrictions unless you design that up front, which is out of scope for a lot of implementations. An issuance policy can only restrict the ability to issue certificates;it can't enable it. The (missing) external link illustrates that the enforcement of issuance policies is slightly different in 2008 than in 2003. I'll fix that external link tonight. Thanks!

Damon Rodriguez said...

Hi Toby,
Long time no write. I had finished installation of my 2 tier PKI but I am having some issues with the HTTP locations of the CDP and AIA. I kept the default naming structures for both except to change the site to pki.company.com and created a DNS entry for it. I get the "Unable to Download" error in pkiview so I know something isn't right. I receive an HTTP Error 403 forbidden error when I try to access the certenroll directory via web browser. When I try to browse the directory from the CA I get "HTTP Error 403.14 - Forbidden" I realize you've helped me with install in reference to your guide but do you have idea of where to start troubelshooting this? I believe this is what is preventing my Lync for iPad/iPhone from verifying the certificate. Thanks again for putting this guide together and for addending it with the CAPolicy file info.

Toby Meyer said...

Hi Damon, I hope you're doing well. Hopefully troubleshooting the IIS permissions should be relatively straightforward. Here are a few tips to get going:
-Use certutil -verify -urlfetch {path to any issued cert} This will display and test all the lookup paths and display any warnings.
-To assist in troubleshooting, you can browse to the location of the certificate revocation list with any web browser. There is no reason you shouldn't be able to access and download it.
-Refer to this guide for IIS Permissions troubleshooting.

The error you're seeing, .14, is usually due to not having directory browsing permissions. That said, hitting a file-specific URL shouldn't need browsing permissions, so I wonder if something isn't quite right with the url. As an example, here is the CDP location for one of my implementations:
URL=http://www.company.com/pki/company.com%20RootCA.crl
Note that it automatically subs in %20 for any spaces; if present you'll need to use that in the URL when testing with your browser as well.

I'm sure as soon as you get the URL tweaked everything will start working; note that you will have to re-issue any certificates after it is updated for them to work correctly though!

Good luck!

itismeap said...

Great article..just a quick note, at the top it says 'Setup a new Windows 2008r2 Standard Edition server. x64 vs. x86 shouldn't make a difference'

2008 R2 is 64 bit, I don't believe you can get 32bit edition.


Toby Meyer said...

@itismeap Good point! Article updated with your welcome improvement. Thanks!

Tom said...

Hi Toby - great article, I just have one quick question. In our domain, we'd like to enforce certificates (in particular with two-factor authentication) for our administrators. This enterprise PKI seems to be set up for ALL users. Is there a step in this process that we can enforce TFA for our admins and not for our users (or make it invisible to our users)?

Toby Meyer said...

@Tom, thanks & absolutely!

The first think you'll want to do is make an active directory group that contains all users you would want to auto-enroll in PKI. (If you haven't done so already) This group will be used to directly trigger the auto-enrollment, so make sure it is accurate. Also note that when people are removed from this group, their certs will not be automatically revoked. If, after you get this working, you remove a user from that group you'll need revoke their cert either manually or via a script. (preferred)

After the user group is in place, ensure you have the user template configured correctly and allowed for auto-enrollment. To do so copy the template: target the "User" template and perform most of the steps (let me know if you want a granular list of which) listed under "Step 4: Template Configuration, etc.". Make sure when you duplicate the template that you do two main things: Set the Superseded Templates to "user" (the default called in user auto-enrollment) and that you have your administrative user group listed under the "Security" tab of the cert. That user group will need to have read, enroll, and autoenroll rights. After doing that publish your duplicated template to your CA.

It would actually work to update the default domain GPO at the user level at this point, but I would not recommend it in most cases. Instead, either create a new GPO for this purpose or tack the following on to a GPO dedicated to this user group. (for this and other settings) Make sure this GPO has security filtering enabled and bound to the Admins group. In that GPO, navigate to User(Not computer like above!) Configuration->Windows Settings->Security Settings->Public Key Policies and set the Certificate Services Client - Auto-Enrollment to Enabled. You will want to check the first two boxes below it as well regarding renewing expired certificates and updating certs that use templates. As for the other options those are at you discretion depending on your needs.

After closing the GPO that should do it! Essentially now you have the User cert template restricted to that Admin group for auto-enrollment, and additionally you have the mechanism of auto-enrollment restricted to that group via GPO.

Hopefully that should do it for you, post more if you have any other questions or to share your results. Thanks!

pk said...

Love the guide. Small typo in one of the commands --

Execute "certutil -setreg ca\ca\ValidityPeriod "Years"

should be

Execute "certutil -setreg ca\ValidityPeriod "Years"

Toby Meyer said...

Thanks @pk for the feedback and the fix, much appreciated!