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

Reply via email to