Does anybody know how the powershell certificate provider paths map to certmgr.msc folders?

Lucas picture Lucas · Nov 5, 2016 · Viewed 8k times · Source

When using powershell to investigate the Certificate Provider i noticed that all the paths seem similar but not the same as the folder structure within certmgr. It seems pretty clear that:

Certs:\LocalMachine ~= Certificates (Local Computer)
Certs:\CurrentUser ~= Certificates - Current User

I'm also guessing that:

Root ~= Trusted Root Certification Authority
My ~= Personal
WebHosting ~= WebHosting
...

But i have been unable to find any sort of official reference (or even sensible explanation) to give me the warm fuzzy I'm looking for...

My intent is to test an https WCF service locally (both server and client side). I can easily generate the self signed certificate needed by the server using New-SelfSignedCertificate. However, if I try to point my client (also .NET) at the service it fails to connect given that the service serves up a non-trusted certificate.

I have found various out-dated references (like this one), showing how I could use a combination of makecert (now deprecated), and certmgr to generate a certificate authority, then use it to sign the cert for my https service, then install the certificate authority cert into Trusted Root Certification Authority container to get everything working. While this approach would likely work, it is certainly not developer/automation friendly.

That said, I was able to use powershell to do this:

$my_cert_store_location = "Cert:\LocalMachine\My"
$root_cert_store_location = "Cert:\LocalMachine\Root"
$root_friendly_name = "Test Root Authority"
$root_cert_subject = "CN=$($root_friendly_name)"
# The ip and port you want to reserve for your app
$ipport = "127.0.0.11:8734"
# Your app guid (found in ApplicationInfo.cs)
$appid = "{f77c65bd-d592-4a7b-ae32-cab24130fdf6}"
# Your dns name
$dns_name = "my-machine-local"
$rebuild_root_cert = $false

$root_cert = Get-ChildItem $my_cert_store_location | 
    Where-Object {$_.SubjectName.Name.Equals($root_cert_subject)}
if ($root_cert -and $rebuild_root_cert) 
{
    Get-ChildItem $root_cert_store_location |
        Where-Object {$_.SubjectName.Name.Equals($root_cert_subject)} |
        Remove-Item

    Remove-Item $root_cert
    $root_cert = $false
}
if (-not $root_cert) 
{
    $root_cert = New-SelfSignedCertificate `
        -Type Custom `
        -FriendlyName $root_friendly_name `
        -HashAlgorithm sha384 `
        -KeyAlgorithm RSA `
        -KeyLength 4096 `
        -Subject $root_cert_subject `
        -KeyUsage DigitalSignature, CertSign `
        -NotAfter (Get-Date).AddYears(20) `
        -CertStoreLocation $my_cert_store_location
    Write-Output "Created root cert: $($root_cert.Thumbprint)"

    $exported_cert = New-TemporaryFile
    Export-Certificate -Cert $root_cert -FilePath $exported_cert.FullName
    $imported_root_cert = Import-Certificate -FilePath $exported_cert.FullName `
        -CertStoreLocation $root_cert_store_location
    Write-Output "Imported root cert to: $($root_cert_store_location)\$($imported_root_cert.Thumbprint)"
}

Write-Output "Root cert is: $($root_cert.Thumbprint)"

$test_signed_cert_subject = "CN=$($dns_name)"
$test_signed_cert = Get-ChildItem $my_cert_store_location | 
    Where-Object {$_.SubjectName.Name.Equals($test_signed_cert_subject)}
if (-not $test_signed_cert)
{
    $test_signed_cert = New-SelfSignedCertificate `
        -Type Custom `
        -Subject $test_signed_cert_subject `
        -FriendlyName $dns_name `
        -Signer $root_cert `
        -CertStoreLocation $my_cert_store_location
    Write-Output "Created signed cert: $($test_signed_cert.Thumbprint)"
}

Write-Output "Signed cert is: $($test_signed_cert.Thumbprint)"

if ($test_signed_cert)
{
    netsh http delete sslcert `
        ipport="$($ipport)"
    netsh http add sslcert `
        ipport="$($ipport)" `
        appid="$($appid)" `
        certstorename="My" `
        certhash="$($test_signed_cert.Thumbprint)"
    Write-Output "Assigned signed cert to: $($ipport)"
}

But the question still stands... Is there any information about how the certificate provider paths map to certmgr folders?

Answer

Crypt32 picture Crypt32 · Nov 5, 2016

Here is the mapping between containers (in parentheses) and their description:

  • Personal (My) — This container is used to store certificates with private keys. When a certificate private key is used, the application looks to this container to find the appropriate certificate and associated private key.
  • Trusted Root Certification Authorities (ROOT) — This container contains trusted, self-signed certificates without private keys. Each certificate chain must chain up to a certificate presented in self-signed form. This self-signed certificate is the ‘root certificate’ or ‘trusted anchor.’ However, not all root certificates can be considered as trusted. You should carefully choose which new certificates you will consider as trusted.
  • Enterprise Trust (trust) — This container is used to store Certificate Trust Lists (CTL). For example, the Key Management Server adds its certificate to this container.
  • Intermediate Certification Authorities (CA) — This container keeps many different types of CA certificates. These certificates are usually used by the certificate chaining engine to build certificate chains.
  • Trusted Publishers (TrustedPublisher) — This container keeps explicitly trusted signing certificates. While the digital signature certificate chains up to the trusted root certification authority, many applications (such Microsoft Office and Windows PowerShell) are required to store a particular signing certificate in this container in order to trust signatures from that particular signer. This means that a digital signature-aware application can trust one signing certificate but not trust another signing certificate even if both certificates are issued by the same certification authority.
  • Untrusted Certificates (Disallowed) — This container keeps explicitly untrusted certificates. If you decide to not trust either a particular certificate or all certificates issued by a particular certification authority, just add these certificates to this container. By default, this container already contains two certificates. It is strongly recommended to NOT REMOVE them from the container. For additional info read the following article: http://support.microsoft.com/kb/293817.
  • Third-Party Root Certification Authorities (AuthRoot) — This certificate container is similar to the Trusted Root Certification Authorities. It keeps the certificates from the Microsoft Root Certificate Program. For more information about the Microsoft Root Certificate program, read the following article: http://support.microsoft.com/kb/931125.
  • Trusted People (TrustedPeople) — This container keeps certificates issued to people or end entities that are explicitly trusted. Most often, these are self-signed certificates or certificates explicitly trusted in an application such as Microsoft Outlook. To share an EFS–encrypted file with other parties, you must have their certificate in this store.
  • Certificate Enrollment Requests (REQUEST) — This container stores certificate enrollment requests until these requests are submitted to the certification authority. When a certification authority issues a certificate in response to a request, you need to install the certificate to this container using a special utility, such CertReq.exe. After that, the certificate enrollment request is transferred to the Personal (My) container as a certificate.
  • Smart Card Trusted Roots (SmartCardRoot) — This container is used to store trusted smart card certificates.
  • Other People (AddressBook) — This container maintains certificates that have been added to an Outlook contact.
  • Active Directory User Object (UserdDS) — This container is used to store certificates associated with a user object and published in Active Directory. The content of this container is equal to the certificates that are shown in the advanced view of the Active Directory Users and Computers console when the properties of a user object are viewed.