Skip to content

Commit 52bf9e5

Browse files
vstrhalter73
andauthored
Exact subject match for CertificateLoader (dotnet#34582)
* Enable exact subject match for LoadFromStoreCert * Usings revert/format * Added tests to cover other usecases * Commenting out added tests security: SecKeychainItemImport: User interaction is not allowed. * Performance improvements changes * Take the first certificate as in original implementation for substring * Reverting tests, using null-coalescing assignment operator * LoadFromStoreCert remarks added * Update src/Servers/Kestrel/Core/src/CertificateLoader.cs Co-authored-by: Stephen Halter <[email protected]>
1 parent 32c457f commit 52bf9e5

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

src/Servers/Kestrel/Core/src/CertificateLoader.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ public static class CertificateLoader
2020
/// <summary>
2121
/// Loads a certificate from the certificate store.
2222
/// </summary>
23+
/// <remarks>
24+
/// Exact subject match is loaded if present, otherwise best matching certificate with the subject name that contains supplied subject.
25+
/// Subject comparison is case-insensitive.
26+
/// </remarks>
2327
/// <param name="subject">The certificate subject.</param>
2428
/// <param name="storeName">The certificate store name.</param>
2529
/// <param name="storeLocation">The certificate store location.</param>
@@ -36,13 +40,21 @@ public static X509Certificate2 LoadFromStoreCert(string subject, string storeNam
3640
{
3741
store.Open(OpenFlags.ReadOnly);
3842
storeCertificates = store.Certificates;
39-
var foundCertificates = storeCertificates.Find(X509FindType.FindBySubjectName, subject, !allowInvalid);
40-
foundCertificate = foundCertificates
43+
foreach (var certificate in storeCertificates.Find(X509FindType.FindBySubjectName, subject, !allowInvalid)
4144
.OfType<X509Certificate2>()
4245
.Where(IsCertificateAllowedForServerAuth)
4346
.Where(DoesCertificateHaveAnAccessiblePrivateKey)
44-
.OrderByDescending(certificate => certificate.NotAfter)
45-
.FirstOrDefault();
47+
.OrderByDescending(certificate => certificate.NotAfter))
48+
{
49+
// Pick the first one if there's no exact match as a fallback to substring default.
50+
foundCertificate ??= certificate;
51+
52+
if (certificate.GetNameInfo(X509NameType.SimpleName, true).Equals(subject, StringComparison.InvariantCultureIgnoreCase))
53+
{
54+
foundCertificate = certificate;
55+
break;
56+
}
57+
}
4658

4759
if (foundCertificate == null)
4860
{

0 commit comments

Comments
 (0)