Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 78 additions & 36 deletions src/Shared/CertificateGeneration/CertificateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,18 +236,22 @@ public EnsureCertificateResult EnsureAspNetCoreHttpsDevelopmentCertificate(

var currentUserCertificates = ListCertificates(StoreName.My, StoreLocation.CurrentUser, isValid: true, requireExportable: true);
var localMachineCertificates = ListCertificates(StoreName.My, StoreLocation.LocalMachine, isValid: true, requireExportable: true);
var certificates = currentUserCertificates.Concat(localMachineCertificates);
var allCertificates = currentUserCertificates.Concat(localMachineCertificates).ToList();

var filteredCertificates = certificates.Where(c => c.Subject == Subject);
var filteredCertificates = allCertificates.Where(c => c.Subject == Subject).ToList();

if (Log.IsEnabled())
{
var excludedCertificates = certificates.Except(filteredCertificates);
var excludedCertificates = allCertificates.Except(filteredCertificates);
Log.FilteredCertificates(ToCertificateDescription(filteredCertificates));
Log.ExcludedCertificates(ToCertificateDescription(excludedCertificates));
}

certificates = filteredCertificates;
// Dispose certificates we're not going to use
var certificatesToDispose = allCertificates.Except(filteredCertificates);
DisposeCertificates(certificatesToDispose);

var certificates = filteredCertificates;

X509Certificate2? certificate = null;
var isNewCertificate = false;
Expand Down Expand Up @@ -319,6 +323,7 @@ public EnsureCertificateResult EnsureAspNetCoreHttpsDevelopmentCertificate(
Log.CreateDevelopmentCertificateError(e.ToString());
}
result = EnsureCertificateResult.ErrorCreatingTheCertificate;
DisposeCertificates(certificates);
return result;
}
Log.CreateDevelopmentCertificateEnd();
Expand All @@ -330,6 +335,11 @@ public EnsureCertificateResult EnsureAspNetCoreHttpsDevelopmentCertificate(
catch (Exception e)
{
Log.SaveCertificateInStoreError(e.ToString());
if (isNewCertificate)
{
certificate?.Dispose();
}
DisposeCertificates(certificates);
result = EnsureCertificateResult.ErrorSavingTheCertificateIntoTheCurrentUserPersonalStore;
return result;
}
Expand Down Expand Up @@ -387,6 +397,11 @@ public EnsureCertificateResult EnsureAspNetCoreHttpsDevelopmentCertificate(
result :
EnsureCertificateResult.ErrorExportingTheCertificate;

if (isNewCertificate)
{
certificate?.Dispose();
}
DisposeCertificates(certificates);
return result;
}
}
Expand All @@ -403,21 +418,41 @@ public EnsureCertificateResult EnsureAspNetCoreHttpsDevelopmentCertificate(
break;
case TrustLevel.Partial:
result = EnsureCertificateResult.PartiallyFailedToTrustTheCertificate;
if (isNewCertificate)
{
certificate?.Dispose();
}
DisposeCertificates(certificates);
return result;
case TrustLevel.None:
default: // Treat unknown status (should be impossible) as failure
result = EnsureCertificateResult.FailedToTrustTheCertificate;
if (isNewCertificate)
{
certificate?.Dispose();
}
DisposeCertificates(certificates);
return result;
}
}
catch (UserCancelledTrustException)
{
result = EnsureCertificateResult.UserCancelledTrustStep;
if (isNewCertificate)
{
certificate?.Dispose();
}
DisposeCertificates(certificates);
return result;
}
catch
{
result = EnsureCertificateResult.FailedToTrustTheCertificate;
if (isNewCertificate)
{
certificate?.Dispose();
}
DisposeCertificates(certificates);
return result;
}

Expand Down Expand Up @@ -454,51 +489,58 @@ internal ImportCertificateResult ImportCertificate(string certificatePath, strin
return ImportCertificateResult.ExistingCertificatesPresent;
}

X509Certificate2 certificate;
X509Certificate2? certificate = null;
try
{
Log.LoadCertificateStart(certificatePath);
certificate = new X509Certificate2(certificatePath, password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.EphemeralKeySet);
if (Log.IsEnabled())
try
{
Log.LoadCertificateEnd(GetDescription(certificate));
Log.LoadCertificateStart(certificatePath);
certificate = new X509Certificate2(certificatePath, password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.EphemeralKeySet);
if (Log.IsEnabled())
{
Log.LoadCertificateEnd(GetDescription(certificate));
}
}
}
catch (Exception e)
{
if (Log.IsEnabled())
catch (Exception e)
{
Log.LoadCertificateError(e.ToString());
if (Log.IsEnabled())
{
Log.LoadCertificateError(e.ToString());
}
return ImportCertificateResult.InvalidCertificate;
}
return ImportCertificateResult.InvalidCertificate;
}

// Note that we're checking Subject, rather than LocalhostHttpsDistinguishedName,
// because the tests use a different subject.
if (!string.Equals(certificate.Subject, Subject, StringComparison.Ordinal) || // Kestrel requires this
!IsHttpsDevelopmentCertificate(certificate))
{
if (Log.IsEnabled())
// Note that we're checking Subject, rather than LocalhostHttpsDistinguishedName,
// because the tests use a different subject.
if (!string.Equals(certificate.Subject, Subject, StringComparison.Ordinal) || // Kestrel requires this
!IsHttpsDevelopmentCertificate(certificate))
{
Log.NoHttpsDevelopmentCertificate(GetDescription(certificate));
if (Log.IsEnabled())
{
Log.NoHttpsDevelopmentCertificate(GetDescription(certificate));
}
return ImportCertificateResult.NoDevelopmentHttpsCertificate;
}
return ImportCertificateResult.NoDevelopmentHttpsCertificate;
}

try
{
SaveCertificate(certificate);
}
catch (Exception e)
{
if (Log.IsEnabled())
try
{
Log.SaveCertificateInStoreError(e.ToString());
certificate = SaveCertificate(certificate);
}
catch (Exception e)
{
if (Log.IsEnabled())
{
Log.SaveCertificateInStoreError(e.ToString());
}
return ImportCertificateResult.ErrorSavingTheCertificateIntoTheCurrentUserPersonalStore;
}
return ImportCertificateResult.ErrorSavingTheCertificateIntoTheCurrentUserPersonalStore;
}

return ImportCertificateResult.Succeeded;
return ImportCertificateResult.Succeeded;
}
finally
{
certificate?.Dispose();
}
}

public void CleanupHttpsCertificates()
Expand Down
Loading