Last year I wrote an blog article about how to trust somebody else’s root certificate with name restrictions. This allows you to trust a vendor/partner/etc root certificate without giving them the possibility of spoof google or any other company they shouldn’t sign for.
Same notice goes on this post. Not all operating systems honor name restrictions. So are you running mostly MacOS machines this won’t help that much.
So let’s get going.
The simple solution:
- Get root certificate from vendor/partner
- Create CSR from certificate
- Verify CSR
- Sign CSR
- Push intermediate certificate to clients, automatic with Windows and use of correct Template.
The more detailed version
Get root certificate from vendor/partner
I choose to download a private google CA. Just for show 🙂 google seems to run their PKI under https://pki.goog/.
So I downloaded GTS LTSR, gtsltsr.crt I will be using this one.
Create CSR from certificate
Now we need a little magic. We will be using the -policy attribute of certreq.exe. The documentation specifies command to run is: certreq -policy certsrv.req policy.inf newcertsrv.req
BUT, it doesn’t really specify how the policy.inf file should look. This is a sample that I have used.
[Version]
$Signature="$Windows NT$"
[NameConstraintsExtension]
Include = NameConstraintsPermitted
Exclude = NameConstraintsExcluded
Critical = True
[NameConstraintsExcluded]
DNS=.secure.example.virot.eu
[NameConstraintsPermitted]
DNS=.example.virot.eu
IPADDRESS=172.16.0.0,255.240.0.0
[RequestAttributes]
CertificateTemplate = CrossCA
[PolicyStatementExtension]
; list of user defined policies
Policies = LimitedUsePolicy
CRITICAL = FALSE
[LimitedUsePolicy]
OID = 1.3.6.1.4.1.311.21.47
Notice = "CA to be used for lock down google"
[BasicConstraintsExtension]
; Subject Type is not supported always set to CA
; maximum subordinate CA path length
PathLength = 1
The important part is under NameConstraintsPermitted. You can do the other way to, but specifying which they cant use seems harder. Or you could combine. I will suggest always using permitted and if needed excluded.
Then we just run this:
C:\temp>certreq -policy gtsltsr.crt ca_policy.inf gtsltsr.csr
Active Directory Enrollment Policy
{B0B1FDA0-7185-46EA-B564-726E86FD6D6D}
ldap:
Searching for private key...
You will get questions for the private key. If you have it please help certreq to it now. This will help later..
Verify CSR
I always tell people to inspect your CSR’s prior to signing. Microsoft has included a tool for this, certutil.exe has no problems with this.
C:\temp>certutil -dump gtsltsr.csr
PKCS7/CMS Message:
CMSG_SIGNED(2)
CMSG_SIGNED_DATA_CMS_VERSION(3)
Content Type: 1.3.6.1.5.5.7.12.2 CMC Data
PKCS7 Message Content:
================ Begin Nesting Level 1 ================
CMS Certificate Request:
Tagged Attributes: 1
<Lots of lines removed>
2.5.29.30: Flags = 1(Critical), Length = 65
Name Constraints
Permitted
[1]Subtrees (0..Max):
Other Name:
Principal Name=
[2]Subtrees (0..Max):
RFC822 Name=
[3]Subtrees (0..Max):
DNS Name=.example.virot.eu
[4]Subtrees (0..Max):
Directory Address
[5]Subtrees (0..Max):
URL=
[6]Subtrees (0..Max):
IP Address=172.16.0.0
Mask=255.240.0.0
Excluded
[1]Subtrees (0..Max):
DNS Name=.secure.example.virot.eu
2.5.29.19: Flags = 1(Critical), Length = 8
Basic Constraints
<Lots of lines removed>
Sign CSR
Now we come to the point where the question is did we sign the CSR with the key. If we look at the microsoft certificate template. We will find the following section:
If you didn’t sign the csr with a key, you will need to uncheck “This number of authorized signatures”.
For more information about this please read the open specifications from Microsoft.
C:\temp>certreq -submit gtsltsr.csr
Active Directory Enrollment Policy
{B0B1FDA0-7185-46EA-B564-726E86FD6D6D}
ldap:
RequestId: 1169
RequestId: "1169"
Certificate retrieved(Issued) Issued
Distribute intermediate certificate
This can differ much depending on your setup.
For instance you might have multiple domains where you want to distribute the intermediate certificate to.