static Wincrypt.CRYPT_ATTRIBUTE create_attribute(IntPtr handle, UInt32 propId) { UInt32 pcbData = 0; Wincrypt.CRYPT_ATTRIBUTE attrib = new Wincrypt.CRYPT_ATTRIBUTE(); if (Crypt32.CertGetCertificateContextProperty(handle, propId, IntPtr.Zero, ref pcbData)) { attrib.rgValue = Marshal.AllocHGlobal((Int32)pcbData); attrib.pszObjId = "1.3.6.1.4.1.311.10.11." + propId; attrib.cValue = pcbData; Crypt32.CertGetCertificateContextProperty(handle, propId, attrib.rgValue, ref pcbData); } else { throw new Win32Exception(Marshal.GetLastWin32Error()); } return(attrib); }
/// <summary> /// Gets a specified certificate context property. /// </summary> /// <param name="cert">Certificate.</param> /// <param name="propID">Property ID to retrieve.</param> /// <exception cref="ArgumentNullException"> /// <strong>cert</strong> parameter is null reference. /// </exception> /// <exception cref="UninitializedObjectException"> /// Certificate object is not initialized and is empty. /// </exception> /// <exception cref="Exception"> /// Requested context property is not found for the current certificate object. /// </exception> /// <returns>Specified certificate context property.</returns> public static X509CertificateContextProperty GetCertificateContextProperty(this X509Certificate2 cert, X509CertificatePropertyType propID) { if (cert == null) { throw new ArgumentNullException(nameof(cert)); } if (IntPtr.Zero.Equals(cert.Handle)) { throw new UninitializedObjectException(); } UInt32 pcbData = 0; switch (propID) { case X509CertificatePropertyType.Handle: case X509CertificatePropertyType.KeyContext: case X509CertificatePropertyType.ProviderInfo: if (!Crypt32.CertGetCertificateContextProperty(cert.Handle, propID, IntPtr.Zero, ref pcbData)) { throw new Exception("No such property."); } IntPtr ptr = Marshal.AllocHGlobal((Int32)pcbData); Crypt32.CertGetCertificateContextProperty(cert.Handle, propID, ptr, ref pcbData); try { return(new X509CertificateContextProperty(cert, propID, ptr)); } finally { Marshal.FreeHGlobal(ptr); } // byte[] default: if (!Crypt32.CertGetCertificateContextProperty(cert.Handle, propID, null, ref pcbData)) { throw new Exception("No such property."); } Byte[] bytes = new Byte[pcbData]; Crypt32.CertGetCertificateContextProperty(cert.Handle, propID, bytes, ref pcbData); return(new X509CertificateContextProperty(cert, propID, bytes)); } }