@@ -373,25 +373,28 @@ protected override IList<X509Certificate2> GetCertificatesToRemove(StoreName sto
373
373
return ListCertificates ( StoreName . My , StoreLocation . CurrentUser , isValid : false ) ;
374
374
}
375
375
376
- protected override void PopulateCertificatesFromStore ( X509Store store , List < X509Certificate2 > certificates )
376
+ protected override void PopulateCertificatesFromStore ( X509Store store , List < X509Certificate2 > certificates , bool requireExportable )
377
377
{
378
378
if ( store . Name ! == StoreName . My . ToString ( ) && store . Location == StoreLocation . CurrentUser && Directory . Exists ( MacOSUserHttpsCertificateLocation ) )
379
379
{
380
380
var certsFromDisk = GetCertsFromDisk ( ) ;
381
381
382
382
var certsFromStore = new List < X509Certificate2 > ( ) ;
383
- base . PopulateCertificatesFromStore ( store , certsFromStore ) ;
383
+ base . PopulateCertificatesFromStore ( store , certsFromStore , requireExportable ) ;
384
384
385
385
// Certs created by pre-.NET 7.
386
386
var onlyOnKeychain = certsFromStore . Except ( certsFromDisk , ThumbprintComparer . Instance ) ;
387
387
388
388
// Certs created (or "upgraded") by .NET 7+.
389
389
// .NET 7+ installs the certificate on disk as well as on the user keychain (for backwards
390
390
// compatibility with pre-.NET 7).
391
- // Note that the actual certs we populate need to be the ones from the store location, and
392
- // not the version from disk, since we may do other operations with these certs later (such
393
- // as exporting) which would fail with crypto errors otherwise.
394
- var onDiskAndKeychain = certsFromStore . Intersect ( certsFromDisk , ThumbprintComparer . Instance ) ;
391
+ // Note that if we require exportable certs, the actual certs we populate need to be the ones
392
+ // from the store location, and not the version from disk. If we don't require exportability,
393
+ // we favor the version of the cert that's on disk (avoiding unnecessary keychain access
394
+ // prompts). Intersect compares with the specified comparer and returns the matching elements
395
+ // from the first set.
396
+ var onDiskAndKeychain = requireExportable ? certsFromStore . Intersect ( certsFromDisk , ThumbprintComparer . Instance )
397
+ : certsFromDisk . Intersect ( certsFromStore , ThumbprintComparer . Instance ) ;
395
398
396
399
// The only times we can find a certificate on the keychain and a certificate on keychain+disk
397
400
// are when the certificate on disk and keychain has expired and a pre-.NET 7 SDK has been
@@ -403,7 +406,7 @@ protected override void PopulateCertificatesFromStore(X509Store store, List<X509
403
406
}
404
407
else
405
408
{
406
- base . PopulateCertificatesFromStore ( store , certificates ) ;
409
+ base . PopulateCertificatesFromStore ( store , certificates , requireExportable ) ;
407
410
}
408
411
}
409
412
0 commit comments