0 votes
by (150 points)
edited

I am getting the error "Unable to Load PFX (0x80090020)." This happens when i issue the line: CertificateChain chain = CertificateChain.LoadPfx(CertPath, CertPassword);

This happens on all userids except my own user; including our all powerful domain admin userids.

Any idea what is causing this error?

Thank you, Bob Feller

Applies to: Rebex FTP/SSL

1 Answer

0 votes
by (144k points)
edited
 
Best answer

Unfortunately, this error is not very specific. It was reported by Windows CryptoAPI's PFXImportCertStore function. Its code is NTE_FAIL and it means that "an internal error occured", which is not helpful at all.

Are you able to import these PFX files into the certificate store by double-clicking them in Windows explorer when running under the same user account as the one under which the application runs? Is this an ordinary application executed by the user, or is it a service or an ASP.NET application? Is there any difference if you specify KeySetOptions.MachineKeySet as the third argument of CertificateChain.LoadPfx method?

The following C# code should reproduce the issue without using any Rebex code:

    using System.IO;
    using System.Runtime.InteropServices;

    ...

    public const uint CRYPT_EXPORTABLE = 0x0001;
    public const uint CRYPT_USER_PROTECTED = 0x0002;
    public const uint CRYPT_MACHINE_KEYSET = 0x0020;
    public const uint CRYPT_USER_KEYSET = 0x1000;

    [StructLayout(LayoutKind.Sequential)]
    public struct CRYPT_DATA_BLOB
    {
        public int cbData;
        public IntPtr pbData;
    }

    [DllImport("crypt32.dll", SetLastError = true)]
    public static extern IntPtr PFXImportCertStore(ref CRYPT_DATA_BLOB pPfx, [MarshalAs(UnmanagedType.LPWStr)] string szPassword, uint dwFlags);

    static void Main()
    {
        string pfxPath = ...;
        string pfxPassword = ...;

        // load PFX/P7B data
        byte[] data = File.ReadAllBytes(pfxPath);

        // allocate unmanaged memory for PFX/P7B data
        IntPtr pbData = Marshal.AllocHGlobal(data.Length);
        Marshal.Copy(data, 0, pbData, data.Length);

        // create a blob to pass to PFXImportCertStore method
        CRYPT_DATA_BLOB pPfx = new CRYPT_DATA_BLOB();
        pPfx.cbData = data.Length;
        pPfx.pbData = pbData;

        IntPtr handle = PFXImportCertStore(ref pPfx, pfxPassword, CRYPT_USER_KEYSET);
        if (handle == IntPtr.Zero)
        {
            int errorCode = Marshal.GetLastWin32Error();
            Console.WriteLine("Error occured: {0:X8}", errorCode);
        }
        else
        {
            Console.WriteLine("Import successful.");
        }

        // free the unmanaged memory
        Marshal.FreeHGlobal(pbData);            
    }

(If you prefer VB.NET, please let us know.)

Please give this a try and let us know whether the problem persists. If it does, we would know this is not a Rebex issue and can ask elsewhere.

by (150 points)
edited

Thank you very much! The KeySetOptions.MachineKeySet did the trick. I appreciate your fast response.

Thanks, Bob

...