locked
[Request for Help] Windows Vista Problem : Repeated Calling of CryptAcquireContext()/CryptReleaseContext() Causes Corruption of Logged on User Key Container RRS feed

  • Question

  • Hello All,

    1. Background
    We have developed an application which creates hashes for some purpose. We created an API for this. Our API internally performs the following sequence of action :

    1.1. Calls CryptAcquireContext() to obtain a handle to a Crypto Service Provider. The 5th "flag" parameter is set to 0. 

    1.1.1 If the call fails and the failure is due to NTE_BAD_KEYSET (which we interpret to mean that the key container of the current logged on user does not exist), we create such a key container by calling CryptAcquireContext() again with flag CRYPT_NEWKEYSET.

    1.1.2 However, in this case, before we later call CryptReleaseContext(), we will delete the key container by calling CryptAcquireContext() again with flag CRYPT_DELETEKEYSET.

    1.2. We proceed to perform hashing via CryptCreateHash() with the handle to the Crypto Service Provider which we obtained in step(1.1). There is always no problem here.

    1.3. After the hashing operation, we proceed to call CryptReleaseContext().
    1.3.1 However, as mentioned earlier in step (1), if a new key set has been created earlier, we will delete this key set first by calling CryptAcquireContext() again with flag CRYPT_DELETEKEYSET.

    1.3.2 We then call CryptReleaseContext().

    2. The Problem
    2.1 The above sequence of action is wrapped up inside our API call which is used by our client.

    2.2 Everything has gone well until recently when they reported to us that the API has failed. After investigating the issue, we discovered the following problem :

    2.2.1 The call to CryptAcquireContext() to obtain a handle to a Crypto Service Provider results in failure. The error was NTE_BAD_KEYSET. As part of the flow of our API, when we attempt to create such a key container by calling CryptAcquireContext() again with flag CRYPT_NEWKEYSET, this too failed.

    2.2.2 We thus deem that the key container of the current logged on user cannot be created at all. To the clients, our explanation is that the key container "has been corrupted".

    3. A Potential Solution
    3.1 We have recently tried a new approach by making the initial call to CryptAcquireContext() with flag CRYPT_VERIFYCONTEXT which we have read in MSDN to be useful because it is meant for applications that do not use public/private key pairs and that performs only hashing and symmetric encryption types of operations. 

    3.2 We have yet to receive any report from our clients.

    4. OS Platform
    4.1 So far, this problem has occurred only in Windows Vista. It has so far not occurred in Windows XP.

    5. Questions
    5.1 Our questions are :
    5.1.1 Has anyone experienced such a problem or anything similar ?

    5.1.2 Is this a known or reported problem in Windows Vista ?

    5.1.3 Will the use of the CRYPT_VERIFYCONTEXT flag help us  to avert key container corruption ? Please note that we suspect the problem is due to repeated calling of CryptAcquireContext()/CryptReleaseContext() many many times.

    5.1.4 I have suggested that we provide an initialization function which is called only once by the client and an uninitialization function that is called only once also by clients. However, this will take time to be approved.

    Thanks, all,
    - Bio.


    • Edited by Lim Bio Liong Friday, December 25, 2009 1:18 AM Making it clear that this is a request for help. Also corrected some grammatic errors.
    Wednesday, December 23, 2009 4:47 AM

Answers

  • Hello All,

    For the benefit of anyone facing similar problems, here are some of our latest findings :

    1.  We now believe that the continuous and numerous calls to delete the key set of the current logged on user (via CryptAcquireContext() with flag CRYPT_DELETEKEYSET) may be the contributing factor to the "corruption" of the key container.

    2. The use of the CRYPT_VERIFYCONTEXT flag in the initial call to CryptAcquireContext() would solve our problem because it renders unnecessary any subsequent creation of a ("temporary") key container by calling CryptAcquireContext() again with flag CRYPT_NEWKEYSET.

    3. We now believe that even if we had created a ("temporary") key container by calling CryptAcquireContext() with flag CRYPT_NEWKEYSET, we should leave this key container alone and need not delete it later. The requirement to delete the key container may be an over-specification.

    4. However, after all is said and done, the use of the CRYPT_VERIFYCONTEXT flag in the first call to CryptAcquireContext() is sufficient for our purposes.

    I guess we can call it and consider this case closed. However, if anyone know of any tools that specifically targets the repair of the key container, please let us know :-)

    Thanks all,
    Bio.

    • Marked as answer by Lim Bio Liong Thursday, December 31, 2009 2:28 AM
    Thursday, December 31, 2009 2:27 AM

All replies

  • Hello all,

    Oh yes : one more v important question : for such a case of key container corruption, is there any way to recover the key container ?

    Unfortunately for us, we advised our client to delete the user account of the current logged on user and then re-create it. But this is not acceptable in the long run.

    Thanks,
    Bio.

    Wednesday, December 23, 2009 4:53 AM
  • Hello All,

    For the benefit of anyone facing similar problems, here are some of our latest findings :

    1.  We now believe that the continuous and numerous calls to delete the key set of the current logged on user (via CryptAcquireContext() with flag CRYPT_DELETEKEYSET) may be the contributing factor to the "corruption" of the key container.

    2. The use of the CRYPT_VERIFYCONTEXT flag in the initial call to CryptAcquireContext() would solve our problem because it renders unnecessary any subsequent creation of a ("temporary") key container by calling CryptAcquireContext() again with flag CRYPT_NEWKEYSET.

    3. We now believe that even if we had created a ("temporary") key container by calling CryptAcquireContext() with flag CRYPT_NEWKEYSET, we should leave this key container alone and need not delete it later. The requirement to delete the key container may be an over-specification.

    4. However, after all is said and done, the use of the CRYPT_VERIFYCONTEXT flag in the first call to CryptAcquireContext() is sufficient for our purposes.

    I guess we can call it and consider this case closed. However, if anyone know of any tools that specifically targets the repair of the key container, please let us know :-)

    Thanks all,
    Bio.

    • Marked as answer by Lim Bio Liong Thursday, December 31, 2009 2:28 AM
    Thursday, December 31, 2009 2:27 AM