HTTPS Certificate Not Found

HTTPS Certificate Not Found

Version: Any
Issue:
After configuration the certificate for your PowerShell Universal and attempting to start the server, you receive the following error. 

Unhandled exception. System.InvalidOperationException: The requested certificate CN=xxxxxxxx.dddd.ch could not be found in LocalMachine/My with AllowInvalid setting: False.
at Microsoft.AspNetCore.Server.Kestrel.Https.CertificateLoader.LoadFromStoreCert(String subject, String storeName, StoreLocation storeLocation, Boolean allowInvalid)
at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.LoadFromStoreCert(CertificateConfig certInfo)
at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.LoadCertificate(CertificateConfig certInfo, String endpointName)
at Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader.Load()
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.ValidateOptions()
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)
at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
at Universal.Server.Program.Main(String[] args) in D:\a\universal\universal\src\Universal.Server\Program.cs:line 31
The certificate is correctly returned by PowerShell.
Get-ChildItem Cert:\LocalMachine\My
Root Cause:
The root cause of the issue is that the ASP.NET Core certificate location code is different than PowerShell. 
Workaround:
When specifying the certificate, do not use the fully qualified subject name. Rather, use the portion after CN=. For example, if PowerShell shows the subject name of my certificate as CN=localhost, then I would enter localhost in to appsettings.json. 
We have created a PowerShell script you can use to determine whether your certificate can be found by the web host. Enter your subject name in the variable below and run the script. 
$allowInvalid = $true
$subject = 'localhost'
$store = [System.Security.Cryptography.X509Certificates.X509Store]::new('My', 'LocalMachine')
$store.Open('ReadOnly')

$storeCertificates = $store.Certificates;
$foundCertificates = $storeCertificates.Find('FindBySubjectName', $Subject, $allowInvalid);

function Test-IsCertificateAllowedForServerAuth
{
    param($Cert)

    $ServerAuthenticationOid = "1.3.6.1.5.5.7.3.1";
    $result = $false 

    foreach($cert in $foundCertificates)
    {
        if ($cert.Extensions)
        {
            foreach($extension in $cert.Extensions  | Where-Object { $_ -is [System.Security.Cryptography.X509Certificates.X509EnhancedKeyUsageExtension] })
            {
                $result = $true
                foreach ($oid in $extension.EnhancedKeyUsages)
                {
                    if ($oid.Value -eq $ServerAuthenticationOid)
                    {
                        return $true;
                    }
                }
            }
        }
    }
    -not $result
}

$foundCertificates | Where-Object { (Test-IsCertificateAllowedForServerAuth $_) -and $_.HasPrivateKey  }