Hi all,

When working with RSACryptoServiceProvider, we may get an exception like the following:

System.Security.Cryptography.CryptographicException: Unable to open the access token of the current thread
   at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
   at System.Security.Cryptography.Utils._GetKeyParameter(SafeKeyHandle hKey, UInt32 paramID)
   at System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle)
   at System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
   at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 dwKeySize, CspParameters parameters, Boolean useDefaultKeySize)
   at System.Security.Cryptography.RSACryptoServiceProvider..ctor(CspParameters parameters)

I've seen this exception i.e. when signing an XML with a certificate associated to a specific Cryptographic Service Provider (CSP).

Let's use my CryptoAPI Tracer script to get all CryptoAPI calls that .NET is making behind the scenes. This will help us to know exactly what's going on.

We can see in the logs generated by the script the call to CryptAcquireContext we make to get the key container of the certificate. We can also see the CSP associated to the certificate:

CryptAcquireContextA (0xd8c)

IN
pszContainer
00228620  "2e065b6c-027a-4746-bdf3-901a9980"
00228640  "66ea"

pszProvider
00205e60  "Third-party CSP"

dwProvType
PROV_RSA_FULL

dwFlags
0

OUT
hProv
0x228248

RESULT
CryptAcquireContextA (0xd8c) SUCCEEDED

Note: I won't use the real name of the third-party CSP where I detected this issue. This post is for illustration purposes only. I don't prettend to blame anyone in particular.

Then .NET makes the following call to CryptGetKeyParam to find out the size of a buffer which will hold the value of the algorithm of the key:

CryptGetKeyParam (0xd8c)

IN
hKey
0x230058

dwParam
KP_ALGID

pbData
NULL 

dwDataLen
0

dwFlags
0

OUT
dwDataLen
4

RESULT
CryptGetKeyParam (0xd8c) FAILED
LastErrorValue: (HRESULT) 0x80010125 (2147549477) - Unable to open the access token of the current thread
LastStatusValue: (NTSTATUS) 0xc0000034 - Object Name not found.

Note on IN parameters:

- This hKey value is the key handle.

- This dwParam value indicates that we want the algorithm of the key.

- This pbData value indicates that there is no buffer available yet.

- This pdwDataLen value is 0 because we want to find out the size that we need for the pbData buffer.

- dwFlags should always be 0.

This call is returning 4 in dwDataLen, which is correct as the ALGID will be 4 bytes long. But the API is also returning the error 0x80010125 (2147549477) - "Unable to open the access token of the current thread". CryptoAPI just passes the parameters to the CSP and returns the results. The call to the API is 100% correct, but the CSP is not honoring it. This is not a bug in .NET or CryptoAPI. This is a bug on the CSP.

If you are facing this issue please contact the CSP provider. At least in the case of the third-party CSP where we found the issue they were already aware of it. They immediately sent an upgrade to our customers which fixed this issue.

I hope this helps.

Cheers,

 

Alex (Alejandro Campos Magencio)