Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/aspnetcore.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAditya Mandaleeka <adityamandaleeka@users.noreply.github.com>2022-11-04 06:31:00 +0300
committerGitHub <noreply@github.com>2022-11-04 06:31:00 +0300
commitd417c3a9bd655808cb04e25b92ae095398c171c5 (patch)
tree144633fbaf671c93be6eed1290cbbf6da822795d
parent2e2972065f59a186259b7d19357951a4874686c4 (diff)
Make Kestrel prefer on-disk cert for macOS bind. (#44835)
-rw-r--r--src/Servers/Kestrel/Core/src/KestrelServerOptions.cs2
-rw-r--r--src/Shared/CertificateGeneration/CertificateManager.cs4
-rw-r--r--src/Shared/CertificateGeneration/MacOSCertificateManager.cs17
3 files changed, 13 insertions, 10 deletions
diff --git a/src/Servers/Kestrel/Core/src/KestrelServerOptions.cs b/src/Servers/Kestrel/Core/src/KestrelServerOptions.cs
index fc6322dd41..9a76bb8432 100644
--- a/src/Servers/Kestrel/Core/src/KestrelServerOptions.cs
+++ b/src/Servers/Kestrel/Core/src/KestrelServerOptions.cs
@@ -287,7 +287,7 @@ public class KestrelServerOptions
var logger = ApplicationServices!.GetRequiredService<ILogger<KestrelServer>>();
try
{
- DefaultCertificate = CertificateManager.Instance.ListCertificates(StoreName.My, StoreLocation.CurrentUser, isValid: true)
+ DefaultCertificate = CertificateManager.Instance.ListCertificates(StoreName.My, StoreLocation.CurrentUser, isValid: true, requireExportable: false)
.FirstOrDefault();
if (DefaultCertificate != null)
diff --git a/src/Shared/CertificateGeneration/CertificateManager.cs b/src/Shared/CertificateGeneration/CertificateManager.cs
index 97616be6d1..e5fba1e410 100644
--- a/src/Shared/CertificateGeneration/CertificateManager.cs
+++ b/src/Shared/CertificateGeneration/CertificateManager.cs
@@ -78,7 +78,7 @@ internal abstract class CertificateManager
{
using var store = new X509Store(storeName, location);
store.Open(OpenFlags.ReadOnly);
- PopulateCertificatesFromStore(store, certificates);
+ PopulateCertificatesFromStore(store, certificates, requireExportable);
IEnumerable<X509Certificate2> matchingCertificates = certificates;
matchingCertificates = matchingCertificates
.Where(c => HasOid(c, AspNetHttpsOid));
@@ -161,7 +161,7 @@ internal abstract class CertificateManager
GetCertificateVersion(certificate) >= AspNetHttpsCertificateVersion;
}
- protected virtual void PopulateCertificatesFromStore(X509Store store, List<X509Certificate2> certificates)
+ protected virtual void PopulateCertificatesFromStore(X509Store store, List<X509Certificate2> certificates, bool requireExportable)
{
certificates.AddRange(store.Certificates.OfType<X509Certificate2>());
}
diff --git a/src/Shared/CertificateGeneration/MacOSCertificateManager.cs b/src/Shared/CertificateGeneration/MacOSCertificateManager.cs
index 343a93f00b..30237e445f 100644
--- a/src/Shared/CertificateGeneration/MacOSCertificateManager.cs
+++ b/src/Shared/CertificateGeneration/MacOSCertificateManager.cs
@@ -373,14 +373,14 @@ internal sealed class MacOSCertificateManager : CertificateManager
return ListCertificates(StoreName.My, StoreLocation.CurrentUser, isValid: false);
}
- protected override void PopulateCertificatesFromStore(X509Store store, List<X509Certificate2> certificates)
+ protected override void PopulateCertificatesFromStore(X509Store store, List<X509Certificate2> certificates, bool requireExportable)
{
if (store.Name! == StoreName.My.ToString() && store.Location == StoreLocation.CurrentUser && Directory.Exists(MacOSUserHttpsCertificateLocation))
{
var certsFromDisk = GetCertsFromDisk();
var certsFromStore = new List<X509Certificate2>();
- base.PopulateCertificatesFromStore(store, certsFromStore);
+ base.PopulateCertificatesFromStore(store, certsFromStore, requireExportable);
// Certs created by pre-.NET 7.
var onlyOnKeychain = certsFromStore.Except(certsFromDisk, ThumbprintComparer.Instance);
@@ -388,10 +388,13 @@ internal sealed class MacOSCertificateManager : CertificateManager
// Certs created (or "upgraded") by .NET 7+.
// .NET 7+ installs the certificate on disk as well as on the user keychain (for backwards
// compatibility with pre-.NET 7).
- // Note that the actual certs we populate need to be the ones from the store location, and
- // not the version from disk, since we may do other operations with these certs later (such
- // as exporting) which would fail with crypto errors otherwise.
- var onDiskAndKeychain = certsFromStore.Intersect(certsFromDisk, ThumbprintComparer.Instance);
+ // Note that if we require exportable certs, the actual certs we populate need to be the ones
+ // from the store location, and not the version from disk. If we don't require exportability,
+ // we favor the version of the cert that's on disk (avoiding unnecessary keychain access
+ // prompts). Intersect compares with the specified comparer and returns the matching elements
+ // from the first set.
+ var onDiskAndKeychain = requireExportable ? certsFromStore.Intersect(certsFromDisk, ThumbprintComparer.Instance)
+ : certsFromDisk.Intersect(certsFromStore, ThumbprintComparer.Instance);
// The only times we can find a certificate on the keychain and a certificate on keychain+disk
// are when the certificate on disk and keychain has expired and a pre-.NET 7 SDK has been
@@ -403,7 +406,7 @@ internal sealed class MacOSCertificateManager : CertificateManager
}
else
{
- base.PopulateCertificatesFromStore(store, certificates);
+ base.PopulateCertificatesFromStore(store, certificates, requireExportable);
}
}