CertificateDsc icon indicating copy to clipboard operation
CertificateDsc copied to clipboard

Lost Private Key after sysprep

Open mattbowes opened this issue 6 years ago • 5 comments

Details of the scenario you tried and the problem that is occurring:

After syspreping a server, the certificate is left in the cert store but the private key is removed during the sysprep process. xPfxImport only checks to ensure the thumbprint is present. It does not check to see if the certificate has a private key so it never imports the pfx file and the certificate.

The DSC configuration that is using the resource (as detailed as possible):

xPfxImport Wildcard { Thumbprint = $wildcardthumbprint Path = $certificatepath Location = 'LocalMachine' Store = 'My' Exportable = $true Credential = $Credential1 Ensure = 'Present' DependsOn = "[xDSCDomainjoin]JoinDomain" }

Version of the Operating System and PowerShell the DSC Target Node is running:

DSC running in Azure OS version: 2012R2

Version of the DSC module you're using, or 'dev' if you're using current dev branch:

xCertificate 3.2.0.0

mattbowes avatar Apr 19 '18 20:04 mattbowes

Hi @mattbowes - ah, this is a great catch.

We should be able to fix this by changing the Test-TargetResource to check the Private Key with something like this:

(Get-ChildItem -path Cert:\LocalMachine\My\498F1F592D3E56A7124BBCD65AE70C1FD615BDE5).HasPrivateKey

Might have a look at this tonight.

PlagueHO avatar May 01 '18 06:05 PlagueHO

@PlagueHO checking .hasPrivateKey still wont work after a sysprep. It returns true even though the private key is gone. If you run something like (gci cert:\localmachine\my | where thumbprint -eq $thumb).HasPrivateKey (gci cert:\localmachine\my | where thumbprint -eq $thumb).PrivateKey.CspKeyContainerInfo you will see that .hasPrivateKey returns true but CSPKeyContainerInfo returns nothing. The private key file on the file system does not exist.

Could the check be changed to if ($certificate.hasprivatekey -and $certificate.PrivateKey.CspKeyContainerInfo)

mattbowes avatar May 24 '18 19:05 mattbowes

Great info @mattbowes - I'll make the change this weekend. Seems that sysprep doesn't do a great job here!

PlagueHO avatar May 24 '18 20:05 PlagueHO

I updated MSFT_PfxImport.psm1 and created a pull request. I think that will fix it

mattbowes avatar May 24 '18 20:05 mattbowes

Simplified from this excellent post: http://paulstovell.com/blog/x509certificate2 The Public key is (usually) written to registry, and the Private key written to file (never stored together, unless exported to PFX), either with system/machine files or User data. The point is that it's only 'linked' by the .Net object, but not really the same thing at all, and stored differently.

When the cert request is still stored with all info, a /repairstore can fix that issue. But sysprep destroys personal data to generalise the machine, hence probably why I think it's lost. Even if the file is still there, it can be inaccessible, because of permissions.

Anyhow, up until .Net 4.8 (with GetRSAPrivateKey()) there's no easy way to get the Private key, and I'm yet to find a nice way to find if the Private key is actually available on the system or not (something quick we can run every 15min). Until then, there's not much we can do on the resource side.

gaelcolas avatar Jul 01 '19 12:07 gaelcolas