static Wincrypt.CTL_ENTRY create_ctlentry(IntPtr handle, String thumbprint) { Wincrypt.CTL_ENTRY entry = new Wincrypt.CTL_ENTRY { SubjectIdentifier = { pbData = get_thumbptr(thumbprint), cbData = (UInt32)(thumbprint.Length / 2) } }; List <UInt32> ids = new List <UInt32>(); Boolean end = false; do { UInt32 retn = Crypt32.CertEnumCertificateContextProperties(handle, 0); if (retn == 0) { end = true; } else { ids.Add(retn); } } while (!end); if (ids.Count > 0) { entry.cAttribute = (UInt32)ids.Count; entry.rgAttribute = create_attributes(handle, ids); } return(entry); }
void get_ctlentries() { if (CTLInfo.cCTLEntry > 0) { Entries = new X509CTLEntryCollection(); IntPtr rgCTLEntry = CTLInfo.rgCTLEntry; for (Int32 index = 0; index < CTLInfo.cCTLEntry; index++) { StringBuilder SB = new StringBuilder(); X509AttributeCollection attributes = new X509AttributeCollection(); Wincrypt.CTL_ENTRY CTLEntry = (Wincrypt.CTL_ENTRY)Marshal.PtrToStructure(rgCTLEntry, typeof(Wincrypt.CTL_ENTRY)); byte[] bytes = new Byte[CTLEntry.SubjectIdentifier.cbData]; Marshal.Copy(CTLEntry.SubjectIdentifier.pbData, bytes, 0, bytes.Length); foreach (Byte item in bytes) { SB.Append($"{item:X2}"); } String thumbprint = SB.ToString(); if (CTLEntry.cAttribute > 0) { IntPtr rgAttribute = CTLEntry.rgAttribute; for (Int32 indexx = 0; indexx < CTLEntry.cAttribute; indexx++) { Wincrypt.CRYPT_ATTRIBUTE attrib = (Wincrypt.CRYPT_ATTRIBUTE)Marshal.PtrToStructure(rgAttribute, typeof(Wincrypt.CRYPT_ATTRIBUTE)); Oid pszOid = new Oid(attrib.pszObjId); Wincrypt.CRYPTOAPI_BLOB blob = (Wincrypt.CRYPTOAPI_BLOB)Marshal.PtrToStructure(attrib.rgValue, typeof(Wincrypt.CRYPTOAPI_BLOB)); bytes = new Byte[blob.cbData]; Marshal.Copy(blob.pbData, bytes, 0, bytes.Length); attributes.Add(new X509Attribute(pszOid, bytes)); rgAttribute = (IntPtr)((UInt64)rgAttribute + (UInt32)Marshal.SizeOf(typeof(Wincrypt.CRYPT_ATTRIBUTE))); } } Entries.Add(new X509CTLEntry(thumbprint, attributes)); rgCTLEntry = (IntPtr)((UInt64)rgCTLEntry + (UInt32)Marshal.SizeOf(typeof(Wincrypt.CTL_ENTRY))); } } }