Decrypt my World

Cryptography, Security, Debugging and more!

How to view a certificate programatically (C#)

How to view a certificate programatically (C#)

  • Comments 10

Hi all,

The following C# sample shows a dialog to view a certificate and its properties. This is the same dialog that appears when we double-click on the cert file in Explorer. I'll use CryptUIDlgViewCertificate API and its CRYPTUI_VIEWCERTIFICATE_STRUCT structure to achieve this:

...
using System.Security.Cryptography.X509Certificates;
using System.Runtime.InteropServices;

namespace MyNamespace
{
    public partial class MyClass
    {
...
        public const int CRYPTUI_DISABLE_ADDTOSTORE = 0x00000010;

        [DllImport("CryptUI.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern Boolean CryptUIDlgViewCertificate(
            ref CRYPTUI_VIEWCERTIFICATE_STRUCT pCertViewInfo,
            ref bool pfPropertiesChanged
        );

        public struct CRYPTUI_VIEWCERTIFICATE_STRUCT
        {
            public int dwSize;
            public IntPtr hwndParent;
            public int dwFlags;
            [MarshalAs(UnmanagedType.LPWStr)]
            public String szTitle;
            public IntPtr pCertContext;
            public IntPtr rgszPurposes;
            public int cPurposes;
            public IntPtr pCryptProviderData; // or hWVTStateData
            public Boolean fpCryptProviderDataTrustedUsage;
            public int idxSigner;
            public int idxCert;
            public Boolean fCounterSigner;
            public int idxCounterSigner;
            public int cStores;
            public IntPtr rghStores;
            public int cPropSheetPages;
            public IntPtr rgPropSheetPages;
            public int nStartPage;
        }

        private void MySampleFunction()
        {
            // Get the cert
            X509Certificate2 cert = new X509Certificate2(@"C:\temp\mycert.cer");

            // Show the cert
            CRYPTUI_VIEWCERTIFICATE_STRUCT certViewInfo = new CRYPTUI_VIEWCERTIFICATE_STRUCT();
            certViewInfo.dwSize = Marshal.SizeOf(certViewInfo);
            certViewInfo.pCertContext = cert.Handle;
            certViewInfo.szTitle = "Certificate Info";
            certViewInfo.dwFlags = CRYPTUI_DISABLE_ADDTOSTORE;
            certViewInfo.nStartPage = 0;
            bool fPropertiesChanged = false;
            if (!CryptUIDlgViewCertificate(ref certViewInfo, ref fPropertiesChanged))
            {
                int error = Marshal.GetLastWin32Error();
                MessageBox.Show(error.ToString());
            }
        }
    }
}

I hope this helps.

Regards,

 

Alex (Alejandro Campos Magencio)

  • Hi,

    Very interesting code you have. I am wanting to one, detect the card, two, have a user enter a pin, and lastly, I want to read the card user information, which I will validate via other methods.

    Will your sample, with some tweaking, allow me to do this?

    Thanks in advance for your input!

    Dave

  • I need to access a CTL on an IIS server using C#.  I have been looking at your P/Invoke examples and I can probably do it using that.  However, our customer has some concerns with using unmanaged code.  I have been unable to get to the CTL using the X509 objects that I am aware of.  Is there a way to access the CTL (assuming I know which store it is in and I know the CTL identifier from the SSLCtlIdentifier and SSLCtlStore values from AD/WMI).  I just need to verify that the CTL contains certain roots and I can't seem to find a way to access it using C#.  

    The tool ssldiag.exe from MS shows the contents of the CTL, but I am not sure how it is implemented.  I would like to do it in C# without having to use P/Invoke if at all possible.

    Thanks in advance for any help you can provide.

  • I can't get this code working in VB.NET environment. I wrote such a code in VB.NET, but when I call CryptUIDlgViewCertificate() application throws an exception. I would be very thankful if you could try to do this in VB.NET and post here if it works. I could send you my code to review, but don't know your e-mail.

  • Certificate2 cert = new X509Certificate2(@"C:\temp\mycert.cer");

    X509Certificate2UI.DisplayCertificate(cert);

  • Yes, thanks. This one works well. Just need to mention, that reference to "system.security.dll" should be added in VB.NET.

  • We are trying to automate importing of contacts to Outlook (both 2003 and 2007).

    Basically we read the contact details from a DB or csv file and create the contact items using C# code.

    In a folder we also have contact's certificate files that we would like to attach to the above created contacts in code.

    We have a code for Outlook 2007 that uses propertyaccessor and which does the import with no reported errors. However when we open Outlook contacts manually, there are no certificates attached!

    Tot troubleshoot, we compared, byte by byte, the certificate that we import via code and the same certificate that is manually attached to a contact.

    They differ for few bytes both at the begining and at the end!

    It seems that Outlook adds some header and footer bytes to the attached certificate when we import it manually.

    If we artificially add those header and footer bytes to our certificate in code, it will be imported and shown later in Outlook just fine!

    However these header/footer bytes seem to be certificate related and are not the same for every certificate. Just their total number is the same.

    The question now is, how can we determine the process of adding these extra bytes before and after the certificate so it is always recognized by Outlook?

    We searched on the internet a lot in regards to this problem but so far no solution was found.

    I hope you can give us a clue on this?

  • Sorry, I don't know what outlook does, as I don't the product to that extent...

  • How do you display the dialog as a Modal Dialog as you can return to the main application and just keep clicking button to view certificates, not a good idea?

  • Hi Spitz,

    Never tried it, but does it help if you pass a valid window handle in hwndParent param of the CRYPTUI_VIEWCERTIFICATE_STRUCT struct?

  • Yes, it does!

    Though I worked this one out myself and only came here to update my findings lol

    certViewInfo.hwndParent = this.Handle;

Page 1 of 1 (10 items)
Leave a Comment
  • Please add 7 and 5 and type the answer here:
  • Post
Translate This Page