see sharp RSS 2.0
# Monday, 04 April 2011

i wrote about parsing the san of a certificate before, here is another way to do it:

1) add a reference to CertEnroll 1.0 Type Library

2) use IX509ExtensionAlternativeNames to get a collection of IAlternativeName objects

3) get the data using the IAlternativeName.strValue and IAlternativeName.Type attributes

 Here's an example:

private string GetSAN(X509Certificate2 cert)
{
        X509Extension ext = cert.Extensions["2.5.29.17"]; // get the SAN extension

        if (null != ext)
        {                 
            try
            {
                string temp = string.Empty;
                IX509ExtensionAlternativeNames an = new CX509ExtensionAlternativeNames();
                an.InitializeDecode(EncodingType.XCN_CRYPT_STRING_BASE64, Convert.ToBase64String(ext.RawData));
                foreach (IAlternativeName name in an.AlternativeNames)
                {
                    temp += name.Type+":"+name.strValue+Environment.NewLine;
                }
                return temp;                   
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        return "no SAN present";
}
Monday, 04 April 2011 11:44:34 (Mitteleuropäische Sommerzeit, UTC+02:00)  #    -
C# | CAPI | Certificates
# Wednesday, 16 March 2011

If you have to parse the Subject Alternative Name (aka SAN) of a Certificate CertGetNameString is your friend:

[DllImport("crypt32.dll", EntryPoint = "CertGetNameString", CharSet = CharSet.Auto, SetLastError = true)]
static extern UInt32 CertGetNameString(
    IntPtr CertContext, 
    UInt32 lType, 
    UInt32 lFlags, 
    IntPtr pTypeParameter, 
    StringBuilder str, 
    UInt32 cch);

private const int CERT_NAME_EMAIL_TYPE = 1;
private const int CERT_NAME_UPN_TYPE = 8;
private const int CERT_NAME_NO_FLAG = 0;
private const int SIZE = 255;

private static void ParseSan(X509Certificate2 cc)
{
    Oid oid = new Oid("2.5.29.17");
    X509Extension ext = cc.Extensions[oid.Value]; // get the SAN extension

    if (null != ext)
    {
        StringBuilder Buffer = new StringBuilder(SIZE);               

        UInt32 nChars = CertGetNameString(cc.Handle,
                CERT_NAME_EMAIL_TYPE,
                CERT_NAME_NO_FLAG,
                IntPtr.Zero,
                Buffer,
                SIZE);
        if (nChars == 1)
        {
            nChars = CertGetNameString(cc.Handle,
                CERT_NAME_UPN_TYPE,
                CERT_NAME_NO_FLAG,
                IntPtr.Zero,
                Buffer,
                SIZE);
        }
                
        Console.WriteLine("{1}:'{0}'", Buffer.ToString(), cc.Thumbprint);

               
    }
}
Wednesday, 16 March 2011 15:34:13 (Mitteleuropäische Zeit, UTC+01:00)  #    -
C# | CAPI | Certificates | P/INVOKE
# Tuesday, 26 May 2009

Alejandro Campos Magencio has written a nice post on how to import a certificate without user interaction:

http://blogs.msdn.com/alejacma/archive/2008/01/31/how-to-import-a-certificate-without-user-interaction-c-c.aspx

It is built around CryptUIWizImport which is described here: http://msdn.microsoft.com/en-us/library/aa380598.aspx

Be sure to check all flags available:

 

Value Meaning
CRYPTUI_WIZ_NO_UI
0x0001

This function will perform the import based on the information in the CRYPTUI_WIZ_IMPORT_SRC_INFO structure pointed to by pImportSrc into the store specified by hDestCertStore without displaying any user interface. If this flag is not specified, this function will display a wizard to guide the user through the import process.

CRYPTUI_WIZ_IGNORE_NO_UI_FLAG_FOR_CSPS
0x0002

Suppress all user interfaces generated by cryptographic service providers (CSPs). This option can be overridden by the CRYPTUI_WIZ_NO_UI_EXCEPT_CSP option.

CRYPTUI_WIZ_NO_UI_EXCEPT_CSP
0x0003

Suppress all user interfaces except those generated by CSPs. This option overrides the CRYPTUI_WIZ_IGNORE_NO_UI_FLAG_FOR_CSPS option.

CRYPTUI_WIZ_IMPORT_ALLOW_CERT
0x00020000

Allow certificates to be imported.

CRYPTUI_WIZ_IMPORT_ALLOW_CRL
0x00040000

Allow CRLs to be imported.

CRYPTUI_WIZ_IMPORT_ALLOW_CTL
0x00080000

Allow CTLs to be imported.

CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE
0x00010000

Do not allow the user to change the destination certificate store represented by the hDestCertStore parameter.

CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE
0x00100000

Import the object to the certificate store for the local computer. This applies only to Personal Information Exchange (PFX) imports.

CRYPTUI_WIZ_IMPORT_TO_CURRENTUSER
0x00200000

Import the object to the certificate store for the current user. This applies only to PFX imports.

CRYPTUI_WIZ_IMPORT_REMOTE_DEST_STORE
0x00400000

Import the object to a remote certificate store. Set this flag if the hDestCertStore parameter represents a remote certificate store.


Tuesday, 26 May 2009 20:04:39 (Mitteleuropäische Sommerzeit, UTC+02:00)  #    -
C# | CAPI | Certificates
# Tuesday, 24 March 2009
To delete a certificate store you created using the .NET API (X509Store) you have to use the P/Invoke version of  CertOpenStore with the CERT_STORE_DELETE flag:

First, import the function:
[DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CertOpenStore(
        IntPtr storeProvider,
        uint dwMsgAndCertEncodingType,
        IntPtr hCryptProv,
        uint dwFlags,
        String cchNameString);


Next define some constants (wincrypt.h is your friend):
const int CERT_STORE_PROV_SYSTEM = 10;
const int CERT_SYSTEM_STORE_CURRENT_USER = 0x1 << 16;
const int CERT_STORE_DELETE_FLAG = 0x10; 


Finally, call the open function:
CertOpenStore(
(IntPtr)CERT_STORE_PROV_SYSTEM,
0,
IntPtr.Zero,
CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_DELETE_FLAG,
storeName);

Tuesday, 24 March 2009 18:21:52 (Mitteleuropäische Zeit, UTC+01:00)  #    -
C# | CAPI | P/INVOKE
Archive
<2017 December>
SunMonTueWedThuFriSat
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
Any link on this site may lead to an external website that is not under my control and that external website might show an opinion that is not mine.

© Copyright 2017
Hannes Köhler
Sign In
Statistics
Total Posts: 39
This Year: 0
This Month: 0
This Week: 0
Comments: 1
All Content © 2017, Hannes Köhler
DasBlog theme 'Business' created by Christoph De Baene (delarou)