I am trying to automate deployment of certificates, including managing permissions on the private key. Using this question, I have cobbled together some code that should update permissions for a certificate:
public static SetPermissionsResult SetPermissions(X509Certificate2 certificate, string userName)
{
var account = new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null);
using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
{
store.Open(OpenFlags.MaxAllowed);
var newCertificate = store.Certificates.Find(X509FindType.FindBySerialNumber, certificate.SerialNumber, false)[0];
var rsa = newCertificate.PrivateKey as RSACryptoServiceProvider;
if (rsa == null)
{
return SetPermissionsResult.Failure;
}
rsa.PersistKeyInCsp = true;
var cspParams = new CspParameters(
rsa.CspKeyContainerInfo.ProviderType,
rsa.CspKeyContainerInfo.ProviderName,
rsa.CspKeyContainerInfo.KeyContainerName)
{
Flags =
CspProviderFlags.UseExistingKey
| CspProviderFlags.UseMachineKeyStore,
CryptoKeySecurity =
rsa.CspKeyContainerInfo.CryptoKeySecurity,
KeyNumber = (int)rsa.CspKeyContainerInfo.KeyNumber/*,
KeyPassword = password*/
};
cspParams.CryptoKeySecurity.AddAccessRule(
new CryptoKeyAccessRule(account, CryptoKeyRights.GenericRead, AccessControlType.Allow));
using (var rsa2 = new RSACryptoServiceProvider(cspParams))
{
}
return SetPermissionsResult.Success;
}
}
On the line that reads using (var rsa2 = new RSACryptoServiceProvider(cspParams))
(where the new crypto provider is instantiated to persist the new access rule), I get a CryptographicException "Keyset does not exist".
I know from experience that this generally means that the current security context does not have permissions to access the primary key. To troubleshoot this possibility, I have done the following:
- Figure out what the current user is with
System.Security.Principal.WindowsIdentity.GetCurrent()
in the Immediate window - Ensure that that user has Full control permission in the MMC snap-in for certificates (and double-checked that I'm looking at the right store for it)
- Granted Full control to the Everyone user.
- Tried creating the CspParameters object with and without the KeyPassword (you can see it commented there).
I am out of ideas. The certificate is a bogus self-signed test cert, so it's not a matter of other certs in the chain missing permissions. Any help would be appreciated.
UPDATE:
I've been able to get this code to execute by modifying some of the flags for the installation of the certificate that precedes this step. Now, the code executes, apparently successfully, but to no visible effect I can see in the MMC.