The other day, a client was deploying a new solution and needed a subordinate (SubCA) certificate for their networking device. The device basically needed to issue its own trusted certificates to clients within the internal network. They already had an internal 2-tier Microsoft CA infrastructure in place. One offline root CA and 2 enterprise subordinate issuing CAs. When we made an attempt to issue a SubCA certificate from the issuing subordinate CA servers, we got a “Denied by Policy Module” error. Long story short, the PathLength constraint attribute value had to be changed but they didn’t want to replace their subordinate certificate. As a workaround, we ended up issuing subordinate CA certificate directly from offline root CA. Read on for more details…
This is the error we received when we tried to issue a SubCA certificate from the subordinates:
Digging deeper, we found the following corresponding error in the event log:
Active Directory Certificate Services denied request 12345 because The certification authority’s certificate contains invalid data. 0x80094005 (-2146877435 CERTSRV_E_INVALID_CA_CERTIFICATE). The request was for CN=servername, OU=organizationalunit, O=organization, L=city, S=state, C=country. Additional information: Denied by Policy Module
It turned out that the CApolicy files on the issuing servers had a basic constraint of PathLength=0. RFC5280 describes this basic constraint as follows:
A pathLenConstraint of zero indicates that no non-self-issued intermediate CA certificates may follow in a valid certification path. Where it appears, the pathLenConstraint field MUST be greater than or equal to zero. Where pathLenConstraint does not appear, no limit is imposed.
In other words, there may be no further issuing CAs beyond our existing issuing subordinates. One way to check for basic constraints of an existing subordinate certificate is to open the certificate and view its Basic Constraints field under the “Details” tab:
So we needed a SubCA certificate but our issuing CAs were not willing to hand it out due to their basic constraint of PathLength=0. We had two options:
1. Change the PathLength constraint of one of the issuing CAs from 0 to 1. Reissue SubCA and try again.
2. Issue subordinate CA certificate from offline root directly.
The client ended up electing option 2 (the “shortcut”) due to the perceived reduced risk of not having to reissue their existing subordinate certificate. At this point it was not a question of which option was better. We simply had to fulfill the client’s request.
How to Issue Subordinate CA Certificate from Offline Root CA
In order to issue subordinate CA certificate from offline root CA we needed access to a SubCA template. However, because the offline root CA is exactly that, an offline (Off-Domain) root CA, it does not have access to any of the certificate templates which are available to the issuing CAs via ActiveDirectory. Well, using Certreq it is possible to build a “custom-templated” CSR. While this process is not popular, Microsoft does have a command-line reference for it.
After some trial-and-error, we were able to create a “custom” SubCA CSR on our offline root CA manually without any certificate templates.
First, we had to create a policy.inf file containing the following key values. For reference, please see Microsoft’s command-line reference for certreq.exe.
Subject=” CN=servername, OU=organizationalunit, O=organization, L=city, S=state, C=country”
KeyUsage=”CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERT_KEY_CERT_SIGN_KEY_USAGE | CERT_CRL_SIGN_KEY_USAGE”
CertificateTemplate = “SubCA”
We then ran the following certreq command (this can be done on any Windows machine that has certreq.exe available):
certreq -new policy.inf newcsrfile.csr
We submitted the new request by opening the Certification Authority snap-in on the root CA, right-clicking the root CA server node, selecting All Tasks, clicking Submit new request, and selecting our newly-created CSR file from above.
We finally went into Pending Requests to issue the new certificate.
A quick note. Since we generated the CSR on a device other than the device that was going to consume the certificate, we had to specify for the private key Exportable=true in our policy.inf file. It is not best practice to mark private key as exportable, but for this specific scenario, we absolutely had to. Don’t forget to make sure that any traces of the private key are properly cleaned up after it is exported.
To wrap up. It is possible to issue subordinate CA certificate from offline root CA. All you have to do is to build an appropriate policy.inf file to use in combination with a certreq -new command as outlined above.