public IntPtr GetFirstCert(CertificateFilterInfo filter) { this.filterHandle = null; if (X509NativeStore.fIsWin8AndAbove && filter != null) { IntPtr zero = IntPtr.Zero; this.filterHandle = new CertificateFilterHandle(); int num = NativeMethods.CCFindCertificateBuildFilter(filter.FilterString, ref zero); if (num == 0) { this.filterHandle.Handle = zero; } else { this.filterHandle = null; throw new Win32Exception(num); } } return(this.GetNextCert(IntPtr.Zero)); }
public IntPtr GetFirstCert( CertificateFilterInfo filter) { _filterHandle = null; if (DownLevelHelper.NativeFilteringSupported() && filter != null) { IntPtr hFilter = IntPtr.Zero; _filterHandle = new CertificateFilterHandle(); int hr = Security.NativeMethods.CCFindCertificateBuildFilter( filter.FilterString, ref hFilter); if (hr != Security.NativeConstants.S_OK) { _filterHandle = null; throw new System.ComponentModel.Win32Exception(hr); } _filterHandle.Handle = hFilter; } return GetNextCert(IntPtr.Zero); }
// If it's Win8 or above, filter matching for certain properties is done by // the certificate enumeration filter at the API level. In that case, // filter.Purpose will be 'None' and MatchesFilter will return 'True'. private static bool MatchesFilter(X509Certificate2 cert, CertificateFilterInfo filter) { // // no filter means, match everything // if ((filter == null) || (filter.Purpose == CertificatePurpose.NotSpecified) || (filter.Purpose == CertificatePurpose.All)) { return true; } switch (filter.Purpose) { case CertificatePurpose.CodeSigning: if (SecuritySupport.CertIsGoodForSigning(cert)) { return true; } break; case CertificatePurpose.DocumentEncryption: if (SecuritySupport.CertIsGoodForEncryption(cert)) { return true; } break; default: break; } return false; }
private CertificateFilterInfo GetFilter() { CertificateFilterInfo filter = null; if (DynamicParameters != null) { if (DownLevelHelper.NativeFilteringSupported()) { CertificateProviderDynamicParameters dp = DynamicParameters as CertificateProviderDynamicParameters; if (dp != null) { bool filterSpecified = false; filter = new CertificateFilterInfo(); if (dp.CodeSigningCert) { filter.Purpose = CertificatePurpose.CodeSigning; filterSpecified = true; } if (dp.DocumentEncryptionCert) { filter.Purpose = CertificatePurpose.DocumentEncryption; filterSpecified = true; } if (dp.SSLServerAuthentication) { filter.SSLServerAuthentication = true; filterSpecified = true; } if (dp.DnsName.Punycode != null) { filter.DnsName = dp.DnsName.Punycode; filterSpecified = true; } if (dp.Eku != null) { filter.Eku = dp.Eku; filterSpecified = true; } if (dp.ExpiringInDays >= 0) { filter.ExpiringInDays = dp.ExpiringInDays; filterSpecified = true; } if (!filterSpecified) { filter = null; } } } else { CertificateProviderCodeSigningDynamicParameters dp = DynamicParameters as CertificateProviderCodeSigningDynamicParameters; if (dp != null) { if (dp.CodeSigningCert) { filter = new CertificateFilterInfo(); filter.Purpose = CertificatePurpose.CodeSigning; } } } } return filter; }
/// <summary> /// gets X509NativeStore objects or their name at the specified path. /// </summary> /// /// <param name="path"> path to the store </param> /// /// <param name="recurse"> recursively return all items if true </param> /// /// <param name="returnNames"> </param> /// /// <param name="filter"> filter info </param> /// /// <returns> Does not return a value </returns> /// /// <remarks> </remarks> /// private void GetStoresOrNames( string path, bool recurse, bool returnNames, CertificateFilterInfo filter) { object thingToReturn = null; X509StoreLocation location = GetStoreLocation(path); string storePath = null; // // enumerate over each store // foreach (string name in location.StoreNames.Keys) { storePath = MakePath(path, name); if (returnNames) { thingToReturn = name; } else { X509NativeStore store = GetStore(storePath, name, location); X509Store ManagedStore = new X509Store( store.StoreName, store.Location.Location); thingToReturn = ManagedStore; } // 'returnNames' is true only when called from // GetChildNames(), in which case 'recurse' will always be // false. When the -Path parameter needs to be globbed, // the potential store names should be returned by // calling this method from GetChildNames. // The original code didn't have a "|| returnNames" clause. // Suppose the user types: // dir cert:\CurrentUser\Tru* -CodeSigningCert -recurse // We need to do path globbing here to resolve wild cards. // Since -CodeSigningCert is present, 'filter' is not null. // Since this method is called from GetChildNames() when // doing the path globbing, 'returnNames' is true and // 'recurse' is false. // In the original code, nothing was returned by // WriteItemObject(), so the path globbing fails and the // above dir command would not display the certificates // as expected. // Another case is: // dir cert:\CurrentUser -CodeSigningCert -Recurse // -Recurse is present, so we need to call // DoManualGetChildItems, and inside DoManualGetChildItems, // this method will be called to get the names. // The original code had the same problem for this case. // With the "|| returnNames" clause, we test if this method // is called from the GetChildNames(). When this method is // called from GetChildNames(), 'recurse' will always be // false. Then we should return the names whether 'filter' // is null or not. if (filter == null || returnNames) { WriteItemObject(thingToReturn, name, true); } // // if recurse is true, get cert objects (or names) as well // if (recurse) { string[] pathElements = GetPathElements(storePath); GetCertificatesOrNames( storePath, pathElements, returnNames, filter); } } }
/// <summary> /// Get cert objects or their name at the specified path /// </summary> /// /// <param name="path"> path to cert </param> /// /// <param name="pathElements"> path elements </param> /// /// <param name="returnNames"> whether we should return only the names (instead of objects) </param> /// /// <param name="filter"> filter info </param> /// /// <returns> Does not return a value </returns> /// private void GetCertificatesOrNames(string path, string[] pathElements, bool returnNames, CertificateFilterInfo filter) { object thingToReturn = null; string certPath = null; X509NativeStore store = null; // // first open the store // store = GetStore(path, false, pathElements); store.Open(IncludeArchivedCerts()); // // enumerate over each cert and return it (or its name) // IntPtr certContext = store.GetFirstCert(filter); while (IntPtr.Zero != certContext) { X509Certificate2 cert = new X509Certificate2(certContext); if (MatchesFilter(cert, filter)) { string certName = GetCertName(cert); certPath = MakePath(path, certName); if (returnNames) { thingToReturn = (object)certName; } else { #if CORECLR //TODO:CORECLR See if there is a need to create a copy of cert like its done on Full PS X509Certificate2 cert2 = cert; #else X509Certificate2 cert2 = new X509Certificate2(cert); #endif PSObject myPsObj = new PSObject(cert2); thingToReturn = (object)myPsObj; } WriteItemObject(thingToReturn, certPath, false); } certContext = store.GetNextCert(certContext); } }
/// <summary> /// Helper function to get store-location/store/cert at /// the specified path. /// </summary> /// /// <param name="path"> path to the item </param> /// /// <param name="recurse"> whether we need to recursively find all </param> /// /// <param name="returnContainers"> /// Determines if all containers should be returned or only those containers that match the /// filter(s). /// </param> /// /// <param name="returnNames"> whether we only need the names </param> /// /// <param name="filter"> filter info </param> /// /// <returns> Does not return a value </returns> /// /// <remarks> </remarks> /// private void GetChildItemsOrNames( string path, bool recurse, ReturnContainers returnContainers, bool returnNames, CertificateFilterInfo filter) { object thingToReturn = null; string childPath = null; bool returnAllContainers = returnContainers == ReturnContainers.ReturnAllContainers; Utils.CheckArgForNull(path, "path"); // // children at the root path are store locations // if (path.Length == 0) { foreach (X509StoreLocation l in s_storeLocations) { thingToReturn = returnNames ? (object)l.LocationName : (object)l; // 'returnNames' is true only when called from // GetChildNames(), in which case 'recurse' will always be // false. When the -Path parameter needs to be globbed, // the potential location names should be returned by // calling this method from GetChildNames. // The original code didn't have a "|| returnNames" clause. // Suppose the user types: // dir cert:\curr* -CodeSigningCert -recurse // We need to do path globbing here to resolve wild cards. // Since -CodeSigningCert is present, 'filter' is not null. // Since this method is called from GetChildNames() when // doing the path globbing, 'returnNames' is true and // 'recurse' is false. // In the original code, nothing was returned by // WriteItemObject(), so the path globbing fails and the // above dir command would not display the certificates // as expected. // Another case is: // dir cert:\ -CodeSigningCert -Recurse // -Recurse is present, so we need to call // DoManualGetChildItems, and inside DoManualGetChildItems, // this method will be called to get the names. // The original code had the same problem for this case. // With the "|| returnNames" clause, we test if this method // is called from the GetChildNames(). When this method is // called from GetChildNames(), 'recurse' will always be // false. Then we should return the names whether 'filter' // is null or not. if (filter == null || returnNames) { WriteItemObject(thingToReturn, l.LocationName, true); } childPath = l.LocationName; if (recurse) { GetChildItemsOrNames( childPath, recurse, returnContainers, returnNames, filter); } } } else { string[] pathElements = GetPathElements(path); // // children at depth 1 are stores // if (pathElements.Length == 1) { GetStoresOrNames(pathElements[0], recurse, returnNames, filter); } // // children at depth 2 are certificates // else if (pathElements.Length == 2) { GetCertificatesOrNames(path, pathElements, returnNames, filter); } else { ThrowItemNotFound(path, CertificateProviderItem.Certificate); } } }