csharp: SDK:CAPICOM

http://www.microsoft.com/zh-cn/download/details.aspx?id=25281

 

//******************************************************************************
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
// WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
//
// Copyright (C) 1999 - 2002.  Microsoft Corporation.  All rights reserved.
//
//******************************************************************************
//
// storesh.cs
//
// This is a sample script to illustrate how to use CAPICOM and C#. It creates a
// pseudo shell to navigate certificate stores.
//
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// To run this sample you need to have Microsoft Visual C# .NET
// To start: open the storesh.sln file in Visual Studio
//
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
//
//  Try these commands:
//
//	help
//	dir
//	cd ..
//	cd ..\addressbook
//	dir -l
//	dir -subject John
//	cd \LocalMachine
//	cd \lm
//	display 3
//	view 2
//	import c:\home\temp\pfx1.pfx
//	export 7 c:\home\temp\itm.cer
//  pfxexport 11 c:\home\temp\foo.pfx secretpassword
//	rem 2
//  dir -issuer "Thawte"
//  dir -eku "Code Signing"
//  dir -eku 1.3.6.1.5.5.7.3.4
//
// Note: For simplicity, this script does not handle exceptions.
//
//******************************************************************************

using System;
using System.Collections;
using System.Runtime.InteropServices;
using CAPICOM;
using System.Text;

namespace storesh
{

	
	public class Win32 
	{

		[DllImport("crypt32.dll",CharSet=CharSet.Unicode )]
		public static extern uint CertEnumSystemStore(
			uint dwFlags, 
			uint pvSystemStoreLocationPara, 
			String pvArg, 
			CertEnumSystemStoreCallback pfnEnum
			);

	}

	public delegate bool CertEnumSystemStoreCallback(
		[In, MarshalAs( UnmanagedType.LPWStr) ] String pvSystemStore, 
		uint dwFlags, 
		ref CERT_SYSTEM_STORE_INFO pStoreInfo, 
		uint pvReserved, 
		[In, MarshalAs( UnmanagedType.LPWStr) ] String pvArg
	);

	[StructLayout(LayoutKind.Sequential)]
	public struct CERT_SYSTEM_STORE_INFO
	{
		uint cbSize;
	}



	class Storesh 
	{
		const uint CERT_SYSTEM_STORE_CURRENT_USER  = 0x10000;
		const uint CERT_SYSTEM_STORE_LOCAL_MACHINE  = 0x20000;
		const int VALIDITY_LENGTH = 23;
		const int CERTNAME_LENGTH = 20;
		const int THUMBPRINT_LENGTH = 42;
		const int FRIENDLYNAME_LENGTH = 20;
		const int CAPICOM_ENCODED_DATA_FORMAT_MULTI_LINES =1 ;
		const int HELP_PAD = 30;
		const String CurrentUser = "CurrentUser";
		const String LocalMachine = "LocalMachine";

		static private String _currStoreName = "My";
		static private String _currStoreLocation = CurrentUser;
		static IEnumerator _currFilter;
		static StoreClass _oCurrStore;

		enum Listing {Brief, Long};
		
		
		/// The main entry point for the application.
		[STAThread]
		static void Main(string[] args)
		{
			
			//We take one argument, a starting store name
			if (args.Length > 0)
			{
				_currStoreName = args[0];
			}
			_oCurrStore = new StoreClass();
			_oCurrStore.Open(
				CAPICOM_STORE_LOCATION.CAPICOM_CURRENT_USER_STORE,
				_currStoreName,
				CAPICOM_STORE_OPEN_MODE.CAPICOM_STORE_OPEN_EXISTING_ONLY | 
				CAPICOM_STORE_OPEN_MODE.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED);
			waitForInput();
		}

		static void waitForInput()
		{
			bool done = false;
			String input;
			while (!done) 
			{
				Console.Write(_currStoreLocation + "\\" + _currStoreName + ">");
				input = Console.ReadLine();
				done = parseCommandLine(input);
			}
		}

		static bool parseCommandLine ( String input)
		{
			
			ArrayList alArgs = ParseArgs(input);
			Certificate oCert = null;
			
			switch ((String)alArgs[0])
			{
				case "cd":
				{
					//This is the 'change directory' command
					String storename;
					if (alArgs.Count > 1)
					{
						storename = (String)alArgs[1];
					}
					else 
					{
						storename = _currStoreName; //reset store name
					}

					if (storename.Equals("..") && _currStoreName.Length > 0 )
					{
						_oCurrStore = new StoreClass();
						storename = null;
						_currFilter = null;
						_currStoreName = "";
					} 
					else if (storename.StartsWith("..") && _currStoreName.Length > 0 )
					{
						_oCurrStore = new StoreClass();
						_currFilter = null;
						storename = storename.Substring(3,storename.Length - 3);
						_currStoreName = "";
					} 
					else if (storename.Equals(".."))
					{
						storename = null;
					} 
					else if (storename.Equals("\\" + LocalMachine)  || storename.Equals("\\lm" ))
					{
						_oCurrStore = new StoreClass();
						_currStoreName = "";
						storename = null;
						_currStoreLocation = LocalMachine;
						_currFilter = null;
					}
					else if (storename.Equals("\\" + CurrentUser)  || storename.Equals("\\cu" ))
					{
						_oCurrStore = new StoreClass();
						_currStoreName = "";
						storename = null;
						_currStoreLocation = CurrentUser;
						_currFilter = null;
					}
					if (storename != null && _currStoreName.Equals("")) 
					{

						try 
						{
							CAPICOM_STORE_LOCATION OpenMode = CAPICOM_STORE_LOCATION.CAPICOM_CURRENT_USER_STORE;
							if (_currStoreLocation.Equals(LocalMachine))
							{
								OpenMode = CAPICOM_STORE_LOCATION.CAPICOM_LOCAL_MACHINE_STORE;
							}

							//Open the store MAX_ALLOWED in case the user wants to import/rem/export
							//They may not have permission to modify HKLM stores
							_oCurrStore.Open(	OpenMode,
								storename,
								CAPICOM_STORE_OPEN_MODE.CAPICOM_STORE_OPEN_EXISTING_ONLY | 
								CAPICOM_STORE_OPEN_MODE.CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED);
							_currStoreName = storename;

						} 
						catch (Exception e)
						{
							Console.WriteLine (e.Message);
						}
					}
					return false;
				}
				case "q":
				case "quit":
				{
					return true;
				}
				case "h":
				case "help":
				{
					DisplayHelp();
				
					return false;
				} 
				case "v":
				case "view":
					try 
					{
						oCert = GetCertByIndex(Convert.ToInt32(alArgs[1]));
						if (oCert != null ) 
						{
							DisplayCertificate(oCert, "");
						}
						else
						{
							Console.WriteLine ("No certificate with that index (" + alArgs[1] + ") could be found.");
						}
					} 
					catch (Exception e)
					{
						Console.WriteLine ("An error was encountered processing the " + alArgs[0] + " command: " + e.Message);
					}
					break;
				case "y":
				case "display":
					try 
					{
						oCert = GetCertByIndex(Convert.ToInt32(alArgs[1]));
						if (oCert != null ) 
						{
							oCert.Display();
						}
						else
						{
							Console.WriteLine ("No certificate with that index (" + alArgs[1] + ") could be found.");
						}
					} 
					catch (Exception e)
					{
						Console.WriteLine ("An error was encountered processing the " + alArgs[0] + " command: " + e.Message);
					}
					break;
				case "rem":
					try 
					{
						oCert = GetCertByIndex(Convert.ToInt32(alArgs[1]));
						if (oCert != null ) 
						{
							String answer = "n";
							Console.WriteLine(	ToColumn (oCert.GetInfo(CAPICOM_CERT_INFO_TYPE.CAPICOM_CERT_INFO_SUBJECT_SIMPLE_NAME), CERTNAME_LENGTH) + 
								" " + 
								ToColumn (oCert.Thumbprint, THUMBPRINT_LENGTH ));
							Console.WriteLine ("Issuer: " + oCert.GetInfo(CAPICOM_CERT_INFO_TYPE.CAPICOM_CERT_INFO_ISSUER_SIMPLE_NAME));
							Console.WriteLine ("Validity Period: " + oCert.ValidFromDate + " - " + oCert.ValidToDate);
							DisplayEKU(oCert.ExtendedKeyUsage().EKUs);
							Console.WriteLine();
							Console.Write("Are you sure you want to remove this certificate (y/n)? ");
							answer = Console.ReadLine();
							if (!answer.Equals("y"))
							{
								break;
							}

							if (oCert.HasPrivateKey() && !oCert.PrivateKey.IsHardwareDevice() )
							{
								oCert.PrivateKey.Delete();
								Console.WriteLine ("The private key was deleted.");
							}
							try 
							{
								_oCurrStore.Remove(oCert);
								Console.WriteLine("The certificate was removed.");
							} 
							catch 
							{
								Console.WriteLine("The certificate could not be removed.");
							}
						}
						else
						{
							Console.WriteLine ("No certificate with that index (" + alArgs[1] + ") could be found.");
						}
					} 
					catch (Exception e)
					{
						Console.WriteLine ("An error was encountered processing the " + alArgs[0] + " command: " + e.Message);
					}
					break;
				case "e":
				case "export":
					try 
					{
						oCert = GetCertByIndex(Convert.ToInt32(alArgs[1]));
						if (oCert != null ) 
						{
							String filename =  (String)alArgs[2];
							if (filename != null)
							{
								oCert.Save(filename,
									"",
									CAPICOM_CERTIFICATE_SAVE_AS_TYPE.CAPICOM_CERTIFICATE_SAVE_AS_CER,
									CAPICOM_CERTIFICATE_INCLUDE_OPTION.CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY);

							} 
							else
							{
								Console.WriteLine("No filename specified.");
							}
						}
						else
						{
							Console.WriteLine ("No certificate with that index (" + alArgs[1] + ") could be found.");
						}
					} 
					catch (Exception e)
					{
						Console.WriteLine ("An error was encountered processing the " + alArgs[0] + " command: " + e.Message);
					}
					break;
				case "i":
				case "import":
					try 
					{
						String filename = null;
						String password = null;
						CAPICOM_KEY_STORAGE_FLAG iFlag = CAPICOM_KEY_STORAGE_FLAG.CAPICOM_KEY_STORAGE_DEFAULT;
						
						if (alArgs.Count >= 2)
						{
							filename = (String)alArgs[1];
						}
						if (alArgs.Count >= 3)
						{
							password = (String)alArgs[2];
						}
						if (alArgs.Count >= 4)
						{
							String flag = null;
							if (alArgs.Count == 4)
							{
								password = null;
								flag = (String)alArgs[3];
							}
							else if (alArgs.Count == 5)
							{
								flag = (String)alArgs[4];
							}
							if (flag.Equals ("e"))
							{
								iFlag = CAPICOM_KEY_STORAGE_FLAG.CAPICOM_KEY_STORAGE_EXPORTABLE;
							} 
							else if (flag.Equals ("p"))
							{
								iFlag = CAPICOM_KEY_STORAGE_FLAG.CAPICOM_KEY_STORAGE_USER_PROTECTED;
							}
							else if (flag.Equals ("ep") || flag.Equals ("pe"))
							{
								iFlag = CAPICOM_KEY_STORAGE_FLAG.CAPICOM_KEY_STORAGE_USER_PROTECTED | CAPICOM_KEY_STORAGE_FLAG.CAPICOM_KEY_STORAGE_EXPORTABLE;
							}
						}
						_oCurrStore.Load(filename, password, iFlag);
					}
					catch (Exception e)
					{
						Console.WriteLine ("An error was encountered processing the " + alArgs[0] + " command: " + e.Message);
					}
					break;
				case "p":
				case "pfxexport":
					try 
					{
						oCert = GetCertByIndex(Convert.ToInt32(alArgs[1]));
						if (oCert != null ) 
						{
							String filename =  (String)alArgs[2];
							String password =  (String)alArgs[3];
										
							if (filename != null)
							{
								oCert.Save(filename,
									password,
									CAPICOM_CERTIFICATE_SAVE_AS_TYPE.CAPICOM_CERTIFICATE_SAVE_AS_PFX,
									CAPICOM_CERTIFICATE_INCLUDE_OPTION.CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN);
							} 
							else
							{
								Console.WriteLine("No filename specified.");
							}
						}
						else
						{
							Console.WriteLine ("No certificate with that index (" + alArgs[1] + ") could be found.");
						}
					} 
					catch (Exception e)
					{
						Console.WriteLine ("An error was encountered processing the " + alArgs[0] + " command: " + e.Message);
					}
					break;
				case "c":
                                case "create":
                                case "del":
                                        try
                                        {
                                                // Opening it is the same whether we're creating or deleting
                                                if (alArgs.Count == 1) {
                                                        Console.WriteLine ("Please enter a name for the store");
                                                        break;
                                                }
                                                String name = (String) alArgs[1];
                                                for (int i = 2; i < alArgs.Count; i++) {
                                                        name += " " + alArgs[i];
                                                }
                                                Store newStore = new Store();
                                                CAPICOM_STORE_LOCATION storeLoc = CAPICOM_STORE_LOCATION.CAPICOM_CURRENT_USER_STORE;
                                                if (_currStoreLocation.Equals(LocalMachine)) {
                                                        storeLoc = CAPICOM_STORE_LOCATION.CAPICOM_LOCAL_MACHINE_STORE;
                                                }
                                                newStore.Open(storeLoc,
                                                              name,
                                                              CAPICOM_STORE_OPEN_MODE.CAPICOM_STORE_OPEN_READ_WRITE);

                                                // Now delete if that is what was chosen
                                                if (alArgs[0].Equals("del")) {
                                                        if (_currStoreName.Equals(name)) {
                                                                Console.WriteLine("You cannot delete the store you are currently viewing");
                                                                Console.WriteLine("Please use the  command to change stores first");
                                                                break;
                                                        }
													    newStore.Delete();
                                                }
                                        }
                                        catch (Exception e)
                                        {
                                                Console.WriteLine ("An error was encountered processing the " + alArgs[0] + " command: " + e.Message);
                                        }
                                        break;
				case "d":
				case "dir":
				{
					Certificates oCerts;
					Listing listing = Listing.Brief;

					if ((_currStoreLocation.Equals(CurrentUser) || _currStoreLocation.Equals(LocalMachine))
						&& _currStoreName.Length == 0)
					{
						uint retval = 0;
						uint dwFlags = CERT_SYSTEM_STORE_CURRENT_USER;

						CertEnumSystemStoreCallback StoreCallback = new CertEnumSystemStoreCallback(Storesh.CertEnumSystemStoreCallback);
						if (_currStoreLocation.Equals(LocalMachine)) 
						{
							dwFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE;
						}
						retval= Win32.CertEnumSystemStore(
							dwFlags, 
							0, 
							_currStoreName, 
							StoreCallback 
							);
					}
					else if (alArgs.Count >= 1)
					{
						int i =0 ;
						try 
						{
							_currFilter = _oCurrStore.Certificates.GetEnumerator();
							for (i = 1; i < alArgs.Count; i++)
							{
								String param = ((String)alArgs[i]).ToLower();
								if (param.Equals("/l") || param.Equals("-l"))
								{
									listing = Listing.Long;
								} 
								else if (param.Equals("/subject") || param.Equals("-subject"))
								{
									Object filter = (System.String)alArgs[++i]; 
									oCerts = (Certificates)_oCurrStore.Certificates;
									oCerts = (Certificates)oCerts.Find(CAPICOM_CERTIFICATE_FIND_TYPE.CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME,
										filter,
										false);
									_currFilter = oCerts.GetEnumerator();

								}
								else if (param.Equals("/eku") || param.Equals("-eku"))
								{
									Object filter = (System.String)alArgs[++i]; 
									oCerts = (Certificates)_oCurrStore.Certificates;
									oCerts = (Certificates)oCerts.Find(CAPICOM_CERTIFICATE_FIND_TYPE.CAPICOM_CERTIFICATE_FIND_APPLICATION_POLICY,
										filter,
										false);
									_currFilter = oCerts.GetEnumerator();

								}
								else if (param.Equals("/issuer") || param.Equals("-issuer"))
								{
									Object filter = (System.String)alArgs[++i]; 
									oCerts = (Certificates)_oCurrStore.Certificates;
									oCerts = (Certificates)oCerts.Find(CAPICOM_CERTIFICATE_FIND_TYPE.CAPICOM_CERTIFICATE_FIND_ISSUER_NAME,
										filter,
										false);
									_currFilter = oCerts.GetEnumerator();

								}
								else if (param.Equals("/sha1") || param.Equals("-sha1"))
								{
									String filter = (String)alArgs[++i]; 
									oCerts = (Certificates)_oCurrStore.Certificates;
									oCerts = (Certificates)oCerts.Find(CAPICOM_CERTIFICATE_FIND_TYPE.CAPICOM_CERTIFICATE_FIND_SHA1_HASH,
										filter,
										false);
									_currFilter = oCerts.GetEnumerator();
								}
							}
							i = 1;
							while (_currFilter.MoveNext() == true)
							{
								oCert = (Certificate) _currFilter.Current;
								Console.Write ( (i++ + ". ").PadRight(4,' '));
								switch (listing)
								{
									case Listing.Brief:
										Console.WriteLine(	ToColumn (oCert.GetInfo(CAPICOM_CERT_INFO_TYPE.CAPICOM_CERT_INFO_SUBJECT_SIMPLE_NAME), CERTNAME_LENGTH) +
											" " + 
											ToColumn (oCert.ValidToDate.ToString(), VALIDITY_LENGTH) + 
											ToColumn (oCert.GetInfo(CAPICOM_CERT_INFO_TYPE.CAPICOM_CERT_INFO_ISSUER_SIMPLE_NAME), CERTNAME_LENGTH) );
										break;
									case Listing.Long:
									{
										Console.WriteLine(	ToColumn (oCert.GetInfo(CAPICOM_CERT_INFO_TYPE.CAPICOM_CERT_INFO_SUBJECT_SIMPLE_NAME), CERTNAME_LENGTH) + 
											" " + 
											ToColumn (oCert.Thumbprint, THUMBPRINT_LENGTH ));
										Console.WriteLine ("Issuer: " + oCert.GetInfo(CAPICOM_CERT_INFO_TYPE.CAPICOM_CERT_INFO_ISSUER_SIMPLE_NAME));
										Console.WriteLine ("Validity Period: " + oCert.ValidFromDate + " - " + oCert.ValidToDate);
										DisplayEKU(oCert.ExtendedKeyUsage().EKUs);
										Console.WriteLine();
										break;
									}
								}
							}
						}
						catch (Exception e)
						{
							Console.WriteLine("An error was encountered: " + e.Message);
						}
					}
					break;
				}
				default:
					DisplayHelp();
					break;

			}

			return false;
		}

		public static bool CertEnumSystemStoreCallback(
			String pvSystemStore, 
			uint dwFlags, 
			ref CERT_SYSTEM_STORE_INFO pStoreInfo, 
			uint pvReserved, 
			String pvArg
			)
		{
			Console.WriteLine("[ " +pvSystemStore + " ]");
			return true;
		}

		public static Certificate GetCertByIndex( int idx )
		{
			Certificate oCert;
			int i = 0;

			if (_oCurrStore != null) 
			{
				if (_currFilter == null) 
				{
					_currFilter = _oCurrStore.Certificates.GetEnumerator();
				}
				else 
				{
					_currFilter.Reset();
				}

				while (_currFilter.MoveNext() == true)
				{
					oCert  = (Certificate)_currFilter.Current;
					i++;
					if (i == idx)
					{
						return oCert;
					}
				}
			}
			return null;
		}

		private static ArrayList ParseArgs(String input)
		{
			char[] delims = new char[] {' '};
			ArrayList argsarray = new ArrayList();
			String multiString = null;

			String[] argSplit = input.Split(delims);
			for (int i = 0; i < argSplit.Length; i++)
			{
				String curr = argSplit[i];
				if (curr.StartsWith("\"") && curr.EndsWith("\""))
				{
					argsarray.Add(curr.Substring(1,curr.Length-2));
				}
				else if (curr.StartsWith("\""))
				{
					multiString = curr;
				}
				else if (argSplit[i].EndsWith("\""))
				{
					multiString = multiString + " " + curr;
					argsarray.Add(multiString.Substring(1,multiString.Length-2));
					multiString = null;
				}
				else
				{
					if (multiString != null)
					{
						multiString = multiString + " " + curr;
					}
					else 
					{
						argsarray.Add(curr);
					}
				}
			}
			argSplit = null;
			return argsarray;
		}
		
		public static void DisplayHelp()
		{
			Console.WriteLine();
			Console.Write("[h]elp".PadRight(HELP_PAD, ' '));
			Console.WriteLine("This screen");

			Console.WriteLine();
			Console.Write("cd ".PadRight(HELP_PAD, ' '));
			Console.WriteLine(" is a store name or ..");
			Console.WriteLine("".PadRight(HELP_PAD, ' ')+ "Can also be \\LocalMachine (\\lm) or \\CurrentUser (\\cu)");
				
			Console.WriteLine();
			Console.Write("[d]ir ".PadRight(HELP_PAD, ' '));
			Console.WriteLine("List the contents of a certificate store");
			Console.WriteLine("".PadRight(HELP_PAD, ' ')+ "-l	Long listing");
			Console.WriteLine("".PadRight(HELP_PAD, ' ')+ "-subject 	Match subject name.");
			Console.WriteLine("".PadRight(HELP_PAD, ' ')+ "-issuer 	Match issuer name.");
			Console.WriteLine("".PadRight(HELP_PAD, ' ')+ "-eku 	Must have specified EKU.");
			Console.WriteLine("".PadRight(HELP_PAD, ' ')+ "-sha1 	Match thumbprint.");

			Console.WriteLine();
			Console.Write("[v]iew ".PadRight(HELP_PAD, ' '));
			Console.WriteLine(" is the number of the certificate to view");

			Console.WriteLine();
			Console.Write("rem ".PadRight(HELP_PAD, ' '));
			Console.WriteLine(" is the number of the certificate to remove");

			Console.WriteLine();
			Console.Write("displa[y] ".PadRight(HELP_PAD, ' '));
			Console.WriteLine(" is the number of the certificate to display");

                        Console.WriteLine();
                        Console.Write("[c]reate ".PadRight(HELP_PAD, ' '));
                        Console.WriteLine(" is the name of the store to create");

                        Console.WriteLine();
                        Console.Write("del ".PadRight(HELP_PAD, ' '));
                        Console.WriteLine(" is the name of the store to delete");
                        Console.WriteLine("".PadRight(HELP_PAD, ' ')+ "This cannot be a system store");

			Console.WriteLine();
			Console.Write("[e]xport  ".PadRight(HELP_PAD, ' '));
			Console.WriteLine(" is the number of the certificate to display");
			Console.WriteLine("".PadRight(HELP_PAD, ' ')+ " is the destination filename");

			Console.WriteLine();
			Console.Write("[p]fxexport   ".PadRight(HELP_PAD, ' '));
			Console.WriteLine(" is the number of the certificate to display");
			Console.WriteLine("".PadRight(HELP_PAD, ' ')+ " is the destination filename");
			Console.WriteLine("".PadRight(HELP_PAD, ' ')+ " is the password");

			Console.WriteLine();
			Console.Write("[i]mport   [-key e|p]".PadRight(HELP_PAD, ' '));
			Console.WriteLine(" is the input filename");
			Console.WriteLine("".PadRight(HELP_PAD, ' ')+ " is the filename password");
			Console.WriteLine("".PadRight(HELP_PAD, ' ')+ "-key: e is exportable");
			Console.WriteLine("".PadRight(HELP_PAD, ' ')+ "-key: p is user protected. Both may be specified");

		}
		
		public static String ToColumn (String s, int i)
		{
			String retval;
			if (s == null || i > s.Length )
			{
				retval = s.PadRight(i);
			}
			else
			{
				retval = s.Substring(0,i).PadRight(i,' ');
			}
			return retval;
		}

		public static void DisplayEKU (EKUs EKUs)
		{
			if (EKUs.Count > 0)
			{
				OID OID;
				OID = new OIDClass();
				foreach (EKU EKU in EKUs)
				{
					OID.Value = EKU.OID;
					Console.WriteLine( "  " + OID.FriendlyName + " (" + OID.Value + ")" );
				}
				OID = null;
			}
		}

		public static void DisplayCertificate ( Certificate Certificate , String Title)
		{
			String[] KeySpecStrings = {"Unknown", "Exchange","Signature" };
			String[] ProviderTypes = {	"Unknown", 
										 "PROV_RSA_FULL",
										 "PROV_RSA_SIG",
										 "PROV_DSS",
										 "PROV_FORTEZZA",
										 "PROV_MS_EXCHANGE",
										 "PROV_SSL",
										 "PROV_STT_MER",
										 "PROV_STT_ACQ",
										 "PROV_STT_BRND",
										 "PROV_STT_ROOT",
										 "PROV_STT_ISS",
										 "PROV_RSA_SCHANNEL",
										 "PROV_DSS_DH",
										 "PROV_EC_ECDSA_SIG",
										 "PROV_EC_ECNRA_SIG",
										 "PROV_EC_ECDSA_FULL",
										 "PROV_EC_ECNRA_FULL",
										 "PROV_DH_SCHANNEL",
										 "PROV_SPYRUS_LYNKS",
										 "PROV_RNG",
										 "PROV_INTEL_SEC",
										 "PROV_REPLACE_OWF",
										 "PROV_RSA_AES" };
   
			//int iIndex = 0;
			
			Console.WriteLine( Title );
			Console.WriteLine();
			Console.WriteLine( "Subject Name:");
			Console.WriteLine( "  Simple name = " + Certificate.SubjectName);
			Console.WriteLine( "  Email name  = " + Certificate.GetInfo(CAPICOM_CERT_INFO_TYPE.CAPICOM_CERT_INFO_SUBJECT_EMAIL_NAME));
			Console.WriteLine( "  UPN name    = " + Certificate.GetInfo(CAPICOM_CERT_INFO_TYPE.CAPICOM_CERT_INFO_SUBJECT_UPN));
			Console.WriteLine( "  DNS name    = " + Certificate.GetInfo(CAPICOM_CERT_INFO_TYPE.CAPICOM_CERT_INFO_SUBJECT_DNS_NAME));
			Console.WriteLine();
			Console.WriteLine( "Issuer Name: " + Certificate.IssuerName);
			Console.WriteLine();
			Console.WriteLine( "Serial Number: " + Certificate.SerialNumber);
			Console.WriteLine();
			Console.WriteLine( "Not Before: " + Certificate.ValidFromDate);
			Console.WriteLine();
			Console.WriteLine( "Not After: " + Certificate.ValidToDate);
			Console.WriteLine();
			Console.WriteLine( "SHA1 Hash: " + Certificate.Thumbprint);
			Console.WriteLine();
			Console.WriteLine( "IsValid: " + Certificate.IsValid().Result);
			Console.WriteLine();
			Console.WriteLine( "Archived: " + Certificate.Archived);
			Console.WriteLine();
       

			if (Certificate.BasicConstraints().IsPresent) 
			{
				Console.WriteLine( "Basic Constraints:" );
				Console.WriteLine( "  Critical          = " + Certificate.BasicConstraints().IsCritical );
				Console.WriteLine( "  CA                = " + Certificate.BasicConstraints().IsCertificateAuthority );
				Console.WriteLine( "  PathLenConstraint = ");
				if (Certificate.BasicConstraints().IsPathLenConstraintPresent) 
				{
					Console.WriteLine( Certificate.BasicConstraints().PathLenConstraint);
				}
				else
				{
					Console.WriteLine( "Not present.");
				}
			}	
			else
			{
				Console.WriteLine( "Basic Constraints: Not present." );
			}          
			Console.WriteLine();
   
			if (Certificate.KeyUsage().IsPresent) 
			{
				Console.WriteLine( "Key Usage:");
				Console.WriteLine( "  Critical                  = " + Certificate.KeyUsage().IsCritical);
				Console.WriteLine( "  IsDigitalSignatureEnabled = " + Certificate.KeyUsage().IsDigitalSignatureEnabled );
				Console.WriteLine( "  IsNonRepudiationEnabled   = " + Certificate.KeyUsage().IsNonRepudiationEnabled);
				Console.WriteLine( "  IsKeyEnciphermentEnabled  = " + Certificate.KeyUsage().IsKeyEnciphermentEnabled);
				Console.WriteLine( "  IsDataEnciphermentEnabled = " + Certificate.KeyUsage().IsDataEnciphermentEnabled);
				Console.WriteLine( "  IsKeyAgreementEnabled     = " + Certificate.KeyUsage().IsKeyAgreementEnabled);
				Console.WriteLine( "  IsKeyCertSignEnabled      = " + Certificate.KeyUsage().IsKeyCertSignEnabled);
				Console.WriteLine( "  IsCRLSignEnabled          = " + Certificate.KeyUsage().IsCRLSignEnabled);
				Console.WriteLine( "  IsEncipherOnlyEnabled     = " + Certificate.KeyUsage().IsEncipherOnlyEnabled);
				Console.WriteLine( "  IsDecipherOnlyEnabled     = " + Certificate.KeyUsage().IsDecipherOnlyEnabled);
			}
			else
			{
				Console.WriteLine( "Key Usage: Not present.");

			}
			Console.WriteLine();
   
			if (Certificate.ExtendedKeyUsage().IsPresent) 
			{
				if (Certificate.ExtendedKeyUsage().EKUs.Count > 0)
				{
					OID OID;
					OID = new OIDClass();
					Console.WriteLine( "Extended Key Usage:");
					Console.WriteLine( "  Critical = " + Certificate.ExtendedKeyUsage().IsCritical);
					foreach (EKU EKU in Certificate.ExtendedKeyUsage().EKUs)
					{
						OID.Value = EKU.OID;
						Console.WriteLine( "  " + OID.FriendlyName + " (" + OID.Value + ")" );
					}
					OID = null;
				}
				else
				{
					Console.WriteLine( "Extended Key Usage: Not valid for any usage.");
					Console.WriteLine( "  Critical = " + Certificate.ExtendedKeyUsage().IsCritical );
				}
			}
			else
			{
				Console.WriteLine( "Extended Key Usage: Not present (valid for all usages).");
			}
			Console.WriteLine();
   
			if (Certificate.Template().IsPresent) 
			{
				Console.WriteLine( "Template:");
				Console.WriteLine( "  Critical = " + Certificate.Template().IsCritical);
				Console.WriteLine( "  Name     = " + Certificate.Template().Name);
				Console.WriteLine( "  OID      = " + Certificate.Template().OID.FriendlyName + "(" + Certificate.Template().OID.Value + ")");
				Console.WriteLine( "  Major    = " + Certificate.Template().MajorVersion);
				Console.WriteLine( "  Minor    = " + Certificate.Template().MinorVersion);
			}
			else
			{
				Console.WriteLine( "Template: Not present.");
			}
			Console.WriteLine();
   
			Console.WriteLine( "Public Key:");
			Console.WriteLine( "  Algorithm  = " + Certificate.PublicKey().Algorithm.FriendlyName + "(" + Certificate.PublicKey().Algorithm.Value + ")");
			Console.WriteLine( "  Length     = " + Certificate.PublicKey().Length + " bits");
			Console.WriteLine( "  Key blob   = " + Certificate.PublicKey().EncodedKey.Format(true));
			Console.WriteLine( "  Parameters = " + Certificate.PublicKey().EncodedParameters.Format(true));
   
			if (Certificate.HasPrivateKey()) 
			{
				Console.WriteLine( "Private Key:");
				Console.WriteLine( "  Container name   = " + Certificate.PrivateKey.ContainerName);
				//Don't display unique container name for hardware token because it may cause UI to be displayed.
				if (! Certificate.PrivateKey.IsHardwareDevice()) 
				{
					Console.WriteLine( "  Unique name      = " + Certificate.PrivateKey.UniqueContainerName);
				}
				Console.WriteLine( "  Provider name    = " + Certificate.PrivateKey.ProviderName);
				Console.WriteLine(     "  Provider type    = " );
				if (Convert.ToInt32(Certificate.PrivateKey.ProviderType) > ProviderTypes.GetUpperBound(0))
				{
					Console.WriteLine( ProviderTypes[0] + " (" + Convert.ToString(Certificate.PrivateKey.ProviderType) + ")");
				}
				else
				{
					Console.WriteLine( ProviderTypes[Convert.ToInt32(Certificate.PrivateKey.ProviderType)] + " (" + Convert.ToString(Certificate.PrivateKey.ProviderType) + ")");
				}
				Console.WriteLine(     "  Key spec         = " );
				if (Convert.ToInt32(Certificate.PrivateKey.KeySpec) > KeySpecStrings.GetUpperBound(0)) 
				{
					Console.WriteLine( KeySpecStrings[0] + " (" + Convert.ToString(Certificate.PrivateKey.KeySpec) + ")");
				}
				else
				{
					Console.WriteLine( KeySpecStrings[Convert.ToInt32(Certificate.PrivateKey.KeySpec)] + " (" + Convert.ToString(Certificate.PrivateKey.KeySpec) + ")");
				}
				Console.WriteLine( "  Accessible       = " + Certificate.PrivateKey.IsAccessible());
				Console.WriteLine( "  Protected        = " + Certificate.PrivateKey.IsProtected());
				Console.WriteLine( "  Exportable       = " + Certificate.PrivateKey.IsExportable());
				Console.WriteLine( "  Removable        = " + Certificate.PrivateKey.IsRemovable());
				Console.WriteLine( "  Machine keyset   = " + Certificate.PrivateKey.IsMachineKeyset());
				Console.WriteLine( "  Hardware storage = " + Certificate.PrivateKey.IsHardwareDevice());
			}
			else
			{
				Console.WriteLine( "Private Key: Not found." );
			}
			Console.WriteLine();
   
			if (true) 
			{
				int iIndex = 0;
		
				foreach (Extension Extension in Certificate.Extensions())
				{
					iIndex++;
					Console.WriteLine( "Extension #" + Convert.ToString(iIndex) + ": " + Extension.OID.FriendlyName + "(" + Extension.OID.Value + ")");
					Console.WriteLine( "  " + Extension.EncodedData.Format(true));
         
					if (Extension.EncodedData.Decoder() != null)
					{
						switch (Extension.OID.Value)
						{
							case Constants.CAPICOM_CERT_POLICIES_OID:
							{
								CertificatePolicies CertPolicies;
								int pIndex = 0;

								CertPolicies = (CertificatePolicies)Extension.EncodedData.Decoder();
								Console.WriteLine( "Decoded Certificate Policies: " + Convert.ToString(CertPolicies.Count) + " PolicyInformation(s)");
               
								foreach  (PolicyInformation PolicyInformation in CertPolicies)
								{
									int qIndex = 0;
									pIndex++;
									Console.WriteLine( "  PolicyInformation #" + Convert.ToString(pIndex) + ": " + Convert.ToString(PolicyInformation.Qualifiers.Count) + " Qualifier(s)");
									Console.WriteLine( "    OID = " + PolicyInformation.OID.FriendlyName + "(" + PolicyInformation.OID.Value + ")");
                  
                  
									foreach (Qualifier Qualifier  in PolicyInformation.Qualifiers)
									{
										qIndex++;
										Console.WriteLine( "    Qualifier #" + Convert.ToString(qIndex) + ":");
										Console.WriteLine( "      OID               = " + Qualifier.OID.FriendlyName + "(" + Qualifier.OID.Value + ")");
										Console.WriteLine( "      CPS URI           = " + Qualifier.CPSPointer);
										Console.WriteLine( "      Organization name = " + Qualifier.OrganizationName);
										Console.WriteLine( "      Notice number(s)  = ");
										if (Qualifier.NoticeNumbers != null) 
										{
											foreach (NoticeNumbers NoticeNumber in Qualifier.NoticeNumbers)
											{
												Console.WriteLine( Convert.ToString(NoticeNumber));
											}
										}
										Console.WriteLine();
										Console.WriteLine( "      Explicit text     = " + Qualifier.ExplicitText);
									}
									Console.WriteLine();
								}
								break;
							}
						}
					}
				}
				if (iIndex == 0) 
				{
					Console.WriteLine( "Extension: None.");
					Console.WriteLine();
				}
      
				iIndex = 0;
				foreach (ExtendedProperty ExtendedProperty in Certificate.ExtendedProperties())
				{
					iIndex ++;
					Console.WriteLine( "Property #" + Convert.ToString(iIndex) + " (ID = " + ExtendedProperty.PropID + "):" );
					Console.WriteLine( "  " + ExtendedProperty.get_Value(CAPICOM_ENCODING_TYPE.CAPICOM_ENCODE_BASE64));
				}
				if (iIndex == 0) 
				{
					Console.WriteLine( "Property: None.");
					Console.WriteLine();
				}
				
			}
		}
	}

	
}

  

//******************************************************************************
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
//
// Copyright (C) 1999- 2002.  Microsoft Corporation.  All rights reserved.
//
//******************************************************************************
//
// chainsh.cs
//
// This is a C# sample that illustrates how to use features introduced in
// CAPICOM's bridging support to interop between CAPI and CAPICOM.
//
// Note: for simplicity, this script does not handle exceptions.
//
//******************************************************************************

using System;
using CAPICOM;
using System.Collections;
using System.Runtime.InteropServices;


namespace Sample
{
	public class Win32 
	{
			
		[DllImport("crypt32.dll",CharSet=CharSet.Unicode)]
		public static extern uint CertOpenSystemStore(
			uint hProv, 
			String szSubsystemProtocol 
			);

		[DllImport("crypt32.dll",CharSet=CharSet.Unicode)]
		public static extern uint  CertFindChainInStore(
			uint hCertStore,
			uint dwCertEncodingType,
			uint dwFindFlags,
			uint dwFindType,
			ref CERT_CHAIN_FIND_BY_ISSUER_PARA pvFindData,
			uint pPrevChainContext
			);

		public struct CERT_CHAIN_FIND_BY_ISSUER_PARA 
		{
			public int  cbSize;
			public String pszUsageIdentifier;  
			public uint dwKeySpec;
			public uint dwAcquirePrivateKeyFlags;
			public uint cIssuer;
			public uint rgIssuer;
			public uint pfnFindCallback;
			public uint pvFindArg;
			public uint pdwIssuerChainIndex;
			public uint pdwIssuerElementIndex;
		}
	}
	
	class Sample
	{
		[STAThread]
		public static void Main(string[] args)
		{	
			uint pStoreContext  = 0;
			uint pChainContext  = 0;
			String [] input     = new String[2];
			bool done           = false;
			
			displayHelp();

			while (!done)
			{
				Console.Write(">>");
				input = Console.ReadLine().Split(' ');
				
				//parse command line
				if (input[0].ToLower() == "q" || input[0].ToLower() == "quit")
				{
					done = true;
				}
				else if(input[0].ToLower() == "help" || input[0].ToLower() == "h")
				{
					displayHelp();
				}
				else if (input[0].ToLower() == "open"  || input[0].ToLower() == "o")
				{
					if (input.Length == 2)
					{
						pStoreContext = openStore(input[1]);
					}
					else
					{
						displayHelp();
					}
				}
				else if (input[0].ToLower() == "chains" || input[0].ToLower() == "c")
				{
					showChains(pStoreContext);	
				}
				else if (input[0].ToLower() == "display"  || input[0].ToLower() == "d")
				{
					if (input.Length == 2)
					{
						pChainContext = getChainFromStore(pStoreContext, System.Convert.ToInt32(input[1]));	
					
						if (pChainContext == 0)
						{
							Console.WriteLine("Couldn't display chain with indexnvalid chain index.");
						}
						else				
						{
							displayChain(pChainContext);
						}
					}
					else
					{
						displayHelp();
					}
					
				}
				else if (input[0].ToLower() == "verify"  || input[0].ToLower() == "v")
				{
					if (input.Length == 2)
					{
						pChainContext = getChainFromStore(pStoreContext, System.Convert.ToInt32(input[1]));	
						
						if (pChainContext == 0)
						{
							Console.WriteLine("Invalid chain index.");
						}
						else
						{				
							checkValidity(pChainContext);						
						}
					}
					else
					{
						displayHelp();				
					}		
				}
			}
		}
		
		public static uint openStore(String szStoreName)
		{
			
			uint  pStoreContext = 0;     // system store handle
			ICertStore iStore;			
			Store oStore;				 // CAPICOM object
			
			//verify that valid system store name was passed in
			if (szStoreName.ToLower() != "my" & 
				szStoreName.ToLower() != "ca" &
				szStoreName.ToLower() != "root")
			{	
				displayHelp();
				return 0;
			}
						
			try 
			{
				//open system store, use default CSP
				pStoreContext = Win32.CertOpenSystemStore(
					0,
					szStoreName);
				
				// API bridging
				oStore = new StoreClass();
				iStore = (ICertStore)oStore;
				iStore.StoreHandle = (int)pStoreContext;

				Console.WriteLine ("The store has " + oStore.Certificates.Count + " certificates");
				
				return pStoreContext;
			}
			catch (Exception e)
			{
				Console.WriteLine("Error in " + e.Source + ": " + e.Message);
				return 0;
			}
		}
		public static void showChains(uint pStoreContext)
		{
			const uint X509_ASN_ENCODING						= 0x00000001;
			const uint PKCS_7_ASN_ENCODING						= 0x00010000;
			const uint CERT_CHAIN_FIND_BY_ISSUER				= 1;
			const uint CERT_CHAIN_FIND_BY_ISSUER_NO_KEY_FLAG	=  0x4000;

			uint  pChainContext = 0;
					
			if (pStoreContext == 0)
			{	
				Console.WriteLine("No store is currently open.");
				return;
			}
			
			Win32.CERT_CHAIN_FIND_BY_ISSUER_PARA pvFindPara =
								new Win32.CERT_CHAIN_FIND_BY_ISSUER_PARA();
			
			//get size of CERT_CHAIN_FIND_BY_ISSUER_PARA struct
			pvFindPara.cbSize = Marshal.SizeOf(pvFindPara);
			try 
			{
				//get first chain
				pChainContext = Win32.CertFindChainInStore(
					pStoreContext,
					X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
					CERT_CHAIN_FIND_BY_ISSUER_NO_KEY_FLAG,
					CERT_CHAIN_FIND_BY_ISSUER,
					ref pvFindPara,
					0
					);

				//get the rest 		
				while (pChainContext != 0)
				{
					displayChain(pChainContext);  // display chains
					pChainContext = Win32.CertFindChainInStore(
						pStoreContext,
						X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
						CERT_CHAIN_FIND_BY_ISSUER_NO_KEY_FLAG,
						CERT_CHAIN_FIND_BY_ISSUER,
						ref pvFindPara,
						pChainContext);
					
				}
				return;
			}
			catch (Exception e)
			{
				Console.WriteLine("Error in " + e.Source + ": " + e.Message);
				return;
			}
		}
		public static uint getChainFromStore(uint pStoreContext, int index)
		{
			const uint X509_ASN_ENCODING						= 0x00000001;
			const uint PKCS_7_ASN_ENCODING						= 0x00010000;
			const uint CERT_CHAIN_FIND_BY_ISSUER				= 1;
			const uint CERT_CHAIN_FIND_BY_ISSUER_NO_KEY_FLAG	=  0x4000;

			uint  pChainContext = 0;
					
			if (pStoreContext == 0)
			{	
				Console.WriteLine("No store is currently open.");
				return 0;
			}
			
			Win32.CERT_CHAIN_FIND_BY_ISSUER_PARA pvFindPara =
				new Win32.CERT_CHAIN_FIND_BY_ISSUER_PARA();
			
			//get size of CERT_CHAIN_FIND_BY_ISSUER_PARA struct
			pvFindPara.cbSize = Marshal.SizeOf(pvFindPara);
			try 
			{
				//get the chain
				while (index > 0)
				{
					pChainContext = Win32.CertFindChainInStore(
						pStoreContext,
						X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
						CERT_CHAIN_FIND_BY_ISSUER_NO_KEY_FLAG,
						CERT_CHAIN_FIND_BY_ISSUER,
						ref pvFindPara,
						pChainContext);

					if (pChainContext == 0)
					{
						Console.WriteLine(" Couldn't find chain with index " + index);
						return 0;
					}					
					index--;					
				}
				return pChainContext;
			}
			catch (Exception e)
			{
				Console.WriteLine("Error in " + e.Source + ": " + e.Message);
				return 0;
			}
		}
		public static void checkValidity(uint pChainContext)
		{	
			IChainContext iChain;
			CAPICOM.Chain oChain;	
			int status;
				
			//API bridging
			oChain = new ChainClass();
			iChain = (IChainContext)oChain;
			iChain.ChainContext = (int)pChainContext;

			//get status of the entire chain
			status = oChain.get_Status(0);
			
			if (status == 0)
			{
				Console.Write("The chain appears trustworthy.");
				Console.WriteLine();
				return;
			}
			
			Console.WriteLine("The chain is invalid.");

			// display specific chain status
			// note: for simplicity, only SOME possible status 
			// values are presented below
			if ((status & Constants.CAPICOM_TRUST_IS_NOT_TIME_VALID) == Constants.CAPICOM_TRUST_IS_NOT_TIME_VALID)
				Console.WriteLine("Chain status: not time valid");
				
			if ((status & Constants.CAPICOM_TRUST_IS_NOT_TIME_NESTED) == Constants.CAPICOM_TRUST_IS_NOT_TIME_NESTED)
				Console.WriteLine("Chain status: time nested.");
				
			if ((status & Constants.CAPICOM_TRUST_IS_REVOKED) == Constants.CAPICOM_TRUST_IS_REVOKED)
				Console.WriteLine("Chain status: is revoked");
				
			if ((status & Constants.CAPICOM_TRUST_IS_NOT_SIGNATURE_VALID) == Constants.CAPICOM_TRUST_IS_REVOKED)
				Console.WriteLine("Chain status:  invalid signature");
				
			if ((status & Constants.CAPICOM_TRUST_IS_UNTRUSTED_ROOT) == Constants.CAPICOM_TRUST_IS_UNTRUSTED_ROOT)
					Console.WriteLine("Chain status: untrusted root");
				
			if ((status & Constants.CAPICOM_TRUST_REVOCATION_STATUS_UNKNOWN) == Constants.CAPICOM_TRUST_REVOCATION_STATUS_UNKNOWN)
					Console.WriteLine("Chain status: revocation status unknown");
				
			if ((status & Constants.CAPICOM_TRUST_INVALID_EXTENSION) == Constants.CAPICOM_TRUST_INVALID_EXTENSION)
					Console.WriteLine("Chain status: invalid extension");
				
			if ((status & Constants.CAPICOM_TRUST_INVALID_POLICY_CONSTRAINTS) == Constants.CAPICOM_TRUST_INVALID_POLICY_CONSTRAINTS)
					Console.WriteLine("Chain status: invalid policy constraints");
				
			if ((status & Constants.CAPICOM_TRUST_INVALID_BASIC_CONSTRAINTS) == Constants.CAPICOM_TRUST_INVALID_BASIC_CONSTRAINTS)
					Console.WriteLine("Chain status: invalid basic constraints");
				
			if ((status & Constants.CAPICOM_TRUST_INVALID_NAME_CONSTRAINTS) == Constants.CAPICOM_TRUST_INVALID_NAME_CONSTRAINTS)
					Console.WriteLine("Chain status:  invalid name constraints");
				
			if ((status & Constants.CAPICOM_TRUST_IS_OFFLINE_REVOCATION) == Constants.CAPICOM_TRUST_IS_OFFLINE_REVOCATION)
					Console.WriteLine("Chain status: offline revocation");
			
			if ((status & Constants.CAPICOM_TRUST_IS_PARTIAL_CHAIN) == Constants.CAPICOM_TRUST_IS_PARTIAL_CHAIN)
					Console.WriteLine("Chain status: partial chain");
				
			Console.WriteLine();
						
		}
		public static void displayChain(uint pChainContext)
		{
			Certificate cert;
			IChainContext iChain;
			CAPICOM.Chain oChain;
				
			IEnumerator eEnum;
			int i = 0;
					
			//API bridging
			oChain = new ChainClass();
			iChain = (IChainContext)oChain;
			iChain.ChainContext = (int)pChainContext;

			//get the number of certificates in chain
			eEnum = oChain.Certificates.GetEnumerator();
			
			Console.WriteLine();
			Console.WriteLine("Chain: ");

			//display properties of each certificate in the chain
			while (eEnum.MoveNext() == true)
			{
				i++;
				cert = (Certificate) eEnum.Current;
				Console.WriteLine("Certificate: " + i);
				Console.WriteLine("Subject: " + cert.SubjectName);
				Console.WriteLine("Issuer: " + cert.IssuerName);
				Console.WriteLine("Hash: " + cert.Thumbprint);
				Console.WriteLine("Valid From: " + cert.ValidFromDate);
				Console.WriteLine("Valid To: " + cert.ValidToDate);
				Console.WriteLine();
			}
		}	
		
		public static void displayHelp()
		{
			const int HELP_PAD = 30;

			Console.WriteLine("Usage:");
			Console.WriteLine();
			Console.Write("[h]elp".PadRight(HELP_PAD, ' '));
			Console.WriteLine("This screen");

			Console.WriteLine();
			Console.Write("[o]pen ".PadRight(HELP_PAD, ' '));
			Console.WriteLine("Open 'my', 'ca', or 'root' system store");
								
			Console.WriteLine();
			Console.Write("[c]hains".PadRight(HELP_PAD, ' '));
			Console.WriteLine("List all chains found in store");
				
			Console.WriteLine();
			Console.Write("[d]isplay ".PadRight(HELP_PAD, ' '));
			Console.WriteLine(" is the number of the chain to display");

			Console.WriteLine();
			Console.Write("[v]erify ".PadRight(HELP_PAD, ' '));
			Console.WriteLine(" is the number of the chain to verify");

			Console.WriteLine();
			Console.Write("[q]uit".PadRight(HELP_PAD, ' '));
			Console.WriteLine("Exit this program.");

			Console.WriteLine();
		}

	}
}

  

你可能感兴趣的:(csharp: SDK:CAPICOM)