CAPI2 code that will try to translate a CSP handle into a CNG handle
This blog post is with respect to CAPI2 and CNG.
We might encounter situations where in our CAPI2 code we see that the CSP handle being used is CNG. This might be tricky to understand as we are using a CAPI2 provider.
The reason is: There are many places in CAPI2 code that will try to translate a CSP handle into a CNG handle. This is the way the code is implemented and the selection criteria is based either on the ALG_ID or on the nature of the provider. If ALG_ID indicates CNG OR if a CNG provider is used, the CNG flag is set.
By default for OID "1.2.840.113549.1.1.11", if we don't use a CNG provider and do not initialize the CRYPT_OID_INFO structure (that contains the ALG_ID attribute), it sets the values as shown below:
0:000> dx -r1 (*((CRYPT32!_CRYPT_OID_INFO *)0x768bc02c))
(*((CRYPT32!_CRYPT_OID_INFO*)0x768bc02c)) [Type: _CRYPT_OID_INFO]
[+0x000] cbSize : 0x24
[+0x004] pszOID : 0x768bc2e0 : "1.2.840.113549.1.1.11" [Type: char *]
[+0x008] pwszName : 0x768bc2cc : "sha256RSA" [Type: wchar_t *]
[+0x00c] dwGroupId : 0x4
[+0x010] dwValue : 0xffffffff
[+0x010] Algid : 0xffffffff
[+0x010] dwLength : 0xffffffff
[+0x014] ExtraInfo [Type: _CRYPTOAPI_BLOB]
[+0x01c] pwszCNGAlgid : 0x768bb83c : "SHA256" [Type: wchar_t *]
[+0x020] pwszCNGExtraAlgid : 0x768bc53c : "RSA" [Type: wchar_t *]
0:000> dx -r1 (*((CRYPT32!_CRYPT_ALGORITHM_IDENTIFIER*)0x15f688))
(*((CRYPT32!_CRYPT_ALGORITHM_IDENTIFIER*)0x15f688)) [Type: _CRYPT_ALGORITHM_IDENTIFIER]
[+0x000] pszObjId : 0x1123424 : "1.2.840.113549.1.1.11" [Type: char *]
[+0x004] Parameters [Type: _CRYPTOAPI_BLOB]
For example, CryptSignCertificate() checks the ALG_ID and based on its value it sets the CNG flag. In the above case since Algid is 0xffffffff (CALG_OID_INFO_CNG_ONLY) so the CNG flag is set.
If we set the ALG_ID to say CALG_SHA_256, the CNG route is not followed. The issue here is not with the CAPI2 CSP, but it's the way the CAPI2 code is implemented.