How the AD Certificate Profile got into macOS when I was at Apple

I have created a macOS command line tool called “tcscertrequest” that submits requests to a Microsoft Certificate Authority from the macOS command line. The request is sent the same way it would be sent from a Windows computer so no modifications to the Windows infrastructure is required to work with the Mac. The history of the project is interesting, but if you just want to learn about the tool, skip down to The tcsertrequest Command Line Tool section below. If you think you might be interested in using this tool, ping me on twitter @tperfitt, the macadmins slack channel #twocanoes-certrequest, or send us an message via our contact form on Twocanoes.


How the AD Certificate Profile got into macOS when I was at Apple

and a new open source project called tcscertrequest

By Tim Perfitt

I worked at Apple in 2011 with enterprise customers to help them integrate Macs into their environments. The iPhone had really taken off, and there was a big push to use SCEP to get certificates for WiFi and other services that required digital certificates. Most large organizations, however, didn’t issue digital certificates via SCEP, they used the Microsoft Certificate Authority (MSCA) service in Windows Server. There was an add-on to the MSCA for SCEP (named NDES), but it was limited as NDES was generally used for routers / fixed devices renewing certificates. Configuration profiles were just coming to the Mac and the SCEP profile was include as one of the profiles available on the Mac. The problem was that it required large organizations to modify their MSCA to support SCEP, and it still didn’t get them the types of certificates they needed for 802.1X and any other services on the Mac that require certificate-based authentication.

But here’s the thing: There was something that did work to retrieve certificates and it was the Web CA component of MSCA. It had problems, though. Using the Web CA meant turning on IIS / Web Services and giving web services access to the certificate authority. Enterprise environments resisted doing this because of security issues with web access. To top it off, a lot of the Web CA web pages only worked in IE 6, so it sometimes required upgrading Windows services to get it to work properly on the Mac. Instead of saying “the Mac just works” with certificates in these enterprise environments, IT had to do a bunch of infrastructure changes. So that led me to ask some questions: How do Windows systems get certificates? Can the Mac get certificates the same way?

The answer to the first question was easily answered. Windows requests certificates via DCE/RPC. DCE stands for distributed computing environment and RPC stands for remote procedure calls. DCE/RPC uses Kerberos for authentication and provides a way for distributed machines to do remote calls to Windows services. Could a Mac call those same APIs to make a certificate request?

If you look in /System/Library/PrivateFrameworks/ in macOS, you’ll find the DCERPC.framework. As it turns out, the DCE/RPC framework is an open source project with a long history. It involves Novell, Likewise, IBM, and others. This framework is how the SMB client on macOS talks to Windows servers. Luckily for me, there were some amazing folks in Apple’s CoreOS team who were also part of the Open Source community that worked on DCE/RPC and they helped me a bunch as I did research.

The first thing I discovered was that working with DCE/RPC on the Mac wasn’t just about sending a certificate request. There needed to be an authenticated request (authenticated as the machine account or a user) sent for DCE/RPC to work. Fortunately, Windows Server uses Kerberos as an authentication mechanism for DCE/RPC calls. Now I knew it was possible to make the authenticated call using kerberos but how could I actually implement it?

Interestingly, it turns out that only a single API call is really needed to make the Kerberos authenticated call: CertServerRequest. In order to call that single API, you had to have a properly defined interface that can be compiled with a dce compiler. So, with a lot of advice from the Open Source folks and a bunch of late nights reading old O’Reilly books, I got the interface compiled, figured out the data structure of the Certificate Signing Request (CSR) and other data to pass to the function, and got my first certificate signed via the Microsoft Certificate Authority.

This. Was. Huge.

I could now generate a Certificate Signing Request using Keychain Utility, or on the command line on the Mac using OpenSSL, and submit it natively to a Microsoft Certificate Authority without any changes required to the Windows environment. I documented my steps, provided some sample code, and submitted a feature request to have this process added as part of macOS so that certificates to a Microsoft CA could be configured via a configuration profile. I kept track of the progress of my enhancement request in Radar (Apple’s bug tracking system).

Then something interesting happened.

One of the managers said that folks in iOS software engineering were asking about the process I’d outlined. I thought this was great at first, but then he broke the bad news to me: since iOS was so secretive, he could not longer talk to me about the enhancement request and I could no longer access the issue in Radar.

My radar went dark for a few months but I was still happy. I had a way to get certificates signed in a standard Active Directory environment from macOS. Getting a way to submit the request via a configuration profile included in the OS was just gravy.

Around this same time I decided to leave Apple and start Twocanoes Software. Right before I left, I was talking to a friend who was in AppleCare Enterprise Services and he was helping me test and document the DCE/RPC findings. I told him that my one regret was that I hadn’t gotten the DCE/RPC stuff into macOS before leaving. My buddy said that he’d make sure it would happen. And sure enough, a few months (or maybe many months later), I got a message with this link:

Request a certificate from a Microsoft Certificate Authority – https://support.apple.com/en-us/HT204602

In later releases of macOS, they even added certificate renewal via DCE/RPC. That same AppleCare buddy mentioned that when ‘packet level privacy’ became the default RPC authentication level in Windows 2012 Server, macOS also got enhanced to support that higher level of security.

And that, my friends, is the story of how the DCE/RPC configuration profile came into being on macOS.

Using the tcscertrequest Command Line Tool

I was thinking about the DCE/RPC configuration profile project recently, and wondered if macOS 10.13 could make the same API call to a Windows Server 2016 Certificate Authority.

Using the same process I’d done back in 2011, I compiled the interface and created a new tool called tcscertrequest. I set up a Microsoft Certificate Authority and Active Directory. I did not enable the Web CA since it is not required for requesting certificates over DCE/RPC.

To use the tcscertrequest tool, a certificate signing request is needed, as well as the DNS name of the MS Certificate Authority, the name of the Certificate Authority, and the name of the template in the Microsoft Certificate Authority.

A template is a collection of settings that tells the MS CA what information to include in the certificate and who is allowed to submit the request. The Microsoft CA has preconfigured templates, and the ones most commonly used are User and Computer. The User template is commonly used for certificate-based authentication via Smart Cards and websites. The Computer template is commonly used for 802.1X certificate-based authentication and other services that the computer authenticates to. Here is what the templates look like in the Microsoft Certificate Authority:

The most common templates are Computer or User. When a request is submitted to the Certificate Authority, the request specifies a template that the CA uses to determine what information to populate in the certificate that is generated. The template also specifies what type of user is allowed to use that template to generate a certificate. A Computer template usually requires a Kerberos ticket from the machine credentials, and the User template usually requires a kerberos ticket from an Active Directory User.

The syntax to use when the tcscertrequest tool is called is:

tcscertrequest -r <csr path> -s <server dns name> -c \
<name of ca> -w <output file path> -t <template name>

The best way to illustrate how to use the tcscertrequest tool is with some examples. I’ll show two examples below: One with machine credentials and one with a user credentials. You don’t need to be bound to Active Directory to use this tool, but binding does make it easy to get Kerberos tickets. For these examples, the test Mac will be bound to Active Directory.

Example 1: Computer Certificate

The first example shows how to get a computer certificate. The first step is to get a kerberos ticket with the machine credentials (in this example, the Mac is named MachPower):

MachPower:~ tperfitt$ sudo kinit -k machpower$

Now the kerberos ticket can be viewed using the klist command to see that a Kerberos Ticket Granting Ticket (TGT) has been issued:

MachPower:~ tperfitt$ klist

Credentials cache: API:3FB02FDF-608F-4548-AFEC-85BFFBF4E073
Principal: machpower$@TWOCANOES.COM
Issued                Expires               Principal
Jan 27 22:53:33 2018  Jan 28 08:53:33 2018  krbtgt/TWOCANOES.COM@TWOCANOES.COM

Next, a certificate signing request is needed. There are many ways to do this on the Mac, but a simple way is to use the OpenSSL command line tool. The Computer template requires that the common name, or CN, match the computer name in the certificate, so that must be included in the signing request using the “subj” command line argument. The format of the CSR is expected to be DER (binary version). The CSR doesn’t need to be encrypted with a password, so the “nodes” option will be specified. Finally, the options to save the certificate in a file called twocanoes.csr and the private key to a file named twocanoes.key will be given.

Here is what the final command looks like:

MachPower:~ tperfitt$ openssl req -nodes -newkey rsa:2048 \
-keyout twocanoes.key -out twocanoes.csr -subj '/CN=machpower' \
 -outform der
Generating a 2048 bit RSA private key
writing new private key to 'twocanoes.key'

Now that the kerberos credentials have been received and a signing request has been generated, the CSR can be submitted to the Windows Certificate Authority. As mentioned earlier, the Common Name of the Certificate Authority (tcsca in this example) must be given along with the Certificate Authority Server DNS name (win-fgivt3j3gi9.twocanoes.com in this example).

Here is the final command:

MachPower:~ tperfitt$ ./tcscertrequest  -r twocanoes.csr  \
-c tcsca -s win-fgivt3j3gi9.twocanoes.com -w machine.cer -t Machine
Certificate issued.
Certificate saved to machine.cer. 

Success! The machine certificate has now been generated and can be viewed with Quicklook:

In the Windows Certificate Authority, it shows the issued certificate:

Example 2: User Certificate

The second example shows the same process, but with user information and credentials.

First, a Kerberos ticket is requested for an Active Directory user. In this example, the Active Directory user is Administrator:

MachPower:~ tperfitt$ kinit Administrator
Administrator@TWOCANOES.COM's password: 

After authenticating, a kerberos TGT has been issued:

MachPower:~ tperfitt$ klist
 Credentials cache: API:EA1EADF6-195E-4503-A92D-8FA11A8FA327
 Principal: Administrator@TWOCANOES.COM
 Issued                Expires               Principal
 Jan 27 22:57:16 2018  Jan 28 08:57:13 2018  krbtgt/TWOCANOES.COM@TWOCANOES.COM

A certificate signing request is generated using the OpenSSL command line tool, with options to save the key as Administrator.key, the CSR as Administrator.csr, use a Common Name of Administrator, and output in DER format:

MachPower:~ tperfitt$ openssl req -nodes -newkey rsa:2048 \
-keyout Administrator.key -out Administrator.csr \
-subj '/CN=Administrator' -outform der
Generating a 2048 bit RSA private key
writing new private key to 'Administrator.key'

The new certificate signing request can be submitted to the CA for signing using the CA common name of tcsca, the DNS name of the Microsoft Certificate Authority, and the User template.

MachPower:~ tperfitt$ ./tcscertrequest  -r Administrator.csr  -c tcsca -s win-fgivt3j3gi9.twocanoes.com -w Administrator.cer -t UserCertificate issued.
Certificate saved to Administrator.cer.

The user certificate is now issued and the Administrator certificate can be viewed with Quicklook:

In the Microsoft CA, the successful request can be viewed under Issued Certificates:


So the tool works equally well for computer and user certificates in a standard AD environments without the web CA because it is using DCE/RPC. 

Where to find the tcscertrequest Command Line Tool

A package installer for tcscertrequest command line tool for macOS is available from the download section of the github repository here.

Building a better tcscertrequest Tool

There are a bunch of improvements that could be done to the tcscertrequest tool, such as:

  1. Include certificate signing request generation
  2. Do the certificate signing request in keychain with a non-exportable key in keychain
  3. Do the certificate signing request via the secure element on TouchBar Macs / iMac Pro
  4. Associate the certificate with a WiFi config for 802.1x
  5. Look up information in Active Directory (DNS name of CA, etc)

If you think you might be interested in using this tool, helping to improve it, or making suggestions, ping me on twitter @tperfitt, the macadmins slack channel #twocanoes-certrequest, or send us an message via our contact form on Twocanoes.