CertificateDsc
CertificateDsc copied to clipboard
How to set permissions on private key after importing cert via DSC
After importing pfx file how to set permissions on private key with DSC?
e.g., After loading cert into localcomputer \ my store how would one set IIS_IUSRS access to private key for use with IIS site using DSC process?
Hi @plraustin - this is a really good question.
There isn't currently a resource that can be used to assign access to private keys to other local or domain accounts. This does seem like a good idea for a resource and wouldn't be too difficult to implement (based on the work I'm currently doing).
But in the meant time, you could use xScript to do this fairly easily.
Are you importing the certificate with xCertificateImport or are you requesting it using xCertReq?
I build for my use this (ugly) workaround:
Script Certicate
{
GetScript = {
$store = "My"
$thumbprint = "xxxx"
$cert = Get-ChildItem "Cert:\LocalMachine\$store" | where {$_.Thumbprint -like $thumbprint}
$path = "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\$($cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName)"
@{Result = $path }
}
TestScript = {
$store = "My"
$thumbprint = "xxxx"
$userName = "IIS AppPool\DefaultAppPool"
$cert = Get-ChildItem "Cert:\LocalMachine\$store" | where {$_.Thumbprint -like $thumbprint}
$path = "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\$($cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName)"
$acl = get-acl $path
($acl.Access | Where {$_.IdentityReference -eq $userName}) -ne $null
}
SetScript = {
$store = "My"
$thumbprint = "xxxx"
$userName = "IIS AppPool\DefaultAppPool"
$cert = Get-ChildItem "Cert:\LocalMachine\$store" | where {$_.Thumbprint -like $thumbprint}
$path = "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\$($cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName)"
$acl = get-acl $path
$rule = new-object security.accesscontrol.filesystemaccessrule $userName, "Read", allow
$acl.AddAccessRule($rule)
set-acl $path $acl
}
}
As per my experience, current powershell implementation cannot be used to import a PFX certificate and then assign permissions. As this DSC module is using the standard PS mechanism is affected too.
My current alternative is not to use the DSC module to import a certificate where I need special rights. See this example implementation using other .Net classes. See this blogpost for more technical details.
Configuration ImportPfxCertificate {
param(
[PSCredential] $AdminCreds,
[String] $CertificateFile,
[String] $ThumbPrint,
[String] $PrivateKeyPwd,
[String] $CertUserName
)
Import-DscResource -ModuleName PSDesiredStateConfiguration
Script InstallPfxCert
{
Getscript = {
$Store = New-Object System.Security.Cryptography.X509Certificates.X509Store -Argumentlist "My", LocalMachine
$Store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly)
$cert = $Store.Certificates | Where Thumbprint -eq $using:thumbprint
$Store.Close()
@{Result = $cert }
}
TestScript = {
$Store = New-Object System.Security.Cryptography.X509Certificates.X509Store -Argumentlist "My", LocalMachine
$Store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly)
$cert = $Store.Certificates | Where Thumbprint -eq $using:thumbprint
$Store.Close()
$cert -ne $null
}
SetScript = {
$pwd = ConvertTo-SecureString $using:PrivateKeyPwd -AsPlainText -Force
$flags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable
$Certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($using:CertificateFile, $pwd, $flags)
$Store = New-Object System.Security.Cryptography.X509Certificates.X509Store -Argumentlist "MY", LocalMachine
$Store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$Store.Add($Certificate)
$Store.Close()
}
PsDscRunAsCredential = $AdminCreds
Dependson = "[xRemoteFile]SpPfxCertFile"
}
Script SetCerticatePermission
{
GetScript = {
$Store = New-Object System.Security.Cryptography.X509Certificates.X509Store -Argumentlist "MY", LocalMachine
$Store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly)
$cert = $Store.Certificates | Where Thumbprint -eq $using:thumbprint
$Store.Close()
$path = "$($env:ProgramData)\Microsoft\Crypto\RSA\MachineKeys\$($cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName)"
@{Result = $path }
}
TestScript = {
$Store = New-Object System.Security.Cryptography.X509Certificates.X509Store -Argumentlist "MY", LocalMachine
$Store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly)
$cert = $Store.Certificates | Where Thumbprint -eq $using:thumbprint
$Store.Close()
$path = "$($env:ProgramData)\Microsoft\Crypto\RSA\MachineKeys\$($cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName)"
$acl = get-acl $path
($acl.Access | Where {$_.IdentityReference -eq $using:CertUserName}) -ne $null
}
SetScript = {
$Store = New-Object System.Security.Cryptography.X509Certificates.X509Store -Argumentlist "MY", LocalMachine
$Store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly)
$cert = $Store.Certificates | Where Thumbprint -eq $using:thumbprint
$Store.Close()
$PKFile = Get-ChildItem "$env:ProgramData\Microsoft\Crypto\RSA\MachineKeys\$($cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName)"
$PKAcl = $PKFile.GetAccessControl("Access")
$ReadAccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($using:CertUserName, [System.Security.AccessControl.FileSystemRights]::Read, [System.Security.AccessControl.AccessControlType]::Allow)
$PKAcl.AddAccessRule($ReadAccessRule)
Set-Acl $PKFile.FullName $PKAcl
}
DependsOn = "[Script]InstallPfxCert"
}
}
I wrote a module for this issue, https://github.com/twerthi/xCertificatePermission