Impersonating to X509Store.Add to StoreName.Root - The Request Is Not Supported

707 Views Asked by At

I cannot find anything related to the error that I am encountering.

The problem is that I am encountering a CryptographicException on store.Add below:

"The request is not supported."

The MSDN Documentation is not very helpful, it states that:

The certificate could not be added to the store.

I used the following code as a guide, with the following change:

  • They are adding to StoreName.My and I want to add to StoreName.Root
  • I want to use an IDisposable class to impersonate the user.

My proof of concept code (abridged/shoddy):

public class UserLogonImpersonator : IDisposable
{
    private WindowsImpersonationContext _impersonationContext = null;
    private const int LOGON_INTERACTIVE = 2;
    private const int PROVIDER_DEFAULT = 0;

    [DllImport("advapi32.dll", SetLastError=true)]
        private static extern int LogonUser(
        string lpszUserName,
        string lpszDomain,
        string lpszPassword,
        int dwLogonType,
        int dwLogonProvider,
        ref IntPtr phToken);

    public UserLogonImpersonator()
    {
        _impersonationContext = null;
        IntPtr userHandle = IntPtr.Zero;
        const string domain = "domain";
        const string user = "user";
        const string hcpw = "password";

        try
        {
            int logonResult = LogonUser(user, domain, hcpw, 
                LOGON_INTERACTIVE, PROVIDER_DEFAULT, ref userHandle);
            bool isLoggedOn = logonResult != 0;

            if (isLoggedOn)
            {
                _impersonationContext = 
                    WindowsIdentity.Impersonate(userHandle);
            }

        }
        catch(Exception e)
        {
            // Handle Exception
        }
    }

    public void Dispose()
    {
        // UndoImpersonation();
    }

    // Private methods ...
}

public class CertService
{
    public void AddCertToRootStore()
    {
        using(new UserLogonImpersonator())
        {
            X509Certificate2 rootCert = 
                new X509Certificate2(certData.CertFilePath);
            X509Store store = 
                new X509Store(StoreName.Root, StoreLocation.CurrentUser);
            store.Open(OpenFlags.MaxAllowed);
            store.Add(rootCert);
            store.Close();
        }
    }
}

I can remove the impersonation and no exceptions are thrown, but that is not the correct user's store.

With the impersonation, I can put the cert into StoreName.AuthRoot without exception. This is not the store that I want the cert to go into.

Neither of these exception-free solutions will work. I require that the program be run with elevated privileges and go into another user's store.

1

There are 1 best solutions below

0
On BEST ANSWER

I solved this by doing it manually.

I wanted to do this to automate "test chain certificates." Our third party CA gave us a set of certificates for a .local domain.

Our real-life use case would already have the root and chain certificate installed.