windows icon indicating copy to clipboard operation
windows copied to clipboard

Unable to set private key permissions - private key null

Open taliesins opened this issue 7 years ago • 10 comments

Cookbook version

Latest version

Chef-client version

Latest version

Platform Details

Windows Server 2012 R2 with latest patches applied. I have tried to install the latest WIM 5.1 and it did not help.

Scenario:

Trying to set ACL permissions on certificate

Steps to Reproduce:

windows_certificate 'certname' do
  private_key_acl ["#{node["kernel"]["cs_info"]["user_name"]}", 'Administrator', 'BUILTIN\Administrators']
end

Expected Result:

Private key permissions to be set for certificate.

Actual Result:

When not setting certificate permissions and loading MMC, you can see that certificate does have a private key.

This does not occur with all certificates. Only when CSP is CNG.

I think the error is related to the following (TL;DR; .net has problems getting private key when CSP is CNG): https://blogs.technet.microsoft.com/vishalagarwal/2010/03/30/verifying-the-private-key-property-for-a-certificate-in-the-store/

And we might be able to fix it using the following: https://stackoverflow.com/questions/17185429/how-to-grant-permission-to-private-key-from-powershell/22146915#22146915

Exception occurs with the following error message:

[2017-07-03T15:25:53+00:00] FATAL: Mixlib::ShellOut::ShellCommandFailed: windows
_certificate[wildcard.office.interxion.net] (role-servicebus::default line 75) h
ad an error: Mixlib::ShellOut::ShellCommandFailed: powershell_script[wildcard.of
fice.interxion.net] (C:/chef/cache/cookbooks/windows/resources/certificate.rb li
ne 39) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to e
xit with [0], but received '1'
---- Begin output of "C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe"
 -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Bypass -InputFormat None -F
ile "C:/Users/vagrant/AppData/Local/Temp/1/chef-script20170703-2168-1vd4wys.ps1"
 ----
STDOUT:
STDERR: C:\Users\vagrant\AppData\Local\Temp\1\chef-script20170703-2168-1vd4wys.p
s1 :
no private key exists.
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorExcep
   tion
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExceptio
   n,chef-script20170703-2168-1vd4wys.ps1
---- End output of "C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe" -
NoLogo -NonInteractive -NoProfile -ExecutionPolicy Bypass -InputFormat None -Fil
e "C:/Users/vagrant/AppData/Local/Temp/1/chef-script20170703-2168-1vd4wys.ps1" -
---
Ran "C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NonInte
ractive -NoProfile -ExecutionPolicy Bypass -InputFormat None -File "C:/Users/vag
rant/AppData/Local/Temp/1/chef-script20170703-2168-1vd4wys.ps1" returned 1
[2017-07-03T15:25:53+00:00] FATAL: Mixlib::ShellOut::ShellCommandFailed: windows
_certificate[wildcard.office.interxion.net] (role-servicebus::default line 75) h
ad an error: Mixlib::ShellOut::ShellCommandFailed: powershell_script[wildcard.of
fice.interxion.net] (C:/chef/cache/cookbooks/windows/resources/certificate.rb li
ne 39) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to e
xit with [0], but received '1'
---- Begin output of "C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe"
 -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Bypass -InputFormat None -F
ile "C:/Users/vagrant/AppData/Local/Temp/1/chef-script20170703-2168-1vd4wys.ps1"
 ----
STDOUT:
STDERR: C:\Users\vagrant\AppData\Local\Temp\1\chef-script20170703-2168-1vd4wys.p
s1 :
no private key exists.
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorExcep
   tion
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExceptio
   n,chef-script20170703-2168-1vd4wys.ps1
---- End output of "C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe" -
NoLogo -NonInteractive -NoProfile -ExecutionPolicy Bypass -InputFormat None -Fil
e "C:/Users/vagrant/AppData/Local/Temp/1/chef-script20170703-2168-1vd4wys.ps1" -
---
Ran "C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NonInte
ractive -NoProfile -ExecutionPolicy Bypass -InputFormat None -File "C:/Users/vag
rant/AppData/Local/Temp/1/chef-script20170703-2168-1vd4wys.ps1" returned 1

taliesins avatar Jul 03 '17 15:07 taliesins

I think the way around this problem is to make use of the powershell commandlets for certificates. When I used the cmdlet instead of the powershell generated by Chef I was able to access certificate private key.

cmdlet: Import-PfxCertificate -FilePath C:\chef\cache\test.pfx -CertStoreLocation Cert:\LocalMachine\My

chef powershell:

$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 "C:\chef\cache\test.pfx", "", ([System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeyset)
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store "MY", ([System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine)
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$store.Add($cert)
$store.Close()

I can only think it was implemented this way as perhaps Powershell 3 did not have this commandlet. Perhaps Get-Command could be used so that systems that support the commandlet will use it.

taliesins avatar Jul 06 '17 09:07 taliesins

@taliesins Thanks for reporting and the extra information. This has been brought up to the team to review.

iennae avatar Jul 11 '17 19:07 iennae

I experience the reported issue when using Import-PfxCertificate. The issue being where a user imports a certificate and private key from a PKCS package (*.pfx), and the certificate appears to have a private key c/o the HasPrivateKey data member, but the PrivateKey data member is null.

adamfortuno avatar Apr 16 '18 19:04 adamfortuno

Actual problem as I see, is with guard script (at least with Win 2016) When guard script runs second time behind LocalSystem (Chef configured as Task) it deletes Private Key from C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys When System.Security.Cryptography.X509Certificates.X509Certificate2 class instantiated it creates temporary PrivateKey container (with actual conatiner name), and deletes it when disposed.

sergeydeg avatar May 15 '18 07:05 sergeydeg

@sergeydeg Do you know any way around this?

ilovemysillybanana avatar May 24 '18 01:05 ilovemysillybanana

@sergeydeg and @ilovemysillybanana have a look at #483 and vote for it. This problem exists in .net 4.61 and below. Powershell leverages .net so the problem bubbles up.

taliesins avatar May 24 '18 05:05 taliesins

@ilovemysillybanana I implemented whole PFX import and ACL with true PowerShell. It is not out-of-box usage, and strictly tied to my task. Can share code block, if someone can make this more usable to implement in this cookbook. My solution only works with Server 2012/ Windows 8 and UP

@taliesins a comment to your solution - it not remove the problem with subsequent guard script runs

sergeydeg avatar May 24 '18 12:05 sergeydeg

@sergeydeg I've actually just started working with powershell, but if I could adapt the solution to my own needs I'd be happy to do so and create a pull request after. I'm using windows 2k16 so that would be great.

@taliesins I am new to developing on Windows, my version of windows is using .NET 4.7 shouldn't I be immune from this problem?

ilovemysillybanana avatar May 24 '18 13:05 ilovemysillybanana

@ilovemysillybanana take a look: chef pfx import acl

sergeydeg avatar May 24 '18 14:05 sergeydeg

@sergeydeg will do! I don't know if it matters but I'm doing this through vagrant when I bake my images. If you guys know of anyone who's done it that way, that'd be great to see.

ilovemysillybanana avatar May 25 '18 20:05 ilovemysillybanana