Repository: dotnet/aspnetcore
File: src/Shared/CertificateGeneration/CertificateManager.cs (C#)

Code before:

    /// <remarks>Implementations may choose to throw, rather than returning <see cref="TrustLevel.None"/>.</remarks>
    protected abstract TrustLevel TrustCertificateCore(X509Certificate2 certificate);

    internal abstract bool IsExportable(X509Certificate2 c);

    protected abstract void RemoveCertificateFromTrustedRoots(X509Certificate2 certificate);

    protected abstract IList<X509Certificate2> GetCertificatesToRemove(StoreName storeName, StoreLocation storeLocation);

    protected abstract void CreateDirectoryWithPermissions(string directoryPath);

    /// <remarks>
    /// Will create directories to make it possible to write to <paramref name="path"/>.
    /// If you don't want that, check for existence before calling this method.
    /// </remarks>
    internal void ExportCertificate(X509Certificate2 certificate, string path, bool includePrivateKey, string? password, CertificateKeyExportFormat format)
    {
        if (Log.IsEnabled())
        {
            Log.ExportCertificateStart(GetDescription(certificate), path, includePrivateKey);
        }

        if (includePrivateKey && password == null)
        {
            Log.NoPasswordForCertificate();
        }

        var targetDirectoryPath = Path.GetDirectoryName(path);
        if (!string.IsNullOrEmpty(targetDirectoryPath))
        {
            Log.CreateExportCertificateDirectory(targetDirectoryPath);
            CreateDirectoryWithPermissions(targetDirectoryPath);
        }

        byte[] bytes;
        byte[] keyBytes;
        byte[]? pemEnvelope = null;
        RSA? key = null;

        try
        {
            if (includePrivateKey)
            {
                switch (format)
                {
                    case CertificateKeyExportFormat.Pfx:
                        bytes = certificate.Export(X509ContentType.Pkcs12, password);
                        break;
                    case CertificateKeyExportFormat.Pem:
                        key = certificate.GetRSAPrivateKey()!;

Review comment (suggestion):
@copilot
Might just be worth putting a try { } finally { cert.Dispose(); } around everything below this line.

Also EnsureAspNetCoreHttpsDevelopmentCertificate above doesn't look like it disposes the certificates in all cases.

Code after:
        }

        DisposeCertificates(!isNewCertificate ? certificates : certificates.Append(certificate));

        return result;
    }

    internal ImportCertificateResult ImportCertificate(string certificatePath, string password)
    {
        if (!File.Exists(certificatePath))
        {
            Log.ImportCertificateMissingFile(certificatePath);
            return ImportCertificateResult.CertificateFileMissing;
        }

        var certificates = ListCertificates(StoreName.My, StoreLocation.CurrentUser, isValid: false, requireExportable: false);
        if (certificates.Any())
        {
            if (Log.IsEnabled())
            {
                Log.ImportCertificateExistingCertificates(ToCertificateDescription(certificates));
            }
            return ImportCertificateResult.ExistingCertificatesPresent;
        }

        X509Certificate2? certificate = null;
        try
        {
            try
            {
                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())
                {
                    Log.LoadCertificateError(e.ToString());
                }
                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))
            {