/// <summary> /// Returns an object that can be used to access the store. /// </summary> public static ICertificateStore CreateStore(string storeType) { ICertificateStore store = null; if (String.IsNullOrEmpty(storeType)) { return(new CertificateIdentifierCollection()); } #if !SILVERLIGHT switch (storeType) { case CertificateStoreType.Windows: { store = new WindowsCertificateStore(); break; } case CertificateStoreType.Directory: { store = new DirectoryCertificateStore(); break; } } #endif return(store); }
/// <summary> /// Enumerates the available windows certificate store. /// </summary> public static IList<WindowsCertificateStore> EnumerateStores( WindowsStoreType storeType, string hostName, string serviceNameOrUserSid) { List<WindowsCertificateStore> stores = new List<WindowsCertificateStore>(); EnumResults results = new EnumResults(); GCHandle hResults = GCHandle.Alloc(results, GCHandleType.Pinned); IntPtr wszStoreBaseName = IntPtr.Zero; try { uint dwFlags = 0; // contruct base name for the store to enumerate. string storeBaseName = null; if (!String.IsNullOrEmpty(hostName) && hostName != ".") { storeBaseName = Utils.Format("{0}", hostName); } if (!String.IsNullOrEmpty(serviceNameOrUserSid)) { if (!String.IsNullOrEmpty(storeBaseName)) { storeBaseName = Utils.Format("{0}\\{1}", storeBaseName, serviceNameOrUserSid); } else { storeBaseName = serviceNameOrUserSid; } } // allocate the store base name. wszStoreBaseName = DuplicateString(storeBaseName); // set the flags based on store type. dwFlags |= GetFlags(storeType); // get list of names. results.Capacity = 10; results.Count = 0; results.Names = Marshal.AllocHGlobal(results.Capacity*IntPtr.Size); IntPtr pResults = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(EnumResults))); Marshal.StructureToPtr(results, pResults, false); int bResult = NativeMethods.CertEnumSystemStore( dwFlags, wszStoreBaseName, pResults, EnumStoreCallback); int dwError = Marshal.GetLastWin32Error(); results = (EnumResults)Marshal.PtrToStructure(pResults, typeof(EnumResults)); Marshal.DestroyStructure(pResults, typeof(EnumResults)); Marshal.FreeHGlobal(pResults); if (bResult == 0) { throw ServiceResultException.Create( StatusCodes.BadUnexpectedError, "Can't enumerate the contents of the certificate store.\r\nType={0}, HostName={1}, ServiceNameOrUserSid={2}, Error={3:X8}", storeType, hostName, serviceNameOrUserSid, dwError); } // copy names. IntPtr[] names = new IntPtr[results.Count]; Marshal.Copy(results.Names, names, 0, results.Count); for (uint ii = 0; ii < results.Count; ii++) { IntPtr wszSymbolicName = names[ii]; IntPtr hStore = NativeMethods.CertOpenStore( new IntPtr(CERT_STORE_PROV_SYSTEM), 0, IntPtr.Zero, GetFlags(storeType) | CERT_STORE_READONLY_FLAG | CERT_STORE_OPEN_EXISTING_FLAG, wszSymbolicName); if (hStore == IntPtr.Zero) { continue; } int result = NativeMethods.CertCloseStore(hStore, 0); if (result == 0) { Utils.Trace("Could not close certificate store. Error={0:X8}", Marshal.GetLastWin32Error()); } WindowsCertificateStore store = new WindowsCertificateStore(); store.m_symbolicName = Marshal.PtrToStringUni(wszSymbolicName); store.m_storeType = storeType; store.m_displayName = store.m_symbolicName; // extract the store name from the end of the symbolic name. int index = store.m_symbolicName.LastIndexOf('\\'); if (index >= 0) { store.m_displayName = store.m_symbolicName.Substring(index+1); store.m_serviceNameOrUserSid = store.m_symbolicName.Substring(0, index); } // check if the service name or user sid has a host name prefix. if (!String.IsNullOrEmpty(store.m_serviceNameOrUserSid)) { index = store.m_serviceNameOrUserSid.LastIndexOf('\\'); if (index >= 0) { store.m_hostName = store.m_serviceNameOrUserSid.Substring(0, index); store.m_serviceNameOrUserSid = store.m_serviceNameOrUserSid.Substring(index+1); } } // remove the leading '\\' from the host name. if (!String.IsNullOrEmpty(store.m_hostName)) { if (store.m_hostName.StartsWith("\\\\", StringComparison.Ordinal)) { store.m_hostName = store.m_hostName.Substring(2); } } store.m_displayName = GetStoreDisplayName(store.m_storeType, store.m_serviceNameOrUserSid, store.m_symbolicName); // add the store to the list. stores.Add(store); } } finally { if (results.Names != IntPtr.Zero) { IntPtr[] names = new IntPtr[results.Count]; Marshal.Copy(results.Names, names, 0, results.Count); for (uint ii = 0; ii < names.Length; ii++) { Marshal.FreeHGlobal(names[ii]); } Marshal.FreeHGlobal(results.Names); } if (hResults.IsAllocated) { hResults.Free(); } if (wszStoreBaseName != IntPtr.Zero) { Marshal.FreeHGlobal(wszStoreBaseName); } } return stores; }
/// <summary> /// Returns an object that can be used to access the store. /// </summary> public static ICertificateStore CreateStore(string storeType) { ICertificateStore store = null; if (String.IsNullOrEmpty(storeType)) { return new CertificateIdentifierCollection(); } #if !SILVERLIGHT switch (storeType) { case CertificateStoreType.Windows: { store = new WindowsCertificateStore(); break; } case CertificateStoreType.Directory: { store = new DirectoryCertificateStore(); break; } } #endif return store; }