-
-
Save javiercn/9f2657f88498ce1b0b8c99d326131b54 to your computer and use it in GitHub Desktop.
dotnet-dev-certs diagnostics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Param( | |
[switch]$TryCreateCertificate | |
) | |
function Get-DevCertDiagnostics() { | |
$localHostCurrentUserPersonal = Get-ChildItem Cert:\CurrentUser\My -SSLServerAuthentication -DnsName localhost; | |
$localHostCurrentUserTrustedRoot = Get-ChildItem Cert:\CurrentUser\Root -SSLServerAuthentication -DnsName localhost; | |
$withOidCurrentUserPersonal = GetCertsWithOid(Get-ChildItem Cert:\CurrentUser\My); | |
$withOidCurrentUserTrustedRoot = GetCertsWithOid(Get-ChildItem Cert:\CurrentUser\Root); | |
$allData = [ordered]@{ | |
LocalhostCertificatesOnPersonalStore = $localHostCurrentUserPersonal | %{ GetCertData($_) }; | |
LocalhostCertificatesOnTrustedRoot = $localHostCurrentUserTrustedRoot | %{ GetCertData($_) }; | |
CertificatesWithAspNetOidOnPersonalStore = $withOidCurrentUserPersonal | %{ GetCertData($_) }; | |
CertificatesWithAspNetOidOnTrustedRoot = $withOidCurrentUserTrustedRoot | %{ GetCertData($_) }; | |
} | |
PrintDiagnostics($allData); | |
# return $allData; | |
} | |
function PrintDiagnostics ($allData) { | |
Write-Output "Localhost certificates on the current user store:"; | |
$allData.LocalhostCertificatesOnPersonalStore | Format-List; | |
Write-Output "Localhost certificates on the trust root for the current user:"; | |
$allData.LocalhostCertificatesOnTrustedRoot | Format-List; | |
Write-Output "Certificates with the ASP.NET Core Oid on the current user store:"; | |
$allData.CertificatesWithAspNetOidOnPersonalStore | Format-List; | |
Write-Output "Certificates with the ASP.NET Core Oid trust root for the current user:"; | |
$allData.CertificatesWithAspNetOidOnTrustedRoot | Format-List; | |
Write-Output "Specific checks:"; | |
$oidPersonalCount = ($allData.CertificatesWithAspNetOidOnPersonalStore | Measure-Object).Count; | |
Write-Output "Certificates with our OID on CurrentUser\My: $oidPersonalCount"; | |
if ($oidPersonalCount -gt 1) { | |
Write-Output "There should be at most 1 certificate with the ASP.NET Core OID on CurrentUser\My. Manually remove one or all of them and run dotnet-dev-certs again"; | |
} | |
$oidPersonalTrustedCount = ($allData.CertificatesWithAspNetOidOnTrustedRoot | Measure-Object).Count; | |
Write-Output "Certificates with our OID on CurrentUser\Root: $oidPersonalTrustedCount"; | |
if ($oidPersonalTrustedCount -gt 1) { | |
Write-Output "There should be at most 1 certificate with the ASP.NET Core OID on CurrentUser\Root. Manually remove one or all of them and run dotnet-dev-certs again"; | |
} | |
if (($oidPersonalCount -le 1) -and ($oidPersonalTrustedCount -le 1)) { | |
Write-Output "The number of certificates in the store looks correct. You could try running this script with -TryCreateCertificate to generate a certificate equivalent to the one 'dotnet dev-certs https' creates. Use this flag at your own risk"; | |
} | |
} | |
function GetCertsWithOid ($certificates) { | |
$results = @(); | |
foreach ($cert in $certificates) { | |
foreach ($ext in $cert.Extensions) { | |
if ($ext.Oid.Value -eq "1.3.6.1.4.1.311.84.1.1") { | |
$results+=$cert; | |
break; | |
} | |
} | |
} | |
return $results; | |
} | |
function GetCertData ($certificate) { | |
$data = [ordered]@{ | |
Subject = $certificate.Subject; | |
DnsNameList = $certificate.DnsNameList; | |
Issuer = $certificate.Issuer; | |
NotBefore = $certificate.NotBefore; | |
NotAfter = $certificate.NotAfter; | |
Thumbprint = $certificate.Thumbprint; | |
HasPrivateKey = $certificate.HasPrivateKey; | |
} | |
for ($i = 0; $i -lt $certificate.Extensions.Count; $i++) { | |
$extension = $certificate.Extensions[$i]; | |
$data["Extension-$i-Oid"] = $extension.Oid.Value; | |
$data["Extension-$i-FriendlyName"] = $extension.Oid.FriendlyName; | |
$data["Extension-$i-AspNetDevCertOid"] = $extension.Oid.Value -eq "1.3.6.1.4.1.311.84.1.1" | |
} | |
return New-Object pscustomobject -Property $data; | |
} | |
Get-DevCertDiagnostics | |
function TryCreateAspNetCoreCertUsingPowershell () { | |
$ekuOidCollection = [System.Security.Cryptography.OidCollection]::new(); | |
$ekuOidCollection.Add([System.Security.Cryptography.Oid]::new("1.3.6.1.5.5.7.3.1","Server Authentication")); | |
$sanBuilder = [System.Security.Cryptography.X509Certificates.SubjectAlternativeNameBuilder]::new(); | |
$sanBuilder.AddDnsName("localhost"); | |
$certificateExtensions = @( | |
# Subject Alternative Name | |
$sanBuilder.Build($true), | |
# ASP.NET Core OID | |
[System.Security.Cryptography.X509Certificates.X509Extension]::new( | |
"1.3.6.1.4.1.311.84.1.1", | |
[System.Text.Encoding]::ASCII.GetBytes("ASP.NET Core HTTPS development certificate"), | |
$false), | |
# KeyUsage | |
[System.Security.Cryptography.X509Certificates.X509KeyUsageExtension]::new( | |
[System.Security.Cryptography.X509Certificates.X509KeyUsageFlags]::KeyEncipherment, | |
$true), | |
# Enhanced key usage | |
[System.Security.Cryptography.X509Certificates.X509EnhancedKeyUsageExtension]::new( | |
$ekuOidCollection, | |
$true), | |
# Basic constraints | |
[System.Security.Cryptography.X509Certificates.X509BasicConstraintsExtension]::new($false,$false,0,$true)) | |
$parameters = @{ | |
Subject = "localhost"; | |
KeyAlgorithm = "RSA"; | |
KeyLength = 2048; | |
CertStoreLocation = "Cert:\CurrentUser\My"; | |
KeyExportPolicy = "Exportable"; | |
NotBefore = Get-Date; | |
NotAfter = (Get-Date).AddYears(1); | |
HashAlgorithm = "SHA256"; | |
Extension = $certificateExtensions; | |
SuppressOid = @("2.5.29.14"); | |
FriendlyName = "ASP.NET Core HTTPS development certificate" | |
} | |
New-SelfSignedCertificate @parameters | |
} | |
if($TryCreateCertificate){ | |
TryCreateAspNetCoreCertUsingPowershell | |
} | |
# Trust the cert using powershel | |
# Put the cert into the $cert variable with Get-ChildItem Cert:\CurrentUser\My\<<Thumbprint>> | |
# Export-Certificate -Cert $cert -FilePath <<TempPath>> -Type CERT | |
# Import-Certificate <<TempPath>> -CertStoreLocation Cert:\CurrentUser\Root\ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment