1

I'm working on a NT service that uses SChannel to support client TLS connections. Certificates are installed manually via Local Machine Certificate Manager (certlm.msc) into a custom cert store, called "Public Hub Interface". The service has already been in production for several months now and, apart from the issue below, is running smoothly.

Although everything works fine under LocalSystem, to maximize security, I'm trying to use a virtual service account, such as "NT Service\Public Hub Interface". However, because the account is so heavily restricted, the service no longer has access to the system's private keys, which, consequently, causes AcquireCredentialsHandle to return SEC_E_UNKNOWN_CREDENTIALS. I've tried manually and programmatically granting access to various file and registry objects, as outlined in the following links, but with partial success - CAPI certificates work, but not CNG.

https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/d2a477c4-c366-4a68-8014-83632651bc91/how-to-grant-an-account-access-to-the-certificate-in-a-service-store-programmatically?forum=windowssecurity

https://learn.microsoft.com/en-us/windows/desktop/seccng/key-storage-and-retrieval

https://learn.microsoft.com/en-us/windows/desktop/SecCrypto/modifying-key-container-access

https://www.codeguru.com/cpp/i-n/internet/security/article.php/c6211/Security-Certificates-Treatment-with-CryptoAPI.htm

There are others, but they all pretty much say the same things. Additionally, many of the solutions work on individual certs and assume direct access to them or, at least, knowledge of their locations. Unfortunately, this isn't the case for me, as the certs are installed externally via certlm, and, a separate, custom cert installation app is not in the game plan. Indeed, I'm more interested in accessing the containers, as opposed to working on their specific contents, if possible. Furthermore, there are many certs, of which none are known ahead of time and most are usually installed well after the service is in operation.

I'd rather not switch from the local machine's store provider to the service's (i.e. current user's) store provider, especially since I'm very close to release and don't have the time to modify/retest already working code, let alone re-import the certs as well as retrain operators on a new procedure. As such, I'm hoping there's a simple and reliable way to grant the service the same access to the system private keys that the LocalSystem account has.

Please note that the service is installed via a MSI package that uses an unmanaged C++ custom action DLL to perform advanced operations, such as configuring service recovery options and creating the cert store; I'm planning on using this same DLL to set up the required access during installation. That said, I'd prefer a programmatic solution to one that uses an external program (e.g. WinHttpCertCfg.exe or CertUtil.exe), which might not even work on the target system, or, would have to be included in the package if it doesn't yet exist.

Many thanks for any assistance.

Luxabundus
  • 33
  • 4
  • Is it useful to set permissions with this tool:[SubInACL](https://www.microsoft.com/en-us/download/details.aspx?id=23510)? – Drake Wu Apr 16 '19 at 10:08
  • Unfortunately, no. Mainly because I don't even know what objects need to be accessed. This might work if I can first identify the keys or folders, but, by that time, I'd be able to do this programmatically, which is preferred. Thanks anyways. – Luxabundus Apr 19 '19 at 19:47

0 Answers0