G
Guest
I'm trying to invoke CertFindCertificateInStore to find all certificates that
have the Code Signing enhanced key attribute. I'd just like to find 1 cert
(not even all at this point), however, I keep coming up with the error - "
Can not marshal parameter #5: Invalid managed/unmanaged type combination
(this value type must be paired with Struct)."
The structs are defined as:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public struct CRYPT_OID_INFO
{
public uint cbSize;
[MarshalAs(UnmanagedType.LPStr)] public String pszOID;
[MarshalAs(UnmanagedType.LPWStr)]public String pwszName;
public uint dwGroupID;
public uint dwValue;
public int cbData; //ExtraInfo blob
public IntPtr pbData;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public struct _CTL_USAGE
{
public int cUsageIdentifier;
[MarshalAs(UnmanagedType.LPArray)]
public CRYPT_OID_INFO[] rgpszUseageIdentifier;
}
The CertFindCertificateInStore is defined as:
[DllImport("crypt32.dll", SetLastError=true)]
public static extern IntPtr CertFindCertificateInStore(
IntPtr hCertStore,
uint dwCertEncodingType,
uint dwFindFlags,
uint dwFindType,
[In, MarshalAs(UnmanagedType.LPStruct)]
WinCapi._CTL_USAGE pvFindPara,
IntPtr pPrevCertCntxt) ;
The code essentially does the following:
Gets a handle to the store by calling CertOpenSystemStore.
Gets a handle for the OID structure for CodeSigning by calling
CryptFindOIDInfo.
I then build a structure object of _CTL_USAGE and assign cUsageIdentifier to
1 and rgpszUseageIdentifier to an array of CRYPT_OID_INFO structs. The array
consists of one element (the located OID structure).
I then attempt to call CertFindCertificateInStore which fails the the
mentioned error. Any ideas? The following is the snippet of code that I just
desciibed:
IntPtr hOID = OIDName(szOID_PKIX_KP_CODE_SIGNING);
if(hOID != IntPtr.Zero)
{
WinCapi.CRYPT_OID_INFO coiInfo =
(WinCapi.CRYPT_OID_INFO)Marshal.PtrToStructure(hOID,typeof(WinCapi.CRYPT_OID_INFO));
test.cUsageIdentifier = 1;
test.rgpszUseageIdentifier = new WinCapi.CRYPT_OID_INFO[1];
test.rgpszUseageIdentifier[0] = coiInfo;
if(hSysStore != IntPtr.Zero)
{
hCertCntxt=WinCapi.CertFindCertificateInStore(
hSysStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_ENHKEY_USAGE,
test,
IntPtr.Zero) ;
have the Code Signing enhanced key attribute. I'd just like to find 1 cert
(not even all at this point), however, I keep coming up with the error - "
Can not marshal parameter #5: Invalid managed/unmanaged type combination
(this value type must be paired with Struct)."
The structs are defined as:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public struct CRYPT_OID_INFO
{
public uint cbSize;
[MarshalAs(UnmanagedType.LPStr)] public String pszOID;
[MarshalAs(UnmanagedType.LPWStr)]public String pwszName;
public uint dwGroupID;
public uint dwValue;
public int cbData; //ExtraInfo blob
public IntPtr pbData;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public struct _CTL_USAGE
{
public int cUsageIdentifier;
[MarshalAs(UnmanagedType.LPArray)]
public CRYPT_OID_INFO[] rgpszUseageIdentifier;
}
The CertFindCertificateInStore is defined as:
[DllImport("crypt32.dll", SetLastError=true)]
public static extern IntPtr CertFindCertificateInStore(
IntPtr hCertStore,
uint dwCertEncodingType,
uint dwFindFlags,
uint dwFindType,
[In, MarshalAs(UnmanagedType.LPStruct)]
WinCapi._CTL_USAGE pvFindPara,
IntPtr pPrevCertCntxt) ;
The code essentially does the following:
Gets a handle to the store by calling CertOpenSystemStore.
Gets a handle for the OID structure for CodeSigning by calling
CryptFindOIDInfo.
I then build a structure object of _CTL_USAGE and assign cUsageIdentifier to
1 and rgpszUseageIdentifier to an array of CRYPT_OID_INFO structs. The array
consists of one element (the located OID structure).
I then attempt to call CertFindCertificateInStore which fails the the
mentioned error. Any ideas? The following is the snippet of code that I just
desciibed:
IntPtr hOID = OIDName(szOID_PKIX_KP_CODE_SIGNING);
if(hOID != IntPtr.Zero)
{
WinCapi.CRYPT_OID_INFO coiInfo =
(WinCapi.CRYPT_OID_INFO)Marshal.PtrToStructure(hOID,typeof(WinCapi.CRYPT_OID_INFO));
test.cUsageIdentifier = 1;
test.rgpszUseageIdentifier = new WinCapi.CRYPT_OID_INFO[1];
test.rgpszUseageIdentifier[0] = coiInfo;
if(hSysStore != IntPtr.Zero)
{
hCertCntxt=WinCapi.CertFindCertificateInStore(
hSysStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_ENHKEY_USAGE,
test,
IntPtr.Zero) ;