HTTPS certificate not found

HI,

I’m trying to configure HTTPS for the admin site and the rest API’s I’ve created.
I’ve configured the appsettings.json as below:

“Kestrel”: {
“Endpoints”: {
“HTTP”: {
“Url”: “http://:5000"
},
“HTTPS”: {
“Url”: "https://
:5001”,
“Certificate”: {
“Subject”: “CN=xxx, O=xxx, L=xxx, C=xxx”,
“Store”: “Root”,
“Location”: “LocalMachine”,
“AllowInvalid”: “true”
}
}
}

I’ve installed Universal using the MSI and it runs as local system as a windows service.
However, it doesn’t start and gives the error:

Unable to start Kestrel. (fc6a528d)
System.InvalidOperationException: The requested certificate CN=xxx, O=xxx, L=xxx, C=xxx could not be found in LocalMachine/Root with AllowInvalid setting: False.

I’ve checked the certificates MMC and can see it installed.
Get-ChildItem -Path cert:\LocalMachine\root\ | Select-Object subject

Lists my certificate.
Is there any command I can run to check?

Thanks,

Product: PowerShell Universal
Version: 1.4.6

You could try to run the command Get-ChildItem -Path cert:\LocalMachine\root\ | Select-Object subject within an Automation job so it’s running as the same local system account to validate that it’s picking up the cert there.

Hi There,
I have the same issue … just cannot seem to find the certificate

I added the “Get-ChildItem -Path Cert:LocalMachine/My” command to one of my API functions and the certificate is found …

So I do not know haw to proceed …
The only way forward would be to host the service in IIS …

Any further suggestions?
Cheers Paul

I have just update to the latest version 1.5.0 … as soon I try to enable HTTPS in appsettings.json
“Kestrel”: {
“Endpoints”: {
“HTTP”: {
“Url”: “http://:5000"
},
“HttpsInlineCertStore”: {
“Url”: "https://
:5001”,
“Certificate”: {
“Subject”: “CN=xxxxxxx.dddd.ch”,
“Store”: “My”,
“Location”: “LocalMachine”,
“AllowInvalid”: “false”
}
}
},
“RedirectToHttps”: “true”
},
I get the following Exception:
2020-11-18 04:08:33 [INFO] (Hangfire.Server.BackgroundServerProcess) Server xxxxxxx:4932:502e050d has been stopped in total 771.4286 ms
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

But still the cert is found when Looking it up inside an API function

Cheers Paul

I’ve done some digging into this. I actually recreated the CertificateLoader class used by ASP.NET in PowerShell. This is the class that is internally being used to look up the cert.

Here’s that 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  }

What I found is that I needed to avoid including the CN= in the subject name. So for my CN=localhost cert, I had to use localhost in the appsettings.json.

PS C:\Users\adamr\Desktop> c:\Users\adamr\Desktop\findcert.ps1

Thumbprint                                Subject              EnhancedKeyUsageList 
----------                                -------              -------------------- 
F1F2CC29D68E05E3561293BA3955286A7AF751C3  CN=localhost         Server Authentication

PS C:\Users\adamr\Desktop> dir Cert:\LocalMachine\my


   PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\my

Thumbprint                                Subject              EnhancedKeyUsageList
----------                                -------              --------------------
F1F2CC29D68E05E3561293BA3955286A7AF751C3  CN=localhost         Server Authentication

You should be able to run that script to experiment faster than trying to start the PSU server over and over again.

Hello Adam,
first let me thank you for the fast response :slight_smile: and taking my request serious!
First I took the script ran it on my server and everything worked fine. Then I changed my appsettings.json and started the server … it worked!!!
HTTPS over Kestrel seems to work now!!

Only thing I need to investigate a bit is, that if you have more than one certificate with very similar subject names, it seems to find more than one certificate and just takes the first … which could be the wrong one …

But hey HTTPS work!! Thanks alot!!
Cheers Paul

1 Like

Working for me too.
Thank you so much :relaxed: