I have been frustrated in my attempts to call CryptDecodeObjectEx from C#
code [1].
Depending on the flags passed in, the function allocates memory for the
structure using the LocalAlloc() function and sets the passed in pointer
to pointer parameter (void**) to the allocated structure. In theory, it
should be sufficient to pass in a reference to a IntPtr and then call
PtrToStructure to get back the managed code representation of the
structure.
However, while the function call appears to work (it returns success and
also sets the number of bytes allocated), I haven't been able to get the
PtrToStructure call to work. The exception thrown is "object reference not
set". I have even tried preallocating memory for the structure using
Marshal.AllocHGlobal() but to no avail.
[1]:
The C++ signature of the function is as follows:
CryptDecodeObject(
IN DWORD dwCertEncodingType,
IN LPCSTR lpszStructType,
IN const BYTE *pbEncoded,
IN DWORD cbEncoded,
IN DWORD dwFlags,
OUT void *pvStructInfo, ->This is ** CERT_REQUEST
IN OUT DWORD *pcbStructInfo
);
The corresponding signature in C# code is:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
internal struct DATA_BLOB
{
public int cbData;
public IntPtr pbData;
}
[StructLayout(LayoutKind.Sequential,
CharSet=CharSet.Unicode)]
struct CRYPT_ALGORITHM_IDENTIFIER
{
string pszObjId;
/*CRYPT_OBJID_BLOB*/ DATA_BLOB Parameters;
};
[StructLayout(LayoutKind.Sequential,
CharSet=CharSet.Unicode)]
struct CERT_PUBLIC_KEY_INFO
{
CRYPT_ALGORITHM_IDENTIFIER Algorithm;
/*CRYPT_BIT_BLOB*/ DATA_BLOB PublicKey;
}
[StructLayout(LayoutKind.Sequential,
CharSet=CharSet.Unicode)]
struct CERT_EXTENSION
{
string pszObjId;
bool fCritical;
/*CRYPT_OBJID_BLOB*/DATA_BLOB Value;
}
[StructLayout(LayoutKind.Sequential,
CharSet=CharSet.Unicode)]
internal struct CERT_INFO
{
int dwVersion;
/*CRYPT_INTEGER_BLOB*/DATA_BLOB SerialNumber;
CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;
/*CERT_NAME_BLOB*/DATA_BLOB Issuer;
FILETIME NotBefore;
FILETIME NotAfter;
/*CERT_NAME_BLOB*/DATA_BLOB Subject;
CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo;
/*CRYPT_BIT_BLOB*/DATA_BLOB IssuerUniqueId;
/*CRYPT_BIT_BLOB*/DATA_BLOB SubjectUniqueId;
int cExtension;
/*PCERT_EXTENSION*/IntPtr rgExtension;
}
[DllImport("Crypt32.dll", SetLastError=true, CharSet =
System.Runtime.InteropServices.CharSet.Auto)]
public static extern bool CryptDecodeObjectEx(int
dwCertEncodingType,
int lpszStructType,
byte[] pbEncoded,
int cbEncoded,
int dwFlags,
IntPtr pDecodePara,
ref IntPtr pvStructInfo,
out int pcbStructInfo);
Atul