none
Certificate does not import, PFXImportCertStore() returns NTE_BAD_KEY_STATE

    Question

  • Hi,

    I'm debugging a problem that my customer has. He's trying to move an SSL client certificate from one WinXP SP2 box to another. He exported the certificate into a PFX file. When he's trying to import, he gets the following message:

    "An internal error occurred. The private key that you are importing might require a cryptographic service provider that is not installed on your system."

    The private key is 1024-bit RSA with a SHA1 signature - very plain vanilla. We've tried the steps in KB919074 to no effect.

    I've written a simple test program that asks for certificate file path, export password, then tries to read the certificate into a temp store by means of PFXImportCertStore() - it fails with error 0x8009000b, NTE_BAD_KEY_STATE. The last parameter of PFXImportCertStore() is CRYPT_EXPORTABLE|CRYPT_USER_KEYSET, in case that matters.

    Any ideas why would that happen? This sounds like some kind of CryptoAPI misconfiguration. The providers (Base, Enhanced) are all in place, I've checked his registry.

    UPDATE:

    Still no result, but some details. I've poked around with the debugger and traced the error to the following call stack:

    0x77ab0b9c CRYPT32.dll+0x30b9c - CryptProtectData()
    0xffeb7ad rsaenh.dll+0x1b7ad - MyCryptProtectData()
    0xffebda2 rsaenh.dll+0x1bda2 - TryDPAPI()
    0xffdd599 rsaenh.dll+0xd599 - OpenUserKeyGroup()
    0xffdeb3e rsaenh.dll+0xeb3e - NTagLogonUser()
    0xffded6e rsaenh.dll+0xed6e - CPAcquireContext()
    0x77de8307 ADVAPI32.dll+0x18307 - CryptAcquireContextA()
    0x77de8675 ADVAPI32.dll+0x18675 - CryptAcquireContextW()
    0x77a866c6 CRYPT32.dll+0x66c6 - HCryptProv_Query_Func()
    0x77af5609 CRYPT32.dll+0x75609 - ???
    0x77aef215 CRYPT32.dll+0x6f215 - CryptImportPKCS8()
    0x77af5af3 CRYPT32.dll+0x75af3 - CertImportSafeContents()
    0x77aef800 CRYPT32.dll+0x6f800  - PFXImportCertStore()
    0x401193 ImpCert.exe+0x1193 (that's my code)

    So CryptProtectData fails with NTE_BAD_KEY_STATE, which causes CryptAcquireContext to fail, which causes the import to fail. And that's even before the CryptoAPI starts to do anything about the certificate we're importing. Why would it call CryptProtectData during context acquisition - beats me.

    The CryptProtectData() calls into the Protected Storage service via RPC, and I could not debug that deep remotely.

    This posting describes a similar situation: http://www.derkeiler.com/Newsgroups/microsoft.public.platformsdk.security/2004-02/0345.html
    but we tried the whole excercise under a different, brand new user, to the same effect. So the mess-up is on the machine level, not on the user level.
    Thursday, July 30, 2009 8:16 PM

Answers

  • Resolved. The file
    c:\Documents and Settings\(username)\Application Data\Microsoft\Protect\CREDHIST
    was read-only. Once they cleared the read-only flag, everything was fine. Yay, go me.

    How'd that sad condition come to be, who knows.

    Now. How do I go about writing a Knowledge base article for Microsoft?

    • Marked as answer by Seva Alekseyev Wednesday, August 05, 2009 2:20 PM
    Wednesday, August 05, 2009 2:20 PM

All replies

  • UPDATE 2: scratch the bit about inability to debug the Protected Storage service remotely. It resides in lsass.exe, specifically in lsasrv.dll, and I can debug it all right (after a little DACL adjustment :). Once the customer in question comes back from his vacation, we continue. I'll get a Knowledge Base article out of it yet.

    The customer is on vacation, but I can do some static analysis in the meantime. From the disassembly of lsasrv.dll: SPCryptProtect() calls into GetSpecifiedMasterKey(), which can return NTE_BAD_KEY_STATE. There are several code paths to that spot, it's hard to tell without a live test which one is followed.
    Monday, August 03, 2009 2:30 PM
  • Did you try using the built-in UI for this? For example:

    1. Start | Run | certmgr.msc
    2. Expand the nodes for Certificates - Current User | Personal
    3. Right-click on Certificates, select Import
    4. Point it to your PFX and click through

    One way to determine if you're really having a DPAPI issue is to try the same thing on that PC but as a different user. If that fails, try with a different PC.

    Monday, August 03, 2009 11:44 PM
  • > Did you try using the built-in UI for this?

    It's the first thing my customer tried. If that worked as expected, I wouldn't be exploring the issue in the first place.

    > the same thing on that PC but as a different user

    Yes, tried that under a different account as well. See the last paragraph in the top posting.

    > try with a different PC.

    The certificate installed fine on a different PC. So the file is not to blame. However, they want this certificate on that specific PC. This is home, not office - so replacing the PC is not really an option.

    Tuesday, August 04, 2009 12:57 AM
  • Resolved. The file
    c:\Documents and Settings\(username)\Application Data\Microsoft\Protect\CREDHIST
    was read-only. Once they cleared the read-only flag, everything was fine. Yay, go me.

    How'd that sad condition come to be, who knows.

    Now. How do I go about writing a Knowledge base article for Microsoft?

    • Marked as answer by Seva Alekseyev Wednesday, August 05, 2009 2:20 PM
    Wednesday, August 05, 2009 2:20 PM