Exact subject match for CertificateLoader (#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 <halter73@gmail.com>
This commit is contained in:
Volodymyr S 2021-07-23 01:04:25 +03:00 коммит произвёл GitHub
Родитель 32c457f547
Коммит 52bf9e55ba
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 16 добавлений и 4 удалений

Просмотреть файл

@ -20,6 +20,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https
/// <summary>
/// Loads a certificate from the certificate store.
/// </summary>
/// <remarks>
/// Exact subject match is loaded if present, otherwise best matching certificate with the subject name that contains supplied subject.
/// Subject comparison is case-insensitive.
/// </remarks>
/// <param name="subject">The certificate subject.</param>
/// <param name="storeName">The certificate store name.</param>
/// <param name="storeLocation">The certificate store location.</param>
@ -36,13 +40,21 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https
{
store.Open(OpenFlags.ReadOnly);
storeCertificates = store.Certificates;
var foundCertificates = storeCertificates.Find(X509FindType.FindBySubjectName, subject, !allowInvalid);
foundCertificate = foundCertificates
foreach (var certificate in storeCertificates.Find(X509FindType.FindBySubjectName, subject, !allowInvalid)
.OfType<X509Certificate2>()
.Where(IsCertificateAllowedForServerAuth)
.Where(DoesCertificateHaveAnAccessiblePrivateKey)
.OrderByDescending(certificate => certificate.NotAfter)
.FirstOrDefault();
.OrderByDescending(certificate => certificate.NotAfter))
{
// Pick the first one if there's no exact match as a fallback to substring default.
foundCertificate ??= certificate;
if (certificate.GetNameInfo(X509NameType.SimpleName, true).Equals(subject, StringComparison.InvariantCultureIgnoreCase))
{
foundCertificate = certificate;
break;
}
}
if (foundCertificate == null)
{