How to use WSMan config provider for certificate authentication


WSMan Client certificate authentication is primarily used in non-domain cases: client can specify certain certificate as credential, after authentication each other, it’s mapped to a local account on the server, meaning the WinRM service runs under the context of the mapped account when processing the request. When using client certificates, multiple client certificates can be mapped to a single account using pattern matching rules


 


In this blog, we discuss three topics:


              Enable config settings for certificate auth


              Configure cert mapping entry on the server machine


              Perform remote operation using certificate auth on the client machine


 


1) Enable config settings for certificate auth


There’re specific config settings that control whether WinRM client and service will support Certificate Based Authentication


1.a) Client stack support for certificate auth is enabled by default, so you don’t need to change it if Certificate Based Authentication is desired



PS C:\Windows\system32> dir WSMan:\localhost\Client\Auth\Certificate


   WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Client\Auth


Name                      Value                                                             Type


—-                      —–                                                             —-


Certificate               true                                                              System.String


 


1.b) Service support for certificate auth is disabled by default to reduce attack surface, so you’ll have to explicitly enable it if Certificate Based Authentication is desired



PS C:\Windows\system32> dir WSMan:\localhost\Service\Auth\Certificate


   WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Service\Auth


Name                      Value                                                             Type


—-                      —–                                                             —-


Certificate               false                                                             System.String


PS C:\Windows\system32> set-item -Path WSMan:\localhost\Service\Auth\Certificate -Value $true


 


2) Configure cert mapping entry


There are no entries in the certificate mapping table by default, but you can use certificate mapping resource URI “http://schemas.microsoft.com/wbem/wsman/1/config/service/certmapping” to perform get, put, create, delete, and enumerate operations using WSMan-related PS cmdlet such as “Get-WSManInstance, Set-WSManInstance, New-WSManInstance, Remove-WSManInstance”, but here in this blog I show examples using WSMan config provider instead as demonstrated by the following traversal.



PS C:\Windows\system32> cd WSMan:\localhost\ClientCertificate


PS WSMan:\localhost\ClientCertificate>


 


Before configuring cert mapping entries on the server machine, let’s look at some of the key properties in the cert mapping entry


              Subject : it’s the Subject field or Subject Alternative Name (SAN) field of client certificate, which contains the name of the entity that the certificate was issued to, first “*” character could match anything. For example:


o             If the certificate is issued to a user: then it contains the username in the form “Principal Name=user@domain.com”


o             If the certificate is issued to a machine: then it contains the name of the machine in the form “DNS Name=machine.foo.com”


              Issuer: it’s the certificate thumbprint of the CA that issued the certificate. The certificate identified by the thumbprint must be present in the server machine “CA” store. The certificate must have key usage that allows it to sign other certificates (CERT_KEY_CERT_SIGN_KEY_USAGE), unless it’s a self-signed certificate in which case the key usage is not required


              URI: it’s the URI or URI prefix for which this cert mapping will apply, last “*” character could match anything


 


2.1) Create cert mapping entry if the entry does not already exist, following PS script automates this process: first find user certificate which has the usage “Client Authentication (1.3.6.1.5.5.7.3.2)” as this is required for subsequent client cert auth; then get ISSUER name for the above user certificate, get the ISSUER thumbprint, which was used in the last line to create cert mapping entry, so remote access to WinRM using client certificates is mapped to user “certAdminAccount1” on the server machine. Please note if this local user is not in “administrators” group, you need to configure security to allow non-admin through but this is out of the scope of this blog, We’ll discuss “How to configure security for different URI” in a separate blog.



foreach ($cert in get-childitem cert:\CurrentUser\My)


{


    foreach ($ext in $cert.Extensions)


    {


        if ($ext.Oid.FriendlyName -eq “Enhanced Key Usage”)


        {


            $ekey = [System.Security.Cryptography.X509Certificates.X509EnhancedKeyUsageExtension]$ext


            $oids = $ekey.EnhancedKeyUsages


            foreach ($oid in $oids)


            {


                if ($oid.FriendlyName -eq “Client Authentication”)


                {


                    $usercerts=$cert


                }


            }


        }


    }


}


if ($usercerts.count -eq $null) {$issuername = (, $usercerts)[0].Issuer} else {$issuername = $usercerts[0].Issuer}


$IssuerThumbprint=(get-childitem -path cert:\CurrentUser\ca | where-object { $_.Subject -eq $issuername }).Thumbprint


net user certAdminAccount1 /delete


net user certAdminAccount1 Dummy_pswd /add


net localgroup administrators certAdminAccount1 /add


$password = ConvertTo-SecureString Dummy_pswd -AsPlainText –Force


$adminuser = New-Object System.Management.Automation.PSCredential certAdminAccount1,$password


New-Item -Path WSMan:\localhost\ClientCertificate -URI http://microsoft.test.mig.wsman/* -Subject *.com -Issuer $IssuerThumbprint -Credential $adminuser -force


 


Output is similar to the following



   WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\ClientCertificate


Name                      Type                 Keys


—-                      —-                 —-


ClientCertificate_6047… Container            {URI=http://microsoft.test.mig.wsman/*, Issuer=1B3FD224D66C6413FE20D2…


 


2.2) Get cert mapping entry with specific keys if the entry exists



PS C:\Windows\System32> Get-Item -Path WSMan:\localhost\ClientCertificate\ClientCertificate_604778647\* -force


   WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\ClientCertificate\ClientCertificate_604778647


Name                      Value                                                             Type


—-                      —–                                                             —-


URI                       http://microsoft.test.mig.wsman/*                                 System.String


Subject                   *.com                                                             System.String


Issuer                    1B3FD224D66C6413FE20D21E38B304226D192DFE                          System.String


UserName                  certAdminAccount1                                                 System.String


Enabled                   true                                                              System.String


Password                                                                                    System.String


 


2.3) change any non-keys of cert mapping entry if the entry already exists [The Issuer, Subject, and URI properties are keys for the purposes of WS-Transfer operations.]



PS C:\Windows\System32> Set-Item WSMan:\localhost\ClientCertificate\ClientCertificate_604778647\Enabled $true -force


 


 


2.4) Enumerate will list all existing cert mapping entries



PS C:\Windows\System32> Get-Item -Path WSMan:\localhost\ClientCertificate\* -force


   WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\ClientCertificate


Name                      Type                 Keys


—-                      —-                 —-


ClientCertificate_6047… Container            {URI=http://microsoft.test.mig.wsman/*, Issuer=1B3FD224D66C6413FE20D2…


 


 


2.5) Delete cert mapping entry if the entry exists



PS C:\Windows\System32> Remove-Item -Path WSMan:\localhost\ClientCertificate\ClientCertificate_* -Recurse -force


 


3) Perform remote operation using certificate auth on the client machine


In the above first step, you enable both client and server config settings for certificate auth. In the second step, you configure cert mapping entry on the server machine that defines the actual mapping behavior. So here’s the final step on how to perform remote operation using certificate auth. These demo scripts in this blog may need to be changed a little bit to make it work for yourself such as valid URI, valid server name etc…


3.1) On the server machine you must have https listener and port is opened for through traffic, as client certificate authentication is allowed only when connecting to a https address.



PS D:\Windows\system32> Set-WSManQuickConfig -UseSSL -Force


WinRM already is set up to receive requests on this machine.


WinRM has been updated for remote management.


Created a WinRM listener on HTTPS://* to accept WS-Man requests to any IP on this machine.


Configured CertificateThumbprint setting for the service.


PS D:\Windows\system32> netsh advfirewall firewall add rule name=”Port 443″ dir=in action=allow protocol=TCP localport=443


Ok.


 


3.2) On the client machine, following PS script demonstrates the process to perform a remote GET operation using certificate auth: first find user certificate which has the usage “Client Authentication (1.3.6.1.5.5.7.3.2)” as this is required for client cert auth; its thumbprint was used in the last line as the client credential



foreach ($cert in get-childitem cert:\CurrentUser\My)


{


    foreach ($ext in $cert.Extensions)


    {


        if ($ext.Oid.FriendlyName -eq “Enhanced Key Usage”)


        {


            $ekey = [System.Security.Cryptography.X509Certificates.X509EnhancedKeyUsageExtension]$ext


            $oids = $ekey.EnhancedKeyUsages


            foreach ($oid in $oids)


            {


                if ($oid.FriendlyName -eq “Client Authentication”)


                {


                    $usercertThumbprint=$cert.Thumbprint


                }


            }


        }


    }


}


winrm g http://microsoft.test.mig.wsman/test -r:https://machine.STBTEST.MICROSOFT.COM -a:certificate -certificate:$usercertThumbprint


 

Comments (3)

  1. Apostille says:

    Hi,

            It is very informative and very helpful on my research regarding seo techniques. Thanks for sharing this post.

    <a href="http://www.certificate-attestation.in/apostille.html">Apostille  

    </a>.

  2. Luis says:

    For the client certificate, you say

    If the certificate is issued to a user: then it contains the username in the form “Principal Name=user@domain.com”

    Local users aren't in domains.

    What is the SAN for them?

Skip to main content