Sinking Our Teeth Into SCEP

In my last post I provided a very high-level overview of some of the certificate related services in Windows Server 2008 R2, and said I would be digging further into the material. Looking through the archives it seems I have been able to produce at least one article pr month since I started this site and it almost looked like I wouldn’t deliver this month. Well, December and January are always busy months, but I did find some spare time to look into SCEP, (Simple Certificate Enrollment Protocol), and thought this was a good time to bring some more details.

The quick recap first; SCEP is a protocol defined by Cisco for enrolling machine certificates. SCEP is implemented in Windows Server as Network Device Enrollment Service (NDES). iPhone uses SCEP for secure bootstrapping/provisioning, and maybe it could be relevant for other devices too.

As far as installation of the NDES role I would recommend the following white paper by MSFT:
http://www.microsoft.com/downloads/details.aspx?familyid=E11780DE-819F-40D7-8B8E-10845BC8D446&displaylang=en

Let’s get down to actually using it. SCEP is implemented as a dll file called mscep.dll which you can interact with through HTTP GET commands. There are a couple of different operations you can specify as the desired action. The first one is called “GetCACaps” which is used to retrieve what operations and behavior the server supports, but this operation is optional and as far as I can tell it is not implemented by Microsoft.

The next, which is supported, and not optional, is “GetCACert”. An example URL of this would be:
https://CA/certsrv/mscep/mscep.dll?operation=GetCACert&message=MobilityDojo
(You’ll notice I’ve attached a message parameter as well, but the message part of the URL can be any random text at this point.)

If doing this in a browser you’ll see a response in the form of a file called “mscep”. Save this as a p7b file, and you will have the entire certificate chain of the CA relating to NDES. If you have a single Root CA, and do a “next-next” install of the NDES role you will have three certificates in the chain; one for the Root CA, and two for the certificate request agents. image

Before moving on to the next step, let’s take a quick de-tour looking at how this setup works on a high level:
You have three URLs that work in your browser
http://CA/certsrv/mscep & http://CA/certsrv/mscep/mscep.dll which will both give you the same html output:
image

http://CA/certsrv/mscep_admin which gives some info for the admin who enrolls the device:
image

And following this these are the steps involved in an enrollment:
- Device generates a key pair (public and private).
- Admin logs on to the admin page in his browser, and retrieves the password.
- Device generates a certificate signing request (CSR), and sends off to the SCEP/NDES server.
- NDES sends the request to the CA. (This can be on the same server.)
- A response is received by the device containing the actual certificate.

It does sound easy doesn’t it. You generate a request, and if you have it in the form of a file it will be a long Base64-string like this (I left out most lines of the string to make the screenshot smaller):
image

And you submit it to the NDES service through the browser:
http://CA/certsrv/mscep/mscep.dll?operation=PKIMessage&Message=MIID9Q=
I’ve left out most of the string here too, but it’s really just copy & paste everything from the CSR file except the first and last lines. You’ll once again get a file called “mscep” back, but it’s not going to work saving it as pfx, cer, etc.

Checking out the Event Viewer on the CA we see something similar to this:
image

Ah, but thing is, when I said generate a CSR above I left out a couple of the finer details. You see, you’re not able to just go through the certificate request process in IIS or the Certificates MMC. As the error indicates you aren’t getting all the details embedded that you need for a SCEP request. I found a neat tool called “ASN.1 Editor” (ASN is the format for CSR files), and thought I would be able to handcraft the request with this utility. Then it occurred to me that generating a valid key pair in my head, using it for signing, and inputting it in the request probably is well above my mental capabilities :) Nonetheless it is a useful utility if you’re generating CSRs and want to “debug” these. (If you have a certificate you already have on file, you can look at that too.)
Hit the link for download: http://lipingshare.com/Asn1Editor

This leaves us to the programmatic approach, and I’d love to have given you all some finished C# code as the next step. I ran into a couple of challenges while testing this though – the first being that support for crypto stuff is so-so in C#, barely present in Compact Framework, and dependent on the OS on the desktop side. Realistically you need to run it on Windows Server 2008/Vista or Windows 7. While I certainly have access to those platforms, and it is workable with some dll imports, it gave me a couple of pointers to where this had to be taken for building a proper solution, but not the solution itself. I initially thought that a client on Windows Mobile was feasible, but maybe it’s more work than it’s worth. You’d also have to go through all the same obstacles implementing it for the Android if that became a feature request, and you’d still have to adapt in some way if using it on the iPhone. (The iPhone already has native support courtesy of Apple Inc. mind you – I’ll get back to that.)

I’ll also admit that learning the crypto APIs required for this was more than I could chew through in an hour. I’ve managed to create a CSR programmatically and getting the same error as above, and I’ve managed to put together a request that crashes the program entirely when running. Basically I have to learn it proper if I want to get it working, and that’s probably an exercise better left for later on when I see a greater need for it. At the moment it’s more of a nice-to-have than need-to-have for what I do. (Man, I felt stupid trying to guess my way to something that would work.)

If you want the “algorithm” it works roughly like this:
Create a PKCS#10 request, wrap it in a PKCS#7 request with a couple of extra attributes (senderNonce, TransactionID, MessageType). Sign this with the public key from the certificate of the RA and submit.

If you want the gory details there’s no way to avoid reading the RFC:
http://tools.ietf.org/html/draft-nourse-scep-20
And this paper is also of great help:
http://www.gamingstandards.com/…/appendix_d_scep_operations.htm

So, let’s say for the sake of discussion that we have solved the coding issues – what would we do next? I’d probably start by removing one more obstacle on the server side. The default install of the NDES role on the CA will require you to use one-time passwords (remember the admin web page?). While this is a good secure by default implementation I find it slightly impractical  for our purposes, so let’s disable it. Navigate to regedit on your CA, and flip the following registry key to 0 (if it doesn’t exist create a DWORD value):
HKLM\Software\Microsoft\Cryptography\MSCEP\EnforcePassword\EnforcePassword

So, the iPhone works you say…How did I solve that since I didn’t see the coding through to the bitter end? Well, I resorted to “cheating” actually :) I installed the latest Feature Pack for an Afaria Server I’ve got running, since this adds iPhone support. The funny thing is that the technical approach I was evaluating was/is very similar to what Sybase have done. I’m not going into the details of the Sybase implementation as some elements are only relevant for the iPhone, and not SCEP enrollment in general, but it basically starts with an SMS sent to the device to trigger the enrollment process. The device generates a request, sends this to a provisioning server, and the server signs this request before passing it onto the CA. The iPhone picks up the generated certificate by talking to the CA directly though, and doesn’t do everything through the provisioning server. (I’m not entirely sure as to when the communication end-points are switched.)

What I’m thinking is that it should be possible to channel everything through a proxy web service so you don’t have to expose the CA directly to the Internet. (Yes, I am aware of a reverse proxy like ISA Server, but not published at all is even better.) This web service could also handle requests from both clients able to generate the actual request themselves, and clients who has to make do with a “light” request and have the server do the rest.

Eventually you should end up with a certificate on your device, and your CA will have it on record if you get it right:
image
Notice how the common name does not easily identify the device.

So, great, another certificate on the device. What to do with it? The iPhone uses it for signing of the provisioning profiles you send to it. You can lock down the iPhone with security policies – like enforcing Power-on-Password, removing YouTube/Camera/AppStore, and the user will not be able to remove it.

While I haven’t investigated it further I believe it should be possible to enforce restrictions like only allowing devices with the proper device certificate to access ActiveSync – while still allowing ActiveSync without the need for VPN tunnels and the like. Like so many other things – the technology is there and it’s up to you to find a use for it :)

19 Responses to “Sinking Our Teeth Into SCEP”

  1. Jay

    Hello,

    Thanks for posting this excellent note on SCEP. We are working on using MS SCEP to provision an iPhone and are running into some issues. We are not getting any help from Apple. The following is a description of our problem.

    I’m using Windows Server 2008 Enterprise with the Microsoft SCEP implementation (NDES) installed and configured. I can verify that a client computer receives a certificate back, but on the iPhone I can only validate that it’s failing because it doesn’t tell me anything other than it failed to install. Through using a packet sniffer, I can validate the following HTTP conversation between the CA/SCEP server and the iPhone.

    The iPhone is sending an HTTP GET command with the URI:
    Location: /certsrv/mscep/
    Operation: GetCACert
    Message: hostname

    The response from the CA/SCEP machine is StatusCode of 200 with a payload of type ‘application/x-x509-ca-ra-cert’, which I have validated through using another host where I can examine the file that it is a p7b file which is a PKCS #7 file.

    The iPhone next issues another GET command, with the URI:
    Location: /certsrv/mscep/
    Operation: GetCACaps
    Message: hostname

    The response from the CA/SCEP machine is StatusCode of 200 with a 0 length content.

    The iPhone next issues another GET command, with the URI:
    Location: /certsrv/mscep/
    Operation: PKIOperation
    Message: message: MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCAJIAEggNnMIAG%0ACSqGSIb3DQEHA6CAMIACAQAxggF9MIIBeQIBADBhMFMxEzARBgoJkiaJk%2FIsZAEZFgNsYWIxFzAV%0ABgoJkiaJk%2FIsZAEZFgdtYXR0bGFiMSMwIQYDVQQDExptYXR0bGFiLU1BVFRMQUJWTTY0MjAwOC1D%0AQQIKYQrpd

    To which the CA/SCEP machine responds with StatusCode 200 with a payload of type ‘application/x-pki-message.’ The contents of the payload are included as an attachment. So, ultimately, it appears that the iPhone doesn’t like the contents of the application/x-pki-message.

    Any thoughts on what could be wrong?

    Your help much appreciated.

    Jay

  2. And I thought Apple was all about being helpful :)

    Jokes aside; tThe first operation, GetCACert, is ok. The second, GetCACaps, is not supported on MS CA (as far as I can tell), so that’s ok too since it’s optional anyways. The third, PKIOperation, which just happens to be the tricky one to get right fails. You get a statuscode 200 because the request was POSTed successfully to the SCEP server, and possibly processed by the CA too. But it most likely failed because the request wasn’t properly built or something.

    You should check the event viewer on the CA – it might provide an error message as to what was wrong with the request – could be missing/incorrect attributes, missing key material, etc.

    Are you letting the iPhone do the actual enrollment, or is there a component server side that is trying to request certificates and provision the result to the iPhones?

  3. Stephen Buck

    I’m having a problem with our Cisco devices auto-renewing their certificates. It seems that since the GetCACaps operation is not supported by Microsoft’s NDES, the devices can’t automatically renew their certs and so generate a new request for a new cert.

    Have you heard if Microsoft is going to support the GetCACaps operation to allow devices to renew their certs?

  4. I do not know if renewing certificates is dependent on GetCACaps since this operation is just about providing info on what the CA supports. So, I do not know if it could be an issue with the templates, or something else security-related.

    Service Pack 1 for 2008 R2 is due in a couple of months, but I have not seen anything in the info regarding this service pack that there will be any updates to the CA role or anything pertaining to NDES/SCEP. It is due in a public beta before the end of July so we’ll just have to take a closer look then. If it’s not added in that release it’s anybody’s guess if/when it will be added. (A new major CA release would probably be a bit into the future.)

  5. Pablo Nunez

    Hi, I don’t know if your are still having problems with the GetCACaps operation, if so, you can check this link: http://www.ipointsystems.com/blog/?p=183

    Is my company’s blog, we also have problems related to the GetCACaps operation not been supported on Microsoft; but we found that you can add the CA Capabilities directly if you built a custom solution, we posted all the information we found there.

    Hope this helps you!

    By the way, thanks for all the information on this post, was excellent and help us to find the fix to our problem.

  6. Thanks for this update Pablo – very interesting.

    I have not done much more work with SCEP on a programmatic level lately – I basically use the SCEP implementation in Afaria for most of my iPhone MDM work. But although I have nothing bad to say about the developers working at Sybase they’re not able to keep track of all these little Apple peculiarities, so bits & bytes stuff like this is necessary to have the knowledge required for implementing/troubleshooting at customer sites.

  7. Thomas

    Hi Andreas!
    Thank you for this interesting post. I want to create a test scenario for iPhone Exchange ActiveSync certificate based authentication. Those certificates should be requested from a central system. This system makes a CSR to a CA that is member of a domain. This CA does a SCEP roll out back to the central system. And the central system sends the mobileconfig,
    including certificate PKCS12 container to the iPhone.

    The problem is, that the requester name of the certificate is always the user which the IIS SCEP Module runs with. In result the assignment to the user and deposit of the certificate in the AD is always wrong.

    Have you ever tried such a configuration?

    Thank you in advance.
    Best regards
    Thomas

  8. I have not tried this scenario, but I would look into the certificate template you use. Some templates specify that the common name of the certificate is the user requesting it, while other templates specify that the common name will be supplied in the request. (I assume you are including the necessary details in the request you are creating.)

  9. Arthur Heijnen

    Microsft has posted a hotfix for the “GetCACaps” Problem.

    “Renewal request for an SCEP certificate fails in Windows Server 2008 R2 if the certificate is managed by using NDES”
    http://support.microsoft.com/kb/2483564/d

    http://mscep/certsrv/mscep/mscep.dll?operation=GetCACaps&Message=1 now outputs a list of capabilities instead of a empty response.

  10. Nice that there’s a proper fix for this. (Even if only as a hotfix you need to request and not part of a regular update.) They don’t mention any Apple products by name, but one suspects Microsoft have been tipped off as to how iOS handles the “missing” CA Caps :)

  11. Ralph

    Hey,

    nice Articel! I have a problem, and perhaps you can help me..

    I have a Windows Server 2008 Enterprise with NDES and an own Microsoft PKI. Everything works fine with configuration profiles and iOS devices.
    Now it would be great if we can configure that a PKI admin must approve the certrequest from the mobile device.
    On the Microsoft PKI I have activated the checkbox in the certtemplate and if a mobile device wants to install the configuration profile a pending certrequest is created. After the PKI admin approve this request the cert is not “sending” to the mobile device. If the mobile device wants to install the configuration profile again a second request is created.
    Thanks!

  12. I don’t think it’s possible. iOS expects everything to be done in one session. If you interrupt the process before the device has received the certificate from the CA, it will start over again when restarting, and a new request will be created.
    I have seen a solution (which I have not tested) in Sybase Afaria where you can install an extra dll on the CA. This dll sets up scep so only devices approved by Afaria can request certificates. It’s not the same as having an admin approve each manually, but achieves the same end purpose (sort of). The problem with manually approving certs is that it’s a process that doesn’t really scale so well. Plus you need to have the ability to configure the common name so that the pending request actually tells you which device you’re looking at.

  13. Chris

    Hi Andreas,

    I have been reading your blog for a solution with EAS not talking to iPhone/iPad with a SCEP certificate. In my lab EAS denies communication with such devices and certificates.
    My lab setup: all Win2008R2 SP1 Servers, Exchange 2010 SP1RU6, Enterprise CA with SCEP service configured and running and, iPhone4/iPad2 (both iOS5).
    I have configured a .mobileconfig file using Apple’s iPCU. It contains the link+dll for the SCEP server, the CA name, a x.500 name with O and CN defined, a valid challenge and both the signature and encryption options are ticked. I’ve also included the Root CA and Intermediate CA certificates in the certificate section of the .mobileconfig file.
    The profile installs fine, adding the root and intermediate certificates, generates a key, send the request to the ca and is issued a valid certificate. I then export this certificate and publish it in Active Directory for the user account.
    I then setup an EAS account on the iPhone/iPad and configure it for the appropiate user. Communication with EAS fails with the message: ASHTTPConnectionErrorDomain error 403.
    I’ve already tried adding Clientauthentication, Secure Email and Encryption to the SCEP template. Still no good.
    If I use a certificate issued on the base of the “User” template, include it in the .mobileconfig file, configure the EAS section with the appropiate details and then select the this user certificate to be used for the EAS communication, it all works like a charm.
    The trick seems to be to have a private key included in the .mobileconfig file and specify this one as the one to be used with EAS. Using a SCEP certificate requested from the device does not work, as I cannot get the private key from the device into the iPCU on the PC.

    Do you have any ideas or suggestions for me?
    Thx a lot and sorry about the looong text :-)

    Best regards
    Chris

  14. Hi Chris,

    It’s an interesting scenario to attach the SCEP certs to the EAS profile, although I haven’t really gotten around to testing it.

    The configuration profile reference state that to attach a certificate to an Exchange payload you need to either attach the certificate as a blob (the contents of a pfx/p12-file) thus including the private key. Alternatively you can use the PayloadCertificateUUID key to reference an identity. I have not checked if there’s a way through iPCU to fetch the UUID required. If you can fetch this UUID you could build a complete EAS profile. Needless to say it would be messy to do mass deployments this way :)

    Using Afaria as a reference implementation, when you build an EAS profile and want to use certificates you can either attach an existing certificate or request a new cert through SCEP. Which means you’ll have one SCEP identity in general for MDM, and another for EAS. Not knowing the profiles being built behind the scenes I don’t know the details, but I’m guessing it’s done this way for a reason.

    I don’t know if you’re trying to build it the manual way just for learning purposes, but ready made MDM solutions are easier :) iPCU doesn’t expose everything the .mobileconfig and .provision files can do as some of it is intended to only do in MDM scenarios where you have a server component controlling parts of the process.

  15. chris

    Hi Andreas,

    thx for the answer.

    I’ve checked the Apple documentation “iOS Configuration Profile Reference” in regards to the PayloadCertificateUUID and did a little messing around with a .mobileconfig
    file. It turns out that what I did describe in my first posting (quote: The trick seems to be to have a private key included in the .mobileconfig file and specify this one
    as the one to be used with EAS.) is exactly what this PayloadCertificateUUID referencing part does. As soon as I configure the certificate section in the iPCU to include a
    private key, a PayloadCertificateUUID is listed in that particular part of the xml code. The next step is to configure the Exchange-ActiveSync part of this config file
    (option: identity certificate – data for connection with ActiveSync). Selecting the same private key from the previous step, adds the same PayloadCertificateUUID to the
    ActiveSync part of the xml code. Thus, the issue remains because I would need to get the private key off of the device to include it in the .mobileconfig file to be able to link this PayloadCertificateUUID.

    What you are describing for Afaria (quote: you can either attach an existing certificate or request a new cert through SCEP. Which means you’ll have one SCEP identity in general for MDM, and another for EAS) got me thinking. Doesn’t that mean that the Afaria system is managing the private part of the key? How else would they be able to do the PayloadCertificateUUID referencing part described above? Is the Afaria system generating the certificate request and passes the private key on to the device? How does
    that impact the security of the private key?

    I’ll get the Apple documentation for MDM solutions and have a read. Maybe that’ll sched some more light :-)

  16. chris

    I did some more digging and it seems that I need to configure the CA for key archival and designate a trusted user to be able to recover private keys. If that works out, I should be able to obtain the private part of the SCEP certificate and include it in the .mobileconfig file…

  17. I noticed an interesting thing yesterday with iPCU. If you create a SCEP payload, and then create an Exchange payload you can actually select that the identity provided by SCEP will be used in the Exchange payload.
    But this seems to only apply for the OSX version of iPCU…
    If you have access to a Mac that would kind of be a solution. (You could at least verify a correct .mobileconfig that way.)

  18. chris

    Well, that did work :-)
    I have used a Mac to create the profile and was able to link the SCEP part to the EAS part. The SCEP services is now issuing certificates which can be used for 802.x and EAS. Works like a charm. Thx a lot for the hint :-)
    The part where I tried to store the iPhone’s private key in the CA’s DB didn’t work out, as the device is refusing to send the private part of the key. The SCEP server was showing a message stating the operation had failed due to a missing private part of the key.

  19. So Chris

    Would you please summarize the steps it took to create the profile on the Mac and how you linked the SCEP part to he EAS part? I am looking to completely automate this for a large number of OS X machines using Apple’s /usr/bin/profiles tool.

    TIA!

Leave a Reply

*
RSS for Posts RSS for Comments