A few days ago I worked in a test environment that also consists of a PKI. I used the Microsoft Terminal Services Client (mstsc.msc) for a while to connect to various machines in the test environment. One day, I helped a coworker troubleshooting a certificate problem in the test environment. From his machine, I connected via Microsoft Terminal Services Client to one of the test servers. While connected to the test server, I opened the Certificates MMC snap-in (certmgr.msc) and looked to the current user’s personal certificate store. Besides test certificates I also saw certificates with my personal name in the subject attribute. What was going on here, I thought? Where do these certificates come from? Time to investigate!

Investigation

I opened one of the certificates with my name in it to find out more details. The certificate definitely belonged to me. Even worse, the General tab of the certificate details told me that I have a private key for this certificate (“You have a private key that corresponds to this certificate.”). I copied the serial number of that certificate from the Details tab and opened a command prompt. What certificate service provider was used to issue that certificate?

The following command told me the answer:

certutil -v -silent -user -store My "05 05 1c 00 22 7f 3c dd fa 98" | find "Provider ="
Provider = Microsoft Base Smart Card Crypto Provider

I looked down to the notebook and noticed that no smartcard was sitting in the reader. That made me even wonder more. What has finally happened here?

Analysis

  1. When I connected to the test environment from my personal notebook, my smartcard was in the reader while I was using a Terminal Services session.
  2. I didn’t use a custom RDP file when I started the Microsoft Terminal Services Client (mstsc.msc), so the settings from %USERPROFILE%\documents\Default.rdp configuration file have been applied.
  3. Under the Options >>> button on the Local Resources tab under the More … button, Smart cards was check-marked. That setting caused the Microsoft Terminal Services Client to map my smartcard into the remote desktop session.
    image
  4. On the remote test server, the Certificate Propagation service (CertPropSvc) was running.

The combination of those 4 conditions caused my personal certificates to appear in the user profile of the remote desktop session. The Microsoft Terminal Services Client maps the smart card reader as a device into the remote desktop session. If a smartcard is available in the reader, the certificates become accessible within the remote desktop session. The Certificate Propagation Service (CertPropSvc) reads certificates (not the private keys!) from a smartcard and puts them into the current user’s certificate store. This is exactly what has happened here.

The reason why the Certificate Propagation Service is doing so, is related to certificate autoenrollment. When autoenrollment is triggered as part of the regular group policy interval (default is every 8 hours with a timescew of +/-90 minutes) it examines certificates in the personal store and determines if certificate enrollment, renewal or archival is required. To enable autoenrollment for certificates on smartcards, it is required that these certificates are registered in the personal store. Otherwise, autoenrollment would have to know on which devices (smartcards, tokens, …) certificates have ever been stored. For every certificate that is associated with a private key on the local system, an entry for the certificate service provider (CSP) exists in the key properties. Once autoenrollment has access to a certificate and the CSP, it is able to manage a certificate that is stored on a device.

A question remains, regarding the statement “You have a private key that corresponds to this certificate.” on the General page of the certificate details dialog. Why is that? How could the system tell me that there is a private key while my smart card is not inserted into the reader? Here is the answer: When the Certificate Propagation Service reads a certificate from the card, it is a true statement that you have a private key for the certificate. The private key is available on the smartcard and therefore, in the certificate’s key property (which is stored in the certificate store) it is noted that a private key is there. However, the key property which links a certificate with a key is only written once when a certificate is copied into the certificate store. There is no later update mechanism that continuously verifies the key property. So in my case, the key property was created when the Certificate Propagation Service read the certificate from my mapped smart card and at that time, the private key was available to the system. However, if the smart card with the key on it is removed from the system, the key property is not updated.

To summarize, the Certificate Propagation Service just copied my certificates into the certificate store while the private key was available on the smart card. The security of my private keys was not at risk at any time. Only the certificates – which can bee treated as public information anyways - have been disclosed.

Prevention and cleanup

What have I done to avoid distribution of my certificates when working with remote desktop sessions? The simplest thing is to manually uncheck the Smart card mapping in the Microsoft Terminal Services Client. This can also be done with group policies. Since all four conditions from above have to be true, disabling the Smart card mapping is effective. Additionally I stopped the Certificate Propagation Service with a group policy on all servers in the test environment. This optional configuration step avoids unintended certificate distribution in case a unmanaged workstation still has enabled Smart card mapping.

Finally, I used the following command to manually remove the certificates from a user profile:

certutil –user –delstore My "Firstname Lastname"

In my case, manual cleanup was doable because the number of remote profiles was low. An automated solution would be required if a broader certificate store cleanup is required. But that’s another story …