none
CryptographicException when using X509Certificate2 constructor to load self signed certificates that are not in the store

    Question

  • I'm working on an application that is using WCF message based security and experimenting with providing self signed certificates on both the client and server portions of the application. Recently when attempting to run the server portion of the application on a Windows 2003 Server running under the usual Network Service account, I've noticed that I've been getting exceptions when calling the constructor for the X509Certificate2 class.

    So far what I've noticed is that there were two issues I was running into innitially, one I believe we have found a workaround for and the second is what I'm still working on.

    1. On machines running Windows 2003 Server or Windows XP it appears that attempting to use the constructors that do not take passwords in order to load a certificate from a .pfx file that has no password seems to fail with an CryptographicException.

    Type: CryptographicException
    Stack Trace: at
    System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32
    hr)
    at
    System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[]
    rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet,
    SafeCertContextHandle& pCertCtx)
    at
    System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[]
    rawData, Object password, X509KeyStorageFlags keyStorageFlags)
    at
    System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[]
    rawData, String password)
    at CertTester.Program.Main(String[] args)


    WORKAROUND
    It appears that if you instead explicity pass in an empty string "" for the password when calling the constructor to the X509Certificate2 class that the issue seems to be no more. Strange but this doesn't seem to be a problem at all on Vista either way.

    2. When running in restricted mode or under the ASP.NET default account "NETWORK SERVICE" on 2003 Server or XP again you will get a CryptographicException with the message "Access is denied." A full stack trace is given below.
    Exception: Access is denied.

    Type: CryptographicException
    Stack Trace: at
    System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32
    hr)
    at
    System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[]
    rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet,
    SafeCertContextHandle& pCertCtx)
    at
    System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[]
    rawData, Object password, X509KeyStorageFlags keyStorageFlags)
    at
    System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[]
    rawData, String password)
    at CertTester.Program.Main(String[] args)


    I ran ProcMon.exe in order to see what was going on and it looks like I'm getting ACCESS DENIED on a few items that I'll list below.

    QueryOpen C:\Documents and Settings\MYUSERNAME\Application Data
    CreateFile C:\WINDOWS\Debug\UserMode\ChkAcc.log
    CreateFile C:\Documents and Settings\MYUSERNAME\Application Data\Microsoft\CLR Security Config\v2.0.50727.42\security.config
    CreateFile C:\Documents and Settings\MYUSERNAME\Application Data\Microsoft\CLR Security Config\v2.0.50727.42\security.config.cch
    QueryOpen C:\Documents and Settings\MYUSERNAME\Local Settings\Temporary Internet Files

    RegCreateKey HKCU\Software\Microsoft\Windows NT\CurrentVersion\Winlogon
    QueryOpen C:\Documents and Settings\MYUSERNAME\Local Settings\Temp
    CreateFile C:\Documents and Settings\MYUSERNAME\Application Data\Microsoft\Crypto\RSA\S-1-5-21-771398147-3444043734-1454783757-1635

    Currently we are using the version of the constructor that takes a byte array in order to load the certificate from an embedded resource but we have tried loading our .pfx files directly by specifying the file path and we get the same results.

    I would greatly appreciate any advice anybody could give on getting around this issue.

    Tuesday, February 10, 2009 5:12 PM

Answers

  • It appears that we have found the solution to this problem by using one of the other constructors that takes a X509KeyStorageFlags value as a parameter like so.

    X509Certificate2 cert = new X509Certificate2(certBytes, string.Empty, X509KeyStorageFlags.MachineKeySet); 

    This seems to have solved the issue both for when running under the Network Service account as well as running under a user account with restricted access.
    • Marked as answer by kainhart Tuesday, February 10, 2009 5:22 PM
    Tuesday, February 10, 2009 5:22 PM

All replies