1

I have a service that requires access to its own certificate store but gets an access denied.

I checked with mmc and the Certificates snapin for the service and the store exists and contains certificates. However, in the snapin I cannot see or set permissions.

I tried dumping the certificates (for a test, later to change permissions) using certutil but I keep getting a FAILED with "The parameter is incorrect". Syntax I use is

certutil -service -store servicename\my

The servicename is my service's name and "my" is correctly identified as the name of the "Personal" store of the service by certutil. I know the store exists since mmc shows it.

What am I doing wrong with certutil?

Andrew J. Brehm
  • 1,611
  • 7
  • 37
  • 57

1 Answers1

2

I don't think you're able to import certificates into another user's personal store. I would recommend adding it to the machine's store and giving the service user access to the certificates/keys there. You might also try logging on/runas the service user and adding it that way but I've never tried that.

Edit: I have confirmed this after testing, although I am not sure if this is the expected behavior due to poor documentation of certutil. certutil.exe -store -service (StoreName) seems to be the proper syntax to access the certificates under a service store. The service store is located at HKLM\SOFTWARE\Microsoft\Cryptography\Services\(ServiceName)\ in the registry, but certutil inserts the current user's SID instead of the service name when searching like this: HKLM\Software\Microsoft\Cryptography\Services\(SID)\SystemCertificates\, making the search fail. You can override the SID with the -sid parameter, but it doesn't seem to work if you provide the service name. If you look up the service SID with sc.exe showsid (ServiceName) and plug that in, it says "The user name or password is incorrect." It seems that certutil only supports a couple of well-known SIDs (I even tried converting the service SID to its numeric form). If you'd like to replicate my work, you'll need to bust out Procmon.

So, having found that, I am going to assume you can only import certificates if you run certutil under the context of the service. It seems the easiest way to solve your issue would be to either

  1. manually edit the registry
  2. store the certificates in the machine store, and give the service permissions to them
  3. store the certificates in the user store of the user that the service runs as
flashbang
  • 135
  • 1
  • 1
  • 11
  • Potentially related - https://serverfault.com/questions/450831/remove-a-certificate-from-the-windows-network-service-certificate-store?rq=1 – flashbang Jul 08 '21 at 14:36
  • No, that't not it. I don't want to import certificates into another user's personal store. (In fact, neither importing nor another user's store are mentioned in the question.) This is about service stores (not service users' stores) which mmc can look at but certutil apparently cannot. – Andrew J. Brehm Jul 08 '21 at 15:05
  • Hi @AndrewJ.Brehm - I have updated my answer with some research which I believe confirms my original theory. – flashbang Jul 08 '21 at 16:51
  • Interesting observations. But how can I run in the context of the service as opposed to the context of the service account? – Andrew J. Brehm Jul 09 '21 at 18:07
  • Good question, one way I can think of is to use psexec. It seems it supports a `-r` flag which allows you to interact with a service, but that may not work since I think psexec runs as its own service. You could also potentially try something in PowerShell like this: `New-PSDrive MySvcCert -PSProvider Certificate -Root '(ServiceName)\My'` then `cd MySvcCert:` but I've never done that. – flashbang Jul 12 '21 at 16:35
  • Have you tried using the "well known SID" of the local Administrators group or LOCAL SYSTEM? – SamErde Jul 13 '21 at 14:40
  • @SturdyErde I tried one of the well-known SIDs it supported (Network Service - 24) and it inserted the full `S-1-5-20` SID. Didn't feel like checking the others, but I'd assume it would be similar. The other two it claims to support are 22 and 23 for Local System/Local Service. – flashbang Jul 13 '21 at 15:47
  • Those are still sids for accounts. Here I need access to the service's cert store, not a specific account's (and not the service account's either). – Andrew J. Brehm Jul 20 '21 at 07:56
  • I realise this is older, but for anyone else's info, instantiating a PSDrive with the cert provider doesn't work with a Service account root - it seems to be using `[system.security.cryptography.x509certificates.storelocation]`, which only has values for `CurrentUser` and `LocalMachine`. https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.storelocation – LeeM Mar 16 '23 at 05:28
  • Since MS seems to treat `Certutil` as abandonware and isn't fixing the bug or providing a PS alternative, I get around it like this: install the required cert to the LocalMachine store, grant LocalService Read perms, and copy the cert into the Service store location in the registry. To check cert validity and so on, my scripts read the details out of the LocalMachine copy. Another annoyance is that I haven't figured out how to create the Service store the first time without using the Certificates MMC. – LeeM Mar 16 '23 at 05:34