I'm using IX509PrivateKey to create a key for an X.509 cert request (as "NT AUTHORITY\NETWORK SERVICE"), and the Create method is generating an access denied (I'm P/Invoke-ing the dispatch interface from C#, so the HRESULT is getting translated to a .NET exception). Process Monitor also shows an access denied attempt to access the key file (the key file is being created).

If I create a user key set instead (by setting MachineContext to false), I see a "File Not Found" instead of "Access Denied". But ProcMon shows nothing; no attempt to access any key files.

In Process Monitor, I was able to determine that "Network Service" did not have access to the key file, so I used the IX509PrivateKey::SecurityDescriptor property to set it. "Network Service" indeed then had access to the key file, but I still received the access denied from Create, and ProcMon still showed an access denied attempt on the file.

What is the path you see denied in Procmon ? IIRC, NETWORK_SERVICE does not have much rigths under `C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys`, where the keys are stored.
–
ixe013Jun 28 '12 at 1:30

The access deined is the key file in the MachineKeys directory in the path you have above. But when the security descriptor is provided, Network Service has full control on that file and still access is denied.
–
JohnCJun 28 '12 at 12:10

1 Answer
1

The call to IX509PrivateKey::Create was occurring within a web service. As a result, it was occurring under impersonation of IUSR. We edited ACLs enabling the wrong user. It turned out to be straightforward access denied, only for an obfuscated user account. This condition can be observed in ProcMon. ProcMon's "Detail" column will clearly indicate (you may have to enable "Advanced Output")that the call was under an impersonated user account.

In order to more tightly control the user account under which the call is made, and the CA is accessed, we moved the request out-of-process. The enrollment API calls are now made from their own Windows service, and exposed via WCF (net.tcp) to the web service running in IIS. That would be my recommendation for others. IMO, the risk of having another "moving part" is outweighed by the lack of control of making the calls within IIS.